001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019:
020: package org.netbeans.modules.xml.xpath.ext.impl;
021:
022: import javax.xml.namespace.QName;
023: import org.apache.commons.jxpath.ri.Compiler;
024: import org.netbeans.modules.xml.xpath.ext.CoreFunctionType;
025: import org.netbeans.modules.xml.xpath.ext.CoreOperationType;
026: import org.netbeans.modules.xml.xpath.ext.LocationStep;
027: import org.netbeans.modules.xml.xpath.ext.StepNodeNameTest;
028: import org.netbeans.modules.xml.xpath.ext.StepNodeTest;
029: import org.netbeans.modules.xml.xpath.ext.StepNodeTestType;
030: import org.netbeans.modules.xml.xpath.ext.StepNodeTypeTest;
031: import org.netbeans.modules.xml.xpath.ext.XPathCoreFunction;
032: import org.netbeans.modules.xml.xpath.ext.XPathCoreOperation;
033: import org.netbeans.modules.xml.xpath.ext.XPathExpression;
034: import org.netbeans.modules.xml.xpath.ext.XPathExpressionPath;
035: import org.netbeans.modules.xml.xpath.ext.XPathExtensionFunction;
036: import org.netbeans.modules.xml.xpath.ext.XPathLocationPath;
037: import org.netbeans.modules.xml.xpath.ext.XPathModel;
038: import org.netbeans.modules.xml.xpath.ext.XPathPredicateExpression;
039: import org.netbeans.modules.xml.xpath.ext.XPathVariableReference;
040:
041: /**
042: * @author nk160297
043: *
044: * Extendes the Compiler for constructing netbeans specific XPath model.
045: */
046: public class XPathTreeCompiler implements Compiler {
047:
048: private XPathModel myXPathModel;
049:
050: public XPathTreeCompiler(XPathModel xPathModel) {
051: myXPathModel = xPathModel;
052: }
053:
054: /**
055: * overriden this method to create
056: * appropriate Long or Double as the value stored in
057: * Constant.
058: */
059: public Object number(String value) {
060: //distinguish between Long and Double
061: try {
062: long intVal = Long.parseLong(value);
063: return myXPathModel.getFactory().newXPathNumericLiteral(
064: new Long(intVal));
065: } catch (NumberFormatException ex) {
066: //Do Nothing
067: }
068: //
069: try {
070: double doubleVal = Double.parseDouble(value);
071: return myXPathModel.getFactory().newXPathNumericLiteral(
072: new Double(doubleVal));
073: } catch (NumberFormatException ex) {
074: //Do Nothing
075: }
076: //
077: return null;
078: }
079:
080: public Object literal(String value) {
081: return myXPathModel.getFactory().newXPathStringLiteral(value);
082: }
083:
084: public Object qname(String prefix, String name) {
085: if (prefix == null || prefix.length() == 0) {
086: return new QName(name);
087: } else {
088: return new QName(null, name, prefix);
089: }
090: }
091:
092: public Object sum(Object[] arguments) {
093: return createOperation(arguments, CoreOperationType.OP_SUM);
094: }
095:
096: public Object minus(Object left, Object right) {
097: return createOperation(left, right, CoreOperationType.OP_MINUS);
098: }
099:
100: public Object multiply(Object left, Object right) {
101: return createOperation(left, right, CoreOperationType.OP_MULT);
102: }
103:
104: public Object divide(Object left, Object right) {
105: return createOperation(left, right, CoreOperationType.OP_DIV);
106: }
107:
108: public Object mod(Object left, Object right) {
109: return createOperation(left, right, CoreOperationType.OP_MOD);
110: }
111:
112: public Object lessThan(Object left, Object right) {
113: return createOperation(left, right, CoreOperationType.OP_LT);
114: }
115:
116: public Object lessThanOrEqual(Object left, Object right) {
117: return createOperation(left, right, CoreOperationType.OP_LE);
118: }
119:
120: public Object greaterThan(Object left, Object right) {
121: return createOperation(left, right, CoreOperationType.OP_GT);
122: }
123:
124: public Object greaterThanOrEqual(Object left, Object right) {
125: return createOperation(left, right, CoreOperationType.OP_GE);
126: }
127:
128: public Object equal(Object left, Object right) {
129: return createOperation(left, right, CoreOperationType.OP_EQ);
130:
131: // TODO sort out if the old code is necessary or not.
132: // if (isNameAttributeTest((XPathExpression) left)) {
133: // return new NameAttributeTest((Expression) left, (Expression) right);
134: // }
135: // else {
136: // return createOperation(left, right, XPathCoreOperation.OP_EQ);
137: // }
138: }
139:
140: public Object notEqual(Object left, Object right) {
141: return createOperation(left, right, CoreOperationType.OP_NE);
142: }
143:
144: public Object minus(Object argument) {
145: XPathCoreOperation operation = myXPathModel.getFactory()
146: .newXPathCoreOperation(CoreOperationType.OP_NEGATIVE);
147: operation.addChild((XPathExpression) argument);
148: return operation;
149: }
150:
151: public Object variableReference(Object qName) {
152: assert qName instanceof QName;
153: XPathVariableReference var = myXPathModel.getFactory()
154: .newXPathVariableReference((QName) qName);
155: return var;
156: }
157:
158: public Object function(int code, Object[] args) {
159: CoreFunctionType funcType = convertFunctionCodeToType(code);
160: if (funcType == null) {
161: return null;
162: }
163: //
164: XPathCoreFunction func = myXPathModel.getFactory()
165: .newXPathCoreFunction(funcType);
166: if (args != null) {
167: for (Object arg : args) {
168: func.addChild((XPathExpression) arg);
169: }
170: }
171: return func;
172: }
173:
174: public Object function(Object name, Object[] args) {
175: XPathExtensionFunction func = myXPathModel.getFactory()
176: .newXPathExtensionFunction((QName) name);
177: if (args != null) {
178: for (Object arg : args) {
179: func.addChild((XPathExpression) arg);
180: }
181: }
182: return func;
183: }
184:
185: public Object and(Object[] arguments) {
186: return createOperation(arguments, CoreOperationType.OP_AND);
187: }
188:
189: public Object or(Object[] arguments) {
190: return createOperation(arguments, CoreOperationType.OP_OR);
191: }
192:
193: public Object union(Object[] arguments) {
194: return createOperation(arguments, CoreOperationType.OP_UNION);
195: }
196:
197: public Object locationPath(boolean absolute, Object[] steps) {
198: XPathLocationPath locPath = myXPathModel.getFactory()
199: .newXPathLocationPath(toLocationStepArray(steps));
200: locPath.setAbsolute(absolute);
201: return locPath;
202: }
203:
204: public Object expressionPath(Object expression,
205: Object[] predicates, Object[] steps) {
206: // TODO Predicates are ignored here ????
207: XPathExpressionPath exprPath = myXPathModel.getFactory()
208: .newXPathExpressionPath((XPathExpression) expression,
209: toLocationStepArray(steps));
210: return exprPath;
211: }
212:
213: public Object nodeNameTest(Object qname) {
214: return new StepNodeNameTest((QName) qname);
215: }
216:
217: public Object nodeTypeTest(int nodeType) {
218: return new StepNodeTypeTest(nodeType, null);
219: }
220:
221: public Object processingInstructionTest(String instruction) {
222: // instruction is ignored in this model
223: StepNodeTypeTest newST = new StepNodeTypeTest(
224: StepNodeTestType.NODETYPE_PI, instruction);
225: return newST;
226: }
227:
228: public Object step(int axis, Object nodeTest, Object[] predicates) {
229: LocationStep newStep = new LocationStepImpl(myXPathModel, axis,
230: (StepNodeTest) nodeTest,
231: toPredicateExpressionArray(predicates));
232: return newStep;
233: }
234:
235: // =========================================================================
236:
237: private XPathPredicateExpression[] toPredicateExpressionArray(
238: Object[] array) {
239: XPathPredicateExpression[] pExpArray = null;
240: if (array != null) {
241: pExpArray = new XPathPredicateExpression[array.length];
242: for (int i = 0; i < pExpArray.length; i++) {
243: XPathExpression expr = (XPathExpression) array[i];
244: if (expr instanceof XPathPredicateExpression) {
245: pExpArray[i] = (XPathPredicateExpression) expr;
246: } else {
247: pExpArray[i] = myXPathModel.getFactory()
248: .newXPathPredicateExpression(expr);
249: }
250: }
251: }
252: return pExpArray;
253: }
254:
255: private LocationStep[] toLocationStepArray(Object[] array) {
256: LocationStep[] stepArray = null;
257: if (array != null) {
258: stepArray = new LocationStep[array.length];
259: for (int i = 0; i < stepArray.length; i++) {
260: stepArray[i] = (LocationStep) array[i];
261: }
262: }
263: return stepArray;
264: }
265:
266: // private boolean isNameAttributeTest(XPathExpression arg) {
267: // if (!(arg instanceof XPathLocationPath)) {
268: // return false;
269: // }
270: //
271: // LocationStep[] steps = ((XPathLocationPath)arg).getSteps();
272: // if (steps.length != 1) {
273: // return false;
274: // }
275: // if (steps[0].getAxis() != LocationStep.AXIS_ATTRIBUTE) {
276: // return false;
277: // }
278: // StepNodeTest test = steps[0].getNodeTest();
279: // if (!(test instanceof StepNodeNameTest)) {
280: // return false;
281: // }
282: // if (!((StepNodeNameTest)test).getNodeName().equals("name")) {
283: // return false;
284: // }
285: // return true;
286: // }
287:
288: private Object createOperation(Object left, Object right,
289: CoreOperationType operationType) {
290: XPathCoreOperation operation = myXPathModel.getFactory()
291: .newXPathCoreOperation(operationType);
292: operation.addChild((XPathExpression) left);
293: operation.addChild((XPathExpression) right);
294: return operation;
295: }
296:
297: private Object createOperation(Object[] arguments,
298: CoreOperationType operationType) {
299: XPathCoreOperation operation = myXPathModel.getFactory()
300: .newXPathCoreOperation(operationType);
301: for (Object arg : arguments) {
302: operation.addChild((XPathExpression) arg);
303: }
304: return operation;
305: }
306:
307: private CoreFunctionType convertFunctionCodeToType(int code) {
308: switch (code) {
309: case 1:
310: return CoreFunctionType.FUNC_LAST;
311: case 2:
312: return CoreFunctionType.FUNC_POSITION;
313: case 3:
314: return CoreFunctionType.FUNC_COUNT;
315: case 4:
316: return CoreFunctionType.FUNC_ID;
317: case 5:
318: return CoreFunctionType.FUNC_LOCAL_NAME;
319: case 6:
320: return CoreFunctionType.FUNC_NAMESPACE_URI;
321: case 7:
322: return CoreFunctionType.FUNC_NAME;
323: case 8:
324: return CoreFunctionType.FUNC_STRING;
325: case 9:
326: return CoreFunctionType.FUNC_CONCAT;
327: case 10:
328: return CoreFunctionType.FUNC_STARTS_WITH;
329: case 11:
330: return CoreFunctionType.FUNC_CONTAINS;
331: case 12:
332: return CoreFunctionType.FUNC_SUBSTRING_BEFORE;
333: case 13:
334: return CoreFunctionType.FUNC_SUBSTRING_AFTER;
335: case 14:
336: return CoreFunctionType.FUNC_SUBSTRING;
337: case 15:
338: return CoreFunctionType.FUNC_STRING_LENGTH;
339: case 16:
340: return CoreFunctionType.FUNC_NORMALIZE_SPACE;
341: case 17:
342: return CoreFunctionType.FUNC_TRANSLATE;
343: case 18:
344: return CoreFunctionType.FUNC_BOOLEAN;
345: case 19:
346: return CoreFunctionType.FUNC_NOT;
347: case 20:
348: return CoreFunctionType.FUNC_TRUE;
349: case 21:
350: return CoreFunctionType.FUNC_FALSE;
351: case 22:
352: return CoreFunctionType.FUNC_LANG;
353: case 23:
354: return CoreFunctionType.FUNC_NUMBER;
355: case 24:
356: return CoreFunctionType.FUNC_SUM;
357: case 25:
358: return CoreFunctionType.FUNC_FLOOR;
359: case 26:
360: return CoreFunctionType.FUNC_CEILING;
361: case 27:
362: return CoreFunctionType.FUNC_ROUND;
363: //
364: // WRONG Functions
365: // COMMENTED BECAUSE THE RUNTIME DOESN'T SUPPORT THEM!
366: // case 28: return CoreFunctionType.FUNC_NULL;
367: // case 29: return CoreFunctionType.FUNC_KEY;
368: // case 30: return CoreFunctionType.FUNC_FORMAT_NUMBER;
369: case 28:
370: case 29:
371: case 30:
372: return null;
373: }
374: //
375: assert true : "Unknown Core Function";
376: return null;
377: }
378:
379: }
|