Thanks,
Matthias
On 2/25/07, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
> Author: mmarinschek
> Date: Sun Feb 25 00:10:54 2007
> New Revision: 511461
>
> URL: http://svn.apache.org/viewvc?view=rev&rev=511461
> Log:
> partial state saving improvement
>
> Added:
>
myfaces/core/trunk/api/src/main/java/javax/faces/webapp/_DummyPageContextOutWriter.java
> myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/
>
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/BufferedStringWriter.java
>
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/EncodeAllComponentUtil.java
>
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/FastStringWriter.java
>
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/PartialTreeStructureManager.java
>
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/PssJspStateManagerImpl.java
>
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/PssJspViewHandlerImpl.java
>
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/TempServletOutputStream.java
>
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/TreeStructComponent.java
>
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/UIViewRootWrapper.java
>
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/ViewHandlerResponseWrapperHelperImpl.java
> Modified:
>
myfaces/core/trunk/api/src/main/java/javax/faces/webapp/UIComponentTag.java
>
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java
>
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/portlet/PortletExternalContextImpl.java
>
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImpl.java
>
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/taglib/core/ViewTag.java
>
myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlResponseWriterImpl.java
> myfaces/tomahawk/trunk/examples/simple/src/main/webapp/WEB-INF/web.xml
>
> Modified:
myfaces/core/trunk/api/src/main/java/javax/faces/webapp/UIComponentTag.java
> URL:
http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/webapp/UIComponentTag.java?view=diff&rev=511461&r1=511460&r2=511461
> ==============================================================================
> ---
myfaces/core/trunk/api/src/main/java/javax/faces/webapp/UIComponentTag.java
(original)
> +++
myfaces/core/trunk/api/src/main/java/javax/faces/webapp/UIComponentTag.java Sun
Feb 25 00:10:54 2007
> @@ -26,6 +26,7 @@
> import javax.faces.application.Application;
> import javax.faces.component.UIComponent;
> import javax.faces.component.UIViewRoot;
> +import javax.faces.component.UIOutput;
> import javax.faces.context.FacesContext;
> import javax.faces.context.ResponseWriter;
> import javax.faces.context.ExternalContext;
> @@ -35,8 +36,11 @@
>
> import javax.servlet.jsp.JspException;
> import javax.servlet.jsp.PageContext;
> +import javax.servlet.jsp.JspWriter;
> import javax.servlet.jsp.tagext.Tag;
> +import javax.servlet.jsp.tagext.BodyContent;
> import java.io.IOException;
> +import java.io.Reader;
> import java.util.*;
>
> /**
> @@ -63,6 +67,12 @@
>
> private static final String UNIQUE_ID_COUNTER_ATTR =
UIComponentTag.class.getName() + ".UNIQUE_ID_COUNTER";
>
> + private static final String PARTIAL_STATE_SAVING_METHOD_PARAM_NAME =
"javax.faces.PARTIAL_STATE_SAVING_METHOD";
> + private static final String PARTIAL_STATE_SAVING_METHOD_ON = "true";
> + private static final String PARTIAL_STATE_SAVING_METHOD_OFF = "false";
> +
> + private static final String BEFORE_VIEW_CONTEXT =
"org.apache.myfaces.BEFORE_VIEW_CONTEXT";
> +
> protected PageContext pageContext = null;
> private Tag _parent = null;
>
> @@ -78,8 +88,36 @@
> private ResponseWriter _writer = null;
> private Set _childrenAdded = null;
> private Set _facetsAdded = null;
> + private Boolean _partialStateSaving = null;
>
> private static Log log = LogFactory.getLog(UIComponentTag.class);
> + private static final int READ_LENGTH = 8000;
> +
> + private boolean isPartialStateSavingOn(javax.faces.context.FacesContext
context)
> + {
> + if(context == null) throw new NullPointerException("context");
> + if (_partialStateSaving != null) return
_partialStateSaving.booleanValue();
> + String stateSavingMethod =
context.getExternalContext().getInitParameter(PARTIAL_STATE_SAVING_METHOD_PARAM_NAME);
> + if (stateSavingMethod == null)
> + {
> + _partialStateSaving = Boolean.FALSE; //Specs 10.1.3: default
server saving
> + context.getExternalContext().log("No partial state saving method
defined, assuming default partial state saving methode off.");
> + }
> + else if (stateSavingMethod.equals(PARTIAL_STATE_SAVING_METHOD_ON))
> + {
> + _partialStateSaving = Boolean.TRUE;
> + }
> + else if (stateSavingMethod.equals(PARTIAL_STATE_SAVING_METHOD_OFF))
> + {
> + _partialStateSaving = Boolean.FALSE;
> + }
> + else
> + {
> + _partialStateSaving = Boolean.FALSE; //Specs 10.1.3: default
server saving
> + context.getExternalContext().log("Illegal partial state saving method '" +
stateSavingMethod + "', default partial state saving will be used (partial state saving
off).");
> + }
> + return _partialStateSaving.booleanValue();
> + }
>
>
> public UIComponentTag()
> @@ -297,6 +335,116 @@
> }
>
> /**
> + * Flushes the Writer and adds the content of the Writer ( which is only
the direct output
> + * of the JSP if the component uses a dummyWriter wich does not render
the Component itself) as
> + * UIOutput component after the current component to the myfaces
component tree.
> + * @param writerToFlush
> + * @throws JspException
> + * @throws IOException
> + */
> +
> + private void flushWriter( JspWriter writerToFlush ) throws
JspException,IOException {
> +
> + if (getFacesContext() == null)
> + return;
> + BodyContent tempwriter;
> + _componentInstance = findComponent(_facesContext);
> + if (writerToFlush instanceof BodyContent)
> + {
> + int count = 0;
> + char [] readChars = new char[READ_LENGTH];
> + tempwriter = (BodyContent) writerToFlush;
> + Reader read =tempwriter.getReader();
> + count = read.read(readChars,0,READ_LENGTH);
> + String readString = new String(readChars,0,count);
> + if(!readString.trim().equals(""))
> + {
> + //_componentInstance = findComponent(_facesContext);
> + UIComponentTag parentTag =
getParentUIComponentTag(pageContext);
> +
addOutputComponentAfterComponent(parentTag,createUIOutputComponentFromString(readString),_componentInstance);
> + tempwriter.clearBody();
> + }
> +
> + }
> + else
> + {
> + if (_componentInstance.getParent() == null) {
> + writerToFlush.flush();
> + String beforeViewContent =
_facesContext.getExternalContext().getResponse().toString();
> + if((beforeViewContent !=
null)&&(!beforeViewContent.trim().equals("")))
> + { // BEFORE BODY CONTENT
> +
_facesContext.getExternalContext().getRequestMap().put(BEFORE_VIEW_CONTEXT,beforeViewContent);
> + }
> + }
> + }
> +
> + }
> +
> + /**
> + * Adds an Output Component afert a given component.
> + * @param parentTag the parent tag of the component.
> + * @param outputComponent the component which should be added after this
component.
> + * @param component the component after witch the outputComponent should
be added.
> + */
> + private void addOutputComponentAfterComponent(UIComponentTag parentTag,
> + UIComponent
outputComponent,
> + UIComponent component) {
> + int indexOfComponentInParent = 0;
> + UIComponent parent = component.getParent();
> +
> + if (null == parent) {
> + return;
> + }
> + List children = parent.getChildren();
> + indexOfComponentInParent = children.indexOf(component);
> + if (children.size() - 1 == indexOfComponentInParent) {
> + children.add(outputComponent);
> + }
> + else {
> + children.add(indexOfComponentInParent + 1, outputComponent);
> + }
> + parentTag.addChildIdToParentTag(parentTag,outputComponent.getId());
> +
> + }
> +
> +
> + /**
> + * Creates a UIOutput component and fill in the content. The attribute
> + * escape will be set to false. The content will be renderd as it is.
> + * @param content the content of the UIOutput component.
> + * @return A UIOutput component with the content an the attribute escape
> + * set to false.
> + */
> + private UIComponent createUIOutputComponentFromString( String content) {
> + UIOutput outputComponent = null;
> +
> + outputComponent = createUIOutputComponent(getFacesContext());
> + outputComponent.setValue(content);
> +
> + return outputComponent;
> + }
> +
> +
> + /**
> + * Creates a UIOutput component with the attribute escape = false. The
Value
> + * of the Component will be rendert as it is, which is useful if there
are html tags
> + * which should be injectet into the component tree.
> + * @param context the Myfaces Context.
> + * @return A UIOutput Component with escape = false. The String of this
Component
> + * will be rendert as it is.
> + */
> + private UIOutput createUIOutputComponent(FacesContext context) {
> + if (context == null) return null;
> + UIOutput outputComponent = null;
> + Application application = context.getApplication();
> + outputComponent = (UIOutput)
application.createComponent("javax.faces.HtmlOutputText");
> + outputComponent.setTransient(true);
> + outputComponent.getAttributes().put("escape", Boolean.FALSE);
> + outputComponent.setId(context.getViewRoot().createUniqueId());
> + return outputComponent;
> + }
> +
> + /**
> * Invoked by the standard jsp processing mechanism when the opening
> * tag of a JSF component element is found.
> * <p>
> @@ -312,6 +460,15 @@
> {
> setupResponseWriter();
> FacesContext facesContext = getFacesContext();
> + if ( isPartialStateSavingOn(facesContext) )
> + {
> + JspWriter writer = pageContext.getOut();
> + try {
> + flushWriter(writer);
> + } catch (IOException e) {
> + log.error(e.toString());
> + }
> + }
> UIComponent component = findComponent(facesContext);
> if (!component.getRendersChildren() && !isSuppressed())
> {
> @@ -349,6 +506,21 @@
> public int doEndTag()
> throws JspException
> {
> + if (isPartialStateSavingOn(getFacesContext()))
> + {
> + JspWriter writerToFlush = pageContext.getOut();
> + if (_componentInstance == null) {
> + findComponent(getFacesContext());
> + }
> + if ((!(writerToFlush instanceof BodyContent)) &&
_componentInstance.getParent() == null) {
> + //add the before view content to the UIViewRoot
> + _componentInstance.getChildren().add(0,
> + createUIOutputComponentFromString((String)
> +
_facesContext.getExternalContext().getRequestMap().get(BEFORE_VIEW_CONTEXT)));
> +
_facesContext.getExternalContext().getRequestMap().remove(BEFORE_VIEW_CONTEXT);
> + }
> + }
> +
> popTag();
> UIComponent component = getComponentInstance();
> removeFormerChildren(component);
> @@ -937,9 +1109,16 @@
> RenderKit renderKit = renderFactory.getRenderKit(facesContext,
>
facesContext.getViewRoot().getRenderKitId());
>
> - _writer = renderKit.createResponseWriter(new
_PageContextOutWriter(pageContext),
> - null /*Default: get the
allowed content-types from the accept-header*/,
> -
pageContext.getRequest().getCharacterEncoding());
> + if (isPartialStateSavingOn(facesContext)) {
> + _writer = renderKit.createResponseWriter(new
_DummyPageContextOutWriter(pageContext),
> + null /*Default:
get the allowed content-types from the accept-header*/,
> +
pageContext.getRequest().getCharacterEncoding());
> + } else {
> + _writer = renderKit.createResponseWriter(new
_PageContextOutWriter(pageContext),
> + null /*Default:
get the allowed content-types from the accept-header*/,
> +
pageContext.getRequest().getCharacterEncoding());
> +
> + }
> facesContext.setResponseWriter(_writer);
> }
> }
>
> Added:
myfaces/core/trunk/api/src/main/java/javax/faces/webapp/_DummyPageContextOutWriter.java
> URL:
http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/webapp/_DummyPageContextOutWriter.java?view=auto&rev=511461
> ==============================================================================
> ---
myfaces/core/trunk/api/src/main/java/javax/faces/webapp/_DummyPageContextOutWriter.java
(added)
> +++
myfaces/core/trunk/api/src/main/java/javax/faces/webapp/_DummyPageContextOutWriter.java
Sun Feb 25 00:10:54 2007
> @@ -0,0 +1,73 @@
> +/*
> + * Copyright 2004 The Apache Software Foundation.
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +
> +package javax.faces.webapp;
> +
> +import javax.servlet.jsp.PageContext;
> +import java.io.Writer;
> +import java.io.IOException;
> +
> +/**
> + * This Writer is a dummy Writer.
> + *
> + * @author Martin Haimberger
> + */
> +class _DummyPageContextOutWriter
> + extends Writer
> +{
> + private PageContext _pageContext;
> +
> + public _DummyPageContextOutWriter(PageContext pageContext)
> + {
> + _pageContext = pageContext;
> + }
> +
> + public void close() throws IOException
> + {
> +
> + }
> +
> + public void flush() throws IOException
> + {
> +
> + }
> +
> + public void write(char cbuf[], int off, int len) throws IOException
> + {
> +
> + }
> +
> + public void write(int c) throws IOException
> + {
> +
> + }
> +
> + public void write(char cbuf[]) throws IOException
> + {
> +
> + }
> +
> + public void write(String str) throws IOException
> + {
> +
> + }
> +
> + public void write(String str, int off, int len) throws IOException
> + {
> +
> + }
> +
> +}
>
> Modified:
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java
> URL:
http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java?view=diff&rev=511461&r1=511460&r2=511461
> ==============================================================================
> ---
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java
(original)
> +++
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java
Sun Feb 25 00:10:54 2007
> @@ -52,8 +52,39 @@
> extends NavigationHandler
> {
> private static final Log log =
LogFactory.getLog(NavigationHandlerImpl.class);
> + private static final String PARTIAL_STATE_SAVING_METHOD_PARAM_NAME =
"javax.faces.PARTIAL_STATE_SAVING_METHOD";
> + private static final String PARTIAL_STATE_SAVING_METHOD_ON = "true";
> + private static final String PARTIAL_STATE_SAVING_METHOD_OFF = "false";
>
> private static final String ASTERISK = "*";
> + private Boolean _partialStateSaving = null;
> +
> + private boolean isPartialStateSavingOn(javax.faces.context.FacesContext
context)
> + {
> + if(context == null) throw new NullPointerException("context");
> + if (_partialStateSaving != null) return
_partialStateSaving.booleanValue();
> + String stateSavingMethod =
context.getExternalContext().getInitParameter(PARTIAL_STATE_SAVING_METHOD_PARAM_NAME);
> + if (stateSavingMethod == null)
> + {
> + _partialStateSaving = Boolean.FALSE; //Specs 10.1.3: default
server saving
> + context.getExternalContext().log("No partial state saving method
defined, assuming default partial state saving methode off.");
> + }
> + else if (stateSavingMethod.equals(PARTIAL_STATE_SAVING_METHOD_ON))
> + {
> + _partialStateSaving = Boolean.TRUE;
> + }
> + else if (stateSavingMethod.equals(PARTIAL_STATE_SAVING_METHOD_OFF))
> + {
> + _partialStateSaving = Boolean.FALSE;
> + }
> + else
> + {
> + _partialStateSaving = Boolean.FALSE; //Specs 10.1.3: default
server saving
> + context.getExternalContext().log("Illegal partial state saving method '" +
stateSavingMethod + "', default partial state saving will be used (partial state saving
off).");
> + }
> + return _partialStateSaving.booleanValue();
> + }
> +
>
> private Map _navigationCases = null;
> private List _wildcardKeys = new ArrayList();
> @@ -102,7 +133,12 @@
> ViewHandler viewHandler =
facesContext.getApplication().getViewHandler();
> //create new view
> String newViewId = navigationCase.getToViewId();
> - UIViewRoot viewRoot = viewHandler.createView(facesContext,
newViewId);
> + UIViewRoot viewRoot = null;
> + if (isPartialStateSavingOn(facesContext)) {
> + viewRoot =
viewHandler.restoreView(facesContext,newViewId);
> + } else {
> + viewRoot = viewHandler.createView(facesContext,
newViewId);
> + }
> facesContext.setViewRoot(viewRoot);
> facesContext.renderResponse();
> }
>
> Added:
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/BufferedStringWriter.java
> URL:
http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/BufferedStringWriter.java?view=auto&rev=511461
> ==============================================================================
> ---
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/BufferedStringWriter.java
(added)
> +++
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/BufferedStringWriter.java
Sun Feb 25 00:10:54 2007
> @@ -0,0 +1,123 @@
> +/*
> + * Copyright 2004 The Apache Software Foundation.
> + *
> + * Licensed 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.application.pss;
> +
> +import org.apache.myfaces.application.jsp.JspViewHandlerImpl;
> +import org.apache.myfaces.application.MyfacesStateManager;
> +import org.apache.myfaces.shared_impl.renderkit.html.HtmlLinkRendererBase;
> +import org.apache.commons.logging.Log;
> +import org.apache.commons.logging.LogFactory;
> +
> +import javax.faces.context.FacesContext;
> +import javax.faces.context.ResponseWriter;
> +import javax.faces.application.StateManager;
> +import java.io.Writer;
> +import java.io.IOException;
> +
> +/**
> + * @author Martin Haimberger
> + */
> +public class BufferedStringWriter extends FastStringWriter {
> +
> + private static final Log log =
LogFactory.getLog(BufferedStringWriter.class);
> +
> + public BufferedStringWriter(FacesContext context, int
initialCapcity) {
> + super(initialCapcity);
> + }
> +
> + /**
> + * flushes the content of this writer to the given writer.
> + * @param writer the content of this writer is written to the given
writer
> + * @throws IOException IOException
> + */
> + public void flushToWriter(Writer writer) throws IOException {
> +
> +
> + FacesContext facesContext =
FacesContext.getCurrentInstance();
> + StateManager stateManager =
facesContext.getApplication().getStateManager();
> + StateManager.SerializedView serializedView
> + = stateManager.saveSerializedView(facesContext);
> + if (serializedView != null)
> + {
> + //until now we have written to a buffer
> + ResponseWriter bufferWriter =
facesContext.getResponseWriter();
> + bufferWriter.flush();
> + //now we switch to real output
> + ResponseWriter realWriter =
bufferWriter.cloneWithWriter(writer);
> + facesContext.setResponseWriter(realWriter);
> +
> + String bodyStr = _buffer.toString();
> + //if ( stateManager.isSavingStateInClient(facesContext) )
> + //{
> + int form_marker =
bodyStr.indexOf(JspViewHandlerImpl.FORM_STATE_MARKER);
> + int url_marker =
bodyStr.indexOf(HtmlLinkRendererBase.URL_STATE_MARKER);
> + int lastMarkerEnd = 0;
> + while (form_marker != -1 || url_marker != -1)
> + {
> + if (url_marker == -1 || (form_marker != -1 &&
form_marker < url_marker))
> + {
> + //replace form_marker
> + realWriter.write(bodyStr, lastMarkerEnd,
form_marker - lastMarkerEnd);
> + stateManager.writeState(facesContext,
serializedView);
> + lastMarkerEnd = form_marker +
JspViewHandlerImpl.FORM_STATE_MARKER_LEN;
> + form_marker =
bodyStr.indexOf(JspViewHandlerImpl.FORM_STATE_MARKER, lastMarkerEnd);
> + }
> + else
> + {
> + //replace url_marker
> + realWriter.write(bodyStr, lastMarkerEnd,
url_marker - lastMarkerEnd);
> + if (stateManager instanceof
MyfacesStateManager)
> + {
> +
((MyfacesStateManager)stateManager).writeStateAsUrlParams(facesContext,
> +
serializedView);
> + }
> + else
> + {
> + log.error("Current StateManager is no
MyfacesStateManager and does not support saving state in url parameters.");
> + }
> + lastMarkerEnd = url_marker +
HtmlLinkRendererBase.URL_STATE_MARKER_LEN;
> + url_marker =
bodyStr.indexOf(HtmlLinkRendererBase.URL_STATE_MARKER, lastMarkerEnd);
> + }
> + }
> + realWriter.write(bodyStr, lastMarkerEnd,
bodyStr.length() - lastMarkerEnd);
> + /*}
> + else
> + {
> + realWriter.write( bodyStr );
> + } */
> + }
> + else
> + {
> + // Save state in Server Session ... only write out the
content
> + ResponseWriter bufferWriter =
facesContext.getResponseWriter();
> + bufferWriter.flush();
> + //now we switch to real output
> + ResponseWriter realWriter =
bufferWriter.cloneWithWriter(writer);
> + facesContext.setResponseWriter(realWriter);
> +
> + String bodyStr = _buffer.toString();
> +
> + realWriter.write( bodyStr );
> + }
> + }
> +
> + public int length() {
> + return _buffer.length();
> + }
> +
> +
> + }
> \ No newline at end of file
>
> Added:
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/EncodeAllComponentUtil.java
> URL:
http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/EncodeAllComponentUtil.java?view=auto&rev=511461
> ==============================================================================
> ---
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/EncodeAllComponentUtil.java
(added)
> +++
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/EncodeAllComponentUtil.java
Sun Feb 25 00:10:54 2007
> @@ -0,0 +1,45 @@
> +package org.apache.myfaces.application.pss;
> +
> +import javax.faces.component.UIComponent;
> +import javax.faces.context.FacesContext;
> +import java.io.IOException;
> +import java.util.Iterator;
> +
> +/**
> + * @author Martin Haimberger
> + */
> +public class EncodeAllComponentUtil {
> + /**
> + * ensure that this util class can not be instanciated
> + */
> + private EncodeAllComponentUtil(){}
> +
> + /**
> + * Encodes a whole UI-Component Tree or a part of the tree.
> + * @param context The facescontext
> + * @param component The base of the tree or the part or the tree
> + * @throws IOException thrown Exception
> + */
> +
> + public static void encodeAll(FacesContext context, UIComponent component)
> + throws IOException
> + {
> + if (!component.isRendered()) {
> + return;
> + }
> +
> + component.encodeBegin(context);
> + if (component.getRendersChildren()) {
> + component.encodeChildren(context);
> + }
> + else if (component.getChildCount() > 0) {
> + Iterator kids = component.getChildren().iterator();
> + while (kids.hasNext()) {
> + UIComponent kid = (UIComponent) kids.next();
> + encodeAll(context,kid);
> + }
> + }
> +
> + component.encodeEnd(context);
> + }
> +}
>
> Added:
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/FastStringWriter.java
> URL:
http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/FastStringWriter.java?view=auto&rev=511461
> ==============================================================================
> ---
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/FastStringWriter.java
(added)
> +++
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/FastStringWriter.java
Sun Feb 25 00:10:54 2007
> @@ -0,0 +1,98 @@
> +/*
> + * Copyright 2004 The Apache Software Foundation.
> + *
> + * Licensed 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.application.pss;
> +
> +/**
> + * @author Martin Haimberger
> + */
> +import java.io.IOException;
> +import java.io.Writer;
> +
> +public class FastStringWriter extends Writer {
> +
> + protected StringBuffer _buffer;
> +
> + // ------------------------------------------------------------
Constructors
> +
> + /**
> + * <p>Constructs a new <code>FastStringWriter</code> instance
> + * using the default capacity of <code>16</code>.</p>
> + */
> + public FastStringWriter() {
> + _buffer = new StringBuffer();
> + }
> +
> + /**
> + * <p>Constructs a new <code>FastStringWriter</code> instance
> + * using the specified <code>initialCapacity</code>.</p>
> + *
> + * @param initialCapacity specifies the initial capacity of the buffer
> + *
> + * @throws IllegalArgumentException if initialCapacity is less than zero
> + */
> + public FastStringWriter(int initialCapacity) {
> + if (initialCapacity < 0) {
> + throw new IllegalArgumentException();
> + }
> + _buffer = new StringBuffer(initialCapacity);
> + }
> +
> + // ----------------------------------------------------- Methods from
Writer
> +
> + 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;
> + }
> + _buffer.append(cbuf, off, len);
> + }
> +
> + /**
> + * noop
> + * @throws IOException
> + */
> + public void flush() throws IOException {
> + }
> +
> + /**
> + * noop
> + * @throws IOException
> + */
> + public void close() throws IOException {
> + }
> +
> + // ---------------------------------------------------------- Public
Methods
> +
> + public void write(String str) {
> + write(str, 0, str.length());
> + }
> +
> + public void write(String str, int off, int len) {
> + _buffer.append(str.substring(off, off + len));
> + }
> +
> + public StringBuffer getBuffer() {
> + return _buffer;
> + }
> +
> + public String toString() {
> + return _buffer.toString();
> + }
> +
> +}
> \ No newline at end of file
>
> Added:
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/PartialTreeStructureManager.java
> URL:
http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/PartialTreeStructureManager.java?view=auto&rev=511461
> ==============================================================================
> ---
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/PartialTreeStructureManager.java
(added)
> +++
myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/PartialTreeStructureManager.java
Sun Feb 25 00:10:54 2007
> @@ -0,0 +1,300 @@
> +/*
> + * Copyright 2004 The Apache Software Foundation.
> + *
> + * Licensed 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.application.pss;
> +
> +import org.apache.myfaces.shared_impl.util.ClassUtils;
> +
> +import javax.faces.component.UIViewRoot;
> +import javax.faces.component.UIComponent;
> +import javax.faces.context.FacesContext;
> +import java.util.*;
> +
> +/**
> + * @author Martin Haimberger
> + */
> +public class PartialTreeStructureManager
> +{
> + public static final String PARTIAL_STATE_CLASS_IDS =
PartialTreeStructureManager.class.getName() +
".PARTIAL_STATE_MANAGER_COMPONENT_IDS";
> +
> + private FacesContext _facesContext;
> +
> + public PartialTreeStructureManager(FacesContext facesContext)
> + {
> + _facesContext = facesContext;
> + }
> +
> + public Object buildTreeStructureToSave(UIViewRoot viewRoot, FacesContext
facesContext)
> + {
> + Object savedStateTree = viewRoot.processSaveState(facesContext);
> + if (viewRoot instanceof UIViewRootWrapper) {
> + // the first call ... all components have to be saved in the
template
> + return
internalBuildInitalTreeStructureToSave(viewRoot,facesContext, savedStateTree,0);
> + }
> + else return internalBuildTreeStructureToSave(viewRoot,facesContext,
savedStateTree,0);
> + }
> +
> + private TreeStructComponent
internalBuildInitalTreeStructureToSave(UIComponent component,FacesContext
facesContext, Object state, int childIndex)
> + {
> +
> + Object myState = null;
> + Map facetStateMap = null;
> + List childrenStateList = null;
> +
> +
> + if (state != null)
> + {
> + myState = ((Object[])state)[0];
> + facetStateMap = (Map)((Object[])state)[1];
> + childrenStateList = (List)((Object[])state)[2];
> + }
> + else
> + {
> +
> + }
> + TreeStructComponent structComp = new
TreeStructComponent(convertStringToComponentClassId(facesContext,component.getClass().getName()),
> +
component.getId(),myState,component.isTransient());
> +
> + //children
> + if (component.getChildCount() > 0)
> + {
> + List childList = component.getChildren();
> + List structChildList = new ArrayList();
> + for (int i = 0, len = childList.size(); i < len; i++)
> + {
> + UIComponent child = (UIComponent)childList.get(i);
> + if (!child.isTransient())
> + {
> +
> + TreeStructComponent structChild =
internalBuildInitalTreeStructureToSave(child,facesContext,childrenStateList !=
null ? childrenStateList.get(childIndex++):null,0);
> + structChildList.add(structChild);
> + }
> + else
> + {
> +
> + child.setTransient(false);
> + TreeStructComponent structChild =
internalBuildInitalTreeStructureToSave(child,facesContext,child.processSaveState(facesContext),0);
> + structChildList.add(structChild);
> + child.setTransient(true);
> +
> + }
> + }
> + TreeStructComponent[] childArray =
(TreeStructComponent[])structChildList.toArray(new
TreeStructComponent[structChildList.size()]);
> + structComp.setChildren(childArray);
> + }
> +
> + //facets
> + Map facetMap = component.getFacets();
> + if (!facetMap.isEmpty())
> + {
> + List structFacetList = new ArrayList();
> + for (Iterator it = facetMap.entrySet().iterator(); it.hasNext();
)
> + {
> + Map.Entry entry = (Map.Entry)it.next();
> + UIComponent child = (UIComponent)entry.getValue();
> + String facetName = (String)entry.getKey();
> + if (!child.isTransient())
> + {
> +
> + TreeStructComponent structChild =
internalBuildInitalTreeStructureToSave(child,facesContext,facetStateMap.get(facetName),0);
> + structFacetList.add(new Object[] {facetName,
structChild});
> + }
> + else
> + {
> + // this is a transient Component ... save it anyway
> + child.setTransient(false);
> + TreeStructComponent structChild =
internalBuildInitalTreeStructureToSave(child,facesContext,child.processSaveState(facesContext),0);
> + structFacetList.add(new Object[] {facetName,
structChild});
> + child.setTransient(true);
> + }
> + }
> + Object[] facetArray = structFacetList.toArray(new
Object[structFacetList.size()]);
> + structComp.setFacets(facetArray);
> + }
> +
> + return structComp;
> + }
> +
> + private TreeStructComponent internalBuildTreeStructureToSave(UIComponent
component,FacesContext facesContext, Object state, int childIndex)
> + {
> +
> + Object myState = null;
> + Map facetStateMap = null;
> + List childrenStateList = null;
> +
> +
> + if (state != null)
> + {
> + myState = ((Object[])state)[0];
> + facetStateMap = (Map)((Object[])state)[1];
> + childrenStateList = (List)((Object[])state)[2];
> + }
> + else
> + {
> +
> + }
> + TreeStructComponent structComp = new
TreeStructComponent(convertStringToComponentClassId(facesContext,component.getClass().getName()),
> +
component.getId(),myState,component.isTransient());
> +
> + //children
> + if (component.getChildCount() > 0)
> + {
> + List childList = component.getChildren();
> + List structChildList = new ArrayList();
> + for (int i = 0, len = childList.size(); i < len; i++)
> + {
> + UIComponent child = (UIComponent)childList.get(i);
> + if (!child.isTransient())
> + {
> +
> + TreeStructComponent structChild =
internalBuildTreeStructureToSave(child,facesContext,childrenStateList != null ?
childrenStateList.get(childIndex++):null,0);
> + structChildList.add(structChild);
> + }
> + }
> + TreeStructComponent[] childArray =
(TreeStructComponent[])structChildList.toArray(new
TreeStructComponent[structChildList.size()]);
> + structComp.setChildren(childArray);
> + }
> +
> + //facets
> + Map facetMap = component.getFacets();
> + if (!facetMap.isEmpty())
> + {
> + List structFacetList = new ArrayList();
> + for (Iterator it = facetMap.entrySet().iterator(); it.hasNext();
)
> + {
> + Map.Entry entry = (Map.Entry)it.next();
> + UIComponent child = (UIComponent)entry.getValue();
> + String facetName = (String)entry.getKey();
> + if (!child.isTransient())
> + {
> +
> + TreeStructComponent structChild =
internalBuildTreeStructureToSave(child,facesContext,facetStateMap.get(facetName),0);
> + structFacetList.add(new Object[] {facetName,
structChild});
> + }
> +
> + }
> + Object[] facetArray = structFacetList.toArray(new
Object[structFacetList.size()]);
> + structComp.setFacets(facetArray);
> + }
> +
> + return structComp;
> + }
> +
> +
> +
> + public UIViewRoot restoreTreeStructure(FacesContext facesContext,Object
treeStructRoot)
> + {
> + if (treeStructRoot instanceof TreeStructComponent)
> + {
> + return
(UIViewRoot)internalRestoreTreeStructure((TreeStructComponent)treeStructRoot,facesContext);
> + }
> + else
> + {
> + throw new IllegalArgumentException("TreeStructure of type " +
treeStructRoot.getClass().getName() + " is not supported.");
> + }
> + }
> +
> + private UIComponent internalRestoreTreeStructure(TreeStructComponent
treeStructComp,FacesContext facesContext)
> + {
> + String compClass =
convertComponentClassIdToString(facesContext,treeStructComp.getComponentClass());
> + String compId = treeStructComp.getComponentId();
> + UIComponent component = (UIComponent)
ClassUtils.newInstance(compClass);
> + component.setId(compId);
> + component.setTransient(treeStructComp.isTransient());
> +
> + //children
> + TreeStructComponent[] childArray = treeStructComp.getChildren();
> + if (childArray != null)
> + {
> + List childList = component.getChildren();
> + for (int i = 0, len = childArray.length; i < len; i++)
> + {
> + UIComponent child =
internalRestoreTreeStructure(childArray[i],facesContext);
> + childList.add(child);
> + }
> + }
> +
> + //facets
> + Object[] facetArray = treeStructComp.getFacets();
> + if (facetArray != null)
> + {
> + Map facetMap = component.getFacets();
> + for (int i = 0, len = facetArray.length; i < len; i++)
> + {
> + TreeStructComponent structChild =
(TreeStructComponent)((Object[])facetArray[i])[1];
> + String facetName = (String)((Object[])facetArray[i])[0];
> + UIComponent child =
internalRestoreTreeStructure(structChild,facesContext);
> + facetMap.put(facetName, child);
> + }
> + }
> +
> +
> + return component;
> + }
> +
> +
> +
> + private String convertComponentClassIdToString(FacesContext
facesContext,Integer classId){
> + Object[] idmaps =
(Object[])facesContext.getExternalContext().getApplicationMap().get(PARTIAL_STATE_CLASS_IDS);
> +
> + if ( idmaps== null)
> + {
> + // create on
> + idmaps = new Object[2];
> + // contains the Classid as Map
> + idmaps[0] = new HashMap();
> + idmaps[1] = new HashMap();
> +
facesContext.getExternalContext().getApplicationMap().put(PARTIAL_STATE_CLASS_IDS,idmaps);
> + }
> + return (String)((HashMap)idmaps[0]).get(classId);
> + }
> +
> + private Integer convertStringToComponentClassId(FacesContext
facesContext,String stringToConvert){
> +
> + // if it was the first time and the wrapper was use ... use the
original UIViewRoot
> +
> + if
(stringToConvert.equalsIgnoreCase("org.apache.myfaces.application.pss.UIViewRootWrapper"))
{
> + stringToConvert = "javax.faces.component.UIViewRoot";
> + }
> +
> + Object[] idmaps =
(Object[])facesContext.getExternalContext().getApplicationMap().get(PARTIAL_STATE_CLASS_IDS);
> +
> + if ( idmaps== null)
> + {
> + // create on
> + idmaps = new Object[2];
> + // contains the Classid as Map
> + idmaps[0] = new HashMap();
> + idmaps[1] = new HashMap();
> + }
> + Integer idInMap = (Integer)((HashMap)idmaps[1]).get(stringToConvert);
> + HashMap idToStringMap=((HashMap)idmaps[0]);
> + HashMap stringToIdMap=((HashMap)idmaps[1]);
> +
> + if (idInMap == null )
> + {
> + // this type is not jet registerd ... register now
> + Integer id = new Integer(stringToIdMap.size());
> +
> + stringToIdMap.put(stringToConvert,id);
> + idToStringMap.put(id,stringToConvert);
> + }
> +
facesContext.getExternalContext().getApplicationMap().put(PARTIAL_STATE_CLASS_IDS,idmaps);
> + return (Integer)stringToIdMap.get(stringToConvert);
> + }
> +
> +
> +}
>
>
>
--
Matthias Wessendorf
http://tinyurl.com/fmywh
further stuff:
blog: http://jroller.com/page/mwessendorf
mail: mwessendorf-at-gmail-dot-com