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

Reply via email to