Author: lfryc(a)redhat.com
Date: 2010-12-13 13:46:10 -0500 (Mon, 13 Dec 2010)
New Revision: 20540
Added:
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/LazyLoadingChecker.java
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/LazyLoadingListener.java
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/Reference.java
Modified:
modules/tests/metamer/trunk/application/pom.xml
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/bean/RichTreeModelRecursiveAdaptorBean.java
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/ModelNode.java
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/Node.java
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/RecursiveNode.java
modules/tests/metamer/trunk/application/src/main/webapp/components/richTree/treeAdaptors.xhtml
Log:
added lazy loading checking capability (RF-9698)
Modified: modules/tests/metamer/trunk/application/pom.xml
===================================================================
--- modules/tests/metamer/trunk/application/pom.xml 2010-12-13 18:44:55 UTC (rev 20539)
+++ modules/tests/metamer/trunk/application/pom.xml 2010-12-13 18:46:10 UTC (rev 20540)
@@ -110,6 +110,12 @@
<artifactId>testng</artifactId>
<scope>test</scope>
</dependency>
+
+ <dependency>
+ <groupId>javassist</groupId>
+ <artifactId>javassist</artifactId>
+ <version>3.12.1.GA</version>
+ </dependency>
<!--
<dependency> <groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
Modified:
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/bean/RichTreeModelRecursiveAdaptorBean.java
===================================================================
---
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/bean/RichTreeModelRecursiveAdaptorBean.java 2010-12-13
18:44:55 UTC (rev 20539)
+++
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/bean/RichTreeModelRecursiveAdaptorBean.java 2010-12-13
18:46:10 UTC (rev 20540)
@@ -22,7 +22,9 @@
package org.richfaces.tests.metamer.bean;
import java.io.Serializable;
+import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Set;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
@@ -30,7 +32,10 @@
import org.richfaces.component.UITreeModelRecursiveAdaptor;
import org.richfaces.tests.metamer.Attributes;
+import org.richfaces.tests.metamer.model.treeAdaptor.LazyLoadingListener;
+import org.richfaces.tests.metamer.model.treeAdaptor.Node;
import org.richfaces.tests.metamer.model.treeAdaptor.RecursiveNode;
+import org.richfaces.tests.metamer.model.treeAdaptor.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -48,6 +53,21 @@
private boolean leafChildrenNullable = true;
private transient List<RecursiveNode> rootNodes;
+ /*
+ * Nodes which was loaded lazily in the current request
+ */
+ private Set<Node> lazyInitializedNodes = new LinkedHashSet<Node>();
+
+ private LazyLoadingListener<Node> nodeLazyLoadingListener = new
LazyLoadingListener<Node>() {
+ public void notify(Node node) {
+ lazyInitializedNodes.add(node);
+ };
+ };
+
+ public Set<Node> getLazyInitializedNodes() {
+ return lazyInitializedNodes;
+ }
+
/**
* Initializes the managed bean.
*/
@@ -71,7 +91,13 @@
public List<RecursiveNode> getRootNodes() {
if (rootNodes == null) {
- rootNodes = RecursiveNode.createChildren(null, leafChildrenNullable);
+ rootNodes = RecursiveNode.createChildren(null, leafChildrenNullable,
+ new Reference<LazyLoadingListener<Node>>() {
+ @Override
+ public LazyLoadingListener<Node> get() {
+ return nodeLazyLoadingListener;
+ }
+ });
}
return rootNodes;
}
Added:
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/LazyLoadingChecker.java
===================================================================
---
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/LazyLoadingChecker.java
(rev 0)
+++
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/LazyLoadingChecker.java 2010-12-13
18:46:10 UTC (rev 20540)
@@ -0,0 +1,56 @@
+package org.richfaces.tests.metamer.model.treeAdaptor;
+
+import static java.lang.reflect.Modifier.isStatic;
+
+import java.lang.reflect.Method;
+
+import javassist.util.proxy.MethodHandler;
+import javassist.util.proxy.ProxyFactory;
+import javassist.util.proxy.ProxyObject;
+
+import org.apache.commons.lang.Validate;
+
+public final class LazyLoadingChecker<T> implements MethodHandler {
+
+ T instance;
+ Reference<LazyLoadingListener<T>> listenerReference = null;
+
+ private LazyLoadingChecker(T instance, Reference<LazyLoadingListener<T>>
listenerReference) {
+ this.instance = instance;
+ this.listenerReference = listenerReference;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> T wrapInstance(T instance,
Reference<LazyLoadingListener<T>> listenerReference) {
+ Validate.notNull(listenerReference);
+ ProxyFactory f = new ProxyFactory();
+ f.setSuperclass(instance.getClass());
+ Class<?> c = f.createClass();
+
+ T proxy;
+ try {
+ proxy = (T) c.newInstance();
+ } catch (InstantiationException e) {
+ throw new IllegalStateException(e);
+ } catch (IllegalAccessException e) {
+ throw new IllegalStateException(e);
+ }
+
+ ((ProxyObject) proxy).setHandler(new LazyLoadingChecker<T>(instance,
listenerReference));
+ return proxy;
+ }
+
+ @Override
+ public Object invoke(Object self, Method m, Method proceed, Object[] args) throws
Throwable {
+ if (!isStatic(m.getModifiers())) {
+ LazyLoadingListener<T> listener = listenerReference.get();
+ if (listener != null) {
+ listener.notify(instance);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+ Object result = m.invoke(instance, args);
+ return result;
+ }
+}
Added:
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/LazyLoadingListener.java
===================================================================
---
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/LazyLoadingListener.java
(rev 0)
+++
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/LazyLoadingListener.java 2010-12-13
18:46:10 UTC (rev 20540)
@@ -0,0 +1,5 @@
+package org.richfaces.tests.metamer.model.treeAdaptor;
+
+public interface LazyLoadingListener<T> {
+ void notify(T instance);
+}
Modified:
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/ModelNode.java
===================================================================
---
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/ModelNode.java 2010-12-13
18:44:55 UTC (rev 20539)
+++
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/ModelNode.java 2010-12-13
18:46:10 UTC (rev 20540)
@@ -34,10 +34,18 @@
List<B> bs;
List<RecursiveNode> rs;
- public ModelNode(Node parent, boolean nullable) {
- super(parent, nullable);
+ public ModelNode() {
+ super(null, true, null);
}
+
+ protected ModelNode(Node parent, boolean nullable,
Reference<LazyLoadingListener<Node>> lazyLoadingListenerReference) {
+ super(parent, nullable, lazyLoadingListenerReference);
+ }
+ public static ModelNode getInstance(Node parent, boolean nullable,
Reference<LazyLoadingListener<Node>> lazyLoadingListenerReference) {
+ return lazyLoadingChecker(new ModelNode(parent, nullable,
lazyLoadingListenerReference));
+ }
+
public String getLabel() {
return isRoot() ? "M" : parent.getLabel() + "-M";
}
@@ -58,7 +66,7 @@
public List<RecursiveNode> getRecursive() {
if (rs == null) {
- rs = RecursiveNode.createChildren(this, nullable);
+ rs = RecursiveNode.createChildren(this, nullable, null);
}
return rs;
}
@@ -80,6 +88,11 @@
return ModelNode.this.getLabel() + "-B-" + number;
}
}
+
+ @Override
+ public String toString() {
+ return getLabel();
+ }
private RecursiveNode getParentRecursive() {
for (Node predecessor : getPredecessorsFromRoot()) {
@@ -89,4 +102,5 @@
}
return null;
}
+
}
\ No newline at end of file
Modified:
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/Node.java
===================================================================
---
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/Node.java 2010-12-13
18:44:55 UTC (rev 20539)
+++
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/Node.java 2010-12-13
18:46:10 UTC (rev 20540)
@@ -32,12 +32,20 @@
Node parent;
boolean nullable;
- public Node(Node parent, boolean nullable) {
- super();
+ Reference<LazyLoadingListener<Node>> lazyLoadingListenerReference = new
NodeReference();
+
+ protected Node(Node parent, boolean nullable,
Reference<LazyLoadingListener<Node>> lazyLoadingListenerReference) {
this.parent = parent;
this.nullable = nullable;
+ if (lazyLoadingListenerReference != null) {
+ this.lazyLoadingListenerReference = lazyLoadingListenerReference;
+ }
}
+ public static <T extends Node> T lazyLoadingChecker(T node) {
+ return (T) LazyLoadingChecker.wrapInstance(node,
node.getLazyLoadingListenerReference());
+ }
+
public Node getParent() {
return parent;
}
@@ -66,4 +74,23 @@
}
public abstract String getLabel();
+
+ public Reference<LazyLoadingListener<Node>>
getLazyLoadingListenerReference() {
+ return lazyLoadingListenerReference;
+ }
+
+ public void setLazyLoadingListener(Reference<LazyLoadingListener<Node>>
lazyLoadingListener) {
+ this.lazyLoadingListenerReference = lazyLoadingListener;
+ }
+
+ public class NodeReference implements
Reference<LazyLoadingListener<Node>> {
+ @Override
+ public LazyLoadingListener<Node> get() {
+ Node root = getRoot();
+ if (root == Node.this) {
+ return null;
+ }
+ return getRoot().getLazyLoadingListenerReference().get();
+ }
+ }
}
Modified:
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/RecursiveNode.java
===================================================================
---
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/RecursiveNode.java 2010-12-13
18:44:55 UTC (rev 20539)
+++
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/RecursiveNode.java 2010-12-13
18:46:10 UTC (rev 20540)
@@ -37,11 +37,19 @@
List<RecursiveNode> children = null;
ModelNode model;
- public RecursiveNode(Node parent, boolean nullable, int number) {
- super(parent, nullable);
+ public RecursiveNode() {
+ super(null, true, null);
+ }
+
+ protected RecursiveNode(Node parent, boolean nullable, int number,
Reference<LazyLoadingListener<Node>> lazyLoadingListenerReference) {
+ super(parent, nullable, lazyLoadingListenerReference);
this.number = number;
}
+ public static RecursiveNode getInstance(Node parent, boolean nullable, int number,
Reference<LazyLoadingListener<Node>> lazyLoadingListenerReference) {
+ return lazyLoadingChecker(new RecursiveNode(parent, nullable, number,
lazyLoadingListenerReference));
+ }
+
public int getNumber() {
return number;
}
@@ -55,7 +63,7 @@
return getEmpty();
}
if (children == null) {
- children = createChildren(this, nullable);
+ children = createChildren(this, nullable, null);
}
return children;
}
@@ -73,7 +81,7 @@
public ModelNode getModel() {
if (isLeaf() && !isPreceededByModel()) {
if (model == null) {
- model = new ModelNode(this, nullable);
+ model = ModelNode.getInstance(this, nullable, null);
}
return model;
}
@@ -92,10 +100,11 @@
}
}
- public static List<RecursiveNode> createChildren(Node parent, boolean nullable)
{
+ public static List<RecursiveNode> createChildren(Node parent, boolean nullable,
Reference<LazyLoadingListener<Node>> lazyLoadingListenerReference) {
List<RecursiveNode> children = new LinkedList<RecursiveNode>();
for (int i = 0; i < CHILDREN; i++) {
- children.add(new RecursiveNode(parent, nullable, i));
+ RecursiveNode node = RecursiveNode.getInstance(parent, nullable, i,
lazyLoadingListenerReference);
+ children.add(node);
}
return children;
}
@@ -117,4 +126,9 @@
}
return this.number % 2 == 1;
}
+
+ @Override
+ public String toString() {
+ return getLabel();
+ }
}
\ No newline at end of file
Added:
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/Reference.java
===================================================================
---
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/Reference.java
(rev 0)
+++
modules/tests/metamer/trunk/application/src/main/java/org/richfaces/tests/metamer/model/treeAdaptor/Reference.java 2010-12-13
18:46:10 UTC (rev 20540)
@@ -0,0 +1,6 @@
+package org.richfaces.tests.metamer.model.treeAdaptor;
+
+public interface Reference<T> {
+
+ public T get();
+}
Modified:
modules/tests/metamer/trunk/application/src/main/webapp/components/richTree/treeAdaptors.xhtml
===================================================================
---
modules/tests/metamer/trunk/application/src/main/webapp/components/richTree/treeAdaptors.xhtml 2010-12-13
18:44:55 UTC (rev 20539)
+++
modules/tests/metamer/trunk/application/src/main/webapp/components/richTree/treeAdaptors.xhtml 2010-12-13
18:46:10 UTC (rev 20540)
@@ -72,7 +72,9 @@
<a4j:ajax event="selectionchange"
render="selectionOutput" />
+ <a4j:ajax event="nodetoggle"
render="selectionOutput" />
+
<rich:treeModelRecursiveAdaptor
roots="#{richTreeModelRecursiveAdaptorBean.rootNodes}"
nodes="#{node.recursive}"
@@ -84,12 +86,6 @@
#{node.label}
</a4j:outputPanel>
</rich:treeNode>
-
- <!-- <rich:treeModelAdaptor nodes="{node.model.value}"
rendered="{not empty node.model}">
- <rich:treeNode>
- {node}
- </rich:treeNode>
- </rich:treeModelAdaptor>-->
<rich:treeModelAdaptor nodes="#{node.model.list}"
rendered="#{richTreeModelAdaptorBean.attributes['rendered'].value}">
<rich:treeNode>
@@ -98,7 +94,7 @@
</rich:treeModelAdaptor>
<rich:treeModelRecursiveAdaptor
roots="#{node.model.recursive}" nodes="#{node.recursive}"
rendered="#{richTreeModelRecursiveAdaptorBean.attributes['rendered'].value}">
- <rich:treeNode
rendered="#{richTreeNodeBean.attributes['rendered'].value || node.number !=
1}">
+ <rich:treeNode
rendered="#{richTreeNodeBean.attributes['rendered'].value || node.number !=
1}">
#{node.label}
</rich:treeNode>
</rich:treeModelRecursiveAdaptor>
@@ -109,9 +105,16 @@
<ui:define name="outOfTemplateAfter">
- <a4j:outputPanel id="selectionOutput">
+ <h:panelGrid id="selectionOutput" columns="2">
<h:outputLabel value="Selection: " />
<h:outputText value="#{richTreeBean.selection}" />
+
+ <h:outputLabel value="Lazy Initialized:" />
+ <h:outputText
value="#{richTreeModelRecursiveAdaptorBean.lazyInitializedNodes}" />
+ </h:panelGrid>
+
+ <a4j:outputPanel>
+
</a4j:outputPanel>
<fieldset>