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