1 18 package org.enhydra.barracuda.contrib.sam.xmlform.dtd; 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 public class ElementImpl extends DefaultHandler implements Cloneable , Unmarshallable, LexicalHandler , Element { 46 47 private Text text; 48 private Textarea textarea; 49 private Select select; 50 private Radio radio; 51 private Hidden hidden; 52 private Validator validator; 53 private String label; 54 private boolean zeus_LabelSet; 55 private String name; 56 private boolean zeus_NameSet; 57 private String ref; 58 private boolean zeus_RefSet; 59 60 61 private String docTypeString; 62 63 64 private String outputEncoding; 65 66 67 private Unmarshallable zeus_currentUNode; 68 69 70 private Unmarshallable zeus_parentUNode; 71 72 73 private boolean zeus_thisNodeHandled = false; 74 75 76 private boolean hasDTD; 77 78 79 private boolean validate; 80 81 82 private Map namespaceMappings; 83 84 85 private static EntityResolver entityResolver; 86 87 88 private static ErrorHandler errorHandler; 89 90 private static ElementImpl prototype = null; 91 92 public static void setPrototype(ElementImpl prototype) { 93 ElementImpl.prototype = prototype; 94 } 95 public static ElementImpl newInstance() { 96 try { 97 return (prototype!=null)?(ElementImpl)prototype.clone(): new ElementImpl(); 98 } catch (CloneNotSupportedException e) { 99 return null; } 101 } 102 public ElementImpl() { 103 zeus_LabelSet = false; 104 zeus_NameSet = false; 105 zeus_RefSet = false; 106 docTypeString = ""; 107 hasDTD = false; 108 validate = false; 109 namespaceMappings = new HashMap (); 110 } 111 112 public Text getText() { 113 return text; 114 } 115 116 public void setText(Text text) { 117 this.text = text; 118 } 119 120 public Textarea getTextarea() { 121 return textarea; 122 } 123 124 public void setTextarea(Textarea textarea) { 125 this.textarea = textarea; 126 } 127 128 public Select getSelect() { 129 return select; 130 } 131 132 public void setSelect(Select select) { 133 this.select = select; 134 } 135 136 public Radio getRadio() { 137 return radio; 138 } 139 140 public void setRadio(Radio radio) { 141 this.radio = radio; 142 } 143 144 public Hidden getHidden() { 145 return hidden; 146 } 147 148 public void setHidden(Hidden hidden) { 149 this.hidden = hidden; 150 } 151 152 public Validator getValidator() { 153 return validator; 154 } 155 156 public void setValidator(Validator validator) { 157 this.validator = validator; 158 } 159 160 public String getLabel() { 161 return label; 162 } 163 164 public void setLabel(String label) { 165 this.label = label; 166 zeus_LabelSet = true; 167 } 168 169 public String getName() { 170 return name; 171 } 172 173 public void setName(String name) { 174 this.name = name; 175 zeus_NameSet = true; 176 } 177 178 public String getRef() { 179 return ref; 180 } 181 182 public void setRef(String ref) { 183 this.ref = ref; 184 zeus_RefSet = true; 185 } 186 187 public void setDocType(String name, String publicID, String systemID) { 188 try { 189 startDTD(name, publicID, systemID); 190 } catch (SAXException neverHappens) { } 191 } 192 193 public void setOutputEncoding(String outputEncoding) { 194 this.outputEncoding = outputEncoding; 195 } 196 197 public void marshal(File file) throws IOException { 198 marshal(new FileWriter (file)); 200 } 201 202 public void marshal(OutputStream outputStream) throws IOException { 203 marshal(new OutputStreamWriter (outputStream)); 205 } 206 207 public void marshal(Writer writer) throws IOException { 208 writer.write("<?xml version=\"1.0\" "); 210 if (outputEncoding != null) { 211 writer.write("encoding=\""); 212 writer.write(outputEncoding); 213 writer.write("\"?>\n\n"); 214 215 } else { 216 writer.write("encoding=\"UTF-8\"?>\n\n"); 217 218 } 219 writer.write(docTypeString); 221 writer.write("\n"); 222 writeXMLRepresentation(writer, ""); 224 225 writer.flush(); 227 writer.close(); 228 } 229 230 protected void writeXMLRepresentation(Writer writer, 231 String indent) 232 throws IOException { 233 234 writer.write(indent); 235 writer.write("<element"); 236 237 for (Iterator i = namespaceMappings.keySet().iterator(); i.hasNext(); ) { 239 String prefix = (String )i.next(); 240 String uri = (String )namespaceMappings.get(prefix); 241 writer.write(" xmlns"); 242 if (!prefix.trim().equals("")) { 243 writer.write(":"); 244 writer.write(prefix); 245 } 246 writer.write("=\""); 247 writer.write(uri); 248 writer.write("\"\n "); 249 } 250 251 if (zeus_LabelSet) { 253 writer.write(" label=\""); 254 writer.write(escapeAttributeValue(label)); 255 writer.write("\""); 256 } 257 if (zeus_NameSet) { 258 writer.write(" name=\""); 259 writer.write(escapeAttributeValue(name)); 260 writer.write("\""); 261 } 262 if (zeus_RefSet) { 263 writer.write(" ref=\""); 264 writer.write(escapeAttributeValue(ref)); 265 writer.write("\""); 266 } 267 writer.write(">"); 268 writer.write("\n"); 269 270 if (text != null) { 272 ((TextImpl)text).writeXMLRepresentation(writer, 273 new StringBuffer (indent).append(" ").toString()); 274 } 275 276 if (textarea != null) { 277 ((TextareaImpl)textarea).writeXMLRepresentation(writer, 278 new StringBuffer (indent).append(" ").toString()); 279 } 280 281 if (select != null) { 282 ((SelectImpl)select).writeXMLRepresentation(writer, 283 new StringBuffer (indent).append(" ").toString()); 284 } 285 286 if (radio != null) { 287 ((RadioImpl)radio).writeXMLRepresentation(writer, 288 new StringBuffer (indent).append(" ").toString()); 289 } 290 291 if (hidden != null) { 292 ((HiddenImpl)hidden).writeXMLRepresentation(writer, 293 new StringBuffer (indent).append(" ").toString()); 294 } 295 296 if (validator != null) { 297 ((ValidatorImpl)validator).writeXMLRepresentation(writer, 298 new StringBuffer (indent).append(" ").toString()); 299 } 300 301 writer.write(indent); 302 writer.write("</element>\n"); 303 } 304 305 private String escapeAttributeValue(String attributeValue) { 306 String returnValue = attributeValue; 307 for (int i = 0; i < returnValue.length(); i++) { 308 char ch = returnValue.charAt(i); 309 if (ch == '"') { 310 returnValue = new StringBuffer () 311 .append(returnValue.substring(0, i)) 312 .append(""") 313 .append(returnValue.substring(i+1)) 314 .toString(); 315 } 316 } 317 return returnValue; 318 } 319 320 private String escapeTextValue(String textValue) { 321 String returnValue = textValue; 322 for (int i = 0; i < returnValue.length(); i++) { 323 char ch = returnValue.charAt(i); 324 if (ch == '<') { 325 returnValue = new StringBuffer () 326 .append(returnValue.substring(0, i)) 327 .append("<") 328 .append(returnValue.substring(i+1)) 329 .toString(); 330 } else if (ch == '>') { 331 returnValue = new StringBuffer () 332 .append(returnValue.substring(0, i)) 333 .append(">") 334 .append(returnValue.substring(i+1)) 335 .toString(); 336 } 337 } 338 return returnValue; 339 } 340 341 348 public static void setEntityResolver(EntityResolver resolver) { 349 entityResolver = resolver; 350 } 351 352 359 public static void setErrorHandler(ErrorHandler handler) { 360 errorHandler = handler; 361 } 362 363 public static Element unmarshal(File file) throws IOException { 364 return unmarshal(new FileReader (file)); 366 } 367 368 public static Element unmarshal(File file, boolean validate) throws IOException { 369 return unmarshal(new FileReader (file), validate); 371 } 372 373 public static Element unmarshal(InputStream inputStream) throws IOException { 374 return unmarshal(new InputStreamReader (inputStream)); 376 } 377 378 public static Element unmarshal(InputStream inputStream, boolean validate) throws IOException { 379 return unmarshal(new InputStreamReader (inputStream), validate); 381 } 382 383 public static Element unmarshal(Reader reader) throws IOException { 384 return unmarshal(reader, false); 386 } 387 388 public static Element unmarshal(Reader reader, boolean validate) throws IOException { 389 ElementImpl element = ElementImpl.newInstance(); 390 element.setValidating(validate); 391 element.setCurrentUNode(element); 392 element.setParentUNode(null); 393 XMLReader parser = null; 395 String parserClass = System.getProperty("org.xml.sax.driver", 396 "org.apache.xerces.parsers.SAXParser"); 397 try { 398 parser = XMLReaderFactory.createXMLReader(parserClass); 399 400 if (entityResolver != null) { 402 parser.setEntityResolver(entityResolver); 403 } 404 405 parser.setErrorHandler(element); 407 408 parser.setProperty("http://xml.org/sax/properties/lexical-handler", element); 410 411 parser.setContentHandler(element); 413 } catch (SAXException e) { 414 throw new IOException ("Could not load XML parser: " + 415 e.getMessage()); 416 } 417 418 InputSource inputSource = new InputSource (reader); 419 try { 420 parser.setFeature("http://xml.org/sax/features/validation", new Boolean (validate).booleanValue()); 421 parser.setFeature("http://xml.org/sax/features/namespaces", true); 422 parser.setFeature("http://xml.org/sax/features/namespace-prefixes", false); 423 parser.parse(inputSource); 424 } catch (SAXException e) { 425 throw new IOException ("Error parsing XML document: " + 426 e.getMessage()); 427 } 428 429 return element; 431 } 432 433 public Unmarshallable getParentUNode() { 434 return zeus_parentUNode; 435 } 436 437 public void setParentUNode(Unmarshallable parentUNode) { 438 this.zeus_parentUNode = parentUNode; 439 } 440 441 public Unmarshallable getCurrentUNode() { 442 return zeus_currentUNode; 443 } 444 445 public void setCurrentUNode(Unmarshallable currentUNode) { 446 this.zeus_currentUNode = currentUNode; 447 } 448 449 public void setValidating(boolean validate) { 450 this.validate = validate; 451 } 452 453 public void startDocument() throws SAXException { 454 } 456 457 public void setDocumentLocator(Locator locator) { 458 } 460 461 public void startPrefixMapping(String prefix, String uri) 462 throws SAXException { 463 namespaceMappings.put(prefix, uri); 464 } 465 466 public void startElement(String namespaceURI, String localName, 467 String qName, org.xml.sax.Attributes atts) 468 throws SAXException { 469 470 Unmarshallable current = getCurrentUNode(); 472 if (current != this) { 473 current.startElement(namespaceURI, localName, qName, atts); 474 return; 475 } 476 477 if ((localName.equals("element")) && (!zeus_thisNodeHandled)) { 479 for (int i=0, len=atts.getLength(); i<len; i++) { 481 String attName= atts.getLocalName(i); 482 String attValue = atts.getValue(i); 483 if (attName.equals("label")) { 484 setLabel(attValue); 485 } 486 if (attName.equals("name")) { 487 setName(attValue); 488 } 489 if (attName.equals("ref")) { 490 setRef(attValue); 491 } 492 } 493 zeus_thisNodeHandled = true; 494 return; 495 } else { 496 if (localName.equals("text") && (text==null)) { 498 TextImpl text = TextImpl.newInstance(); 499 current = getCurrentUNode(); 500 text.setParentUNode(current); 501 text.setCurrentUNode(text); 502 this.setCurrentUNode(text); 503 text.startElement(namespaceURI, localName, qName, atts); 504 this.text = text; 506 return; 507 } 508 if (localName.equals("textarea") && (textarea==null)) { 509 TextareaImpl textarea = TextareaImpl.newInstance(); 510 current = getCurrentUNode(); 511 textarea.setParentUNode(current); 512 textarea.setCurrentUNode(textarea); 513 this.setCurrentUNode(textarea); 514 textarea.startElement(namespaceURI, localName, qName, atts); 515 this.textarea = textarea; 517 return; 518 } 519 if (localName.equals("select") && (select==null)) { 520 SelectImpl select = SelectImpl.newInstance(); 521 current = getCurrentUNode(); 522 select.setParentUNode(current); 523 select.setCurrentUNode(select); 524 this.setCurrentUNode(select); 525 select.startElement(namespaceURI, localName, qName, atts); 526 this.select = select; 528 return; 529 } 530 if (localName.equals("radio") && (radio==null)) { 531 RadioImpl radio = RadioImpl.newInstance(); 532 current = getCurrentUNode(); 533 radio.setParentUNode(current); 534 radio.setCurrentUNode(radio); 535 this.setCurrentUNode(radio); 536 radio.startElement(namespaceURI, localName, qName, atts); 537 this.radio = radio; 539 return; 540 } 541 if (localName.equals("hidden") && (hidden==null)) { 542 HiddenImpl hidden = HiddenImpl.newInstance(); 543 current = getCurrentUNode(); 544 hidden.setParentUNode(current); 545 hidden.setCurrentUNode(hidden); 546 this.setCurrentUNode(hidden); 547 hidden.startElement(namespaceURI, localName, qName, atts); 548 this.hidden = hidden; 550 return; 551 } 552 if (localName.equals("validator") && (validator==null)) { 553 ValidatorImpl validator = ValidatorImpl.newInstance(); 554 current = getCurrentUNode(); 555 validator.setParentUNode(current); 556 validator.setCurrentUNode(validator); 557 this.setCurrentUNode(validator); 558 validator.startElement(namespaceURI, localName, qName, atts); 559 this.validator = validator; 561 return; 562 } 563 } 564 } 565 566 public void endElement(String namespaceURI, String localName, 567 String qName) 568 throws SAXException { 569 570 Unmarshallable current = getCurrentUNode(); 571 if (current != this) { 572 current.endElement(namespaceURI, localName, qName); 573 return; 574 } 575 576 Unmarshallable parent = getCurrentUNode().getParentUNode(); 577 if (parent != null) { 578 parent.setCurrentUNode(parent); 579 } 580 } 581 582 public void characters(char[] ch, int start, int len) 583 throws SAXException { 584 585 Unmarshallable current = getCurrentUNode(); 587 if (current != this) { 588 current.characters(ch, start, len); 589 return; 590 } 591 592 String text = new String (ch, start, len); 593 text = text.trim(); 594 } 595 596 public void comment(char ch[], int start, int len) throws SAXException { 597 } 599 600 public void warning(SAXParseException e) throws SAXException { 601 if (errorHandler != null) { 602 errorHandler.warning(e); 603 } 604 } 605 606 public void error(SAXParseException e) throws SAXException { 607 if ((validate) && (!hasDTD)) { 608 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."); 609 } 610 if (errorHandler != null) { 611 errorHandler.error(e); 612 } 613 } 614 615 public void fatalError(SAXParseException e) throws SAXException { 616 if ((validate) && (!hasDTD)) { 617 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."); 618 } 619 if (errorHandler != null) { 620 errorHandler.fatalError(e); 621 } 622 } 623 624 public void startDTD(String name, String publicID, String systemID) 625 throws SAXException { 626 627 if ((name == null) || (name.equals(""))) { 628 docTypeString = ""; 629 return; 630 } 631 632 hasDTD = true; 633 StringBuffer docTypeSB = new StringBuffer (); 634 boolean hasPublic = false; 635 636 docTypeSB.append("<!DOCTYPE ") 637 .append(name); 638 639 if ((publicID != null) && (!publicID.equals(""))) { 640 docTypeSB.append(" PUBLIC \"") 641 .append(publicID) 642 .append("\""); 643 hasPublic = true; 644 } 645 646 if ((systemID != null) && (!systemID.equals(""))) { 647 if (!hasPublic) { 648 docTypeSB.append(" SYSTEM"); 649 } 650 docTypeSB.append(" \"") 651 .append(systemID) 652 .append("\""); 653 654 } 655 656 docTypeSB.append(">"); 657 658 docTypeString = docTypeSB.toString(); 659 } 660 661 public void endDTD() throws SAXException { 662 } 664 665 public void startEntity(String name) throws SAXException { 666 } 668 669 public void endEntity(String name) throws SAXException { 670 } 672 673 public void startCDATA() throws SAXException { 674 } 676 677 public void endCDATA() throws SAXException { 678 } 680 681 } 682 | Popular Tags |