    1   /*
    2    * Copyright 1999-2004 The Apache Software Foundation
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *     http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  package org.apache.commons.jxpath.ri.compiler;
    17
    18  import org.apache.commons.jxpath.ri.Compiler;
    19  import org.apache.commons.jxpath.ri.QName;
    20
    21  /***
    22   * @author Dmitri Plotnikov
    23   * @version $Revision: 1.10 $ $Date: 2004/02/29 14:17:39 $
    24   */
    25  public class TreeCompiler implements Compiler {
    26
    27      private static final QName QNAME_NAME = new QName(null, "name");
    28
    29      public Object number(String value) {
    30          return new Constant(new Double(value));
    31      }
    32
    33      public Object literal(String value) {
    34          return new Constant(value);
    35      }
    36
    37      public Object qname(String prefix, String name) {
    38          return new QName(prefix, name);
    39      }
    40
    41      public Object sum(Object[] arguments) {
    42          return new CoreOperationAdd(toExpressionArray(arguments));
    43      }
    44
    45      public Object minus(Object left, Object right) {
    46          return new CoreOperationSubtract(
    47              (Expression) left,
    48              (Expression) right);
    49      }
    50
    51      public Object multiply(Object left, Object right) {
    52          return new CoreOperationMultiply((Expression) left, (Expression) right);
    53      }
    54
    55      public Object divide(Object left, Object right) {
    56          return new CoreOperationDivide((Expression) left, (Expression) right);
    57      }
    58
    59      public Object mod(Object left, Object right) {
    60          return new CoreOperationMod((Expression) left, (Expression) right);
    61      }
    62
    63      public Object lessThan(Object left, Object right) {
    64          return new CoreOperationLessThan((Expression) left, (Expression) right);
    65      }
    66
    67      public Object lessThanOrEqual(Object left, Object right) {
    68          return new CoreOperationLessThanOrEqual(
    69              (Expression) left,
    70              (Expression) right);
    71      }
    72
    73      public Object greaterThan(Object left, Object right) {
    74          return new CoreOperationGreaterThan(
    75              (Expression) left,
    76              (Expression) right);
    77      }
    78
    79      public Object greaterThanOrEqual(Object left, Object right) {
    80          return new CoreOperationGreaterThanOrEqual(
    81              (Expression) left,
    82              (Expression) right);
    83      }
    84
    85      public Object equal(Object left, Object right) {
    86          if (isNameAttributeTest((Expression) left)) {
    87              return new NameAttributeTest((Expression) left, (Expression) right);
    88          }
    89          else {
    90              return new CoreOperationEqual(
    91                  (Expression) left,
    92                  (Expression) right);
    93          }
    94      }
    95
    96      public Object notEqual(Object left, Object right) {
    97          return new CoreOperationNotEqual(
    98              (Expression) left,
    99              (Expression) right);
    100     }
    101
    102     public Object minus(Object argument) {
    103         return new CoreOperationNegate((Expression) argument);
    104     }
    105
    106     public Object variableReference(Object qName) {
    107         return new VariableReference((QName) qName);
    108     }
    109
    110     public Object function(int code, Object[] args) {
    111         return new CoreFunction(code, toExpressionArray(args));
    112     }
    113
    114     public Object function(Object name, Object[] args) {
    115         return new ExtensionFunction((QName) name, toExpressionArray(args));
    116     }
    117
    118     public Object and(Object arguments[]) {
    119         return new CoreOperationAnd(
    120             toExpressionArray(arguments));
    121     }
    122
    123     public Object or(Object arguments[]) {
    124         return new CoreOperationOr(
    125             toExpressionArray(arguments));
    126     }
    127
    128     public Object union(Object[] arguments) {
    129         return new CoreOperationUnion(
    130             toExpressionArray(arguments));
    131     }
    132
    133     public Object locationPath(boolean absolute, Object[] steps) {
    134         return new LocationPath(absolute, toStepArray(steps));
    135     }
    136
    137     public Object expressionPath(
    138         Object expression,
    139         Object[] predicates,
    140         Object[] steps)
    141     {
    142         return new ExpressionPath(
    143             (Expression) expression,
    144             toExpressionArray(predicates),
    145             toStepArray(steps));
    146     }
    147
    148     public Object nodeNameTest(Object qname) {
    149         return new NodeNameTest((QName) qname);
    150     }
    151
    152     public Object nodeTypeTest(int nodeType) {
    153         return new NodeTypeTest(nodeType);
    154     }
    155
    156     public Object processingInstructionTest(String instruction) {
    157         return new ProcessingInstructionTest(instruction);
    158     }
    159
    160     public Object step(int axis, Object nodeTest, Object[] predicates) {
    161         return new Step(
    162             axis,
    163             (NodeTest) nodeTest,
    164             toExpressionArray(predicates));
    165     }
    166
    167     private Expression[] toExpressionArray(Object[] array) {
    168         Expression expArray[] = null;
    169         if (array != null) {
    170             expArray = new Expression[array.length];
    171             for (int i = 0; i < expArray.length; i++) {
    172                 expArray[i] = (Expression) array[i];
    173             }
    174         }
    175         return expArray;
    176     }
    177
    178     private Step[] toStepArray(Object[] array) {
    179         Step stepArray[] = null;
    180         if (array != null) {
    181             stepArray = new Step[array.length];
    182             for (int i = 0; i < stepArray.length; i++) {
    183                 stepArray[i] = (Step) array[i];
    184             }
    185         }
    186         return stepArray;
    187     }
    188
    189     private boolean isNameAttributeTest(Expression arg) {
    190         if (!(arg instanceof LocationPath)) {
    191             return false;
    192         }
    193
    194         Step[] steps = ((LocationPath) arg).getSteps();
    195         if (steps.length != 1) {
    196             return false;
    197         }
    198         if (steps[0].getAxis() != Compiler.AXIS_ATTRIBUTE) {
    199             return false;
    200         }
    201         NodeTest test = steps[0].getNodeTest();
    202         if (!(test instanceof NodeNameTest)) {
    203             return false;
    204         }
    205         if (!((NodeNameTest) test).getNodeName().equals(QNAME_NAME)) {
    206             return false;
    207         }
    208         return true;
    209     }
    210 }