001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.jxpath.ri.compiler; 018 019import org.apache.commons.jxpath.ri.Compiler; 020import org.apache.commons.jxpath.ri.QName; 021 022/** 023 * @author Dmitri Plotnikov 024 * @version $Revision: 652845 $ $Date: 2008-05-02 19:46:46 +0200 (Fr, 02 Mai 2008) $ 025 */ 026public class TreeCompiler implements Compiler { 027 028 private static final QName QNAME_NAME = new QName(null, "name"); 029 030 public Object number(String value) { 031 return new Constant(new Double(value)); 032 } 033 034 public Object literal(String value) { 035 return new Constant(value); 036 } 037 038 public Object qname(String prefix, String name) { 039 return new QName(prefix, name); 040 } 041 042 public Object sum(Object[] arguments) { 043 return new CoreOperationAdd(toExpressionArray(arguments)); 044 } 045 046 public Object minus(Object left, Object right) { 047 return new CoreOperationSubtract( 048 (Expression) left, 049 (Expression) right); 050 } 051 052 public Object multiply(Object left, Object right) { 053 return new CoreOperationMultiply((Expression) left, (Expression) right); 054 } 055 056 public Object divide(Object left, Object right) { 057 return new CoreOperationDivide((Expression) left, (Expression) right); 058 } 059 060 public Object mod(Object left, Object right) { 061 return new CoreOperationMod((Expression) left, (Expression) right); 062 } 063 064 public Object lessThan(Object left, Object right) { 065 return new CoreOperationLessThan((Expression) left, (Expression) right); 066 } 067 068 public Object lessThanOrEqual(Object left, Object right) { 069 return new CoreOperationLessThanOrEqual( 070 (Expression) left, 071 (Expression) right); 072 } 073 074 public Object greaterThan(Object left, Object right) { 075 return new CoreOperationGreaterThan( 076 (Expression) left, 077 (Expression) right); 078 } 079 080 public Object greaterThanOrEqual(Object left, Object right) { 081 return new CoreOperationGreaterThanOrEqual( 082 (Expression) left, 083 (Expression) right); 084 } 085 086 public Object equal(Object left, Object right) { 087 return isNameAttributeTest((Expression) left) 088 ? new NameAttributeTest((Expression) left, (Expression) right) 089 : new CoreOperationEqual((Expression) left, (Expression) right); 090 } 091 092 public Object notEqual(Object left, Object right) { 093 return new CoreOperationNotEqual((Expression) left, (Expression) right); 094 } 095 096 public Object minus(Object argument) { 097 return new CoreOperationNegate((Expression) argument); 098 } 099 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}