blob: 666f7ae4a57b39850b17c954a1c1ad5d0b07f37e [file] [log] [blame]
/*
* $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//jelly/src/java/org/apache/commons/jelly/Jelly.java,v 1.24 2002/10/30 19:16:26 jstrachan Exp $
* $Revision: 1.24 $
* $Date: 2002/10/30 19:16:26 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* $Id: Jelly.java,v 1.24 2002/10/30 19:16:26 jstrachan Exp $
*/
package org.apache.commons.jelly;
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Properties;
import org.apache.commons.jelly.parser.XMLParser;
import org.apache.commons.jelly.util.CommandLineParser;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* <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> Command line usage is as follows:
*
* <pre>
* jelly [scriptFile] [-script scriptFile -o outputFile -Dsysprop=syspropval]
* </pre>
*
* @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
* @version $Revision: 1.24 $
*/
public class Jelly {
/** The Log to which logging calls will be made. */
private static final Log log = LogFactory.getLog(Jelly.class);
/** The JellyContext to use */
private JellyContext context;
/** The URL of the script to execute */
private URL url;
/** The URL of the root context for other scripts */
private URL rootContext;
/** Whether we have loaded the properties yet */
private boolean loadedProperties = false;
/**
* whether to override the default namespace
*/
private String defaultNamespaceURI = null;
/**
* whether or not to validate the Jelly script
*/
private boolean validateXML = false;
public Jelly() {
}
/**
* Usage: jelly [scriptFile] [-script scriptFile -o outputFile -Dsysprop=syspropval]
*/
public static void main(String[] args) throws Exception {
try {
if (args.length <= 0) {
System.out.println("Usage: jelly [scriptFile] [-script scriptFile -o outputFile -Dsysprop=syspropval]");
return;
}
// parse the command line options using CLI
// using a separate class to avoid unnecessary
// dependencies
CommandLineParser.getInstance().invokeCommandLineJelly(args);
}
catch (JellyException e) {
Throwable cause = e.getCause();
if (cause != null) {
cause.printStackTrace();
}
else {
e.printStackTrace();
}
}
}
/**
* Compiles the script
*/
public Script compileScript() throws Exception {
if (! loadedProperties) {
loadedProperties = true;
loadJellyProperties();
}
XMLParser parser = new XMLParser();
parser.setContext(getJellyContext());
parser.setDefaultNamespaceURI(this.defaultNamespaceURI);
parser.setValidating(this.validateXML);
Script script = parser.parse(getUrl());
script = script.compile();
if (log.isDebugEnabled()) {
log.debug("Compiled script: " + getUrl());
}
return script;
}
// 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;
}
/**
* Gets the root context
*/
public URL getRootContext() throws MalformedURLException {
if (rootContext == null) {
rootContext = new File(System.getProperty("user.dir")).toURL();
}
return rootContext;
}
/**
* Sets the root context
*/
public void setRootContext(URL rootContext) {
this.rootContext = rootContext;
}
/**
* The context to use
*/
public JellyContext getJellyContext() throws MalformedURLException {
if (context == null) {
// take off the name off the URL
String text = getUrl().toString();
int idx = text.lastIndexOf('/');
text = text.substring(0, idx + 1);
context = new JellyContext(getRootContext(), new URL(text));
}
return context;
}
/**
* Set the jelly namespace to use for unprefixed elements.
* Will be overridden by an explicit namespace in the
* XML document.
*
* @param namespace jelly namespace to use (e.g. 'jelly:core')
*/
public void setDefaultNamespaceURI(String namespace) {
this.defaultNamespaceURI = namespace;
}
/**
* When set to true, the XML parser will attempt to validate
* the Jelly XML before converting it into a Script.
*
* @param validate whether or not to validate
*/
public void setValidateXML(boolean validate) {
this.validateXML = validate;
}
// Implementation methods
//-------------------------------------------------------------------------
/**
* @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);
}
/**
* Attempts to load jelly.properties from the current directory,
* the users home directory or from the classpath
*/
protected void loadJellyProperties() {
InputStream is = null;
String userDir = System.getProperty("user.home");
File f = new File(userDir + File.separator + "jelly.properties");
try {
if (f.exists()) {
is = new FileInputStream(f);
loadProperties(is);
}
}
catch (Exception e) {
log.error( "Caught exception while loading: " + f.getName() + ". Reason: " + e, e );
}
f = new File("jelly.properties");
try {
if (f.exists()) {
is = new FileInputStream(f);
loadProperties(is);
}
}
catch (Exception e) {
log.error( "Caught exception while loading: " + f.getName() + ". Reason: " + e, e );
}
is = getClass().getClassLoader().getResourceAsStream("jelly.properties");
if (is != null) {
try {
loadProperties(is);
}
catch (Exception e) {
log.error( "Caught exception while loading jelly.properties from the classpath. Reason: " + e, e );
}
}
}
/**
* Loads the properties from the given input stream
*/
protected void loadProperties(InputStream is) throws Exception {
JellyContext context = getJellyContext();
Properties props = new Properties();
props.load(is);
Enumeration enum = props.propertyNames();
while (enum.hasMoreElements()) {
String key = (String) enum.nextElement();
String value = props.getProperty(key);
// @todo we should parse the value in case its an Expression
context.setVariable(key, value);
}
}
}