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;
+
+
+ /**
* 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>();
+
+
// ------------------------------------------------------------- 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: [email protected]
For additional commands, e-mail: [email protected]