1 32 37 38 package com.hp.hpl.jena.rdf.arp; 39 40 import java.util.*; 41 42 import org.xml.sax.Locator ; 43 import org.xml.sax.Attributes ; 44 import org.xml.sax.SAXException ; 45 import org.xml.sax.SAXParseException ; 46 47 48 49 57 abstract class XMLHandler 58 extends LexicalHandlerImpl 59 implements RDFParserConstants, ARPErrorNumbers { 60 static { 61 CharacterModel.isFullyNormalizedConstruct( 63 "make the linkage error happen early"); 64 } 65 66 boolean encodingProblems = false; 67 68 69 public void startPrefixMapping(String prefix, String uri) 70 { 71 handlers.getNamespaceHandler().startPrefixMapping(prefix,uri); 72 73 } 74 public void endPrefixMapping(String prefix) 75 { 76 handlers.getNamespaceHandler().endPrefixMapping(prefix); 77 } 78 79 80 81 void userWarning(ParseException e) throws SAXException { 82 handlers.getErrorHandler().warning(e.rootCause()); 84 } 89 void userError(ParseException e) throws SAXException { 90 if (e.getFatal()) 91 handlers.getErrorHandler().fatalError(e.rootCause()); 92 else 93 handlers.getErrorHandler().error(e.rootCause()); 94 } 95 private Map nodeIdUserData; 96 97 98 Locator getLocator() { 99 return pipe == null ? null : pipe.getLocator(); 100 } 101 StatementHandler getStatementHandler() { 102 return handlers.getStatementHandler(); 103 } 104 public ARPHandlers getHandlers() { 105 return handlers; 106 } 107 108 ARPOptions getOptions() { 109 return options; 110 } 111 void setOptionsWith(ARPOptions newOpts) { 112 options = newOpts.copy(); 113 } 114 void setHandlersWith(ARPHandlers newHh){ 115 handlers = newHh.copy(); 116 } XMLContext documentContext; 118 TokenPipe pipe; 120 Locator locator; 121 static final String rdfns = 122 "http://www.w3.org/1999/02/22-rdf-syntax-ns#".intern(); 123 static final String xmlns = "http://www.w3.org/XML/1998/namespace".intern(); 124 static final Map rdfnames = new HashMap(); 125 static { 126 rdfnames.put("Description", new Integer (E_DESCRIPTION)); 127 rdfnames.put("RDF", new Integer (E_RDF)); 128 rdfnames.put("li", new Integer (E_LI)); 129 } 130 static final Set knownRDFProperties = new HashSet(); 131 static final Set knownRDFTypes = knownRDFProperties; 132 static { 135 knownRDFTypes.add("Bag"); 136 knownRDFTypes.add("Seq"); 137 knownRDFTypes.add("Alt"); 138 knownRDFTypes.add("List"); 139 knownRDFTypes.add("XMLLiteral"); 140 knownRDFTypes.add("Property"); 141 knownRDFProperties.add("type"); 142 knownRDFTypes.add("Statement"); 143 knownRDFProperties.add("subject"); 144 knownRDFProperties.add("predicate"); 145 knownRDFProperties.add("object"); 146 knownRDFProperties.add("value"); 147 knownRDFProperties.add("first"); 148 knownRDFProperties.add("rest"); 149 knownRDFProperties.add("nil"); 151 } 152 static final Set knownBadRDFNames = new HashSet(); 153 static { 154 knownBadRDFNames.add("ID"); 155 knownBadRDFNames.add("about"); 156 knownBadRDFNames.add("aboutEach"); 157 knownBadRDFNames.add("aboutEachPrefix"); 158 knownBadRDFNames.add("resource"); 159 knownBadRDFNames.add("bagID"); 160 knownBadRDFNames.add("parseType"); 161 knownBadRDFNames.add("datatype"); 162 knownBadRDFNames.add("li"); 163 knownBadRDFNames.add("type"); 164 knownBadRDFNames.add("Description"); 165 knownBadRDFNames.add("nodeID"); 166 } 167 static private String specialAtts[] = 169 { "base", "lang", "space", "ID", "about", "nodeID", "resource", 170 "parseType", "datatype", "type" }; 172 static private String specialNameSpaces[] = 173 { xmlns, xmlns, xmlns, rdfns, rdfns, rdfns, 174 rdfns, rdfns, rdfns, rdfns }; 176 static private int specialAttValues[] = 178 { 179 A_XMLBASE, 180 A_XMLLANG, 181 A_XMLSPACE, 182 A_ID, 183 A_ABOUT, 184 A_NODEID, 185 A_RESOURCE, 186 A_PARSETYPE, A_DATATYPE, A_TYPE, }; 188 189 void warning(int id, String s) { 190 try { 191 switch (options.getErrorMode()[id]) { 192 case EM_IGNORE : 193 break; 194 case EM_WARNING : 195 handlers.getErrorHandler().warning(new ParseException(id, s)); 196 break; 197 case EM_ERROR : 198 handlers.getErrorHandler().error(new ParseException(id, s)); 199 break; 200 case EM_FATAL : 201 handlers.getErrorHandler().fatalError(new ParseException(id, s)); 202 break; 203 } 204 205 } catch (SAXException e) { 206 throw new WrappedException(e); 207 } 208 } 209 210 private ARPOptions options = new ARPOptions(); 211 private ARPHandlers handlers = new ARPHandlers(); 212 213 void parseWarning(int id, Location where, String s) throws ParseException { 214 parseWarning(id, where, s, null); 215 } 216 void parseWarning(int id, Location where, String s, SAXParseException saxe) 217 throws ParseException { 218 int mode = options.getErrorMode()[id]; 219 if (mode == EM_IGNORE) 220 return; 221 ParseException pe = new ParseException(id, where, s, saxe); 222 if (mode == EM_FATAL) { 223 pe.setFatal(true); 224 mode = EM_ERROR; 225 } 226 if (mode == EM_ERROR) 227 throw pe; 228 229 try { 230 userWarning(pe); 231 return; 232 } catch (ParseException rethrown) { 233 if (rethrown == pe) 234 throw rethrown; 235 throw new WrappedException(pe); 236 } catch (SAXException e) { 237 throw new WrappedException(e); 238 } 239 } 240 void parseWarning(Warn w) throws ParseException { 241 parseWarning(w.number, w.location, w.msg); 242 } 243 void putWarning(int no, Location where, String msg) throws SAXParseException { 244 pipe.putNextToken(new Warn(no, where, msg)); 245 } 246 247 void setUserData(String nodeId, Object v) { 248 nodeIdUserData.put(nodeId, v); 249 } 250 251 Object getUserData(String nodeId) { 252 return nodeIdUserData.get(nodeId); 253 } 254 public void setDocumentLocator(Locator locator) { 255 this.locator = locator; 256 } 257 258 private void doSpecialAtt( 259 int ix, 260 int attName, 261 String ns, 262 BitSet attsDone, 263 Attributes atts, 264 Location where) 265 throws SAXException { 266 267 attsDone.set(ix); 268 269 if (attName == A_XMLSPACE) 270 return; 271 272 pipe.putNextToken( 273 new ARPQname(attName, where, ns, null, atts.getQName(ix))); 274 String val = atts.getValue(ix); 275 276 if (attName == A_PARSETYPE) { 277 if (val.equals("Resource")) { 278 pipe.putNextToken(new StrToken(AV_RESOURCE, where, val)); 279 } else if (val.equals("Collection")) { 280 pipe.putNextToken(new StrToken(AV_COLLECTION, where, val)); 281 } else if ( 282 val.equals("daml:collection") 283 && options.getErrorMode()[WARN_IN_STRICT_MODE] != EM_ERROR) { 284 pipe.putNextToken(new StrToken(AV_DAMLCOLLECTION, where, val)); 285 putWarning( 286 IGN_DAML_COLLECTION, 287 where, 288 "Illegal parseType: " + val); 289 } else { 290 pipe.putNextToken(new StrToken(AV_LITERAL, where, val)); 291 if (!val.equals("Literal")) { 292 putWarning( 293 WARN_UNKNOWN_PARSETYPE, 294 where, 295 "Unknown parseType: " + val); 296 } 297 } 298 } else { 299 pipe.putNextToken(new StrToken(AV_STRING, where, val)); 300 } 301 } 302 public void startElement( 303 String uri, 304 String localName, 305 String rawName, 306 Attributes atts) 307 throws SAXException { 308 Location where = new Location(locator); 309 putElementQname(uri, localName, rawName, where); 310 BitSet attsDone = new BitSet(); 311 312 for (int i = 0; i < atts.getLength(); i++) { 313 String qn = atts.getQName(i); 314 String prefix; 315 if (qn.startsWith("xmlns")) { 316 prefix = ""; 317 if (qn.equals("xmlns")) { 318 } else if (qn.charAt(5) == ':') { 319 prefix = qn.substring(6); 320 } else { 322 continue; 323 } 324 325 attsDone.set(i); 326 pipe.putNextToken(new StrToken(A_XMLNS, where, prefix)); 327 String nsuri = atts.getValue(i); 328 pipe.putNextToken(new StrToken(AV_STRING, where, nsuri)); 329 if (nsuri.startsWith(rdfns) && !nsuri.equals(rdfns)) 331 putWarning( 332 WARN_BAD_RDF_NAMESPACE_URI, 333 where, 334 "Namespace URI ref " 335 + nsuri 336 + " may not be used in RDF/XML."); 337 if (nsuri.startsWith(xmlns) && !nsuri.equals(xmlns)) 338 putWarning( 339 WARN_BAD_XML_NAMESPACE_URI, 340 where, 341 "Namespace URI ref " 342 + nsuri 343 + " may not be used in RDF/XML."); 344 345 } 346 } 347 for (int i = 0; i < specialAtts.length; i++) { 348 int ix = atts.getIndex(specialNameSpaces[i], specialAtts[i]); 349 if (ix != -1) { 350 doSpecialAtt( 351 ix, 352 specialAttValues[i], 353 specialNameSpaces[i], 354 attsDone, 355 atts, 356 where); 357 } 358 if (specialNameSpaces[i] == rdfns) { 359 ix = atts.getIndex("", specialAtts[i]); 360 if (ix != -1) { 361 putWarning( 362 WARN_UNQUALIFIED_RDF_ATTRIBUTE, 363 where, 364 "Unqualified use of rdf:" 365 + atts.getLocalName(ix) 366 + " has been deprecated."); 367 doSpecialAtt( 368 ix, 369 specialAttValues[i], 370 "", 371 attsDone, 372 atts, 373 where); 374 } 375 } 376 } 377 for (int i = 0; i < atts.getLength(); i++) { 378 if (!attsDone.get(i)) { 379 String ns = atts.getURI(i); 380 String qn = atts.getQName(i); 381 if (qn.length() >= 3 382 && qn.substring(0, 3).toLowerCase().equals("xml")) { 383 putWarning( 384 WARN_UNKNOWN_XML_ATTRIBUTE, 385 where, 386 "XML attribute: " 387 + atts.getQName(i) 388 + " is not known and is being discarded."); 389 continue; 390 } 391 if (ns.equals("")) { 392 putWarning( 393 WARN_UNQUALIFIED_ATTRIBUTE, 394 where, 395 "Attribute: " 396 + atts.getLocalName(i) 397 + ". Unqualified use is deprecated. Assuming namespace: " 398 + uri); 399 ns = uri; 400 } 401 putAttributeQname(ns, atts.getLocalName(i), qn, where); 402 pipe.putNextToken( 403 new StrToken(AV_STRING, where, atts.getValue(i))); 404 } 405 } 406 } 407 408 public void endElement(String uri, String localName, String rawName) 409 throws SAXException { 410 Location loc = new Location(locator); 411 pipe.putNextToken(new Token(E_END, loc)); 412 } 413 public void characters(char ch[], int start, int length) 414 throws SAXException { 415 Location loc = new Location(locator); 416 pipe.putNextToken( 417 new StrToken(CD_STRING, loc, new String (ch, start, length))); 418 } 419 public void ignorableWhitespace(char ch[], int start, int length) 420 throws SAXException { characters(ch, start, length); 422 } 423 private boolean isMemberProperty(String name) { 424 if (name.startsWith("_")) { 425 String number = name.substring(1); 426 if (number.startsWith("-") || number.startsWith("0")) 427 return false; 428 try { 429 Integer.parseInt(number); 430 return true; 431 } catch (NumberFormatException e) { 432 try { 433 new java.math.BigInteger (number); 435 return true; 436 } catch (NumberFormatException ee) { 437 return false; 438 } 439 } 440 } 441 return false; 442 } 443 private boolean isKnownRDFProperty(String name) { 444 return knownRDFProperties.contains(name); 445 } 446 private void putElementQname( 447 String uri, 448 String localName, 449 String q, 450 Location where) 451 throws SAXException { 452 Token warn = null; 453 if (uri.equals(rdfns)) { 454 Integer val = (Integer ) rdfnames.get(localName); 455 if (val == null) { 456 if (isMemberProperty(localName)) { 457 pipe.putNextToken( 458 new ARPQname(E_RDF_N, where, uri, localName, q)); 459 return; 460 } else if ( 461 !(knownRDFTypes.contains(localName) 462 || isKnownRDFProperty(localName))) { 463 if (knownBadRDFNames.contains(localName)) 464 warn = 465 new Warn( 466 ERR_BAD_RDF_ELEMENT, 467 where, 468 "Creating statement(s) for syntactic RDF element: '<rdf:" 469 + localName 470 + "'."); 471 else 472 warn = 473 new Warn( 474 WARN_UNKNOWN_RDF_ELEMENT, 475 where, 476 "Creating statement(s) for unknown RDF element: '<rdf:" 477 + localName 478 + "'."); 479 } 480 } else { 481 pipe.putNextToken( 482 new ARPQname(val.intValue(), where, uri, localName, q)); 483 return; 484 } 485 } 486 pipe.putNextToken(new ARPQname(E_OTHER, where, uri, localName, q)); 487 if (warn != null) 488 pipe.putNextToken(warn); 489 } 490 491 private void putAttributeQname( 492 String ns, 493 String local, 494 String q, 495 Location where) 496 throws SAXException { 497 if (ns.equals(rdfns)) { 498 if (isMemberProperty(local)) { 499 pipe.putNextToken(new ARPQname(A_RDF_N, where, ns, local, q)); 500 return; 501 } else if (!isKnownRDFProperty(local)) { 502 if (knownBadRDFNames.contains(local)) 503 putWarning( 504 ERR_BAD_RDF_ATTRIBUTE, 505 where, 506 "Inappropriate or removed RDF attribute: 'rdf:" 507 + local 508 + "'."); 509 else 510 putWarning( 511 WARN_UNKNOWN_RDF_ATTRIBUTE, 512 where, 513 "Creating statement for unknown RDF property: 'rdf:" 514 + local 515 + "'."); 516 } 517 } 518 pipe.putNextToken(new ARPQname(A_OTHER, where, ns, local, q)); 519 } 520 521 522 523 524 public void comment(char[] ch, int start, int length) throws SAXParseException { 525 Location where = new Location(locator); 526 pipe.putNextToken( 527 new StrToken(COMMENT, where, new String (ch, start, length))); 528 } 529 530 public void processingInstruction(String target, String data) 531 throws SAXException { 532 Location where = new Location(locator); 533 pipe.putNextToken( 534 new StrToken( 535 PROCESSING_INSTRUCTION, 536 where, 537 (data == null ? target : target + " " + data))); 538 } 540 541 public void error(SAXParseException e) throws SAXParseException { 542 saxError(ERR_SAX_ERROR, e); 543 } 544 public void warning(SAXParseException e) throws SAXParseException { 545 saxError(WARN_SAX_WARNING, e); 546 } 547 public void fatalError(SAXParseException e) throws SAXException { 548 saxError(ERR_SAX_FATAL_ERROR, e); 549 throw new FatalParsingErrorException(); 550 } 551 void generalError(int i, Exception e) throws SAXParseException { 552 Location where = new Location(locator); 553 pipe.putNextToken(new ExceptionToken(i, where, e)); 555 556 } 557 private void saxError(int i, SAXParseException e) throws SAXParseException { 558 Location where = 559 new Location( 560 e.getSystemId(), 561 e.getLineNumber(), 562 e.getColumnNumber()); 563 564 pipe.putNextToken(new ExceptionToken(i, where, e)); 565 566 } 567 568 571 void endLocalScope(Object v) { 572 573 if (handlers.getExtendedHandler() != ARPHandlers.nullScopeHandler 574 && v != null 575 && v instanceof ARPResource) { 576 ARPResource bn = (ARPResource) v; 577 if (!bn.isAnonymous()) 578 return; 579 if (!bn.getHasBeenUsed()) 580 return; 581 if (bn.hasNodeID()) { 582 if ( handlers.getExtendedHandler().discardNodesWithNodeID()) 584 return; 585 586 String bnodeID = bn.nodeID; 587 if (!nodeIdUserData.containsKey(bnodeID)) 588 nodeIdUserData.put(bnodeID, null); 589 } else { 590 handlers.getExtendedHandler().endBNodeScope(bn); 591 592 } 593 } 594 } 595 596 void endRDF() { 597 handlers.getExtendedHandler().endRDF(); 598 } 599 void startRDF() { 600 handlers.getExtendedHandler().startRDF(); 601 } 602 603 boolean ignoring(int eCode) { 604 return options.getErrorMode()[eCode]==EM_IGNORE; 605 } 606 protected void initParse(String base) throws MalformedURIException { 607 nodeIdUserData = new HashMap(); 608 if (base == null) { 610 warning( 611 IGN_NO_BASE_URI_SPECIFIED, 612 "Base URI not specified for input file; local URI references will be in error."); 613 documentContext = 614 new XMLNullContext(this, ERR_RESOLVING_URI_AGAINST_NULL_BASE); 615 616 } else if (base.equals("")) { 617 warning( 618 IGN_NO_BASE_URI_SPECIFIED, 619 "Base URI specified as \"\"; local URI references will not be resolved."); 620 documentContext = 621 new XMLNullContext(this, WARN_RESOLVING_URI_AGAINST_EMPTY_BASE); 622 } else { 623 base = ParserSupport.truncateXMLBase(base); 624 625 documentContext = new XMLContext(base); 626 } 627 } 628 void endBnodeScope() { 629 if ( getHandlers().getExtendedHandler() != ARPHandlers.nullScopeHandler ) { 630 Iterator it = nodeIdUserData.keySet().iterator(); 631 while (it.hasNext()) { 632 String nodeId = (String )it.next(); 633 ARPResource bn = new ARPResource(this); 634 bn.setNodeId(nodeId); 635 getHandlers().getExtendedHandler().endBNodeScope(bn); 636 } 637 } 638 } 639 640 641 } 642 | Popular Tags |