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 import java.util.Iterator ; 47 import java.util.List ; 48 import java.util.LinkedList ; 49 50 public class FilterImpl extends DefaultHandler implements Cloneable , Unmarshallable, LexicalHandler , Filter { 51 52 private Icon icon; 53 private FilterName filterName; 54 private DisplayName displayName; 55 private Description description; 56 private FilterClass filterClass; 57 private List initParamList; 58 private String id; 59 private boolean zeus_IdSet; 60 61 62 private String docTypeString; 63 64 65 private String outputEncoding; 66 67 68 private Unmarshallable zeus_currentUNode; 69 70 71 private Unmarshallable zeus_parentUNode; 72 73 74 private boolean zeus_thisNodeHandled = false; 75 76 77 private boolean hasDTD; 78 79 80 private boolean validate; 81 82 83 private Map namespaceMappings; 84 85 86 private static EntityResolver entityResolver; 87 88 89 private static ErrorHandler errorHandler; 90 91 private static FilterImpl prototype = null; 92 93 public static void setPrototype(FilterImpl prototype) { 94 FilterImpl.prototype = prototype; 95 } 96 public static FilterImpl newInstance() { 97 try { 98 return (prototype!=null)?(FilterImpl)prototype.clone(): new FilterImpl(); 99 } catch (CloneNotSupportedException e) { 100 return null; } 102 } 103 public FilterImpl() { 104 initParamList = new LinkedList (); 105 zeus_IdSet = false; 106 docTypeString = ""; 107 hasDTD = false; 108 validate = false; 109 namespaceMappings = new HashMap (); 110 } 111 112 public Icon getIcon() { 113 return icon; 114 } 115 116 public void setIcon(Icon icon) { 117 this.icon = icon; 118 } 119 120 public FilterName getFilterName() { 121 return filterName; 122 } 123 124 public void setFilterName(FilterName filterName) { 125 this.filterName = filterName; 126 } 127 128 public DisplayName getDisplayName() { 129 return displayName; 130 } 131 132 public void setDisplayName(DisplayName displayName) { 133 this.displayName = displayName; 134 } 135 136 public Description getDescription() { 137 return description; 138 } 139 140 public void setDescription(Description description) { 141 this.description = description; 142 } 143 144 public FilterClass getFilterClass() { 145 return filterClass; 146 } 147 148 public void setFilterClass(FilterClass filterClass) { 149 this.filterClass = filterClass; 150 } 151 152 public List getInitParamList() { 153 return initParamList; 154 } 155 156 public void setInitParamList(List initParamList) { 157 this.initParamList = initParamList; 158 } 159 160 public void addInitParam(InitParam initParam) { 161 initParamList.add(initParam); 162 } 163 164 public void removeInitParam(InitParam initParam) { 165 initParamList.remove(initParam); 166 } 167 168 public String getId() { 169 return id; 170 } 171 172 public void setId(String id) { 173 this.id = id; 174 zeus_IdSet = true; 175 } 176 177 public void setDocType(String name, String publicID, String systemID) { 178 try { 179 startDTD(name, publicID, systemID); 180 } catch (SAXException neverHappens) { } 181 } 182 183 public void setOutputEncoding(String outputEncoding) { 184 this.outputEncoding = outputEncoding; 185 } 186 187 public void marshal(File file) throws IOException { 188 marshal(new FileWriter (file)); 190 } 191 192 public void marshal(OutputStream outputStream) throws IOException { 193 marshal(new OutputStreamWriter (outputStream)); 195 } 196 197 public void marshal(Writer writer) throws IOException { 198 writer.write("<?xml version=\"1.0\" "); 200 if (outputEncoding != null) { 201 writer.write("encoding=\""); 202 writer.write(outputEncoding); 203 writer.write("\"?>\n\n"); 204 205 } else { 206 writer.write("encoding=\"UTF-8\"?>\n\n"); 207 208 } 209 writer.write(docTypeString); 211 writer.write("\n"); 212 writeXMLRepresentation(writer, ""); 214 215 writer.flush(); 217 writer.close(); 218 } 219 220 protected void writeXMLRepresentation(Writer writer, 221 String indent) 222 throws IOException { 223 224 writer.write(indent); 225 writer.write("<filter"); 226 227 for (Iterator i = namespaceMappings.keySet().iterator(); i.hasNext(); ) { 229 String prefix = (String )i.next(); 230 String uri = (String )namespaceMappings.get(prefix); 231 writer.write(" xmlns"); 232 if (!prefix.trim().equals("")) { 233 writer.write(":"); 234 writer.write(prefix); 235 } 236 writer.write("=\""); 237 writer.write(uri); 238 writer.write("\"\n "); 239 } 240 241 if (zeus_IdSet) { 243 writer.write(" id=\""); 244 writer.write(escapeAttributeValue(id)); 245 writer.write("\""); 246 } 247 writer.write(">"); 248 writer.write("\n"); 249 250 if (icon != null) { 252 ((IconImpl)icon).writeXMLRepresentation(writer, 253 new StringBuffer (indent).append(" ").toString()); 254 } 255 256 if (filterName != null) { 257 ((FilterNameImpl)filterName).writeXMLRepresentation(writer, 258 new StringBuffer (indent).append(" ").toString()); 259 } 260 261 if (displayName != null) { 262 ((DisplayNameImpl)displayName).writeXMLRepresentation(writer, 263 new StringBuffer (indent).append(" ").toString()); 264 } 265 266 if (description != null) { 267 ((DescriptionImpl)description).writeXMLRepresentation(writer, 268 new StringBuffer (indent).append(" ").toString()); 269 } 270 271 if (filterClass != null) { 272 ((FilterClassImpl)filterClass).writeXMLRepresentation(writer, 273 new StringBuffer (indent).append(" ").toString()); 274 } 275 276 for (Iterator i=initParamList.iterator(); i.hasNext(); ) { 277 InitParamImpl initParam = (InitParamImpl)i.next(); 278 initParam.writeXMLRepresentation(writer, 279 new StringBuffer (indent).append(" ").toString()); 280 } 281 writer.write(indent); 282 writer.write("</filter>\n"); 283 } 284 285 private String escapeAttributeValue(String attributeValue) { 286 String returnValue = attributeValue; 287 for (int i = 0; i < returnValue.length(); i++) { 288 char ch = returnValue.charAt(i); 289 if (ch == '"') { 290 returnValue = new StringBuffer () 291 .append(returnValue.substring(0, i)) 292 .append(""") 293 .append(returnValue.substring(i+1)) 294 .toString(); 295 } 296 } 297 return returnValue; 298 } 299 300 private String escapeTextValue(String textValue) { 301 String returnValue = textValue; 302 for (int i = 0; i < returnValue.length(); i++) { 303 char ch = returnValue.charAt(i); 304 if (ch == '<') { 305 returnValue = new StringBuffer () 306 .append(returnValue.substring(0, i)) 307 .append("<") 308 .append(returnValue.substring(i+1)) 309 .toString(); 310 } else if (ch == '>') { 311 returnValue = new StringBuffer () 312 .append(returnValue.substring(0, i)) 313 .append(">") 314 .append(returnValue.substring(i+1)) 315 .toString(); 316 } 317 } 318 return returnValue; 319 } 320 321 328 public static void setEntityResolver(EntityResolver resolver) { 329 entityResolver = resolver; 330 } 331 332 339 public static void setErrorHandler(ErrorHandler handler) { 340 errorHandler = handler; 341 } 342 343 public static Filter unmarshal(File file) throws IOException { 344 return unmarshal(new FileReader (file)); 346 } 347 348 public static Filter unmarshal(File file, boolean validate) throws IOException { 349 return unmarshal(new FileReader (file), validate); 351 } 352 353 public static Filter unmarshal(InputStream inputStream) throws IOException { 354 return unmarshal(new InputStreamReader (inputStream)); 356 } 357 358 public static Filter unmarshal(InputStream inputStream, boolean validate) throws IOException { 359 return unmarshal(new InputStreamReader (inputStream), validate); 361 } 362 363 public static Filter unmarshal(Reader reader) throws IOException { 364 return unmarshal(reader, false); 366 } 367 368 public static Filter unmarshal(Reader reader, boolean validate) throws IOException { 369 FilterImpl filter = FilterImpl.newInstance(); 370 filter.setValidating(validate); 371 filter.setCurrentUNode(filter); 372 filter.setParentUNode(null); 373 XMLReader parser = null; 375 String parserClass = System.getProperty("org.xml.sax.driver", 376 "org.apache.xerces.parsers.SAXParser"); 377 try { 378 parser = XMLReaderFactory.createXMLReader(parserClass); 379 380 if (entityResolver != null) { 382 parser.setEntityResolver(entityResolver); 383 } 384 385 parser.setErrorHandler(filter); 387 388 parser.setProperty("http://xml.org/sax/properties/lexical-handler", filter); 390 391 parser.setContentHandler(filter); 393 } catch (SAXException e) { 394 throw new IOException ("Could not load XML parser: " + 395 e.getMessage()); 396 } 397 398 InputSource inputSource = new InputSource (reader); 399 try { 400 parser.setFeature("http://xml.org/sax/features/validation", new Boolean (validate).booleanValue()); 401 parser.setFeature("http://xml.org/sax/features/namespaces", true); 402 parser.setFeature("http://xml.org/sax/features/namespace-prefixes", false); 403 parser.parse(inputSource); 404 } catch (SAXException e) { 405 throw new IOException ("Error parsing XML document: " + 406 e.getMessage()); 407 } 408 409 return filter; 411 } 412 413 public Unmarshallable getParentUNode() { 414 return zeus_parentUNode; 415 } 416 417 public void setParentUNode(Unmarshallable parentUNode) { 418 this.zeus_parentUNode = parentUNode; 419 } 420 421 public Unmarshallable getCurrentUNode() { 422 return zeus_currentUNode; 423 } 424 425 public void setCurrentUNode(Unmarshallable currentUNode) { 426 this.zeus_currentUNode = currentUNode; 427 } 428 429 public void setValidating(boolean validate) { 430 this.validate = validate; 431 } 432 433 public void startDocument() throws SAXException { 434 } 436 437 public void setDocumentLocator(Locator locator) { 438 } 440 441 public void startPrefixMapping(String prefix, String uri) 442 throws SAXException { 443 namespaceMappings.put(prefix, uri); 444 } 445 446 public void startElement(String namespaceURI, String localName, 447 String qName, org.xml.sax.Attributes atts) 448 throws SAXException { 449 450 Unmarshallable current = getCurrentUNode(); 452 if (current != this) { 453 current.startElement(namespaceURI, localName, qName, atts); 454 return; 455 } 456 457 if ((localName.equals("filter")) && (!zeus_thisNodeHandled)) { 459 for (int i=0, len=atts.getLength(); i<len; i++) { 461 String attName= atts.getLocalName(i); 462 String attValue = atts.getValue(i); 463 if (attName.equals("id")) { 464 setId(attValue); 465 } 466 } 467 zeus_thisNodeHandled = true; 468 return; 469 } else { 470 if (localName.equals("icon") && (icon==null)) { 472 IconImpl icon = IconImpl.newInstance(); 473 current = getCurrentUNode(); 474 icon.setParentUNode(current); 475 icon.setCurrentUNode(icon); 476 this.setCurrentUNode(icon); 477 icon.startElement(namespaceURI, localName, qName, atts); 478 this.icon = icon; 480 return; 481 } 482 if (localName.equals("filter-name") && (filterName==null)) { 483 FilterNameImpl filterName = FilterNameImpl.newInstance(); 484 current = getCurrentUNode(); 485 filterName.setParentUNode(current); 486 filterName.setCurrentUNode(filterName); 487 this.setCurrentUNode(filterName); 488 filterName.startElement(namespaceURI, localName, qName, atts); 489 this.filterName = filterName; 491 return; 492 } 493 if (localName.equals("display-name") && (displayName==null)) { 494 DisplayNameImpl displayName = DisplayNameImpl.newInstance(); 495 current = getCurrentUNode(); 496 displayName.setParentUNode(current); 497 displayName.setCurrentUNode(displayName); 498 this.setCurrentUNode(displayName); 499 displayName.startElement(namespaceURI, localName, qName, atts); 500 this.displayName = displayName; 502 return; 503 } 504 if (localName.equals("description") && (description==null)) { 505 DescriptionImpl description = DescriptionImpl.newInstance(); 506 current = getCurrentUNode(); 507 description.setParentUNode(current); 508 description.setCurrentUNode(description); 509 this.setCurrentUNode(description); 510 description.startElement(namespaceURI, localName, qName, atts); 511 this.description = description; 513 return; 514 } 515 if (localName.equals("filter-class") && (filterClass==null)) { 516 FilterClassImpl filterClass = FilterClassImpl.newInstance(); 517 current = getCurrentUNode(); 518 filterClass.setParentUNode(current); 519 filterClass.setCurrentUNode(filterClass); 520 this.setCurrentUNode(filterClass); 521 filterClass.startElement(namespaceURI, localName, qName, atts); 522 this.filterClass = filterClass; 524 return; 525 } 526 if (localName.equals("init-param")) { 527 InitParamImpl initParam = InitParamImpl.newInstance(); 528 current = getCurrentUNode(); 529 initParam.setParentUNode(current); 530 initParam.setCurrentUNode(initParam); 531 this.setCurrentUNode(initParam); 532 initParam.startElement(namespaceURI, localName, qName, atts); 533 initParamList.add(initParam); 535 return; 536 } 537 } 538 } 539 540 public void endElement(String namespaceURI, String localName, 541 String qName) 542 throws SAXException { 543 544 Unmarshallable current = getCurrentUNode(); 545 if (current != this) { 546 current.endElement(namespaceURI, localName, qName); 547 return; 548 } 549 550 Unmarshallable parent = getCurrentUNode().getParentUNode(); 551 if (parent != null) { 552 parent.setCurrentUNode(parent); 553 } 554 } 555 556 public void characters(char[] ch, int start, int len) 557 throws SAXException { 558 559 Unmarshallable current = getCurrentUNode(); 561 if (current != this) { 562 current.characters(ch, start, len); 563 return; 564 } 565 566 String text = new String (ch, start, len); 567 } 568 569 public void comment(char ch[], int start, int len) throws SAXException { 570 } 572 573 public void warning(SAXParseException e) throws SAXException { 574 if (errorHandler != null) { 575 errorHandler.warning(e); 576 } 577 } 578 579 public void error(SAXParseException e) throws SAXException { 580 if ((validate) && (!hasDTD)) { 581 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."); 582 } 583 if (errorHandler != null) { 584 errorHandler.error(e); 585 } 586 } 587 588 public void fatalError(SAXParseException e) throws SAXException { 589 if ((validate) && (!hasDTD)) { 590 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."); 591 } 592 if (errorHandler != null) { 593 errorHandler.fatalError(e); 594 } 595 } 596 597 public void startDTD(String name, String publicID, String systemID) 598 throws SAXException { 599 600 if ((name == null) || (name.equals(""))) { 601 docTypeString = ""; 602 return; 603 } 604 605 hasDTD = true; 606 StringBuffer docTypeSB = new StringBuffer (); 607 boolean hasPublic = false; 608 609 docTypeSB.append("<!DOCTYPE ") 610 .append(name); 611 612 if ((publicID != null) && (!publicID.equals(""))) { 613 docTypeSB.append(" PUBLIC \"") 614 .append(publicID) 615 .append("\""); 616 hasPublic = true; 617 } 618 619 if ((systemID != null) && (!systemID.equals(""))) { 620 if (!hasPublic) { 621 docTypeSB.append(" SYSTEM"); 622 } 623 docTypeSB.append(" \"") 624 .append(systemID) 625 .append("\""); 626 627 } 628 629 docTypeSB.append(">"); 630 631 docTypeString = docTypeSB.toString(); 632 } 633 634 public void endDTD() throws SAXException { 635 } 637 638 public void startEntity(String name) throws SAXException { 639 } 641 642 public void endEntity(String name) throws SAXException { 643 } 645 646 public void startCDATA() throws SAXException { 647 } 649 650 public void endCDATA() throws SAXException { 651 } 653 654 } 655 | Popular Tags |