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