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