Hi All ,
I need your help in getting the Context in my Custom Action Class.
Here is the scenario:
1. I have a SIP Servlet (MainPOCAS) , In the servlet I am parsing a SCXML
file and making a SCXML object out of that file .
Then I make the Context ( tried SImpleContext , JexlContext ) and set
it using
StopClock clock=new StopClock(scxml);
clock.getEngine().setRootContext((Context) jc);
If I try retrieving the Context variable in the same class I can vey well
retrieve it .
2. But when I try to retrieve the contest i my StateMachine Class , I get
the value NULL , I am not able to understand why .
What i think is that since I had set the root context of the scxml object I
should be able to retrieve the context .
Please let me know if there is any gap in my understanding .
I am attaching the source code ( copy pasted from various examples from
commons-scxml site )
MainPocAS ( SipServlet ) , StopClock.java ( StateMachine Class) Hello.java
( Custom Action class ).
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package PocAS;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.sip.Proxy;
import javax.servlet.sip.SipErrorEvent;
import javax.servlet.sip.SipErrorListener;
import javax.servlet.sip.SipServlet;
import javax.servlet.sip.SipServletRequest;
import javax.servlet.sip.SipServletResponse;
import java.io.IOException;
import java.net.URL;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.commons.jexl.JexlContext;
import org.apache.commons.jexl.JexlHelper;
import org.apache.commons.scxml.Context;
import org.apache.commons.scxml.PathResolver;
import org.apache.commons.scxml.SCXMLExecutor;
import org.apache.commons.scxml.env.SimpleContext;
import org.apache.commons.scxml.env.SimpleErrorHandler;
import org.apache.commons.scxml.env.servlet.ServletContextResolver;
import org.apache.commons.scxml.io.SCXMLParser;
import org.apache.commons.scxml.model.CustomAction;
import org.apache.commons.scxml.model.Event;
import org.apache.commons.scxml.model.ModelException;
import org.apache.commons.scxml.model.SCXML;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.ext.DefaultHandler2;
import org.xml.sax.helpers.DefaultHandler;
/**
*
* @author sauragar
*/
@javax.servlet.sip.annotation.SipServlet
public class MainPocAS extends javax.servlet.sip.SipServlet implements
SipErrorListener,Servlet {
private static final long serialVersionUID = 3978425801979081269L;
//Reference to context - The ctx Map is used as a central storage for
this app
javax.servlet.ServletContext ctx = null;
protected void doInvite(SipServletRequest request)
throws ServletException, IOException {
log(" $$$ ############################ SimpleProxyServlet: Got
request:\n" + request+" TO::"+request.getTo());
log (" New log To::"+request.getTo().toString());
HashMap aMap=new HashMap() ;
aMap.put("SipMessage","Saurabh" );
SimpleContext sc=new SimpleContext(aMap);
JexlContext jc = JexlHelper.createContext();
jc.setVars(aMap);
// (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);
CustomAction ca1 =
new CustomAction("http://my.custom-actions.domain/CUSTOM2",
"bar", Hello.class);
customActions.add(ca);
customActions.add(ca1);
// (2) Parse the SCXML document containing the custom action(s)
SCXML scxml = null;
try {
// try {URL url=new URL
(StopClock.class.getClassLoader().getResource("PocAS/stopwatch.xml"));
scxml =
SCXMLParser.parse(StopClock.class.getClassLoader().getResource("PocAS/stopwatch.xml"),
new SimpleErrorHandler(), customActions);
// Also see other methods in SCXMLParser API
// "url" points to SCXML document
// "errorHandler" is SAX ErrorHandler
} catch (SAXException ex) {
Logger.getLogger(MainPocAS.class.getName()).log(Level.SEVERE,
null, ex);
} catch (ModelException ex) {
Logger.getLogger(MainPocAS.class.getName()).log(Level.SEVERE,
null, ex);
}
// Also see other methods in SCXMLParser API
// "url" points to SCXML document
// "errorHandler" is SAX ErrorHandler
StopClock clock=new StopClock(scxml);
clock.getEngine().setRootContext((Context) jc);
Context RCtx= clock.getEngine().getRootContext();
System.out.println(" In Main Root Context ::"+ RCtx.toString());
System.out.println(" In Main Root Context Msg ::"+
RCtx.get("SipMessage"));
System.out.println(" In Main Root Context ::"+ RCtx.getVars());
// if(request.getTo().toString().equals("Alice1"))
clock.fireEvent(StopClock.EVENT_RESET);
// else
// clock.fireEvent(StopClock.EVENT_STOP);
/*SCXML scxml = null;
try {
try {
scxml = SCXMLParser.parse(new URL("
http://svn.apache.org/repos/asf/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/stopwatch.xml"),
new DefaultHandler2());
log("SimpleProxyServlet: Children::"+scxml.getChildren());
} catch (ModelException ex) {
Logger.getLogger(MainPocAS.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (IOException ioe) {
log("SimpleProxyServlet: err"+ioe.getMessage());
// IOException while parsing
} catch (SAXException se) {
// SAXException while parsing
log("SimpleProxyServlet: ERR::"+se.getMessage());
}
if (scxml == null) {
log("SimpleProxyServlet: Parsing Failed::");
}
SCXMLExecutor exec = null;
try {
exec = new SCXMLExecutor();
exec.setStateMachine(scxml);
//exec.addListener(scxml, <SCXMLListener>);
//exec.setRootContext(<Context>);
log("SimpleProxyServlet: Going to start the state machine");
exec.go();
} catch (ModelException me) {
// Executor initialization failed, because the
// state machine specified has inconsistencies
}*/
/*if (request.isInitial()) {
Proxy proxy = request.getProxy();
proxy.setRecordRoute(true);
proxy.setSupervised(true);
proxy.proxyTo(request.getRequestURI()); // bobs uri
}*/
System.out.println("SimpleProxyServlet: Got request:\n" + request);
}
protected void doBye(SipServletRequest request) throws ServletException,
IOException {
System.out.println("SimpleProxyServlet: Got BYE request:\n" +
request);
super.doBye(request);
}
protected void doResponse(SipServletResponse response)
throws ServletException, IOException {
System.out.println("SimpleProxyServlet: Got response:\n" +
response);
super.doResponse(response);
}
// SipErrorListener
public void noAckReceived(SipErrorEvent ee) {
System.out.println("SimpleProxyServlet: Error: noAckReceived.");
}
public void noPrackReceived(SipErrorEvent ee) {
System.out.println("SimpleProxyServlet: Error: noPrackReceived.");
}
@Override
public void init(javax.servlet.ServletConfig config) throws
javax.servlet.ServletException {
super.init(config);
ctx = config.getServletContext();
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package PocAS;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.sip.SipServlet;
import org.apache.commons.jexl.JexlContext;
import org.apache.commons.scxml.Context;
import org.apache.commons.scxml.env.AbstractStateMachine;
import org.apache.commons.scxml.model.SCXML;
/**
26 * A SCXML document driven stop watch.
27 *
28 * Using SCXML makes the StopWatch class simplistic; you are neither
29 * managing the stopwatch "lifecycle" nor coding any "transitions",
30 * that information is pulled in straight from the behavioral model
* of the stop watch, which is encapsulated in the SCXML document
* the constructor points to (which in turn may be generated straight
* from the UML model).
*/
public class StopClock extends AbstractStateMachine {
/** The events for the stop watch. */
public static final String EVENT_START = "watch.start",
EVENT_STOP = "watch.stop", EVENT_SPLIT = "watch.split",
EVENT_UNSPLIT = "watch.unsplit", EVENT_RESET = "watch.reset";
/** The fragments of the elapsed time. */
private int hr, min, sec, fract;
/** The fragments of the display time. */
private int dhr, dmin, dsec, dfract;
/** The stopwatch "split" (display freeze). */
private boolean split;
/** The Timer to keep time. */
private Timer timer;
/** The display decorations. */
private static final String DELIM = ":", DOT = ".", EMPTY = "", ZERO =
"0";
public StopClock(SCXML scxml) throws MalformedURLException {
// super(StopClock.class.getClassLoader().
// getResource("PocAS/stopwatch.xml"));
// super(new URL ("
http://svn.apache.org/repos/asf/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml/env/stopwatch.xml
"));
super(scxml);
System.out.println("### $$$$$$$$ CONTEXT
"+this.getEngine().getRootContext().toString());
System.out.println("### Context
Val::"+this.getEngine().getRootContext().get("SipMessage"));
//javax.servlet.sip.SipServlet ss=(SipServlet)
this.getEngine().getRootContext().get("SipMessage");
//log("$$$$$$$$ CONTEXT
"+this.getEngine().getRootContext().toString());
}
// Each method below is the activity corresponding to a state in the
// SCXML document (see class constructor for pointer to the document).
public void reset() {
System.out.println(" In constructor of stop clock ");
System.out.println("RESET ### $$$$$$$$ CONTEXT
"+this.getEngine().getRootContext().toString());
System.out.println("RESET VARS
::"+this.getEngine().getRootContext().getVars());
System.out.println("RESET ### Context
Val::"+this.getEngine().getRootContext().get("SipMessage"));
JexlContext ctx=(JexlContext)
this.getEngine().getRootContext();
System.out.println("RESET ### JEXL Context
::"+ctx.getVars());
//javax.servlet.sip.SipServlet ss=(SipServlet)
this.getEngine().getRootContext().get("SipMessage");
hr = min = sec = fract = dhr = dmin = dsec = dfract = 0;
split = false;
}
public void running() {
System.out.println (" Running");
split = false;
if (timer == null) {
timer = new Timer(true);
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
increment();
}
}, 100, 100);
}
}
public void paused() {
split = true;
}
public void stopped() {
timer.cancel();
timer = null;
}
public String getDisplay() {
String padhr = dhr > 9 ? EMPTY : ZERO;
String padmin = dmin > 9 ? EMPTY : ZERO;
String padsec = dsec > 9 ? EMPTY : ZERO;
return new StringBuffer().append(padhr).append(dhr).append(DELIM).
append(padmin).append(dmin).append(DELIM).append(padsec).
append(dsec).append(DOT).append(dfract).toString();
}
// used by the demonstration (see StopWatchDisplay usecase)
public String getCurrentState() {
Set states = getEngine().getCurrentStatus().getStates();
return ((org.apache.commons.scxml.model.State) states.iterator().
next()).getId();
}
private void increment() {
if (fract < 9) {
fract++;
} else {
fract = 0;
if (sec < 59) {
sec++;
} else {
sec = 0;
if (min < 59) {
min++;
} else {
min = 0;
if (hr < 99) {
hr++;
} else {
hr = 0; //wrap
}
}
}
}
if (!split) {
dhr = hr;
dmin = min;
dsec = sec;
dfract = fract;
}
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package PocAS;
import java.util.Collection;
import java.util.List;
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.Action;
import org.apache.commons.scxml.model.ExternalContent;
import org.apache.commons.scxml.model.ModelException;
/**
* 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();
System.out.println("Hello: Got in Hello constructor...");
}
/**
* Get the name.
*
* @return Returns the name.
*/
public String getName() {
System.out.println("Hello: getName");
return name;
}
/**
* Set the name.
*
* @param name The name to set.
*/
public void setName(String name) {
this.name = name;
System.out.println("Hello: setName");
}
/**
* @inheritDoc
*/
public void execute(final EventDispatcher evtDispatcher,
final ErrorReporter errRep, final SCInstance scInstance,
final Log appLog, final Collection derivedEvents)
throws ModelException, SCXMLExpressionException {
System.out.println("Hello: execute");
if (appLog.isInfoEnabled()) {
appLog.info("Hello " + name);
}
// For derived events payload testing
TriggerEvent event =
new TriggerEvent("helloevent", TriggerEvent.TIME_EVENT, name);
derivedEvents.add(event);
callbacks++;
}
}
Please try to help me .
Thanks & Regards
Saurabh
--
"Successful people make more mistakes because they do more "
Thanks
Saurabh Agarwal
|