Clover coverage report - Code Coverage for tapestry release 4.0-alpha-3
Coverage timestamp: Mon May 16 2005 09:05:49 EDT
file stats: LOC: 385   Methods: 25
NCLOC: 223   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
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.util.ClasspathResource;
 26   
 import org.apache.hivemind.ApplicationRuntimeException;
 27   
 import org.apache.hivemind.ClassResolver;
 28   
 import org.apache.hivemind.Location;
 29   
 import org.apache.hivemind.Resource;
 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  124
     public Namespace(String id, INamespace parent, ILibrarySpecification specification,
 84   
             ISpecificationSource specificationSource, ClassResolver resolver)
 85   
     {
 86  124
         _id = id;
 87  124
         _parent = parent;
 88  124
         _specification = specification;
 89  124
         _specificationSource = specificationSource;
 90  124
         _resolver = resolver;
 91   
 
 92  124
         _applicationNamespace = (_id == null);
 93  124
         _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  135
     public String getId()
 113   
     {
 114  135
         return _id;
 115   
     }
 116   
 
 117  228
     public String getExtendedId()
 118   
     {
 119  228
         if (_applicationNamespace)
 120  164
             return null;
 121   
 
 122  64
         if (_extendedId == null)
 123  31
             _extendedId = buildExtendedId();
 124   
 
 125  64
         return _extendedId;
 126   
     }
 127   
 
 128  0
     public INamespace getParentNamespace()
 129   
     {
 130  0
         return _parent;
 131   
     }
 132   
 
 133  164
     public INamespace getChildNamespace(String id)
 134   
     {
 135  164
         String firstId = id;
 136  164
         String nextIds = null;
 137   
 
 138   
         // Split the id into first and next if it is a dot separated sequence
 139  164
         int index = id.indexOf('.');
 140  164
         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  164
         INamespace result = (INamespace) _children.get(firstId);
 148   
 
 149  164
         if (result == null)
 150   
         {
 151  18
             result = createNamespace(firstId);
 152   
 
 153  18
             _children.put(firstId, result);
 154   
         }
 155   
 
 156   
         // If the id is a dot separated sequence, recurse to find
 157   
         // the needed namespace
 158  164
         if (result != null && nextIds != null)
 159  0
             result = result.getChildNamespace(nextIds);
 160   
 
 161  164
         return result;
 162   
     }
 163   
 
 164  0
     public List getChildIds()
 165   
     {
 166  0
         return _specification.getLibraryIds();
 167   
     }
 168   
 
 169  71
     public IComponentSpecification getPageSpecification(String name)
 170   
     {
 171  71
         IComponentSpecification result = (IComponentSpecification) _pages.get(name);
 172   
 
 173  71
         if (result == null)
 174   
         {
 175  49
             result = locatePageSpecification(name);
 176   
 
 177  49
             _pages.put(name, result);
 178   
         }
 179   
 
 180  71
         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  1525
     public IComponentSpecification getComponentSpecification(String alias)
 198   
     {
 199  1525
         IComponentSpecification result = (IComponentSpecification) _components.get(alias);
 200   
 
 201  1525
         if (result == null)
 202   
         {
 203  339
             result = locateComponentSpecification(alias);
 204  339
             _components.put(alias, result);
 205   
         }
 206   
 
 207  1525
         return result;
 208   
     }
 209   
 
 210  76
     public ILibrarySpecification getSpecification()
 211   
     {
 212  76
         return _specification;
 213   
     }
 214   
 
 215  31
     private String buildExtendedId()
 216   
     {
 217  31
         if (_parent == null)
 218  19
             return _id;
 219   
 
 220  12
         String parentId = _parent.getExtendedId();
 221   
 
 222   
         // If immediate child of application namespace
 223   
 
 224  12
         if (parentId == null)
 225  12
             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  49
     private IComponentSpecification locatePageSpecification(String name)
 254   
     {
 255  49
         String path = _specification.getPageSpecificationPath(name);
 256   
 
 257  49
         if (path == null)
 258  0
             throw new ApplicationRuntimeException(Tapestry.format(
 259   
                     "Namespace.no-such-page",
 260   
                     name,
 261   
                     getNamespaceId()));
 262   
 
 263  49
         Resource location = getSpecificationLocation().getRelativeResource(path);
 264   
 
 265  49
         return _specificationSource.getPageSpecification(location);
 266   
     }
 267   
 
 268  339
     private IComponentSpecification locateComponentSpecification(String type)
 269   
     {
 270  339
         String path = _specification.getComponentSpecificationPath(type);
 271   
 
 272  339
         if (path == null)
 273  0
             throw new ApplicationRuntimeException(Tapestry.format(
 274   
                     "Namespace.no-such-alias",
 275   
                     type,
 276   
                     getNamespaceId()));
 277   
 
 278  339
         Resource location = getSpecificationLocation().getRelativeResource(path);
 279   
 
 280  339
         return _specificationSource.getComponentSpecification(location);
 281   
     }
 282   
 
 283  18
     private INamespace createNamespace(String id)
 284   
     {
 285  18
         String path = _specification.getLibrarySpecificationPath(id);
 286   
 
 287  18
         if (path == null)
 288  0
             throw new ApplicationRuntimeException(Tapestry.format(
 289   
                     "Namespace.library-id-not-found",
 290   
                     id,
 291   
                     getNamespaceId()));
 292   
 
 293  18
         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  18
         if (location.getResourceURL() == null && path.startsWith("/"))
 301  1
             location = new ClasspathResource(_resolver, path);
 302   
 
 303  18
         ILibrarySpecification ls = _specificationSource.getLibrarySpecification(location);
 304   
 
 305  18
         return new Namespace(id, this, ls, _specificationSource, _resolver);
 306   
     }
 307   
 
 308  171
     public synchronized boolean containsPage(String name)
 309   
     {
 310  171
         return _pages.containsKey(name) || (_specification.getPageSpecificationPath(name) != null);
 311   
     }
 312   
 
 313   
     /** @since 2.3 * */
 314   
 
 315  140
     public String constructQualifiedName(String pageName)
 316   
     {
 317  140
         String prefix = getExtendedId();
 318   
 
 319  140
         if (prefix == null)
 320  107
             return pageName;
 321   
 
 322  33
         return prefix + SEPARATOR + pageName;
 323   
     }
 324   
 
 325   
     /** @since 3.0 * */
 326   
 
 327  987
     public Resource getSpecificationLocation()
 328   
     {
 329  987
         return _specification.getSpecificationLocation();
 330   
     }
 331   
 
 332   
     /** @since 3.0 * */
 333   
 
 334  274
     public boolean isApplicationNamespace()
 335   
     {
 336  274
         return _applicationNamespace;
 337   
     }
 338   
 
 339   
     /** @since 3.0 * */
 340   
 
 341  69
     public synchronized void installPageSpecification(String pageName,
 342   
             IComponentSpecification specification)
 343   
     {
 344  69
         _pages.put(pageName, specification);
 345   
     }
 346   
 
 347   
     /** @since 3.0 * */
 348   
 
 349  185
     public synchronized void installComponentSpecification(String type,
 350   
             IComponentSpecification specification)
 351   
     {
 352  185
         _components.put(type, specification);
 353   
     }
 354   
 
 355   
     /** @since 3.0 * */
 356   
 
 357  1710
     public synchronized boolean containsComponentType(String type)
 358   
     {
 359  1710
         return _components.containsKey(type)
 360   
                 || (_specification.getComponentSpecificationPath(type) != null);
 361   
     }
 362   
 
 363   
 
 364   
     /** @since 3.0 * */
 365   
 
 366  0
     public Location getLocation()
 367   
     {
 368  0
         if (_specification == null)
 369  0
             return null;
 370   
 
 371  0
         return _specification.getLocation();
 372   
     }
 373   
 
 374   
     /**
 375   
      * Returns property values defined in the namespace's library specification.
 376   
      * 
 377   
      * @return the property, or null if not provided in the specification.
 378   
      * @since 4.0
 379   
      */
 380   
 
 381  90
     public String getPropertyValue(String propertyName)
 382   
     {
 383  90
         return _specification.getProperty(propertyName);
 384   
     }
 385   
 }