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 import java.util.Iterator ; 47 import java.util.List ; 48 import java.util.LinkedList ; 49 50 public class SelectImpl extends DefaultHandler implements Cloneable , Unmarshallable, LexicalHandler , Select { 51 52 private List optionList; 53 private String multivalue; 54 private static boolean zeus_MultivalueInitialized; 55 private static java.util.Vector zeus_validMultivalue; 56 private boolean zeus_MultivalueSet; 57 private String xmlclass; 58 private boolean zeus_XmlclassSet; 59 private String method; 60 private boolean zeus_MethodSet; 61 62 63 private String docTypeString; 64 65 66 private String outputEncoding; 67 68 69 private Unmarshallable zeus_currentUNode; 70 71 72 private Unmarshallable zeus_parentUNode; 73 74 75 private boolean zeus_thisNodeHandled = false; 76 77 78 private boolean hasDTD; 79 80 81 private boolean validate; 82 83 84 private Map namespaceMappings; 85 86 87 private static EntityResolver entityResolver; 88 89 90 private static ErrorHandler errorHandler; 91 92 private static SelectImpl prototype = null; 93 94 public static void setPrototype(SelectImpl prototype) { 95 SelectImpl.prototype = prototype; 96 } 97 public static SelectImpl newInstance() { 98 try { 99 return (prototype!=null)?(SelectImpl)prototype.clone(): new SelectImpl(); 100 } catch (CloneNotSupportedException e) { 101 return null; } 103 } 104 public SelectImpl() { 105 optionList = new LinkedList (); 106 zeus_MultivalueInitialized = false; 107 zeus_validMultivalue = null; 108 zeus_MultivalueSet = false; 109 zeus_XmlclassSet = false; 110 zeus_MethodSet = false; 111 docTypeString = ""; 112 hasDTD = false; 113 validate = false; 114 namespaceMappings = new HashMap (); 115 } 116 117 public List getOptionList() { 118 return optionList; 119 } 120 121 public void setOptionList(List optionList) { 122 this.optionList = optionList; 123 } 124 125 public void addOption(Option option) { 126 optionList.add(option); 127 } 128 129 public void removeOption(Option option) { 130 optionList.remove(option); 131 } 132 133 public String getMultivalue() { 134 return multivalue; 135 } 136 137 public void setMultivalue(String multivalue) 138 throws IllegalArgumentException { 139 if (!zeus_MultivalueInitialized) { 140 zeus_validMultivalue = new java.util.Vector (); 141 zeus_validMultivalue.addElement("true"); 142 zeus_validMultivalue.addElement("false"); 143 zeus_MultivalueInitialized = true; 144 } 145 if (!zeus_validMultivalue.contains(multivalue)) { 146 throw new IllegalArgumentException ("Illegal value for attribute 'multivalue'"); 147 } else { 148 this.multivalue = multivalue; 149 this.zeus_MultivalueSet = true; 150 } 151 } 152 153 public String getXmlclass() { 154 return xmlclass; 155 } 156 157 public void setXmlclass(String xmlclass) { 158 this.xmlclass = xmlclass; 159 zeus_XmlclassSet = true; 160 } 161 162 public String getMethod() { 163 return method; 164 } 165 166 public void setMethod(String method) { 167 this.method = method; 168 zeus_MethodSet = true; 169 } 170 171 public void setDocType(String name, String publicID, String systemID) { 172 try { 173 startDTD(name, publicID, systemID); 174 } catch (SAXException neverHappens) { } 175 } 176 177 public void setOutputEncoding(String outputEncoding) { 178 this.outputEncoding = outputEncoding; 179 } 180 181 public void marshal(File file) throws IOException { 182 marshal(new FileWriter (file)); 184 } 185 186 public void marshal(OutputStream outputStream) throws IOException { 187 marshal(new OutputStreamWriter (outputStream)); 189 } 190 191 public void marshal(Writer writer) throws IOException { 192 writer.write("<?xml version=\"1.0\" "); 194 if (outputEncoding != null) { 195 writer.write("encoding=\""); 196 writer.write(outputEncoding); 197 writer.write("\"?>\n\n"); 198 199 } else { 200 writer.write("encoding=\"UTF-8\"?>\n\n"); 201 202 } 203 writer.write(docTypeString); 205 writer.write("\n"); 206 writeXMLRepresentation(writer, ""); 208 209 writer.flush(); 211 writer.close(); 212 } 213 214 protected void writeXMLRepresentation(Writer writer, 215 String indent) 216 throws IOException { 217 218 writer.write(indent); 219 writer.write("<select"); 220 221 for (Iterator i = namespaceMappings.keySet().iterator(); i.hasNext(); ) { 223 String prefix = (String )i.next(); 224 String uri = (String )namespaceMappings.get(prefix); 225 writer.write(" xmlns"); 226 if (!prefix.trim().equals("")) { 227 writer.write(":"); 228 writer.write(prefix); 229 } 230 writer.write("=\""); 231 writer.write(uri); 232 writer.write("\"\n "); 233 } 234 235 if (zeus_MultivalueSet) { 237 writer.write(" multivalue=\""); 238 writer.write(escapeAttributeValue(multivalue)); 239 writer.write("\""); 240 } 241 if (zeus_XmlclassSet) { 242 writer.write(" class=\""); 243 writer.write(escapeAttributeValue(xmlclass)); 244 writer.write("\""); 245 } 246 if (zeus_MethodSet) { 247 writer.write(" method=\""); 248 writer.write(escapeAttributeValue(method)); 249 writer.write("\""); 250 } 251 writer.write(">"); 252 writer.write("\n"); 253 254 for (Iterator i=optionList.iterator(); i.hasNext(); ) { 256 OptionImpl option = (OptionImpl)i.next(); 257 option.writeXMLRepresentation(writer, 258 new StringBuffer (indent).append(" ").toString()); 259 } 260 writer.write(indent); 261 writer.write("</select>\n"); 262 } 263 264 private String escapeAttributeValue(String attributeValue) { 265 String returnValue = attributeValue; 266 for (int i = 0; i < returnValue.length(); i++) { 267 char ch = returnValue.charAt(i); 268 if (ch == '"') { 269 returnValue = new StringBuffer () 270 .append(returnValue.substring(0, i)) 271 .append(""") 272 .append(returnValue.substring(i+1)) 273 .toString(); 274 } 275 } 276 return returnValue; 277 } 278 279 private String escapeTextValue(String textValue) { 280 String returnValue = textValue; 281 for (int i = 0; i < returnValue.length(); i++) { 282 char ch = returnValue.charAt(i); 283 if (ch == '<') { 284 returnValue = new StringBuffer () 285 .append(returnValue.substring(0, i)) 286 .append("<") 287 .append(returnValue.substring(i+1)) 288 .toString(); 289 } else if (ch == '>') { 290 returnValue = new StringBuffer () 291 .append(returnValue.substring(0, i)) 292 .append(">") 293 .append(returnValue.substring(i+1)) 294 .toString(); 295 } 296 } 297 return returnValue; 298 } 299 300 307 public static void setEntityResolver(EntityResolver resolver) { 308 entityResolver = resolver; 309 } 310 311 318 public static void setErrorHandler(ErrorHandler handler) { 319 errorHandler = handler; 320 } 321 322 public static Select unmarshal(File file) throws IOException { 323 return unmarshal(new FileReader (file)); 325 } 326 327 public static Select unmarshal(File file, boolean validate) throws IOException { 328 return unmarshal(new FileReader (file), validate); 330 } 331 332 public static Select unmarshal(InputStream inputStream) throws IOException { 333 return unmarshal(new InputStreamReader (inputStream)); 335 } 336 337 public static Select unmarshal(InputStream inputStream, boolean validate) throws IOException { 338 return unmarshal(new InputStreamReader (inputStream), validate); 340 } 341 342 public static Select unmarshal(Reader reader) throws IOException { 343 return unmarshal(reader, false); 345 } 346 347 public static Select unmarshal(Reader reader, boolean validate) throws IOException { 348 SelectImpl select = SelectImpl.newInstance(); 349 select.setValidating(validate); 350 select.setCurrentUNode(select); 351 select.setParentUNode(null); 352 XMLReader parser = null; 354 String parserClass = System.getProperty("org.xml.sax.driver", 355 "org.apache.xerces.parsers.SAXParser"); 356 try { 357 parser = XMLReaderFactory.createXMLReader(parserClass); 358 359 if (entityResolver != null) { 361 parser.setEntityResolver(entityResolver); 362 } 363 364 parser.setErrorHandler(select); 366 367 parser.setProperty("http://xml.org/sax/properties/lexical-handler", select); 369 370 parser.setContentHandler(select); 372 } catch (SAXException e) { 373 throw new IOException ("Could not load XML parser: " + 374 e.getMessage()); 375 } 376 377 InputSource inputSource = new InputSource (reader); 378 try { 379 parser.setFeature("http://xml.org/sax/features/validation", new Boolean (validate).booleanValue()); 380 parser.setFeature("http://xml.org/sax/features/namespaces", true); 381 parser.setFeature("http://xml.org/sax/features/namespace-prefixes", false); 382 parser.parse(inputSource); 383 } catch (SAXException e) { 384 throw new IOException ("Error parsing XML document: " + 385 e.getMessage()); 386 } 387 388 return select; 390 } 391 392 public Unmarshallable getParentUNode() { 393 return zeus_parentUNode; 394 } 395 396 public void setParentUNode(Unmarshallable parentUNode) { 397 this.zeus_parentUNode = parentUNode; 398 } 399 400 public Unmarshallable getCurrentUNode() { 401 return zeus_currentUNode; 402 } 403 404 public void setCurrentUNode(Unmarshallable currentUNode) { 405 this.zeus_currentUNode = currentUNode; 406 } 407 408 public void setValidating(boolean validate) { 409 this.validate = validate; 410 } 411 412 public void startDocument() throws SAXException { 413 } 415 416 public void setDocumentLocator(Locator locator) { 417 } 419 420 public void startPrefixMapping(String prefix, String uri) 421 throws SAXException { 422 namespaceMappings.put(prefix, uri); 423 } 424 425 public void startElement(String namespaceURI, String localName, 426 String qName, org.xml.sax.Attributes atts) 427 throws SAXException { 428 429 Unmarshallable current = getCurrentUNode(); 431 if (current != this) { 432 current.startElement(namespaceURI, localName, qName, atts); 433 return; 434 } 435 436 if ((localName.equals("select")) && (!zeus_thisNodeHandled)) { 438 for (int i=0, len=atts.getLength(); i<len; i++) { 440 String attName= atts.getLocalName(i); 441 String attValue = atts.getValue(i); 442 if (attName.equals("multivalue")) { 443 setMultivalue(attValue); 444 } 445 if (attName.equals("class")) { 446 setXmlclass(attValue); 447 } 448 if (attName.equals("method")) { 449 setMethod(attValue); 450 } 451 } 452 zeus_thisNodeHandled = true; 453 return; 454 } else { 455 if (localName.equals("option")) { 457 OptionImpl option = OptionImpl.newInstance(); 458 current = getCurrentUNode(); 459 option.setParentUNode(current); 460 option.setCurrentUNode(option); 461 this.setCurrentUNode(option); 462 option.startElement(namespaceURI, localName, qName, atts); 463 optionList.add(option); 465 return; 466 } 467 } 468 } 469 470 public void endElement(String namespaceURI, String localName, 471 String qName) 472 throws SAXException { 473 474 Unmarshallable current = getCurrentUNode(); 475 if (current != this) { 476 current.endElement(namespaceURI, localName, qName); 477 return; 478 } 479 480 Unmarshallable parent = getCurrentUNode().getParentUNode(); 481 if (parent != null) { 482 parent.setCurrentUNode(parent); 483 } 484 } 485 486 public void characters(char[] ch, int start, int len) 487 throws SAXException { 488 489 Unmarshallable current = getCurrentUNode(); 491 if (current != this) { 492 current.characters(ch, start, len); 493 return; 494 } 495 496 String text = new String (ch, start, len); 497 text = text.trim(); 498 } 499 500 public void comment(char ch[], int start, int len) throws SAXException { 501 } 503 504 public void warning(SAXParseException e) throws SAXException { 505 if (errorHandler != null) { 506 errorHandler.warning(e); 507 } 508 } 509 510 public void error(SAXParseException e) throws SAXException { 511 if ((validate) && (!hasDTD)) { 512 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."); 513 } 514 if (errorHandler != null) { 515 errorHandler.error(e); 516 } 517 } 518 519 public void fatalError(SAXParseException e) throws SAXException { 520 if ((validate) && (!hasDTD)) { 521 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."); 522 } 523 if (errorHandler != null) { 524 errorHandler.fatalError(e); 525 } 526 } 527 528 public void startDTD(String name, String publicID, String systemID) 529 throws SAXException { 530 531 if ((name == null) || (name.equals(""))) { 532 docTypeString = ""; 533 return; 534 } 535 536 hasDTD = true; 537 StringBuffer docTypeSB = new StringBuffer (); 538 boolean hasPublic = false; 539 540 docTypeSB.append("<!DOCTYPE ") 541 .append(name); 542 543 if ((publicID != null) && (!publicID.equals(""))) { 544 docTypeSB.append(" PUBLIC \"") 545 .append(publicID) 546 .append("\""); 547 hasPublic = true; 548 } 549 550 if ((systemID != null) && (!systemID.equals(""))) { 551 if (!hasPublic) { 552 docTypeSB.append(" SYSTEM"); 553 } 554 docTypeSB.append(" \"") 555 .append(systemID) 556 .append("\""); 557 558 } 559 560 docTypeSB.append(">"); 561 562 docTypeString = docTypeSB.toString(); 563 } 564 565 public void endDTD() throws SAXException { 566 } 568 569 public void startEntity(String name) throws SAXException { 570 } 572 573 public void endEntity(String name) throws SAXException { 574 } 576 577 public void startCDATA() throws SAXException { 578 } 580 581 public void endCDATA() throws SAXException { 582 } 584 585 } 586 | Popular Tags |