diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/uscxml/Interpreter.cpp | 50 | ||||
-rw-r--r-- | src/uscxml/Interpreter.h | 9 | ||||
-rw-r--r-- | src/uscxml/debug/DebugSession.cpp | 2 | ||||
-rw-r--r-- | src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp | 4 | ||||
-rw-r--r-- | src/uscxml/transform/ChartToPromela.cpp | 15 |
5 files changed, 55 insertions, 25 deletions
diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index 4dabcb9..cb780df 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -372,7 +372,7 @@ InterpreterImpl::InterpreterImpl() { #endif } -Interpreter Interpreter::fromDOM(const Arabica::DOM::Document<std::string>& dom, const NameSpaceInfo& nameSpaceInfo) { +Interpreter Interpreter::fromDOM(const Arabica::DOM::Document<std::string>& dom, const NameSpaceInfo& nameSpaceInfo, const std::string& sourceURI) { 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); @@ -397,14 +397,14 @@ Interpreter Interpreter::fromDOM(const Arabica::DOM::Document<std::string>& dom, return interpreter; } -Interpreter Interpreter::fromXML(const std::string& xml) { +Interpreter Interpreter::fromXML(const std::string& xml, const std::string& sourceURI) { std::stringstream* ss = new std::stringstream(); (*ss) << xml; // we need an auto_ptr for arabica to assume ownership std::auto_ptr<std::istream> ssPtr(ss); Arabica::SAX::InputSource<std::string> inputSource; inputSource.setByteStream(ssPtr); - return fromInputSource(inputSource); + return fromInputSource(inputSource, sourceURI); } @@ -421,7 +421,7 @@ Interpreter Interpreter::fromURI(const std::string& uri) { if (iequals(absUrl.scheme(), "file")) { Arabica::SAX::InputSource<std::string> inputSource; inputSource.setSystemId(absUrl.asString()); - interpreter = fromInputSource(inputSource); + interpreter = fromInputSource(inputSource, absUrl); } else { // use curl for everything !file - even for http as arabica won't follow redirects std::stringstream ss; @@ -429,20 +429,17 @@ Interpreter Interpreter::fromURI(const std::string& uri) { if (absUrl.downloadFailed()) { ERROR_COMMUNICATION_THROW("Downloading SCXML document from '" + absUrl.asString() + "' failed"); } - interpreter = fromXML(ss.str()); + interpreter = fromXML(ss.str(), absUrl); } // try to establish URI root for relative src attributes in document - if (interpreter) { - interpreter._impl->_baseURI = URL::asBaseURL(absUrl); - interpreter._impl->_sourceURI = absUrl; - } else { + if (!interpreter) { ERROR_PLATFORM_THROW("Cannot create interpreter from URI '" + absUrl.asString() + "'"); } return interpreter; } -Interpreter Interpreter::fromInputSource(Arabica::SAX::InputSource<std::string>& source) { +Interpreter Interpreter::fromInputSource(Arabica::SAX::InputSource<std::string>& source, const std::string& sourceUri) { tthread::lock_guard<tthread::recursive_mutex> lock(_instanceMutex); // remove old instances @@ -463,6 +460,9 @@ Interpreter Interpreter::fromInputSource(Arabica::SAX::InputSource<std::string>& if (parser.parse(source) && parser.getDocument() && parser.getDocument().hasChildNodes()) { interpreterImpl->setNameSpaceInfo(parser.nameSpace); interpreterImpl->_document = parser.getDocument(); + interpreterImpl->_baseURI = URL::asBaseURL(sourceUri); + interpreterImpl->_sourceURI = sourceUri; + interpreterImpl->setupDOM(); } else { if (parser.errorsReported()) { @@ -1224,6 +1224,8 @@ void InterpreterImpl::setupDOM() { ERROR_PLATFORM_THROW("Interpreter has no DOM"); } + resolveXIncludes(); + // find scxml element if (!_scxml) { NodeList<std::string> scxmls; @@ -1284,6 +1286,34 @@ void InterpreterImpl::setupDOM() { _domIsSetup = true; } +void InterpreterImpl::resolveXIncludes() { + std::string xIncludeNS = _nsInfo.getXMLPrefixForNS("http://www.w3.org/2001/XInclude"); + if (xIncludeNS.size() > 0) { + Arabica::XPath::NodeSet<std::string> xincludes = _xpath.evaluate("//" + xIncludeNS + "include", _document.getDocumentElement()).asNodeSet(); + for (int i = 0; i < xincludes.size(); i++) { + if (HAS_ATTR_CAST(xincludes[i], "href")) { + URL src(ATTR_CAST(xincludes[i], "href")); + if (!src.isAbsolute()) { + if (!src.toAbsolute(_baseURI)) { + LOG(ERROR) << "Cannot resolve relative URL '" << ATTR_CAST(xincludes[i], "href") << "' to absolute URL via base URL '" << _baseURI << "'"; + continue; + } + } + NameSpacingParser xiParser = NameSpacingParser::fromXML(src.getInContent()); + if (xiParser.errorsReported()) { + ERROR_PLATFORM_THROW(xiParser.errors()); + } else { + // import DOM + Node<std::string> imported = _document.importNode(xiParser.getDocument().getDocumentElement(), true); + xincludes[i].getParentNode().insertBefore(imported, xincludes[i]); + xincludes[i].getParentNode().removeChild(xincludes[i]); + } + } + } + } + +} + void InterpreterImpl::init() { // make sure we have a factory if none was set before if (_factory == NULL) diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index d6da7bd..d962083 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -458,6 +458,7 @@ protected: InterpreterImpl(); void init(); void setupDOM(); + void resolveXIncludes(); virtual void setupIOProcessors(); std::list<InterpreterIssue> validate(); @@ -583,8 +584,10 @@ protected: class USCXML_API Interpreter { public: static Interpreter fromDOM(const Arabica::DOM::Document<std::string>& dom, - const NameSpaceInfo& nameSpaceInfo); - static Interpreter fromXML(const std::string& xml); + const NameSpaceInfo& nameSpaceInfo, + const std::string& sourceURI); + static Interpreter fromXML(const std::string& xml, + const std::string& sourceURI); static Interpreter fromURI(const std::string& uri); static Interpreter fromClone(const Interpreter& other); @@ -815,7 +818,7 @@ protected: return _impl->setInvokeRequest(req); } - static Interpreter fromInputSource(Arabica::SAX::InputSource<std::string>& source); + static Interpreter fromInputSource(Arabica::SAX::InputSource<std::string>& source, const std::string& sourceUri); boost::shared_ptr<InterpreterImpl> _impl; static std::map<std::string, boost::weak_ptr<InterpreterImpl> > _instances; diff --git a/src/uscxml/debug/DebugSession.cpp b/src/uscxml/debug/DebugSession.cpp index c73f53e..d81be51 100644 --- a/src/uscxml/debug/DebugSession.cpp +++ b/src/uscxml/debug/DebugSession.cpp @@ -106,7 +106,7 @@ Data DebugSession::debugPrepare(const Data& data) { _isAttached = false; if (data.hasKey("xml")) { - _interpreter = Interpreter::fromXML(data.at("xml").atom); + _interpreter = Interpreter::fromXML(data.at("xml").atom, ""); } else if (data.hasKey("url")) { _interpreter = Interpreter::fromURI(data.at("url").atom); } else { diff --git a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp index 5a447c4..84e5520 100644 --- a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp +++ b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp @@ -82,9 +82,9 @@ void USCXMLInvoker::invoke(const InvokeRequest& req) { Arabica::DOM::Node<std::string> newNode = dom.importNode(req.dom, true); dom.appendChild(newNode); // TODO: where do we get the namespace from? - _invokedInterpreter = Interpreter::fromDOM(dom, std::map<std::string, std::string>()); + _invokedInterpreter = Interpreter::fromDOM(dom, _interpreter->getNameSpaceInfo(), _interpreter->getSourceURI()); } else if (req.content.size() > 0) { - _invokedInterpreter = Interpreter::fromXML(req.content); + _invokedInterpreter = Interpreter::fromXML(req.content, _interpreter->getSourceURI()); } else { LOG(ERROR) << "Cannot invoke nested SCXML interpreter, neither src attribute nor content nor DOM is given"; } diff --git a/src/uscxml/transform/ChartToPromela.cpp b/src/uscxml/transform/ChartToPromela.cpp index 9d297ad..7676a37 100644 --- a/src/uscxml/transform/ChartToPromela.cpp +++ b/src/uscxml/transform/ChartToPromela.cpp @@ -2041,6 +2041,7 @@ void ChartToPromela::writeDeclarations(std::ostream& stream) { if (_analyzer->getTypes().types.find("_ioprocessors") != _analyzer->getTypes().types.end()) { stream << "hidden _ioprocessors_t " << _prefix << "_ioprocessors;" << std::endl; + _varInitializers.push_front("_ioprocessors.scxml.location = " + (_invokerid.size() > 0 ? _analyzer->macroForLiteral(_invokerid) : "1") + ";"); } if (_prefix.size() == 0 || _prefix == "MAIN_") { @@ -2110,21 +2111,17 @@ void ChartToPromela::writeDeclarations(std::ostream& stream) { type = type.substr(0, bracketPos); } std::string decl = type + " " + _prefix + identifier + arrSize; + stream << decl << ";" << std::endl; if (arrSize.length() > 0) { - stream << decl << ";" << std::endl; _varInitializers.push_back(value); } else { - stream << decl; if (expression.length() > 0) { // id and expr given - stream << " = " << ADAPT_SRC(boost::trim_copy(expression)) << ";" << std::endl; + _varInitializers.push_back(identifier + " = " + boost::trim_copy(expression) + ";"); } else if (value.length() > 0) { // id and text content given - stream << " = " << ADAPT_SRC(value) << ";" << std::endl; - } else { - // only id given - stream << ";" << std::endl; + _varInitializers.push_back(identifier + " = " + value + ";"); } } } else if (value.length() > 0) { @@ -2625,7 +2622,7 @@ void ChartToPromela::writeMain(std::ostream& stream) { if (_varInitializers.size() > 0) { std::list<std::string>::iterator initIter = _varInitializers.begin(); while(initIter != _varInitializers.end()) { - stream << ADAPT_SRC(beautifyIndentation(*initIter)); + stream << ADAPT_SRC(beautifyIndentation(*initIter)) << std::endl; initIter++; } stream << std::endl; @@ -2717,7 +2714,7 @@ void ChartToPromela::initNodes() { Node<std::string> importRoot = nestedDoc.importNode(nestedRoot[0], true); nestedDoc.appendChild(importRoot); - nested = Interpreter::fromDOM(nestedDoc, _nsInfo); + nested = Interpreter::fromDOM(nestedDoc, _nsInfo, _sourceURI); } // std::cout << invokes[i] << std::endl; |