1 18 package org.enhydra.convert.xml; 19 20 import java.io.File ; 22 import java.io.FileReader ; 23 import java.io.FileWriter ; 24 import java.io.InputStream ; 25 import java.io.InputStreamReader ; 26 import java.io.IOException ; 27 import java.io.OutputStream ; 28 import java.io.OutputStreamWriter ; 29 import java.io.Reader ; 30 import java.io.Writer ; 31 import java.util.HashMap ; 32 import java.util.Iterator ; 33 import java.util.Map ; 34 import org.xml.sax.EntityResolver ; 35 import org.xml.sax.ErrorHandler ; 36 import org.xml.sax.InputSource ; 37 import org.xml.sax.Locator ; 38 import org.xml.sax.SAXException ; 39 import org.xml.sax.SAXParseException ; 40 import org.xml.sax.XMLReader ; 41 import org.xml.sax.ext.LexicalHandler ; 42 import org.xml.sax.helpers.DefaultHandler ; 43 import org.xml.sax.helpers.XMLReaderFactory ; 44 45 import java.util.Iterator ; 47 import java.util.List ; 48 import java.util.LinkedList ; 49 50 public class WebResourceCollectionImpl extends DefaultHandler implements Cloneable , Unmarshallable, LexicalHandler , WebResourceCollection { 51 52 private WebResourceName webResourceName; 53 private Description description; 54 private List urlPatternList; 55 private List httpMethodList; 56 private String id; 57 private boolean zeus_IdSet; 58 59 60 private String docTypeString; 61 62 63 private String outputEncoding; 64 65 66 private Unmarshallable zeus_currentUNode; 67 68 69 private Unmarshallable zeus_parentUNode; 70 71 72 private boolean zeus_thisNodeHandled = false; 73 74 75 private boolean hasDTD; 76 77 78 private boolean validate; 79 80 81 private Map namespaceMappings; 82 83 84 private static EntityResolver entityResolver; 85 86 87 private static ErrorHandler errorHandler; 88 89 private static WebResourceCollectionImpl prototype = null; 90 91 public static void setPrototype(WebResourceCollectionImpl prototype) { 92 WebResourceCollectionImpl.prototype = prototype; 93 } 94 public static WebResourceCollectionImpl newInstance() { 95 try { 96 return (prototype!=null)?(WebResourceCollectionImpl)prototype.clone(): new WebResourceCollectionImpl(); 97 } catch (CloneNotSupportedException e) { 98 return null; } 100 } 101 public WebResourceCollectionImpl() { 102 urlPatternList = new LinkedList (); 103 httpMethodList = new LinkedList (); 104 zeus_IdSet = false; 105 docTypeString = ""; 106 hasDTD = false; 107 validate = false; 108 namespaceMappings = new HashMap (); 109 } 110 111 public WebResourceName getWebResourceName() { 112 return webResourceName; 113 } 114 115 public void setWebResourceName(WebResourceName webResourceName) { 116 this.webResourceName = webResourceName; 117 } 118 119 public Description getDescription() { 120 return description; 121 } 122 123 public void setDescription(Description description) { 124 this.description = description; 125 } 126 127 public List getUrlPatternList() { 128 return urlPatternList; 129 } 130 131 public void setUrlPatternList(List urlPatternList) { 132 this.urlPatternList = urlPatternList; 133 } 134 135 public void addUrlPattern(UrlPattern urlPattern) { 136 urlPatternList.add(urlPattern); 137 } 138 139 public void removeUrlPattern(UrlPattern urlPattern) { 140 urlPatternList.remove(urlPattern); 141 } 142 143 public List getHttpMethodList() { 144 return httpMethodList; 145 } 146 147 public void setHttpMethodList(List httpMethodList) { 148 this.httpMethodList = httpMethodList; 149 } 150 151 public void addHttpMethod(HttpMethod httpMethod) { 152 httpMethodList.add(httpMethod); 153 } 154 155 public void removeHttpMethod(HttpMethod httpMethod) { 156 httpMethodList.remove(httpMethod); 157 } 158 159 public String getId() { 160 return id; 161 } 162 163 public void setId(String id) { 164 this.id = id; 165 zeus_IdSet = true; 166 } 167 168 public void setDocType(String name, String publicID, String systemID) { 169 try { 170 startDTD(name, publicID, systemID); 171 } catch (SAXException neverHappens) { } 172 } 173 174 public void setOutputEncoding(String outputEncoding) { 175 this.outputEncoding = outputEncoding; 176 } 177 178 public void marshal(File file) throws IOException { 179 marshal(new FileWriter (file)); 181 } 182 183 public void marshal(OutputStream outputStream) throws IOException { 184 marshal(new OutputStreamWriter (outputStream)); 186 } 187 188 public void marshal(Writer writer) throws IOException { 189 writer.write("<?xml version=\"1.0\" "); 191 if (outputEncoding != null) { 192 writer.write("encoding=\""); 193 writer.write(outputEncoding); 194 writer.write("\"?>\n\n"); 195 196 } else { 197 writer.write("encoding=\"UTF-8\"?>\n\n"); 198 199 } 200 writer.write(docTypeString); 202 writer.write("\n"); 203 writeXMLRepresentation(writer, ""); 205 206 writer.flush(); 208 writer.close(); 209 } 210 211 protected void writeXMLRepresentation(Writer writer, 212 String indent) 213 throws IOException { 214 215 writer.write(indent); 216 writer.write("<web-resource-collection"); 217 218 for (Iterator i = namespaceMappings.keySet().iterator(); i.hasNext(); ) { 220 String prefix = (String )i.next(); 221 String uri = (String )namespaceMappings.get(prefix); 222 writer.write(" xmlns"); 223 if (!prefix.trim().equals("")) { 224 writer.write(":"); 225 writer.write(prefix); 226 } 227 writer.write("=\""); 228 writer.write(uri); 229 writer.write("\"\n "); 230 } 231 232 if (zeus_IdSet) { 234 writer.write(" id=\""); 235 writer.write(escapeAttributeValue(id)); 236 writer.write("\""); 237 } 238 writer.write(">"); 239 writer.write("\n"); 240 241 if (webResourceName != null) { 243 ((WebResourceNameImpl)webResourceName).writeXMLRepresentation(writer, 244 new StringBuffer (indent).append(" ").toString()); 245 } 246 247 if (description != null) { 248 ((DescriptionImpl)description).writeXMLRepresentation(writer, 249 new StringBuffer (indent).append(" ").toString()); 250 } 251 252 for (Iterator i=urlPatternList.iterator(); i.hasNext(); ) { 253 UrlPatternImpl urlPattern = (UrlPatternImpl)i.next(); 254 urlPattern.writeXMLRepresentation(writer, 255 new StringBuffer (indent).append(" ").toString()); 256 } 257 for (Iterator i=httpMethodList.iterator(); i.hasNext(); ) { 258 HttpMethodImpl httpMethod = (HttpMethodImpl)i.next(); 259 httpMethod.writeXMLRepresentation(writer, 260 new StringBuffer (indent).append(" ").toString()); 261 } 262 writer.write(indent); 263 writer.write("</web-resource-collection>\n"); 264 } 265 266 private String escapeAttributeValue(String attributeValue) { 267 String returnValue = attributeValue; 268 for (int i = 0; i < returnValue.length(); i++) { 269 char ch = returnValue.charAt(i); 270 if (ch == '"') { 271 returnValue = new StringBuffer () 272 .append(returnValue.substring(0, i)) 273 .append(""") 274 .append(returnValue.substring(i+1)) 275 .toString(); 276 } 277 } 278 return returnValue; 279 } 280 281 private String escapeTextValue(String textValue) { 282 String returnValue = textValue; 283 for (int i = 0; i < returnValue.length(); i++) { 284 char ch = returnValue.charAt(i); 285 if (ch == '<') { 286 returnValue = new StringBuffer () 287 .append(returnValue.substring(0, i)) 288 .append("<") 289 .append(returnValue.substring(i+1)) 290 .toString(); 291 } else if (ch == '>') { 292 returnValue = new StringBuffer () 293 .append(returnValue.substring(0, i)) 294 .append(">") 295 .append(returnValue.substring(i+1)) 296 .toString(); 297 } 298 } 299 return returnValue; 300 } 301 302 309 public static void setEntityResolver(EntityResolver resolver) { 310 entityResolver = resolver; 311 } 312 313 320 public static void setErrorHandler(ErrorHandler handler) { 321 errorHandler = handler; 322 } 323 324 public static WebResourceCollection unmarshal(File file) throws IOException { 325 return unmarshal(new FileReader (file)); 327 } 328 329 public static WebResourceCollection unmarshal(File file, boolean validate) throws IOException { 330 return unmarshal(new FileReader (file), validate); 332 } 333 334 public static WebResourceCollection unmarshal(InputStream inputStream) throws IOException { 335 return unmarshal(new InputStreamReader (inputStream)); 337 } 338 339 public static WebResourceCollection unmarshal(InputStream inputStream, boolean validate) throws IOException { 340 return unmarshal(new InputStreamReader (inputStream), validate); 342 } 343 344 public static WebResourceCollection unmarshal(Reader reader) throws IOException { 345 return unmarshal(reader, false); 347 } 348 349 public static WebResourceCollection unmarshal(Reader reader, boolean validate) throws IOException { 350 WebResourceCollectionImpl webResourceCollection = WebResourceCollectionImpl.newInstance(); 351 webResourceCollection.setValidating(validate); 352 webResourceCollection.setCurrentUNode(webResourceCollection); 353 webResourceCollection.setParentUNode(null); 354 XMLReader parser = null; 356 String parserClass = System.getProperty("org.xml.sax.driver", 357 "org.apache.xerces.parsers.SAXParser"); 358 try { 359 parser = XMLReaderFactory.createXMLReader(parserClass); 360 361 if (entityResolver != null) { 363 parser.setEntityResolver(entityResolver); 364 } 365 366 parser.setErrorHandler(webResourceCollection); 368 369 parser.setProperty("http://xml.org/sax/properties/lexical-handler", webResourceCollection); 371 372 parser.setContentHandler(webResourceCollection); 374 } catch (SAXException e) { 375 throw new IOException ("Could not load XML parser: " + 376 e.getMessage()); 377 } 378 379 InputSource inputSource = new InputSource (reader); 380 try { 381 parser.setFeature("http://xml.org/sax/features/validation", new Boolean (validate).booleanValue()); 382 parser.setFeature("http://xml.org/sax/features/namespaces", true); 383 parser.setFeature("http://xml.org/sax/features/namespace-prefixes", false); 384 parser.parse(inputSource); 385 } catch (SAXException e) { 386 throw new IOException ("Error parsing XML document: " + 387 e.getMessage()); 388 } 389 390 return webResourceCollection; 392 } 393 394 public Unmarshallable getParentUNode() { 395 return zeus_parentUNode; 396 } 397 398 public void setParentUNode(Unmarshallable parentUNode) { 399 this.zeus_parentUNode = parentUNode; 400 } 401 402 public Unmarshallable getCurrentUNode() { 403 return zeus_currentUNode; 404 } 405 406 public void setCurrentUNode(Unmarshallable currentUNode) { 407 this.zeus_currentUNode = currentUNode; 408 } 409 410 public void setValidating(boolean validate) { 411 this.validate = validate; 412 } 413 414 public void startDocument() throws SAXException { 415 } 417 418 public void setDocumentLocator(Locator locator) { 419 } 421 422 public void startPrefixMapping(String prefix, String uri) 423 throws SAXException { 424 namespaceMappings.put(prefix, uri); 425 } 426 427 public void startElement(String namespaceURI, String localName, 428 String qName, org.xml.sax.Attributes atts) 429 throws SAXException { 430 431 Unmarshallable current = getCurrentUNode(); 433 if (current != this) { 434 current.startElement(namespaceURI, localName, qName, atts); 435 return; 436 } 437 438 if ((localName.equals("web-resource-collection")) && (!zeus_thisNodeHandled)) { 440 for (int i=0, len=atts.getLength(); i<len; i++) { 442 String attName= atts.getLocalName(i); 443 String attValue = atts.getValue(i); 444 if (attName.equals("id")) { 445 setId(attValue); 446 } 447 } 448 zeus_thisNodeHandled = true; 449 return; 450 } else { 451 if (localName.equals("web-resource-name") && (webResourceName==null)) { 453 WebResourceNameImpl webResourceName = WebResourceNameImpl.newInstance(); 454 current = getCurrentUNode(); 455 webResourceName.setParentUNode(current); 456 webResourceName.setCurrentUNode(webResourceName); 457 this.setCurrentUNode(webResourceName); 458 webResourceName.startElement(namespaceURI, localName, qName, atts); 459 this.webResourceName = webResourceName; 461 return; 462 } 463 if (localName.equals("description") && (description==null)) { 464 DescriptionImpl description = DescriptionImpl.newInstance(); 465 current = getCurrentUNode(); 466 description.setParentUNode(current); 467 description.setCurrentUNode(description); 468 this.setCurrentUNode(description); 469 description.startElement(namespaceURI, localName, qName, atts); 470 this.description = description; 472 return; 473 } 474 if (localName.equals("url-pattern")) { 475 UrlPatternImpl urlPattern = UrlPatternImpl.newInstance(); 476 current = getCurrentUNode(); 477 urlPattern.setParentUNode(current); 478 urlPattern.setCurrentUNode(urlPattern); 479 this.setCurrentUNode(urlPattern); 480 urlPattern.startElement(namespaceURI, localName, qName, atts); 481 urlPatternList.add(urlPattern); 483 return; 484 } 485 if (localName.equals("http-method")) { 486 HttpMethodImpl httpMethod = HttpMethodImpl.newInstance(); 487 current = getCurrentUNode(); 488 httpMethod.setParentUNode(current); 489 httpMethod.setCurrentUNode(httpMethod); 490 this.setCurrentUNode(httpMethod); 491 httpMethod.startElement(namespaceURI, localName, qName, atts); 492 httpMethodList.add(httpMethod); 494 return; 495 } 496 } 497 } 498 499 public void endElement(String namespaceURI, String localName, 500 String qName) 501 throws SAXException { 502 503 Unmarshallable current = getCurrentUNode(); 504 if (current != this) { 505 current.endElement(namespaceURI, localName, qName); 506 return; 507 } 508 509 Unmarshallable parent = getCurrentUNode().getParentUNode(); 510 if (parent != null) { 511 parent.setCurrentUNode(parent); 512 } 513 } 514 515 public void characters(char[] ch, int start, int len) 516 throws SAXException { 517 518 Unmarshallable current = getCurrentUNode(); 520 if (current != this) { 521 current.characters(ch, start, len); 522 return; 523 } 524 525 String text = new String (ch, start, len); 526 } 527 528 public void comment(char ch[], int start, int len) throws SAXException { 529 } 531 532 public void warning(SAXParseException e) throws SAXException { 533 if (errorHandler != null) { 534 errorHandler.warning(e); 535 } 536 } 537 538 public void error(SAXParseException e) throws SAXException { 539 if ((validate) && (!hasDTD)) { 540 throw new SAXException ("Validation is turned on, but no DTD has been specified in the input XML document. Please supply a DTD through a DOCTYPE reference."); 541 } 542 if (errorHandler != null) { 543 errorHandler.error(e); 544 } 545 } 546 547 public void fatalError(SAXParseException e) throws SAXException { 548 if ((validate) && (!hasDTD)) { 549 throw new SAXException ("Validation is turned on, but no DTD has been specified in the input XML document. Please supply a DTD through a DOCTYPE reference."); 550 } 551 if (errorHandler != null) { 552 errorHandler.fatalError(e); 553 } 554 } 555 556 public void startDTD(String name, String publicID, String systemID) 557 throws SAXException { 558 559 if ((name == null) || (name.equals(""))) { 560 docTypeString = ""; 561 return; 562 } 563 564 hasDTD = true; 565 StringBuffer docTypeSB = new StringBuffer (); 566 boolean hasPublic = false; 567 568 docTypeSB.append("<!DOCTYPE ") 569 .append(name); 570 571 if ((publicID != null) && (!publicID.equals(""))) { 572 docTypeSB.append(" PUBLIC \"") 573 .append(publicID) 574 .append("\""); 575 hasPublic = true; 576 } 577 578 if ((systemID != null) && (!systemID.equals(""))) { 579 if (!hasPublic) { 580 docTypeSB.append(" SYSTEM"); 581 } 582 docTypeSB.append(" \"") 583 .append(systemID) 584 .append("\""); 585 586 } 587 588 docTypeSB.append(">"); 589 590 docTypeString = docTypeSB.toString(); 591 } 592 593 public void endDTD() throws SAXException { 594 } 596 597 public void startEntity(String name) throws SAXException { 598 } 600 601 public void endEntity(String name) throws SAXException { 602 } 604 605 public void startCDATA() throws SAXException { 606 } 608 609 public void endCDATA() throws SAXException { 610 } 612 613 } 614 | Popular Tags |