// setup / fetch the documents initial transitions NodeSet<std::string> InterpreterDraft6::getDocumentInitialTransitions() { NodeSet<std::string> initialTransitions; if (_userDefinedStartConfiguration.size() > 0) { // we emulate entering a given configuration by creating a pseudo deep history Element<std::string> initHistory = _document.createElementNS(_nsInfo.nsURL, "history"); _nsInfo.setPrefix(initHistory); initHistory.setAttribute("id", UUID::getUUID()); initHistory.setAttribute("type", "deep"); _scxml.insertBefore(initHistory, _scxml.getFirstChild()); std::string histId = ATTR(initHistory, "id"); NodeSet<std::string> histStates; for (int i = 0; i < _userDefinedStartConfiguration.size(); i++) { histStates.push_back(getState(_userDefinedStartConfiguration[i])); } _historyValue[histId] = histStates; Element<std::string> initialElem = _document.createElementNS(_nsInfo.nsURL, "initial"); _nsInfo.setPrefix(initialElem); initialElem.setAttribute("generated", "true"); Element<std::string> transitionElem = _document.createElementNS(_nsInfo.nsURL, "transition"); _nsInfo.setPrefix(transitionElem); transitionElem.setAttribute("target", histId); initialElem.appendChild(transitionElem); _scxml.appendChild(initialElem); initialTransitions.push_back(transitionElem); } else { // try to get initial transition from initial element initialTransitions = _xpath.evaluate("/" + _nsInfo.xpathPrefix + "initial/" + _nsInfo.xpathPrefix + "transition", _scxml).asNodeSet(); if (initialTransitions.size() == 0) { Arabica::XPath::NodeSet<std::string> initialStates; // fetch per draft initialStates = getInitialStates(); assert(initialStates.size() > 0); for (int i = 0; i < initialStates.size(); i++) { Element<std::string> initialElem = _document.createElementNS(_nsInfo.nsURL, "initial"); _nsInfo.setPrefix(initialElem); initialElem.setAttribute("generated", "true"); Element<std::string> transitionElem = _document.createElementNS(_nsInfo.nsURL, "transition"); _nsInfo.setPrefix(transitionElem); transitionElem.setAttribute("target", ATTR(initialStates[i], "id")); initialElem.appendChild(transitionElem); _scxml.appendChild(initialElem); initialTransitions.push_back(transitionElem); } } } return initialTransitions; }
Arabica::XPath::NodeSet<std::string> InterpreterDraft6::selectTransitions(const std::string& event) { Arabica::XPath::NodeSet<std::string> enabledTransitions; NodeSet<std::string> states; for (unsigned int i = 0; i < _configuration.size(); i++) { if (isAtomic(_configuration[i])) states.push_back(_configuration[i]); } states.to_document_order(); #if 0 std::cout << "Atomic states: " << std::endl; for (int i = 0; i < states.size(); i++) { std::cout << states[i] << std::endl << "----" << std::endl; } std::cout << std::endl; #endif unsigned int index = 0; while(states.size() > index) { bool foundTransition = false; NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", states[index]); for (unsigned int k = 0; k < transitions.size(); k++) { if (isEnabledTransition(transitions[k], event)) { enabledTransitions.push_back(transitions[k]); foundTransition = true; goto LOOP; } } if (!foundTransition) { Node<std::string> parent = states[index].getParentNode(); if (parent) { states.push_back(parent); } } LOOP: index++; } enabledTransitions = filterPreempted(enabledTransitions); #if 0 std::cout << "Enabled transitions: " << std::endl; for (int i = 0; i < enabledTransitions.size(); i++) { std::cout << DOMUtils::xPathForNode(enabledTransitions[i]) << std::endl; } std::cout << std::endl; #endif return enabledTransitions; }
void XPathDataModel::init(const Element<std::string>& dataElem, const Node<std::string>& node, const std::string& content) { std::string location; if (HAS_ATTR(dataElem, "id")) { location = ATTR(dataElem, "id"); } else if (HAS_ATTR(dataElem, "location")) { location = ATTR(dataElem, "location"); } NodeSet<std::string> nodeSet; if (node || (content.length() > 0)) { _datamodel.appendChild(_doc.importNode(dataElem, true)); nodeSet.push_back(dataElem); } else if (HAS_ATTR(dataElem, "expr")) { try { Element<std::string> container = _doc.createElement("data"); container.setAttribute("id", location); XPathValue<std::string> expr = _xpath.evaluate_expr(ATTR(dataElem, "expr"), _doc); switch (expr.type()) { case NODE_SET: { for (size_t i = 0; i < expr.asNodeSet().size(); i++) { container.appendChild(expr.asNodeSet()[i].cloneNode(true)); nodeSet.push_back(expr.asNodeSet()[i].cloneNode(true)); } break; } case STRING: container.appendChild(_doc.createTextNode(expr.asString())); nodeSet.push_back(_doc.createTextNode(expr.asString())); break; case NUMBER: { container.appendChild(_doc.createTextNode(toStr(expr.asNumber()))); nodeSet.push_back(_doc.createTextNode(toStr(expr.asNumber()))); break; } case Arabica::XPath::BOOL: case ANY: ERROR_EXECUTION_THROW("expr evaluates to type ANY"); } _datamodel.appendChild(container); } catch (SyntaxException e) { ERROR_EXECUTION_THROW(e.what()); } } else { LOG(ERROR) << "data element has no content"; } _varResolver.setVariable(location, nodeSet); }
Arabica::XPath::NodeSet<std::string> InterpreterDraft6::selectEventlessTransitions() { Arabica::XPath::NodeSet<std::string> enabledTransitions; NodeSet<std::string> states; for (unsigned int i = 0; i < _configuration.size(); i++) { if (isAtomic(_configuration[i])) states.push_back(_configuration[i]); } states.to_document_order(); #if 0 std::cout << "Atomic States: "; for (int i = 0; i < atomicStates.size(); i++) { std::cout << ATTR(atomicStates[i], "id") << ", "; } std::cout << std::endl; #endif unsigned int index = 0; while(states.size() > index) { bool foundTransition = false; NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", states[index]); for (unsigned int k = 0; k < transitions.size(); k++) { if (!HAS_ATTR(transitions[k], "event") && hasConditionMatch(transitions[k])) { enabledTransitions.push_back(transitions[k]); foundTransition = true; goto LOOP; } } if (!foundTransition) { Node<std::string> parent = states[index].getParentNode(); if (parent) { states.push_back(parent); } } LOOP: index++; } #if 0 std::cout << "Enabled eventless transitions: " << std::endl; for (int i = 0; i < enabledTransitions.size(); i++) { std::cout << enabledTransitions[i] << std::endl << "----" << std::endl; } std::cout << std::endl; #endif enabledTransitions = filterPreempted(enabledTransitions); return enabledTransitions; }
NodeSet<std::string> XPathDataModel::dataToNodeSet(const Data& data) { NodeSet<std::string> dataNodeSet; if (data.atom.length() > 0) { dataNodeSet.push_back(_doc.createTextNode(data.atom)); } return dataNodeSet; }
bool InterpreterDraft6::isWithinParallel(const Node<std::string>& transition) { if (isTargetless(transition)) return false; Node<std::string> source; if (HAS_ATTR(transition, "type") && iequals(ATTR(transition, "type"), "internal")) { source = getSourceState(transition); } else { source = getSourceState(transition).getParentNode(); } NodeSet<std::string> targets = getTargetStates(transition); targets.push_back(source); Node<std::string> lcpa = findLCPA(targets); return lcpa; }
virtual XPathValue value(const DOMNode& node, ExecutionContext<string_type, string_adaptor>& context, DOMSink<string_type, string_adaptor>& sink) const { if(select_) return select_->evaluate(node, context.xpathContext()); execute_children(node, context); if(sink.node() == 0) return StringValue::createValue(string_adaptor::empty_string()); NodeSet nodeset; for(DOMNode n = sink.node().getFirstChild(); n != 0; n = n.getNextSibling()) nodeset.push_back(n); return NodeSetValue::createValue(nodeset); } // value
//enumerate all the possible vertex set upto size fragSize+1, and insert into the fragment table of the database //fragSize+1 is the fragSize+1 value (see paper), gid is the gid in the Graph table of the database //D is the distance matrix // generate closely connected vertex set //can reduce the size of the table significantly void LoadGraph::insertFragments() { assert(fragSize>=2); NodeSetList list1, list2; for(int v1=0; v1<G->n()-fragSize+1; v1++) { for(int v2=v1+1; v2<G->n()-fragSize+2; v2++) { if((*pOrthinfolist)[v1][0]==0 || (*pOrthinfolist)[v2][0]==0) continue; NodeSet vs; vs.push_back(v1); vs.push_back(v2); if(fragSize==2 && D[v1][v2]<=fragLimit) { vector<NodeOrtholog> vfset; insertFragmentHelp(vs, 0, vfset); } else list1.push_back(vs); } } NodeSetList* prev_list, *curr_list; prev_list=&list1; curr_list=&list2; //we have k-subset, we want to generat k+1-subset for(int k=2; k<fragSize; k++) { unsigned int numloop=prev_list->size(); NodeSetList::iterator prev_it; for(unsigned int count=0; count<numloop; count++) { //debug(15, "count= "<<count<<endl); prev_it=prev_list->begin(); NodeSet pvs=(*prev_it);//the vertex set int i=pvs[pvs.size()-1]+1; //vertex set sorted by id for(; i<G->n()-fragSize+k+1; i++) { //debug(15, "i="<<i<<endl); if((*pOrthinfolist)[i][0]==0) continue; NodeSet vs(pvs); vs.push_back(i); if((int)vs.size()==fragSize) { //only work for fragment size=3 int numSmall=0; bool ok=false; for(unsigned int s=0; s<vs.size()-1; s++) { for(unsigned int t=s+1; t<vs.size(); t++) { if(D[ vs[s] ][ vs[t] ]<=fragLimit) { numSmall++; if(numSmall>=2) { ok=true; break;} } } if(ok) break; } if(ok) { vector<NodeOrtholog> vfset; insertFragmentHelp(vs, 0, vfset); } } else curr_list->push_back(vs); //debug(15, "after something"); } prev_list->erase(prev_it); } //swap curr_map and prev_map NodeSetList* temp=prev_list; prev_list=curr_list; curr_list=temp; } }
int main(int argc, char** argv) { factory_ = Arabica::SimpleDOM::DOMImplementation<string_type, string_adaptor>::getDOMImplementation(); document_ = factory_.createDocument(SA::construct_from_utf8(""), SA::construct_from_utf8(""), 0); root_ = document_.createElement("root"); document_.appendChild(root_); assert(root_); element1_ = document_.createElement(SA::construct_from_utf8("child1")); element2_ = document_.createElement(SA::construct_from_utf8("child2")); element3_ = document_.createElement(SA::construct_from_utf8("child3")); element1_.setAttribute(SA::construct_from_utf8("one"), SA::construct_from_utf8("1")); element2_.setAttribute(SA::construct_from_utf8("one"), SA::construct_from_utf8("1")); element2_.setAttribute(SA::construct_from_utf8("two"), SA::construct_from_utf8("1")); element2_.setAttribute(SA::construct_from_utf8("three"), SA::construct_from_utf8("1")); element2_.setAttribute(SA::construct_from_utf8("four"), SA::construct_from_utf8("1")); text_ = document_.createTextNode(SA::construct_from_utf8("data")); comment_ = document_.createComment(SA::construct_from_utf8("comment")); processingInstruction_ = document_.createProcessingInstruction(SA::construct_from_utf8("target"), SA::construct_from_utf8("data")); element2_.appendChild(text_); spinkle_ = document_.createElement(SA::construct_from_utf8("spinkle")); element2_.appendChild(spinkle_); element2_.appendChild(comment_); element2_.appendChild(processingInstruction_); attr_ = element1_.getAttributeNode(SA::construct_from_utf8("one")); root_.appendChild(element1_); root_.appendChild(element2_); root_.appendChild(element3_); chapters_ = factory_.createDocument(SA::construct_from_utf8(""), SA::construct_from_utf8(""), 0); chapters_.appendChild(chapters_.createElement(SA::construct_from_utf8("document"))); chapters_.getFirstChild().appendChild(chapters_.createElement(SA::construct_from_utf8("chapter"))).appendChild(chapters_.createTextNode(SA::construct_from_utf8("one"))); chapters_.getFirstChild().appendChild(chapters_.createElement(SA::construct_from_utf8("chapter"))).appendChild(chapters_.createTextNode(SA::construct_from_utf8("two"))); chapters_.getFirstChild().appendChild(chapters_.createElement(SA::construct_from_utf8("chapter"))).appendChild(chapters_.createTextNode(SA::construct_from_utf8("three"))); chapters_.getFirstChild().appendChild(chapters_.createElement(SA::construct_from_utf8("chapter"))).appendChild(chapters_.createTextNode(SA::construct_from_utf8("four"))); chapters_.getFirstChild().appendChild(chapters_.createElement(SA::construct_from_utf8("chapter"))).appendChild(chapters_.createTextNode(SA::construct_from_utf8("five"))); numbers_ = factory_.createDocument(SA::construct_from_utf8(""), SA::construct_from_utf8(""), 0); numbers_.appendChild(numbers_.createElement(SA::construct_from_utf8("doc"))); numbers_.getFirstChild().appendChild(numbers_.createElement(SA::construct_from_utf8("number"))).appendChild(numbers_.createTextNode(SA::construct_from_utf8("1"))); numbers_.getFirstChild().appendChild(numbers_.createElement(SA::construct_from_utf8("number"))).appendChild(numbers_.createTextNode(SA::construct_from_utf8("2"))); numbers_.getFirstChild().appendChild(numbers_.createElement(SA::construct_from_utf8("number"))).appendChild(numbers_.createTextNode(SA::construct_from_utf8("3"))); numbers_.getFirstChild().appendChild(numbers_.createElement(SA::construct_from_utf8("number"))).appendChild(numbers_.createTextNode(SA::construct_from_utf8("4"))); numbers_.getFirstChild().appendChild(numbers_.createElement(SA::construct_from_utf8("number"))).appendChild(numbers_.createTextNode(SA::construct_from_utf8("5"))); numbers_.getFirstChild().appendChild(numbers_.createElement(SA::construct_from_utf8("number"))).appendChild(numbers_.createTextNode(SA::construct_from_utf8("6"))); numbers_.getFirstChild().appendChild(numbers_.createElement(SA::construct_from_utf8("number"))).appendChild(numbers_.createTextNode(SA::construct_from_utf8("7"))); numbers_.getFirstChild().appendChild(numbers_.createElement(SA::construct_from_utf8("number"))).appendChild(numbers_.createTextNode(SA::construct_from_utf8("8"))); numbers_.getFirstChild().appendChild(numbers_.createElement(SA::construct_from_utf8("number"))).appendChild(numbers_.createTextNode(SA::construct_from_utf8("9"))); std::cout << document_ << std::endl; std::cout << numbers_ << std::endl; std::cout << chapters_ << std::endl; if (true) { using namespace Arabica::XPath; using namespace Arabica::DOM; XPathValue<string_type, string_adaptor> result = parser.evaluate(SA::construct_from_utf8("//*"), document_); for(int i = 0; i < result.asNodeSet().size(); i++) { Node<string_type, string_adaptor> node = result.asNodeSet()[i]; std::string xpathExpr = uscxml::DOMUtils::xPathForNode(node); if (xpathExpr.size()) { XPathValue<string_type, string_adaptor> innerResult = parser.evaluate(xpathExpr, document_); assert(innerResult.asNodeSet().size() > 0); assert(innerResult.asNodeSet().size() == 1); assert(innerResult.asNodeSet()[0] == node); } else { assert(node.getNodeType() != Node_base::ELEMENT_NODE); } } } if (false) { using namespace Arabica::XPath; StringVariableResolver svr; svr.setVariable(SA::construct_from_utf8("index"), SA::construct_from_utf8("1")); parser.setVariableResolver(svr); XPathValue<string_type, string_adaptor> result = parser.evaluate(SA::construct_from_utf8("/root/*[@two = $index]"), document_); assert(NODE_SET == result.type()); assert(element2_ == result.asNodeSet()[0]); parser.resetVariableResolver(); } // test18 if (false) { using namespace Arabica::XPath; XPathExpression<string_type, string_adaptor> xpath = parser.compile(SA::construct_from_utf8("root/*[position() = 2]")); XPathValue<string_type, string_adaptor> result = xpath.evaluate(document_); assert(NODE_SET == result.type()); assert(1 == result.asNodeSet().size()); Arabica::DOM::Node<string_type, string_adaptor> n = result.asNodeSet()[0]; assert(element2_ == n); } // test19 if (false) { using namespace Arabica::XPath; Arabica::DOM::DocumentFragment<string_type, string_adaptor> frag = document_.createDocumentFragment(); frag.appendChild(document_.createElement(SA::construct_from_utf8("foo"))); NodeSetVariableResolver svr; NodeSet<string_type, string_adaptor> ns; ns.push_back(frag); svr.setVariable(SA::construct_from_utf8("fruit"), ns); parser.setVariableResolver(svr); XPathValue<string_type, string_adaptor> result = parser.evaluate_expr(SA::construct_from_utf8("$fruit/foo|/root/child3"), document_); assert(NODE_SET == result.type()); assert(2 == result.asNodeSet().size()); assert(element3_ == result.asNodeSet()[0]); } // testUnion11 if (false) { using namespace Arabica::XPath; XPathValue<string_type, string_adaptor> result = parser.evaluate_expr(SA::construct_from_utf8("local-name(/root)"), document_); assert(STRING == result.type()); assert(SA::construct_from_utf8("root") == result.asString()); } // testLocalNameFn1 if (0) { using namespace Arabica::XPath; Arabica::DOM::DocumentFragment<std::string> frag = document_.createDocumentFragment(); frag.appendChild(document_.createElement("foo")); NodeSetVariableResolver svr; NodeSet<string_type, string_adaptor> ns; ns.push_back(frag); svr.setVariable("fruit", ns); parser.setVariableResolver(svr); XPathValue<string_type, string_adaptor> result = parser.evaluate(SA::construct_from_utf8("local-name($fruit/foo) == 'foo'"), document_); std::cout << result.asBool() << std::endl; } }
boost::shared_ptr<DataModelImpl> XPathDataModel::create(InterpreterInfo* interpreter) { boost::shared_ptr<XPathDataModel> dm = boost::shared_ptr<XPathDataModel>(new XPathDataModel()); dm->_interpreter = interpreter; // dm->_xpath->setVariableCompileTimeResolver(_varCTResolver); // dm->_xpath->setNamespaceContext(interpreter->getNSContext()); dm->_funcResolver.setInterpreter(interpreter); dm->_xpath.setNamespaceContext(*interpreter->getNameSpaceInfo().getNSContext()); dm->_xpath.setFunctionResolver(dm->_funcResolver); dm->_xpath.setVariableResolver(dm->_varResolver); dm->_domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation(); dm->_doc = dm->_domFactory.createDocument("http://www.w3.org/2005/07/scxml", "", 0); dm->_datamodel = dm->_doc.createElement("datamodel"); dm->_doc.appendChild(dm->_datamodel); Element<std::string> ioProcElem = dm->_doc.createElement("data"); ioProcElem.setAttribute("id", "_ioprocessors"); std::map<std::string, IOProcessor>::const_iterator ioProcIter = interpreter->getIOProcessors().begin(); while(ioProcIter != interpreter->getIOProcessors().end()) { Element<std::string> ioProc = dm->_doc.createElement("processor"); ioProc.setAttribute("name", ioProcIter->first); Data ioProcData = ioProcIter->second.getDataModelVariables(); Element<std::string> ioProcLoc = dm->_doc.createElement("location"); Text<std::string> ioProcLocText = dm->_doc.createTextNode(ioProcData.compound["location"].atom); ioProcLoc.appendChild(ioProcLocText); ioProc.appendChild(ioProcLoc); ioProcElem.appendChild(ioProc); ioProcIter++; } dm->_datamodel.appendChild(ioProcElem); NodeSet<std::string> ioProcNodeSet; ioProcNodeSet.push_back(ioProcElem); dm->_varResolver.setVariable("_ioprocessors", ioProcNodeSet); Element<std::string> sessIdElem = dm->_doc.createElement("data"); sessIdElem.setAttribute("id", "_sessionid"); Text<std::string> sessIdText = dm->_doc.createTextNode(interpreter->getSessionId()); sessIdElem.appendChild(sessIdText); dm->_datamodel.appendChild(sessIdElem); NodeSet<std::string> sessIdNodeSet; sessIdNodeSet.push_back(sessIdText); dm->_varResolver.setVariable("_sessionid", sessIdNodeSet); Element<std::string> nameElem = dm->_doc.createElement("data"); nameElem.setAttribute("id", "_name"); Text<std::string> nameText = dm->_doc.createTextNode(interpreter->getName()); nameElem.appendChild(nameText); dm->_datamodel.appendChild(nameElem); NodeSet<std::string> nameNodeSet; nameNodeSet.push_back(nameText); dm->_varResolver.setVariable("_name", nameNodeSet); return dm; }
void XPathDataModel::assign(const Element<std::string>& assignElem, const Node<std::string>& node, const std::string& content) { std::string location; if (HAS_ATTR(assignElem, "id")) { location = ATTR(assignElem, "id"); } else if (HAS_ATTR(assignElem, "location")) { location = ATTR(assignElem, "location"); } // test 326ff XPathValue<std::string> key = _xpath.evaluate_expr(location, _doc); #ifdef VERBOSE LOG(INFO) << "Key XPath : " << key.asString(); #endif #if 0 if (key.type() == NODE_SET) { try { for (size_t i = 0; i < key.asNodeSet().size(); i++) { Node<std::string> node = key.asNodeSet()[i]; if (node == _varResolver.resolveVariable("", "_ioprocessors").asNodeSet()[0]) ERROR_EXECUTION_THROW("Cannot assign _ioProcessors"); if (node == _varResolver.resolveVariable("", "_sessionid").asNodeSet()[0]) ERROR_EXECUTION_THROW("Cannot assign _sessionid"); if (node == _varResolver.resolveVariable("", "_name").asNodeSet()[0]) ERROR_EXECUTION_THROW("Cannot assign _name"); if (node == _varResolver.resolveVariable("", "_event").asNodeSet()[0]) ERROR_EXECUTION_THROW("Cannot assign _event"); } } catch (Event e) {} } #endif NodeSet<std::string> nodeSet; if (node) { Node<std::string> data = node; while (data) { // do not add empty text as a node if (data.getNodeType() == Node_base::TEXT_NODE) { std::string trimmed = data.getNodeValue(); boost::trim(trimmed); if (trimmed.length() == 0) { data = data.getNextSibling(); continue; } } nodeSet.push_back(data); data = data.getNextSibling(); } assign(key, nodeSet, assignElem); } else if (content.length() > 0) { Text<std::string> textNode = _doc.createTextNode(spaceNormalize(content)); nodeSet.push_back(textNode); assign(key, nodeSet, assignElem); } else if (HAS_ATTR(assignElem, "expr")) { XPathValue<std::string> value = _xpath.evaluate_expr(ATTR(assignElem, "expr"), _doc); #ifdef VERBOSE LOG(INFO) << "Value XPath : " << value.asString(); #endif assign(key, value, assignElem); } else { LOG(ERROR) << "assign element has no content"; } // std::cout << _datamodel << std::endl; }
void XPathDataModel::setForeach(const std::string& item, const std::string& array, const std::string& index, uint32_t iteration) { XPathValue<std::string> arrayResult = _xpath.evaluate_expr(array, _doc); assert(arrayResult.type() == NODE_SET); #if 0 std::cout << "Array Size: " << arrayResult.asNodeSet().size() << std::endl; for (size_t i = 0; i < arrayResult.asNodeSet().size(); i++) { std::cout << arrayResult.asNodeSet()[i] << std::endl; } #endif assert(arrayResult.asNodeSet().size() >= iteration); NodeSet<std::string> arrayNodeSet; arrayNodeSet.push_back(arrayResult.asNodeSet()[iteration]); if (!isDeclared(item)) { if (!isValidIdentifier(item)) ERROR_EXECUTION_THROW("Expression '" + item + "' not a valid identifier."); Element<std::string> container = _doc.createElement("data"); container.setAttribute("id", item); container.appendChild(arrayResult.asNodeSet()[iteration].cloneNode(true)); _datamodel.appendChild(container); _varResolver.setVariable(item, arrayNodeSet); } XPathValue<std::string> itemResult = _varResolver.resolveVariable("", item); assign(itemResult, arrayNodeSet, Element<std::string>()); if (index.length() > 0) { NodeSet<std::string> indexNodeSet; Text<std::string> indexElem = _doc.createTextNode(toStr(iteration)); indexNodeSet.push_back(indexElem); if (!isDeclared(index)) { Element<std::string> container = _doc.createElement("data"); container.setAttribute("id", index); container.appendChild(indexElem); _datamodel.appendChild(container); NodeSet<std::string> indexVarNodeSet; indexVarNodeSet.push_back(container); _varResolver.setVariable(index, indexVarNodeSet); } XPathValue<std::string> indexResult = _varResolver.resolveVariable("", index); assign(indexResult, indexNodeSet, Element<std::string>()); } #if 0 std::cout << _datamodel << std::endl << std::endl; std::cout << "Index: " << indexResult.asNodeSet().size() << std::endl; for (size_t i = 0; i < indexResult.asNodeSet().size(); i++) { std::cout << indexResult.asNodeSet()[i] << std::endl; } std::cout << std::endl; #endif }
void XPathDataModel::setEvent(const Event& event) { Element<std::string> eventElem = _doc.createElement("data"); eventElem.setAttribute("id", "_event"); Element<std::string> eventDataElem = _doc.createElement("data"); NodeSet<std::string> eventNodeSet; { // -- name Element<std::string> eventNameElem = _doc.createElement("name"); Text<std::string> eventName = _doc.createTextNode(event.name.c_str()); eventNameElem.appendChild(eventName); eventElem.appendChild(eventNameElem); } { // -- origin Element<std::string> eventOriginElem = _doc.createElement("origin"); Text<std::string> eventOrigin = _doc.createTextNode(event.origin.c_str()); eventOriginElem.appendChild(eventOrigin); eventElem.appendChild(eventOriginElem); } { // -- type Element<std::string> eventTypeElem = _doc.createElement("type"); Text<std::string> eventType; switch (event.eventType) { case Event::INTERNAL: eventType = _doc.createTextNode("internal"); break; case Event::EXTERNAL: eventType = _doc.createTextNode("external"); break; case Event::PLATFORM: eventType = _doc.createTextNode("platform"); break; } eventTypeElem.appendChild(eventType); eventElem.appendChild(eventTypeElem); } if (event.params.size() > 0) { std::multimap<std::string, Data>::const_iterator paramIter = event.params.begin(); while(paramIter != event.params.end()) { Element<std::string> eventParamElem = _doc.createElement("data"); // this is simplified - Data might be more elaborate than a simple string atom Text<std::string> eventParamText = _doc.createTextNode(paramIter->second.atom); eventParamElem.setAttribute("id", paramIter->first); eventParamElem.appendChild(eventParamText); eventDataElem.appendChild(eventParamElem); paramIter++; } } if (event.namelist.size() > 0) { std::map<std::string, Data>::const_iterator namelistIter = event.namelist.begin(); while(namelistIter != event.namelist.end()) { Element<std::string> eventNamelistElem = _doc.createElement("data"); // this is simplified - Data might be more elaborate than a simple string atom Text<std::string> eventNamelistText = _doc.createTextNode(namelistIter->second.atom); eventNamelistElem.setAttribute("id", namelistIter->first); eventNamelistElem.appendChild(eventNamelistText); eventDataElem.appendChild(eventNamelistElem); namelistIter++; } } if (event.raw.size() > 0) { Element<std::string> eventRawElem = _doc.createElement("raw"); Text<std::string> textNode = _doc.createTextNode(event.raw.c_str()); eventRawElem.appendChild(textNode); eventElem.appendChild(eventRawElem); } if (event.content.size() > 0) { Text<std::string> textNode = _doc.createTextNode(spaceNormalize(event.content).c_str()); eventDataElem.appendChild(textNode); } if (event.dom) { Node<std::string> importedNode = _doc.importNode(event.dom, true); eventDataElem.appendChild(importedNode); } if (event.data.array.size() == 1) { Text<std::string> textNode = _doc.createTextNode(event.data.array.front().atom.c_str()); eventDataElem.appendChild(textNode); } else if (event.data.array.size() > 1) { std::list<uscxml::Data>::const_iterator ptr; unsigned int i; for( i = 0 , ptr = event.data.array.begin() ; ((i < event.data.array.size()) && (ptr != event.data.array.end())); i++ , ptr++ ) { Element<std::string> eventMESElem = _doc.createElement("data"); Text<std::string> textNode = _doc.createTextNode(ptr->atom.c_str()); std::stringstream ss; ss << i; eventMESElem.setAttribute("id", ss.str()); eventMESElem.appendChild(textNode); eventDataElem.appendChild(eventMESElem); } } eventElem.appendChild(eventDataElem); eventNodeSet.push_back(eventElem); // do we need to replace an existing event? Node<std::string> oldEventElem = _datamodel.getFirstChild(); while(oldEventElem) { if (oldEventElem.getNodeType() == Node_base::ELEMENT_NODE) { if (HAS_ATTR_CAST(oldEventElem, "id") && iequals(ATTR_CAST(oldEventElem, "id"), "_event")) break; } oldEventElem = oldEventElem.getNextSibling(); } if (oldEventElem) { _datamodel.replaceChild(eventElem, oldEventElem); } else { _datamodel.appendChild(eventElem); } _varResolver.setVariable("_event", eventNodeSet); }
void InterpreterDraft6::enterStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) { NodeSet<std::string> statesToEnter; NodeSet<std::string> statesForDefaultEntry; monIter_t monIter; #if VERBOSE std::cout << _name << ": Enabled enter transitions: " << std::endl; for (int i = 0; i < enabledTransitions.size(); i++) { std::cout << "\t" << enabledTransitions[i] << std::endl; } std::cout << std::endl; #endif for (int i = 0; i < enabledTransitions.size(); i++) { Element<std::string> transition = ((Element<std::string>)enabledTransitions[i]); if (!isTargetless(transition)) { std::string transitionType = (iequals(transition.getAttribute("type"), "internal") ? "internal" : "external"); NodeSet<std::string> tStates = getTargetStates(transition); #if VERBOSE std::cout << _name << ": Target States: "; for (int i = 0; i < tStates.size(); i++) { std::cout << ATTR(tStates[i], "id") << ", "; } std::cout << std::endl; #endif Node<std::string> ancestor; Node<std::string> source = getSourceState(transition); #if VERBOSE std::cout << _name << ": Source States: " << ATTR(source, "id") << std::endl; #endif assert(source); bool allDescendants = true; for (int j = 0; j < tStates.size(); j++) { if (!isDescendant(tStates[j], source)) { allDescendants = false; break; } } if (iequals(transitionType, "internal") && isCompound(source) && allDescendants) { ancestor = source; } else { NodeSet<std::string> tmpStates; tmpStates.push_back(source); tmpStates.insert(tmpStates.end(), tStates.begin(), tStates.end()); ancestor = findLCCA(tmpStates); } #if VERBOSE std::cout << _name << ": Ancestor: " << ATTR(ancestor, "id") << std::endl; #endif for (int j = 0; j < tStates.size(); j++) { addStatesToEnter(tStates[j], statesToEnter, statesForDefaultEntry); } #if VERBOSE std::cout << _name << ": States to enter: "; for (int i = 0; i < statesToEnter.size(); i++) { std::cout << LOCALNAME(statesToEnter[i]) << ":" << ATTR(statesToEnter[i], "id") << ", "; } std::cout << std::endl; #endif for (int j = 0; j < tStates.size(); j++) { NodeSet<std::string> ancestors = getProperAncestors(tStates[j], ancestor); #if VERBOSE std::cout << _name << ": Proper Ancestors of " << ATTR(tStates[j], "id") << " and " << ATTR(ancestor, "id") << ": "; for (int i = 0; i < ancestors.size(); i++) { std::cout << ATTR(ancestors[i], "id") << ", "; } std::cout << std::endl; #endif for (int k = 0; k < ancestors.size(); k++) { statesToEnter.push_back(ancestors[k]); if(isParallel(ancestors[k])) { NodeSet<std::string> childs = getChildStates(ancestors[k]); for (int l = 0; l < childs.size(); l++) { bool someIsDescendant = false; for (int m = 0; m < statesToEnter.size(); m++) { if (isDescendant(statesToEnter[m], childs[l])) { someIsDescendant = true; break; } } if (!someIsDescendant) { addStatesToEnter(childs[l], statesToEnter, statesForDefaultEntry); } } } } } } } statesToEnter.to_document_order(); #if VERBOSE std::cout << _name << ": States to enter: "; for (int i = 0; i < statesToEnter.size(); i++) { std::cout << ATTR(statesToEnter[i], "id") << ", "; } std::cout << std::endl; #endif for (int i = 0; i < statesToEnter.size(); i++) { Element<std::string> stateElem = (Element<std::string>)statesToEnter[i]; // extension for flattened interpreters for (unsigned int k = 0; k < statesToEnter.size(); k++) { NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", statesToEnter[k]); for (unsigned int j = 0; j < invokes.size(); j++) { if (HAS_ATTR(invokes[j], "persist") && DOMUtils::attributeIsTrue(ATTR(invokes[j], "persist"))) { invoke(invokes[j]); } } } // --- MONITOR: beforeEnteringState ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->beforeEnteringState(shared_from_this(), stateElem, (i + 1 < statesToEnter.size())); } USCXML_MONITOR_CATCH_BLOCK(beforeEnteringState) } // extension for flattened SCXML documents, we will need an explicit uninvoke element NodeSet<std::string> uninvokes = filterChildElements(_nsInfo.xmlNSPrefix + "uninvoke", statesToEnter[i]); for (int j = 0; j < uninvokes.size(); j++) { Element<std::string> uninvokeElem = (Element<std::string>)uninvokes[j]; cancelInvoke(uninvokeElem); } _configuration.push_back(stateElem); _statesToInvoke.push_back(stateElem); // if (_binding == LATE && stateElem.getAttribute("isFirstEntry").size() > 0) { if (_binding == LATE && !isMember(stateElem, _alreadyEntered)) { NodeSet<std::string> dataModelElems = filterChildElements(_nsInfo.xmlNSPrefix + "datamodel", stateElem); if(dataModelElems.size() > 0 && _dataModel) { Arabica::XPath::NodeSet<std::string> dataElems = filterChildElements(_nsInfo.xmlNSPrefix + "data", dataModelElems[0]); for (int j = 0; j < dataElems.size(); j++) { if (dataElems[j].getNodeType() == Node_base::ELEMENT_NODE) initializeData(Element<std::string>(dataElems[j])); } } _alreadyEntered.push_back(stateElem); // stateElem.setAttribute("isFirstEntry", ""); } // execute onentry executable content NodeSet<std::string> onEntryElems = filterChildElements(_nsInfo.xmlNSPrefix + "onEntry", stateElem); executeContent(onEntryElems, false); // --- MONITOR: afterEnteringState ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->afterEnteringState(shared_from_this(), stateElem, (i + 1 < statesToEnter.size())); } USCXML_MONITOR_CATCH_BLOCK(afterEnteringState) } if (isMember(stateElem, statesForDefaultEntry)) { // execute initial transition content for compound states Arabica::XPath::NodeSet<std::string> transitions = _xpath.evaluate("" + _nsInfo.xpathPrefix + "initial/" + _nsInfo.xpathPrefix + "transition", stateElem).asNodeSet(); for (int j = 0; j < transitions.size(); j++) { executeContent(transitions[j]); } } if (isFinal(stateElem)) { internalDoneSend(stateElem); Element<std::string> parent = (Element<std::string>)stateElem.getParentNode(); if (isParallel(parent.getParentNode())) { Element<std::string> grandParent = (Element<std::string>)parent.getParentNode(); Arabica::XPath::NodeSet<std::string> childs = getChildStates(grandParent); bool inFinalState = true; for (int j = 0; j < childs.size(); j++) { if (!isInFinalState(childs[j])) { inFinalState = false; break; } } if (inFinalState) { internalDoneSend(parent); } } } } for (int i = 0; i < _configuration.size(); i++) { Element<std::string> stateElem = (Element<std::string>)_configuration[i]; if (isFinal(stateElem) && parentIsScxmlState(stateElem)) { _running = false; _done = true; } } }
void InterpreterDraft6::exitStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) { NodeSet<std::string> statesToExit; monIter_t monIter; #if VERBOSE std::cout << _name << ": Enabled exit transitions: " << std::endl; for (int i = 0; i < enabledTransitions.size(); i++) { std::cout << enabledTransitions[i] << std::endl; } std::cout << std::endl; #endif for (int i = 0; i < enabledTransitions.size(); i++) { Element<std::string> t = ((Element<std::string>)enabledTransitions[i]); if (!isTargetless(t)) { Node<std::string> ancestor; Node<std::string> source = getSourceState(t); // std::cout << t << std::endl << TAGNAME(t) << std::endl; NodeSet<std::string> tStates = getTargetStates(t); bool isInternal = (HAS_ATTR(t, "type") && iequals(ATTR(t, "type"), "internal")); // external is default bool allDescendants = true; for (int j = 0; j < tStates.size(); j++) { if (!isDescendant(tStates[j], source)) { allDescendants = false; break; } } if (isInternal && allDescendants && isCompound(source)) { ancestor = source; } else { NodeSet<std::string> tmpStates; tmpStates.push_back(source); tmpStates.insert(tmpStates.end(), tStates.begin(), tStates.end()); #if VERBOSE std::cout << _name << ": tmpStates: "; for (int i = 0; i < tmpStates.size(); i++) { std::cout << ATTR(tmpStates[i], "id") << ", "; } std::cout << std::endl; #endif ancestor = findLCCA(tmpStates); } #if VERBOSE std::cout << _name << ": Ancestor: " << ATTR(ancestor, "id") << std::endl;; #endif for (int j = 0; j < _configuration.size(); j++) { if (isDescendant(_configuration[j], ancestor)) statesToExit.push_back(_configuration[j]); } } } // remove statesToExit from _statesToInvoke std::list<Node<std::string> > tmp; for (int i = 0; i < _statesToInvoke.size(); i++) { if (!isMember(_statesToInvoke[i], statesToExit)) { tmp.push_back(_statesToInvoke[i]); } } _statesToInvoke = NodeSet<std::string>(); _statesToInvoke.insert(_statesToInvoke.end(), tmp.begin(), tmp.end()); statesToExit.forward(false); statesToExit.sort(); #if VERBOSE std::cout << _name << ": States to exit: "; for (int i = 0; i < statesToExit.size(); i++) { std::cout << LOCALNAME(statesToExit[i]) << ":" << ATTR(statesToExit[i], "id") << ", "; } std::cout << std::endl; #endif for (int i = 0; i < statesToExit.size(); i++) { NodeSet<std::string> histories = filterChildElements(_nsInfo.xmlNSPrefix + "history", statesToExit[i]); for (int j = 0; j < histories.size(); j++) { Element<std::string> historyElem = (Element<std::string>)histories[j]; std::string historyType = (historyElem.hasAttribute("type") ? historyElem.getAttribute("type") : "shallow"); NodeSet<std::string> historyNodes; for (int k = 0; k < _configuration.size(); k++) { if (iequals(historyType, "deep")) { if (isAtomic(_configuration[k]) && isDescendant(_configuration[k], statesToExit[i])) historyNodes.push_back(_configuration[k]); } else { if (_configuration[k].getParentNode() == statesToExit[i]) historyNodes.push_back(_configuration[k]); } } _historyValue[historyElem.getAttribute("id")] = historyNodes; #if VERBOSE std::cout << _name << ": History node " << ATTR(historyElem, "id") << " contains: "; for (int i = 0; i < historyNodes.size(); i++) { std::cout << ATTR(historyNodes[i], "id") << ", "; } std::cout << std::endl; #endif } } for (int i = 0; i < statesToExit.size(); i++) { // --- MONITOR: beforeExitingState ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->beforeExitingState(shared_from_this(), Element<std::string>(statesToExit[i]), (i + 1 < statesToExit.size())); } USCXML_MONITOR_CATCH_BLOCK(beforeExitingState) } NodeSet<std::string> onExits = filterChildElements(_nsInfo.xmlNSPrefix + "onExit", statesToExit[i]); for (int j = 0; j < onExits.size(); j++) { Element<std::string> onExitElem = (Element<std::string>)onExits[j]; executeContent(onExitElem); } // --- MONITOR: afterExitingState ------------------------------ for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) { try { (*monIter)->afterExitingState(shared_from_this(), Element<std::string>(statesToExit[i]), (i + 1 < statesToExit.size())); } USCXML_MONITOR_CATCH_BLOCK(afterExitingState) } NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", statesToExit[i]); for (int j = 0; j < invokes.size(); j++) { Element<std::string> invokeElem = (Element<std::string>)invokes[j]; if (HAS_ATTR(invokeElem, "persist") && DOMUtils::attributeIsTrue(ATTR(invokeElem, "persist"))) { // extension for flattened SCXML documents, we will need an explicit uninvoke element } else { cancelInvoke(invokeElem); } } // remove statesToExit[i] from _configuration - test409 tmp.clear(); for (int j = 0; j < _configuration.size(); j++) { if (_configuration[j] != statesToExit[i]) { tmp.push_back(_configuration[j]); } } _configuration = NodeSet<std::string>(); _configuration.insert(_configuration.end(), tmp.begin(), tmp.end()); } }