1 16 package org.apache.commons.jelly; 17 18 import java.io.File ; 19 import java.io.IOException ; 20 import java.io.InputStream ; 21 import java.net.MalformedURLException ; 22 import java.net.URL ; 23 import java.util.Hashtable ; 24 import java.util.Iterator ; 25 import java.util.Map ; 26 import java.util.HashMap ; 27 28 import org.apache.commons.jelly.parser.XMLParser; 29 import org.apache.commons.jelly.util.ClassLoaderUtils; 30 import org.apache.commons.logging.Log; 31 import org.apache.commons.logging.LogFactory; 32 33 import org.xml.sax.InputSource ; 34 import org.xml.sax.SAXException ; 35 36 42 public class JellyContext { 43 44 45 private static final Log log = LogFactory.getLog(JellyContext.class); 46 47 48 private static final boolean DEFAULT_INHERIT = true; 49 50 51 private static final boolean DEFAULT_EXPORT = false; 52 53 54 private static final String BAD_PARSE = "Could not parse Jelly script"; 55 56 62 protected ClassLoader classLoader; 63 64 68 protected boolean useContextClassLoader = false; 69 70 71 private URL rootURL; 72 73 74 private URL currentURL; 75 76 77 private Map taglibs = new Hashtable (); 78 79 80 private Map variables = new HashMap (); 81 82 83 private JellyContext parent; 84 85 86 private boolean inherit = JellyContext.DEFAULT_INHERIT; 87 88 89 private boolean export = JellyContext.DEFAULT_EXPORT; 90 91 92 private boolean exportLibraries = true; 93 94 95 private boolean cacheTags = false; 96 97 100 public JellyContext() { 101 this.currentURL = rootURL; 102 init(); 103 } 104 105 109 public JellyContext(URL rootURL) { 110 this( rootURL, rootURL ); 111 } 112 113 118 public JellyContext(URL rootURL, URL currentURL) { 119 this.rootURL = rootURL; 120 this.currentURL = currentURL; 121 init(); 122 } 123 124 125 132 public JellyContext(JellyContext parent) { 133 this.parent = parent; 134 this.rootURL = parent.rootURL; 135 this.currentURL = parent.currentURL; 136 this.variables.put("parentScope", parent.variables); 137 this.cacheTags = parent.cacheTags; 138 init(); 139 } 140 141 149 public JellyContext(JellyContext parentJellyContext, URL currentURL) { 150 this(parentJellyContext); 151 this.currentURL = currentURL; 152 } 153 154 162 public JellyContext(JellyContext parentJellyContext, URL rootURL, URL currentURL) { 163 this(parentJellyContext, currentURL); 164 this.rootURL = rootURL; 165 } 166 167 172 private void init() { 173 variables.put("context",this); 174 try { 175 variables.put("systemScope", System.getProperties() ); 176 } catch (SecurityException e) { 177 log.debug("security exception accessing system properties", e); 178 } 179 } 180 181 184 public JellyContext getParent() { 185 return parent; 186 } 187 188 193 public JellyContext getScope(String name) { 194 if ( "parent".equals( name ) ) { 195 return getParent(); 196 } 197 return null; 198 } 199 200 208 public Object findVariable(String name) { 209 Object answer = variables.get(name); 210 boolean definedHere = answer != null || variables.containsKey(name); 211 212 if (definedHere) return answer; 213 214 if ( answer == null && parent != null ) { 215 answer = parent.findVariable(name); 216 } 217 if ( answer == null ) { 219 answer = getSystemProperty(name); 220 } 221 222 if (log.isDebugEnabled()) { 223 log.debug("findVariable: " + name + " value: " + answer ); 224 } 225 return answer; 226 } 227 228 229 230 public Object getVariable(String name) { 231 Object value = variables.get(name); 232 boolean definedHere = value != null || variables.containsKey(name); 233 234 if (definedHere) return value; 235 236 if ( value == null && isInherit() ) { 237 JellyContext parentContext = getParent(); 238 if (parentContext != null) { 239 value = parentContext.getVariable( name ); 240 } 241 } 242 243 if ( value == null ) { 245 value = getSystemProperty(name); 246 } 247 248 return value; 249 } 250 251 256 private Object getSystemProperty(String name) { 257 try { 258 return System.getProperty(name); 259 } 260 catch (SecurityException e) { 261 log.debug("security exception accessing system properties", e); 262 } 263 return null; 264 } 265 266 272 public Object getVariable(String name, String scopeName) { 273 JellyContext scope = getScope(scopeName); 274 if ( scope != null ) { 275 return scope.getVariable(name); 276 } 277 return null; 278 } 279 280 281 282 283 public void setVariable(String name, Object value) { 284 if ( isExport() ) { 285 getParent().setVariable( name, value ); 286 return; 287 } 288 variables.put(name, value); 289 } 290 291 298 public void setVariable(String name, String scopeName, Object value) { 299 JellyContext scope = getScope(scopeName); 300 if ( scope != null ) { 301 scope.setVariable(name, value); 302 } 303 } 304 305 306 public void removeVariable(String name) { 307 variables.remove(name); 308 } 309 310 317 public void removeVariable(String name, String scopeName) { 318 JellyContext scope = getScope(scopeName); 319 if ( scope != null ) { 320 scope.removeVariable(name); 321 } 322 } 323 324 328 public Iterator getVariableNames() { 329 return variables.keySet().iterator(); 330 } 331 332 335 public Map getVariables() { 336 return variables; 337 } 338 339 342 public void setVariables(Map variables) { 343 for (Iterator iter = variables.entrySet().iterator(); iter.hasNext();) { 346 Map.Entry element = (Map.Entry ) iter.next(); 347 if (element.getValue() != null) { 348 this.variables.put(element.getKey(), element.getValue()); 349 } 350 } 351 } 353 354 358 public JellyContext newJellyContext(Map newVariables) { 359 newVariables.put("parentScope", variables); 364 JellyContext answer = createChildContext(); 365 answer.setVariables(newVariables); 366 return answer; 367 } 368 369 373 public JellyContext newJellyContext() { 374 return createChildContext(); 375 } 376 377 380 public void clear() { 381 clearVariables(); 382 } 383 384 387 protected void clearVariables() { 388 variables.clear(); 389 } 390 391 394 public void registerTagLibrary(String namespaceURI, TagLibrary taglib) { 395 if (log.isDebugEnabled()) { 396 log.debug("Registering tag library to: " + namespaceURI + " taglib: " + taglib); 397 } 398 taglibs.put(namespaceURI, taglib); 399 400 if (isExportLibraries() && parent != null) { 401 parent.registerTagLibrary( namespaceURI, taglib ); 402 } 403 } 404 405 409 public void registerTagLibrary( 410 String namespaceURI, 411 String className) { 412 413 if (log.isDebugEnabled()) { 414 log.debug("Registering tag library to: " + namespaceURI + " taglib: " + className); 415 } 416 taglibs.put(namespaceURI, className); 417 418 if (isExportLibraries() && parent != null) { 419 parent.registerTagLibrary( namespaceURI, className ); 420 } 421 } 422 423 public boolean isTagLibraryRegistered(String namespaceURI) { 424 boolean answer = taglibs.containsKey( namespaceURI ); 425 if (answer) { 426 return true; 427 } 428 else if ( parent != null ) { 429 return parent.isTagLibraryRegistered(namespaceURI); 430 } 431 else { 432 return false; 433 } 434 } 435 436 439 public TagLibrary getTagLibrary(String namespaceURI) { 440 441 444 Object answer = taglibs.get(namespaceURI); 445 446 if ( answer == null && parent != null ) { 447 answer = parent.getTagLibrary( namespaceURI ); 448 } 449 450 if ( answer instanceof TagLibrary ) { 451 return (TagLibrary) answer; 452 } 453 else if ( answer instanceof String ) { 454 String className = (String ) answer; 455 Class theClass = null; 456 try { 457 theClass = getClassLoader().loadClass(className); 458 } 459 catch (ClassNotFoundException e) { 460 log.error("Could not find the class: " + className, e); 461 } 462 if ( theClass != null ) { 463 try { 464 Object object = theClass.newInstance(); 465 if (object instanceof TagLibrary) { 466 taglibs.put(namespaceURI, object); 467 return (TagLibrary) object; 468 } 469 else { 470 log.error( 471 "The tag library object mapped to: " 472 + namespaceURI 473 + " is not a TagLibrary. Object = " 474 + object); 475 } 476 } 477 catch (Exception e) { 478 log.error( 479 "Could not instantiate instance of class: " + className + ". Reason: " + e, 480 e); 481 } 482 } 483 } 484 485 return null; 486 } 487 488 492 public Script compileScript(String uri) throws JellyException { 493 XMLParser parser = getXMLParser(); 494 parser.setContext(this); 495 InputStream in = getResourceAsStream(uri); 496 if (in == null) { 497 throw new JellyException("Could not find Jelly script: " + uri); 498 } 499 Script script = null; 500 try { 501 script = parser.parse(in); 502 } catch (IOException e) { 503 throw new JellyException(JellyContext.BAD_PARSE, e); 504 } catch (SAXException e) { 505 throw new JellyException(JellyContext.BAD_PARSE, e); 506 } 507 508 return script.compile(); 509 } 510 511 515 public Script compileScript(URL url) throws JellyException { 516 XMLParser parser = getXMLParser(); 517 parser.setContext(this); 518 519 Script script = null; 520 try { 521 script = parser.parse(url.toString()); 522 } catch (IOException e) { 523 throw new JellyException(JellyContext.BAD_PARSE, e); 524 } catch (SAXException e) { 525 throw new JellyException(JellyContext.BAD_PARSE, e); 526 } 527 528 return script.compile(); 529 } 530 531 535 public Script compileScript(InputSource source) throws JellyException { 536 XMLParser parser = getXMLParser(); 537 parser.setContext(this); 538 539 Script script = null; 540 try { 541 script = parser.parse(source); 542 } catch (IOException e) { 543 throw new JellyException(JellyContext.BAD_PARSE, e); 544 } catch (SAXException e) { 545 throw new JellyException(JellyContext.BAD_PARSE, e); 546 } 547 548 return script.compile(); 549 } 550 551 555 protected XMLParser getXMLParser() { 556 XMLParser parser = createXMLParser(); 557 return parser; 558 } 559 560 564 protected XMLParser createXMLParser() { 565 return new XMLParser(); 566 } 567 568 573 public JellyContext runScript(File file, XMLOutput output) throws JellyException { 574 try { 575 return runScript(file.toURL(), output, JellyContext.DEFAULT_EXPORT, 576 JellyContext.DEFAULT_INHERIT); 577 } catch (MalformedURLException e) { 578 throw new JellyException(e.toString()); 579 } 580 } 581 582 587 public JellyContext runScript(URL url, XMLOutput output) throws JellyException { 588 return runScript(url, output, JellyContext.DEFAULT_EXPORT, 589 JellyContext.DEFAULT_INHERIT); 590 } 591 592 597 public JellyContext runScript(InputSource source, XMLOutput output) throws JellyException { 598 return runScript(source, output, JellyContext.DEFAULT_EXPORT, 599 JellyContext.DEFAULT_INHERIT); 600 } 601 602 608 public JellyContext runScript(String uri, XMLOutput output) throws JellyException { 609 URL url = null; 610 try { 611 url = getResource(uri); 612 } catch (MalformedURLException e) { 613 throw new JellyException(e.toString()); 614 } 615 616 if (url == null) { 617 throw new JellyException("Could not find Jelly script: " + url); 618 } 619 return runScript(url, output, JellyContext.DEFAULT_EXPORT, 620 JellyContext.DEFAULT_INHERIT); 621 } 622 623 629 public JellyContext runScript(String uri, XMLOutput output, 630 boolean export, boolean inherit) throws JellyException { 631 URL url = null; 632 try { 633 url = getResource(uri); 634 } catch (MalformedURLException e) { 635 throw new JellyException(e.toString()); 636 } 637 638 if (url == null) { 639 throw new JellyException("Could not find Jelly script: " + url); 640 } 641 642 return runScript(url, output, export, inherit); 643 } 644 645 650 public JellyContext runScript(File file, XMLOutput output, 651 boolean export, boolean inherit) throws JellyException { 652 try { 653 return runScript(file.toURL(), output, export, inherit); 654 } catch (MalformedURLException e) { 655 throw new JellyException(e.toString()); 656 } 657 } 658 659 664 public JellyContext runScript(URL url, XMLOutput output, 665 boolean export, boolean inherit) throws JellyException { 666 return runScript(new InputSource (url.toString()), output, export, inherit); 667 } 668 669 674 public JellyContext runScript(InputSource source, XMLOutput output, 675 boolean export, boolean inherit) throws JellyException { 676 Script script = compileScript(source); 677 678 URL newJellyContextURL = null; 679 try { 680 newJellyContextURL = getJellyContextURL(source); 681 } catch (MalformedURLException e) { 682 throw new JellyException(e.toString()); 683 } 684 685 JellyContext newJellyContext = newJellyContext(); 686 newJellyContext.setRootURL( newJellyContextURL ); 687 newJellyContext.setCurrentURL( newJellyContextURL ); 688 newJellyContext.setExport( export ); 689 newJellyContext.setInherit( inherit ); 690 691 if ( inherit ) { 692 newJellyContext.variables = this.variables; 694 } 695 696 if (log.isDebugEnabled() ) { 697 log.debug( "About to run script: " + source.getSystemId() ); 698 log.debug( "root context URL: " + newJellyContext.rootURL ); 699 log.debug( "current context URL: " + newJellyContext.currentURL ); 700 } 701 702 script.run(newJellyContext, output); 703 704 return newJellyContext; 705 } 706 707 716 public URL getResource(String uri) throws MalformedURLException { 717 if (uri.startsWith("/")) { 718 return createRelativeURL(rootURL, uri.substring(1)); 720 } 721 else { 722 try { 723 return new URL (uri); 724 } 725 catch (MalformedURLException e) { 726 try { 728 return createRelativeURL(currentURL, uri); 729 } catch (MalformedURLException e2) { 730 throw e; 731 } 732 } 733 } 734 } 735 736 746 public InputStream getResourceAsStream(String uri) { 747 try { 748 URL url = getResource(uri); 749 return url.openStream(); 750 } 751 catch (Exception e) { 752 if (log.isTraceEnabled()) { 753 log.trace( 754 "Caught exception attempting to open: " + uri + ". Exception: " + e, 755 e); 756 } 757 return null; 758 } 759 } 760 761 762 765 770 public URL getRootURL() { 771 return rootURL; 772 } 773 774 779 public void setRootURL(URL rootURL) { 780 this.rootURL = rootURL; 781 } 782 783 784 789 public URL getCurrentURL() { 790 return currentURL; 791 } 792 793 798 public void setCurrentURL(URL currentURL) { 799 this.currentURL = currentURL; 800 } 801 802 810 public boolean isCacheTags() { 811 return cacheTags; 812 } 813 814 822 public void setCacheTags(boolean cacheTags) { 823 this.cacheTags = cacheTags; 824 } 825 826 830 public boolean isExportLibraries() { 831 return exportLibraries; 832 } 833 834 838 public void setExportLibraries(boolean exportLibraries) { 839 this.exportLibraries = exportLibraries; 840 } 841 842 843 846 public void setExport(boolean export) { 847 this.export = export; 848 } 849 850 853 public boolean isExport() { 854 return this.export; 855 } 856 857 860 public void setInherit(boolean inherit) { 861 this.inherit = inherit; 862 } 863 864 867 public boolean isInherit() { 868 return this.inherit; 869 } 870 871 872 882 public ClassLoader getClassLoader() { 883 return ClassLoaderUtils.getClassLoader(classLoader, useContextClassLoader, getClass()); 884 } 885 886 893 public void setClassLoader(ClassLoader classLoader) { 894 this.classLoader = classLoader; 895 } 896 897 900 public boolean getUseContextClassLoader() { 901 return useContextClassLoader; 902 } 903 904 913 public void setUseContextClassLoader(boolean use) { 914 useContextClassLoader = use; 915 } 916 917 918 928 protected URL createRelativeURL(URL rootURL, String relativeURI) 929 throws MalformedURLException { 930 URL url = rootURL; 931 if (url == null) { 932 File file = new File (System.getProperty("user.dir")); 933 url = file.toURL(); 934 } 935 String urlText = url.toString() + relativeURI; 936 if ( log.isDebugEnabled() ) { 937 log.debug("Attempting to open url: " + urlText); 938 } 939 return new URL (urlText); 940 } 941 942 945 protected URL getJellyContextURL(URL url) throws MalformedURLException { 946 String text = url.toString(); 947 int idx = text.lastIndexOf('/'); 948 text = text.substring(0, idx + 1); 949 return new URL (text); 950 } 951 952 955 protected URL getJellyContextURL(InputSource source) throws MalformedURLException { 956 String text = source.getSystemId(); 957 if (text != null) { 958 int idx = text.lastIndexOf('/'); 959 text = text.substring(0, idx + 1); 960 return new URL (text); 961 } else { 962 return null; 963 } 964 965 } 966 967 970 protected JellyContext createChildContext() { 971 return new JellyContext(this); 972 } 973 974 978 protected void setParent(JellyContext context) 979 { 980 parent = context; 981 this.variables.put("parentScope", parent.variables); 982 if (isExportLibraries() && parent != null) { 984 for (Iterator keys = taglibs.keySet().iterator(); keys.hasNext();) 985 { 986 String namespaceURI = (String ) keys.next(); 987 Object tagLibOrClassName = taglibs.get(namespaceURI); 988 if (tagLibOrClassName instanceof TagLibrary) 989 { 990 parent.registerTagLibrary( namespaceURI, (TagLibrary) tagLibOrClassName ); 991 } 992 else 993 { 994 parent.registerTagLibrary( namespaceURI, (String ) tagLibOrClassName ); 995 } 996 } 997 } 998 999 } 1000 1001} 1002 | Popular Tags |