Coverage Report - org.webmacro.resource.URLTemplate
 
Classes in this File Line Coverage Branch Coverage Complexity
URLTemplate
0%
0/61
0%
0/28
3.571
 
 1  
 /*
 2  
  * Copyright (C) 1998-2000 Semiotek Inc.  All Rights Reserved.
 3  
  *
 4  
  * Redistribution and use in source and binary forms, with or without
 5  
  * modification, are permitted under the terms of either of the following
 6  
  * Open Source licenses:
 7  
  *
 8  
  * The GNU General Public License, version 2, or any later version, as
 9  
  * published by the Free Software Foundation
 10  
  * (http://www.fsf.org/copyleft/gpl.html);
 11  
  *
 12  
  *  or
 13  
  *
 14  
  * The Semiotek Public License (http://webmacro.org/LICENSE.)
 15  
  *
 16  
  * This software is provided "as is", with NO WARRANTY, not even the
 17  
  * implied warranties of fitness to purpose, or merchantability. You
 18  
  * assume all risks and liabilities associated with its use.
 19  
  *
 20  
  * See www.webmacro.org for more information on the WebMacro project.
 21  
  */
 22  
 
 23  
 package org.webmacro.resource;
 24  
 
 25  
 import java.io.BufferedReader;
 26  
 import java.io.File;
 27  
 import java.io.IOException;
 28  
 import java.io.InputStream;
 29  
 import java.io.InputStreamReader;
 30  
 import java.io.Reader;
 31  
 import java.net.URL;
 32  
 import java.util.HashMap;
 33  
 import java.util.Locale;
 34  
 import java.util.Properties;
 35  
 
 36  
 import org.slf4j.Logger;
 37  
 import org.slf4j.LoggerFactory;
 38  
 
 39  
 import org.webmacro.Broker;
 40  
 import org.webmacro.TemplateException;
 41  
 import org.webmacro.WMConstants;
 42  
 import org.webmacro.engine.WMTemplate;
 43  
 import org.webmacro.servlet.LocaleTool;
 44  
 import org.webmacro.util.NativeAsciiReader;
 45  
 
 46  
 /**
 47  
  * FileTemplate objects read their template data from a text file.
 48  
  */
 49  
 
 50  
 public class URLTemplate extends WMTemplate
 51  
 {
 52  
 
 53  0
     static Logger _log =  LoggerFactory.getLogger(URLTemplate.class);
 54  
 
 55  
     /** CVS revision  */
 56  
     public static final String RCS = "@(#) $Id: URLTemplate.java,v 1.13 2010/02/24 21:02:17 timp Exp $";
 57  
 
 58  
     /**
 59  
      * The location of the resourse (file) this template was read from.
 60  
      */
 61  
     private final URL _url;
 62  
 
 63  
     /**
 64  
      * The physical file referred to by "file:" and "jar:" URLs.
 65  
      */
 66  0
     private File underLyingFile = null;
 67  
 
 68  
     /**
 69  
      * The time the underlying file was last modified.
 70  
      */
 71  0
     private long underLyingFileLastModTime = 0;
 72  
 
 73  
     /**
 74  
      * Cache for any per-directory encoding files.
 75  
      */
 76  0
     private final HashMap propertiesCache = new HashMap();
 77  
 
 78  0
     private String _inputEncoding = null;
 79  0
     private String _outputEncoding = null;
 80  0
     private Locale _outputLocale = null;
 81  
 
 82  
     /**
 83  
      * A dummy object used as a place holder in the encoding cache.
 84  
      */
 85  0
     private static final Object dummy = new Object();
 86  
 
 87  
     /**
 88  
      * Instantiate a template based on the specified file.
 89  
      * We use can use the special case or URLs like
 90  
      * <pre>
 91  
      *        file:xxxxxx
 92  
      * or
 93  
      *        jar:xxxxxx!yyyyyy
 94  
      *</pre>
 95  
      * extracting the xxxxxx.  
 96  
      * In the latter case the reference is to the jar containing the
 97  
      * template.
 98  
      */
 99  
     public URLTemplate (
 100  
             Broker broker,
 101  
             URL templateURL
 102  
             )
 103  
     {
 104  0
         super(broker);
 105  0
         _url = templateURL;
 106  0
         String _u = _url.toExternalForm();
 107  
 
 108  0
         _log.debug("URLTemplate: " + _u);
 109  
 
 110  0
         if (_u.startsWith("jar:"))
 111  
         {
 112  0
             int p = _u.indexOf("!");
 113  0
             _u = _u.substring(4, p);
 114  
         }
 115  
 
 116  0
         if (_u.startsWith("file:"))
 117  
         {
 118  0
             underLyingFile = new File(_u.substring(5));
 119  0
             underLyingFileLastModTime = underLyingFile.lastModified();
 120  
         }
 121  
 
 122  0
         setupLocalProperties();
 123  0
     }
 124  
 
 125  
     /**
 126  
      * URL based templates are difficult to detect as changed in general, but the two
 127  
      * special cases can be determined for reloading.
 128  
      * <pre>
 129  
      * file:[path] and 
 130  
      * jar:file:[jarpath]![path]
 131  
      * </pre>
 132  
      * Imply a reference to the actual file.
 133  
      */
 134  
     public boolean shouldReload ()
 135  
     {
 136  0
         if (underLyingFile == null) return false;
 137  0
         long lastMod = underLyingFile.lastModified();
 138  
 
 139  0
         return ((lastMod > 0) && (lastMod > underLyingFileLastModTime));
 140  
     }
 141  
 
 142  
 
 143  
     /**
 144  
      * Look for TemplateEncoding in a file WebMacro.local in the same
 145  
      * directory as the template
 146  
      *
 147  
      * TODO - should make the encoding cache a bit smarter- doesn't detect
 148  
      * if the file changes
 149  
      */
 150  
     private void setupLocalProperties ()
 151  
     {
 152  0
         InputStream is = null;
 153  0
         URL u = null;
 154  
 
 155  
         try
 156  
         {
 157  
 
 158  0
             u = new URL(_url, WMConstants.WEBMACRO_LOCAL_FILE);
 159  0
             _log.debug("Looking for encodings file: " + u);
 160  0
             Object obj = propertiesCache.get(u);
 161  
 
 162  0
             if (obj != null)
 163  
             {
 164  
                 return;
 165  
             }
 166  
 
 167  0
             Properties p = new Properties();
 168  0
             is = u.openStream();
 169  0
             p.load(is);
 170  0
             _inputEncoding = p.getProperty(WMConstants.TEMPLATE_INPUT_ENCODING);
 171  0
             _outputEncoding = p.getProperty(WMConstants.TEMPLATE_OUTPUT_ENCODING);
 172  
 
 173  0
             String loc = p.getProperty(WMConstants.TEMPLATE_LOCALE);
 174  0
             if (loc != null)
 175  
             {
 176  0
                 _outputLocale = LocaleTool.buildLocale(loc);
 177  
             }
 178  
 
 179  0
             propertiesCache.put(u, dummy);
 180  
 
 181  
 
 182  
         }
 183  0
         catch (Exception e)
 184  
         {
 185  
             // if there's an Exception here, put a dummy object here so
 186  
             // we don't try to look for the file every time
 187  
             //
 188  0
             propertiesCache.put(u, dummy);
 189  
         }
 190  
         finally
 191  
         {
 192  0
             if (_inputEncoding == null)
 193  
             {
 194  0
                 _inputEncoding = getDefaultEncoding();
 195  
             }
 196  
 
 197  0
             if (is != null)
 198  
             {
 199  
                 try
 200  
                 {
 201  0
                     is.close();
 202  
                 }
 203  0
                 catch (Exception ignore)
 204  
                 {
 205  0
                 }
 206  
             }
 207  
         }
 208  0
     }
 209  
 
 210  
     /**
 211  
      * Get the stream the template should be read from. Parse will
 212  
      * call this method in order to locate a stream.
 213  
      *
 214  
      */
 215  
     protected Reader getReader () throws IOException
 216  
     {
 217  0
         _log.debug("Using encoding " + _inputEncoding);
 218  
 
 219  0
         if (_inputEncoding.equals("native_ascii"))
 220  
         {
 221  0
             return new NativeAsciiReader(
 222  
                     new InputStreamReader(_url.openStream(), "ASCII"));
 223  
         }
 224  
         else
 225  
         {
 226  0
             return new BufferedReader(
 227  
                     new InputStreamReader(_url.openStream(), _inputEncoding));
 228  
         }
 229  
     }
 230  
 
 231  
     /**
 232  
      * @return the URL for the current template
 233  
      */
 234  
     public URL getURL ()
 235  
     {
 236  0
         return _url;
 237  
     }
 238  
 
 239  
     /**
 240  
      * Return a name for this template. For example, if the template reads
 241  
      * from a file you might want to mention which it is--will be used to
 242  
      * produce error messages describing which template had a problem.
 243  
      */
 244  
     public String toString ()
 245  
     {
 246  0
         return "URLTemplate:" + _url;
 247  
     }
 248  
 
 249  
     public void parse () throws IOException, TemplateException
 250  
     {
 251  0
         super.parse();
 252  0
         if ((_outputEncoding != null)
 253  
                 && (getParam(WMConstants.TEMPLATE_OUTPUT_ENCODING) == null))
 254  
         {
 255  0
             _log.debug("Setting output encoding to " + _outputEncoding);
 256  0
             setParam(WMConstants.TEMPLATE_OUTPUT_ENCODING, _outputEncoding);
 257  
         }
 258  0
         if ((_outputLocale != null)
 259  
                 && (getParam(WMConstants.TEMPLATE_LOCALE) == null))
 260  
         {
 261  0
             _log.debug("Setting output locale to " + _outputLocale);
 262  0
             setParam(WMConstants.TEMPLATE_LOCALE, _outputLocale);
 263  
         }
 264  0
     }
 265  
 }