/*
 * 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.orchestra.viewController;

import org.apache.myfaces.orchestra.frameworkAdapter.FrameworkAdapter;

/**
 * A partial implementation of the ViewControllerManager interface which
 * allows subclasses to just implement two simple abstract methods in order
 * to provide a fully functional ViewControllerManager implementation.
 * <p>
 * This implementation splits responsibility for invoking view lifecycle
 * events into three parts:
 * <ul>
 * <li>A "name mapper" that maps a view identifier to a bean name
 * <li>An "executor" that decides which methods on a bean to invoke, and
 * <li>A controller that invokes the mapper and executor.
 * </ul>
 * This class implements the "controller" bit itself, and leaves subclasses
 * to just choose the "name mapper" and "executor" to use by overriding
 * the abstract methods defined here.
 */
public abstract class AbstractViewControllerManager implements ViewControllerManager
{
    protected abstract ViewControllerNameMapper getViewControllerNameMapper();
    protected abstract ViewControllerExecutor getViewControllerExecutor();

    public String getViewControllerName(String viewId)
    {
        ViewControllerNameMapper nameMapper = getViewControllerNameMapper();
        return nameMapper.mapViewId(viewId);
    }

    public Object getViewController(String viewId)
    {
        String beanName = getViewControllerName(viewId);
        if (beanName == null)
        {
            return null;
        }

        return FrameworkAdapter.getCurrentInstance().getBean(beanName);
    }

    public void assertConversationState(String viewId)
    {
    }

    public void executeInitView(String viewId)
    {
        String beanName = getViewControllerNameMapper().mapViewId(viewId);
        Object viewController = getViewController(viewId);
        if (viewController != null)
        {
            getViewControllerExecutor().invokeInitView(beanName, viewController);
        }
    }

    public void executePreProcess(String viewId)
    {
        String beanName = getViewControllerNameMapper().mapViewId(viewId);
        Object viewController = getViewController(viewId);
        if (viewController != null)
        {
            getViewControllerExecutor().invokePreProcess(beanName, viewController);
        }
    }

    public void executePreRenderView(String viewId)
    {
        String beanName = getViewControllerNameMapper().mapViewId(viewId);
        Object viewController = getViewController(viewId);
        if (viewController != null)
        {
            getViewControllerExecutor().invokePreRenderView(beanName, viewController);
        }
    }
}