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