1 package net.sf.saxon.event; 2 import net.sf.saxon.Configuration; 3 import net.sf.saxon.om.Name; 4 import net.sf.saxon.om.NamePool; 5 import net.sf.saxon.om.XMLChar; 6 import net.sf.saxon.om.NodeInfo; 7 import net.sf.saxon.style.StandardNames; 8 import net.sf.saxon.tinytree.CharSlice; 9 import net.sf.saxon.trans.XPathException; 10 import net.sf.saxon.type.ValidationException; 11 import org.xml.sax.*; 12 import org.xml.sax.ext.LexicalHandler ; 13 14 import javax.xml.transform.TransformerException ; 15 import java.net.URI ; 16 import java.net.URISyntaxException ; 17 import java.util.HashMap ; 18 19 27 28 public class ReceivingContentHandler 29 implements ContentHandler, LexicalHandler , DTDHandler, SaxonLocator 30 { 31 private NamePool pool; 32 private PipelineConfiguration pipe; 33 private Receiver receiver; 34 private boolean inDTD = false; private Locator locator; 37 39 private char[] buffer = new char[4096]; 40 private int used = 0; 41 private CharSlice slice = new CharSlice(buffer, 0, 0); 42 43 45 private int[] namespaces = new int[50]; 46 private int namespacesUsed = 0; 47 48 50 53 54 public ReceivingContentHandler() { 55 } 56 57 public void setReceiver(Receiver e) { 58 receiver = e; 59 } 60 61 public void setPipelineConfiguration(PipelineConfiguration pipe) { 62 this.pipe = pipe; 63 pipe.setLocationProvider(this); 64 this.pool = pipe.getConfiguration().getNamePool(); 65 66 } 67 68 public PipelineConfiguration getPipelineConfiguration() { 69 return pipe; 70 } 71 72 public Configuration getConfiguration() { 73 return pipe.getConfiguration(); 74 } 75 76 79 80 public void startDocument () throws SAXException { 81 try { 83 used = 0; 84 namespacesUsed = 0; 85 pipe.setLocationProvider(this); 86 receiver.setPipelineConfiguration(pipe); 87 receiver.open(); 88 receiver.startDocument(0); 89 } catch (XPathException err) { 90 throw new SAXException(err); 91 } 92 } 93 94 97 98 public void endDocument () throws SAXException { 99 try { 100 flush(); 101 receiver.endDocument(); 102 receiver.close(); 103 } catch (ValidationException err) { 104 err.setLocator(locator); 105 throw new SAXException(err); 106 } catch (XPathException err) { 107 throw new SAXException(err); 108 } 109 } 110 111 114 115 public void setDocumentLocator (Locator locator) { 116 this.locator = locator; 117 } 118 119 122 123 public void startPrefixMapping(String prefix, String uri) throws SAXException { 124 if (namespacesUsed >= namespaces.length) { 126 int[] n2 = new int[namespacesUsed * 2]; 127 System.arraycopy(namespaces, 0, n2, 0, namespacesUsed); 128 namespaces = n2; 129 } 130 namespaces[namespacesUsed++] = pool.allocateNamespaceCode(prefix, uri); 131 } 132 133 136 137 public void endPrefixMapping(String prefix) throws SAXException {} 138 139 142 public void startElement (String uri, String localname, String rawname, Attributes atts) 143 throws SAXException 144 { 145 try { 150 flush(); 151 152 int nameCode = getNameCode(uri, localname, rawname); 153 receiver.startElement(nameCode, StandardNames.XDT_UNTYPED, 0, 0); 154 155 for (int n=0; n<namespacesUsed; n++) { 156 receiver.namespace(namespaces[n], 0); 157 } 158 159 160 for (int a=0; a<atts.getLength(); a++) { 161 int properties = 0; 162 int attCode = getNameCode(atts.getURI(a), atts.getLocalName(a), atts.getQName(a)); 163 String type = atts.getType(a); 164 int typeCode = StandardNames.XDT_UNTYPED_ATOMIC; 165 if (getConfiguration().isRetainDTDAttributeTypes()) { 166 if (type.equals("CDATA")) { 167 } else if (type.equals("ID")) { 169 typeCode = StandardNames.XS_ID; 170 } else if (type.equals("IDREF")) { 171 typeCode = StandardNames.XS_IDREF; 172 } else if (type.equals("IDREFS")) { 173 typeCode = StandardNames.XS_IDREFS; 174 } else if (type.equals("NMTOKEN")) { 175 typeCode = StandardNames.XS_NMTOKEN; 176 } else if (type.equals("NMTOKENS")) { 177 typeCode = StandardNames.XS_NMTOKENS; 178 } else if (type.equals("ENTITY")) { 179 typeCode = StandardNames.XS_ENTITY; 180 } else if (type.equals("ENTITIES")) { 181 typeCode = StandardNames.XS_ENTITIES; 182 } 183 } else { 184 if (type.equals("ID")) { 185 typeCode = StandardNames.XS_ID | NodeInfo.IS_DTD_TYPE; 186 } else if (type.equals("IDREF")) { 187 typeCode = StandardNames.XS_IDREF | NodeInfo.IS_DTD_TYPE; 188 } else if (type.equals("IDREFS")) { 189 typeCode = StandardNames.XS_IDREFS | NodeInfo.IS_DTD_TYPE; 190 } 191 } 192 193 receiver.attribute(attCode, typeCode, atts.getValue(a), 0, properties); 194 } 195 196 receiver.startContent(); 197 198 namespacesUsed = 0; 199 } catch (XPathException err) { 203 throw new SAXException(err); 204 } 205 } 206 207 private int getNameCode(String uri, String localname, String rawname) throws SAXException { 208 if (rawname.equals("")) { 212 throw new SAXException("Saxon requires an XML parser that reports the QName of each element"); 213 } 214 if (localname.equals("")) { 217 throw new SAXException("Parser configuration problem: namespace reporting is not enabled"); 218 } 219 220 225 HashMap map2 = (uri.equals("") ? noNamespaceMap : (HashMap )cache.get(uri)); 226 if (map2 == null) { 227 map2 = new HashMap (50); 228 cache.put(uri, map2); 229 if (uri.equals("")) { 230 noNamespaceMap = map2; 231 } 232 } 233 234 Integer n = (Integer )map2.get(rawname); 235 if (n == null) { 236 String prefix = Name.getPrefix(rawname); 237 int nc = pool.allocate(prefix, uri, localname); 238 n = new Integer (nc); 239 map2.put(rawname, n); 240 return nc; 241 } else { 242 return n.intValue(); 243 } 244 245 } 246 247 253 254 private HashMap cache = new HashMap (10); 255 private HashMap noNamespaceMap; 256 257 258 261 262 public void endElement (String uri, String localname, String rawname) throws SAXException { 263 try { 265 flush(); 266 receiver.endElement(); 267 } catch (ValidationException err) { 268 err.setLocator(locator); 269 if (!err.hasBeenReported()) { 270 try { 271 pipe.getErrorListener().fatalError(err); 272 } catch (TransformerException e) { 273 } 275 } 276 throw new SAXException(err); 277 } catch (XPathException err) { 278 throw new SAXException(err); 279 } 280 } 281 282 285 286 public void characters (char ch[], int start, int length) throws SAXException { 287 290 while (used + length > buffer.length) { 291 char[] newbuffer = new char[buffer.length*2]; 292 System.arraycopy(buffer, 0, newbuffer, 0, used); 293 buffer = newbuffer; 294 slice = new CharSlice(buffer, 0, 0); 295 } 296 System.arraycopy(ch, start, buffer, used, length); 297 used += length; 298 } 299 300 303 304 public void ignorableWhitespace (char ch[], int start, int length) throws SAXException { 305 characters(ch, start, length); 306 } 307 308 311 312 public void processingInstruction (String name, String remainder) throws SAXException { 313 try { 314 flush(); 315 if (!inDTD) { 316 if (name==null) { 317 comment(remainder.toCharArray(), 0, remainder.length()); 319 } else { 320 if (!XMLChar.isValidNCName(name)) { 322 throw new SAXException("Invalid processing instruction name (" + name + ')'); 323 } 324 receiver.processingInstruction(name, remainder, 0, 0); 325 } 326 } 327 } catch (XPathException err) { 328 throw new SAXException(err); 329 } 330 } 331 332 335 336 public void comment (char ch[], int start, int length) throws SAXException { 337 try { 338 flush(); 339 if (!inDTD) { 340 receiver.comment(new CharSlice(ch, start, length), 0, 0); 341 } 342 } catch (XPathException err) { 343 throw new SAXException(err); 344 } 345 } 346 347 350 351 private void flush() throws XPathException { 352 if (used > 0) { 353 slice.setLength(used); 354 receiver.characters(slice, 0, 0); 355 used = 0; 356 } 357 } 358 359 public void skippedEntity(String name) throws SAXException {} 360 361 363 367 368 public void startDTD (String name, String publicId, String systemId) throws SAXException { 369 inDTD = true; 370 } 371 372 376 377 public void endDTD () throws SAXException { 378 inDTD = false; 379 } 380 381 public void startEntity (String name) throws SAXException {}; 382 383 public void endEntity (String name) throws SAXException {}; 384 385 public void startCDATA () throws SAXException {}; 386 387 public void endCDATA () throws SAXException {}; 388 389 393 394 public void notationDecl( String name, 395 String publicId, 396 String systemId) throws SAXException 397 {} 398 399 400 public void unparsedEntityDecl( String name, 401 String publicId, 402 String systemId, 403 String notationName) throws SAXException 404 { 405 407 410 String uri = systemId; 411 if (locator!=null) { 412 try { 413 String baseURI = locator.getSystemId(); 414 URI absoluteURI = new URI (baseURI).resolve(systemId); 415 uri = absoluteURI.toString(); 416 } catch (URISyntaxException err) {} 417 } 418 try { 419 receiver.setUnparsedEntity(name, uri, publicId); 420 } catch (XPathException err) { 421 throw new SAXException(err); 422 } 423 } 424 425 427 432 433 public String getSystemId() { 434 if (locator == null) { 435 return null; 436 } else { 437 return locator.getSystemId(); 438 } 439 } 440 441 446 447 public String getPublicId() { 448 if (locator==null) { 449 return null; 450 } else { 451 return locator.getPublicId(); 452 } 453 } 454 455 459 460 public int getLineNumber() { 461 if (locator==null) { 462 return -1; 463 } else { 464 return locator.getLineNumber(); 465 } 466 } 467 468 472 473 public int getColumnNumber() { 474 if (locator==null) { 475 return -1; 476 } else { 477 return locator.getColumnNumber(); 478 } 479 } 480 481 public String getSystemId(int locationId) { 482 return getSystemId(); 483 } 484 485 public int getLineNumber(int locationId) { 486 return getLineNumber(); 487 } 488 489 } 491 | Popular Tags |