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/06/23 03:36:37 UTC
svn commit: r787511 - in /myfaces/core/branches/2_0_0/api/src:
main/java/javax/faces/component/ test/java/javax/faces/component/
Author: lu4242
Date: Tue Jun 23 01:36:37 2009
New Revision: 787511
URL: http://svn.apache.org/viewvc?rev=787511&view=rev
Log:
MYFACES-2250 implement getStateHelper
Added:
myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/_AttachedDeltaWrapper.java (with props)
myfaces/core/branches/2_0_0/api/src/test/java/javax/faces/component/_Delta2StateHelperTest.java (with props)
Modified:
myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponentBase.java
myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/_DeltaStateHelper.java
myfaces/core/branches/2_0_0/api/src/test/java/javax/faces/component/_DeltaStateHelperTest.java
Modified: myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponentBase.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponentBase.java?rev=787511&r1=787510&r2=787511&view=diff
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponentBase.java (original)
+++ myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/UIComponentBase.java Tue Jun 23 01:36:37 2009
@@ -85,6 +85,7 @@
private String _id = null;
private UIComponent _parent = null;
private boolean _transient = false;
+ private boolean _initialStateMarked = false;
public UIComponentBase()
{
@@ -349,7 +350,7 @@
public void clearInitialState()
{
- // TODO: IMPLEMENT HERE
+ _initialStateMarked = false;
}
/**
@@ -876,7 +877,7 @@
{
// TODO: IMPLEMENT HERE
// FIXME: Nofity EG, this method should be in the specification
- return false;
+ return _initialStateMarked;
}
/**
@@ -907,7 +908,7 @@
public void markInitialState()
{
- // TODO: IMPLEMENT HERE
+ _initialStateMarked = true;
}
@Override
@@ -1348,17 +1349,9 @@
{
if (attachedObject == null)
return null;
- if (attachedObject instanceof List)
- {
- List<Object> lst = new ArrayList<Object>(((List<?>) attachedObject).size());
- for (Object item : (List<?>) attachedObject)
- {
- lst.add(saveAttachedState(context, item));
- }
-
- return new _AttachedListStateWrapper(lst);
- }
- else if (attachedObject instanceof StateHolder)
+ // StateHolder interface should take precedence over
+ // List children
+ if (attachedObject instanceof StateHolder)
{
StateHolder holder = (StateHolder) attachedObject;
if (holder.isTransient())
@@ -1367,6 +1360,16 @@
}
return new _AttachedStateWrapper(attachedObject.getClass(), holder.saveState(context));
+ }
+ else if (attachedObject instanceof List)
+ {
+ List<Object> lst = new ArrayList<Object>(((List<?>) attachedObject).size());
+ for (Object item : (List<?>) attachedObject)
+ {
+ lst.add(saveAttachedState(context, item));
+ }
+
+ return new _AttachedListStateWrapper(lst);
}
else if (attachedObject instanceof Serializable)
{
@@ -1434,7 +1437,7 @@
*/
public Object saveState(FacesContext context)
{
- Object values[] = new Object[7];
+ Object values[] = new Object[8];
values[0] = _id;
values[1] = _rendered;
values[2] = _rendererType;
@@ -1442,6 +1445,11 @@
values[4] = saveAttributesMap();
values[5] = saveAttachedState(context, _facesListeners);
values[6] = saveBindings(context);
+ StateHelper stateHelper = getStateHelper(false);
+ if (stateHelper != null)
+ {
+ values[7] = stateHelper.saveState(context);
+ }
return values;
}
@@ -1464,6 +1472,7 @@
restoreAttributesMap(values[4]);
_facesListeners = (List<FacesListener>) restoreAttachedState(context, values[5]);
restoreValueExpressionMap(context, values[6]);
+ getStateHelper().restoreState(context, values[7]);
}
private Object saveAttributesMap()
Added: myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/_AttachedDeltaWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/_AttachedDeltaWrapper.java?rev=787511&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/_AttachedDeltaWrapper.java (added)
+++ myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/_AttachedDeltaWrapper.java Tue Jun 23 01:36:37 2009
@@ -0,0 +1,58 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+
+/**
+ * @author Leonardo Uribe (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+class _AttachedDeltaWrapper implements Serializable
+{
+ private static final long serialVersionUID = 4732389964367986402L;
+ private Class<?> _class;
+ 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");
+ }
+ _class = clazz;
+ _wrappedStateObject = wrappedStateObject;
+ }
+
+ public Class<?> getClazz()
+ {
+ return _class;
+ }
+
+ public Object getWrappedStateObject()
+ {
+ return _wrappedStateObject;
+ }
+}
Propchange: myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/_AttachedDeltaWrapper.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/_AttachedDeltaWrapper.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Modified: myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/_DeltaStateHelper.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/_DeltaStateHelper.java?rev=787511&r1=787510&r2=787511&view=diff
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/_DeltaStateHelper.java (original)
+++ myfaces/core/branches/2_0_0/api/src/main/java/javax/faces/component/_DeltaStateHelper.java Tue Jun 23 01:36:37 2009
@@ -22,136 +22,233 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Set;
+
import javax.el.ValueExpression;
import javax.faces.context.FacesContext;
/**
- * A delta enabled state holder implementing the StateHolder Interface
- *
- * components implementing the PartalStateHolder interface have an initial state
+ * A delta enabled state holder implementing the StateHolder Interface.
+ * <p>
+ * Components implementing the PartalStateHolder interface have an initial state
* and delta states, the initial state is the one holding all root values
* and deltas store differences to the initial states
- *
- * for components not implementing partial state saving only the initial states are
+ * </p>
+ * <p>
+ * For components not implementing partial state saving only the initial states are
* of importance, everything is stored and restored continously there
- *
- * The state helper seems to have three internal storage mechanisms
- * one being a list which stores plain values
+ * </p>
+ * <p>
+ * The state helper seems to have three internal storage mechanisms:
+ * one being a list which stores plain values,
* one being a key value pair which stores key values in maps
* add serves the plain list type while put serves the
- * key value type
- *
+ * key value type,
* the third is the value which has to be stored plainly as is!
+ * </p>
+ * In other words, this map can be seen as a composite map. It has two maps:
+ * initial state map and delta map.
+ * <p>
+ * If delta map is used (method component.initialStateMarked() ),
+ * base or initial state map cannot be changed, since all changes
+ * should be tracked on delta map.
+ * </p>
+ * <p>
+ * The intention of this class is just hold property values
+ * and do a clean separation between initial state and delta.
+ * </p>
+ * <p>
+ * The code from this class comes from a refactor of
+ * org.apache.myfaces.trinidad.bean.util.PropertyHashMap
+ * </p>
+ * <p>
+ * The context from this class comes and that should be taken into account
+ * is this:
+ * </p>
+ * <p>
+ * First request:
+ * </p>
+ * <ul>
+ * <li> A new template is created (using
+ * javax.faces.view.ViewDeclarationLanguage.buildView method)
+ * and component.markInitialState is called from its related TagHandler classes
+ * (see javax.faces.view.facelets.ComponentHandler ).
+ * When this method is executed, the component tree was populated from the values
+ * set in the facelet abstract syntax tree (or in other words composition of
+ * facelets templates). </li>
+ * <li> From this point all updates on the variables are considered "delta". </li>
+ * <li> SaveState, if initialStateMarked is true, only delta is saved. </li>
+ * </ul>
+ * <p>
+ * Second request (and next ones)
+ * </p>
+ * <ul>
+ * <li> A new template is created and component.markInitialState is called from
+ * its related TagHandler classes again. In this way, components like c:forEach
+ * or c:if, that add or remove components could notify about this and handle
+ * them properly (see javax.faces.view.StateManagementStrategy). Note that a
+ * component restored using this method is no different as the same component
+ * at the first request at the same time. </li>
+ * <li> A call for restoreState is done, passing the delta as object value. If no
+ * delta, the state is complete and no call is triggered. </li>
+ * <li> Lifecycle occur, changing the necessary stuff. </li>
+ * <li> SaveState, if initialStateMarked is true, only delta is saved. </li>
+ * </ul>
+ * <p>
+ * From the previous analysis, the following conclusions arise:
+ * <ul>
+ * <li>This class only needs to keep track of delta changes, so when
+ * restoreState/saveState is called, the right objects are passed.</li>
+ * <li>UIComponent.clearInitialState is used to reset the partial
+ * state holder to a non delta state, so the state to be saved by
+ * saveState is no longer a delta instead is a full state. If a call
+ * to clearInitialState occur it is not expected a call for
+ * UIComponent.markInitialState occur on the current request.</li>
+ * <li>The state is handled in the same way on UIData, so components
+ * inside UIData share its state on all rows. There is no way to save
+ * delta per row.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * NOTE: The current implementation of StateHelper on RI does not handle
+ * stateHolder values internally. To prevent problems when developers create
+ * custom components we should do this too. But anyway, the code that
+ * handle this case should be let here as comment, if some day this feature
+ * is provided. Note than stateHolder aware properties like converter,
+ * validator or listeners should deal with StateHolder or PartialStateHolder
+ * on component classes.
+ *
+ * </p>
*
- *
- * The flow probably goes following
- * restore -> restore initial state done from the outside
- * switch component to -> initialState = true
- * store the deltas as well!
- *
- * the main save and restore works only on the deltas
- * as far as it seems!
- *
- * we are keeping two states the full state and the delta state
- * the full state must access all values, full + delta
- * and the delta state should keep the states only if initialState is set
- *
- * @author Werner Punz (latest modification by $Author$)
+ * @author Werner Punz
+ * @author Leonardo Uribe (latest modification by $Author$)
* @version $Rev$ $Date$
*/
public class _DeltaStateHelper implements StateHelper
{
- UIComponent _component = null;
- Map<Serializable, Object> _fullState = null;
- Map<Serializable, Object> _deltas = null;
- Set<Object> _deleted = null;
- boolean _transient = false;
- static final String INTERNAL_MAP_KEY = "_MYFACES._IMAP";
- static final String INTERNAL_LIST_KEY = "_MYFACES._ILIST";
- static final String INTERNAL_DELETED_KEY = "_MYFACES._DELETED";
+ /**
+ * We need to hold a component instance because:
+ *
+ * - The component is the one who knows if we are on initial or delta mode
+ * - eval assume calls to component.ValueExpression
+ */
+ private UIComponent _component;
+
+ /**
+ * This map holds the full current state
+ */
+ private Map<Serializable, Object> _fullState;
+
+ /**
+ * This map only keep track of delta changes to be saved
+ */
+ private Map<Serializable, Object> _deltas;
+
+ /**
+ * This map keep track of StateHolder keys, to be saved when
+ * saveState is called.
+ */
+ //private Set<Serializable> _stateHolderKeys;
+
+ private boolean _transient = false;
public _DeltaStateHelper(UIComponent component)
{
+ super();
this._component = component;
_fullState = new HashMap<Serializable, Object>();
- //we only can store the deltas if the component is instance of partial state holder
- //but as it seems the latest specs already have enforced PartialStateHolder on UIComponent
- //initialStateMarked is responsible for determination if we have partial saving
-
- _deltas = new HashMap<Serializable, Object>();
- _transient = (component != null) ? component.isTransient() : true;
+ _deltas = null;
+ //_stateHolderKeys = new HashSet<Serializable>();
}
+ /**
+ * Used to create delta map on demand
+ *
+ * @return
+ */
+ private boolean _createDeltas()
+ {
+ if (isInitalStateMarked())
+ {
+ if (_deltas == null)
+ {
+ _deltas = new HashMap<Serializable, Object>(2);
+ }
+ return true;
+ }
+
+ return false;
+ }
+
protected boolean isInitalStateMarked()
{
return _component.initialStateMarked();
}
- /**
- * stores the object in an internal list if not present in the detal map
- */
@Override
public void add(Serializable key, Object value)
{
- if (_deleted != null)
- {
- _deleted.remove(key);
- }
- if (isInitalStateMarked())
+ if (_createDeltas())
{
-
- List<Object> deltaStorageList = (List) _deltas.get(key);
- if (deltaStorageList == null)
+ //Track delta case
+ Map<Object, Boolean> deltaListMapValues = (Map<Object, Boolean>) _deltas
+ .get(key);
+ if (deltaListMapValues == null)
{
- deltaStorageList = new InternalList(3);
+ deltaListMapValues = new InternalDeltaListMap<Object, Boolean>(
+ 3);
+ _deltas.put(key, deltaListMapValues);
}
- deltaStorageList.add(value);
- _deltas.put(key, deltaStorageList);
-
+ deltaListMapValues.put(value, Boolean.TRUE);
}
- List<Object> fullStorageList = (List) _fullState.get(key);
- if (fullStorageList == null)
+
+ //Handle change on full map
+ List<Object> fullListValues = (List<Object>) _fullState.get(key);
+ if (fullListValues == null)
{
- fullStorageList = new InternalList(3);
+ fullListValues = new InternalList<Object>(3);
+ _fullState.put(key, fullListValues);
}
- fullStorageList.add(value);
- _fullState.put(key, fullStorageList);
+ fullListValues.add(value);
}
@Override
public Object eval(Serializable key)
{
- return eval(key, null);
+ Object returnValue = _fullState.get(key);
+ if (returnValue != null)
+ {
+ return returnValue;
+ }
+ ValueExpression expression = _component.getValueExpression(key
+ .toString());
+ if (expression != null)
+ {
+ return expression.getValue(_component.getFacesContext()
+ .getELContext());
+ }
+ return null;
}
@Override
- /**
- * returns a given value or the result of a value expression
- * @param key the key or value expression to be evaluated
- * @return the result of the eval or the default value if
- * the value is not present in our states
- */
public Object eval(Serializable key, Object defaultValue)
{
- Object retVal = get(key);
- if (retVal != null)
+ Object returnValue = _fullState.get(key);
+ if (returnValue != null)
{
- return retVal;
+ return returnValue;
}
- //not found lets do the eval of a possible value expression
- ValueExpression expr = _component.getValueExpression(key.toString());
- if (expr == null)
+ ValueExpression expression = _component.getValueExpression(key
+ .toString());
+ if (expression != null)
{
- return defaultValue;
+ return expression.getValue(_component.getFacesContext()
+ .getELContext());
}
- retVal = expr.getValue(_component.getFacesContext().getELContext());
- return (retVal == null) ? defaultValue : retVal;
+ return defaultValue;
}
@Override
@@ -161,110 +258,224 @@
}
@Override
- /**
- * puts an object into the data structures with a given key
- *
- * @param key the key for the mapping
- * @param value the value to be stored
- * @returns the old value if present
- */
public Object put(Serializable key, Object value)
{
- if (_deleted != null)
+ Object returnValue = null;
+ if (_createDeltas())
{
- _deleted.remove(key);
+ if (_deltas.containsKey(key))
+ {
+ returnValue = _deltas.put(key, value);
+ _fullState.put(key, value);
+ }
+ else
+ {
+ _deltas.put(key, value);
+ returnValue = _fullState.put(key, value);
+ }
}
- if (isInitalStateMarked())
+ else
{
- //delta tracking is on
- Object oldValue = _deltas.put(key, value);
- if (oldValue == null)
+ /*
+ if (value instanceof StateHolder)
{
- oldValue = _fullState.put(key, value);
+ _stateHolderKeys.add(key);
}
- return oldValue;
+ */
+ returnValue = _fullState.put(key, value);
}
-
- return _fullState.put(key, value);
+ return returnValue;
}
- /**
- * puts a value into the internal data structures and the value has to be map
- * mapped via mapkey,
- * @param key the key for the mapping
- * @param mapKey the internal map key for the mapping
- * @returns the old value of key->mapKey if present!
- */
@Override
public Object put(Serializable key, String mapKey, Object value)
{
- Object oldValue = null;
- if (_deleted != null)
- {
- _deleted.remove(key);
- }
- if (isInitalStateMarked())
- {
- oldValue = _putMap(_deltas, key, mapKey, value);
- if (oldValue == null)
+ boolean returnSet = false;
+ Object returnValue = null;
+ if (_createDeltas())
+ {
+ //Track delta case
+ Map<String, Object> mapValues = (Map<String, Object>) _deltas
+ .get(key);
+ if (mapValues == null)
{
- oldValue = _putMap(_fullState, key, mapKey, value);
-
+ mapValues = new InternalMap<String, Object>();
+ _deltas.put(key, mapValues);
+ }
+ if (mapValues.containsKey(mapKey))
+ {
+ returnValue = mapValues.put(mapKey, value);
+ returnSet = true;
+ }
+ else
+ {
+ mapValues.put(mapKey, value);
}
- return oldValue;
}
- //either no initial state or no delta state saving
- return _putMap(_fullState, key, mapKey, value);
+ //Handle change on full map
+ Map<String, Object> mapValues = (Map<String, Object>) _fullState
+ .get(key);
+ if (mapValues == null)
+ {
+ mapValues = new InternalMap<String, Object>();
+ _fullState.put(key, mapValues);
+ }
+ if (returnSet)
+ {
+ mapValues.put(mapKey, value);
+ }
+ else
+ {
+ returnValue = mapValues.put(mapKey, value);
+ }
+ return returnValue;
}
@Override
public Object remove(Serializable key)
{
- Object deltaRetVal = _deltas.remove(key);
- Object initRetVal = _fullState.remove(key);
- //delta if given is always newer than init!
- if (_deleted == null)
+ Object returnValue = null;
+ if (_createDeltas())
{
- _deleted = new HashSet<Object>();
+ if (_deltas.containsKey(key))
+ {
+ // Keep track of the removed values using key/null pair on the delta map
+ returnValue = _deltas.put(key, null);
+ _fullState.remove(key);
+ }
+ else
+ {
+ // Keep track of the removed values using key/null pair on the delta map
+ _deltas.put(key, null);
+ returnValue = _fullState.remove(key);
+ }
+ }
+ else
+ {
+ returnValue = _fullState.remove(key);
}
- _deleted.add(key);
- return (deltaRetVal != null) ? deltaRetVal : initRetVal;
+ return returnValue;
}
@Override
public Object remove(Serializable key, Object valueOrKey)
{
- Object deltaDS = _deltas.get(key);
- Object initDS = _fullState.get(key);
-
- Object deltaRetVal = null;
- Object initRetVal = null;
+ // Comment by lu4242 : The spec javadoc says if it is a Collection
+ // or Map deal with it. But the intention of this method is work
+ // with add(?,?) and put(?,?,?), this ones return instances of
+ // InternalMap and InternalList to prevent mixing, so to be
+ // consistent we'll cast to those classes here.
+
+ Object collectionOrMap = _fullState.get(key);
+ Object returnValue = null;
+ if (collectionOrMap instanceof InternalMap)
+ {
+ if (_createDeltas())
+ {
+ returnValue = _removeValueOrKeyFromMap(_deltas, key,
+ valueOrKey, true);
+ _removeValueOrKeyFromMap(_fullState, key, valueOrKey, false);
+ }
+ else
+ {
+ returnValue = _removeValueOrKeyFromMap(_fullState, key,
+ valueOrKey, false);
+ }
+ }
+ else if (collectionOrMap instanceof InternalList)
+ {
+ if (_createDeltas())
+ {
+ returnValue = _removeValueOrKeyFromCollectionDelta(_deltas,
+ key, valueOrKey);
+ _removeValueOrKeyFromCollection(_fullState, key, valueOrKey);
+ }
+ else
+ {
+ returnValue = _removeValueOrKeyFromCollection(_fullState, key,
+ valueOrKey);
+ }
+ }
+ return returnValue;
+ }
- if (deltaDS != null)
+ private static Object _removeValueOrKeyFromCollectionDelta(
+ Map<Serializable, Object> stateMap, Serializable key,
+ Object valueOrKey)
+ {
+ Object returnValue = null;
+ Map<Object, Boolean> c = (Map<Object, Boolean>) stateMap.get(key);
+ if (c != null)
{
- deltaRetVal = _removeFromCollection(_deltas, key, deltaDS,
- valueOrKey);
+ if (c.containsKey(valueOrKey))
+ {
+ returnValue = valueOrKey;
+ }
+ c.put(valueOrKey, Boolean.FALSE);
}
- if (initDS != null)
+ return returnValue;
+ }
+
+ private static Object _removeValueOrKeyFromCollection(
+ Map<Serializable, Object> stateMap, Serializable key,
+ Object valueOrKey)
+ {
+ Object returnValue = null;
+ Collection c = (Collection) stateMap.get(key);
+ if (c != null)
{
- initRetVal = _removeFromCollection(_fullState, key, initDS,
- valueOrKey);
+ if (c.remove(valueOrKey))
+ {
+ returnValue = valueOrKey;
+ }
+ if (c.isEmpty())
+ {
+ stateMap.remove(key);
+ }
}
+ return returnValue;
+ }
- if (_deleted == null)
+ private static Object _removeValueOrKeyFromMap(
+ Map<Serializable, Object> stateMap, Serializable key,
+ Object valueOrKey, boolean delta)
+ {
+ if (valueOrKey == null)
{
- _deleted = new HashSet<Object>();
+ return null;
}
- if (!_deltas.containsKey(key))
+ Object returnValue = null;
+ Map<String, Object> map = (Map<String, Object>) stateMap.get(key);
+ if (map != null)
{
- _deleted.add(key);
+ if (delta)
+ {
+ // Keep track of the removed values using key/null pair on the delta map
+ returnValue = map.put((String) valueOrKey, null);
+ }
+ else
+ {
+ returnValue = map.remove(valueOrKey);
+ }
+
+ if (map.isEmpty())
+ {
+ //stateMap.remove(key);
+ stateMap.put(key, null);
+ }
}
- return (deltaRetVal != null) ? deltaRetVal : initRetVal;
+ return returnValue;
}
- /*
+ @Override
+ public boolean isTransient()
+ {
+ return _transient;
+ }
+
+ /**
* Serializing cod
* the serialized data structure consists of key value pairs unless the value itself is an internal array
* or a map in case of an internal array or map the value itself is another array with its initial value
@@ -280,12 +491,30 @@
public Object saveState(FacesContext context)
{
Map serializableMap = (isInitalStateMarked()) ? _deltas : _fullState;
- Set<Object> deltaDeleted = (isInitalStateMarked()) ? _deleted : null;
+ if (serializableMap == null || serializableMap.size() == 0)
+ {
+ return null;
+ }
+
+ /*
+ int stateHolderKeyCount = 0;
+ if (isInitalStateMarked())
+ {
+ for (Iterator<Serializable> it = _stateHolderKeys.iterator(); it.hasNext();)
+ {
+ Serializable key = it.next();
+ if (!_deltas.containsKey(key))
+ {
+ stateHolderKeyCount++;
+ }
+ }
+ }*/
+
Map.Entry<Serializable, Object> entry;
//entry == key, value, key, value
- Object[] retArr = new Object[serializableMap.entrySet().size() * 2
- + ((_deleted != null && _deleted.size() > 0) ? 2 : 0)];
+ Object[] retArr = new Object[serializableMap.entrySet().size() * 2];
+ //Object[] retArr = new Object[serializableMap.entrySet().size() * 2 + stateHolderKeyCount];
Iterator<Map.Entry<Serializable, Object>> it = serializableMap
.entrySet().iterator();
@@ -294,216 +523,293 @@
{
entry = it.next();
retArr[cnt] = entry.getKey();
- if (entry instanceof InternalList)
- {
- //TODO add list serialisation code
- retArr[cnt + 1] = serializeOneDimDS((InternalList) entry);
- }
- else if (entry instanceof InternalMap)
- {
- //TODO add map serialisation code here
- retArr[cnt + 1] = serializeInternalMap((InternalMap) entry);
+
+ Object value = entry.getValue();
+
+ // The condition in which the call to saveAttachedState
+ // is to handle List, StateHolder or non Serializable instances.
+ // we check it here, to prevent unnecessary calls.
+ if (value instanceof StateHolder ||
+ value instanceof List ||
+ !(value instanceof Serializable))
+ {
+ Object savedValue = UIComponentBase.saveAttachedState(context,
+ value);
+ retArr[cnt + 1] = savedValue;
}
else
{
-
- retArr[cnt + 1] = (Serializable) entry.getValue();
+ retArr[cnt + 1] = value;
}
cnt += 2;
-
}
-
- //we now store the deleted deltas as well, we cannot handle deleted in our map alone!
- if (deltaDeleted != null && deltaDeleted.size() > 0)
+
+ /*
+ if (isInitalStateMarked())
{
- Object[] serializedDeletes = serializeOneDimDS(_deleted);
- retArr[cnt] = INTERNAL_DELETED_KEY;
- retArr[cnt + 1] = serializedDeletes;
+ for (Iterator<Serializable> it2 = _stateHolderKeys.iterator(); it.hasNext();)
+ {
+ Serializable key = it2.next();
+ if (!_deltas.containsKey(key))
+ {
+ retArr[cnt] = key;
+ Object value = _fullState.get(key);
+ if (value instanceof PartialStateHolder)
+ {
+ //Could contain delta, save it as _AttachedDeltaState
+ PartialStateHolder holder = (PartialStateHolder) value;
+ if (holder.isTransient())
+ {
+ retArr[cnt + 1] = null;
+ }
+ else
+ {
+ retArr[cnt + 1] = new _AttachedDeltaWrapper(value.getClass(), holder.saveState(context));
+ }
+ }
+ else
+ {
+ //Save everything
+ retArr[cnt + 1] = UIComponentBase.saveAttachedState(context, _fullState.get(key));
+ }
+ cnt += 2;
+ }
+ }
}
+ */
return retArr;
}
- /**
- * serializes a one dimensional data structure (array, list, set)
- *
- * @param entry the one dimensional collection to be serialized
- * @return an array representation of the collection with two entries
- * the first entry an identifier key and the second entry an array
- * of elements which represent our collection
- */
- private Object[] serializeOneDimDS(Collection<Object> entry)
- {
- Object[] retVal = new Object[2]; //array with two elements one the marker second the array
- retVal[0] = _DeltaStateHelper.INTERNAL_LIST_KEY;
- retVal[1] = entry.toArray(new Object[entry.size()]);
-
- return retVal;
- }
-
- private void deserializeOneDimDS(Object param, Collection target)
- {
- Object[] saveState = (Object[]) param;
- //first element list marker, already processed!
- Object[] listAsArr = (Object[]) saveState[1];
-
- //since all other options would mean dual iteration we have to do it the hard way
- for (Object elem : listAsArr)
- {
- target.add(elem);
- }
-
- }
-
- private InternalMap deserializeInternalMap(Object param)
- {
- Object[] saveState = (Object[]) param;
- Object[] listAsMap = (Object[]) saveState[1];
-
- InternalMap retVal = new InternalMap(listAsMap.length / 2);
- for (int cnt = 0; cnt < listAsMap.length; cnt += 2)
- {
- retVal.put((String) listAsMap[cnt], listAsMap[cnt + 1]);
- }
- return retVal;
- }
-
- private Object[] serializeInternalMap(Map<String, Object> map)
- {
- Object[] retVal = new Object[2];
- retVal[0] = _DeltaStateHelper.INTERNAL_MAP_KEY;
-
- int cnt = 0;
- Object[] mapArr = new Object[map.size()];
- retVal[1] = mapArr;
- for (Map.Entry<String, Object> entry : map.entrySet())
- {
- mapArr[cnt] = entry.getKey();
- mapArr[cnt + 1] = entry.getValue();
- cnt += 2;
- }
- return retVal;
- }
-
@Override
public void restoreState(FacesContext context, Object state)
{
+ if (state == null)
+ return;
+
Object[] serializedState = (Object[]) state;
for (int cnt = 0; cnt < serializedState.length; cnt += 2)
{
Serializable key = (Serializable) serializedState[cnt];
- Object value = serializedState[cnt + 1];
+ Object savedValue = UIComponentBase.restoreAttachedState(context,
+ serializedState[cnt + 1]);
- if (key instanceof String
- && ((String) key).equals(INTERNAL_DELETED_KEY))
+ if (isInitalStateMarked())
{
- _deleted = new HashSet<Object>();
- deserializeOneDimDS(value, _deleted);
- }
- else if (value instanceof String
- && ((String) value).equals(INTERNAL_LIST_KEY))
- {
- Object[] valArr = (Object[]) ((Object[]) value)[1];
- InternalList target = new InternalList(valArr.length * 2);
- deserializeOneDimDS(value, target);
- put(key, target);
+ if (savedValue instanceof InternalDeltaListMap)
+ {
+ for (Map.Entry<Object, Boolean> mapEntry : ((Map<Object, Boolean>) savedValue)
+ .entrySet())
+ {
+ boolean addOrRemove = mapEntry.getValue();
+ if (addOrRemove)
+ {
+ //add
+ this.add(key, mapEntry.getKey());
+ }
+ else
+ {
+ //remove
+ this.remove(key, mapEntry.getKey());
+ }
+ }
+ }
+ else if (savedValue instanceof InternalMap)
+ {
+ for (Map.Entry<String, Object> mapEntry : ((Map<String, Object>) savedValue)
+ .entrySet())
+ {
+ this.put(key, mapEntry.getKey(), mapEntry.getValue());
+ }
+ }
+ /*
+ else if (savedValue instanceof _AttachedDeltaWrapper)
+ {
+ _AttachedStateWrapper wrapper = (_AttachedStateWrapper) savedValue;
+ //Restore delta state
+ ((PartialStateHolder)_fullState.get(key)).restoreState(context, wrapper.getWrappedStateObject());
+ //Add this key as StateHolder key
+ _stateHolderKeys.add(key);
+ }
+ */
+ else
+ {
+ put(key, savedValue);
+ }
}
- else if (value instanceof String
- && ((String) value).equals(INTERNAL_MAP_KEY))
+ else
{
- value = deserializeInternalMap(value);
- put(key, value);
+ put(key, savedValue);
}
}
}
@Override
- public boolean isTransient()
+ public void setTransient(boolean transientValue)
{
- return _transient;
+ _transient = transientValue;
}
- @Override
- public void setTransient(boolean newTransientValue)
+ //We use our own data structures just to make sure
+ //nothing gets mixed up internally
+ static class InternalMap<K, V> extends HashMap<K, V> implements StateHolder
{
- _transient = newTransientValue;
- }
+ public InternalMap()
+ {
+ super();
+ }
- private Object _putMap(Map rootMap, Serializable key, String mapKey,
- Object value)
- {
- Object oldValue = rootMap.get(key);
- //if no delta is found we add it to both DS
- if (oldValue == null)
+ public InternalMap(int initialCapacity, float loadFactor)
{
- Map storageMap = new InternalMap(3);
- storageMap.put(mapKey, value);
- return rootMap.put(key, storageMap);
+ super(initialCapacity, loadFactor);
}
- else
+
+ public InternalMap(Map<? extends K, ? extends V> m)
{
- return ((Map) oldValue).put(mapKey, value);
+ super(m);
}
- }
- private Object _removeFromCollection(Map initialMap, Serializable key,
- Object dataStructure, Object valueOrKey)
- {
- Object retVal = null;
- if (dataStructure != null)
+ public InternalMap(int initialSize)
{
- if (dataStructure instanceof InternalList)
- {
- retVal = ((InternalList) dataStructure).remove(valueOrKey);
- if (((Collection) dataStructure).isEmpty())
- {
- initialMap.remove(key);
- if (_deleted == null)
- {
- _deleted = new HashSet<Object>();
- }
- _deleted.add(key);
+ super(initialSize);
+ }
- }
+ @Override
+ public boolean isTransient()
+ {
+ return false;
+ }
+
+ @Override
+ public void setTransient(boolean newTransientValue)
+ {
+ // No op
+ }
+
+ @Override
+ public void restoreState(FacesContext context, Object state)
+ {
+ Object[] listAsMap = (Object[]) state;
+ for (int cnt = 0; cnt < listAsMap.length; cnt += 2)
+ {
+ this.put((K) listAsMap[cnt], (V) UIComponentBase
+ .restoreAttachedState(context, listAsMap[cnt + 1]));
}
- else if (dataStructure instanceof InternalMap)
+ }
+
+ @Override
+ public Object saveState(FacesContext context)
+ {
+ int cnt = 0;
+ Object[] mapArr = new Object[this.size() * 2];
+ for (Map.Entry<K, V> entry : this.entrySet())
{
- retVal = ((InternalMap) dataStructure).remove(valueOrKey);
- if (((InternalMap) dataStructure).isEmpty())
+ mapArr[cnt] = entry.getKey();
+ Object value = entry.getValue();
+
+ if (value instanceof StateHolder ||
+ value instanceof List ||
+ !(value instanceof Serializable))
{
- initialMap.remove(key);
- if (_deleted == null)
- {
- _deleted = new HashSet<Object>();
- }
- _deleted.add(key);
+ mapArr[cnt + 1] = UIComponentBase.saveAttachedState(context, value);
}
+ else
+ {
+ mapArr[cnt + 1] = value;
+ }
+ cnt += 2;
}
- else
- {
- retVal = dataStructure;
- }
+ return mapArr;
}
- return retVal;
}
- //We use our own data structures just to make sure
- //nothing gets mixed up internally
- class InternalMap extends HashMap
+ /**
+ * Map used to keep track of list changes
+ */
+ static class InternalDeltaListMap<K, V> extends InternalMap<K, V>
{
- public InternalMap(int initialSize)
+ public InternalDeltaListMap()
+ {
+ super();
+ }
+
+ public InternalDeltaListMap(int initialCapacity, float loadFactor)
+ {
+ super(initialCapacity, loadFactor);
+ }
+
+ public InternalDeltaListMap(int initialSize)
{
super(initialSize);
}
+
+ public InternalDeltaListMap(Map<? extends K, ? extends V> m)
+ {
+ super(m);
+ }
}
- class InternalList extends ArrayList
+ static class InternalList<T> extends ArrayList<T> implements StateHolder
{
+ public InternalList()
+ {
+ super();
+ }
+
+ public InternalList(Collection<? extends T> c)
+ {
+ super(c);
+ }
public InternalList(int initialSize)
{
super(initialSize);
}
+
+ @Override
+ public boolean isTransient()
+ {
+ return false;
+ }
+
+ @Override
+ public void setTransient(boolean newTransientValue)
+ {
+ }
+
+ @Override
+ public void restoreState(FacesContext context, Object state)
+ {
+ Object[] listAsArr = (Object[]) state;
+ //since all other options would mean dual iteration
+ //we have to do it the hard way
+ for (Object elem : listAsArr)
+ {
+ add((T) UIComponentBase.restoreAttachedState(context, elem));
+ }
+ }
+
+ @Override
+ public Object saveState(FacesContext context)
+ {
+ Object[] values = new Object[size()];
+ for (int i = 0; i < size(); i++)
+ {
+ Object value = get(i);
+
+ if (value instanceof StateHolder ||
+ value instanceof List ||
+ !(value instanceof Serializable))
+ {
+ values[i] = UIComponentBase.saveAttachedState(context, value);
+ }
+ else
+ {
+ values[i] = value;
+ }
+ }
+ return values;
+ }
}
}
Added: myfaces/core/branches/2_0_0/api/src/test/java/javax/faces/component/_Delta2StateHelperTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/test/java/javax/faces/component/_Delta2StateHelperTest.java?rev=787511&view=auto
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/test/java/javax/faces/component/_Delta2StateHelperTest.java (added)
+++ myfaces/core/branches/2_0_0/api/src/test/java/javax/faces/component/_Delta2StateHelperTest.java Tue Jun 23 01:36:37 2009
@@ -0,0 +1,484 @@
+/*
+ * 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;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.context.FacesContext;
+
+
+public class _Delta2StateHelperTest extends AbstractComponentTest
+{
+
+ public _Delta2StateHelperTest(String name)
+ {
+ super(name);
+ }
+
+ public static class UITestComponent extends UIComponentBase
+ {
+ public UITestComponent()
+ {
+ super();
+ }
+
+ @Override
+ public String getFamily()
+ {
+ return "javax.faces.Test";
+ }
+
+ private enum PropertyKeys
+ {
+ testProperty1,
+ testProperty2
+ }
+
+ public String getTestProperty1()
+ {
+ return (String) getStateHelper().eval(PropertyKeys.testProperty1);
+ }
+
+ public void setTestProperty1(String testProperty1)
+ {
+ getStateHelper().put(PropertyKeys.testProperty1, testProperty1);
+ }
+
+ public String getTestProperty2()
+ {
+ return (String) getStateHelper().eval(PropertyKeys.testProperty2);
+ }
+
+ public void setTestProperty2(String testProperty2)
+ {
+ getStateHelper().put(PropertyKeys.testProperty2, testProperty2);
+ }
+
+ /*
+ private StateHelper _stateHelper = null;
+
+ public StateHelper getStateHelper(boolean create) {
+
+ if (create && _stateHelper == null)
+ {
+ _stateHelper = new _DeltaStateHelper(this);
+ }
+ return _stateHelper;
+ }
+ */
+
+ public StateHelper getStateHelper()
+ {
+ return super.getStateHelper();
+ }
+
+ @Override
+ public void restoreState(FacesContext context, Object state)
+ {
+ Object[] values = (Object[]) state;
+ super.restoreState(context, values[0]);
+ //getStateHelper().restoreState(context, values[1]);
+ }
+
+ @Override
+ public Object saveState(FacesContext context)
+ {
+ Object[] values = new Object[2];
+ values[0] = super.saveState(context);
+ //values[1] = _stateHelper == null ? null : _stateHelper.saveState(context);
+ return values;
+ }
+ }
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ super.tearDown();
+ }
+
+ public void testSimpleGetterSetter() throws Exception
+ {
+ UITestComponent a = new UITestComponent();
+ assertNull(a.getTestProperty1());
+ a.setTestProperty1("testProperty1");
+ assertEquals("testProperty1", a.getTestProperty1());
+ a.setTestProperty1(null);
+ assertNull(a.getTestProperty1());
+ }
+
+ public void testEmptySaveRestore() throws Exception
+ {
+ UITestComponent a = new UITestComponent();
+ UITestComponent b = new UITestComponent();
+
+ Object state1 = (Object) a.saveState(facesContext);
+
+ b.restoreState(facesContext, state1);
+
+ Object state2 = b.saveState(facesContext);
+
+ assertEquals(a.getTestProperty1(), b.getTestProperty1());
+ assertEquals(a.getTestProperty2(), b.getTestProperty2());
+ }
+
+ public void testSimpleSaveRestore() throws Exception
+ {
+ UITestComponent a = new UITestComponent();
+ UITestComponent b = new UITestComponent();
+
+ a.setTestProperty1("testProperty1");
+ a.setTestProperty2(null);
+ Object state1 = (Object) a.saveState(facesContext);
+
+ b.restoreState(facesContext, state1);
+
+ Object state2 = b.saveState(facesContext);
+
+ assertEquals(a.getTestProperty1(), b.getTestProperty1());
+ assertEquals(a.getTestProperty2(), b.getTestProperty2());
+ }
+
+ public void testDeltaStateSaveRestore()
+ {
+ UITestComponent a = new UITestComponent();
+ UITestComponent b = new UITestComponent();
+
+ a.setTestProperty1("testProperty1");
+ a.setTestProperty2(null);
+
+ //Replicate the stuff to reach template status
+ b.setTestProperty1("testProperty1");
+ b.setTestProperty2(null);
+
+ a.markInitialState();
+ b.markInitialState();
+
+ a.setTestProperty2("testProperty2");
+ a.setTestProperty1(null);
+
+ Object state1 = (Object) a.saveState(facesContext);
+
+ b.restoreState(facesContext, state1);
+
+ Object state2 = b.saveState(facesContext);
+
+ assertNull(a.getTestProperty1());
+ assertNull(b.getTestProperty1());
+ assertEquals("testProperty2", a.getTestProperty2());
+ assertEquals("testProperty2", b.getTestProperty2());
+ }
+
+ public void testPutPropertyStateHelper1()
+ {
+ UITestComponent a = new UITestComponent();
+
+ StateHelper helper = a.getStateHelper();
+
+ Object retValue = helper.put("someProperty", "someValue");
+ //No value previously set
+ assertNull(retValue);
+
+ a.markInitialState();
+
+ retValue = helper.put("someProperty", "someOtherValue");
+
+ assertEquals("someValue",retValue);
+
+ retValue = helper.put("someProperty", "someOtherOtherValue");
+
+ assertEquals("someOtherValue",retValue);
+
+ a.clearInitialState();
+
+ retValue = helper.put("someProperty", "someOtherOtherOtherValue");
+
+ assertEquals("someOtherOtherValue",retValue);
+ }
+
+ public void testPutPropertyStateHelper2()
+ {
+ UITestComponent a = new UITestComponent();
+
+ StateHelper helper = a.getStateHelper();
+
+ Object retValue = helper.put("someProperty", "someValue");
+ //No value previously set
+ assertNull(retValue);
+
+ a.markInitialState();
+
+ retValue = helper.put("someProperty", null);
+
+ assertEquals("someValue",retValue);
+
+ retValue = helper.put("someProperty", "someOtherOtherValue");
+
+ assertNull(retValue);
+
+ a.clearInitialState();
+
+ retValue = helper.put("someProperty", null);
+
+ assertEquals("someOtherOtherValue",retValue);
+ }
+
+ public void testRemovePropertyStateHelper1()
+ {
+ UITestComponent a = new UITestComponent();
+
+ StateHelper helper = a.getStateHelper();
+
+ Object retValue = helper.put("someProperty", "someValue");
+ //No value previously set
+ assertNull(retValue);
+
+ a.markInitialState();
+
+ retValue = helper.remove("someProperty");
+
+ assertEquals("someValue",retValue);
+
+ retValue = helper.put("someProperty", "someOtherOtherValue");
+
+ assertNull(retValue);
+
+ a.clearInitialState();
+
+ retValue = helper.remove("someProperty");
+
+ assertEquals("someOtherOtherValue",retValue);
+ }
+
+
+ public void testAddItemOnList1()
+ {
+ UITestComponent a = new UITestComponent();
+ UITestComponent b = new UITestComponent();
+
+ StateHelper helperA = a.getStateHelper();
+ StateHelper helperB = b.getStateHelper();
+
+ helperA.add("somePropertyList", "someValue1");
+ helperB.add("somePropertyList", "someValue1");
+ a.markInitialState();
+ b.markInitialState();
+
+ helperA.add("somePropertyList", "someValue2");
+ helperA.add("somePropertyList", "someValue3");
+
+ b.restoreState(facesContext, a.saveState(facesContext));
+
+ List listA = (List) helperA.get("somePropertyList");
+
+ assertEquals("someValue1",listA.get(0));
+ assertEquals("someValue2",listA.get(1));
+ assertEquals("someValue3",listA.get(2));
+
+ List listB = (List) helperB.get("somePropertyList");
+
+ assertEquals("someValue1",listB.get(0));
+ assertEquals("someValue2",listB.get(1));
+ assertEquals("someValue3",listB.get(2));
+ }
+
+ public void testAddItemOnList2()
+ {
+ UITestComponent a = new UITestComponent();
+ UITestComponent b = new UITestComponent();
+
+ StateHelper helperA = a.getStateHelper();
+ StateHelper helperB = b.getStateHelper();
+
+ helperA.add("somePropertyList", "someValue1");
+ helperB.add("somePropertyList", "someValue1");
+ a.markInitialState();
+ b.markInitialState();
+
+ helperA.add("somePropertyList", "someValue2");
+ //helperA.add("somePropertyList", "someValue3");
+
+ helperA.remove("somePropertyList","someValue1");
+ helperA.remove("somePropertyList","someValue2");
+
+ b.restoreState(facesContext, a.saveState(facesContext));
+
+ List listA = (List) helperA.get("somePropertyList");
+
+ if (listA != null)
+ {
+ assertFalse("The list should not contain [someValue1]", listA.contains("someValue1"));
+ assertFalse("The list should not contain [someValue2]", listA.contains("someValue2"));
+ }
+
+ List listB = (List) helperB.get("somePropertyList");
+
+ if (listB != null)
+ {
+ assertFalse("The list should not contain [someValue2]", listB.contains("someValue2"));
+ assertFalse("The list should not contain [someValue1]", listB.contains("someValue1"));
+ }
+ }
+
+ public void testAddItemOnList3()
+ {
+ UITestComponent a = new UITestComponent();
+ UITestComponent b = new UITestComponent();
+
+ StateHelper helperA = a.getStateHelper();
+ StateHelper helperB = b.getStateHelper();
+
+ helperA.add("somePropertyList", "someValue1");
+ helperB.add("somePropertyList", "someValue1");
+ a.markInitialState();
+ b.markInitialState();
+
+ helperA.add("somePropertyList", "someValue2");
+ helperA.add("somePropertyList", "someValue3");
+
+ helperA.remove("somePropertyList","someValue1");
+ helperA.remove("somePropertyList","someValue2");
+
+ b.restoreState(facesContext, a.saveState(facesContext));
+
+ List listA = (List) helperA.get("somePropertyList");
+
+ assertTrue("The list should contain [someValue3]", listA.contains("someValue3"));
+ assertFalse("The list should not contain [someValue1]", listA.contains("someValue1"));
+ assertFalse("The list should not contain [someValue2]", listA.contains("someValue2"));
+
+ List listB = (List) helperB.get("somePropertyList");
+
+ assertTrue("The list should contain [someValue3]", listB.contains("someValue3"));
+ assertFalse("The list should not contain [someValue2]", listB.contains("someValue2"));
+ assertFalse("The list should not contain [someValue1]", listB.contains("someValue1"));
+ }
+
+ public void testPutItemOnMap1()
+ {
+ UITestComponent a = new UITestComponent();
+ UITestComponent b = new UITestComponent();
+
+ StateHelper helperA = a.getStateHelper();
+ StateHelper helperB = b.getStateHelper();
+
+ helperA.put("somePropertyMap","key1", "someValue1");
+ helperB.put("somePropertyMap","key1", "someValue1");
+ a.markInitialState();
+ b.markInitialState();
+
+ helperA.put("somePropertyMap","key2", "someValue2");
+ helperA.put("somePropertyMap","key3", "someValue3");
+
+ b.restoreState(facesContext, a.saveState(facesContext));
+
+ Map mapA = (Map) helperA.get("somePropertyMap");
+
+ assertEquals("someValue1",mapA.get("key1"));
+ assertEquals("someValue2",mapA.get("key2"));
+ assertEquals("someValue3",mapA.get("key3"));
+
+ Map mapB = (Map) helperB.get("somePropertyMap");
+
+ assertEquals("someValue1",mapB.get("key1"));
+ assertEquals("someValue2",mapB.get("key2"));
+ assertEquals("someValue3",mapB.get("key3"));
+ }
+
+ public void testPutRemoveItemOnMap2()
+ {
+ UITestComponent a = new UITestComponent();
+ UITestComponent b = new UITestComponent();
+
+ StateHelper helperA = a.getStateHelper();
+ StateHelper helperB = b.getStateHelper();
+
+ helperA.put("somePropertyMap","key1", "someValue1");
+ helperB.put("somePropertyMap","key1", "someValue1");
+ a.markInitialState();
+ b.markInitialState();
+
+ helperA.put("somePropertyMap","key2", "someValue2");
+
+ helperA.remove("somePropertyMap","key1");
+ helperA.remove("somePropertyMap","key2");
+
+ b.restoreState(facesContext, a.saveState(facesContext));
+
+ Map mapA = (Map) helperA.get("somePropertyMap");
+
+ if (mapA != null)
+ {
+ assertNull(mapA.get("key2"));
+ assertNull(mapA.get("key1"));
+ }
+
+ Map mapB = (Map) helperB.get("somePropertyMap");
+
+ if (mapB != null)
+ {
+ assertNull(mapB.get("key2"));
+ assertNull(mapB.get("key1"));
+ }
+ }
+
+ public void testPutRemoveItemOnMap3()
+ {
+ UITestComponent a = new UITestComponent();
+ UITestComponent b = new UITestComponent();
+
+ StateHelper helperA = a.getStateHelper();
+ StateHelper helperB = b.getStateHelper();
+
+ helperA.put("somePropertyMap","key1", "someValue1");
+ helperB.put("somePropertyMap","key1", "someValue1");
+ a.markInitialState();
+ b.markInitialState();
+
+ helperA.put("somePropertyMap","key2", "someValue2");
+ helperA.put("somePropertyMap","key3", "someValue3");
+
+ helperA.remove("somePropertyMap","key1");
+ helperA.remove("somePropertyMap","key2");
+
+ b.restoreState(facesContext, a.saveState(facesContext));
+
+ Map mapA = (Map) helperA.get("somePropertyMap");
+
+ if (mapA != null)
+ {
+ assertNull(mapA.get("key2"));
+ assertNull(mapA.get("key1"));
+ }
+
+ Map mapB = (Map) helperB.get("somePropertyMap");
+
+ if (mapB != null)
+ {
+ assertNull(mapB.get("key2"));
+ assertNull(mapB.get("key1"));
+ }
+ }
+}
Propchange: myfaces/core/branches/2_0_0/api/src/test/java/javax/faces/component/_Delta2StateHelperTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/core/branches/2_0_0/api/src/test/java/javax/faces/component/_Delta2StateHelperTest.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Modified: myfaces/core/branches/2_0_0/api/src/test/java/javax/faces/component/_DeltaStateHelperTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2_0_0/api/src/test/java/javax/faces/component/_DeltaStateHelperTest.java?rev=787511&r1=787510&r2=787511&view=diff
==============================================================================
--- myfaces/core/branches/2_0_0/api/src/test/java/javax/faces/component/_DeltaStateHelperTest.java (original)
+++ myfaces/core/branches/2_0_0/api/src/test/java/javax/faces/component/_DeltaStateHelperTest.java Tue Jun 23 01:36:37 2009
@@ -21,15 +21,13 @@
import java.util.List;
import java.util.Map;
-import junit.framework.TestCase;
-
/**
* A generic framework less testcase for our _DeltaStateHelper class!
*
* @author Werner Punz (latest modification by $Author$)
* @version $Rev$ $Date$
*/
-public class _DeltaStateHelperTest extends TestCase
+public class _DeltaStateHelperTest extends AbstractComponentTest
{
private static final String KEY3 = "key3";
@@ -260,19 +258,19 @@
_setupGetTests();
_instance.setInitialStateMarked(false);
Object serializedState = _instance.saveState(null);
- _instance.restoreState(null, serializedState);
+ _instance.restoreState(facesContext, serializedState);
assertStructure();
_setupGetTests();
_instance.setInitialStateMarked(true);
serializedState = _instance.saveState(null);
- _instance.restoreState(null, serializedState);
+ _instance.restoreState(facesContext, serializedState);
assertStructure();
_instance.setInitialStateMarked(true);
_setupGetTests();
serializedState = _instance.saveState(null);
- _instance.restoreState(null, serializedState);
+ _instance.restoreState(facesContext, serializedState);
assertStructure();
}