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