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 import java.util.Iterator ; 47 import java.util.List ; 48 import java.util.LinkedList ; 49 50 public class ConfigurationImpl extends DefaultHandler implements Cloneable , Unmarshallable, LexicalHandler , Configuration { 51 52 private List SiteList; 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 ConfigurationImpl prototype = null; 85 86 public static void setPrototype(ConfigurationImpl prototype) { 87 ConfigurationImpl.prototype = prototype; 88 } 89 public static ConfigurationImpl newInstance() { 90 try { 91 return (prototype!=null)?(ConfigurationImpl)prototype.clone(): new ConfigurationImpl(); 92 } catch (CloneNotSupportedException e) { 93 return null; } 95 } 96 public ConfigurationImpl() { 97 SiteList = new LinkedList (); 98 docTypeString = ""; 99 hasDTD = false; 100 validate = false; 101 namespaceMappings = new HashMap (); 102 } 103 104 public List getSiteList() { 105 return SiteList; 106 } 107 108 public void setSiteList(List SiteList) { 109 this.SiteList = SiteList; 110 } 111 112 public void addSite(Site Site) { 113 SiteList.add(Site); 114 } 115 116 public void removeSite(Site Site) { 117 SiteList.remove(Site); 118 } 119 120 public void setDocType(String name, String publicID, String systemID) { 121 try { 122 startDTD(name, publicID, systemID); 123 } catch (SAXException neverHappens) { } 124 } 125 126 public void setOutputEncoding(String outputEncoding) { 127 this.outputEncoding = outputEncoding; 128 } 129 130 public void marshal(File file) throws IOException { 131 marshal(new FileWriter (file)); 133 } 134 135 public void marshal(OutputStream outputStream) throws IOException { 136 marshal(new OutputStreamWriter (outputStream)); 138 } 139 140 public void marshal(Writer writer) throws IOException { 141 writer.write("<?xml version=\"1.0\" "); 143 if (outputEncoding != null) { 144 writer.write("encoding=\""); 145 writer.write(outputEncoding); 146 writer.write("\"?>\n\n"); 147 148 } else { 149 writer.write("encoding=\"UTF-8\"?>\n\n"); 150 151 } 152 writer.write(docTypeString); 154 writer.write("\n"); 155 writeXMLRepresentation(writer, ""); 157 158 writer.flush(); 160 writer.close(); 161 } 162 163 protected void writeXMLRepresentation(Writer writer, 164 String indent) 165 throws IOException { 166 167 writer.write(indent); 168 writer.write("<Configuration"); 169 170 for (Iterator i = namespaceMappings.keySet().iterator(); i.hasNext(); ) { 172 String prefix = (String )i.next(); 173 String uri = (String )namespaceMappings.get(prefix); 174 writer.write(" xmlns"); 175 if (!prefix.trim().equals("")) { 176 writer.write(":"); 177 writer.write(prefix); 178 } 179 writer.write("=\""); 180 writer.write(uri); 181 writer.write("\"\n "); 182 } 183 184 writer.write(">"); 186 writer.write("\n"); 187 188 for (Iterator i=SiteList.iterator(); i.hasNext(); ) { 190 SiteImpl site = (SiteImpl)i.next(); 191 site.writeXMLRepresentation(writer, 192 new StringBuffer (indent).append(" ").toString()); 193 } 194 writer.write(indent); 195 writer.write("</Configuration>\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 Configuration unmarshal(File file) throws IOException { 257 return unmarshal(new FileReader (file)); 259 } 260 261 public static Configuration unmarshal(File file, boolean validate) throws IOException { 262 return unmarshal(new FileReader (file), validate); 264 } 265 266 public static Configuration unmarshal(InputStream inputStream) throws IOException { 267 return unmarshal(new InputStreamReader (inputStream)); 269 } 270 271 public static Configuration unmarshal(InputStream inputStream, boolean validate) throws IOException { 272 return unmarshal(new InputStreamReader (inputStream), validate); 274 } 275 276 public static Configuration unmarshal(Reader reader) throws IOException { 277 return unmarshal(reader, false); 279 } 280 281 public static Configuration unmarshal(Reader reader, boolean validate) throws IOException { 282 ConfigurationImpl configuration = ConfigurationImpl.newInstance(); 283 configuration.setValidating(validate); 284 configuration.setCurrentUNode(configuration); 285 configuration.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(configuration); 300 301 parser.setProperty("http://xml.org/sax/properties/lexical-handler", configuration); 303 304 parser.setContentHandler(configuration); 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 configuration; 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("Configuration")) && (!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("Site")) { 382 SiteImpl site = SiteImpl.newInstance(); 383 current = getCurrentUNode(); 384 site.setParentUNode(current); 385 site.setCurrentUNode(site); 386 this.setCurrentUNode(site); 387 site.startElement(namespaceURI, localName, qName, atts); 388 SiteList.add(site); 390 return; 391 } 392 } 393 } 394 395 public void endElement(String namespaceURI, String localName, 396 String qName) 397 throws SAXException { 398 399 Unmarshallable current = getCurrentUNode(); 400 if (current != this) { 401 current.endElement(namespaceURI, localName, qName); 402 return; 403 } 404 405 Unmarshallable parent = getCurrentUNode().getParentUNode(); 406 if (parent != null) { 407 parent.setCurrentUNode(parent); 408 } 409 } 410 411 public void characters(char[] ch, int start, int len) 412 throws SAXException { 413 414 Unmarshallable current = getCurrentUNode(); 416 if (current != this) { 417 current.characters(ch, start, len); 418 return; 419 } 420 421 String text = new String (ch, start, len); 422 } 423 424 public void comment(char ch[], int start, int len) throws SAXException { 425 } 427 428 public void warning(SAXParseException e) throws SAXException { 429 if (errorHandler != null) { 430 errorHandler.warning(e); 431 } 432 } 433 434 public void error(SAXParseException e) throws SAXException { 435 if ((validate) && (!hasDTD)) { 436 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."); 437 } 438 if (errorHandler != null) { 439 errorHandler.error(e); 440 } 441 } 442 443 public void fatalError(SAXParseException e) throws SAXException { 444 if ((validate) && (!hasDTD)) { 445 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."); 446 } 447 if (errorHandler != null) { 448 errorHandler.fatalError(e); 449 } 450 } 451 452 public void startDTD(String name, String publicID, String systemID) 453 throws SAXException { 454 455 if ((name == null) || (name.equals(""))) { 456 docTypeString = ""; 457 return; 458 } 459 460 hasDTD = true; 461 StringBuffer docTypeSB = new StringBuffer (); 462 boolean hasPublic = false; 463 464 docTypeSB.append("<!DOCTYPE ") 465 .append(name); 466 467 if ((publicID != null) && (!publicID.equals(""))) { 468 docTypeSB.append(" PUBLIC \"") 469 .append(publicID) 470 .append("\""); 471 hasPublic = true; 472 } 473 474 if ((systemID != null) && (!systemID.equals(""))) { 475 if (!hasPublic) { 476 docTypeSB.append(" SYSTEM"); 477 } 478 docTypeSB.append(" \"") 479 .append(systemID) 480 .append("\""); 481 482 } 483 484 docTypeSB.append(">"); 485 486 docTypeString = docTypeSB.toString(); 487 } 488 489 public void endDTD() throws SAXException { 490 } 492 493 public void startEntity(String name) throws SAXException { 494 } 496 497 public void endEntity(String name) throws SAXException { 498 } 500 501 public void startCDATA() throws SAXException { 502 } 504 505 public void endCDATA() throws SAXException { 506 } 508 509 } 510 | Popular Tags |