[prev in list] [next in list] [prev in thread] [next in thread]
List: taglibs-dev
Subject: svn commit: r226454 [1/3] - in /jakarta/taglibs/proper/rdc/trunk:
From: rahul () apache ! org
Date: 2005-07-30 1:28:51
Message-ID: 20050730012904.69449.qmail () minotaur ! apache ! org
[Download RAW message or body]
Author: rahul
Date: Fri Jul 29 18:28:30 2005
New Revision: 226454
URL: http://svn.apache.org/viewcvs?rev=226454&view=rev
Log:
Summary:
Adding an alpha implementation of an SCXML (State Chart XML) engine and an alpha \
version of a SCXML dialog management strategy for the RDC group container.
Details:
1) SCXML Engine - The W3C Voice Browser Working Group recently announced the \
publication of the first Working Draft of State Chart XML. SCXML provides a generic \
state-machine based execution environment based on CCXML and Harel State Tables. The \
SCXML Working Draft is available here [ http://www.w3.org/TR/2005/WD-scxml-20050705/ \
]. The RDC tag library has included an alpha of a SCXML engine implementation.
The SCXML engine implementation is under development. The major items that are yet \
unimplemented are: a) Multiple (simultaneous) targets for a single transition \
(Section 3.3.1) b) Outgoing transitions from a parallel (Section 3.4)
c) JOIN (Section 4.3)
d) SYNCH (Section 4.4)
2) SCXML Dialog Management Strategy - An alpha version of a dialog management \
strategy for the RDC group container that works off of a SCXML configuration document \
is provided. A simple example in rdc-examples.war is scxml-dialog-test.jsp
Added:
jakarta/taglibs/proper/rdc/trunk/examples/web/config/scxml/
jakarta/taglibs/proper/rdc/trunk/examples/web/config/scxml/scxml-test.xml (with \
props) jakarta/taglibs/proper/rdc/trunk/examples/web/scxml-dialog-test.jsp (with \
props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/
jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Context.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/ErrorReporter.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Evaluator.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/EventDispatcher.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/NotificationRegistry.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Observable.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/PathResolver.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLDigester.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLExecutor.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLExpressionException.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLHelper.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLListener.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLSemantics.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Status.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Step.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/TransitionTargetComparator.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/TriggerEvent.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/env/
jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/env/ELContext.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/env/ELEvaluator.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/env/RootContext.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/env/ServletContextResolver.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/env/SimpleDispatcher.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/env/Standalone.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/env/Tracer.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/env/URLResolver.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/env/package.html \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/
jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/Action.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/Assign.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/Cancel.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/Else.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/ElseIf.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/Executable.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/Exit.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/ExternalNode.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/History.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/If.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/Initial.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/Log.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/ModelException.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/OnEntry.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/OnExit.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/Parallel.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/Path.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/SCXML.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/Send.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/State.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/Transition.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/TransitionTarget.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/Var.java \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/model/package.html \
(with props) jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/package.html \
(with props) Modified:
jakarta/taglibs/proper/rdc/trunk/xml/intro.xml
jakarta/taglibs/proper/rdc/trunk/xml/rdc.xml
Added: jakarta/taglibs/proper/rdc/trunk/examples/web/config/scxml/scxml-test.xml
URL: http://svn.apache.org/viewcvs/jakarta/taglibs/proper/rdc/trunk/examples/web/config/scxml/scxml-test.xml?rev=226454&view=auto
==============================================================================
--- jakarta/taglibs/proper/rdc/trunk/examples/web/config/scxml/scxml-test.xml (added)
+++ jakarta/taglibs/proper/rdc/trunk/examples/web/config/scxml/scxml-test.xml Fri Jul \
29 18:28:30 2005 @@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<scxml xmlns="http://www.w3.org/2005/01/SCXML"
+ version="1.0" initialstate="mySelect">
+<!--
+ Copyright 2004 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.
+-->
+ <state id="mySelect">
+ <transition event="mySelect.done" cond="${mySelect eq 'date'}">
+ <target next="myDate"/>
+ </transition>
+ <transition event="mySelect.done" cond="${mySelect eq 'time'}">
+ <target next="myTime"/>
+ </transition>
+ <transition event="mySelect.done" cond="${mySelect ne 'date' and mySelect ne \
'time'}"> + <exit/>
+ </transition>
+ </state>
+
+ <state id="myDate" final="true" />
+
+ <state id="myTime" final="true" />
+
+</scxml>
Propchange: jakarta/taglibs/proper/rdc/trunk/examples/web/config/scxml/scxml-test.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/taglibs/proper/rdc/trunk/examples/web/config/scxml/scxml-test.xml
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: jakarta/taglibs/proper/rdc/trunk/examples/web/scxml-dialog-test.jsp
URL: http://svn.apache.org/viewcvs/jakarta/taglibs/proper/rdc/trunk/examples/web/scxml-dialog-test.jsp?rev=226454&view=auto
==============================================================================
--- jakarta/taglibs/proper/rdc/trunk/examples/web/scxml-dialog-test.jsp (added)
+++ jakarta/taglibs/proper/rdc/trunk/examples/web/scxml-dialog-test.jsp Fri Jul 29 \
18:28:30 2005 @@ -0,0 +1,48 @@
+<!--Example:Start-->
+<%--
+ Copyright 2004 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$-->
+<!--
+<%@ page language="java" contentType="application/vxml" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="rdc" uri="http://jakarta.apache.org/taglibs/rdc-1.0"%>
+-->
+<vxml version="2.0" xml:lang="en-US" xmlns="http://www.w3.org/2001/vxml" >
+ <jsp:useBean id="dialogMap" class="java.util.LinkedHashMap" scope="session"/>
+ <rdc:task map="${dialogMap}">
+
+ <rdc:group id="scxmlGrp" strategy="org.apache.taglibs.rdc.dm.SCXMLDialog"
+ config="${empty param.scxml ? 'config/scxml/scxml-test.xml' : param.scxml}">
+
+ <rdc:time id="myTime" confirm="true" echo="true"/>
+
+ <rdc:date id="myDate" confirm="true" echo="true"/>
+
+ <rdc:select1 id="mySelect" maxNoInput="5" maxNoMatch="3"
+ optionList="config/rule-based-dialog/conditional-exec-opt.xml" />
+
+ </rdc:group>
+
+ <c:if test="${not empty scxmlGrp}">
+ <block>
+ <prompt>
+ The choice selected was ${scxmlGrp.mySelect}
+ </prompt>
+ </block>
+ </c:if>
+
+ </rdc:task>
+</vxml>
+<!--Example:End-->
Propchange: jakarta/taglibs/proper/rdc/trunk/examples/web/scxml-dialog-test.jsp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/taglibs/proper/rdc/trunk/examples/web/scxml-dialog-test.jsp
------------------------------------------------------------------------------
svn:executable = *
Propchange: jakarta/taglibs/proper/rdc/trunk/examples/web/scxml-dialog-test.jsp
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Context.java
URL: http://svn.apache.org/viewcvs/jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Context.java?rev=226454&view=auto
==============================================================================
--- jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Context.java \
(added)
+++ jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Context.java \
Fri Jul 29 18:28:30 2005 @@ -0,0 +1,88 @@
+/*
+ *
+ * Copyright 2004 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.taglibs.rdc.scxml;
+
+import java.util.Iterator;
+
+/**
+ * A Context or "scope" for storing variables; usually tied to
+ * a SCXML root or State object
+ *
+ * @author Jaroslav Gergic
+ * @author Rahul Akolkar
+ *
+*/
+public interface Context {
+ /**
+ * Assigns a new value to an existing variable or creates a new one.
+ * The method searches the chain of parent Contexts for variable
+ * existence.
+ *
+ * @param name The variable name
+ * @param value The variable value
+ */
+ public void set(String name, Object value);
+
+ /**
+ * Assigns a new value to an existing variable or creates a new one.
+ * The method allows to shaddow a variable of the same name up the
+ * Context chain.
+ *
+ * @param name The variable name
+ * @param value The variable value
+ */
+ public void setLocal(String name, Object value);
+
+ /**
+ * Get the value of this variable; delegating to parent
+ *
+ * @param name The name of the variable
+ * @return The value (or null)
+ */
+ public Object get(String name);
+
+ /**
+ * Check if this variable exists, delegating to parent
+ *
+ * @param name The name of the variable
+ * @return Whether a variable with the name exists in this Context
+ */
+ public boolean has(String name);
+
+ /**
+ * Get an Iterator over all variables in this Context
+ *
+ * @return Local entries iterator (Map.Entry)
+ * To get parent entries, call getParent().iterator().
+ * @see #getParent()
+ */
+ public Iterator iterator();
+
+ /**
+ * Clear this Context
+ */
+ public void reset();
+
+ /**
+ * Get the parent Context, may be null
+ *
+ * @return The parent Context in a chained Context environment
+ */
+ public Context getParent();
+
+}
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Context.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Context.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/ErrorReporter.java
URL: http://svn.apache.org/viewcvs/jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/ErrorReporter.java?rev=226454&view=auto
==============================================================================
--- jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/ErrorReporter.java \
(added)
+++ jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/ErrorReporter.java \
Fri Jul 29 18:28:30 2005 @@ -0,0 +1,84 @@
+/*
+ *
+ * Copyright 2004 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.taglibs.rdc.scxml;
+
+/**
+ * An interface for reporting SCXML errors to the host environment,
+ * containing the definition of commonly occuring errors while executing
+ * SCXML documents.
+ *
+ * @author Jaroslav Gergic
+ * @author Rahul Akolkar
+ */
+public interface ErrorReporter {
+
+ /**
+ * @param errCode
+ * one of the ErrorReporter's constants
+ * @param errDetail
+ * human readable description
+ * @param errCtx
+ * typically an SCXML element which caused an error,
+ * may be accompanied by additional information
+ */
+ public void onError(String errCode, String errDetail, Object errCtx);
+
+ /**
+ * Missing initial state for a composite state or for the smxml root.
+ *
+ * @see org.apache.taglibs.rdc.scxml.model.SCXML#getInitialState()
+ * @see org.apache.taglibs.rdc.scxml.model.State#getInitial()
+ */
+ public static final String NO_INITIAL = "NO_INITIAL";
+
+ /**
+ * An initial state for a composite state whose Transition does not
+ * Map to a descendant of the composite state.
+ *
+ */
+ public static final String ILLEGAL_INITIAL = "ILLEGAL_INITIAL";
+
+ /**
+ * Unknown action - unsupported executable content. List of supported
+ * actions: assign, cancel, elseif, else, if, log, send, var
+ */
+ public static final String UNKNOWN_ACTION = "UNKNOWN_ACTION";
+
+ /**
+ * Illegal state machine configuration.
+ * Either a parallel exists which does not have all its AND sub-states
+ * active or there are multiple enabled OR states on the same level.
+ */
+ public static final String ILLEGAL_CONFIG = "ILLEGAL_CONFIG";
+
+ /**
+ * Non-deterministic situation has occured - there are more than
+ * one enabled transitions in conflict.
+ */
+ public static final String NON_DETERMINISTIC = "NON_DETERMINISTIC";
+
+ /**
+ * A variable reffered to by assign@name is undefined.
+ */
+ public static final String UNDEFINED_VARIABLE = "UNDEFINED_VARIABLE";
+
+ /**
+ * An expression language error.
+ */
+ public static final String EXPRESSION_ERROR = "EXPRESSION_ERROR";
+}
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/ErrorReporter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/ErrorReporter.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Evaluator.java
URL: http://svn.apache.org/viewcvs/jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Evaluator.java?rev=226454&view=auto
==============================================================================
--- jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Evaluator.java \
(added)
+++ jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Evaluator.java \
Fri Jul 29 18:28:30 2005 @@ -0,0 +1,57 @@
+/*
+ *
+ * Copyright 2004 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.taglibs.rdc.scxml;
+
+/**
+ * Interface for a component that may be used by the SCXML engines to
+ * evaluate the expressions within the SCXML document.
+ *
+ * @author Jaroslav Gergic
+ * @author Rahul Akolkar
+ */
+public interface Evaluator {
+
+ /**
+ * Evaluate an expression
+ *
+ * @param ctx variable context
+ * @param expr expression
+ * @return a result of the evaluation
+ * @throws SCXMLExpressionException
+ */
+ public Object eval(Context ctx, String exp) throws SCXMLExpressionException;
+
+ /**
+ * Create a new child context.
+ *
+ * @param parent parent context
+ * @return new child context
+ */
+ public Context newContext(Context parent);
+
+ /**
+ * Evaluate a condition.
+ *
+ * @param ctx variable context
+ * @param expr expression
+ * @return true/false
+ * @throws SCXMLExpressionException
+ */
+ public Boolean evalCond(Context ctx, String expr) throws \
SCXMLExpressionException; +
+}
\ No newline at end of file
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Evaluator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Evaluator.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/EventDispatcher.java
URL: http://svn.apache.org/viewcvs/jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/EventDispatcher.java?rev=226454&view=auto
==============================================================================
--- jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/EventDispatcher.java \
(added)
+++ jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/EventDispatcher.java \
Fri Jul 29 18:28:30 2005 @@ -0,0 +1,55 @@
+/*
+ *
+ * Copyright 2004 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.taglibs.rdc.scxml;
+
+import java.util.Map;
+
+/**
+ * The event controller interface used to send messages containing
+ * events or other information directly to another SCXML Interpreter,
+ * other external systems using an Event I/O Processor or to raise
+ * events in the current SCXML session.
+ *
+ * @author Jaroslav Gergic
+ * @author Rahul Akolkar
+ */
+public interface EventDispatcher {
+
+ /**
+ * Cancel the specified send message
+ *
+ * @param sendId The ID of the send message to cancel
+ */
+ public void cancel(String sendId);
+
+ /**
+ * @param sendId The ID of the send message
+ * @param target An expression returning the target location of the event
+ * @param targetType The type of the Event I/O Processor that the event
+ * should be dispatched to
+ * @param event The type of event being generated.
+ * @param params A list of zero or more whitespace separated variable
+ * names to be included with the event.
+ * @param hints The data containing information which may be
+ * used by the implementing platform to configure the event processor
+ * @param delay The event is dispatched after the delay interval elapses
+ */
+ public void send(String sendId, String target, String targetType,
+ String event, Map params, Object hints, long delay);
+
+}
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/EventDispatcher.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/EventDispatcher.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/NotificationRegistry.java
URL: http://svn.apache.org/viewcvs/jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/NotificationRegistry.java?rev=226454&view=auto
==============================================================================
--- jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/NotificationRegistry.java \
(added)
+++ jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/NotificationRegistry.java \
Fri Jul 29 18:28:30 2005 @@ -0,0 +1,132 @@
+/*
+ *
+ * Copyright 2004 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.taglibs.rdc.scxml;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import org.apache.taglibs.rdc.scxml.model.Transition;
+import org.apache.taglibs.rdc.scxml.model.TransitionTarget;
+
+/**
+ * The registry where SCXML listeners are recorded for Observable
+ * objects. The registry performs book keeping functions and notifies
+ * all listeners of the events of interest.
+ *
+ * @author Jaroslav Gergic
+ * @author Rahul Akolkar
+ */
+public class NotificationRegistry {
+
+ private HashMap regs = new HashMap();
+
+ /**
+ * Constructor
+ */
+ public NotificationRegistry(){
+ super();
+ }
+
+ /**
+ * Register this SCXMLListener for this Observable
+ *
+ * @param source The observable this listener wants to listen to
+ * @param lst The listener
+ */
+ public void addListener(Observable source, SCXMLListener lst) {
+ HashSet entries = (HashSet)regs.get(source);
+ if(entries == null) {
+ entries = new HashSet();
+ regs.put(source, entries);
+ }
+ entries.add(lst);
+ }
+
+ /**
+ * Deregister this SCXMLListener for this Observable
+ *
+ * @param source The observable this listener wants to stop listening to
+ * @param lst The listener
+ */
+ public void removeListener(Observable source, SCXMLListener lst) {
+ HashSet entries = (HashSet)regs.get(source);
+ if(entries != null) {
+ entries.remove(lst);
+ if(entries.size() == 0){
+ regs.remove(source);
+ }
+ }
+ }
+
+ /**
+ * Inform all relevant listeners that a TransitionTarget has been
+ * entered
+ *
+ * @param source The Observable
+ * @param state The TransitionTarget that was entered
+ */
+ public void fireOnEntry(Observable source, TransitionTarget state) {
+ HashSet entries = (HashSet)regs.get(source);
+ if(entries != null) {
+ Iterator iter = entries.iterator();
+ while(iter.hasNext()){
+ SCXMLListener lst = (SCXMLListener)iter.next();
+ lst.onEntry(state);
+ }
+ }
+ }
+
+ /**
+ * Inform all relevant listeners that a TransitionTarget has been
+ * exited
+ *
+ * @param source The Observable
+ * @param state The TransitionTarget that was exited
+ */
+ public void fireOnExit(Observable source, TransitionTarget state) {
+ HashSet entries = (HashSet)regs.get(source);
+ if(entries != null) {
+ Iterator iter = entries.iterator();
+ while(iter.hasNext()){
+ SCXMLListener lst = (SCXMLListener)iter.next();
+ lst.onExit(state);
+ }
+ }
+ }
+
+ /**
+ * Inform all relevant listeners of a transition that has occured
+ *
+ * @param source The Observable
+ * @param from The source TransitionTarget
+ * @param to The destination TransitionTarget
+ * @param transition The Transition that was taken
+ */
+ public void fireOnTransition(Observable source, TransitionTarget from,
+ TransitionTarget to, Transition transition) {
+ HashSet entries = (HashSet)regs.get(source);
+ if(entries != null) {
+ Iterator iter = entries.iterator();
+ while(iter.hasNext()){
+ SCXMLListener lst = (SCXMLListener)iter.next();
+ lst.onTransition(from, to, transition);
+ }
+ }
+ }
+}
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/NotificationRegistry.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/NotificationRegistry.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Observable.java
URL: http://svn.apache.org/viewcvs/jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Observable.java?rev=226454&view=auto
==============================================================================
--- jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Observable.java \
(added)
+++ jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Observable.java \
Fri Jul 29 18:28:30 2005 @@ -0,0 +1,46 @@
+/*
+ *
+ * Copyright 2004 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.taglibs.rdc.scxml;
+
+/**
+ * Interface that allows an entity within an SCXML document to have
+ * listeners attached to itself so they may be informed of events within
+ * this entity's realm.
+ *
+ * @author Jaroslav Gergic
+ * @author Rahul Akolkar
+ */
+public interface Observable {
+
+ /**
+ * Add this SCXMLListener to the list of listeners associated
+ * with this SCXML model entity
+ *
+ * @param lst The listener to be added
+ */
+ public void addListener(SCXMLListener lst);
+
+ /**
+ * Remove this SCXMLListener from the list of listeners associated
+ * with this SCXML model entity.
+ *
+ * @param lst The listener to be removed
+ */
+ public void removeListener(SCXMLListener lst);
+
+}
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Observable.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/Observable.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/PathResolver.java
URL: http://svn.apache.org/viewcvs/jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/PathResolver.java?rev=226454&view=auto
==============================================================================
--- jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/PathResolver.java \
(added)
+++ jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/PathResolver.java \
Fri Jul 29 18:28:30 2005 @@ -0,0 +1,45 @@
+/*
+ *
+ * Copyright 2004 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.taglibs.rdc.scxml;
+
+/**
+ * Interface for a component that may be used by the SCXML engines
+ * to resolve context sensitive paths.
+ *
+ * @author Jaroslav Gergic
+ * @author Rahul Akolkar
+ */
+public interface PathResolver {
+
+ /**
+ * Resolve this context sensitive path to an absolute URL.
+ *
+ * @param ctxPath Context sensitive path, can be a relative URL
+ * @return Resolved path (an absolute URL) or <code>null</code>
+ */
+ public String resolvePath(String ctxPath);
+
+ /**
+ * Get a PathResolver rooted at this context sensitive path.
+ *
+ * @param ctxPath Context sensitive path, can be a relative URL
+ * @return Returns a new resolver rooted at ctxPath
+ */
+ public PathResolver getResolver(String ctxPath);
+
+}
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/PathResolver.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/PathResolver.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLDigester.java
URL: http://svn.apache.org/viewcvs/jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLDigester.java?rev=226454&view=auto
==============================================================================
--- jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLDigester.java \
(added)
+++ jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLDigester.java \
Fri Jul 29 18:28:30 2005 @@ -0,0 +1,894 @@
+/*
+ *
+ * Copyright 2004 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.taglibs.rdc.scxml;
+
+import java.net.URL;
+import java.text.MessageFormat;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.ServletContext;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.ExtendedBaseRules;
+import org.apache.commons.digester.ObjectCreateRule;
+import org.apache.commons.digester.Rule;
+import org.apache.commons.digester.SetNextRule;
+import org.apache.commons.digester.SetPropertiesRule;
+import org.apache.commons.logging.LogFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ErrorHandler;
+
+import org.apache.taglibs.rdc.scxml.env.ServletContextResolver;
+import org.apache.taglibs.rdc.scxml.env.URLResolver;
+import org.apache.taglibs.rdc.scxml.model.Action;
+import org.apache.taglibs.rdc.scxml.model.Assign;
+import org.apache.taglibs.rdc.scxml.model.Cancel;
+import org.apache.taglibs.rdc.scxml.model.Else;
+import org.apache.taglibs.rdc.scxml.model.ElseIf;
+import org.apache.taglibs.rdc.scxml.model.Executable;
+import org.apache.taglibs.rdc.scxml.model.Exit;
+import org.apache.taglibs.rdc.scxml.model.History;
+import org.apache.taglibs.rdc.scxml.model.If;
+import org.apache.taglibs.rdc.scxml.model.Initial;
+import org.apache.taglibs.rdc.scxml.model.Log;
+import org.apache.taglibs.rdc.scxml.model.OnEntry;
+import org.apache.taglibs.rdc.scxml.model.OnExit;
+import org.apache.taglibs.rdc.scxml.model.Parallel;
+import org.apache.taglibs.rdc.scxml.model.SCXML;
+import org.apache.taglibs.rdc.scxml.model.Send;
+import org.apache.taglibs.rdc.scxml.model.State;
+import org.apache.taglibs.rdc.scxml.model.Transition;
+import org.apache.taglibs.rdc.scxml.model.TransitionTarget;
+import org.apache.taglibs.rdc.scxml.model.Var;
+
+/**
+ * The SCXMLDigester can be used to: <br>
+ * a) Digest a SCXML file placed in a web application context <br>
+ * b) Obtain a Digester instance configured with rules for SCXML digestion <br>
+ * c) Serialize an SCXML object (primarily for debugging) <br>
+ *
+ * @author Rahul Akolkar
+ */
+public class SCXMLDigester {
+
+ private static final String ERR_PARSE_FAIL = "<!-- Error parsing " +
+ "SCXML document for group: \"{0}\", with message: \"{1}\" -->\n";
+
+ // Logging
+ private static org.apache.commons.logging.Log log = LogFactory
+ .getLog(SCXMLDigester.class);
+
+ //-- PUBLIC METHODS --//
+ /**
+ * Convenience method for the RDC SCXML DM strategy impl
+ *
+ * @param ServletContext
+ * The ServletContext within which this RDC group is hosted
+ * @param String
+ * The absolute file from the base of the application context
+ * @param ErrorHandler
+ * The SAX ErrorHandler
+ *
+ * @return SCXML The SCXML object corresponding to the file argument
+ */
+ public static SCXML digest(ServletContext sc, String file,
+ ErrorHandler errHandler, Context evalCtx, Evaluator evalEngine) {
+
+ SCXML scxml = null;
+ Digester scxmlDigester = SCXMLDigester.newInstance(null,
+ new ServletContextResolver(sc));
+ scxmlDigester.setErrorHandler(errHandler);
+
+ try {
+ scxml = (SCXML) scxmlDigester.parse(sc.getRealPath(file));
+ } catch (Exception e) {
+ MessageFormat msgFormat = new MessageFormat(ERR_PARSE_FAIL);
+ String errMsg = msgFormat.format(new Object[] {sc.
+ getRealPath(file), e.getMessage()});
+ log.error(errMsg, e);
+ }
+
+ if (scxml != null) {
+ updateSCXML(scxml, evalCtx, evalEngine);
+ }
+
+ return scxml;
+
+ }
+
+ /**
+ * API for standalone usage.
+ *
+ * @param scxmlURL
+ * a canonical absolute URL to parse (relative URLs within the
+ * top level document are to be resovled against this URL).
+ * @param errHandler
+ * The SAX ErrorHandler
+ * @param evalCtx
+ * the document-level variable context for guard condition
+ * evaluation
+ * @param evalEngine
+ * the scripting/expression language engine for creating local
+ * state-level variable contexts (if supported by a given
+ * scripting engine)
+ * @see Context
+ * @see Evaluator
+ *
+ * @return SCXML The SCXML object corresponding to the file argument
+ */
+ public static SCXML digest(URL scxmlURL, ErrorHandler errHandler,
+ Context evalCtx, Evaluator evalEngine) {
+
+ SCXML scxml = null;
+ Digester scxmlDigester = SCXMLDigester
+ .newInstance(null, new URLResolver(scxmlURL));
+ scxmlDigester.setErrorHandler(errHandler);
+
+ try {
+ scxml = (SCXML) scxmlDigester.parse(scxmlURL.toString());
+ } catch (Exception e) {
+ MessageFormat msgFormat = new MessageFormat(ERR_PARSE_FAIL);
+ String errMsg = msgFormat.format(new Object[] {scxmlURL.toString(),
+ e.getMessage()});
+ log.error(errMsg, e);
+ }
+
+ if (scxml != null) {
+ updateSCXML(scxml, evalCtx, evalEngine);
+ }
+
+ return scxml;
+
+ }
+
+ /**
+ * Serialize this SCXML object (primarily for debugging)
+ *
+ * @param scxml
+ * The SCXML to be serialized
+ * @return String The serialized SCXML
+ */
+ public static String serializeSCXML(SCXML scxml) {
+ StringBuffer b = new StringBuffer("<scxml xmlns=\"").append(
+ scxml.getXmlns()).append("\" version=\"").append(
+ scxml.getVersion()).append("\" initialstate=\"").append(
+ scxml.getInitialstate()).append("\">\n");
+ Map s = scxml.getStates();
+ Iterator i = s.keySet().iterator();
+ while (i.hasNext()) {
+ serializeState(b, (State) s.get(i.next()), INDENT);
+ }
+ b.append("</scxml>\n");
+ return b.toString();
+ }
+
+ //-- PRIVATE CONSTANTS --//
+ //// Patterns to get the digestion going
+ private static final String XP_SM = "scxml";
+
+ private static final String XP_SM_ST = "scxml/state";
+
+ //// Universal matches
+ // State
+ private static final String XP_ST_ST = "!*/state/state";
+
+ private static final String XP_PAR_ST = "!*/parallel/state";
+
+ private static final String XP_TR_TAR_ST = "!*/transition/target/state";
+
+ //private static final String XP_ST_TAR_ST = "!*/state/target/state";
+
+ // Parallel
+ private static final String XP_ST_PAR = "!*/state/parallel";
+
+ // If
+ private static final String XP_IF = "!*/if";
+
+ //// Path Fragments
+ // Onentries and Onexits
+ private static final String XP_ONEN = "/onentry";
+
+ private static final String XP_ONEX = "/onexit";
+
+ // Initial
+ private static final String XP_INI = "/initial";
+
+ // History
+ private static final String XP_HIST = "/history";
+
+ // Transition, target and exit
+ private static final String XP_TR = "/transition";
+
+ private static final String XP_TAR = "/target";
+
+ private static final String XP_ST = "/state";
+
+ private static final String XP_EXT = "/exit";
+
+ // Actions
+ private static final String XP_VAR = "/var";
+
+ private static final String XP_ASN = "/assign";
+
+ private static final String XP_LOG = "/log";
+
+ private static final String XP_SND = "/send";
+
+ private static final String XP_CAN = "/cancel";
+
+ private static final String XP_EIF = "/elseif";
+
+ private static final String XP_ELS = "/else";
+
+ //// Other constants
+ private static final String INDENT = " ";
+
+ //-- PRIVATE UTILITY METHODS --//
+ /*
+ * Get a SCXML digester instance
+ *
+ * @return Digester A newly configured SCXML digester instance
+ */
+ private static Digester newInstance(SCXML scxml, PathResolver sc) {
+
+ Digester digester = new Digester();
+ //Uncomment next line after SCXML DTD is available
+ //digester.setValidating(true);
+ digester.setRules(initRules(scxml, sc));
+ return digester;
+ }
+
+ /*
+ * Private utility functions for configuring digester rule base for SCXML
+ */
+ private static ExtendedBaseRules initRules(SCXML scxml, PathResolver sc) {
+
+ ExtendedBaseRules scxmlRules = new ExtendedBaseRules();
+
+ //// SCXML
+ scxmlRules.add(XP_SM, new ObjectCreateRule(SCXML.class));
+ scxmlRules.add(XP_SM, new SetPropertiesRule());
+
+ //// States
+ // Level one states
+ addStateRules(XP_SM_ST, scxmlRules, scxml, sc, 0);
+ scxmlRules.add(XP_SM_ST, new SetNextRule("addState"));
+ // Nested states
+ addStateRules(XP_ST_ST, scxmlRules, scxml, sc, 1);
+ scxmlRules.add(XP_ST_ST, new SetNextRule("addChild"));
+ // Initial states (no longer needed due to addition of Initial)
+ //addStateRules(XP_ST_TAR_ST, scxmlRules, scxml, sc, 1);
+ //scxmlRules.add(XP_ST_TAR_ST, new SetNextRule("addChild"));
+ //scxmlRules.add(XP_ST_TAR_ST, new SetNextRule("setInitial"));
+ // Parallel states
+ addStateRules(XP_PAR_ST, scxmlRules, scxml, sc, 1);
+ scxmlRules.add(XP_PAR_ST, new SetNextRule("addState"));
+ // Target states
+ addStateRules(XP_TR_TAR_ST, scxmlRules, scxml, sc, 2);
+ scxmlRules.add(XP_TR_TAR_ST, new SetNextRule("setTarget"));
+
+ //// Parallels
+ addParallelRules(XP_ST_PAR, scxmlRules, scxml);
+
+ //// Ifs
+ addIfRules(XP_IF, scxmlRules);
+
+ return scxmlRules;
+
+ }
+
+ private static void addStateRules(String xp, ExtendedBaseRules scxmlRules,
+ SCXML scxml, PathResolver sc, int parent) {
+ scxmlRules.add(xp, new ObjectCreateRule(State.class));
+ addStatePropertiesRules(xp, scxmlRules, sc);
+ //scxmlRules.add(xp + XP_TAR, new SetPropertiesRule());
+ //scxmlRules.add(xp + XP_INI_TR_TAR, new SetPropertiesRule());
+ addInitialRule(xp + XP_INI, scxmlRules, sc, scxml);
+ addHistoryRules(xp + XP_HIST, scxmlRules, sc, scxml);
+ addParentRule(xp, scxmlRules, parent);
+ addTransitionRules(xp + XP_TR, scxmlRules, "addTransition");
+ addHandlerRules(xp, scxmlRules);
+ scxmlRules.add(xp, new UpdateModelRule(scxml));
+ }
+
+ private static void addParallelRules(String xp,
+ ExtendedBaseRules scxmlRules, SCXML scxml) {
+ addSimpleRulesTuple(xp, scxmlRules, Parallel.class, null, null,
+ "setParallel");
+ addHandlerRules(xp, scxmlRules);
+ addParentRule(xp, scxmlRules, 1);
+ scxmlRules.add(xp, new UpdateModelRule(scxml));
+ }
+
+ private static void addStatePropertiesRules(String xp,
+ ExtendedBaseRules scxmlRules, PathResolver sc) {
+ scxmlRules.add(xp, new SetPropertiesRule(
+ new String[] { "id", "final" },
+ new String[] { "id", "isFinal" }));
+ scxmlRules.add(xp, new DigestSrcAttributeRule(sc));
+ }
+
+ private static void addInitialRule(String xp,
+ ExtendedBaseRules scxmlRules, PathResolver sc, SCXML scxml) {
+ scxmlRules.add(xp, new ObjectCreateRule(Initial.class));
+ addPseudoStatePropertiesRules(xp, scxmlRules, sc);
+ scxmlRules.add(xp, new UpdateModelRule(scxml));
+ addTransitionRules(xp + XP_TR, scxmlRules, "setTransition");
+ scxmlRules.add(xp, new SetNextRule("setInitial"));
+ }
+
+ private static void addHistoryRules(String xp,
+ ExtendedBaseRules scxmlRules, PathResolver sc, SCXML scxml) {
+ scxmlRules.add(xp, new ObjectCreateRule(History.class));
+ addPseudoStatePropertiesRules(xp, scxmlRules, sc);
+ scxmlRules.add(xp, new UpdateModelRule(scxml));
+ scxmlRules.add(xp, new SetPropertiesRule(
+ new String[] { "type" }, new String[] { "type" }));
+ addTransitionRules(xp + XP_TR, scxmlRules, "setTransition");
+ scxmlRules.add(xp, new SetNextRule("addHistory"));
+ }
+
+ private static void addPseudoStatePropertiesRules(String xp,
+ ExtendedBaseRules scxmlRules, PathResolver sc) {
+ scxmlRules.add(xp, new SetPropertiesRule(
+ new String[] { "id" }, new String[] { "id" }));
+ scxmlRules.add(xp, new DigestSrcAttributeRule(sc));
+ addParentRule(xp, scxmlRules, 1);
+ }
+
+ private static void addParentRule(String xp, ExtendedBaseRules scxmlRules,
+ final int parent) {
+ if (parent < 1) {
+ return;
+ }
+ scxmlRules.add(xp, new Rule() {
+ // A generic version of setTopRule
+ public void body(String namespace, String name, String text)
+ throws Exception {
+ TransitionTarget t = (TransitionTarget) getDigester().peek();
+ TransitionTarget p = (TransitionTarget) getDigester().peek(
+ parent);
+ // CHANGE - Moved parent property to TransitionTarget
+ t.setParent(p);
+ }
+ });
+ }
+
+ private static void addTransitionRules(String xp,
+ ExtendedBaseRules scxmlRules, String setNextMethod) {
+ scxmlRules.add(xp, new ObjectCreateRule(Transition.class));
+ scxmlRules.add(xp, new SetPropertiesRule());
+ scxmlRules.add(xp + XP_TAR, new SetPropertiesRule());
+ addActionRules(xp, scxmlRules);
+ scxmlRules.add(xp + XP_EXT, new Rule() {
+ public void end(String namespace, String name) {
+ Transition t = (Transition) getDigester().peek(1);
+ State exitState = new State();
+ exitState.setIsFinal(true);
+ t.setTarget(exitState);
+ }
+ });
+ scxmlRules.add(xp, new SetNextRule(setNextMethod));
+ }
+
+ private static void addHandlerRules(String xp, ExtendedBaseRules scxmlRules) {
+ scxmlRules.add(xp + XP_ONEN, new ObjectCreateRule(OnEntry.class));
+ addActionRules(xp + XP_ONEN, scxmlRules);
+ scxmlRules.add(xp + XP_ONEN, new SetNextRule("setOnEntry"));
+ scxmlRules.add(xp + XP_ONEX, new ObjectCreateRule(OnExit.class));
+ addActionRules(xp + XP_ONEX, scxmlRules);
+ scxmlRules.add(xp + XP_ONEX, new SetNextRule("setOnExit"));
+ }
+
+ private static void addActionRules(String xp, ExtendedBaseRules scxmlRules) {
+ addActionRulesTuple(xp + XP_ASN, scxmlRules, Assign.class);
+ addActionRulesTuple(xp + XP_VAR, scxmlRules, Var.class);
+ addActionRulesTuple(xp + XP_LOG, scxmlRules, Log.class);
+ addActionRulesTuple(xp + XP_SND, scxmlRules, Send.class);
+ addActionRulesTuple(xp + XP_CAN, scxmlRules, Cancel.class);
+ addActionRulesTuple(xp + XP_EXT, scxmlRules, Exit.class);
+ }
+
+ private static void addIfRules(String xp, ExtendedBaseRules scxmlRules) {
+ addActionRulesTuple(xp, scxmlRules, If.class);
+ addActionRules(xp, scxmlRules);
+ addActionRulesTuple(xp + XP_EIF, scxmlRules, ElseIf.class);
+ addActionRulesTuple(xp + XP_ELS, scxmlRules, Else.class);
+ }
+
+ private static void addActionRulesTuple(String xp,
+ ExtendedBaseRules scxmlRules, Class klass) {
+ addSimpleRulesTuple(xp, scxmlRules, klass, null, null, "addAction");
+ scxmlRules.add(xp, new SetExecutableParentRule());
+ }
+
+ private static void addSimpleRulesTuple(String xp,
+ ExtendedBaseRules scxmlRules, Class klass, String[] args,
+ String[] props, String addMethod) {
+ scxmlRules.add(xp, new ObjectCreateRule(klass));
+ if (args == null) {
+ scxmlRules.add(xp, new SetPropertiesRule());
+ } else {
+ scxmlRules.add(xp, new SetPropertiesRule(args, props));
+ }
+ scxmlRules.add(xp, new SetNextRule(addMethod));
+ }
+
+ /*
+ * Post-processing methods to make the SCXML object Executor-ready.
+ */
+ private static void updateSCXML(SCXML scxml, Context evalCtx,
+ Evaluator evalEngine) {
+ // Watch case, slightly unfortunate naming ;-)
+ String initialstate = scxml.getInitialstate();
+ //we have to use getTargets() here since the initialState can be
+ //an indirect descendant
+ //TODO: better type check, now ClassCastException happens for Parallel
+ State initialState = (State) scxml.getTargets().get(initialstate);
+ if (initialState == null) {
+ // Where do we, where do we go?
+ System.err.println("ERROR: SCXMLDigester - No SCXML child state "
+ + "with ID \"" + initialstate
+ + "\" found i.e. no initialstate" + " for SCXML ;-)");
+ }
+ scxml.setInitialState(initialState);
+ scxml.setRootContext(evalCtx);
+ Map targets = scxml.getTargets();
+ Map states = scxml.getStates();
+ Iterator i = states.keySet().iterator();
+ while (i.hasNext()) {
+ updateState((State) states.get(i.next()), targets, evalCtx,
+ evalEngine);
+ }
+ }
+
+ private static void updateState(State s, Map targets, Context evalCtx,
+ Evaluator evalEngine) {
+ //setup local variable context
+ Context localCtx = null;
+ if (s.getParent() == null) {
+ localCtx = evalEngine.newContext(evalCtx);
+ } else {
+ State parentState = null;
+ if (s.getParent() instanceof Parallel) {
+ parentState = (State) (s.getParent().getParent());
+ } else {
+ parentState = (State) (s.getParent());
+ }
+ localCtx = evalEngine.newContext(parentState.getContext());
+ }
+ s.setContext(localCtx);
+ //ensure both onEntry and onExit have parent
+ //TODO: add this rather as a Digester rule for OnEntry/OnExit
+ s.getOnEntry().setParent(s);
+ s.getOnExit().setParent(s);
+ //ENDTODO
+ //initialize next / inital
+ Initial ini = s.getInitial();
+ Map c = s.getChildren();
+ if (!c.isEmpty()) {
+ if (ini == null) {
+ System.err.println("WARNING: SCXMLDigester - Initial "
+ + "null for " + (SCXMLHelper.isStringEmpty(s.getId()) ?
+ "anonymous state" : s.getId()));
+ }
+ Transition initialTransition = ini.getTransition();
+ updateTransition(initialTransition, targets);
+ TransitionTarget initialState = initialTransition.getTarget();
+ // we have to allow for an indirect descendant initial (targets)
+ //check that initialState is a descendant of s
+ if (initialState == null || !SCXMLHelper.isDescendant(initialState, s)) {
+ System.err.println("WARNING: SCXMLDigester - Initial state "
+ + "null or not descendant for " + (SCXMLHelper.
+ isStringEmpty(s.getId()) ? "anonymous state" : s.getId()));
+ }
+ }
+ List histories = s.getHistory();
+ Iterator histIter = histories.iterator();
+ while (histIter.hasNext()) {
+ History h = (History) histIter.next();
+ Transition historyTransition = h.getTransition();
+ updateTransition(historyTransition, targets);
+ State historyState = (State)historyTransition.getTarget();
+ if (historyState == null) {
+ System.err.println("WARNING: SCXMLDigester - History state "
+ + "null " + (SCXMLHelper.isStringEmpty(s.getId()) ?
+ "anonymous state" : s.getId()));
+ }
+ if (!h.isDeep()) {
+ if (!c.containsValue(historyState)) {
+ System.err.println("WARNING: SCXMLDigester - History state "
+ + "for shallow history is not child for " + (SCXMLHelper.
+ isStringEmpty(s.getId()) ? "anonymous state" : s.getId()));
+ }
+ } else {
+ if (!SCXMLHelper.isDescendant(historyState, s)) {
+ System.err.println("WARNING: SCXMLDigester - History state "
+ + "for deep history is not descendant for " + (SCXMLHelper.
+ isStringEmpty(s.getId()) ? "anonymous state" : s.getId()));
+ }
+ }
+ }
+ Map t = s.getTransitions();
+ Iterator i = t.keySet().iterator();
+ while (i.hasNext()) {
+ Iterator j = ((List) t.get(i.next())).iterator();
+ while (j.hasNext()) {
+ Transition trn = (Transition) j.next();
+ // TODO: add this rather as a Digester rule for Transition
+ trn.setNotificationRegistry(s.getNotificationRegistry());
+ trn.setParent(s);
+ // ENDTODO
+ updateTransition(trn, targets);
+ }
+ }
+ Parallel p = s.getParallel();
+ if (p != null) {
+ updateParallel(p, targets, evalCtx, evalEngine);
+ } else {
+ Iterator j = c.keySet().iterator();
+ while (j.hasNext()) {
+ updateState((State) c.get(j.next()), targets, evalCtx,
+ evalEngine);
+ }
+ }
+ }
+
+ private static void updateParallel(Parallel p, Map targets,
+ Context evalCtx, Evaluator evalEngine) {
+ Iterator i = p.getStates().iterator();
+ while (i.hasNext()) {
+ updateState((State) i.next(), targets, evalCtx, evalEngine);
+ }
+ }
+
+ private static void updateTransition(Transition t, Map targets) {
+ String next = t.getNext();
+ TransitionTarget tt = t.getTarget();
+ if (tt == null) {
+ tt = (TransitionTarget) targets.get(next);
+ if (tt == null) {
+ // TODO: Move Digester warnings to errors
+ System.err.println("WARNING: SCXMLDigester - Transition "
+ + "target \"" + next + "\" not found");
+ }
+ t.setTarget(tt);
+ }
+ }
+
+ /*
+ * Private SCXML object serialization utility functions
+ */
+ private static void serializeState(StringBuffer b, State s, String indent) {
+ b.append(indent).append("<state");
+ serializeTransitionTargetAttributes(b, s);
+ boolean f = s.getIsFinal();
+ if (f) {
+ b.append(" final=\"true\"");
+ }
+ b.append(">\n");
+ Initial ini = s.getInitial();
+ if (ini != null) {
+ serializeInitial(b, ini, indent + INDENT);
+ }
+ List h = s.getHistory();
+ if (h != null) {
+ serializeHistory(b, h, indent + INDENT);
+ }
+ serializeOnEntry(b, (TransitionTarget) s, indent + INDENT);
+ Map t = s.getTransitions();
+ Iterator i = t.keySet().iterator();
+ while (i.hasNext()) {
+ List et = (List) t.get(i.next());
+ for (int len = 0; len < et.size(); len++) {
+ serializeTransition(b, (Transition) et.get(len), indent
+ + INDENT);
+ }
+ }
+ Parallel p = s.getParallel();
+ if (p != null) {
+ serializeParallel(b, p, indent + INDENT);
+ } else {
+ Map c = s.getChildren();
+ Iterator j = c.keySet().iterator();
+ while (j.hasNext()) {
+ State cs = (State) c.get(j.next());
+ serializeState(b, cs, indent + INDENT);
+ }
+ }
+ serializeOnExit(b, (TransitionTarget) s, indent + INDENT);
+ b.append(indent).append("</state>\n");
+ }
+
+ private static void serializeParallel(StringBuffer b, Parallel p,
+ String indent) {
+ b.append(indent).append("<parallel");
+ serializeTransitionTargetAttributes(b, p);
+ b.append(">\n");
+ serializeOnEntry(b, (TransitionTarget) p, indent + INDENT);
+ Set s = p.getStates();
+ Iterator i = s.iterator();
+ while (i.hasNext()) {
+ serializeState(b, (State) i.next(), indent + INDENT);
+ }
+ serializeOnExit(b, (TransitionTarget) p, indent + INDENT);
+ b.append(indent).append("</parallel>\n");
+ }
+
+ private static void serializeInitial(StringBuffer b, Initial i,
+ String indent) {
+ b.append(indent).append("<initial");
+ serializeTransitionTargetAttributes(b, i);
+ b.append(">\n");
+ serializeTransition(b, i.getTransition(), indent + INDENT);
+ b.append(indent).append("</initial>\n");
+ }
+
+ private static void serializeHistory(StringBuffer b, List l,
+ String indent) {
+ if (l.size() > 0) {
+ for (int i = 0; i < l.size(); i++) {
+ History h = (History) l.get(i);
+ b.append(indent).append("<history");
+ serializeTransitionTargetAttributes(b, h);
+ if(h.isDeep()) {
+ b.append(" type=\"deep\"");
+ } else {
+ b.append(" type=\"shallow\"");
+ }
+ b.append(">\n");
+ serializeTransition(b, h.getTransition(), indent + INDENT);
+ b.append(indent).append("</history>\n");
+ }
+ }
+ }
+
+ private static void serializeTransitionTargetAttributes(StringBuffer b,
+ TransitionTarget t) {
+ String id = t.getId();
+ if (id != null) {
+ b.append(" id=\"" + id + "\"");
+ }
+ TransitionTarget pt = t.getParent();
+ if (pt != null) {
+ String pid = pt.getId();
+ if (pid != null) {
+ b.append(" parentid=\"").append(pid).append("\"");
+ }
+ }
+ }
+
+ private static void serializeTransition(StringBuffer b, Transition t,
+ String indent) {
+ b.append(indent).append("<transition event=\"").append(t.getEvent())
+ .append("\" cond=\"").append(t.getCond()).append("\">\n");
+ boolean exit = serializeActions(b, t.getActions(), indent + INDENT);
+ if (!exit) {
+ serializeTarget(b, t, indent + INDENT);
+ }
+ b.append(indent).append("</transition>\n");
+ }
+
+ private static void serializeTarget(StringBuffer b, Transition t,
+ String indent) {
+ b.append(indent).append("<target");
+ String n = t.getNext();
+ if (n != null) {
+ b.append(" next=\"" + n + "\">\n");
+ } else {
+ b.append(">\n");
+ if (t.getTarget() != null) {
+ // The inline transition target can only be a state
+ serializeState(b, (State) t.getTarget(), indent + INDENT);
+ }
+ }
+ b.append(indent).append("</target>\n");
+ }
+
+ private static void serializeOnEntry(StringBuffer b, TransitionTarget t,
+ String indent) {
+ OnEntry e = t.getOnEntry();
+ if (e != null && e.getActions().size() > 0) {
+ b.append(indent).append("<onentry>\n");
+ serializeActions(b, e.getActions(), indent + INDENT);
+ b.append(indent).append("</onentry>\n");
+ }
+ }
+
+ private static void serializeOnExit(StringBuffer b, TransitionTarget t,
+ String indent) {
+ OnExit x = t.getOnExit();
+ if (x != null && x.getActions().size() > 0) {
+ b.append(indent).append("<onexit>\n");
+ serializeActions(b, x.getActions(), indent + INDENT);
+ b.append(indent).append("</onexit>\n");
+ }
+ }
+
+ private static boolean serializeActions(StringBuffer b, List l,
+ String indent) {
+ if (l == null) {
+ return false;
+ }
+ boolean exit = false;
+ Iterator i = l.iterator();
+ while (i.hasNext()) {
+ Action a = (Action) i.next();
+ // TODO - Serialize action attrs, bodies; Priority: Very low ;-)
+ if (a instanceof Var) {
+ Var v = (Var) a;
+ b.append(indent).append("<var name=\"").append(v.getName())
+ .append("\" expr=\"").append(v.getExpr()).append(
+ "\"/>\n");
+ } else if (a instanceof Assign) {
+ Assign asn = (Assign) a;
+ b.append(indent).append("<assign name=\"")
+ .append(asn.getName()).append("\" expr=\"").append(
+ asn.getExpr()).append("\"/>\n");
+ } else if (a instanceof Send) {
+ Send s = (Send) a;
+ b.append(indent).append("<send/>\n");
+ } else if (a instanceof Cancel) {
+ Cancel c = (Cancel) a;
+ b.append(indent).append("<cancel/>\n");
+ } else if (a instanceof Log) {
+ Log lg = (Log) a;
+ b.append(indent).append("<log expr=\"").append(lg.getExpr())
+ .append("\"/>\n");
+ } else if (a instanceof Exit) {
+ Exit e = (Exit) a;
+ b.append(indent).append("<exit");
+ String expr = e.getExpr();
+ String nl = e.getNamelist();
+ if (expr != null) {
+ b.append(" expr=\"" + expr + "\"");
+ }
+ if (nl != null) {
+ b.append(" namelist=\"" + nl + "\"");
+ }
+ b.append("/>\n");
+ exit = true;
+ } else if (a instanceof If) {
+ If IF = (If) a;
+ serializeIf(b, IF, indent);
+ } else if (a instanceof Else) {
+ Else el = (Else) a;
+ b.append(indent).append("<else/>\n");
+ } else if (a instanceof ElseIf) {
+ ElseIf eif = (ElseIf) a;
+ b.append(indent).append("<elseif cond=\"")
+ .append(eif.getCond()).append("\" />\n");
+ }
+ }
+ return exit;
+ }
+
+ private static void serializeIf(StringBuffer b, If IF, String indent) {
+ b.append(indent).append("<if cond=\"").append(IF.getCond()).append(
+ "\">\n");
+ serializeActions(b, IF.getActions(), indent + INDENT);
+ b.append(indent).append("</if>\n");
+ }
+
+ /**
+ * Custom digestion rule for establishing necessary associations within the
+ * SCXML object, which include: <br>
+ * 1) Updation of the SCXML object's global targets Map <br>
+ * 2) Obtaining a handle to the SCXML object's NotificationRegistry <br>
+ *
+ * @author Rahul Akolkar
+ */
+ public static class UpdateModelRule extends Rule {
+
+ private SCXML scxml;
+
+ public UpdateModelRule(SCXML scxml) {
+ super();
+ this.scxml = scxml;
+ }
+
+ public void end(String namespace, String name) {
+ if (scxml == null) {
+ scxml = (SCXML) getDigester()
+ .peek(getDigester().getCount() - 1);
+ }
+ NotificationRegistry notifReg = scxml.getNotificationRegistry();
+ TransitionTarget tt = (TransitionTarget) getDigester().peek();
+ scxml.addTarget(tt);
+ tt.setNotificationRegistry(notifReg);
+ }
+ }
+
+ /**
+ * Custom digestion rule for setting Executable parent of Action elements
+ *
+ * @author Rahul Akolkar
+ */
+ public static class SetExecutableParentRule extends Rule {
+
+ public SetExecutableParentRule() {
+ super();
+ }
+
+ public void end(String namespace, String name) {
+ Action child = (Action) getDigester().peek();
+ for (int i = 1; i < getDigester().getCount() - 1; i++) {
+ Object ancestor = (Object) getDigester().peek(i);
+ if (ancestor instanceof Executable) {
+ child.setParent((Executable) ancestor);
+ return;
+ }
+ }
+ }
+ }
+
+ /**
+ * Custom digestion rule for external sources, that is, the src attribute of
+ * the <state> element
+ *
+ * @author Rahul Akolkar
+ */
+ public static class DigestSrcAttributeRule extends Rule {
+
+ private PathResolver ctx;
+
+ public DigestSrcAttributeRule(PathResolver sc) {
+ super();
+ this.ctx = sc;
+ }
+
+ public void begin(String namespace, String name, Attributes attributes) {
+ String src = attributes.getValue("src");
+ if (SCXMLHelper.isStringEmpty(src)) {
+ return;
+ }
+ Digester digester = getDigester();
+ SCXML scxml = (SCXML) digester.peek(digester.getCount() - 1);
+ // 1) Digest the external SCXML file
+ Digester externalSrcDigester = newInstance(scxml, ctx.getResolver(src));
+ SCXML externalSCXML = null;
+ String path = ctx == null ? src : ctx.resolvePath(src);
+
+ try {
+ externalSCXML = (SCXML) externalSrcDigester.parse(path);
+ } catch (Exception e) {
+ log.error(null, e);
+ }
+ // 2) Adopt the children
+ // TODO - Clarify spec; Priority: High
+ if (externalSCXML == null) {
+ return;
+ }
+ State s = (State) digester.peek();
+ Transition t = new Transition();
+ t.setNext(externalSCXML.getInitialstate());
+ Initial ini = new Initial();
+ ini.setTransition(t);
+ s.setInitial(ini);
+ Map children = externalSCXML.getStates();
+ Object[] ids = children.keySet().toArray();
+ for (int i = 0; i < ids.length; i++) {
+ s.addChild((State) children.get(ids[i]));
+ }
+ }
+ }
+}
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLDigester.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLDigester.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLExecutor.java
URL: http://svn.apache.org/viewcvs/jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLExecutor.java?rev=226454&view=auto
==============================================================================
--- jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLExecutor.java \
(added)
+++ jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLExecutor.java \
Fri Jul 29 18:28:30 2005 @@ -0,0 +1,316 @@
+/*
+ *
+ * Copyright 2004 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.taglibs.rdc.scxml;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.taglibs.rdc.scxml.model.ModelException;
+import org.apache.taglibs.rdc.scxml.model.SCXML;
+import org.apache.taglibs.rdc.scxml.model.State;
+import org.apache.taglibs.rdc.scxml.model.TransitionTarget;
+
+/**
+ * The SCXML "engine" that executes SCXML documents. The
+ * particular semantics used by this engine for executing the SCXML are
+ * encapsulated in SCXMLSemantics.
+ *
+ * @author Jaroslav Gergic
+ * @see SCXMLSemantics
+ */
+public class SCXMLExecutor {
+
+ private static Log log = LogFactory.getLog(SCXMLExecutor.class);
+
+ /**
+ * The stateMachine being executed
+ */
+ private SCXML stateMachine;
+
+ /**
+ * The evaluator for expressions
+ */
+ private Evaluator evaluator;
+
+ /**
+ * The current status of the stateMachine
+ */
+ private Status currentStatus;
+
+ /**
+ * The event dispatcher to interface with external documents etc.
+ */
+ private EventDispatcher eventdispatcher;
+
+ /**
+ * The environment specific error reporter
+ */
+ private ErrorReporter errorReporter = null;
+
+ /**
+ * Run-to-completion
+ */
+ private boolean superStep = true;
+
+ /**
+ * Interpretation semantics
+ * (not configurable without re-compilation for now,
+ * since we have one implementation anyway)
+ */
+ private SCXMLSemantics semantics = new SCXMLSemantics();
+
+ /**
+ * The worker method. Re-evaluates current status whenever any events
+ * are triggered.
+ *
+ * @param evts
+ * an array of external events which triggered during the last
+ * time quantum
+ * @throws ModelException in case there is a fatal SCXML object
+ * model problem.
+ */
+ public void triggerEvents(TriggerEvent evts[])
+ throws ModelException {
+ ArrayList evs = new ArrayList(Arrays.asList(evts));
+ do {
+ // CreateStep
+ Step step = new Step(evs, currentStatus);
+ // EnumerateReachableTransitions
+ semantics.enumerateReachableTransitions(stateMachine, step,
+ errorReporter);
+ // FilterTransitionSet
+ semantics.filterTransitionsSet(step, evaluator, errorReporter);
+ // SeedTargetSet
+ semantics.seedTargetSet(step, errorReporter);
+ // DetermineTargetStates
+ semantics.determineTargetStates(
+ step.getAfterStatus().getStates(), errorReporter);
+ // BuildOnExitOnEntryLists
+ semantics.buildOnExitOnEntryLists(step, errorReporter);
+ // UpdateHistoryStates
+ semantics.updateHistoryStates(step, errorReporter);
+ // ExecuteActions
+ semantics.executeActions(step, this, errorReporter);
+ // AssignCurrentStatus
+ updateStatus(step);
+ // ***Cleanup external events if superStep
+ if(superStep) {
+ evs.clear();
+ }
+ } while(superStep && currentStatus.getEvents().size() > 0);
+ logState();
+ }
+
+ public SCXMLExecutor() throws ModelException {
+ this(null, null, null);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param stateMachine The stateMachine to execute
+ * @param evaluator The expression evaluator
+ * @param evtDisp The event dispatcher
+ * @param errRep The error reporter
+ * @throws ModelException in case there is a fatal SCXML object
+ * model problem.
+ */
+ public SCXMLExecutor(Evaluator evaluator, EventDispatcher evtDisp,
+ ErrorReporter errRep) throws ModelException {
+ this.evaluator = evaluator;
+ this.eventdispatcher = evtDisp;
+ this.errorReporter = errRep;
+ this.currentStatus = null;
+ this.stateMachine = null;
+ }
+
+ /**
+ * Clear all state and begin from "initialstate" indicated
+ * on root SCXML element.
+ *
+ * @throws ModelException in case there is a fatal SCXML object
+ * model problem.
+ */
+ public void reset() throws ModelException {
+ // Reset all variable contexts
+ stateMachine.getRootContext().reset();
+ // all states and parallels, only states have var. contexts
+ Iterator i = stateMachine.getTargets().values().iterator();
+ while(i.hasNext()) {
+ TransitionTarget tt = (TransitionTarget)i.next();
+ if(tt instanceof State) {
+ ((State)tt).getContext().reset();
+ }
+ }
+ // CreateEmptyStatus
+ currentStatus = new Status();
+ Step step = new Step(null, currentStatus);
+ // DetermineInitialStates
+ semantics.determineInitialStates(stateMachine,
+ step.getAfterStatus().getStates(),
+ step.getEntryList(), errorReporter);
+ // ExecuteActions
+ semantics.executeActions(step, this, errorReporter);
+ // AssignCurrentStatus
+ updateStatus(step);
+ // Execute Immediate Transitions
+ if(superStep && currentStatus.getEvents().size() > 0) {
+ this.triggerEvents(new TriggerEvent[0]);
+ } else {
+ logState();
+ }
+ }
+
+ /**
+ * Get the current status
+ *
+ * @return The current Status
+ */
+ public Status getCurrentStatus() {
+ return currentStatus;
+ }
+
+ /**
+ * Get the expression evaluator
+ *
+ * @return Returns the evaluator.
+ */
+ public Evaluator getEvaluator() {
+ return evaluator;
+ }
+
+ /**
+ * @param evaluator The evaluator to set.
+ */
+ public void setEvaluator(Evaluator evaluator) {
+ this.evaluator = evaluator;
+ }
+
+ /**
+ * Get the state machine that is being executed
+ *
+ * @return Returns the stateMachine.
+ */
+ public SCXML getStateMachine() {
+ return stateMachine;
+ }
+
+ /**
+ * Set the state machine to be executed
+ *
+ * @param stateMachine The stateMachine to set.
+ * @throws ModelException in case there is a fatal SCXML object
+ * model problem.
+ */
+ public void setStateMachine(SCXML statemachine) throws ModelException {
+ // NormalizeStateMachine
+ SCXML sm = semantics.normalizeStateMachine(statemachine,
+ errorReporter);
+ // StoreStateMachine
+ this.stateMachine = sm;
+ // reset
+ this.reset();
+ }
+
+ /**
+ * Get the environment specific error reporter
+ *
+ * @return Returns the errorReporter.
+ */
+ public ErrorReporter getErrorReporter() {
+ return errorReporter;
+ }
+
+ /**
+ * Set the environment specific error reporter
+ *
+ * @param errorReporter The errorReporter to set.
+ */
+ public void setErrorReporter(ErrorReporter errorReporter) {
+ this.errorReporter = errorReporter;
+ }
+
+ /**
+ * Get the event dispatcher
+ *
+ * @return Returns the eventdispatcher.
+ */
+ public EventDispatcher getEventdispatcher() {
+ return eventdispatcher;
+ }
+
+ /**
+ * Set the event dispatcher
+ *
+ * @param eventdispatcher The eventdispatcher to set.
+ */
+ public void setEventdispatcher(EventDispatcher eventdispatcher) {
+ this.eventdispatcher = eventdispatcher;
+ }
+
+ /**
+ * Use "super-step", default is <code>true</code>
+ * (that is, run-to-completion is default)
+ * @return Returns the superStep property.
+ * @see #setSuperStep(boolean)
+ */
+ public boolean isSuperStep() {
+ return superStep;
+ }
+
+ /**
+ * Set the super step
+ * @param superStep
+ * if true, the internal derived events are also processed (run-to-completion);
+ * if false, the internal derived events are stored in the
+ * CurrentStatus property and processed within the next
+ * triggerEvents() invocation, also the immediate (empty event) transitions
+ * are deferred until the next step
+ */
+ public void setSuperStep(boolean superStep) {
+ this.superStep = superStep;
+ }
+
+ private void logState() {
+ if(log.isInfoEnabled()) {
+ Iterator si = currentStatus.getStates().iterator();
+ StringBuffer sb = new StringBuffer("Current States: [");
+ while(si.hasNext()) {
+ State s = (State)si.next();
+ sb.append(s.getId());
+ if(si.hasNext()) {
+ sb.append(", ");
+ }
+ }
+ sb.append(']');
+ log.info(sb.toString());
+ }
+ }
+
+ /**
+ * @param step
+ */
+ private void updateStatus(Step step) {
+ this.currentStatus = step.getAfterStatus();
+ stateMachine.getRootContext().setLocal("_ALL_STATES",
+ SCXMLHelper.getAncestorClosure(currentStatus.getStates(), null));
+ }
+}
\ No newline at end of file
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLExecutor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLExecutor.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLExpressionException.java
URL: http://svn.apache.org/viewcvs/jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLExpressionException.java?rev=226454&view=auto
==============================================================================
--- jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLExpressionException.java \
(added)
+++ jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLExpressionException.java \
Fri Jul 29 18:28:30 2005 @@ -0,0 +1,61 @@
+/*
+ *
+ * Copyright 2004 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.taglibs.rdc.scxml;
+
+/**
+ * Exception thrown when a malformed expression is encountered during
+ * evaluation of an expression in a SCXML document.
+ *
+ * @author Jaroslav Gergic
+ * @author Rahul Akolkar
+ */
+public class SCXMLExpressionException extends Exception {
+
+ /**
+ * @see java.lang.Exception#Exception()
+ */
+ public SCXMLExpressionException() {
+ super();
+ }
+
+ /**
+ * @see java.lang.Exception#Exception(java.lang.String)
+ * @param message
+ */
+ public SCXMLExpressionException(String message) {
+ super(message);
+ }
+
+ /**
+ * @see java.lang.Exception#Exception(java.lang.Throwable)
+ * @param cause
+ */
+ public SCXMLExpressionException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * @see java.lang.Exception#Exception(java.lang.String, java.lang.Throwable)
+ * @param message
+ * @param cause
+ */
+ public SCXMLExpressionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLExpressionException.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLExpressionException.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLHelper.java
URL: http://svn.apache.org/viewcvs/jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLHelper.java?rev=226454&view=auto
==============================================================================
--- jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLHelper.java \
(added)
+++ jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLHelper.java \
Fri Jul 29 18:28:30 2005 @@ -0,0 +1,271 @@
+/*
+ *
+ * Copyright 2004 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.taglibs.rdc.scxml;
+
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.taglibs.rdc.scxml.model.Parallel;
+import org.apache.taglibs.rdc.scxml.model.Path;
+import org.apache.taglibs.rdc.scxml.model.State;
+import org.apache.taglibs.rdc.scxml.model.Transition;
+import org.apache.taglibs.rdc.scxml.model.TransitionTarget;
+
+/**
+ * Helper class, all methods static final.
+ *
+ */
+public class SCXMLHelper {
+
+ /**
+ * Return true if the string is empty
+ *
+ * @param attr The String to test
+ * @return Is string empty
+ */
+ public static final boolean isStringEmpty(String attr) {
+ return (attr == null || attr.trim().length() == 0) ? true : false;
+ }
+
+ /**
+ * Checks whether a transition target tt (State or Parallel) is a descendant
+ * of the transition target ctx.
+ *
+ * @param tt
+ * TransitionTarget to check - a potential descendant
+ * @param ctx
+ * TransitionTarget context - a potential ancestor
+ * @return true iff tt is a descendant of ctx, false otherwise
+ */
+ public static final boolean isDescendant(TransitionTarget tt,
+ TransitionTarget ctx) {
+ while ((tt = tt.getParent()) != null) {
+ if (tt == ctx) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Creates a set which contains given states and all their ancestors
+ * recursively up to the upper bound. Null upperBound means root
+ * of the state machine.
+ *
+ * @param upperBounds
+ * @param transTargets
+ * [in]
+ *
+ * @return transitive closure of a given state set
+ */
+ public static final Set getAncestorClosure(Set states, Set upperBounds) {
+ HashSet closure = new HashSet((int) (states.size() * 2));
+ Iterator i = states.iterator();
+ while (i.hasNext()) {
+ TransitionTarget tt = (TransitionTarget) i.next();
+ closure.add(tt);
+ while ((tt = tt.getParent()) != null) {
+ if (upperBounds != null && upperBounds.contains(tt)) {
+ break;
+ }
+ if (!closure.add(tt)) {
+ //parent is already a part of the closure
+ break;
+ }
+ }
+ }
+ return closure;
+ }
+
+ /**
+ * Checks whether a given set of states is a legal Harel State Table
+ * configuration (with the respect to the definition of the OR and AND
+ * states).
+ *
+ * @param states
+ * a set of states
+ * @param errRep
+ * ErrorReporter to report detailed error info if needed
+ * @return true if a given state configuration is legal, false otherwise
+ */
+ public static final boolean isLegalConfig(Set states, ErrorReporter errRep) {
+ /*
+ * For every active state we add 1 to the count of its parent. Each
+ * Parallel should reach count equal to the number of its children and
+ * contribute by 1 to its parent. Each State should reach count exactly
+ * 1. SXML elemnt (top) should reach count exactly 1. We essentially
+ * summarize up the hierarchy tree starting with a given set of states =
+ * active configuration.
+ */
+ boolean legalConfig = true; // let's be optimists
+ IdentityHashMap counts = new IdentityHashMap();
+ HashSet scxmlCount = new HashSet();
+ Iterator i = states.iterator();
+ while (i.hasNext()) {
+ TransitionTarget tt = (TransitionTarget) i.next();
+ TransitionTarget parent = null;
+ while ((parent = tt.getParent()) != null) {
+ HashSet cnt = (HashSet) counts.get(parent);
+ if (cnt == null) {
+ cnt = new HashSet();
+ counts.put(parent, cnt);
+ }
+ cnt.add(tt);
+ tt = parent;
+ }
+ //top-level contribution
+ scxmlCount.add(tt);
+ }
+ //Validate counts:
+ i = counts.entrySet().iterator();
+ while (i.hasNext()) {
+ Map.Entry entry = (Map.Entry) i.next();
+ TransitionTarget tt = (TransitionTarget) entry.getKey();
+ HashSet count = (HashSet) entry.getValue();
+ if (tt instanceof Parallel) {
+ Parallel p = (Parallel) tt;
+ if (count.size() < p.getStates().size()) {
+ errRep.onError(ErrorReporter.ILLEGAL_CONFIG,
+ "Not all AND states active for parallel "
+ + p.getId(), entry);
+ legalConfig = false;
+ }
+ } else {
+ if (count.size() > 1) {
+ errRep
+ .onError(ErrorReporter.ILLEGAL_CONFIG,
+ "Multiple OR states active for state "
+ + tt.getId(), entry);
+ legalConfig = false;
+ }
+ }
+ count.clear(); //cleanup
+ }
+ if (scxmlCount.size() > 1) {
+ errRep.onError(ErrorReporter.ILLEGAL_CONFIG,
+ "Multiple top-level OR states active!", scxmlCount);
+ }
+ //cleanup
+ scxmlCount.clear();
+ counts.clear();
+ return legalConfig;
+ }
+
+ /**
+ * finds the least common ancestor of transition targets tt1 and tt2 if one
+ * exists.
+ *
+ * @param tt1
+ * @param tt2
+ * @return closest common ancestor of tt1 and tt2 or null
+ */
+ public static final TransitionTarget getLCA(TransitionTarget tt1,
+ TransitionTarget tt2) {
+ if (tt1 == tt2) {
+ return tt1; //self-transition
+ } else if (isDescendant(tt1, tt2)) {
+ return tt2;
+ } else if (isDescendant(tt2, tt1)) {
+ return tt1;
+ }
+ HashSet parents = new HashSet();
+ TransitionTarget tmp = tt1;
+ while ((tmp = tmp.getParent()) != null) {
+ if (tmp instanceof State) {
+ parents.add(tmp);
+ }
+ }
+ tmp = tt2;
+ while ((tmp = tmp.getParent()) != null) {
+ if (tmp instanceof State) {
+ //test redundant add = common ancestor
+ if (!parents.add(tmp)) {
+ parents.clear();
+ return tmp;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the set of all states (and parallels) which are exited if a given \
transition t is + * going to be taken. Current states are necessary to be taken into \
account + * due to orthogonal states and cross-region transitions - see UML specs.
+ * for more details.
+ *
+ * @param t
+ * transition to be taken
+ * @param currentStates
+ * the set of current states (simple states only)
+ * @return a set of all states (including composite) which are exited if a
+ * given transition is taken
+ */
+ public static final Set getStatesExited(Transition t, Set currentStates) {
+ HashSet allStates = new HashSet();
+ Path p = t.getPath();
+ //the easy part
+ allStates.addAll(p.getUpwardSegment());
+ if (p.isCrossRegion()) {
+ Iterator regions = p.getRegionsExited().iterator();
+ while (regions.hasNext()) {
+ Parallel par = ((Parallel) ((State) regions.next()).getParent());
+ //let's find affected states in sibling regions
+ Iterator siblings = par.getStates().iterator();
+ while (siblings.hasNext()) {
+ State s = (State) siblings.next();
+ Iterator act = currentStates.iterator();
+ while (act.hasNext()) {
+ TransitionTarget a = (TransitionTarget) act.next();
+ if (isDescendant(a, s)) {
+ //a is affected
+ boolean added = false;
+ added = allStates.add(a);
+ while (added && a != s) {
+ a = a.getParent();
+ added = allStates.add(a);
+ }
+ }
+ }
+ }
+ }
+ }
+ return allStates;
+ }
+
+ /**
+ * According to the UML definition, two transitions
+ * are conflicting if the sets of states they exit overlap.
+ *
+ * @param t1 a transition to check against t2
+ * @param t2 a transition to check against t1
+ * @param currentStates the set of current states (simple states only)
+ * @return true if the t1 and t2 are conflicting transitions
+ * @see #getStatesExited(Transition, Set)
+ */
+ public static final boolean inConflict(Transition t1, Transition t2,
+ Set currentStates) {
+ Set ts1 = getStatesExited(t1, currentStates);
+ Set ts2 = getStatesExited(t2, currentStates);
+ ts1.retainAll(ts2);
+ return (ts1.isEmpty()) ? false : true;
+ }
+}
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLHelper.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLHelper.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLListener.java
URL: http://svn.apache.org/viewcvs/jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLListener.java?rev=226454&view=auto
==============================================================================
--- jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLListener.java \
(added)
+++ jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLListener.java \
Fri Jul 29 18:28:30 2005 @@ -0,0 +1,54 @@
+/*
+ *
+ * Copyright 2004 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.taglibs.rdc.scxml;
+
+import org.apache.taglibs.rdc.scxml.model.Transition;
+import org.apache.taglibs.rdc.scxml.model.TransitionTarget;
+
+/**
+ * Listener interface for Observable entities in the SCXML model.
+ *
+ * @author Jaroslav Gergic
+ */
+public interface SCXMLListener {
+
+ /**
+ * Handle the entry into a TransitionTarget
+ *
+ * @param state The TransitionTarget entered
+ */
+ public void onEntry(TransitionTarget state);
+
+ /**
+ * Handle the exit out of a TransitionTarget
+ *
+ * @param state The TransitionTarget exited
+ */
+ public void onExit(TransitionTarget state);
+
+ /**
+ * Handle the transition
+ *
+ * @param from The source TransitionTarget
+ * @param to The destination TransitionTarget
+ * @param transition The Transition taken
+ */
+ public void onTransition(TransitionTarget from, TransitionTarget to,
+ Transition transition);
+
+}
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/taglibs/proper/rdc/trunk/src/org/apache/taglibs/rdc/scxml/SCXMLListener.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
---------------------------------------------------------------------
To unsubscribe, e-mail: taglibs-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: taglibs-dev-help@jakarta.apache.org
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic