| 1 16 package org.apache.commons.jelly.parser; 17 18 import java.io.File ; 19 import java.io.InputStream ; 20 import java.io.IOException ; 21 import java.io.Reader ; 22 import java.net.URL ; 23 import java.util.ArrayList ; 24 import java.util.EmptyStackException ; 25 import java.util.HashMap ; 26 import java.util.Iterator ; 27 import java.util.Map ; 28 import java.util.Properties ; 29 30 import javax.xml.parsers.SAXParser ; 31 import javax.xml.parsers.SAXParserFactory ; 32 33 import org.apache.commons.collections.ArrayStack; 34 35 import org.apache.commons.jelly.JellyContext; 36 import org.apache.commons.jelly.JellyException; 37 import org.apache.commons.jelly.Script; 38 import org.apache.commons.jelly.Tag; 39 import org.apache.commons.jelly.TagLibrary; 40 import org.apache.commons.jelly.impl.CompositeTextScriptBlock; 41 import org.apache.commons.jelly.impl.ExpressionScript; 42 import org.apache.commons.jelly.impl.StaticTag; 43 import org.apache.commons.jelly.impl.ScriptBlock; 44 import org.apache.commons.jelly.impl.StaticTagScript; 45 import org.apache.commons.jelly.impl.TagFactory; 46 import org.apache.commons.jelly.impl.TagScript; 47 import org.apache.commons.jelly.impl.TextScript; 48 import org.apache.commons.jelly.util.ClassLoaderUtils; 49 import org.apache.commons.jelly.util.SAXParseException; 50 import org.apache.commons.jelly.expression.CompositeExpression; 51 import org.apache.commons.jelly.expression.ConstantExpression; 52 import org.apache.commons.jelly.expression.Expression; 53 import org.apache.commons.jelly.expression.ExpressionFactory; 54 import org.apache.commons.jelly.expression.jexl.JexlExpressionFactory; 55 56 import org.apache.commons.logging.Log; 57 import org.apache.commons.logging.LogFactory; 58 59 import org.xml.sax.Attributes ; 60 import org.xml.sax.ErrorHandler ; 61 import org.xml.sax.helpers.DefaultHandler ; 62 import org.xml.sax.InputSource ; 63 import org.xml.sax.Locator ; 64 import org.xml.sax.SAXException ; 65 import org.xml.sax.XMLReader ; 66 import org.xml.sax.helpers.AttributesImpl ; 67 68 74 public class XMLParser extends DefaultHandler { 75 76 79 private static Properties jellyProperties; 80 81 82 83 private JellyContext context = new JellyContext(); 84 85 86 private ExpressionFactory expressionFactory; 87 88 89 private ScriptBlock script; 90 91 92 private TagScript tagScript; 93 94 95 private ArrayStack scriptStack = new ArrayStack(); 96 97 98 private ArrayList tagScriptStack = new ArrayList (); 99 100 101 private StringBuffer textBuffer; 102 103 109 protected ClassLoader classLoader = null; 110 111 115 protected boolean useContextClassLoader = false; 116 117 121 protected ErrorHandler errorHandler = null; 122 123 126 protected static SAXParserFactory factory = null; 127 128 131 protected SAXParser parser = null; 132 133 136 protected XMLReader reader = null; 137 138 141 protected Locator locator = null; 142 143 151 protected Map namespaces = new HashMap (); 152 153 154 private Map elementNamespaces; 155 156 160 private String fileName; 161 162 165 protected boolean validating = false; 166 167 168 private boolean configured; 169 170 175 private String defaultNamespaceURI = null; 176 177 180 private Log log = LogFactory.getLog(XMLParser.class); 181 182 185 public XMLParser() { 186 } 187 188 195 public XMLParser(SAXParser parser) { 196 this.parser = parser; 197 } 198 199 206 public XMLParser(XMLReader reader) { 207 this.reader = reader; 208 } 209 210 219 public Script parse(File file) throws IOException , SAXException { 220 return parse(file.toURL()); 221 } 222 223 232 public Script parse(URL url) throws IOException , SAXException { 233 ensureConfigured(); 234 this.fileName = url.toString(); 235 236 InputSource source = new InputSource (url.toString()); 237 238 getXMLReader().parse(source); 239 return script; 240 } 241 242 251 public Script parse(InputSource input) throws IOException , SAXException { 252 ensureConfigured(); 253 this.fileName = input.getSystemId(); 254 getXMLReader().parse(input); 255 return script; 256 } 257 258 272 public Script parse(InputStream input) throws IOException , SAXException { 273 ensureConfigured(); 274 this.fileName = getCurrentURI(); 275 getXMLReader().parse(new InputSource (input)); 276 return script; 277 } 278 279 293 public Script parse(Reader reader) throws IOException , SAXException { 294 ensureConfigured(); 295 this.fileName = getCurrentURI(); 296 getXMLReader().parse(new InputSource (reader)); 297 return script; 298 } 299 300 309 public Script parse(String uri) throws IOException , SAXException { 310 ensureConfigured(); 311 this.fileName = uri; 312 getXMLReader().parse(uri); 313 return script; 314 } 315 316 323 public String findNamespaceURI(String prefix) { 324 ArrayStack stack = (ArrayStack) namespaces.get(prefix); 325 if (stack == null) { 326 return (null); 327 } 328 try { 329 return ((String ) stack.peek()); 330 } 331 catch (EmptyStackException e) { 332 return (null); 333 } 334 } 335 336 public JellyContext getContext() { 339 return context; 340 } 341 342 public void setContext(JellyContext context) { 343 this.context = context; 344 } 345 346 353 public void setDefaultNamespaceURI(String namespace) { 354 this.defaultNamespaceURI = namespace; 355 } 356 357 367 public ClassLoader getClassLoader() { 368 return ClassLoaderUtils.getClassLoader(classLoader, useContextClassLoader, getClass()); 369 } 370 371 378 public void setClassLoader(ClassLoader classLoader) { 379 this.classLoader = classLoader; 380 } 381 382 385 public boolean getUseContextClassLoader() { 386 return useContextClassLoader; 387 } 388 389 398 public void setUseContextClassLoader(boolean use) { 399 useContextClassLoader = use; 400 } 401 402 405 public ErrorHandler getErrorHandler() { 406 return (this.errorHandler); 407 } 408 409 414 public void setErrorHandler(ErrorHandler errorHandler) { 415 this.errorHandler = errorHandler; 416 } 417 418 421 public Log getLogger() { 422 return log; 423 } 424 425 428 public void setLogger(Log log) { 429 this.log = log; 430 } 431 432 433 public ExpressionFactory getExpressionFactory() { 434 if (expressionFactory == null) { 435 expressionFactory = createExpressionFactory(); 436 } 437 return expressionFactory; 438 } 439 440 441 public void setExpressionFactory(ExpressionFactory expressionFactory) { 442 this.expressionFactory = expressionFactory; 443 } 444 445 449 public SAXParser getParser() { 450 if (parser != null) { 452 return (parser); 453 } 454 synchronized (this) { 456 try { 457 if (factory == null) { 458 factory = SAXParserFactory.newInstance(); 459 } 460 factory.setNamespaceAware(true); 461 factory.setValidating(validating); 462 parser = factory.newSAXParser(); 463 return (parser); 464 } 465 catch (Exception e) { 466 log.error("XMLParser.getParser: ", e); 467 return (null); 468 } 469 } 470 } 471 472 479 public XMLReader getReader() { 480 try { 481 return (getXMLReader()); 482 } 483 catch (SAXException e) { 484 log.error("Cannot get XMLReader", e); 485 return (null); 486 } 487 } 488 489 494 public synchronized XMLReader getXMLReader() throws SAXException { 495 if (reader == null) { 496 reader = getParser().getXMLReader(); 497 if (this.defaultNamespaceURI != null) { 498 reader = new DefaultNamespaceFilter(this.defaultNamespaceURI,reader); 499 } 500 } 501 reader.setContentHandler(this); 503 reader.setDTDHandler(this); 504 reader.setErrorHandler(this); 506 507 return reader; 508 } 509 510 513 public boolean getValidating() { 514 return (this.validating); 515 } 516 517 523 public void setValidating(boolean validating) { 524 this.validating = validating; 525 } 526 527 528 535 public ScriptBlock getScript() { 536 return script; 537 } 538 539 540 547 public void startDocument() throws SAXException { 548 script = new ScriptBlock(); 549 textBuffer = new StringBuffer (); 550 tagScript = null; 551 scriptStack.clear(); 552 tagScriptStack.clear(); 553 } 554 555 560 public void endDocument() throws SAXException { 561 textBuffer = null; 562 } 563 564 578 public void startElement( 579 String namespaceURI, 580 String localName, 581 String qName, 582 Attributes list) 583 throws SAXException { 584 585 try { 586 if ( namespaceURI == null ) { 588 namespaceURI = ""; 589 } 590 591 TagScript newTagScript = createTag(namespaceURI, localName, list); 594 if (newTagScript == null) { 595 newTagScript = createStaticTag(namespaceURI, localName, qName, list); 596 } 597 tagScript = newTagScript; 598 tagScriptStack.add(tagScript); 599 if (tagScript != null) { 600 if ( locator != null ) { 602 tagScript.setLocator(locator); 603 } 604 tagScript.setFileName(fileName); 606 tagScript.setElementName(qName); 607 tagScript.setLocalName(localName); 608 609 if (textBuffer.length() > 0) { 610 addTextScript(textBuffer.toString()); 611 textBuffer.setLength(0); 612 } 613 script.addScript(tagScript); 614 scriptStack.push(script); 616 script = new ScriptBlock(); 617 tagScript.setTagBody(script); 618 } 619 else { 620 textBuffer.append("<"); 622 textBuffer.append(qName); 623 int size = list.getLength(); 624 for (int i = 0; i < size; i++) { 625 textBuffer.append(" "); 626 textBuffer.append(list.getQName(i)); 627 textBuffer.append("="); 628 textBuffer.append("\""); 629 textBuffer.append(list.getValue(i)); 630 textBuffer.append("\""); 631 } 632 textBuffer.append(">"); 633 } 634 } 635 catch (SAXException e) { 636 throw e; 637 } 638 catch (Exception e) { 639 log.error( "Caught exception: " + e, e ); 640 throw new SAXException ( "Runtime Exception: " + e, e ); 641 } 642 } 643 644 654 public void characters(char buffer[], int start, int length) 655 throws SAXException { 656 textBuffer.append(buffer, start, length); 657 } 658 659 671 public void endElement(String namespaceURI, String localName, String qName) 672 throws SAXException { 673 try { 674 tagScript = (TagScript) tagScriptStack.remove(tagScriptStack.size() - 1); 675 if (tagScript != null) { 676 if (textBuffer.length() > 0) { 677 addTextScript(textBuffer.toString()); 678 textBuffer.setLength(0); 679 } 680 script = (ScriptBlock) scriptStack.pop(); 681 } 682 else { 683 textBuffer.append("</"); 684 textBuffer.append(qName); 685 textBuffer.append(">"); 686 } 687 688 if ( tagScriptStack.isEmpty() ) { 690 tagScript = null; 691 } 692 else { 693 tagScript = (TagScript) tagScriptStack.get(tagScriptStack.size() - 1); 694 } 695 } catch (Exception e) { 696 log.error( "Caught exception: " + e, e ); 697 throw new SAXException ( "Runtime Exception: " + e, e ); 698 } 699 } 700 701 709 public void startPrefixMapping(String prefix, String namespaceURI) 710 throws SAXException { 711 ArrayStack stack = (ArrayStack) namespaces.get(prefix); 713 if (stack == null) { 714 stack = new ArrayStack(); 715 namespaces.put(prefix, stack); 716 } 717 stack.push(namespaceURI); 718 719 if ( elementNamespaces == null ) { 720 elementNamespaces = new HashMap (); 721 } 722 elementNamespaces.put(prefix, namespaceURI); 723 } 724 725 732 public void endPrefixMapping(String prefix) throws SAXException { 733 ArrayStack stack = (ArrayStack) namespaces.get(prefix); 735 if (stack == null) { 736 return; 737 } 738 try { 739 stack.pop(); 740 if (stack.empty()) { 741 namespaces.remove(prefix); 742 } 743 } 744 catch (EmptyStackException e) { 745 throw createSAXException("endPrefixMapping popped too many times"); 746 } 747 } 748 749 759 public void ignorableWhitespace(char buffer[], int start, int len) 760 throws SAXException { 761 ; } 763 764 772 public void processingInstruction(String target, String data) 773 throws SAXException { 774 ; } 776 777 782 public void setDocumentLocator(Locator locator) { 783 this.locator = locator; 784 } 785 786 793 public void skippedEntity(String name) throws SAXException { 794 ; } 796 797 798 801 808 public void notationDecl(String name, String publicId, String systemId) { 809 } 810 811 819 public void unparsedEntityDecl( 820 String name, 821 String publicId, 822 String systemId, 823 String notation) { 824 } 825 826 827 830 838 public void error(SAXParseException exception) throws SAXException { 839 log.error( 840 "Parse Error at line " 841 + exception.getLineNumber() 842 + " column " 843 + exception.getColumnNumber() 844 + ": " 845 + exception.getMessage(), 846 exception); 847 if (errorHandler != null) { 848 errorHandler.error(exception); 849 } else { 850 throw exception; 851 } 852 } 853 854 862 public void fatalError( |