summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2014-08-05 15:18:25 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2014-08-05 15:18:25 (GMT)
commit799ca6d265d7a362526d66e7f615f914695b867e (patch)
tree357afa5281dcfe72c7fee3e12c75505eca8dea1a
parent83ef70ebc7527240f56e2e601777a613bce6e47e (diff)
downloaduscxml-799ca6d265d7a362526d66e7f615f914695b867e.zip
uscxml-799ca6d265d7a362526d66e7f615f914695b867e.tar.gz
uscxml-799ca6d265d7a362526d66e7f615f914695b867e.tar.bz2
Catch std::exception before ... and output e.what()
-rw-r--r--src/uscxml/Interpreter.cpp41
-rw-r--r--src/uscxml/Interpreter.h1
-rw-r--r--src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp2
-rw-r--r--src/uscxml/transform/ChartToFSM.cpp57
-rw-r--r--src/uscxml/transform/ChartToFSM.h6
-rw-r--r--src/uscxml/transform/FlatStateIdentifier.h39
-rw-r--r--test/src/test-flat-stateid.cpp4
-rw-r--r--test/src/test-w3c.cpp2
8 files changed, 101 insertions, 51 deletions
diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp
index 7a8b807..b9b5d94 100644
--- a/src/uscxml/Interpreter.cpp
+++ b/src/uscxml/Interpreter.cpp
@@ -23,6 +23,7 @@
#include "uscxml/URL.h"
#include "uscxml/UUID.h"
#include "uscxml/DOMUtils.h"
+#include "uscxml/transform/FlatStateIdentifier.h"
#include "uscxml/transform/ChartToFSM.h" // only for testing
#include "getopt.h"
@@ -371,8 +372,20 @@ Interpreter Interpreter::fromDOM(const Arabica::DOM::Document<std::string>& dom,
tthread::lock_guard<tthread::recursive_mutex> lock(_instanceMutex);
boost::shared_ptr<INTERPRETER_IMPL> interpreterImpl = boost::shared_ptr<INTERPRETER_IMPL>(new INTERPRETER_IMPL);
Interpreter interpreter(interpreterImpl);
+
+ // *copy* the given DOM to get rid of event listeners
+
+ DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation();
+ interpreterImpl->_document = domFactory.createDocument(dom.getNamespaceURI(), "", 0);
+
+ Node<std::string> child = dom.getFirstChild();
+ while (child) {
+ Node<std::string> newNode = interpreterImpl->_document.importNode(child, true);
+ interpreterImpl->_document.appendChild(newNode);
+ child = child.getNextSibling();
+ }
+
interpreterImpl->setNameSpaceInfo(nameSpaceInfo);
- interpreterImpl->_document = dom;
interpreterImpl->setupDOM();
// interpreterImpl->init();
@@ -759,7 +772,6 @@ void InterpreterImpl::setupDOM() {
eventTarget.addEventListener("DOMNodeInserted", _domEventListener, true);
eventTarget.addEventListener("DOMNodeRemoved", _domEventListener, true);
eventTarget.addEventListener("DOMSubtreeModified", _domEventListener, true);
-
_domIsSetup = true;
}
@@ -1262,6 +1274,8 @@ void InterpreterImpl::delayedSend(void* userdata, std::string eventName) {
ioProc.send(sendReq);
} catch(Event e) {
throw e;
+ } catch (const std::exception &e) {
+ LOG(ERROR) << "Exception caught while sending event to ioprocessor " << sendReq.type << ":" << e.what();
} catch(...) {
LOG(ERROR) << "Exception caught while sending event to ioprocessor " << sendReq.type;
}
@@ -1425,11 +1439,15 @@ void InterpreterImpl::invoke(const Arabica::DOM::Element<std::string>& element)
} catch(boost::bad_lexical_cast e) {
LOG(ERROR) << "Exception caught while sending invoke request to invoker " << invokeReq.invokeid << ": " << e.what();
+ } catch (const std::exception &e) {
+ LOG(ERROR) << "Unknown exception caught while sending invoke request to invoker " << invokeReq.invokeid << ": " << e.what();
} catch(...) {
LOG(ERROR) << "Unknown exception caught while sending invoke request to invoker " << invokeReq.invokeid;
}
try {
// _dataModel.assign("_invokers['" + invokeReq.invokeid + "']", invoker.getDataModelVariables());
+ } catch (const std::exception &e) {
+ LOG(ERROR) << "Exception caught while assigning datamodel variables from invoker " << invokeReq.invokeid << ": " << e.what();
} catch(...) {
LOG(ERROR) << "Exception caught while assigning datamodel variables from invoker " << invokeReq.invokeid;
}
@@ -1906,6 +1924,8 @@ void InterpreterImpl::finalizeAndAutoForwardCurrentEvent() {
// Yes do so, see test229!
// if (!boost::equals(_currEvent.getOriginType(), "http://www.w3.org/TR/scxml/#SCXMLEventProcessor"))
invokeIter->second.send(_currEvent);
+ } catch (const std::exception &e) {
+ LOG(ERROR) << "Exception caught while sending event to invoker " << invokeIter->first << ": " << e.what();
} catch(...) {
LOG(ERROR) << "Exception caught while sending event to invoker " << invokeIter->first;
}
@@ -2718,18 +2738,10 @@ bool InterpreterImpl::isInState(const std::string& stateId) {
// extension for flattened SCXML documents
if (_configuration.size() > 0 && HAS_ATTR_CAST(_configuration[0], "id")) {
// all states are encoded in the current statename
- std::string encStateList = ATTR_CAST(_configuration[0], "id");
- size_t startActive = encStateList.find_first_of("-");
- size_t endActive = encStateList.find_first_of(";");
- encStateList = encStateList.substr(startActive, endActive - startActive);
- std::stringstream ss(encStateList);
- std::string unencodedStateId;
- while(std::getline(ss, unencodedStateId, '-')) {
- if (unencodedStateId.length() == 0)
- continue;
- if (iequals(unencodedStateId, stateId)) {
+ FlatStateIdentifier flatId(ATTR_CAST(_configuration[0], "id"));
+ for (std::list<std::string>::const_iterator iter = flatId.getActive().begin(); iter != flatId.getActive().end(); iter++) {
+ if (iequals(stateId, *iter))
return true;
- }
}
}
return false;
@@ -2765,7 +2777,8 @@ void InterpreterImpl::handleDOMEvent(Arabica::DOM::Events::Event<std::string>& e
}
void InterpreterImpl::DOMEventListener::handleEvent(Arabica::DOM::Events::Event<std::string>& event) {
- _interpreter->handleDOMEvent(event);
+ if (_interpreter)
+ _interpreter->handleDOMEvent(event);
}
std::ostream& operator<< (std::ostream& os, const InterpreterState& interpreterState) {
diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h
index c3acc98..66379f9 100644
--- a/src/uscxml/Interpreter.h
+++ b/src/uscxml/Interpreter.h
@@ -443,6 +443,7 @@ protected:
class DOMEventListener : public Arabica::DOM::Events::EventListener<std::string> {
public:
+ DOMEventListener() : _interpreter(NULL) {}
void handleEvent(Arabica::DOM::Events::Event<std::string>& event);
InterpreterImpl* _interpreter;
};
diff --git a/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp
index 00b47f4..9ba3e63 100644
--- a/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp
+++ b/src/uscxml/plugins/ioprocessor/scxml/SCXMLIOProcessor.cpp
@@ -162,6 +162,8 @@ void SCXMLIOProcessor::send(const SendRequest& req) {
} catch(Event e) {
// Is this the right thing to do?
_interpreter->receive(e);
+ } catch (const std::exception &e) {
+ LOG(ERROR) << "Exception caught while sending event to invoker " << invokeId << ": " << e.what();
} catch(...) {
LOG(ERROR) << "Exception caught while sending event to invoker " << invokeId;
}
diff --git a/src/uscxml/transform/ChartToFSM.cpp b/src/uscxml/transform/ChartToFSM.cpp
index 9665b56..073805f 100644
--- a/src/uscxml/transform/ChartToFSM.cpp
+++ b/src/uscxml/transform/ChartToFSM.cpp
@@ -19,6 +19,7 @@
#include "uscxml/transform/ChartToFSM.h"
#include "uscxml/transform/FlatStateIdentifier.h"
+#include "uscxml/Convenience.h"
#include "uscxml/Factory.h"
#include <DOM/io/Stream.hpp>
@@ -202,9 +203,11 @@ InterpreterState FlatteningInterpreter::interpret() {
_currGlobalTransition = NULL;
// very first state
- _start = new GlobalState(_configuration, _alreadyEntered, _historyValue);
+ GlobalState::gIndex = 0;
+ _start = new GlobalState(_configuration, _alreadyEntered, _historyValue, _nsInfo.xmlNSPrefix);
_globalConf[_start->stateId] = _start;
-
+ _globalConf[_start->stateId]->index = GlobalState::gIndex++;
+
NodeSet<std::string> initialTransitions;
// enter initial configuration
@@ -246,13 +249,16 @@ InterpreterState FlatteningInterpreter::interpret() {
#endif
createDocument();
-
+
NodeSet<std::string> elements = InterpreterImpl::filterChildType(Node_base::ELEMENT_NODE, _scxml, true);
uint64_t nrStates = 0;
for (int i = 0; i < elements.size(); i++) {
- Element<std::string> stateElem = Element<std::string>(elements[i]);
- if (isState(stateElem) && !HAS_ATTR(stateElem, "transient"))
+ Element<std::string> elem = Element<std::string>(elements[i]);
+ if (isState(elem) && !HAS_ATTR(elem, "transient"))
nrStates++;
+ if (elem.getLocalName() == "transition" && elem.hasAttribute("id")) {
+ elem.removeAttribute("id");
+ }
}
std::cout << "Actual Complexity: " << nrStates << std::endl;
@@ -442,7 +448,7 @@ void FlatteningInterpreter::explode() {
std::map<std::string, Arabica::XPath::NodeSet<std::string> > historyValue = _historyValue;
// create current state from global configuration
- GlobalState* globalState = new GlobalState(configuration, alreadyEntered, historyValue);
+ GlobalState* globalState = new GlobalState(configuration, alreadyEntered, historyValue, _nsInfo.xmlNSPrefix);
// remember that the last transition lead here
if (_currGlobalTransition) {
@@ -465,10 +471,14 @@ void FlatteningInterpreter::explode() {
delete globalState;
return; // we have already been here
}
+
_globalConf[globalState->stateId] = globalState;
-
+ _globalConf[globalState->stateId]->index = GlobalState::gIndex++;
assert(isLegalConfiguration(configuration));
+ if(_globalConf[globalState->stateId]->isFinal)
+ return; // done in this branch
+
// get all transition elements from states in the current configuration
NodeSet<std::string> allTransitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", configuration);
@@ -673,6 +683,10 @@ NEXT_DEPTH:
}
}
+static bool sortStatesByIndex(const std::pair<std::string,GlobalState*>& s1, const std::pair<std::string,GlobalState*>& s2) {
+ return s1.second->index < s2.second->index;
+}
+
void FlatteningInterpreter::createDocument() {
Element<std::string> _origSCXML = _scxml;
@@ -720,8 +734,12 @@ void FlatteningInterpreter::createDocument() {
_scxml.appendChild(imported);
}
- for (std::map<std::string, GlobalState*>::iterator confIter = _globalConf.begin();
- confIter != _globalConf.end();
+ std::vector<std::pair<std::string,GlobalState*> > sortedStates;
+ sortedStates.insert(sortedStates.begin(), _globalConf.begin(), _globalConf.end());
+ std::sort(sortedStates.begin(), sortedStates.end(), sortStatesByIndex);
+
+ for (std::vector<std::pair<std::string,GlobalState*> >::iterator confIter = sortedStates.begin();
+ confIter != sortedStates.end();
confIter++) {
Node<std::string> state = globalStateToNode(confIter->second);
_scxml.appendChild(state);
@@ -739,6 +757,8 @@ Node<std::string> FlatteningInterpreter::globalStateToNode(GlobalState* globalSt
if (globalState->isFinal)
state.setAttribute("final", "true");
+// state.setAttribute("index", toStr(globalState->index));
+
std::list<GlobalTransition*> transitionList;
for (std::map<std::string, GlobalTransition*>::iterator outIter = globalState->outgoing.begin();
outIter != globalState->outgoing.end();
@@ -985,22 +1005,27 @@ void FlatteningInterpreter::beforeEnteringState(Interpreter interpreter, const A
void FlatteningInterpreter::beforeTakingTransition(Interpreter interpreter, const Arabica::DOM::Element<std::string>& transition, bool moreComing) {
}
-
+int GlobalState::gIndex = 0;
GlobalState::GlobalState(const Arabica::XPath::NodeSet<std::string>& activeStates_,
const Arabica::XPath::NodeSet<std::string>& alreadyEnteredStates_, // we need to remember for binding=late
- const std::map<std::string, Arabica::XPath::NodeSet<std::string> >& historyStates_) {
+ const std::map<std::string, Arabica::XPath::NodeSet<std::string> >& historyStates_,
+ const std::string& xmlNSPrefix) {
// make copies and sort
activeStates = activeStates_;
alreadyEnteredStates = alreadyEnteredStates_;
historyStates = historyStates_;
- isFinal = true; // is set to false if we contain a non-final state
+ isFinal = false;
- // start state is not final
- if (activeStates.size() == 0) {
- isFinal = false;
+ for(int i = 0; i < activeStates.size(); i++) {
+ Arabica::DOM::Element<std::string> state = Arabica::DOM::Element<std::string>(activeStates[i]);
+ Arabica::DOM::Element<std::string> parentElem = (Arabica::DOM::Element<std::string>)state.getParentNode();
+ if(InterpreterImpl::isFinal(state) && iequals(parentElem.getTagName(), xmlNSPrefix + "scxml")) {
+ isFinal = true;
+ break;
+ }
}
-
+
// sort configuration
activeStates.to_document_order();
alreadyEnteredStates.to_document_order();
diff --git a/src/uscxml/transform/ChartToFSM.h b/src/uscxml/transform/ChartToFSM.h
index aeeb058..5ee5c8e 100644
--- a/src/uscxml/transform/ChartToFSM.h
+++ b/src/uscxml/transform/ChartToFSM.h
@@ -38,7 +38,8 @@ public:
GlobalState() {}
GlobalState(const Arabica::XPath::NodeSet<std::string>& activeStates,
const Arabica::XPath::NodeSet<std::string>& alreadyEnteredStates, // we need to remember for binding=late
- const std::map<std::string, Arabica::XPath::NodeSet<std::string> >& historyStates);
+ const std::map<std::string, Arabica::XPath::NodeSet<std::string> >& historyStates,
+ const std::string& xmlNSPrefix);
Arabica::XPath::NodeSet<std::string> activeStates;
Arabica::XPath::NodeSet<std::string> alreadyEnteredStates;
@@ -48,6 +49,9 @@ public:
std::map<std::string, GlobalTransition*> outgoing;
std::string stateId;
+ static int gIndex;
+
+ int index;
bool isFinal;
};
diff --git a/src/uscxml/transform/FlatStateIdentifier.h b/src/uscxml/transform/FlatStateIdentifier.h
index 3a9ee49..61d0f1b 100644
--- a/src/uscxml/transform/FlatStateIdentifier.h
+++ b/src/uscxml/transform/FlatStateIdentifier.h
@@ -142,34 +142,39 @@ protected:
std::stringstream stateIdSS;
std::string seperator;
+
stateIdSS << "active:{";
for (std::list<std::string>::const_iterator actIter = active.begin(); actIter != active.end(); actIter++) {
stateIdSS << seperator << *actIter;
seperator = ",";
}
- stateIdSS << "};";
+ stateIdSS << "}";
- seperator = "";
- stateIdSS << "entered:{";
- for (std::list<std::string>::const_iterator visitIter = visited.begin(); visitIter != visited.end(); visitIter++) {
- stateIdSS << seperator << *visitIter;
- seperator = ",";
+ if (visited.size() > 0) {
+ seperator = "";
+ stateIdSS << ";entered:{";
+ for (std::list<std::string>::const_iterator visitIter = visited.begin(); visitIter != visited.end(); visitIter++) {
+ stateIdSS << seperator << *visitIter;
+ seperator = ",";
+ }
+ stateIdSS << "}";
}
- stateIdSS << "};";
- seperator = "";
- stateIdSS << "history:{";
- for (std::map<std::string, std::list<std::string> >::const_iterator histIter = histories.begin(); histIter != histories.end(); histIter++) {
- stateIdSS << seperator << histIter->first << ":{";
- seperator = ",";
- std::string itemSeperator;
- for (std::list<std::string>::const_iterator histItemIter = histIter->second.begin(); histItemIter != histIter->second.end(); histItemIter++) {
- stateIdSS << itemSeperator << *histItemIter;
- itemSeperator = ",";
+ if (histories.size() > 0) {
+ seperator = "";
+ stateIdSS << ";history:{";
+ for (std::map<std::string, std::list<std::string> >::const_iterator histIter = histories.begin(); histIter != histories.end(); histIter++) {
+ stateIdSS << seperator << histIter->first << ":{";
+ seperator = ",";
+ std::string itemSeperator;
+ for (std::list<std::string>::const_iterator histItemIter = histIter->second.begin(); histItemIter != histIter->second.end(); histItemIter++) {
+ stateIdSS << itemSeperator << *histItemIter;
+ itemSeperator = ",";
+ }
+ stateIdSS << "}";
}
stateIdSS << "}";
}
- stateIdSS << "}";
stateId = stateIdSS.str();
}
diff --git a/test/src/test-flat-stateid.cpp b/test/src/test-flat-stateid.cpp
index 7bc826c..6eb1ed8 100644
--- a/test/src/test-flat-stateid.cpp
+++ b/test/src/test-flat-stateid.cpp
@@ -5,7 +5,7 @@ int main(int argc, char** argv) {
std::list<std::string>::const_iterator listIter;
{
- std::string stateId = "active:{};entered:{};history:{}";
+ std::string stateId = "active:{}";
uscxml::FlatStateIdentifier flat1(stateId);
assert(flat1.getActive().size() == 0);
assert(flat1.getVisited().size() == 0);
@@ -16,7 +16,7 @@ int main(int argc, char** argv) {
}
{
- std::string stateId = "active:{s1};entered:{s1,s2};history:{}";
+ std::string stateId = "active:{s1};entered:{s1,s2}";
uscxml::FlatStateIdentifier flat1(stateId);
assert(flat1.getActive().size() == 1);
assert(flat1.getVisited().size() == 2);
diff --git a/test/src/test-w3c.cpp b/test/src/test-w3c.cpp
index 7eb54a7..6a3294d 100644
--- a/test/src/test-w3c.cpp
+++ b/test/src/test-w3c.cpp
@@ -145,7 +145,7 @@ class W3CStatusMonitor : public uscxml::InterpreterMonitor {
if (config.size() == 1) {
if (withFlattening) {
std::cout << ATTR_CAST(config[0], "id") << std::endl;
- if (boost::starts_with(ATTR_CAST(config[0], "id"), "active-pass")) {
+ if (boost::starts_with(ATTR_CAST(config[0], "id"), "active:{pass")) {
std::cout << "TEST SUCCEEDED" << std::endl;
exit(EXIT_SUCCESS);
}