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