You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2003/03/23 02:27:23 UTC

cvs commit: jakarta-tapestry/framework/src/org/apache/tapestry/resolver ISpecificationResolverDelegate.java NullSpecificationResolverDelegate.java AbstractSpecificationResolver.java ComponentSpecificationResolver.java PageSpecificationResolver.java

hlship      2003/03/22 17:27:23

  Modified:    framework/src/org/apache/tapestry/resolver
                        AbstractSpecificationResolver.java
                        ComponentSpecificationResolver.java
                        PageSpecificationResolver.java
  Added:       framework/src/org/apache/tapestry/resolver
                        ISpecificationResolverDelegate.java
                        NullSpecificationResolverDelegate.java
  Log:
  Add new extensions for locating page and component specifications and templates (when not found by the standard rules).
  
  Revision  Changes    Path
  1.2       +29 -3     jakarta-tapestry/framework/src/org/apache/tapestry/resolver/AbstractSpecificationResolver.java
  
  Index: AbstractSpecificationResolver.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/resolver/AbstractSpecificationResolver.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AbstractSpecificationResolver.java	5 Mar 2003 22:59:48 -0000	1.1
  +++ AbstractSpecificationResolver.java	23 Mar 2003 01:27:23 -0000	1.2
  @@ -65,6 +65,7 @@
   import org.apache.tapestry.Tapestry;
   import org.apache.tapestry.engine.ISpecificationSource;
   import org.apache.tapestry.spec.ComponentSpecification;
  +import org.apache.tapestry.spec.IApplicationSpecification;
   
   /**
    *  Base class for resolving a {@link org.apache.tapestry.spec.ComponentSpecification}
  @@ -93,6 +94,8 @@
   
       private IResourceLocation _webInfAppLocation;
   
  +    private ISpecificationResolverDelegate _delegate;
  +
       public AbstractSpecificationResolver(IRequestCycle cycle)
       {
           IEngine engine = cycle.getEngine();
  @@ -101,11 +104,35 @@
   
           _applicationRootLocation = Tapestry.getApplicationRootLocation(cycle);
   
  -        String servletName = cycle.getRequestContext().getServlet().getServletConfig().getServletName();
  +        String servletName =
  +            cycle.getRequestContext().getServlet().getServletConfig().getServletName();
   
           _webInfLocation = _applicationRootLocation.getRelativeLocation("/WEB-INF/");
   
           _webInfAppLocation = _webInfLocation.getRelativeLocation(servletName + "/");
  +
  +        IApplicationSpecification specification = engine.getSpecification();
  +
  +        if (specification.checkExtension(Tapestry.SPECIFICATION_RESOLVER_DELEGATE_EXTENSION_NAME))
  +            _delegate =
  +                (ISpecificationResolverDelegate) engine.getSpecification().getExtension(
  +                    Tapestry.SPECIFICATION_RESOLVER_DELEGATE_EXTENSION_NAME,
  +                    ISpecificationResolverDelegate.class);
  +        else
  +            _delegate = NullSpecificationResolverDelegate.getSharedInstance();
  +    }
  +
  +    /**
  +     *  Returns the {@link ISpecificationResolverDelegate} instance registered
  +     *  in the application specification as extension
  +     *  {@link Tapestry#SPECIFICATION_RESOLVER_DELEGATE_EXTENSION_NAME},
  +     *  or null if no such extension exists.
  +     * 
  +     **/
  +
  +    public ISpecificationResolverDelegate getDelegate()
  +    {
  +        return _delegate;
       }
   
       /**
  @@ -190,7 +217,6 @@
       {
           _specification = specification;
       }
  -
   
       /**
        *  Clears the namespace, specification and simpleName properties.
  
  
  
  1.3       +43 -13    jakarta-tapestry/framework/src/org/apache/tapestry/resolver/ComponentSpecificationResolver.java
  
  Index: ComponentSpecificationResolver.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/resolver/ComponentSpecificationResolver.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ComponentSpecificationResolver.java	15 Mar 2003 21:22:29 -0000	1.2
  +++ ComponentSpecificationResolver.java	23 Mar 2003 01:27:23 -0000	1.3
  @@ -82,11 +82,20 @@
    *  of the page, goes as follows:
    * 
    *  <ul>
  + *  <li>As declared in the application specification
    *  <li><i>type</i>.jwc in the same folder as the application specification
    *  <li><i>type</i> jwc in the WEB-INF/<i>servlet-name</i> directory of the context root
    *  <li><i>type</i>.jwc in WEB-INF
    *  <li><i>type</i>.jwc in the application root (within the context root)
  -  *  </ul> 
  + *  <li>By searching the framework namespace
  + *  </ul> 
  + * 
  + *  The search for components in library namespaces is more abbreviated:
  + *  <li>As declared in the library specification
  + *  <li><i>type</i>.jwc in the same folder as the library specification
  + *  <li>By searching the framework namespace
  + *  </ul>
  + *
    * 
    *  @author Howard Lewis Ship
    *  @version $Id$
  @@ -112,6 +121,7 @@
        *  or the framework namespace
        *  (a search occurs in that order).
        * 
  +     *  @param cycle current request cycle
        *  @param containerNamespace namespace that may contain
        *  a library referenced in the type
        *  @param type the component specification
  @@ -120,11 +130,10 @@
        * 
        *  @see #getNamespace()
        *  @see #getSpecification()
  -     *  @throws PageLoaderException if the type cannot be resolved
        * 
        **/
   
  -    public void resolve(INamespace containerNamespace, String type)
  +    public void resolve(IRequestCycle cycle, INamespace containerNamespace, String type)
       {
           int colonx = type.indexOf(':');
   
  @@ -133,26 +142,31 @@
               String libraryId = type.substring(0, colonx);
               String simpleType = type.substring(colonx + 1);
   
  -            resolve(containerNamespace, libraryId, simpleType);
  +            resolve(cycle, containerNamespace, libraryId, simpleType);
           }
           else
  -            resolve(containerNamespace, null, type);
  +            resolve(cycle, containerNamespace, null, type);
       }
   
       /**
        *  Like {@link #resolve(INamespace, String)}, but used when the type has already
        *  been parsed into a library id and a simple type.
        * 
  +     *  @param cycle current request cycle
        *  @param containerNamespace namespace that may contain
        *  a library referenced in the type
        *  @param libraryId the library id within the container namespace, or null
        *  @param type the component specification
  -     *  to  find as a simple name
  +     *  to  find as a simple name (without a library prefix)
        *  @throws ApplicationRuntimeException if the type cannot be resolved
        * 
        **/
   
  -    public void resolve(INamespace containerNamespace, String libraryId, String type)
  +    public void resolve(
  +        IRequestCycle cycle,
  +        INamespace containerNamespace,
  +        String libraryId,
  +        String type)
       {
           reset();
           _type = type;
  @@ -172,7 +186,7 @@
               return;
           }
   
  -        searchForComponent();
  +        searchForComponent(cycle);
   
           // If not found after search, check to see if it's in
           // the framework instead.
  @@ -181,12 +195,15 @@
           {
   
               throw new ApplicationRuntimeException(
  -                Tapestry.getString("Namespace.no-such-component-type", type, namespace.getNamespaceId()));
  +                Tapestry.getString(
  +                    "Namespace.no-such-component-type",
  +                    type,
  +                    namespace.getNamespaceId()));
   
           }
       }
   
  -    private void searchForComponent()
  +    private void searchForComponent(IRequestCycle cycle)
       {
           INamespace namespace = getNamespace();
   
  @@ -223,10 +240,17 @@
           INamespace framework = getSpecificationSource().getFrameworkNamespace();
   
           if (framework.containsComponentType(_type))
  +        {
               setSpecification(framework.getComponentSpecification(_type));
  +            return;
  +        }
   
  -        // If not found by here, an exception will be thrown.
  +        ComponentSpecification specification =
  +            getDelegate().findComponentSpecification(cycle, namespace, _type);
   
  +        setSpecification(specification);
  +
  +        // If not found by here, an exception will be thrown.
       }
   
       private boolean found(IResourceLocation location)
  @@ -250,7 +274,13 @@
           ComponentSpecification specification = getSpecification();
   
           if (LOG.isDebugEnabled())
  -            LOG.debug("Installing component type " + _type + " into " + namespace + " as " + specification);
  +            LOG.debug(
  +                "Installing component type "
  +                    + _type
  +                    + " into "
  +                    + namespace
  +                    + " as "
  +                    + specification);
   
           namespace.installComponentSpecification(_type, specification);
       }
  
  
  
  1.2       +52 -38    jakarta-tapestry/framework/src/org/apache/tapestry/resolver/PageSpecificationResolver.java
  
  Index: PageSpecificationResolver.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/resolver/PageSpecificationResolver.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- PageSpecificationResolver.java	5 Mar 2003 22:59:48 -0000	1.1
  +++ PageSpecificationResolver.java	23 Mar 2003 01:27:23 -0000	1.2
  @@ -73,16 +73,24 @@
    *  of the page, goes as follows:
    * 
    *  <ul>
  + *  <li>As declared in the application specification
    *  <li><i>simple-name</i>.page in the same folder as the application specification
    *  <li><i>simple-name</i> page in the WEB-INF/<i>servlet-name</i> directory of the context root
    *  <li><i>simple-name</i>.page in WEB-INF
    *  <li><i>simple-name</i>.page in the application root (within the context root)
    *  <li><i>simple-name</i>.html as a template in the application root, 
    *      for which an implicit specification is generated
  + *  <li>By searching the framework namespace
  + *  <li>By invoking {@link org.apache.tapestry.resolver.ISpecificationResolverDelegate#findPageSpecification(IRequestCycle, INamespace, String)}
    *  </ul>
    * 
  - *  <p>If none of these work out, then the page is searched for in the framework namespace.
  - *  This is used to find default implementations of pages such as Exception and StaleLink.
  + *  <p>Pages in a component library are searched for in a more abbreviated fashion:
  + *  <ul>
  + *  <li>As declared in the library specification
  + *  <li><i>simple-name</i>.page in the same folder as the library specification
  + *  <li>By searching the framework namespace
  + *  <li>By invoking {@link org.apache.tapestry.resolver.ISpecificationResolverDelegate#findPageSpecification(IRequestCycle, INamespace, String)}
  + *  </ul>
    *
    *  @see org.apache.tapestry.IPageSource
    *  @author Howard Lewis Ship
  @@ -110,7 +118,7 @@
        * 
        **/
   
  -    public void resolve(String prefixedName)
  +    public void resolve(IRequestCycle cycle, String prefixedName)
       {
           reset();
   
  @@ -147,7 +155,7 @@
   
           // Not defined in the specification, so it's time to hunt it down.
   
  -        searchForPage();
  +        searchForPage(cycle);
   
           if (getSpecification() == null)
               throw new ApplicationRuntimeException(
  @@ -163,7 +171,7 @@
           return _simpleName;
       }
   
  -    private void searchForPage()
  +    private void searchForPage(IRequestCycle cycle)
       {
           INamespace namespace = getNamespace();
   
  @@ -181,54 +189,60 @@
           if (found(namespaceLocation.getRelativeLocation(expectedName)))
               return;
   
  -        // If not for the (unnamed) application specification, then return ... which will
  -        // cause an exception.
  -
  -        if (!namespace.isApplicationNamespace())
  -            return;
  +        if (namespace.isApplicationNamespace())
  +        {
   
  -        // The application namespace gets some extra searching.
  +            // The application namespace gets some extra searching.
   
  -        if (found(getWebInfAppLocation().getRelativeLocation(expectedName)))
  -            return;
  +            if (found(getWebInfAppLocation().getRelativeLocation(expectedName)))
  +                return;
   
  -        if (found(getWebInfLocation().getRelativeLocation(expectedName)))
  -            return;
  +            if (found(getWebInfLocation().getRelativeLocation(expectedName)))
  +                return;
   
  -        if (found(getApplicationRootLocation().getRelativeLocation(expectedName)))
  -            return;
  +            if (found(getApplicationRootLocation().getRelativeLocation(expectedName)))
  +                return;
   
  -        // The wierd one ... where we see if there's a templatge in the application root location.
  +            // The wierd one ... where we see if there's a template in the application root location.
   
  -        String templateName = _simpleName + "." + getTemplateExtension();
  +            String templateName = _simpleName + "." + getTemplateExtension();
   
  -        IResourceLocation templateLocation =
  -            getApplicationRootLocation().getRelativeLocation(templateName);
  +            IResourceLocation templateLocation =
  +                getApplicationRootLocation().getRelativeLocation(templateName);
   
  -        if (templateLocation.getResourceURL() != null)
  -        {
  -            setupImplicitPage(templateLocation);
  -            return;
  -        }
  +            if (templateLocation.getResourceURL() != null)
  +            {
  +                setupImplicitPage(templateLocation);
  +                return;
  +            }
   
  -        // Not found in application namespace, so maybe its a framework page.
  +            // Not found in application namespace, so maybe its a framework page.
   
  -        INamespace framework = getSpecificationSource().getFrameworkNamespace();
  +            INamespace framework = getSpecificationSource().getFrameworkNamespace();
   
  -        if (framework.containsPage(_simpleName))
  -        {
  -            if (LOG.isDebugEnabled())
  -                LOG.debug("Found " + _simpleName + " in framework namespace.");
  +            if (framework.containsPage(_simpleName))
  +            {
  +                if (LOG.isDebugEnabled())
  +                    LOG.debug("Found " + _simpleName + " in framework namespace.");
   
  -            setNamespace(framework);
  +                setNamespace(framework);
   
  -            // Note:  This implies that normal lookup rules don't work
  -            // for the framework!  Framework pages must be
  -            // defined in the framework library specification.
  +                // Note:  This implies that normal lookup rules don't work
  +                // for the framework!  Framework pages must be
  +                // defined in the framework library specification.
   
  -            setSpecification(framework.getPageSpecification(_simpleName));
  +                setSpecification(framework.getPageSpecification(_simpleName));
  +                return;
  +            }
           }
   
  +        // Not found by any normal rule, so its time to
  +        // consult the delegate.
  +
  +        ComponentSpecification specification =
  +            getDelegate().findPageSpecification(cycle, namespace, _simpleName);
  +            
  +        setSpecification(specification);
       }
   
       private void setupImplicitPage(IResourceLocation location)
  
  
  
  1.1                  jakarta-tapestry/framework/src/org/apache/tapestry/resolver/ISpecificationResolverDelegate.java
  
  Index: ISpecificationResolverDelegate.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation", "Tapestry" 
   *    must not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache" 
   *    or "Tapestry", nor may "Apache" or "Tapestry" appear in their 
   *    name, without prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE TAPESTRY CONTRIBUTOR COMMUNITY
   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.tapestry.resolver;
  
  import org.apache.tapestry.INamespace;
  import org.apache.tapestry.IRequestCycle;
  import org.apache.tapestry.spec.ComponentSpecification;
  
  /**
   *  Delegate interface used when a page or component specification
   *  can not be found by the normal means.  This allows hooks
   *  to support specifications from unusual locations, or generated
   *  on the fly.
   * 
   *  <p>The delegate must be coded in a threadsafe manner.
   * 
   *  @author Howard Lewis Ship
   *  @version $Id: ISpecificationResolverDelegate.java,v 1.1 2003/03/23 01:27:23 hlship Exp $
   *  @since 2.4
   *
   **/
  
  public interface ISpecificationResolverDelegate
  {
      /**
       *  Invoked by {@link PageSpecificationResolver} to find the indicated
       *  page specification.  Returns
       *  the specification, or null.  The specification, if returned, is not cached by Tapestry
       *  (it is up to the delegate to cache the specification if desired).
       * 
       *  @parameter cycle used to gain access to framework and Servlet API objects
       *  @parameter namespace the namespace containing the page
       *  @parameter simplePageName the name of the page (without any namespace prefix)
       * 
       **/
  
      public ComponentSpecification findPageSpecification(
          IRequestCycle cycle,
          INamespace namespace,
          String simplePageName);
  
      /**
       *  Invoked by {@link PageSpecificationResolver} to find the indicated
       *  component specification.  Returns
       *  the specification, or null.  The specification, if returned, is not cached by Tapestry
       *  (it is up to the delegate to cache the specification if desired).
       * 
       *  <p>The delegate must be coded in a threadsafe manner.
       * 
       *  @parameter cycle used to gain access to framework and Servlet API objects
       *  @parameter namespace the namespace containing the component
       *  @parameter type the component type (without any namespace prefix)
       * 
       **/
  
      public ComponentSpecification findComponentSpecification(
          IRequestCycle cycle,
          INamespace namespace,
          String type);
  }
  
  
  
  1.1                  jakarta-tapestry/framework/src/org/apache/tapestry/resolver/NullSpecificationResolverDelegate.java
  
  Index: NullSpecificationResolverDelegate.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation", "Tapestry" 
   *    must not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache" 
   *    or "Tapestry", nor may "Apache" or "Tapestry" appear in their 
   *    name, without prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE TAPESTRY CONTRIBUTOR COMMUNITY
   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  package org.apache.tapestry.resolver;
  
  import org.apache.tapestry.INamespace;
  import org.apache.tapestry.IRequestCycle;
  import org.apache.tapestry.spec.ComponentSpecification;
  
  /**
   *  Stand-in class used when the application fails to specify an actual delegate.
   *
   *  @author Howard Lewis Ship
   *  @version $Id: NullSpecificationResolverDelegate.java,v 1.1 2003/03/23 01:27:23 hlship Exp $
   *  @since 2.4
   *
   **/
  
  public class NullSpecificationResolverDelegate implements ISpecificationResolverDelegate
  {
      private static NullSpecificationResolverDelegate _shared;
  
      public static NullSpecificationResolverDelegate getSharedInstance()
      {
          if (_shared == null)
              _shared = new NullSpecificationResolverDelegate();
  
          return _shared;
      }
  
      /**
       *  Returns null.
       * 
       **/
  
      public ComponentSpecification findPageSpecification(
          IRequestCycle cycle,
          INamespace namespace,
          String simplePageName)
      {
          return null;
      }
  
      /**
       *  Returns null.
       * 
       **/
  
      public ComponentSpecification findComponentSpecification(
          IRequestCycle cycle,
          INamespace namespace,
          String type)
      {
          return null;
      }
  
  }