You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by jv...@locus.apache.org on 2000/12/19 06:30:06 UTC

cvs commit: jakarta-velocity/src/java/org/apache/velocity/runtime/resource/loader FileResourceLoader.java ResourceLoader.java ResourceLoaderFactory.java

jvanzyl     00/12/18 21:30:06

  Added:       src/java/org/apache/velocity/runtime/resource
                        ContentResource.java Resource.java
                        ResourceFactory.java ResourceManager.java
               src/java/org/apache/velocity/runtime/resource/loader
                        FileResourceLoader.java ResourceLoader.java
                        ResourceLoaderFactory.java
  Log:
  - Code for the new resource management mechanism. This allows
    a single mechanism to deal with text resources. Right now
    templates and static content pulled in by the #include
    mechanism. So templates and static content can be pulled from
    any arbitrary source and be cached in the same manner.
  
  Revision  Changes    Path
  1.1                  jakarta-velocity/src/java/org/apache/velocity/runtime/resource/ContentResource.java
  
  Index: ContentResource.java
  ===================================================================
  package org.apache.velocity.runtime.resource;
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000 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", "Velocity", 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/>.
   */
  
  import java.io.StringWriter;
  import java.io.BufferedReader;
  import java.io.InputStreamReader;
  
  import org.apache.velocity.runtime.Runtime;
  
  /**
   * This class represent a general text resource that
   * may have been retrieved from any number of possible
   * sources.
   *
   * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
   * @version $Id: ContentResource.java,v 1.1 2000/12/19 05:30:05 jvanzyl Exp $
   */
  public class ContentResource extends Resource
  {
      /** Default empty constructor */
      public ContentResource()
      {
      }
      
      /** Pull in static content and store it */
      public boolean process()
      {
          try
          {
              StringWriter sw = new StringWriter();
              
              BufferedReader reader = new BufferedReader(
                  new InputStreamReader(resourceLoader.getResourceStream(name)));
              
              char buf[] = new char[1024];
              int len = 0;
              
              while ( ( len = reader.read( buf, 0, 1024 )) != -1)
                  sw.write( buf, 0, len );
          
              data = sw.toString();
              
              return true;
          }
          catch ( Exception e ) 
          {
              Runtime.error("#include() : " + e.toString() );
              return false;
          }
      }
  }
  
  
  
  1.1                  jakarta-velocity/src/java/org/apache/velocity/runtime/resource/Resource.java
  
  Index: Resource.java
  ===================================================================
  package org.apache.velocity.runtime.resource;
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000 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", "Velocity", 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/>.
   */
  
  import java.io.InputStream;
  import java.io.IOException;
  import java.io.Writer;
  
  import org.apache.velocity.runtime.Runtime;
  import org.apache.velocity.runtime.parser.ParseException;
  import org.apache.velocity.runtime.parser.node.SimpleNode;
  import org.apache.velocity.runtime.resource.loader.ResourceLoader;
  
  /**
   * This class represent a general text resource that
   * may have been retrieved from any number of possible
   * sources.
   *
   * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
   * @version $Id: Resource.java,v 1.1 2000/12/19 05:30:05 jvanzyl Exp $
   */
  public abstract class Resource
  {
      /**
       * The template loader that initially loaded the input
       * stream for this template, and knows how to check the
       * source of the input stream for modification.
       */
      protected ResourceLoader resourceLoader;
  
      /**
       * The number of milliseconds in a minute, used to calculate the
       * check interval.
       */
      protected static final long MILLIS_PER_MINUTE = 60 * 1000;
  
      /**
       * How often the file modification time is checked (in milliseconds).
       */
      protected long modificationCheckInterval = 0;
  
      /**
       * The file modification time (in milliseconds) for the cached template.
       */
      protected long lastModified = 0;
  
      /**
       * The next time the file modification time will be checked (in 
       * milliseconds).
       */
      protected long lastCheck = 0;
  
      /**
       * The next time the file modification time will be checked (in 
       * milliseconds).
       */
      protected long nextCheck = 0;
  
      /** Resource name */
      protected String name;
  
      /** Resource might require ancillary storage of some kind */
      protected Object data = null;
  
      /** Default constructor */
      public Resource()
      {
      }
      
      /**
       * Perform any subsequent processing that might need
       * to be done by a resource. In the case of a template
       * the actual parsing of the input stream needs to be
       * performed.
       */
      public abstract boolean process();
  
      public boolean isSourceModified()
      {
          return resourceLoader.isSourceModified(this);
      }
  
      /**
       * Set the modification check interval.
       * @param interval The interval (in minutes).
       */
      public void setModificationCheckInterval(long modificationCheckInterval)
      {
          this.modificationCheckInterval = modificationCheckInterval;
      }
      
      /**
       * Is it time to check to see if the resource
       * source has been updated?
       */
       public boolean requiresChecking()
       {
          if ( lastCheck >= nextCheck)
          {
              return true;
          }            
          else
          {
              lastCheck = System.currentTimeMillis();
              return false;
          }
      }
  
      /**
       * Touch this template and thereby resetting
       * the lastCheck, and nextCheck fields.
       */
      public void touch()
      {
          lastCheck = System.currentTimeMillis();
          nextCheck = lastCheck + modificationCheckInterval;
      }
      
      /**
       * Set the name of this resource, for example
       * test.vm.
       */
      public void setName(String name)
      {
          this.name = name;
      }        
  
      /**
       * Get the name of this template.
       */
      public String getName()
      {
          return name;
      }        
  
      /**
       * Return the lastModifed time of this
       * template.
       */
      public long getLastModified()
      {
          return lastModified;
      }        
      
      /**
       * Set the last modified time for this
       * template.
       */
      public void setLastModified(long lastModified)
      {
          this.lastModified = lastModified;
      }        
  
      /**
       * Return the template loader that pulled
       * in the template stream
       */
      public ResourceLoader getResourceLoader()
      {
          return resourceLoader;
      }
      
      /**
       * Set the template loader for this template. Set
       * when the Runtime determines where this template
       * came from the list of possible sources.
       */
      public void setResourceLoader(ResourceLoader resourceLoader)
      {
          this.resourceLoader = resourceLoader;
      }        
  
      /** 
       * Set arbitrary data object that might be used
       * by the resource.
       */
      public void setData(Object data)
      {
          this.data = data;
      }
      
      /**
       * Get arbitrary data object that might be used
       * by the resource.
       */
      public Object getData()
      {
          return data;
      }        
  }
  
  
  
  1.1                  jakarta-velocity/src/java/org/apache/velocity/runtime/resource/ResourceFactory.java
  
  Index: ResourceFactory.java
  ===================================================================
  package org.apache.velocity.runtime.resource;
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000 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", "Velocity", 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/>.
   */
  
  import org.apache.velocity.Template;
  
  /**
   * Class responsible for instantiated a given resource type
   * given the resource type.
   */
  public class ResourceFactory
  {
      public static Resource getResource(String resourceName, int resourceType)
      {
          Resource resource = null;
          
          switch (resourceType)
          {
              case ResourceManager.RESOURCE_TEMPLATE:
                  resource = new Template();
                  break;
              
              case ResourceManager.RESOURCE_CONTENT:
                  resource = new ContentResource();
                  break;
          }
      
          return resource;
      }
  }
  
  
  
  1.1                  jakarta-velocity/src/java/org/apache/velocity/runtime/resource/ResourceManager.java
  
  Index: ResourceManager.java
  ===================================================================
  package org.apache.velocity.runtime.resource;
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000 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", "Velocity", 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/>.
   */
  
  import java.util.ArrayList;
  import java.util.Enumeration;
  import java.util.Hashtable;
  import java.util.Map;
  
  import org.apache.velocity.Template;
  import org.apache.velocity.runtime.Runtime;
  import org.apache.velocity.runtime.configuration.VelocityResources;
  import org.apache.velocity.runtime.resource.ResourceFactory;
  import org.apache.velocity.runtime.resource.loader.ResourceLoader;
  import org.apache.velocity.runtime.resource.loader.ResourceLoaderFactory;
  
  /**
   * Class to manage the text resource for the Velocity
   * Runtime.
   *
   * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
   * @version $Id: ResourceManager.java,v 1.1 2000/12/19 05:30:05 jvanzyl Exp $
   */
  public class ResourceManager
  {
      public static final int RESOURCE_TEMPLATE = 1;
      public static final int RESOURCE_CONTENT = 2;
  
      private static Hashtable globalCache = new Hashtable();
      
      /**
       * The List of templateLoaders that the Runtime will
       * use to locate the InputStream source of a template.
       */
      private static ArrayList resourceLoaders = new ArrayList();
      
      /**
       * This is a list of the template stream source
       * initializers, basically properties for a particular
       * template stream source. The order in this list
       * reflects numbering of the properties i.e.
       * template.loader.1.<property> = <value>
       * template.loader.2.<property> = <value>
       */
      private static ArrayList sourceInitializerList = new ArrayList();
      
      /**
       * This is a map of public name of the template
       * stream source to it's initializer. This is so
       * that clients of velocity can set properties of
       * a template source stream with its public name.
       * So for example, a client could set the 
       * File.template.path property and this would
       * change the template.path property for the
       * file template stream source.
       */
      private static Hashtable sourceInitializerMap = new Hashtable();
  
      /**
       * Initialize the ResourceManager. It is assumed
       * that assembleSourceInitializers() has been
       * called before this is run.
       */
      public static void initialize() throws Exception
      {
          ResourceLoader resourceLoader;
          
          assembleSourceInitializers();
          
          for (int i = 0; i < sourceInitializerList.size(); i++)
          {
              Map initializer = (Map) sourceInitializerList.get(i);
              String loaderClass = (String) initializer.get("class");
              resourceLoader = ResourceLoaderFactory.getLoader(loaderClass);
              resourceLoader.init(initializer);
              resourceLoaders.add(resourceLoader);
          }
      }
  
      /**
       * This will produce a List of Hashtables, each
       * hashtable contains the intialization info for
       * a particular template loader. This Hastable
       * will be passed in when initializing the
       * the template loader.
       */
      private static void assembleSourceInitializers()
      {
          for (int i = 0; i < 10; i++)
          {
              String loaderID = "resource.loader." + new Integer(i).toString();
              Enumeration e = VelocityResources.getKeys(loaderID);
              
              if (!e.hasMoreElements())
              {
                  continue;
              }
              
              Hashtable sourceInitializer = new Hashtable();
              
              while (e.hasMoreElements())
              {
                  String property = (String) e.nextElement();
                  String value = VelocityResources.getString(property);
                  
                  property = property.substring(loaderID.length() + 1);
                  sourceInitializer.put(property, value);
                  
                  /*
                   * Make a Map of the public names for the sources
                   * to the sources property identifier so that external
                   * clients can set source properties. For example:
                   * File.template.path would get translated into
                   * template.loader.1.template.path and the translated
                   * name would be used to set the property.
                   */
                  if (property.equalsIgnoreCase("public.name"))
                  {
                      sourceInitializerMap.put(value.toLowerCase(), sourceInitializer);
                  }
              }    
              sourceInitializerList.add(sourceInitializer);
          }
      }
  
      public static Resource getResource(String resourceName, int resourceType)
      {
          Resource resource = null;
          ResourceLoader resourceLoader = null;
          
          /* 
           * Check to see if the resource was placed in the cache.
           * If it was placed in the cache then we will use
           * the cached version of the resource. If not we
           * will load it.
           */
          
          if (globalCache.containsKey(resourceName))
          {
              resource = (Resource) globalCache.get(resourceName);
  
              /* 
               * The resource knows whether it needs to be checked
               * or not, and the resource's loader can check to
               * see if the source has been modified. If both
               * these conditions are true then we must reload
               * the input stream and parse it to make a new
               * AST for the resource.
               */
              if (resource.requiresChecking() && 
                  resource.isSourceModified())
              {
                  try
                  {
                      resource.process();
                      return resource;
                  }
                  catch (Exception e)
                  {
                      Runtime.error(e);
                  }
              }
              return resource;
          }
          else
          {
              try
              {
                  resource = ResourceFactory.getResource(resourceName, resourceType);
                  resource.setName(resourceName);
                  
                  /* 
                   * Now we have to try to find the appropriate
                   * loader for this resource. We have to cycle through
                   * the list of available resource loaders and see
                   * which one gives us a stream that we can use to
                   * make a resource with.
                   */
                  
                  for (int i = 0; i < resourceLoaders.size(); i++)
                  {
                      resourceLoader = (ResourceLoader) resourceLoaders.get(i);
                      resource.setResourceLoader(resourceLoader);
                      
                      if (resource.process())
                          break;
                  }
                  
                  /*
                   * Return null if we can't find a resource.
                   */
                  if (resource.getData() == null)
                      throw new Exception("Can't find " + resourceName + "!");
                  
                  resource.setLastModified(resourceLoader.getLastModified(resource));
                  resource.setModificationCheckInterval(resourceLoader.getModificationCheckInterval());
                  resource.touch();
                  
                  /*
                   * Place the resource in the cache if the resource
                   * loader says to.
                   */
                  
                  if (resourceLoader.isCachingOn())
                      globalCache.put(resourceName, resource);
              }
              catch (Exception e)
              {
                  Runtime.error(e);
              }
          }
          return resource;
      }
  
      /**
       * Allow clients of Velocity to set a template stream
       * source property before the template source streams
       * are initialized. This would for example allow clients
       * to set the template path that would be used by the
       * file template stream source. Right now these properties
       * have to be set before the template stream source is
       * initialized. Maybe we should allow these properties
       * to be changed on the fly.
       *
       * It is assumed that the initializers have been
       * assembled.
       */
      public static void setSourceProperty(String key, String value)
      {
          String publicName = key.substring(0, key.indexOf("."));
          String property = key.substring(key.indexOf(".") + 1);
          ((Map)sourceInitializerMap.get(publicName.toLowerCase())).put(property, value);
      }
  }
  
  
  
  1.1                  jakarta-velocity/src/java/org/apache/velocity/runtime/resource/loader/FileResourceLoader.java
  
  Index: FileResourceLoader.java
  ===================================================================
  package org.apache.velocity.runtime.resource.loader;
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000 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", "Tomcat", 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/>.
   */
  
  import java.io.File;
  import java.io.InputStream;
  import java.io.FileInputStream;
  import java.io.BufferedInputStream;
  
  import java.util.Map;
  import java.util.Hashtable;
  
  import org.apache.velocity.util.StringUtils;
  import org.apache.velocity.runtime.Runtime;
  import org.apache.velocity.runtime.resource.Resource;
  
  
  /**
   * This is a simple template file loader.
   * Currently it only supports a  single path to templates.
   * That'll change once we decide how we want to do configuration
   * 
   * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
   * $Revision: 1.1 $
   */
  public class FileResourceLoader extends ResourceLoader
  {
      private String path;
  
      /*
       * This should probably be moved into the super class,
       * the stand init stuff. For the properties that all
       * loaders will probably share.
       */
      public void init(Map initializer)
      {
          path = (String) initializer.get("resource.path");
          Runtime.info("Resources Loaded From: " +  new File(path).getAbsolutePath());
          Runtime.info("Resource Loader Initialized.");
      }
  
      /**
       * Get an InputStream so that the Runtime can build a
       * template with it.
       */
      public synchronized InputStream getResourceStream( String name )
          throws Exception
      {
          if (name == null || name.length() == 0)
          {
              throw new Exception ("Need to specify a file name or file path!");
          }
  
          String normalizedPath = StringUtils.normalizePath(name);
          if ( normalizedPath == null || normalizedPath.length() == 0 )
          {
              Runtime.error( "File resource error : argument " + normalizedPath + 
                  " contains .. and may be trying to access " + 
                  "content outside of template root.  Rejected." );
              
              return null;
          }
  
          /*
           *  if a / leads off, then just nip that :)
           */
          if ( normalizedPath.startsWith("/") )
              normalizedPath = normalizedPath.substring(1);
  
          File file = new File( path, normalizedPath );           
          if ( file.canRead() )
          {
              return new BufferedInputStream(
                  new FileInputStream(file.getAbsolutePath()));
          }
          
          return null;
      }
  
      public boolean isSourceModified(Resource resource)
      {
          File file = new File( path, resource.getName() );           
          
          if ( file.canRead() )
          {
              if (file.lastModified() != resource.getLastModified())
                  return true;
              else
                  return false;
          }
          
          // If the file is now unreadable, or it has
          // just plain disappeared then we'll just say
          // that it's modified :-) When the loader attempts
          // to load the stream it will fail and the error
          // will be reported then.
          
          return true;
      }
  
      public long getLastModified(Resource resource)
      {
          File file = new File(path, resource.getName());
      
          if (file.canRead())
              return file.lastModified();
          else
              return 0;
      }
  }
  
  
  
  1.1                  jakarta-velocity/src/java/org/apache/velocity/runtime/resource/loader/ResourceLoader.java
  
  Index: ResourceLoader.java
  ===================================================================
  package org.apache.velocity.runtime.resource.loader;
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000 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", "Tomcat", 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/>.
   */
  
  import java.io.InputStream;
  import java.util.Map;
  
  import org.apache.velocity.runtime.Runtime;
  import org.apache.velocity.runtime.resource.Resource;
  
  /**
   * This is abstract class the all text resource loaders should
   * extend.
   * 
   * @autor <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
   * $Id: ResourceLoader.java,v 1.1 2000/12/19 05:30:06 jvanzyl Exp $
   */
  public abstract class ResourceLoader
  {
      /** 
       * Does this loader want templates produced with it
       * cached in the Runtime.
       */
       protected boolean isCachingOn = false;
      
      /**
       * This property will be passed on to the templates
       * that are created with this loader.
       */
      protected long modificationCheckInterval = 2;
      
      /**
       * This initialization is used by all resource
       * loaders and must be called to set up common
       * properties shared by all resource loaders
       */
      protected void commonInit(Map initializer)
      {
          isCachingOn = new Boolean((String)initializer
              .get("cache")).booleanValue();
          
          modificationCheckInterval = Long.parseLong((String)initializer
              .get("modificationCheckInterval"));
      }
  
      /** 
       * Initialize the template loader with a
       * Map.
       */
      public abstract void init(Map initializer);
  
      /** 
       * Get the InputStream that the Runtime will parse
       * to create a template.
       */
      public abstract InputStream getResourceStream( String source ) throws Exception;
  
      /**
       * Given a template, check to see if the source of InputStream
       * has been modified.
       */
      public abstract boolean isSourceModified(Resource resource);
      
      /**
       * Get the last modified time of the InputStream source
       * that was used to create the template. We need the template
       * here because we have to extract the name of the template
       * in order to locate the InputStream source.
       */
      public abstract long getLastModified(Resource resource);
  
      /**
       * Set the caching state. If true, then this loader
       * would like the Runtime to cache templates that
       * have been created with InputStreams provided
       * by this loader.
       */
      public void setCachingOn(boolean value)
      {
          isCachingOn = value;
      }        
  
      /**
       * The Runtime uses this to find out whether this
       * template loader wants the Runtime to cache
       * templates created with InputStreams provided
       * by this loader.
       */
      public boolean isCachingOn()
      {
          return isCachingOn;
      }
  
      /**
       * Set the interval at which the InputStream source
       * should be checked for modifications.
       */
      public void setModificationCheckInterval(long modificationCheckInterval)
      {
          this.modificationCheckInterval = modificationCheckInterval;
      }
      
      /**
       * Get the interval at which the InputStream source
       * should be checked for modifications.
       */
      public long getModificationCheckInterval()
      {
          return modificationCheckInterval;
      }        
  }
  
  
  
  1.1                  jakarta-velocity/src/java/org/apache/velocity/runtime/resource/loader/ResourceLoaderFactory.java
  
  Index: ResourceLoaderFactory.java
  ===================================================================
  package org.apache.velocity.runtime.resource.loader;
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000 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", "Tomcat", 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/>.
   */
  
  import org.apache.velocity.runtime.Runtime;
  import org.apache.velocity.util.StringUtils;
  
  /**
   * Factory to grab a template loader.
   * 
   * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
   * $Id: ResourceLoaderFactory.java,v 1.1 2000/12/19 05:30:06 jvanzyl Exp $
   */
  public class ResourceLoaderFactory
  {
      /**
       * Gets the loader specified in the configuration file.
       * @return TemplateLoader
       */
      public static ResourceLoader getLoader(String loaderClassName)
       throws Exception
      {
          ResourceLoader loader = null;
          
          try
          {
              loader = ((ResourceLoader)Class.forName(loaderClassName)
                  .newInstance());
              
              Runtime.info("Resource Loader Instantiated: " + 
                  loader.getClass().getName());
              
              return loader;
          }
          catch( Exception e)
          {
              Runtime.error("Problem instantiating the template loader.\n" +
                            "Look at your properties file and make sure the\n" +
                            "name of the template loader is correct. Here is the\n" +
                            "error: " + StringUtils.stackTrace(e));
              
              throw new Exception("Problem initializing template loader: " + loaderClassName + 
              "\nError is: " + StringUtils.stackTrace(e));
          }
      }
  }