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 2014/09/02 01:18:41 UTC

[1/6] git commit: Add a toString() to PlasticClassImpl

Repository: tapestry-5
Updated Branches:
  refs/heads/master 72bb4e217 -> df93764ad


Add a toString() to PlasticClassImpl


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/fe7e20dc
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/fe7e20dc
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/fe7e20dc

Branch: refs/heads/master
Commit: fe7e20dcd4e6d16415c202c211026b7df151046d
Parents: 72bb4e2
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Mon Sep 1 14:22:11 2014 -0700
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Mon Sep 1 14:22:11 2014 -0700

----------------------------------------------------------------------
 .../internal/plastic/PlasticClassImpl.java      | 92 ++++++++++++--------
 1 file changed, 55 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/fe7e20dc/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
----------------------------------------------------------------------
diff --git a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java b/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
index 328d2db..e4e3707 100644
--- a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
+++ b/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
@@ -166,9 +166,9 @@ public class PlasticClassImpl extends Lockable implements PlasticClass, Internal
     // Set of methods that need to contribute to the shim and gain access to it
 
     final Set<PlasticMethodImpl> shimMethods = PlasticInternalUtils.newSet();
-    
+
     final ClassNode implementationClassNode;
-    
+
     private ClassNode interfaceClassNode;
 
     /**
@@ -186,14 +186,14 @@ public class PlasticClassImpl extends Lockable implements PlasticClass, Internal
         this.pool = pool;
         this.proxy = proxy;
         this.implementationClassNode = implementationClassNode;
-        
+
         staticContext = parentStaticContext.dupe();
 
         className = PlasticInternalUtils.toClassName(classNode.name);
         superClassName = PlasticInternalUtils.toClassName(classNode.superName);
 
         fieldInstrumentations = new FieldInstrumentations(classNode.superName);
-        
+
         annotationAccess = new DelegatingAnnotationAccess(pool.createAnnotationAccess(classNode.visibleAnnotations),
                 pool.createAnnotationAccess(superClassName));
 
@@ -334,49 +334,56 @@ public class PlasticClassImpl extends Lockable implements PlasticClass, Internal
 
         return annotationAccess.getAnnotation(annotationType);
     }
-    
+
     private static void addMethodAndParameterAnnotationsFromExistingClass(MethodNode methodNode, ClassNode source)
     {
         if (source != null)
         {
-        
+
             for (MethodNode implementationNode : source.methods)
             {
                 // Find corresponding method in the implementation class MethodNode
                 if (methodNode.name.equals(implementationNode.name) && methodNode.desc.equals(implementationNode.desc))
                 {
-                    
+
                     // Copied and adapted from MethodNode.accept(). We want annotation info, but not code nor attributes
                     // Otherwise, we get ClassFormatError (Illegal exception table range) later
 
                     // visits the method attributes
                     int i, j, n;
-                    if (implementationNode.annotationDefault != null) {
+                    if (implementationNode.annotationDefault != null)
+                    {
                         AnnotationVisitor av = methodNode.visitAnnotationDefault();
                         AnnotationNode.accept(av, null, implementationNode.annotationDefault);
-                        if (av != null) {
+                        if (av != null)
+                        {
                             av.visitEnd();
                         }
                     }
                     n = implementationNode.visibleAnnotations == null ? 0 : implementationNode.visibleAnnotations.size();
-                    for (i = 0; i < n; ++i) {
+                    for (i = 0; i < n; ++i)
+                    {
                         AnnotationNode an = implementationNode.visibleAnnotations.get(i);
                         an.accept(methodNode.visitAnnotation(an.desc, true));
                     }
                     n = implementationNode.invisibleAnnotations == null ? 0 : implementationNode.invisibleAnnotations.size();
-                    for (i = 0; i < n; ++i) {
+                    for (i = 0; i < n; ++i)
+                    {
                         AnnotationNode an = implementationNode.invisibleAnnotations.get(i);
                         an.accept(methodNode.visitAnnotation(an.desc, false));
                     }
                     n = implementationNode.visibleParameterAnnotations == null
                             ? 0
                             : implementationNode.visibleParameterAnnotations.length;
-                    for (i = 0; i < n; ++i) {
+                    for (i = 0; i < n; ++i)
+                    {
                         List<?> l = implementationNode.visibleParameterAnnotations[i];
-                        if (l == null) {
+                        if (l == null)
+                        {
                             continue;
                         }
-                        for (j = 0; j < l.size(); ++j) {
+                        for (j = 0; j < l.size(); ++j)
+                        {
                             AnnotationNode an = (AnnotationNode) l.get(j);
                             an.accept(methodNode.visitParameterAnnotation(i, an.desc, true));
                         }
@@ -384,27 +391,30 @@ public class PlasticClassImpl extends Lockable implements PlasticClass, Internal
                     n = implementationNode.invisibleParameterAnnotations == null
                             ? 0
                             : implementationNode.invisibleParameterAnnotations.length;
-                    for (i = 0; i < n; ++i) {
+                    for (i = 0; i < n; ++i)
+                    {
                         List<?> l = implementationNode.invisibleParameterAnnotations[i];
-                        if (l == null) {
+                        if (l == null)
+                        {
                             continue;
                         }
-                        for (j = 0; j < l.size(); ++j) {
+                        for (j = 0; j < l.size(); ++j)
+                        {
                             AnnotationNode an = (AnnotationNode) l.get(j);
                             an.accept(methodNode.visitParameterAnnotation(i, an.desc, false));
                         }
                     }
-                    
+
                     methodNode.visitEnd();
-                    
+
                     break;
-                    
+
                 }
-                
+
             }
-            
+
         }
-        
+
     }
 
     @Override
@@ -428,7 +438,7 @@ public class PlasticClassImpl extends Lockable implements PlasticClass, Internal
     public ClassInstantiator createInstantiator()
     {
         lock();
-        
+
         addClassAnnotations(implementationClassNode);
 
         createShimIfNeeded();
@@ -449,21 +459,23 @@ public class PlasticClassImpl extends Lockable implements PlasticClass, Internal
         // Copy annotations from implementation if available.
         // Code adapted from ClassNode.accept(), as we just want to copy
         // the annotations and nothing more.
-        if (otherClassNode != null) 
+        if (otherClassNode != null)
         {
-            
+
             int i, n;
             n = otherClassNode.visibleAnnotations == null ? 0 : otherClassNode.visibleAnnotations.size();
-            for (i = 0; i < n; ++i) {
+            for (i = 0; i < n; ++i)
+            {
                 AnnotationNode an = otherClassNode.visibleAnnotations.get(i);
                 an.accept(classNode.visitAnnotation(an.desc, true));
             }
             n = otherClassNode.invisibleAnnotations == null ? 0 : otherClassNode.invisibleAnnotations.size();
-            for (i = 0; i < n; ++i) {
+            for (i = 0; i < n; ++i)
+            {
                 AnnotationNode an = otherClassNode.invisibleAnnotations.get(i);
                 an.accept(classNode.visitAnnotation(an.desc, false));
             }
-            
+
         }
     }
 
@@ -792,8 +804,9 @@ public class PlasticClassImpl extends Lockable implements PlasticClass, Internal
         MethodNode methodNode = new MethodNode(description.modifiers, description.methodName, desc,
                 description.genericSignature, exceptions);
         boolean isOverride = inheritanceData.isImplemented(methodNode.name, desc);
-        
-        if (!isOverride) {
+
+        if (!isOverride)
+        {
             addMethodAndParameterAnnotationsFromExistingClass(methodNode, interfaceClassNode);
             addMethodAndParameterAnnotationsFromExistingClass(methodNode, implementationClassNode);
         }
@@ -811,7 +824,7 @@ public class PlasticClassImpl extends Lockable implements PlasticClass, Internal
     private boolean isDefaultMethod(Method method)
     {
         return method.getDeclaringClass().isInterface() &&
-            (method.getModifiers() & (Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_ABSTRACT)) == Opcodes.ACC_PUBLIC;
+                (method.getModifiers() & (Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_ABSTRACT)) == Opcodes.ACC_PUBLIC;
     }
 
     private void createNewMethodImpl(MethodDescription methodDescription, MethodNode methodNode)
@@ -1201,12 +1214,11 @@ public class PlasticClassImpl extends Lockable implements PlasticClass, Internal
                     "Class %s is not an interface; ony interfaces may be introduced.", interfaceType.getName()));
 
         String interfaceName = nameCache.toInternalName(interfaceType);
-        
+
         try
         {
             interfaceClassNode = PlasticClassPool.readClassNode(interfaceType.getName(), getClass().getClassLoader());
-        }
-        catch (IOException e)
+        } catch (IOException e)
         {
             throw new RuntimeException(e);
         }
@@ -1216,7 +1228,7 @@ public class PlasticClassImpl extends Lockable implements PlasticClass, Internal
             classNode.interfaces.add(interfaceName);
             inheritanceData.addInterface(interfaceName);
         }
-        
+
         addClassAnnotations(interfaceClassNode);
 
         Set<PlasticMethod> introducedMethods = new HashSet<PlasticMethod>();
@@ -1230,7 +1242,7 @@ public class PlasticClassImpl extends Lockable implements PlasticClass, Internal
                 introducedMethods.add(introduceMethod(m));
             }
         }
-        
+
         interfaceClassNode = null;
 
         return introducedMethods;
@@ -1314,4 +1326,10 @@ public class PlasticClassImpl extends Lockable implements PlasticClass, Internal
             pool.setFieldReadInstrumentation(classNode.name, fieldName, fi);
         }
     }
+
+    @Override
+    public String toString()
+    {
+        return String.format("PlasticClassImpl[%s]", className);
+    }
 }


[5/6] git commit: Improve the layout of the demo page

Posted by hl...@apache.org.
Improve the layout of the demo page


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/8a10194a
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/8a10194a
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/8a10194a

Branch: refs/heads/master
Commit: 8a10194ae4293e75981c47f0f38d1892516cbe65
Parents: 014d739
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Mon Sep 1 16:00:32 2014 -0700
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Mon Sep 1 16:00:32 2014 -0700

----------------------------------------------------------------------
 .../src/test/app1/MultiZoneUpdateInsideForm.tml | 32 ++++++++++++--------
 1 file changed, 19 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8a10194a/tapestry-core/src/test/app1/MultiZoneUpdateInsideForm.tml
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/app1/MultiZoneUpdateInsideForm.tml b/tapestry-core/src/test/app1/MultiZoneUpdateInsideForm.tml
index 5334b34..f2cb425 100644
--- a/tapestry-core/src/test/app1/MultiZoneUpdateInsideForm.tml
+++ b/tapestry-core/src/test/app1/MultiZoneUpdateInsideForm.tml
@@ -1,17 +1,23 @@
 <t:border xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">
 
-  <h1>Multi Zone Update Inside Form Demo</h1>
+    <h1>Multi Zone Update Inside Form Demo</h1>
 
-  <form t:type="Form" t:id="form" t:clientValidation="none" action="#">
-    <t:label for="selectValue1"/>
-    <select t:type="Select" t:id="selectValue1" t:validate="required" t:zone="select1ValueZone" t:context="selectContext"/>
-    <t:zone t:id="select1ValueZone" visible="false">Show</t:zone>
-    <t:zone t:id="select2ValueZone">
-      <t:label for="selectValue2"/>
-      <!-- Only necessary to "lock down" the clientId to facilliate the test. -->
-      <select t:type="Select" t:id="selectValue2" clientId="selectValue2" t:validate="required"/>
-    </t:zone>
-    <br/>
-    <input type="submit" value="Upate Form"/>
-  </form>
+    <form t:type="Form" t:id="form" t:clientValidation="none" action="#">
+        <div class="form-group">
+            <t:label for="selectValue1"/>
+        </div>
+        <select t:type="Select" t:id="selectValue1" t:validate="required" t:zone="select1ValueZone"
+                t:context="selectContext"/>
+        <t:zone t:id="select1ValueZone" visible="false">Show</t:zone>
+        <t:zone t:id="select2ValueZone">
+            <div class="form-group">
+                <t:label for="selectValue2"/>
+                <!-- Only necessary to "lock down" the clientId to facilliate the test. -->
+                <select t:type="Select" t:id="selectValue2" clientId="selectValue2" t:validate="required"/>
+            </div>
+        </t:zone>
+        <div class="form-group">
+            <input type="submit" value="Update Form" class="bt btn-primary"/>
+        </div>
+    </form>
 </t:border>
\ No newline at end of file


[2/6] git commit: Convert tabs to spaces

Posted by hl...@apache.org.
Convert tabs to spaces


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/145b368c
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/145b368c
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/145b368c

Branch: refs/heads/master
Commit: 145b368c42ac75fab0d3fc05ac3bb652239772b9
Parents: fe7e20d
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Mon Sep 1 14:55:00 2014 -0700
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Mon Sep 1 14:55:00 2014 -0700

----------------------------------------------------------------------
 .../integration/app1/CoreBehaviorsTests.java    | 106 ++++++++++---------
 1 file changed, 55 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/145b368c/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
index f7b7ea9..cc93804 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
@@ -606,7 +606,8 @@ public class CoreBehaviorsTests extends App1TestCase
     }
 
     @Test
-    public void client_persistence_complex_object() {
+    public void client_persistence_complex_object()
+    {
         openLinks("Client Persistence Demo", "nix session", "store complex");
 
         assertText("persisted-value", "ClientDataWrapper[data inside wrapper]");
@@ -1723,7 +1724,7 @@ public class CoreBehaviorsTests extends App1TestCase
         assertTextPresent("Page called with correct activation context",
                 "You should never see me if use an erroneous activation context");
     }
-    
+
     /**
      * TAP5-2311
      */
@@ -1733,63 +1734,66 @@ public class CoreBehaviorsTests extends App1TestCase
         openLinks("Reload on nested page");
 
         assertTextPresent("This page throws an exception");
-        
+
         clickAndWait("css=a:contains('Go to page'):contains('with reload')");
-        
+
         assertTextPresent("This page throws an exception");
     }
-    
+
     @Test
     public void bound_generic_types()
     {
-    	openLinks("Generic bound type demo");
-    	
-    	assertTextPresent("description=mapOfStrings,type=java.util.Map,genericType=java.util.Map<java.lang.String, java.lang.String>");
-    	assertTextPresent("description=mapOfStrings.get('foo'),type=java.lang.String,genericType=class java.lang.String");
-    	assertTextPresent("description=setOfLongs,type=java.util.Set,genericType=java.util.Set<java.lang.Long>");
-    	assertTextPresent("description=listOfListOfDates,type=java.util.List,genericType=java.util.List<java.util.List<java.util.Date>>");
-    	assertTextPresent("description=listOfListOfDates.get(0),type=java.util.List,genericType=interface java.util.List");
-    	assertTextPresent("description=listOfListOfDates.get(0).get(0),type=java.util.Date,genericType=class java.util.Date");
-    	assertTextPresent("description=[1,2,3],type=java.util.List,genericType=interface java.util.List");
-    	assertTextPresent("description={'foo':'bar'},type=java.util.Map,genericType=interface java.util.Map");
-    	assertTextPresent("description=baz,type=java.lang.String,genericType=class java.lang.String");
-    }
-    
-    static class PacScenario {
-    	String link;
-    	String expextedPacValues;
-    	String expectedUri;
-    	
-		public PacScenario(String link, String expextedPacValues,
-				String expectedUri) {
-			super();
-			this.link = link;
-			this.expextedPacValues = expextedPacValues;
-			this.expectedUri = expectedUri;
-		}
-    }
-    
+        openLinks("Generic bound type demo");
+
+        assertTextPresent("description=mapOfStrings,type=java.util.Map,genericType=java.util.Map<java.lang.String, java.lang.String>");
+        assertTextPresent("description=mapOfStrings.get('foo'),type=java.lang.String,genericType=class java.lang.String");
+        assertTextPresent("description=setOfLongs,type=java.util.Set,genericType=java.util.Set<java.lang.Long>");
+        assertTextPresent("description=listOfListOfDates,type=java.util.List,genericType=java.util.List<java.util.List<java.util.Date>>");
+        assertTextPresent("description=listOfListOfDates.get(0),type=java.util.List,genericType=interface java.util.List");
+        assertTextPresent("description=listOfListOfDates.get(0).get(0),type=java.util.Date,genericType=class java.util.Date");
+        assertTextPresent("description=[1,2,3],type=java.util.List,genericType=interface java.util.List");
+        assertTextPresent("description={'foo':'bar'},type=java.util.Map,genericType=interface java.util.Map");
+        assertTextPresent("description=baz,type=java.lang.String,genericType=class java.lang.String");
+    }
+
+    static class PacScenario
+    {
+        String link;
+        String expextedPacValues;
+        String expectedUri;
+
+        public PacScenario(String link, String expextedPacValues,
+                           String expectedUri)
+        {
+            super();
+            this.link = link;
+            this.expextedPacValues = expextedPacValues;
+            this.expectedUri = expectedUri;
+        }
+    }
+
     @Test
     public void multiple_pac_fields()
     {
-    	openLinks("PageActivationContext Multiple Demo");
-    	
-    	assertText("//span[@id='pacValues']", "zero=NULL, one=NULL, two=NULL");
-    	
-    	PacScenario[] scenarios = {
-			new PacScenario("link=Change PAC (null, null, null)", "zero=NULL, one=NULL, two=NULL", "/pacmultipleannotationdemo"),
-			new PacScenario("link=Change PAC (zero, null, null)", "zero=zero, one=NULL, two=NULL", "/pacmultipleannotationdemo/zero"),
-			new PacScenario("link=Change PAC (zero, 1, null)", "zero=zero, one=1, two=NULL", "/pacmultipleannotationdemo/zero/1"),
-			new PacScenario("link=Change PAC (zero, 1, 2.2)", "zero=zero, one=1, two=2.2", "/pacmultipleannotationdemo/zero/1/2.2"),
-			new PacScenario("link=Change PAC (zero, 1, 2.2, 3)", "zero=zero, one=1, two=2.2", "/pacmultipleannotationdemo/zero/1/2.2"),
-			new PacScenario("link=Change PAC (null, null, 2.2)", "zero=NULL, one=NULL, two=2.2", "/pacmultipleannotationdemo/$N/$N/2.2"),
-			new PacScenario("link=Change PAC (zero, null, 2.2)", "zero=zero, one=NULL, two=2.2", "/pacmultipleannotationdemo/zero/$N/2.2"),
-    	};
-    	
-    	for (PacScenario scenario : scenarios) {
-        	clickAndWait(scenario.link);
-        	assertText("//span[@id='pacValues']", scenario.expextedPacValues);
-        	assertTrue(selenium.getLocation().endsWith(scenario.expectedUri));
-    	}
+        openLinks("PageActivationContext Multiple Demo");
+
+        assertText("//span[@id='pacValues']", "zero=NULL, one=NULL, two=NULL");
+
+        PacScenario[] scenarios = {
+                new PacScenario("link=Change PAC (null, null, null)", "zero=NULL, one=NULL, two=NULL", "/pacmultipleannotationdemo"),
+                new PacScenario("link=Change PAC (zero, null, null)", "zero=zero, one=NULL, two=NULL", "/pacmultipleannotationdemo/zero"),
+                new PacScenario("link=Change PAC (zero, 1, null)", "zero=zero, one=1, two=NULL", "/pacmultipleannotationdemo/zero/1"),
+                new PacScenario("link=Change PAC (zero, 1, 2.2)", "zero=zero, one=1, two=2.2", "/pacmultipleannotationdemo/zero/1/2.2"),
+                new PacScenario("link=Change PAC (zero, 1, 2.2, 3)", "zero=zero, one=1, two=2.2", "/pacmultipleannotationdemo/zero/1/2.2"),
+                new PacScenario("link=Change PAC (null, null, 2.2)", "zero=NULL, one=NULL, two=2.2", "/pacmultipleannotationdemo/$N/$N/2.2"),
+                new PacScenario("link=Change PAC (zero, null, 2.2)", "zero=zero, one=NULL, two=2.2", "/pacmultipleannotationdemo/zero/$N/2.2"),
+        };
+
+        for (PacScenario scenario : scenarios)
+        {
+            clickAndWait(scenario.link);
+            assertText("//span[@id='pacValues']", scenario.expextedPacValues);
+            assertTrue(selenium.getLocation().endsWith(scenario.expectedUri));
+        }
     }
 }


[4/6] git commit: Simplify waitForAjaxRequestsToComplete() to make it more stable & predictable

Posted by hl...@apache.org.
Simplify waitForAjaxRequestsToComplete() to make it more stable & predictable


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/014d7391
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/014d7391
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/014d7391

Branch: refs/heads/master
Commit: 014d7391c801a8506e76a6fdd058714da8b7a1d6
Parents: 3475b4d
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Mon Sep 1 16:00:13 2014 -0700
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Mon Sep 1 16:00:13 2014 -0700

----------------------------------------------------------------------
 .../apache/tapestry5/test/SeleniumTestCase.java   | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/014d7391/tapestry-test/src/main/java/org/apache/tapestry5/test/SeleniumTestCase.java
----------------------------------------------------------------------
diff --git a/tapestry-test/src/main/java/org/apache/tapestry5/test/SeleniumTestCase.java b/tapestry-test/src/main/java/org/apache/tapestry5/test/SeleniumTestCase.java
index b0b2020..fda70c5 100644
--- a/tapestry-test/src/main/java/org/apache/tapestry5/test/SeleniumTestCase.java
+++ b/tapestry-test/src/main/java/org/apache/tapestry5/test/SeleniumTestCase.java
@@ -1733,21 +1733,27 @@ public abstract class SeleniumTestCase extends Assert implements Selenium
 
     /**
      * Waits until all active XHR requests (as noted by the t5/core/dom module)
-     * have completed.  Waits up to 500 ms.
+     * have completed.
      *
      * @since 5.4
      */
-    protected final void waitForAjaxRequestsToComplete() {
-        for (int i = 0; i < 6; i++)
+    protected final void waitForAjaxRequestsToComplete()
+    {
+        // Ugly but necessary. Give the Ajax operation sufficient time to execute normally, then start
+        // polling to see if it has complete.
+        sleep(250);
+
+        // The t5/core/dom module tracks how many Ajax requests are active
+        // and body[data-ajax-active] as appropriate.
+
+        for (int i = 0; i < 10; i++)
         {
             if (i > 0)
             {
                 sleep(100);
             }
 
-            // The t5/core/dom module tracks how many Ajax requests are active
-            // and updates this property as appropriate.
-            if (getAttribute("//body/@data-ajax-active").equals("false"))
+            if (getCssCount("body[data-ajax-active=false]").equals(1))
             {
                 return;
             }


[6/6] git commit: TAP5-1736: Overriding a base class abstract event handler method causes the sub-class method to be invoked twice

Posted by hl...@apache.org.
TAP5-1736: Overriding a base class abstract event handler method causes the sub-class method to be invoked twice


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/df93764a
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/df93764a
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/df93764a

Branch: refs/heads/master
Commit: df93764ad8b5ecdda365f2c205e652692993e084
Parents: 8a10194
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Mon Sep 1 16:18:48 2014 -0700
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Mon Sep 1 16:18:48 2014 -0700

----------------------------------------------------------------------
 .../internal/plastic/InheritanceData.java       | 51 ++++++++++++--------
 .../internal/plastic/PlasticClassImpl.java      | 11 +++--
 .../internal/plastic/PlasticMethodImpl.java     |  8 ++-
 .../apache/tapestry5/plastic/PlasticMethod.java | 21 +++++---
 .../tapestry5/plastic/MethodAdviceTests.groovy  | 39 +++++++++++++--
 .../java/testsubjects/AbstractPlaceholder.java  |  6 +++
 .../test/java/testsubjects/PlaceholderImpl.java |  8 +++
 .../integration/app1/CoreBehaviorsTests.java    |  9 +++-
 .../base/OverrideEventHandlerDemoBaseClass.java | 26 ++++++++++
 .../tapestry5/integration/app1/pages/Index.java |  2 +
 .../app1/pages/OverrideEventHandlerDemo.java    | 15 ++++++
 .../base/OverrideEventHandlerDemoBaseClass.tml  | 13 +++++
 12 files changed, 171 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InheritanceData.java
----------------------------------------------------------------------
diff --git a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InheritanceData.java b/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InheritanceData.java
index ab7a17f..44c1734 100644
--- a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InheritanceData.java
+++ b/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InheritanceData.java
@@ -1,5 +1,3 @@
-// Copyright 2011 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
@@ -52,49 +50,58 @@ public class InheritanceData
      * Returns a new MethodBundle that represents the methods of a child class
      * of this bundle. The returned bundle will always be {@linkplain #isTransformed() transformed}.
      *
-     * @param childClassName name of subclass
      * @return new method bundle
      */
-    public InheritanceData createChild(String childClassName)
+    public InheritanceData createChild()
     {
         return new InheritanceData(this);
     }
 
     /**
-     * Adds a new instance method. Only non-private, non-abstract methods should be added (that is, methods which might
+     * Adds a new instance method. Only non-private methods should be added (that is, methods which might
      * be overridden in subclasses). This can later be queried to see if any base class implements the method.
      *
-     * @param name name of method
-     * @param desc method descriptor
+     * @param name
+     *         name of method
+     * @param desc
+     *         describes the parameters and return value of the method
      */
     public void addMethod(String name, String desc)
     {
-        String value = toValue(name, desc);
-
-        methods.add(value);
+        methods.add(toValue(name, desc));
         methodNames.add(name);
     }
 
+
     /**
-     * Returns true if a transformed parent class contains the indicated method.
+     * Returns true if a transformed parent class contains an implementation of, or abstract placeholder for, the method.
      *
-     * @param name method name
-     * @param desc method descriptor
-     * @return the <em>internal name</em> of the implementing base class for this method,
-     *         or null if no base class implements the method
+     * @param name
+     *         method name
+     * @param desc
+     *         method descriptor
+     * @return true if a base class implements the method (including abstract methods)
      */
     public boolean isImplemented(String name, String desc)
     {
         return checkForMethod(toValue(name, desc));
     }
 
-
     private boolean checkForMethod(String value)
     {
-        if (methods.contains(value))
-            return true;
+        InheritanceData cursor = this;
 
-        return parent == null ? false : parent.checkForMethod(value);
+        while (cursor != null)
+        {
+            if (cursor.methods.contains(value))
+            {
+                return true;
+            }
+
+            cursor = cursor.parent;
+        }
+
+        return false;
     }
 
     /**
@@ -118,8 +125,10 @@ public class InheritanceData
         return false;
     }
 
-    public void addInterface(String name) {
-        if (!interfaceNames.contains(name)) {
+    public void addInterface(String name)
+    {
+        if (!interfaceNames.contains(name))
+        {
             interfaceNames.add(name);
         }
     }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
----------------------------------------------------------------------
diff --git a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java b/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
index e4e3707..c07bcaf 100644
--- a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
+++ b/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
@@ -198,7 +198,8 @@ public class PlasticClassImpl extends Lockable implements PlasticClass, Internal
                 pool.createAnnotationAccess(superClassName));
 
         this.parentInheritanceData = parentInheritanceData;
-        inheritanceData = parentInheritanceData.createChild(className);
+
+        inheritanceData = parentInheritanceData.createChild();
 
         for (String interfaceName : classNode.interfaces)
         {
@@ -233,7 +234,7 @@ public class PlasticClassImpl extends Lockable implements PlasticClass, Internal
              */
             if (Modifier.isStatic(node.access))
             {
-                if (!Modifier.isPrivate(node.access))
+                if (isInheritableMethod(node))
                 {
                     inheritanceData.addMethod(node.name, node.desc);
                 }
@@ -782,8 +783,10 @@ public class PlasticClassImpl extends Lockable implements PlasticClass, Internal
 
         methodNames.add(methodNode.name);
 
-        if (!Modifier.isPrivate(methodNode.access))
+        if (isInheritableMethod(methodNode))
+        {
             inheritanceData.addMethod(methodNode.name, methodNode.desc);
+        }
     }
 
     private PlasticMethod createNewMethod(MethodDescription description)
@@ -1183,7 +1186,7 @@ public class PlasticClassImpl extends Lockable implements PlasticClass, Internal
 
     private boolean isInheritableMethod(MethodNode node)
     {
-        return (node.access & (ACC_ABSTRACT | ACC_PRIVATE)) == 0;
+        return !Modifier.isPrivate(node.access);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticMethodImpl.java
----------------------------------------------------------------------
diff --git a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticMethodImpl.java b/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticMethodImpl.java
index 980bd84..bc3c14c 100644
--- a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticMethodImpl.java
+++ b/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticMethodImpl.java
@@ -1,5 +1,3 @@
-// Copyright 2011 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
@@ -85,6 +83,12 @@ class PlasticMethodImpl extends PlasticMember implements PlasticMethod, Comparab
     }
 
     @Override
+    public boolean isAbstract()
+    {
+        return Modifier.isAbstract(node.access);
+    }
+
+    @Override
     public String getMethodIdentifier()
     {
         plasticClass.check();

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticMethod.java
----------------------------------------------------------------------
diff --git a/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticMethod.java b/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticMethod.java
index f77b441..7ec9342 100644
--- a/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticMethod.java
+++ b/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticMethod.java
@@ -1,5 +1,3 @@
-// Copyright 2011 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
@@ -48,7 +46,8 @@ public interface PlasticMethod extends AnnotationAccess
      * If the method has advice, the advice is <em>not</em> lost but will instead wrap around the new method
      * implementation.
      *
-     * @param callback passed the InstructionBuilder so that an implementation of the method can be created
+     * @param callback
+     *         passed the InstructionBuilder so that an implementation of the method can be created
      * @return this method, for further configuration
      */
     PlasticMethod changeImplementation(InstructionBuilderCallback callback);
@@ -68,7 +67,8 @@ public interface PlasticMethod extends AnnotationAccess
      * Note additionally that a recursive method invocation will still invoke the MethodAdvice chain on each recursive
      * call (this is an intended side-effect of copying the exact bytecode of the method implementation.
      *
-     * @param advice advice to add to the method
+     * @param advice
+     *         advice to add to the method
      * @return this method, for further configuration
      */
     PlasticMethod addAdvice(MethodAdvice advice);
@@ -78,7 +78,8 @@ public interface PlasticMethod extends AnnotationAccess
      * correct interface (or extend the correct class). The original implementation of the method is lost,
      * though (as with {@link #changeImplementation(InstructionBuilderCallback)}), method advice is retained.
      *
-     * @param field to delegate to
+     * @param field
+     *         to delegate to
      * @return this method, for further configuration
      */
     PlasticMethod delegateTo(PlasticField field);
@@ -88,7 +89,8 @@ public interface PlasticMethod extends AnnotationAccess
      * is dynamically computed by another method of the class. The method should take no parameters
      * and must not return null, or throw any exceptions not compatible with the method being proxied.
      *
-     * @param method to provide the dynamic delegate
+     * @param method
+     *         to provide the dynamic delegate
      * @return this method, for further configuration
      */
     PlasticMethod delegateTo(PlasticMethod method);
@@ -107,6 +109,13 @@ public interface PlasticMethod extends AnnotationAccess
     boolean isOverride();
 
     /**
+     * Returns true if the method is abstract.
+     *
+     * @since 5.4
+     */
+    boolean isAbstract();
+
+    /**
      * Returns a short identifier for the method that includes the class name, the method name,
      * and the types of all parameters. This is often used when producing debugging output
      * about the method.

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/plastic/src/test/groovy/org/apache/tapestry5/plastic/MethodAdviceTests.groovy
----------------------------------------------------------------------
diff --git a/plastic/src/test/groovy/org/apache/tapestry5/plastic/MethodAdviceTests.groovy b/plastic/src/test/groovy/org/apache/tapestry5/plastic/MethodAdviceTests.groovy
index 727000e..bd20978 100644
--- a/plastic/src/test/groovy/org/apache/tapestry5/plastic/MethodAdviceTests.groovy
+++ b/plastic/src/test/groovy/org/apache/tapestry5/plastic/MethodAdviceTests.groovy
@@ -109,7 +109,7 @@ class MethodAdviceTests extends AbstractPlasticSpecification {
 
     def "setting return value clears checked exceptions"() {
         def mgr = createMgr({ PlasticClass pc ->
-            findMethod(pc, "maybeThrow").addAdvice({  MethodInvocation mi ->
+            findMethod(pc, "maybeThrow").addAdvice({ MethodInvocation mi ->
 
                 mi.proceed()
 
@@ -221,7 +221,9 @@ class MethodAdviceTests extends AbstractPlasticSpecification {
             })
         } as PlasticClassTransformer)
 
-        if (false) { enableBytecodeDebugging(mgr) }
+        if (false) {
+            enableBytecodeDebugging(mgr)
+        }
 
         def o = mgr.getClassInstantiator(testsubjects.FieldConduitInsideAdvisedMethod.name).with(MagicContainer, container).newInstance()
 
@@ -256,7 +258,9 @@ class MethodAdviceTests extends AbstractPlasticSpecification {
             })
         } as PlasticClassTransformer)
 
-        if (false) { enableBytecodeDebugging(mgr) }
+        if (false) {
+            enableBytecodeDebugging(mgr)
+        }
 
         def o = mgr.getClassInstantiator(testsubjects.FieldConduitAdvisedMethodComplexCase.name).with(MagicContainer, container).newInstance()
 
@@ -303,4 +307,33 @@ class MethodAdviceTests extends AbstractPlasticSpecification {
         o.magic() == "<<MAGIC!>>"
     }
 
+    def "abstract methods are identified as such by PlasticMethod"() {
+
+        setup:
+
+        PlasticClass pc = mgr.getPlasticClass(testsubjects.AbstractPlaceholder.name)
+
+        PlasticMethod m = findMethod pc, "placeholder"
+
+        expect:
+
+        m.isAbstract() == true
+    }
+
+    def "implementations of abstract methods are considered to be overrides"() {
+        setup:
+
+        def packages = ["testsubjects"] as Set
+
+        PlasticManager mgr = PlasticManager.withContextClassLoader().packages(packages).create()
+
+        PlasticClass pc = mgr.getPlasticClass(testsubjects.PlaceholderImpl.name)
+
+        PlasticMethod m = findMethod pc, "placeholder"
+
+        expect:
+
+        m.isOverride() == true
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/plastic/src/test/java/testsubjects/AbstractPlaceholder.java
----------------------------------------------------------------------
diff --git a/plastic/src/test/java/testsubjects/AbstractPlaceholder.java b/plastic/src/test/java/testsubjects/AbstractPlaceholder.java
new file mode 100644
index 0000000..e18ae37
--- /dev/null
+++ b/plastic/src/test/java/testsubjects/AbstractPlaceholder.java
@@ -0,0 +1,6 @@
+package testsubjects;
+
+public abstract class AbstractPlaceholder
+{
+    public abstract void placeholder();
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/plastic/src/test/java/testsubjects/PlaceholderImpl.java
----------------------------------------------------------------------
diff --git a/plastic/src/test/java/testsubjects/PlaceholderImpl.java b/plastic/src/test/java/testsubjects/PlaceholderImpl.java
new file mode 100644
index 0000000..a9d7ed3
--- /dev/null
+++ b/plastic/src/test/java/testsubjects/PlaceholderImpl.java
@@ -0,0 +1,8 @@
+package testsubjects;
+
+public class PlaceholderImpl extends AbstractPlaceholder
+{
+    public void placeholder()
+    {
+    }
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
index cc93804..bbae36a 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
@@ -1,5 +1,3 @@
-// Copyright 2009-2013 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
@@ -1796,4 +1794,11 @@ public class CoreBehaviorsTests extends App1TestCase
             assertTrue(selenium.getLocation().endsWith(scenario.expectedUri));
         }
     }
+
+    @Test
+    public void event_handler_that_overrides_abstract_method_invoked_once() {
+        openLinks("Event Handler Override Demo", "Trigger");
+
+        assertTextSeries("//ul[@id='method-names']/li[%d]", 1, "sub-class", "DONE");
+    }
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/OverrideEventHandlerDemoBaseClass.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/OverrideEventHandlerDemoBaseClass.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/OverrideEventHandlerDemoBaseClass.java
new file mode 100644
index 0000000..babfbb4
--- /dev/null
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/OverrideEventHandlerDemoBaseClass.java
@@ -0,0 +1,26 @@
+package org.apache.tapestry5.integration.app1.base;
+
+import org.apache.tapestry5.annotations.Persist;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+
+import java.util.List;
+
+public abstract class OverrideEventHandlerDemoBaseClass
+{
+    @Persist
+    @Property
+    private List<String> methodNames;
+
+    protected void add(String methodName)
+    {
+        if (methodNames == null)
+        {
+            methodNames = CollectionFactory.newList();
+        }
+        
+        methodNames.add(methodName);
+    }
+
+    public abstract Object onActionFromTrigger();
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
index ae49e59..f3df68f 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
@@ -56,6 +56,8 @@ public class Index
 
     private static final List<Item> ITEMS = CollectionFactory
             .newList(
+                    new Item("OverrideEventHandlerDemo", "Event Handler Override Demo", "Event Handler methods overridden by sub-classes invoke base-class correctly."),
+
                     new Item("LogoSubclass", "Base class Assets in sub-classes", "Assets are resolved for the parent class if that's where the annotations are."),
 
                     new Item("MissingRequiredARP", "Missing Query Parameter for @ActivationRequestParameter", "Activating a page with a required @ActivationRequestParameter, but no matching query parameter, is an error."),

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/OverrideEventHandlerDemo.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/OverrideEventHandlerDemo.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/OverrideEventHandlerDemo.java
new file mode 100644
index 0000000..0d114bf
--- /dev/null
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/OverrideEventHandlerDemo.java
@@ -0,0 +1,15 @@
+package org.apache.tapestry5.integration.app1.pages;
+
+import org.apache.tapestry5.integration.app1.base.OverrideEventHandlerDemoBaseClass;
+
+public class OverrideEventHandlerDemo extends OverrideEventHandlerDemoBaseClass
+{
+    @Override
+    public Object onActionFromTrigger()
+    {
+        add("sub-class");
+        add("DONE");
+
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/base/OverrideEventHandlerDemoBaseClass.tml
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/base/OverrideEventHandlerDemoBaseClass.tml b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/base/OverrideEventHandlerDemoBaseClass.tml
new file mode 100644
index 0000000..9e8f696
--- /dev/null
+++ b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/base/OverrideEventHandlerDemoBaseClass.tml
@@ -0,0 +1,13 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
+
+    <h1>Event Handler Override Demo</h1>
+
+
+    <ul id="method-names">
+        <li t:type="loop" source="methodNames" value="var:methodName">${var:methodName}</li>
+    </ul>
+
+    <t:actionlink class="btn btn-primary" t:id="trigger">Trigger</t:actionlink>
+
+</html>
+


[4/6] git commit: Simplify waitForAjaxRequestsToComplete() to make it more stable & predictable

Posted by hl...@apache.org.
Simplify waitForAjaxRequestsToComplete() to make it more stable & predictable


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/014d7391
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/014d7391
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/014d7391

Branch: refs/heads/master
Commit: 014d7391c801a8506e76a6fdd058714da8b7a1d6
Parents: 3475b4d
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Mon Sep 1 16:00:13 2014 -0700
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Mon Sep 1 16:00:13 2014 -0700

----------------------------------------------------------------------
 .../apache/tapestry5/test/SeleniumTestCase.java   | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/014d7391/tapestry-test/src/main/java/org/apache/tapestry5/test/SeleniumTestCase.java
----------------------------------------------------------------------
diff --git a/tapestry-test/src/main/java/org/apache/tapestry5/test/SeleniumTestCase.java b/tapestry-test/src/main/java/org/apache/tapestry5/test/SeleniumTestCase.java
index b0b2020..fda70c5 100644
--- a/tapestry-test/src/main/java/org/apache/tapestry5/test/SeleniumTestCase.java
+++ b/tapestry-test/src/main/java/org/apache/tapestry5/test/SeleniumTestCase.java
@@ -1733,21 +1733,27 @@ public abstract class SeleniumTestCase extends Assert implements Selenium
 
     /**
      * Waits until all active XHR requests (as noted by the t5/core/dom module)
-     * have completed.  Waits up to 500 ms.
+     * have completed.
      *
      * @since 5.4
      */
-    protected final void waitForAjaxRequestsToComplete() {
-        for (int i = 0; i < 6; i++)
+    protected final void waitForAjaxRequestsToComplete()
+    {
+        // Ugly but necessary. Give the Ajax operation sufficient time to execute normally, then start
+        // polling to see if it has complete.
+        sleep(250);
+
+        // The t5/core/dom module tracks how many Ajax requests are active
+        // and body[data-ajax-active] as appropriate.
+
+        for (int i = 0; i < 10; i++)
         {
             if (i > 0)
             {
                 sleep(100);
             }
 
-            // The t5/core/dom module tracks how many Ajax requests are active
-            // and updates this property as appropriate.
-            if (getAttribute("//body/@data-ajax-active").equals("false"))
+            if (getCssCount("body[data-ajax-active=false]").equals(1))
             {
                 return;
             }


[5/6] git commit: Improve the layout of the demo page

Posted by hl...@apache.org.
Improve the layout of the demo page


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/8a10194a
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/8a10194a
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/8a10194a

Branch: refs/heads/master
Commit: 8a10194ae4293e75981c47f0f38d1892516cbe65
Parents: 014d739
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Mon Sep 1 16:00:32 2014 -0700
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Mon Sep 1 16:00:32 2014 -0700

----------------------------------------------------------------------
 .../src/test/app1/MultiZoneUpdateInsideForm.tml | 32 ++++++++++++--------
 1 file changed, 19 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/8a10194a/tapestry-core/src/test/app1/MultiZoneUpdateInsideForm.tml
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/app1/MultiZoneUpdateInsideForm.tml b/tapestry-core/src/test/app1/MultiZoneUpdateInsideForm.tml
index 5334b34..f2cb425 100644
--- a/tapestry-core/src/test/app1/MultiZoneUpdateInsideForm.tml
+++ b/tapestry-core/src/test/app1/MultiZoneUpdateInsideForm.tml
@@ -1,17 +1,23 @@
 <t:border xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">
 
-  <h1>Multi Zone Update Inside Form Demo</h1>
+    <h1>Multi Zone Update Inside Form Demo</h1>
 
-  <form t:type="Form" t:id="form" t:clientValidation="none" action="#">
-    <t:label for="selectValue1"/>
-    <select t:type="Select" t:id="selectValue1" t:validate="required" t:zone="select1ValueZone" t:context="selectContext"/>
-    <t:zone t:id="select1ValueZone" visible="false">Show</t:zone>
-    <t:zone t:id="select2ValueZone">
-      <t:label for="selectValue2"/>
-      <!-- Only necessary to "lock down" the clientId to facilliate the test. -->
-      <select t:type="Select" t:id="selectValue2" clientId="selectValue2" t:validate="required"/>
-    </t:zone>
-    <br/>
-    <input type="submit" value="Upate Form"/>
-  </form>
+    <form t:type="Form" t:id="form" t:clientValidation="none" action="#">
+        <div class="form-group">
+            <t:label for="selectValue1"/>
+        </div>
+        <select t:type="Select" t:id="selectValue1" t:validate="required" t:zone="select1ValueZone"
+                t:context="selectContext"/>
+        <t:zone t:id="select1ValueZone" visible="false">Show</t:zone>
+        <t:zone t:id="select2ValueZone">
+            <div class="form-group">
+                <t:label for="selectValue2"/>
+                <!-- Only necessary to "lock down" the clientId to facilliate the test. -->
+                <select t:type="Select" t:id="selectValue2" clientId="selectValue2" t:validate="required"/>
+            </div>
+        </t:zone>
+        <div class="form-group">
+            <input type="submit" value="Update Form" class="bt btn-primary"/>
+        </div>
+    </form>
 </t:border>
\ No newline at end of file


[2/6] git commit: Convert tabs to spaces

Posted by hl...@apache.org.
Convert tabs to spaces


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/145b368c
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/145b368c
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/145b368c

Branch: refs/heads/master
Commit: 145b368c42ac75fab0d3fc05ac3bb652239772b9
Parents: fe7e20d
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Mon Sep 1 14:55:00 2014 -0700
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Mon Sep 1 14:55:00 2014 -0700

----------------------------------------------------------------------
 .../integration/app1/CoreBehaviorsTests.java    | 106 ++++++++++---------
 1 file changed, 55 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/145b368c/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
index f7b7ea9..cc93804 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
@@ -606,7 +606,8 @@ public class CoreBehaviorsTests extends App1TestCase
     }
 
     @Test
-    public void client_persistence_complex_object() {
+    public void client_persistence_complex_object()
+    {
         openLinks("Client Persistence Demo", "nix session", "store complex");
 
         assertText("persisted-value", "ClientDataWrapper[data inside wrapper]");
@@ -1723,7 +1724,7 @@ public class CoreBehaviorsTests extends App1TestCase
         assertTextPresent("Page called with correct activation context",
                 "You should never see me if use an erroneous activation context");
     }
-    
+
     /**
      * TAP5-2311
      */
@@ -1733,63 +1734,66 @@ public class CoreBehaviorsTests extends App1TestCase
         openLinks("Reload on nested page");
 
         assertTextPresent("This page throws an exception");
-        
+
         clickAndWait("css=a:contains('Go to page'):contains('with reload')");
-        
+
         assertTextPresent("This page throws an exception");
     }
-    
+
     @Test
     public void bound_generic_types()
     {
-    	openLinks("Generic bound type demo");
-    	
-    	assertTextPresent("description=mapOfStrings,type=java.util.Map,genericType=java.util.Map<java.lang.String, java.lang.String>");
-    	assertTextPresent("description=mapOfStrings.get('foo'),type=java.lang.String,genericType=class java.lang.String");
-    	assertTextPresent("description=setOfLongs,type=java.util.Set,genericType=java.util.Set<java.lang.Long>");
-    	assertTextPresent("description=listOfListOfDates,type=java.util.List,genericType=java.util.List<java.util.List<java.util.Date>>");
-    	assertTextPresent("description=listOfListOfDates.get(0),type=java.util.List,genericType=interface java.util.List");
-    	assertTextPresent("description=listOfListOfDates.get(0).get(0),type=java.util.Date,genericType=class java.util.Date");
-    	assertTextPresent("description=[1,2,3],type=java.util.List,genericType=interface java.util.List");
-    	assertTextPresent("description={'foo':'bar'},type=java.util.Map,genericType=interface java.util.Map");
-    	assertTextPresent("description=baz,type=java.lang.String,genericType=class java.lang.String");
-    }
-    
-    static class PacScenario {
-    	String link;
-    	String expextedPacValues;
-    	String expectedUri;
-    	
-		public PacScenario(String link, String expextedPacValues,
-				String expectedUri) {
-			super();
-			this.link = link;
-			this.expextedPacValues = expextedPacValues;
-			this.expectedUri = expectedUri;
-		}
-    }
-    
+        openLinks("Generic bound type demo");
+
+        assertTextPresent("description=mapOfStrings,type=java.util.Map,genericType=java.util.Map<java.lang.String, java.lang.String>");
+        assertTextPresent("description=mapOfStrings.get('foo'),type=java.lang.String,genericType=class java.lang.String");
+        assertTextPresent("description=setOfLongs,type=java.util.Set,genericType=java.util.Set<java.lang.Long>");
+        assertTextPresent("description=listOfListOfDates,type=java.util.List,genericType=java.util.List<java.util.List<java.util.Date>>");
+        assertTextPresent("description=listOfListOfDates.get(0),type=java.util.List,genericType=interface java.util.List");
+        assertTextPresent("description=listOfListOfDates.get(0).get(0),type=java.util.Date,genericType=class java.util.Date");
+        assertTextPresent("description=[1,2,3],type=java.util.List,genericType=interface java.util.List");
+        assertTextPresent("description={'foo':'bar'},type=java.util.Map,genericType=interface java.util.Map");
+        assertTextPresent("description=baz,type=java.lang.String,genericType=class java.lang.String");
+    }
+
+    static class PacScenario
+    {
+        String link;
+        String expextedPacValues;
+        String expectedUri;
+
+        public PacScenario(String link, String expextedPacValues,
+                           String expectedUri)
+        {
+            super();
+            this.link = link;
+            this.expextedPacValues = expextedPacValues;
+            this.expectedUri = expectedUri;
+        }
+    }
+
     @Test
     public void multiple_pac_fields()
     {
-    	openLinks("PageActivationContext Multiple Demo");
-    	
-    	assertText("//span[@id='pacValues']", "zero=NULL, one=NULL, two=NULL");
-    	
-    	PacScenario[] scenarios = {
-			new PacScenario("link=Change PAC (null, null, null)", "zero=NULL, one=NULL, two=NULL", "/pacmultipleannotationdemo"),
-			new PacScenario("link=Change PAC (zero, null, null)", "zero=zero, one=NULL, two=NULL", "/pacmultipleannotationdemo/zero"),
-			new PacScenario("link=Change PAC (zero, 1, null)", "zero=zero, one=1, two=NULL", "/pacmultipleannotationdemo/zero/1"),
-			new PacScenario("link=Change PAC (zero, 1, 2.2)", "zero=zero, one=1, two=2.2", "/pacmultipleannotationdemo/zero/1/2.2"),
-			new PacScenario("link=Change PAC (zero, 1, 2.2, 3)", "zero=zero, one=1, two=2.2", "/pacmultipleannotationdemo/zero/1/2.2"),
-			new PacScenario("link=Change PAC (null, null, 2.2)", "zero=NULL, one=NULL, two=2.2", "/pacmultipleannotationdemo/$N/$N/2.2"),
-			new PacScenario("link=Change PAC (zero, null, 2.2)", "zero=zero, one=NULL, two=2.2", "/pacmultipleannotationdemo/zero/$N/2.2"),
-    	};
-    	
-    	for (PacScenario scenario : scenarios) {
-        	clickAndWait(scenario.link);
-        	assertText("//span[@id='pacValues']", scenario.expextedPacValues);
-        	assertTrue(selenium.getLocation().endsWith(scenario.expectedUri));
-    	}
+        openLinks("PageActivationContext Multiple Demo");
+
+        assertText("//span[@id='pacValues']", "zero=NULL, one=NULL, two=NULL");
+
+        PacScenario[] scenarios = {
+                new PacScenario("link=Change PAC (null, null, null)", "zero=NULL, one=NULL, two=NULL", "/pacmultipleannotationdemo"),
+                new PacScenario("link=Change PAC (zero, null, null)", "zero=zero, one=NULL, two=NULL", "/pacmultipleannotationdemo/zero"),
+                new PacScenario("link=Change PAC (zero, 1, null)", "zero=zero, one=1, two=NULL", "/pacmultipleannotationdemo/zero/1"),
+                new PacScenario("link=Change PAC (zero, 1, 2.2)", "zero=zero, one=1, two=2.2", "/pacmultipleannotationdemo/zero/1/2.2"),
+                new PacScenario("link=Change PAC (zero, 1, 2.2, 3)", "zero=zero, one=1, two=2.2", "/pacmultipleannotationdemo/zero/1/2.2"),
+                new PacScenario("link=Change PAC (null, null, 2.2)", "zero=NULL, one=NULL, two=2.2", "/pacmultipleannotationdemo/$N/$N/2.2"),
+                new PacScenario("link=Change PAC (zero, null, 2.2)", "zero=zero, one=NULL, two=2.2", "/pacmultipleannotationdemo/zero/$N/2.2"),
+        };
+
+        for (PacScenario scenario : scenarios)
+        {
+            clickAndWait(scenario.link);
+            assertText("//span[@id='pacValues']", scenario.expextedPacValues);
+            assertTrue(selenium.getLocation().endsWith(scenario.expectedUri));
+        }
     }
 }


[3/6] git commit: Tweak code for handling Ajax updates triggered by changing a Select

Posted by hl...@apache.org.
Tweak code for handling Ajax updates triggered by changing a Select


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/3475b4dd
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/3475b4dd
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/3475b4dd

Branch: refs/heads/master
Commit: 3475b4dd2de35232ddb9044531c8fba4d7de5bea
Parents: 145b368
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Mon Sep 1 15:45:10 2014 -0700
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Mon Sep 1 15:45:10 2014 -0700

----------------------------------------------------------------------
 .../META-INF/modules/t5/core/select.coffee        | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3475b4dd/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/select.coffee
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/select.coffee b/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/select.coffee
index 23c05e2..bf2f856 100644
--- a/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/select.coffee
+++ b/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/select.coffee
@@ -1,5 +1,3 @@
-# Copyright 2012 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
@@ -20,11 +18,15 @@ define ["./events", "./dom", "./zone"],
 
   (events, dom, zone) ->
 
-        dom.onDocument "change", "select[data-update-zone]", ->
+    dom.onDocument "change", "select[data-update-zone]", ->
+
+      containingZone = zone.findZone this
 
-          containingZone = zone.findZone this
+      if containingZone
+        containingZone.trigger events.zone.refresh,
+          url: @attr "data-update-url"
+          parameters:
+            "t:selectvalue": @value()
 
-          containingZone and containingZone.trigger events.zone.refresh,
-            url: @attr "data-update-url"
-            parameters:
-              "t:selectvalue": @value()
+      return
+    return


[3/6] git commit: Tweak code for handling Ajax updates triggered by changing a Select

Posted by hl...@apache.org.
Tweak code for handling Ajax updates triggered by changing a Select


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/3475b4dd
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/3475b4dd
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/3475b4dd

Branch: refs/heads/master
Commit: 3475b4dd2de35232ddb9044531c8fba4d7de5bea
Parents: 145b368
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Mon Sep 1 15:45:10 2014 -0700
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Mon Sep 1 15:45:10 2014 -0700

----------------------------------------------------------------------
 .../META-INF/modules/t5/core/select.coffee        | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/3475b4dd/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/select.coffee
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/select.coffee b/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/select.coffee
index 23c05e2..bf2f856 100644
--- a/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/select.coffee
+++ b/tapestry-core/src/main/coffeescript/META-INF/modules/t5/core/select.coffee
@@ -1,5 +1,3 @@
-# Copyright 2012 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
@@ -20,11 +18,15 @@ define ["./events", "./dom", "./zone"],
 
   (events, dom, zone) ->
 
-        dom.onDocument "change", "select[data-update-zone]", ->
+    dom.onDocument "change", "select[data-update-zone]", ->
+
+      containingZone = zone.findZone this
 
-          containingZone = zone.findZone this
+      if containingZone
+        containingZone.trigger events.zone.refresh,
+          url: @attr "data-update-url"
+          parameters:
+            "t:selectvalue": @value()
 
-          containingZone and containingZone.trigger events.zone.refresh,
-            url: @attr "data-update-url"
-            parameters:
-              "t:selectvalue": @value()
+      return
+    return


[6/6] git commit: TAP5-1736: Overriding a base class abstract event handler method causes the sub-class method to be invoked twice

Posted by hl...@apache.org.
TAP5-1736: Overriding a base class abstract event handler method causes the sub-class method to be invoked twice


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/df93764a
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/df93764a
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/df93764a

Branch: refs/heads/master
Commit: df93764ad8b5ecdda365f2c205e652692993e084
Parents: 8a10194
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Mon Sep 1 16:18:48 2014 -0700
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Mon Sep 1 16:18:48 2014 -0700

----------------------------------------------------------------------
 .../internal/plastic/InheritanceData.java       | 51 ++++++++++++--------
 .../internal/plastic/PlasticClassImpl.java      | 11 +++--
 .../internal/plastic/PlasticMethodImpl.java     |  8 ++-
 .../apache/tapestry5/plastic/PlasticMethod.java | 21 +++++---
 .../tapestry5/plastic/MethodAdviceTests.groovy  | 39 +++++++++++++--
 .../java/testsubjects/AbstractPlaceholder.java  |  6 +++
 .../test/java/testsubjects/PlaceholderImpl.java |  8 +++
 .../integration/app1/CoreBehaviorsTests.java    |  9 +++-
 .../base/OverrideEventHandlerDemoBaseClass.java | 26 ++++++++++
 .../tapestry5/integration/app1/pages/Index.java |  2 +
 .../app1/pages/OverrideEventHandlerDemo.java    | 15 ++++++
 .../base/OverrideEventHandlerDemoBaseClass.tml  | 13 +++++
 12 files changed, 171 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InheritanceData.java
----------------------------------------------------------------------
diff --git a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InheritanceData.java b/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InheritanceData.java
index ab7a17f..44c1734 100644
--- a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InheritanceData.java
+++ b/plastic/src/main/java/org/apache/tapestry5/internal/plastic/InheritanceData.java
@@ -1,5 +1,3 @@
-// Copyright 2011 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
@@ -52,49 +50,58 @@ public class InheritanceData
      * Returns a new MethodBundle that represents the methods of a child class
      * of this bundle. The returned bundle will always be {@linkplain #isTransformed() transformed}.
      *
-     * @param childClassName name of subclass
      * @return new method bundle
      */
-    public InheritanceData createChild(String childClassName)
+    public InheritanceData createChild()
     {
         return new InheritanceData(this);
     }
 
     /**
-     * Adds a new instance method. Only non-private, non-abstract methods should be added (that is, methods which might
+     * Adds a new instance method. Only non-private methods should be added (that is, methods which might
      * be overridden in subclasses). This can later be queried to see if any base class implements the method.
      *
-     * @param name name of method
-     * @param desc method descriptor
+     * @param name
+     *         name of method
+     * @param desc
+     *         describes the parameters and return value of the method
      */
     public void addMethod(String name, String desc)
     {
-        String value = toValue(name, desc);
-
-        methods.add(value);
+        methods.add(toValue(name, desc));
         methodNames.add(name);
     }
 
+
     /**
-     * Returns true if a transformed parent class contains the indicated method.
+     * Returns true if a transformed parent class contains an implementation of, or abstract placeholder for, the method.
      *
-     * @param name method name
-     * @param desc method descriptor
-     * @return the <em>internal name</em> of the implementing base class for this method,
-     *         or null if no base class implements the method
+     * @param name
+     *         method name
+     * @param desc
+     *         method descriptor
+     * @return true if a base class implements the method (including abstract methods)
      */
     public boolean isImplemented(String name, String desc)
     {
         return checkForMethod(toValue(name, desc));
     }
 
-
     private boolean checkForMethod(String value)
     {
-        if (methods.contains(value))
-            return true;
+        InheritanceData cursor = this;
 
-        return parent == null ? false : parent.checkForMethod(value);
+        while (cursor != null)
+        {
+            if (cursor.methods.contains(value))
+            {
+                return true;
+            }
+
+            cursor = cursor.parent;
+        }
+
+        return false;
     }
 
     /**
@@ -118,8 +125,10 @@ public class InheritanceData
         return false;
     }
 
-    public void addInterface(String name) {
-        if (!interfaceNames.contains(name)) {
+    public void addInterface(String name)
+    {
+        if (!interfaceNames.contains(name))
+        {
             interfaceNames.add(name);
         }
     }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
----------------------------------------------------------------------
diff --git a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java b/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
index e4e3707..c07bcaf 100644
--- a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
+++ b/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
@@ -198,7 +198,8 @@ public class PlasticClassImpl extends Lockable implements PlasticClass, Internal
                 pool.createAnnotationAccess(superClassName));
 
         this.parentInheritanceData = parentInheritanceData;
-        inheritanceData = parentInheritanceData.createChild(className);
+
+        inheritanceData = parentInheritanceData.createChild();
 
         for (String interfaceName : classNode.interfaces)
         {
@@ -233,7 +234,7 @@ public class PlasticClassImpl extends Lockable implements PlasticClass, Internal
              */
             if (Modifier.isStatic(node.access))
             {
-                if (!Modifier.isPrivate(node.access))
+                if (isInheritableMethod(node))
                 {
                     inheritanceData.addMethod(node.name, node.desc);
                 }
@@ -782,8 +783,10 @@ public class PlasticClassImpl extends Lockable implements PlasticClass, Internal
 
         methodNames.add(methodNode.name);
 
-        if (!Modifier.isPrivate(methodNode.access))
+        if (isInheritableMethod(methodNode))
+        {
             inheritanceData.addMethod(methodNode.name, methodNode.desc);
+        }
     }
 
     private PlasticMethod createNewMethod(MethodDescription description)
@@ -1183,7 +1186,7 @@ public class PlasticClassImpl extends Lockable implements PlasticClass, Internal
 
     private boolean isInheritableMethod(MethodNode node)
     {
-        return (node.access & (ACC_ABSTRACT | ACC_PRIVATE)) == 0;
+        return !Modifier.isPrivate(node.access);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticMethodImpl.java
----------------------------------------------------------------------
diff --git a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticMethodImpl.java b/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticMethodImpl.java
index 980bd84..bc3c14c 100644
--- a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticMethodImpl.java
+++ b/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticMethodImpl.java
@@ -1,5 +1,3 @@
-// Copyright 2011 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
@@ -85,6 +83,12 @@ class PlasticMethodImpl extends PlasticMember implements PlasticMethod, Comparab
     }
 
     @Override
+    public boolean isAbstract()
+    {
+        return Modifier.isAbstract(node.access);
+    }
+
+    @Override
     public String getMethodIdentifier()
     {
         plasticClass.check();

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticMethod.java
----------------------------------------------------------------------
diff --git a/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticMethod.java b/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticMethod.java
index f77b441..7ec9342 100644
--- a/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticMethod.java
+++ b/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticMethod.java
@@ -1,5 +1,3 @@
-// Copyright 2011 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
@@ -48,7 +46,8 @@ public interface PlasticMethod extends AnnotationAccess
      * If the method has advice, the advice is <em>not</em> lost but will instead wrap around the new method
      * implementation.
      *
-     * @param callback passed the InstructionBuilder so that an implementation of the method can be created
+     * @param callback
+     *         passed the InstructionBuilder so that an implementation of the method can be created
      * @return this method, for further configuration
      */
     PlasticMethod changeImplementation(InstructionBuilderCallback callback);
@@ -68,7 +67,8 @@ public interface PlasticMethod extends AnnotationAccess
      * Note additionally that a recursive method invocation will still invoke the MethodAdvice chain on each recursive
      * call (this is an intended side-effect of copying the exact bytecode of the method implementation.
      *
-     * @param advice advice to add to the method
+     * @param advice
+     *         advice to add to the method
      * @return this method, for further configuration
      */
     PlasticMethod addAdvice(MethodAdvice advice);
@@ -78,7 +78,8 @@ public interface PlasticMethod extends AnnotationAccess
      * correct interface (or extend the correct class). The original implementation of the method is lost,
      * though (as with {@link #changeImplementation(InstructionBuilderCallback)}), method advice is retained.
      *
-     * @param field to delegate to
+     * @param field
+     *         to delegate to
      * @return this method, for further configuration
      */
     PlasticMethod delegateTo(PlasticField field);
@@ -88,7 +89,8 @@ public interface PlasticMethod extends AnnotationAccess
      * is dynamically computed by another method of the class. The method should take no parameters
      * and must not return null, or throw any exceptions not compatible with the method being proxied.
      *
-     * @param method to provide the dynamic delegate
+     * @param method
+     *         to provide the dynamic delegate
      * @return this method, for further configuration
      */
     PlasticMethod delegateTo(PlasticMethod method);
@@ -107,6 +109,13 @@ public interface PlasticMethod extends AnnotationAccess
     boolean isOverride();
 
     /**
+     * Returns true if the method is abstract.
+     *
+     * @since 5.4
+     */
+    boolean isAbstract();
+
+    /**
      * Returns a short identifier for the method that includes the class name, the method name,
      * and the types of all parameters. This is often used when producing debugging output
      * about the method.

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/plastic/src/test/groovy/org/apache/tapestry5/plastic/MethodAdviceTests.groovy
----------------------------------------------------------------------
diff --git a/plastic/src/test/groovy/org/apache/tapestry5/plastic/MethodAdviceTests.groovy b/plastic/src/test/groovy/org/apache/tapestry5/plastic/MethodAdviceTests.groovy
index 727000e..bd20978 100644
--- a/plastic/src/test/groovy/org/apache/tapestry5/plastic/MethodAdviceTests.groovy
+++ b/plastic/src/test/groovy/org/apache/tapestry5/plastic/MethodAdviceTests.groovy
@@ -109,7 +109,7 @@ class MethodAdviceTests extends AbstractPlasticSpecification {
 
     def "setting return value clears checked exceptions"() {
         def mgr = createMgr({ PlasticClass pc ->
-            findMethod(pc, "maybeThrow").addAdvice({  MethodInvocation mi ->
+            findMethod(pc, "maybeThrow").addAdvice({ MethodInvocation mi ->
 
                 mi.proceed()
 
@@ -221,7 +221,9 @@ class MethodAdviceTests extends AbstractPlasticSpecification {
             })
         } as PlasticClassTransformer)
 
-        if (false) { enableBytecodeDebugging(mgr) }
+        if (false) {
+            enableBytecodeDebugging(mgr)
+        }
 
         def o = mgr.getClassInstantiator(testsubjects.FieldConduitInsideAdvisedMethod.name).with(MagicContainer, container).newInstance()
 
@@ -256,7 +258,9 @@ class MethodAdviceTests extends AbstractPlasticSpecification {
             })
         } as PlasticClassTransformer)
 
-        if (false) { enableBytecodeDebugging(mgr) }
+        if (false) {
+            enableBytecodeDebugging(mgr)
+        }
 
         def o = mgr.getClassInstantiator(testsubjects.FieldConduitAdvisedMethodComplexCase.name).with(MagicContainer, container).newInstance()
 
@@ -303,4 +307,33 @@ class MethodAdviceTests extends AbstractPlasticSpecification {
         o.magic() == "<<MAGIC!>>"
     }
 
+    def "abstract methods are identified as such by PlasticMethod"() {
+
+        setup:
+
+        PlasticClass pc = mgr.getPlasticClass(testsubjects.AbstractPlaceholder.name)
+
+        PlasticMethod m = findMethod pc, "placeholder"
+
+        expect:
+
+        m.isAbstract() == true
+    }
+
+    def "implementations of abstract methods are considered to be overrides"() {
+        setup:
+
+        def packages = ["testsubjects"] as Set
+
+        PlasticManager mgr = PlasticManager.withContextClassLoader().packages(packages).create()
+
+        PlasticClass pc = mgr.getPlasticClass(testsubjects.PlaceholderImpl.name)
+
+        PlasticMethod m = findMethod pc, "placeholder"
+
+        expect:
+
+        m.isOverride() == true
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/plastic/src/test/java/testsubjects/AbstractPlaceholder.java
----------------------------------------------------------------------
diff --git a/plastic/src/test/java/testsubjects/AbstractPlaceholder.java b/plastic/src/test/java/testsubjects/AbstractPlaceholder.java
new file mode 100644
index 0000000..e18ae37
--- /dev/null
+++ b/plastic/src/test/java/testsubjects/AbstractPlaceholder.java
@@ -0,0 +1,6 @@
+package testsubjects;
+
+public abstract class AbstractPlaceholder
+{
+    public abstract void placeholder();
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/plastic/src/test/java/testsubjects/PlaceholderImpl.java
----------------------------------------------------------------------
diff --git a/plastic/src/test/java/testsubjects/PlaceholderImpl.java b/plastic/src/test/java/testsubjects/PlaceholderImpl.java
new file mode 100644
index 0000000..a9d7ed3
--- /dev/null
+++ b/plastic/src/test/java/testsubjects/PlaceholderImpl.java
@@ -0,0 +1,8 @@
+package testsubjects;
+
+public class PlaceholderImpl extends AbstractPlaceholder
+{
+    public void placeholder()
+    {
+    }
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
index cc93804..bbae36a 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
@@ -1,5 +1,3 @@
-// Copyright 2009-2013 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
@@ -1796,4 +1794,11 @@ public class CoreBehaviorsTests extends App1TestCase
             assertTrue(selenium.getLocation().endsWith(scenario.expectedUri));
         }
     }
+
+    @Test
+    public void event_handler_that_overrides_abstract_method_invoked_once() {
+        openLinks("Event Handler Override Demo", "Trigger");
+
+        assertTextSeries("//ul[@id='method-names']/li[%d]", 1, "sub-class", "DONE");
+    }
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/OverrideEventHandlerDemoBaseClass.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/OverrideEventHandlerDemoBaseClass.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/OverrideEventHandlerDemoBaseClass.java
new file mode 100644
index 0000000..babfbb4
--- /dev/null
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/base/OverrideEventHandlerDemoBaseClass.java
@@ -0,0 +1,26 @@
+package org.apache.tapestry5.integration.app1.base;
+
+import org.apache.tapestry5.annotations.Persist;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+
+import java.util.List;
+
+public abstract class OverrideEventHandlerDemoBaseClass
+{
+    @Persist
+    @Property
+    private List<String> methodNames;
+
+    protected void add(String methodName)
+    {
+        if (methodNames == null)
+        {
+            methodNames = CollectionFactory.newList();
+        }
+        
+        methodNames.add(methodName);
+    }
+
+    public abstract Object onActionFromTrigger();
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
index ae49e59..f3df68f 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
@@ -56,6 +56,8 @@ public class Index
 
     private static final List<Item> ITEMS = CollectionFactory
             .newList(
+                    new Item("OverrideEventHandlerDemo", "Event Handler Override Demo", "Event Handler methods overridden by sub-classes invoke base-class correctly."),
+
                     new Item("LogoSubclass", "Base class Assets in sub-classes", "Assets are resolved for the parent class if that's where the annotations are."),
 
                     new Item("MissingRequiredARP", "Missing Query Parameter for @ActivationRequestParameter", "Activating a page with a required @ActivationRequestParameter, but no matching query parameter, is an error."),

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/OverrideEventHandlerDemo.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/OverrideEventHandlerDemo.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/OverrideEventHandlerDemo.java
new file mode 100644
index 0000000..0d114bf
--- /dev/null
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/OverrideEventHandlerDemo.java
@@ -0,0 +1,15 @@
+package org.apache.tapestry5.integration.app1.pages;
+
+import org.apache.tapestry5.integration.app1.base.OverrideEventHandlerDemoBaseClass;
+
+public class OverrideEventHandlerDemo extends OverrideEventHandlerDemoBaseClass
+{
+    @Override
+    public Object onActionFromTrigger()
+    {
+        add("sub-class");
+        add("DONE");
+
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/df93764a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/base/OverrideEventHandlerDemoBaseClass.tml
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/base/OverrideEventHandlerDemoBaseClass.tml b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/base/OverrideEventHandlerDemoBaseClass.tml
new file mode 100644
index 0000000..9e8f696
--- /dev/null
+++ b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/base/OverrideEventHandlerDemoBaseClass.tml
@@ -0,0 +1,13 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
+
+    <h1>Event Handler Override Demo</h1>
+
+
+    <ul id="method-names">
+        <li t:type="loop" source="methodNames" value="var:methodName">${var:methodName}</li>
+    </ul>
+
+    <t:actionlink class="btn btn-primary" t:id="trigger">Trigger</t:actionlink>
+
+</html>
+