You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2009/09/13 02:14:34 UTC
svn commit: r814253 - in /myfaces/core/trunk:
api/src/main/java/javax/faces/component/
api/src/test/java/javax/faces/component/
impl/src/main/java/org/apache/myfaces/view/facelets/
Author: lu4242
Date: Sun Sep 13 00:14:34 2009
New Revision: 814253
URL: http://svn.apache.org/viewvc?rev=814253&view=rev
Log:
MYFACES-2342 New objects added for new api in UIViewRoot, UIComponent and UIComponentBase could be saved and restored
Modified:
myfaces/core/trunk/api/src/main/java/javax/faces/component/UIComponent.java
myfaces/core/trunk/api/src/test/java/javax/faces/component/_DeltaListTest.java
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java
Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/UIComponent.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/UIComponent.java?rev=814253&r1=814252&r2=814253&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/UIComponent.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/UIComponent.java Sun Sep 13 00:14:34 2009
@@ -925,11 +925,10 @@
}
}
- static class EventListenerWrapper implements SystemEventListener, StateHolder {
+ static class EventListenerWrapper implements SystemEventListener, PartialStateHolder {
- private UIComponent component;
+ private Class<?> componentClass;
private ComponentSystemEventListener listener;
- private boolean transientObject = false;
public EventListenerWrapper()
{
@@ -937,21 +936,38 @@
super();
}
+ /**
+ * Note we have two cases:
+ *
+ * 1. listener is an instance of UIComponent. In this case we cannot save and restore
+ * it because we need to point to the real component, but we can assume the instance
+ * is the same because UIComponent.subscribeToEvent says so. Also take into account
+ * this case is the reason why we need a wrapper for UIComponent.subscribeToEvent
+ * 2. listener is an instance of ComponentSystemEventListener but not from UIComponent.
+ * In this case, the instance could implement StateHolder, PartialStateHolder or do
+ * implement anything, so we have to deal with that case as usual.
+ *
+ * @param component
+ * @param listener
+ */
public EventListenerWrapper(UIComponent component, ComponentSystemEventListener listener) {
assert component != null;
assert listener != null;
- this.component = component;
+ this.componentClass = component.getClass();
this.listener = listener;
}
@Override
public boolean equals(Object o) {
- if (o == this) {
+ if (o == this)
+ {
return true;
- } else if (o instanceof EventListenerWrapper) {
+ }
+ else if (o instanceof EventListenerWrapper)
+ {
EventListenerWrapper other = (EventListenerWrapper) o;
- return component.equals(other.component) && listener.equals(other.listener);
+ return componentClass.equals(other.componentClass) && listener.equals(other.listener);
} else {
return false;
}
@@ -959,17 +975,21 @@
@Override
public int hashCode() {
- return component.hashCode() + listener.hashCode();
+ return componentClass.hashCode() + listener.hashCode();
}
- public boolean isListenerForSource(Object source) {
+ @Override
+ public boolean isListenerForSource(Object source)
+ {
// and its implementation of SystemEventListener.isListenerForSource(java.lang.Object) must return true
// if the instance class of this UIComponent is assignable from the argument to isListenerForSource.
- return source.getClass().isAssignableFrom(component.getClass());
+ return source.getClass().isAssignableFrom(componentClass);
}
- public void processEvent(SystemEvent event) {
+ @Override
+ public void processEvent(SystemEvent event)
+ {
// This inner class must call through to the argument componentListener in its implementation of
// SystemEventListener.processEvent(javax.faces.event.SystemEvent)
@@ -977,130 +997,76 @@
listener.processEvent((ComponentSystemEvent) event);
}
-
+
@Override
- public boolean isTransient() {
- return transientObject;
+ public void clearInitialState()
+ {
+ if (!(listener instanceof UIComponent) && listener instanceof PartialStateHolder)
+ {
+ ((PartialStateHolder)listener).clearInitialState();
+ }
}
@Override
- public void restoreState(FacesContext context, Object state)
+ public boolean initialStateMarked()
{
- if(state == null)
+ if (!(listener instanceof UIComponent) && listener instanceof PartialStateHolder)
{
- return;
+ ((PartialStateHolder)listener).initialStateMarked();
}
-
- Object[] values = (Object[]) state;
- component = (UIComponent) getClassInstance((String)values[0]);
- String listenerClass = (String)values[1];
- Serializable listenerState = (Serializable)values[2];
-
- if(listenerClass == null && listenerState == null)
- {
- //no listenerClass or listenerState to restore
- listener = null;
- }
- else if(listenerClass == null && listenerState != null)
- {
- // the listenerState is the listener for Serializable but not StateHolder objects
- listener = (ComponentSystemEventListener)listenerState;
- }
- else
- {
- // restore the listener and listenerState for StateHolder objects
- listener = (ComponentSystemEventListener)getClassInstance(listenerClass);
-
- if(listener != null && listenerState != null && listener instanceof StateHolder)
- {
- ((StateHolder) listener).restoreState(context, listenerState);
- }
- }
+ return false;
}
@Override
- public Object saveState(FacesContext context)
+ public void markInitialState()
{
- Serializable listenerState = null;
- String listenerClass = null;
-
- if(listener instanceof UIComponent)
+ if (!(listener instanceof UIComponent) && listener instanceof PartialStateHolder)
{
- //just save the component
+ ((PartialStateHolder)listener).markInitialState();
}
- else if (listener instanceof StateHolder)
- {
- //save component, listener state and listener class
- if (!((StateHolder) listener).isTransient())
- {
- listenerState = (Serializable) ((StateHolder) listener).saveState(context);
- listenerClass = listener.getClass().getName();
- }
- }
- else if (listener instanceof Serializable)
+ }
+
+ @Override
+ public boolean isTransient()
+ {
+ if (listener instanceof StateHolder)
{
- //save only listener state
- listenerState = (Serializable) listener;
- listenerClass = null;
- }
-
- Object[] state = new Object[3];
- state[0] = component.getClass().getName();
- state[1] = listenerClass;
- state[2] = listenerState;
- return state;
+ return ((StateHolder)listener).isTransient();
+ }
+ return false;
}
-
+
@Override
- public void setTransient(boolean transientObject)
- {
- this.transientObject = transientObject;
+ public void restoreState(FacesContext context, Object state)
+ {
+ //TODO: Delta
+ Object[] values = (Object[]) state;
+ componentClass = (Class) values[0];
+ listener = values[1] == null ?
+ UIComponent.getCurrentComponent(context) :
+ (ComponentSystemEventListener) UIComponentBase.restoreAttachedState(context, values[1]);
}
- private Object getClassInstance(String name)
+
+ @Override
+ public Object saveState(FacesContext context)
{
- ClassLoader cl;
- if (System.getSecurityManager() != null)
- {
- try {
- cl = AccessController.doPrivileged(new PrivilegedExceptionAction<ClassLoader>()
- {
- public ClassLoader run() throws PrivilegedActionException
- {
- return Thread.currentThread().getContextClassLoader();
- }
- });
- }
- catch (PrivilegedActionException pae)
- {
- throw new FacesException(pae);
- }
- }
- else
- {
- cl = Thread.currentThread().getContextClassLoader();
- }
-
- if (cl == null)
- {
- cl = this.getClass().getClassLoader();
- }
-
- try
+ //TODO: Delta
+ Object[] state = new Object[2];
+ state[0] = componentClass;
+ if (!(listener instanceof UIComponent))
{
- return Class.forName(name, false, cl).newInstance();
+ state[1] = UIComponentBase.saveAttachedState(context, listener);
}
- catch (IllegalAccessException e)
- {
- throw new IllegalStateException(e);
- }
- catch (InstantiationException e)
- {
- throw new IllegalStateException(e);
- }
- catch (ClassNotFoundException e)
+ return state;
+ }
+
+ @Override
+ public void setTransient(boolean newTransientValue)
+ {
+ if (listener instanceof StateHolder)
{
- throw new IllegalStateException(e);
- }
+ ((StateHolder)listener).setTransient(newTransientValue);
+ }
}
}
}
\ No newline at end of file
Modified: myfaces/core/trunk/api/src/test/java/javax/faces/component/_DeltaListTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/test/java/javax/faces/component/_DeltaListTest.java?rev=814253&r1=814252&r2=814253&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/test/java/javax/faces/component/_DeltaListTest.java (original)
+++ myfaces/core/trunk/api/src/test/java/javax/faces/component/_DeltaListTest.java Sun Sep 13 00:14:34 2009
@@ -640,4 +640,30 @@
assertTrue(a._facesListeners.contains(listener1));
assertFalse(b._facesListeners.contains(listener1));
}
+
+ public void testSimpleSaveRestoreTransient5()
+ {
+ UITestComponent a = new UITestComponent();
+ UITestComponent b = new UITestComponent();
+ StateFacesListener listener1 = new StateFacesListener();
+ listener1.setTransient(true);
+ listener1.setValue("value");
+ StateFacesListener listener2 = new StateFacesListener();
+ listener2.setValue("value");
+ a.addTestFacesListener(listener1);
+ a.addTestFacesListener(listener2);
+ b.addTestFacesListener(listener1);
+ b.addTestFacesListener(listener2);
+ a.markInitialState();
+ b.markInitialState();
+ listener2.setValue("value2");
+ //Since listener1 is transient
+ Object [] savedState1 = (Object[]) a.saveState(facesContext);
+ b.restoreState(facesContext, savedState1);
+ assertTrue(a._facesListeners.contains(listener1));
+ assertFalse(b._facesListeners.contains(listener1));
+ assertTrue(a._facesListeners.contains(listener2));
+ assertTrue(b._facesListeners.contains(listener2));
+ assertEquals("value2", ((StateFacesListener)b._facesListeners.get(b._facesListeners.indexOf(listener2))).getValue());
+ }
}
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java?rev=814253&r1=814252&r2=814253&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java Sun Sep 13 00:14:34 2009
@@ -20,6 +20,7 @@
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -30,6 +31,7 @@
import javax.faces.FacesException;
import javax.faces.component.ContextCallback;
import javax.faces.component.UIComponent;
+import javax.faces.component.UIViewParameter;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.event.PostAddToViewEvent;
@@ -39,6 +41,7 @@
import javax.faces.render.ResponseStateManager;
import javax.faces.view.StateManagementStrategy;
import javax.faces.view.ViewDeclarationLanguage;
+import javax.faces.view.ViewMetadata;
import org.apache.myfaces.shared_impl.renderkit.RendererUtils;
import org.apache.myfaces.shared_impl.util.ClassUtils;
@@ -99,15 +102,32 @@
Object state[];
Map<String, Object> states;
- UIViewRoot view;
+ UIViewRoot view = null;
// Per the spec: build the view.
try {
- view = vdl.getViewMetadata (context, viewId).createMetadataView (context);
+ ViewMetadata metadata = vdl.getViewMetadata (context, viewId);
+
+ Collection<UIViewParameter> viewParameters = null;
+
+ if (metadata != null)
+ {
+ view = metadata.createMetadataView(context);
+
+ if (view != null)
+ {
+ viewParameters = metadata.getViewParameters(view);
+ }
+ }
+ if (view == null)
+ {
+ view = vdl.createView(context, viewId);
+ }
context.setViewRoot (view);
+ //TODO: Why is necessary disable event processing?
context.setProcessingEvents (true);
vdl.buildView (context, view);
context.setProcessingEvents (false);
@@ -241,45 +261,53 @@
return;
}
- //Restore view
- Object state = states.get(component.getClientId());
- if (state != null)
+ try
{
- component.restoreState(context, state);
- }
-
- //Scan children
- if (component.getChildCount() > 0)
- {
- String currentClientId = component.getClientId();
-
- List<UIComponent> children = component.getChildren();
- for (int i = 0; i < children.size(); i++)
+ //Restore view
+ component.pushComponentToEL(context, component);
+ Object state = states.get(component.getClientId());
+ if (state != null)
{
- UIComponent child = children.get(i);
- if (child != null && !child.isTransient())
+ component.restoreState(context, state);
+ }
+
+ //Scan children
+ if (component.getChildCount() > 0)
+ {
+ String currentClientId = component.getClientId();
+
+ List<UIComponent> children = component.getChildren();
+ for (int i = 0; i < children.size(); i++)
{
- restoreStateFromMap( context, states, child);
+ UIComponent child = children.get(i);
+ if (child != null && !child.isTransient())
+ {
+ restoreStateFromMap( context, states, child);
+ }
}
}
- }
-
- //Scan facets
- Map<String, UIComponent> facetMap = component.getFacets();
- if (!facetMap.isEmpty())
- {
- String currentClientId = component.getClientId();
-
- for (Map.Entry<String, UIComponent> entry : facetMap.entrySet())
+
+ //Scan facets
+ Map<String, UIComponent> facetMap = component.getFacets();
+ if (!facetMap.isEmpty())
{
- UIComponent child = entry.getValue();
- if (child != null && !child.isTransient())
+ String currentClientId = component.getClientId();
+
+ for (Map.Entry<String, UIComponent> entry : facetMap.entrySet())
{
- String facetName = entry.getKey();
- restoreStateFromMap( context, states, child);
+ UIComponent child = entry.getValue();
+ if (child != null && !child.isTransient())
+ {
+ String facetName = entry.getKey();
+ restoreStateFromMap( context, states, child);
+ }
}
}
}
+ finally
+ {
+ component.popComponentFromEL(context);
+ }
}
static List<String> getClientIdsAdded(UIViewRoot root)
@@ -304,77 +332,85 @@
private void saveStateOnMap(final FacesContext context, final Map<String,Object> states,
final UIComponent component)
- {
- //Save state
- Object savedState = component.saveState(context);
-
- //Only save if the value returned is null
- if (savedState != null)
- {
- states.put(component.getClientId(), savedState);
- }
-
- //Scan children
- if (component.getChildCount() > 0)
+ {
+ try
{
- String currentClientId = component.getClientId();
+ component.pushComponentToEL(context, component);
+ //Save state
+ Object savedState = component.saveState(context);
+
+ //Only save if the value returned is null
+ if (savedState != null)
+ {
+ states.put(component.getClientId(), savedState);
+ }
- List<UIComponent> children = component.getChildren();
- for (int i = 0; i < children.size(); i++)
+ //Scan children
+ if (component.getChildCount() > 0)
{
- UIComponent child = children.get(i);
- if (child != null && !child.isTransient())
+ String currentClientId = component.getClientId();
+
+ List<UIComponent> children = component.getChildren();
+ for (int i = 0; i < children.size(); i++)
{
- if (child.getAttributes().containsKey(COMPONENT_ADDED_AFTER_BUILD_VIEW))
- {
- //Save all required info to restore the subtree.
- //This includes position, structure and state of subtree
- states.put(child.getClientId(),
- new Object[]{
- currentClientId,
- null,
- i,
- internalBuildTreeStructureToSave(child),
- child.processSaveState(context)});
- }
- else
+ UIComponent child = children.get(i);
+ if (child != null && !child.isTransient())
{
- saveStateOnMap( context, states, child);
+ if (child.getAttributes().containsKey(COMPONENT_ADDED_AFTER_BUILD_VIEW))
+ {
+ //Save all required info to restore the subtree.
+ //This includes position, structure and state of subtree
+ states.put(child.getClientId(),
+ new Object[]{
+ currentClientId,
+ null,
+ i,
+ internalBuildTreeStructureToSave(child),
+ child.processSaveState(context)});
+ }
+ else
+ {
+ saveStateOnMap( context, states, child);
+ }
}
}
}
- }
-
- //Scan facets
- Map<String, UIComponent> facetMap = component.getFacets();
- if (!facetMap.isEmpty())
- {
- String currentClientId = component.getClientId();
-
- for (Map.Entry<String, UIComponent> entry : facetMap.entrySet())
+
+ //Scan facets
+ Map<String, UIComponent> facetMap = component.getFacets();
+ if (!facetMap.isEmpty())
{
- UIComponent child = entry.getValue();
- if (child != null && !child.isTransient())
+ String currentClientId = component.getClientId();
+
+ for (Map.Entry<String, UIComponent> entry : facetMap.entrySet())
{
- String facetName = entry.getKey();
- if (child.getAttributes().containsKey(COMPONENT_ADDED_AFTER_BUILD_VIEW))
- {
- //Save all required info to restore the subtree.
- //This includes position, structure and state of subtree
- states.put(child.getClientId(), new Object[]{
- currentClientId,
- facetName,
- null,
- internalBuildTreeStructureToSave(child),
- child.processSaveState(context)});
- }
- else
+ UIComponent child = entry.getValue();
+ if (child != null && !child.isTransient())
{
- saveStateOnMap( context, states, child);
+ String facetName = entry.getKey();
+ if (child.getAttributes().containsKey(COMPONENT_ADDED_AFTER_BUILD_VIEW))
+ {
+ //Save all required info to restore the subtree.
+ //This includes position, structure and state of subtree
+ states.put(child.getClientId(), new Object[]{
+ currentClientId,
+ facetName,
+ null,
+ internalBuildTreeStructureToSave(child),
+ child.processSaveState(context)});
+ }
+ else
+ {
+ saveStateOnMap( context, states, child);
+ }
}
}
}
}
+ finally
+ {
+ component.popComponentFromEL(context);
+ }
}
public void suscribeListeners(UIViewRoot uiViewRoot)