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