Package org.apache.myfaces.application

Source Code of org.apache.myfaces.application.StateManagerImpl

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.myfaces.application;

import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.faces.FactoryFinder;
import javax.faces.application.StateManager;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.render.RenderKit;
import javax.faces.render.RenderKitFactory;
import javax.faces.render.ResponseStateManager;
import javax.faces.view.StateManagementStrategy;
import javax.faces.view.ViewDeclarationLanguage;

import org.apache.myfaces.renderkit.StateCacheUtils;

public class StateManagerImpl extends StateManager
{
    private static final Logger log = Logger.getLogger(StateManagerImpl.class.getName());
   
    private static final String SERIALIZED_VIEW_REQUEST_ATTR =
        StateManagerImpl.class.getName() + ".SERIALIZED_VIEW";
   
    private RenderKitFactory _renderKitFactory = null;
   
    public StateManagerImpl()
    {
    }

    @Override
    protected Object getComponentStateToSave(FacesContext facesContext)
    {
        if (log.isLoggable(Level.FINEST)) log.finest("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.isLoggable(Level.FINEST)) log.finest("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.
     */
    @Override
    protected Object getTreeStructureToSave(FacesContext facesContext)
    {
        if (log.isLoggable(Level.FINEST)) log.finest("Entering getTreeStructureToSave");
        UIViewRoot viewRoot = facesContext.getViewRoot();
        if (viewRoot.isTransient())
        {
            return null;
        }
        TreeStructureManager tsm = new TreeStructureManager();
        Object retVal = tsm.buildTreeStructureToSave(viewRoot);
        if (log.isLoggable(Level.FINEST)) log.finest("Exiting getTreeStructureToSave");
        return retVal;
    }

    @Override
    public UIViewRoot restoreView(FacesContext facesContext, String viewId, String renderKitId)
    {
        if (log.isLoggable(Level.FINEST)) log.finest("Entering restoreView - viewId: "+viewId+" ; renderKitId: "+renderKitId);

        UIViewRoot uiViewRoot = null;
       
        ViewDeclarationLanguage vdl = facesContext.getApplication().
            getViewHandler().getViewDeclarationLanguage(facesContext,viewId);
        StateManagementStrategy sms = null;
        if (vdl != null)
        {
            sms = vdl.getStateManagementStrategy(facesContext, viewId);
        }
       
        if (sms != null)
        {
            if (log.isLoggable(Level.FINEST)) log.finest("Redirect to StateManagementStrategy: "+sms.getClass().getName());
           
            uiViewRoot = sms.restoreView(facesContext, viewId, renderKitId);
        }
        else
        {
            RenderKit renderKit = getRenderKitFactory().getRenderKit(facesContext, renderKitId);
            ResponseStateManager responseStateManager = renderKit.getResponseStateManager();

            Object state = responseStateManager.getState(facesContext, viewId);

            if (state != null) {
                Object[] stateArray = (Object[])state;
                TreeStructureManager tsm = new TreeStructureManager();
                uiViewRoot = tsm.restoreTreeStructure(stateArray[0]);

                if (uiViewRoot != null) {
                    facesContext.setViewRoot (uiViewRoot);
                    uiViewRoot.processRestoreState(facesContext, stateArray[1]);
                }
            }           
        }
        if (log.isLoggable(Level.FINEST)) log.finest("Exiting restoreView - "+viewId);

        return uiViewRoot;
    }

    /**
     * Wrap the original method and redirect to VDL StateManagementStrategy when
     * necessary
     */
    @Override
    public Object saveView(FacesContext facesContext)
    {
        Object serializedView = null;
        UIViewRoot uiViewRoot = facesContext.getViewRoot();
        ResponseStateManager responseStateManager = facesContext.getRenderKit().getResponseStateManager();
       
        String viewId = uiViewRoot.getViewId();
        ViewDeclarationLanguage vdl = facesContext.getApplication().
            getViewHandler().getViewDeclarationLanguage(facesContext,viewId);
        if (vdl != null)
        {
            StateManagementStrategy sms = vdl.getStateManagementStrategy(facesContext, viewId);
           
            if (sms != null)
            {
                if (log.isLoggable(Level.FINEST)) log.finest("Calling saveView of StateManagementStrategy: "+sms.getClass().getName());
               
                serializedView = sms.saveView(facesContext);
               
                // If MyfacesResponseStateManager is used, give the option to do
                // additional operations for save the state if is necessary.
                if (StateCacheUtils.isMyFacesResponseStateManager(responseStateManager))
                {
                    StateCacheUtils.getMyFacesResponseStateManager(responseStateManager).saveState(facesContext, serializedView);
                }
               
                return serializedView;
            }
        }

        // In StateManagementStrategy.saveView there is a check for transient at
        // start, but the same applies for VDL without StateManagementStrategy,
        // so this should be checked before call parent (note that parent method
        // does not do this check).
        if (uiViewRoot.isTransient())
        {
            return null;
        }

        if (log.isLoggable(Level.FINEST)) log.finest("Entering saveSerializedView");

        checkForDuplicateIds(facesContext, facesContext.getViewRoot(), new HashSet<String>());

        if (log.isLoggable(Level.FINEST)) log.finest("Processing saveSerializedView - Checked for duplicate Ids");

        ExternalContext externalContext = facesContext.getExternalContext();

        // SerializedView already created before within this request?
        serializedView = externalContext.getRequestMap()
                                                            .get(SERIALIZED_VIEW_REQUEST_ATTR);
        if (serializedView == null)
        {
            if (log.isLoggable(Level.FINEST)) log.finest("Processing saveSerializedView - create new serialized view");

            // first call to saveSerializedView --> create SerializedView
            Object treeStruct = getTreeStructureToSave(facesContext);
            Object compStates = getComponentStateToSave(facesContext);
            serializedView = new Object[] {treeStruct, compStates};
            externalContext.getRequestMap().put(SERIALIZED_VIEW_REQUEST_ATTR,
                                                serializedView);

            if (log.isLoggable(Level.FINEST)) log.finest("Processing saveSerializedView - new serialized view created");
        }
       
        // If MyfacesResponseStateManager is used, give the option to do
        // additional operations for save the state if is necessary.
        if (StateCacheUtils.isMyFacesResponseStateManager(responseStateManager))
        {
            StateCacheUtils.getMyFacesResponseStateManager(responseStateManager).saveState(facesContext, serializedView);
        }

        if (log.isLoggable(Level.FINEST)) log.finest("Exiting saveView");

        return serializedView;
    }

    private static void checkForDuplicateIds(FacesContext context,
                                             UIComponent component,
                                             Set<String> 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));
        }
       
        if (component instanceof NamingContainer)
        {
            ids = new HashSet<String>();
        }
       
        int facetCount = component.getFacetCount();
        if (facetCount > 0)
        {
            for (UIComponent facet : component.getFacets().values())
            {
                checkForDuplicateIds (context, facet, ids);
            }
        }
        for (int i = 0, childCount = component.getChildCount(); i < childCount; i++)
        {
            UIComponent child = component.getChildren().get(i);
            checkForDuplicateIds (context, child, 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());

        getPathToComponent(component.getParent(),buf);
    }

    @Override
    public void writeState(FacesContext facesContext,
                           Object state) throws IOException
    {
        if (log.isLoggable(Level.FINEST)) log.finest("Entering writeState");

        UIViewRoot uiViewRoot = facesContext.getViewRoot();
        //save state in response (client)
        RenderKit renderKit = getRenderKitFactory().getRenderKit(facesContext, uiViewRoot.getRenderKitId());
        ResponseStateManager responseStateManager = renderKit.getResponseStateManager();

        responseStateManager.writeState(facesContext, state);

        if (log.isLoggable(Level.FINEST)) log.finest("Exiting writeState");

    }

    //helpers

    protected RenderKitFactory getRenderKitFactory()
    {
        if (_renderKitFactory == null)
        {
            _renderKitFactory = (RenderKitFactory)FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
        }
        return _renderKitFactory;
    }

}
TOP

Related Classes of org.apache.myfaces.application.StateManagerImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.