Clover coverage report - Code Coverage for tapestry release 4.0.2
Coverage timestamp: Thu Apr 13 2006 10:52:06 EDT
file stats: LOC: 289   Methods: 10
NCLOC: 136   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ComponentSpecificationResolverImpl.java 96.9% 98.6% 100% 98.3%
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.Location;
 20    import org.apache.hivemind.Resource;
 21    import org.apache.hivemind.impl.LocationImpl;
 22    import org.apache.hivemind.util.Defense;
 23    import org.apache.tapestry.INamespace;
 24    import org.apache.tapestry.IRequestCycle;
 25    import org.apache.tapestry.services.ClassFinder;
 26    import org.apache.tapestry.spec.ComponentSpecification;
 27    import org.apache.tapestry.spec.IComponentSpecification;
 28   
 29    /**
 30    * Utility class that understands the rules of component types (which may optionally have a library
 31    * prefix) and can resolve the type to a {@link org.apache.tapestry.INamespace}and a
 32    * {@link org.apache.tapestry.spec.IComponentSpecification}.
 33    * <p>
 34    * Like {@link org.apache.tapestry.resolver.PageSpecificationResolver}, if the component is not
 35    * defined explicitly in the namespace, a search may occur: Performs the tricky work of resolving a
 36    * page name to a page specification. The search for pages in the application namespace is the most
 37    * complicated, since Tapestry searches for pages that aren't explicitly defined in the application
 38    * specification. The search, based on the <i>simple-name </i> of the page, goes as follows:
 39    * <ul>
 40    * <li>As declared in the application specification
 41    * <li><i>type</i>.jwc in the same folder as the application specification
 42    * <li><i>type</i> jwc in the WEB-INF/ <i>servlet-name </i> directory of the context root
 43    * <li><i>type</i>.jwc in WEB-INF
 44    * <li><i>type</i>.jwc in the application root (within the context root)
 45    * <li>By searching the framework namespace
 46    * <li>By searching for a named class file within the org.apache.tapestry.component-class-packages
 47    * property (defined within the namespace)
 48    * </ul>
 49    * The search for components in library namespaces is more abbreviated:
 50    * <li>As declared in the library specification
 51    * <li><i>type </i>.jwc in the same folder as the library specification
 52    * <li>By searching the framework namespace
 53    * </ul>
 54    *
 55    * @author Howard Lewis Ship
 56    * @since 3.0
 57    */
 58   
 59    public class ComponentSpecificationResolverImpl extends AbstractSpecificationResolver implements
 60    ComponentSpecificationResolver
 61    {
 62    /** Set by container */
 63    private Log _log;
 64   
 65    /** Set by resolve() */
 66    private String _type;
 67   
 68    private ClassFinder _classFinder;
 69   
 70  1367 protected void reset()
 71    {
 72  1367 _type = null;
 73   
 74  1367 super.reset();
 75    }
 76   
 77    /**
 78    * Passed the namespace of a container (to resolve the type in) and the type to resolve,
 79    * performs the processing. A "bare type" (without a library prefix) may be in the
 80    * containerNamespace, or the framework namespace (a search occurs in that order).
 81    *
 82    * @param cycle
 83    * current request cycle
 84    * @param containerNamespace
 85    * namespace that may contain a library referenced in the type
 86    * @param type
 87    * the component specification to find, either a simple name, or prefixed with a
 88    * library id (defined for the container namespace)
 89    * @see #getNamespace()
 90    * @see #getSpecification()
 91    */
 92   
 93  897 public void resolve(IRequestCycle cycle, INamespace containerNamespace, String type,
 94    Location location)
 95    {
 96  897 Defense.notNull(type, "type");
 97   
 98  897 int colonx = type.indexOf(':');
 99   
 100  897 if (colonx > 0)
 101    {
 102  90 String libraryId = type.substring(0, colonx);
 103  90 String simpleType = type.substring(colonx + 1);
 104   
 105  90 resolve(cycle, containerNamespace, libraryId, simpleType, location);
 106    }
 107    else
 108  807 resolve(cycle, containerNamespace, null, type, location);
 109   
 110  896 IComponentSpecification spec = getSpecification();
 111   
 112  896 if (spec.isDeprecated())
 113  6 _log.warn(ResolverMessages.componentIsDeprecated(type, location));
 114    }
 115   
 116    /**
 117    * Like
 118    * {@link #resolve(org.apache.tapestry.IRequestCycle, org.apache.tapestry.INamespace, java.lang.String, org.apache.tapestry.ILocation)},
 119    * but used when the type has already been parsed into a library id and a simple type.
 120    *
 121    * @param cycle
 122    * current request cycle
 123    * @param containerNamespace
 124    * namespace that may contain a library referenced in the type
 125    * @param libraryId
 126    * the library id within the container namespace, or null
 127    * @param type
 128    * the component specification to find as a simple name (without a library prefix)
 129    * @param location
 130    * of reference to be resolved
 131    * @throws ApplicationRuntimeException
 132    * if the type cannot be resolved
 133    */
 134   
 135  1367 public void resolve(IRequestCycle cycle, INamespace containerNamespace, String libraryId,
 136    String type, Location location)
 137    {
 138  1367 reset();
 139  1367 _type = type;
 140   
 141  1367 INamespace namespace = findNamespaceForId(containerNamespace, libraryId);
 142   
 143  1367 setNamespace(namespace);
 144   
 145  1367 if (namespace.containsComponentType(type))
 146    {
 147  1210 setSpecification(namespace.getComponentSpecification(type));
 148  1210 return;
 149    }
 150   
 151  157 IComponentSpecification spec = searchForComponent(cycle);
 152   
 153    // If not found after search, check to see if it's in
 154    // the framework instead.
 155   
 156  157 if (spec == null)
 157    {
 158  1 throw new ApplicationRuntimeException(ResolverMessages.noSuchComponentType(
 159    type,
 160    namespace), location, null);
 161   
 162    }
 163   
 164  156 setSpecification(spec);
 165   
 166    // Install it into the namespace, to short-circuit any future search.
 167   
 168  156 install();
 169    }
 170   
 171    // Hm. This could maybe go elsewhere, say onto ISpecificationSource
 172   
 173  157 private IComponentSpecification searchForComponent(IRequestCycle cycle)
 174    {
 175  157 IComponentSpecification result = null;
 176  157 INamespace namespace = getNamespace();
 177   
 178  157 if (_log.isDebugEnabled())
 179  7 _log.debug(ResolverMessages.resolvingComponent(_type, namespace));
 180   
 181  157 String expectedName = _type + ".jwc";
 182  157 Resource namespaceLocation = namespace.getSpecificationLocation();
 183   
 184    // Look for appropriate file in same folder as the library (or application)
 185    // specificaiton.
 186   
 187  157 result = check(namespaceLocation.getRelativeResource(expectedName));
 188   
 189  157 if (result != null)
 190  9 return result;
 191   
 192  148 if (namespace.isApplicationNamespace())
 193    {
 194   
 195    // The application namespace gets some extra searching.
 196   
 197  108 result = check(getWebInfAppLocation().getRelativeResource(expectedName));
 198   
 199  108 if (result == null)
 200  107 result = check(getWebInfLocation().getRelativeResource(expectedName));
 201   
 202  108 if (result == null)
 203  106 result = check((getContextRoot().getRelativeResource(expectedName)));
 204   
 205  108 if (result != null)
 206  3 return result;
 207    }
 208   
 209  145 result = searchForComponentClass(namespace, _type);
 210   
 211  145 if (result != null)
 212  0 return result;
 213   
 214    // Not in the library or app spec; does it match a component
 215    // provided by the Framework?
 216   
 217  145 INamespace framework = getSpecificationSource().getFrameworkNamespace();
 218   
 219  145 if (framework.containsComponentType(_type))
 220  143 return framework.getComponentSpecification(_type);
 221   
 222  2 return getDelegate().findComponentSpecification(cycle, namespace, _type);
 223    }
 224   
 225  146 IComponentSpecification searchForComponentClass(INamespace namespace, String type)
 226    {
 227  146 String packages = namespace
 228    .getPropertyValue("org.apache.tapestry.component-class-packages");
 229   
 230  146 String className = type.replace('/', '.');
 231   
 232  146 Class componentClass = _classFinder.findClass(packages, className);
 233   
 234  146 if (componentClass == null)
 235  145 return null;
 236   
 237  1 IComponentSpecification spec = new ComponentSpecification();
 238   
 239  1 Resource namespaceResource = namespace.getSpecificationLocation();
 240   
 241  1 Resource componentResource = namespaceResource.getRelativeResource(type + ".jwc");
 242   
 243  1 Location location = new LocationImpl(componentResource);
 244   
 245  1 spec.setLocation(location);
 246  1 spec.setSpecificationLocation(componentResource);
 247  1 spec.setComponentClassName(componentClass.getName());
 248   
 249  1 return spec;
 250    }
 251   
 252  478 private IComponentSpecification check(Resource resource)
 253    {
 254  478 if (_log.isDebugEnabled())
 255  13 _log.debug("Checking: " + resource);
 256   
 257  478 if (resource.getResourceURL() == null)
 258  466 return null;
 259   
 260  12 return getSpecificationSource().getComponentSpecification(resource);
 261    }
 262   
 263  156 private void install()
 264    {
 265  156 INamespace namespace = getNamespace();
 266  156 IComponentSpecification specification = getSpecification();
 267   
 268  156 if (_log.isDebugEnabled())
 269  5 _log.debug(ResolverMessages.installingComponent(_type, namespace, specification));
 270   
 271  156 namespace.installComponentSpecification(_type, specification);
 272    }
 273   
 274  887 public String getType()
 275    {
 276  887 return _type;
 277    }
 278   
 279  102 public void setLog(Log log)
 280    {
 281  102 _log = log;
 282    }
 283   
 284  98 public void setClassFinder(ClassFinder classFinder)
 285    {
 286  98 _classFinder = classFinder;
 287    }
 288   
 289    }