KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tapestry > resolver > PageSpecificationResolverImpl


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.resolver;
16
17 import org.apache.commons.logging.Log;
18 import org.apache.hivemind.ApplicationRuntimeException;
19 import org.apache.hivemind.Resource;
20 import org.apache.tapestry.INamespace;
21 import org.apache.tapestry.IRequestCycle;
22 import org.apache.tapestry.PageNotFoundException;
23 import org.apache.tapestry.Tapestry;
24 import org.apache.tapestry.services.ComponentPropertySource;
25 import org.apache.tapestry.spec.ComponentSpecification;
26 import org.apache.tapestry.spec.IComponentSpecification;
27
28 /**
29  * Performs the tricky work of resolving a page name to a page specification. The search for pages
30  * in the application namespace is the most complicated, since Tapestry searches for pages that
31  * aren't explicitly defined in the application specification. The search, based on the
32  * <i>simple-name </i> of the page, goes as follows:
33  * <ul>
34  * <li>As declared in the application specification
35  * <li><i>simple-name </i>.page in the same folder as the application specification
36  * <li><i>simple-name </i> page in the WEB-INF/ <i>servlet-name </i> directory of the context root
37  * <li><i>simple-name </i>.page in WEB-INF
38  * <li><i>simple-name </i>.page in the application root (within the context root)
39  * <li><i>simple-name </i>.html as a template in the application root, for which an implicit
40  * specification is generated
41  * <li>By searching the framework namespace
42  * <li>By invoking
43  * {@link org.apache.tapestry.resolver.ISpecificationResolverDelegate#findPageSpecification(IRequestCycle, INamespace, String)}
44  * </ul>
45  * <p>
46  * Pages in a component library are searched for in a more abbreviated fashion:
47  * <ul>
48  * <li>As declared in the library specification
49  * <li><i>simple-name </i>.page in the same folder as the library specification
50  * <li>By searching the framework namespace
51  * <li>By invoking
52  * {@link org.apache.tapestry.resolver.ISpecificationResolverDelegate#findPageSpecification(IRequestCycle, INamespace, String)}
53  * </ul>
54  *
55  * @see org.apache.tapestry.engine.IPageSource
56  * @author Howard Lewis Ship
57  * @since 3.0
58  */

59
60 public class PageSpecificationResolverImpl extends AbstractSpecificationResolver implements
61         PageSpecificationResolver
62 {
63     /** set by container */
64     private Log _log;
65
66     /** Set by resolve() */
67     private String JavaDoc _simpleName;
68
69     /** @since 4.0 * */
70     private INamespace _applicationNamespace;
71
72     /** @since 4.0 * */
73     private INamespace _frameworkNamespace;
74
75     /** @since 4.0 */
76
77     private ComponentPropertySource _componentPropertySource;
78
79     public void initializeService()
80     {
81         _applicationNamespace = getSpecificationSource().getApplicationNamespace();
82         _frameworkNamespace = getSpecificationSource().getFrameworkNamespace();
83
84         super.initializeService();
85     }
86
87     protected void reset()
88     {
89         _simpleName = null;
90
91         super.reset();
92     }
93
94     /**
95      * Resolve the name (which may have a library id prefix) to a namespace (see
96      * {@link #getNamespace()}) and a specification (see {@link #getSpecification()}).
97      *
98      * @throws ApplicationRuntimeException
99      * if the name cannot be resolved
100      */

101
102     public void resolve(IRequestCycle cycle, String JavaDoc prefixedName)
103     {
104         reset();
105
106         INamespace namespace = null;
107
108         int colonx = prefixedName.indexOf(':');
109
110         if (colonx > 0)
111         {
112             _simpleName = prefixedName.substring(colonx + 1);
113             String JavaDoc namespaceId = prefixedName.substring(0, colonx);
114
115             if (namespaceId.equals(INamespace.FRAMEWORK_NAMESPACE))
116                 namespace = _frameworkNamespace;
117             else
118                 namespace = _applicationNamespace.getChildNamespace(namespaceId);
119         }
120         else
121         {
122             _simpleName = prefixedName;
123
124             namespace = _applicationNamespace;
125         }
126
127         setNamespace(namespace);
128
129         if (namespace.containsPage(_simpleName))
130         {
131             setSpecification(namespace.getPageSpecification(_simpleName));
132             return;
133         }
134
135         // Not defined in the specification, so it's time to hunt it down.
136

137         searchForPage(cycle);
138
139         if (getSpecification() == null)
140             throw new PageNotFoundException(ResolverMessages.noSuchPage(_simpleName, namespace));
141     }
142
143     public String JavaDoc getSimplePageName()
144     {
145         return _simpleName;
146     }
147
148     private void searchForPage(IRequestCycle cycle)
149     {
150         INamespace namespace = getNamespace();
151
152         if (_log.isDebugEnabled())
153             _log.debug(ResolverMessages.resolvingPage(_simpleName, namespace));
154
155         String JavaDoc expectedName = _simpleName + ".page";
156
157         Resource namespaceLocation = namespace.getSpecificationLocation();
158
159         // See if there's a specification file in the same folder
160
// as the library or application specification that's
161
// supposed to contain the page.
162

163         if (found(namespaceLocation.getRelativeResource(expectedName)))
164             return;
165
166         if (namespace.isApplicationNamespace())
167         {
168
169             // The application namespace gets some extra searching.
170

171             if (found(getWebInfAppLocation().getRelativeResource(expectedName)))
172                 return;
173
174             if (found(getWebInfLocation().getRelativeResource(expectedName)))
175                 return;
176
177             if (found(getContextRoot().getRelativeResource(expectedName)))
178                 return;
179
180             // The wierd one ... where we see if there's a template in the application root
181
// location.
182

183             String JavaDoc templateName = _simpleName + "." + getTemplateExtension();
184
185             Resource templateResource = getContextRoot().getRelativeResource(templateName);
186
187             if (_log.isDebugEnabled())
188                 _log.debug(ResolverMessages.checkingResource(templateResource));
189
190             if (templateResource.getResourceURL() != null)
191             {
192                 setupImplicitPage(templateResource);
193                 return;
194             }
195
196             // Not found in application namespace, so maybe its a framework page.
197

198             if (_frameworkNamespace.containsPage(_simpleName))
199             {
200                 if (_log.isDebugEnabled())
201                     _log.debug(ResolverMessages.foundFrameworkPage(_simpleName));
202
203                 setNamespace(_frameworkNamespace);
204
205                 // Note: This implies that normal lookup rules don't work
206
// for the framework! Framework pages must be
207
// defined in the framework library specification.
208

209                 setSpecification(_frameworkNamespace.getPageSpecification(_simpleName));
210                 return;
211             }
212         }
213
214         // Not found by any normal rule, so its time to
215
// consult the delegate.
216

217         IComponentSpecification specification = getDelegate().findPageSpecification(
218                 cycle,
219                 namespace,
220                 _simpleName);
221
222         if (specification != null)
223         {
224             setSpecification(specification);
225             install();
226         }
227     }
228
229     private void setupImplicitPage(Resource resource)
230     {
231         if (_log.isDebugEnabled())
232             _log.debug(ResolverMessages.foundHTMLTemplate(resource));
233
234         // TODO The SpecFactory in Specification parser should be used in some way to
235
// create an IComponentSpecification!
236

237         IComponentSpecification specification = new ComponentSpecification();
238         specification.setPageSpecification(true);
239         specification.setSpecificationLocation(resource);
240
241         setSpecification(specification);
242
243         install();
244     }
245
246     private boolean found(Resource resource)
247     {
248         if (_log.isDebugEnabled())
249             _log.debug(ResolverMessages.checkingResource(resource));
250
251         if (resource.getResourceURL() == null)
252             return false;
253
254         setSpecification(getSpecificationSource().getPageSpecification(resource));
255
256         install();
257
258         return true;
259     }
260
261     private void install()
262     {
263         INamespace namespace = getNamespace();
264         IComponentSpecification specification = getSpecification();
265
266         if (_log.isDebugEnabled())
267             _log.debug(ResolverMessages.installingPage(_simpleName, namespace, specification));
268
269         namespace.installPageSpecification(_simpleName, specification);
270     }
271
272     /**
273      * If the namespace defines the template extension (as property
274      * {@link Tapestry#TEMPLATE_EXTENSION_PROPERTY}, then that is used, otherwise the default is
275      * used.
276      */

277
278     private String JavaDoc getTemplateExtension()
279     {
280         return _componentPropertySource.getNamespaceProperty(
281                 getNamespace(),
282                 Tapestry.TEMPLATE_EXTENSION_PROPERTY);
283     }
284
285     /** @since 4.0 */
286
287     public void setLog(Log log)
288     {
289         _log = log;
290     }
291
292     /** @since 4.0 */
293     public void setComponentPropertySource(ComponentPropertySource componentPropertySource)
294     {
295         _componentPropertySource = componentPropertySource;
296     }
297 }
Popular Tags