|
|||||||||||||||||||
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 | |||||||||||||||
PageLoader.java | 88.2% | 96.8% | 100% | 95.8% |
|
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.pageload;
|
|
16 |
|
|
17 |
import java.util.ArrayList;
|
|
18 |
import java.util.Iterator;
|
|
19 |
import java.util.List;
|
|
20 |
import java.util.Locale;
|
|
21 |
|
|
22 |
import org.apache.commons.logging.Log;
|
|
23 |
import org.apache.hivemind.ApplicationRuntimeException;
|
|
24 |
import org.apache.hivemind.HiveMind;
|
|
25 |
import org.apache.hivemind.Location;
|
|
26 |
import org.apache.tapestry.AbstractComponent;
|
|
27 |
import org.apache.tapestry.BaseComponent;
|
|
28 |
import org.apache.tapestry.IAsset;
|
|
29 |
import org.apache.tapestry.IBinding;
|
|
30 |
import org.apache.tapestry.IComponent;
|
|
31 |
import org.apache.tapestry.IEngine;
|
|
32 |
import org.apache.tapestry.INamespace;
|
|
33 |
import org.apache.tapestry.IPage;
|
|
34 |
import org.apache.tapestry.IRequestCycle;
|
|
35 |
import org.apache.tapestry.ITemplateComponent;
|
|
36 |
import org.apache.tapestry.asset.AssetSource;
|
|
37 |
import org.apache.tapestry.binding.BindingConstants;
|
|
38 |
import org.apache.tapestry.binding.BindingSource;
|
|
39 |
import org.apache.tapestry.binding.BindingUtils;
|
|
40 |
import org.apache.tapestry.binding.ExpressionBinding;
|
|
41 |
import org.apache.tapestry.binding.ListenerBinding;
|
|
42 |
import org.apache.tapestry.coerce.ValueConverter;
|
|
43 |
import org.apache.tapestry.engine.IPageLoader;
|
|
44 |
import org.apache.tapestry.event.ChangeObserver;
|
|
45 |
import org.apache.tapestry.resolver.ComponentSpecificationResolver;
|
|
46 |
import org.apache.tapestry.services.BSFManagerFactory;
|
|
47 |
import org.apache.tapestry.services.ComponentConstructor;
|
|
48 |
import org.apache.tapestry.services.ComponentConstructorFactory;
|
|
49 |
import org.apache.tapestry.services.ComponentTemplateLoader;
|
|
50 |
import org.apache.tapestry.spec.BindingType;
|
|
51 |
import org.apache.tapestry.spec.IAssetSpecification;
|
|
52 |
import org.apache.tapestry.spec.IBindingSpecification;
|
|
53 |
import org.apache.tapestry.spec.IComponentSpecification;
|
|
54 |
import org.apache.tapestry.spec.IContainedComponent;
|
|
55 |
import org.apache.tapestry.spec.IListenerBindingSpecification;
|
|
56 |
|
|
57 |
/**
|
|
58 |
* Runs the process of building the component hierarchy for an entire page.
|
|
59 |
* <p>
|
|
60 |
* This implementation is not threadsafe, therefore the threaded service model must be used.
|
|
61 |
*
|
|
62 |
* @author Howard Lewis Ship
|
|
63 |
*/
|
|
64 |
|
|
65 |
public class PageLoader implements IPageLoader |
|
66 |
{ |
|
67 |
private Log _log;
|
|
68 |
|
|
69 |
/** @since 4.0 */
|
|
70 |
|
|
71 |
private ComponentSpecificationResolver _componentResolver;
|
|
72 |
|
|
73 |
/** @since 4.0 */
|
|
74 |
|
|
75 |
private String _defaultScriptLanguage;
|
|
76 |
|
|
77 |
/** @since 4.0 */
|
|
78 |
|
|
79 |
private BindingSource _bindingSource;
|
|
80 |
|
|
81 |
/** @since 4.0 */
|
|
82 |
|
|
83 |
private ComponentTemplateLoader _componentTemplateLoader;
|
|
84 |
|
|
85 |
/** @since 4.0 */
|
|
86 |
|
|
87 |
private BSFManagerFactory _managerFactory;
|
|
88 |
|
|
89 |
private IEngine _engine;
|
|
90 |
|
|
91 |
private List _inheritedBindingQueue = new ArrayList(); |
|
92 |
|
|
93 |
/** @since 4.0 */
|
|
94 |
private IComponentVisitor _establishDefaultParameterValuesVisitor;
|
|
95 |
|
|
96 |
private ComponentTreeWalker _establishDefaultParameterValuesWalker;
|
|
97 |
|
|
98 |
private ComponentTreeWalker _verifyRequiredParametersWalker;
|
|
99 |
|
|
100 |
/** @since 4.0 */
|
|
101 |
|
|
102 |
private ComponentConstructorFactory _componentConstructorFactory;
|
|
103 |
|
|
104 |
/** @since 4.0 */
|
|
105 |
|
|
106 |
private ValueConverter _valueConverter;
|
|
107 |
|
|
108 |
/** @since 4.0 */
|
|
109 |
|
|
110 |
private AssetSource _assetSource;
|
|
111 |
|
|
112 |
/** @since 4.0 */
|
|
113 |
|
|
114 |
private PageClassProvider _pageClassProvider;
|
|
115 |
|
|
116 |
/**
|
|
117 |
* The locale of the application, which is also the locale of the page being loaded.
|
|
118 |
*/
|
|
119 |
|
|
120 |
private Locale _locale;
|
|
121 |
|
|
122 |
/**
|
|
123 |
* Number of components instantiated, excluding the page itself.
|
|
124 |
*/
|
|
125 |
|
|
126 |
private int _count; |
|
127 |
|
|
128 |
/**
|
|
129 |
* The recursion depth. A page with no components is zero. A component on a page is one.
|
|
130 |
*/
|
|
131 |
|
|
132 |
private int _depth; |
|
133 |
|
|
134 |
/**
|
|
135 |
* The maximum depth reached while building the page.
|
|
136 |
*/
|
|
137 |
|
|
138 |
private int _maxDepth; |
|
139 |
|
|
140 | 110 |
public void initializeService() |
141 |
{ |
|
142 |
|
|
143 |
// Create the mechanisms for walking the component tree when it is
|
|
144 |
// complete
|
|
145 | 110 |
IComponentVisitor verifyRequiredParametersVisitor = new VerifyRequiredParametersVisitor();
|
146 |
|
|
147 | 110 |
_verifyRequiredParametersWalker = new ComponentTreeWalker(new IComponentVisitor[] |
148 |
{ verifyRequiredParametersVisitor }); |
|
149 |
|
|
150 | 110 |
_establishDefaultParameterValuesWalker = new ComponentTreeWalker(new IComponentVisitor[] |
151 |
{ _establishDefaultParameterValuesVisitor }); |
|
152 |
} |
|
153 |
|
|
154 |
/**
|
|
155 |
* Binds properties of the component as defined by the container's specification.
|
|
156 |
* <p>
|
|
157 |
* This implementation is very simple, we will need a lot more sanity checking and eror checking
|
|
158 |
* in the final version.
|
|
159 |
*
|
|
160 |
* @param container
|
|
161 |
* The containing component. For a dynamic binding ({@link ExpressionBinding}) the
|
|
162 |
* property name is evaluated with the container as the root.
|
|
163 |
* @param component
|
|
164 |
* The contained component being bound.
|
|
165 |
* @param spec
|
|
166 |
* The specification of the contained component.
|
|
167 |
* @param contained
|
|
168 |
* The contained component specification (from the container's
|
|
169 |
* {@link IComponentSpecification}).
|
|
170 |
*/
|
|
171 |
|
|
172 | 416 |
private void bind(IComponent container, IComponent component, IContainedComponent contained) |
173 |
{ |
|
174 | 416 |
IComponentSpecification spec = component.getSpecification(); |
175 | 416 |
boolean formalOnly = !spec.getAllowInformalParameters();
|
176 |
|
|
177 | 416 |
IComponentSpecification containerSpec = container.getSpecification(); |
178 | 416 |
boolean containerFormalOnly = !containerSpec.getAllowInformalParameters();
|
179 |
|
|
180 | 416 |
if (contained.getInheritInformalParameters())
|
181 |
{ |
|
182 | 3 |
if (formalOnly)
|
183 | 1 |
throw new ApplicationRuntimeException(PageloadMessages |
184 |
.inheritInformalInvalidComponentFormalOnly(component), component, contained |
|
185 |
.getLocation(), null);
|
|
186 |
|
|
187 | 2 |
if (containerFormalOnly)
|
188 | 1 |
throw new ApplicationRuntimeException(PageloadMessages |
189 |
.inheritInformalInvalidContainerFormalOnly(container, component), |
|
190 |
component, contained.getLocation(), null);
|
|
191 |
|
|
192 | 1 |
IQueuedInheritedBinding queued = new QueuedInheritInformalBindings(component);
|
193 | 1 |
_inheritedBindingQueue.add(queued); |
194 |
} |
|
195 |
|
|
196 | 414 |
Iterator i = contained.getBindingNames().iterator(); |
197 |
|
|
198 | 414 |
while (i.hasNext())
|
199 |
{ |
|
200 | 565 |
String name = (String) i.next(); |
201 |
|
|
202 | 565 |
boolean isFormal = spec.getParameter(name) != null; |
203 |
|
|
204 | 565 |
IBindingSpecification bspec = contained.getBinding(name); |
205 |
|
|
206 |
// If not allowing informal parameters, check that each binding
|
|
207 |
// matches
|
|
208 |
// a formal parameter.
|
|
209 |
|
|
210 | 565 |
if (formalOnly && !isFormal)
|
211 | 0 |
throw new ApplicationRuntimeException(PageloadMessages.formalParametersOnly( |
212 |
component, |
|
213 |
name), component, bspec.getLocation(), null);
|
|
214 |
|
|
215 |
// If an informal parameter that conflicts with a reserved name,
|
|
216 |
// then skip it.
|
|
217 |
|
|
218 | 565 |
if (!isFormal && spec.isReservedParameterName(name))
|
219 | 1 |
continue;
|
220 |
|
|
221 |
// The type determines how to interpret the value:
|
|
222 |
// As a simple static String
|
|
223 |
// As a nested property name (relative to the component)
|
|
224 |
// As the name of a binding inherited from the containing component.
|
|
225 |
// As the name of a public field
|
|
226 |
// As a script for a listener
|
|
227 |
|
|
228 | 564 |
BindingType type = bspec.getType(); |
229 |
|
|
230 |
// For inherited bindings, defer until later. This gives components
|
|
231 |
// a chance to setup bindings from static values and expressions in
|
|
232 |
// the template. The order of operations is tricky, template bindings
|
|
233 |
// come later. Note that this is a hold over from the Tapestry 3.0 DTD
|
|
234 |
// and will some day no longer be supported.
|
|
235 |
|
|
236 | 564 |
if (type == BindingType.INHERITED)
|
237 |
{ |
|
238 | 1 |
QueuedInheritedBinding queued = new QueuedInheritedBinding(component, bspec
|
239 |
.getValue(), name); |
|
240 | 1 |
_inheritedBindingQueue.add(queued); |
241 | 1 |
continue;
|
242 |
} |
|
243 |
|
|
244 | 563 |
if (type == BindingType.LISTENER)
|
245 |
{ |
|
246 | 3 |
constructListenerBinding(component, name, (IListenerBindingSpecification) bspec); |
247 | 3 |
continue;
|
248 |
} |
|
249 |
|
|
250 | 560 |
String description = PageloadMessages.parameterName(name); |
251 |
|
|
252 |
// For informal parameters, or formal parameters that fail to specify a default binding
|
|
253 |
// type, use OGNL.
|
|
254 |
|
|
255 | 560 |
String defaultBindingType = BindingUtils.getDefaultBindingType( |
256 |
spec, |
|
257 |
name, |
|
258 |
BindingConstants.OGNL_PREFIX); |
|
259 |
|
|
260 | 560 |
IBinding binding = convert(container, description, defaultBindingType, bspec); |
261 |
|
|
262 | 560 |
component.setBinding(name, binding); |
263 |
} |
|
264 |
} |
|
265 |
|
|
266 | 560 |
private IBinding convert(IComponent container, String description, String defaultBindingType,
|
267 |
IBindingSpecification spec) |
|
268 |
{ |
|
269 | 560 |
Location location = spec.getLocation(); |
270 | 560 |
String bindingReference = spec.getValue(); |
271 |
|
|
272 | 560 |
return _bindingSource.createBinding(
|
273 |
container, |
|
274 |
description, |
|
275 |
bindingReference, |
|
276 |
defaultBindingType, |
|
277 |
location); |
|
278 |
} |
|
279 |
|
|
280 |
/**
|
|
281 |
* Construct a {@link ListenerBinding}for the component, and add it.
|
|
282 |
*
|
|
283 |
* @since 3.0
|
|
284 |
*/
|
|
285 |
|
|
286 | 3 |
private void constructListenerBinding(IComponent component, String parameterName, |
287 |
IListenerBindingSpecification spec) |
|
288 |
{ |
|
289 | 3 |
String language = spec.getLanguage(); |
290 |
|
|
291 |
// If not provided in the page or component specification, then
|
|
292 |
// search for a default (factory default is "jython").
|
|
293 |
|
|
294 | 3 |
if (HiveMind.isBlank(language))
|
295 | 0 |
language = _defaultScriptLanguage; |
296 |
|
|
297 |
// Construct the binding. The first parameter is the compononent
|
|
298 |
// (not the DirectLink or Form, but the page or component containing the
|
|
299 |
// link or form).
|
|
300 |
|
|
301 | 3 |
String description = PageloadMessages.parameterName(parameterName); |
302 |
|
|
303 | 3 |
IBinding binding = new ListenerBinding(description, _valueConverter, spec.getLocation(),
|
304 |
component.getContainer(), language, spec.getScript(), _managerFactory); |
|
305 |
|
|
306 | 3 |
component.setBinding(parameterName, binding); |
307 |
} |
|
308 |
|
|
309 |
/**
|
|
310 |
* Sets up a component. This involves:
|
|
311 |
* <ul>
|
|
312 |
* <li>Instantiating any contained components.
|
|
313 |
* <li>Add the contained components to the container.
|
|
314 |
* <li>Setting up bindings between container and containees.
|
|
315 |
* <li>Construct the containees recursively.
|
|
316 |
* <li>Invoking
|
|
317 |
* {@link IComponent#finishLoad(IRequestCycle, IPageLoader, IComponentSpecification)}
|
|
318 |
* </ul>
|
|
319 |
*
|
|
320 |
* @param cycle
|
|
321 |
* the request cycle for which the page is being (initially) constructed
|
|
322 |
* @param page
|
|
323 |
* The page on which the container exists.
|
|
324 |
* @param container
|
|
325 |
* The component to be set up.
|
|
326 |
* @param containerSpec
|
|
327 |
* The specification for the container.
|
|
328 |
* @param the
|
|
329 |
* namespace of the container
|
|
330 |
*/
|
|
331 |
|
|
332 | 1160 |
private void constructComponent(IRequestCycle cycle, IPage page, IComponent container, |
333 |
IComponentSpecification containerSpec, INamespace namespace) |
|
334 |
{ |
|
335 | 1160 |
_depth++; |
336 | 1160 |
if (_depth > _maxDepth)
|
337 | 331 |
_maxDepth = _depth; |
338 |
|
|
339 | 1160 |
List ids = new ArrayList(containerSpec.getComponentIds());
|
340 | 1160 |
int count = ids.size();
|
341 |
|
|
342 | 1160 |
try
|
343 |
{ |
|
344 | 1160 |
for (int i = 0; i < count; i++) |
345 |
{ |
|
346 | 416 |
String id = (String) ids.get(i); |
347 |
|
|
348 |
// Get the sub-component specification from the
|
|
349 |
// container's specification.
|
|
350 |
|
|
351 | 416 |
IContainedComponent contained = containerSpec.getComponent(id); |
352 |
|
|
353 | 416 |
String type = contained.getType(); |
354 | 416 |
Location location = contained.getLocation(); |
355 |
|
|
356 | 416 |
_componentResolver.resolve(cycle, namespace, type, location); |
357 |
|
|
358 | 416 |
IComponentSpecification componentSpecification = _componentResolver |
359 |
.getSpecification(); |
|
360 | 416 |
INamespace componentNamespace = _componentResolver.getNamespace(); |
361 |
|
|
362 |
// Instantiate the contained component.
|
|
363 |
|
|
364 | 416 |
IComponent component = instantiateComponent( |
365 |
page, |
|
366 |
container, |
|
367 |
id, |
|
368 |
componentSpecification, |
|
369 |
componentNamespace, |
|
370 |
location); |
|
371 |
|
|
372 |
// Add it, by name, to the container.
|
|
373 |
|
|
374 | 416 |
container.addComponent(component); |
375 |
|
|
376 |
// Set up any bindings in the IContainedComponent specification
|
|
377 |
|
|
378 | 416 |
bind(container, component, contained); |
379 |
|
|
380 |
// Now construct the component recusively; it gets its chance
|
|
381 |
// to create its subcomponents and set their bindings.
|
|
382 |
|
|
383 | 414 |
constructComponent( |
384 |
cycle, |
|
385 |
page, |
|
386 |
component, |
|
387 |
componentSpecification, |
|
388 |
componentNamespace); |
|
389 |
} |
|
390 |
|
|
391 | 1158 |
addAssets(container, containerSpec); |
392 |
|
|
393 |
// Finish the load of the component; most components (which
|
|
394 |
// subclass BaseComponent) load their templates here.
|
|
395 |
// Properties with initial values will be set here (or the
|
|
396 |
// initial value will be recorded for later use in pageDetach().
|
|
397 |
// That may cause yet more components to be created, and more
|
|
398 |
// bindings to be set, so we defer some checking until
|
|
399 |
// later.
|
|
400 |
|
|
401 | 1158 |
container.finishLoad(cycle, this, containerSpec);
|
402 |
|
|
403 |
// Have the component switch over to its active state.
|
|
404 |
|
|
405 | 1151 |
container.enterActiveState(); |
406 |
} |
|
407 |
catch (ApplicationRuntimeException ex)
|
|
408 |
{ |
|
409 | 9 |
throw ex;
|
410 |
} |
|
411 |
catch (RuntimeException ex)
|
|
412 |
{ |
|
413 | 0 |
throw new ApplicationRuntimeException(PageloadMessages.unableToInstantiateComponent( |
414 |
container, |
|
415 |
ex), container, null, ex);
|
|
416 |
} |
|
417 |
|
|
418 | 1151 |
_depth--; |
419 |
} |
|
420 |
|
|
421 |
/**
|
|
422 |
* Invoked to create an implicit component (one which is defined in the containing component's
|
|
423 |
* template, rather that in the containing component's specification).
|
|
424 |
*
|
|
425 |
* @see org.apache.tapestry.services.impl.ComponentTemplateLoaderImpl
|
|
426 |
* @since 3.0
|
|
427 |
*/
|
|
428 |
|
|
429 | 609 |
public IComponent createImplicitComponent(IRequestCycle cycle, IComponent container,
|
430 |
String componentId, String componentType, Location location) |
|
431 |
{ |
|
432 | 609 |
IPage page = container.getPage(); |
433 |
|
|
434 | 609 |
_componentResolver.resolve(cycle, container.getNamespace(), componentType, location); |
435 |
|
|
436 | 609 |
INamespace componentNamespace = _componentResolver.getNamespace(); |
437 | 609 |
IComponentSpecification spec = _componentResolver.getSpecification(); |
438 |
|
|
439 | 609 |
IComponent result = instantiateComponent( |
440 |
page, |
|
441 |
container, |
|
442 |
componentId, |
|
443 |
spec, |
|
444 |
componentNamespace, |
|
445 |
location); |
|
446 |
|
|
447 | 608 |
container.addComponent(result); |
448 |
|
|
449 |
// Recusively build the component.
|
|
450 |
|
|
451 | 608 |
constructComponent(cycle, page, result, spec, componentNamespace); |
452 |
|
|
453 | 606 |
return result;
|
454 |
} |
|
455 |
|
|
456 |
/**
|
|
457 |
* Instantiates a component from its specification. We instantiate the component object, then
|
|
458 |
* set its specification, page, container and id.
|
|
459 |
*
|
|
460 |
* @see AbstractComponent
|
|
461 |
*/
|
|
462 |
|
|
463 | 1025 |
private IComponent instantiateComponent(IPage page, IComponent container, String id,
|
464 |
IComponentSpecification spec, INamespace namespace, Location location) |
|
465 |
{ |
|
466 | 1025 |
IComponent result = null;
|
467 | 1025 |
String className = spec.getComponentClassName(); |
468 |
|
|
469 | 1025 |
if (HiveMind.isBlank(className))
|
470 | 39 |
className = BaseComponent.class.getName();
|
471 |
|
|
472 | 1025 |
ComponentConstructor cc = _componentConstructorFactory.getComponentConstructor( |
473 |
spec, |
|
474 |
className); |
|
475 |
|
|
476 | 1025 |
try
|
477 |
{ |
|
478 | 1025 |
result = (IComponent) cc.newInstance(); |
479 |
|
|
480 |
} |
|
481 |
catch (ClassCastException ex)
|
|
482 |
{ |
|
483 | 1 |
throw new ApplicationRuntimeException(PageloadMessages.classNotComponent(cc |
484 |
.getComponentClass()), container, spec.getLocation(), ex); |
|
485 |
} |
|
486 |
|
|
487 | 1024 |
if (result instanceof IPage) |
488 | 0 |
throw new ApplicationRuntimeException(PageloadMessages.pageNotAllowed(result), result, |
489 |
null, null); |
|
490 |
|
|
491 | 1024 |
result.setNamespace(namespace); |
492 | 1024 |
result.setPage(page); |
493 | 1024 |
result.setContainer(container); |
494 | 1024 |
result.setId(id); |
495 | 1024 |
result.setLocation(location); |
496 |
|
|
497 | 1024 |
_count++; |
498 |
|
|
499 | 1024 |
return result;
|
500 |
} |
|
501 |
|
|
502 |
/**
|
|
503 |
* Instantitates a page from its specification.
|
|
504 |
*
|
|
505 |
* @param name
|
|
506 |
* the unqualified, simple, name for the page
|
|
507 |
* @param namespace
|
|
508 |
* the namespace containing the page's specification
|
|
509 |
* @param spec
|
|
510 |
* the page's specification We instantiate the page object, then set its
|
|
511 |
* specification, names and locale.
|
|
512 |
* @see IEngine
|
|
513 |
* @see ChangeObserver
|
|
514 |
*/
|
|
515 |
|
|
516 | 140 |
private IPage instantiatePage(String name, INamespace namespace, IComponentSpecification spec)
|
517 |
{ |
|
518 | 140 |
IPage result = null;
|
519 |
|
|
520 | 140 |
PageClassProviderContext context = new PageClassProviderContext(name, spec, namespace);
|
521 | 140 |
String className = _pageClassProvider.providePageClassName(context); |
522 |
|
|
523 | 140 |
String pageName = namespace.constructQualifiedName(name); |
524 | 140 |
Location location = spec.getLocation(); |
525 |
|
|
526 | 140 |
ComponentConstructor cc = _componentConstructorFactory.getComponentConstructor( |
527 |
spec, |
|
528 |
className); |
|
529 |
|
|
530 | 139 |
try
|
531 |
{ |
|
532 | 139 |
result = (IPage) cc.newInstance(); |
533 |
|
|
534 | 138 |
result.setNamespace(namespace); |
535 | 138 |
result.setPageName(pageName); |
536 | 138 |
result.setPage(result); |
537 | 138 |
result.setLocale(_locale); |
538 | 138 |
result.setLocation(location); |
539 |
} |
|
540 |
catch (ClassCastException ex)
|
|
541 |
{ |
|
542 | 1 |
throw new ApplicationRuntimeException(PageloadMessages.classNotPage(cc |
543 |
.getComponentClass()), location, ex); |
|
544 |
} |
|
545 |
|
|
546 | 138 |
return result;
|
547 |
} |
|
548 |
|
|
549 | 140 |
public IPage loadPage(String name, INamespace namespace, IRequestCycle cycle,
|
550 |
IComponentSpecification specification) |
|
551 |
{ |
|
552 | 140 |
IPage page = null;
|
553 |
|
|
554 | 140 |
_engine = cycle.getEngine(); |
555 |
|
|
556 | 140 |
_locale = _engine.getLocale(); |
557 |
|
|
558 | 140 |
_count = 0; |
559 | 140 |
_depth = 0; |
560 | 140 |
_maxDepth = 0; |
561 |
|
|
562 | 140 |
try
|
563 |
{ |
|
564 | 140 |
page = instantiatePage(name, namespace, specification); |
565 |
|
|
566 | 138 |
constructComponent(cycle, page, page, specification, namespace); |
567 |
|
|
568 |
// Walk through the complete component tree to set up the default
|
|
569 |
// parameter values.
|
|
570 | 131 |
_establishDefaultParameterValuesWalker.walkComponentTree(page); |
571 |
|
|
572 | 131 |
establishInheritedBindings(); |
573 |
|
|
574 |
// Walk through the complete component tree to ensure that required
|
|
575 |
// parameters are bound
|
|
576 | 131 |
_verifyRequiredParametersWalker.walkComponentTree(page); |
577 |
} |
|
578 |
finally
|
|
579 |
{ |
|
580 | 140 |
_locale = null;
|
581 | 140 |
_engine = null;
|
582 | 140 |
_inheritedBindingQueue.clear(); |
583 |
} |
|
584 |
|
|
585 | 131 |
if (_log.isDebugEnabled())
|
586 | 0 |
_log.debug("Loaded page " + page + " with " + _count + " components (maximum depth " |
587 |
+ _maxDepth + ")");
|
|
588 |
|
|
589 | 131 |
return page;
|
590 |
} |
|
591 |
|
|
592 |
/** @since 4.0 */
|
|
593 |
|
|
594 | 227 |
public void loadTemplateForComponent(IRequestCycle cycle, ITemplateComponent component) |
595 |
{ |
|
596 | 227 |
_componentTemplateLoader.loadTemplate(cycle, component); |
597 |
} |
|
598 |
|
|
599 | 131 |
private void establishInheritedBindings() |
600 |
{ |
|
601 | 131 |
_log.debug("Establishing inherited bindings");
|
602 |
|
|
603 | 131 |
int count = _inheritedBindingQueue.size();
|
604 |
|
|
605 | 131 |
for (int i = 0; i < count; i++) |
606 |
{ |
|
607 | 2 |
IQueuedInheritedBinding queued = (IQueuedInheritedBinding) _inheritedBindingQueue |
608 |
.get(i); |
|
609 |
|
|
610 | 2 |
queued.connect(); |
611 |
} |
|
612 |
} |
|
613 |
|
|
614 | 1158 |
private void addAssets(IComponent component, IComponentSpecification specification) |
615 |
{ |
|
616 | 1158 |
List names = specification.getAssetNames(); |
617 |
|
|
618 | 1158 |
if (names.isEmpty())
|
619 | 1102 |
return;
|
620 |
|
|
621 | 56 |
Iterator i = names.iterator(); |
622 |
|
|
623 | 56 |
while (i.hasNext())
|
624 |
{ |
|
625 | 60 |
String name = (String) i.next(); |
626 |
|
|
627 | 60 |
IAssetSpecification assetSpec = specification.getAsset(name); |
628 |
|
|
629 | 60 |
IAsset asset = convertAsset(assetSpec); |
630 |
|
|
631 | 60 |
component.addAsset(name, asset); |
632 |
} |
|
633 |
} |
|
634 |
|
|
635 |
/**
|
|
636 |
* Builds an instance of {@link IAsset}from the specification.
|
|
637 |
*/
|
|
638 |
|
|
639 | 60 |
private IAsset convertAsset(IAssetSpecification spec)
|
640 |
{ |
|
641 |
// AssetType type = spec.getType();
|
|
642 | 60 |
String path = spec.getPath(); |
643 | 60 |
Location location = spec.getLocation(); |
644 |
|
|
645 | 60 |
return _assetSource.findAsset(location.getResource(), path, _locale, location);
|
646 |
} |
|
647 |
|
|
648 |
/** @since 4.0 */
|
|
649 |
|
|
650 | 110 |
public void setLog(Log log) |
651 |
{ |
|
652 | 110 |
_log = log; |
653 |
} |
|
654 |
|
|
655 |
/** @since 4.0 */
|
|
656 |
|
|
657 | 110 |
public void setComponentResolver(ComponentSpecificationResolver resolver) |
658 |
{ |
|
659 | 110 |
_componentResolver = resolver; |
660 |
} |
|
661 |
|
|
662 |
/** @since 4.0 */
|
|
663 |
|
|
664 | 110 |
public void setDefaultScriptLanguage(String string) |
665 |
{ |
|
666 | 110 |
_defaultScriptLanguage = string; |
667 |
} |
|
668 |
|
|
669 |
/** @since 4.0 */
|
|
670 |
|
|
671 | 110 |
public void setBindingSource(BindingSource bindingSource) |
672 |
{ |
|
673 | 110 |
_bindingSource = bindingSource; |
674 |
} |
|
675 |
|
|
676 |
/**
|
|
677 |
* @since 4.0
|
|
678 |
*/
|
|
679 | 110 |
public void setComponentTemplateLoader(ComponentTemplateLoader componentTemplateLoader) |
680 |
{ |
|
681 | 110 |
_componentTemplateLoader = componentTemplateLoader; |
682 |
} |
|
683 |
|
|
684 |
/** @since 4.0 */
|
|
685 | 110 |
public void setEstablishDefaultParameterValuesVisitor( |
686 |
IComponentVisitor establishDefaultParameterValuesVisitor) |
|
687 |
{ |
|
688 | 110 |
_establishDefaultParameterValuesVisitor = establishDefaultParameterValuesVisitor; |
689 |
} |
|
690 |
|
|
691 |
/** @since 4.0 */
|
|
692 | 110 |
public void setComponentConstructorFactory( |
693 |
ComponentConstructorFactory componentConstructorFactory) |
|
694 |
{ |
|
695 | 110 |
_componentConstructorFactory = componentConstructorFactory; |
696 |
} |
|
697 |
|
|
698 |
/** @since 4.0 */
|
|
699 | 110 |
public void setValueConverter(ValueConverter valueConverter) |
700 |
{ |
|
701 | 110 |
_valueConverter = valueConverter; |
702 |
} |
|
703 |
|
|
704 |
/** @since 4.0 */
|
|
705 | 110 |
public void setAssetSource(AssetSource assetSource) |
706 |
{ |
|
707 | 110 |
_assetSource = assetSource; |
708 |
} |
|
709 |
|
|
710 |
/** @since 4.0 */
|
|
711 | 110 |
public void setManagerFactory(BSFManagerFactory managerFactory) |
712 |
{ |
|
713 | 110 |
_managerFactory = managerFactory; |
714 |
} |
|
715 |
|
|
716 |
/** @since 4.0 */
|
|
717 | 110 |
public void setPageClassProvider(PageClassProvider pageClassProvider) |
718 |
{ |
|
719 | 110 |
_pageClassProvider = pageClassProvider; |
720 |
} |
|
721 |
} |
|