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