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