From 01e7e16d34b23b1198455809860abe4e43d9606a Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Sun, 14 Apr 2013 10:43:05 +0200 Subject: Apps working again --- CMakeLists.txt | 20 +-- apps/samples/server-push/server-push.scxml | 14 +- apps/samples/vrml/vrml-server.scxml | 35 +++-- contrib/ctest/run-tests.vbs | 3 +- src/uscxml/Factory.cpp | 4 +- src/uscxml/Interpreter.cpp | 3 +- src/uscxml/interpreter/InterpreterDraft6.cpp | 12 +- .../plugins/element/postpone/PostponeElement.cpp | 2 +- .../plugins/element/respond/RespondElement.cpp | 164 +++++++++++++++++++++ .../plugins/element/respond/RespondElement.h | 42 ++++++ .../plugins/element/response/ResponseElement.cpp | 164 --------------------- .../plugins/element/response/ResponseElement.h | 42 ------ test/src/test-url.cpp | 6 +- 13 files changed, 256 insertions(+), 255 deletions(-) create mode 100644 src/uscxml/plugins/element/respond/RespondElement.cpp create mode 100644 src/uscxml/plugins/element/respond/RespondElement.h delete mode 100644 src/uscxml/plugins/element/response/ResponseElement.cpp delete mode 100644 src/uscxml/plugins/element/response/ResponseElement.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 05ecd83..fea1b5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -538,21 +538,21 @@ else() endif() -# Response element +# Respond element -file(GLOB_RECURSE RESPONSE_ELEMENT - src/uscxml/plugins/element/response/*.cpp - src/uscxml/plugins/element/response/*.h +file(GLOB_RECURSE RESPOND_ELEMENT + src/uscxml/plugins/element/respond/*.cpp + src/uscxml/plugins/element/respond/*.h ) -source_group("Element\\response" FILES ${RESPONSE_ELEMENT}) +source_group("Element\\respond" FILES ${RESPOND_ELEMENT}) if (BUILD_AS_PLUGINS) add_library( - element_response SHARED - ${RESPONSE_ELEMENT}) - target_link_libraries(element_response uscxml) - set_target_properties(element_response PROPERTIES FOLDER "Plugin Element") + element_respond SHARED + ${RESPOND_ELEMENT}) + target_link_libraries(element_respond uscxml) + set_target_properties(element_respond PROPERTIES FOLDER "Plugin Element") else() - list (APPEND USCXML_FILES ${RESPONSE_ELEMENT}) + list (APPEND USCXML_FILES ${RESPOND_ELEMENT}) endif() diff --git a/apps/samples/server-push/server-push.scxml b/apps/samples/server-push/server-push.scxml index 4193560..a9d231e 100644 --- a/apps/samples/server-push/server-push.scxml +++ b/apps/samples/server-push/server-push.scxml @@ -17,27 +17,27 @@ - +
- + - + This is awesome! - - + + - + @@ -74,7 +74,7 @@ ]]> - + diff --git a/apps/samples/vrml/vrml-server.scxml b/apps/samples/vrml/vrml-server.scxml index 0d6517c..6f376e8 100644 --- a/apps/samples/vrml/vrml-server.scxml +++ b/apps/samples/vrml/vrml-server.scxml @@ -255,6 +255,9 @@ + @@ -275,19 +278,19 @@ - +
- + - +
- + - +
- + - +
- + - +
- + - +
- + - +
- + diff --git a/contrib/ctest/run-tests.vbs b/contrib/ctest/run-tests.vbs index 66e187b..03e2774 100644 --- a/contrib/ctest/run-tests.vbs +++ b/contrib/ctest/run-tests.vbs @@ -79,10 +79,9 @@ if (CTEST_SUBMIT_TYPE = "Continuous") Then End If shell.CurrentDirectory = TEST_DIR -Set exec = shell.Exec("CMD /S /C ctest -VV --timeout 100 -S " + TESTFILE + " 2>&1") +Set exec = shell.Exec("CMD /S /K ctest -VV --timeout 100 -S " + TESTFILE + " 2>&1") Do While exec.Status = 0 WScript.Sleep 10 WScript.StdOut.Write(exec.StdOut.ReadLine() & vbCRLF) ' WScript.StdErr.Write(exec.StdErr.ReadLine()) Loop -WScript.Sleep 1000000 \ No newline at end of file diff --git a/src/uscxml/Factory.cpp b/src/uscxml/Factory.cpp index c74196a..76da139 100644 --- a/src/uscxml/Factory.cpp +++ b/src/uscxml/Factory.cpp @@ -52,7 +52,7 @@ # include "uscxml/plugins/element/fetch/FetchElement.h" -# include "uscxml/plugins/element/response/ResponseElement.h" +# include "uscxml/plugins/element/respond/RespondElement.h" # include "uscxml/plugins/element/postpone/PostponeElement.h" @@ -194,7 +194,7 @@ Factory::Factory() { registerExecutableContent(element); } { - ResponseElement* element = new ResponseElement(); + RespondElement* element = new RespondElement(); registerExecutableContent(element); } { diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index 27fd10b..de2b8b5 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -1191,7 +1191,8 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node& cont if (_executableContent.find(content) == _executableContent.end()) { execContent = Factory::createExecutableContent(content.getLocalName(), content.getNamespaceURI(), this); if (!execContent) { - LOG(ERROR) << "No custom executable content known for " << content.getLocalName() << " in " << content.getNamespaceURI(); + LOG(ERROR) << "No custom executable content known for '" + << content.getLocalName() << "' in namespace '" << content.getNamespaceURI() << "'"; return; } _executableContent[content] = execContent; diff --git a/src/uscxml/interpreter/InterpreterDraft6.cpp b/src/uscxml/interpreter/InterpreterDraft6.cpp index d3019d9..ef40362 100644 --- a/src/uscxml/interpreter/InterpreterDraft6.cpp +++ b/src/uscxml/interpreter/InterpreterDraft6.cpp @@ -379,14 +379,12 @@ bool InterpreterDraft6::isEnabledTransition(const Node& transition, std::vector eventNames = tokenizeIdRefs(eventName); - if (eventNames.size() > 0 && hasConditionMatch(transition)) { - std::vector::iterator eventIter = eventNames.begin(); - while(eventIter != eventNames.end()) { - if(nameMatch(*eventIter, event)) { - return true; - } - eventIter++; + std::vector::iterator eventIter = eventNames.begin(); + while(eventIter != eventNames.end()) { + if(nameMatch(*eventIter, event) && hasConditionMatch(transition)) { + return true; } + eventIter++; } return false; } diff --git a/src/uscxml/plugins/element/postpone/PostponeElement.cpp b/src/uscxml/plugins/element/postpone/PostponeElement.cpp index 54f2499..3c1d1b8 100644 --- a/src/uscxml/plugins/element/postpone/PostponeElement.cpp +++ b/src/uscxml/plugins/element/postpone/PostponeElement.cpp @@ -112,7 +112,7 @@ void PostponeElement::Resubmitter::onStableConfiguration(Interpreter interpreter // LOG(INFO) << " -> is TRUE"; eventIter->event.name += ".postponed"; interpreter.receive(eventIter->event, true); - _postponedEvents.erase(eventIter); + _postponedEvents.erase(eventIter++); dispatched = true; } // LOG(INFO) << " -> is FALSE"; diff --git a/src/uscxml/plugins/element/respond/RespondElement.cpp b/src/uscxml/plugins/element/respond/RespondElement.cpp new file mode 100644 index 0000000..3c47b83 --- /dev/null +++ b/src/uscxml/plugins/element/respond/RespondElement.cpp @@ -0,0 +1,164 @@ +#include "RespondElement.h" +#include "uscxml/plugins/invoker/http/HTTPServletInvoker.h" +#include + +#ifdef BUILD_AS_PLUGINS +#include +#endif + +namespace uscxml { + +#ifdef BUILD_AS_PLUGINS +PLUMA_CONNECTOR +bool connect(pluma::Host& host) { + host.add( new RespondElementProvider() ); + return true; +} +#endif + +boost::shared_ptr RespondElement::create(InterpreterImpl* interpreter) { + boost::shared_ptr invoker = boost::shared_ptr(new RespondElement()); + invoker->_interpreter = interpreter; + return invoker; +} + +void RespondElement::enterElement(const Arabica::DOM::Node& node) { + // try to get the request id + if (!HAS_ATTR(node, "to")) { + LOG(ERROR) << "Respond element requires to attribute"; + return; + } + if (HAS_ATTR(node, "to") && !_interpreter->getDataModel()) { + LOG(ERROR) << "Respond element with to requires datamodel"; + return; + } + std::string requestId = _interpreter->getDataModel().evalAsString(ATTR(node, "to")); + + // try to get the request object + InterpreterServlet* servlet = _interpreter->getHTTPServlet(); + tthread::lock_guard lock(servlet->getMutex()); + + if (servlet->getRequests().find(requestId) == servlet->getRequests().end()) { + LOG(ERROR) << "No matching HTTP request for respond element"; + return; + } + + assert(servlet->getRequests().find(requestId) != servlet->getRequests().end()); + HTTPServer::Request httpReq = servlet->getRequests()[requestId]; + assert(httpReq.curlReq != NULL); + HTTPServer::Reply httpReply(httpReq); + servlet->getRequests().erase(requestId); + + // get the status or default to 200 + std::string statusStr = (HAS_ATTR(node, "status") ? ATTR(node, "status") : "200"); + if (!isNumeric(statusStr.c_str(), 10)) { + LOG(ERROR) << "Respond element with non-numeric status " << statusStr; + return; + } + httpReply.status = strTo(statusStr);; + + // extract the content + Arabica::XPath::NodeSet contents = Interpreter::filterChildElements(_interpreter->getXMLPrefixForNS(getNamespace()) + "content", node); + if (contents.size() > 0) { + if (HAS_ATTR(contents[0], "expr")) { // -- content is evaluated string from datamodel ------ + if (_interpreter->getDataModel()) { + try { + std::string contentValue = _interpreter->getDataModel().evalAsString(ATTR(contents[0], "expr")); + httpReply.content = contentValue; + } catch (Event e) { + LOG(ERROR) << "Syntax error with expr in content child of Respond element:" << std::endl << e << std::endl; + return; + } + } else { + LOG(ERROR) << "content element has expr attribute but no datamodel is specified."; + return; + } + } else if (HAS_ATTR(contents[0], "file") || HAS_ATTR(contents[0], "fileexpr")) { // -- content is from file ------ + URL file; + if (HAS_ATTR(contents[0], "fileexpr")) { + if (_interpreter->getDataModel()) { + try { + file = "file://" + _interpreter->getDataModel().evalAsString(ATTR(contents[0], "fileexpr")); + } catch (Event e) { + LOG(ERROR) << "Syntax error with fileexpr in content child of Respond element:" << std::endl << e << std::endl; + return; + } + } + } else { + file = "file://" + ATTR(contents[0], "fileexpr"); + } + if (file) { + httpReply.content = file.getInContent(); + size_t lastDot; + if ((lastDot = file.path().find_last_of(".")) != std::string::npos) { + std::string extension = file.path().substr(lastDot + 1); + std::string mimeType = HTTPServer::mimeTypeForExtension(extension); + if (mimeType.length() > 0) { + httpReply.headers["Content-Type"] = mimeType; + } + } + } + } else if (contents[0].hasChildNodes()) { // -- content embedded as child nodes ------ + httpReply.content = contents[0].getFirstChild().getNodeValue(); + } else { + LOG(ERROR) << "content element does not specify any content."; + return; + } + } + + // process headers + Arabica::XPath::NodeSet headers = Interpreter::filterChildElements(_interpreter->getXMLPrefixForNS(getNamespace()) + "header", node); + for (int i = 0; i < headers.size(); i++) { + std::string name; + if (HAS_ATTR(headers[i], "name")) { + name = ATTR(headers[i], "name"); + } else if(HAS_ATTR(headers[i], "nameexpr")) { + if (_interpreter->getDataModel()) { + try { + name = _interpreter->getDataModel().evalAsString(ATTR(headers[i], "nameexpr")); + } catch (Event e) { + LOG(ERROR) << "Syntax error with nameexpr in header child of Respond element:" << std::endl << e << std::endl; + return; + } + } else { + LOG(ERROR) << "header element has nameexpr attribute but no datamodel is specified."; + return; + } + } else { + LOG(ERROR) << "header element has no name or nameexpr attribute."; + return; + } + + std::string value; + if (HAS_ATTR(headers[i], "value")) { + value = ATTR(headers[i], "value"); + } else if(HAS_ATTR(headers[i], "expr")) { + if (_interpreter->getDataModel()) { + try { + value = _interpreter->getDataModel().evalAsString(ATTR(headers[i], "expr")); + } catch (Event e) { + LOG(ERROR) << "Syntax error with expr in header child of Respond element:" << std::endl << e << std::endl; + return; + } + } else { + LOG(ERROR) << "header element has expr attribute but no datamodel is specified."; + return; + } + } else { + LOG(ERROR) << "header element has no value or expr attribute."; + return; + } + + httpReply.headers[name] = value; + } + + // send the reply + HTTPServer::reply(httpReply); + servlet->getRequests().erase(requestId); +} + +void RespondElement::exitElement(const Arabica::DOM::Node& node) { + +} + +} \ No newline at end of file diff --git a/src/uscxml/plugins/element/respond/RespondElement.h b/src/uscxml/plugins/element/respond/RespondElement.h new file mode 100644 index 0000000..c53d60a --- /dev/null +++ b/src/uscxml/plugins/element/respond/RespondElement.h @@ -0,0 +1,42 @@ +#ifndef RESPONDELEMENT_H_I11KQ39Q +#define RESPONDELEMENT_H_I11KQ39Q + +#include + +#ifdef BUILD_AS_PLUGINS +#include "uscxml/plugins/Plugins.h" +#endif + +namespace uscxml { + +class RespondElement : public ExecutableContentImpl { +public: + RespondElement() {} + virtual ~RespondElement() {} + boost::shared_ptr create(InterpreterImpl* interpreter); + + std::string getLocalName() { + return "respond"; + } + + std::string getNamespace() { + return "http://www.w3.org/2005/07/scxml"; + } + + bool processChildren() { + return false; + } + + void enterElement(const Arabica::DOM::Node& node); + void exitElement(const Arabica::DOM::Node& node); + +}; + +#ifdef BUILD_AS_PLUGINS +PLUMA_INHERIT_PROVIDER(RespondElement, ExecutableContentImpl); +#endif + +} + + +#endif /* end of include guard: RESPONDELEMENT_H_I11KQ39Q */ diff --git a/src/uscxml/plugins/element/response/ResponseElement.cpp b/src/uscxml/plugins/element/response/ResponseElement.cpp deleted file mode 100644 index 675bc1e..0000000 --- a/src/uscxml/plugins/element/response/ResponseElement.cpp +++ /dev/null @@ -1,164 +0,0 @@ -#include "ResponseElement.h" -#include "uscxml/plugins/invoker/http/HTTPServletInvoker.h" -#include - -#ifdef BUILD_AS_PLUGINS -#include -#endif - -namespace uscxml { - -#ifdef BUILD_AS_PLUGINS -PLUMA_CONNECTOR -bool connect(pluma::Host& host) { - host.add( new ResponseElementProvider() ); - return true; -} -#endif - -boost::shared_ptr ResponseElement::create(InterpreterImpl* interpreter) { - boost::shared_ptr invoker = boost::shared_ptr(new ResponseElement()); - invoker->_interpreter = interpreter; - return invoker; -} - -void ResponseElement::enterElement(const Arabica::DOM::Node& node) { - // try to get the request id - if (!HAS_ATTR(node, "request") && !HAS_ATTR(node, "requestexpr")) { - LOG(ERROR) << "Response element requires request or requestexpr"; - return; - } - if (HAS_ATTR(node, "requestexpr") && !_interpreter->getDataModel()) { - LOG(ERROR) << "Response element with requestexpr requires datamodel"; - return; - } - std::string requestId = (HAS_ATTR(node, "request") ? ATTR(node, "request") : _interpreter->getDataModel().evalAsString(ATTR(node, "requestexpr"))); - - // try to get the request object - InterpreterServlet* servlet = _interpreter->getHTTPServlet(); - tthread::lock_guard lock(servlet->getMutex()); - - if (servlet->getRequests().find(requestId) == servlet->getRequests().end()) { - LOG(ERROR) << "No matching HTTP request for response element"; - return; - } - - assert(servlet->getRequests().find(requestId) != servlet->getRequests().end()); - HTTPServer::Request httpReq = servlet->getRequests()[requestId]; - assert(httpReq.curlReq != NULL); - HTTPServer::Reply httpReply(httpReq); - servlet->getRequests().erase(requestId); - - // get the status or default to 200 - std::string statusStr = (HAS_ATTR(node, "status") ? ATTR(node, "status") : "200"); - if (!isNumeric(statusStr.c_str(), 10)) { - LOG(ERROR) << "Response element with non-numeric status " << statusStr; - return; - } - httpReply.status = strTo(statusStr);; - - // extract the content - Arabica::XPath::NodeSet contents = Interpreter::filterChildElements(_interpreter->getXMLPrefixForNS(getNamespace()) + "content", node); - if (contents.size() > 0) { - if (HAS_ATTR(contents[0], "expr")) { // -- content is evaluated string from datamodel ------ - if (_interpreter->getDataModel()) { - try { - std::string contentValue = _interpreter->getDataModel().evalAsString(ATTR(contents[0], "expr")); - httpReply.content = contentValue; - } catch (Event e) { - LOG(ERROR) << "Syntax error with expr in content child of response element:" << std::endl << e << std::endl; - return; - } - } else { - LOG(ERROR) << "content element has expr attribute but no datamodel is specified."; - return; - } - } else if (HAS_ATTR(contents[0], "file") || HAS_ATTR(contents[0], "fileexpr")) { // -- content is from file ------ - URL file; - if (HAS_ATTR(contents[0], "fileexpr")) { - if (_interpreter->getDataModel()) { - try { - file = "file://" + _interpreter->getDataModel().evalAsString(ATTR(contents[0], "fileexpr")); - } catch (Event e) { - LOG(ERROR) << "Syntax error with fileexpr in content child of response element:" << std::endl << e << std::endl; - return; - } - } - } else { - file = "file://" + ATTR(contents[0], "fileexpr"); - } - if (file) { - httpReply.content = file.getInContent(); - size_t lastDot; - if ((lastDot = file.path().find_last_of(".")) != std::string::npos) { - std::string extension = file.path().substr(lastDot + 1); - std::string mimeType = HTTPServer::mimeTypeForExtension(extension); - if (mimeType.length() > 0) { - httpReply.headers["Content-Type"] = mimeType; - } - } - } - } else if (contents[0].hasChildNodes()) { // -- content embedded as child nodes ------ - httpReply.content = contents[0].getFirstChild().getNodeValue(); - } else { - LOG(ERROR) << "content element does not specify any content."; - return; - } - } - - // process headers - Arabica::XPath::NodeSet headers = Interpreter::filterChildElements(_interpreter->getXMLPrefixForNS(getNamespace()) + "header", node); - for (int i = 0; i < headers.size(); i++) { - std::string name; - if (HAS_ATTR(headers[i], "name")) { - name = ATTR(headers[i], "name"); - } else if(HAS_ATTR(headers[i], "nameexpr")) { - if (_interpreter->getDataModel()) { - try { - name = _interpreter->getDataModel().evalAsString(ATTR(headers[i], "nameexpr")); - } catch (Event e) { - LOG(ERROR) << "Syntax error with nameexpr in header child of response element:" << std::endl << e << std::endl; - return; - } - } else { - LOG(ERROR) << "header element has nameexpr attribute but no datamodel is specified."; - return; - } - } else { - LOG(ERROR) << "header element has no name or nameexpr attribute."; - return; - } - - std::string value; - if (HAS_ATTR(headers[i], "value")) { - value = ATTR(headers[i], "value"); - } else if(HAS_ATTR(headers[i], "expr")) { - if (_interpreter->getDataModel()) { - try { - value = _interpreter->getDataModel().evalAsString(ATTR(headers[i], "expr")); - } catch (Event e) { - LOG(ERROR) << "Syntax error with expr in header child of response element:" << std::endl << e << std::endl; - return; - } - } else { - LOG(ERROR) << "header element has expr attribute but no datamodel is specified."; - return; - } - } else { - LOG(ERROR) << "header element has no value or expr attribute."; - return; - } - - httpReply.headers[name] = value; - } - - // send the reply - HTTPServer::reply(httpReply); - servlet->getRequests().erase(requestId); -} - -void ResponseElement::exitElement(const Arabica::DOM::Node& node) { - -} - -} \ No newline at end of file diff --git a/src/uscxml/plugins/element/response/ResponseElement.h b/src/uscxml/plugins/element/response/ResponseElement.h deleted file mode 100644 index 333dd98..0000000 --- a/src/uscxml/plugins/element/response/ResponseElement.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef RESPONSEELEMENT_H_I11KQ39Q -#define RESPONSEELEMENT_H_I11KQ39Q - -#include - -#ifdef BUILD_AS_PLUGINS -#include "uscxml/plugins/Plugins.h" -#endif - -namespace uscxml { - -class ResponseElement : public ExecutableContentImpl { -public: - ResponseElement() {} - virtual ~ResponseElement() {} - boost::shared_ptr create(InterpreterImpl* interpreter); - - std::string getLocalName() { - return "response"; - } - - std::string getNamespace() { - return "http://www.w3.org/2005/07/scxml"; - } - - bool processChildren() { - return false; - } - - void enterElement(const Arabica::DOM::Node& node); - void exitElement(const Arabica::DOM::Node& node); - -}; - -#ifdef BUILD_AS_PLUGINS -PLUMA_INHERIT_PROVIDER(ResponseElement, ExecutableContentImpl); -#endif - -} - - -#endif /* end of include guard: RESPONSEELEMENT_H_I11KQ39Q */ diff --git a/test/src/test-url.cpp b/test/src/test-url.cpp index 5e8ea02..86fcb9f 100644 --- a/test/src/test-url.cpp +++ b/test/src/test-url.cpp @@ -29,9 +29,9 @@ public: int main(int argc, char** argv) { { - Interpreter interpreter = Interpreter::fromURI("https://raw.github.com/tklab-tud/uscxml/master/test/samples/uscxml/test-execution.scxml"); - assert(interpreter); - interpreter.interpret(); +// Interpreter interpreter = Interpreter::fromURI("https://raw.github.com/tklab-tud/uscxml/master/test/samples/uscxml/test-execution.scxml"); +// assert(interpreter); +// interpreter.interpret(); } { -- cgit v0.12