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