jstrachan    02/04/26 04:28:55

  Modified:    jelly/src/java/org/apache/commons/jelly Context.java
                        Jelly.java
               jelly/src/java/org/apache/commons/jelly/tags/define
                        DynamicTag.java InvokeBodyTag.java
  Log:
  Added support in the Context for getResource() to allow loading of resources via 
explicit URL or relative URI as well as a compile and run methods to invoke other 
jelly scripts from inside jelly. This needs testing but the code is just about there I 
think. Also fixed the invokeBody tag so that it works fine now - though it uses a 
private variable 'jelly.body' which is not ideal but works fine.
  
  Revision  Changes    Path
  1.9       +130 -9    
jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/Context.java
  
  Index: Context.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/Context.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- Context.java      25 Apr 2002 18:58:47 -0000      1.8
  +++ Context.java      26 Apr 2002 11:28:55 -0000      1.9
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/Context.java,v
 1.8 2002/04/25 18:58:47 jstrachan Exp $
  - * $Revision: 1.8 $
  - * $Date: 2002/04/25 18:58:47 $
  + * $Header: 
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/Context.java,v
 1.9 2002/04/26 11:28:55 jstrachan Exp $
  + * $Revision: 1.9 $
  + * $Date: 2002/04/26 11:28:55 $
    *
    * ====================================================================
    *
  @@ -57,14 +57,20 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    * 
  - * $Id: Context.java,v 1.8 2002/04/25 18:58:47 jstrachan Exp $
  + * $Id: Context.java,v 1.9 2002/04/26 11:28:55 jstrachan Exp $
    */
   package org.apache.commons.jelly;
   
  +import java.io.File;
  +import java.io.InputStream;
  +import java.net.MalformedURLException;
  +import java.net.URL;
   import java.util.Hashtable;
   import java.util.Iterator;
   import java.util.Map;
   
  +import org.apache.commons.jelly.parser.XMLParser;
  +
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
   
  @@ -72,10 +78,16 @@
   /** <p><code>Context</code> represents the Jelly context.</p>
     *
     * @author <a href="mailto:[EMAIL PROTECTED]";>James Strachan</a>
  -  * @version $Revision: 1.8 $
  +  * @version $Revision: 1.9 $
     */
   public class Context {
   
  +    /** The root URL context (where scripts are located from) */
  +    private URL rootContext;
  +    
  +    /** The current URL context (where relative scripts are located from) */
  +    private URL currentContext;
  +    
       /** Tag libraries found so far */
       private Map taglibs = new Hashtable();
       
  @@ -86,12 +98,30 @@
       private Log log = LogFactory.getLog( Context.class );
   
       public Context() {
  +        this.currentContext = rootContext;
       }
       
  -    public Context(Map variables) {
  -        this.variables.putAll( variables );
  +    public Context(URL rootContext) {
  +        this.rootContext = rootContext;
  +        this.currentContext = rootContext;
       }
       
  +    public Context(URL rootContext, URL currentContext) {
  +        this.rootContext = rootContext;
  +        this.currentContext = currentContext;
  +    }
  +    
  +    public Context(Context parentContext) {
  +        this.rootContext = parentContext.rootContext;
  +        this.currentContext = parentContext.currentContext;
  +        this.taglibs = parentContext.taglibs;
  +    }
  +    
  +    public Context(Context parentContext, URL currentContext) {
  +        this( parentContext );
  +        this.currentContext = currentContext;
  +    }
  +        
       /** @return the value of the given variable name */
       public Object getVariable( String name ) {
           return variables.get( name );
  @@ -145,8 +175,8 @@
           // XXXX: Or at least publish the parent scope
           // XXXX: as a Map in this new variable scope?
           newVariables.put( "parentScope", variables );
  -        Context answer = new Context( newVariables );
  -        answer.taglibs = this.taglibs;
  +        Context answer = new Context( this );
  +        answer.setVariables( newVariables );
           return answer;
       }
       
  @@ -191,5 +221,96 @@
        */
       public TagLibrary getTagLibrary(String namespaceURI) {
           return (TagLibrary) taglibs.get( namespaceURI );
  +    }
  +
  +
  +    /** 
  +     * Attempts to parse the script from the given uri using the 
  +     * {#link getResource()} method then returns the compiled script.
  +     */
  +    public Script compileScript(String uri) throws Exception {
  +        XMLParser parser = new XMLParser();
  +        parser.setContext( this );
  +        
  +        Script script = parser.parse( getResourceAsStream( uri ) );
  +        return script.compile();
  +    }
  +
  +    /** 
  +     * Attempts to parse the script from the given uri using the 
  +     * Context.getResource() API then compiles it and runs it.
  +     */
  +    public void runScript(String uri, XMLOutput output) throws Exception {
  +        Script script = compileScript( uri );
  +        script.run( this, output );
  +    }
  +
  +    /**
  +     * Returns a URL for the given resource from the specified path.
  +     * If the uri starts with "/" then the path is taken as relative to 
  +     * the current context root. If the uri is a well formed URL then it
  +     * is used. Otherwise the uri is interpreted as relative to the current
  +     * context (the location of the current script).
  +     */
  +    public URL getResource(String uri) throws MalformedURLException {
  +        if ( uri.startsWith( "/" ) ) {
  +            // append this uri to the context root
  +            return createRelativeURL( rootContext, uri.substring(1) );
  +        }
  +        else {
  +            try {
  +                return new URL( uri );
  +            }
  +            catch (MalformedURLException e) {
  +                // lets try find a relative resource
  +                try {
  +                    return createRelativeURL( currentContext, uri );
  +                }
  +                catch (MalformedURLException e2) {
  +                    throw e;
  +                }
  +            }
  +        }
  +    }
  +    
  +    /**
  +     * Attempts to open an InputStream to the given resource at the specified path.
  +     * If the uri starts with "/" then the path is taken as relative to 
  +     * the current context root. If the uri is a well formed URL then it
  +     * is used. Otherwise the uri is interpreted as relative to the current
  +     * context (the location of the current script).
  +     *
  +     * @return null if this resource could not be loaded, otherwise the resources 
  +     *  input stream is returned.
  +     */
  +    public InputStream getResourceAsStream(String uri) {
  +        try {
  +            URL url = getResource( uri );
  +            return url.openStream();
  +        }
  +        catch (Exception e) {
  +            if ( log.isTraceEnabled() ) {
  +                log.trace( "Caught exception attempting to open: " + uri + ". 
Exception: " + e, e );
  +            }
  +            return null;
  +        }
  +    }
  +    
  +    // Implementation methods
  +    //-------------------------------------------------------------------------     
           
  +    
  +    /**
  +     * @return a new relative URL from the given root and with the addition of the
  +     * extra relative URI
  +     *
  +     * @param rootURL is the root context from which the relative URI will be 
applied
  +     * @param relativeURI is the relative URI (without a leading "/")
  +     * @throws MalformedURLException if the URL is invalid.
  +     */
  +    protected URL createRelativeURL(URL rootURL, String relativeURI) throws 
MalformedURLException {
  +        if ( rootURL == null ) {
  +            return new URL( "file://" + relativeURI );
  +        }
  +        return new URL( rootURL.toString() + relativeURI );
       }
   }
  
  
  
  1.6       +95 -23    
jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/Jelly.java
  
  Index: Jelly.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/Jelly.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- Jelly.java        25 Apr 2002 18:58:47 -0000      1.5
  +++ Jelly.java        26 Apr 2002 11:28:55 -0000      1.6
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/Jelly.java,v 
1.5 2002/04/25 18:58:47 jstrachan Exp $
  - * $Revision: 1.5 $
  - * $Date: 2002/04/25 18:58:47 $
  + * $Header: 
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/Jelly.java,v 
1.6 2002/04/26 11:28:55 jstrachan Exp $
  + * $Revision: 1.6 $
  + * $Date: 2002/04/26 11:28:55 $
    *
    * ====================================================================
    *
  @@ -57,37 +57,56 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    * 
  - * $Id: Jelly.java,v 1.5 2002/04/25 18:58:47 jstrachan Exp $
  + * $Id: Jelly.java,v 1.6 2002/04/26 11:28:55 jstrachan Exp $
    */
   package org.apache.commons.jelly;
   
   import java.io.BufferedWriter;
  +import java.io.File;
   import java.io.FileWriter;
  +import java.io.InputStream;
   import java.io.OutputStreamWriter;
   import java.io.Writer;
  +import java.net.MalformedURLException;
  +import java.net.URL;
   
   import org.apache.commons.jelly.parser.XMLParser;
   
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
   
  -/** <p><code>Jelly</code> an application which runs a Jelly script.</p>
  -  *
  -  * @author <a href="mailto:[EMAIL PROTECTED]";>James Strachan</a>
  -  * @version $Revision: 1.5 $
  -  */
  +/** 
  + * <p><code>Jelly</code> is a helper class which is capable of
  + * running a Jelly script. This class can be used from the command line
  + * or can be used as the basis of an Ant task.</p>
  + *
  + * @author <a href="mailto:[EMAIL PROTECTED]";>James Strachan</a>
  + * @version $Revision: 1.6 $
  + */
   public class Jelly {
   
       /** The Log to which logging calls will be made. */
       private static final Log log = LogFactory.getLog( Jelly.class );
   
  -
  +    /** The Context to use */
  +    private Context context;
  +    
  +    /** The URL of the script to execute */
  +    private URL url;
  +    
  +    public Jelly() {
  +    }
  +    
  +    
       public static void main(String[] args) throws Exception {
           if ( args.length <= 0 ) {
               System.out.println( "Usage: Jelly scriptFile [outputFile]" );
               return;
           }
  -        String input = args[0];
  +        
  +        Jelly jelly = new Jelly();
  +        jelly.setScript( args[0] );
  +        
           
   /*
           // later we might wanna add some command line arguments 
  @@ -103,25 +122,78 @@
               new OutputStreamWriter( System.out )
           );
           
  +        Script script = jelly.compileScript();                
  +        XMLOutput output = XMLOutput.createXMLOutput( writer );
  +        
           // add the system properties and the command line arguments
  -        //Context context = new Context( System.getProperties() );
  -        Context context = new Context();
  +        Context context = jelly.getContext();        
           context.setVariable( "args", args );
  +
  +        script.run( context, output );
           
  +        writer.close();
  +    }    
  +
  +    /**
  +     * Compiles the script
  +     */
  +    public Script compileScript() throws Exception {
           XMLParser parser = new XMLParser();
  -        parser.setContext( context );
  -        Script script = parser.parse( input );
  -    
  +        parser.setContext( getContext() );
  +        Script script = parser.parse( getUrl().openStream() );
           script = script.compile();
           
           if ( log.isDebugEnabled() ) {
  -            log.debug( "Compiled script: " + script );
  +            log.debug( "Compiled script: " + getUrl() );
           }
  +        return script;
  +    }
  +    
           
  -        XMLOutput output = XMLOutput.createXMLOutput( writer );
  -        
  -        script.run( context, output );
  -        
  -        writer.close();
  -    }    
  +    // Properties
  +    //-------------------------------------------------------------------------     
           
  +    
  +    /** 
  +     * Sets the script URL to use as an absolute URL or a relative filename
  +     */
  +    public void setScript(String script) throws MalformedURLException {
  +        setUrl( resolveURL( script ) );
  +    }
  +    
  +    public URL getUrl() {
  +        return url;
  +    }
  +
  +    /** 
  +     * Sets the script URL to use 
  +     */
  +    public void setUrl(URL url) {
  +        this.url = url;
  +    }
  +    
  +    
  +    /**
  +     * The context to use
  +     */
  +    public Context getContext() {
  +        if ( context == null ) {
  +            context = new Context( getUrl() );
  +        }
  +        return context;
  +    }
  +    
  +    // Properties
  +    //-------------------------------------------------------------------------     
           
  +    
  +    /**
  +     * @return the URL for the relative file name or absolute URL 
  +     */
  +    protected URL resolveURL(String name) throws MalformedURLException {
  +        File file = new File(name);
  +        if ( file.exists() ) {
  +            return file.toURL();
  +        }
  +        return new URL( name );
  +    }
  +    
   }
  
  
  
  1.3       +7 -5      
jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/define/DynamicTag.java
  
  Index: DynamicTag.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/define/DynamicTag.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DynamicTag.java   25 Apr 2002 18:58:47 -0000      1.2
  +++ DynamicTag.java   26 Apr 2002 11:28:55 -0000      1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/define/DynamicTag.java,v
 1.2 2002/04/25 18:58:47 jstrachan Exp $
  - * $Revision: 1.2 $
  - * $Date: 2002/04/25 18:58:47 $
  + * $Header: 
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/define/DynamicTag.java,v
 1.3 2002/04/26 11:28:55 jstrachan Exp $
  + * $Revision: 1.3 $
  + * $Date: 2002/04/26 11:28:55 $
    *
    * ====================================================================
    *
  @@ -57,7 +57,7 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    * 
  - * $Id: DynamicTag.java,v 1.2 2002/04/25 18:58:47 jstrachan Exp $
  + * $Id: DynamicTag.java,v 1.3 2002/04/26 11:28:55 jstrachan Exp $
    */
   package org.apache.commons.jelly.tags.define;
   
  @@ -81,7 +81,7 @@
    * as variables and will allow the template to invoke its instance body.</p>
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>James Strachan</a>
  - * @version $Revision: 1.2 $
  + * @version $Revision: 1.3 $
    */
   public class DynamicTag extends TagSupport implements DynaTag {
   
  @@ -106,6 +106,8 @@
       public void run(Context context, XMLOutput output) throws Exception {
   
           log.info( "Invoking dynamic tag with attributes: " + attributes );
  +
  +        attributes.put( "jelly.body", getBody() );
           
           // create new context based on current attributes
           Context newContext = context.newContext( attributes );
  
  
  
  1.3       +20 -13    
jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/define/InvokeBodyTag.java
  
  Index: InvokeBodyTag.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/define/InvokeBodyTag.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- InvokeBodyTag.java        25 Apr 2002 18:58:47 -0000      1.2
  +++ InvokeBodyTag.java        26 Apr 2002 11:28:55 -0000      1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/define/InvokeBodyTag.java,v
 1.2 2002/04/25 18:58:47 jstrachan Exp $
  - * $Revision: 1.2 $
  - * $Date: 2002/04/25 18:58:47 $
  + * $Header: 
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/define/InvokeBodyTag.java,v
 1.3 2002/04/26 11:28:55 jstrachan Exp $
  + * $Revision: 1.3 $
  + * $Date: 2002/04/26 11:28:55 $
    *
    * ====================================================================
    *
  @@ -57,12 +57,13 @@
    * information on the Apache Software Foundation, please see
    * <http://www.apache.org/>.
    * 
  - * $Id: InvokeBodyTag.java,v 1.2 2002/04/25 18:58:47 jstrachan Exp $
  + * $Id: InvokeBodyTag.java,v 1.3 2002/04/26 11:28:55 jstrachan Exp $
    */
   package org.apache.commons.jelly.tags.define;
   
   import org.apache.commons.jelly.Context;
   import org.apache.commons.jelly.JellyException;
  +import org.apache.commons.jelly.Script;
   import org.apache.commons.jelly.Tag;
   import org.apache.commons.jelly.TagSupport;
   import org.apache.commons.jelly.XMLOutput;
  @@ -77,7 +78,7 @@
    * body.</p>
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>James Strachan</a>
  - * @version $Revision: 1.2 $
  + * @version $Revision: 1.3 $
    */
   public class InvokeBodyTag extends TagSupport {
   
  @@ -91,16 +92,22 @@
       // Tag interface
       //-------------------------------------------------------------------------     
               
       public void run(Context context, XMLOutput output) throws Exception {
  -        
  -        // #### note this mechanism does not work properly for arbitrarily 
  -        // #### nested dynamic tags. A better way is required.
  -        Tag tag = findAncestorWithClass(this, DynamicTag.class);
  -        if ( tag == null ) {
  -            // throw new JellyException( "Cannot invoke body, no dynamic tag is 
defined in this block" );
  -            log.warn( "Cannot invoke body, no dynamic tag is defined in this block" 
);
  +
  +        // Try find find the body from the reserved 'jelly.body' variable
  +        Script script = (Script) context.getVariable( "jelly.body" );
  +        if ( script != null ) {
  +            script.run( context, output );
           }
           else {
  -            tag.getBody().run(context, output);
  +            // note this mechanism does not work properly for arbitrarily 
  +            // nested dynamic tags. A better way is required.
  +            Tag tag = findAncestorWithClass(this, DynamicTag.class);
  +            if ( tag == null ) {
  +                throw new JellyException( "Cannot invoke body, no dynamic tag is 
defined in this block" );
  +            }
  +            else {
  +                tag.getBody().run(context, output);
  +            }
           }
       }    
   }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to