/// <summary> This initialization is used by all resource /// loaders and must be called to set up common /// properties shared by all resource loaders /// </summary> /// <param name="rs"> /// </param> /// <param name="configuration"> /// </param> public virtual void CommonInit(IRuntimeServices rs, ExtendedProperties configuration) { this.rsvc = rs; this.log = rsvc.Log; /* * these two properties are not required for all loaders. * For example, for ClasspathLoader, what would cache mean? * so adding default values which I think are the safest * * don't cache, and modCheckInterval irrelevant... */ try { isCachingOn = configuration.GetBoolean("cache", false); } catch (System.Exception e) { isCachingOn = false; string msg = "Exception parsing cache setting: " + configuration.GetString("cache"); log.Error(msg, e); throw new VelocityException(msg, e); } try { modificationCheckInterval = configuration.GetLong("modificationCheckInterval", 0); } catch (System.Exception e) { modificationCheckInterval = 0; string msg = "Exception parsing modificationCheckInterval setting: " + configuration.GetString("modificationCheckInterval"); log.Error(msg, e); throw new VelocityException(msg, e); } /* * this is a must! */ className = typeof(ResourceCacheImpl).FullName; try { className = configuration.GetString("class", className); } catch (System.Exception e) { string msg = "Exception retrieving resource cache class name"; log.Error(msg, e); throw new VelocityException(msg, e); } }
/// <summary> Check whether any given resource exists. This is not really /// a very efficient test and it can and should be overridden in the /// subclasses extending ResourceLoader. /// /// </summary> /// <param name="resourceName">The name of a resource. /// </param> /// <returns> true if a resource exists and can be accessed. /// </returns> /// <since> 1.6 /// </since> public virtual bool ResourceExists(string resourceName) { System.IO.Stream is_Renamed = null; try { is_Renamed = GetResourceStream(resourceName); } catch (ResourceNotFoundException e) { if (log.DebugEnabled) { log.Debug("Could not load resource '" + resourceName + "' from ResourceLoader " + this.GetType().FullName + ": ", e); } } finally { try { if (is_Renamed != null) { is_Renamed.Close(); } } catch (System.Exception e) { if (log.ErrorEnabled) { string msg = "While closing InputStream for resource '" + resourceName + "' from ResourceLoader " + this.GetType().FullName; log.Error(msg, e); throw new VelocityException(msg, e); } } } return(is_Renamed != null); }
/// <summary> Initialize the ResourceManager. /// /// </summary> /// <param name="rsvc"> The Runtime Services object which is associated with this Resource Manager. /// /// </param> /// <throws> Exception </throws> public virtual void Initialize(IRuntimeServices rsvc) { lock (syncOjb) { if (isInit) { log.Debug("Re-initialization of ResourceLoader attempted and ignored."); return; } ResourceLoader resourceLoader = null; this.rsvc = rsvc; log = rsvc.Log; log.Trace("Default ResourceManager initializing. (" + this.GetType() + ")"); AssembleResourceLoaderInitializers(); for (IEnumerator it = sourceInitializerList.GetEnumerator(); it.MoveNext();) { /** * Resource loader can be loaded either via class name or be passed * in as an instance. */ ExtendedProperties configuration = (ExtendedProperties)it.Current; string loaderClass = StringUtils.NullTrim(configuration.GetString("class")); ResourceLoader loaderInstance = (ResourceLoader)configuration["instance"]; if (loaderInstance != null) { resourceLoader = loaderInstance; } else if (loaderClass != null) { resourceLoader = ResourceLoaderFactory.GetLoader(rsvc, loaderClass); } else { string msg = "Unable to find '" + configuration.GetString(RESOURCE_LOADER_IDENTIFIER) + ".resource.loader.class' specification in configuration." + " This is a critical value. Please adjust configuration."; log.Error(msg); throw new System.Exception(msg); } resourceLoader.CommonInit(rsvc, configuration); resourceLoader.Init(configuration); resourceLoaders.Add(resourceLoader); } /* * now see if this is overridden by configuration */ logWhenFound = rsvc.GetBoolean(NVelocity.Runtime.RuntimeConstants.RESOURCE_MANAGER_LOGWHENFOUND, true); /* * now, is a global cache specified? */ string cacheClassName = rsvc.GetString(RuntimeConstants.RESOURCE_MANAGER_CACHE_CLASS); object cacheObject = null; if (!string.IsNullOrEmpty(cacheClassName)) { try { cacheObject = System.Activator.CreateInstance(Type.GetType(cacheClassName.Replace(';', ','))); } catch (System.Exception cnfe) { string msg = "The specified class for ResourceCache (" + cacheClassName + ") does not exist or is not accessible to the current classloader."; log.Error(msg, cnfe); throw cnfe; } if (!(cacheObject is IResourceCache)) { string msg = "The specified resource cache class (" + cacheClassName + ") must implement " + typeof(IResourceCache).FullName; log.Error(msg); throw new System.SystemException(msg); } } /* * if we didn't Get through that, just use the default. */ if (cacheObject == null) { cacheObject = new ResourceCacheImpl(); } globalCache = (IResourceCache)cacheObject; globalCache.Initialize(rsvc); log.Trace("Default ResourceManager initialization complete."); } }
/// <summary> Gets the named resource. Returned class type corresponds to specified type (i.e. <code>Template</code> to <code> /// RESOURCE_TEMPLATE</code>). /// /// This method is now unsynchronized which requires that ResourceCache /// implementations be thread safe (as the default is). /// /// </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. /// /// </returns> /// <throws> ResourceNotFoundException if template not found from any available source. </throws> /// <throws> ParseErrorException if template cannot be parsed due to syntax (or other) Error. </throws> /// <throws> Exception if a problem in parse </throws> 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. * * Note: the type is included in the key to differentiate ContentResource * (static content from #include) with a Template. */ string resourceKey = resourceType + resourceName; Resource resource = globalCache.Get(resourceKey); if (resource != null) { try { // avoids additional method call to refreshResource if (resource.RequiresChecking()) { /* * both loadResource() and refreshResource() now return * a new Resource instance when they are called * (Put in the cache when appropriate) in order to allow * several threads to parse the same template simultaneously. * It is redundant work and will cause more garbage collection but the * benefit is that it allows concurrent parsing and processing * without race conditions when multiple requests try to * refresh/load the same template at the same time. * * Another alternative is to limit template parsing/retrieval * so that only one thread can parse each template at a time * but that creates a scalability bottleneck. * * See VELOCITY-606, VELOCITY-595 and VELOCITY-24 */ resource = RefreshResource(resource, encoding); } } catch (ResourceNotFoundException) { /* * something exceptional happened to that resource * this could be on purpose, * so clear the cache and try again */ globalCache.Remove(resourceKey); return(GetResource(resourceName, resourceType, encoding)); } catch (ParseErrorException pee) { log.Error("ResourceManager.getResource() exception", pee); throw pee; } catch (System.SystemException re) { log.Error("ResourceManager.getResource() exception", re); throw re; } catch (System.Exception e) { log.Error("ResourceManager.getResource() exception", e); throw e; } } else { try { /* * it's not in the cache, so load it. */ resource = LoadResource(resourceName, resourceType, encoding); if (resource.ResourceLoader.CachingOn) { globalCache.Put(resourceKey, resource); } } catch (ResourceNotFoundException rnfe) { log.Error("ResourceManager : unable to find resource '" + resourceName + "' in any resource loader."); throw rnfe; } catch (ParseErrorException pee) { log.Error("ResourceManager.getResource() parse exception", pee); throw pee; } catch (System.SystemException re) { log.Error("ResourceManager.getResource() load exception", re); throw re; } catch (System.Exception e) { log.Error("ResourceManager.getResource() exception new", e); throw e; } } return(resource); }