You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by mm...@apache.org on 2007/02/25 09:10:55 UTC
svn commit: r511461 [2/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/java/org/...
Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/PssJspStateManagerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/PssJspStateManagerImpl.java?view=auto&rev=511461
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/PssJspStateManagerImpl.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/PssJspStateManagerImpl.java Sun Feb 25 00:10:54 2007
@@ -0,0 +1,1408 @@
+/*
+ * 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.MyfacesStateManager;
+import org.apache.myfaces.application.TreeStructureManager;
+import org.apache.myfaces.renderkit.MyfacesResponseStateManager;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.collections.map.ReferenceMap;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.beanutils.BeanUtils;
+
+import javax.faces.context.FacesContext;
+import javax.faces.context.ExternalContext;
+import javax.faces.application.StateManager;
+import javax.faces.application.Application;
+import javax.faces.application.ViewHandler;
+import javax.faces.component.UIViewRoot;
+import javax.faces.component.UIComponent;
+import javax.faces.component.NamingContainer;
+import javax.faces.component.UIOutput;
+import javax.faces.render.RenderKit;
+import javax.faces.render.ResponseStateManager;
+import javax.faces.render.RenderKitFactory;
+import javax.faces.FactoryFinder;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.util.*;
+import java.util.zip.GZIPOutputStream;
+import java.util.zip.GZIPInputStream;
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.myfaces.shared_impl.renderkit.ViewSequenceUtils;
+import org.apache.myfaces.shared_impl.util.MyFacesObjectInputStream;
+import org.apache.myfaces.context.servlet.ServletExternalContextImpl;
+import org.apache.myfaces.context.portlet.PortletExternalContextImpl;
+
+/**
+ * @author Martin Haimberger
+ */
+public class PssJspStateManagerImpl extends MyfacesStateManager
+{
+
+ private static final Log log = LogFactory.getLog(PssJspStateManagerImpl.class);
+ private static final String SERIALIZED_VIEW_SESSION_ATTR
+ = PssJspStateManagerImpl.class.getName() + ".SERIALIZED_VIEW";
+ private static final String SERIALIZED_VIEW_REQUEST_ATTR
+ = PssJspStateManagerImpl.class.getName() + ".SERIALIZED_VIEW";
+ private static final String RESTORED_SERIALIZED_VIEW_REQUEST_ATTR
+ = PssJspStateManagerImpl.class.getName() + ".RESTORED_SERIALIZED_VIEW";
+
+ private static final String PARTIAL_STATE_MANAGER_TREES = PssJspStateManagerImpl.class.getName() + ".PARTIAL_STATE_MANAGER_TREES";
+
+
+
+ /**
+ * Only applicable if state saving method is "server" (= default).
+ * Defines the amount (default = 20) of the latest views are stored in session.
+ */
+ /**
+ * Only applicable if state saving method is "server" (= default).
+ * Defines the amount (default = 20) of the latest views are stored in session.
+ */
+ private static final String NUMBER_OF_VIEWS_IN_SESSION_PARAM = "org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION";
+
+ /**
+ * Default value for <code>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</code> context parameter.
+ */
+ /**
+ * Default value for <code>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</code> context parameter.
+ */
+ private static final int DEFAULT_NUMBER_OF_VIEWS_IN_SESSION = 20;
+
+ /**
+ * Only applicable if state saving method is "server" (= default).
+ * If <code>true</code> (default) the state will be serialized to a byte stream before it is written to the session.
+ * If <code>false</code> the state will not be serialized to a byte stream.
+ */
+ private static final String SERIALIZE_STATE_IN_SESSION_PARAM = "org.apache.myfaces.SERIALIZE_STATE_IN_SESSION";
+
+ /**
+ * Only applicable if state saving method is "server" (= default) and if <code>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</code> is <code>true</code> (= default).
+ * If <code>true</code> (default) the serialized state will be compressed before it is written to the session.
+ * If <code>false</code> the state will not be compressed.
+ */
+ private static final String COMPRESS_SERVER_STATE_PARAM = "org.apache.myfaces.COMPRESS_STATE_IN_SESSION";
+
+ /**
+ * Default value for <code>org.apache.myfaces.COMPRESS_STATE_IN_SESSION</code> context parameter.
+ */
+ private static final boolean DEFAULT_COMPRESS_SERVER_STATE_PARAM = true;
+
+ /**
+ * Default value for <code>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</code> context parameter.
+ */
+ private static final boolean DEFAULT_SERIALIZE_STATE_IN_SESSION = true;
+
+ private static final int UNCOMPRESSED_FLAG = 0;
+ private static final int COMPRESSED_FLAG = 1;
+
+ private RenderKitFactory _renderKitFactory = null;
+
+ 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 PARTIAL_STATE_SAVING_DISPATCH_PARAM_NAME = "javax.faces.PARTIAL_STATE_SAVING_DISPATCH_EVERY_TIME";
+
+
+ private Boolean _partialStateSaving = null;
+ private Boolean _partialStateSavingDispatch = null;
+
+ public PssJspStateManagerImpl()
+ {
+ if (log.isTraceEnabled()) log.trace("New JspStateManagerImpl instance created");
+ }
+
+ private boolean isPartialStateSavingOn(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 boolean isPartialStateSavingDispatch(FacesContext context)
+ {
+ if(context == null) throw new NullPointerException("context");
+ if (_partialStateSavingDispatch != null) return _partialStateSavingDispatch.booleanValue();
+ String stateSavingDispatch = context.getExternalContext().getInitParameter(PARTIAL_STATE_SAVING_DISPATCH_PARAM_NAME);
+ if (stateSavingDispatch == null)
+ {
+ _partialStateSavingDispatch = Boolean.TRUE; //Specs 10.1.3: default server saving
+ context.getExternalContext().log("No partial state saving dispatch usage behavior, assuming default partial state saving dispatch mode on.");
+ }
+ else if (stateSavingDispatch.equals(PARTIAL_STATE_SAVING_METHOD_ON))
+ {
+ _partialStateSavingDispatch = Boolean.TRUE;
+ }
+ else if (stateSavingDispatch.equals(PARTIAL_STATE_SAVING_METHOD_OFF))
+ {
+ _partialStateSavingDispatch = Boolean.FALSE;
+ }
+ else
+ {
+ _partialStateSavingDispatch = Boolean.TRUE; //Specs 10.1.3: default server saving
+ context.getExternalContext().log("Illegal partial state saving behavior '" + stateSavingDispatch + "', default partial state saving dispatch behavior will be used (dispatch behavior on).");
+ }
+ return _partialStateSaving.booleanValue();
+ }
+
+
+ protected Object getComponentStateToSave(FacesContext facesContext)
+ {
+ if (log.isTraceEnabled()) log.trace("Entering getComponentStateToSave");
+
+ UIViewRoot viewRoot = facesContext.getViewRoot();
+ if (viewRoot.isTransient())
+ {
+ return null;
+ }
+
+ Object serializedComponentStates = viewRoot.processSaveState(facesContext);
+ //Locale is a state attribute of UIViewRoot and need not be saved explicitly
+ if (log.isTraceEnabled()) log.trace("Exiting getComponentStateToSave");
+ return serializedComponentStates;
+ }
+
+ /**
+ * Return an object which contains info about the UIComponent type
+ * of each node in the view tree. This allows an identical UIComponent
+ * tree to be recreated later, though all the components will have
+ * just default values for their members.
+ */
+ protected Object getTreeStructureToSave(FacesContext facesContext)
+ {
+ if (log.isTraceEnabled()) log.trace("Entering getTreeStructureToSave");
+ UIViewRoot viewRoot = facesContext.getViewRoot();
+ if (viewRoot.isTransient())
+ {
+ return null;
+ }
+ TreeStructureManager tsm = new TreeStructureManager();
+ Object retVal = tsm.buildTreeStructureToSave(viewRoot);
+ if (log.isTraceEnabled()) log.trace("Exiting getTreeStructureToSave");
+ return retVal;
+ }
+
+ /**
+ * Return an object which contains info about the UIComponent type
+ * of each node in the view tree. This allows an identical UIComponent
+ * tree to be recreated later, though all the components will have
+ * just default values for their members.
+ */
+ protected Object getTreeToSave(FacesContext facesContext)
+ {
+ if (log.isTraceEnabled()) log.trace("Entering getTreeStructureToSave");
+ UIViewRoot viewRoot = facesContext.getViewRoot();
+ if (viewRoot.isTransient())
+ {
+ return null;
+ }
+ PartialTreeStructureManager tsm = new PartialTreeStructureManager(facesContext);
+ Object retVal = tsm.buildTreeStructureToSave(viewRoot,facesContext);
+ if (log.isTraceEnabled()) log.trace("Exiting getTreeStructureToSave");
+ return retVal;
+ }
+
+
+ /**
+ * Return an object which contains info about the UIComponent type
+ * of each node in the view tree. This allows an identical UIComponent
+ * tree to be recreated later, though all the components will have
+ * just default values for their members.
+ */
+ protected Object restoreViewRoot(FacesContext facesContext, Object storedView)
+ {
+ if (log.isTraceEnabled()) log.trace("Entering getTreeStructureToSave");
+ PartialTreeStructureManager tsm = new PartialTreeStructureManager(facesContext);
+ Object retVal = tsm.restoreTreeStructure(facesContext,storedView);
+ if (log.isTraceEnabled()) log.trace("Exiting getTreeStructureToSave");
+ return retVal;
+ }
+
+
+ private String getSequenceString(FacesContext facesContext, String renderKitId, String viewId) {
+ RenderKit rk = getRenderKitFactory().getRenderKit(facesContext, renderKitId);
+ ResponseStateManager responseStateManager = rk.getResponseStateManager();
+ String sequenceStr = (String) responseStateManager.getTreeStructureToRestore(facesContext, viewId);
+ return sequenceStr;
+ }
+
+
+ /**
+ * Given a tree of UIComponent objects created the default constructor
+ * for each node, retrieve saved state info (from either the client or
+ * the server) and walk the tree restoring the members of each node
+ * from the saved state information.
+ */
+ protected UIViewRoot restoreComponentState(FacesContext facesContext,
+ String viewID,
+ String renderKitId)
+ {
+ if (log.isTraceEnabled()) log.trace("Entering restoreComponentState");
+
+ //===========================================
+ // first, locate the saved state information
+ //===========================================
+
+ UIViewRoot uiViewRoot = null;
+
+ Object serializedComponentStates = null;
+ if (isSavingStateInClient(facesContext))
+ {
+ RenderKit renderKit = getRenderKitFactory().getRenderKit(facesContext, renderKitId);
+ ResponseStateManager responseStateManager = renderKit.getResponseStateManager();
+ // the State with the View ID
+ serializedComponentStates = responseStateManager.getComponentStateToRestore(facesContext);
+ }
+ else
+ {
+ String sequenceStr = getSequenceString(facesContext, renderKitId, viewID);
+ SerializedView serializedView = getSerializedViewFromServletSession(facesContext,
+ viewID,
+ sequenceStr);
+
+ if (serializedView != null)
+ {
+ serializedComponentStates = serializedView.getStructure();
+ }
+
+ }
+
+ // now ask the view root component to restore its state
+
+ Object template = LoadTreeFromManager(facesContext,viewID);
+ if (serializedComponentStates != null )
+ {
+ // we have got a view
+ String serializedViewID = (String)((Object[])serializedComponentStates)[0];
+ if (!serializedViewID.equals(viewID)) {
+ // not the right view.
+ serializedComponentStates = null;
+ }
+ }
+ if (serializedComponentStates != null) {
+
+
+ uiViewRoot = mergeComponentData(facesContext,viewID,(TreeStructComponent)((Object [])serializedComponentStates)[1]);
+ }
+ else {
+ uiViewRoot = mergeComponentData(facesContext,viewID,(TreeStructComponent)null);
+ }
+ Object rebuildStateTree = null;
+ if (serializedComponentStates != null)
+ {
+
+ rebuildStateTree = rebuildStateTree((TreeStructComponent)((Object [])serializedComponentStates)[1]);
+ }
+ else
+ {
+ rebuildStateTree = rebuildStateTree((TreeStructComponent)template);
+ }
+
+ uiViewRoot.processRestoreState(facesContext,rebuildStateTree);
+
+ if (uiViewRoot.getRenderKitId() == null)
+ {
+ //Just to be sure...
+ uiViewRoot.setRenderKitId(renderKitId);
+ }
+
+
+ if (log.isTraceEnabled()) log.trace("Exiting restoreComponentState");
+ return uiViewRoot;
+ }
+
+ private Object[] rebuildStateTree(TreeStructComponent componentState) {
+
+ Map facetMap = null;
+ if (componentState.getFacets() != null)
+ {
+ for (int iter = 0;iter < componentState.getFacets().length;iter++)
+ {
+ if (facetMap == null) facetMap = new HashMap();
+ TreeStructComponent componentchild = (TreeStructComponent)((Object[])(componentState.getFacets()[iter]))[1];
+ Object componentKey = ((Object[])(componentState.getFacets()[iter]))[0];
+ facetMap.put(componentKey,rebuildStateTree(componentchild));
+ }
+
+ }
+
+ List childrenList = null;
+ if (componentState.getChildren() != null)
+ {
+
+ TreeStructComponent[] children = componentState.getChildren();
+ for (int it = 0; it < children.length;it++ )
+ {
+
+ TreeStructComponent child = children[it];
+ if (childrenList == null) {
+ childrenList = new ArrayList(children.length);
+ }
+ Object childState = rebuildStateTree(child);
+ if (childState != null) {
+ childrenList.add(childState);
+ }
+ }
+ }
+ return new Object[] {componentState.get_componentState(),
+ facetMap,
+ childrenList};
+ }
+
+
+ private void mergeComponent(TreeStructComponent currentComponent, TreeStructComponent templateComponent)
+ {
+
+ TreeStructComponent[] currentchildren;
+ Object[] facets;
+
+ TreeStructComponent[] templatechildren = null;
+
+ currentchildren = currentComponent.getChildren();
+ facets = currentComponent.getFacets();
+
+ if (templateComponent != null)
+ {
+ templatechildren = templateComponent.getChildren();
+ if (currentComponent.getStatus() == TreeStructComponent.STATE_IS_TEMPLATE_STATE)
+ {
+ // restore State from template
+ currentComponent.set_componentState(templateComponent.get_componentState());
+ currentComponent.setStatus(TreeStructComponent.STATE_IS_RESTORED);
+ }
+ if ((currentComponent.getStatus() == TreeStructComponent.STATE_IS_NEW_COMPONENT) ||
+ (currentComponent.getStatus() == TreeStructComponent.STATE_IS_NEW_STATE))
+ {
+ currentComponent.setStatus(TreeStructComponent.STATE_IS_RESTORED);
+ }
+ }
+ else
+ { // new Component ... State is restored
+ currentComponent.setStatus(TreeStructComponent.STATE_IS_RESTORED);
+
+ }
+
+ if ((currentchildren != null) )
+ {
+ // create HashMap to find the children easily
+ HashMap templatechildrenMap = new HashMap();
+ if (templatechildren != null)
+ {
+ for(int componentIndex = 0;componentIndex < templatechildren.length;componentIndex++ )
+ {
+ templatechildrenMap.put(templatechildren[componentIndex].getComponentId(),templatechildren[componentIndex]);
+ }
+ }
+ // loop throw the childs
+ for(int componentIndex = 0;componentIndex < currentchildren.length;componentIndex++ )
+ {
+ String id = currentchildren[componentIndex].getComponentId();
+ TreeStructComponent foundtemplateComponent =(TreeStructComponent) templatechildrenMap.get(id);
+ mergeComponent(currentchildren[componentIndex] ,foundtemplateComponent);
+ }
+
+ }
+
+ if (facets != null)
+ {
+ // create HashMap to find the children easily
+ HashMap templatefacetMap = new HashMap();
+ if ((templateComponent != null) && (templateComponent.getFacets() != null))
+ {
+ Object [] templatefacets = templateComponent.getFacets();
+ for(int componentIndex = 0;componentIndex < templatefacets.length;componentIndex++ )
+ {
+ templatefacetMap.put(((Object[])(templatefacets[componentIndex]))[0],(TreeStructComponent)((Object[])(templatefacets[componentIndex]))[1]);
+ }
+ }
+
+ Map facetMap = new HashMap();
+ for (int iter = 0;iter < facets.length;iter++)
+ {
+ TreeStructComponent facet = (TreeStructComponent)(((Object[])facets[iter])[1]);
+ Object key = (((Object[])facets[iter])[0]);
+ facetMap.put(key,facet);
+ }
+
+ Iterator iter = facetMap.entrySet().iterator();
+
+ while(iter.hasNext())
+ {
+ Map.Entry entry = (Map.Entry)iter.next();
+
+ TreeStructComponent foundtemplateComponent =(TreeStructComponent) templatefacetMap.get(entry.getKey());
+ mergeComponent((TreeStructComponent)entry.getValue() ,foundtemplateComponent);
+ }
+ }
+
+ }
+
+
+
+ private UIViewRoot mergeComponentData(FacesContext facesContext,String viewRoot, TreeStructComponent state) {
+
+ TreeStructComponent template = (TreeStructComponent)LoadTreeFromManager(facesContext,viewRoot);
+
+ UIViewRoot tempRoot = null;
+ if (state == null)
+ {
+ // nothing loaded ... use the templeate
+ tempRoot = (UIViewRoot)restoreViewRoot(facesContext,template);
+
+ }
+ else
+ {
+ mergeComponent(state,template);
+ tempRoot = (UIViewRoot)restoreViewRoot(facesContext,state);
+ }
+ return tempRoot;
+ }
+
+ /**
+ * See getTreeStructureToSave.
+ */
+ protected UIViewRoot restoreTreeStructure(FacesContext facesContext,
+ String viewId,
+ String renderKitId)
+ {
+ if (log.isTraceEnabled()) log.trace("Entering restoreTreeStructure");
+ if (!isPartialStateSavingOn(facesContext)) {
+ log.fatal("Partial state saving StateManager is installed, but partial state saving is not enabled. Please enable partial state saving or use another StateManager.");
+ }
+
+ UIViewRoot uiViewRoot;
+ if (isSavingStateInClient(facesContext))
+ {
+ //reconstruct tree structure from request
+ RenderKit rk = getRenderKitFactory().getRenderKit(facesContext, renderKitId);
+ ResponseStateManager responseStateManager = rk.getResponseStateManager();
+ Object treeStructure = responseStateManager.getTreeStructureToRestore(facesContext, viewId);
+ if (treeStructure == null)
+ {
+ if (log.isDebugEnabled()) log.debug("Exiting restoreTreeStructure - No tree structure state found in client request");
+ return null;
+ }
+
+ TreeStructureManager tsm = new TreeStructureManager();
+ uiViewRoot = tsm.restoreTreeStructure((TreeStructureManager.TreeStructComponent)treeStructure);
+ if (log.isTraceEnabled()) log.trace("Tree structure restored from client request");
+ }
+ else {
+ String sequenceStr = getSequenceString(facesContext, renderKitId, viewId);
+ //reconstruct tree structure from ServletSession
+ SerializedView serializedView = getSerializedViewFromServletSession(facesContext,
+ viewId,
+ sequenceStr);
+ if (serializedView == null)
+ {
+ if (log.isDebugEnabled()) log.debug("Exiting restoreTreeStructure - No serialized view found in server session!");
+ return null;
+ }
+
+ Object treeStructure = serializedView.getStructure();
+ if (treeStructure == null)
+ {
+ if (log.isDebugEnabled()) log.debug("Exiting restoreTreeStructure - No tree structure state found in server session, former UIViewRoot must have been transient");
+ return null;
+ }
+
+ TreeStructureManager tsm = new TreeStructureManager();
+ uiViewRoot = tsm.restoreTreeStructure((TreeStructureManager.TreeStructComponent)serializedView.getStructure());
+ if (log.isTraceEnabled()) log.trace("Tree structure restored from server session");
+ }
+
+ if (log.isTraceEnabled()) log.trace("Exiting restoreTreeStructure");
+ return uiViewRoot;
+ }
+
+ protected void restoreComponentState(FacesContext context, UIViewRoot viewRoot, String renderKitId) {
+ }
+
+ public UIViewRoot restoreView(FacesContext facescontext, String viewId, String renderKitId)
+ {
+ if (log.isTraceEnabled()) log.trace("Entering restoreView");
+ UIViewRoot uiViewRoot = null;
+
+ Object template = LoadTreeFromManager(facescontext,viewId);
+
+ if (template != null)
+ {
+ uiViewRoot = restoreComponentState(facescontext,viewId,renderKitId);
+ uiViewRoot.setViewId(viewId);
+ String restoredViewId = uiViewRoot.getViewId();
+ if (restoredViewId == null || !(restoredViewId.equals(viewId)))
+ {
+ if (log.isTraceEnabled()) log.trace("Exiting restoreView - restored view is null.");
+ return null;
+ }
+ if (isPartialStateSavingDispatch(facescontext)) {
+ dispatchJSP(facescontext,viewId);
+ }
+ }
+ else
+ {
+ dispatchJSP(facescontext, viewId);
+
+ SaveTreeInManager(facescontext);
+ // reload the current view.
+ uiViewRoot = restoreComponentState(facescontext,viewId,renderKitId);
+
+
+ }
+
+ if (log.isTraceEnabled()) log.trace("Exiting restoreView");
+
+ return uiViewRoot;
+ }
+
+ /**
+ * Dispatches the JSP with a wrapped UIViewRoot so no Component is rendered, but
+ * the component tree is created and every tag will be executed too. This is helpfull
+ * if you want to use the f:loadBundle instead of the new s:loadBundle from the Sandbox.
+ * @param facescontext the faces context.
+ * @param viewId the view id which should be dispatched.
+ */
+
+ private void dispatchJSP(FacesContext facescontext, String viewId) {
+ UIViewRoot uiViewRoot;
+ // the first time the jsp page is called
+ // so create tree
+
+ Application application = facescontext.getApplication();
+ ViewHandler applicationViewHandler = application.getViewHandler();
+
+ // create Component Tree
+ ExternalContext externalContext = facescontext.getExternalContext();
+ uiViewRoot = applicationViewHandler.createView(facescontext, viewId);
+ uiViewRoot.setViewId(viewId);
+ UIViewRootWrapper currentWrapper = new UIViewRootWrapper(uiViewRoot);
+
+ facescontext.setViewRoot(currentWrapper);
+
+ // save original Response
+ Object orgResponse = facescontext.getExternalContext().getResponse();
+
+ ViewHandlerResponseWrapperHelperImpl wrapped = new ViewHandlerResponseWrapperHelperImpl((HttpServletResponse)facescontext.getExternalContext().getResponse());
+
+ // set the wrapped response into the externalContext
+ if ((externalContext instanceof ServletExternalContextImpl)
+ || (externalContext instanceof PortletExternalContextImpl)) {
+ try {
+ BeanUtils.setProperty(externalContext,"response",wrapped);
+ } catch (IllegalAccessException e) {
+ log.error(e.toString());
+ } catch (InvocationTargetException e) {
+ log.error(e.toString());
+ }
+ } else {
+ log.error("External Response could not be set! Deaktivate Partial State Saving!");
+ }
+
+ try
+ {
+ externalContext.dispatch(viewId);
+ }
+ catch (IOException e)
+ {
+ log.error(e.toString());
+ }
+ // set the original response back into the externalContext
+ if ((externalContext instanceof ServletExternalContextImpl)
+ || (externalContext instanceof PortletExternalContextImpl)) {
+ try {
+ BeanUtils.setProperty(externalContext,"response",orgResponse);
+ } catch (IllegalAccessException e) {
+ log.error(e.toString());
+ } catch (InvocationTargetException e) {
+ log.error(e.toString());
+ }
+
+ } else {
+ log.error("External Response could not be set! Deaktivate Partial State Saving!");
+ }
+
+ // After view Content
+ // the first Component in the UIViewRoot is the before view content .... get it's length
+
+ int beforeViewLength = 0;
+ UIComponent beforeview = (UIComponent)facescontext.getViewRoot().getChildren().get(0);
+ if (beforeview instanceof UIOutput) {
+ // what we expect
+ beforeViewLength = ((String)(((UIOutput)beforeview).getValue())).length();
+ } else {
+ log.error("No before view element found!");
+ }
+
+ String beforeViewContent = wrapped.toString().substring(beforeViewLength);
+ facescontext.getViewRoot().getChildren().add(facescontext.getViewRoot().getChildCount(),createUIOutputComponentFromString(facescontext,beforeViewContent));
+ wrapped.resetWriter();
+ }
+
+
+ protected UIComponent createUIOutputComponentFromString(FacesContext context, String content) {
+ UIOutput verbatim = null;
+
+ verbatim = createUIOutputComponent(context);
+ verbatim.setValue(content);
+
+ return verbatim;
+ }
+
+
+
+ protected UIOutput createUIOutputComponent(FacesContext context) {
+ //assert(null != (context));
+ if (context == null) return null;
+ UIOutput verbatim = null;
+ Application application = context.getApplication();
+ verbatim = (UIOutput) application.createComponent("javax.faces.HtmlOutputText");
+ verbatim.setTransient(true);
+ verbatim.getAttributes().put("escape", Boolean.FALSE);
+ verbatim.setId(context.getViewRoot().createUniqueId());
+ return verbatim;
+ }
+
+
+
+ public void SaveTreeInManager(FacesContext facesContext) throws IllegalStateException
+ {
+ if (log.isTraceEnabled()) log.trace("Entering saveSerializedView");
+
+ checkForDuplicateIds(facesContext, facesContext.getViewRoot(), new HashSet());
+
+ if (log.isTraceEnabled()) log.trace("Processing saveSerializedView - Checked for duplicate Ids");
+
+ // save the Tree for Partial State Saving
+
+ Object Tree = getTreeToSave(facesContext);
+
+
+ Map appmap = facesContext.getExternalContext().getApplicationMap();
+
+ HashMap mymap = (HashMap)appmap.get(PARTIAL_STATE_MANAGER_TREES);
+
+ if ( mymap== null)
+ {
+ // create on
+ mymap = new HashMap();
+ }
+
+ mymap.put(facesContext.getViewRoot().getViewId(),Tree);
+ appmap.put(PARTIAL_STATE_MANAGER_TREES,mymap);
+
+ }
+
+ public Object LoadUIViewRootFromManager(FacesContext facesContext, String viewID) throws IllegalStateException
+ {
+ Object tree = LoadTreeFromManager(facesContext,viewID);
+ // get state
+ if (tree != null)
+ {
+ return restoreViewRoot(facesContext,tree);
+ }
+ return null;
+ }
+
+ public Object LoadTreeFromManager(FacesContext facesContext, String viewID) throws IllegalStateException
+ {
+ Map appmap = facesContext.getExternalContext().getApplicationMap();
+
+ HashMap mymap = (HashMap)appmap.get(PARTIAL_STATE_MANAGER_TREES);
+
+ if ( mymap != null)
+ {
+ Object test = mymap.get(viewID);
+ return test;
+ }
+ return null;
+ }
+
+ public SerializedView saveSerializedView(FacesContext facesContext) throws IllegalStateException
+ {
+ if (log.isTraceEnabled()) log.trace("Entering saveSerializedView");
+
+ checkForDuplicateIds(facesContext, facesContext.getViewRoot(), new HashSet());
+
+ if (log.isTraceEnabled()) log.trace("Processing saveSerializedView - Checked for duplicate Ids");
+
+ ExternalContext externalContext = facesContext.getExternalContext();
+
+ TreeStructComponent templateRoot = (TreeStructComponent)LoadTreeFromManager(facesContext,facesContext.getViewRoot().getViewId());
+ // now diff betwee the current and the template ViewRoot
+
+ TreeStructComponent diff = null;
+ if (templateRoot != null)
+ {
+ diff = diffAgainsTemplate(facesContext, templateRoot);
+ }
+
+ // SerializedView already created before within this request?
+ SerializedView serializedView = (SerializedView)externalContext.getRequestMap()
+ .get(SERIALIZED_VIEW_REQUEST_ATTR);
+ if (serializedView == null)
+ {
+ if (log.isTraceEnabled()) log.trace("Processing saveSerializedView - create new serialized view");
+
+ // first call to saveSerializedView --> create SerializedView
+ // save the View ID also in the serialzed View
+ serializedView = new StateManager.SerializedView(null, new Object[]{facesContext.getViewRoot().getViewId(),diff});
+ externalContext.getRequestMap().put(SERIALIZED_VIEW_REQUEST_ATTR,
+ serializedView);
+
+ if (log.isTraceEnabled()) log.trace("Processing saveSerializedView - new serialized view created");
+ }
+
+ if (!isSavingStateInClient(facesContext))
+ {
+ if (log.isTraceEnabled()) log.trace("Processing saveSerializedView - server-side state saving - save state");
+ //save state in server session
+ saveSerializedViewInServletSession(facesContext, serializedView);
+
+ if (log.isTraceEnabled()) log.trace("Exiting saveSerializedView - server-side state saving - saved state");
+ Integer sequence = ViewSequenceUtils.getViewSequence(facesContext);
+ return new SerializedView(sequence.toString(), null); }
+
+ if (log.isTraceEnabled()) log.trace("Exiting saveSerializedView - client-side state saving");
+
+ return serializedView;
+ }
+
+ private boolean difState(Object[] currentState,Object[] templateState)
+ {
+
+ boolean isEqual = true;
+
+ for(int index = 0;index < currentState.length;index++)
+ {
+ if ((templateState[index] == null) && (currentState[index] != null )) {
+ isEqual = false;
+ }else if (currentState[index] instanceof Object[])
+ {
+ if ( !difState((Object[])currentState[index],(Object[])templateState[index]))
+ {
+ isEqual = false;
+ }
+ }
+ else
+ {
+ if ((currentState[index] != null)&&(!currentState[index].equals(templateState[index])))
+ {
+ isEqual= false;
+ }
+ }
+ }
+ return isEqual;
+ }
+
+ private TreeStructComponent diffComponent(TreeStructComponent currentComponent, TreeStructComponent templateComponent)
+ {
+ TreeStructComponent diffComponent = currentComponent.clone(templateComponent);
+
+ boolean isEqual = false;
+ Object[] currentComponentState;
+ TreeStructComponent[] currentchildren;
+
+ Object[] templateComponentState = null;
+ TreeStructComponent[] templatechildren = null;
+
+ currentComponentState = (Object[])currentComponent.get_componentState();
+ currentchildren = currentComponent.getChildren();
+
+ if (templateComponent != null)
+ {
+ templateComponentState = (Object[])templateComponent.get_componentState();
+ templatechildren = templateComponent.getChildren();
+
+ if (currentComponentState.length == templateComponentState.length)
+ {
+ isEqual = difState(currentComponentState,templateComponentState);
+ }
+ }
+ else
+ {
+ isEqual = false;
+ }
+
+ if (!isEqual)
+ {
+ diffComponent.set_componentState(currentComponent.get_componentState());
+ diffComponent.setStatus(TreeStructComponent.STATE_IS_NEW_STATE);
+ }
+ else
+ {
+ diffComponent.setStatus(TreeStructComponent.STATE_IS_TEMPLATE_STATE);
+ diffComponent.set_componentState(null);
+ }
+
+ if ((currentchildren != null) )
+ {
+ // create HashMap to find the children easily
+ HashMap templatechildrenMap = new HashMap();
+ if (templatechildren != null)
+ {
+ for(int componentIndex = 0;componentIndex < templatechildren.length;componentIndex++ )
+ {
+ templatechildrenMap.put(templatechildren[componentIndex].getComponentId(),templatechildren[componentIndex]);
+ }
+ }
+ // loop throw the childs
+ // get count of current child which are not transient
+ ArrayList childs = new ArrayList();
+ //TreeStructComponent[] childs= new TreeStructComponent[currentchildren.length];
+ for(int componentIndex = 0;componentIndex < currentchildren.length;componentIndex++ )
+ {
+ // only process not transient components
+ if (!currentchildren[componentIndex].isTransient()) {
+ String id = currentchildren[componentIndex].getComponentId();
+ TreeStructComponent foundtemplateComponent =(TreeStructComponent) templatechildrenMap.get(id);
+ childs.add(diffComponent(currentchildren[componentIndex] ,foundtemplateComponent));
+ }
+ }
+ childs.toArray(new TreeStructComponent[childs.size()]);
+ diffComponent.setChildren((TreeStructComponent[])childs.toArray(new TreeStructComponent[childs.size()]));
+ }
+
+ // process facets
+
+ if (currentComponent.getFacets() != null)
+ {
+
+ ArrayList facets = new ArrayList();
+ //Object[] facets= new Object[currentComponent.getFacets().length];
+
+ // create HashMap to find the children easily
+ HashMap templatefacetMap = new HashMap();
+ if ((templateComponent != null) && (templateComponent.getFacets() != null))
+ {
+ Object [] templatefacets = templateComponent.getFacets();
+ for(int componentIndex = 0;componentIndex < templatefacets.length;componentIndex++ )
+ {
+ templatefacetMap.put(((Object[])(templatefacets[componentIndex]))[0],(TreeStructComponent)((Object[])(templatefacets[componentIndex]))[1]);
+ }
+ }
+
+ Map facetMap = new HashMap();
+ if ((currentComponent != null) && (currentComponent.getFacets() != null))
+ {
+ Object [] currentfacets = currentComponent.getFacets();
+ for(int componentIndex = 0;componentIndex < currentfacets.length;componentIndex++ )
+ {
+ facetMap.put(((Object[])(currentfacets[componentIndex]))[0],(TreeStructComponent)((Object[])(currentfacets[componentIndex]))[1]);
+ }
+ }
+
+ Iterator iter = facetMap.entrySet().iterator();
+ int facetindex = 0;
+ while(iter.hasNext())
+ {
+ Map.Entry entry = (Map.Entry)iter.next();
+ // only process not transient components
+ if (!((TreeStructComponent)entry.getValue()).isTransient() ) {
+ TreeStructComponent foundtemplateComponent =(TreeStructComponent) (templatefacetMap.get(entry.getKey()));
+ Object[] objectEntry = new Object[2];
+ objectEntry[0] = entry.getKey();
+ objectEntry[1] = diffComponent((TreeStructComponent)entry.getValue() ,foundtemplateComponent);
+ facets.add(objectEntry);
+ //facets[facetindex++] = objectEntry;
+ }
+ }
+ diffComponent.setFacets(facets.toArray());
+ }
+
+ return diffComponent;
+ }
+
+ private TreeStructComponent diffAgainsTemplate(FacesContext facesContext, TreeStructComponent templateRoot)
+ {
+
+ TreeStructComponent currentTree = (TreeStructComponent)getTreeToSave(facesContext);
+ TreeStructComponent dif = diffComponent(currentTree,templateRoot);
+ return dif;
+
+ }
+
+
+ private static void checkForDuplicateIds(FacesContext context,
+ UIComponent component,
+ Set ids)
+ {
+ String id = component.getId();
+ if (id != null && !ids.add(id))
+ {
+ throw new IllegalStateException("Client-id : "+id +
+ " is duplicated in the faces tree. Component : "+component.getClientId(context)+", path: "+
+ getPathToComponent(component));
+ }
+ Iterator it = component.getFacetsAndChildren();
+ boolean namingContainer = component instanceof NamingContainer;
+ while (it.hasNext())
+ {
+ UIComponent kid = (UIComponent) it.next();
+ if (namingContainer)
+ {
+ checkForDuplicateIds(context, kid, new HashSet());
+ }
+ else
+ {
+ checkForDuplicateIds(context, kid, ids);
+ }
+ }
+ }
+
+ private static String getPathToComponent(UIComponent component)
+ {
+ StringBuffer buf = new StringBuffer();
+
+ if(component == null)
+ {
+ buf.append("{Component-Path : ");
+ buf.append("[null]}");
+ return buf.toString();
+ }
+
+ getPathToComponent(component,buf);
+
+ buf.insert(0,"{Component-Path : ");
+ buf.append("}");
+
+ return buf.toString();
+ }
+
+ private static void getPathToComponent(UIComponent component, StringBuffer buf)
+ {
+ if(component == null)
+ return;
+
+ StringBuffer intBuf = new StringBuffer();
+
+ intBuf.append("[Class: ");
+ intBuf.append(component.getClass().getName());
+ if(component instanceof UIViewRoot)
+ {
+ intBuf.append(",ViewId: ");
+ intBuf.append(((UIViewRoot) component).getViewId());
+ }
+ else
+ {
+ intBuf.append(",Id: ");
+ intBuf.append(component.getId());
+ }
+ intBuf.append("]");
+
+ buf.insert(0,intBuf.toString());
+
+ if(component!=null)
+ {
+ getPathToComponent(component.getParent(),buf);
+ }
+ }
+
+
+ public void writeState(FacesContext facesContext,
+ SerializedView serializedView) throws IOException {
+ if (log.isTraceEnabled()) log.trace("Entering writeState");
+
+ if (log.isTraceEnabled())
+ log.trace("Processing writeState - either client-side (full state) or server-side (partial information; e.g. sequence)");
+ if (serializedView != null) {
+ UIViewRoot uiViewRoot = facesContext.getViewRoot();
+ //save state in response (client-side: full state; server-side: sequence)
+ RenderKit renderKit = getRenderKitFactory().getRenderKit(facesContext, uiViewRoot.getRenderKitId());
+ renderKit.getResponseStateManager().writeState(facesContext, serializedView);
+
+ if (log.isTraceEnabled()) log.trace("Exiting writeState");
+ }
+ }
+
+ /**
+ * MyFaces extension
+ * @param facesContext
+ * @param serializedView
+ * @throws IOException
+ */
+ public void writeStateAsUrlParams(FacesContext facesContext,
+ SerializedView serializedView) throws IOException
+ {
+ if (log.isTraceEnabled()) log.trace("Entering writeStateAsUrlParams");
+
+ if (isSavingStateInClient(facesContext))
+ {
+ if (log.isTraceEnabled()) log.trace("Processing writeStateAsUrlParams - client-side state saving writing state");
+
+ UIViewRoot uiViewRoot = facesContext.getViewRoot();
+ //save state in response (client)
+ RenderKit renderKit = getRenderKitFactory().getRenderKit(facesContext, uiViewRoot.getRenderKitId());
+ ResponseStateManager responseStateManager = renderKit.getResponseStateManager();
+ if (responseStateManager instanceof MyfacesResponseStateManager)
+ {
+ ((MyfacesResponseStateManager)responseStateManager).writeStateAsUrlParams(facesContext,
+ serializedView);
+ }
+ else
+ {
+ log.error("ResponseStateManager of render kit " + uiViewRoot.getRenderKitId() + " is no MyfacesResponseStateManager and does not support saving state in url parameters.");
+ }
+ }
+
+ if (log.isTraceEnabled()) log.trace("Exiting writeStateAsUrlParams");
+ }
+
+ //helpers
+
+ protected RenderKitFactory getRenderKitFactory()
+ {
+ if (_renderKitFactory == null)
+ {
+ _renderKitFactory = (RenderKitFactory)FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
+ }
+ return _renderKitFactory;
+ }
+
+
+ protected void saveSerializedViewInServletSession(FacesContext context,
+ SerializedView serializedView) {
+ Map sessionMap = context.getExternalContext().getSessionMap();
+ SerializedViewCollection viewCollection = (SerializedViewCollection) sessionMap
+ .get(SERIALIZED_VIEW_SESSION_ATTR);
+ if (viewCollection == null) {
+ viewCollection = new SerializedViewCollection();
+ sessionMap.put(SERIALIZED_VIEW_SESSION_ATTR, viewCollection);
+ }
+ viewCollection.add(context, serializeView(context, serializedView));
+ // replace the value to notify the container about the change
+ sessionMap.put(SERIALIZED_VIEW_SESSION_ATTR, viewCollection);
+ }
+
+ protected SerializedView getSerializedViewFromServletSession(FacesContext context, String viewId, String sequenceStr)
+ {
+ ExternalContext externalContext = context.getExternalContext();
+ Map requestMap = externalContext.getRequestMap();
+ SerializedView serializedView = null;
+ if (requestMap.containsKey(RESTORED_SERIALIZED_VIEW_REQUEST_ATTR))
+ {
+ serializedView = (SerializedView) requestMap.get(RESTORED_SERIALIZED_VIEW_REQUEST_ATTR);
+ }
+ else
+ {
+ SerializedViewCollection viewCollection = (SerializedViewCollection) externalContext
+ .getSessionMap().get(SERIALIZED_VIEW_SESSION_ATTR);
+ if (viewCollection != null) {
+ Integer sequence = null;
+ if (sequenceStr == null) {
+ // use latest sequence
+ sequence = ViewSequenceUtils.getCurrentSequence(context);
+ }
+ else {
+ sequence = new Integer(sequenceStr);
+ }
+ if (sequence != null) {
+ Object state = viewCollection.get(sequence, viewId);
+ if (state != null) {
+ serializedView = deserializeView(state);
+ }
+ }
+ }
+ requestMap.put(RESTORED_SERIALIZED_VIEW_REQUEST_ATTR, serializedView);
+ ViewSequenceUtils.nextViewSequence(context);
+ }
+ return serializedView;
+ }
+
+ protected Object serializeView(FacesContext context, SerializedView serializedView)
+ {
+ if (log.isTraceEnabled()) log.trace("Entering serializeView");
+
+ if(isSerializeStateInSession(context))
+ {
+ if (log.isTraceEnabled()) log.trace("Processing serializeView - serialize state in session");
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
+ try
+ {
+ OutputStream os = baos;
+ if(isCompressStateInSession(context))
+ {
+ if (log.isTraceEnabled()) log.trace("Processing serializeView - serialize compressed");
+
+ os.write(COMPRESSED_FLAG);
+ os = new GZIPOutputStream(os, 1024);
+ }
+ else
+ {
+ if (log.isTraceEnabled()) log.trace("Processing serializeView - serialize uncompressed");
+
+ os.write(UNCOMPRESSED_FLAG);
+ }
+ ObjectOutputStream out = new ObjectOutputStream(os);
+ out.writeObject(serializedView.getStructure());
+ out.writeObject(serializedView.getState());
+ out.close();
+ baos.close();
+
+ if (log.isTraceEnabled()) log.trace("Exiting serializeView - serialized. Bytes : "+baos.size());
+ return baos.toByteArray();
+ }
+ catch (IOException e)
+ {
+ log.error("Exiting serializeView - Could not serialize state: " + e.getMessage(), e);
+ return null;
+ }
+ }
+ else
+ {
+ if (log.isTraceEnabled()) log.trace("Exiting serializeView - do not serialize state in session.");
+ return new Object[] {serializedView.getStructure(), serializedView.getState()};
+ }
+ }
+
+ /**
+ * Reads the value of the <code>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</code> context parameter.
+ * @see SERIALIZE_STATE_IN_SESSION_PARAM
+ * @param context <code>FacesContext</code> for the request we are processing.
+ * @return boolean true, if the server state should be serialized in the session
+ */
+ protected boolean isSerializeStateInSession(FacesContext context)
+ {
+ String value = context.getExternalContext().getInitParameter(
+ SERIALIZE_STATE_IN_SESSION_PARAM);
+ boolean serialize = DEFAULT_SERIALIZE_STATE_IN_SESSION;
+ if (value != null)
+ {
+ serialize = new Boolean(value).booleanValue();
+ }
+ return serialize;
+ }
+
+ /**
+ * Reads the value of the <code>org.apache.myfaces.COMPRESS_STATE_IN_SESSION</code> context parameter.
+ * @see COMPRESS_SERVER_STATE_PARAM
+ * @param context <code>FacesContext</code> for the request we are processing.
+ * @return boolean true, if the server state steam should be compressed
+ */
+ protected boolean isCompressStateInSession(FacesContext context)
+ {
+ String value = context.getExternalContext().getInitParameter(
+ COMPRESS_SERVER_STATE_PARAM);
+ boolean compress = DEFAULT_COMPRESS_SERVER_STATE_PARAM;
+ if (value != null)
+ {
+ compress = new Boolean(value).booleanValue();
+ }
+ return compress;
+ }
+
+ protected SerializedView deserializeView(Object state)
+ {
+ if (log.isTraceEnabled()) log.trace("Entering deserializeView");
+
+ if(state instanceof byte[])
+ {
+ if (log.isTraceEnabled()) log.trace("Processing deserializeView - deserializing serialized state. Bytes : "+((byte[]) state).length);
+
+ try
+ {
+ ByteArrayInputStream bais = new ByteArrayInputStream((byte[]) state);
+ InputStream is = bais;
+ if(is.read() == COMPRESSED_FLAG)
+ {
+ is = new GZIPInputStream(is);
+ }
+ ObjectInputStream in = new MyFacesObjectInputStream(
+ is);
+ Object a = in.readObject();
+ Object b = in.readObject();
+ return new SerializedView(a, b);
+ }
+ catch (IOException e)
+ {
+ log.error("Exiting deserializeView - Could not deserialize state: " + e.getMessage(), e);
+ return null;
+ }
+ catch (ClassNotFoundException e)
+ {
+ log.error("Exiting deserializeView - Could not deserialize state: " + e.getMessage(), e);
+ return null;
+ }
+ }
+ else if (state instanceof Object[])
+ {
+ if (log.isTraceEnabled()) log.trace("Exiting deserializeView - state not serialized.");
+
+ Object[] value = (Object[]) state;
+ return new SerializedView(value[0], value[1]);
+ }
+ else if(state == null)
+ {
+ log.error("Exiting deserializeView - this method should not be called with a null-state.");
+ return null;
+ }
+ else
+ {
+ log.error("Exiting deserializeView - this method should not be called with a state of type : "+state.getClass());
+ return null;
+ }
+ }
+
+ protected static class SerializedViewCollection implements Serializable
+ {
+ private static final long serialVersionUID = -3734849062185115847L;
+
+ private final List _keys = new ArrayList(DEFAULT_NUMBER_OF_VIEWS_IN_SESSION);
+ private final Map _serializedViews = new HashMap();
+
+ // old views will be hold as soft references which will be removed by
+ // the garbage collector if free memory is low
+ private transient Map _oldSerializedViews = null;
+
+ public synchronized void add(FacesContext context, Object state)
+ {
+ Object key = new SerializedViewKey(context);
+ _serializedViews.put(key, state);
+
+ while (_keys.remove(key));
+ _keys.add(key);
+
+ int views = getNumberOfViewsInSession(context);
+ while (_keys.size() > views)
+ {
+ key = _keys.remove(0);
+ Object oldView = _serializedViews.remove(key);
+ if (oldView != null)
+ {
+ getOldSerializedViewsMap().put(key, oldView);
+ }
+ }
+ }
+
+ /**
+ * Reads the amount (default = 20) of views to be stored in session.
+ * @see NUMBER_OF_VIEWS_IN_SESSION_PARAM
+ * @param context FacesContext for the current request, we are processing
+ * @return Number vf views stored in the session
+ */
+ protected int getNumberOfViewsInSession(FacesContext context)
+ {
+ String value = context.getExternalContext().getInitParameter(
+ NUMBER_OF_VIEWS_IN_SESSION_PARAM);
+ int views = DEFAULT_NUMBER_OF_VIEWS_IN_SESSION;
+ if (value != null)
+ {
+ try
+ {
+ views = Integer.parseInt(value);
+ if (views <= 0)
+ {
+ log.error("Configured value for " + NUMBER_OF_VIEWS_IN_SESSION_PARAM
+ + " is not valid, must be an value > 0, using default value ("
+ + DEFAULT_NUMBER_OF_VIEWS_IN_SESSION);
+ views = DEFAULT_NUMBER_OF_VIEWS_IN_SESSION;
+ }
+ }
+ catch (Throwable e)
+ {
+ log.error("Error determining the value for " + NUMBER_OF_VIEWS_IN_SESSION_PARAM
+ + ", expected an integer value > 0, using default value ("
+ + DEFAULT_NUMBER_OF_VIEWS_IN_SESSION + "): " + e.getMessage(), e);
+ }
+ }
+ return views;
+ }
+
+ /**
+ * @return old serialized views map
+ */
+ protected Map getOldSerializedViewsMap()
+ {
+ if (_oldSerializedViews == null)
+ {
+ _oldSerializedViews = new ReferenceMap();
+ }
+ return _oldSerializedViews;
+ }
+
+ public Object get(Integer sequence, String viewId)
+ {
+ Object key = new SerializedViewKey(viewId, sequence);
+ Object value = _serializedViews.get(key);
+ if (value == null)
+ {
+ value = getOldSerializedViewsMap().get(key);
+ }
+ return value;
+ }
+ }
+
+ protected static class SerializedViewKey implements Serializable {
+ private static final long serialVersionUID = -1170697124386063642L;
+
+ private final String _viewId;
+ private final Integer _sequenceId;
+
+ public SerializedViewKey(String viewId, Integer sequence) {
+ _sequenceId = sequence;
+ _viewId = viewId;
+ }
+
+ public SerializedViewKey(FacesContext context) {
+ _sequenceId = ViewSequenceUtils.getViewSequence(context);
+ _viewId = context.getViewRoot().getViewId();
+ }
+
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (obj == this) {
+ return true;
+ }
+ if (obj instanceof SerializedViewKey) {
+ SerializedViewKey other = (SerializedViewKey) obj;
+ return new EqualsBuilder().append(other._viewId, _viewId).append(other._sequenceId,
+ _sequenceId).isEquals();
+ }
+ return false;
+ }
+
+ public int hashCode() {
+ return new HashCodeBuilder().append(_viewId).append(_sequenceId).toHashCode();
+ }
+ }
+}
Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/PssJspViewHandlerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/PssJspViewHandlerImpl.java?view=auto&rev=511461
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/PssJspViewHandlerImpl.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/PssJspViewHandlerImpl.java Sun Feb 25 00:10:54 2007
@@ -0,0 +1,323 @@
+/*
+ * 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.portlet.PortletUtil;
+import org.apache.myfaces.shared_impl.webapp.webxml.ServletMapping;
+import org.apache.myfaces.shared_impl.webapp.webxml.WebXml;
+import org.apache.myfaces.util.DebugUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.faces.application.ViewHandler;
+import javax.faces.application.Application;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.component.UIViewRoot;
+import javax.faces.FacesException;
+import javax.faces.FactoryFinder;
+import javax.faces.render.RenderKitFactory;
+import javax.faces.render.RenderKit;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletResponseWrapper;
+import java.util.Locale;
+import java.util.List;
+import java.io.IOException;
+
+/**
+ * @author Martin Haimberger
+ */
+public class PssJspViewHandlerImpl extends ViewHandler
+{
+ private static final Log log = LogFactory.getLog(JspViewHandlerImpl.class);
+ private ViewHandler oldViewHandler = null;
+
+ 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 Boolean _partialStateSaving = null;
+
+
+ private int bufSize = 32;
+
+ private boolean isPartialStateSavingOn(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 ViewHandler getOldViewHandler()
+ {
+ if (oldViewHandler == null)
+ {
+ oldViewHandler = new JspViewHandlerImpl();
+ }
+ return oldViewHandler;
+ }
+
+ public PssJspViewHandlerImpl() {
+ super();
+ if (log.isTraceEnabled()) log.trace("New partial ViewHandler instance created");
+ }
+
+ public Locale calculateLocale(FacesContext context)
+ {
+ return getOldViewHandler().calculateLocale(context);
+ }
+
+ public String calculateRenderKitId(FacesContext context)
+ {
+ return getOldViewHandler().calculateRenderKitId(context);
+ }
+
+ public UIViewRoot createView(FacesContext context, String viewId)
+ {
+ return getOldViewHandler().createView(context,viewId);
+ }
+
+ public String getActionURL(FacesContext context, String viewId)
+ {
+ return getOldViewHandler().getActionURL(context,viewId);
+ }
+
+ public String getResourceURL(FacesContext context, String path)
+ {
+ return getOldViewHandler().getResourceURL(context,path);
+ }
+
+ public UIViewRoot restoreView(FacesContext context, String viewId)
+ {
+ if (!isPartialStateSavingOn(context)) {
+ log.fatal("Partial state saving ViewHandler is installed, but partial state saving is not enabled. Please enable partial state saving or use another ViewHandler.");
+ }
+
+
+ UIViewRoot root = null;
+
+ Application application = context.getApplication();
+ ViewHandler applicationViewHandler = application.getViewHandler();
+ String renderKitId = applicationViewHandler.calculateRenderKitId(context);
+
+ root = context.getApplication().getStateManager().restoreView(context,viewId,renderKitId);
+ return root;
+ }
+
+
+
+
+ public void writeState(FacesContext context) throws IOException
+ {
+ getOldViewHandler().writeState(context);
+ }
+
+ public void renderView(FacesContext facesContext, UIViewRoot viewToRender)
+ throws IOException, FacesException
+ {
+ if (viewToRender == null)
+ {
+ log.fatal("viewToRender must not be null");
+ throw new NullPointerException("viewToRender must not be null");
+ }
+
+ ExternalContext externalContext = facesContext.getExternalContext();
+
+ String viewId = facesContext.getViewRoot().getViewId();
+
+ if (PortletUtil.isPortletRequest(facesContext)) {
+ externalContext.dispatch(viewId);
+ return;
+ }
+
+ ServletMapping servletMapping = getServletMapping(externalContext);
+
+ if (servletMapping != null && servletMapping.isExtensionMapping())
+ {
+ String defaultSuffix = externalContext.getInitParameter(ViewHandler.DEFAULT_SUFFIX_PARAM_NAME);
+ String suffix = defaultSuffix != null ? defaultSuffix : ViewHandler.DEFAULT_SUFFIX;
+ DebugUtils.assertError(suffix.charAt(0) == '.',
+ log, "Default suffix must start with a dot!");
+ if (!viewId.endsWith(suffix))
+ {
+ int dot = viewId.lastIndexOf('.');
+ if (dot == -1)
+ {
+ if (log.isTraceEnabled()) log.trace("Current viewId has no extension, appending default suffix " + suffix);
+ viewId = viewId + suffix;
+ }
+ else
+ {
+ if (log.isTraceEnabled()) log.trace("Replacing extension of current viewId by suffix " + suffix);
+ viewId = viewId.substring(0, dot) + suffix;
+ }
+ facesContext.getViewRoot().setViewId(viewId);
+ }
+ }
+
+ if (log.isTraceEnabled()) log.trace("Dispatching to " + viewId);
+
+ // handle character encoding as of section 2.5.2.2 of JSF 1.1
+ if (externalContext.getResponse() instanceof ServletResponse) {
+ ServletResponse response = (ServletResponse) externalContext.getResponse();
+ response.setLocale(viewToRender.getLocale());
+ }
+
+ ResponseWriter oldWriter = facesContext.getResponseWriter();
+ HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
+ HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
+
+ RenderKitFactory renderFactory = (RenderKitFactory)
+ FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
+ RenderKit renderKit =
+ renderFactory.getRenderKit(facesContext, viewToRender.getRenderKitId());
+
+
+ BufferedStringWriter strWriter = new BufferedStringWriter(facesContext, bufSize);
+ ResponseWriter newWriter;
+ if (null != oldWriter) {
+ newWriter = oldWriter.cloneWithWriter(strWriter);
+ } else {
+ newWriter = renderKit.createResponseWriter(strWriter, null,
+ request.getCharacterEncoding());
+ }
+ facesContext.setResponseWriter(newWriter);
+
+
+ ResponseWriter responseWriter;
+ if (null != oldWriter) {
+ responseWriter = oldWriter.cloneWithWriter(response.getWriter());
+ } else {
+ response.reset();
+ responseWriter = newWriter.cloneWithWriter(response.getWriter());
+ }
+
+ // now render the UIViewRoot
+ newWriter.startDocument();
+ newWriter.flush();
+ EncodeAllComponentUtil.encodeAll(facesContext,viewToRender);
+ newWriter.flush();
+ newWriter.endDocument();
+
+ facesContext.setResponseWriter(responseWriter);
+ strWriter.flushToWriter(responseWriter);
+
+ if (oldWriter != null)
+ {
+ facesContext.setResponseWriter(oldWriter);
+ }
+
+ if (facesContext.getExternalContext().getResponse() instanceof ServletResponseWrapper)
+ ((ServletResponseWrapper)facesContext.getExternalContext().getResponse()).setContentType("text/html");
+
+
+ // handle character encoding as of section 2.5.2.2 of JSF 1.1
+ if (externalContext.getRequest() instanceof HttpServletRequest) {
+ HttpSession session = request.getSession(false);
+
+ if (session != null) {
+ session.setAttribute(ViewHandler.CHARACTER_ENCODING_KEY, response.getCharacterEncoding());
+ }
+ }
+
+ }
+
+
+ private static ServletMapping getServletMapping(ExternalContext externalContext)
+ {
+ String servletPath = externalContext.getRequestServletPath();
+ String requestPathInfo = externalContext.getRequestPathInfo();
+
+ WebXml webxml = WebXml.getWebXml(externalContext);
+ List mappings = webxml.getFacesServletMappings();
+
+
+ if (requestPathInfo == null)
+ {
+ // might be extension mapping
+ for (int i = 0, size = mappings.size(); i < size; i++)
+ {
+ ServletMapping servletMapping = (ServletMapping) mappings.get(i);
+ String urlpattern = servletMapping.getUrlPattern();
+ String extension = urlpattern.substring(1, urlpattern.length());
+ if (servletPath.endsWith(extension))
+ {
+ return servletMapping;
+ } else if (servletPath.equals(urlpattern)) {
+ // path mapping with no pathInfo for the current request
+ return servletMapping;
+ }
+ }
+ }
+ else
+ {
+ // path mapping
+ for (int i = 0, size = mappings.size(); i < size; i++)
+ {
+
+ ServletMapping servletMapping = (ServletMapping) mappings.get(i);
+ String urlpattern = servletMapping.getUrlPattern();
+ urlpattern = urlpattern.substring(0, urlpattern.length() - 2);
+ // servletPath starts with "/" except in the case where the
+ // request is matched with the "/*" pattern, in which case
+ // it is the empty string (see Servlet Sepc 2.3 SRV4.4)
+ if (servletPath.equals(urlpattern))
+ {
+ return servletMapping;
+ }
+ }
+ }
+
+ // handle cases as best possible where servletPath is not a faces servlet,
+ // such as when coming through struts-faces
+ if (mappings.size() > 0)
+ {
+ return (ServletMapping) mappings.get(0);
+ }
+ else
+ {
+ log.warn("no faces servlet mappings found");
+ return null;
+ }
+ }
+}
Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/TempServletOutputStream.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/TempServletOutputStream.java?view=auto&rev=511461
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/TempServletOutputStream.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/TempServletOutputStream.java Sun Feb 25 00:10:54 2007
@@ -0,0 +1,63 @@
+/*
+ * 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 javax.servlet.ServletOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.io.PrintWriter;
+import java.io.CharArrayWriter;
+
+/**
+ * @author Martin Haimberger
+ */
+
+class TempServletOutputStream extends ServletOutputStream {
+ private ByteArrayOutputStream tempOS = null;
+
+
+ public TempServletOutputStream() {
+ tempOS = new ByteArrayOutputStream();
+ }
+
+ public void write(int n) {
+ tempOS.write(n);
+ }
+
+ public void resetByteArray() {
+ tempOS.reset();
+ }
+
+ public byte[] toByteArray() {
+ return tempOS.toByteArray();
+ }
+
+ public String toString() {
+ return tempOS.toString();
+ }
+
+ public String toString(String enc) {
+ String result = null;
+ try {
+ result = tempOS.toString(enc);
+ }
+ catch (UnsupportedEncodingException usee) {
+ }
+ return result;
+ }
+ }
+
Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/TreeStructComponent.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/TreeStructComponent.java?view=auto&rev=511461
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/TreeStructComponent.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/TreeStructComponent.java Sun Feb 25 00:10:54 2007
@@ -0,0 +1,117 @@
+/*
+ * 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 javax.faces.context.FacesContext;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.HashSet;
+
+/**
+ * @author Martin Haimberger
+ */
+public class TreeStructComponent
+ implements Serializable
+{
+
+ final public static byte STATE_IS_TEMPLATE_STATE = 1;
+ final public static byte STATE_IS_NEW_STATE = 2;
+ final public static byte STATE_IS_NEW_COMPONENT = 3;
+ final public static byte STATE_IS_RESTORED = 4;
+
+ private static final long serialVersionUID = 5069177074684737231L;
+ private Integer _componentClass;
+ private String _componentId;
+ private TreeStructComponent[] _children = null; // Array of children
+ private Object[] _facets = null; // Array of Array-tuples with Facetname and TreeStructComponent
+ private Object _componentState = null;
+ private byte status = 0;
+ private boolean _transient;
+
+ public boolean isTransient() {
+ return _transient;
+ }
+
+ public void setTransient(boolean _transient) {
+ this._transient = _transient;
+ }
+
+ public byte getStatus() {
+ return status;
+ }
+
+ public void setStatus(byte status) {
+ this.status = status;
+ }
+
+ public Object get_componentState() {
+ return _componentState;
+ }
+
+ public void set_componentState(Object _componentState) {
+ this._componentState = _componentState;
+ }
+
+ TreeStructComponent(Integer componentClass, String componentId,Object componentState, boolean isTransient)
+ {
+ _componentClass = componentClass;
+ _componentId = componentId;
+ set_componentState(componentState);
+ _transient = isTransient;
+
+ }
+
+ public Integer getComponentClass()
+ {
+ return _componentClass;
+ }
+
+ public String getComponentId()
+ {
+ return _componentId;
+ }
+
+ void setChildren(TreeStructComponent[] children)
+ {
+ _children = children;
+ }
+
+ TreeStructComponent[] getChildren()
+ {
+ return _children;
+ }
+
+ Object[] getFacets()
+ {
+ return _facets;
+ }
+
+ void setFacets(Object[] facets)
+ {
+ _facets = facets;
+ }
+
+ public TreeStructComponent clone(TreeStructComponent org)
+ {
+ if (org == null)
+ {
+ return new TreeStructComponent(getComponentClass(),getComponentId(),get_componentState(),isTransient());
+ }
+ return new TreeStructComponent(org.getComponentClass(),org.getComponentId(),org.get_componentState(),org.isTransient());
+ }
+
+}
Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/UIViewRootWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/UIViewRootWrapper.java?view=auto&rev=511461
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/UIViewRootWrapper.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/UIViewRootWrapper.java Sun Feb 25 00:10:54 2007
@@ -0,0 +1,127 @@
+package org.apache.myfaces.application.pss;
+
+import javax.faces.component.UIViewRoot;
+import javax.faces.component.UIComponentBase;
+import javax.faces.event.FacesEvent;
+import javax.faces.context.FacesContext;
+import java.util.*;
+import java.io.IOException;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: retro
+ * Date: Feb 23, 2007
+ * Time: 1:12:32 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class UIViewRootWrapper extends UIViewRoot
+{
+
+ private UIViewRoot _originalViewRoot;
+
+ public UIViewRootWrapper( UIViewRoot orUiViewRoot) {
+ _originalViewRoot = orUiViewRoot;
+ }
+
+ public boolean getRendersChildren() {
+ return true;
+ }
+
+
+
+ public String getViewId()
+ {
+ return _originalViewRoot.getViewId();
+ }
+
+ public void setViewId(String viewId)
+ {
+ _originalViewRoot.setViewId(viewId);
+ }
+
+ public void queueEvent(FacesEvent event)
+ {
+ _originalViewRoot.queueEvent(event);
+ }
+
+ public void processDecodes(FacesContext context)
+ {
+ _originalViewRoot.processDecodes(context);
+ }
+
+ public void processValidators(FacesContext context)
+ {
+ _originalViewRoot.processValidators(context);
+ }
+
+ public void processUpdates(FacesContext context)
+ {
+ _originalViewRoot.processUpdates(context);
+ }
+
+ public void processApplication(FacesContext context)
+ {
+ _originalViewRoot.processApplication(context);
+ }
+
+ public void encodeBegin(FacesContext context)
+ throws java.io.IOException
+ {
+ _originalViewRoot.encodeBegin(context);
+ }
+
+ /* Provides a unique id for this component instance.
+ */
+ public String createUniqueId()
+ {
+ return _originalViewRoot.createUniqueId();
+ }
+
+ public Locale getLocale()
+ {
+ return _originalViewRoot.getLocale();
+ }
+
+
+ public void setLocale(Locale locale)
+ {
+ _originalViewRoot.setLocale(locale);
+ }
+
+ //------------------ GENERATED CODE BEGIN (do not modify!) --------------------
+
+ public static final String COMPONENT_TYPE = "javax.faces.ViewRoot";
+ public static final String COMPONENT_FAMILY = "javax.faces.ViewRoot";
+ //private static final String DEFAULT_RENDERKITID = RenderKitFactory.HTML_BASIC_RENDER_KIT;
+
+ public String getFamily()
+ {
+ return COMPONENT_FAMILY;
+ }
+
+
+ public void setRenderKitId(String renderKitId)
+ {
+ _originalViewRoot.setRenderKitId(renderKitId);
+ }
+
+ public String getRenderKitId()
+ {
+ return _originalViewRoot.getRenderKitId();
+ }
+
+
+
+ public Object saveState(FacesContext context)
+ {
+ return _originalViewRoot.saveState(context);
+ }
+
+ public void restoreState(FacesContext context, Object state)
+ {
+ _originalViewRoot.restoreState(context,state);
+ }
+ //------------------ GENERATED CODE END ---------------------------------------
+
+
+}
Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/ViewHandlerResponseWrapperHelperImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/ViewHandlerResponseWrapperHelperImpl.java?view=auto&rev=511461
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/ViewHandlerResponseWrapperHelperImpl.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/pss/ViewHandlerResponseWrapperHelperImpl.java Sun Feb 25 00:10:54 2007
@@ -0,0 +1,108 @@
+/*
+ * 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 javax.servlet.http.HttpServletResponseWrapper;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.CharArrayWriter;
+
+/**
+ * @author Martin Haimberger
+ */
+public class ViewHandlerResponseWrapperHelperImpl extends HttpServletResponseWrapper {
+ private TempServletOutputStream tempOS = null;
+ private PrintWriter pw = null;
+ private CharArrayWriter caw = null;
+ private int status = HttpServletResponse.SC_OK;
+
+ public PrintWriter getPw() {
+ if (pw == null) {
+ caw = new CharArrayWriter();
+ pw = new PrintWriter(caw);
+ }
+ return pw;
+ }
+
+ public ServletOutputStream getTempOS() {
+ if (tempOS == null)
+ {
+ tempOS = new TempServletOutputStream();
+ }
+ return tempOS;
+ }
+
+ public ViewHandlerResponseWrapperHelperImpl(HttpServletResponse httpServletResponse) {
+ super(httpServletResponse);
+ }
+
+
+ // from HttpServletResponseWrapper
+ public void sendError(int i, String string) throws IOException {
+ super.sendError(i, string);
+ status = i;
+ }
+
+ public void sendError(int i) throws IOException {
+ super.sendError(i);
+ status = i;
+ }
+
+ public void setStatus(int i) {
+ super.setStatus(i);
+ status = i;
+ }
+
+ public void setStatus(int i, String string) {
+ super.setStatus(i, string);
+ status = i;
+ }
+
+
+ public String toString() {
+ String result = null;
+ if (caw != null) {
+ result = caw.toString();
+ }
+ else if (tempOS != null) {
+ result = tempOS.toString();
+ }
+
+ return result;
+ }
+
+ public PrintWriter getWriter() throws IOException {
+ return getPw();
+ }
+
+ public ServletOutputStream getOutputStream() throws IOException {
+ return getTempOS();
+ }
+
+ public void resetWriter() {
+ if (caw != null)
+ {
+ pw.flush();
+ caw.flush();
+ caw.reset();
+ }
+ }
+
+
+}
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/portlet/PortletExternalContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/portlet/PortletExternalContextImpl.java?view=diff&rev=511461&r1=511460&r2=511461
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/portlet/PortletExternalContextImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/portlet/PortletExternalContextImpl.java Sun Feb 25 00:10:54 2007
@@ -334,6 +334,12 @@
return _portletResponse;
}
+ public void setResponse(Object response) {
+ if (response instanceof PortletResponse) {
+ this._portletResponse = (PortletResponse) response;
+ }
+ }
+
public Object getSession(boolean create) {
return _portletRequest.getPortletSession(create);
}
Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImpl.java?view=diff&rev=511461&r1=511460&r2=511461
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImpl.java Sun Feb 25 00:10:54 2007
@@ -215,6 +215,12 @@
return _servletResponse;
}
+ public void setResponse(Object response) {
+ if (response instanceof ServletResponse) {
+ this._servletResponse = (ServletResponse) response;
+ }
+ }
+
public Map getApplicationMap()
{
if (_applicationMap == null)