You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by mm...@apache.org on 2007/10/26 13:39:20 UTC
svn commit: r588608 - in /myfaces:
core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/application/jsp/
core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/renderkit/html/
shared/branches/3_0_1/core/src/main/java/org/apache/myfaces/shared/c...
Author: mmarinschek
Date: Fri Oct 26 04:39:18 2007
New Revision: 588608
URL: http://svn.apache.org/viewvc?rev=588608&view=rev
Log:
https://issues.apache.org/jira/browse/MYFACES-1742 (MYFACES-1742): Improved view-state handling in View-Handler. Thanks to Michael Kurz.
Modified:
myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/application/jsp/JspViewHandlerImpl.java
myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlFormRenderer.java
myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlResponseStateManager.java
myfaces/shared/branches/3_0_1/core/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java
myfaces/shared/branches/3_0_1/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java
Modified: myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/application/jsp/JspViewHandlerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/application/jsp/JspViewHandlerImpl.java?rev=588608&r1=588607&r2=588608&view=diff
==============================================================================
--- myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/application/jsp/JspViewHandlerImpl.java (original)
+++ myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/application/jsp/JspViewHandlerImpl.java Fri Oct 26 04:39:18 2007
@@ -20,6 +20,8 @@
import org.apache.myfaces.application.DefaultViewHandlerSupport;
import org.apache.myfaces.application.InvalidViewIdException;
import org.apache.myfaces.application.ViewHandlerSupport;
+import org.apache.myfaces.shared_impl.config.MyfacesConfig;
+import org.apache.myfaces.shared_impl.renderkit.html.util.JavascriptUtils;
import javax.faces.FacesException;
import javax.faces.FactoryFinder;
@@ -414,17 +416,51 @@
*/
public void writeState(FacesContext facesContext) throws IOException
{
- facesContext.getResponseWriter().write(FORM_STATE_MARKER);
+ // Only write state marker if javascript view state is disabled
+ ExternalContext extContext = facesContext.getExternalContext();
+ if (!(JavascriptUtils.isJavascriptAllowed(extContext) && MyfacesConfig.getCurrentInstance(extContext).isViewStateJavascript())) {
+ facesContext.getResponseWriter().write(FORM_STATE_MARKER);
+ }
}
/**
* Writes the response and replaces the state marker tags with the state information for the current context
*/
- private static class StateMarkerAwareWriter extends StringWriter
+ private static class StateMarkerAwareWriter extends Writer
{
- public StateMarkerAwareWriter()
- {
- }
+ private StringBuilder buf;
+
+ public StateMarkerAwareWriter()
+ {
+ this.buf = new StringBuilder();
+ }
+
+ @Override
+ public void close() throws IOException
+ {
+ }
+
+ @Override
+ public void flush() throws IOException
+ {
+ }
+
+ @Override
+ public void write(char[] cbuf, int off, int len) throws IOException
+ {
+ if ((off < 0) || (off > cbuf.length) || (len < 0) ||
+ ((off + len) > cbuf.length) || ((off + len) < 0)) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0) {
+ return;
+ }
+ buf.append(cbuf, off, len);
+ }
+
+ public StringBuilder getStringBuilder()
+ {
+ return buf;
+ }
public void flushToWriter(Writer writer) throws IOException
{
@@ -440,32 +476,60 @@
stateManager.writeState(facesContext, serializedView);
facesContext.setResponseWriter(realWriter);
- StringBuffer contentBuffer = getBuffer();
- StringBuffer state = stateWriter.getBuffer();
+ StringBuilder contentBuffer = getStringBuilder();
+ String state = stateWriter.getBuffer().toString();
- int form_marker;
- while ((form_marker = contentBuffer.indexOf(JspViewHandlerImpl.FORM_STATE_MARKER)) > -1 )
- {
- //FORM_STATE_MARKER found, replace it
- contentBuffer.replace(form_marker, form_marker + FORM_STATE_MARKER_LEN, state.toString());
+ ExternalContext extContext = facesContext.getExternalContext();
+ if (JavascriptUtils.isJavascriptAllowed(extContext) && MyfacesConfig.getCurrentInstance(extContext).isViewStateJavascript()) {
+ // If javascript viewstate is enabled no state markers were written
+ write(contentBuffer, 0, contentBuffer.length(), writer);
+ writer.write(state);
+ } else {
+ // If javascript viewstate is disabled state markers must be replaced
+ int lastFormMarkerPos = 0;
+ int formMarkerPos = 0;
+ // Find all state markers and write out actual state instead
+ while ((formMarkerPos = contentBuffer.indexOf(FORM_STATE_MARKER, formMarkerPos)) > -1)
+ {
+ // Write content before state marker
+ write(contentBuffer, lastFormMarkerPos, formMarkerPos, writer);
+ // Write state and move position in buffer after marker
+ writer.write(state);
+ formMarkerPos += FORM_STATE_MARKER_LEN;
+ lastFormMarkerPos = formMarkerPos;
+ }
+ // Write content after last state marker
+ if (lastFormMarkerPos < contentBuffer.length()) {
+ write(contentBuffer, lastFormMarkerPos, contentBuffer.length(), writer);
+ }
}
+
+ }
- int bufferLength = contentBuffer.length();
- int index = 0;
- int bufferSize = 512;
+ /**
+ * Writes the content of the specified StringBuffer from index
+ * <code>beginIndex</code> to index <code>endIndex - 1</code>.
+ *
+ * @param contentBuffer the <code>StringBuffer</code> to copy content from
+ * @param begin the beginning index, inclusive.
+ * @param end the ending index, exclusive
+ * @param writer the <code>Writer</code> to write to
+ * @throws IOException if an error occurs writing to specified <code>Writer</code>
+ */
+ private void write(StringBuilder contentBuffer, int beginIndex, int endIndex, Writer writer) throws IOException {
+ int index = beginIndex;
+ int bufferSize = 2048;
+ char[] bufToWrite = new char[bufferSize];
- while (index < bufferLength)
+ while (index < endIndex)
{
- int maxSize = Math.min(bufferSize, bufferLength - index);
- char[] bufToWrite = new char[maxSize];
+ int maxSize = Math.min(bufferSize, endIndex - index);
contentBuffer.getChars(index, index + maxSize, bufToWrite, 0);
- writer.write(bufToWrite);
+ writer.write(bufToWrite, 0, maxSize);
index += bufferSize;
}
-
}
}
-
}
Modified: myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlFormRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlFormRenderer.java?rev=588608&r1=588607&r2=588608&view=diff
==============================================================================
--- myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlFormRenderer.java (original)
+++ myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlFormRenderer.java Fri Oct 26 04:39:18 2007
@@ -15,7 +15,17 @@
*/
package org.apache.myfaces.renderkit.html;
+import java.io.IOException;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+
+import org.apache.myfaces.shared_impl.config.MyfacesConfig;
+import org.apache.myfaces.shared_impl.renderkit.html.HTML;
import org.apache.myfaces.shared_impl.renderkit.html.HtmlFormRendererBase;
+import org.apache.myfaces.shared_impl.renderkit.html.util.JavascriptUtils;
/**
@@ -28,5 +38,23 @@
extends HtmlFormRendererBase
{
//private static final Log log = LogFactory.getLog(HtmlFormRenderer.class);
-
+
+ @Override
+ protected void afterFormElementsEnd(FacesContext facesContext,
+ UIComponent component) throws IOException {
+ super.afterFormElementsEnd(facesContext, component);
+
+ ResponseWriter writer = facesContext.getResponseWriter();
+ ExternalContext extContext = facesContext.getExternalContext();
+
+ // If javascript viewstate is enabled write empty hidden input in forms
+ if (JavascriptUtils.isJavascriptAllowed(extContext) && MyfacesConfig.getCurrentInstance(extContext).isViewStateJavascript()) {
+ writer.startElement(HTML.INPUT_ELEM, null);
+ writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
+ writer.writeAttribute(HTML.NAME_ATTR, HtmlResponseStateManager.VIEW_STATE_PARAM, null);
+ writer.writeAttribute(HTML.ID_ATTR, HtmlResponseStateManager.VIEW_STATE_PARAM, null);
+ writer.writeAttribute(HTML.VALUE_ATTR, "", null);
+ writer.endElement(HTML.INPUT_ELEM);
+ }
+ }
}
Modified: myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlResponseStateManager.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlResponseStateManager.java?rev=588608&r1=588607&r2=588608&view=diff
==============================================================================
--- myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlResponseStateManager.java (original)
+++ myfaces/core/branches/1_2_1/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlResponseStateManager.java Fri Oct 26 04:39:18 2007
@@ -18,10 +18,14 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.renderkit.MyfacesResponseStateManager;
+import org.apache.myfaces.shared_impl.config.MyfacesConfig;
import org.apache.myfaces.shared_impl.renderkit.html.HTML;
+import org.apache.myfaces.shared_impl.renderkit.html.HtmlRendererUtils;
+import org.apache.myfaces.shared_impl.renderkit.html.util.JavascriptUtils;
import org.apache.myfaces.shared_impl.util.StateUtils;
import javax.faces.application.StateManager;
+import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.RenderKitFactory;
@@ -95,13 +99,21 @@
ResponseWriter responseWriter,
Object savedState) throws IOException
{
- responseWriter.startElement(HTML.INPUT_ELEM, null);
- responseWriter.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
- responseWriter.writeAttribute(HTML.NAME_ATTR, STANDARD_STATE_SAVING_PARAM, null);
- responseWriter.writeAttribute(HTML.ID_ATTR, STANDARD_STATE_SAVING_PARAM, null);
- responseWriter.writeAttribute(HTML.VALUE_ATTR, StateUtils.construct(savedState,
- facesContext.getExternalContext()), null);
- responseWriter.endElement(HTML.INPUT_ELEM);
+ String serializedState = StateUtils.construct(savedState,
+ facesContext.getExternalContext());
+ ExternalContext extContext = facesContext.getExternalContext();
+ // Write Javascript viewstate if enabled and if javascript is allowed,
+ // otherwise write hidden input
+ if (JavascriptUtils.isJavascriptAllowed(extContext) && MyfacesConfig.getCurrentInstance(extContext).isViewStateJavascript()) {
+ HtmlRendererUtils.renderViewStateJavascript(facesContext, STANDARD_STATE_SAVING_PARAM, serializedState);
+ } else {
+ responseWriter.startElement(HTML.INPUT_ELEM, null);
+ responseWriter.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
+ responseWriter.writeAttribute(HTML.NAME_ATTR, STANDARD_STATE_SAVING_PARAM, null);
+ responseWriter.writeAttribute(HTML.ID_ATTR, STANDARD_STATE_SAVING_PARAM, null);
+ responseWriter.writeAttribute(HTML.VALUE_ATTR, serializedState, null);
+ responseWriter.endElement(HTML.INPUT_ELEM);
+ }
}
private void writeRenderKitIdField(FacesContext facesContext,
Modified: myfaces/shared/branches/3_0_1/core/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java
URL: http://svn.apache.org/viewvc/myfaces/shared/branches/3_0_1/core/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java?rev=588608&r1=588607&r2=588608&view=diff
==============================================================================
--- myfaces/shared/branches/3_0_1/core/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java (original)
+++ myfaces/shared/branches/3_0_1/core/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java Fri Oct 26 04:39:18 2007
@@ -74,6 +74,8 @@
public static final String INIT_PARAM_CONFIG_REFRESH_PERIOD = "org.apache.myfaces.CONFIG_REFRESH_PERIOD";
public static final long INIT_PARAM_CONFIG_REFRESH_PERIOD_DEFAULT = 2;
+ private static final String INIT_PARAM_VIEWSTATE_JAVASCRIPT = "org.apache.myfaces.VIEWSTATE_JAVASCRIPT";
+ private static final boolean INIT_PARAM_VIEWSTATE_JAVASCRIPT_DEFAULT = false;
private boolean _prettyHtml;
private boolean _detectJavascript;
@@ -84,6 +86,7 @@
private boolean _checkExtensionsFilter;
private boolean _readonlyAsDisabledForSelect;
private long _configRefreshPeriod;
+ private boolean _viewStateJavascript;
private static final boolean TOMAHAWK_AVAILABLE;
@@ -166,6 +169,9 @@
myfacesConfig.setConfigRefreshPeriod(getLongInitParameter(extCtx, INIT_PARAM_CONFIG_REFRESH_PERIOD,
INIT_PARAM_CONFIG_REFRESH_PERIOD_DEFAULT));
+ myfacesConfig.setViewStateJavascript(getBooleanInitParameter(extCtx, INIT_PARAM_VIEWSTATE_JAVASCRIPT,
+ INIT_PARAM_VIEWSTATE_JAVASCRIPT_DEFAULT));
+
if (TOMAHAWK_AVAILABLE)
{
@@ -394,5 +400,18 @@
public void setCheckExtensionsFilter(boolean extensionsFilter)
{
_checkExtensionsFilter = extensionsFilter;
+ }
+
+ /**
+ *
+ */
+ public boolean isViewStateJavascript()
+ {
+ return _viewStateJavascript;
+ }
+
+ private void setViewStateJavascript(boolean viewStateJavascript)
+ {
+ _viewStateJavascript = viewStateJavascript;
}
}
Modified: myfaces/shared/branches/3_0_1/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java
URL: http://svn.apache.org/viewvc/myfaces/shared/branches/3_0_1/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java?rev=588608&r1=588607&r2=588608&view=diff
==============================================================================
--- myfaces/shared/branches/3_0_1/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java (original)
+++ myfaces/shared/branches/3_0_1/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java Fri Oct 26 04:39:18 2007
@@ -1601,6 +1601,35 @@
return (String)component.getAttributes().get(JSFAttr.STYLE_LOCATION);
}
+ public static void renderViewStateJavascript(FacesContext facesContext, String hiddenId, String serializedState) throws IOException {
+ ResponseWriter writer = facesContext.getResponseWriter();
+
+ writer.startElement(HTML.SCRIPT_ELEM, null);
+ writer.writeAttribute(HTML.TYPE_ATTR, "text/javascript", null);
+
+ final ExternalContext externalContext = facesContext.getExternalContext();
+ final MyfacesConfig currentInstance = MyfacesConfig.getCurrentInstance(externalContext);
+
+ ScriptContext context = new ScriptContext(currentInstance.isPrettyHtml());
+ context.prettyLine();
+ context.increaseIndent();
+
+ context.append("function setViewState() {\n");
+ context.append("\tvar state = '");
+ context.append(serializedState);
+ context.append("';\n");
+ context.append("\tfor (var i = 0; i < document.forms.length; i++) {\n");
+ context.append("\t\tdocument.forms[i]['" + hiddenId + "'].value = state;\n");
+ context.append("\t}\n");
+ context.append("}\n");
+ context.append("setViewState();\n");
+
+ context.decreaseIndent();
+
+ writer.writeText(context.toString(), null);
+
+ writer.endElement(HTML.SCRIPT_ELEM);
+ }
/**
* The ScriptContext offers methods and fields
* to help with rendering out a script and keeping a