Clover coverage report - Code Coverage for tapestry release 4.0-beta-2
Coverage timestamp: Sat Jul 9 2005 22:02:17 EDT
file stats: LOC: 254   Methods: 8
NCLOC: 118   Classes: 1
30 day Evaluation License registered to hlship@comcast.net Your 30 day evaluation period has expired. Please visit http://www.cenqua.com to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
ComponentSpecificationResolverImpl.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.Location;
 20    import org.apache.hivemind.Resource;
 21    import org.apache.tapestry.INamespace;
 22    import org.apache.tapestry.IRequestCycle;
 23    import org.apache.tapestry.spec.IComponentSpecification;
 24   
 25    /**
 26    * Utility class that understands the rules of component types (which may optionally have a library
 27    * prefix) and can resolve the type to a {@link org.apache.tapestry.INamespace}and a
 28    * {@link org.apache.tapestry.spec.IComponentSpecification}.
 29    * <p>
 30    * Like {@link org.apache.tapestry.resolver.PageSpecificationResolver}, if the component is not
 31    * defined explicitly in the namespace, a search may occur: Performs the tricky work of resolving a
 32    * page name to a page specification. The search for pages in the application namespace is the most
 33    * complicated, since Tapestry searches for pages that aren't explicitly defined in the application
 34    * specification. The search, based on the <i>simple-name </i> of the page, goes as follows:
 35    * <ul>
 36    * <li>As declared in the application specification
 37    * <li><i>type </i>.jwc in the same folder as the application specification
 38    * <li><i>type </i> jwc in the WEB-INF/ <i>servlet-name </i> directory of the context root
 39    * <li><i>type </i>.jwc in WEB-INF
 40    * <li><i>type </i>.jwc in the application root (within the context root)
 41    * <li>By searching the framework namespace
 42    * </ul>
 43    * The search for components in library namespaces is more abbreviated:
 44    * <li>As declared in the library specification
 45    * <li><i>type </i>.jwc in the same folder as the library specification
 46    * <li>By searching the framework namespace
 47    * </ul>
 48    *
 49    * @author Howard Lewis Ship
 50    * @since 3.0
 51    */
 52   
 53    public class ComponentSpecificationResolverImpl extends AbstractSpecificationResolver implements
 54    ComponentSpecificationResolver
 55    {
 56    /** Set by container */
 57    private Log _log;
 58   
 59    /** Set by resolve() */
 60    private String _type;
 61   
 62  1469 protected void reset()
 63    {
 64  1469 _type = null;
 65   
 66  1469 super.reset();
 67    }
 68   
 69    /**
 70    * Passed the namespace of a container (to resolve the type in) and the type to resolve,
 71    * performs the processing. A "bare type" (without a library prefix) may be in the
 72    * containerNamespace, or the framework namespace (a search occurs in that order).
 73    *
 74    * @param cycle
 75    * current request cycle
 76    * @param containerNamespace
 77    * namespace that may contain a library referenced in the type
 78    * @param type
 79    * the component specification to find, either a simple name, or prefixed with a
 80    * library id (defined for the container namespace)
 81    * @see #getNamespace()
 82    * @see #getSpecification()
 83    */
 84   
 85  978 public void resolve(IRequestCycle cycle, INamespace containerNamespace, String type,
 86    Location location)
 87    {
 88  978 int colonx = type.indexOf(':');
 89   
 90  978 if (colonx > 0)
 91    {
 92  90 String libraryId = type.substring(0, colonx);
 93  90 String simpleType = type.substring(colonx + 1);
 94   
 95  90 resolve(cycle, containerNamespace, libraryId, simpleType, location);
 96    }
 97    else
 98  888 resolve(cycle, containerNamespace, null, type, location);
 99   
 100  977 IComponentSpecification spec = getSpecification();
 101   
 102  977 if (spec.isDeprecated())
 103  5 _log.error(ResolverMessages.componentIsDeprecated(type, location));
 104    }
 105   
 106    /**
 107    * Like
 108    * {@link #resolve(org.apache.tapestry.IRequestCycle, org.apache.tapestry.INamespace, java.lang.String, org.apache.tapestry.ILocation)},
 109    * but used when the type has already been parsed into a library id and a simple type.
 110    *
 111    * @param cycle
 112    * current request cycle
 113    * @param containerNamespace
 114    * namespace that may contain a library referenced in the type
 115    * @param libraryId
 116    * the library id within the container namespace, or null
 117    * @param type
 118    * the component specification to find as a simple name (without a library prefix)
 119    * @param location
 120    * of reference to be resolved
 121    * @throws ApplicationRuntimeException
 122    * if the type cannot be resolved
 123    */
 124   
 125  1469 public void resolve(IRequestCycle cycle, INamespace containerNamespace, String libraryId,
 126    String type, Location location)
 127    {
 128  1469 reset();
 129  1469 _type = type;
 130   
 131  1469 INamespace namespace = null;
 132   
 133  1469 if (libraryId != null)
 134  160 namespace = containerNamespace.getChildNamespace(libraryId);
 135    else
 136  1309 namespace = containerNamespace;
 137   
 138  1469 setNamespace(namespace);
 139   
 140  1469 if (namespace.containsComponentType(type))
 141  1303 setSpecification(namespace.getComponentSpecification(type));
 142    else
 143  166 searchForComponent(cycle);
 144   
 145    // If not found after search, check to see if it's in
 146    // the framework instead.
 147   
 148  1469 if (getSpecification() == null)
 149    {
 150   
 151  1 throw new ApplicationRuntimeException(ResolverMessages.noSuchComponentType(
 152    type,
 153    namespace), location, null);
 154   
 155    }
 156    }
 157   
 158    // TODO: This looks like a chain-of-command to me
 159   
 160  166 private void searchForComponent(IRequestCycle cycle)
 161    {
 162  166 INamespace namespace = getNamespace();
 163   
 164  166 if (_log.isDebugEnabled())
 165  7 _log.debug(ResolverMessages.resolvingComponent(_type, namespace));
 166   
 167  166 String expectedName = _type + ".jwc";
 168  166 Resource namespaceLocation = namespace.getSpecificationLocation();
 169   
 170    // Look for appropriate file in same folder as the library (or application)
 171    // specificaiton.
 172   
 173  166 if (found(namespaceLocation.getRelativeResource(expectedName)))
 174  9 return;
 175   
 176  157 if (namespace.isApplicationNamespace())
 177    {
 178   
 179    // The application namespace gets some extra searching.
 180   
 181  117 if (found(getWebInfAppLocation().getRelativeResource(expectedName)))
 182  1 return;
 183   
 184  116 if (found(getWebInfLocation().getRelativeResource(expectedName)))
 185  1 return;
 186   
 187  115 if (found(getContextRoot().getRelativeResource(expectedName)))
 188  1 return;
 189    }
 190   
 191    // Not in the library or app spec; does it match a component
 192    // provided by the Framework?
 193   
 194  154 INamespace framework = getSpecificationSource().getFrameworkNamespace();
 195   
 196  154 if (framework.containsComponentType(_type))
 197    {
 198  152 setSpecification(framework.getComponentSpecification(_type));
 199   
 200  152 install();
 201   
 202  152 return;
 203    }
 204   
 205  2 IComponentSpecification specification = getDelegate().findComponentSpecification(
 206    cycle,
 207    namespace,
 208    _type);
 209   
 210  2 if (specification != null)
 211    {
 212  1 setSpecification(specification);
 213  1 install();
 214  1 return;
 215    }
 216    }
 217   
 218  514 private boolean found(Resource resource)
 219    {
 220  514 if (_log.isDebugEnabled())
 221  13 _log.debug("Checking: " + resource);
 222   
 223  514 if (resource.getResourceURL() == null)
 224  502 return false;
 225   
 226  12 setSpecification(getSpecificationSource().getComponentSpecification(resource));
 227   
 228  12 install();
 229   
 230  12 return true;
 231    }
 232   
 233  165 private void install()
 234    {
 235  165 INamespace namespace = getNamespace();
 236  165 IComponentSpecification specification = getSpecification();
 237   
 238  165 if (_log.isDebugEnabled())
 239  5 _log.debug(ResolverMessages.installingComponent(_type, namespace, specification));
 240   
 241  165 namespace.installComponentSpecification(_type, specification);
 242    }
 243   
 244  968 public String getType()
 245    {
 246  968 return _type;
 247    }
 248   
 249  109 public void setLog(Log log)
 250    {
 251  109 _log = log;
 252    }
 253   
 254    }