| 1 2 package org.xquark.xquery.parser; 3 4 import java.util.*; 5 import org.xquark.xquery.*; 6 import org.xquark.xquery.typing.*; 7 import org.xquark.xquery.parser.util.*; 8 import org.xquark.xquery.parser.primitivefunctions.fnfunctions.*; 9 import org.xquark.xquery.parser.primitivefunctions.xsfunctions.*; 10 import org.xquark.xquery.parser.hinttree.*; 11 import org.xquark.xquery.normalize.*; 12 import org.xquark.util.*; 13 import org.xquark.xpath.*; 14 import org.xquark.xquery.metadata.*; 15 import org.xquark.schema.*; 16 import org.xquark.xquery.metadata.resolver.*; 17 import java.net.*; 18 import org.xml.sax.SAXException; 19 20 public class XQueryParser implements XQueryParserConstants { 21 private static final String RCSRevision = "$Revision: 1.14 $"; 22 private static final String RCSName = "$Name: $"; 23 24 private boolean restriction = true; 26 27 private Token currentToken = null; 28 private StaticContext staticcontext = null; 29 private SchemaManager initialSchemamanager = null; 30 private XQueryModule parentModule = null; 32 33 private final String VAR_NAME = "var"; 34 private final String XMLNS = "xmlns"; 35 private final String XML = "xml"; 36 private final String XS = "xs"; 37 private final String XSI = "xsi"; 38 private final String FN = "fn"; 39 private final String XDT = "xdt"; 40 private final String LOCAL = "local"; 41 private final String XMLURI = "http://www.w3.org/XML/1998/namespace"; 42 private final String XSURI = "http://www.w3.org/2001/XMLSchema"; 43 private final String XSIURI = "http://www.w3.org/2001/XMLSchema-instance"; 44 private final String FNURI = "http://www.w3.org/2003/11/xpath-functions"; 45 private final String XDTURI = "http://www.w3.org/2003/11/xpath-datatypes"; 46 private final String LOCALURI = "http://www.w3.org/2003/11/xquery-local-functions"; 47 48 private ParserFactoryInterface factory = null; 49 50 51 private Map viewDefinitions = null; 52 53 private HashMap varDefNames = new HashMap(); 54 private HashMap linkMap = new HashMap(); 55 56 private NamespaceContextStack namespaceContextStack = new NamespaceContextStack(); 57 58 private ArrayList declList = new ArrayList(); 59 60 private HashMap hashDeclVarList = new HashMap(); 61 private HashMap hashExtVar = new HashMap(); 62 63 private HashMap hashDeclFuncList = new HashMap(); 64 65 private HashMap importSchemas = new HashMap(); 66 private ArrayList schemaList = new ArrayList(); 67 68 private HashMap importModules = new HashMap(); 69 private ArrayList moduleList = new ArrayList(); 70 71 private String defaultElementNameSpace = null; 72 private String defaultFunctionNameSpace = null; 73 74 private String defaultCollation = null; 75 private String baseURI = null; 76 private boolean hasDeclaredBaseURI = false; 77 private int xmlspace = Constants.NOTHING; private int validation = Constants.NOTHING; 79 80 private boolean inPredicate = false; 81 82 private String libraryPrefix = null; 83 84 public void reset() { 85 varDefNames.clear(); 86 namespaceContextStack.reset(); 87 88 declList = new ArrayList(); 89 hashDeclVarList = new HashMap(); 90 hashDeclFuncList = new HashMap(); 91 importSchemas = new HashMap(); 92 importModules = new HashMap(); 93 schemaList = new ArrayList(); 94 moduleList = new ArrayList(); 95 hashExtVar = new HashMap(); 96 97 defaultElementNameSpace = null; 98 defaultFunctionNameSpace = null; 99 defaultCollation = null; 100 xmlspace = Constants.NOTHING; 101 validation = Constants.NOTHING; 102 inPredicate = false; 103 token_source.getStateStack().clear(); 104 } 105 106 public void setBaseURI(String uri) { 107 baseURI = uri; 108 } 109 110 private String unquote(String s) { 111 return s.substring(1, s.length()-1); 112 } 113 114 private String getNameSpace(String prefixname) { 115 if (prefixname == null) return null; 116 String str = namespaceContextStack.getNamespaceURI(prefixname); 117 if (str == null) { 118 if (prefixname.equals(XML)) 119 str = XMLURI; 120 else if (prefixname.equals(XS)) 122 str = XSURI; 123 else if (prefixname.equals(XSI)) 125 str = XSIURI; 126 else if (prefixname.equals(FN)) 128 str = FNURI; 129 else if (prefixname.equals(XDT)) 131 str = XDTURI; 132 else if (prefixname.equals(LOCAL)) 134 str =LOCALURI; 135 } 138 return str; 139 } 140 141 public TypeVisitor getTypeVisitor() { 142 return staticcontext.getTypeVisitor(); 143 } 144 145 public SchemaManager getSchemaManager() { 146 return initialSchemamanager; 147 } 148 149 public void setFactory(String factoryClassName) throws ParseException { 150 try { 151 Class c = Class.forName (factoryClassName) ; 152 factory = (ParserFactoryInterface) c.newInstance () ; 153 } 154 catch (ClassNotFoundException e) { 155 throw new ParseException("Could not find class " + factoryClassName); 156 } 157 catch (IllegalAccessException e) { 158 throw new ParseException("Could not access factory builder"); 159 } 160 catch (InstantiationException e) { 161 throw new ParseException("Could not instantiate factory"); 162 } 163 } 164 165 166 public void setViewDefinitions(Map viewDefinitions) { 167 this.viewDefinitions = viewDefinitions; 168 } 169 170 private char parsePredefinedEntityRef(String predefinedEntityRef) throws ParseException { 171 if (predefinedEntityRef.equals("<")) return '<'; 172 if (predefinedEntityRef.equals(">")) return '>'; 173 if (predefinedEntityRef.equals("&")) return '&'; 174 if (predefinedEntityRef.equals(""")) return '"'; 175 if (predefinedEntityRef.equals("'")) return '\''; 176 throw new ParseException("Invalid token error."); 177 } 178 179 private static char parseCharRef(String charRef) { 180 int value = -1; 181 if (charRef.startsWith("&#x")) value = Integer.parseInt(charRef.substring(3, charRef.length() - 1), 16); 182 else value = Integer.parseInt(charRef.substring(2, charRef.length() - 1)); 183 switch(value) { 184 case(9): 185 return '\t'; 186 case(10): 187 return '\n'; 188 case(13): 189 return '\r'; 190 default: 191 return (new Character((char)value)).charValue(); 192 } 193 } 194 195 private String extractName(String image,String left, String right) { 196 int index; 197 if (left != null) { 198 index = image.indexOf(left); 199 if (index != -1) 200 image = image.substring(index+left.length()).trim(); 201 } 202 if (right != null) { 203 index = image.indexOf(right); 204 if (index != -1) 205 image = image.substring(0,index).trim(); 206 } 207 return image; 208 } 209 210 216 private QName QName(String image) throws ParseException, TypeException, XQueryException { 217 return QName(image,true,false); 218 } 219 private QName QName(String image, boolean check) throws ParseException, TypeException, XQueryException { 220 return QName(image,check,false); 221 } 222 private QName QName(String image, boolean check, boolean isFunction) throws ParseException, TypeException, XQueryException { 223 return QName(image,check,null,false); 224 } 225 private QName QName(String image, boolean check, String prefix, boolean isFunction) throws ParseException, TypeException, XQueryException { 226 String namespace = null; 227 String prefixname = null; 228 String typeName = null; 229 230 int index = image.indexOf(':'); 232 if (index == -1) 233 typeName = image; 234 else { 235 prefixname = image.substring(0,index); 236 typeName = image.substring(index+1); 237 } 238 if (prefix != null && !prefix.equals(prefixname)) { 239 throw new TypeException("Incorrect prefix [ " + prefixname + " ], expected [ " + prefix + " ]" , currentToken.beginLine, currentToken.beginColumn); 240 } 241 try { 242 String tmpStr = null; 243 if (prefixname == null) 244 { 245 if (isFunction) 246 namespace = defaultFunctionNameSpace; 247 else 250 namespace = defaultElementNameSpace; 251 } 252 else 253 { 254 if (!prefixname.equals(XMLNS) && check) 255 { 256 tmpStr = getNameSpace(prefixname); 257 if (tmpStr == null) 258 throw new TypeException("Could not match prefix [ " + prefixname + " ]" , currentToken.beginLine, currentToken.beginColumn); 259 namespace = tmpStr; 260 } 261 } 262 return factory.createQName(namespace, prefixname, typeName, parentModule, namespaceContextStack.getNamespaceContext()); 263 } catch (TypeException te) 264 { 265 throw new TypeException(te.getMessage(), currentToken.beginLine, currentToken.beginColumn); 266 } 267 } 268 269 272 private XQueryExpression VarName(String varname) throws ParseException, TypeException, XQueryException { 273 return VarName(varname, true, null, true); 274 } 275 private XQueryExpression VarName(String varname, String prefix) throws ParseException, TypeException, XQueryException { 276 return VarName(varname, true, prefix, true); 277 } 278 private XQueryExpression VarName(String varname, boolean isnew) throws ParseException, TypeException, XQueryException { 279 return VarName(varname, isnew, null, true); 280 } 281 private XQueryExpression VarName(String varname, boolean isnew, String prefix, boolean rename) throws ParseException, TypeException, XQueryException { 282 Variable var = null; 283 284 String varStr = "$" + varname; 285 String namespace = null; 286 String prefixname = null; 287 String localName = null; 288 289 int index = varname.indexOf(':'); 291 if (index == -1) 292 localName = varname; 293 else { 294 prefixname = varname.substring(0,index); 295 localName = varname.substring(index+1); 296 } 297 if (prefix != null && !prefix.equals(prefixname)) { 298 throw new TypeException("Incorrect prefix [ " + prefixname + " ], expected [ " + prefix + " ]" , currentToken.beginLine, currentToken.beginColumn); 299 } 300 if (prefixname != null) 301 { 302 String tmpStr = getNameSpace(prefixname); 303 if (tmpStr == null) 304 throw new TypeException("Could not match prefix [ " + prefixname + " ]" , currentToken.beginLine, currentToken.beginColumn); 305 namespace = tmpStr; 306 } 307 String varStringValue = localName; 308 if (namespace != null) { 309 varStringValue = "${"+namespace+"}"+varStringValue; 310 } else { 311 varStringValue = "$"+varStringValue; 312 } 313 if (isnew) 315 { 316 if (varDefNames.containsKey(varStr) || hashDeclVarList.containsKey(varStr)) 317 { 318 throw new ParseException("Error : Variable $" + varname + " already defined!"); 319 } 320 if (rename) { 321 localName = staticcontext.getVarName(parentModule).getLocalName(); 322 String varNewStringValue = localName; 323 if (namespace != null) { 324 varNewStringValue = "${"+namespace+"}"+varNewStringValue; 325 } else { 326 varNewStringValue = "$"+varNewStringValue; 327 } 328 linkMap.put(varNewStringValue,varStringValue); 329 } 330 try 331 { 332 var = factory.createVariable(factory.createQName(namespace, prefixname, localName, parentModule, namespaceContextStack.getNamespaceContext()), parentModule); 333 addVarDefinition(varStringValue,var); 334 } 335 catch (TypeException te) 336 { 337 throw new TypeException(te.getMessage(), currentToken.beginLine, currentToken.beginColumn); 338 } 339 } 340 else 341 { 342 348 var = getVarDefinition(varStringValue); 349 if (var == null) 350 { 351 throw new TypeException("Error : Variable $" + varname + " not defined!", currentToken.beginLine, currentToken.beginColumn); 352 } 353 ExternalVariable extVar = (ExternalVariable)hashExtVar.get(var); 354 if (extVar != null) 355 return extVar; 356 } 357 return var; 358 } 359 360 private void addVarDefinition(String varStr, Variable var) { 361 Stack st = (Stack)varDefNames.get(varStr); 362 if (st == null) { 363 st = new Stack(); 364 varDefNames.put(varStr,st); 365 } 366 st.push(var); 367 } 368 369 private void removeVarDefinition(String varStr) { 370 String str = (String)linkMap.get(varStr); 371 if (str == null) str = varStr; 372 Stack st = (Stack)varDefNames.get(str); 373 st.pop(); 374 if (st.isEmpty()) 375 varDefNames.remove(str); 376 } 377 378 private Variable getVarDefinition(String varStr) { 379 Stack st = (Stack)varDefNames.get(varStr); 380 if (st == null || st.isEmpty()) 381 return null; 382 return (Variable)st.peek(); 383 } 384 385 public XQueryModule Start(MetadataAccess metadata, SchemaManager schemamanager, ModuleManager modulemanager, VarCounter varCounter, boolean qaOnly) throws ParseException, TypeException, XQueryException { 386 return Start(metadata, schemamanager, modulemanager, varCounter, qaOnly, true); 387 } 388 389 public XQueryModule Start(MetadataAccess metadata, SchemaManager schemamanager, ModuleManager modulemanager, VarCounter varCounter) throws ParseException, TypeException, XQueryException { 390 return Start(metadata, schemamanager, modulemanager, varCounter, false, true); 391 } 392 393 final public XQueryModule Start(MetadataAccess metadata, SchemaManager schemamanager, ModuleManager modulemanager, VarCounter varCounter, boolean qaOnly, boolean restriction) throws ParseException, TypeException, XQueryException { 394 this.restriction = restriction; 395 if (factory == null) factory = new ParserFactory(); 396 parentModule = factory.createXQueryModule(); 397 initialSchemamanager = schemamanager; 398 staticcontext = new StaticContext(metadata,initialSchemamanager,modulemanager,varCounter); 399 staticcontext.setTypeVisitor(new TypeVisitor(staticcontext, qaOnly)); 400 parentModule.setStaticContext(staticcontext); 401 reset(); 402 try { 403 XQueryModule(); 404 jj_consume_token(0); 405 } catch (TypeException te) { 406 String strmsg = te.getMessage(); 407 Iterator it = linkMap.keySet().iterator(); 408 while (it.hasNext()) 409 { 410 String search = (String)it.next(); 411 int index=-1; 412 while ((index = strmsg.indexOf(search, index+1)) != -1) 413 { 414 strmsg = strmsg.substring(0, index)+(String)linkMap.get(search)+strmsg.substring(index+search.length()); 415 } 416 } 417 {if (true) throw new TypeException(strmsg);} 418 } catch (TokenMgrError tme) { 419 {if (true) throw new ParseException(tme.getMessage());} 420 } 421 {if (true) return parentModule;} 422 throw new Error("Missing return statement in function"); 423 } 424 425 429 final public void XQueryModule() throws ParseException, TypeException, XQueryException { 430 String version = null; 431 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { 432 case XQUERY_VERSION: 433 currentToken = jj_consume_token(XQUERY_VERSION); 434 currentToken = jj_consume_token(StringLiteral); 435 version = unquote(currentToken.image); 436 token_source.switchState(DEFAULT); 438 currentToken = jj_consume_token(SEMI_COLON); 439 break; 440 default: 441 jj_la1[0] = jj_gen; 442 ; 443 } 444 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { 445 case ELEMENT_L_PAREN: 446 case ATTRIBUTE_L_PAREN: 447 case COMMENT_L_PAREN: 448 case TEXT_L_PAREN: 449 case NODE_L_PAREN: 450 case DOCUMENT_NODE_L_PAREN: 451 case PROCESSING_INSTRUCTION_L_PAREN: 452 case STAR: 453 case DECLARE_VALIDATION: 454 case DECLARE_NAMESPACE: 455 case DECLARE_BASE_URI: 456 case DECLARE_VARIABLE_$: 457 case XMLCOMMENT_START: 458 case XMLPROCESSING_START: 459 case CDATA_START: 460 case TAG_START: 461 case DECLARE_XMLSPACE: 462 case VALIDATE_GLOBAL: 463 case VALIDATE_CONTEXT: 464 case VALIDATE_LAX: 465 case VALIDATE_STRICT: 466 case VALIDATE_SKIP: 467 case ELEMENT_QNAME_L_BRACE: 468 case ELEMENT_L_BRACE: 469 case ATTRIBUTE_L_BRACE: 470 case ATTRIBUTE_QNAME_L_BRACE: 471 case NAMESPACE_NCNAME_L_BRACE: 472 case DOCUMENT_L_BRACE: 473 case TEXT_L_BRACE: 474 case PROCESSING_INSTRUCTION_L_BRACE: 475 case PROCESSING_INSTRUCTION_NCNAME_L_BRACE: 476 case COMMENT_L_BRACE: 477 case DECLARE_FUNCTION: 478 case AROBASE: 479 case ANCESTOR_OR_SELF_DCOLON: 480 case ANCESTOR_DCOLON: 481 case ATTRIBUTE_DCOLON: 482 case CHILD_DCOLON: 483 case DESCENDANT_SELF_DCOLON: 484 case DESCENDANT_DCOLON: 485 case FOLLOWING_SIBLING_DCOLON: 486 case FOLLOWING_DCOLON: 487 case PARENT_DCOLON: 488 case PRECEDING_SIBLING_DCOLON: 489 case PRECEDING_DCOLON: 490 case SELF_DCOLON: 491 case IF_L_PAREN: 492 case QNAME_L_PAREN: 493 case DOLLAR: 494 case FOR_$: 495 case LET_$: 496 case SOME_$: 497 case EVERY_$: 498 case DECLARE_DEFAULT_COLLATION: 499 case DECLARE_DEFAULT_ELEMENT: 500 case DECLARE_DEFAULT_FUNCTION: 501 case IMPORT_SCHEMA: 502 case IMPORT_MODULE: 503 case VALIDATE_L_BRACE: 504 case TYPESWITCH_L_PAREN: 505 case L_PAREN: 506 case MINUS: 507 case PLUS: 508 case SLASH_SLASH: 509 case SLASH: 510 case DecimalLiteral: 511 case DOTDOT: 512 case DOT: 513 case DoubleLiteral: 514 case IntegerLiteral: 515 case NCNAME_STAR: 516 case STAR_NCNAME: 517 case StringLiteral: 518 case QNAME: 519 case KINDTEST_ELEMENT_L_PAREN: 520 case ELEMENT_CONTENT_ELT_LESS: 521 case ELEMENT_CONTENT_XMLCOMMENT_START: 522 case ELEMENT_CONTENT_XMLPROCESSING_START: 523 case ELEMENT_CONTENT_CDATA_START: 524 MainModule(); 525 break; 526 case MODULE_NAMESPACE: 527 LibraryModule(); 528 break; 529 default: 530 jj_la1[1] = jj_gen; 531 jj_consume_token(-1); 532 throw new ParseException(); 533 } 534 if (version != null) 535 parentModule.setVersion(version); 536 } 537 538 543 final public void MainModule() throws ParseException, TypeException, XQueryException { 544 XQueryExpression expression = null; 545 ArrayList tmpVect = new ArrayList(); 546 Prolog(); 547 expression = ExprSingle(); 548 if (expression != null) 549 tmpVect.add(expression); 550 label_1: 551 while (true) { 552 switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { 553 case COMMA: 554 ; 555 break; 556 default: 557 jj_la1[2] = jj_gen; 558 break label_1; 559 } 560 currentToken = jj_consume_token(COMMA); 561 expression = ExprSingle(); 562 if (expression != null) 563 tmpVect.add(expression); 564 } 565 if (hashDeclVarList.isEmpty()) { hashDeclVarList = null; } 566 if (hashDeclFuncList.isEmpty()) { hashDeclFuncList = null; } 567 if (importSchemas.isEmpty()) { importSchemas = null; schemaList = null; } 568 if (importModules.isEmpty()) { importModules = null; moduleList = null; } 569 if (declList.isEmpty()) { declList = null; } 570 571 parentModule.setExpressions(tmpVect); 572 parentModule.setDefaultCollation(defaultCollation); 573 if (hasDeclaredBaseURI) parentModule.setBaseURI(baseURI); 574 parentModule.setDefaultFunctionNamespace(defaultFunctionNameSpace); 575 parentModule.setDeclarations(namespaceContextStack); 576 parentModule.setVariables(hashDeclVarList); 577 parentModule.setExternalVariables(hashExtVar); 578 parentModule.setFunctions(hashDeclFuncList); 579 parentModule.setImportSchemas(importSchemas); 580 parentModule.setImportModules(importModules); 581 parentModule.setDeclList(declList); 582 parentModule.setSchemaList(schemaList); 583 parentModule.setModuleList(moduleList); 584 if (xmlspace != Constants.NOTHING) parentModule.setXmlSpace(xmlspace); 585 if (validation != Constants.NOTHING) parentModule.setValidation(validation); 586 parentModule.setSchemaManager(staticcontext.getSchemaManager()); 587 } 588 589 593 final public void LibraryModule() throws ParseException, TypeException, XQueryException { 594 String modulePrefix = null; 595 String moduleNamespace = null; 596 currentToken = jj_consume_token(MODULE_NAMESPACE); 597 currentToken = jj_consume_token(NAMESPACEDECL_NCNAME); 598 modulePrefix = currentToken.image; 599 libraryPrefix = modulePrefix; 600 currentToken = jj_consume_token(NAMESPACEDECL_EQUAL); 601 currentToken = jj_consume_token(NAMESPACEDECL_StringLiteral); 602 moduleNamespace = unquote(currentToken.image); 603 namespaceContextStack.declarePrefix(modulePrefix,moduleNamespace); 604 currentToken = jj_consume_token(SEMI_COLON); 605 Prolog(); 606 if (hashDeclVarList.isEmpty()) { hashDeclVarList = null; } 607 if (hashDeclFuncList.isEmpty()) { hashDeclFuncList = null; } 608 if (importSchemas.isEmpty()) { importSchemas = null; schemaList = null; } 609 if (importModules.isEmpty()) { importModules = null; moduleList = null; } 610 if (declList.isEmpty()) { declList = null; } 611 612 parentModule.setPrefix(modulePrefix); 613 parentModule.setNamespace(moduleNamespace); 614 parentModule.setDefaultCollation(defaultCollation); 615 if (hasDeclaredBaseURI) parentModule.setBaseURI(baseURI); 616 parentModule.setDefaultFunctionNamespace(defaultFunctionNameSpace); 617 parentModule.setDeclarations(namespaceContextStack); 618 parentModule.setVariables(hashDeclVarList); 619 parentModule.setExternalVariables(hashExtVar); 620 parentModule.setFunctions(hashDeclFuncList); 621 parentModule.setImportSchemas(importSchemas); 622 parentModule.setImportModules(importModules); 623 parentModule.setDeclList(declList); 624 parentModule.setSchemaList(schemaList); 625 parentModule.setModuleList(moduleList); 626 if (xmlspace != Constants.NOTHING) parentModule.setXmlSpace(xmlspace); 627 if (validation != Constants.NOTHING) parentModule.setValidation(validation); 628 parentModule.setSchemaManager(staticcontext.getSchemaManager()); 629 } 630 631 |