/*
 * 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;

/**
 * Route per-view lifecycle events to the correct user methods.
 * <p>
 * The name "view" is used for the resource that the user has accessed. For example
 * with JSF either one or two views are accessed per user request; possibly a "postback"
 * and always a "render" view. Orchestra adaptors for other UI frameworks select
 * an interpretation of the name "view" appropriate for that framework. 
 * <p>
 * Orchestra retrieves a concrete implementation of this interface and invokes it at the
 * appropriate processing phases. Exactly what those phases are depend upon the underlying
 * UI framework. The concrete ViewControllerManager is then responsible for determining
 * which beans should receive callbacks (based upon the resource that the user has accessed)
 * <p>
 * Orchestra provides a default implementation of this interface; see
 * {@link DefaultViewControllerManager}.
 *
 * <h2>Defining your own ViewControllerManager</h2>
 *
 * If you would like to customise the way beans are located for a view, or which methods
 * are invoked on them then either
 * <ul>
 * <li>Implement this interface directly, or
 * <li>Subclass {@link AbstractViewControllerManager} (the recommended way).
 * </ul>
 * <p>
 * To activate your custom manager, configure it as a managed bean (preferably in
 * application or singleton scope), using the bean-name
 * <code>org.apache.myfaces.orchestra.viewController.ViewControllerManager</code>
 * (see constant {@link ViewControllerManager#VIEW_CONTROLLER_MANAGER_NAME}).
 * 
 * <h2>How the ViewControllerManager is invoked</h2>
 * 
 * Each UI framework needs to ensure that the ViewControllerManager is retrieved via the
 * special name shown above, and invoked at appropriate times. For example, for JSF
 * see class @{org.apache.myfaces.orchestra.viewController.jsf.ViewControllerPhaseListener};
 * this is automatically configured for JSF applications when the orchestra jarfile is
 * placed in the classpath.
 */
public interface ViewControllerManager
{
    public final static String VIEW_CONTROLLER_MANAGER_NAME = ViewControllerManager.class.getName();

    public Object getViewController(String viewId);
    public String getViewControllerName(String viewId);

    /**
     * Check whether any conversations required for the specified view currently exist.
     * <p>
     * TODO: Consider renaming this method. It is very Orchestra-specific, although this
     * ViewController framework is supposed to be generic. In fact this method
     * is really just a "validate view" hook, and one of the validations that can be hooked
     * in here is a conversation-check.
     */
    public void assertConversationState(String viewId);

    /**
     * This method is guaranteed to be called before any other lifecycle method (ie any of
     * the other execute* methods on this interface. It is also guaranteed to be called
     * before any expression in a page is evaluated.
     * <p>
     * For component-based frameworks, the component tree may not yet exist.
     */
    public void executeInitView(String viewId);

    /**
     * This method is called at most once per request for each view.  
     * <p>
     * For component-based frameworks, this method gets called after all components have
     * transferred their state into associated backing beans. If validation errors have
     * occurred within the view, then this method is not invoked.
     */
    public void executePreProcess(String viewId);

    /**
     * This method is called just before a view is required to render its representation
     * back to the user.
     * <p>
     * If a view X handles a "postback" event, and then navigates to a different view Y then
     * this callback does not occur for the controller bean for view X, but does get invoked
     * for the controller bean for view Y.
     * <p>
     * For component-based frameworks, the component tree may not yet exist at the time this
     * method is invoked.
     */
    public void executePreRenderView(String viewId);
    
    // TODO: implement an endView callback too (and corresponding annotation).
    
    // TODO: implement isPostback() for JSF1.1 users? This is of course built-in for JSF1.2 users...
}
