You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by Matthias Wessendorf <ma...@apache.org> on 2007/02/25 10:53:33 UTC

Re: svn commit: r511461 [1/3] - in /myfaces: core/trunk/api/src/main/java/javax/faces/webapp/ core/trunk/impl/src/main/java/org/apache/myfaces/application/ core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/ core/trunk/impl/src/main/jav

-is this:
https://issues.apache.org/jira/browse/MYFACES-1541  ?
   please add the jira issue number in future commits

I think adding private methods to javax.faces.xxx classes is fine, isnt't it ?


Thanks,
Matthias


On 2/25/07, mmarinschek@apache.org <mm...@apache.org> 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

Re: svn commit: r511461 [1/3] - in /myfaces: core/trunk/api/src/main/java/javax/faces/webapp/ core/trunk/impl/src/main/java/org/apache/myfaces/application/ core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/ core/trunk/impl/src/main/jav

Posted by Matthias Wessendorf <ma...@apache.org>.
the configurable wasn't the point of mine.
I expected to be able to add private methods, since that isn't
"extending" the API. I wasn't 100% sure, so I asked.

thanks,
Matthias

On 2/25/07, Martin Marinschek <ma...@gmail.com> wrote:
> What we do is
>
> a) private - so that's ok
> b) changes behaviour - so that's not ok but is
> c) configurable, so that's ok again....
>
> regards,
>
> Martin
>
> On 2/25/07, Matthias Wessendorf <ma...@apache.org> wrote:
> > > > I think adding private methods to javax.faces.xxx classes is fine, isnt't it ?
> > >
> > > What do you mean ? Have i added too much public methods ?
> >
> > since the javax.faces.xxxx clazzes are specifed by the EG we can't
> > enhance the API,
> > like adding public methods, but ... adding privates should be fine.
> >
> > -M
> >
> > > Regards
> > > Martin Haimberger
> > >
> > > On 2/25/07, Matthias Wessendorf <ma...@apache.org> wrote:
> > > >
> > > >
> > > >
> > > > Thanks,
> > > > Matthias
> > > >
> > > >
> > > > On 2/25/07, mmarinschek@apache.org <mm...@apache.org> 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
> > > >
> > >
> >
> >
> > --
> > Matthias Wessendorf
> > http://tinyurl.com/fmywh
> >
> > further stuff:
> > blog: http://jroller.com/page/mwessendorf
> > mail: mwessendorf-at-gmail-dot-com
> >
>
>
> --
>
> http://www.irian.at
>
> Your JSF powerhouse -
> JSF Consulting, Development and
> Courses in English and German
>
> Professional Support for Apache MyFaces
>


-- 
Matthias Wessendorf
http://tinyurl.com/fmywh

further stuff:
blog: http://jroller.com/page/mwessendorf
mail: mwessendorf-at-gmail-dot-com

Re: svn commit: r511461 [1/3] - in /myfaces: core/trunk/api/src/main/java/javax/faces/webapp/ core/trunk/impl/src/main/java/org/apache/myfaces/application/ core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/ core/trunk/impl/src/main/jav

Posted by Martin Marinschek <ma...@gmail.com>.
What we do is

a) private - so that's ok
b) changes behaviour - so that's not ok but is
c) configurable, so that's ok again....

regards,

Martin

On 2/25/07, Matthias Wessendorf <ma...@apache.org> wrote:
> > > I think adding private methods to javax.faces.xxx classes is fine, isnt't it ?
> >
> > What do you mean ? Have i added too much public methods ?
>
> since the javax.faces.xxxx clazzes are specifed by the EG we can't
> enhance the API,
> like adding public methods, but ... adding privates should be fine.
>
> -M
>
> > Regards
> > Martin Haimberger
> >
> > On 2/25/07, Matthias Wessendorf <ma...@apache.org> wrote:
> > >
> > >
> > >
> > > Thanks,
> > > Matthias
> > >
> > >
> > > On 2/25/07, mmarinschek@apache.org <mm...@apache.org> 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
> > >
> >
>
>
> --
> Matthias Wessendorf
> http://tinyurl.com/fmywh
>
> further stuff:
> blog: http://jroller.com/page/mwessendorf
> mail: mwessendorf-at-gmail-dot-com
>


-- 

http://www.irian.at

Your JSF powerhouse -
JSF Consulting, Development and
Courses in English and German

Professional Support for Apache MyFaces

Re: svn commit: r511461 [1/3] - in /myfaces: core/trunk/api/src/main/java/javax/faces/webapp/ core/trunk/impl/src/main/java/org/apache/myfaces/application/ core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/ core/trunk/impl/src/main/jav

Posted by Matthias Wessendorf <ma...@apache.org>.
> > I think adding private methods to javax.faces.xxx classes is fine, isnt't it ?
>
> What do you mean ? Have i added too much public methods ?

since the javax.faces.xxxx clazzes are specifed by the EG we can't
enhance the API,
like adding public methods, but ... adding privates should be fine.

-M

> Regards
> Martin Haimberger
>
> On 2/25/07, Matthias Wessendorf <ma...@apache.org> wrote:
> >
> >
> >
> > Thanks,
> > Matthias
> >
> >
> > On 2/25/07, mmarinschek@apache.org <mm...@apache.org> 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
> >
>


-- 
Matthias Wessendorf
http://tinyurl.com/fmywh

further stuff:
blog: http://jroller.com/page/mwessendorf
mail: mwessendorf-at-gmail-dot-com

Re: svn commit: r511461 [1/3] - in /myfaces: core/trunk/api/src/main/java/javax/faces/webapp/ core/trunk/impl/src/main/java/org/apache/myfaces/application/ core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/ core/trunk/impl/src/main/jav

Posted by Martin Haimberger <ma...@gmail.com>.
Hy,

> -is this:
> https://issues.apache.org/jira/browse/MYFACES-1541  ?
>    please add the jira issue number in future commits

yes this issue was the commit.

> I think adding private methods to javax.faces.xxx classes is fine, isnt't it ?

What do you mean ? Have i added too much public methods ?

Regards
Martin Haimberger

On 2/25/07, Matthias Wessendorf <ma...@apache.org> wrote:
>
>
>
> Thanks,
> Matthias
>
>
> On 2/25/07, mmarinschek@apache.org <mm...@apache.org> 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
>