CVS: Tapestry/framework/src/net/sf/tapestry/pageload PageSpecificationResolver.java,NONE,1.1.2.1 PageLoader.java,1.15.2.4,1.15.2.5 PageSource.java,1.13.2.2,1.13.2.3

Howard Lewis Ship <[email protected]>
Newsgroups gmane.comp.java.tapestry.cvs
Message-ID <[email protected]>
Update of /cvsroot/tapestry/Tapestry/framework/src/net/sf/tapestry/pageload
In directory sc8-pr-cvs1:/tmp/cvs-serv15280/framework/src/net/sf/tapestry/pageload

Modified Files:
      Tag: hship-2-3
	PageLoader.java PageSource.java 
Added Files:
      Tag: hship-2-3
	PageSpecificationResolver.java 
Log Message:
Check in support for templates in the application root.

--- NEW FILE: PageSpecificationResolver.java ---
package net.sf.tapestry.pageload;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import net.sf.tapestry.ApplicationRuntimeException;
import net.sf.tapestry.IEngine;
import net.sf.tapestry.INamespace;
import net.sf.tapestry.IRequestCycle;
import net.sf.tapestry.IResourceLocation;
import net.sf.tapestry.ISpecificationSource;
import net.sf.tapestry.Tapestry;
import net.sf.tapestry.html.BasePage;
import net.sf.tapestry.spec.ComponentSpecification;

/**
 *  Performs the tricky work of resolving a page name to a page specification.
 *  The search for pages in the application namespace is the most complicated,
 *  since Tapestry searches for pages that aren't explicitly defined in the
 *  application specification.  The search, based on the <i>simple-name</i>
 *  of the page, goes as follows:
 * 
 *  <ul>
 *  <li><i>simple-name</i>.page in the same folder as the application specification
 *  <li><i>simple-name</i>.page in WEB-INF of the context root
 *  <li><i>simple-name</i>.page in the application root (within the context root)
 *  <li><i>simple-name</i>.html as a template, for which an implicit specification is generated
 *  </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 the
 *  pages such as Exception and StaleLink.
 *
 *  @see net.sf.tapestry.IPageSource
 *  @author Howard Lewis Ship
 *  @version $Id: PageSpecificationResolver.java,v 1.1.2.1 2002/12/11 14:02:27 hship Exp $
 *  @since 2.4
 *
 **/

public class PageSpecificationResolver
{
    private static final Log LOG = LogFactory.getLog(PageSpecificationResolver.class);

    private ISpecificationSource _source;
    private String _simplePageName;
    private INamespace _namespace;
    private ComponentSpecification _specification;
    private IResourceLocation _applicationRootLocation;
    private IResourceLocation _webInfLocation;
    private IResourceLocation _webInfPagesLocation;

    public PageSpecificationResolver(IRequestCycle cycle)
    {
        IEngine engine = cycle.getEngine();

        _source = engine.getSpecificationSource();

        _applicationRootLocation = Tapestry.getApplicationRootLocation(cycle);

        _webInfLocation = _applicationRootLocation.getRelativeLocation("/WEB-INF/");
        _webInfPagesLocation = _webInfLocation.getRelativeLocation("pages/");
    }

    public void resolve(String pageName)
    {
        int colonx = pageName.indexOf(':');

        if (colonx > 0)
        {
            _simplePageName = pageName.substring(colonx + 1);
            String namespaceId = pageName.substring(0, colonx);

            if (namespaceId.equals(INamespace.FRAMEWORK_NAMESPACE))
                _namespace = _source.getFrameworkNamespace();
            else
                _namespace = _source.getApplicationNamespace().getChildNamespace(namespaceId);
        }
        else
        {
            _simplePageName = pageName;

            _namespace = _source.getApplicationNamespace();
        }

        if (_namespace.containsPage(_simplePageName))
            _specification = _namespace.getPageSpecification(_simplePageName);
        {

            searchForPage();

            if (_specification == null)
                throw new ApplicationRuntimeException(
                    Tapestry.getString("Namespace.no-such-page", _simplePageName, _namespace.getNamespaceId()));
        }

    }

    public INamespace getNamespace()
    {
        return _namespace;
    }

    public ComponentSpecification getSpecification()
    {
        return _specification;
    }

    public String getSimplePageName()
    {
        return _simplePageName;
    }

    private void searchForPage()
    {
        if (LOG.isDebugEnabled())
            LOG.debug("Resolving unknown page '" + _simplePageName + "' in " + _namespace);

        String expectedName = _simplePageName + ".page";

        IResourceLocation namespaceLocation = _namespace.getSpecificationLocation();

        if (found(namespaceLocation.getRelativeLocation(expectedName)))
            return;

        // If not for the (unnamed) application specification, then return ... which will
        // cause an exception.

        if (!_namespace.isApplicationNamespace())
            return;

        // The application namespace gets some extra searching.

        if (found(_webInfPagesLocation.getRelativeLocation(expectedName)))
            return;

        if (found(_webInfLocation.getRelativeLocation(expectedName)))
            return;

        if (found(_applicationRootLocation.getRelativeLocation(expectedName)))
            return;

        // The wierd one ... where we see if there's an HTML file in the application root location.

        String templateName = _simplePageName + ".html";

        IResourceLocation templateLocation = _applicationRootLocation.getRelativeLocation(templateName);

        if (templateLocation.getResourceURL() != null)
        {
            setupImplicitPage(templateLocation);
            return;
        }

        // Not found in application namespace, so maybe its a framework page.

        INamespace framework = _source.getFrameworkNamespace();

        if (framework.containsPage(_simplePageName))
        {
            if (LOG.isDebugEnabled())
                LOG.debug("Found " + _simplePageName + " in framework namespace.");

            _namespace = framework;
            _specification = framework.getPageSpecification(_simplePageName);
        }

    }

    private void setupImplicitPage(IResourceLocation location)
    {
        if (LOG.isDebugEnabled())
            LOG.debug("Found HTML template at " + location);

        _specification = new ComponentSpecification();
        _specification.setComponentClassName(BasePage.class.getName());
        _specification.setPageSpecification(true);
        _specification.setSpecificationLocation(location);

        install();
    }

    private boolean found(IResourceLocation location)
    {
        if (LOG.isDebugEnabled())
            LOG.debug("Checking: " + location);

        if (location.getResourceURL() == null)
            return false;

        _specification = _source.getPageSpecification(location);

        install();

        return true;
    }

    private void install()
    {
        if (LOG.isDebugEnabled())
            LOG.debug("Installing " + _simplePageName + " into " + _namespace + " as " + _specification);

        _namespace.installPageSpecification(_simplePageName, _specification);
    }

}

Index: PageLoader.java
===================================================================
RCS file: /cvsroot/tapestry/Tapestry/framework/src/net/sf/tapestry/pageload/PageLoader.java,v
retrieving revision 1.15.2.4
retrieving revision 1.15.2.5
diff -C2 -d -r1.15.2.4 -r1.15.2.5
*** PageLoader.java	8 Dec 2002 15:04:46 -0000	1.15.2.4
--- PageLoader.java	11 Dec 2002 14:02:27 -0000	1.15.2.5
***************
*** 45,48 ****
--- 45,53 ----
  /**
   *  Runs the process of building the component hierarchy for an entire page.
+  * 
+  *  <p>
+  *  This class is not threadsafe; however, {@link net.sf.tapestry.pageload.PageSource}
+  *  creates a new instance of it for each page to be loaded, which bypasses
+  *  multithreading issues.
   *
   *  @author Howard Lewis Ship
***************
*** 132,137 ****
          _pageSource = pageSource;
  
!         IEngine engine = cycle.getEngine();
!         RequestContext context = cycle.getRequestContext();
  
          // Need the location of the servlet within the context as the basis
--- 137,141 ----
          _pageSource = pageSource;
  
!          RequestContext context = cycle.getRequestContext();
  
          // Need the location of the servlet within the context as the basis
***************
*** 492,502 ****
          throws PageLoaderException
      {
-         String className;
-         Class pageClass;
          IPage result = null;
  
!         className = spec.getComponentClassName();
! 
!         pageClass = _resolver.findClass(className);
  
          try
--- 496,503 ----
          throws PageLoaderException
      {
          IPage result = null;
  
!         String className = spec.getComponentClassName();
!         Class pageClass = _resolver.findClass(className);
  
          try
***************
*** 637,644 ****
              baseLocation = _servletLocation;
  
          IResourceLocation assetLocation = baseLocation.getRelativeLocation(path);
  
          return _pageSource.getAsset(assetLocation);
- 
      }
  
--- 638,648 ----
              baseLocation = _servletLocation;
  
+         // One known problem is that relative private assets for pages
+         // whose spec is in the context (not the classpath) will be computed
+         // wrong!  In fact, they'll be ContextAssets.
+         
          IResourceLocation assetLocation = baseLocation.getRelativeLocation(path);
  
          return _pageSource.getAsset(assetLocation);
      }
  

Index: PageSource.java
===================================================================
RCS file: /cvsroot/tapestry/Tapestry/framework/src/net/sf/tapestry/pageload/PageSource.java,v
retrieving revision 1.13.2.2
retrieving revision 1.13.2.3
diff -C2 -d -r1.13.2.2 -r1.13.2.3
*** PageSource.java	8 Dec 2002 15:04:46 -0000	1.13.2.2
--- PageSource.java	11 Dec 2002 14:02:27 -0000	1.13.2.3
***************
*** 72,76 ****
      private Map _fieldBindings = new HashMap();
      private Map _staticBindings = new HashMap();
!         
      /**
       *  Map of {@link IAsset}.  Some entries use a string as a key (for extenal assets).
--- 72,76 ----
      private Map _fieldBindings = new HashMap();
      private Map _staticBindings = new HashMap();
! 
      /**
       *  Map of {@link IAsset}.  Some entries use a string as a key (for extenal assets).
***************
*** 79,129 ****
       * 
       **/
-     
-     private Map _assets = new HashMap();
-     
-     private IResourceResolver _resolver;
- 
-     private static class PageSpecificationResolver
-     {
-         private String _simplePageName;
-         private INamespace _namespace;
- 
-         private PageSpecificationResolver(ISpecificationSource source, String pageName)
-         {
-             int colonx = pageName.indexOf(':');
- 
-             if (colonx > 0)
-             {
-                 _simplePageName = pageName.substring(colonx + 1);
-                 String namespaceId = pageName.substring(0, colonx);
- 
  
!                 if (namespaceId.equals(INamespace.FRAMEWORK_NAMESPACE))
!                     _namespace = source.getFrameworkNamespace();
!                 else
!                     _namespace = source.getApplicationNamespace().getChildNamespace(namespaceId);
!             }
!             else
!             {
!                 _simplePageName = pageName;
! 
!                 _namespace = source.getApplicationNamespace();
! 
!                 if (!_namespace.containsPage(_simplePageName))
!                     _namespace = source.getFrameworkNamespace();
! 
!             }
!         }
! 
!         public INamespace getNamespace()
!         {
!             return _namespace;
!         }
  
!         public ComponentSpecification getSpecification()
!         {
!             return _namespace.getPageSpecification(_simplePageName);
!         }
!     }
  
      /**
--- 79,86 ----
       * 
       **/
  
!     private Map _assets = new HashMap();
  
!     private IResourceResolver _resolver;
  
      /**
***************
*** 135,138 ****
--- 92,104 ----
      private Pool _pool;
  
+     /**
+      *  Used to resolve page names to a namespace, a simple name, and a page specification.
+      * 
+      *  @since 2.4
+      * 
+      **/
+ 
+     private PageSpecificationResolver _pageSpecificationResolver;
+ 
      public PageSource(IResourceResolver resolver)
      {
***************
*** 197,203 ****
                  monitor.pageCreateBegin(pageName);
  
!             PageSpecificationResolver specificationResolver =
!                 new PageSpecificationResolver(engine.getSpecificationSource(), pageName);
  
              PageLoader loader = new PageLoader(this, cycle);
  
--- 163,175 ----
                  monitor.pageCreateBegin(pageName);
  
!             if (_pageSpecificationResolver == null)
!                 _pageSpecificationResolver = new PageSpecificationResolver(cycle);
  
+             _pageSpecificationResolver.resolve(pageName);
+ 
+             // Page loader's are not threadsafe, so we create a new
+             // one as needed.  However, they would make an excellent
+             // candidate for pooling.
+             
              PageLoader loader = new PageLoader(this, cycle);
  
***************
*** 205,213 ****
                  loader.loadPage(
                      pageName,
!                     specificationResolver.getNamespace(),
                      cycle,
!                     specificationResolver.getSpecification());
  
!              if (monitor != null)
                  monitor.pageCreateEnd(pageName);
          }
--- 177,185 ----
                  loader.loadPage(
                      pageName,
!                     _pageSpecificationResolver.getNamespace(),
                      cycle,
!                     _pageSpecificationResolver.getSpecification());
  
!             if (monitor != null)
                  monitor.pageCreateEnd(pageName);
          }
***************
*** 306,315 ****
      public synchronized IAsset getAsset(IResourceLocation location)
      {
!        IAsset result = (IAsset) _assets.get(location);
  
          if (result == null)
          {
              result = location.toAsset();
!             
              _assets.put(location, result);
          }
--- 278,287 ----
      public synchronized IAsset getAsset(IResourceLocation location)
      {
!         IAsset result = (IAsset) _assets.get(location);
  
          if (result == null)
          {
              result = location.toAsset();
! 
              _assets.put(location, result);
          }
***************
*** 322,326 ****
      {
          ToStringBuilder builder = new ToStringBuilder(this);
!         
          builder.append("pool", _pool);
          builder.append("assets", _assets);
--- 294,298 ----
      {
          ToStringBuilder builder = new ToStringBuilder(this);
! 
          builder.append("pool", _pool);
          builder.append("assets", _assets);
***************
*** 328,332 ****
          builder.append("staticBindings", _staticBindings);
          builder.append("resolver", _resolver);
!         
          return builder.toString();
      }
--- 300,304 ----
          builder.append("staticBindings", _staticBindings);
          builder.append("resolver", _resolver);
! 
          return builder.toString();
      }



-------------------------------------------------------
This sf.net email is sponsored by:
With Great Power, Comes Great Responsibility 
Learn to use your power at OSDN's High Performance Computing Channel
http://hpc.devchannel.org/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.