Clover coverage report - Code Coverage for tapestry release 4.0-beta-6
Coverage timestamp: Wed Sep 7 2005 18:41:34 EDT
file stats: LOC: 384   Methods: 25
NCLOC: 223   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
Namespace.java 66.7% 70.8% 80% 71.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.engine;
 16   
 17    import java.util.ArrayList;
 18    import java.util.Collections;
 19    import java.util.HashMap;
 20    import java.util.HashSet;
 21    import java.util.List;
 22    import java.util.Map;
 23    import java.util.Set;
 24   
 25    import org.apache.hivemind.ApplicationRuntimeException;
 26    import org.apache.hivemind.ClassResolver;
 27    import org.apache.hivemind.Location;
 28    import org.apache.hivemind.Resource;
 29    import org.apache.hivemind.util.ClasspathResource;
 30    import org.apache.tapestry.INamespace;
 31    import org.apache.tapestry.Tapestry;
 32    import org.apache.tapestry.spec.IComponentSpecification;
 33    import org.apache.tapestry.spec.ILibrarySpecification;
 34   
 35    /**
 36    * Implementation of {@link org.apache.tapestry.INamespace}that works with a
 37    * {@link ISpecificationSource}to obtain page and component specifications as needed.
 38    *
 39    * @author Howard Lewis Ship
 40    * @since 2.2
 41    */
 42   
 43    public class Namespace implements INamespace
 44    {
 45    private ILibrarySpecification _specification;
 46   
 47    private ISpecificationSource _specificationSource;
 48   
 49    private String _id;
 50   
 51    private String _extendedId;
 52   
 53    private INamespace _parent;
 54   
 55    private boolean _frameworkNamespace;
 56   
 57    private boolean _applicationNamespace;
 58   
 59    /** @since 4.0 */
 60   
 61    private ClassResolver _resolver;
 62   
 63    /**
 64    * Map of {@link org.apache.tapestry.spec.ComponentSpecification}keyed on page name. The map is
 65    * synchronized because different threads may try to update it simultaneously (due to dynamic
 66    * page discovery in the application namespace).
 67    */
 68   
 69    private Map _pages = Collections.synchronizedMap(new HashMap());
 70   
 71    /**
 72    * Map of {@link org.apache.tapestry.spec.ComponentSpecification}keyed on component alias.
 73    */
 74   
 75    private Map _components = Collections.synchronizedMap(new HashMap());
 76   
 77    /**
 78    * Map, keyed on id, of {@link INamespace}.
 79    */
 80   
 81    private Map _children = Collections.synchronizedMap(new HashMap());
 82   
 83  116 public Namespace(String id, INamespace parent, ILibrarySpecification specification,
 84    ISpecificationSource specificationSource, ClassResolver resolver)
 85    {
 86  116 _id = id;
 87  116 _parent = parent;
 88  116 _specification = specification;
 89  116 _specificationSource = specificationSource;
 90  116 _resolver = resolver;
 91   
 92  116 _applicationNamespace = (_id == null);
 93  116 _frameworkNamespace = FRAMEWORK_NAMESPACE.equals(_id);
 94    }
 95   
 96  0 public String toString()
 97    {
 98  0 StringBuffer buffer = new StringBuffer("Namespace@");
 99  0 buffer.append(Integer.toHexString(hashCode()));
 100  0 buffer.append('[');
 101   
 102  0 if (_applicationNamespace)
 103  0 buffer.append("<application>");
 104    else
 105  0 buffer.append(getExtendedId());
 106   
 107  0 buffer.append(']');
 108   
 109  0 return buffer.toString();
 110    }
 111   
 112  118 public String getId()
 113    {
 114  118 return _id;
 115    }
 116   
 117  212 public String getExtendedId()
 118    {
 119  212 if (_applicationNamespace)
 120  151 return null;
 121   
 122  61 if (_extendedId == null)
 123  29 _extendedId = buildExtendedId();
 124   
 125  61 return _extendedId;
 126    }
 127   
 128  0 public INamespace getParentNamespace()
 129    {
 130  0 return _parent;
 131    }
 132   
 133  161 public INamespace getChildNamespace(String id)
 134    {
 135  161 String firstId = id;
 136  161 String nextIds = null;
 137   
 138    // Split the id into first and next if it is a dot separated sequence
 139  161 int index = id.indexOf('.');
 140  161 if (index >= 0)
 141    {
 142  0 firstId = id.substring(0, index);
 143  0 nextIds = id.substring(index + 1);
 144    }
 145   
 146    // Get the first namespace
 147  161 INamespace result = (INamespace) _children.get(firstId);
 148   
 149  161 if (result == null)
 150    {
 151  17 result = createNamespace(firstId);
 152   
 153  17 _children.put(firstId, result);
 154    }
 155   
 156    // If the id is a dot separated sequence, recurse to find
 157    // the needed namespace
 158  161 if (result != null && nextIds != null)
 159  0 result = result.getChildNamespace(nextIds);
 160   
 161  161 return result;
 162    }
 163   
 164  0 public List getChildIds()
 165    {
 166  0 return _specification.getLibraryIds();
 167    }
 168   
 169  67 public IComponentSpecification getPageSpecification(String name)
 170    {
 171  67 IComponentSpecification result = (IComponentSpecification) _pages.get(name);
 172   
 173  67 if (result == null)
 174    {
 175  45 result = locatePageSpecification(name);
 176   
 177  45 _pages.put(name, result);
 178    }
 179   
 180  67 return result;
 181    }
 182   
 183  0 public List getPageNames()
 184    {
 185  0 Set names = new HashSet();
 186   
 187  0 names.addAll(_pages.keySet());
 188  0 names.addAll(_specification.getPageNames());
 189   
 190  0 List result = new ArrayList(names);
 191   
 192  0 Collections.sort(result);
 193   
 194  0 return result;
 195    }
 196   
 197  1473 public IComponentSpecification getComponentSpecification(String alias)
 198    {
 199  1473 IComponentSpecification result = (IComponentSpecification) _components.get(alias);
 200   
 201  1473 if (result == null)
 202    {
 203  304 result = locateComponentSpecification(alias);
 204  304 _components.put(alias, result);
 205    }
 206   
 207  1473 return result;
 208    }
 209   
 210  70 public ILibrarySpecification getSpecification()
 211    {
 212  70 return _specification;
 213    }
 214   
 215  29 private String buildExtendedId()
 216    {
 217  29 if (_parent == null)
 218  18 return _id;
 219   
 220  11 String parentId = _parent.getExtendedId();
 221   
 222    // If immediate child of application namespace
 223   
 224  11 if (parentId == null)
 225  11 return _id;
 226   
 227  0 return parentId + "." + _id;
 228    }
 229   
 230    /**
 231    * Returns a string identifying the namespace, for use in error messages. I.e., "Application
 232    * namespace" or "namespace 'foo'".
 233    */
 234   
 235  1 public String getNamespaceId()
 236    {
 237  1 if (_frameworkNamespace)
 238  0 return Tapestry.getMessage("Namespace.framework-namespace");
 239   
 240  1 if (_applicationNamespace)
 241  1 return Tapestry.getMessage("Namespace.application-namespace");
 242   
 243  0 return Tapestry.format("Namespace.nested-namespace", getExtendedId());
 244    }
 245   
 246    /**
 247    * Gets the specification from the specification source.
 248    *
 249    * @throws ApplicationRuntimeException
 250    * if the named page is not defined.
 251    */
 252   
 253  45 private IComponentSpecification locatePageSpecification(String name)
 254    {
 255  45 String path = _specification.getPageSpecificationPath(name);
 256   
 257  45 if (path == null)
 258  0 throw new ApplicationRuntimeException(Tapestry.format(
 259    "Namespace.no-such-page",
 260    name,
 261    getNamespaceId()));
 262   
 263  45 Resource location = getSpecificationLocation().getRelativeResource(path);
 264   
 265  45 return _specificationSource.getPageSpecification(location);
 266    }
 267   
 268  304 private IComponentSpecification locateComponentSpecification(String type)
 269    {
 270  304 String path = _specification.getComponentSpecificationPath(type);
 271   
 272  304 if (path == null)
 273  0 throw new ApplicationRuntimeException(Tapestry.format(
 274    "Namespace.no-such-alias",
 275    type,
 276    getNamespaceId()));
 277   
 278  304 Resource location = getSpecificationLocation().getRelativeResource(path);
 279   
 280  304 return _specificationSource.getComponentSpecification(location);
 281    }
 282   
 283  17 private INamespace createNamespace(String id)
 284    {
 285  17 String path = _specification.getLibrarySpecificationPath(id);
 286   
 287  17 if (path == null)
 288  0 throw new ApplicationRuntimeException(Tapestry.format(
 289    "Namespace.library-id-not-found",
 290    id,
 291    getNamespaceId()));
 292   
 293  17 Resource location = getSpecificationLocation().getRelativeResource(path);
 294   
 295    // Ok, an absolute path to a library for an application whose specification
 296    // is in the context root is problematic, cause getRelativeLocation()
 297    // will still be looking in the context. Handle this case with the
 298    // following little kludge:
 299   
 300  17 if (location.getResourceURL() == null && path.startsWith("/"))
 301  1 location = new ClasspathResource(_resolver, path);
 302   
 303  17 ILibrarySpecification ls = _specificationSource.getLibrarySpecification(location);
 304   
 305  17 return new Namespace(id, this, ls, _specificationSource, _resolver);
 306    }
 307   
 308  161 public synchronized boolean containsPage(String name)
 309    {
 310  161 return _pages.containsKey(name) || (_specification.getPageSpecificationPath(name) != null);
 311    }
 312   
 313    /** @since 2.3 * */
 314   
 315  131 public String constructQualifiedName(String pageName)
 316    {
 317  131 String prefix = getExtendedId();
 318   
 319  131 if (prefix == null)
 320  99 return pageName;
 321   
 322  32 return prefix + SEPARATOR + pageName;
 323    }
 324   
 325    /** @since 3.0 * */
 326   
 327  992 public Resource getSpecificationLocation()
 328    {
 329  992 return _specification.getSpecificationLocation();
 330    }
 331   
 332    /** @since 3.0 * */
 333   
 334  260 public boolean isApplicationNamespace()
 335    {
 336  260 return _applicationNamespace;
 337    }
 338   
 339    /** @since 3.0 * */
 340   
 341  64 public synchronized void installPageSpecification(String pageName,
 342    IComponentSpecification specification)
 343    {
 344  64 _pages.put(pageName, specification);
 345    }
 346   
 347    /** @since 3.0 * */
 348   
 349  159 public synchronized void installComponentSpecification(String type,
 350    IComponentSpecification specification)
 351    {
 352  159 _components.put(type, specification);
 353    }
 354   
 355    /** @since 3.0 * */
 356   
 357  1632 public synchronized boolean containsComponentType(String type)
 358    {
 359  1632 return _components.containsKey(type)
 360    || (_specification.getComponentSpecificationPath(type) != null);
 361    }
 362   
 363    /** @since 3.0 * */
 364   
 365  0 public Location getLocation()
 366    {
 367  0 if (_specification == null)
 368  0 return null;
 369   
 370  0 return _specification.getLocation();
 371    }
 372   
 373    /**
 374    * Returns property values defined in the namespace's library specification.
 375    *
 376    * @return the property, or null if not provided in the specification.
 377    * @since 4.0
 378    */
 379   
 380  276 public String getPropertyValue(String propertyName)
 381    {
 382  276 return _specification.getProperty(propertyName);
 383    }
 384    }