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 2010/01/31 01:18:54 UTC

svn commit: r904923 - in /myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior: BehaviorBase.java _AttachedDeltaWrapper.java _DeltaList.java

Author: lu4242
Date: Sun Jan 31 00:18:53 2010
New Revision: 904923

URL: http://svn.apache.org/viewvc?rev=904923&view=rev
Log:
MYFACES-2342 New objects added for new api in UIViewRoot, UIComponent and UIComponentBase could be saved and restored

Added:
    myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/_AttachedDeltaWrapper.java
    myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/_DeltaList.java
Modified:
    myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/BehaviorBase.java

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/BehaviorBase.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/BehaviorBase.java?rev=904923&r1=904922&r2=904923&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/BehaviorBase.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/BehaviorBase.java Sun Jan 31 00:18:53 2010
@@ -22,6 +22,7 @@
 import java.util.List;
 
 import javax.faces.component.PartialStateHolder;
+import javax.faces.component.StateHolder;
 import javax.faces.component.UIComponentBase;
 import javax.faces.context.FacesContext;
 import javax.faces.event.BehaviorEvent;
@@ -29,8 +30,6 @@
 
 /**
  * 
- * TODO: IMPLEMENT HERE - Delta state saving support
- * 
  * @author Simon Lessard (latest modification by $Author: slessard $)
  * @version $Revision: 696523 $ $Date: 2009-03-14 15:29:14 -0400 (mer., 17 sept. 2008) $
  *
@@ -99,12 +98,51 @@
 
     public void restoreState(FacesContext context, Object state)
     {
-        _behaviorListeners = (List<BehaviorListener>) UIComponentBase.restoreAttachedState(context, state);
+        if (state == null)
+        {
+            return;
+        }
+        else if (state instanceof _AttachedDeltaWrapper)
+        {
+            //Delta: check for null is not necessary since _behaviorListener field
+            //is only set once and never reset
+            //if (_behaviorListeners != null)
+            //{
+                ((StateHolder)_behaviorListeners).restoreState(context,
+                        ((_AttachedDeltaWrapper) state).getWrappedStateObject());
+            //}
+        }
+        else
+        {
+            //Full
+            _behaviorListeners = (_DeltaList<BehaviorListener>)
+                UIComponentBase.restoreAttachedState(context, state);
+        }
     }
 
     public Object saveState(FacesContext context)
     {
-        return UIComponentBase.saveAttachedState(context, _behaviorListeners);
+        return saveBehaviorListenersList(context);
+    }
+    
+    private Object saveBehaviorListenersList(FacesContext facesContext)
+    {
+        PartialStateHolder holder = (PartialStateHolder) _behaviorListeners;
+        if (initialStateMarked() && _behaviorListeners != null && holder.initialStateMarked())
+        {                
+            Object attachedState = holder.saveState(facesContext);
+            if (attachedState != null)
+            {
+                return new _AttachedDeltaWrapper(_behaviorListeners.getClass(),
+                        attachedState);
+            }
+            //_behaviorListeners instances once is created never changes, we can return null
+            return null;
+        }
+        else
+        {
+            return UIComponentBase.saveAttachedState(facesContext,_behaviorListeners);
+        }
     }
 
     public void setTransient(boolean newTransientValue)
@@ -122,7 +160,7 @@
         if (_behaviorListeners == null)
         {
             // Lazy instanciation
-            _behaviorListeners = new ArrayList<BehaviorListener>();
+            _behaviorListeners = new _DeltaList<BehaviorListener>(new ArrayList<BehaviorListener>());
         }
         
         _behaviorListeners.add(listener);

Added: myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/_AttachedDeltaWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/_AttachedDeltaWrapper.java?rev=904923&view=auto
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/_AttachedDeltaWrapper.java (added)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/_AttachedDeltaWrapper.java Sun Jan 31 00:18:53 2010
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package javax.faces.component.behavior;
+
+import java.io.Serializable;
+
+/**
+ * @author Leonardo Uribe (latest modification by $Author: lu4242 $)
+ * @version $Revision: 788877 $ $Date: 2009-06-26 16:30:38 -0500 (vie, 26 jun 2009) $
+ */
+class _AttachedDeltaWrapper implements Serializable
+{
+    private static final long serialVersionUID = 4732389964367986402L;
+
+    private Object _wrappedStateObject;
+
+    /**
+     * @param clazz
+     *            null means wrappedStateObject is a List of state objects
+     * @param wrappedStateObject
+     */
+    public _AttachedDeltaWrapper(Class<?> clazz, Object wrappedStateObject)
+    {
+        if (wrappedStateObject != null && !(wrappedStateObject instanceof Serializable))
+        {
+            throw new IllegalArgumentException("Attached state for Object of type " + clazz + " (Class "
+                    + wrappedStateObject.getClass().getName() + ") is not serializable");
+        }
+        _wrappedStateObject = wrappedStateObject;
+    }
+
+    public Object getWrappedStateObject()
+    {
+        return _wrappedStateObject;
+    }
+}

Added: myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/_DeltaList.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/_DeltaList.java?rev=904923&view=auto
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/_DeltaList.java (added)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/behavior/_DeltaList.java Sun Jan 31 00:18:53 2010
@@ -0,0 +1,349 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package javax.faces.component.behavior;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import javax.faces.component.PartialStateHolder;
+import javax.faces.component.StateHolder;
+import javax.faces.component.UIComponentBase;
+import javax.faces.context.FacesContext;
+
+/**
+ * This class handle deltas on facesListener and validatorList.
+ * 
+ * It is only used by this methods on UIComponentBase:
+ * 
+ * addFacesListener
+ * broadcast
+ * getFacesListeners
+ * removeFacesListener
+ * 
+ * A facesListener could hold PartialStateHolder instances, so it 
+ * is necessary to provide convenient methods to track deltas.
+ * 
+ * @author Leonardo Uribe (latest modification by $Author: lu4242 $)
+ * @version $Revision: 899525 $ $Date: 2010-01-14 23:53:46 -0500 (Jue, 14 Ene 2010) $
+ */
+class _DeltaList<T> implements List<T>, PartialStateHolder
+{
+
+    private List<T> _delegate;
+    private boolean _initialStateMarked;
+    
+    public _DeltaList()
+    {
+    }
+    
+    public _DeltaList(List<T> delegate)
+    {
+        _delegate = delegate;
+    }
+    
+    public void add(int index, T element)
+    {
+        clearInitialState();
+        _delegate.add(index, element);
+    }
+
+    public boolean add(T e)
+    {
+        clearInitialState();
+        return _delegate.add(e);
+    }
+
+    public boolean addAll(Collection<? extends T> c)
+    {
+        clearInitialState();
+        return _delegate.addAll(c);
+    }
+
+    public boolean addAll(int index, Collection<? extends T> c)
+    {
+        clearInitialState();
+        return _delegate.addAll(index, c);
+    }
+
+    public void clear()
+    {
+        clearInitialState();
+        _delegate.clear();
+    }
+
+    public boolean contains(Object o)
+    {
+        return _delegate.contains(o);
+    }
+
+    public boolean containsAll(Collection<?> c)
+    {
+        return _delegate.containsAll(c);
+    }
+
+    public boolean equals(Object o)
+    {
+        return _delegate.equals(o);
+    }
+
+    public T get(int index)
+    {
+        return _delegate.get(index);
+    }
+
+    public int hashCode()
+    {
+        return _delegate.hashCode();
+    }
+
+    public int indexOf(Object o)
+    {
+        return _delegate.indexOf(o);
+    }
+
+    public boolean isEmpty()
+    {
+        return _delegate.isEmpty();
+    }
+
+    public Iterator<T> iterator()
+    {
+        return _delegate.iterator();
+    }
+
+    public int lastIndexOf(Object o)
+    {
+        return _delegate.lastIndexOf(o);
+    }
+
+    public ListIterator<T> listIterator()
+    {
+        return _delegate.listIterator();
+    }
+
+    public ListIterator<T> listIterator(int index)
+    {
+        return _delegate.listIterator(index);
+    }
+
+    public T remove(int index)
+    {
+        clearInitialState();
+        return _delegate.remove(index);
+    }
+
+    public boolean remove(Object o)
+    {
+        clearInitialState();
+        return _delegate.remove(o);
+    }
+
+    public boolean removeAll(Collection<?> c)
+    {
+        clearInitialState();
+        return _delegate.removeAll(c);
+    }
+
+    public boolean retainAll(Collection<?> c)
+    {
+        return _delegate.retainAll(c);
+    }
+
+    public T set(int index, T element)
+    {
+        clearInitialState();
+        return _delegate.set(index, element);
+    }
+
+    public int size()
+    {
+        return _delegate == null ? 0 : _delegate.size();
+    }
+
+    public List<T> subList(int fromIndex, int toIndex)
+    {
+        return _delegate.subList(fromIndex, toIndex);
+    }
+
+    public Object[] toArray()
+    {
+        return _delegate.toArray();
+    }
+
+    public <T> T[] toArray(T[] a)
+    {
+        return _delegate.toArray(a);
+    }
+
+    public boolean isTransient()
+    {
+        return false;
+    }
+
+    public void setTransient(boolean newTransientValue)
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    public void restoreState(FacesContext context, Object state)
+    {
+        if (state == null)
+        {
+            return;
+        }
+        
+        if (initialStateMarked())
+        {            
+            //Restore delta
+            Object[] lst = (Object[]) state;
+            int j = 0;
+            int i = 0;
+            while (i < lst.length)
+            {
+                if (lst[i] instanceof _AttachedDeltaWrapper)
+                {
+                    //Delta
+                    ((StateHolder)_delegate.get(j)).restoreState(context, ((_AttachedDeltaWrapper) lst[i]).getWrappedStateObject());
+                    j++;
+                }
+                else if (lst[i] != null)
+                {
+                    //Full
+                    _delegate.set(j, (T) UIComponentBase.restoreAttachedState(context, lst[i]));
+                    j++;
+                }
+                else
+                {
+                    _delegate.remove(j);
+                }
+                i++;
+            }
+            if (i != j)
+            {
+                // StateHolder transient objects found, next time save and restore it fully
+                //because the size of the list changes.
+                clearInitialState();
+            }
+        }
+        else
+        {
+            //Restore delegate
+            Object[] lst = (Object[]) state;
+            _delegate = new ArrayList<T>(lst.length);
+            for (int i = 0; i < lst.length; i++)
+            {
+                T value = (T) UIComponentBase.restoreAttachedState(context, lst[i]);
+                if (value != null)
+                {
+                    _delegate.add(value);
+                }
+            }
+        }
+    }
+
+    public Object saveState(FacesContext context)
+    {
+        if (initialStateMarked())
+        {
+            Object [] lst = new Object[_delegate.size()];
+            boolean nullDelta = true;
+            for (int i = 0; i < _delegate.size(); i++)
+            {
+                Object value = _delegate.get(i);
+                if (value instanceof PartialStateHolder)
+                {
+                    //Delta
+                    PartialStateHolder holder = (PartialStateHolder) value;
+                    if (!holder.isTransient())
+                    {
+                        Object attachedState = holder.saveState(context);
+                        if (attachedState != null)
+                        {
+                            nullDelta = false;
+                        }
+                        lst[i] = new _AttachedDeltaWrapper(value.getClass(),
+                            attachedState);
+                    }
+                }
+                else
+                {
+                    //Full
+                    lst[i] = UIComponentBase.saveAttachedState(context, value);
+                    nullDelta = false;
+                }
+            }
+            if (nullDelta)
+            {
+                return null;
+            }
+            return lst;
+        }
+        else
+        {
+            Object [] lst = new Object[_delegate.size()];
+            for (int i = 0; i < _delegate.size(); i++)
+            {
+                lst[i] = UIComponentBase.saveAttachedState(context, _delegate.get(i));
+            }
+            return lst;
+        }
+    }
+
+    public void clearInitialState()
+    {
+        //Reset delta setting to null
+        if (_initialStateMarked)
+        {
+            _initialStateMarked = false;
+            if (_delegate != null)
+            {
+                for (T value : _delegate)
+                {
+                    if (value instanceof PartialStateHolder)
+                    {
+                        ((PartialStateHolder)value).clearInitialState();
+                    }
+                }
+            }
+        }
+    }
+
+    public boolean initialStateMarked()
+    {
+        return _initialStateMarked;
+    }
+
+    public void markInitialState()
+    {
+        _initialStateMarked = true;
+        if (_delegate != null)
+        {
+            for (T value : _delegate)
+            {
+                if (value instanceof PartialStateHolder)
+                {
+                    ((PartialStateHolder)value).markInitialState();
+                }
+            }
+        }
+    }
+}