⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scxmldialognavigationhandler.java

📁 java xml bean把xml解析成bean
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * 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.
 */
/*
 * You may build in a package on your choice. Dependency information:
 *
 * Commons SCXML dependencies -
 * http://commons.apache.org/scxml/dependencies.html
 *
 * Apache Shale dependencies -
 * http://shale.apache.org/dependencies.html
 */
package org.apache.commons.scxml.usecases;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.faces.application.NavigationHandler;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;

import org.apache.commons.digester.Digester;
import org.apache.commons.digester.Rule;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.commons.scxml.SCXMLDigester;
import org.apache.commons.scxml.SCXMLExecutor;
import org.apache.commons.scxml.TriggerEvent;
import org.apache.commons.scxml.env.SimpleDispatcher;
import org.apache.commons.scxml.env.SimpleErrorHandler;
import org.apache.commons.scxml.env.SimpleErrorReporter;
import org.apache.commons.scxml.env.SimpleSCXMLListener;
import org.apache.commons.scxml.env.faces.SessionContext;
import org.apache.commons.scxml.env.faces.ShaleDialogELEvaluator;
import org.apache.commons.scxml.model.ModelException;
import org.apache.commons.scxml.model.SCXML;
import org.apache.commons.scxml.model.TransitionTarget;

import org.apache.shale.dialog.Globals;
import org.apache.shale.dialog.Status;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;

/**
 * <p>SCXML configuration file(s) driven Shale dialog navigation handler.</p>
 *
 * <p>Recipe for using SCXML documents to drive Shale dialogs:
 *   <ol>
 *    <li>Build the <code>SCXMLDialogNavigationHandler</code> (available
 *     below, use a Commons SCXML nightly build 10/09/05 or later) and make it
 *     available to your web application classpath (<code>WEB-INF/classes</code>).
 *    </li>
 *    <li>Update the &quot;<code>WEB-INF/faces-config.xml</code>&quot;
 *     for your web application such that the
 *     &quot;<code>faces-config/application/navigation-handler</code>&quot;
 *     entry points to
 *     &quot;<code>org.apache.commons.scxml.usecases.SCXMLDialogNavigationHandler</code>&quot;
 *     (with the appropriate package name, if you changed it).
 *    </li>
 *    <li>As an alternative to (1) and (2), you can place a <i>jar</i> in the 
 *     <code>WEB-INF/lib</code> directory which contains the
 *     <code>SCXMLDialogNavigationHandler</code> and a
 *     <code>META-INF/faces-config.xml</code> with just the entry in (2).</li>
 *    <li>Use SCXML documents to describe Shale dialog flows (details below)
 *     in your application. You may have multiple mappings from transition
 *     targets to JSF views to support multi-channel applications.</li>
 *    <li>The SCXML-based dialog is entered when
 *     <code>handleNavigation()</code> is called with a logical outcome
 *     of the form &quot;<code>dialog:xxx</code>&quot; and there is no current
 *     dialog in progress, where &quot;<code>xxx</code>&quot; is the URL pointing
 *     to the SCXML document.</li>
 *   </ol>
 * </p>
 *
 * <p>Using SCXML documents to define the Shale dialog "flows":
 *   <ul>
 *     <li>ActionState instances may be mapped to executable content
 *         in UML &lt;onentry&gt (and may be chained similarly).</li>
 *     <li>ViewState instances may be mapped to UML transition
 *         targets.</li>
 *     <li>SubdialogState instances may be mapped to external SCXML
 *         documents.</li>
 *     <li>EndState instances may be mapped to SCXML final states.</li>
 *     <li>The {@link SCXMLDialogNavigationHandler} defines a
 *         &quot;faces.outcome&quot; event which the relevant SCXML
 *         transitions from a &quot;view state&quot; can wait for.</li>
 *   </ul>
 * </p>
 *
 * <p>Towards pluggable dialog management in Shale - A &quot;black box&quot;
 *    dialog may consist of the following tuple:
 *   <ul>
 *     <li>Unique dialog identifier</li>
 *     <li>A generic NavigationHandler (i.e. dialog strategy)</li>
 *     <li>An dialog/flow configuration resource (Ex: SCXML document)</li>
 *     <li>Optionally, multiple other configuration resources,
 *      (Ex: one for each channel - web, voice, small device, etc.)</li>
 *   </ul>
 *    The Shale DialogNavigationHandler may then delegate appropriately.
 * </p>
 */
public final class SCXMLDialogNavigationHandler extends NavigationHandler {

    // ------------------------------------------------------------ Constructors
    /**
     * <p>Create a new {@link SCXMLDialogNavigationHandler}, wrapping the
     * specified standard navigation handler implementation.</p>
     *
     * @param handler Standard <code>NavigationHandler</code> we are wrapping
     */
    public SCXMLDialogNavigationHandler(NavigationHandler handler) {

        this.handler = handler;

    }

    // -------------------------------------------------------- Static Variables
    /**
     * <p>The prefix on a logical outcome String that indicates the remainder
     * of the string is the URL of a SCXML-based Shale dialog to be entered.</p>
     */
    public static final String PREFIX = "dialog:";

    // ------------------------------------------------------ Instance Variables

    /**
     * <p>The standard <code>NavigationHandler</code> implementation that
     * we are wrapping.</p>
     */
    private NavigationHandler handler = null;

    /**
     * <p>The <code>Log</code> instance for this class.</p>
     */
    private final Log log = LogFactory.getLog(getClass());

    /**
     * <p>Key under which we will store the SCXMLExecutor (more generally,
     * some session scoped state pertaining to the current dialog).</p>
     */
    private String dialogKey = null; // Cached on first use

    /**
     * <p>Map storing SCXML state IDs as keys and JSF view IDs as values.</p>
     */
    private Map target2viewMap = null;

    // ----------------------------------------------- NavigationHandler Methods

    /**
     * <p>Handle the navigation request implied by the specified parameters.</p>
     *
     * @param context <code>FacesContext</code> for the current request
     * @param fromAction The action binding expression that was evaluated
     *  to retrieve the specified outcome (if any)
     * @param outcome The logical outcome returned by the specified action
     *
     * @exception IllegalArgumentException if the configuration information
     *  for a previously saved position cannot be found
     * @exception IllegalArgumentException if an unknown State type is found
     */
    public void handleNavigation(FacesContext context, String fromAction,
                                 String outcome) {

        if (log.isDebugEnabled()) {
            log.debug("handleNavigation(viewId=" +
                      context.getViewRoot().getViewId() +
                      ",fromAction=" + fromAction +
                      ",outcome=" + outcome + ")");
        }

        SCXMLExecutor exec = getDialogExecutor(context);
        String viewId = null;
        
        if (exec == null && outcome != null && outcome.startsWith(PREFIX)) {
        	
        	/**** DIALOG ENTRY ****/
        	// dialog is a state machine, parse & obtain an executor
        	exec = initDialogExecutor(context, outcome.substring(PREFIX.
        			length()));

        	if (exec != null) {
        		// cache executor in session scope
        		// TODO: Shale caches Dialog instances. SCXMLExecutor
        		// knows what state(s) the dialog is in, so Dialog#findState()
        		// is not needed.
        		setDialogExecutor(context, exec);
        		// obtain our initial view
        		viewId = getCurrentViewId(exec);
        	}
        	// else delegate
        	
        } else if (exec != null) {
        	
        	/**** SUBSEQUENT TURNS OF DIALOG ****/
        	// pass a handle to the current ctx (for evaluating binding exprs)
        	updateEvaluator(context, outcome);
        	// fire a "faces.outcome" event on the dialog's state machine
        	TriggerEvent[] te = { new TriggerEvent("faces.outcome",
        			TriggerEvent.SIGNAL_EVENT) };
        	try {
        		exec.triggerEvents(te);
        	} catch (ModelException me) {
        		log.error(me.getMessage(), me);
        	}
        	// obtain next view
        	viewId = getCurrentViewId(exec);
        }

        if (viewId != null) {
        
        	// we understood this "outcome" and we have a new view to render
        	log.info("Rendering view: " + viewId);
        	updateDialogStatus(context, exec);
        	render(context, viewId);

        } else {
        
        	/**** DELEGATE BY DEFAULT ****/
        	handler.handleNavigation(context, fromAction, outcome);

        }


    }

    /**
     * <p>Return the SCXMLExecutor for the specified SCXML document, if it
     * exists; otherwise, return <code>null</code>.</p>
     *
     * @param context <code>FacesContext</code> for the current request
     * @param dialogIdentifier URL of the SCXML document for the requested
     *                         dialog
     */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -