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)