You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shale.apache.org by cr...@apache.org on 2006/08/29 01:51:08 UTC

svn commit: r437880 [1/2] - in /shale/sandbox/shale-dialog2-legacy: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/shale/ src/main/java/org/apache/shale/dialog2/ src/main/java/org/apache/shale/dia...

Author: craigmcc
Date: Mon Aug 28 16:51:07 2006
New Revision: 437880

URL: http://svn.apache.org/viewvc?rev=437880&view=rev
Log:
State machine implementation for shale-dialog2 that refactors the
existing machinery to use the new APIs.  The new implementation has not
been tested yet.

This implementation was partly done as a proof that the abstracted API
in shale-dialog2 is actually sufficient to implement a version of the
existing functionality, but also might be useful if we decide to stick
with some variant of the existing state machine approach.

SHALE-10 SHALE-48 SHALE-61


Added:
    shale/sandbox/shale-dialog2-legacy/
    shale/sandbox/shale-dialog2-legacy/pom.xml
    shale/sandbox/shale-dialog2-legacy/src/
    shale/sandbox/shale-dialog2-legacy/src/main/
    shale/sandbox/shale-dialog2-legacy/src/main/java/
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/Globals.java
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/LegacyContext.java
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/LegacyContexts.java
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/Position.java
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/AbstractState.java
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/ActionStateImpl.java
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/ConfigurationParser.java
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/DialogImpl.java
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/EndStateImpl.java
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/SubdialogStateImpl.java
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/TransitionImpl.java
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/ViewStateImpl.java
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/ActionState.java
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/Dialog.java
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/EndState.java
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/State.java
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/SubdialogState.java
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/Transition.java
    shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/ViewState.java
    shale/sandbox/shale-dialog2-legacy/src/main/resources/
    shale/sandbox/shale-dialog2-legacy/src/main/resources/META-INF/
    shale/sandbox/shale-dialog2-legacy/src/main/resources/META-INF/LICENSE.txt
    shale/sandbox/shale-dialog2-legacy/src/main/resources/META-INF/NOTICE.txt
    shale/sandbox/shale-dialog2-legacy/src/main/resources/META-INF/faces-config.xml
    shale/sandbox/shale-dialog2-legacy/src/test/
    shale/sandbox/shale-dialog2-legacy/src/test/java/
    shale/sandbox/shale-dialog2-legacy/src/test/resources/

Added: shale/sandbox/shale-dialog2-legacy/pom.xml
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-legacy/pom.xml?rev=437880&view=auto
==============================================================================
--- shale/sandbox/shale-dialog2-legacy/pom.xml (added)
+++ shale/sandbox/shale-dialog2-legacy/pom.xml Mon Aug 28 16:51:07 2006
@@ -0,0 +1,58 @@
+<!--
+/*
+ * Copyright 2006 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.
+ *
+ * $Id: pom.xml 160258 2006-05-21 01:56:12Z wsmoak $
+ */
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.shale</groupId>
+        <artifactId>shale-parent</artifactId>
+        <version>1.0.4-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>shale-dialog2-legacy</artifactId>
+    <packaging>jar</packaging>
+    <name>Shale Dialog Manager (Legacy Implementation)</name>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+<!--
+        <dependency>
+            <groupId>org.apache.shale</groupId>
+            <artifactId>shale-core</artifactId>
+            <version>${pom.version}</version>
+        </dependency>
+-->
+
+        <dependency>
+            <groupId>org.apache.shale</groupId>
+            <artifactId>shale-dialog2</artifactId>
+            <version>${pom.version}</version>
+        </dependency>
+
+    </dependencies>
+
+</project>

Added: shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/Globals.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/Globals.java?rev=437880&view=auto
==============================================================================
--- shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/Globals.java (added)
+++ shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/Globals.java Mon Aug 28 16:51:07 2006
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2006 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.shale.dialog2.legacy;
+
+import org.apache.shale.dialog2.legacy.model.Dialog;
+
+/**
+ * <p>Manifest constants for the legacy dialog state manager implementation.</p>
+ *
+ * @since 1.0.4
+ */
+public class Globals {
+    
+
+    /**
+     * <p>Context initialization paramater name under which a comma separated
+     * list of configuration resources to be parsed exists.</p>
+     */
+    public static final String CONFIGURATION =
+            "org.apache.shale.dialog2.legacy.CONFIGURATION";
+
+
+    /**
+     * <p>Application scope attribute under which a <code>Map</code> of
+     * {@link Dialog} definitions (keyed by dialog name) is stored.</p>
+     */
+    public static final String DIALOGS =
+            "org.apache.shale.dialog2.legacy.DIALOGS";
+
+
+}

Added: shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/LegacyContext.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/LegacyContext.java?rev=437880&view=auto
==============================================================================
--- shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/LegacyContext.java (added)
+++ shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/LegacyContext.java Mon Aug 28 16:51:07 2006
@@ -0,0 +1,451 @@
+/*
+ * Copyright 2006 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.shale.dialog2.legacy;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
+import javax.faces.el.MethodBinding;
+import org.apache.shale.dialog2.Context;
+import org.apache.shale.dialog2.Contexts;
+import org.apache.shale.dialog2.legacy.config.ConfigurationParser;
+import org.apache.shale.dialog2.legacy.model.ActionState;
+import org.apache.shale.dialog2.legacy.model.Dialog;
+import org.apache.shale.dialog2.legacy.model.EndState;
+import org.apache.shale.dialog2.legacy.model.State;
+import org.apache.shale.dialog2.legacy.model.SubdialogState;
+import org.apache.shale.dialog2.legacy.model.Transition;
+import org.apache.shale.dialog2.legacy.model.ViewState;
+
+/**
+ * <p>Implementation of {@link Contexts} for integrating
+ * legacy dialog support into the Shale Dialog Manager.</p>
+ *
+ * <p><strong>IMPLEMENTATION NOTE</strong> - Takes on the responsibilities
+ * of the <code>org.apache.shale.dialog.Status</code> implementation in the
+ * original approach.</p>
+ * 
+ * @since 1.0.4
+ */
+final class LegacyContext implements Context, Serializable {
+    
+
+    // ------------------------------------------------------------ Constructors
+
+
+    /**
+     * <p>Construct a new instance.</p>
+     * 
+     * @param instances {@link Contexts} instance that owns us
+     * @param dialog Configured dialog definition we will be following
+     * @param id Dialog identifier assigned to this instance
+     */
+    LegacyContext(Contexts instances, Dialog dialog, String id) {
+
+        this.instances = instances;
+        this.dialog = dialog;
+        this.id = id;
+
+        start(dialog);
+
+    }
+    
+
+    // ------------------------------------------------------ Context Variables
+
+
+    /**
+     * <p>Flag indicating that this {@link Context} is currently active.</p>
+     */
+    private boolean active = true;
+
+
+    /**
+     * <p>Generic data object containing state information for this instance.</p>
+     */
+    private Object data = null;
+
+
+    /**
+     * <p>The {@link Dialog} that this instance is executing.</p>
+     */
+    private Dialog dialog = null;
+
+
+    /**
+     * <p><code>Map</code> of configured dialogs, keyed by logical name.</p>
+     */
+    private Map dialogs = null;
+
+
+    /**
+     * <p>Dialog identifier for this instance.</p>
+     */
+    private String id = null;
+
+
+    /**
+     * <p>{@link Contexts} instance that owns us.</p>
+     */
+    private Contexts instances = null;
+
+
+    /**
+     * <p>The stack of currently stored Position instances.  If there
+     * are no entries, we have completed the exit state and should deactivate
+     * ourselves.</p>
+     */
+    private List positions = new ArrayList();
+
+
+    /**
+     * <p>References to data objects that are associated with the
+     * Position instances at corresponding indexes in the
+     * <code>positions</code> list.</p>
+     */
+    private List references = new ArrayList();
+
+
+    /**
+     * <p>An empty parameter list to pass to the action method called by
+     * a method binding expression.</p>
+     */
+    private static final Object[] ACTION_STATE_PARAMETERS = new Object[0];
+
+
+    /**
+     * <p>Parameter signature we create for method bindings used to execute
+     * expressions specified by an {@link ActionState}.</p>
+     */
+    private static final Class[] ACTION_STATE_SIGNATURE = new Class[0];
+
+
+    // ----------------------------------------------------- Context Properties
+
+
+    /** {@inheritDoc} */
+    public boolean isActive() {
+
+        return this.active;
+
+    }
+
+
+    /** {@inheritDoc} */
+    public Object getData() {
+
+        // Locks on "positions" for consistency
+        synchronized (positions) {
+            int index = positions.size() - 1;
+            if (index < 0) {
+                return null;
+            }
+            return references.get(index);
+        }
+
+    }
+
+
+
+    /** {@inheritDoc} */
+    public void setData(Object data) {
+
+        // Locks on "positions" for consistency
+        synchronized (positions) {
+            int index = positions.size() - 1;
+            if (index < 0) {
+                throw new IllegalStateException("Cannot set data when no positions are stacked");
+            }
+            references.set(index, data);
+        }
+
+    }
+
+
+    /** {@inheritDoc} */
+    public String getId() {
+
+        return this.id;
+
+    }
+
+
+    /** {@inheritDoc} */
+    public String getName() {
+
+        Position position = peek();
+        if (position != null) {
+            return position.getDialog().getName();
+        } else {
+            return null;
+        }
+
+    }
+
+
+    // -------------------------------------------------------- Context Methods
+
+
+    /** {@inheritDoc} */
+    public String advance(FacesContext context, String outcome) {
+
+        Position position = peek();
+        transition(position, outcome);
+        State state = position.getState();
+        while (true) {
+            if (state instanceof ActionState) {
+                ActionState astate = (ActionState) state;
+                MethodBinding mb = context.getApplication().
+                  createMethodBinding(astate.getMethod(), ACTION_STATE_SIGNATURE);
+                outcome = (String) mb.invoke(context, ACTION_STATE_PARAMETERS);
+                transition(position, outcome);
+                state = position.getState();
+                continue;
+            } else if (state instanceof EndState) {
+                pop();
+                position = peek();
+                if (position == null) {
+                    deactivate();
+                }
+                return ((EndState) state).getViewId();
+            } else if (state instanceof SubdialogState) {
+                SubdialogState sstate = (SubdialogState) state;
+                Dialog subdialog = (Dialog) dialogs(context).get(sstate.getDialogName());
+                if (subdialog == null) {
+                    throw new IllegalStateException("Cannot find dialog definition '"
+                      + sstate.getDialogName() + "'");
+                }
+                start(subdialog);
+                position = peek();
+                continue;
+            } else if (state instanceof ViewState) {
+                return ((ViewState) state).getViewId();
+            } else {
+                throw new IllegalStateException
+                  ("State '" + state.getName()
+                   + "' of dialog '" + position.getDialog().getName()
+                   + "' is of unknown type '" + state.getClass().getName() + "'");
+            }
+        }
+
+
+    }
+
+
+    // ------------------------------------------------- Package Private Methods
+
+
+    /**
+     * <p>Mark this {@link Context} as being deactivated.  This should only
+     * be called by the <code>remove()</code> method on our associated
+     * {@link Contexts}.</p>
+     */
+    void deactivate() {
+
+        this.active = false;
+
+    }
+
+
+    // --------------------------------------------------------- Private Methods
+
+
+    /**
+     * <p>Return a <code>Map</code> of the configured {@link Dialog}s, keyed
+     * by logical dialog name.</p>
+     *
+     * @param context FacesContext for the current request
+     *
+     * @exception IllegalStateException if dialog configuration has not
+     *  been completed
+     */
+    private Map dialogs(FacesContext context) {
+
+        // Return the cached instance (if any)
+        if (this.dialogs != null) {
+            return this.dialogs;
+        }
+
+        // Return the previously configured application scope instance (if any)
+        this.dialogs = (Map)
+          context.getExternalContext().getApplicationMap().get(Globals.DIALOGS);
+        if (this.dialogs != null) {
+            return this.dialogs;
+        }
+
+        // Parse our configuration resources and cache the results
+        ConfigurationParser parser = new ConfigurationParser();
+        parser.setDialogs(new HashMap());
+        String resources =
+          context.getExternalContext().getInitParameter(Globals.CONFIGURATION);
+        if (resources == null) {
+            resources = "";
+        }
+        int comma = 0;
+        String path = null;
+        try {
+            while (true) {
+                comma = resources.indexOf(",");
+                if (comma < 0) {
+                    path = resources.trim();
+                    resources = "";
+                } else {
+                    path = resources.substring(0, comma).trim();
+                    resources = resources.substring(comma + 1);
+                }
+                if (path.length() < 1) {
+                    break;
+                }
+                parser.setResource(context.getExternalContext().getResource(path));
+                parser.parse();
+            }
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new FacesException(e);
+        }
+
+        // Cache the results both locally and in application scope
+        this.dialogs = parser.getDialogs();
+        context.getExternalContext().getApplicationMap().put(Globals.DIALOGS, this.dialogs);
+        return this.dialogs;
+
+    }
+
+
+    /**
+     * <p>Return a <code>Position</code> representing the currently executing
+     * dialog and state (if any); otherwise, return <code>null</code>.</p>
+     */
+    private Position peek() {
+
+        synchronized (positions) {
+            int index = positions.size() - 1;
+            if (index < 0) {
+                return null;
+            }
+            return (Position) positions.get(index);
+        }
+
+    }
+
+
+    /**
+     * <p>Pop the currently executing <code>Position</code> and return the
+     * previously executing <code>Position</code> (if any); otherwise,
+     * return <code>null</code>.</p>
+     */
+    private Position pop() {
+
+        synchronized (positions) {
+            int index = positions.size() - 1;
+            if (index < 0) {
+                throw new IllegalStateException("No position to be popped");
+            }
+            positions.remove(index);
+            references.remove(index);
+            if (index > 0) {
+                return (Position) positions.get(index - 1);
+            } else {
+                return null;
+            }
+        }
+
+    }
+
+
+    /**
+     * <p>Push the specified <code>Position</code>, making it the currently
+     * executing one.</p>
+     *
+     * @param position The new currently executing <code>Position</code>
+     */
+    private void push(Position position) {
+
+        if (position == null) {
+            throw new IllegalArgumentException();
+        }
+        synchronized (positions) {
+            positions.add(position);
+            references.add(null);
+        }
+
+    }
+
+
+    /**
+     * <p>Push a new {@link Position} instance representing the starting
+     * {@link State} of the specified {@link Dialog}.</p>
+     *
+     * @param dialog {@link Dialog} instance to be started and pushed
+     */
+    private void start(Dialog dialog) {
+
+        State state = dialog.findState(dialog.getStart());
+        if (state == null) {
+            throw new IllegalStateException
+              ("Cannot find starting state '"
+               + dialog.getStart()
+               + "' for dialog '" + dialog.getName() + "'");
+        }
+        push(new Position(dialog, state));
+
+    }
+
+
+    /**
+     * <p>Transition the specified {@link Position}, based on the specified
+     * logical outcome, to the appropriate next {@link State}.</p>
+     *
+     * @param position {@link Position} to be transitioned
+     * @param outcome Logical outcome to use for transitioning
+     */
+    private void transition(Position position, String outcome) {
+
+        // If the outcome is null, stay on the same state to be consistent
+        // with JSF semantics on null outcomes
+        if (outcome == null) {
+            return;
+        }
+
+        // Select the next state based on the specified outcome
+        Transition transition = position.getState().findTransition(outcome);
+        if (transition == null) {
+            transition = position.getDialog().findTransition(outcome);
+        }
+        if (transition == null) {
+            throw new IllegalStateException
+              ("Cannot find transition '" + outcome
+               + "' for state '" + position.getState().getName()
+               + "' of dialog '" + position.getDialog().getName() + "'");
+        }
+        State next = position.getDialog().findState(transition.getTarget());
+        if (next == null) {
+            throw new IllegalStateException
+              ("Cannot find state '" + transition.getTarget()
+               + "' for dialog '" + position.getDialog().getName() + "'");
+        }
+        position.setState(next);
+
+    }
+
+
+}

Added: shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/LegacyContexts.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/LegacyContexts.java?rev=437880&view=auto
==============================================================================
--- shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/LegacyContexts.java (added)
+++ shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/LegacyContexts.java Mon Aug 28 16:51:07 2006
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2006 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.shale.dialog2.legacy;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import javax.faces.context.FacesContext;
+import org.apache.shale.dialog2.Constants;
+import org.apache.shale.dialog2.Context;
+import org.apache.shale.dialog2.Contexts;
+import org.apache.shale.dialog2.legacy.model.Dialog;
+
+/**
+ * <p>Implementation of {@link Contexts} for integrating
+ * legacy dialog support into the Shale Dialog Manager.</p>
+ * 
+ * @since 1.0.4
+ */
+public final class LegacyContexts implements Contexts, Serializable {
+
+
+    // ------------------------------------------------------ Context Variables
+
+
+    /**
+     * <p>Map containing all currently active {@link Context} instances for
+     * the current user.</p>
+     */
+    private final HashMap map = new HashMap();
+
+
+    /**
+     * <p>Serial number used to generate dialog instance identifiers.</p>
+     */
+    private int serial = 0;
+
+
+    // ------------------------------------------------------- Contexts Methods
+
+
+    /** {@inheritDoc} */
+    public Context create(FacesContext context, String name) {
+
+        // Look up the specified dialog configuration
+        Map dialogs = (Map)
+          context.getApplication().getVariableResolver().
+          resolveVariable(context, Globals.DIALOGS);
+        if (dialogs == null) {
+            throw new IllegalStateException("Dialog definitions have not been configured");
+        }
+        Dialog dialog = (Dialog) dialogs.get(name);
+        if (dialog == null) {
+            throw new IllegalArgumentException("No definition for dialog name '"
+                                               + name + "' can be found");
+        }
+
+        // Configure a new LegacyContext instance
+        LegacyContext instance = new LegacyContext(this, dialog, generateId());
+        instance.setData(new HashMap());
+        map.put(instance.getId(), instance);
+        context.getExternalContext().getRequestMap().put(Constants.CONTEXT_BEAN, instance);
+        return instance;
+
+    }
+
+
+    /** @{inheritDoc} */
+    public Context get(String id) {
+        return (Context) map.get(id);
+    }
+
+
+    /** @{inheritDoc} */
+    public void remove(Context instance) {
+        if (map.remove(instance.getId()) == instance) {
+            ((LegacyContext) instance).deactivate();
+        }
+    }
+
+
+    // --------------------------------------------------------- Private Methods
+
+
+    /**
+     * <p>Generate and return a new dialog identifier.  FIXME - switch to
+     * something that creates randomized identifiers?</p>
+     */
+    private String generateId() {
+        return "" + ++serial;
+    }
+
+
+}

Added: shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/Position.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/Position.java?rev=437880&view=auto
==============================================================================
--- shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/Position.java (added)
+++ shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/Position.java Mon Aug 28 16:51:07 2006
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2006 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.shale.dialog2.legacy;
+
+import org.apache.shale.dialog2.legacy.model.Dialog;
+import org.apache.shale.dialog2.legacy.model.State;
+
+/**
+ * <p>JavaBean that represents the current {@link State} within
+ * a {@link Dialog}.</p>
+ */
+class Position {
+    
+
+    // ------------------------------------------------------------ Constructors
+
+
+    /**
+     * <p>Construct a new {@link Position} representing the starting
+     * {@link State} for the specified {@link Dialog}.</p>
+     */
+    Position(Dialog dialog) {
+        this(dialog, null);
+    }
+
+
+    /**
+     * <p>Construct a new {@link Position} representing the specified
+     * {@link State} for the specified {@link Dialog}.</p>
+     *
+     * @param dialog {@link Dialog} to be recorded
+     * @param state {@link State} to be recorded
+     */
+    Position(Dialog dialog, State state) {
+        if (dialog == null) {
+            throw new IllegalArgumentException("Dialog cannot be null");
+        }
+        this.dialog = dialog;
+        this.state = state;
+    }
+
+
+    // ------------------------------------------------------ Instance Variables
+
+
+    /**
+     * <p>The {@link Dialog} within which this {@link Position} is reported.</p>
+     */
+    private Dialog dialog = null;
+
+
+    /**
+     * <p>The {@link State} that represents the current position within the
+     * {@link Dialog} that is being executed.</p>
+     */
+    private State state = null;
+
+
+    // ------------------------------------------------------ Package Properties
+
+
+    /**
+     * <p>Return the {@link Dialog} whose execution is tracked by this
+     * {@link Position}.</p>
+     */
+    Dialog getDialog() {
+        return this.dialog;
+    }
+
+
+    /**
+     * <p>Return the {@link State} representing the current execution position
+     * within the owning {@link Dialog}.</p>
+     */
+    State getState() {
+        return this.state;
+    }
+
+
+    /**
+     * <p>Set the {@link State} representing the current execution position
+     * within the owning {@link Dialog}.</p>
+     *
+     * @param state The new {@link State}
+     */
+    void setState(State state) {
+        this.state = state;
+    }
+
+
+    // ---------------------------------------------------------- Public Methods
+
+
+    /**
+     * <p>Return a String representation of this object.</p>
+     */
+    public String toString() {
+        if (state == null) {
+            return "Position[dialog=" + dialog.getName() + "]";
+        } else {
+            return "Position[dialog=" + dialog.getName() + ",state=" + state.getName() + "]";
+        }
+    }
+
+
+}

Added: shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/AbstractState.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/AbstractState.java?rev=437880&view=auto
==============================================================================
--- shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/AbstractState.java (added)
+++ shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/AbstractState.java Mon Aug 28 16:51:07 2006
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2006 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.shale.dialog2.legacy.config;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.apache.shale.dialog2.legacy.model.Dialog;
+import org.apache.shale.dialog2.legacy.model.State;
+import org.apache.shale.dialog2.legacy.model.Transition;
+
+/**
+ * <p>Abstract base class for {@link State} definitions.  Each state is owned
+ * by exactly one owning {@link Dialog}.  While an application
+ * is running, {@link Dialog} (and the constituent {@link State}s and
+ * other configuration information) is immutable, so that it may be
+ * shared by multiple simultaneous paths of execution.</p>
+ *
+ * @since 1.0.4
+ */
+
+abstract class AbstractState implements State {
+
+
+    // ------------------------------------------------------ Instance Variables
+
+
+    /**
+     * <p>The {@link Dialog} that owns this {@link State} instance.</p>
+     */
+    private Dialog dialog = null;
+
+
+    /**
+     * <p>The identifier of this {@link State}, which must be unique among
+     * all {@link State}s within the owning {@link Dialog}.</p>
+     */
+    private String name = null;
+
+
+    /**
+     * <p>The {@link Transition}s owned by this {@link State}, keyed by
+     * outcome.  <strong>FIXME</strong> - a different strategy will be needed
+     * if {@link Transition}s become more complex and manage their own
+     * criteria.</p>
+     */
+    private Map transitions = new HashMap();
+
+
+    // -------------------------------------------------------------- Properties
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Dialog getDialog() {
+
+        return this.dialog;
+
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getName() {
+
+        return this.name;
+
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public Iterator getTransitionOutcomes() {
+
+        return this.transitions.keySet().iterator();
+
+    }
+
+
+    // ---------------------------------------------------------- Public Methods
+
+
+    /**
+     * <p>Return the {@link Transition} for the specified logical outcome,
+     * if any; otherwise, return <code>null</code>.</p>
+     *
+     * @param outcome Logical outcome for which to return a {@link Transition}
+     */
+    public Transition findTransition(String outcome) {
+
+        return (Transition) transitions.get(outcome);
+
+    }
+
+
+    // --------------------------------------------------- Configuration Methods
+
+
+    /**
+     * <p>Add the specified {@link Transition} to the {@link Transition}s owned
+     * by this {@link State}.</p>
+     *
+     * @param transition {@link Transition} to be added
+     *
+     * @exception IllegalArgumentException if the specified {@link Transition}
+     *  cannot be added to this {@link State}
+     */
+    public void addTransition(Transition transition) throws IllegalArgumentException {
+
+        // FIXME - addTransition() - ignore duplicate outcomes for now
+        transitions.put(transition.getOutcome(), transition);
+
+    }
+
+
+    /**
+     * <p>Remove the specified {@link Transition} from the {@link Transition}s
+     * owned by this {@link State}, if it is currently registered.  Otherwise,
+     * do nothing.</p>
+     *
+     * @param transition {@link Transition} to be removed
+     */
+    public void removeTransition(Transition transition) {
+
+        transitions.remove(transition.getOutcome());
+
+    }
+
+
+    /**
+     * <p>Set the {@link Dialog} that owns this {@link State}.</p>
+     *
+     * @param dialog New owning {@link Dialog}
+     */
+    public void setDialog(Dialog dialog) {
+
+        this.dialog = dialog;
+
+    }
+
+
+
+    /**
+     * <p>Set the identifier of this {@link State}, which must be unique
+     * among the {@link State}s owned by the same {@link Dialog}.</p>
+     *
+     * @param name New identifier
+     */
+    public void setName(String name) {
+
+        this.name = name;
+
+    }
+
+
+}

Added: shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/ActionStateImpl.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/ActionStateImpl.java?rev=437880&view=auto
==============================================================================
--- shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/ActionStateImpl.java (added)
+++ shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/ActionStateImpl.java Mon Aug 28 16:51:07 2006
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2004-2005 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.shale.dialog2.legacy.config;
+
+import org.apache.shale.dialog2.legacy.model.ActionState;
+
+
+/**
+ * <p>{@link ActionStateImpl} is a basic implementation of
+ * {@link ActionState}.</p>
+ *
+ * @since 1.0.4
+ */
+
+final class ActionStateImpl extends AbstractState implements ActionState {
+
+
+    // ------------------------------------------------------ Instance Variables
+
+
+    /**
+     * <p>Method binding expression specifying the method to be invoked
+     * when this {@link State} is entered.</p>
+     */
+    private String method = null;
+
+
+    // -------------------------------------------------------------- Properties
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getMethod() {
+
+        return this.method;
+
+    }
+
+
+    // ---------------------------------------------------------- Public Methods
+
+
+    /**
+     * <p>Render a printable version of this instance.</p>
+     */
+    public String toString() {
+
+        return "ActionState[dialog=" +
+               ((getDialog() != null) ? getDialog().getName() : "<null>") +
+               ",name=" + getName() +
+               ",method=" + getMethod() +
+               "]";
+
+    }
+
+
+    // --------------------------------------------------- Configuration Methods
+
+
+    /**
+     * <p>Set the method binding expression specifying the method to be
+     * invoked when this {@link State} is entered.</p>
+     *
+     * @param method The new method binding expression
+     */
+    public void setMethod(String method) {
+
+        this.method = method;
+
+    }
+
+
+}

Added: shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/ConfigurationParser.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/ConfigurationParser.java?rev=437880&view=auto
==============================================================================
--- shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/ConfigurationParser.java (added)
+++ shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/ConfigurationParser.java Mon Aug 28 16:51:07 2006
@@ -0,0 +1,295 @@
+/*
+ * Copyright 2006 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.shale.dialog2.legacy.config;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Map;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.Rule;
+import org.apache.shale.dialog2.legacy.model.Dialog;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * <p>Configuration utility for parsing configuration resources for
+ * defining dialogs.  This class has no dependencies on web tier APIs,
+ * only on the parsing technology (Commons Digester) being used.</p>
+ *
+ * <p>To use this utility, instantiate a new instance and set the
+ * <code>dialogs</code>, <code>resource</code>, and <code>validating</code>
+ * properties.  Then, call the <code>parse()</code> method.  You can parse
+ * more than one resource by resetting the <code>resource</code>
+ * property and calling <code>parse()</code> again.</p>
+ *
+ * @since 1.0.4
+ */
+
+public final class ConfigurationParser {
+
+
+    // ------------------------------------------------------ Instance Variables
+
+
+    /**
+     * <p>Registration information for the DTD we will use to validate.</p>
+     */
+    private static final String REGISTRATIONS[] =
+    { "-//Apache Software Foundation//DTD Shale Dialog Configuration 1.0//EN",
+      "/org/apache/shale/dialog/dialog-config_1_0.dtd" };
+
+
+    // -------------------------------------------------------------- Properties
+
+
+    /**
+     * <p><code>Map</code> of <code>Dialog</code> instances resulting
+     * from parsing, keyed by dialog name.</p>
+     */
+    private Map dialogs = null;
+
+
+    /**
+     * <p>Return the <code>Map</code> of <code>Dialog</code> instances
+     * into which parsed information will be stored, keyed by dialog
+     * name.</p>
+     */
+    public Map getDialogs() {
+        return this.dialogs;
+    }
+
+
+    /**
+     * <p>Set the <code>Map</code> of <code>Dialog</code> instances
+     * into which parsed information will be stored, keyed by dialog
+     * name.</p>
+     *
+     * @param dialogs The new map
+     */
+    public void setDialogs(Map dialogs) {
+        this.dialogs = dialogs;
+    }
+
+
+    /**
+     * <p>The URL of the configuration resource to be parsed.</p>
+     */
+    private URL resource = null;
+
+
+    /**
+     * <p>Return the URL of the configuration resource to be parsed.</p>
+     */
+    public URL getResource() {
+        return this.resource;
+    }
+
+
+    /**
+     * <p>Set the URL of the configuration resource to be parsed.</p>
+     *
+     * @param resource The new resource URL
+     */
+    public void setResource(URL resource) {
+        this.resource = resource;
+    }
+
+
+    /**
+     * <p>Flag indicating whether we should do a validating parse or not.</p>
+     */
+    private boolean validating = true;
+
+
+    /**
+     * <p>Return a flag indicating whether we will be doing a validating parse
+     * or not.  Default value is <code>true</code>.</p>
+     */
+    public boolean isValidating() {
+        return this.validating;
+    }
+
+
+    /**
+     * <p>Set a flag indicating whether we will be doing a validating parse
+     * or not.</p>
+     *
+     * @param validating New flag value
+     */
+    public void setValidating(boolean validating) {
+        this.validating = validating;
+    }
+
+
+    // ---------------------------------------------------------- Public Methods
+
+
+    /**
+     * <p>Parse the configuration resource identified by the <code>resource</code>
+     * property, storing resulting information in the <code>Map</code> specified
+     * by the <code>dialogs</code> property.</p>
+     *
+     * @exception IOException if an input/output error occurs
+     * @exception SAXException if an XML parsing error occurs
+     */
+    public void parse() throws IOException, SAXException {
+
+        Digester digester = digester();
+        digester.clear();
+        digester.push(getDialogs());
+        InputSource source = new InputSource(getResource().toExternalForm());
+        source.setByteStream(getResource().openStream());
+        digester.parse(source);
+
+    }
+
+
+    // --------------------------------------------------------- Private Methods
+
+
+    /**
+     * <p>Return a fully configured <code>Digester</code> instance.</p>
+     */
+    private Digester digester() {
+
+        Digester digester = new Digester();
+
+        // Configure global characteristics
+        digester.setNamespaceAware(false);
+        digester.setUseContextClassLoader(true);
+        digester.setValidating(isValidating());
+
+        // Register local copy of our DTDs
+        for (int i = 0; i < REGISTRATIONS.length; i += 2) {
+            URL url = this.getClass().getResource(REGISTRATIONS[i + 1]);
+            digester.register(REGISTRATIONS[i], url.toString());
+        }
+
+        // Configure processing rules
+
+        // dialogs/dialog
+        digester.addObjectCreate("dialogs/dialog", "className", DialogImpl.class);
+        digester.addSetProperties("dialogs/dialog");
+        digester.addSetProperty("dialogs/dialog/property", "name", "value");
+        digester.addRule("dialogs/dialog", new AddDialogRule());
+
+        // dialogs/dialog/action
+        digester.addObjectCreate("dialogs/dialog/action", "className",
+                                 ActionStateImpl.class);
+        digester.addSetProperties("dialogs/dialog/action");
+        digester.addSetProperty("dialogs/dialog/action/property", "name", "value");
+        digester.addSetNext("dialogs/dialog/action",
+                            "addState", "org.apache.shale.dialog.State");
+
+        // dialogs/dialog/action/transition
+        digester.addObjectCreate("dialogs/dialog/action/transition", "className",
+                                 TransitionImpl.class);
+        digester.addSetProperties("dialogs/dialog/action/transition");
+        digester.addSetProperty("dialogs/dialog/action/transition/property", "name", "value");
+        digester.addSetNext("dialogs/dialog/action/transition",
+                            "addTransition", "org.apache.shale.dialog.Transition");
+
+        // dialogs/dialog/end
+        digester.addObjectCreate("dialogs/dialog/end", "className",
+                                 EndStateImpl.class);
+        digester.addSetProperties("dialogs/dialog/end");
+        digester.addSetProperty("dialogs/dialog/end/property", "name", "value");
+        digester.addSetNext("dialogs/dialog/end",
+                            "addState", "org.apache.shale.dialog.State");
+
+        // dialogs/dialog/end/transition
+        digester.addObjectCreate("dialogs/dialog/end/transition", "className",
+                                 TransitionImpl.class);
+        digester.addSetProperties("dialogs/dialog/end/transition");
+        digester.addSetProperty("dialogs/dialog/end/transition/property", "name", "value");
+        digester.addSetNext("dialogs/dialog/end/transition",
+                            "addTransition", "org.apache.shale.dialog.Transition");
+
+        // dialogs/dialog/subdialog
+        digester.addObjectCreate("dialogs/dialog/subdialog", "className",
+                                 SubdialogStateImpl.class);
+        digester.addSetProperties("dialogs/dialog/subdialog");
+        digester.addSetProperty("dialogs/dialog/subdialog/property", "name", "value");
+        digester.addSetNext("dialogs/dialog/subdialog",
+                            "addState", "org.apache.shale.dialog.State");
+
+        // dialogs/dialog/subdialog/transition
+        digester.addObjectCreate("dialogs/dialog/subdialog/transition", "className",
+                                 TransitionImpl.class);
+        digester.addSetProperties("dialogs/dialog/subdialog/transition");
+        digester.addSetProperty("dialogs/dialog/subdialog/transition/property", "name", "value");
+        digester.addSetNext("dialogs/dialog/subdialog/transition",
+                            "addTransition", "org.apache.shale.dialog.Transition");
+
+        // dialogs/dialog/transition
+        digester.addObjectCreate("dialogs/dialog/transition", "className",
+                                 TransitionImpl.class);
+        digester.addSetProperties("dialogs/dialog/transition");
+        digester.addSetProperty("dialogs/dialog/transition/property", "name", "value");
+        digester.addSetNext("dialogs/dialog/transition",
+                            "addTransition", "org.apache.shale.dialog.Transition");
+
+        // dialogs/dialog/view
+        digester.addObjectCreate("dialogs/dialog/view", "className",
+                                 ViewStateImpl.class);
+        digester.addSetProperties("dialogs/dialog/view");
+        digester.addSetProperty("dialogs/dialog/view/property", "name", "value");
+        digester.addSetNext("dialogs/dialog/view",
+                            "addState", "org.apache.shale.dialog.State");
+
+        // dialogs/dialog/view/transition
+        digester.addObjectCreate("dialogs/dialog/view/transition", "className",
+                                 TransitionImpl.class);
+        digester.addSetProperties("dialogs/dialog/view/transition");
+        digester.addSetProperty("dialogs/dialog/view/transition/property", "name", "value");
+        digester.addSetNext("dialogs/dialog/view/transition",
+                            "addTransition", "org.apache.shale.dialog.Transition");
+
+        return digester;
+
+    }
+
+
+    // -------------------------------------------- Private Rule Implementations
+
+
+    /**
+     * <p>Custom <code>Digester</code> rule to add a dialog.</p>
+     */
+    static class AddDialogRule extends Rule {
+
+        /**
+         * <p>Process the "end" event for this rule.</p>
+         *
+         * @param namespace XML namespace of this element
+         * @param name Name of this element
+         *
+         * @exception Exception if a processing exception occurs
+         */
+        public void end(String namespace, String name) throws Exception {
+
+            Dialog dialog = (Dialog) getDigester().peek();
+            Map map = (Map) getDigester().peek(1);
+            map.put(dialog.getName(), dialog);
+
+        }
+
+    }
+
+
+}

Added: shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/DialogImpl.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/DialogImpl.java?rev=437880&view=auto
==============================================================================
--- shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/DialogImpl.java (added)
+++ shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/DialogImpl.java Mon Aug 28 16:51:07 2006
@@ -0,0 +1,251 @@
+/*
+ * Copyright 2006 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.shale.dialog2.legacy.config;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.apache.shale.dialog2.legacy.model.Dialog;
+import org.apache.shale.dialog2.legacy.model.State;
+import org.apache.shale.dialog2.legacy.model.Transition;
+
+/**
+ * <p>{@link DialogImpl} is a basic implementation of {@link Dialog}.</p>
+ *
+ * @since 1.0.4
+ */
+final class DialogImpl implements Dialog {
+
+
+    // ------------------------------------------------------ Instance Variables
+
+
+    /**
+     * <p>Name of this {@link Dialog}.</p>
+     */
+    private String name = null;
+
+
+    /**
+     * <p>Name of the starting {@link State} for this {@link Dialog}.</p>
+     */
+    private String start = null;
+
+
+    /**
+     * <p>The {@link State}s owned by this {@link Dialog}, keyed by
+     * identifier.</p>
+     */
+    private Map states = new HashMap();
+
+
+    /**
+     * <p>The global {@link Transition}s owned by this {@link Dialog}, keyed by
+     * outcome.  Logic that performs transition management should first check
+     * for a {@link Transition} associated with the origin {@link State}, then
+     * consult the {@link Dialog} for a global definition.</p>
+     */
+    private Map transitions = new HashMap();
+
+
+    // -------------------------------------------------------------- Properties
+
+
+    /**
+     * <p>Return the name of this {@link Dialog}.</p>
+     */
+    public String getName() {
+
+        return this.name;
+
+    }
+
+
+    /**
+     * <p>Return the name of the starting {@link State} for this
+     * {@link Dialog}.</p>
+     */
+    public String getStart() {
+
+        return this.start;
+
+    }
+
+
+    /**
+     * <p>Return an <code>Iterator</code> over the names of {@link State}s
+     * that are owned by this {@link Dialog}.  If there are no such
+     * {@link State}s, an empty <code>Iterator</code> is returned.</p>
+     */
+    public Iterator getStateIds() {
+
+        return this.states.keySet().iterator();
+
+    }
+
+
+    /**
+     * <p>Return an <code>Iterator</code> over the logical outcomes of
+     * global {@link Transition}s for this {@link Dialog}.  If there are
+     * no such {@link Transition}s, an empty <code>Iterator</code> is
+     * returned.</p>
+     */
+    public Iterator getTransitionOutcomes() {
+
+        return this.transitions.keySet().iterator();
+
+    }
+
+
+    // ---------------------------------------------------------- Public Methods
+
+
+    /**
+     * <p>Return the specified {@link State}, owned by this {@link Dialog},
+     * if any.  Otherwise, return <code>null</code>.</p>
+     *
+     * @param id Identifier of the requested {@link State}
+     */
+    public State findState(String id) {
+
+        return (State) states.get(id);
+
+    }
+
+
+    /**
+     * <p>Return the global {@link Transition} for the specified logical outcome,
+     * if any; otherwise, return <code>null</code>.</p>
+     *
+     * @param outcome Logical outcome for which to return a {@link Transition}
+     */
+    public Transition findTransition(String outcome) {
+
+        return (Transition) transitions.get(outcome);
+
+    }
+
+
+    /**
+     * <p>Render a printable version of this instance.</p>
+     */
+    public String toString() {
+
+        return "Dialog[name=" + this.name + ",start=" + this.start + "]";
+
+    }
+
+
+    // --------------------------------------------------- Configuration Methods
+
+
+    /**
+     * <p>Add the specified {@link State} to the {@link State}s owned by
+     * this {@link Dialog}.</p>
+     *
+     * @param state {@link State} to be added
+     *
+     * @exception IllegalArgumentException if there is already a {@link State}
+     *  with the specified <code>id</code> owned by this {@link Dialog}
+     */
+    public void addState(State state) throws IllegalArgumentException {
+
+        if (states.containsKey(state.getName())) {
+            throw new IllegalArgumentException(state.getName());
+        }
+        states.put(state.getName(), state);
+        if (state instanceof AbstractState) {
+            ((AbstractState) state).setDialog(this);
+        }
+
+    }
+
+
+    /**
+     * <p>Add the specified {@link Transition} to the global {@link Transition}s
+     * associated with this {@link Dialog}.</p>
+     *
+     * @param transition {@link Transition} to be added
+     *
+     * @exception IllegalArgumentException if the specified {@link Transition}
+     *  cannot be added to this {@link State}
+     */
+    public void addTransition(Transition transition) throws IllegalArgumentException {
+
+        // FIXME - addTransition() - ignore duplicate outcomes for now
+        transitions.put(transition.getOutcome(), transition);
+
+    }
+
+
+    /**
+     * <p>Set the name of this {@link Dialog}.</p>
+     *
+     * @param name New name
+     */
+    public void setName(String name) {
+
+        this.name = name;
+
+    }
+
+
+    /**
+     * <p>Set the name of the starting {@link State} for this
+     * {@link Dialog}.</p>
+     *
+     * @param start Name of the starting {@link State}
+     */
+    public void setStart(String start) {
+
+        this.start = start;
+
+    }
+
+
+    /**
+     * <p>Remove the specified {@link State} from the {@link State}s owned by
+     * this {@link Dialog}, if it is currently registered.  Otherwise,
+     * do nothing.</p>
+     *
+     * @param state {@link State} to be removed
+     */
+    public void removeState(State state) {
+
+        states.remove(state.getName());
+        if (state instanceof AbstractState) {
+            ((AbstractState) state).setDialog(null);
+        }
+
+    }
+
+
+    /**
+     * <p>Remove the specified {@link Transition} from the global
+     * {@link Transition}s associated with this {@link Dialog}, if it is
+     * currently registered.  Otherwise, do nothing.</p>
+     *
+     * @param transition {@link Transition} to be removed
+     */
+    public void removeTransition(Transition transition) {
+
+        transitions.remove(transition.getOutcome());
+
+    }
+
+
+}

Added: shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/EndStateImpl.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/EndStateImpl.java?rev=437880&view=auto
==============================================================================
--- shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/EndStateImpl.java (added)
+++ shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/EndStateImpl.java Mon Aug 28 16:51:07 2006
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2006 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.shale.dialog2.legacy.config;
+
+import org.apache.shale.dialog2.legacy.model.EndState;
+
+/**
+ * <p>{@link EndStateImpl} is a basic implementation of
+ * {@link EndState}.</p>
+ *
+ * $Id: EndStateImpl.java 419431 2006-07-06 04:38:39Z wsmoak $
+ */
+
+final class EndStateImpl extends ViewStateImpl implements EndState {
+
+
+    // ---------------------------------------------------------- Public Methods
+
+
+    /**
+     * <p>Render a printable version of this instance.</p>
+     */
+    public String toString() {
+
+        return "EndState[dialog=" +
+               ((getDialog() != null) ? getDialog().getName() : "<null>") +
+               ",name=" + getName() +
+               ",viewId=" + getViewId() + "]";
+
+    }
+
+
+}

Added: shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/SubdialogStateImpl.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/SubdialogStateImpl.java?rev=437880&view=auto
==============================================================================
--- shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/SubdialogStateImpl.java (added)
+++ shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/SubdialogStateImpl.java Mon Aug 28 16:51:07 2006
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2006 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.shale.dialog2.legacy.config;
+
+import org.apache.shale.dialog2.legacy.model.SubdialogState;
+
+/**
+ * <p>{@link SubdialogStateImpl} is a basic implementation of
+ * {@link SubdialogState}.</p>
+ *
+ * @since 1.0.4
+ */
+
+final class SubdialogStateImpl extends AbstractState implements SubdialogState {
+
+
+    // ------------------------------------------------------ Instance Variables
+
+
+    /**
+     * <p>The name of the subordinate dialog to be executed by this state.</p>
+     */
+    private String dialogName = null;
+
+
+    // -------------------------------------------------------------- Properties
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getDialogName() {
+
+        return this.dialogName;
+
+    }
+
+
+    // ---------------------------------------------------------- Public Methods
+
+
+    /**
+     * <p>Render a printable version of this instance.</p>
+     */
+    public String toString() {
+
+        return "SubdialogState[dialog=" +
+               ((getDialog() != null) ? getDialog().getName() : "<null>") +
+               ",name=" + getName() +
+               ",dialogName=" + this.dialogName + "]";
+
+    }
+
+
+    // --------------------------------------------------- Configuration Methods
+
+
+    /**
+     * <p>Set the name of the subordinate dialog to be executed
+     * by this state.</p>
+     *
+     * @param dialogName The subordinate dialog name
+     */
+    public void setDialogName(String dialogName) {
+
+        this.dialogName = dialogName;
+
+    }
+
+
+}

Added: shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/TransitionImpl.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/TransitionImpl.java?rev=437880&view=auto
==============================================================================
--- shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/TransitionImpl.java (added)
+++ shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/TransitionImpl.java Mon Aug 28 16:51:07 2006
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2006 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.shale.dialog2.legacy.config;
+
+import org.apache.shale.dialog2.legacy.model.Transition;
+
+/**
+ * <p>{@link TransitionImpl} is a basic implementation of
+ * {@link Transition}.</p>
+ *
+ * @since 1.0.4
+ */
+
+final class TransitionImpl implements Transition {
+
+
+    // ------------------------------------------------------ Instance Variables
+
+
+    /**
+     * <p>The logical outcome used to select this {@link Transition}.</p>
+     */
+    private String outcome = null;
+
+
+    /**
+     * <p>The identifier of the target {@link State} for this
+     * {@link Transition}.</p>
+     */
+    private String target = null;
+
+
+    // -------------------------------------------------------------- Properties
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getOutcome() {
+
+        return this.outcome;
+
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getTarget() {
+
+        return this.target;
+
+    }
+
+
+    // ---------------------------------------------------------- Public Methods
+
+
+    /**
+     * <p>Render a printable version of this instance.</p>
+     */
+    public String toString() {
+
+        return "Transition[outcome=" + this.outcome +
+               ",target=" + this.target + "]";
+
+    }
+
+
+    // --------------------------------------------------- Configuration Methods
+
+
+    /**
+     * <p>Set the logical outcome used to select this {@link Transition}.</p>
+     *
+     * @param outcome New logical outcome
+     */
+    public void setOutcome(String outcome) {
+
+        this.outcome = outcome;
+
+    }
+
+
+    /**
+     * <p>Set the target {@link State} identifier for this
+     * {@link Transition}.</p>
+     *
+     * @param target New target identifier
+     */
+    public void setTarget(String target) {
+
+        this.target = target;
+
+    }
+
+
+}

Added: shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/ViewStateImpl.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/ViewStateImpl.java?rev=437880&view=auto
==============================================================================
--- shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/ViewStateImpl.java (added)
+++ shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/config/ViewStateImpl.java Mon Aug 28 16:51:07 2006
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2006 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.shale.dialog2.legacy.config;
+
+import org.apache.shale.dialog2.legacy.model.ViewState;
+
+/**
+ * <p>{@link ViewStateImpl} is a basic implementation of
+ * {@link ViewState}.</p>
+ *
+ * @since 1.0.4
+ */
+
+class ViewStateImpl extends AbstractState implements ViewState {
+
+
+    // ------------------------------------------------------ Instance Variables
+
+
+    /**
+     * <p>The view identifier of the JavaServer Faces view to render if this
+     * state is entered.</p>
+     */
+    private String viewId = null;
+
+
+    // -------------------------------------------------------------- Properties
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getViewId() {
+
+        return this.viewId;
+
+    }
+
+
+    // ---------------------------------------------------------- Public Methods
+
+
+    /**
+     * <p>Render a printable version of this instance.</p>
+     */
+    public String toString() {
+
+        return "ViewState[dialog=" +
+               ((getDialog() != null) ? getDialog().getName() : "<null>") +
+               ",name=" + getName() +
+               ",viewId=" + this.viewId + "]";
+
+    }
+
+
+    // --------------------------------------------------- Configuration Methods
+
+
+    /**
+     * <p>Set the view identifier of the JavaServer Faces view to render
+     * if this state is entered.</p>
+     *
+     * @param viewId The new view identifier
+     */
+    public void setViewId(String viewId) {
+
+        this.viewId = viewId;
+
+    }
+
+
+}

Added: shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/ActionState.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/ActionState.java?rev=437880&view=auto
==============================================================================
--- shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/ActionState.java (added)
+++ shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/ActionState.java Mon Aug 28 16:51:07 2006
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2006 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.shale.dialog2.legacy.model;
+
+/**
+ * <p>An {@link ActionState} represents the execution of an action method
+ * (typically delegating behavior to appropriate business logic).  The
+ * actual method must be a public method that returns a String and takes
+ * no arguments, and is represented by a JavaServer Faces method binding
+ * expression.  Note that this method signature is identical to the definition
+ * of an "action" method as used in the JavaServer Faces
+ * <code>ActionSource</code> APIs.</p>
+ */
+
+public interface ActionState extends State {
+
+
+    // -------------------------------------------------------------- Properties
+
+
+    /**
+     * <p>Return the method binding expression specifying the method to be
+     * invoked when this {@link State} is entered.</p>
+     */
+    public String getMethod();
+
+
+}

Added: shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/Dialog.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/Dialog.java?rev=437880&view=auto
==============================================================================
--- shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/Dialog.java (added)
+++ shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/Dialog.java Mon Aug 28 16:51:07 2006
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2006 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.shale.dialog2.legacy.model;
+
+import java.util.Iterator;
+
+/**
+ * <p>Overall configuration of an individual dialog.  During application
+ * execution, this information is immutable (so that simultaneous execution
+ * threads may be processing states or transitions through this dialog).
+ * Therefore, access to configuration information is not synchronized.</p>
+ *
+ * <p>A {@link Dialog} is characterized by a set of named {@link State}s,
+ * which are executed in an order that is determined by {@link Transition}s
+ * between those {@link State}s.  Execution of a {@link Dialog} begins at
+ * the {@link State} specified by the <code>start</code> property, and ends
+ * when an {@link EndState} is executed.</p>
+ *
+ * <p>{@link Transition}s describe the rule that determines the name of the
+ * next {@link State} to be executed, based upon a logical outcome returned
+ * by the execution of a previous {@link State}.  {@link Transition}s
+ * associated with a {@link Dialog} define dialog-wide rules for specified
+ * outcomes, while {@link Transition}s associated with a particular
+ * {@link State} can replace the global {@link Transition} that would normally
+ * be selected with one specific to the executing {@link State}.</p>
+ */
+
+public interface Dialog {
+
+
+    // -------------------------------------------------------------- Properties
+
+
+    /**
+     * <p>Return the name of this {@link Dialog}.</p>
+     */
+    public String getName();
+
+
+    /**
+     * <p>Return the name of the starting {@link State} for this
+     * {@link Dialog}.</p>
+     */
+    public String getStart();
+
+
+    /**
+     * <p>Return an <code>Iterator</code> over the names of {@link State}s
+     * that are owned by this {@link Dialog}.  If there are no such
+     * {@link State}s, an empty <code>Iterator</code> is returned.</p>
+     */
+    public Iterator getStateIds();
+
+
+    /**
+     * <p>Return an <code>Iterator</code> over the logical outcomes of
+     * global {@link Transition}s for this {@link Dialog}.  If there are
+     * no such {@link Transition}s, an empty <code>Iterator</code> is
+     * returned.</p>
+     */
+    public Iterator getTransitionOutcomes();
+
+
+    // ---------------------------------------------------------- Public Methods
+
+
+    /**
+     * <p>Return the specified {@link State}, owned by this {@link Dialog},
+     * if any.  Otherwise, return <code>null</code>.</p>
+     *
+     * @param id Identifier of the requested {@link State}
+     */
+    public State findState(String id);
+
+
+    /**
+     * <p>Return the global {@link Transition} for the specified logical outcome,
+     * if any; otherwise, return <code>null</code>.</p>
+     *
+     * @param outcome Logical outcome for which to return a {@link Transition}
+     */
+    public Transition findTransition(String outcome);
+
+
+}

Added: shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/EndState.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/EndState.java?rev=437880&view=auto
==============================================================================
--- shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/EndState.java (added)
+++ shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/EndState.java Mon Aug 28 16:51:07 2006
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2006 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.shale.dialog2.legacy.model;
+
+/**
+ * <p>{@link EndState} is a spacialized {@link ViewState} that also marks
+ * this as the final {@link State} to be executed in the owning {@link Dialog}.
+ * When this {@link State} is entered, context information for the owning
+ * {@link Dialog} is removed.  Then, if a view identifier is specified,
+ * the corresponding JavaServer Faces <code>view</code> will be rendered,
+ * and the logical outcome returned by the subsequently invoked action method
+ * will be returned to the parent {@link Dialog} (if any) as the logical
+ * outcome of this dialog's execution.  If no view identifier is specified,
+ * it is assumed that some other mechanism will be used to return output to
+ * the client.</p>
+ */
+
+public interface EndState extends ViewState {
+
+}

Added: shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/State.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/State.java?rev=437880&view=auto
==============================================================================
--- shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/State.java (added)
+++ shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/State.java Mon Aug 28 16:51:07 2006
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2006 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.shale.dialog2.legacy.model;
+
+import java.util.Iterator;
+
+/**
+ * <p>A {@link State} is an executable entity, within the scope of an
+ * owning {@link Dialog}.  Execution of a {@link State} returns a logical
+ * outcome (represented as a String), which is used to select the next
+ * {@link State} to be executed, via a {@link Transition}.</p>
+ *
+ * <p>Specialized subinterfaces of {@link State} are defined for the
+ * standard execution entity types that are supported, including:</p>
+ * <ul>
+ * <li>{@link ActionState} - Execution of an action method (typically
+ *     delegating behavior to appropriate business logic).</li>
+ * <li>{@link SubdialogState} - Execution of a separate {@link Dialog},
+ *     with continuation based on the logical outcome returned by the
+ *     ending {@link State} within the subordinate dialog.</li>
+ * <li>{@link ViewState} - Execution of the rendering of a JavaServer
+ *     Faces <code>view</code>, and returning the logical outcome returned
+ *     by the action method that processes the subsequent submit.</li>
+ * <li>{@link EndState} - Specialized {@link ViewState} that also marks
+ *     the end of execution of this {@link Dialog}.</li>
+ * </ul>
+ */
+
+public interface State {
+
+
+    // -------------------------------------------------------------- Properties
+
+
+    /**
+     * <p>Return the {@link Dialog} that owns this {@link State}.</p>
+     */
+    public Dialog getDialog();
+
+
+    /**
+     * <p>Return the identifier of this {@link State}, which must be unique
+     * among the {@link State}s owned by the same {@link Dialog}.</p>
+     */
+    public String getName();
+
+
+    /**
+     * <p>Return an <code>Iterator</code> over the logical outcomes of
+     * local {@link Transition}s for this {@link State}.  If there are
+     * no such {@link Transition}s, an empty <code>Iterator</code> is
+     * returned.</p>
+     */
+    public Iterator getTransitionOutcomes();
+
+
+    // ---------------------------------------------------------- Public Methods
+
+
+    /**
+     * <p>Return the {@link Transition} for the specified logical outcome,
+     * if any; otherwise, return <code>null</code>.</p>
+     *
+     * @param outcome Logical outcome for which to return a {@link Transition}
+     */
+    public Transition findTransition(String outcome);
+
+
+}

Added: shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/SubdialogState.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/SubdialogState.java?rev=437880&view=auto
==============================================================================
--- shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/SubdialogState.java (added)
+++ shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/SubdialogState.java Mon Aug 28 16:51:07 2006
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2006 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.shale.dialog2.legacy.model;
+
+/**
+ * <p>A {@link SubdialogState} represents the execution of a separate
+ * {@link Dialog}, after which processing proceeds within the current
+ * {@link Dialog} based upon the logical outcome returned by the
+ * {@link EndState} of the subordinate dialog.</p>
+ */
+
+public interface SubdialogState extends State {
+
+
+    // -------------------------------------------------------------- Properties
+
+
+    /**
+     * <p>Return the name of the subordinate dialog to be executed
+     * by this state.</p>
+     */
+    public String getDialogName();
+
+
+}

Added: shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/Transition.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/Transition.java?rev=437880&view=auto
==============================================================================
--- shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/Transition.java (added)
+++ shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/Transition.java Mon Aug 28 16:51:07 2006
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2006 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.shale.dialog2.legacy.model;
+
+/**
+ * <p>Description of a transition from the owning {@link State} to another
+ * {@link State} with a specified identifier.  {@link Transition} instances
+ * are owned by a single {@link State} instance, or are global to an entire
+ * {@link Dialog} instance, and during execution of an application they are
+ * immutabe.</p>
+ */
+
+public interface Transition {
+
+
+    // -------------------------------------------------------------- Properties
+
+
+    /**
+     * <p>Return the logical outcome used to select this {@link Transition}.</p>
+     */
+    public String getOutcome();
+
+
+    /**
+     * <p>Return the target {@link State} identifier for this
+     * {@link Transition}.</p>
+     */
+    public String getTarget();
+
+
+}

Added: shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/ViewState.java
URL: http://svn.apache.org/viewvc/shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/ViewState.java?rev=437880&view=auto
==============================================================================
--- shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/ViewState.java (added)
+++ shale/sandbox/shale-dialog2-legacy/src/main/java/org/apache/shale/dialog2/legacy/model/ViewState.java Mon Aug 28 16:51:07 2006
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2006 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.shale.dialog2.legacy.model;
+
+/**
+ * <p>A {@link ViewState} encapsulates the rendering of a JavaServer Faces
+ * <em>view</em>, identified by a specified view identifier.  When the
+ * view is rendered, standard {@link org.apache.shale.view.ViewController}
+ * functionality will be supported if there is such a corresponding backing
+ * bean.  The logical outcome returned by a {@link ViewState} will be the
+ * one returned by the JavaServer Faces action method that was invoked
+ * (if any).</p>
+ */
+
+public interface ViewState extends State {
+
+
+    // -------------------------------------------------------------- Properties
+
+
+    /**
+     * <p>Return the view identifier of the JavaServer Faces view to render
+     * if this state is entered.</p>
+     */
+    public String getViewId();
+
+
+}