[Adapdev-commits] Adapdev/src/Adapdev.NVelocity/Runtime/Resource ContentResource.cs,1.4,1.5 Resource
Status: Beta
Brought to you by:
intesar66
From: Sean M. <int...@us...> - 2005-11-16 07:02:14
|
Update of /cvsroot/adapdev/Adapdev/src/Adapdev.NVelocity/Runtime/Resource In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv909/src/Adapdev.NVelocity/Runtime/Resource Added Files: ContentResource.cs Resource.cs ResourceCache.cs ResourceCacheImpl.cs ResourceFactory.cs ResourceManager.cs ResourceManagerImpl.cs Log Message: --- NEW FILE: ResourceFactory.cs --- namespace NVelocity.Runtime.Resource { /* * The Apache Software License, Version 1.1 * * Copyright (c) 2001 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 ap...@ap.... * * 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/>. */ using System; /// <summary> Class responsible for instantiating <code>Resource</code> objects, /// given name and type. /// * /// </summary> /// <author> <a href="mailto:jv...@ap...">Jason van Zyl</a> /// </author> /// <author> <a href="mailto:ge...@op...">Geir Magnusson Jr.</a> /// </author> /// <version> $Id: ResourceFactory.cs,v 1.5 2005/11/16 07:01:51 intesar66 Exp $ /// /// </version> public class ResourceFactory { public static Resource getResource(String resourceName, int resourceType) { Resource resource = null; switch (resourceType) { case ResourceManager_Fields.RESOURCE_TEMPLATE: resource = new Template(); break; case ResourceManager_Fields.RESOURCE_CONTENT: resource = new ContentResource(); break; } return resource; } } } --- NEW FILE: ContentResource.cs --- namespace NVelocity.Runtime.Resource { /* * The Apache Software License, Version 1.1 * * Copyright (c) 2001 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 ap...@ap.... * * 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/>. */ using System; using System.IO; /// <summary> This class represent a general text resource that /// may have been retrieved from any number of possible /// sources. /// * /// </summary> /// <author> <a href="mailto:jv...@ap...">Jason van Zyl</a> /// </author> /// <author> <a href="mailto:ge...@op...">Geir Magnusson Jr.</a> /// </author> /// <version> $Id: ContentResource.cs,v 1.5 2005/11/16 07:01:51 intesar66 Exp $ /// /// </version> public class ContentResource : Resource { /// <summary>Default empty constructor /// </summary> public ContentResource() { } /// <summary>Pull in static content and store it /// </summary> public override bool Process() { try { StringWriter sw = new StringWriter(); //UPGRADE_ISSUE: The equivalent of constructor 'java.io.BufferedReader.BufferedReader' is incompatible with the expected type in C#. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1109"' StreamReader reader = new StreamReader(new StreamReader(resourceLoader.getResourceStream(name), System.Text.Encoding.GetEncoding(encoding)).BaseStream); char[] buf = new char[1024]; int len = 0; // -1 in java, 0 in .Net while ((len = reader.Read(buf, 0, 1024)) > 0) { sw.Write(buf, 0, len); } data = sw.ToString(); return true; } catch (Exception e) { rsvc.error("Cannot process content resource : " + e.ToString()); return false; } } } } --- NEW FILE: ResourceCacheImpl.cs --- namespace NVelocity.Runtime.Resource { using System; using System.Collections; /// <summary> Default implementation of the resource cache for the default /// ResourceManager. /// * /// </summary> /// <author> <a href="mailto:ge...@ap...">Geir Magnusson Jr.</a> /// </author> /// <author> <a href="mailto:dl...@fi...">Daniel Rall</a> /// </author> /// <version> $Id: ResourceCacheImpl.cs,v 1.5 2005/11/16 07:01:51 intesar66 Exp $ /// /// </version> public class ResourceCacheImpl : ResourceCache { /// <summary> /// Cache storage, assumed to be thread-safe. /// </summary> //UPGRADE_NOTE: The initialization of 'cache' was moved to method 'InitBlock'. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1005"' protected internal Hashtable cache = new Hashtable(); /// <summary> /// Runtime services, generally initialized by the /// <code>initialize()</code> method. /// </summary> protected internal RuntimeServices rsvc = null; public ResourceCacheImpl() { } public virtual void initialize(RuntimeServices rs) { rsvc = rs; rsvc.info("ResourceCache : initialized. (" + this.GetType() + ")"); } public virtual Resource get(Object key) { return (Resource) cache[key]; } public virtual Resource put(Object key, Resource value_Renamed) { Object o = cache[key]; cache[key] = value_Renamed; return (Resource) o; } public virtual Resource remove(Object key) { Object o = cache[key]; cache.Remove(key); return (Resource) o; } public virtual IEnumerator enumerateKeys() { return cache.Keys.GetEnumerator(); } } } --- NEW FILE: ResourceCache.cs --- namespace NVelocity.Runtime.Resource { using System; using System.Collections; /// <summary> Interface that defines the shape of a pluggable resource cache /// for the included ResourceManager /// * /// </summary> /// <author> <a href="mailto:ge...@op...">Geir Magnusson Jr.</a> /// </author> /// <version> $Id: ResourceCache.cs,v 1.5 2005/11/16 07:01:51 intesar66 Exp $ /// /// </version> public interface ResourceCache { /// <summary> initializes the ResourceCache. Will be /// called before any utilization /// * /// </summary> /// <param name="rs">RuntimeServices to use for logging, etc /// /// </param> void initialize(RuntimeServices rs); /// <summary> retrieves a Resource from the /// cache /// * /// </summary> /// <param name="resourceKey">key for Resource to be retrieved /// </param> /// <returns>Resource specified or null if not found /// /// </returns> Resource get(Object resourceKey); /// <summary> stores a Resource in the cache /// * /// </summary> /// <param name="resourceKey">key to associate with the Resource /// </param> /// <param name="resource">Resource to be stored /// </param> /// <returns>existing Resource stored under this key, or null if none /// /// </returns> Resource put(Object resourceKey, Resource resource); /// <summary> removes a Resource from the cache /// * /// </summary> /// <param name="resourceKey">resource to be removed /// </param> /// <param name="Resource">stored under key /// /// </param> Resource remove(Object resourceKey); /// <summary> returns an Iterator of Keys in the cache /// </summary> IEnumerator enumerateKeys(); } } --- NEW FILE: Resource.cs --- namespace NVelocity.Runtime.Resource { using System; using NVelocity.Runtime.Resource.Loader; /// <summary> This class represent a general text resource that /// may have been retrieved from any number of possible /// sources. /// * /// </summary> /// <author> <a href="mailto:jv...@ap...">Jason van Zyl</a> /// </author> /// <author> <a href="mailto:ge...@op...">Geir Magnusson Jr.</a> /// </author> /// <version> $Id: Resource.cs,v 1.5 2005/11/16 07:01:51 intesar66 Exp $ /// /// </version> public abstract class Resource { private void InitBlock() { encoding = RuntimeConstants_Fields.ENCODING_DEFAULT; } public virtual RuntimeServices RuntimeServices { set { rsvc = value; } } public virtual long ModificationCheckInterval { set { this.modificationCheckInterval = value; } } public virtual String Name { get { return name; } set { this.name = value; } } public virtual String Encoding { get { return encoding; } set { this.encoding = value; } } public virtual long LastModified { get { return lastModified; } set { this.lastModified = value; } } public virtual ResourceLoader ResourceLoader { get { return resourceLoader; } set { this.resourceLoader = value; } } public virtual Object Data { get { return data; } set { this.data = value; } } protected internal RuntimeServices rsvc = null; /// <summary> 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. /// </summary> protected internal ResourceLoader resourceLoader; /// <summary> The number of milliseconds in a minute, used to calculate the /// check interval. /// </summary> protected internal const long MILLIS_PER_SECOND = 1000; /// <summary> How often the file modification time is checked (in milliseconds). /// </summary> protected internal long modificationCheckInterval = 0; /// <summary> The file modification time (in milliseconds) for the cached template. /// </summary> protected internal long lastModified = 0; /// <summary> The next time the file modification time will be checked (in /// milliseconds). /// </summary> protected internal long nextCheck = 0; /// <summary> Name of the resource /// </summary> protected internal String name; /// <summary> Character encoding of this resource /// </summary> //UPGRADE_NOTE: The initialization of 'encoding' was moved to method 'InitBlock'. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1005"' protected internal String encoding; /// /// <summary> Resource might require ancillary storage of some kind /// </summary> protected internal Object data = null; /// /// <summary> Default constructor /// </summary> public Resource() { InitBlock(); } /// <summary> 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. /// </summary> public abstract bool Process(); public virtual bool IsSourceModified() { return resourceLoader.isSourceModified(this); } /// <summary> Set the modification check interval. /// </summary> /// <param name="interval">The interval (in minutes). /// /// </param> /// <summary> Is it time to check to see if the resource /// source has been updated? /// </summary> public virtual bool RequiresChecking() { /* * short circuit this if modificationCheckInterval == 0 * as this means "don't check" */ if (modificationCheckInterval <= 0) { return false; } /* * see if we need to check now */ return ((DateTime.Now.Ticks - 621355968000000000)/10000 >= nextCheck); } /// <summary> 'Touch' this template and thereby resetting /// the nextCheck field. /// </summary> public virtual void Touch() { nextCheck = (DateTime.Now.Ticks - 621355968000000000)/10000 + (MILLIS_PER_SECOND*modificationCheckInterval); } /// <summary> Set the name of this resource, for example /// test.vm. /// </summary> /// <summary> Get the name of this template. /// </summary> /// <summary> set the encoding of this resource /// for example, "ISO-8859-1" /// </summary> /// <summary> get the encoding of this resource /// for example, "ISO-8859-1" /// </summary> /// <summary> Return the lastModifed time of this /// template. /// </summary> /// <summary> Set the last modified time for this /// template. /// </summary> /// <summary> Return the template loader that pulled /// in the template stream /// </summary> /// <summary> Set the template loader for this template. Set /// when the Runtime determines where this template /// came from the list of possible sources. /// </summary> /// /// <summary> Set arbitrary data object that might be used /// by the resource. /// </summary> /// <summary> Get arbitrary data object that might be used /// by the resource. /// </summary> } } --- NEW FILE: ResourceManager.cs --- namespace NVelocity.Runtime.Resource { using System; /// <summary> Class to manage the text resource for the Velocity /// Runtime. /// * /// </summary> /// <author> <a href="mailto:jv...@ap...">Jason van Zyl</a> /// </author> /// <author> <a href="mailto:pau...@kr...">Paulo Gaspar</a> /// </author> /// <author> <a href="mailto:ge...@op...">Geir Magnusson Jr.</a> /// </author> /// <version> $Id: ResourceManager.cs,v 1.5 2005/11/16 07:01:51 intesar66 Exp $ /// /// </version> public struct ResourceManager_Fields { public const int RESOURCE_TEMPLATE = 1; public const int RESOURCE_CONTENT = 2; } public interface ResourceManager { //UPGRADE_NOTE: Members of interface 'ResourceManager' were extracted into structure 'ResourceManager_Fields'. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1045"' /// <summary> A template resources. /// </summary> /// <summary> A static content resource. /// </summary> /// <summary> Initialize the ResourceManager. It is assumed /// that assembleSourceInitializers() has been /// called before this is run. /// </summary> void initialize(RuntimeServices rs); /// <summary> Gets the named resource. Returned class type corresponds to specified type /// (i.e. <code>Template</code> to <code>RESOURCE_TEMPLATE</code>). /// * /// </summary> /// <param name="resourceName">The name of the resource to retrieve. /// </param> /// <param name="resourceType">The type of resource (<code>RESOURCE_TEMPLATE</code>, /// <code>RESOURCE_CONTENT</code>, etc.). /// </param> /// <param name="encoding"> The character encoding to use. /// </param> /// <returns>Resource with the template parsed and ready. /// @throws ResourceNotFoundException if template not found /// from any available source. /// @throws ParseErrorException if template cannot be parsed due /// to syntax (or other) error. /// @throws Exception if a problem in parse /// /// </returns> Resource getResource(String resourceName, int resourceType, String encoding); /// <summary> Determines is a template exists, and returns name of the loader that /// provides it. This is a slightly less hokey way to support /// the Velocity.templateExists() utility method, which was broken /// when per-template encoding was introduced. We can revisit this. /// * /// </summary> /// <param name="resourceName">Name of template or content resource /// </param> /// <returns>class name of loader than can provide it /// /// </returns> String getLoaderNameForResource(String resourceName); } } --- NEW FILE: ResourceManagerImpl.cs --- namespace NVelocity.Runtime.Resource { using System; using System.Collections; using System.IO; using Commons.Collections; using NVelocity.Exception; using NVelocity.Runtime.Resource.Loader; /// <summary> Class to manage the text resource for the Velocity /// Runtime. /// * /// </summary> /// <author> <a href="mailto:jv...@ap...">Jason van Zyl</a> /// </author> /// <author> <a href="mailto:pau...@kr...">Paulo Gaspar</a> /// </author> /// <author> <a href="mailto:ge...@op...">Geir Magnusson Jr.</a> /// </author> /// <version> $Id: ResourceManagerImpl.cs,v 1.5 2005/11/16 07:01:51 intesar66 Exp $ /// /// </version> public class ResourceManagerImpl : ResourceManager { public ResourceManagerImpl() { InitBlock(); } private void InitBlock() { resourceLoaders = new ArrayList(); sourceInitializerList = new ArrayList(); sourceInitializerMap = new Hashtable(); } /// <summary> A template resources. /// </summary> public const int RESOURCE_TEMPLATE = 1; /// <summary> A static content resource. /// </summary> public const int RESOURCE_CONTENT = 2; /// <summary> token used to identify the loader internally /// </summary> private const String RESOURCE_LOADER_IDENTIFIER = "_RESOURCE_LOADER_IDENTIFIER_"; /// <summary> Object implementing ResourceCache to /// be our resource manager's Resource cache. /// </summary> protected internal ResourceCache globalCache = null; /// <summary> The List of templateLoaders that the Runtime will /// use to locate the InputStream source of a template. /// </summary> //UPGRADE_NOTE: The initialization of 'resourceLoaders' was moved to method 'InitBlock'. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1005"' protected internal ArrayList resourceLoaders; /// <summary> This is a list of the template input stream source /// initializers, basically properties for a particular /// template stream source. The order in this list /// reflects numbering of the properties i.e. /// * /// <loader-id>.resource.loader.<property> = <value> /// </summary> //UPGRADE_NOTE: The initialization of 'sourceInitializerList' was moved to method 'InitBlock'. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1005"' private ArrayList sourceInitializerList; /// <summary> 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.resource.path property and this would /// change the resource.path property for the /// file template stream source. /// </summary> //UPGRADE_NOTE: The initialization of 'sourceInitializerMap' was moved to method 'InitBlock'. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1005"' private Hashtable sourceInitializerMap; /// <summary> Each loader needs a configuration object for /// its initialization, this flags keeps track of whether /// or not the configuration objects have been created /// for the resource loaders. /// </summary> private bool resourceLoaderInitializersActive = false; /// <summary> /// switch to turn off log notice when a resource is found for /// the first time. /// </summary> private bool logWhenFound = true; protected internal RuntimeServices rsvc = null; /// <summary> Initialize the ResourceManager. It is assumed /// that assembleSourceInitializers() has been /// called before this is run. /// </summary> public virtual void initialize(RuntimeServices rs) { rsvc = rs; rsvc.info("Default ResourceManager initializing. (" + this.GetType() + ")"); ResourceLoader resourceLoader; assembleResourceLoaderInitializers(); for (int i = 0; i < sourceInitializerList.Count; i++) { ExtendedProperties configuration = (ExtendedProperties) sourceInitializerList[i]; String loaderClass = configuration.GetString("class"); if (loaderClass == null) { rsvc.error("Unable to find '" + configuration.GetString(RESOURCE_LOADER_IDENTIFIER) + ".resource.loader.class' specification in configuation." + " This is a critical value. Please adjust configuration."); continue; } resourceLoader = ResourceLoaderFactory.getLoader(rsvc, loaderClass); resourceLoader.commonInit(rsvc, configuration); resourceLoader.init(configuration); resourceLoaders.Add(resourceLoader); } /* * now see if this is overridden by configuration */ logWhenFound = rsvc.getBoolean(RuntimeConstants_Fields.RESOURCE_MANAGER_LOGWHENFOUND, true); /* * now, is a global cache specified? */ String claz = rsvc.getString(RuntimeConstants_Fields.RESOURCE_MANAGER_CACHE_CLASS); Object o = null; if (claz != null && claz.Length > 0) { try { Type type = Type.GetType(claz); o = Activator.CreateInstance(type); } catch (Exception cnfe) { String err = "The specified class for ResourceCache (" + claz + ") does not exist (or is not accessible to the current classlaoder)."; rsvc.error(err); o = null; } if (!(o is ResourceCache)) { String err = "The specified class for ResourceCache (" + claz + ") does not implement NVelocity.Runtime.Resource.ResourceCache." + " Using default ResourceCache implementation."; rsvc.error(err); o = null; } } /* * if we didn't get through that, just use the default. */ if (o == null) { o = new ResourceCacheImpl(); } globalCache = (ResourceCache) o; globalCache.initialize(rsvc); rsvc.info("Default ResourceManager initialization complete."); } /// <summary> This will produce a List of Hashtables, each /// hashtable contains the intialization info for /// a particular resource loader. This Hastable /// will be passed in when initializing the /// the template loader. /// </summary> private void assembleResourceLoaderInitializers() { if (resourceLoaderInitializersActive) { return; } ArrayList resourceLoaderNames = rsvc.Configuration.GetVector(RuntimeConstants_Fields.RESOURCE_LOADER); for (int i = 0; i < resourceLoaderNames.Count; i++) { /* * The loader id might look something like the following: * * file.resource.loader * * The loader id is the prefix used for all properties * pertaining to a particular loader. */ String loaderID = resourceLoaderNames[i] + "." + RuntimeConstants_Fields.RESOURCE_LOADER; ExtendedProperties loaderConfiguration = rsvc.Configuration.Subset(loaderID); /* * we can't really count on ExtendedProperties to give us an empty set */ if (loaderConfiguration == null) { rsvc.warn("ResourceManager : No configuration information for resource loader named '" + resourceLoaderNames[i] + "'. Skipping."); continue; } /* * add the loader name token to the initializer if we need it * for reference later. We can't count on the user to fill * in the 'name' field */ loaderConfiguration.SetProperty(RESOURCE_LOADER_IDENTIFIER, resourceLoaderNames[i]); /* * Add resources to the list of resource loader * initializers. */ sourceInitializerList.Add(loaderConfiguration); } resourceLoaderInitializersActive = true; } /// <summary> Gets the named resource. Returned class type corresponds to specified type /// (i.e. <code>Template</code> to <code>RESOURCE_TEMPLATE</code>). /// * /// </summary> /// <param name="resourceName">The name of the resource to retrieve. /// </param> /// <param name="resourceType">The type of resource (<code>RESOURCE_TEMPLATE</code>, /// <code>RESOURCE_CONTENT</code>, etc.). /// </param> /// <param name="encoding"> The character encoding to use. /// </param> /// <returns>Resource with the template parsed and ready. /// @throws ResourceNotFoundException if template not found /// from any available source. /// @throws ParseErrorException if template cannot be parsed due /// to syntax (or other) error. /// @throws Exception if a problem in parse /// /// </returns> public virtual Resource getResource(String resourceName, int resourceType, String encoding) { /* * 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. */ Resource resource = globalCache.get(resourceName); if (resource != null) { /* * refresh the resource */ try { refreshResource(resource, encoding); } catch (ResourceNotFoundException rnfe) { /* * something exceptional happened to that resource * this could be on purpose, * so clear the cache and try again */ globalCache.remove(resourceName); return getResource(resourceName, resourceType, encoding); } catch (ParseErrorException pee) { rsvc.error("ResourceManager.getResource() exception: " + pee); throw pee; } catch (Exception eee) { rsvc.error("ResourceManager.getResource() exception: " + eee); throw eee; } } else { try { /* * it's not in the cache, so load it. */ resource = loadResource(resourceName, resourceType, encoding); if (resource.ResourceLoader.isCachingOn()) { globalCache.put(resourceName, resource); } } catch (ResourceNotFoundException rnfe2) { rsvc.error("ResourceManager : unable to find resource '" + resourceName + "' in any resource loader."); throw rnfe2; } catch (ParseErrorException pee) { rsvc.error("ResourceManager.getResource() parse exception: " + pee); throw pee; } catch (Exception ee) { rsvc.error("ResourceManager.getResource() exception new: " + ee); throw ee; } } return resource; } /// <summary> /// Loads a resource from the current set of resource loaders /// </summary> /// <param name="resourceName">The name of the resource to retrieve.</param> /// <param name="resourceType">The type of resource (<code>RESOURCE_TEMPLATE</code>, /// <code>RESOURCE_CONTENT</code>, etc.). /// </param> /// <param name="encoding"> The character encoding to use.</param> /// <returns>Resource with the template parsed and ready. /// @throws ResourceNotFoundException if template not found /// from any available source. /// @throws ParseErrorException if template cannot be parsed due /// to syntax (or other) error. /// @throws Exception if a problem in parse /// </returns> protected internal virtual Resource loadResource(String resourceName, int resourceType, String encoding) { Resource resource = ResourceFactory.getResource(resourceName, resourceType); resource.RuntimeServices = rsvc; resource.Name = resourceName; resource.Encoding = encoding; /* * 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. */ long howOldItWas = 0; // Initialize to avoid warnings ResourceLoader resourceLoader = null; for (int i = 0; i < resourceLoaders.Count; i++) { resourceLoader = (ResourceLoader) resourceLoaders[i]; resource.ResourceLoader = resourceLoader; /* * catch the ResourceNotFound exception * as that is ok in our new multi-loader environment */ try { if (resource.Process()) { /* * FIXME (gmj) * moved in here - technically still * a problem - but the resource needs to be * processed before the loader can figure * it out due to to the new * multi-path support - will revisit and fix */ if (logWhenFound) { rsvc.info("ResourceManager : found " + resourceName + " with loader " + resourceLoader.ClassName); } howOldItWas = resourceLoader.getLastModified(resource); break; } } catch (ResourceNotFoundException rnfe) { /* * that's ok - it's possible to fail in * multi-loader environment */ } } /* * Return null if we can't find a resource. */ if (resource.Data == null) { throw new ResourceNotFoundException("Unable to find resource '" + resourceName + "'"); } /* * some final cleanup */ resource.LastModified = howOldItWas; resource.ModificationCheckInterval = resourceLoader.ModificationCheckInterval; resource.Touch(); return resource; } /// <summary> Takes an existing resource, and 'refreshes' it. This /// generally means that the source of the resource is checked /// for changes according to some cache/check algorithm /// and if the resource changed, then the resource data is /// reloaded and re-parsed. /// * /// </summary> /// <param name="resource">resource to refresh /// * /// @throws ResourceNotFoundException if template not found /// from current source for this Resource /// @throws ParseErrorException if template cannot be parsed due /// to syntax (or other) error. /// @throws Exception if a problem in parse /// /// </param> protected internal virtual void refreshResource(Resource resource, String encoding) { /* * 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()) { /* * touch() the resource to reset the counters */ resource.Touch(); if (resource.IsSourceModified()) { /* * now check encoding info. It's possible that the newly declared * encoding is different than the encoding already in the resource * this strikes me as bad... */ if (!resource.Encoding.Equals(encoding)) { rsvc.error("Declared encoding for template '" + resource.Name + "' is different on reload. Old = '" + resource.Encoding + "' New = '" + encoding); resource.Encoding = encoding; } /* * read how old the resource is _before_ * processing (=>reading) it */ long howOldItWas = resource.ResourceLoader.getLastModified(resource); /* * read in the fresh stream and parse */ resource.Process(); /* * now set the modification info and reset * the modification check counters */ resource.LastModified = howOldItWas; } } } /// <summary> Gets the named resource. Returned class type corresponds to specified type /// (i.e. <code>Template</code> to <code>RESOURCE_TEMPLATE</code>). /// * /// </summary> /// <param name="resourceName">The name of the resource to retrieve. /// </param> /// <param name="resourceType">The type of resource (<code>RESOURCE_TEMPLATE</code>, /// <code>RESOURCE_CONTENT</code>, etc.). /// </param> /// <returns>Resource with the template parsed and ready. /// @throws ResourceNotFoundException if template not found /// from any available source. /// @throws ParseErrorException if template cannot be parsed due /// to syntax (or other) error. /// @throws Exception if a problem in parse /// * /// </returns> /// <deprecated>Use /// {@link #getResource(String resourceName, int resourceType, /// String encoding )} /// /// </deprecated> public virtual Resource getResource(String resourceName, int resourceType) { return getResource(resourceName, resourceType, RuntimeConstants_Fields.ENCODING_DEFAULT); } /// <summary> Determines is a template exists, and returns name of the loader that /// provides it. This is a slightly less hokey way to support /// the Velocity.templateExists() utility method, which was broken /// when per-template encoding was introduced. We can revisit this. /// * /// </summary> /// <param name="resourceName">Name of template or content resource /// </param> /// <returns>class name of loader than can provide it /// /// </returns> public virtual String getLoaderNameForResource(String resourceName) { ResourceLoader resourceLoader = null; /* * loop through our loaders... */ for (int i = 0; i < resourceLoaders.Count; i++) { resourceLoader = (ResourceLoader) resourceLoaders[i]; Stream is_Renamed = null; /* * if we find one that can provide the resource, * return the name of the loaders's Class */ try { is_Renamed = resourceLoader.getResourceStream(resourceName); if (is_Renamed != null) { return resourceLoader.GetType().ToString(); } } catch (ResourceNotFoundException e) { /* * this isn't a problem. keep going */ } finally { /* * if we did find one, clean up because we were * returned an open stream */ if (is_Renamed != null) { try { is_Renamed.Close(); } catch (IOException ioe) { } } } } return null; } } } |