Coverage Report - org.webmacro.resource.TemplateProvider
 
Classes in this File Line Coverage Branch Coverage Complexity
TemplateProvider
49%
31/63
25%
4/16
4
TemplateProvider$FTReloadContext
100%
5/5
50%
1/2
4
 
 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  
 
 24  
 package org.webmacro.resource;
 25  
 
 26  
 import java.io.File;
 27  
 import java.util.StringTokenizer;
 28  
 
 29  
 import org.slf4j.Logger;
 30  
 import org.slf4j.LoggerFactory;
 31  
 
 32  
 import org.webmacro.Broker;
 33  
 import org.webmacro.InitException;
 34  
 import org.webmacro.NotFoundException;
 35  
 import org.webmacro.ResourceException;
 36  
 import org.webmacro.Template;
 37  
 import org.webmacro.TemplateException;
 38  
 import org.webmacro.engine.FileTemplate;
 39  
 import org.webmacro.util.Settings;
 40  
 
 41  
 /**
 42  
  * The TemplateProvider is the WebMacro class responsible for
 43  
  * loading templates. You could replace it with your own version
 44  
  * in the configuration file. Templates are loaded from the filesystem,
 45  
  * relative to the TemplatePath specified in the configuration.
 46  
  * <p>
 47  
  * Ordinarily you would not access this class directly, but
 48  
  * instead you would call the Broker and it would look up and
 49  
  * use the TemplateProvider for you.
 50  
  * 
 51  
  * @see org.webmacro.Provider
 52  
  */
 53  63
 final public class TemplateProvider extends CachingProvider
 54  
 {
 55  
 
 56  40
     static Logger _log =  LoggerFactory.getLogger(TemplateProvider.class);
 57  
     // INITIALIZATION
 58  
 
 59  40
     private static String _pathSeparator = ";";
 60  63
     private String _templateDirectory[] = null;
 61  63
     private Broker _broker = null;
 62  
     private String _templatePath;
 63  
     private BrokerTemplateProviderHelper _btpHelper;
 64  
 
 65  
     /**
 66  
      * Responsible for deciding, how often resources
 67  
      * should be checked for modification at max.
 68  
      */
 69  
     private ReloadDelayDecorator reloadDelay;
 70  
 
 71  
     static
 72  
     {
 73  
         try
 74  
         {
 75  40
             _pathSeparator = System.getProperty("path.separator");
 76  
         }
 77  0
         catch (Throwable t)
 78  
         {
 79  
             // do nothing
 80  40
         }
 81  40
     }
 82  
 
 83  
     /**
 84  
      * ReloadContext for file templates.  Uses last-modified to determine
 85  
      * if resource should be reloaded.
 86  
      */
 87  63
     public static class FTReloadContext extends CacheReloadContext
 88  
     {
 89  
 
 90  
         private File file;
 91  
         private long lastModified;
 92  
 
 93  
         public FTReloadContext (File f, long lastModified)
 94  57
         {
 95  57
             this.file = f;
 96  57
             this.lastModified = lastModified;
 97  57
         }
 98  
 
 99  
         public boolean shouldReload ()
 100  
         {
 101  1779
             return (lastModified != file.lastModified());
 102  
         }
 103  
     }
 104  
 
 105  
 
 106  
     /**
 107  
      * Create a new TemplateProvider that uses the specified directory
 108  
      * as the source for Template objects that it will return.
 109  
      * @exception InitException provider failed to initialize
 110  
      */
 111  
     public void init (Broker b, Settings config) throws InitException
 112  
     {
 113  63
         super.init(b, config);
 114  63
         _broker = b;
 115  
 
 116  
         try
 117  
         {
 118  63
             _templatePath = config.getSetting("TemplatePath", "");
 119  63
             if (_templatePath.equals(""))
 120  63
                 _log.info("Template path is empty; will load from class path");
 121  
             else
 122  
             {
 123  0
                 StringTokenizer st =
 124  
                         new StringTokenizer(_templatePath, _pathSeparator);
 125  0
                 _templateDirectory = new String[st.countTokens()];
 126  0
                 for (int i = 0; i < _templateDirectory.length; i++)
 127  
                 {
 128  0
                     String dir = st.nextToken();
 129  0
                     _templateDirectory[i] = dir;
 130  
                 }
 131  
             }
 132  63
             reloadDelay = new ReloadDelayDecorator();
 133  63
             reloadDelay.init(b, config);
 134  
 
 135  63
             _btpHelper = new BrokerTemplateProviderHelper();
 136  63
             _btpHelper.init(b, config);
 137  63
             _btpHelper.setReload(_cacheSupportsReload);
 138  
         }
 139  0
         catch (Exception e)
 140  
         {
 141  0
             throw new InitException("Could not initialize", e);
 142  63
         }
 143  63
     }
 144  
 
 145  
     /**
 146  
      * Supports the "template" type.
 147  
      */
 148  
     final public String getType ()
 149  
     {
 150  252
         return "template";
 151  
     }
 152  
 
 153  
     /**
 154  
      * Grab a template based on its name.
 155  
      */
 156  
     final public Object load (String name, CacheElement ce)
 157  
             throws ResourceException
 158  
     {
 159  57
         Object ret = null;
 160  
 
 161  57
         _log.info("Loading template: " + name);
 162  
 
 163  57
         File tFile = findFileTemplate(name);
 164  57
         if (tFile != null)
 165  
         {
 166  
             try
 167  
             {
 168  0
                 Template t = new FileTemplate(_broker, tFile);
 169  0
                 t.parse();
 170  0
                 ret = t;
 171  0
                 if (_cacheSupportsReload)
 172  
                 {
 173  0
                     CacheReloadContext reloadContext =
 174  
                             new FTReloadContext(tFile, tFile.lastModified());
 175  0
                     ce.setReloadContext(reloadDelay.decorate("file",
 176  
                             reloadContext));
 177  
                 }
 178  
             }
 179  0
             catch (NullPointerException npe)
 180  
             {
 181  0
                 _log.warn("TemplateProvider: Template not found: " + name,
 182  
                         npe);
 183  0
                 throw new ResourceException("Error fetching template " + name, npe);
 184  
             }
 185  0
             catch (TemplateException e)
 186  
             {
 187  
                 // Parse error
 188  0
                 _log.warn("TemplateProvider: Error occured while parsing "
 189  
                         + name, e);
 190  0
                 throw new InvalidResourceException("Error parsing template "
 191  
                         + name, e);
 192  
             }
 193  0
             catch (Exception e)
 194  
             {
 195  0
                 _log.warn("TemplateProvider: Error occured while fetching "
 196  
                         + name, e);
 197  0
                 throw new ResourceException("Error fetching template " + name, e);
 198  0
             }
 199  
         }
 200  
         else
 201  
         {
 202  
             // Let the BrokerTemplateProvider have a crack at it
 203  57
             ret = _btpHelper.load(name, ce);
 204  
         }
 205  
 
 206  57
         if (ret == null)
 207  
         {
 208  0
             throw new NotFoundException(
 209  
                     this + " could not locate " + name + " on path " + _templatePath);
 210  
         }
 211  57
         return ret;
 212  
     }
 213  
 
 214  
 
 215  
     // IMPLEMENTATION
 216  
 
 217  
     /**
 218  
      * @param fileName the template filename to find, relative to the
 219  
      * TemplatePath
 220  
      * @return a File object that represents the specified template file
 221  
      *  null if template file cannot be found.  */
 222  
     final private File findFileTemplate (String fileName)
 223  
     {
 224  57
         if (_templateDirectory != null)
 225  
         {
 226  0
             _log.debug("Looking for template in TemplatePath: " + fileName);
 227  0
             for (int i = 0; i < _templateDirectory.length; i++)
 228  
             {
 229  0
                 String dir = _templateDirectory[i];
 230  0
                 File tFile = new File(dir, fileName);
 231  0
                 if (tFile.canRead())
 232  
                 {
 233  0
                     _log.debug("TemplateProvider: Found " + fileName + " in " + dir);
 234  0
                     return tFile;
 235  
                 }
 236  
             }
 237  
         }
 238  57
         return null;
 239  
     }
 240  
 }
 241  
 
 242