KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tapestry > engine > Namespace


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 JavaDoc;
18 import java.util.Collections JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.HashSet JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Map JavaDoc;
23 import java.util.Set JavaDoc;
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 JavaDoc _id;
50
51     private String JavaDoc _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 JavaDoc _pages = Collections.synchronizedMap(new HashMap JavaDoc());
70
71     /**
72      * Map of {@link org.apache.tapestry.spec.ComponentSpecification}keyed on component alias.
73      */

74
75     private Map JavaDoc _components = Collections.synchronizedMap(new HashMap JavaDoc());
76
77     /**
78      * Map, keyed on id, of {@link INamespace}.
79      */

80
81     private Map JavaDoc _children = Collections.synchronizedMap(new HashMap JavaDoc());
82
83     public Namespace(String JavaDoc id, INamespace parent, ILibrarySpecification specification,
84             ISpecificationSource specificationSource, ClassResolver resolver)
85     {
86         _id = id;
87         _parent = parent;
88         _specification = specification;
89         _specificationSource = specificationSource;
90         _resolver = resolver;
91
92         _applicationNamespace = (_id == null);
93         _frameworkNamespace = FRAMEWORK_NAMESPACE.equals(_id);
94     }
95
96     public String JavaDoc toString()
97     {
98         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc("Namespace@");
99         buffer.append(Integer.toHexString(hashCode()));
100         buffer.append('[');
101
102         if (_applicationNamespace)
103             buffer.append("<application>");
104         else
105             buffer.append(getExtendedId());
106
107         buffer.append(']');
108
109         return buffer.toString();
110     }
111
112     public String JavaDoc getId()
113     {
114         return _id;
115     }
116
117     public String JavaDoc getExtendedId()
118     {
119         if (_applicationNamespace)
120             return null;
121
122         if (_extendedId == null)
123             _extendedId = buildExtendedId();
124
125         return _extendedId;
126     }
127
128     public INamespace getParentNamespace()
129     {
130         return _parent;
131     }
132
133     public INamespace getChildNamespace(String JavaDoc id)
134     {
135         String JavaDoc firstId = id;
136         String JavaDoc nextIds = null;
137
138         // Split the id into first and next if it is a dot separated sequence
139
int index = id.indexOf('.');
140         if (index >= 0)
141         {
142             firstId = id.substring(0, index);
143             nextIds = id.substring(index + 1);
144         }
145
146         // Get the first namespace
147
INamespace result = (INamespace) _children.get(firstId);
148
149         if (result == null)
150         {
151             result = createNamespace(firstId);
152
153             _children.put(firstId, result);
154         }
155
156         // If the id is a dot separated sequence, recurse to find
157
// the needed namespace
158
if (result != null && nextIds != null)
159             result = result.getChildNamespace(nextIds);
160
161         return result;
162     }
163
164     public List JavaDoc getChildIds()
165     {
166         return _specification.getLibraryIds();
167     }
168
169     public IComponentSpecification getPageSpecification(String JavaDoc name)
170     {
171         IComponentSpecification result = (IComponentSpecification) _pages.get(name);
172
173         if (result == null)
174         {
175             result = locatePageSpecification(name);
176
177             _pages.put(name, result);
178         }
179
180         return result;
181     }
182
183     public List JavaDoc getPageNames()
184     {
185         Set JavaDoc names = new HashSet JavaDoc();
186
187         names.addAll(_pages.keySet());
188         names.addAll(_specification.getPageNames());
189
190         List JavaDoc result = new ArrayList JavaDoc(names);
191
192         Collections.sort(result);
193
194         return result;
195     }
196
197     public IComponentSpecification getComponentSpecification(String JavaDoc alias)
198     {
199         IComponentSpecification result = (IComponentSpecification) _components.get(alias);
200
201         if (result == null)
202         {
203             result = locateComponentSpecification(alias);
204             _components.put(alias, result);
205         }
206
207         return result;
208     }
209
210     public ILibrarySpecification getSpecification()
211     {
212         return _specification;
213     }
214
215     private String JavaDoc buildExtendedId()
216     {
217         if (_parent == null)
218             return _id;
219
220         String JavaDoc parentId = _parent.getExtendedId();
221
222         // If immediate child of application namespace
223

224         if (parentId == null)
225             return _id;
226
227         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     public String JavaDoc getNamespaceId()
236     {
237         if (_frameworkNamespace)
238             return Tapestry.getMessage("Namespace.framework-namespace");
239
240         if (_applicationNamespace)
241             return Tapestry.getMessage("Namespace.application-namespace");
242
243         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     private IComponentSpecification locatePageSpecification(String JavaDoc name)
254     {
255         String JavaDoc path = _specification.getPageSpecificationPath(name);
256
257         if (path == null)
258             throw new ApplicationRuntimeException(Tapestry.format(
259                     "Namespace.no-such-page",
260                     name,
261                     getNamespaceId()));
262
263         Resource location = getSpecificationLocation().getRelativeResource(path);
264
265         return _specificationSource.getPageSpecification(location);
266     }
267
268     private IComponentSpecification locateComponentSpecification(String JavaDoc type)
269     {
270         String JavaDoc path = _specification.getComponentSpecificationPath(type);
271
272         if (path == null)
273             throw new ApplicationRuntimeException(Tapestry.format(
274                     "Namespace.no-such-alias",
275                     type,
276                     getNamespaceId()));
277
278         Resource location = getSpecificationLocation().getRelativeResource(path);
279
280         return _specificationSource.getComponentSpecification(location);
281     }
282
283     private INamespace createNamespace(String JavaDoc id)
284     {
285         String JavaDoc path = _specification.getLibrarySpecificationPath(id);
286
287         if (path == null)
288             throw new ApplicationRuntimeException(Tapestry.format(
289                     "Namespace.library-id-not-found",
290                     id,
291                     getNamespaceId()));
292
293         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         if (location.getResourceURL() == null && path.startsWith("/"))
301             location = new ClasspathResource(_resolver, path);
302
303         ILibrarySpecification ls = _specificationSource.getLibrarySpecification(location);
304
305         return new Namespace(id, this, ls, _specificationSource, _resolver);
306     }
307
308     public synchronized boolean containsPage(String JavaDoc name)
309     {
310         return _pages.containsKey(name) || (_specification.getPageSpecificationPath(name) != null);
311     }
312
313     /** @since 2.3 * */
314
315     public String JavaDoc constructQualifiedName(String JavaDoc pageName)
316     {
317         String JavaDoc prefix = getExtendedId();
318
319         if (prefix == null)
320             return pageName;
321
322         return prefix + SEPARATOR + pageName;
323     }
324
325     /** @since 3.0 * */
326
327     public Resource getSpecificationLocation()
328     {
329         return _specification.getSpecificationLocation();
330     }
331
332     /** @since 3.0 * */
333
334     public boolean isApplicationNamespace()
335     {
336         return _applicationNamespace;
337     }
338
339     /** @since 3.0 * */
340
341     public synchronized void installPageSpecification(String JavaDoc pageName,
342             IComponentSpecification specification)
343     {
344         _pages.put(pageName, specification);
345     }
346
347     /** @since 3.0 * */
348
349     public synchronized void installComponentSpecification(String JavaDoc type,
350             IComponentSpecification specification)
351     {
352         _components.put(type, specification);
353     }
354
355     /** @since 3.0 * */
356
357     public synchronized boolean containsComponentType(String JavaDoc type)
358     {
359         return _components.containsKey(type)
360                 || (_specification.getComponentSpecificationPath(type) != null);
361     }
362
363
364     /** @since 3.0 * */
365
366     public Location getLocation()
367     {
368         if (_specification == null)
369             return null;
370
371         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     public String JavaDoc getPropertyValue(String JavaDoc propertyName)
382     {
383         return _specification.getProperty(propertyName);
384     }
385 }
Popular Tags