当前位置: 首页 > 工具软件 > SCXML > 使用案例 >

java+scxml+onentry_apache common scxml框架学习DEMO

方鸿羲
2023-12-01

官网:http://commons.apache.org/proper/commons-scxml/index.html

SCXML W3C规范:http://www.w3.org/TR/scxml/

pom.xml

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0

com.ctrip.infosec.offline

fsm

0.0.1-SNAPSHOT

Java.Net

http://download.java.net/maven/2/

JBoss repository

http://repository.jboss.com/maven2/

maven

http://repo1.maven.org/maven2/

commons-scxml

commons-scxml

0.9

commons-jexl

commons-jexl

20040901.055348

commons-logging

commons-logging

1.1.3

org.codehaus.groovy

groovy-all

2.2.2

xalan

xalan

2.7.1

javax.servlet

servlet-api

2.5

jstl

jstl

1.2

src

src

**/*.java

maven-compiler-plugin

2.3.2

1.7

1.7

myfsm.xml

version="1.0" initial="reset">

SCXMLEngine.java(状态机引擎,参考AbstractStateMachine类)

package com.ctrip.infosec.offline.fsm;

import java.io.IOException;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.util.ArrayList;

import java.util.List;

import java.util.Map;

import java.util.Scanner;

import java.util.Set;

import org.apache.commons.scxml.SCXMLExecutor;

import org.apache.commons.scxml.SCXMLListener;

import org.apache.commons.scxml.Status;

import org.apache.commons.scxml.TriggerEvent;

import org.apache.commons.scxml.env.SimpleDispatcher;

import org.apache.commons.scxml.env.SimpleErrorHandler;

import org.apache.commons.scxml.env.SimpleErrorReporter;

import org.apache.commons.scxml.env.jexl.JexlContext;

import org.apache.commons.scxml.env.jexl.JexlEvaluator;

import org.apache.commons.scxml.io.SCXMLParser;

import org.apache.commons.scxml.model.CustomAction;

import org.apache.commons.scxml.model.ModelException;

import org.apache.commons.scxml.model.SCXML;

import org.apache.commons.scxml.model.State;

import org.apache.commons.scxml.model.Transition;

import org.apache.commons.scxml.model.TransitionTarget;

import org.xml.sax.SAXException;

public class SCXMLEngine {

private static SCXMLExecutor engine = null;

public static void main(String[] args) {

engine = new SCXMLExecutor(new JexlEvaluator(), new SimpleDispatcher(),

new SimpleErrorReporter());

// (1) Create a list of custom actions, add as many as are needed

List customActions = new ArrayList();

CustomAction ca = new CustomAction(

"http://my.custom-actions.domain/custom1", "hello", Hello.class);

customActions.add(ca);

SCXML stateMachine;

try {

stateMachine = SCXMLParser.parse(SCXMLEngine.class.getClassLoader()

.getResource("myfsm.xml"), new SimpleErrorHandler(),

customActions);

TransitionTarget tt = null;

Map targets = stateMachine.getTargets();

tt = (TransitionTarget)targets.get("paused");

stateMachine.setInitialTarget(tt);

engine.setStateMachine(stateMachine);

engine.setSuperStep(true);

engine.setRootContext(new JexlContext());

engine.addListener(stateMachine,

new SCXMLEngine().new EntryListener());

} catch (IOException e) {

e.printStackTrace();

} catch (SAXException e) {

e.printStackTrace();

} catch (ModelException e) {

e.printStackTrace();

}

try {

engine.go();

} catch (ModelException me) {

me.printStackTrace();

}

String event = null;

Scanner input = new Scanner(System.in);

while (true) {

event = input.nextLine();

if (event.trim() != null && !event.trim().equals("")) {

if (event.equals("exit")) {

input.close();

break;

} else {

TriggerEvent[] evts = { new TriggerEvent(event,

TriggerEvent.SIGNAL_EVENT, null) };

try {

engine.triggerEvents(evts);

Status currStatus = engine.getCurrentStatus();

Set states = currStatus.getStates();

for(Object object : states) {

State state = ((State)object);

System.out.println("current status id is : " + state.getId());

/*if (((State)object).getId().equals("reset")) {

TransitionTarget parent = state.getParent();

System.out.println("parent is : " + parent.getId());

}*/

}

} catch (ModelException me) {

me.printStackTrace();

}

}

}

}

}

/**

* Invoke the no argument method with the following name.

*

* @param methodName The method to invoke.

* @return Whether the invoke was successful.

*/

public boolean invoke(final String methodName) {

Class clas = this.getClass();

try {

Method method = clas.getDeclaredMethod(methodName, new Class[0]);

method.invoke(this, new Object[0]);

} catch (SecurityException se) {

System.out.println(se);

return false;

} catch (NoSuchMethodException nsme) {

System.out.println(nsme);

return false;

} catch (IllegalArgumentException iae) {

System.out.println(iae);

return false;

} catch (IllegalAccessException iae) {

System.out.println(iae);

return false;

} catch (InvocationTargetException ite) {

System.out.println(ite);

return false;

}

return true;

}

public void reset() {

System.out.println("reset method called");

}

public void running() {

System.out.println("running method called");

}

public void paused() {

System.out.println("paused method called");

}

public void stopped() {

System.out.println("stopped method called");

}

/**

* A SCXMLListener that is only concerned about "onentry"

* notifications.

*/

protected class EntryListener implements SCXMLListener {

public void onEntry(final TransitionTarget entered) {

System.out.println("Entering State : " + entered.getId() + ", begin to invoke method " + entered.getId());

invoke(entered.getId());

}

public void onTransition(final TransitionTarget from,

final TransitionTarget to, final Transition transition) {

System.out.println("Transiting from " + from.getId() + " to "

+ to.getId());

}

public void onExit(final TransitionTarget exited) {

System.out.println("Exiting :" + exited.getId());

}

}

}

Hello.java

/*

* Licensed to the Apache Software Foundation (ASF) under one or more

* contributor license agreements. See the NOTICE file distributed with

* this work for additional information regarding copyright ownership.

* The ASF licenses this file to You under the Apache License, Version 2.0

* (the "License"); you may not use this file except in compliance with

* the License. You may obtain a copy of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/

package com.ctrip.infosec.offline.fsm;

import java.util.Collection;

import org.apache.commons.logging.Log;

import org.apache.commons.scxml.ErrorReporter;

import org.apache.commons.scxml.EventDispatcher;

import org.apache.commons.scxml.SCInstance;

import org.apache.commons.scxml.SCXMLExpressionException;

import org.apache.commons.scxml.TriggerEvent;

import org.apache.commons.scxml.model.ModelException;

import org.apache.commons.scxml.model.Action;

/**

* Our custom "hello world" action.

*/

public class Hello extends Action {

/** Serial version UID. */

private static final long serialVersionUID = 1L;

/** This is who we say hello to. */

private String name;

/** We count callbacks to execute() as part of the test suite. */

public static int callbacks = 0;

/** Public constructor is needed for the I in SCXML IO. */

public Hello() {

super();

}

/**

* Get the name.

*

* @return Returns the name.

*/

public String getName() {

return name;

}

/**

* Set the name.

*

* @param name

* The name to set.

*/

public void setName(String name) {

this.name = name;

}

/*@Override

public void execute(ActionExecutionContext exctx) throws ModelException,

SCXMLExpressionException {

if (exctx.getAppLog().isInfoEnabled()) {

exctx.getAppLog().info("Hello " + name);

}

// For derived events payload testing

TriggerEvent event = new TriggerEvent("helloevent",

TriggerEvent.SIGNAL_EVENT, name);

exctx.getInternalIOProcessor().addEvent(event);

callbacks++;

}*/

@Override

public void execute(EventDispatcher evtDispatcher, ErrorReporter errRep,

SCInstance scInstance, Log appLog, Collection derivedEvents)

throws ModelException, SCXMLExpressionException {

/*if (appLog.isInfoEnabled()) {

appLog.info("Hello " + name);

}*/

System.out.println("Hello " + name);

// For derived events payload testing

TriggerEvent event = new TriggerEvent("watch.test",

TriggerEvent.SIGNAL_EVENT, name);

derivedEvents.add(event);

callbacks++;

System.out.println("callbacks=" + callbacks);

}

}

此外,官网还有一个StopWatch的usercase

 类似资料: