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