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 2011/02/06 01:39:39 UTC
svn commit: r1067555 [1/2] - in /myfaces/tomahawk/trunk/sandbox/core20: ./
src/main/conf/META-INF/ src/main/java/org/apache/myfaces/custom/behavior/
src/main/java/org/apache/myfaces/custom/inputAjax/
src/main/java/org/apache/myfaces/custom/suggestajax/...
Author: lu4242
Date: Sun Feb 6 00:39:39 2011
New Revision: 1067555
URL: http://svn.apache.org/viewvc?rev=1067555&view=rev
Log:
TOMAHAWK-1558 Create custom base class for ClientBehaviors
Added:
myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/
myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/ClientBehaviorBase.java
myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/ClientBehaviorBaseTagHandler.java
myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/_AttachedListStateWrapper.java
myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/_AttachedStateWrapper.java
myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/_ClientBehaviorRule.java
myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/_DeltaStateHelper.java
myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/clientBehaviorClass20.vm
Removed:
myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/inputAjax/
myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/suggestajax/
Modified:
myfaces/tomahawk/trunk/sandbox/core20/pom.xml
myfaces/tomahawk/trunk/sandbox/core20/src/main/conf/META-INF/faces-config-base.xml
myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/facelets-taglib20.vm
myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/faces-config20.vm
Modified: myfaces/tomahawk/trunk/sandbox/core20/pom.xml
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core20/pom.xml?rev=1067555&r1=1067554&r2=1067555&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core20/pom.xml (original)
+++ myfaces/tomahawk/trunk/sandbox/core20/pom.xml Sun Feb 6 00:39:39 2011
@@ -269,7 +269,36 @@
org/apache/myfaces/custom/submitOnEvent/**/*.java,
org/apache/myfaces/custom/suggestajax/**/*.java,
org/apache/myfaces/custom/table/**/*.java,
- org/apache/myfaces/custom/timednotifier/**/*.java
+ org/apache/myfaces/custom/timednotifier/**/*.java,
+ org/apache/myfaces/convert/ex/**/*.java,
+ org/apache/myfaces/custom/ajax/**/*.java,
+ org/apache/myfaces/custom/autoupdatedatatable/**/*.java,
+ org/apache/myfaces/custom/clientvalidation/**/*.java,
+ org/apache/myfaces/custom/comparetovalidator/**/*.java,
+ org/apache/myfaces/custom/conversation/**/*.java,
+ org/apache/myfaces/custom/convertboolean/**/*.java,
+ org/apache/myfaces/custom/convertDateTime/**/*.java,
+ org/apache/myfaces/custom/convertNumber/**/*.java,
+ org/apache/myfaces/custom/csvvalidator/**/*.java,
+ org/apache/myfaces/custom/dynamicResources/**/*.java,
+ org/apache/myfaces/custom/exporter/**/*.java,
+ org/apache/myfaces/custom/form/**/*.java,
+ org/apache/myfaces/custom/globalId/**/*.java,
+ org/apache/myfaces/custom/graphicimagedynamic/**/*.java,
+ org/apache/myfaces/custom/inputAjax/**/*.java,
+ org/apache/myfaces/custom/isbnvalidator/**/*.java,
+ org/apache/myfaces/custom/outputlinkdynamic/**/*.java,
+ org/apache/myfaces/custom/redirectTracker/**/*.java,
+ org/apache/myfaces/custom/renderOne/**/*.java,
+ org/apache/myfaces/custom/requestParameterProvider/**/*.java,
+ org/apache/myfaces/custom/scope/**/*.java,
+ org/apache/myfaces/custom/security/**/*.java,
+ org/apache/myfaces/custom/suggest/**/*.java,
+ org/apache/myfaces/custom/urlvalidator/**/*.java,
+ org/apache/myfaces/custom/util/**/*.java,
+ org/apache/myfaces/renderkit/**/*.java,
+ org/apache/myfaces/tomahawk/util/**/*.java,
+ org/apache/myfaces/validator/ex/**/*.java
</excludes>
</artifactItem>
</artifactItems>
@@ -354,6 +383,15 @@
</configuration>
</execution>
<execution>
+ <id>make-client-behaviors</id>
+ <goals>
+ <goal>make-client-behaviors</goal>
+ </goals>
+ <configuration>
+ <mainSourceDirectory2>${project.build.directory}/tomahawk12_sources</mainSourceDirectory2>
+ </configuration>
+ </execution>
+ <execution>
<id>maketags</id>
<configuration>
<jsfVersion>12</jsfVersion>
@@ -379,7 +417,7 @@
<configuration>
<xmlFile>META-INF/myfaces_sandbox.tld</xmlFile>
<xmlBaseFile>src/main/conf/META-INF/myfaces_sandbox-base.tld</xmlBaseFile>
- <templateFile>tomahawk12.vm</templateFile>
+ <templateFile>tld-tomahawk20.vm</templateFile>
<params>
<shortname>s</shortname>
<uri>http://myfaces.apache.org/sandbox</uri>
@@ -387,7 +425,7 @@
<description>Enhanced standard JSP actions and custom MyFaces actions.</description>
</params>
<modelIds>
- <modelId>tomahawk-sandbox12</modelId>
+ <modelId>tomahawk-sandbox20</modelId>
</modelIds>
</configuration>
<goals>
@@ -405,7 +443,7 @@
<uri>http://myfaces.apache.org/sandbox</uri>
</params>
<modelIds>
- <modelId>tomahawk-sandbox12</modelId>
+ <modelId>tomahawk-sandbox20</modelId>
</modelIds>
</configuration>
<goals>
Modified: myfaces/tomahawk/trunk/sandbox/core20/src/main/conf/META-INF/faces-config-base.xml
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core20/src/main/conf/META-INF/faces-config-base.xml?rev=1067555&r1=1067554&r2=1067555&view=diff
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core20/src/main/conf/META-INF/faces-config-base.xml (original)
+++ myfaces/tomahawk/trunk/sandbox/core20/src/main/conf/META-INF/faces-config-base.xml Sun Feb 6 00:39:39 2011
@@ -21,16 +21,31 @@
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
- version="1.2">
-
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
+ version="2.0">
+
+
<lifecycle>
+ <!--
<phase-listener>org.apache.myfaces.custom.ajax.api.AjaxDecodePhaseListener</phase-listener>
+ -->
<phase-listener>org.apache.myfaces.custom.valueChangeNotifier.ValueChangePhaseListener</phase-listener>
+ <!--
<phase-listener>org.apache.myfaces.custom.redirectTracker.RedirectTrackerPhaseListener</phase-listener>
- <phase-listener>org.apache.myfaces.custom.ppr.PPRPhaseListener</phase-listener>
+ <phase-listener>org.apache.myfaces.custom.ppr.PPRPhaseListener</phase-listener>
+ -->
</lifecycle>
-
+
+ <!--
+ <render-kit>
+ <client-behavior-renderer>
+ <client-behavior-renderer-type>org.apache.myfaces.custom.effect.EffectAppearBehavior</client-behavior-renderer-type>
+ <client-behavior-renderer-class>org.apache.myfaces.custom.effect.EffectAppearClientBehaviorRenderer</client-behavior-renderer-class>
+ </client-behavior-renderer>
+ </render-kit>
+ -->
+
+ <!--
<application>
<variable-resolver>org.apache.myfaces.custom.redirectTracker.RedirectTrackerVariableResolver</variable-resolver>
<navigation-handler>org.apache.myfaces.custom.redirectTracker.RedirectTrackerNavigationHandler</navigation-handler>
@@ -41,8 +56,10 @@
<factory>
<lifecycle-factory>org.apache.myfaces.custom.ppr.PPRLifecycleFactory</lifecycle-factory>
</factory>
+ -->
<!-- sandbox managed beans -->
+ <!--
<managed-bean>
<managed-bean-name>ScopeContainer</managed-bean-name>
<managed-bean-class>org.apache.myfaces.custom.scope.ScopeHolder</managed-bean-class>
@@ -55,8 +72,10 @@
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
-
+ -->
+
<!-- extended converters and validators -->
+ <!--
<converter>
<converter-id>javax.faces.Integer</converter-id>
<converter-class>org.apache.myfaces.convert.ex.IntegerConverter</converter-class>
@@ -110,5 +129,6 @@
<validator-id>javax.faces.DoubleRange</validator-id>
<validator-class>org.apache.myfaces.validator.ex.DoubleRangeValidator</validator-class>
</validator>
+ -->
</faces-config>
Added: myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/ClientBehaviorBase.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/ClientBehaviorBase.java?rev=1067555&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/ClientBehaviorBase.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/ClientBehaviorBase.java Sun Feb 6 00:39:39 2011
@@ -0,0 +1,325 @@
+/*
+ * 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.custom.behavior;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+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.context.FacesContext;
+
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFClientBehavior;
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
+
+/**
+ * Base behavior implementation for Apache MyFaces Tomahawk.
+ *
+ */
+@JSFClientBehavior(
+ configExcluded = true,
+ evaluateELOnExecution = true,
+ tagHandler = "org.apache.myfaces.custom.behavior.ClientBehaviorBaseTagHandler")
+public abstract class ClientBehaviorBase extends
+ javax.faces.component.behavior.ClientBehaviorBase
+{
+
+ private transient FacesContext _facesContext;
+ private StateHelper _stateHelper = null;
+
+ /**
+ * @param context
+ */
+ @Override
+ public Object saveState(FacesContext facesContext)
+ {
+ if (initialStateMarked())
+ {
+ Object parentSaved = super.saveState(facesContext);
+ Object stateHelperSaved = null;
+ StateHelper stateHelper = getStateHelper(false);
+ if (stateHelper != null)
+ {
+ stateHelperSaved = stateHelper.saveState(facesContext);
+ }
+
+ if (parentSaved == null && stateHelperSaved == null)
+ {
+ //No values
+ return null;
+ }
+ return new Object[] { parentSaved, stateHelperSaved };
+ }
+ else
+ {
+ Object[] values = new Object[2];
+ values[0] = super.saveState(facesContext);
+ StateHelper stateHelper = getStateHelper(false);
+ if (stateHelper != null)
+ {
+ values[1] = stateHelper.saveState(facesContext);
+ }
+ return values;
+ }
+ }
+
+ @Override
+ public void restoreState(FacesContext facesContext, Object o)
+ {
+ if (o == null)
+ {
+ return;
+ }
+ Object[] values = (Object[]) o;
+ if (values[0] != null)
+ {
+ super.restoreState(facesContext, values[0]);
+ }
+ getStateHelper().restoreState(facesContext, values[1]);
+ }
+
+ // --------------------- borrowed from UIComponentBase ------------
+
+ @SuppressWarnings("unchecked")
+ public ValueExpression getValueExpression(String name)
+ {
+ if (name == null)
+ throw new NullPointerException("name");
+ StateHelper helper = getStateHelper(false);
+ if (helper == null)
+ {
+ return null;
+ }
+ Map<String, Object> bindings = (Map<String, Object>) helper
+ .get(PropertyKeys.bindings);
+ if (bindings == null)
+ {
+ return null;
+ }
+ else
+ {
+ return (ValueExpression) bindings.get(name);
+ }
+ }
+
+ public void setValueExpression(String name, ValueExpression expression)
+ {
+ if (name == null)
+ throw new NullPointerException("name");
+ if (expression == null)
+ {
+ getStateHelper().remove(PropertyKeys.bindings, name);
+ }
+ else
+ {
+ getStateHelper().put(PropertyKeys.bindings, name, expression);
+ }
+ }
+
+ /**
+ * Serializes objects which are "attached" to this component but which are
+ * not UIComponent children of it. Examples are validator and listener
+ * objects. To be precise, it returns an object which implements
+ * java.io.Serializable, and which when serialized will persist the
+ * state of the provided object.
+ * <p>
+ * If the attachedObject is a List then every object in the list is saved
+ * via a call to this method, and the returned wrapper object contains
+ * a List object.
+ * <p>
+ * If the object implements StateHolder then the object's saveState is
+ * called immediately, and a wrapper is returned which contains both
+ * this saved state and the original class name. However in the case
+ * where the StateHolder.isTransient method returns true, null is
+ * returned instead.
+ * <p>
+ * If the object implements java.io.Serializable then the object is simply
+ * returned immediately; standard java serialization will later be used
+ * to store this object.
+ * <p>
+ * In all other cases, a wrapper is returned which simply stores the type
+ * of the provided object. When deserialized, a default instance of that
+ * type will be recreated.
+ */
+ public static Object saveAttachedState(FacesContext context,
+ Object attachedObject)
+ {
+ if (context == null)
+ {
+ throw new NullPointerException("context");
+ }
+
+ if (attachedObject == null)
+ return null;
+ // StateHolder interface should take precedence over
+ // List children
+ if (attachedObject instanceof StateHolder)
+ {
+ StateHolder holder = (StateHolder) attachedObject;
+ if (holder.isTransient())
+ {
+ return null;
+ }
+
+ 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)
+ {
+ if (item != null)
+ {
+ lst.add(saveAttachedState(context, item));
+ }
+ }
+
+ return new _AttachedListStateWrapper(lst);
+ }
+ else if (attachedObject instanceof Serializable)
+ {
+ return attachedObject;
+ }
+ else
+ {
+ return new _AttachedStateWrapper(attachedObject.getClass(), null);
+ }
+ }
+
+ @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 (stateObj instanceof _AttachedListStateWrapper)
+ {
+ List<Object> lst = ((_AttachedListStateWrapper) stateObj)
+ .getWrappedStateList();
+ List<Object> restoredList = new ArrayList<Object>(lst.size());
+ for (Object item : lst)
+ {
+ restoredList.add(restoreAttachedState(context, item));
+ }
+ return restoredList;
+ }
+ else if (stateObj instanceof _AttachedStateWrapper)
+ {
+ Class<?> clazz = ((_AttachedStateWrapper) stateObj).getClazz();
+ Object restoredObject;
+ try
+ {
+ restoredObject = clazz.newInstance();
+ }
+ catch (InstantiationException e)
+ {
+ throw new RuntimeException(
+ "Could not restore StateHolder of type "
+ + clazz.getName()
+ + " (missing no-args constructor?)", e);
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new RuntimeException(e);
+ }
+ if (restoredObject instanceof StateHolder)
+ {
+ _AttachedStateWrapper wrapper = (_AttachedStateWrapper) stateObj;
+ Object wrappedState = wrapper.getWrappedStateObject();
+
+ StateHolder holder = (StateHolder) restoredObject;
+ holder.restoreState(context, wrappedState);
+ }
+ return restoredObject;
+ }
+ else
+ {
+ return stateObj;
+ }
+ }
+
+ protected FacesContext getFacesContext()
+ {
+ 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;
+ }
+
+ /**
+ * The event that this client behavior should be attached.
+ *
+ * @return
+ */
+ @JSFProperty
+ private String getEvent()
+ {
+ return null;
+ }
+
+ enum PropertyKeys
+ {
+ bindings
+ }
+}
Added: myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/ClientBehaviorBaseTagHandler.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/ClientBehaviorBaseTagHandler.java?rev=1067555&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/ClientBehaviorBaseTagHandler.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/ClientBehaviorBaseTagHandler.java Sun Feb 6 00:39:39 2011
@@ -0,0 +1,47 @@
+/*
+ * 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.custom.behavior;
+
+import javax.faces.view.facelets.BehaviorConfig;
+import javax.faces.view.facelets.BehaviorHandler;
+import javax.faces.view.facelets.MetaRuleset;
+
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
+
+@JSFFaceletTag
+public class ClientBehaviorBaseTagHandler extends BehaviorHandler
+{
+
+ public ClientBehaviorBaseTagHandler(BehaviorConfig config)
+ {
+ super(config);
+ }
+
+ @Override
+ protected MetaRuleset createMetaRuleset(Class type)
+ {
+ MetaRuleset ruleSet = super.createMetaRuleset(type);
+
+ //Add rule to handle EL expressions
+ ruleSet.addRule(_ClientBehaviorRule.Instance);
+
+ return ruleSet;
+ }
+
+}
Added: myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/_AttachedListStateWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/_AttachedListStateWrapper.java?rev=1067555&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/_AttachedListStateWrapper.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/_AttachedListStateWrapper.java Sun Feb 6 00:39:39 2011
@@ -0,0 +1,43 @@
+/*
+ * 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.custom.behavior;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author Manfred Geiler (latest modification by $Author: bdudney $)
+ * @version $Revision: 225333 $ $Date: 2005-07-26 17:49:19 +0200 (Di, 26 Jul 2005) $
+ */
+class _AttachedListStateWrapper
+ implements Serializable
+{
+ private static final long serialVersionUID = -3958718149793179776L;
+ private List _wrappedStateList;
+
+ public _AttachedListStateWrapper(List wrappedStateList)
+ {
+ _wrappedStateList = wrappedStateList;
+ }
+
+ public List getWrappedStateList()
+ {
+ return _wrappedStateList;
+ }
+}
Added: myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/_AttachedStateWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/_AttachedStateWrapper.java?rev=1067555&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/_AttachedStateWrapper.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/_AttachedStateWrapper.java Sun Feb 6 00:39:39 2011
@@ -0,0 +1,57 @@
+/*
+ * 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.custom.behavior;
+
+import java.io.Serializable;
+
+/**
+ * @author Manfred Geiler (latest modification by $Author: bdudney $)
+ * @version $Revision: 225333 $ $Date: 2005-07-26 17:49:19 +0200 (Di, 26 Jul 2005) $
+ */
+class _AttachedStateWrapper
+ implements Serializable
+{
+ private static final long serialVersionUID = 4948301780259917764L;
+ private Class _class;
+ private Object _wrappedStateObject;
+
+ /**
+ * @param clazz null means wrappedStateObject is a List of state objects
+ * @param wrappedStateObject
+ */
+ public _AttachedStateWrapper(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;
+ }
+}
Added: myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/_ClientBehaviorRule.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/_ClientBehaviorRule.java?rev=1067555&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/_ClientBehaviorRule.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/_ClientBehaviorRule.java Sun Feb 6 00:39:39 2011
@@ -0,0 +1,99 @@
+/*
+ * 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.custom.behavior;
+
+import javax.faces.view.facelets.FaceletContext;
+import javax.faces.view.facelets.MetaRule;
+import javax.faces.view.facelets.Metadata;
+import javax.faces.view.facelets.MetadataTarget;
+import javax.faces.view.facelets.TagAttribute;
+
+final class _ClientBehaviorRule extends MetaRule {
+
+ final static class ValueExpressionMetadata extends Metadata {
+
+ private final String name;
+
+ private final TagAttribute attr;
+
+ private final Class type;
+
+ public ValueExpressionMetadata(String name, Class type,
+ TagAttribute attr) {
+ this.name = name;
+ this.attr = attr;
+ this.type = type;
+ }
+
+ public void applyMetadata(FaceletContext ctx, Object instance) {
+ ((ClientBehaviorBase) instance).setValueExpression(this.name, this.attr
+ .getValueExpression(ctx, this.type));
+ }
+
+ }
+
+ /*
+ final static class ValueBindingMetadata extends Metadata {
+
+ private final String name;
+
+ private final TagAttribute attr;
+
+ private final Class type;
+
+ public ValueBindingMetadata(String name, Class type, TagAttribute attr) {
+ this.name = name;
+ this.attr = attr;
+ this.type = type;
+ }
+
+ public void applyMetadata(FaceletContext ctx, Object instance) {
+ ((ValidatorBase) instance).setValueBinding(this.name,
+ new LegacyValueBinding(this.attr.getValueExpression(ctx,
+ this.type)));
+ }
+
+ }*/
+
+ public final static _ClientBehaviorRule Instance = new _ClientBehaviorRule();
+
+ public _ClientBehaviorRule() {
+ super();
+ }
+
+ public Metadata applyRule(String name, TagAttribute attribute,
+ MetadataTarget meta) {
+ if (meta.isTargetInstanceOf(ClientBehaviorBase.class)) {
+
+ // if component and dynamic, then must set expression
+ if (!attribute.isLiteral()) {
+ Class type = meta.getPropertyType(name);
+ if (type == null) {
+ type = Object.class;
+ }
+ //if (FacesAPI.getComponentVersion(meta.getTargetClass()) >= 12) {
+ return new ValueExpressionMetadata(name, type, attribute);
+ //} else {
+ // return new ValueBindingMetadata(name, type, attribute);
+ //}
+ }
+ }
+ return null;
+ }
+}
Added: myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/_DeltaStateHelper.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/_DeltaStateHelper.java?rev=1067555&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/_DeltaStateHelper.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core20/src/main/java/org/apache/myfaces/custom/behavior/_DeltaStateHelper.java Sun Feb 6 00:39:39 2011
@@ -0,0 +1,825 @@
+/*
+ * 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.custom.behavior;
+
+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.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 ClientBehaviorBase _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(ClientBehaviorBase 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 = ClientBehaviorBase.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] = ValidatorBase.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 = ClientBehaviorBase.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) ClientBehaviorBase
+ .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] = ClientBehaviorBase.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) ClientBehaviorBase.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] = ClientBehaviorBase.saveAttachedState(context, value);
+ }
+ else
+ {
+ values[i] = value;
+ }
+ }
+ return values;
+ }
+ }
+}
Added: myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/clientBehaviorClass20.vm
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/clientBehaviorClass20.vm?rev=1067555&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/clientBehaviorClass20.vm (added)
+++ myfaces/tomahawk/trunk/sandbox/core20/src/main/resources/META-INF/clientBehaviorClass20.vm Sun Feb 6 00:39:39 2011
@@ -0,0 +1,668 @@
+## Velocity template used to generate JSF1.2-compatible clientBehavior classes
+## from clientBehavior meta-data.
+##
+## Note that there are only one type of clientBehavior generation:
+## * "subclass mode" (use annotated class as a parent class)
+##
+## Variable $clientBehavior refers to a BehaviorMeta object to process
+## Variable $utils refers to an instance of MyfacesUtils.
+##
+##
+## The java package of the generated class is always the same as
+## the package in which the annotated class exists.
+##
+/*
+ * 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 ${clientBehavior.packageName};
+
+import javax.el.ValueExpression;
+import javax.faces.context.FacesContext;
+$utils.importTagClasses($clientBehavior)
+
+#if ($clientBehavior.isTemplate())
+#set ($generatedClassParent = $clientBehavior.sourceClassParentClassName)
+#else
+#set ($generatedClassParent = $clientBehavior.sourceClassName)
+#end
+// Generated from class ${clientBehavior.sourceClassName}.
+//
+// WARNING: This file was automatically generated. Do not edit it directly,
+// or you will lose your changes.
+public class ${utils.getClassFromFullClass($clientBehavior.className)} extends $generatedClassParent
+#if ($clientBehavior.implements)
+ implements $clientBehavior.implements
+#end
+{
+
+#if ($clientBehavior.behaviorId)
+ static public final String BEHAVIOR_ID =
+ "$clientBehavior.behaviorId";
+#end
+#if ($clientBehavior.rendererType)
+#if (!($clientBehavior.rendererType == ""))
+ static public final String RENDERER_TYPE =
+ "$clientBehavior.rendererType";
+#end
+#end
+
+ public ${utils.getClassFromFullClass($clientBehavior.className)}()
+ {
+ }
+
+#if ($clientBehavior.rendererType)
+#if ($clientBehavior.rendererType == "")
+#else
+ public String getRendererType()
+ {
+ return "$clientBehavior.rendererType";
+ }
+#end
+#end
+
+
+
+## ----------------------------- PROPERTY MACROS -----------------------------
+##
+## -------------------------------
+## writePropertySetDeclaration
+## -------------------------------
+##
+#macro (writePropertySetDeclaration $property $type $field $defaultValue )
+#if($utils.isPrimitiveClass($type) && !$property.isTagExcluded() )
+ private boolean ${field}Set;
+
+#end
+#end
+##
+## -------------------------------
+## writePropertyDeclaration
+## -------------------------------
+##
+#macro( writePropertyDeclaration $property $type $field $defaultValue )
+#if ($property.isLiteralOnly() || $property.isTagExcluded() || !($clientBehavior.isEvaluateELOnExecution()))
+ private $type $field #if($defaultValue) = $defaultValue;#{else};#{end}
+
+#else
+ private $type $field;
+
+#end
+#writePropertySetDeclaration ($property $type $field $defaultValue)
+#end
+##
+## -------------------------------
+## writeLocalPropertyGetter
+## -------------------------------
+##
+#macro (writeLocalPropertyGetter $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}()
+ {
+ return $field;
+ }
+
+#end
+#end
+##
+## -------------------------------
+## writePropertyGetter
+## -------------------------------
+##
+#macro (writePropertyGetter $property $type $field $defaultValue )
+ public $type $utils.getMethodReaderFromProperty($property.name, $type)()
+ {
+#if ($property.isTagExcluded() || $property.isLiteralOnly() || !($clientBehavior.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
+ }
+
+#end
+##
+## -------------------------------
+## writePropertySetter
+## -------------------------------
+##
+#macro (writePropertySetter $property $type $field $defaultValue )
+ public void $utils.getPrefixedPropertyName("set", $property.name)($type $utils.getVariableFromName($property.name))
+ {
+ this.$field = $utils.getVariableFromName($property.name);
+#if ($utils.isPrimitiveClass($type) && !$property.isTagExcluded() )
+ this.${field}Set = true;
+#end
+ }
+
+#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() || !($clientBehavior.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 --------------------
+#set ($propertyList = ${clientBehavior.propertyBehaviorList})
+
+#foreach( $property in $propertyList )
+#set ($field = $property.fieldName)
+#set ($type = $utils.getClassFromFullClass($property.className))
+#if($utils.getDefaultValueField($property))
+#set ($defaultValue = $utils.getDefaultValueField($property))
+#else
+#set ($defaultValue = false)
+#end
+ // Property: $property.name
+#if ($clientBehavior.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 ( !($clientBehavior.isEvaluateELOnExecution()) )
+
+ public Object saveState(FacesContext facesContext)
+ {
+#set ($primitiveCount = $propertyList.size() + 1)
+#foreach( $property in $propertyList )
+#if($utils.isPrimitiveClass($property.className))
+#set ($primitiveCount = $primitiveCount + 1)
+#end
+#end
+ Object[] values = new Object[$primitiveCount];
+ values[0] = super.saveState(facesContext);
+#set ($arrayIndex = 0)
+#foreach( $property in $propertyList )
+#set ($field = $property.fieldName)
+#set ($type = $property.className)
+#set ($arrayIndex = $arrayIndex + 1)
+#if ($property.jspName == "validator" && $property.isMethodBinding() )
+ values[$arrayIndex] = saveAttachedState(facesContext,${field}List);
+#elseif ( $property.isStateHolder() )## || $utils.isConverter($type)
+ values[$arrayIndex] = saveAttachedState(facesContext,$field);
+#elseif($utils.isPrimitiveClass($type))
+ values[$arrayIndex] = ${utils.getBoxedClass($type)}.valueOf($field);
+#else
+ values[$arrayIndex] = $field;
+#end
+#if($utils.isPrimitiveClass($type) && !$property.isTagExcluded())
+#set ($arrayIndex = $arrayIndex + 1)
+ values[$arrayIndex] = Boolean.valueOf(${field}Set);
+#end
+#end
+ return values;
+ }
+
+ public void restoreState(FacesContext facesContext, Object state)
+ {
+ Object[] values = (Object[])state;
+ super.restoreState(facesContext,values[0]);
+#set ($arrayIndex = 0)
+#foreach( $property in $propertyList )
+#set ($field = $property.fieldName)
+#set ($type = $property.className)
+#set ($arrayIndex = $arrayIndex + 1)
+#if ( $property.isStateHolder() )
+#if ($property.jspName == "validator" && $property.isMethodBinding() )
+ ${field}List = (List<Validator>) restoreAttachedState(facesContext,values[$arrayIndex]);
+#elseif ($utils.isList($type))
+ $field = (List) restoreAttachedState(facesContext,values[$arrayIndex]);
+#else
+ $field = $utils.castIfNecessary($type) restoreAttachedState(facesContext,values[$arrayIndex]);
+#end
+#elseif ($utils.isConverter($type))
+ $field = (Converter) restoreAttachedState(facesContext,values[$arrayIndex]);
+#elseif ($utils.isPrimitiveClass($type))
+ $field = ($utils.castIfNecessary($type) values[$arrayIndex]).${type}Value();
+#else
+ $field = $utils.castIfNecessary($type) values[$arrayIndex];
+#end
+#if($utils.isPrimitiveClass($type) && !$property.isTagExcluded() )
+#set ($arrayIndex = $arrayIndex + 1)
+ ${field}Set = ((Boolean) values[$arrayIndex]).booleanValue();
+#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
+}