(TRINIDAD-2545)
Update of view state in partial response not working (JSF 2.2)
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/PartialViewContextImpl.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/PartialViewContextImpl.java
index a2d6fe8..1f2daa0 100644
--- a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/PartialViewContextImpl.java
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/PartialViewContextImpl.java
@@ -51,6 +51,7 @@
import org.apache.myfaces.trinidadinternal.renderkit.core.ppr.PPRResponseWriter;
import org.apache.myfaces.trinidadinternal.renderkit.core.ppr.XmlResponseWriter;
import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.PartialPageUtils;
+import org.apache.myfaces.trinidadinternal.util.StateUtils;
public class PartialViewContextImpl
@@ -368,7 +369,7 @@
rw.endUpdate();
//write out JSF state
- rw.startUpdate(PartialResponseWriter.VIEW_STATE_MARKER);
+ rw.startUpdate(StateUtils.getViewStateId(FacesContext.getCurrentInstance()));
String state = context.getApplication().getStateManager().getViewState(context);
rw.write(state);
rw.endUpdate();
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/CoreResponseStateManager.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/CoreResponseStateManager.java
index ac63e54..ea60461 100644
--- a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/CoreResponseStateManager.java
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/CoreResponseStateManager.java
@@ -31,6 +31,7 @@
import org.apache.myfaces.trinidad.logging.TrinidadLogger;
import org.apache.myfaces.trinidadinternal.application.StateManagerImpl;
+import org.apache.myfaces.trinidadinternal.util.JsfUtils;
import org.apache.myfaces.trinidadinternal.util.StateUtils;
/**
@@ -76,9 +77,10 @@
rw.startElement("input", null);
rw.writeAttribute("type", "hidden", null);
rw.writeAttribute("name", VIEW_STATE_PARAM, null);
- // Don't write out the ID, as it can be written
- // out twice
- // rw.writeAttribute("id", VIEW_STATE_PARAM, null);
+ if (JsfUtils.IS_JSF_2_2)
+ {
+ rw.writeAttribute("id", StateUtils.getViewStateId(context), null);
+ }
String s = encodeSerializedViewAsString(context, serializedView);
rw.writeAttribute("value", s, null);
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/ppr/PPRResponseWriter.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/ppr/PPRResponseWriter.java
index c90bae1..d2efd66 100644
--- a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/ppr/PPRResponseWriter.java
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/ppr/PPRResponseWriter.java
@@ -41,6 +41,7 @@
import org.apache.myfaces.trinidadinternal.io.ResponseWriterDecorator;
import org.apache.myfaces.trinidadinternal.renderkit.core.pages.GenericEntry;
+import org.apache.myfaces.trinidadinternal.util.StateUtils;
/**
* Write out a PPR response in the following form:
@@ -305,7 +306,8 @@
{
_startChanges();
_xml.startElement(_ELEMENT_CHANGES_UPDATE, null);
- _xml.writeAttribute(_ATTRIBUTE_ID, PartialResponseWriter.VIEW_STATE_MARKER, null);
+ //_xml.writeAttribute(_ATTRIBUTE_ID, PartialResponseWriter.VIEW_STATE_MARKER, null);
+ _xml.writeAttribute(_ATTRIBUTE_ID, StateUtils.getViewStateId(FacesContext.getCurrentInstance()), null);
_xml.startCDATA();
_xml.write(state);
_xml.endCDATA();
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/FormRenderer.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/FormRenderer.java
index ac4e351..5989677 100644
--- a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/FormRenderer.java
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/FormRenderer.java
@@ -53,6 +53,8 @@
import org.apache.myfaces.trinidadinternal.renderkit.core.CoreResponseStateManager;
import org.apache.myfaces.trinidadinternal.renderkit.uix.SubformRenderer;
import org.apache.myfaces.trinidadinternal.share.data.ServletRequestParameters;
+import org.apache.myfaces.trinidadinternal.util.JsfUtils;
+import org.apache.myfaces.trinidadinternal.util.StateUtils;
// TODO: Remove this class
@@ -430,6 +432,10 @@
rw.writeAttribute("type", "hidden", null);
rw.writeAttribute("name",
PartialResponseWriter.VIEW_STATE_MARKER , null);
+ if (JsfUtils.IS_JSF_2_2)
+ {
+ rw.writeAttribute("id", StateUtils.getViewStateId(context), null);
+ }
rw.writeAttribute("value", state, null);
rw.endElement("input");
}
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/ClassUtils.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/ClassUtils.java
index 25a7b77..895b8c1 100755
--- a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/ClassUtils.java
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/ClassUtils.java
@@ -658,4 +658,13 @@
return current;
}
+
+ public static boolean isPresent(String className) {
+ try {
+ classForName(className);
+ return true;
+ } catch (Throwable ex) {
+ return false;
+ }
+ }
}
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/JsfUtils.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/JsfUtils.java
new file mode 100644
index 0000000..893f6e2
--- /dev/null
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/JsfUtils.java
@@ -0,0 +1,28 @@
+/*
+ * 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.trinidadinternal.util;
+
+public class JsfUtils {
+
+ public static final boolean IS_JSF_2_2 = ClassUtils.isPresent("javax.faces.flow.Flow");
+
+ private JsfUtils() {
+ }
+
+}
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/StateUtils.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/StateUtils.java
index 8600614..5f9c20a 100644
--- a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/StateUtils.java
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/StateUtils.java
@@ -42,7 +42,10 @@
import javax.crypto.spec.SecretKeySpec;
import javax.faces.FacesException;
import javax.faces.application.ViewExpiredException;
+import javax.faces.component.UINamingContainer;
import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.render.ResponseStateManager;
import javax.servlet.ServletContext;
import org.apache.commons.codec.binary.Base64;
@@ -183,13 +186,36 @@
*/
@JSFWebConfigParam(name="org.apache.myfaces.MAC_SECRET.CACHE",group="state")
public static final String INIT_MAC_SECRET_KEY_CACHE = "org.apache.myfaces.MAC_SECRET.CACHE";
-
+
+ private static final String VIEW_STATE_COUNTER = "org.apache.myfaces.trinidad.partial.VIEW_STATE_COUNTER";
+
/** Utility class, do not instatiate */
private StateUtils()
{
//nope
}
+ public static String getViewStateId(FacesContext facesContext)
+ {
+ if (JsfUtils.IS_JSF_2_2) {
+
+ Integer count = (Integer) facesContext.getAttributes().get(VIEW_STATE_COUNTER);
+ if (count == null)
+ {
+ count = 0;
+ }
+ count += 1;
+ String id = facesContext.getViewRoot().getContainerClientId(facesContext)
+ + UINamingContainer.SEPARATOR_CHAR + ResponseStateManager.VIEW_STATE_PARAM + UINamingContainer.SEPARATOR_CHAR + count;
+ facesContext.getAttributes().put(VIEW_STATE_COUNTER, count);
+ return id;
+ }
+ else
+ {
+ return ResponseStateManager.VIEW_STATE_PARAM;
+ }
+ }
+
private static void testConfiguration(ExternalContext ctx)
{