On 12/06/2009, ma...@apache.org <ma...@apache.org> wrote: > Author: markt > Date: Fri Jun 12 11:38:29 2009 > New Revision: 784083 > > URL: http://svn.apache.org/viewvc?rev=784083&view=rev > Log: > Implement alias resources. Key features: > - configured at the context level in the same way as the other resource > related attributes > - maps paths to directories or WAR files (single files not supported) > > Implementation notes: > - Correct results for getRealPath() required this to be pushed down to the > BaseDirContext as the short-cuts previously used needed to take account of > any aliases. This in turn meant an addition to the Context interface > - Thanks to Tim F. The configuration format is all his idea > > Modified: > tomcat/trunk/java/org/apache/catalina/Context.java > tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java > tomcat/trunk/java/org/apache/catalina/core/StandardContext.java > tomcat/trunk/java/org/apache/catalina/core/mbeans-descriptors.xml > tomcat/trunk/java/org/apache/naming/resources/BaseDirContext.java > tomcat/trunk/java/org/apache/naming/resources/FileDirContext.java > tomcat/trunk/java/org/apache/naming/resources/LocalStrings.properties > tomcat/trunk/java/org/apache/naming/resources/VirtualDirContext.java > tomcat/trunk/java/org/apache/naming/resources/WARDirContext.java > tomcat/trunk/webapps/docs/config/context.xml > > Modified: tomcat/trunk/java/org/apache/catalina/Context.java > URL: > http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Context.java?rev=784083&r1=784082&r2=784083&view=diff > > ============================================================================== > --- tomcat/trunk/java/org/apache/catalina/Context.java (original) > +++ tomcat/trunk/java/org/apache/catalina/Context.java Fri Jun 12 11:38:29 > 2009 > @@ -1073,6 +1073,13 @@ > */ > public void setTldNamespaceAware(boolean tldNamespaceAware); > > + /** > + * Return the real path for a given virtual path, if possible; otherwise > + * return <code>null</code>. > + * > + * @param path The path to the desired resource > + */ > + public String getRealPath(String path); > > } > > > Modified: tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java > URL: > http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java?rev=784083&r1=784082&r2=784083&view=diff > > ============================================================================== > --- tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java > (original) > +++ tomcat/trunk/java/org/apache/catalina/core/ApplicationContext.java Fri > Jun 12 11:38:29 2009 > @@ -371,17 +371,7 @@ > * @param path The path to the desired resource > */ > public String getRealPath(String path) { > - > - if (!context.isFilesystemBased()) > - return null; > - > - if (path == null) { > - return null; > - } > - > - File file = new File(basePath, path); > - return (file.getAbsolutePath()); > - > + return context.getRealPath(path); > } > > > > Modified: tomcat/trunk/java/org/apache/catalina/core/StandardContext.java > URL: > http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardContext.java?rev=784083&r1=784082&r2=784083&view=diff > > ============================================================================== > --- tomcat/trunk/java/org/apache/catalina/core/StandardContext.java > (original) > +++ tomcat/trunk/java/org/apache/catalina/core/StandardContext.java Fri Jun > 12 11:38:29 2009 > @@ -670,6 +670,12 @@ > > > /** > + * List of resource aliases. > + */ > + protected String aliases = null; >
This should be private, as there are public get/set methods. > + > + /** > * Non proxied resources. > */ > private DirContext webappResources = null; > @@ -848,6 +854,25 @@ > > > /** > + * Return the list of resource aliases. > + */ > + public String getAliases() { > + return this.aliases; > + } > + > + > + /** > + * Set the current alias configuration. The list of aliases should be > of the > + * form "/aliasPath1=docBase1,/aliasPath2=docBase2" where aliasPathN > must > + * include a leading '/' and docBaseN must be an absolute path to > either a > + * .war file or a directory. > + */ > + public void setAliases(String aliases) { > + this.aliases = aliases; > + } > + > + > + /** > * Return the "follow standard delegation model" flag used to configure > * our ClassLoader. > */ > @@ -1908,6 +1933,7 @@ > ((BaseDirContext) resources).setCacheMaxSize(getCacheMaxSize()); > ((BaseDirContext) resources).setCacheObjectMaxSize( > getCacheObjectMaxSize()); > + ((BaseDirContext) resources).setAliases(getAliases()); > } > if (resources instanceof FileDirContext) { > filesystemBased = true; > @@ -3815,6 +3841,19 @@ > } > > > + /** > + * Return the real path for a given virtual path, if possible; otherwise > + * return <code>null</code>. > + * > + * @param path The path to the desired resource > + */ > + public String getRealPath(String path) { > + if (webappResources instanceof BaseDirContext) { > + return ((BaseDirContext) webappResources).getRealPath(path); > + } > + return null; > + } > + > // --------------------------------------------------------- Public > Methods > > > > Modified: tomcat/trunk/java/org/apache/catalina/core/mbeans-descriptors.xml > URL: > http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/mbeans-descriptors.xml?rev=784083&r1=784082&r2=784083&view=diff > > ============================================================================== > --- tomcat/trunk/java/org/apache/catalina/core/mbeans-descriptors.xml > (original) > +++ tomcat/trunk/java/org/apache/catalina/core/mbeans-descriptors.xml Fri > Jun 12 11:38:29 2009 > @@ -45,6 +45,10 @@ > description="Object that creates and destroys servlets, > filters, and listeners. Include dependency injection and > postConstruct/preDestory handling" > > type="org.apache.catalina.instanceManagement.InstanceManager" /> > > + <attribute name="aliases" > + description="List of resource aliases" > + type="java.lang.String" /> > + > <attribute name="antiJARLocking" > description="Take care to not lock jar files" > type="boolean" /> > > Modified: tomcat/trunk/java/org/apache/naming/resources/BaseDirContext.java > URL: > http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/naming/resources/BaseDirContext.java?rev=784083&r1=784082&r2=784083&view=diff > > ============================================================================== > --- tomcat/trunk/java/org/apache/naming/resources/BaseDirContext.java > (original) > +++ tomcat/trunk/java/org/apache/naming/resources/BaseDirContext.java Fri > Jun 12 11:38:29 2009 > @@ -18,7 +18,12 @@ > > package org.apache.naming.resources; > > +import java.io.File; > +import java.util.HashMap; > import java.util.Hashtable; > +import java.util.Iterator; > +import java.util.Map; > +import java.util.Map.Entry; > > import javax.naming.Binding; > import javax.naming.Context; > @@ -119,10 +124,98 @@ > protected int cacheObjectMaxSize = 512; // 512 K > > > + /** > + * Aliases allow content to be included from other locations. > + */ > + protected Map<String,BaseDirContext> aliases = > + new HashMap<String,BaseDirContext>(); > + > + This should probably be final and private, as there are public access methods. > // ------------------------------------------------------------- > Properties > > > /** > + * Add an alias. > + */ > + public void addAlias(String path, BaseDirContext dirContext) { > + if (!path.startsWith("/")) { > + throw new IllegalArgumentException( > + sm.getString("resources.invalidAliasPath", path)); > + } > + aliases.put(path, dirContext); > + } > + > + > + /** > + * Remove an alias. > + */ > + public void removeAlias(String path) { > + if (!path.startsWith("/")) { > + throw new IllegalArgumentException( > + sm.getString("resources.invalidAliasPath", path)); > + } > + aliases.remove(path); > + } > + > + > + /** > + * Get the current alias configuration in String form. If no aliases are > + * configured, an empty string will be returned. > + */ > + public String getAliases() { > + StringBuilder result = new StringBuilder(); > + Iterator<Entry<String,BaseDirContext>> iter = > + aliases.entrySet().iterator(); > + boolean first = true; > + while (iter.hasNext()) { > + if (first) { > + first = false; > + } else { > + result.append(','); > + } > + Entry<String,BaseDirContext> entry = iter.next(); > + result.append(entry.getKey()); > + result.append('='); > + result.append(entry.getValue().getDocBase()); > + } > + return result.toString(); > + } > + > + > + /** > + * Set the current alias configuration from a String. The String should > be > + * of the form "/aliasPath1=docBase1,/aliasPath2=docBase2" where > aliasPathN > + * must include a leading '/' and docBaseN must be an absolute path to > + * either a .war file or a directory. Any call to this method will > replace > + * the current set of aliases. > + */ > + public void setAliases(String theAliases) { > + // Overwrite whatever is currently set > + aliases.clear(); > + > + if (theAliases == null || theAliases.length() == 0) > + return; > + > + String[] kvps = theAliases.split(","); > + for (String kvp : kvps) { > + String[] kv = kvp.split("="); > + if (kv.length != 2 || kv[0].length() == 0 || kv[1].length() == > 0) > + throw new IllegalArgumentException( > + sm.getString("resources.invalidAliasMapping", kvp)); > + > + BaseDirContext context; > + if (kv[1].endsWith(".war") && !(new File(kv[1]).isDirectory())) > { > + context = new WARDirContext(); > + } else { > + context = new FileDirContext(); > + } > + context.setDocBase(kv[1]); > + addAlias(kv[0], context); > + } > + } > + > + > + /** > * Return the document root for this component. > */ > public String getDocBase() { > @@ -235,6 +328,22 @@ > // No action taken by the default implementation > } > > + > + /** > + * Return the real path for a given virtual path, if possible; otherwise > + * return <code>null</code>. > + * > + * @param path The path to the desired resource > + */ > + public String getRealPath(String name) { > + if (!aliases.isEmpty()) { > + AliasResult result = findAlias(name); > + if (result.dirContext != null) { > + return result.dirContext.doGetRealPath(result.aliasName); > + } > + } > + return doGetRealPath(name); > + } > > // -------------------------------------------------------- Context > Methods > > @@ -262,9 +371,15 @@ > * @return the object bound to name > * @exception NamingException if a naming exception is encountered > */ > - public abstract Object lookup(String name) > - throws NamingException; > - > + public final Object lookup(String name) throws NamingException { > + if (!aliases.isEmpty()) { > + AliasResult result = findAlias(name); > + if (result.dirContext != null) { > + return result.dirContext.lookup(result.aliasName); > + } > + } > + return doLookup(name); > + } > > /** > * Binds a name to an object. All intermediate contexts and the target > @@ -779,9 +894,17 @@ > * indicates that none should be retrieved > * @exception NamingException if a naming exception is encountered > */ > - public abstract Attributes getAttributes(String name, String[] attrIds) > - throws NamingException; > - > + public final Attributes getAttributes(String name, String[] attrIds) > + throws NamingException { > + if (!aliases.isEmpty()) { > + AliasResult result = findAlias(name); > + if (result.dirContext != null) { > + return result.dirContext.getAttributes( > + result.aliasName, attrIds); > + } > + } > + return doGetAttributes(name, attrIds); > + } > > /** > * Modifies the attributes associated with a named object. The order of > @@ -1229,6 +1352,37 @@ > > // ------------------------------------------------------ Protected > Methods > > + protected abstract Attributes doGetAttributes(String name, String[] > attrIds) > + throws NamingException; > + > + protected abstract Object doLookup(String name) throws NamingException; > > + protected abstract String doGetRealPath(String name); > + > + // -------------------------------------------------------- Private > Methods > + private AliasResult findAlias(String name) { > + AliasResult result = new AliasResult(); > + > + String searchName = name; > + > + result.dirContext = aliases.get(searchName); > + while (result.dirContext == null) { > + int slash = searchName.lastIndexOf('/'); > + if (slash < 0) > + break; > + searchName = searchName.substring(0, slash); > + result.dirContext = aliases.get(searchName); > + } > + > + if (result.dirContext != null) > + result.aliasName = name.substring(searchName.length()); > + > + return result; > + } > + > + private static class AliasResult { > + BaseDirContext dirContext; > + String aliasName; > + } > } > > > Modified: tomcat/trunk/java/org/apache/naming/resources/FileDirContext.java > URL: > http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/naming/resources/FileDirContext.java?rev=784083&r1=784082&r2=784083&view=diff > > ============================================================================== > --- tomcat/trunk/java/org/apache/naming/resources/FileDirContext.java > (original) > +++ tomcat/trunk/java/org/apache/naming/resources/FileDirContext.java Fri > Jun 12 11:38:29 2009 > @@ -193,6 +193,17 @@ > } > > > + /** > + * Return the real path for a given virtual path, if possible; otherwise > + * return <code>null</code>. > + * > + * @param path The path to the desired resource > + */ > + protected String doGetRealPath(String path) { > + File file = new File(getDocBase(), path); > + return file.getAbsolutePath(); > + } > + > // -------------------------------------------------------- Context > Methods > > > @@ -203,7 +214,7 @@ > * @return the object bound to name > * @exception NamingException if a naming exception is encountered > */ > - public Object lookup(String name) > + protected Object doLookup(String name) > throws NamingException { > Object result = null; > File file = file(name); > @@ -425,7 +436,7 @@ > * indicates that none should be retrieved > * @exception NamingException if a naming exception is encountered > */ > - public Attributes getAttributes(String name, String[] attrIds) > + protected Attributes doGetAttributes(String name, String[] attrIds) > throws NamingException { > > // Building attribute list > > Modified: > tomcat/trunk/java/org/apache/naming/resources/LocalStrings.properties > URL: > http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/naming/resources/LocalStrings.properties?rev=784083&r1=784082&r2=784083&view=diff > > ============================================================================== > --- tomcat/trunk/java/org/apache/naming/resources/LocalStrings.properties > (original) > +++ tomcat/trunk/java/org/apache/naming/resources/LocalStrings.properties > Fri Jun 12 11:38:29 2009 > @@ -28,6 +28,8 @@ > resources.alreadyBound=Name {0} is already bound in this Context > resources.bindFailed=Bind failed: {0} > resources.unbindFailed=Unbind failed: {0} > +resources.invalidAliasPath=The alias path ''{0}'' must start with ''/'' > +resources.invalidAliasMapping=The alias mapping ''{0}'' is not valid > standardResources.alreadyStarted=Resources has already been started > standardResources.directory=File base {0} is not a directory > standardResources.exists=File base {0} does not exist > > Modified: > tomcat/trunk/java/org/apache/naming/resources/VirtualDirContext.java > URL: > http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/naming/resources/VirtualDirContext.java?rev=784083&r1=784082&r2=784083&view=diff > > ============================================================================== > --- tomcat/trunk/java/org/apache/naming/resources/VirtualDirContext.java > (original) > +++ tomcat/trunk/java/org/apache/naming/resources/VirtualDirContext.java Fri > Jun 12 11:38:29 2009 > @@ -160,7 +160,7 @@ > } > > @Override > - public Object lookup(String name) throws NamingException { > + protected Object doLookup(String name) throws NamingException { > > // handle "virtual" tlds > if (name.startsWith("/WEB-INF/") && name.endsWith(".tld")) { > > Modified: tomcat/trunk/java/org/apache/naming/resources/WARDirContext.java > URL: > http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/naming/resources/WARDirContext.java?rev=784083&r1=784082&r2=784083&view=diff > > ============================================================================== > --- tomcat/trunk/java/org/apache/naming/resources/WARDirContext.java > (original) > +++ tomcat/trunk/java/org/apache/naming/resources/WARDirContext.java Fri Jun > 12 11:38:29 2009 > @@ -167,6 +167,16 @@ > > } > > + /** > + * Return the real path for a given virtual path, if possible; otherwise > + * return <code>null</code>. > + * > + * @param path The path to the desired resource > + */ > + protected String doGetRealPath(String path) { > + return null; > + } > + > > // -------------------------------------------------------- Context > Methods > > @@ -178,7 +188,7 @@ > * @return the object bound to name > * @exception NamingException if a naming exception is encountered > */ > - public Object lookup(String name) > + protected Object doLookup(String name) > throws NamingException { > return lookup(new CompositeName(name)); > } > @@ -423,7 +433,7 @@ > * indicates that none should be retrieved > * @exception NamingException if a naming exception is encountered > */ > - public Attributes getAttributes(String name, String[] attrIds) > + protected Attributes doGetAttributes(String name, String[] attrIds) > throws NamingException { > return getAttributes(new CompositeName(name), attrIds); > } > > Modified: tomcat/trunk/webapps/docs/config/context.xml > URL: > http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/context.xml?rev=784083&r1=784082&r2=784083&view=diff > > ============================================================================== > --- tomcat/trunk/webapps/docs/config/context.xml (original) > +++ tomcat/trunk/webapps/docs/config/context.xml Fri Jun 12 11:38:29 2009 > @@ -251,6 +251,16 @@ > > <attributes> > > + <attribute name="alises" required="false"> > + <p>This attribute provides a list of external locations from which > to > + load resources for this context. These external locations will not > be > + emptied if the context is un-deployed. The list of aliases should > be of > + the form <code>"/aliasPath1=docBase1,/aliasPath2=docBase2"</code> > where > + <code>aliasPathN</code> must include a leading '/' and > + <code>docBaseN</code> must be an absolute path to either a .war > file or > + a directory.</p> > + </attribute> > + > <attribute name="allowLinking" required="false"> > <p>If the value of this flag is <code>true</code>, symlinks will be > allowed inside the web application, pointing to resources outside the > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org > For additional commands, e-mail: dev-h...@tomcat.apache.org > > --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org