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  package org.apache.commons.jxpath.ri.compiler;
18  
19  import org.apache.commons.jxpath.ri.Compiler;
20  import org.apache.commons.jxpath.ri.QName;
21  
22  /**
23   * @author Dmitri Plotnikov
24   * @version $Revision: 652845 $ $Date: 2008-05-02 19:46:46 +0200 (Fr, 02 Mai 2008) $
25   */
26  public class TreeCompiler implements Compiler {
27  
28      private static final QName QNAME_NAME = new QName(null, "name");
29  
30      public Object number(String value) {
31          return new Constant(new Double(value));
32      }
33  
34      public Object literal(String value) {
35          return new Constant(value);
36      }
37  
38      public Object qname(String prefix, String name) {
39          return new QName(prefix, name);
40      }
41  
42      public Object sum(Object[] arguments) {
43          return new CoreOperationAdd(toExpressionArray(arguments));
44      }
45  
46      public Object minus(Object left, Object right) {
47          return new CoreOperationSubtract(
48              (Expression) left,
49              (Expression) right);
50      }
51  
52      public Object multiply(Object left, Object right) {
53          return new CoreOperationMultiply((Expression) left, (Expression) right);
54      }
55  
56      public Object divide(Object left, Object right) {
57          return new CoreOperationDivide((Expression) left, (Expression) right);
58      }
59  
60      public Object mod(Object left, Object right) {
61          return new CoreOperationMod((Expression) left, (Expression) right);
62      }
63  
64      public Object lessThan(Object left, Object right) {
65          return new CoreOperationLessThan((Expression) left, (Expression) right);
66      }
67  
68      public Object lessThanOrEqual(Object left, Object right) {
69          return new CoreOperationLessThanOrEqual(
70              (Expression) left,
71              (Expression) right);
72      }
73  
74      public Object greaterThan(Object left, Object right) {
75          return new CoreOperationGreaterThan(
76              (Expression) left,
77              (Expression) right);
78      }
79  
80      public Object greaterThanOrEqual(Object left, Object right) {
81          return new CoreOperationGreaterThanOrEqual(
82              (Expression) left,
83              (Expression) right);
84      }
85  
86      public Object equal(Object left, Object right) {
87          return isNameAttributeTest((Expression) left)
88                  ? new NameAttributeTest((Expression) left, (Expression) right)
89                  : new CoreOperationEqual((Expression) left, (Expression) right);
90      }
91  
92      public Object notEqual(Object left, Object right) {
93          return new CoreOperationNotEqual((Expression) left, (Expression) right);
94      }
95  
96      public Object minus(Object argument) {
97          return new CoreOperationNegate((Expression) argument);
98      }
99  
100     public Object variableReference(Object qName) {
101         return new VariableReference((QName) qName);
102     }
103 
104     public Object function(int code, Object[] args) {
105         return new CoreFunction(code, toExpressionArray(args));
106     }
107 
108     public Object function(Object name, Object[] args) {
109         return new ExtensionFunction((QName) name, toExpressionArray(args));
110     }
111 
112     public Object and(Object[] arguments) {
113         return new CoreOperationAnd(toExpressionArray(arguments));
114     }
115 
116     public Object or(Object[] arguments) {
117         return new CoreOperationOr(toExpressionArray(arguments));
118     }
119 
120     public Object union(Object[] arguments) {
121         return new CoreOperationUnion(toExpressionArray(arguments));
122     }
123 
124     public Object locationPath(boolean absolute, Object[] steps) {
125         return new LocationPath(absolute, toStepArray(steps));
126     }
127 
128     public Object expressionPath(Object expression, Object[] predicates,
129             Object[] steps) {
130         return new ExpressionPath(
131             (Expression) expression,
132             toExpressionArray(predicates),
133             toStepArray(steps));
134     }
135 
136     public Object nodeNameTest(Object qname) {
137         return new NodeNameTest((QName) qname);
138     }
139 
140     public Object nodeTypeTest(int nodeType) {
141         return new NodeTypeTest(nodeType);
142     }
143 
144     public Object processingInstructionTest(String instruction) {
145         return new ProcessingInstructionTest(instruction);
146     }
147 
148     public Object step(int axis, Object nodeTest, Object[] predicates) {
149         return new Step(
150             axis,
151             (NodeTest) nodeTest,
152             toExpressionArray(predicates));
153     }
154 
155     /**
156      * Get an Object[] as an Expression[].
157      * @param array Object[]
158      * @return Expression[]
159      */
160     private Expression[] toExpressionArray(Object[] array) {
161         Expression[] expArray = null;
162         if (array != null) {
163             expArray = new Expression[array.length];
164             for (int i = 0; i < expArray.length; i++) {
165                 expArray[i] = (Expression) array[i];
166             }
167         }
168         return expArray;
169     }
170 
171     /**
172      * Get an Object[] as a Step[].
173      * @param array Object[]
174      * @return Step[]
175      */
176     private Step[] toStepArray(Object[] array) {
177         Step[] stepArray = null;
178         if (array != null) {
179             stepArray = new Step[array.length];
180             for (int i = 0; i < stepArray.length; i++) {
181                 stepArray[i] = (Step) array[i];
182             }
183         }
184         return stepArray;
185     }
186 
187     /**
188      * Learn whether arg is a name attribute test.
189      * @param arg Expression to test
190      * @return boolean
191      */
192     private boolean isNameAttributeTest(Expression arg) {
193         if (!(arg instanceof LocationPath)) {
194             return false;
195         }
196 
197         Step[] steps = ((LocationPath) arg).getSteps();
198         if (steps.length != 1) {
199             return false;
200         }
201         if (steps[0].getAxis() != Compiler.AXIS_ATTRIBUTE) {
202             return false;
203         }
204         NodeTest test = steps[0].getNodeTest();
205         if (!(test instanceof NodeNameTest)) {
206             return false;
207         }
208         if (!((NodeNameTest) test).getNodeName().equals(QNAME_NAME)) {
209             return false;
210         }
211         return true;
212     }
213 }