1 19 20 package org.netbeans.modules.xml.xpath.impl; 21 22 import java.util.ArrayList ; 23 import java.util.Iterator ; 24 import java.util.logging.Level ; 25 import java.util.logging.Logger ; 26 import javax.xml.namespace.QName ; 27 28 import org.apache.commons.jxpath.JXPathException; 29 import org.apache.commons.jxpath.ri.Compiler; 30 import org.apache.commons.jxpath.ri.Parser; 31 import org.apache.commons.jxpath.ri.compiler.Constant; 32 import org.apache.commons.jxpath.ri.compiler.CoreFunction; 33 import org.apache.commons.jxpath.ri.compiler.CoreOperation; 34 import org.apache.commons.jxpath.ri.compiler.CoreOperationAdd; 35 import org.apache.commons.jxpath.ri.compiler.CoreOperationAnd; 36 import org.apache.commons.jxpath.ri.compiler.CoreOperationDivide; 37 import org.apache.commons.jxpath.ri.compiler.CoreOperationEqual; 38 import org.apache.commons.jxpath.ri.compiler.CoreOperationGreaterThan; 39 import org.apache.commons.jxpath.ri.compiler.CoreOperationGreaterThanOrEqual; 40 import org.apache.commons.jxpath.ri.compiler.CoreOperationLessThan; 41 import org.apache.commons.jxpath.ri.compiler.CoreOperationLessThanOrEqual; 42 import org.apache.commons.jxpath.ri.compiler.CoreOperationMod; 43 import org.apache.commons.jxpath.ri.compiler.CoreOperationMultiply; 44 import org.apache.commons.jxpath.ri.compiler.CoreOperationNegate; 45 import org.apache.commons.jxpath.ri.compiler.CoreOperationNotEqual; 46 import org.apache.commons.jxpath.ri.compiler.CoreOperationOr; 47 import org.apache.commons.jxpath.ri.compiler.CoreOperationSubtract; 48 import org.apache.commons.jxpath.ri.compiler.Expression; 49 import org.apache.commons.jxpath.ri.compiler.ExpressionPath; 50 import org.apache.commons.jxpath.ri.compiler.ExtensionFunction; 51 import org.apache.commons.jxpath.ri.compiler.LocationPath; 52 import org.apache.commons.jxpath.ri.compiler.NodeNameTest; 53 import org.apache.commons.jxpath.ri.compiler.NodeTest; 54 import org.apache.commons.jxpath.ri.compiler.NodeTypeTest; 55 import org.apache.commons.jxpath.ri.compiler.Step; 56 import org.apache.commons.jxpath.ri.compiler.TreeCompiler; 57 import org.apache.commons.jxpath.ri.compiler.VariableReference; 58 import org.netbeans.modules.xml.xpath.AbstractXPathModelHelper; 59 import org.netbeans.modules.xml.xpath.LocationStep; 60 import org.netbeans.modules.xml.xpath.StepNodeTest; 61 import org.netbeans.modules.xml.xpath.StepNodeNameTest; 62 import org.netbeans.modules.xml.xpath.StepNodeTypeTest; 63 import org.netbeans.modules.xml.xpath.XPathCoreFunction; 64 import org.netbeans.modules.xml.xpath.XPathCoreOperation; 65 import org.netbeans.modules.xml.xpath.XPathException; 66 import org.netbeans.modules.xml.xpath.XPathExpression; 67 import org.netbeans.modules.xml.xpath.XPathExpressionPath; 68 import org.netbeans.modules.xml.xpath.XPathLocationPath; 69 import org.netbeans.modules.xml.xpath.XPathModel; 70 import org.netbeans.modules.xml.xpath.XPathNumericLiteral; 71 import org.netbeans.modules.xml.xpath.XPathOperationOrFuntion; 72 import org.netbeans.modules.xml.xpath.XPathPredicateExpression; 73 import org.netbeans.modules.xml.xpath.common.MessageManager; 74 75 88 public class XPathModelImpl 89 implements XPathModel { 90 91 92 private Compiler mCompiler; 93 94 95 private static final Logger mLogger = Logger.getLogger(XPathModelImpl.class.getName()); 96 97 98 private static MessageManager mMsgMgr = MessageManager.getManager(XPathModelImpl.class); 99 100 101 102 public XPathModelImpl() { 103 mCompiler = new XPathTreeCompiler(); 104 } 105 106 107 113 public XPathExpression parseExpression(String expression) 114 throws XPathException { 115 try { 116 Object expr = Parser.parseExpression(expression, mCompiler); 117 if (expr instanceof Expression) { 118 return processExpression((Expression) expr); 119 } else { 120 XPathException xpe = new XPathException( 121 mMsgMgr.getString("Unhandled_XPath_Expression", 122 expression, expr.toString())); 123 mLogger.log(Level.FINEST, "parseExpression", xpe); 124 throw xpe; 125 } 126 } catch (JXPathException jxe) { 127 mLogger.log(Level.FINEST, "parseExpression", jxe); 128 throw new XPathException(jxe); 129 } 130 } 131 132 138 XPathExpression processExpression(Expression expression) 139 throws XPathException { 140 if (expression instanceof LocationPath) { 141 return processLocationPath((LocationPath) expression); 142 } else if (expression instanceof CoreFunction) { 143 return processCoreFunction((CoreFunction) expression); 144 } else if (expression instanceof ExtensionFunction) { 145 return processExtensionFunction((ExtensionFunction) expression); 146 } else if (expression instanceof CoreOperation) { 147 return processCoreOperation((CoreOperation) expression); 148 } else if (expression instanceof Constant) { 149 return processConstant((Constant) expression); 150 } else if (expression instanceof VariableReference) { 151 return processVariableReference((VariableReference) expression); 152 } else if (expression instanceof ExpressionPath) { 153 return processExpressionPath((ExpressionPath) expression); 154 } else { 155 XPathException xpe = new XPathException( 156 mMsgMgr.getString("Unhandled_Expression_Type", 157 expression.toString())); 158 mLogger.log(Level.FINEST, "processExpression", xpe); 159 throw xpe; 160 } 161 } 162 163 XPathExpression processVariableReference(VariableReference varRef) 164 throws XPathException { 165 166 return AbstractXPathModelHelper.getInstance().newXPathVariableReference(varRef); 170 } 171 172 178 XPathExpression processConstant(Constant constant) 179 throws XPathException { 180 Object value = constant.computeValue(null); 181 XPathExpression xpexpr; 182 183 if (value instanceof String ) { 184 xpexpr = AbstractXPathModelHelper.getInstance().newXPathStringLiteral((String ) value); 185 } else if (value instanceof Number ) { 186 xpexpr = AbstractXPathModelHelper.getInstance().newXPathNumericLiteral((Number ) value); 187 } else { 188 XPathException xpe = new XPathException( 189 mMsgMgr.getString("Invalid_XPath_Constant", value)); 190 mLogger.log(Level.FINEST, "processConstant", xpe); 191 throw xpe; 192 } 193 194 mLogger.finer("constant=" + constant + " value=" + value); 195 196 return xpexpr; 197 } 198 199 200 208 XPathExpression processCoreFunction(CoreFunction coreFunction) 209 throws XPathException { 210 int code = getCoreFunctionCode(coreFunction); 211 Expression[] arguments = coreFunction.getArguments(); 212 213 if (-1 == code) { 214 XPathException xpe = new XPathException( 215 mMsgMgr.getString("Unhandled_XPath_Function", 216 coreFunction.toString())); 217 mLogger.log(Level.FINEST, "processCoreFunction", xpe); 218 throw xpe; 219 } 220 221 XPathOperationOrFuntion xpexpr = AbstractXPathModelHelper.getInstance().newXPathCoreFunction(code); 222 223 if (arguments != null) { 225 for (int i = 0; i < arguments.length; i++) { 226 xpexpr.addChild(processExpression(arguments[i])); 227 } 228 } 229 230 mLogger.finer("coreFunction=" + coreFunction); 231 232 return xpexpr; 233 } 234 235 236 244 XPathExpression processCoreOperation(CoreOperation coreOperation) 245 throws XPathException { 246 int code = getCoreOperationCode(coreOperation); 247 Expression[] arguments = coreOperation.getArguments(); 248 249 if (-1 == code) { 250 XPathException xpe = new XPathException( 251 mMsgMgr.getString("Unhandled_XPath_Operator", 252 coreOperation.toString())); 253 mLogger.log(Level.FINEST, "processCoreOperation", xpe); 254 throw xpe; 255 } 256 257 XPathOperationOrFuntion xpexpr = AbstractXPathModelHelper.getInstance().newXPathCoreOperation(code); 258 259 for (int i = 0; i < arguments.length; i++) { 263 xpexpr.addChild(processExpression(arguments[i])); 264 } 265 266 mLogger.finer("coreOperation=" + coreOperation); 267 268 return xpexpr; 269 } 270 271 272 280 XPathExpression processExtensionFunction(ExtensionFunction extensionFunction) 281 throws XPathException { 282 String name = extensionFunction.getFunctionName().toString(); 283 Expression[] arguments = extensionFunction.getArguments(); 284 285 if (null == name) { 286 XPathException xpe = new XPathException( 287 mMsgMgr.getString("Unhandled_XPath_Function", 288 extensionFunction.toString())); 289 mLogger.log(Level.FINEST, "processExtensionFunction", xpe); 290 throw xpe; 291 } else if (!isValidFunction(name)) { 292 XPathException xpe = new XPathException( 293 mMsgMgr.getString("Invalid_XPath_Function", 294 extensionFunction.toString())); 295 mLogger.log(Level.FINEST, "processExtensionFunction", xpe); 296 throw xpe; 297 } 298 299 XPathOperationOrFuntion xpexpr = 300 AbstractXPathModelHelper.getInstance().newXPathExtensionFunction(name); 301 302 if (arguments != null) { 304 for (int i = 0; i < arguments.length; i++) { 305 xpexpr.addChild(processExpression(arguments[i])); 306 } 307 } 308 309 mLogger.finer("extensionFunction=" + extensionFunction 310 + " name=" + name); 311 312 return xpexpr; 313 } 314 315 316 326 XPathExpression processLocationPath(LocationPath locationPath) 327 throws XPathException { 328 Step[] steps = locationPath.getSteps(); 329 330 ArrayList stepList = new ArrayList (); 331 if (steps != null) { 332 for (int i = 0; i < steps.length; i++) { 333 stepList.add(processStep(steps[i])); 334 } 335 } 336 337 LocationStep[] locSteps = new LocationStepImpl[stepList.size()]; 338 Iterator iter = stepList.iterator(); 339 for (int i = 0; iter.hasNext(); i++) { 340 locSteps[i] = (LocationStep) iter.next(); 341 } 342 343 XPathLocationPath path = 344 AbstractXPathModelHelper.getInstance().newXPathLocationPath(locSteps); 345 path.setAbsolute(locationPath.isAbsolute()); 346 path.setSimplePath(locationPath.isSimplePath()); 347 348 return path; 349 } 350 351 352 362 XPathExpression processExpressionPath(ExpressionPath expressionPath) 363 throws XPathException { 364 Expression rootExpression = expressionPath.getExpression(); 365 XPathExpression rExpression = null; 366 if(rootExpression != null) { 367 rExpression = processExpression(rootExpression); 368 } 369 370 Step[] steps = expressionPath.getSteps(); 371 372 ArrayList stepList = new ArrayList (); 373 if (steps != null) { 374 for (int i = 0; i < steps.length; i++) { 375 stepList.add(processStep(steps[i])); 376 } 377 } 378 379 LocationStep[] locSteps = new LocationStepImpl[stepList.size()]; 380 Iterator iter = stepList.iterator(); 381 for (int i = 0; iter.hasNext(); i++) { 382 locSteps[i] = (LocationStep) iter.next(); 383 } 384 385 XPathExpressionPath path = 386 AbstractXPathModelHelper.getInstance().newXPathExpressionPath(rExpression, locSteps); 387 path.setSimplePath(expressionPath.isSimplePath()); 388 389 return path; 390 } 391 392 398 LocationStep processStep(Step step) 399 throws XPathException { 400 int axis = getAxis(step.getAxis()); 401 NodeTest nodeTest = step.getNodeTest(); 402 Expression[] predicates = step.getPredicates(); 403 String name = null; 404 StepNodeTest stepNodeTest = null; 405 406 if (nodeTest instanceof NodeNameTest) { 407 stepNodeTest = 408 new StepNodeNameTest( 409 ((NodeNameTest) nodeTest).getNodeName().toString()); 410 } else if (nodeTest instanceof NodeTypeTest) { 411 stepNodeTest = 412 new StepNodeTypeTest( 413 getNodeType(((NodeTypeTest) nodeTest).getNodeType())); 414 } else { 415 XPathException xpe = new XPathException( 416 mMsgMgr.getString("Invalid_Location_Step", step.toString())); 417 mLogger.log(Level.FINEST, "processStep", xpe); 418 throw xpe; 419 } 420 421 XPathPredicateExpression[] xpathPredicateExpressions = null; 422 if (predicates != null && predicates.length > 0) { 423 XPathExpression[] xpathPredicates = null; 424 xpathPredicates = new XPathExpression[predicates.length]; 425 xpathPredicateExpressions = new XPathPredicateExpression[predicates.length]; 426 for (int i = 0, length = predicates.length; i < length; i++) { 427 xpathPredicates[i] = processExpression(predicates[i]); 428 if (xpathPredicates[i] instanceof XPathNumericLiteral) { 429 xpathPredicates[i] = AbstractXPathModelHelper.getInstance() 430 .newXPathPredicateNumericLiteral 431 (new Long (((XPathNumericLiteral) xpathPredicates[i]).getValue().longValue())); 432 } 433 434 xpathPredicateExpressions[i] = AbstractXPathModelHelper.getInstance() 436 .newXPathPredicateExpression(xpathPredicates[i]); 437 } 438 } 439 return new LocationStepImpl(axis, stepNodeTest, xpathPredicateExpressions); 440 } 441 442 447 int getAxis(int code) { 448 switch (code) { 449 case Compiler.AXIS_SELF: 450 return LocationStep.AXIS_SELF; 451 case Compiler.AXIS_CHILD: 452 return LocationStep.AXIS_CHILD; 453 case Compiler.AXIS_PARENT: 454 return LocationStep.AXIS_PARENT; 455 case Compiler.AXIS_ANCESTOR: 456 return LocationStep.AXIS_ANCESTOR; 457 case Compiler.AXIS_ATTRIBUTE: 458 return LocationStep.AXIS_ATTRIBUTE; 459 case Compiler.AXIS_NAMESPACE: 460 return LocationStep.AXIS_NAMESPACE; 461 case Compiler.AXIS_PRECEDING: 462 return LocationStep.AXIS_PRECEDING; 463 case Compiler.AXIS_FOLLOWING: 464 return LocationStep.AXIS_FOLLOWING; 465 case Compiler.AXIS_DESCENDANT: 466 return LocationStep.AXIS_DESCENDANT; 467 case Compiler.AXIS_ANCESTOR_OR_SELF: 468 return LocationStep.AXIS_ANCESTOR_OR_SELF; 469 case Compiler.AXIS_DESCENDANT_OR_SELF: 470 return LocationStep.AXIS_DESCENDANT_OR_SELF; 471 case Compiler.AXIS_FOLLOWING_SIBLING: 472 return LocationStep.AXIS_FOLLOWING_SIBLING; 473 case Compiler.AXIS_PRECEDING_SIBLING: 474 return LocationStep.AXIS_PRECEDING_SIBLING; 475 } 476 477 return -1; 478 } 479 480 481 486 int getNodeType(int code) { 487 switch (code) { 488 case Compiler.NODE_TYPE_NODE: 489 return LocationStep.NODETYPE_NODE; 490 case Compiler.NODE_TYPE_TEXT: 491 return LocationStep.NODETYPE_TEXT; 492 case Compiler.NODE_TYPE_COMMENT: 493 return LocationStep.NODETYPE_COMMENT; 494 case Compiler.NODE_TYPE_PI: 495 return LocationStep.NODETYPE_PI; 496 } 497 498 return -1; 499 } 500 501 502 508 int getCoreFunctionCode(CoreFunction coreFunction) { 509 int code = coreFunction.getFunctionCode(); 510 511 switch (code) { 512 case Compiler.FUNCTION_LAST: 513 return XPathCoreFunction.FUNC_LAST; 514 case Compiler.FUNCTION_POSITION: 515 return XPathCoreFunction.FUNC_POSITION; 516 case Compiler.FUNCTION_COUNT: 517 return XPathCoreFunction.FUNC_COUNT; 518 case Compiler.FUNCTION_ID: 519 return XPathCoreFunction.FUNC_ID; 520 case Compiler.FUNCTION_LOCAL_NAME: 521 return XPathCoreFunction.FUNC_LOCAL_NAME; 522 case Compiler.FUNCTION_NAMESPACE_URI: 523 return XPathCoreFunction.FUNC_NAMESPACE_URI; 524 case Compiler.FUNCTION_NAME: 525 return XPathCoreFunction.FUNC_NAME; 526 case Compiler.FUNCTION_STRING: 527 return XPathCoreFunction.FUNC_STRING; 528 case Compiler.FUNCTION_CONCAT: 529 return XPathCoreFunction.FUNC_CONCAT; 530 case Compiler.FUNCTION_STARTS_WITH: 531 return XPathCoreFunction.FUNC_STARTS_WITH; 532 case Compiler.FUNCTION_CONTAINS: 533 return XPathCoreFunction.FUNC_CONTAINS; 534 case Compiler.FUNCTION_SUBSTRING_BEFORE: 535 return XPathCoreFunction.FUNC_SUBSTRING_BEFORE; 536 case Compiler.FUNCTION_SUBSTRING_AFTER: 537 return XPathCoreFunction.FUNC_SUBSTRING_AFTER; 538 case Compiler.FUNCTION_SUBSTRING: 539 return XPathCoreFunction.FUNC_SUBSTRING; 540 case Compiler.FUNCTION_STRING_LENGTH: 541 return XPathCoreFunction.FUNC_STRING_LENGTH; 542 case Compiler.FUNCTION_NORMALIZE_SPACE: 543 return XPathCoreFunction.FUNC_NORMALIZE_SPACE; 544 case Compiler.FUNCTION_TRANSLATE: 545 return XPathCoreFunction.FUNC_TRANSLATE; 546 case Compiler.FUNCTION_BOOLEAN: 547 return XPathCoreFunction.FUNC_BOOLEAN; 548 case Compiler.FUNCTION_NOT: 549 return XPathCoreFunction.FUNC_NOT; 550 case Compiler.FUNCTION_TRUE: 551 return XPathCoreFunction.FUNC_TRUE; 552 case Compiler.FUNCTION_FALSE: 553 return XPathCoreFunction.FUNC_FALSE; 554 case Compiler.FUNCTION_LANG: 555 return XPathCoreFunction.FUNC_LANG; 556 case Compiler.FUNCTION_NUMBER: 557 return XPathCoreFunction.FUNC_NUMBER; 558 case Compiler.FUNCTION_SUM: 559 return XPathCoreFunction.FUNC_SUM; 560 case Compiler.FUNCTION_FLOOR: 561 return XPathCoreFunction.FUNC_FLOOR; 562 case Compiler.FUNCTION_CEILING: 563 return XPathCoreFunction.FUNC_CEILING; 564 case Compiler.FUNCTION_ROUND: 565 return XPathCoreFunction.FUNC_ROUND; 566 case Compiler.FUNCTION_NULL: 567 return XPathCoreFunction.FUNC_NULL; 568 case Compiler.FUNCTION_KEY: 569 return XPathCoreFunction.FUNC_KEY; 570 case Compiler.FUNCTION_FORMAT_NUMBER: 571 return XPathCoreFunction.FUNC_FORMAT_NUMBER; 572 case Compiler.FUNCTION_EXISTS: 573 return XPathCoreFunction.FUNC_EXISTS; 574 } 575 576 return -1; 577 } 578 579 580 587 int getCoreOperationCode(CoreOperation coreOperation) { 588 if (coreOperation instanceof CoreOperationAdd) { 589 return XPathCoreOperation.OP_SUM; 590 } else if (coreOperation instanceof CoreOperationSubtract) { 591 return XPathCoreOperation.OP_MINUS; 592 } else if (coreOperation instanceof CoreOperationMultiply) { 593 return XPathCoreOperation.OP_MULT; 594 } else if (coreOperation instanceof CoreOperationDivide) { 595 return XPathCoreOperation.OP_DIV; 596 } else if (coreOperation instanceof CoreOperationMod) { 597 return XPathCoreOperation.OP_MOD; 598 } else if (coreOperation instanceof CoreOperationNegate) { 599 return XPathCoreOperation.OP_NEGATIVE; 600 } else if (coreOperation instanceof CoreOperationAnd) { 601 return XPathCoreOperation.OP_AND; 602 } else if (coreOperation instanceof CoreOperationOr) { 603 return XPathCoreOperation.OP_OR; 604 } else if (coreOperation instanceof CoreOperationEqual) { 605 return XPathCoreOperation.OP_EQ; 606 } else if (coreOperation instanceof CoreOperationNotEqual) { 607 return XPathCoreOperation.OP_NE; 608 } else if (coreOperation instanceof CoreOperationLessThan) { 609 return XPathCoreOperation.OP_LT; 610 } else if (coreOperation instanceof CoreOperationLessThanOrEqual) { 611 return XPathCoreOperation.OP_LE; 612 } else if (coreOperation instanceof CoreOperationGreaterThan) { 613 return XPathCoreOperation.OP_GT; 614 } else if (coreOperation instanceof CoreOperationGreaterThanOrEqual) { 615 return XPathCoreOperation.OP_GE; 616 } 617 return -1; 618 } 619 620 621 627 static boolean isValidFunction(String functionName) { 628 for (int i = 0; i < VALID_FUNCTION_NAMES.length; i++) { 629 if (functionName.equals(VALID_FUNCTION_NAMES[i])) { 630 return true; 631 } 632 } 633 634 String name = functionName; 637 int colon = name.indexOf(':'); 638 if (colon != -1) { 639 name = name.substring(colon + 1, name.length()); 640 } 641 for (int i = 0; i < VALID_BPWS_FUNCTION_NAMES.length; i++) { 642 if (name.equals(VALID_BPWS_FUNCTION_NAMES[i])) { 643 return true; 644 } 645 } 646 647 return false; 648 } 649 } 650 | Popular Tags |