in velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/ResourceManagerImpl.java [278:371]
public Resource getResource(final String resourceName, final int resourceType, final String encoding)
throws ResourceNotFoundException,
ParseErrorException
{
/*
* 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 rnfe)
{
/*
* 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 (RuntimeException re)
{
log.error("ResourceManager.getResource() exception", re);
throw re;
}
}
else
{
try
{
/*
* it's not in the cache, so load it.
*/
resource = loadResource(resourceName, resourceType, encoding);
if (resource.getResourceLoader().isCachingOn())
{
globalCache.put(resourceKey, resource);
}
}
catch (ResourceNotFoundException rnfe)
{
log.error("ResourceManager: unable to find resource '{}' in any resource loader.", resourceName);
throw rnfe;
}
catch (ParseErrorException pee)
{
log.error("ResourceManager: parse exception: {}", pee.getMessage());
throw pee;
}
catch (RuntimeException re)
{
log.error("ResourceManager.getResource() load exception", re);
throw re;
}
}
return resource;
}