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/11/10 03:11:47 UTC
svn commit: r1033329 [1/2] - in /myfaces/commons/branches/jsf_20:
myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/
myfaces-commons-converters/src/main/resources/META-INF/
myfaces-commons-validators/src/main/java/org/apache...
Author: lu4242
Date: Wed Nov 10 02:11:46 2010
New Revision: 1033329
URL: http://svn.apache.org/viewvc?rev=1033329&view=rev
Log:
MFCOMMONS-19 Create branch for JSF 2.0
Added:
myfaces/commons/branches/jsf_20/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/_DeltaStateHelper.java
myfaces/commons/branches/jsf_20/myfaces-commons-validators/src/main/java/org/apache/myfaces/commons/validator/_DeltaStateHelper.java
Modified:
myfaces/commons/branches/jsf_20/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/ConverterBase.java
myfaces/commons/branches/jsf_20/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/EnumConverter.java
myfaces/commons/branches/jsf_20/myfaces-commons-converters/src/main/resources/META-INF/converterClass12.vm
myfaces/commons/branches/jsf_20/myfaces-commons-validators/src/main/java/org/apache/myfaces/commons/validator/ValidatorBase.java
myfaces/commons/branches/jsf_20/myfaces-commons-validators/src/main/resources/META-INF/validatorClass12.vm
Modified: myfaces/commons/branches/jsf_20/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/ConverterBase.java
URL: http://svn.apache.org/viewvc/myfaces/commons/branches/jsf_20/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/ConverterBase.java?rev=1033329&r1=1033328&r2=1033329&view=diff
==============================================================================
--- myfaces/commons/branches/jsf_20/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/ConverterBase.java (original)
+++ myfaces/commons/branches/jsf_20/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/ConverterBase.java Wed Nov 10 02:11:46 2010
@@ -20,14 +20,14 @@ package org.apache.myfaces.commons.conve
import java.io.Serializable;
import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.el.ValueExpression;
import javax.faces.application.FacesMessage;
+import javax.faces.component.PartialStateHolder;
+import javax.faces.component.StateHelper;
import javax.faces.component.StateHolder;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
@@ -45,11 +45,13 @@ import org.apache.myfaces.commons.util.M
evaluateELOnExecution = true,
tagClass = "org.apache.myfaces.commons.converter.ConverterBaseTag",
tagHandler = "org.apache.myfaces.commons.converter.ConverterBaseTagHandler")
-public abstract class ConverterBase implements StateHolder, Converter {
+public abstract class ConverterBase implements PartialStateHolder, Converter {
- private String _summaryMessage = null;
- private String _detailMessage = null;
private boolean _transient = false;
+
+ private transient FacesContext _facesContext;
+ private StateHelper _stateHelper = null;
+ private boolean _initialStateMarked = false;
/**
* alternate conversion error summary message format string
@@ -59,9 +61,7 @@ public abstract class ConverterBase impl
@JSFProperty
public String getSummaryMessage()
{
- if (_summaryMessage != null) return _summaryMessage;
- ValueExpression expression = getValueExpression("summaryMessage");
- return expression != null ? getStringValue(getFacesContext(), expression) : null;
+ return (String) getStateHelper().eval(PropertyKeys.summaryMessage);
}
/**
@@ -69,7 +69,7 @@ public abstract class ConverterBase impl
* @param message The summary message to be displayed.
*/
public void setSummaryMessage(String message) {
- _summaryMessage = message;
+ getStateHelper().put(PropertyKeys.summaryMessage, message);
}
/**
@@ -80,9 +80,7 @@ public abstract class ConverterBase impl
*/
@JSFProperty
public String getDetailMessage() {
- if (_detailMessage != null) return _detailMessage;
- ValueExpression vb = getValueExpression("detailMessage");
- return vb != null ? getStringValue(getFacesContext(), vb) : null;
+ return (String) getStateHelper().eval(PropertyKeys.detailMessage);
}
/**
@@ -90,26 +88,34 @@ public abstract class ConverterBase impl
* @param message The detail message to be displayed.
*/
public void setDetailMessage(String message) {
- _detailMessage = message;
+ getStateHelper().put(PropertyKeys.detailMessage, message);
}
/**
* @param context
*/
- public Object saveState(FacesContext context) {
- Object[] state = new Object[3];
- state[0] = _summaryMessage;
- state[1] = _detailMessage;
- state[2] = saveValueExpressionMap(context);
- return state;
+ public Object saveState(FacesContext context)
+ {
+ if (context == null)
+ {
+ throw new NullPointerException ("context");
+ }
+
+ StateHelper stateHelper = getStateHelper(false);
+ if (stateHelper != null)
+ {
+ return stateHelper.saveState(context);
+ }
+ else
+ {
+ return null;
+ }
}
- public void restoreState(FacesContext context, Object state) {
- Object[] values = (Object[]) state;
- _summaryMessage = (String) values[0];
- _detailMessage = (String) values[1];
- restoreValueExpressionMap(context, values[2]);
+ public void restoreState(FacesContext context, Object state)
+ {
+ getStateHelper().restoreState(context, state);
}
public boolean isTransient() {
@@ -144,69 +150,33 @@ public abstract class ConverterBase impl
// --------------------- borrowed from UIComponentBase ------------
- private Map _valueExpressionMap = null;
-
+ @SuppressWarnings("unchecked")
public ValueExpression getValueExpression(String name)
{
if (name == null) throw new NullPointerException("name");
- if (_valueExpressionMap == null)
+ StateHelper helper = getStateHelper(false);
+ if (helper == null)
{
return null;
}
- else
+ Map<String,Object> bindings = (Map<String,Object>) helper.get(PropertyKeys.bindings);
+ if (bindings == null)
{
- return (ValueExpression)_valueExpressionMap.get(name);
- }
- }
-
- public void setValueExpression(String name,
- ValueExpression binding)
- {
- if (name == null) throw new NullPointerException("name");
- if (_valueExpressionMap == null)
- {
- _valueExpressionMap = new HashMap();
- }
- _valueExpressionMap.put(name, binding);
- }
-
- private Object saveValueExpressionMap(FacesContext context)
- {
- if (_valueExpressionMap != null)
- {
- int initCapacity = (_valueExpressionMap.size() * 4 + 3) / 3;
- HashMap stateMap = new HashMap(initCapacity);
- for (Iterator it = _valueExpressionMap.entrySet().iterator(); it.hasNext(); )
- {
- Map.Entry entry = (Map.Entry)it.next();
- stateMap.put(entry.getKey(),
- saveAttachedState(context, entry.getValue()));
- }
- return stateMap;
+ return null;
}
else
{
- return null;
+ return (ValueExpression) bindings.get(name);
}
}
-
- private void restoreValueExpressionMap(FacesContext context, Object stateObj)
+
+ public void setValueExpression(String name, ValueExpression expression)
{
- if (stateObj != null)
- {
- Map stateMap = (Map)stateObj;
- int initCapacity = (stateMap.size() * 4 + 3) / 3;
- _valueExpressionMap = new HashMap(initCapacity);
- for (Iterator it = stateMap.entrySet().iterator(); it.hasNext(); )
- {
- Map.Entry entry = (Map.Entry)it.next();
- _valueExpressionMap.put(entry.getKey(),
- restoreAttachedState(context, entry.getValue()));
- }
- }
- else
- {
- _valueExpressionMap = null;
+ if (name == null) throw new NullPointerException("name");
+ if (expression == null) {
+ getStateHelper().remove(PropertyKeys.bindings, name);
+ } else {
+ getStateHelper().put(PropertyKeys.bindings, name, expression);
}
}
@@ -235,30 +205,39 @@ public abstract class ConverterBase impl
* of the provided object. When deserialized, a default instance of that
* type will be recreated.
*/
- public static Object saveAttachedState(FacesContext context,
- Object attachedObject)
+ public static Object saveAttachedState(FacesContext context, Object attachedObject)
{
- if (attachedObject == null) return null;
- if (attachedObject instanceof List)
+ if (context == null)
{
- List lst = new ArrayList(((List)attachedObject).size());
- for (Iterator it = ((List)attachedObject).iterator(); it.hasNext(); )
- {
- lst.add(saveAttachedState(context, it.next()));
- }
- return new _AttachedListStateWrapper(lst);
+ throw new NullPointerException ("context");
}
- else if (attachedObject instanceof StateHolder)
+
+ if (attachedObject == null)
+ return null;
+ // StateHolder interface should take precedence over
+ // List children
+ if (attachedObject instanceof StateHolder)
{
- if (((StateHolder)attachedObject).isTransient())
+ StateHolder holder = (StateHolder) attachedObject;
+ if (holder.isTransient())
{
return null;
}
- else
+
+ 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)
{
- return new _AttachedStateWrapper(attachedObject.getClass(),
- ((StateHolder)attachedObject).saveState(context));
+ if (item != null)
+ {
+ lst.add(saveAttachedState(context, item));
+ }
}
+
+ return new _AttachedListStateWrapper(lst);
}
else if (attachedObject instanceof Serializable)
{
@@ -270,25 +249,26 @@ public abstract class ConverterBase impl
}
}
- public static Object restoreAttachedState(FacesContext context,
- Object stateObj)
- throws IllegalStateException
+ @SuppressWarnings("unchecked")
+ public static Object restoreAttachedState(FacesContext context, Object stateObj) throws IllegalStateException
{
- if (context == null) throw new NullPointerException("context");
- if (stateObj == null) return null;
+ if (context == null)
+ throw new NullPointerException("context");
+ if (stateObj == null)
+ return null;
if (stateObj instanceof _AttachedListStateWrapper)
{
- List lst = ((_AttachedListStateWrapper)stateObj).getWrappedStateList();
- List restoredList = new ArrayList(lst.size());
- for (Iterator it = lst.iterator(); it.hasNext(); )
+ List<Object> lst = ((_AttachedListStateWrapper) stateObj).getWrappedStateList();
+ List<Object> restoredList = new ArrayList<Object>(lst.size());
+ for (Object item : lst)
{
- restoredList.add(restoreAttachedState(context, it.next()));
+ restoredList.add(restoreAttachedState(context, item));
}
return restoredList;
}
else if (stateObj instanceof _AttachedStateWrapper)
{
- Class clazz = ((_AttachedStateWrapper)stateObj).getClazz();
+ Class<?> clazz = ((_AttachedStateWrapper) stateObj).getClazz();
Object restoredObject;
try
{
@@ -296,7 +276,8 @@ public abstract class ConverterBase impl
}
catch (InstantiationException e)
{
- throw new RuntimeException("Could not restore StateHolder of type " + clazz.getName() + " (missing no-args constructor?)", e);
+ throw new RuntimeException("Could not restore StateHolder of type " + clazz.getName()
+ + " (missing no-args constructor?)", e);
}
catch (IllegalAccessException e)
{
@@ -304,8 +285,11 @@ public abstract class ConverterBase impl
}
if (restoredObject instanceof StateHolder)
{
- Object wrappedState = ((_AttachedStateWrapper)stateObj).getWrappedStateObject();
- ((StateHolder)restoredObject).restoreState(context, wrappedState);
+ _AttachedStateWrapper wrapper = (_AttachedStateWrapper) stateObj;
+ Object wrappedState = wrapper.getWrappedStateObject();
+
+ StateHolder holder = (StateHolder) restoredObject;
+ holder.restoreState(context, wrappedState);
}
return restoredObject;
}
@@ -315,11 +299,63 @@ public abstract class ConverterBase impl
}
}
-
protected FacesContext getFacesContext()
{
- return FacesContext.getCurrentInstance();
+ if (_facesContext == null)
+ {
+ return FacesContext.getCurrentInstance();
+ }
+ else
+ {
+ return _facesContext;
+ }
+ }
+
+ boolean isCachedFacesContext()
+ {
+ return _facesContext != null;
+ }
+
+ void setCachedFacesContext(FacesContext facesContext)
+ {
+ _facesContext = facesContext;
}
+
+ protected StateHelper getStateHelper() {
+ return getStateHelper(true);
+ }
+
+ /**
+ * returns a delta state saving enabled state helper
+ * for the current component
+ * @param create if true a state helper is created if not already existing
+ * @return an implementation of the StateHelper interface or null if none exists and create is set to false
+ */
+ protected StateHelper getStateHelper(boolean create) {
+ if(_stateHelper != null) {
+ return _stateHelper;
+ }
+ if(create) {
+ _stateHelper = new _DeltaStateHelper(this);
+ }
+ return _stateHelper;
+ }
+
+ public void clearInitialState()
+ {
+ _initialStateMarked = false;
+ }
+
+ public boolean initialStateMarked()
+ {
+ return _initialStateMarked;
+ }
+
+ public void markInitialState()
+ {
+ _initialStateMarked = true;
+ }
+
protected String getStringValue(FacesContext context, ValueExpression vb)
{
Object value = vb.getValue(context.getELContext());
@@ -329,4 +365,11 @@ public abstract class ConverterBase impl
}
return null;
}
+
+ enum PropertyKeys
+ {
+ bindings,
+ summaryMessage,
+ detailMessage
+ }
}
Modified: myfaces/commons/branches/jsf_20/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/EnumConverter.java
URL: http://svn.apache.org/viewvc/myfaces/commons/branches/jsf_20/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/EnumConverter.java?rev=1033329&r1=1033328&r2=1033329&view=diff
==============================================================================
--- myfaces/commons/branches/jsf_20/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/EnumConverter.java (original)
+++ myfaces/commons/branches/jsf_20/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/EnumConverter.java Wed Nov 10 02:11:46 2010
@@ -19,7 +19,7 @@
package org.apache.myfaces.commons.converter;
import javax.faces.application.FacesMessage;
-import javax.faces.component.StateHolder;
+import javax.faces.component.PartialStateHolder;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
@@ -41,7 +41,7 @@ import org.apache.myfaces.commons.util.M
name = "mcc:convertEnum",
tagClass = "org.apache.myfaces.commons.converter.ConvertEnumTag",
serialuidtag = "3864584277821896141L")
-public class EnumConverter implements Converter, StateHolder {
+public class EnumConverter implements Converter, PartialStateHolder {
public static final String CONVERTER_ID = "org.apache.myfaces.commons.converter.Enum";
public static final String ENUM_ID = "org.apache.myfaces.commons.converter.EnumConverter.ENUM";
@@ -168,11 +168,18 @@ public class EnumConverter implements Co
}
public void restoreState(FacesContext context, Object state) {
- targetClass = (Class)state;
+ if (state != null)
+ {
+ targetClass = (Class)state;
+ }
}
public Object saveState(FacesContext context) {
- return targetClass;
+ if (!initialStateMarked())
+ {
+ return targetClass;
+ }
+ return null;
}
public void setTransient(boolean newTransientValue) {
@@ -197,4 +204,21 @@ public class EnumConverter implements Co
{
this.targetClass = targetClass;
}
+
+ private boolean _initialStateMarked = false;
+
+ public void clearInitialState()
+ {
+ _initialStateMarked = false;
+ }
+
+ public boolean initialStateMarked()
+ {
+ return _initialStateMarked;
+ }
+
+ public void markInitialState()
+ {
+ _initialStateMarked = true;
+ }
}
Added: myfaces/commons/branches/jsf_20/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/_DeltaStateHelper.java
URL: http://svn.apache.org/viewvc/myfaces/commons/branches/jsf_20/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/_DeltaStateHelper.java?rev=1033329&view=auto
==============================================================================
--- myfaces/commons/branches/jsf_20/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/_DeltaStateHelper.java (added)
+++ myfaces/commons/branches/jsf_20/myfaces-commons-converters/src/main/java/org/apache/myfaces/commons/converter/_DeltaStateHelper.java Wed Nov 10 02:11:46 2010
@@ -0,0 +1,827 @@
+/*
+ * 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 org.apache.myfaces.commons.converter;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.el.ValueExpression;
+import javax.faces.component.StateHelper;
+import javax.faces.component.StateHolder;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIComponentBase;
+import javax.faces.context.FacesContext;
+
+/**
+ * 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
+ * </p>
+ * <p>
+ * For components not implementing partial state saving only the initial states are
+ * of importance, everything is stored and restored continously there
+ * </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,
+ * 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>
+ * <li>The map backed by method put(Serializable,String,Object) is
+ * a replacement of UIComponentBase.attributesMap and UIComponent.bindings map.
+ * Note that on jsf 1.2, instances saved on attributesMap should not be
+ * StateHolder, but on jsf 2.0 it is possible to have it. PartialStateHolder
+ * instances are not handled in this map, or in other words delta state is not
+ * handled in this classes (markInitialState and clearInitialState is not propagated).</li>
+ * <li>The list backed by method add(Serializable,Object) should be (is not) a
+ * replacement of UIComponentBase.facesListeners, but note that StateHelper
+ * does not implement PartialStateHolder, and facesListener could have instances
+ * of that class that needs to be notified when UIComponent.markInitialState or
+ * UIComponent.clearInitialState is called, or in other words facesListeners
+ * should deal with PartialStateHolder instances.</li>
+ * <li>The list backed by method add(Serializable,Object) is
+ * a replacement of UIViewRoot.phaseListeners list. Note that instances of
+ * PhaseListener are not expected to implement StateHolder or PartialStateHolder.</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>
+ *
+ * @author Werner Punz
+ * @author Leonardo Uribe (latest modification by $Author: lu4242 $)
+ * @version $Rev: 980927 $ $Date: 2010-07-30 14:05:55 -0500 (Vie, 30 Jul 2010) $
+ */
+class _DeltaStateHelper implements StateHelper
+{
+
+ /**
+ * 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 ConverterBase _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(ConverterBase component)
+ {
+ super();
+ this._component = component;
+ _fullState = new HashMap<Serializable, Object>();
+ _deltas = null;
+ //_stateHolderKeys = new HashSet<Serializable>();
+ }
+
+ /**
+ * Used to create delta map on demand
+ *
+ * @return
+ */
+ private boolean _createDeltas()
+ {
+ if (isInitialStateMarked())
+ {
+ if (_deltas == null)
+ {
+ _deltas = new HashMap<Serializable, Object>(2);
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ protected boolean isInitialStateMarked()
+ {
+ return _component.initialStateMarked();
+ }
+
+ public void add(Serializable key, Object value)
+ {
+ if (_createDeltas())
+ {
+ //Track delta case
+ Map<Object, Boolean> deltaListMapValues = (Map<Object, Boolean>) _deltas
+ .get(key);
+ if (deltaListMapValues == null)
+ {
+ deltaListMapValues = new InternalDeltaListMap<Object, Boolean>(
+ 3);
+ _deltas.put(key, deltaListMapValues);
+ }
+ deltaListMapValues.put(value, Boolean.TRUE);
+ }
+
+ //Handle change on full map
+ List<Object> fullListValues = (List<Object>) _fullState.get(key);
+ if (fullListValues == null)
+ {
+ fullListValues = new InternalList<Object>(3);
+ _fullState.put(key, fullListValues);
+ }
+ fullListValues.add(value);
+ }
+
+ public Object eval(Serializable key)
+ {
+ 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;
+ }
+
+ public Object eval(Serializable key, Object defaultValue)
+ {
+ 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 defaultValue;
+ }
+
+ public Object get(Serializable key)
+ {
+ return _fullState.get(key);
+ }
+
+ public Object put(Serializable key, Object value)
+ {
+ Object returnValue = null;
+ if (_createDeltas())
+ {
+ if (_deltas.containsKey(key))
+ {
+ returnValue = _deltas.put(key, value);
+ _fullState.put(key, value);
+ }
+ else if (value == null && !_fullState.containsKey(key))
+ {
+ returnValue = null;
+ }
+ else
+ {
+ _deltas.put(key, value);
+ returnValue = _fullState.put(key, value);
+ }
+ }
+ else
+ {
+ /*
+ if (value instanceof StateHolder)
+ {
+ _stateHolderKeys.add(key);
+ }
+ */
+ returnValue = _fullState.put(key, value);
+ }
+ return returnValue;
+ }
+
+ public Object put(Serializable key, String mapKey, Object value)
+ {
+ boolean returnSet = false;
+ Object returnValue = null;
+ if (_createDeltas())
+ {
+ //Track delta case
+ Map<String, Object> mapValues = (Map<String, Object>) _deltas
+ .get(key);
+ if (mapValues == null)
+ {
+ 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);
+ }
+ }
+
+ //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;
+ }
+
+ public Object remove(Serializable key)
+ {
+ Object returnValue = null;
+ if (_createDeltas())
+ {
+ 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);
+ }
+ return returnValue;
+ }
+
+ public Object remove(Serializable key, Object valueOrKey)
+ {
+ // 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;
+ }
+
+ 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)
+ {
+ if (c.containsKey(valueOrKey))
+ {
+ returnValue = valueOrKey;
+ }
+ c.put(valueOrKey, Boolean.FALSE);
+ }
+ 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)
+ {
+ if (c.remove(valueOrKey))
+ {
+ returnValue = valueOrKey;
+ }
+ if (c.isEmpty())
+ {
+ stateMap.remove(key);
+ }
+ }
+ return returnValue;
+ }
+
+ private static Object _removeValueOrKeyFromMap(
+ Map<Serializable, Object> stateMap, Serializable key,
+ Object valueOrKey, boolean delta)
+ {
+ if (valueOrKey == null)
+ {
+ return null;
+ }
+
+ Object returnValue = null;
+ Map<String, Object> map = (Map<String, Object>) stateMap.get(key);
+ if (map != null)
+ {
+ 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 returnValue;
+ }
+
+ 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
+ * myfaces.InternalArray, myfaces.internalMap
+ *
+ * the internal Array is then mapped to another array
+ *
+ * the internal Map again is then mapped to a map with key value pairs
+ *
+ *
+ */
+ public Object saveState(FacesContext context)
+ {
+ Map serializableMap = (isInitialStateMarked()) ? _deltas : _fullState;
+
+ 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];
+ //Object[] retArr = new Object[serializableMap.entrySet().size() * 2 + stateHolderKeyCount];
+
+ Iterator<Map.Entry<Serializable, Object>> it = serializableMap
+ .entrySet().iterator();
+ int cnt = 0;
+ while (it.hasNext())
+ {
+ entry = it.next();
+ retArr[cnt] = entry.getKey();
+
+ 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] = value;
+ }
+ cnt += 2;
+ }
+
+ /*
+ if (isInitalStateMarked())
+ {
+ 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;
+ }
+
+ public void restoreState(FacesContext context, Object state)
+ {
+ if (state == null)
+ return;
+
+ Object[] serializedState = (Object[]) state;
+
+ if (!isInitialStateMarked() && !_fullState.isEmpty())
+ {
+ _fullState.clear();
+ if(_deltas != null)
+ {
+ _deltas.clear();
+ }
+ }
+
+ for (int cnt = 0; cnt < serializedState.length; cnt += 2)
+ {
+ Serializable key = (Serializable) serializedState[cnt];
+ Object savedValue = UIComponentBase.restoreAttachedState(context,
+ serializedState[cnt + 1]);
+
+ if (isInitialStateMarked())
+ {
+ 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
+ {
+ put(key, savedValue);
+ }
+ }
+ }
+
+ public void setTransient(boolean transientValue)
+ {
+ _transient = transientValue;
+ }
+
+ //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
+ {
+ public InternalMap()
+ {
+ super();
+ }
+
+ public InternalMap(int initialCapacity, float loadFactor)
+ {
+ super(initialCapacity, loadFactor);
+ }
+
+ public InternalMap(Map<? extends K, ? extends V> m)
+ {
+ super(m);
+ }
+
+ public InternalMap(int initialSize)
+ {
+ super(initialSize);
+ }
+
+ public boolean isTransient()
+ {
+ return false;
+ }
+
+ public void setTransient(boolean newTransientValue)
+ {
+ // No op
+ }
+
+ 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]));
+ }
+ }
+
+ public Object saveState(FacesContext context)
+ {
+ int cnt = 0;
+ Object[] mapArr = new Object[this.size() * 2];
+ for (Map.Entry<K, V> entry : this.entrySet())
+ {
+ mapArr[cnt] = entry.getKey();
+ Object value = entry.getValue();
+
+ if (value instanceof StateHolder ||
+ value instanceof List ||
+ !(value instanceof Serializable))
+ {
+ mapArr[cnt + 1] = UIComponentBase.saveAttachedState(context, value);
+ }
+ else
+ {
+ mapArr[cnt + 1] = value;
+ }
+ cnt += 2;
+ }
+ return mapArr;
+ }
+ }
+
+ /**
+ * Map used to keep track of list changes
+ */
+ static class InternalDeltaListMap<K, V> extends InternalMap<K, V>
+ {
+
+ 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);
+ }
+ }
+
+ 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);
+ }
+
+ public boolean isTransient()
+ {
+ return false;
+ }
+
+ public void setTransient(boolean newTransientValue)
+ {
+ }
+
+ 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));
+ }
+ }
+
+ 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;
+ }
+ }
+}
Modified: myfaces/commons/branches/jsf_20/myfaces-commons-converters/src/main/resources/META-INF/converterClass12.vm
URL: http://svn.apache.org/viewvc/myfaces/commons/branches/jsf_20/myfaces-commons-converters/src/main/resources/META-INF/converterClass12.vm?rev=1033329&r1=1033328&r2=1033329&view=diff
==============================================================================
--- myfaces/commons/branches/jsf_20/myfaces-commons-converters/src/main/resources/META-INF/converterClass12.vm (original)
+++ myfaces/commons/branches/jsf_20/myfaces-commons-converters/src/main/resources/META-INF/converterClass12.vm Wed Nov 10 02:11:46 2010
@@ -51,7 +51,7 @@ public class ${utils.getClassFromFullCla
{
#if ($converter.converterId)
- static public final String VALIDATOR_ID =
+ static public final String CONVERTER_ID =
"$converter.converterId";
#end
@@ -176,6 +176,167 @@ public class ${utils.getClassFromFullCla
#end
##
+## -------------------------------
+## writePropertySetStateHelperDeclaration
+## -------------------------------
+##
+#macro (writePropertySetStateHelperDeclaration $property $type $field $defaultValue )
+#if($utils.isPrimitiveClass($type) && !$property.isTagExcluded() && $property.isSetMethod())
+ private boolean ${field}Set;
+
+#end
+#end
+##
+## -------------------------------
+## writePropertyStateHelperDeclaration
+## -------------------------------
+##
+#macro( writePropertyStateHelperDeclaration $property $type $field $defaultValue )
+#if ($property.isPartialStateHolder())
+#if ($property.isLiteralOnly() || $property.isTagExcluded())
+ private $type $field #if($defaultValue) = $defaultValue;#{else};#{end}
+
+#else
+ private $type $field;
+
+#end
+#end
+#writePropertySetStateHelperDeclaration ($property $type $field $defaultValue)
+#end
+##
+## -------------------------------
+## writeLocalPropertyStateHelperGetter
+## -------------------------------
+##
+#macro (writeLocalPropertyStateHelperGetter $property $type $field $defaultValue )
+#if($utils.isPrimitiveClass($type) && !$property.isTagExcluded() && $property.isSetMethod())
+ $property.setMethodScope boolean $utils.getPrefixedPropertyName("isSet", $property.name)()
+ {
+ return ${field}Set;
+ }
+
+#end
+#if($property.isLocalMethod())
+#if("boolean" == $type)
+#set ($methodName = $utils.getPrefixedPropertyName("isLocal", $property.name))
+#else
+#set ($methodName = $utils.getPrefixedPropertyName("getLocal", $property.name))
+#end
+ final $property.localMethodScope $type ${methodName}()
+ {
+#if ($property.isPartialStateHolder())
+ return $field;
+#else
+ return $utils.castIfNecessary($type) getStateHelper().get(PropertyKeys.$field);
+#end
+ }
+
+#end
+#end
+##
+## -------------------------------
+## writePropertyStateHelperGetter
+## -------------------------------
+##
+#macro (writePropertyStateHelperGetter $property $type $field $defaultValue )
+#if ($property.isPartialStateHolder())
+ public $type $utils.getMethodReaderFromProperty($property.name, $type)()
+ {
+#if ($property.isTagExcluded() || $property.isLiteralOnly() || !($converter.isEvaluateELOnExecution()))
+ return $field;
+#else
+#if ($utils.isPrimitiveClass($type))
+ if (${field}Set)
+#else
+ if ($field != null)
+#end
+ {
+ return $field;
+ }
+ ValueExpression vb = getValueExpression("$property.name");
+ if (vb != null)
+ {
+#if ($utils.isPrimitiveClass($type))
+ return ($utils.castIfNecessary($type) vb.getValue(getFacesContext().getELContext())).${type}Value();
+#else
+#set ($pritype = $utils.getPrimitiveType($property.className))
+#if ($utils.isPrimitiveClass($pritype))
+ Object value = vb == null ? null : vb.getValue(getFacesContext().getELContext());
+ if (!(value instanceof $type)){
+ value = ${type}.valueOf(value.toString());
+ }
+ return $utils.castIfNecessary($type) value;
+#else
+ return $utils.castIfNecessary($type) vb.getValue(getFacesContext().getELContext());
+#end
+#end
+ }
+#if ($defaultValue)
+ return $defaultValue;
+#elseif ($utils.isPrimitiveClass($type))
+ return $utils.primitiveDefaultValue($type);
+#else
+ return null;
+#end
+#end
+ }
+
+#else
+ public $type $utils.getMethodReaderFromProperty($property.name, $type)()
+ {
+#if ($property.isLiteralOnly())
+#if ($defaultValue)
+ Object value = getStateHelper().get(PropertyKeys.$field);
+ if (value != null)
+ {
+ return $utils.castIfNecessary($type) value;
+ }
+ return $defaultValue;
+#else
+ return $utils.castIfNecessary($type) getStateHelper().get(PropertyKeys.$field);
+#end
+#else
+#if ($defaultValue)
+ return $utils.castIfNecessary($type) getStateHelper().eval(PropertyKeys.$field, $defaultValue);
+#else
+ return $utils.castIfNecessary($type) getStateHelper().eval(PropertyKeys.$field);
+#end
+#end
+ }
+
+#end
+#end
+##
+## -------------------------------
+## writePropertyStateHelperSetter
+## -------------------------------
+##
+#macro (writePropertyStateHelperSetter $property $type $field $defaultValue )
+#if ($property.isPartialStateHolder())
+ public void $utils.getPrefixedPropertyName("set", $property.name)($type $utils.getVariableFromName($property.name))
+ {
+ this.$field = $utils.getVariableFromName($property.name);
+ if (initialStateMarked())
+ {
+ getStateHelper().put(PropertyKeys.${property.name}Set,Boolean.TRUE);
+ }
+#if ($utils.isPrimitiveClass($type) && !$property.isTagExcluded() && $property.isSetMethod())
+ this.${field}Set = true;
+#end
+ }
+
+#else
+ public void $utils.getPrefixedPropertyName("set", $property.name)($type $utils.getVariableFromName($property.name))
+ {
+ getStateHelper().put(PropertyKeys.$field, $utils.getVariableFromName($property.name) );
+#if ($utils.isPrimitiveClass($type) && !$property.isTagExcluded() && $property.isSetMethod())
+ this.${field}Set = true;
+#end
+ }
+
+#end
+#end
+##
## ----------------------------- END PROPERTY MACROS -------------------------
##
## ----------------------------- START PROPERTY RENDERING --------------------
@@ -190,12 +351,28 @@ public class ${utils.getClassFromFullCla
#set ($defaultValue = false)
#end
// Property: $property.name
+#if ($converter.isEvaluateELOnExecution())
+#if ($property.name == "for")
+## To keep compatibility with RI, we should call it forVal
+#set ($field = "forVal")
+#else
+#set ($field = $property.name)
+#end
+## USING PARTIAL STATE SAVING STATE HELPER
+#writePropertyStateHelperDeclaration($property $type $field $defaultValue)
+#writeLocalPropertyStateHelperGetter ($property $type $field $defaultValue)
+#writePropertyStateHelperGetter ($property $type $field $defaultValue)
+#writePropertyStateHelperSetter ($property $type $field $defaultValue)
+#else
+## USING VARIABLES
#writePropertyDeclaration($property $type $field $defaultValue)
#writeLocalPropertyGetter ($property $type $field $defaultValue)
#writePropertyGetter ($property $type $field $defaultValue)
#writePropertySetter ($property $type $field $defaultValue)
#end
+#end
## ----------------------------- END PROPERTY RENDERING ---------------------
+#if ( !($converter.isEvaluateELOnExecution()) )
public Object saveState(FacesContext facesContext)
{
@@ -259,4 +436,215 @@ public class ${utils.getClassFromFullCla
#end
#end
}
+#else
+ enum PropertyKeys
+ {
+
+#set ($comma = "")
+#set ($addc = "false")
+#foreach( $property in $propertyList )
+#if ($property.name == "for")
+#set ($addc = "true")
+## To keep compatibility with RI, we should call it forVal
+#set ($field = "forVal")
+#else
+#set ($field = $property.name)
+#end
+#set ($type = $utils.getClassFromFullClass($property.className))
+#if($utils.getDefaultValueField($property))
+#set ($defaultValue = $utils.getDefaultValueField($property))
+#else
+#set ($defaultValue = false)
+#end
+#if ($property.name == "for")
+ $comma $field("for")
+#else
+#if ($property.isPartialStateHolder())
+ $comma ${field}Set
+#else
+ $comma $field
+#end
+#end
+#set($comma = ",")
+#end
+#if ("true" == $addc)
+ ;
+ String c;
+
+ PropertyKeys()
+ {
+ }
+
+ //Constructor needed by "for" property
+ PropertyKeys(String c)
+ {
+ this.c = c;
+ }
+
+ public String toString()
+ {
+ return ((this.c != null) ? this.c : super.toString());
+ }
+#end
+ }
+
+#set ($primitiveCount = 1) ## $propertyList.size() + 1
+#foreach( $property in $propertyList )
+#if ($property.isPartialStateHolder())
+#set ($primitiveCount = $primitiveCount + 1)
+#if($utils.isPrimitiveClass($property.className))
+#set ($primitiveCount = $primitiveCount + 1)
+#end
+#end
+#end
+## saveState and restoreState methods only has sense if we have properties
+## that does not use StateHelper class.
+#if ($primitiveCount > 1)
+
+ public void markInitialState()
+ {
+ super.markInitialState();
+#foreach( $property in $propertyList )
+#set ($field = $property.fieldName)
+#if ($property.isPartialStateHolder())
+ if ($field != null &&
+ $field instanceof PartialStateHolder)
+ {
+ ((PartialStateHolder)$field).markInitialState();
+ }
+#end
+#end
+ }
+
+ public void clearInitialState()
+ {
+ if (initialStateMarked())
+ {
+ super.clearInitialState();
+#foreach( $property in $propertyList )
+#set ($field = $property.fieldName)
+#if ($property.isPartialStateHolder())
+## //Only has sense propagate this method if is initialStateMarked
+ if ($field != null &&
+ $field instanceof PartialStateHolder)
+ {
+ ((PartialStateHolder)$field).clearInitialState();
+ }
+#end
+#end
+ }
+ }
+
+ @Override
+ public Object saveState(FacesContext facesContext)
+ {
+ if (initialStateMarked())
+ {
+ boolean nullDelta = true;
+ Object parentSaved = super.saveState(facesContext);
+#set ($arrayIndex = 0)
+#foreach( $property in $propertyList )
+#set ($field = $property.fieldName)
+#set ($type = $property.className)
+#if ($property.isPartialStateHolder())
+#set ($arrayIndex = $arrayIndex + 1)
+ Object ${property.name}Saved = null;
+ if (!_$utils.getPrefixedPropertyName("isSet", $property.name)() &&
+ $field != null && $field instanceof PartialStateHolder)
+ {
+ //Delta
+ StateHolder holder = (StateHolder) $field;
+ if (!holder.isTransient())
+ {
+ Object attachedState = holder.saveState(facesContext);
+ if (attachedState != null)
+ {
+ nullDelta = false;
+ }
+ ${property.name}Saved = new _AttachedDeltaWrapper(${field}.getClass(),
+ attachedState);
+ }
+ }
+ else if (_$utils.getPrefixedPropertyName("isSet", $property.name)() || $field != null )
+ {
+ //Full
+ ${property.name}Saved = saveAttachedState(facesContext,$field);
+ nullDelta = false;
+ }
+## StateHelper Properties does not need save and restore
+#end
+#end
+ if (parentSaved == null && nullDelta)
+ {
+ //No values
+ return null;
+ }
+
+ Object[] values = new Object[$primitiveCount];
+ values[0] = parentSaved;
+## Save full state
+#set ($arrayIndex = 0)
+#foreach( $property in $propertyList )
+#set ($field = $property.fieldName)
+#set ($type = $property.className)
+#if ($property.isPartialStateHolder())
+#set ($arrayIndex = $arrayIndex + 1)
+ values[$arrayIndex] = ${property.name}Saved;
+## StateHelper Properties does not need save and restore
+#end
+#end
+ return values;
+ }
+ else
+ {
+ Object[] values = new Object[$primitiveCount];
+ values[0] = super.saveState(facesContext);
+## Save full state
+#set ($arrayIndex = 0)
+#foreach( $property in $propertyList )
+#set ($field = $property.fieldName)
+#set ($type = $property.className)
+#if ($property.isPartialStateHolder())
+#set ($arrayIndex = $arrayIndex + 1)
+ values[$arrayIndex] = saveAttachedState(facesContext,$field);
+## StateHelper Properties does not need save and restore
+#end
+#end
+ return values;
+ }
+ }
+
+ @Override
+ public void restoreState(FacesContext facesContext, Object state)
+ {
+ if (state == null)
+ {
+ return;
+ }
+
+ Object[] values = (Object[])state;
+ super.restoreState(facesContext,values[0]);
+#set ($arrayIndex = 0)
+#foreach( $property in $propertyList )
+#set ($field = $property.fieldName)
+#set ($type = $property.className)
+#if ($property.isPartialStateHolder())
+#set ($arrayIndex = $arrayIndex + 1)
+ if (values[$arrayIndex] instanceof _AttachedDeltaWrapper)
+ {
+ //Delta
+ ((StateHolder)$field).restoreState(facesContext, ((_AttachedDeltaWrapper) values[$arrayIndex]).getWrappedStateObject());
+ }
+ else
+ {
+ //Full
+ $field = $utils.castIfNecessary($type) restoreAttachedState(facesContext,values[$arrayIndex]);
+ }
+#else
+## StateHelper Properties does not need save and restore
+#end
+#end
+ }
+#end
+#end
}
Modified: myfaces/commons/branches/jsf_20/myfaces-commons-validators/src/main/java/org/apache/myfaces/commons/validator/ValidatorBase.java
URL: http://svn.apache.org/viewvc/myfaces/commons/branches/jsf_20/myfaces-commons-validators/src/main/java/org/apache/myfaces/commons/validator/ValidatorBase.java?rev=1033329&r1=1033328&r2=1033329&view=diff
==============================================================================
--- myfaces/commons/branches/jsf_20/myfaces-commons-validators/src/main/java/org/apache/myfaces/commons/validator/ValidatorBase.java (original)
+++ myfaces/commons/branches/jsf_20/myfaces-commons-validators/src/main/java/org/apache/myfaces/commons/validator/ValidatorBase.java Wed Nov 10 02:11:46 2010
@@ -20,14 +20,14 @@ package org.apache.myfaces.commons.valid
import java.io.Serializable;
import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.el.ValueExpression;
import javax.faces.application.FacesMessage;
+import javax.faces.component.PartialStateHolder;
+import javax.faces.component.StateHelper;
import javax.faces.component.StateHolder;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
@@ -45,11 +45,13 @@ import org.apache.myfaces.commons.util.M
evaluateELOnExecution = true,
tagClass = "org.apache.myfaces.commons.validator.ValidatorBaseTag",
tagHandler = "org.apache.myfaces.commons.validator.ValidatorBaseTagHandler")
-public abstract class ValidatorBase implements StateHolder, Validator {
+public abstract class ValidatorBase implements PartialStateHolder, Validator {
- private String _summaryMessage = null;
- private String _detailMessage = null;
private boolean _transient = false;
+
+ private transient FacesContext _facesContext;
+ private StateHelper _stateHelper = null;
+ private boolean _initialStateMarked = false;
/**
* alternate validation error summary message format string
@@ -59,9 +61,7 @@ public abstract class ValidatorBase impl
@JSFProperty
public String getSummaryMessage()
{
- if (_summaryMessage != null) return _summaryMessage;
- ValueExpression expression = getValueExpression("summaryMessage");
- return expression != null ? getStringValue(getFacesContext(), expression) : null;
+ return (String) getStateHelper().eval(PropertyKeys.summaryMessage);
}
/**
@@ -69,7 +69,7 @@ public abstract class ValidatorBase impl
* @param message The summary message to be displayed.
*/
public void setSummaryMessage(String message) {
- _summaryMessage = message;
+ getStateHelper().put(PropertyKeys.summaryMessage, message);
}
/**
@@ -102,9 +102,7 @@ public abstract class ValidatorBase impl
*/
@JSFProperty
public String getDetailMessage() {
- if (_detailMessage != null) return _detailMessage;
- ValueExpression vb = getValueExpression("detailMessage");
- return vb != null ? getStringValue(getFacesContext(), vb) : null;
+ return (String) getStateHelper().eval(PropertyKeys.detailMessage);
}
/**
@@ -112,26 +110,34 @@ public abstract class ValidatorBase impl
* @param message The detail message to be displayed.
*/
public void setDetailMessage(String message) {
- _detailMessage = message;
+ getStateHelper().put(PropertyKeys.detailMessage, message);
}
/**
* @param context
*/
- public Object saveState(FacesContext context) {
- Object[] state = new Object[3];
- state[0] = _summaryMessage;
- state[1] = _detailMessage;
- state[2] = saveValueExpressionMap(context);
- return state;
+ public Object saveState(FacesContext context)
+ {
+ if (context == null)
+ {
+ throw new NullPointerException ("context");
+ }
+
+ StateHelper stateHelper = getStateHelper(false);
+ if (stateHelper != null)
+ {
+ return stateHelper.saveState(context);
+ }
+ else
+ {
+ return null;
+ }
}
- public void restoreState(FacesContext context, Object state) {
- Object[] values = (Object[]) state;
- _summaryMessage = (String) values[0];
- _detailMessage = (String) values[1];
- restoreValueExpressionMap(context, values[2]);
+ public void restoreState(FacesContext context, Object state)
+ {
+ getStateHelper().restoreState(context, state);
}
public boolean isTransient() {
@@ -166,69 +172,33 @@ public abstract class ValidatorBase impl
// --------------------- borrowed from UIComponentBase ------------
- private Map _valueExpressionMap = null;
-
+ @SuppressWarnings("unchecked")
public ValueExpression getValueExpression(String name)
{
if (name == null) throw new NullPointerException("name");
- if (_valueExpressionMap == null)
+ StateHelper helper = getStateHelper(false);
+ if (helper == null)
{
return null;
}
- else
+ Map<String,Object> bindings = (Map<String,Object>) helper.get(PropertyKeys.bindings);
+ if (bindings == null)
{
- return (ValueExpression)_valueExpressionMap.get(name);
- }
- }
-
- public void setValueExpression(String name,
- ValueExpression binding)
- {
- if (name == null) throw new NullPointerException("name");
- if (_valueExpressionMap == null)
- {
- _valueExpressionMap = new HashMap();
- }
- _valueExpressionMap.put(name, binding);
- }
-
- private Object saveValueExpressionMap(FacesContext context)
- {
- if (_valueExpressionMap != null)
- {
- int initCapacity = (_valueExpressionMap.size() * 4 + 3) / 3;
- HashMap stateMap = new HashMap(initCapacity);
- for (Iterator it = _valueExpressionMap.entrySet().iterator(); it.hasNext(); )
- {
- Map.Entry entry = (Map.Entry)it.next();
- stateMap.put(entry.getKey(),
- saveAttachedState(context, entry.getValue()));
- }
- return stateMap;
+ return null;
}
else
{
- return null;
+ return (ValueExpression) bindings.get(name);
}
}
-
- private void restoreValueExpressionMap(FacesContext context, Object stateObj)
+
+ public void setValueExpression(String name, ValueExpression expression)
{
- if (stateObj != null)
- {
- Map stateMap = (Map)stateObj;
- int initCapacity = (stateMap.size() * 4 + 3) / 3;
- _valueExpressionMap = new HashMap(initCapacity);
- for (Iterator it = stateMap.entrySet().iterator(); it.hasNext(); )
- {
- Map.Entry entry = (Map.Entry)it.next();
- _valueExpressionMap.put(entry.getKey(),
- restoreAttachedState(context, entry.getValue()));
- }
- }
- else
- {
- _valueExpressionMap = null;
+ if (name == null) throw new NullPointerException("name");
+ if (expression == null) {
+ getStateHelper().remove(PropertyKeys.bindings, name);
+ } else {
+ getStateHelper().put(PropertyKeys.bindings, name, expression);
}
}
@@ -257,30 +227,39 @@ public abstract class ValidatorBase impl
* of the provided object. When deserialized, a default instance of that
* type will be recreated.
*/
- public static Object saveAttachedState(FacesContext context,
- Object attachedObject)
+ public static Object saveAttachedState(FacesContext context, Object attachedObject)
{
- if (attachedObject == null) return null;
- if (attachedObject instanceof List)
+ if (context == null)
{
- List lst = new ArrayList(((List)attachedObject).size());
- for (Iterator it = ((List)attachedObject).iterator(); it.hasNext(); )
- {
- lst.add(saveAttachedState(context, it.next()));
- }
- return new _AttachedListStateWrapper(lst);
+ throw new NullPointerException ("context");
}
- else if (attachedObject instanceof StateHolder)
+
+ if (attachedObject == null)
+ return null;
+ // StateHolder interface should take precedence over
+ // List children
+ if (attachedObject instanceof StateHolder)
{
- if (((StateHolder)attachedObject).isTransient())
+ StateHolder holder = (StateHolder) attachedObject;
+ if (holder.isTransient())
{
return null;
}
- else
+
+ 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)
{
- return new _AttachedStateWrapper(attachedObject.getClass(),
- ((StateHolder)attachedObject).saveState(context));
+ if (item != null)
+ {
+ lst.add(saveAttachedState(context, item));
+ }
}
+
+ return new _AttachedListStateWrapper(lst);
}
else if (attachedObject instanceof Serializable)
{
@@ -292,25 +271,26 @@ public abstract class ValidatorBase impl
}
}
- public static Object restoreAttachedState(FacesContext context,
- Object stateObj)
- throws IllegalStateException
+ @SuppressWarnings("unchecked")
+ public static Object restoreAttachedState(FacesContext context, Object stateObj) throws IllegalStateException
{
- if (context == null) throw new NullPointerException("context");
- if (stateObj == null) return null;
+ if (context == null)
+ throw new NullPointerException("context");
+ if (stateObj == null)
+ return null;
if (stateObj instanceof _AttachedListStateWrapper)
{
- List lst = ((_AttachedListStateWrapper)stateObj).getWrappedStateList();
- List restoredList = new ArrayList(lst.size());
- for (Iterator it = lst.iterator(); it.hasNext(); )
+ List<Object> lst = ((_AttachedListStateWrapper) stateObj).getWrappedStateList();
+ List<Object> restoredList = new ArrayList<Object>(lst.size());
+ for (Object item : lst)
{
- restoredList.add(restoreAttachedState(context, it.next()));
+ restoredList.add(restoreAttachedState(context, item));
}
return restoredList;
}
else if (stateObj instanceof _AttachedStateWrapper)
{
- Class clazz = ((_AttachedStateWrapper)stateObj).getClazz();
+ Class<?> clazz = ((_AttachedStateWrapper) stateObj).getClazz();
Object restoredObject;
try
{
@@ -318,7 +298,8 @@ public abstract class ValidatorBase impl
}
catch (InstantiationException e)
{
- throw new RuntimeException("Could not restore StateHolder of type " + clazz.getName() + " (missing no-args constructor?)", e);
+ throw new RuntimeException("Could not restore StateHolder of type " + clazz.getName()
+ + " (missing no-args constructor?)", e);
}
catch (IllegalAccessException e)
{
@@ -326,8 +307,11 @@ public abstract class ValidatorBase impl
}
if (restoredObject instanceof StateHolder)
{
- Object wrappedState = ((_AttachedStateWrapper)stateObj).getWrappedStateObject();
- ((StateHolder)restoredObject).restoreState(context, wrappedState);
+ _AttachedStateWrapper wrapper = (_AttachedStateWrapper) stateObj;
+ Object wrappedState = wrapper.getWrappedStateObject();
+
+ StateHolder holder = (StateHolder) restoredObject;
+ holder.restoreState(context, wrappedState);
}
return restoredObject;
}
@@ -337,11 +321,63 @@ public abstract class ValidatorBase impl
}
}
-
protected FacesContext getFacesContext()
{
- return FacesContext.getCurrentInstance();
+ if (_facesContext == null)
+ {
+ return FacesContext.getCurrentInstance();
+ }
+ else
+ {
+ return _facesContext;
+ }
+ }
+
+ boolean isCachedFacesContext()
+ {
+ return _facesContext != null;
+ }
+
+ void setCachedFacesContext(FacesContext facesContext)
+ {
+ _facesContext = facesContext;
}
+
+ protected StateHelper getStateHelper() {
+ return getStateHelper(true);
+ }
+
+ /**
+ * returns a delta state saving enabled state helper
+ * for the current component
+ * @param create if true a state helper is created if not already existing
+ * @return an implementation of the StateHelper interface or null if none exists and create is set to false
+ */
+ protected StateHelper getStateHelper(boolean create) {
+ if(_stateHelper != null) {
+ return _stateHelper;
+ }
+ if(create) {
+ _stateHelper = new _DeltaStateHelper(this);
+ }
+ return _stateHelper;
+ }
+
+ public void clearInitialState()
+ {
+ _initialStateMarked = false;
+ }
+
+ public boolean initialStateMarked()
+ {
+ return _initialStateMarked;
+ }
+
+ public void markInitialState()
+ {
+ _initialStateMarked = true;
+ }
+
protected String getStringValue(FacesContext context, ValueExpression vb)
{
Object value = vb.getValue(context.getELContext());
@@ -351,4 +387,11 @@ public abstract class ValidatorBase impl
}
return null;
}
+
+ enum PropertyKeys
+ {
+ bindings,
+ summaryMessage,
+ detailMessage
+ }
}