Clover coverage report - Code Coverage for tapestry release 4.0-alpha-3
Coverage timestamp: Mon May 16 2005 09:05:49 EDT
file stats: LOC: 293   Methods: 11
NCLOC: 146   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
PageSpecificationResolverImpl.java 100% 100% 100% 100%
coverage
 1   
 // Copyright 2004, 2005 The Apache Software Foundation
 2   
 //
 3   
 // Licensed under the Apache License, Version 2.0 (the "License");
 4   
 // you may not use this file except in compliance with the License.
 5   
 // You may obtain a copy of the License at
 6   
 //
 7   
 //     http://www.apache.org/licenses/LICENSE-2.0
 8   
 //
 9   
 // Unless required by applicable law or agreed to in writing, software
 10   
 // distributed under the License is distributed on an "AS IS" BASIS,
 11   
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12   
 // See the License for the specific language governing permissions and
 13   
 // limitations under the License.
 14   
 
 15   
 package org.apache.tapestry.resolver;
 16   
 
 17   
 import org.apache.commons.logging.Log;
 18   
 import org.apache.hivemind.ApplicationRuntimeException;
 19   
 import org.apache.hivemind.Resource;
 20   
 import org.apache.tapestry.INamespace;
 21   
 import org.apache.tapestry.IRequestCycle;
 22   
 import org.apache.tapestry.PageNotFoundException;
 23   
 import org.apache.tapestry.Tapestry;
 24   
 import org.apache.tapestry.services.ComponentPropertySource;
 25   
 import org.apache.tapestry.spec.ComponentSpecification;
 26   
 import org.apache.tapestry.spec.IComponentSpecification;
 27   
 
 28   
 /**
 29   
  * Performs the tricky work of resolving a page name to a page specification. The search for pages
 30   
  * in the application namespace is the most complicated, since Tapestry searches for pages that
 31   
  * aren't explicitly defined in the application specification. The search, based on the
 32   
  * <i>simple-name </i> of the page, goes as follows:
 33   
  * <ul>
 34   
  * <li>As declared in the application specification
 35   
  * <li><i>simple-name </i>.page in the same folder as the application specification
 36   
  * <li><i>simple-name </i> page in the WEB-INF/ <i>servlet-name </i> directory of the context root
 37   
  * <li><i>simple-name </i>.page in WEB-INF
 38   
  * <li><i>simple-name </i>.page in the application root (within the context root)
 39   
  * <li><i>simple-name </i>.html as a template in the application root, for which an implicit
 40   
  * specification is generated
 41   
  * <li>By searching the framework namespace
 42   
  * <li>By invoking
 43   
  * {@link org.apache.tapestry.resolver.ISpecificationResolverDelegate#findPageSpecification(IRequestCycle, INamespace, String)}
 44   
  * </ul>
 45   
  * <p>
 46   
  * Pages in a component library are searched for in a more abbreviated fashion:
 47   
  * <ul>
 48   
  * <li>As declared in the library specification
 49   
  * <li><i>simple-name </i>.page in the same folder as the library specification
 50   
  * <li>By searching the framework namespace
 51   
  * <li>By invoking
 52   
  * {@link org.apache.tapestry.resolver.ISpecificationResolverDelegate#findPageSpecification(IRequestCycle, INamespace, String)}
 53   
  * </ul>
 54   
  * 
 55   
  * @see org.apache.tapestry.engine.IPageSource
 56   
  * @author Howard Lewis Ship
 57   
  * @since 3.0
 58   
  */
 59   
 
 60   
 public class PageSpecificationResolverImpl extends AbstractSpecificationResolver implements
 61   
         PageSpecificationResolver
 62   
 {
 63   
     /** set by container */
 64   
     private Log _log;
 65   
 
 66   
     /** Set by resolve() */
 67   
     private String _simpleName;
 68   
 
 69   
     /** @since 4.0 * */
 70   
     private INamespace _applicationNamespace;
 71   
 
 72   
     /** @since 4.0 * */
 73   
     private INamespace _frameworkNamespace;
 74   
 
 75   
     /** @since 4.0 */
 76   
 
 77   
     private ComponentPropertySource _componentPropertySource;
 78   
 
 79  121
     public void initializeService()
 80   
     {
 81  121
         _applicationNamespace = getSpecificationSource().getApplicationNamespace();
 82  121
         _frameworkNamespace = getSpecificationSource().getFrameworkNamespace();
 83   
 
 84  121
         super.initializeService();
 85   
     }
 86   
 
 87  152
     protected void reset()
 88   
     {
 89  152
         _simpleName = null;
 90   
 
 91  152
         super.reset();
 92   
     }
 93   
 
 94   
     /**
 95   
      * Resolve the name (which may have a library id prefix) to a namespace (see
 96   
      * {@link #getNamespace()}) and a specification (see {@link #getSpecification()}).
 97   
      * 
 98   
      * @throws ApplicationRuntimeException
 99   
      *             if the name cannot be resolved
 100   
      */
 101   
 
 102  152
     public void resolve(IRequestCycle cycle, String prefixedName)
 103   
     {
 104  152
         reset();
 105   
 
 106  152
         INamespace namespace = null;
 107   
 
 108  152
         int colonx = prefixedName.indexOf(':');
 109   
 
 110  152
         if (colonx > 0)
 111   
         {
 112  4
             _simpleName = prefixedName.substring(colonx + 1);
 113  4
             String namespaceId = prefixedName.substring(0, colonx);
 114   
 
 115  4
             if (namespaceId.equals(INamespace.FRAMEWORK_NAMESPACE))
 116  1
                 namespace = _frameworkNamespace;
 117   
             else
 118  3
                 namespace = _applicationNamespace.getChildNamespace(namespaceId);
 119   
         }
 120   
         else
 121   
         {
 122  148
             _simpleName = prefixedName;
 123   
 
 124  148
             namespace = _applicationNamespace;
 125   
         }
 126   
 
 127  152
         setNamespace(namespace);
 128   
 
 129  152
         if (namespace.containsPage(_simpleName))
 130   
         {
 131  45
             setSpecification(namespace.getPageSpecification(_simpleName));
 132  45
             return;
 133   
         }
 134   
 
 135   
         // Not defined in the specification, so it's time to hunt it down.
 136   
 
 137  107
         searchForPage(cycle);
 138   
 
 139  107
         if (getSpecification() == null)
 140  2
             throw new PageNotFoundException(ResolverMessages.noSuchPage(_simpleName, namespace));
 141   
     }
 142   
 
 143  150
     public String getSimplePageName()
 144   
     {
 145  150
         return _simpleName;
 146   
     }
 147   
 
 148  107
     private void searchForPage(IRequestCycle cycle)
 149   
     {
 150  107
         INamespace namespace = getNamespace();
 151   
 
 152  107
         if (_log.isDebugEnabled())
 153  8
             _log.debug(ResolverMessages.resolvingPage(_simpleName, namespace));
 154   
 
 155  107
         String expectedName = _simpleName + ".page";
 156   
 
 157  107
         Resource namespaceLocation = namespace.getSpecificationLocation();
 158   
 
 159   
         // See if there's a specification file in the same folder
 160   
         // as the library or application specification that's
 161   
         // supposed to contain the page.
 162   
 
 163  107
         if (found(namespaceLocation.getRelativeResource(expectedName)))
 164  51
             return;
 165   
 
 166  56
         if (namespace.isApplicationNamespace())
 167   
         {
 168   
 
 169   
             // The application namespace gets some extra searching.
 170   
 
 171  54
             if (found(getWebInfAppLocation().getRelativeResource(expectedName)))
 172  1
                 return;
 173   
 
 174  53
             if (found(getWebInfLocation().getRelativeResource(expectedName)))
 175  1
                 return;
 176   
 
 177  52
             if (found(getContextRoot().getRelativeResource(expectedName)))
 178  1
                 return;
 179   
 
 180   
             // The wierd one ... where we see if there's a template in the application root
 181   
             // location.
 182   
 
 183  51
             String templateName = _simpleName + "." + getTemplateExtension();
 184   
 
 185  51
             Resource templateResource = getContextRoot().getRelativeResource(templateName);
 186   
 
 187  51
             if (_log.isDebugEnabled())
 188  2
                 _log.debug(ResolverMessages.checkingResource(templateResource));
 189   
 
 190  51
             if (templateResource.getResourceURL() != null)
 191   
             {
 192  20
                 setupImplicitPage(templateResource);
 193  20
                 return;
 194   
             }
 195   
 
 196   
             // Not found in application namespace, so maybe its a framework page.
 197   
 
 198  31
             if (_frameworkNamespace.containsPage(_simpleName))
 199   
             {
 200  30
                 if (_log.isDebugEnabled())
 201  1
                     _log.debug(ResolverMessages.foundFrameworkPage(_simpleName));
 202   
 
 203  30
                 setNamespace(_frameworkNamespace);
 204   
 
 205   
                 // Note: This implies that normal lookup rules don't work
 206   
                 // for the framework! Framework pages must be
 207   
                 // defined in the framework library specification.
 208   
 
 209  30
                 setSpecification(_frameworkNamespace.getPageSpecification(_simpleName));
 210  30
                 return;
 211   
             }
 212   
         }
 213   
 
 214   
         // Not found by any normal rule, so its time to
 215   
         // consult the delegate.
 216   
 
 217  3
         IComponentSpecification specification = getDelegate().findPageSpecification(
 218   
                 cycle,
 219   
                 namespace,
 220   
                 _simpleName);
 221   
 
 222  3
         setSpecification(specification);
 223   
     }
 224   
 
 225  20
     private void setupImplicitPage(Resource resource)
 226   
     {
 227  20
         if (_log.isDebugEnabled())
 228  1
             _log.debug(ResolverMessages.foundHTMLTemplate(resource));
 229   
 
 230   
         // TODO The SpecFactory in Specification parser should be used in some way to
 231   
         // create an IComponentSpecification!
 232   
 
 233  20
         IComponentSpecification specification = new ComponentSpecification();
 234  20
         specification.setPageSpecification(true);
 235  20
         specification.setSpecificationLocation(resource);
 236   
 
 237  20
         setSpecification(specification);
 238   
 
 239  20
         install();
 240   
     }
 241   
 
 242  266
     private boolean found(Resource resource)
 243   
     {
 244  266
         if (_log.isDebugEnabled())
 245  20
             _log.debug(ResolverMessages.checkingResource(resource));
 246   
 
 247  266
         if (resource.getResourceURL() == null)
 248  212
             return false;
 249   
 
 250  54
         setSpecification(getSpecificationSource().getPageSpecification(resource));
 251   
 
 252  54
         install();
 253   
 
 254  54
         return true;
 255   
     }
 256   
 
 257  74
     private void install()
 258   
     {
 259  74
         INamespace namespace = getNamespace();
 260  74
         IComponentSpecification specification = getSpecification();
 261   
 
 262  74
         if (_log.isDebugEnabled())
 263  4
             _log.debug(ResolverMessages.installingPage(_simpleName, namespace, specification));
 264   
 
 265  74
         namespace.installPageSpecification(_simpleName, specification);
 266   
     }
 267   
 
 268   
     /**
 269   
      * If the namespace defines the template extension (as property
 270   
      * {@link Tapestry#TEMPLATE_EXTENSION_PROPERTY}, then that is used, otherwise the default is
 271   
      * used.
 272   
      */
 273   
 
 274  51
     private String getTemplateExtension()
 275   
     {
 276  51
         return _componentPropertySource.getNamespaceProperty(
 277   
                 getNamespace(),
 278   
                 Tapestry.TEMPLATE_EXTENSION_PROPERTY);
 279   
     }
 280   
 
 281   
     /** @since 4.0 */
 282   
 
 283  118
     public void setLog(Log log)
 284   
     {
 285  118
         _log = log;
 286   
     }
 287   
 
 288   
     /** @since 4.0 */
 289  112
     public void setComponentPropertySource(ComponentPropertySource componentPropertySource)
 290   
     {
 291  112
         _componentPropertySource = componentPropertySource;
 292   
     }
 293   
 }