Coverage report

  %line %branch
org.apache.commons.jelly.Jelly
50% 
75% 

 1  
 /*
 2  
  * Copyright 2002,2004 The Apache Software Foundation.
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *      http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 
 17  
 package org.apache.commons.jelly;
 18  
 
 19  
 import java.io.File;
 20  
 import java.io.InputStream;
 21  
 import java.io.FileInputStream;
 22  
 import java.io.IOException;
 23  
 import java.net.MalformedURLException;
 24  
 import java.net.URL;
 25  
 import java.util.Enumeration;
 26  
 import java.util.Properties;
 27  
 
 28  
 import org.apache.commons.jelly.parser.XMLParser;
 29  
 import org.apache.commons.jelly.util.ClassLoaderUtils;
 30  
 import org.apache.commons.jelly.util.CommandLineParser;
 31  
 import org.apache.commons.logging.Log;
 32  
 import org.apache.commons.logging.LogFactory;
 33  
 
 34  
 import org.xml.sax.SAXException;
 35  
 
 36  
 /** 
 37  
  * <p><code>Jelly</code> is a helper class which is capable of
 38  
  * running a Jelly script. This class can be used from the command line
 39  
  * or can be used as the basis of an Ant task.</p> Command line usage is as follows:
 40  
  *
 41  
  * <pre>
 42  
  * jelly [scriptFile] [-script scriptFile -o outputFile -Dsysprop=syspropval]
 43  
  * </pre>
 44  
  *
 45  
  * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
 46  
  * @version $Revision: 155420 $
 47  
  */
 48  
 public class Jelly {
 49  
     
 50  
     /** The Log to which logging calls will be made. */
 51  520
     private static final Log log = LogFactory.getLog(Jelly.class);
 52  
     
 53  
     /** The JellyContext to use */
 54  
     private JellyContext context;
 55  
     
 56  
     /** The URL of the script to execute */
 57  
     private URL url;
 58  
     
 59  
     /** The URL of the root context for other scripts */
 60  
     private URL rootContext;
 61  
     
 62  
     /** Whether we have loaded the properties yet */
 63  1066
     private boolean loadedProperties = false;
 64  
 
 65  
     /**
 66  
      * whether to override the default namespace
 67  
      */
 68  1066
     private String defaultNamespaceURI = null;
 69  
 
 70  
     /**
 71  
      * whether or not to validate the Jelly script
 72  
      */
 73  1066
     private boolean validateXML = false;
 74  
         
 75  1066
     public Jelly() {
 76  1066
     }
 77  
 
 78  
     /**
 79  
      * Usage: jelly [scriptFile] [-script scriptFile -o outputFile -Dsysprop=syspropval]
 80  
      */
 81  
     public static void main(String[] args) throws Exception {
 82  
 
 83  
         try {
 84  0
             if (args.length <= 0) {
 85  0
                 System.out.println("Usage: jelly [scriptFile] [-script scriptFile -o outputFile -Dsysprop=syspropval]");
 86  0
                 return;
 87  
             }
 88  
 
 89  
             // parse the command line options using CLI
 90  
             // using a separate class to avoid unnecessary 
 91  
             // dependencies
 92  0
             CommandLineParser.getInstance().invokeCommandLineJelly(args);
 93  
         }
 94  0
         catch (JellyException e) {
 95  0
             Throwable cause = e.getCause();
 96  
 
 97  0
             if (cause == null) {
 98  0
                 e.printStackTrace();
 99  0
             } else {
 100  0
                 cause.printStackTrace();
 101  
             }
 102  0
         }
 103  0
     }
 104  
     
 105  
     
 106  
     public static String getJellyVersion() {
 107  0
         return readBuildTimestampResource("jelly-version.txt");
 108  
     }
 109  
     
 110  
     public static String getJellyBuildDate() {
 111  0
         return readBuildTimestampResource("jelly-build-date.txt");
 112  
     }
 113  
     
 114  
     private static String readBuildTimestampResource(String name) {
 115  0
         java.io.Reader in = null;
 116  
         try {
 117  0
             java.io.StringWriter w = new java.io.StringWriter();
 118  0
             in = new java.io.InputStreamReader(Jelly.class.getResourceAsStream(name),"utf-8");
 119  
             int r;
 120  0
             while ( (r=in.read()) >= 0 ) {
 121  0
                 w.write((char) r);
 122  0
             }
 123  0
             return w.toString();
 124  0
         } catch(Exception ex) {
 125  0
             ex.printStackTrace();
 126  0
             try { in.close(); } catch(Exception e) {}
 127  0
             throw new IllegalStateException("Resource \"" + name + "\" not found.");
 128  
         }
 129  
     }
 130  
     
 131  
     
 132  
 
 133  
     /**
 134  
      * Compiles the script
 135  
      */
 136  
     public Script compileScript() throws JellyException {
 137  845
         if (! loadedProperties) {
 138  819
             loadedProperties = true;
 139  819
             loadJellyProperties();
 140  
         }
 141  
         
 142  845
         XMLParser parser = new XMLParser();
 143  
         try {
 144  845
             parser.setContext(getJellyContext());
 145  0
         } catch (MalformedURLException e) {
 146  0
             throw new JellyException(e.toString());
 147  845
         }
 148  
         
 149  845
         Script script = null;
 150  
         try {
 151  845
             parser.setDefaultNamespaceURI(this.defaultNamespaceURI);
 152  845
             parser.setValidating(this.validateXML);
 153  845
             script = parser.parse(getUrl());
 154  806
             script = script.compile();
 155  806
             if (log.isDebugEnabled()) {
 156  0
                log.debug("Compiled script: " + getUrl());
 157  
             }
 158  0
         } catch (IOException e) {
 159  0
             throw new JellyException("could not parse Jelly script",e);
 160  39
         } catch (SAXException e) {
 161  39
             throw new JellyException("could not parse Jelly script",e);
 162  806
         }
 163  
         
 164  806
         return script;
 165  
     }
 166  
 
 167  
     
 168  
     // Properties
 169  
     //-------------------------------------------------------------------------                
 170  
     
 171  
     /** 
 172  
      * Sets the script URL to use as an absolute URL or a relative filename
 173  
      */
 174  
     public void setScript(String script) throws MalformedURLException {
 175  13
         setUrl(resolveURL(script));
 176  13
     }
 177  
     
 178  
     public URL getUrl() {
 179  1664
         return url;
 180  
     }
 181  
     
 182  
     /** 
 183  
      * Sets the script URL to use 
 184  
      */
 185  
     public void setUrl(URL url) {
 186  819
         this.url = url;
 187  819
     }
 188  
     
 189  
     /** 
 190  
      * Gets the root context
 191  
      */
 192  
     public URL getRootContext() throws MalformedURLException {
 193  819
         if (rootContext == null) {
 194  819
             rootContext = new File(System.getProperty("user.dir")).toURL();
 195  
         }
 196  819
         return rootContext;
 197  
     }
 198  
     
 199  
     /** 
 200  
      * Sets the root context
 201  
      */
 202  
     public void setRootContext(URL rootContext) {
 203  0
         this.rootContext = rootContext;
 204  0
     }
 205  
     
 206  
     /**
 207  
      * The context to use
 208  
      */
 209  
     public JellyContext getJellyContext() throws MalformedURLException {
 210  845
         if (context == null) {
 211  
             // take off the name off the URL
 212  819
             String text = getUrl().toString();
 213  819
             int idx = text.lastIndexOf('/');
 214  819
             text = text.substring(0, idx + 1);
 215  819
             context = new JellyContext(getRootContext(), class="keyword">new URL(text));
 216  
         }
 217  845
         return context;
 218  
     }
 219  
 
 220  
 
 221  
     /**
 222  
      * Set the jelly namespace to use for unprefixed elements.
 223  
      * Will be overridden by an explicit namespace in the
 224  
      * XML document.
 225  
      * 
 226  
      * @param namespace jelly namespace to use (e.g. 'jelly:core')
 227  
      */
 228  
     public void setDefaultNamespaceURI(String namespace) {
 229  26
         this.defaultNamespaceURI = namespace;
 230  26
     }
 231  
 
 232  
     /**
 233  
      * When set to true, the XML parser will attempt to validate
 234  
      * the Jelly XML before converting it into a Script.
 235  
      * 
 236  
      * @param validate whether or not to validate
 237  
      */
 238  
     public void setValidateXML(boolean validate) {
 239  65
         this.validateXML = validate;
 240  65
     }
 241  
     
 242  
     // Implementation methods
 243  
     //-------------------------------------------------------------------------                
 244  
     /**
 245  
      * @return the URL for the relative file name or absolute URL 
 246  
      */
 247  
     protected URL resolveURL(String name) throws MalformedURLException {
 248  
         
 249  13
         URL resourceUrl = ClassLoaderUtils.getClassLoader(getClass()).getResource(name);
 250  13
         if (resourceUrl == null)
 251  
         {
 252  13
             File file = new File(name);
 253  13
             if (file.exists()) {
 254  0
                 return file.toURL();
 255  
             }
 256  13
             return new URL(name);
 257  
         } else {
 258  0
             return resourceUrl;
 259  
         }
 260  
     }
 261  
 
 262  
     /**
 263  
      * Attempts to load jelly.properties from the current directory,
 264  
      * the users home directory or from the classpath
 265  
      */
 266  
     protected void loadJellyProperties() {
 267  819
         InputStream is = null;
 268  
     
 269  819
         String userDir = System.getProperty("user.home");
 270  819
         File f = new File(userDir + File.separator + "jelly.properties");
 271  819
         loadProperties(f);
 272  
     
 273  819
         f = new File("jelly.properties");
 274  819
         loadProperties(f);
 275  
         
 276  
         
 277  819
         is = ClassLoaderUtils.getClassLoader(getClass()).getResourceAsStream("jelly.properties");
 278  819
         if (is != null) {
 279  
             try {
 280  0
                 loadProperties(is);
 281  
             }
 282  0
             catch (Exception e) {
 283  0
                 log.error( "Caught exception while loading jelly.properties from the classpath. Reason: " + e, e );
 284  0
             }
 285  
         }
 286  819
     }
 287  
 
 288  
     /**
 289  
      * Load properties from a file into the context
 290  
      * @param f
 291  
      */
 292  
     private void loadProperties(File f) {
 293  1638
         InputStream is = null;
 294  
         try {
 295  1638
             if (f.exists()) {
 296  0
                 is = new FileInputStream(f);
 297  0
                 loadProperties(is);
 298  
             }
 299  0
         } catch (Exception e) {
 300  0
             log.error( "Caught exception while loading: " + f.getName() + ". Reason: " + e, e );
 301  
         } finally {
 302  1638
             if (is != null) {
 303  
                 try {
 304  0
                     is.close();
 305  0
                 } catch (IOException e) {
 306  0
                     if (log.isDebugEnabled()) log.debug("error closing property input stream", e);
 307  0
                 }
 308  0
             }
 309  0
         }
 310  1638
     }
 311  
 
 312  
     /**
 313  
      * Loads the properties from the given input stream 
 314  
      */    
 315  
     protected void loadProperties(InputStream is) throws IOException {
 316  0
         JellyContext theContext = getJellyContext();
 317  0
         Properties props = new Properties();
 318  0
         props.load(is);
 319  0
         Enumeration propsEnum = props.propertyNames();
 320  0
         while (propsEnum.hasMoreElements()) {
 321  0
             String key = (String) propsEnum.nextElement();
 322  0
             String value = props.getProperty(key);
 323  
             
 324  
             // @todo we should parse the value in case its an Expression
 325  0
             theContext.setVariable(key, value);
 326  0
         }
 327  0
     }
 328  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.