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 OptionImpl extends DefaultHandler implements Cloneable , Unmarshallable, LexicalHandler , Option { 46 47 private String value; 48 private boolean zeus_ValueSet; 49 private String selected; 50 private boolean zeus_SelectedSet; 51 private String value2; 52 private boolean zeus_Value2Set; 53 54 55 private String docTypeString; 56 57 58 private String outputEncoding; 59 60 61 private Unmarshallable zeus_currentUNode; 62 63 64 private Unmarshallable zeus_parentUNode; 65 66 67 private boolean zeus_thisNodeHandled = false; 68 69 70 private boolean hasDTD; 71 72 73 private boolean validate; 74 75 76 private Map namespaceMappings; 77 78 79 private static EntityResolver entityResolver; 80 81 82 private static ErrorHandler errorHandler; 83 84 private static OptionImpl prototype = null; 85 86 public static void setPrototype(OptionImpl prototype) { 87 OptionImpl.prototype = prototype; 88 } 89 public static OptionImpl newInstance() { 90 try { 91 return (prototype!=null)?(OptionImpl)prototype.clone(): new OptionImpl(); 92 } catch (CloneNotSupportedException e) { 93 return null; } 95 } 96 public OptionImpl() { 97 zeus_ValueSet = false; 98 zeus_SelectedSet = false; 99 zeus_Value2Set = false; 100 docTypeString = ""; 101 hasDTD = false; 102 validate = false; 103 namespaceMappings = new HashMap (); 104 } 105 106 public String getValue() { 107 return value; 108 } 109 110 public void setValue(String value) { 111 this.value = value; 112 zeus_ValueSet = true; 113 } 114 115 public String getSelected() { 116 return selected; 117 } 118 119 public void setSelected(String selected) { 120 this.selected = selected; 121 zeus_SelectedSet = true; 122 } 123 124 public String getValue2() { 125 return value2; 126 } 127 128 public void setValue2(String value2) { 129 this.value2 = value2; 130 zeus_Value2Set = true; 131 } 132 133 public void setDocType(String name, String publicID, String systemID) { 134 try { 135 startDTD(name, publicID, systemID); 136 } catch (SAXException neverHappens) { } 137 } 138 139 public void setOutputEncoding(String outputEncoding) { 140 this.outputEncoding = outputEncoding; 141 } 142 143 public void marshal(File file) throws IOException { 144 marshal(new FileWriter (file)); 146 } 147 148 public void marshal(OutputStream outputStream) throws IOException { 149 marshal(new OutputStreamWriter (outputStream)); 151 } 152 153 public void marshal(Writer writer) throws IOException { 154 writer.write("<?xml version=\"1.0\" "); 156 if (outputEncoding != null) { 157 writer.write("encoding=\""); 158 writer.write(outputEncoding); 159 writer.write("\"?>\n\n"); 160 161 } else { 162 writer.write("encoding=\"UTF-8\"?>\n\n"); 163 164 } 165 writer.write(docTypeString); 167 writer.write("\n"); 168 writeXMLRepresentation(writer, ""); 170 171 writer.flush(); 173 writer.close(); 174 } 175 176 protected void writeXMLRepresentation(Writer writer, 177 String indent) 178 throws IOException { 179 180 writer.write(indent); 181 writer.write("<option"); 182 183 for (Iterator i = namespaceMappings.keySet().iterator(); i.hasNext(); ) { 185 String prefix = (String )i.next(); 186 String uri = (String )namespaceMappings.get(prefix); 187 writer.write(" xmlns"); 188 if (!prefix.trim().equals("")) { 189 writer.write(":"); 190 writer.write(prefix); 191 } 192 writer.write("=\""); 193 writer.write(uri); 194 writer.write("\"\n "); 195 } 196 197 if (zeus_SelectedSet) { 199 writer.write(" selected=\""); 200 writer.write(escapeAttributeValue(selected)); 201 writer.write("\""); 202 } 203 if (zeus_Value2Set) { 204 writer.write(" value=\""); 205 writer.write(escapeAttributeValue(value2)); 206 writer.write("\""); 207 } 208 if (getValue() != null) { 209 writer.write(">"); 211 writer.write(escapeTextValue(getValue())); 212 writer.write("</option>\n"); 213 } else { 214 writer.write("/>\n"); 215 } 216 } 217 218 private String escapeAttributeValue(String attributeValue) { 219 String returnValue = attributeValue; 220 for (int i = 0; i < returnValue.length(); i++) { 221 char ch = returnValue.charAt(i); 222 if (ch == '"') { 223 returnValue = new StringBuffer () 224 .append(returnValue.substring(0, i)) 225 .append(""") 226 .append(returnValue.substring(i+1)) 227 .toString(); 228 } 229 } 230 return returnValue; 231 } 232 233 private String escapeTextValue(String textValue) { 234 String returnValue = textValue; 235 for (int i = 0; i < returnValue.length(); i++) { 236 char ch = returnValue.charAt(i); 237 if (ch == '<') { 238 returnValue = new StringBuffer () 239 .append(returnValue.substring(0, i)) 240 .append("<") 241 .append(returnValue.substring(i+1)) 242 .toString(); 243 } else if (ch == '>') { 244 returnValue = new StringBuffer () 245 .append(returnValue.substring(0, i)) 246 .append(">") 247 .append(returnValue.substring(i+1)) 248 .toString(); 249 } 250 } 251 return returnValue; 252 } 253 254 261 public static void setEntityResolver(EntityResolver resolver) { 262 entityResolver = resolver; 263 } 264 265 272 public static void setErrorHandler(ErrorHandler handler) { 273 errorHandler = handler; 274 } 275 276 public static Option unmarshal(File file) throws IOException { 277 return unmarshal(new FileReader (file)); 279 } 280 281 public static Option unmarshal(File file, boolean validate) throws IOException { 282 return unmarshal(new FileReader (file), validate); 284 } 285 286 public static Option unmarshal(InputStream inputStream) throws IOException { 287 return unmarshal(new InputStreamReader (inputStream)); 289 } 290 291 public static Option unmarshal(InputStream inputStream, boolean validate) throws IOException { 292 return unmarshal(new InputStreamReader (inputStream), validate); 294 } 295 296 public static Option unmarshal(Reader reader) throws IOException { 297 return unmarshal(reader, false); 299 } 300 301 public static Option unmarshal(Reader reader, boolean validate) throws IOException { 302 OptionImpl option = OptionImpl.newInstance(); 303 option.setValidating(validate); 304 option.setCurrentUNode(option); 305 option.setParentUNode(null); 306 XMLReader parser = null; 308 String parserClass = System.getProperty("org.xml.sax.driver", 309 "org.apache.xerces.parsers.SAXParser"); 310 try { 311 parser = XMLReaderFactory.createXMLReader(parserClass); 312 313 if (entityResolver != null) { 315 parser.setEntityResolver(entityResolver); 316 } 317 318 parser.setErrorHandler(option); 320 321 parser.setProperty("http://xml.org/sax/properties/lexical-handler", option); 323 324 parser.setContentHandler(option); 326 } catch (SAXException e) { 327 throw new IOException ("Could not load XML parser: " + 328 e.getMessage()); 329 } 330 331 InputSource inputSource = new InputSource (reader); 332 try { 333 parser.setFeature("http://xml.org/sax/features/validation", new Boolean (validate).booleanValue()); 334 parser.setFeature("http://xml.org/sax/features/namespaces", true); 335 parser.setFeature("http://xml.org/sax/features/namespace-prefixes", false); 336 parser.parse(inputSource); 337 } catch (SAXException e) { 338 throw new IOException ("Error parsing XML document: " + 339 e.getMessage()); 340 } 341 342 return option; 344 } 345 346 public Unmarshallable getParentUNode() { 347 return zeus_parentUNode; 348 } 349 350 public void setParentUNode(Unmarshallable parentUNode) { 351 this.zeus_parentUNode = parentUNode; 352 } 353 354 public Unmarshallable getCurrentUNode() { 355 return zeus_currentUNode; 356 } 357 358 public void setCurrentUNode(Unmarshallable currentUNode) { 359 this.zeus_currentUNode = currentUNode; 360 } 361 362 public void setValidating(boolean validate) { 363 this.validate = validate; 364 } 365 366 public void startDocument() throws SAXException { 367 } 369 370 public void setDocumentLocator(Locator locator) { 371 } 373 374 public void startPrefixMapping(String prefix, String uri) 375 throws SAXException { 376 namespaceMappings.put(prefix, uri); 377 } 378 379 public void startElement(String namespaceURI, String localName, 380 String qName, org.xml.sax.Attributes atts) 381 throws SAXException { 382 383 Unmarshallable current = getCurrentUNode(); 385 if (current != this) { 386 current.startElement(namespaceURI, localName, qName, atts); 387 return; 388 } 389 390 if ((localName.equals("option")) && (!zeus_thisNodeHandled)) { 392 for (int i=0, len=atts.getLength(); i<len; i++) { 394 String attName= atts.getLocalName(i); 395 String attValue = atts.getValue(i); 396 if (attName.equals("selected")) { 397 setSelected(attValue); 398 } 399 if (attName.equals("value")) { 400 setValue2(attValue); 401 } 402 } 403 zeus_thisNodeHandled = true; 404 return; 405 } else { 406 } 408 } 409 410 public void endElement(String namespaceURI, String localName, 411 String qName) 412 throws SAXException { 413 414 Unmarshallable current = getCurrentUNode(); 415 if (current != this) { 416 current.endElement(namespaceURI, localName, qName); 417 return; 418 } 419 420 if (this.value == null) { 422 this.value = ""; 423 } 424 Unmarshallable parent = getCurrentUNode().getParentUNode(); 425 if (parent != null) { 426 parent.setCurrentUNode(parent); 427 } 428 } 429 430 public void characters(char[] ch, int start, int len) 431 throws SAXException { 432 433 Unmarshallable current = getCurrentUNode(); 435 if (current != this) { 436 current.characters(ch, start, len); 437 return; 438 } 439 440 String text = new String (ch, start, len); 441 text = text.trim(); 442 if (this.value == null) { 443 this.value = text; 444 } else { 445 this.value = new StringBuffer (this.value).append(text).toString(); 446 } 447 } 448 449 public void comment(char ch[], int start, int len) throws SAXException { 450 } 452 453 public void warning(SAXParseException e) throws SAXException { 454 if (errorHandler != null) { 455 errorHandler.warning(e); 456 } 457 } 458 459 public void error(SAXParseException e) throws SAXException { 460 if ((validate) && (!hasDTD)) { 461 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."); 462 } 463 if (errorHandler != null) { 464 errorHandler.error(e); 465 } 466 } 467 468 public void fatalError(SAXParseException e) throws SAXException { 469 if ((validate) && (!hasDTD)) { 470 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."); 471 } 472 if (errorHandler != null) { 473 errorHandler.fatalError(e); 474 } 475 } 476 477 public void startDTD(String name, String publicID, String systemID) 478 throws SAXException { 479 480 if ((name == null) || (name.equals(""))) { 481 docTypeString = ""; 482 return; 483 } 484 485 hasDTD = true; 486 StringBuffer docTypeSB = new StringBuffer (); 487 boolean hasPublic = false; 488 489 docTypeSB.append("<!DOCTYPE ") 490 .append(name); 491 492 if ((publicID != null) && (!publicID.equals(""))) { 493 docTypeSB.append(" PUBLIC \"") 494 .append(publicID) 495 .append("\""); 496 hasPublic = true; 497 } 498 499 if ((systemID != null) && (!systemID.equals(""))) { 500 if (!hasPublic) { 501 docTypeSB.append(" SYSTEM"); 502 } 503 docTypeSB.append(" \"") 504 .append(systemID) 505 .append("\""); 506 507 } 508 509 docTypeSB.append(">"); 510 511 docTypeString = docTypeSB.toString(); 512 } 513 514 public void endDTD() throws SAXException { 515 } 517 518 public void startEntity(String name) throws SAXException { 519 } 521 522 public void endEntity(String name) throws SAXException { 523 } 525 526 public void startCDATA() throws SAXException { 527 } 529 530 public void endCDATA() throws SAXException { 531 } 533 534 } 535 | Popular Tags |