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]>