You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2007/05/16 19:40:21 UTC

svn commit: r538660 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry/internal/services/ main/java/org/apache/tapestry/test/ site/apt/guide/ test/app1/WEB-INF/ test/java/org/apache/tapestry/integration/ test/java/org/apach...

Author: hlship
Date: Wed May 16 10:40:20 2007
New Revision: 538660

URL: http://svn.apache.org/viewvc?view=rev&rev=538660
Log:
TAPESTRY-1463: Way to inherit binding from containing component

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InheritedBinding.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/InheritedBindingsDemo.html
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Inner.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Outer.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InheritedBindingsDemo.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InheritedBindingTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/components/Outer.html
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderProcessor.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
    tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/parameters.apt
    tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/Start.html
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageLoaderImplTest.java

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InheritedBinding.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InheritedBinding.java?view=auto&rev=538660
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InheritedBinding.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/InheritedBinding.java Wed May 16 10:40:20 2007
@@ -0,0 +1,108 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// 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
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import java.lang.annotation.Annotation;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.ioc.BaseLocatable;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+
+/**
+ * Wraps another binding, adjusting the description of the binding and the location of the binding
+ * (as reported in any thrown exceptions).
+ */
+public class InheritedBinding extends BaseLocatable implements Binding
+{
+    private final String _toString;
+
+    private final Binding _binding;
+
+    public InheritedBinding(String toString, Binding binding, Location location)
+    {
+        super(location);
+
+        _toString = toString;
+        _binding = binding;
+    }
+
+    @Override
+    public String toString()
+    {
+        return _toString;
+    }
+
+    public Object get()
+    {
+        try
+        {
+            return _binding.get();
+        }
+        catch (Exception ex)
+        {
+            throw new TapestryException(ex.getMessage(), this, ex);
+        }
+    }
+
+    public Class getBindingType()
+    {
+        try
+        {
+            return _binding.getBindingType();
+        }
+        catch (Exception ex)
+        {
+            throw new TapestryException(ex.getMessage(), this, ex);
+        }
+    }
+
+    public boolean isInvariant()
+    {
+        try
+        {
+            return _binding.isInvariant();
+        }
+        catch (Exception ex)
+        {
+            throw new TapestryException(ex.getMessage(), this, ex);
+        }
+    }
+
+    public void set(Object value)
+    {
+        try
+        {
+            _binding.set(value);
+        }
+        catch (Exception ex)
+        {
+            throw new TapestryException(ex.getMessage(), this, ex);
+        }
+    }
+
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
+    {
+        try
+        {
+            return _binding.getAnnotation(annotationClass);
+        }
+        catch (Exception ex)
+        {
+            throw new TapestryException(ex.getMessage(), this, ex);
+        }
+    }
+
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderProcessor.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderProcessor.java?view=diff&rev=538660&r1=538659&r2=538660
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderProcessor.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageLoaderProcessor.java Wed May 16 10:40:20 2007
@@ -14,11 +14,13 @@
 
 package org.apache.tapestry.internal.services;
 
+import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newMap;
 import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newStack;
 import static org.apache.tapestry.ioc.internal.util.InternalUtils.isBlank;
 import static org.apache.tapestry.ioc.internal.util.InternalUtils.isNonBlank;
 
 import java.util.Locale;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.logging.Log;
@@ -45,6 +47,7 @@
 import org.apache.tapestry.internal.structure.Page;
 import org.apache.tapestry.internal.structure.PageElement;
 import org.apache.tapestry.internal.structure.PageImpl;
+import org.apache.tapestry.ioc.Location;
 import org.apache.tapestry.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry.ioc.internal.util.IdAllocator;
 import org.apache.tapestry.ioc.internal.util.OneShotLock;
@@ -60,6 +63,8 @@
  */
 class PageLoaderProcessor
 {
+    private static final String INHERIT_PREFIX = "inherit:";
+
     private static Runnable NO_OP = new Runnable()
     {
         public void run()
@@ -93,6 +98,8 @@
 
     private ComponentPageElement _loadingElement;
 
+    private final Map<String, Map<String, Binding>> _componentIdToBindingMap = newMap();
+
     private Locale _locale;
 
     private final OneShotLock _lock = new OneShotLock();
@@ -134,15 +141,22 @@
                 name,
                 TapestryConstants.LITERAL_BINDING_PREFIX);
 
-        Binding binding = _bindingSource.newBinding(
-                "parameter " + name,
-                _loadingElement.getComponentResources(),
-                component.getComponentResources(),
-                defaultBindingPrefix,
+        Binding binding = findBinding(
+                _loadingElement,
+                component,
+                name,
                 token.getValue(),
+                defaultBindingPrefix,
                 token.getLocation());
 
-        component.bindParameter(name, binding);
+        if (binding != null)
+        {
+            component.bindParameter(name, binding);
+
+            Map<String, Binding> bindingMap = _componentIdToBindingMap.get(component
+                    .getCompleteId());
+            bindingMap.put(name, binding);
+        }
     }
 
     private void addMixinsToComponent(ComponentPageElement component, EmbeddedComponentModel model,
@@ -162,7 +176,8 @@
     }
 
     private void bindParametersFromModel(EmbeddedComponentModel model,
-            ComponentPageElement loadingComponent, ComponentPageElement component)
+            ComponentPageElement loadingComponent, ComponentPageElement component,
+            Map<String, Binding> bindingMap)
     {
         for (String name : model.getParameterNames())
         {
@@ -173,22 +188,72 @@
                     name,
                     TapestryConstants.PROP_BINDING_PREFIX);
 
-            // At some point we may add meta data to control what the default prefix is within a
-            // component.
-
-            Binding binding = _bindingSource.newBinding(
-                    "parameter " + name,
-                    loadingComponent.getComponentResources(),
-                    component.getComponentResources(),
-                    defaultBindingPrefix,
+            Binding binding = findBinding(
+                    loadingComponent,
+                    component,
+                    name,
                     value,
-                    null);
+                    defaultBindingPrefix,
+                    component.getLocation());
 
-            component.bindParameter(name, binding);
+            if (binding != null)
+            {
+                component.bindParameter(name, binding);
+
+                // So that the binding can be shared if inherited by a subcomponent
+                bindingMap.put(name, binding);
+            }
         }
     }
 
     /**
+     * Creates a new binding, or returns an existing binding (or null) for the "inherit:" binding
+     * prefix. Mostly a wrapper around
+     * {@link BindingSource#newBinding(String, ComponentResources, ComponentResources, String, String, Location)
+     * 
+     * @return the new binding, or an existing binding (if inherited), or null (if inherited, and
+     *         the containing parameter is not bound)
+     */
+    private Binding findBinding(ComponentPageElement loadingComponent,
+            ComponentPageElement component, String name, String value, String defaultBindingPrefix,
+            Location location)
+    {
+        if (value.startsWith(INHERIT_PREFIX))
+        {
+            String loadingParameterName = value.substring(INHERIT_PREFIX.length());
+            Map<String, Binding> loadingComponentBindingMap = _componentIdToBindingMap
+                    .get(loadingComponent.getCompleteId());
+
+            // This may return null if the parameter is not bound in the loading component.
+
+            Binding existing = loadingComponentBindingMap.get(loadingParameterName);
+
+            if (existing == null) return null;
+
+            String description = String.format(
+                    "InheritedBinding[parameter %s %s(inherited from %s of %s)]",
+                    name,
+                    component.getCompleteId(),
+                    loadingParameterName,
+                    loadingComponent.getCompleteId());
+
+            // This helps with debugging, and re-orients any thrown exceptions
+            // to the location of the inherited binding, rather than the container component's
+            // binding.
+
+            return new InheritedBinding(description, existing, location);
+        }
+
+        return _bindingSource.newBinding(
+                "parameter " + name,
+                loadingComponent.getComponentResources(),
+                component.getComponentResources(),
+                defaultBindingPrefix,
+                value,
+                location);
+    }
+
+    /**
      * Determines the default binding prefix for a particular parameter.
      * 
      * @param component
@@ -569,8 +634,11 @@
 
         addMixinsToComponent(newComponent, embeddedModel, token.getMixins());
 
+        Map<String, Binding> bindingMap = newMap();
+        _componentIdToBindingMap.put(newComponent.getCompleteId(), bindingMap);
+
         if (embeddedModel != null)
-            bindParametersFromModel(embeddedModel, _loadingElement, newComponent);
+            bindParametersFromModel(embeddedModel, _loadingElement, newComponent, bindingMap);
 
         addToBody(newComponent);
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java?view=diff&rev=538660&r1=538659&r2=538660
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/test/TapestryTestCase.java Wed May 16 10:40:20 2007
@@ -571,7 +571,7 @@
         expect(source.getClasspathAsset(path, locale)).andReturn(asset);
     }
 
-    protected final void train_getCompleteId(ComponentResources resources, String completeId)
+    protected final void train_getCompleteId(ComponentResourcesCommon resources, String completeId)
     {
         expect(resources.getCompleteId()).andReturn(completeId).atLeastOnce();
     }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/parameters.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/parameters.apt?view=diff&rev=538660&r1=538659&r2=538660
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/parameters.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/parameters.apt Wed May 16 10:40:20 2007
@@ -131,6 +131,8 @@
 *------------+----------------------------------------------------------------------------------+
 
   Parameters have a default prefix, usually "prop:", that is used when the prefix is not provided.
+  
+  A <special prefix>, "inherit:", is used to support {{{#Inherited Parameter Bindings}Inherted Parameter Bindings}}.
     
 Property Bindings
 
@@ -270,6 +272,21 @@
   the min parameter has a default value of 1. That value is used unless the min parameter is bound,
   in which case, the bound value supercedes the default.
   
+  
+{Inherited Parameter Bindings}
+
+  A special prefix, "inherit:" is used to identify the name of a parameter of the containing component.
+  If the parameter is bound in the containing component, then it will be bound to the same value
+  in the embedded component.
+  
+  If the parameter is not bound in the containing component, then it will not be bound in the embedded component
+  (and so, the embedded component may use a default binding).
+  
+  Inherited bindings are useful for complex components; they are often used when an inner component
+  has a default value for a parameter, and the outer component wants to make it possible to override that default.
+  
+  More examples on this coming soon.
+    
 Parameter Binding Defaults
 
   The Parameter annotation's value() attribute can be used to specify a <binding expression> that will be the
@@ -380,7 +397,7 @@
   In rare cases, it is desirable to defeat the caching; this can be done by setting the cache() attribute
   of the Parameter annotation to false.
   
-Parameter Type Cooercion
+Parameter Type Coercion
 
   Tapestry includes a mechanism for {{{coercion.html}coecing types automatically}}. Most often, this is used to
   convert literal strings into appropriate values, but in many cases, more complex conversions
@@ -428,5 +445,5 @@
   These resources are the linkage between the Java class you provide, and the infrastructure Tapestry
   builds around your class.  In any case, once the resources are injected,
   they can be queried.
-  
-  
\ No newline at end of file
+ 
+   
\ No newline at end of file

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/InheritedBindingsDemo.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/InheritedBindingsDemo.html?view=auto&rev=538660
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/InheritedBindingsDemo.html (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/InheritedBindingsDemo.html Wed May 16 10:40:20 2007
@@ -0,0 +1,12 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <h1>Inherited Bindings Demo</h1>
+  
+  <h1>Bound</h1>
+  
+  Bound: <t:outer outerValue="the-bound-value"/>
+
+  <h1>Unbound</h1>
+  
+  Unbound: <t:outer/>
+
+</html>
\ No newline at end of file

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/Start.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/Start.html?view=diff&rev=538660&r1=538659&r2=538660
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/Start.html (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/WEB-INF/Start.html Wed May 16 10:40:20 2007
@@ -127,6 +127,10 @@
             <t:pagelink page="eventhandlerdemo" context="'clear'">EventHandler Demo</t:pagelink>
             -- Tests for event handling method order and matching
           </li>
+          <li>
+            <t:pagelink page="inheritedbindingsdemo">Inherited Bindings Demo</t:pagelink> --
+            Tests for components that inherit bindings from containing components
+          </li>
         </ul>
       </td>
     </tr>

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?view=diff&rev=538660&r1=538659&r2=538660
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Wed May 16 10:40:20 2007
@@ -901,6 +901,16 @@
         clickAndWait("fred");
 
         assertTextPresent("[parent.eventHandlerOne(String), parent.eventHandlerZero(), parent.onAction(), parent.onAction(String), child.eventHandlerForFred(), child.eventHandlerOneChild(), child.eventHandlerZeroChild(), child.onAction(), child.onAction(String), child.onActionFromFred(), child.onActionFromFred(String), child.onAnyEventFromFred(), child.onAnyEventFromFred(String)]");
+    }
 
+    @Test
+    public void inherited_bindings()
+    {
+        open(BASE_URL);
+        clickAndWait("link=Inherited Bindings Demo");
+
+        assertTextPresent(
+                "Bound: [ value: the-bound-value, bound: true ]",
+                "Unbound: [ value: null, bound: false ]");
     }
 }

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Inner.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Inner.java?view=auto&rev=538660
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Inner.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Inner.java Wed May 16 10:40:20 2007
@@ -0,0 +1,34 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// 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
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.components;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotations.Inject;
+import org.apache.tapestry.annotations.Parameter;
+
+public class Inner
+{
+    @Parameter
+    private String _innerValue;
+
+    @Inject
+    private ComponentResources _resources;
+
+    void beginRender(MarkupWriter writer)
+    {
+        writer.writef("[ value: %s, bound: %s ]", _innerValue, _resources.isBound("innerValue"));
+    }
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Outer.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Outer.java?view=auto&rev=538660
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Outer.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Outer.java Wed May 16 10:40:20 2007
@@ -0,0 +1,26 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// 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
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.components;
+
+import static org.apache.tapestry.TapestryConstants.LITERAL_BINDING_PREFIX;
+
+import org.apache.tapestry.annotations.Parameter;
+
+public class Outer
+{
+    @SuppressWarnings("unused")
+    @Parameter(defaultPrefix = LITERAL_BINDING_PREFIX)
+    private String _outerValue;
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InheritedBindingsDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InheritedBindingsDemo.java?view=auto&rev=538660
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InheritedBindingsDemo.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InheritedBindingsDemo.java Wed May 16 10:40:20 2007
@@ -0,0 +1,20 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// 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
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+public class InheritedBindingsDemo
+{
+
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InheritedBindingTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InheritedBindingTest.java?view=auto&rev=538660
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InheritedBindingTest.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/InheritedBindingTest.java Wed May 16 10:40:20 2007
@@ -0,0 +1,272 @@
+// Copyright 2007 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// 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
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.Binding;
+import org.apache.tapestry.annotations.Inject;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.internal.util.TapestryException;
+import org.apache.tapestry.test.TapestryTestCase;
+import org.testng.annotations.Test;
+
+public class InheritedBindingTest extends TapestryTestCase
+{
+    private static final String BINDING_DESCRIPTION = "binding description";
+
+    private static final String MESSAGE = "Exception in inner.";
+
+    private static final Throwable _exception = new RuntimeException(MESSAGE);
+
+    @Test
+    public void to_string_and_location()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(BINDING_DESCRIPTION, inner, l);
+
+        assertSame(binding.toString(), BINDING_DESCRIPTION);
+        assertSame(binding.getLocation(), l);
+
+        verify();
+    }
+
+    @Test
+    public void get_success()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+        Object expected = new Object();
+
+        train_get(inner, expected);
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(BINDING_DESCRIPTION, inner, l);
+
+        assertSame(binding.get(), expected);
+
+        verify();
+    }
+
+    @Test
+    public void get_failure()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+
+        expect(inner.get()).andThrow(_exception);
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(BINDING_DESCRIPTION, inner, l);
+
+        try
+        {
+            binding.get();
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            checkException(ex, l);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void get_binding_type_success()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+        Class expected = Runnable.class;
+
+        expect(inner.getBindingType()).andReturn(expected);
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(BINDING_DESCRIPTION, inner, l);
+
+        assertSame(binding.getBindingType(), expected);
+
+        verify();
+    }
+
+    @Test
+    public void get_binding_type_failure()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+        String description = BINDING_DESCRIPTION;
+
+        expect(inner.getBindingType()).andThrow(_exception);
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(description, inner, l);
+
+        try
+        {
+            binding.getBindingType();
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            checkException(ex, l);
+        }
+
+        verify();
+    }
+
+    private void checkException(TapestryException ex, Location l)
+    {
+        assertEquals(ex.getMessage(), MESSAGE);
+        assertEquals(ex.getLocation(), l);
+        assertSame(ex.getCause(), _exception);
+    }
+
+    @Test
+    public void is_invariant_success()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+        boolean expected = true;
+
+        expect(inner.isInvariant()).andReturn(expected);
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(BINDING_DESCRIPTION, inner, l);
+
+        assertEquals(binding.isInvariant(), expected);
+
+        verify();
+    }
+
+    @Test
+    public void is_invariant_failure()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+        expect(inner.isInvariant()).andThrow(_exception);
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(BINDING_DESCRIPTION, inner, l);
+
+        try
+        {
+            binding.isInvariant();
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            checkException(ex, l);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void set_success()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+        String description = BINDING_DESCRIPTION;
+        Object parameter = new Object();
+
+        inner.set(parameter);
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(description, inner, l);
+
+        binding.set(parameter);
+
+        verify();
+    }
+
+    @Test
+    public void set_failure()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+        Object parameter = new Object();
+
+        inner.set(parameter);
+        getMocksControl().andThrow(_exception);
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(BINDING_DESCRIPTION, inner, l);
+
+        try
+        {
+            binding.set(parameter);
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            checkException(ex, l);
+        }
+
+        verify();
+    }
+
+    @Test
+    public void get_annotation_success()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+        Inject inject = newMock(Inject.class);
+
+        train_getAnnotation(inner, Inject.class, inject);
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(BINDING_DESCRIPTION, inner, l);
+
+        assertSame(binding.getAnnotation(Inject.class), inject);
+
+        verify();
+    }
+
+    @Test
+    public void get_annotation_failure()
+    {
+        Binding inner = mockBinding();
+        Location l = mockLocation();
+
+        expect(inner.getAnnotation(Inject.class)).andThrow(_exception);
+
+        replay();
+
+        InheritedBinding binding = new InheritedBinding(BINDING_DESCRIPTION, inner, l);
+
+        try
+        {
+            binding.getAnnotation(Inject.class);
+            unreachable();
+        }
+        catch (TapestryException ex)
+        {
+            checkException(ex, l);
+        }
+
+        verify();
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageLoaderImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageLoaderImplTest.java?view=diff&rev=538660&r1=538659&r2=538660
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageLoaderImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/PageLoaderImplTest.java Wed May 16 10:40:20 2007
@@ -142,7 +142,10 @@
                 "Barney",
                 "foo.components.Barney",
                 null,
-                l, childElement);
+                l,
+                childElement);
+
+        train_getCompleteId(childElement, PAGE_CLASS_NAME + "/Barney");
 
         rootElement.addToTemplate(childElement);
 

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/components/Outer.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/components/Outer.html?view=auto&rev=538660
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/components/Outer.html (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/resources/org/apache/tapestry/integration/app1/components/Outer.html Wed May 16 10:40:20 2007
@@ -0,0 +1,3 @@
+<span xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+  <t:inner innerValue="inherit:outerValue"/>
+</span>
\ No newline at end of file