You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by jk...@apache.org on 2007/04/28 21:50:33 UTC
svn commit: r533422 - in /tapestry/tapestry4/trunk/tapestry-framework/src:
java/org/apache/tapestry/internal/event/
java/org/apache/tapestry/internal/event/impl/
java/org/apache/tapestry/services/impl/
test/org/apache/tapestry/internal/event/impl/
Author: jkuhnert
Date: Sat Apr 28 12:50:32 2007
New Revision: 533422
URL: http://svn.apache.org/viewvc?view=rev&rev=533422
Log:
-) Made ComponentEventInvoker thread safe.
-) Added caching of component event properties for minor performance improvements in overall component rendering.
Modified:
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/IComponentEventInvoker.java
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/impl/ComponentEventInvoker.java
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentEventConnectionWorker.java
tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/internal/event/impl/ComponentEventInvokerTest.java
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/IComponentEventInvoker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/IComponentEventInvoker.java?view=diff&rev=533422&r1=533421&r2=533422
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/IComponentEventInvoker.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/IComponentEventInvoker.java Sat Apr 28 12:50:32 2007
@@ -51,7 +51,17 @@
* @return The bound listeners, or null if none exist.
*/
List getEventListeners(String componentId);
-
+
+ /**
+ * Gets all bound property event listeners for the specified componentIdPath.
+ *
+ * @param componentIdPath
+ * The unique id path of the component, as returned from {@link org.apache.tapestry.IComponent#getIdPath()}.
+ *
+ * @return The aggregated array of all event properties bound to the specified component, empty if none exist.
+ */
+ ComponentEventProperty[] getEventPropertyListeners(String componentIdPath);
+
/**
* Adds a mapping for an event listener that should be triggered when the specified
* form component with id of <code>formId</code> is submitted. This will later
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/impl/ComponentEventInvoker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/impl/ComponentEventInvoker.java?view=diff&rev=533422&r1=533421&r2=533422
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/impl/ComponentEventInvoker.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/internal/event/impl/ComponentEventInvoker.java Sat Apr 28 12:50:32 2007
@@ -13,6 +13,7 @@
// limitations under the License.
package org.apache.tapestry.internal.event.impl;
+import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
import org.apache.hivemind.util.Defense;
import org.apache.tapestry.IActionListener;
import org.apache.tapestry.IComponent;
@@ -26,6 +27,7 @@
import org.apache.tapestry.internal.event.IComponentEventInvoker;
import org.apache.tapestry.listener.ListenerInvoker;
import org.apache.tapestry.spec.IComponentSpecification;
+import org.apache.tapestry.spec.IEventListener;
import java.util.*;
@@ -37,13 +39,18 @@
*/
public class ComponentEventInvoker implements IComponentEventInvoker, ResetEventListener
{
+ static final ComponentEventProperty[] EMPTY_PROPERTIES = new ComponentEventProperty[0];
+
// Mapped component id path -> List of IEventListeners
- private Map _components = new HashMap();
+ private Map _components = new ConcurrentHashMap();
// Mapped form id path -> List of IEventListeners
- private Map _formComponents = new HashMap();
+ private Map _formComponents = new ConcurrentHashMap();
// Used to invoke actual listener methods
private ListenerInvoker _invoker;
+ // Cached set of ComponentEventProperty[] arrays mapped to specific components
+ private Map _propertyCache = new ConcurrentHashMap();
+
/**
* {@inheritDoc}
*/
@@ -236,6 +243,8 @@
if (!listeners.contains(listener)) {
listeners.add(listener);
}
+
+ _propertyCache.remove(componentId);
}
/**
@@ -243,9 +252,40 @@
*/
public List getEventListeners(String componentId)
{
+ if (componentId == null)
+ return null;
+
return (List)_components.get(componentId);
}
-
+
+ public ComponentEventProperty[] getEventPropertyListeners(String componentIdPath)
+ {
+ if (componentIdPath == null)
+ return EMPTY_PROPERTIES;
+
+ ComponentEventProperty[] ret = (ComponentEventProperty[])_propertyCache.get(componentIdPath);
+ if (ret != null)
+ return ret;
+
+ List listeners = getEventListeners(componentIdPath);
+ if (listeners == null || listeners.size() < 1)
+ return EMPTY_PROPERTIES;
+
+ List props = new ArrayList();
+ for (int i=0; i < listeners.size(); i++) {
+
+ IEventListener listener = (IEventListener)listeners.get(i);
+
+ props.add(listener.getComponentEvents(componentIdPath));
+ }
+
+ ret = (ComponentEventProperty[])props.toArray(new ComponentEventProperty[props.size()]);
+
+ _propertyCache.put(componentIdPath, ret);
+
+ return ret;
+ }
+
/**
* {@inheritDoc}
*/
@@ -268,6 +308,9 @@
*/
public List getFormEventListeners(String formId)
{
+ if (formId == null)
+ return null;
+
return (List)_formComponents.get(formId);
}
@@ -278,6 +321,7 @@
{
_components.clear();
_formComponents.clear();
+ _propertyCache.clear();
}
/** Injected. */
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentEventConnectionWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentEventConnectionWorker.java?view=diff&rev=533422&r1=533421&r2=533422
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentEventConnectionWorker.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/services/impl/ComponentEventConnectionWorker.java Sat Apr 28 12:50:32 2007
@@ -26,7 +26,6 @@
import org.apache.tapestry.internal.event.EventBoundListener;
import org.apache.tapestry.internal.event.IComponentEventInvoker;
import org.apache.tapestry.services.ComponentRenderWorker;
-import org.apache.tapestry.spec.IEventListener;
import org.apache.tapestry.util.ScriptUtils;
import java.util.*;
@@ -96,7 +95,7 @@
void linkComponentEvents(IRequestCycle cycle, IComponent component)
{
- ComponentEventProperty[] props = getComponentEvents(component);
+ ComponentEventProperty[] props = _invoker.getEventPropertyListeners(component.getIdPath());
if (props == null)
return;
@@ -128,24 +127,6 @@
}
}
- ComponentEventProperty[] getComponentEvents(IComponent comp)
- {
- List listeners = _invoker.getEventListeners(comp.getIdPath());
- if (listeners == null || listeners.size() < 1)
- return null;
-
- List ret = new ArrayList();
-
- for (int i=0; i < listeners.size(); i++) {
-
- IEventListener listener = (IEventListener)listeners.get(i);
-
- ret.add(listener.getComponentEvents(comp.getIdPath()));
- }
-
- return (ComponentEventProperty[])ret.toArray(new ComponentEventProperty[ret.size()]);
- }
-
void linkElementEvents(IRequestCycle cycle, IComponent component)
{
if (!component.getSpecification().hasElementEvents())
@@ -227,7 +208,7 @@
linkElementEvents(cycle, component);
- ComponentEventProperty[] props = getComponentEvents(component);
+ ComponentEventProperty[] props = _invoker.getEventPropertyListeners(component.getIdPath());
if (props == null)
continue;
Modified: tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/internal/event/impl/ComponentEventInvokerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/internal/event/impl/ComponentEventInvokerTest.java?view=diff&rev=533422&r1=533421&r2=533422
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/internal/event/impl/ComponentEventInvokerTest.java (original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/internal/event/impl/ComponentEventInvokerTest.java Sat Apr 28 12:50:32 2007
@@ -73,6 +73,32 @@
assertEquals(p.getFormEvents().size(), 1);
}
+ public void test_Get_Event_Property_Listeners()
+ {
+ IComponentSpecification spec = new ComponentSpecification();
+ spec.setComponentClassName("first.test");
+ spec.addEventListener("comp1", new String[] {"onClick"}, "testFoo", null, false, true, false, false);
+ spec.addEventListener("comp1", new String[] {"onClick"}, "testBar", null, false, true, false, false);
+
+ IComponentSpecification spec2 = new ComponentSpecification();
+ spec.setComponentClassName("second.test"); // to make .equals unique
+ spec2.addEventListener("comp1", new String[] {"onClick"}, "testFoo", null, false, true, false, false);
+ spec2.addEventListener("comp1", new String[] {"onClick"}, "testBar", null, false, true, false, false);
+
+ ComponentEventInvoker invoker = new ComponentEventInvoker();
+ invoker.addEventListener("comp1", spec);
+ invoker.addEventListener("comp1", spec2);
+
+ ComponentEventProperty[] empty = invoker.getEventPropertyListeners("bogus");
+ assert empty != null;
+ assertEquals(empty.length, 0);
+
+ ComponentEventProperty[] props = invoker.getEventPropertyListeners("comp1");
+ assertEquals(props.length, 2);
+
+ assert invoker.getEventPropertyListeners("comp1") == props;
+ }
+
public void test_Invoke_Component_Listener()
{
IRequestCycle cycle = newCycle();