Revamped site-specific resource loading to work without requiring a modified
version of Velocity. We still maintain a modified version because we want to be able to access object fields directly instead of requiring getter/setter methods, but with the other requirement gone normal people can compile and use Samskivert with the stock Velocity distribution and not have to worry. It also makes it vastly easier for us to keep up with the latest version of Velocity. git-svn-id: https://samskivert.googlecode.com/svn/trunk@1739 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
Binary file not shown.
@@ -241,6 +241,7 @@ public class DispatcherServlet extends VelocityServlet
|
|||||||
Log.info("Velocity loading templates from site loader.");
|
Log.info("Velocity loading templates from site loader.");
|
||||||
props.setProperty(RuntimeSingleton.RESOURCE_MANAGER_CLASS,
|
props.setProperty(RuntimeSingleton.RESOURCE_MANAGER_CLASS,
|
||||||
SiteResourceManager.class.getName());
|
SiteResourceManager.class.getName());
|
||||||
|
_usingSiteLoading = true;
|
||||||
} else {
|
} else {
|
||||||
// otherwise use a servlet context resource loader
|
// otherwise use a servlet context resource loader
|
||||||
Log.info("Velocity loading templates from servlet context.");
|
Log.info("Velocity loading templates from servlet context.");
|
||||||
@@ -287,7 +288,9 @@ public class DispatcherServlet extends VelocityServlet
|
|||||||
// context
|
// context
|
||||||
SiteIdentifier ident = _app.getSiteIdentifier();
|
SiteIdentifier ident = _app.getSiteIdentifier();
|
||||||
int siteId = ident.identifySite(req);
|
int siteId = ident.identifySite(req);
|
||||||
ctx.put("__siteid__", new Integer(siteId));
|
if (_usingSiteLoading) {
|
||||||
|
ctx.put("__siteid__", new Integer(siteId));
|
||||||
|
}
|
||||||
|
|
||||||
// put the context path in the context as well to make it easier
|
// put the context path in the context as well to make it easier
|
||||||
// to construct full paths
|
// to construct full paths
|
||||||
@@ -434,13 +437,14 @@ public class DispatcherServlet extends VelocityServlet
|
|||||||
protected Template selectTemplate (int siteId, InvocationContext ctx)
|
protected Template selectTemplate (int siteId, InvocationContext ctx)
|
||||||
throws ResourceNotFoundException, ParseErrorException, Exception
|
throws ResourceNotFoundException, ParseErrorException, Exception
|
||||||
{
|
{
|
||||||
// create a site resource key based on the template path and the
|
|
||||||
// id of the site through which this request was made
|
|
||||||
String path = ctx.getRequest().getServletPath();
|
String path = ctx.getRequest().getServletPath();
|
||||||
SiteResourceKey key = new SiteResourceKey(siteId, path);
|
if (_usingSiteLoading) {
|
||||||
|
// if we're using site resource loading, we need to prefix the path
|
||||||
// Log.info("Loading template [key=" + key + "].");
|
// with the site identifier
|
||||||
return RuntimeSingleton.getRuntimeServices().getTemplate(key);
|
path = siteId + ":" + path;
|
||||||
|
}
|
||||||
|
// Log.info("Loading template [path=" + path + "].");
|
||||||
|
return RuntimeSingleton.getRuntimeServices().getTemplate(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -493,6 +497,9 @@ public class DispatcherServlet extends VelocityServlet
|
|||||||
/** The character set in which serve our responses. */
|
/** The character set in which serve our responses. */
|
||||||
protected String _charset;
|
protected String _charset;
|
||||||
|
|
||||||
|
/** Set to true if we're using the {@link SiteResourceLoader}. */
|
||||||
|
protected boolean _usingSiteLoading;
|
||||||
|
|
||||||
/** This is the key used in the context for error messages. */
|
/** This is the key used in the context for error messages. */
|
||||||
protected static final String ERROR_KEY = "error";
|
protected static final String ERROR_KEY = "error";
|
||||||
|
|
||||||
|
|||||||
@@ -72,13 +72,13 @@ public class ImportDirective extends Directive
|
|||||||
MethodInvocationException
|
MethodInvocationException
|
||||||
{
|
{
|
||||||
// make sure an argument was supplied to the directive
|
// make sure an argument was supplied to the directive
|
||||||
if (node.jjtGetChild(0) == null) {
|
if (node.getChild(0) == null) {
|
||||||
rsvc.error("#import() error : null argument");
|
rsvc.error("#import() error : null argument");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure that argument has a value
|
// make sure that argument has a value
|
||||||
Object value = node.jjtGetChild(0).value(context);
|
Object value = node.getChild(0).value(context);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
rsvc.error("#import() error : null argument");
|
rsvc.error("#import() error : null argument");
|
||||||
return false;
|
return false;
|
||||||
@@ -109,27 +109,29 @@ public class ImportDirective extends Directive
|
|||||||
rsvc.getProperty(RuntimeConstants.INPUT_ENCODING);
|
rsvc.getProperty(RuntimeConstants.INPUT_ENCODING);
|
||||||
}
|
}
|
||||||
|
|
||||||
// construct the template key based on the desired path and the
|
// adjust the template path with the site information in the current
|
||||||
// site information in the current context. the siteid was shoved
|
// context if available. the siteid is shoved into the context by the
|
||||||
// into the context by the dispatcher servlet. this is a hack, i
|
// dispatcher servlet when we're using the site resource loader. this
|
||||||
// know, but i couldn't convince the velocity peeps that we should
|
// is a hack, i know, but i couldn't convince the velocity peeps that
|
||||||
// have access to a request context in places like this
|
// we should have access to a request context in places like this
|
||||||
Object siteIdVal = context.get("__siteid__");
|
Object siteIdVal = context.get("__siteid__");
|
||||||
int siteId = SiteIdentifier.DEFAULT_SITE_ID;
|
if (siteIdVal != null) {
|
||||||
try {
|
int siteId = SiteIdentifier.DEFAULT_SITE_ID;
|
||||||
siteId = ((Integer)siteIdVal).intValue();
|
try {
|
||||||
} catch (Exception e) {
|
siteId = ((Integer)siteIdVal).intValue();
|
||||||
rsvc.error("#import() error: No siteId information in context.");
|
} catch (Exception e) {
|
||||||
|
rsvc.error("#import() error: No siteId information in context.");
|
||||||
|
}
|
||||||
|
path = siteId + ":" + path;
|
||||||
}
|
}
|
||||||
Object tkey = new SiteResourceKey(siteId, path);
|
|
||||||
|
|
||||||
// locate the requested template
|
// locate the requested template
|
||||||
Template t = null;
|
Template t = null;
|
||||||
try {
|
try {
|
||||||
t = rsvc.getTemplate(tkey, encoding);
|
t = rsvc.getTemplate(path, encoding);
|
||||||
|
|
||||||
} catch (ResourceNotFoundException rnfe) {
|
} catch (ResourceNotFoundException rnfe) {
|
||||||
rsvc.error("#import(): cannot find template '" + tkey +
|
rsvc.error("#import(): cannot find template '" + path +
|
||||||
"', called from template " +
|
"', called from template " +
|
||||||
context.getCurrentTemplateName() +
|
context.getCurrentTemplateName() +
|
||||||
" at (" + getLine() + ", " + getColumn() + ")");
|
" at (" + getLine() + ", " + getColumn() + ")");
|
||||||
@@ -137,13 +139,13 @@ public class ImportDirective extends Directive
|
|||||||
|
|
||||||
} catch (ParseErrorException pee) {
|
} catch (ParseErrorException pee) {
|
||||||
rsvc.error("#import(): syntax error in #import()-ed template '" +
|
rsvc.error("#import(): syntax error in #import()-ed template '" +
|
||||||
tkey + "', called from template " +
|
path + "', called from template " +
|
||||||
context.getCurrentTemplateName() +
|
context.getCurrentTemplateName() +
|
||||||
" at (" + getLine() + ", " + getColumn() + ")");
|
" at (" + getLine() + ", " + getColumn() + ")");
|
||||||
throw pee;
|
throw pee;
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
rsvc.error("#import(): Error [path=" + tkey +
|
rsvc.error("#import(): Error [path=" + path +
|
||||||
", error=" + e + "].");
|
", error=" + e + "].");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -65,14 +65,14 @@ public class ServletContextResourceManager extends ResourceManagerImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Resource loadResource(
|
protected Resource loadResource(
|
||||||
Object resourceKey, int resourceType, String encoding)
|
String resourceName, int resourceType, String encoding)
|
||||||
throws ResourceNotFoundException, ParseErrorException, Exception
|
throws ResourceNotFoundException, ParseErrorException, Exception
|
||||||
{
|
{
|
||||||
// create a blank new resource
|
// create a blank new resource
|
||||||
Resource resource =
|
Resource resource =
|
||||||
ResourceFactory.getResource(resourceKey, resourceType);
|
ResourceFactory.getResource(resourceName, resourceType);
|
||||||
resource.setRuntimeServices(rsvc);
|
resource.setRuntimeServices(rsvc);
|
||||||
resource.setKey(resourceKey);
|
resource.setName(resourceName);
|
||||||
resource.setEncoding(encoding);
|
resource.setEncoding(encoding);
|
||||||
|
|
||||||
resource.setResourceLoader(_contextLoader);
|
resource.setResourceLoader(_contextLoader);
|
||||||
|
|||||||
@@ -63,29 +63,24 @@ public class SiteJarResourceLoader extends ResourceLoader
|
|||||||
* Returns the input stream that can be used to load the named
|
* Returns the input stream that can be used to load the named
|
||||||
* resource.
|
* resource.
|
||||||
*
|
*
|
||||||
* @param resourceKey the locator key for the resource to be loaded.
|
* @param path the path for the resource to be loaded.
|
||||||
*
|
*
|
||||||
* @return an input stream that can be used to read the resource.
|
* @return an input stream that can be used to read the resource.
|
||||||
*
|
*
|
||||||
* @exception ResourceNotFoundException if the resource was not found.
|
* @exception ResourceNotFoundException if the resource was not found.
|
||||||
*/
|
*/
|
||||||
public InputStream getResourceStream (Object resourceKey)
|
public InputStream getResourceStream (String path)
|
||||||
throws ResourceNotFoundException
|
throws ResourceNotFoundException
|
||||||
{
|
{
|
||||||
SiteResourceKey skey = castKey(resourceKey);
|
SiteKey skey = new SiteKey(path);
|
||||||
if (skey == null) {
|
|
||||||
String errmsg = "Cannot use SiteResourceLoader without " +
|
|
||||||
"loading resources with SiteResourceKey instances.";
|
|
||||||
throw new ResourceNotFoundException(errmsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// load it on up
|
// load it on up
|
||||||
try {
|
try {
|
||||||
InputStream stream = _loader.getResourceAsStream(
|
InputStream stream = _loader.getResourceAsStream(
|
||||||
skey.getSiteId(), skey.getPath());
|
skey.siteId, skey.path);
|
||||||
if (stream == null) {
|
if (stream == null) {
|
||||||
String errmsg = "Unable to load resource via " +
|
String errmsg = "Unable to load resource via " +
|
||||||
"site-specific jar file [key=" + skey + "].";
|
"site-specific jar file [path=" + path + "].";
|
||||||
throw new ResourceNotFoundException(errmsg);
|
throw new ResourceNotFoundException(errmsg);
|
||||||
}
|
}
|
||||||
return stream;
|
return stream;
|
||||||
@@ -97,33 +92,27 @@ public class SiteJarResourceLoader extends ResourceLoader
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Things won't ever be modified when loaded from the servlet context
|
* Things won't ever be modified when loaded from the servlet context
|
||||||
* because they came from the webapp .war file and if that is
|
* because they came from the webapp .war file and if that is reloaded,
|
||||||
* reloaded, everything will be thrown away and started afresh.
|
* everything will be thrown away and started afresh.
|
||||||
*/
|
*/
|
||||||
public boolean isSourceModified (Resource resource)
|
public boolean isSourceModified (Resource resource)
|
||||||
{
|
{
|
||||||
SiteResourceKey skey = castKey(resource.getKey());
|
SiteKey skey = new SiteKey(resource.getName());
|
||||||
if (skey == null) {
|
|
||||||
// return false if we were supplied with a bogus key
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the resource is for the default site, it is never considered
|
// if the resource is for the default site, it is never considered to
|
||||||
// to be modified
|
// be modified
|
||||||
int siteId = skey.getSiteId();
|
if (skey.siteId == SiteIdentifier.DEFAULT_SITE_ID) {
|
||||||
if (siteId == SiteIdentifier.DEFAULT_SITE_ID) {
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// otherwise compare the last modified time of the loaded
|
// otherwise compare the last modified time of the loaded resource
|
||||||
// resource with the last modified time of the associated
|
// with that of the associated site-specific jar file
|
||||||
// site-specific jar file
|
|
||||||
try {
|
try {
|
||||||
return (resource.getLastModified() <
|
return (resource.getLastModified() <
|
||||||
_loader.getLastModified(siteId));
|
_loader.getLastModified(skey.siteId));
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
Log.warning("Failure obtaining last modified time of " +
|
Log.warning("Failure obtaining last modified time of " +
|
||||||
"site-specific jar file [siteId=" + siteId +
|
"site-specific jar file [siteId=" + skey.siteId +
|
||||||
", error=" + ioe + "].");
|
", error=" + ioe + "].");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -132,49 +121,33 @@ public class SiteJarResourceLoader extends ResourceLoader
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Things won't ever be modified when loaded from the servlet context
|
* Things won't ever be modified when loaded from the servlet context
|
||||||
* because they came from the webapp .war file and if that is
|
* because they came from the webapp .war file and if that is reloaded,
|
||||||
* reloaded, everything will be thrown away and started afresh. So we
|
* everything will be thrown away and started afresh. So we can punt here
|
||||||
* can punt here and return zero.
|
* and return zero.
|
||||||
*/
|
*/
|
||||||
public long getLastModified (Resource resource)
|
public long getLastModified (Resource resource)
|
||||||
{
|
{
|
||||||
SiteResourceKey skey = castKey(resource.getKey());
|
SiteKey skey = new SiteKey(resource.getName());
|
||||||
if (skey == null) {
|
|
||||||
// return 0 if we were supplied with a bogus key
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the resource is for the default site, it is never considered
|
// if the resource is for the default site, it is never considered to
|
||||||
// to be modified
|
// be modified
|
||||||
int siteId = skey.getSiteId();
|
if (skey.siteId == SiteIdentifier.DEFAULT_SITE_ID) {
|
||||||
if (siteId == SiteIdentifier.DEFAULT_SITE_ID) {
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// otherwise return the last modified time of the associated
|
// otherwise return the last modified time of the associated
|
||||||
// site-specific jar file
|
// site-specific jar file
|
||||||
try {
|
try {
|
||||||
return _loader.getLastModified(siteId);
|
return _loader.getLastModified(skey.siteId);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
Log.warning("Failure obtaining last modified time of " +
|
Log.warning("Failure obtaining last modified time of " +
|
||||||
"site-specific jar file [siteId=" + siteId +
|
"site-specific jar file [siteId=" + skey.siteId +
|
||||||
", error=" + ioe + "].");
|
", error=" + ioe + "].");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** The site resource loader through which we'll load things. */
|
||||||
* Casts the supplied resource key to a {@link SiteResourceKey} and
|
|
||||||
* returns it iff it is an instance of such. Returns null otherwise.
|
|
||||||
*/
|
|
||||||
protected SiteResourceKey castKey (Object resourceKey)
|
|
||||||
{
|
|
||||||
return (resourceKey instanceof SiteResourceKey) ?
|
|
||||||
(SiteResourceKey)resourceKey : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** A reference to the site resource loader through which we'll load
|
|
||||||
* things. */
|
|
||||||
protected SiteResourceLoader _loader;
|
protected SiteResourceLoader _loader;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
//
|
||||||
|
// samskivert library - useful routines for java programs
|
||||||
|
// Copyright (C) 2001-2004 Michael Bayne
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it
|
||||||
|
// under the terms of the GNU Lesser General Public License as published
|
||||||
|
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
package com.samskivert.velocity;
|
||||||
|
|
||||||
|
import com.samskivert.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes a compound Velocity resource name plus site identifier.
|
||||||
|
*/
|
||||||
|
public class SiteKey
|
||||||
|
{
|
||||||
|
/** The site identifier associated with this path or -1 if no site
|
||||||
|
* identifier was specified in the path. */
|
||||||
|
public int siteId = -1;
|
||||||
|
|
||||||
|
/** The resource path. */
|
||||||
|
public String path;
|
||||||
|
|
||||||
|
public SiteKey (String path)
|
||||||
|
{
|
||||||
|
int cidx = path.indexOf(":");
|
||||||
|
if (cidx == -1) {
|
||||||
|
this.path = path;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
siteId = Integer.parseInt(path.substring(0, cidx));
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.warning("Invalid site path [path=" + path + "].");
|
||||||
|
}
|
||||||
|
this.path = path.substring(cidx+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,180 +0,0 @@
|
|||||||
//
|
|
||||||
// $Id: SiteResourceKey.java,v 1.1 2001/11/06 04:49:32 mdb Exp $
|
|
||||||
//
|
|
||||||
// samskivert library - useful routines for java programs
|
|
||||||
// Copyright (C) 2001 Michael Bayne
|
|
||||||
//
|
|
||||||
// This library is free software; you can redistribute it and/or modify it
|
|
||||||
// under the terms of the GNU Lesser General Public License as published
|
|
||||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public
|
|
||||||
// License along with this library; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
package com.samskivert.velocity;
|
|
||||||
|
|
||||||
import com.samskivert.servlet.SiteIdentifier;
|
|
||||||
import com.samskivert.util.IntListUtil;
|
|
||||||
import com.samskivert.util.StringUtil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The site resource key is used as a key for resources that can be used
|
|
||||||
* for one or more sites. A resource always has the same path, but can be
|
|
||||||
* valid for a single site, or multiple sites and the set of sites for
|
|
||||||
* which a resource is valid can change without impacting the key's hash
|
|
||||||
* value.
|
|
||||||
*/
|
|
||||||
public class SiteResourceKey
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Constructs a new site resource key for the specified resource,
|
|
||||||
* loaded via the specified site.
|
|
||||||
*/
|
|
||||||
public SiteResourceKey (int siteId, String path)
|
|
||||||
{
|
|
||||||
_path = path;
|
|
||||||
_sites = new int[] { siteId };
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resource keys that contain only a single site id will return that
|
|
||||||
* site id as their primary. Those that contain multiple sites are
|
|
||||||
* assumed to reference default resources (which may be applicable to
|
|
||||||
* multiple sites) in which case the default site id is returned.
|
|
||||||
*/
|
|
||||||
public int getSiteId ()
|
|
||||||
{
|
|
||||||
return (_sites.length == 1 ? _sites[0] :
|
|
||||||
SiteIdentifier.DEFAULT_SITE_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the path to the resource referenced by this site resource
|
|
||||||
* key.
|
|
||||||
*/
|
|
||||||
public String getPath ()
|
|
||||||
{
|
|
||||||
return _path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if this resource key contains the specified site in
|
|
||||||
* its site set.
|
|
||||||
*/
|
|
||||||
public boolean containsSite (int siteId)
|
|
||||||
{
|
|
||||||
return IntListUtil.contains(_sites, siteId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a site to this site resource key. The resource to which this
|
|
||||||
* key maps is assumed to be valid for the added site.
|
|
||||||
*/
|
|
||||||
public void addSite (int siteId)
|
|
||||||
{
|
|
||||||
// sanity check
|
|
||||||
if (siteId == 0) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Site IDs cannot have the value 0.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the site to the list only if it's not already there
|
|
||||||
int[] sites = IntListUtil.testAndAdd(_sites, siteId);
|
|
||||||
if (sites != null) {
|
|
||||||
_sites = sites;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes a site from this site resource key. The resource to which
|
|
||||||
* this key maps is no longer assumed to be valid for the removed
|
|
||||||
* site.
|
|
||||||
*/
|
|
||||||
public boolean removeSite (int siteId)
|
|
||||||
{
|
|
||||||
// sanity check
|
|
||||||
if (siteId == 0) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Site IDs cannot have the value 0.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove the site from the list
|
|
||||||
return (IntListUtil.remove(_sites, siteId) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We hash to the hash value of our path.
|
|
||||||
*/
|
|
||||||
public int hashCode ()
|
|
||||||
{
|
|
||||||
return _path.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Two site resource keys are equal if the paths are the same and at
|
|
||||||
* least one site id overlaps between the two keys. Most equality
|
|
||||||
* comparisons will involve one multi-site key and one key that
|
|
||||||
* contains only a single site.
|
|
||||||
*/
|
|
||||||
public boolean equals (Object other)
|
|
||||||
{
|
|
||||||
if (other instanceof SiteResourceKey) {
|
|
||||||
SiteResourceKey okey = (SiteResourceKey)other;
|
|
||||||
|
|
||||||
// make sure the paths match
|
|
||||||
if (!_path.equals(okey._path)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// select the key with fewer sites in its sites array to be in
|
|
||||||
// the outer loop
|
|
||||||
int[] s1 = _sites;
|
|
||||||
int[] s2 = okey._sites;
|
|
||||||
if (s2.length < s1.length) {
|
|
||||||
s1 = s2;
|
|
||||||
s2 = _sites;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i1 = 0; i1 < s1.length; i1++) {
|
|
||||||
for (int i2 = 0; i2 < s2.length; i2++) {
|
|
||||||
if (s1[i1] == s2[i2]) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The string representation of a resource key is just the path so
|
|
||||||
* that it is backwards compatible with older resource loaders.
|
|
||||||
*/
|
|
||||||
public String toString ()
|
|
||||||
{
|
|
||||||
return _path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a string description of this object.
|
|
||||||
*/
|
|
||||||
public String description ()
|
|
||||||
{
|
|
||||||
return ("[path=" + _path +
|
|
||||||
", sites=" + StringUtil.toString(_sites) + "]");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The path to the resource. */
|
|
||||||
protected String _path;
|
|
||||||
|
|
||||||
/** The sites for which this resource is valid. */
|
|
||||||
protected int[] _sites;
|
|
||||||
}
|
|
||||||
@@ -35,13 +35,8 @@ import com.samskivert.servlet.SiteResourceLoader;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A resource manager implementation for Velocity that first loads site
|
* A resource manager implementation for Velocity that first loads site
|
||||||
* specific resources (via the {@link SiteJarResourceLoader}), but falls
|
* specific resources (via the {@link SiteJarResourceLoader}), but falls back
|
||||||
* back to default resources if no site-specific resource loader is
|
* to default resources if no site-specific resource loader is available.
|
||||||
* available.
|
|
||||||
*
|
|
||||||
* <p> If this resource manager is to be used, resources must be fetched
|
|
||||||
* using {@link SiteResourceKey} objects as keys rather than simple
|
|
||||||
* strings.
|
|
||||||
*/
|
*/
|
||||||
public class SiteResourceManager extends ResourceManagerImpl
|
public class SiteResourceManager extends ResourceManagerImpl
|
||||||
{
|
{
|
||||||
@@ -87,37 +82,35 @@ public class SiteResourceManager extends ResourceManagerImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Resource loadResource(
|
protected Resource loadResource(
|
||||||
Object resourceKey, int resourceType, String encoding)
|
String resourceName, int resourceType, String encoding)
|
||||||
throws ResourceNotFoundException, ParseErrorException, Exception
|
throws ResourceNotFoundException, ParseErrorException, Exception
|
||||||
{
|
{
|
||||||
|
SiteKey skey = new SiteKey(resourceName);
|
||||||
|
|
||||||
// create a blank new resource
|
// create a blank new resource
|
||||||
Resource resource =
|
Resource resource =
|
||||||
ResourceFactory.getResource(resourceKey, resourceType);
|
ResourceFactory.getResource(skey.path, resourceType);
|
||||||
resource.setRuntimeServices(rsvc);
|
resource.setRuntimeServices(rsvc);
|
||||||
resource.setKey(resourceKey);
|
|
||||||
resource.setEncoding(encoding);
|
resource.setEncoding(encoding);
|
||||||
|
|
||||||
// if the resource was requested using a site resource key, we can
|
// if the resource was requested using a site resource key, we can
|
||||||
// attempt to load a site-specific version
|
// attempt to load a site-specific version; also make sure the site
|
||||||
if (resourceKey instanceof SiteResourceKey) {
|
// we're loading for is not the default site, in which case we want to
|
||||||
SiteResourceKey rkey = (SiteResourceKey)resourceKey;
|
// skip to the second resource loader directly
|
||||||
|
if (skey.siteId != -1 && skey.siteId != SiteIdentifier.DEFAULT_SITE_ID) {
|
||||||
// make sure the site we're loading for is not the default
|
// try loading it via the site-specific resource loader
|
||||||
// site, in which case we want to skip to the second resource
|
try {
|
||||||
// loader directly
|
resource.setName(resourceName);
|
||||||
if (rkey.getSiteId() != SiteIdentifier.DEFAULT_SITE_ID) {
|
resolveResource(resource, _siteLoader);
|
||||||
// try loading it via the site-specific resource loader
|
} catch (ResourceNotFoundException rnfe) {
|
||||||
try {
|
// nothing to worry about here
|
||||||
resolveResource(resource, _siteLoader);
|
|
||||||
} catch (ResourceNotFoundException rnfe) {
|
|
||||||
// nothing to worry about here
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// try the servlet context loader if we didn't find a
|
// try the servlet context loader if we didn't find a site-specific
|
||||||
// site-specific resource
|
// resource
|
||||||
if (resource.getData() == null) {
|
if (resource.getData() == null) {
|
||||||
|
resource.setName(skey.path);
|
||||||
resolveResource(resource, _contextLoader);
|
resolveResource(resource, _contextLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,8 +128,8 @@ public class SiteResourceManager extends ResourceManagerImpl
|
|||||||
resource.touch();
|
resource.touch();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A reference to the servlet context through which we'll load
|
/** A reference to the servlet context through which we'll load default
|
||||||
* default resources. */
|
* resources. */
|
||||||
protected ServletContext _sctx;
|
protected ServletContext _sctx;
|
||||||
|
|
||||||
/** A reference to the site identifier in use by the application. */
|
/** A reference to the site identifier in use by the application. */
|
||||||
|
|||||||
Reference in New Issue
Block a user