You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2006/11/19 18:58:02 UTC

svn commit: r476861 [1/2] - in /tapestry/tapestry5/tapestry-core/trunk/src: main/java/org/apache/tapestry/ main/java/org/apache/tapestry/annotations/ main/java/org/apache/tapestry/dom/ main/java/org/apache/tapestry/internal/services/ main/java/org/apac...

Author: hlship
Date: Sun Nov 19 09:58:01 2006
New Revision: 476861

URL: http://svn.apache.org/viewvc?view=rev&rev=476861
Log:
Make use of EasyMock's atLeastOnce() qualifier to reduce verbage in unit tests.
Change RequestPageCache to track the active page.
Allow component event handler methods to return a page component instance, to set that page as the active page (for the response).

Added:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentInstanceEventHandler.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/InjectionProvider.java
      - copied, changed from r476234, tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectionProvider.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentInstanceEventHandlerTest.java
Removed:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectionProvider.java
Modified:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResources.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/Inject.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/dom/EndTagStyle.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentResourcesInjectionProvider.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/DefaultInjectionProvider.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectWorker.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCache.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCacheImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElement.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/test/BaseTestCase.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/bindings/PropBindingFactoryTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/InterceptorStackBuilderTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/OneShortServiceCreatorTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/SingletonServiceLifecycleTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentSourceImplTest.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/InjectWorkerTest.java

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResources.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResources.java?view=diff&rev=476861&r1=476860&r2=476861
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResources.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ComponentResources.java Sun Nov 19 09:58:01 2006
@@ -12,52 +12,57 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry;
-
-import org.apache.tapestry.model.ComponentModel;
-import org.apache.tapestry.runtime.Component;
-
-/**
- * Provides a component instance with the resources provided by the framework. In many
- * circumstances, the resources object can be considered the component itself; in others, it is the
- * {@link #getComponent() component property}, and instance of a class provided by the application
- * developer (though transformed in many ways while being loaded) that is the true component. In
- * reality, it is the combination of the resources object with the lifecycle instance.
- */
-public interface ComponentResources extends ComponentResourcesCommon
-{
-    /** Returns the component model object that defines the behavior of the component. */
-    ComponentModel getComponentModel();
-
-    /**
-     * Returns the component this object provides resources for.
-     */
-    Component getComponent();
-
-    /**
-     * Returns the page that contains this component. Technically, the page itself is an internal
-     * object in Tapestry and this returns the root component of the actual page, but from an
-     * application developer point of view, this is the page.
-     */
-    Component getPage();
-
-    /**
-     * Returns an embedded component, given the component's id.
-     * 
-     * @throws IllegalArgumentException
-     *             if this component does not contain a component with the given id
-     */
-
-    Component getEmbeddedComponent(String embeddedId);
-
-    /** Returns true if the named parameter is bound, false if not. */
-    boolean isBound(String parameterName);
-
-    /**
-     * Indentifies all parameters that are not formal parameters and writes each as a
-     * attribute/value pair into the current element of the markup writer.
-     * 
-     * @param writer
-     */
-    void renderInformalParameters(MarkupWriter writer);
-}
+package org.apache.tapestry;
+
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.runtime.Component;
+
+/**
+ * Provides a component instance with the resources provided by the framework. In many
+ * circumstances, the resources object can be considered the component itself; in others, it is the
+ * {@link #getComponent() component property}, and instance of a class provided by the application
+ * developer (though transformed in many ways while being loaded) that is the true component. In
+ * reality, it is the combination of the resources object with the lifecycle instance.
+ */
+public interface ComponentResources extends ComponentResourcesCommon
+{
+    /** Returns the component model object that defines the behavior of the component. */
+    ComponentModel getComponentModel();
+
+    /**
+     * Returns the component this object provides resources for.
+     */
+    Component getComponent();
+
+    /**
+     * Returns the component which contains this component, or null for the root component.
+     */
+    Component getContainer();
+
+    /**
+     * Returns the page that contains this component. Technically, the page itself is an internal
+     * object in Tapestry and this returns the root component of the actual page, but from an
+     * application developer point of view, this is the page.
+     */
+    Component getPage();
+
+    /**
+     * Returns an embedded component, given the component's id.
+     * 
+     * @throws IllegalArgumentException
+     *             if this component does not contain a component with the given id
+     */
+
+    Component getEmbeddedComponent(String embeddedId);
+
+    /** Returns true if the named parameter is bound, false if not. */
+    boolean isBound(String parameterName);
+
+    /**
+     * Indentifies all parameters that are not formal parameters and writes each as a
+     * attribute/value pair into the current element of the markup writer.
+     * 
+     * @param writer
+     */
+    void renderInformalParameters(MarkupWriter writer);
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/Inject.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/Inject.java?view=diff&rev=476861&r1=476860&r2=476861
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/Inject.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/Inject.java Sun Nov 19 09:58:01 2006
@@ -12,29 +12,28 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.annotations;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Allows injection of various objects into a component class.
- * 
- * 
- * @see org.apache.tapestry.internal.services.InjectionProvider
- */
-@Target(FIELD)
-@Documented
-@Retention(RUNTIME)
-public @interface Inject {
-
-    /**
-     * Identifies the value to be injected, when the type by itself is insufficient. Omitted in many
-     * cases.
-     */
-    String value() default "";
-}
+package org.apache.tapestry.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Allows injection of various objects into a component class.
+ * 
+ * @see org.apache.tapestry.services.InjectionProvider
+ */
+@Target(FIELD)
+@Documented
+@Retention(RUNTIME)
+public @interface Inject {
+
+    /**
+     * Identifies the value to be injected, when the type by itself is insufficient. Omitted in many
+     * cases.
+     */
+    String value() default "";
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/dom/EndTagStyle.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/dom/EndTagStyle.java?view=diff&rev=476861&r1=476860&r2=476861
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/dom/EndTagStyle.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/dom/EndTagStyle.java Sun Nov 19 09:58:01 2006
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//     http://www.apache.org/licenses/LICENSE-2.0
+// http://www.apache.org/licenses/LICENSE-2.0
 //
 // Unless required by applicable law or agreed to in writing, software
 // distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,12 +14,19 @@
 
 package org.apache.tapestry.dom;
 
+/**
+ * Part of a {@link MarkupModel}, used to define how end tags are handled when the {@link Document}
+ * in rendered out as a text stream.
+ */
 public enum EndTagStyle {
 
-    /** Omit the end tag.  Examples for HTML include the input, br and img elements. */
+    /** Omit the end tag. Examples for HTML include the input, br and img elements. */
     OMIT,
     /** Require an end tag always. This is the default for most elements in HTML. */
     REQUIRE,
-    /** Require an end tag, but abbreviate it if the element has no children. This is the only value used in XML documents. */
+    /**
+     * Require an end tag, but abbreviate it if the element has no children. This is the only value
+     * used in XML documents.
+     */
     ABBREVIATE
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java?view=diff&rev=476861&r1=476860&r2=476861
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentEventDispatcher.java Sun Nov 19 09:58:01 2006
@@ -14,16 +14,15 @@
 
 package org.apache.tapestry.internal.services;
 
-import java.io.IOException;
-
-import org.apache.tapestry.ComponentEventHandler;
-import org.apache.tapestry.Link;
-import org.apache.tapestry.internal.structure.ComponentPageElement;
-import org.apache.tapestry.internal.structure.Page;
-import org.apache.tapestry.runtime.Component;
-import org.apache.tapestry.services.Dispatcher;
-import org.apache.tapestry.services.WebRequest;
-import org.apache.tapestry.services.WebResponse;
+import java.io.IOException;
+
+import org.apache.tapestry.ComponentEventHandler;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.services.Dispatcher;
+import org.apache.tapestry.services.WebRequest;
+import org.apache.tapestry.services.WebResponse;
 
 /**
  * Processes component action events sent as requests from the client. Action events include an
@@ -31,13 +30,15 @@
  */
 public class ComponentEventDispatcher implements Dispatcher
 {
-
+    private final ComponentEventHandler _componentEventHandler;
+    
     private final RequestPageCache _cache;
 
-    private final LinkFactory _linkFactory;
-
-    public ComponentEventDispatcher(final RequestPageCache cache, LinkFactory linkFactory)
-    {
+    private final LinkFactory _linkFactory;
+    
+    public ComponentEventDispatcher(ComponentEventHandler componentEventHandler, final RequestPageCache cache, LinkFactory linkFactory)
+    {
+        _componentEventHandler = componentEventHandler;
         _cache = cache;
         _linkFactory = linkFactory;
     }
@@ -55,7 +56,11 @@
 
         String logicalPageName = path.substring(1, dotx);
 
-        Page page = _cache.get(logicalPageName);
+        Page page = _cache.get(logicalPageName);
+        
+        // This is the active page, until we know better.
+        
+        _cache.setActive(page);
 
         int slashx = path.indexOf('/', dotx + 1);
 
@@ -73,16 +78,14 @@
 
         ComponentPageElement element = page.getComponentElementByNestedId(nestedComponentId);
 
-        ComponentEventHandler handler = new ComponentEventHandler()
-        {
-            public void handleResult(Object result, Component component, String methodDescription)
-            {
-                // Does nothing, right now. Accepts any return value.
-            }
-        };
-
-        element.triggerEvent(eventType, context, handler);
-
+        element.triggerEvent(eventType, context, _componentEventHandler);
+        
+        // It's possible that the component event will have changed the active page.
+        // Whatever the active page is NOW is what we'll send back (as a client redirect)
+        // to render.
+        
+        page = _cache.getActive();
+        
         Link link = _linkFactory.createPageLink(page);
 
         String URL = link.toRedirectURI();

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentInstanceEventHandler.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentInstanceEventHandler.java?view=auto&rev=476861
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentInstanceEventHandler.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentInstanceEventHandler.java Sun Nov 19 09:58:01 2006
@@ -0,0 +1,44 @@
+package org.apache.tapestry.internal.services;
+
+import org.apache.commons.logging.Log;
+import org.apache.tapestry.ComponentEventHandler;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.runtime.Component;
+
+public class ComponentInstanceEventHandler implements ComponentEventHandler<Component>
+{
+    private final RequestPageCache _requestPageCache;
+
+    private final Log _log;
+
+    public ComponentInstanceEventHandler(final RequestPageCache requestPageCache, Log log)
+    {
+        _requestPageCache = requestPageCache;
+        _log = log;
+    }
+
+    public void handleResult(Component result, Component component, String methodDescription)
+    {
+        ComponentResources resources = result.getComponentResources();
+
+        if (resources.getContainer() != null)
+        {
+            _log.warn(ServicesMessages.componentInstanceIsNotAPage(
+                    methodDescription,
+                    component,
+                    result));
+            resources = resources.getPage().getComponentResources();
+        }
+
+        // We have all these layers and layers between us and the page instance, but its easy to
+        // extract the page class name and quickly re-resolve that to the page instance.
+
+        String pageClassName = resources.getCompleteId();
+
+        Page page = _requestPageCache.getByClassName(pageClassName);
+
+        _requestPageCache.setActive(page);
+    }
+
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentResourcesInjectionProvider.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentResourcesInjectionProvider.java?view=diff&rev=476861&r1=476860&r2=476861
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentResourcesInjectionProvider.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentResourcesInjectionProvider.java Sun Nov 19 09:58:01 2006
@@ -20,6 +20,7 @@
 import org.apache.tapestry.ioc.ServiceLocator;
 import org.apache.tapestry.model.MutableComponentModel;
 import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.InjectionProvider;
 import org.apache.tapestry.services.TransformConstants;
 
 /**

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/DefaultInjectionProvider.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/DefaultInjectionProvider.java?view=diff&rev=476861&r1=476860&r2=476861
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/DefaultInjectionProvider.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/DefaultInjectionProvider.java Sun Nov 19 09:58:01 2006
@@ -17,6 +17,7 @@
 import org.apache.tapestry.ioc.ServiceLocator;
 import org.apache.tapestry.model.MutableComponentModel;
 import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.InjectionProvider;
 
 /**
  * Provider that looks for a unique service with the proper type.

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectWorker.java?view=diff&rev=476861&r1=476860&r2=476861
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectWorker.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectWorker.java Sun Nov 19 09:58:01 2006
@@ -21,6 +21,7 @@
 import org.apache.tapestry.model.MutableComponentModel;
 import org.apache.tapestry.services.ClassTransformation;
 import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.InjectionProvider;
 
 /**
  * Worker for the {@link org.apache.tapestry.annotations.Inject} annotation.

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCache.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCache.java?view=diff&rev=476861&r1=476860&r2=476861
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCache.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCache.java Sun Nov 19 09:58:01 2006
@@ -12,37 +12,46 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.internal.services;
-
-import org.apache.tapestry.internal.structure.Page;
-
-/**
- * Per-thread service that caches page instances for the duration of the request.
- */
-public interface RequestPageCache
-{
-    /**
-     * Gets the page via its page name, in the current locale. The page name is resolved to a class
-     * name, which is used to obtain the page (from the page pool).
-     * 
-     * @param pageName
-     *            the name of the page to retrieve (this is the logical page name, not the fully
-     *            qualified class name)
-     * @return a page instance reserved for this request
-     * @throws RuntimeException
-     *             if the name can not be resolved to a page instance
-     */
-    Page get(String pageName);
-
-    /**
-     * Gets the page via its fully qualified class name, in the current locale.
-     * 
-     * @param pageName
-     *            fully qualified class name
-     * @return a page instance reserved for this request
-     * @throws RuntimeException
-     *             if the name can not be resolved to a page instance
-     */
-    Page getByClassName(String className);
-
-}
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.internal.structure.Page;
+
+/**
+ * Per-thread service that caches page instances for the duration of the request, and is also
+ * responsible for tracking the active page (the page which will ultimately render the response).
+ */
+public interface RequestPageCache
+{
+    /**
+     * Gets the page via its page name, in the current locale. The page name is resolved to a class
+     * name, which is used to obtain the page (from the page pool).
+     * 
+     * @param pageName
+     *            the name of the page to retrieve (this is the logical page name, not the fully
+     *            qualified class name)
+     * @return a page instance reserved for this request
+     * @throws RuntimeException
+     *             if the name can not be resolved to a page instance
+     */
+    Page get(String pageName);
+
+    /**
+     * Gets the page via its fully qualified class name, in the current locale.
+     * 
+     * @param pageName
+     *            fully qualified class name
+     * @return a page instance reserved for this request
+     * @throws RuntimeException
+     *             if the name can not be resolved to a page instance
+     */
+    Page getByClassName(String className);
+
+    /**
+     * Identifies the active page for the current request. The active page is responsible for
+     * rendering the response for the current request (often in a later request).
+     */
+    void setActive(Page page);
+
+    /** Returns the active page (if known), or null. */
+    Page getActive();
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCacheImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCacheImpl.java?view=diff&rev=476861&r1=476860&r2=476861
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCacheImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/RequestPageCacheImpl.java Sun Nov 19 09:58:01 2006
@@ -12,63 +12,75 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.internal.services;
-
-import static org.apache.tapestry.util.CollectionFactory.newMap;
-
-import java.util.Map;
-
-import org.apache.tapestry.internal.structure.Page;
-import org.apache.tapestry.ioc.services.ThreadCleanupListener;
-import org.apache.tapestry.services.ComponentClassResolver;
-
-public class RequestPageCacheImpl implements RequestPageCache, ThreadCleanupListener
-{
-    private final ComponentClassResolver _resolver;
-
-    private final PagePool _pagePool;
-
-    /**
-     * Keyed on fully qualified page class name.
-     */
-    private final Map<String, Page> _cache = newMap();
-
-    public RequestPageCacheImpl(ComponentClassResolver resolver, PagePool pagePool)
-    {
-        _resolver = resolver;
-        _pagePool = pagePool;
-    }
-
-    public Page get(String pageName)
-    {
-        String className = _resolver.resolvePageNameToClassName(pageName);
-
-        if (className == null)
-            throw new RuntimeException(ServicesMessages.pageDoesNotExist(pageName));
-
-        return getByClassName(className);
-    }
-
-    public Page getByClassName(String className)
-    {
-        Page page = _cache.get(className);
-
-        if (page == null)
-        {
-            page = _pagePool.checkout(className);
-
-            page.attached();
-
-            _cache.put(className, page);
-        }
-
-        return page;
-    }
-
-    public void threadDidCleanup()
-    {
-        for (Page p : _cache.values())
-            _pagePool.release(p);
-    }
-
-}
+package org.apache.tapestry.internal.services;
+
+import static org.apache.tapestry.util.CollectionFactory.newMap;
+
+import java.util.Map;
+
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.ioc.services.ThreadCleanupListener;
+import org.apache.tapestry.services.ComponentClassResolver;
+
+public class RequestPageCacheImpl implements RequestPageCache, ThreadCleanupListener
+{
+    private final ComponentClassResolver _resolver;
+
+    private final PagePool _pagePool;
+
+    private Page _active;
+
+    /**
+     * Keyed on fully qualified page class name.
+     */
+    private final Map<String, Page> _cache = newMap();
+
+    public RequestPageCacheImpl(ComponentClassResolver resolver, PagePool pagePool)
+    {
+        _resolver = resolver;
+        _pagePool = pagePool;
+    }
+
+    public Page get(String pageName)
+    {
+        String className = _resolver.resolvePageNameToClassName(pageName);
+
+        if (className == null)
+            throw new RuntimeException(ServicesMessages.pageDoesNotExist(pageName));
+
+        return getByClassName(className);
+    }
+
+    public Page getByClassName(String className)
+    {
+        Page page = _cache.get(className);
+
+        if (page == null)
+        {
+            page = _pagePool.checkout(className);
+
+            page.attached();
+
+            _cache.put(className, page);
+        }
+
+        return page;
+    }
+
+    public void threadDidCleanup()
+    {
+        for (Page p : _cache.values())
+            _pagePool.release(p);
+    }
+
+    public Page getActive()
+    {
+        return _active;
+    }
+
+    public void setActive(Page active)
+    {
+        _active = active;
+    }
+
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java?view=diff&rev=476861&r1=476860&r2=476861
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java Sun Nov 19 09:58:01 2006
@@ -12,227 +12,236 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.internal.services;
-
-import java.util.Collection;
-import java.util.List;
-
-import javassist.CtClass;
-
-import org.apache.tapestry.Location;
-import org.apache.tapestry.Messages;
-import org.apache.tapestry.Resource;
-import org.apache.tapestry.internal.MessagesImpl;
-import org.apache.tapestry.internal.util.InternalUtils;
-import org.apache.tapestry.runtime.RenderCommand;
-import org.apache.tapestry.services.MethodSignature;
-
-class ServicesMessages
-{
-    private static final Messages MESSAGES = MessagesImpl.forClass(ServicesMessages.class);
-
-    private ServicesMessages()
-    {
-    }
-
-    static final String duplicateContribution(Object conflict, String name, Object existing)
-    {
-        return MESSAGES.format("duplicate-contribution", conflict, name, existing);
-    }
-
-    static final String infrastructureModeNotSet()
-    {
-        return MESSAGES.get("infrastructure-mode-not-set");
-    }
-
-    static final String infrastructurePropertyNotFound(String name, Collection<String> known)
-    {
-        String knownList = InternalUtils.joinSorted(known);
-
-        return MESSAGES.format("infrastructure-property-not-found", name, knownList);
-    }
-
-    static final String infrastructurePropertyWrongType(String name, Object object,
-            Class desiredType)
-    {
-        return MESSAGES.format("infrastructure-property-wrong-type", name, object, desiredType
-                .getName());
-    }
-
-    static final String markupWriterNoCurrentElement()
-    {
-        return MESSAGES.get("markup-writer-no-current-element");
-    }
-
-    static String noConstructorFound(Class instanceClass)
-    {
-        return MESSAGES.format("no-constructor-found", instanceClass.getName());
-    }
-
-    static String missingDeclaredField(CtClass ctClass, String fieldName)
-    {
-        return MESSAGES.format("missing-declared-field", ctClass.getName(), fieldName);
-    }
-
-    static String errorAddingMethod(CtClass ctClass, String methodName, Throwable cause)
-    {
-        return MESSAGES.format("error-adding-method", ctClass.getName(), methodName, cause);
-    }
-
-    static String fieldAlreadyClaimed(String fieldName, CtClass ctClass, Object existingTag,
-            Object newTag)
-    {
-        return MESSAGES.format("field-already-claimed", new Object[]
-        { fieldName, ctClass.getName(), existingTag, newTag });
-    }
-
-    static String noDeclaredMethod(CtClass ctClass, MethodSignature methodSignature)
-    {
-        return MESSAGES.format("no-declared-method", ctClass.getName(), methodSignature);
-    }
-
-    static String incorrectClassForInstantiator(String className, Class componentClass)
-    {
-        return MESSAGES.format("incorrect-class-for-instantiator", className, componentClass
-                .getName());
-    }
-
-    static String classNotTransformed(String className)
-    {
-        return MESSAGES.format("class-not-transformed", className);
-    }
-
-    static String newParserError(Resource resource, Throwable cause)
-    {
-        return MESSAGES.format("new-parser-error", resource, cause);
-    }
-
-    static String missingTemplateResource(Resource resource)
-    {
-        return MESSAGES.format("missing-template-resource", resource);
-    }
-
-    static String templateParseError(Resource resource, Throwable cause)
-    {
-        return MESSAGES.format("template-parse-error", resource, cause);
-    }
-
-    static String contentInsideBodyNotAllowed(Location location)
-    {
-        return MESSAGES.format("content-inside-body-not-allowed", location);
-    }
-
-    static String mayNotNestElementsInsideBody(String elementName)
-    {
-        return MESSAGES.format("may-not-nest-elements-inside-body", elementName);
-    }
-
-    static String methodCompileError(MethodSignature signature, String methodBody, Throwable cause)
-    {
-        return MESSAGES.format("method-compile-error", signature, methodBody, cause);
-    }
-
-    static String renderQueueError(RenderCommand command, Throwable cause)
-    {
-        return MESSAGES.format("render-queue-error", command, cause);
-    }
-
-    static String readOnlyField(String className, String fieldName)
-    {
-        return MESSAGES.format("read-only-field", className, fieldName);
-    }
-
-    static String noInjectionFound(String className, String fieldName, String fieldType)
-    {
-        return MESSAGES.format("no-injection-found", className, fieldName, fieldType);
-    }
-
-    static String nonPrivateFields(String className, List<String> names)
-    {
-        return MESSAGES.format("non-private-fields", className, InternalUtils.joinSorted(names));
-    }
-
-    static String compRequiresIdOrType()
-    {
-        return MESSAGES.get("comp-requires-id-or-type");
-    }
-
-    static String compTypeConflict(String embeddedId, String templateType, String modelType)
-    {
-        return MESSAGES.format("comp-type-conflict", embeddedId, templateType, modelType);
-    }
-
-    static String noTypeForEmbeddedComponent(String embeddedId, String componentClassName)
-    {
-        return MESSAGES.format("no-type-for-embedded-component", embeddedId, componentClassName);
-    }
-
-    static String embeddedComponentsNotInTemplate(Collection<String> ids, String componentClassName)
-    {
-        return MESSAGES.format(
-                "embedded-components-not-in-template",
-                InternalUtils.joinSorted(ids),
-                componentClassName);
-    }
-
-    static String bindingSourceFailure(String expression, Throwable cause)
-    {
-        return MESSAGES.format("binding-source-failure", expression, cause);
-    }
-
-    static String contextIndexOutOfRange(String methodDescription)
-    {
-        return MESSAGES.format("context-index-out-of-range", methodDescription);
-    }
-
-    static String pageDoesNotExist(String pageName)
-    {
-        return MESSAGES.format("page-does-not-exist", pageName);
-    }
-
-    static String pageNameUnresolved(String pageClassName)
-    {
-        return MESSAGES.format("page-name-unresolved", pageClassName);
-    }
-
-    static String exceptionInMethodParameter(String methodDescription, int index, Throwable cause)
-    {
-        return MESSAGES
-                .format("exception-in-method-parameter", methodDescription, index + 1, cause);
-    }
-
-    static String componentEventIsAborted(String methodDescription)
-    {
-        return MESSAGES.format("component-event-is-aborted", methodDescription);
-    }
-
-    static String unknownPersistentFieldStrategy(String stategyName, String catalog)
-    {
-        return MESSAGES.format("unknown-persistent-field-strategy", stategyName, catalog);
-    }
-
-    static String couldNotResolvePageName(String pageName)
-    {
-        return MESSAGES.format("could-not-resolve-page-name", pageName);
-    }
-
-    static String couldNotResolveComponentType(String componentType)
-    {
-        return MESSAGES.format("could-not-resolve-component-type", componentType);
-    }
-
-    static String couldNotResolveMixinType(String mixinType)
-    {
-        return MESSAGES.format("could-not-resolve-mixin-type", mixinType);
-    }
-
-    static String parameterNameMustBeUnique(String parameterName, String parameterValue)
-    {
-        return MESSAGES.format("parameter-name-must-be-unique", parameterName, parameterValue);
-    }
-
-    static String pageIsDirty(Object page)
-    {
-        return MESSAGES.format("page-is-dirty", page);
-    }
-}
+package org.apache.tapestry.internal.services;
+
+import java.util.Collection;
+import java.util.List;
+
+import javassist.CtClass;
+
+import org.apache.tapestry.Location;
+import org.apache.tapestry.Messages;
+import org.apache.tapestry.Resource;
+import org.apache.tapestry.internal.MessagesImpl;
+import org.apache.tapestry.internal.util.InternalUtils;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.RenderCommand;
+import org.apache.tapestry.services.MethodSignature;
+
+class ServicesMessages
+{
+    private static final Messages MESSAGES = MessagesImpl.forClass(ServicesMessages.class);
+
+    private ServicesMessages()
+    {
+    }
+
+    static final String duplicateContribution(Object conflict, String name, Object existing)
+    {
+        return MESSAGES.format("duplicate-contribution", conflict, name, existing);
+    }
+
+    static final String infrastructureModeNotSet()
+    {
+        return MESSAGES.get("infrastructure-mode-not-set");
+    }
+
+    static final String infrastructurePropertyNotFound(String name, Collection<String> known)
+    {
+        String knownList = InternalUtils.joinSorted(known);
+
+        return MESSAGES.format("infrastructure-property-not-found", name, knownList);
+    }
+
+    static final String infrastructurePropertyWrongType(String name, Object object,
+            Class desiredType)
+    {
+        return MESSAGES.format("infrastructure-property-wrong-type", name, object, desiredType
+                .getName());
+    }
+
+    static final String markupWriterNoCurrentElement()
+    {
+        return MESSAGES.get("markup-writer-no-current-element");
+    }
+
+    static String noConstructorFound(Class instanceClass)
+    {
+        return MESSAGES.format("no-constructor-found", instanceClass.getName());
+    }
+
+    static String missingDeclaredField(CtClass ctClass, String fieldName)
+    {
+        return MESSAGES.format("missing-declared-field", ctClass.getName(), fieldName);
+    }
+
+    static String errorAddingMethod(CtClass ctClass, String methodName, Throwable cause)
+    {
+        return MESSAGES.format("error-adding-method", ctClass.getName(), methodName, cause);
+    }
+
+    static String fieldAlreadyClaimed(String fieldName, CtClass ctClass, Object existingTag,
+            Object newTag)
+    {
+        return MESSAGES.format("field-already-claimed", new Object[]
+        { fieldName, ctClass.getName(), existingTag, newTag });
+    }
+
+    static String noDeclaredMethod(CtClass ctClass, MethodSignature methodSignature)
+    {
+        return MESSAGES.format("no-declared-method", ctClass.getName(), methodSignature);
+    }
+
+    static String incorrectClassForInstantiator(String className, Class componentClass)
+    {
+        return MESSAGES.format("incorrect-class-for-instantiator", className, componentClass
+                .getName());
+    }
+
+    static String classNotTransformed(String className)
+    {
+        return MESSAGES.format("class-not-transformed", className);
+    }
+
+    static String newParserError(Resource resource, Throwable cause)
+    {
+        return MESSAGES.format("new-parser-error", resource, cause);
+    }
+
+    static String missingTemplateResource(Resource resource)
+    {
+        return MESSAGES.format("missing-template-resource", resource);
+    }
+
+    static String templateParseError(Resource resource, Throwable cause)
+    {
+        return MESSAGES.format("template-parse-error", resource, cause);
+    }
+
+    static String contentInsideBodyNotAllowed(Location location)
+    {
+        return MESSAGES.format("content-inside-body-not-allowed", location);
+    }
+
+    static String mayNotNestElementsInsideBody(String elementName)
+    {
+        return MESSAGES.format("may-not-nest-elements-inside-body", elementName);
+    }
+
+    static String methodCompileError(MethodSignature signature, String methodBody, Throwable cause)
+    {
+        return MESSAGES.format("method-compile-error", signature, methodBody, cause);
+    }
+
+    static String renderQueueError(RenderCommand command, Throwable cause)
+    {
+        return MESSAGES.format("render-queue-error", command, cause);
+    }
+
+    static String readOnlyField(String className, String fieldName)
+    {
+        return MESSAGES.format("read-only-field", className, fieldName);
+    }
+
+    static String noInjectionFound(String className, String fieldName, String fieldType)
+    {
+        return MESSAGES.format("no-injection-found", className, fieldName, fieldType);
+    }
+
+    static String nonPrivateFields(String className, List<String> names)
+    {
+        return MESSAGES.format("non-private-fields", className, InternalUtils.joinSorted(names));
+    }
+
+    static String compRequiresIdOrType()
+    {
+        return MESSAGES.get("comp-requires-id-or-type");
+    }
+
+    static String compTypeConflict(String embeddedId, String templateType, String modelType)
+    {
+        return MESSAGES.format("comp-type-conflict", embeddedId, templateType, modelType);
+    }
+
+    static String noTypeForEmbeddedComponent(String embeddedId, String componentClassName)
+    {
+        return MESSAGES.format("no-type-for-embedded-component", embeddedId, componentClassName);
+    }
+
+    static String embeddedComponentsNotInTemplate(Collection<String> ids, String componentClassName)
+    {
+        return MESSAGES.format(
+                "embedded-components-not-in-template",
+                InternalUtils.joinSorted(ids),
+                componentClassName);
+    }
+
+    static String bindingSourceFailure(String expression, Throwable cause)
+    {
+        return MESSAGES.format("binding-source-failure", expression, cause);
+    }
+
+    static String contextIndexOutOfRange(String methodDescription)
+    {
+        return MESSAGES.format("context-index-out-of-range", methodDescription);
+    }
+
+    static String pageDoesNotExist(String pageName)
+    {
+        return MESSAGES.format("page-does-not-exist", pageName);
+    }
+
+    static String pageNameUnresolved(String pageClassName)
+    {
+        return MESSAGES.format("page-name-unresolved", pageClassName);
+    }
+
+    static String exceptionInMethodParameter(String methodDescription, int index, Throwable cause)
+    {
+        return MESSAGES
+                .format("exception-in-method-parameter", methodDescription, index + 1, cause);
+    }
+
+    static String componentEventIsAborted(String methodDescription)
+    {
+        return MESSAGES.format("component-event-is-aborted", methodDescription);
+    }
+
+    static String unknownPersistentFieldStrategy(String stategyName, String catalog)
+    {
+        return MESSAGES.format("unknown-persistent-field-strategy", stategyName, catalog);
+    }
+
+    static String couldNotResolvePageName(String pageName)
+    {
+        return MESSAGES.format("could-not-resolve-page-name", pageName);
+    }
+
+    static String couldNotResolveComponentType(String componentType)
+    {
+        return MESSAGES.format("could-not-resolve-component-type", componentType);
+    }
+
+    static String couldNotResolveMixinType(String mixinType)
+    {
+        return MESSAGES.format("could-not-resolve-mixin-type", mixinType);
+    }
+
+    static String parameterNameMustBeUnique(String parameterName, String parameterValue)
+    {
+        return MESSAGES.format("parameter-name-must-be-unique", parameterName, parameterValue);
+    }
+
+    static String pageIsDirty(Object page)
+    {
+        return MESSAGES.format("page-is-dirty", page);
+    }
+
+    static String componentInstanceIsNotAPage(String methodDescription, Component component,
+            Component result)
+    {
+        return MESSAGES.format("component-instance-is-not-a-page", methodDescription, component
+                .getComponentResources().getCompleteId(), result.getComponentResources()
+                .getCompleteId());
+    }
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElement.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElement.java?view=diff&rev=476861&r1=476860&r2=476861
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElement.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElement.java Sun Nov 19 09:58:01 2006
@@ -45,7 +45,7 @@
     /**
      * Containing component (or null for the root component of a page).
      */
-    ComponentPageElement getContainer();
+    ComponentPageElement getContainerElement();
 
     /**
      * Used during the construction of a page. Adds a page element as part of the template for this

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java?view=diff&rev=476861&r1=476860&r2=476861
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java Sun Nov 19 09:58:01 2006
@@ -708,7 +708,7 @@
         return _coreResources;
     }
 
-    public ComponentPageElement getContainer()
+    public ComponentPageElement getContainerElement()
     {
         return _container;
     }
@@ -897,7 +897,7 @@
             if (event.isAborted())
                 return result;
 
-            component = component.getContainer();
+            component = component.getContainerElement();
         }
 
         return result;

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java?view=diff&rev=476861&r1=476860&r2=476861
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java Sun Nov 19 09:58:01 2006
@@ -12,225 +12,232 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.internal.structure;
-
-import static org.apache.tapestry.util.CollectionFactory.newMap;
-
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.tapestry.Binding;
-import org.apache.tapestry.ComponentEventHandler;
-import org.apache.tapestry.Link;
-import org.apache.tapestry.MarkupWriter;
-import org.apache.tapestry.internal.InternalComponentResources;
-import org.apache.tapestry.internal.TapestryException;
-import org.apache.tapestry.internal.services.Instantiator;
-import org.apache.tapestry.ioc.services.TypeCoercer;
-import org.apache.tapestry.model.ComponentModel;
-import org.apache.tapestry.runtime.Component;
-
-/**
- * The bridge between a component and its {@link ComponentPageElement}, that supplies all kinds of
- * resources to the component, including access to its parameters, parameter bindings, and
- * persistent field data.
- */
-
-public class InternalComponentResourcesImpl implements InternalComponentResources
-{
-    private final ComponentModel _componentModel;
-
-    private final ComponentPageElement _element;
-
-    private final TypeCoercer _typeCoercer;
-
-    private final Component _component;
-
-    private Map<String, Binding> _bindings;
-
-    public InternalComponentResourcesImpl(ComponentPageElement element,
-            Instantiator componentInstantiator, TypeCoercer typeCoercer)
-    {
-        _element = element;
-        _componentModel = componentInstantiator.getModel();
-        _typeCoercer = typeCoercer;
-
-        _component = componentInstantiator.newInstance(this);
-    }
-
-    @Override
-    public String toString()
-    {
-        return String.format("InternalComponentResources[%s]", getCompleteId());
-    }
-
-    public ComponentModel getComponentModel()
-    {
-        return _componentModel;
-    }
-
-    public Component getEmbeddedComponent(String embeddedId)
-    {
-        return _element.getEmbeddedElement(embeddedId).getComponent();
-    }
-
-    public Object getFieldChange(String fieldName)
-    {
-        return _element.getFieldChange(fieldName);
-    }
-
-    public String getId()
-    {
-        return _element.getId();
-    }
-
-    public boolean hasFieldChange(String fieldName)
-    {
-        return _element.hasFieldChange(fieldName);
-    }
-
-    public Link createActionLink(String action, boolean forForm, Object... context)
-    {
-        return _element.createActionLink(action, forForm, context);
-    }
-
-    public String getCompleteId()
-    {
-        return _element.getCompleteId();
-    }
-
-    public Component getComponent()
-    {
-        return _component;
-    }
-
-    public boolean isBound(String parameterName)
-    {
-        return getBinding(parameterName) != null;
-    }
-
-    public boolean isRendering()
-    {
-        return _element.isRendering();
-    }
-
-    public boolean triggerEvent(String eventType, Object[] context, ComponentEventHandler handler)
-    {
-        return _element.triggerEvent(eventType, context, handler);
-    }
-
-    public String getNestedId()
-    {
-        return _element.getNestedId();
-    }
-
-    public Component getPage()
-    {
-        return _element.getContainingPage().getRootElement().getComponent();
-    }
-
-    public boolean isInvariant(String parameterName)
-    {
-        Binding b = getBinding(parameterName);
-
-        return b != null && b.isInvariant();
-    }
-
-    public boolean isLoaded()
-    {
-        return _element.isLoaded();
-    }
-
-    public void persistFieldChange(String fieldName, Object newValue)
-    {
-        _element.persistFieldChange(fieldName, newValue);
-    }
-
-    public void addParameter(String parameterName, Binding binding)
-    {
-        // TODO: Check for conflicts, etc.
-
-        if (_bindings == null)
-            _bindings = newMap();
-
-        _bindings.put(parameterName, binding);
-    }
-
-    @SuppressWarnings("unchecked")
-    public <T> T readParameter(String parameterName, Class<T> expectedType)
-    {
-        Binding b = getBinding(parameterName);
-
-        // TODO: If binding is null ...
-
-        try
-        {
-            // Will throw NPE if binding is null, but this should never be called if binding is
-            // null.
-            Object boundValue = b.get();
-
-            return _typeCoercer.coerce(boundValue, expectedType);
-        }
-        catch (Exception ex)
-        {
-            throw new TapestryException(StructureMessages.getParameterFailure(
-                    parameterName,
-                    getCompleteId(),
-                    ex), ex);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public <T> void writeParameter(String parameterName, T parameterValue)
-    {
-        Binding b = getBinding(parameterName);
-
-        // TODO: If binding is null ...
-
-        Class bindingType = b.getBindingType();
-
-        try
-        {
-            Object coerced = _typeCoercer.coerce(parameterValue, bindingType);
-
-            b.set(coerced);
-        }
-        catch (Exception ex)
-        {
-            throw new TapestryException(StructureMessages.writeParameterFailure(
-                    parameterName,
-                    getCompleteId(),
-                    ex), ex);
-        }
-    }
-
-    private Binding getBinding(String parameterName)
-    {
-        return _bindings == null ? null : _bindings.get(parameterName);
-    }
-
-    public Log getLog()
-    {
-        return _componentModel.getLog();
-    }
-
-    public Component getMixinByClassName(String mixinClassName)
-    {
-        return _element.getMixinByClassName(mixinClassName);
-    }
-
-    public void renderInformalParameters(MarkupWriter writer)
-    {
-        if (_bindings == null)
-            return;
-
-        for (String name : _bindings.keySet())
-        {
-            if (_componentModel.getParameterModel(name) != null)
-                continue;
-
-            writer.attributes(name, readParameter(name, String.class));
-        }
-    }
-
-}
+package org.apache.tapestry.internal.structure;
+
+import static org.apache.tapestry.util.CollectionFactory.newMap;
+
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ComponentEventHandler;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.internal.InternalComponentResources;
+import org.apache.tapestry.internal.TapestryException;
+import org.apache.tapestry.internal.services.Instantiator;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.runtime.Component;
+
+/**
+ * The bridge between a component and its {@link ComponentPageElement}, that supplies all kinds of
+ * resources to the component, including access to its parameters, parameter bindings, and
+ * persistent field data.
+ */
+
+public class InternalComponentResourcesImpl implements InternalComponentResources
+{
+    private final ComponentModel _componentModel;
+
+    private final ComponentPageElement _element;
+
+    private final TypeCoercer _typeCoercer;
+
+    private final Component _component;
+
+    private Map<String, Binding> _bindings;
+
+    public InternalComponentResourcesImpl(ComponentPageElement element,
+            Instantiator componentInstantiator, TypeCoercer typeCoercer)
+    {
+        _element = element;
+        _componentModel = componentInstantiator.getModel();
+        _typeCoercer = typeCoercer;
+
+        _component = componentInstantiator.newInstance(this);
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("InternalComponentResources[%s]", getCompleteId());
+    }
+
+    public ComponentModel getComponentModel()
+    {
+        return _componentModel;
+    }
+
+    public Component getEmbeddedComponent(String embeddedId)
+    {
+        return _element.getEmbeddedElement(embeddedId).getComponent();
+    }
+
+    public Object getFieldChange(String fieldName)
+    {
+        return _element.getFieldChange(fieldName);
+    }
+
+    public String getId()
+    {
+        return _element.getId();
+    }
+
+    public boolean hasFieldChange(String fieldName)
+    {
+        return _element.hasFieldChange(fieldName);
+    }
+
+    public Link createActionLink(String action, boolean forForm, Object... context)
+    {
+        return _element.createActionLink(action, forForm, context);
+    }
+
+    public String getCompleteId()
+    {
+        return _element.getCompleteId();
+    }
+
+    public Component getComponent()
+    {
+        return _component;
+    }
+
+    public boolean isBound(String parameterName)
+    {
+        return getBinding(parameterName) != null;
+    }
+
+    public boolean isRendering()
+    {
+        return _element.isRendering();
+    }
+
+    public boolean triggerEvent(String eventType, Object[] context, ComponentEventHandler handler)
+    {
+        return _element.triggerEvent(eventType, context, handler);
+    }
+
+    public String getNestedId()
+    {
+        return _element.getNestedId();
+    }
+
+    public Component getPage()
+    {
+        return _element.getContainingPage().getRootElement().getComponent();
+    }
+
+    public boolean isInvariant(String parameterName)
+    {
+        Binding b = getBinding(parameterName);
+
+        return b != null && b.isInvariant();
+    }
+
+    public boolean isLoaded()
+    {
+        return _element.isLoaded();
+    }
+
+    public void persistFieldChange(String fieldName, Object newValue)
+    {
+        _element.persistFieldChange(fieldName, newValue);
+    }
+
+    public void addParameter(String parameterName, Binding binding)
+    {
+        // TODO: Check for conflicts, etc.
+
+        if (_bindings == null)
+            _bindings = newMap();
+
+        _bindings.put(parameterName, binding);
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T readParameter(String parameterName, Class<T> expectedType)
+    {
+        Binding b = getBinding(parameterName);
+
+        // TODO: If binding is null ...
+
+        try
+        {
+            // Will throw NPE if binding is null, but this should never be called if binding is
+            // null.
+            Object boundValue = b.get();
+
+            return _typeCoercer.coerce(boundValue, expectedType);
+        }
+        catch (Exception ex)
+        {
+            throw new TapestryException(StructureMessages.getParameterFailure(
+                    parameterName,
+                    getCompleteId(),
+                    ex), ex);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> void writeParameter(String parameterName, T parameterValue)
+    {
+        Binding b = getBinding(parameterName);
+
+        // TODO: If binding is null ...
+
+        Class bindingType = b.getBindingType();
+
+        try
+        {
+            Object coerced = _typeCoercer.coerce(parameterValue, bindingType);
+
+            b.set(coerced);
+        }
+        catch (Exception ex)
+        {
+            throw new TapestryException(StructureMessages.writeParameterFailure(
+                    parameterName,
+                    getCompleteId(),
+                    ex), ex);
+        }
+    }
+
+    private Binding getBinding(String parameterName)
+    {
+        return _bindings == null ? null : _bindings.get(parameterName);
+    }
+
+    public Log getLog()
+    {
+        return _componentModel.getLog();
+    }
+
+    public Component getMixinByClassName(String mixinClassName)
+    {
+        return _element.getMixinByClassName(mixinClassName);
+    }
+
+    public void renderInformalParameters(MarkupWriter writer)
+    {
+        if (_bindings == null)
+            return;
+
+        for (String name : _bindings.keySet())
+        {
+            if (_componentModel.getParameterModel(name) != null)
+                continue;
+
+            writer.attributes(name, readParameter(name, String.class));
+        }
+    }
+
+    public Component getContainer()
+    {
+        ComponentPageElement containerElement = _element.getContainerElement();
+
+        return _element == null ? null : containerElement.getComponent();
+    }
+
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java?view=diff&rev=476861&r1=476860&r2=476861
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java Sun Nov 19 09:58:01 2006
@@ -12,413 +12,438 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.internal.test;
-
-import static org.apache.tapestry.util.CollectionFactory.newList;
-import static org.apache.tapestry.util.CollectionFactory.newSet;
-import static org.easymock.EasyMock.eq;
-import static org.easymock.EasyMock.isA;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-
-import org.apache.commons.logging.Log;
-import org.apache.tapestry.ComponentResources;
-import org.apache.tapestry.Location;
-import org.apache.tapestry.Resource;
-import org.apache.tapestry.internal.InternalComponentResources;
-import org.apache.tapestry.internal.ioc.InternalRegistry;
-import org.apache.tapestry.internal.ioc.Module;
-import org.apache.tapestry.internal.parser.ComponentTemplate;
-import org.apache.tapestry.internal.parser.TemplateToken;
-import org.apache.tapestry.internal.services.ComponentInstantiatorSource;
-import org.apache.tapestry.internal.services.ComponentTemplateSource;
-import org.apache.tapestry.internal.services.Instantiator;
-import org.apache.tapestry.internal.services.PageElementFactory;
-import org.apache.tapestry.internal.services.PageLoader;
-import org.apache.tapestry.internal.services.PagePool;
-import org.apache.tapestry.internal.services.TemplateParser;
-import org.apache.tapestry.internal.structure.ComponentPageElement;
-import org.apache.tapestry.internal.structure.Page;
-import org.apache.tapestry.internal.structure.PageElement;
-import org.apache.tapestry.ioc.ObjectProvider;
-import org.apache.tapestry.ioc.Registry;
-import org.apache.tapestry.ioc.RegistryBuilder;
-import org.apache.tapestry.ioc.ServiceDecorator;
-import org.apache.tapestry.ioc.ServiceLifecycle;
-import org.apache.tapestry.ioc.ServiceLocator;
-import org.apache.tapestry.ioc.def.ServiceDef;
-import org.apache.tapestry.model.ComponentModel;
-import org.apache.tapestry.model.EmbeddedComponentModel;
-import org.apache.tapestry.runtime.Component;
-import org.apache.tapestry.runtime.RenderQueue;
-import org.apache.tapestry.services.BindingSource;
-import org.apache.tapestry.services.ComponentClassResolver;
-import org.apache.tapestry.services.Infrastructure;
-import org.apache.tapestry.services.TapestryModule;
-import org.apache.tapestry.services.WebRequest;
-import org.apache.tapestry.test.BaseTestCase;
-import org.easymock.EasyMock;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.AfterSuite;
-import org.testng.annotations.BeforeSuite;
-
-/**
- * Contains additional factory and training methods related to internal interfaces.
- */
-
-public class InternalBaseTestCase extends BaseTestCase implements Registry
-{
-    private static Registry _registry;
-
-    @BeforeSuite
-    public final void setup_registry()
-    {
-        RegistryBuilder builder = new RegistryBuilder();
-
-        builder.add(TapestryModule.class);
-
-        _registry = builder.build();
-
-        _registry.getService(Infrastructure.class).setMode("servlet");
-    }
-
-    @AfterSuite
-    public final void shutdown_registry()
-    {
-        _registry.shutdown();
-
-        _registry = null;
-    }
-
-    @AfterMethod
-    public final void cleanupThread()
-    {
-        _registry.cleanupThread();
-    }
-
-    public final <T> T getObject(String reference, Class<T> objectType)
-    {
-        return _registry.getObject(reference, objectType);
-    }
-
-    public final <T> T getService(Class<T> serviceInterface)
-    {
-        return _registry.getService(serviceInterface);
-    }
-
-    public final <T> T getService(String serviceId, Class<T> serviceInterface)
-    {
-        return _registry.getService(serviceId, serviceInterface);
-    }
-
-    public final void shutdown()
-    {
-        throw new UnsupportedOperationException("No registry shutdown until @AfterSuite.");
-    }
-
-    protected final InternalComponentResources newInternalComponentResources()
-    {
-        return newMock(InternalComponentResources.class);
-    }
-
-    protected final ComponentTemplate newComponentTemplate()
-    {
-        return newMock(ComponentTemplate.class);
-    }
-
-    protected final <T> void train_getService(InternalRegistry registry, String serviceId,
-            Class<T> serviceInterface, Module module, T service)
-    {
-        registry.getService(serviceId, serviceInterface, module);
-        setReturnValue(service);
-
-    }
-
-    protected final void train_getLifecycle(InternalRegistry registry, String name,
-            ServiceLifecycle lifecycle)
-    {
-        registry.getServiceLifecycle(name);
-        setReturnValue(lifecycle);
-    }
-
-    protected final void train_findDecoratorsForService(Module module, String serviceId,
-            List<ServiceDecorator> decorators)
-    {
-        module.findDecoratorsForService(serviceId);
-        setReturnValue(decorators);
-    }
-
-    protected final void train_findDecoratorsForService(InternalRegistry registry)
-    {
-        registry.findDecoratorsForService(isA(ServiceDef.class));
-        setReturnValue(newList());
-    }
-
-    protected final InternalRegistry newInternalRegistry()
-    {
-        return newMock(InternalRegistry.class);
-    }
-
-    protected final Registry buildRegistry(Class... moduleClasses)
-    {
-        RegistryBuilder builder = new RegistryBuilder();
-        builder.add(moduleClasses);
-
-        return builder.build();
-    }
-
-    protected final ObjectProvider newObjectProvider()
-    {
-        return newMock(ObjectProvider.class);
-    }
-
-    protected final <T> void train_provide(ObjectProvider provider, String expression,
-            Class<T> objectType, ServiceLocator locator, T object)
-    {
-        provider.provide(expression, objectType, locator);
-        setReturnValue(object);
-    }
-
-    protected final Module newModule()
-    {
-        return newMock(Module.class);
-    }
-
-    protected final ComponentInstantiatorSource newComponentInstantiatorSource()
-    {
-        return newMock(ComponentInstantiatorSource.class);
-    }
-
-    protected Component newComponent()
-    {
-        return newMock(Component.class);
-    }
-
-    protected final Page newPage()
-    {
-        return newMock(Page.class);
-    }
-
-    protected final PageLoader newPageLoader()
-    {
-        return newMock(PageLoader.class);
-    }
-
-    protected final void train_loadPage(PageLoader loader, String pageName, Locale locale, Page page)
-    {
-        loader.loadPage(pageName, locale);
-        setReturnValue(page);
-    }
-
-    protected final void train_getName(Page page, String name)
-    {
-        page.getName();
-        setReturnValue(name);
-    }
-
-    protected final PagePool newPagePool()
-    {
-        return newMock(PagePool.class);
-    }
-
-    protected RenderQueue newRenderQueue()
-    {
-        return newMock(RenderQueue.class);
-    }
-
-    protected final void train_parseTemplate(TemplateParser parser, Resource resource,
-            ComponentTemplate template)
-    {
-        parser.parseTemplate(resource);
-        setReturnValue(template);
-    }
-
-    protected final TemplateParser newTemplateParser()
-    {
-        return newMock(TemplateParser.class);
-    }
-
-    protected final ComponentPageElement newComponentPageElement()
-    {
-        return newMock(ComponentPageElement.class);
-    }
-
-    protected final void train_getComponent(ComponentPageElement element,
-            Component component)
-    {
-        element.getComponent();
-        setReturnValue(component);
-    }
-
-    protected final void train_getId(ComponentPageElement childElement, String id)
-    {
-        childElement.getId();
-        setReturnValue(id);
-    }
-
-    protected final void train_getNestedId(ComponentPageElement element, String nestedId)
-    {
-        element.getNestedId();
-        setReturnValue(nestedId);
-    }
-
-    protected final void train_getContextPath(WebRequest request, String contextPath)
-    {
-        request.getContextPath();
-        setReturnValue(contextPath);
-    }
-
-    protected final void train_resolvePageClassNameToPageName(ComponentClassResolver resolver,
-            String pageClassName, String pageName)
-    {
-        resolver.resolvePageClassNameToPageName(pageClassName);
-        setReturnValue(pageName);
-    }
-
-    protected final void train_getContainingPage(ComponentPageElement element, Page page)
-    {
-        element.getContainingPage();
-        setReturnValue(page);
-    }
-
-    protected final void train_getComponentResources(ComponentPageElement element,
-            InternalComponentResources resources)
-    {
-        element.getComponentResources();
-        setReturnValue(resources);
-    }
-
-    protected final void train_getComponentClassName(EmbeddedComponentModel model, String className)
-    {
-        model.getComponentClassName();
-        setReturnValue(className);
-    }
-
-    protected final void train_newRenderBodyElement(PageElementFactory elementFactory,
-            ComponentPageElement component, PageElement body)
-    {
-        elementFactory.newRenderBodyElement(component);
-        setReturnValue(body);
-    }
-
-    protected final PageElement newPageElement()
-    {
-        return newMock(PageElement.class);
-    }
-
-    protected final void train_getParameterNames(EmbeddedComponentModel model, String... names)
-    {
-        model.getParameterNames();
-        setReturnValue(Arrays.asList(names));
-    }
-
-    protected final void train_newComponentElement(PageElementFactory elementFactory,
-            ComponentPageElement container, String embeddedId, String embeddedType,
-            String componentClassName, Location location, ComponentPageElement embedded)
-    {
-        elementFactory.newComponentElement(
-                isA(Page.class),
-                eq(container),
-                eq(embeddedId),
-                eq(embeddedType),
-                eq(componentClassName),
-                eq(location));
-        setReturnValue(embedded);
-    }
-
-    protected final void train_getComponentType(EmbeddedComponentModel emodel, String componentType)
-    {
-        emodel.getComponentType();
-        setReturnValue(componentType);
-    }
-
-    protected final void train_getEmbeddedComponentModel(ComponentModel model, String embeddedId,
-            EmbeddedComponentModel emodel)
-    {
-        model.getEmbeddedComponentModel(embeddedId);
-        setReturnValue(emodel);
-    }
-
-    protected final EmbeddedComponentModel newEmbeddedComponentModel()
-    {
-        return newMock(EmbeddedComponentModel.class);
-    }
-
-    protected final BindingSource newBindingSource()
-    {
-        return newMock(BindingSource.class);
-    }
-
-    protected final PageElementFactory newPageElementFactory()
-    {
-        return newMock(PageElementFactory.class);
-    }
-
-    protected final ComponentTemplateSource newComponentTemplateSource()
-    {
-        return newMock(ComponentTemplateSource.class);
-    }
-
-    protected final void train_getLog(ComponentModel model, Log log)
-    {
-        model.getLog();
-        setReturnValue(log);
-    }
-
-    protected final void train_getTokens(ComponentTemplate template, TemplateToken... tokens)
-    {
-        template.getTokens();
-        setReturnValue(Arrays.asList(tokens));
-    }
-
-    protected final void train_getComponentIds(ComponentTemplate template, String... ids)
-    {
-        template.getComponentIds();
-        setReturnValue(newSet(Arrays.asList(ids)));
-    }
-
-    protected final void train_getEmbeddedIds(ComponentModel model, String... ids)
-    {
-        model.getEmbeddedComponentIds();
-
-        setReturnValue(Arrays.asList(ids));
-    }
-
-    protected void train_getTemplate(ComponentTemplateSource templateSource, String className,
-            Locale locale, ComponentTemplate template)
-    {
-        templateSource.getTemplate(className, locale);
-        setReturnValue(template);
-    }
-
-    protected final void train_getComponentModel(ComponentResources component, ComponentModel model)
-    {
-        component.getComponentModel();
-        setReturnValue(model);
-    }
-
-    protected final void train_newRootComponentElement(PageElementFactory elementFactory,
-            String className, ComponentPageElement rootElement)
-    {
-        elementFactory.newRootComponentElement(isA(Page.class), eq(className));
-        setReturnValue(rootElement);
-    }
-
-    protected final void train_getModel(Instantiator ins, ComponentModel model)
-    {
-        ins.getModel();
-        setReturnValue(model);
-    }
-
-    protected final Instantiator newInstantiator(Component component)
-    {
-        Instantiator ins = newMock(Instantiator.class);
-    
-        ins.newInstance(EasyMock.isA(InternalComponentResources.class));
-        setReturnValue(component);
-    
-        return ins;
-    }
-}
+package org.apache.tapestry.internal.test;
+
+import static org.apache.tapestry.util.CollectionFactory.newList;
+import static org.apache.tapestry.util.CollectionFactory.newSet;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.isA;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.commons.logging.Log;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.Location;
+import org.apache.tapestry.Resource;
+import org.apache.tapestry.internal.InternalComponentResources;
+import org.apache.tapestry.internal.ioc.InternalRegistry;
+import org.apache.tapestry.internal.ioc.Module;
+import org.apache.tapestry.internal.parser.ComponentTemplate;
+import org.apache.tapestry.internal.parser.TemplateToken;
+import org.apache.tapestry.internal.services.ComponentInstantiatorSource;
+import org.apache.tapestry.internal.services.ComponentTemplateSource;
+import org.apache.tapestry.internal.services.Instantiator;
+import org.apache.tapestry.internal.services.PageElementFactory;
+import org.apache.tapestry.internal.services.PageLoader;
+import org.apache.tapestry.internal.services.PagePool;
+import org.apache.tapestry.internal.services.RequestPageCache;
+import org.apache.tapestry.internal.services.TemplateParser;
+import org.apache.tapestry.internal.structure.ComponentPageElement;
+import org.apache.tapestry.internal.structure.Page;
+import org.apache.tapestry.internal.structure.PageElement;
+import org.apache.tapestry.ioc.ObjectProvider;
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.RegistryBuilder;
+import org.apache.tapestry.ioc.ServiceDecorator;
+import org.apache.tapestry.ioc.ServiceLifecycle;
+import org.apache.tapestry.ioc.ServiceLocator;
+import org.apache.tapestry.ioc.def.ServiceDef;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.model.EmbeddedComponentModel;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.RenderQueue;
+import org.apache.tapestry.services.BindingSource;
+import org.apache.tapestry.services.ComponentClassResolver;
+import org.apache.tapestry.services.Infrastructure;
+import org.apache.tapestry.services.TapestryModule;
+import org.apache.tapestry.services.WebRequest;
+import org.apache.tapestry.test.BaseTestCase;
+import org.easymock.EasyMock;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.BeforeSuite;
+
+/**
+ * Contains additional factory and training methods related to internal interfaces.
+ */
+
+public class InternalBaseTestCase extends BaseTestCase implements Registry
+{
+    private static Registry _registry;
+
+    @BeforeSuite
+    public final void setup_registry()
+    {
+        RegistryBuilder builder = new RegistryBuilder();
+
+        builder.add(TapestryModule.class);
+
+        _registry = builder.build();
+
+        _registry.getService(Infrastructure.class).setMode("servlet");
+    }
+
+    @AfterSuite
+    public final void shutdown_registry()
+    {
+        _registry.shutdown();
+
+        _registry = null;
+    }
+
+    @AfterMethod
+    public final void cleanupThread()
+    {
+        _registry.cleanupThread();
+    }
+
+    public final <T> T getObject(String reference, Class<T> objectType)
+    {
+        return _registry.getObject(reference, objectType);
+    }
+
+    public final <T> T getService(Class<T> serviceInterface)
+    {
+        return _registry.getService(serviceInterface);
+    }
+
+    public final <T> T getService(String serviceId, Class<T> serviceInterface)
+    {
+        return _registry.getService(serviceId, serviceInterface);
+    }
+
+    public final void shutdown()
+    {
+        throw new UnsupportedOperationException("No registry shutdown until @AfterSuite.");
+    }
+
+    protected final InternalComponentResources newInternalComponentResources()
+    {
+        return newMock(InternalComponentResources.class);
+    }
+
+    protected final ComponentTemplate newComponentTemplate()
+    {
+        return newMock(ComponentTemplate.class);
+    }
+
+    protected final <T> void train_getService(InternalRegistry registry, String serviceId,
+            Class<T> serviceInterface, Module module, T service)
+    {
+        registry.getService(serviceId, serviceInterface, module);
+        setReturnValue(service);
+
+    }
+
+    protected final void train_getLifecycle(InternalRegistry registry, String name,
+            ServiceLifecycle lifecycle)
+    {
+        registry.getServiceLifecycle(name);
+        setReturnValue(lifecycle);
+    }
+
+    protected final void train_findDecoratorsForService(Module module, String serviceId,
+            List<ServiceDecorator> decorators)
+    {
+        module.findDecoratorsForService(serviceId);
+        setReturnValue(decorators);
+    }
+
+    protected final void train_findDecoratorsForService(InternalRegistry registry)
+    {
+        registry.findDecoratorsForService(isA(ServiceDef.class));
+        setReturnValue(newList());
+    }
+
+    protected final InternalRegistry newInternalRegistry()
+    {
+        return newMock(InternalRegistry.class);
+    }
+
+    protected final Registry buildRegistry(Class... moduleClasses)
+    {
+        RegistryBuilder builder = new RegistryBuilder();
+        builder.add(moduleClasses);
+
+        return builder.build();
+    }
+
+    protected final ObjectProvider newObjectProvider()
+    {
+        return newMock(ObjectProvider.class);
+    }
+
+    protected final <T> void train_provide(ObjectProvider provider, String expression,
+            Class<T> objectType, ServiceLocator locator, T object)
+    {
+        provider.provide(expression, objectType, locator);
+        setReturnValue(object);
+    }
+
+    protected final Module newModule()
+    {
+        return newMock(Module.class);
+    }
+
+    protected final ComponentInstantiatorSource newComponentInstantiatorSource()
+    {
+        return newMock(ComponentInstantiatorSource.class);
+    }
+
+    protected Component newComponent()
+    {
+        return newMock(Component.class);
+    }
+
+    protected final Page newPage()
+    {
+        return newMock(Page.class);
+    }
+
+    protected final PageLoader newPageLoader()
+    {
+        return newMock(PageLoader.class);
+    }
+
+    protected final void train_loadPage(PageLoader loader, String pageName, Locale locale, Page page)
+    {
+        loader.loadPage(pageName, locale);
+        setReturnValue(page);
+    }
+
+    protected final void train_getName(Page page, String name)
+    {
+        page.getName();
+        setReturnValue(name);
+    }
+
+    protected final PagePool newPagePool()
+    {
+        return newMock(PagePool.class);
+    }
+
+    protected RenderQueue newRenderQueue()
+    {
+        return newMock(RenderQueue.class);
+    }
+
+    protected final void train_parseTemplate(TemplateParser parser, Resource resource,
+            ComponentTemplate template)
+    {
+        parser.parseTemplate(resource);
+        setReturnValue(template);
+    }
+
+    protected final TemplateParser newTemplateParser()
+    {
+        return newMock(TemplateParser.class);
+    }
+
+    protected final ComponentPageElement newComponentPageElement()
+    {
+        return newMock(ComponentPageElement.class);
+    }
+
+    protected final void train_getComponent(ComponentPageElement element, Component component)
+    {
+        element.getComponent();
+        setReturnValue(component);
+    }
+
+    protected final void train_getId(ComponentPageElement childElement, String id)
+    {
+        childElement.getId();
+        setReturnValue(id).atLeastOnce();
+    }
+
+    protected final void train_getNestedId(ComponentPageElement element, String nestedId)
+    {
+        element.getNestedId();
+        setReturnValue(nestedId).atLeastOnce();
+    }
+
+    protected final void train_getContextPath(WebRequest request, String contextPath)
+    {
+        request.getContextPath();
+        setReturnValue(contextPath).atLeastOnce();
+    }
+
+    protected final void train_resolvePageClassNameToPageName(ComponentClassResolver resolver,
+            String pageClassName, String pageName)
+    {
+        resolver.resolvePageClassNameToPageName(pageClassName);
+        setReturnValue(pageName);
+    }
+
+    protected final void train_getContainingPage(ComponentPageElement element, Page page)
+    {
+        element.getContainingPage();
+        setReturnValue(page).atLeastOnce();
+    }
+
+    protected final void train_getComponentResources(ComponentPageElement element,
+            InternalComponentResources resources)
+    {
+        element.getComponentResources();
+        setReturnValue(resources).atLeastOnce();
+    }
+
+    protected final void train_getComponentClassName(EmbeddedComponentModel model, String className)
+    {
+        model.getComponentClassName();
+        setReturnValue(className).atLeastOnce();
+    }
+
+    protected final void train_newRenderBodyElement(PageElementFactory elementFactory,
+            ComponentPageElement component, PageElement body)
+    {
+        elementFactory.newRenderBodyElement(component);
+        setReturnValue(body);
+    }
+
+    protected final PageElement newPageElement()
+    {
+        return newMock(PageElement.class);
+    }
+
+    protected final void train_getParameterNames(EmbeddedComponentModel model, String... names)
+    {
+        model.getParameterNames();
+        setReturnValue(Arrays.asList(names));
+    }
+
+    protected final void train_newComponentElement(PageElementFactory elementFactory,
+            ComponentPageElement container, String embeddedId, String embeddedType,
+            String componentClassName, Location location, ComponentPageElement embedded)
+    {
+        elementFactory.newComponentElement(
+                isA(Page.class),
+                eq(container),
+                eq(embeddedId),
+                eq(embeddedType),
+                eq(componentClassName),
+                eq(location));
+        setReturnValue(embedded);
+    }
+
+    protected final void train_getComponentType(EmbeddedComponentModel emodel, String componentType)
+    {
+        emodel.getComponentType();
+        setReturnValue(componentType).atLeastOnce();
+    }
+
+    protected final void train_getEmbeddedComponentModel(ComponentModel model, String embeddedId,
+            EmbeddedComponentModel emodel)
+    {
+        model.getEmbeddedComponentModel(embeddedId);
+        setReturnValue(emodel).atLeastOnce();
+    }
+
+    protected final EmbeddedComponentModel newEmbeddedComponentModel()
+    {
+        return newMock(EmbeddedComponentModel.class);
+    }
+
+    protected final BindingSource newBindingSource()
+    {
+        return newMock(BindingSource.class);
+    }
+
+    protected final PageElementFactory newPageElementFactory()
+    {
+        return newMock(PageElementFactory.class);
+    }
+
+    protected final ComponentTemplateSource newComponentTemplateSource()
+    {
+        return newMock(ComponentTemplateSource.class);
+    }
+
+    protected final void train_getLog(ComponentModel model, Log log)
+    {
+        model.getLog();
+        setReturnValue(log).atLeastOnce();
+    }
+
+    protected final void train_getTokens(ComponentTemplate template, TemplateToken... tokens)
+    {
+        template.getTokens();
+        setReturnValue(Arrays.asList(tokens));
+    }
+
+    protected final void train_getComponentIds(ComponentTemplate template, String... ids)
+    {
+        template.getComponentIds();
+        setReturnValue(newSet(Arrays.asList(ids)));
+    }
+
+    protected final void train_getEmbeddedIds(ComponentModel model, String... ids)
+    {
+        model.getEmbeddedComponentIds();
+
+        setReturnValue(Arrays.asList(ids));
+    }
+
+    protected void train_getTemplate(ComponentTemplateSource templateSource, String className,
+            Locale locale, ComponentTemplate template)
+    {
+        templateSource.getTemplate(className, locale);
+        setReturnValue(template);
+    }
+
+    protected final void train_getComponentModel(ComponentResources component, ComponentModel model)
+    {
+        component.getComponentModel();
+        setReturnValue(model);
+    }
+
+    protected final void train_newRootComponentElement(PageElementFactory elementFactory,
+            String className, ComponentPageElement rootElement)
+    {
+        elementFactory.newRootComponentElement(isA(Page.class), eq(className));
+        setReturnValue(rootElement);
+    }
+
+    protected final void train_getModel(Instantiator ins, ComponentModel model)
+    {
+        ins.getModel();
+        setReturnValue(model).atLeastOnce();
+    }
+
+    protected final Instantiator newInstantiator(Component component)
+    {
+        Instantiator ins = newMock(Instantiator.class);
+
+        ins.newInstance(EasyMock.isA(InternalComponentResources.class));
+        setReturnValue(component);
+
+        return ins;
+    }
+
+    protected final void train_getByClassName(RequestPageCache cache, String pageClassName,
+            Page page)
+    {
+        cache.getByClassName(pageClassName);
+        setReturnValue(page).atLeastOnce();
+    }
+
+    protected final RequestPageCache newRequestPageCache()
+    {
+        return newMock(RequestPageCache.class);
+    }
+
+    protected final void train_getComponentElementByNestedId(Page page, String nestedId,
+            ComponentPageElement element)
+    {
+        page.getComponentElementByNestedId(nestedId);
+        setReturnValue(element).atLeastOnce();
+    }
+
+    protected final void train_getRootElement(Page page, ComponentPageElement element)
+    {
+        page.getRootElement();
+        setReturnValue(element).atLeastOnce();
+    }
+}