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