summaryrefslogtreecommitdiffstats
path: root/src/uscxml
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-04-20 19:28:50 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-04-20 19:28:50 (GMT)
commitc1ebae519210cd4d09eb63bde593d48e769ad7ca (patch)
tree488cfd8056c2e727a7b49882c2f3d46240d00998 /src/uscxml
parent26609f8b8097b21e952835e7064bc938c8542d93 (diff)
downloaduscxml-c1ebae519210cd4d09eb63bde593d48e769ad7ca.zip
uscxml-c1ebae519210cd4d09eb63bde593d48e769ad7ca.tar.gz
uscxml-c1ebae519210cd4d09eb63bde593d48e769ad7ca.tar.bz2
Support for event.raw and more XPath datamodel refactorings
Diffstat (limited to 'src/uscxml')
-rw-r--r--src/uscxml/Factory.h10
-rw-r--r--src/uscxml/Interpreter.cpp21
-rw-r--r--src/uscxml/Message.h8
-rw-r--r--src/uscxml/URL.cpp6
-rw-r--r--src/uscxml/URL.h2
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp21
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h4
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.cpp9
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.h3
-rw-r--r--src/uscxml/plugins/datamodel/null/NULLDataModel.cpp6
-rw-r--r--src/uscxml/plugins/datamodel/null/NULLDataModel.h5
-rw-r--r--src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp7
-rw-r--r--src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h5
-rw-r--r--src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp245
-rw-r--r--src/uscxml/plugins/datamodel/xpath/XPathDataModel.h20
-rw-r--r--src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp57
-rw-r--r--src/uscxml/plugins/ioprocessor/modality/MMIComponent.h4
-rw-r--r--src/uscxml/plugins/ioprocessor/modality/MMIMessages.cpp40
-rw-r--r--src/uscxml/plugins/ioprocessor/modality/MMIMessages.h40
-rw-r--r--src/uscxml/server/HTTPServer.cpp29
20 files changed, 395 insertions, 147 deletions
diff --git a/src/uscxml/Factory.h b/src/uscxml/Factory.h
index e21fe72..59835b3 100644
--- a/src/uscxml/Factory.h
+++ b/src/uscxml/Factory.h
@@ -237,6 +237,10 @@ public:
// foreach
virtual uint32_t getLength(const std::string& expr) = 0;
+ virtual void setForeach(const std::string& item,
+ const std::string& array,
+ const std::string& index,
+ uint32_t iteration) = 0;
virtual void pushContext() = 0;
virtual void popContext() = 0;
@@ -313,6 +317,12 @@ public:
virtual uint32_t getLength(const std::string& expr) {
return _impl->getLength(expr);
}
+ virtual void setForeach(const std::string& item,
+ const std::string& array,
+ const std::string& index,
+ uint32_t iteration) {
+ return _impl->setForeach(item, array, index, iteration);
+ }
virtual void assign(const Arabica::DOM::Element<std::string>& assignElem,
const Arabica::DOM::Document<std::string>& doc,
diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp
index bec2a2a..21f64cb 100644
--- a/src/uscxml/Interpreter.cpp
+++ b/src/uscxml/Interpreter.cpp
@@ -1033,22 +1033,11 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont
CATCH_AND_DISTRIBUTE("Syntax error in array attribute of foreach element:")
try {
_dataModel.pushContext(); // copy old and enter new context
- if (!_dataModel.isDeclared(item)) {
- _dataModel.init(item, Data());
- }
+// if (!_dataModel.isDeclared(item)) {
+// _dataModel.init(item, Data());
+// }
for (uint32_t iteration = 0; iteration < iterations; iteration++) {
- {
- // assign array element to item
- std::stringstream ss;
- ss << array << "[" << iteration << "]";
- _dataModel.assign(item, ss.str());
- }
- if (index.length() > 0) {
- // assign iteration element to index
- std::stringstream ss;
- ss << iteration;
- _dataModel.assign(index, ss.str());
- }
+ _dataModel.setForeach(item, array, index, iteration);
if (content.hasChildNodes())
// execute content and have exception rethrown to break foreach
executeContent(content.getChildNodes(), true);
@@ -1166,7 +1155,7 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node<std::string>& cont
execContent = Factory::createExecutableContent(content.getLocalName(), content.getNamespaceURI(), this);
if (!execContent) {
LOG(ERROR) << "No custom executable content known for element '"
- << content.getLocalName() << "' in namespace '" << content.getNamespaceURI() << "'";
+ << content.getLocalName() << "' in namespace '" << content.getNamespaceURI() << "'";
return;
}
_executableContent[content] = execContent;
diff --git a/src/uscxml/Message.h b/src/uscxml/Message.h
index 3d41f70..27bd071 100644
--- a/src/uscxml/Message.h
+++ b/src/uscxml/Message.h
@@ -140,6 +140,13 @@ public:
this->dom = dom;
}
+ std::string getRaw() {
+ return raw;
+ }
+ void setRaw(const std::string& raw) {
+ this->raw = raw;
+ }
+
std::string getContent() {
return content;
}
@@ -227,6 +234,7 @@ public:
protected:
#endif
+ std::string raw;
std::string name;
Type type;
std::string origin;
diff --git a/src/uscxml/URL.cpp b/src/uscxml/URL.cpp
index 83d3dcb..45aba88 100644
--- a/src/uscxml/URL.cpp
+++ b/src/uscxml/URL.cpp
@@ -266,11 +266,11 @@ URL URL::asBaseURL(const URL& uri) {
return URL(baseUriStr);
}
-
+
const bool URLImpl::toAbsolute(const std::string& baseUrl) {
if (_uri.is_absolute())
return true;
-
+
std::string uriStr = _uri.as_string();
#ifdef _WIN32
if (baseUrl.find("file://") == 0) {
@@ -281,7 +281,7 @@ const bool URLImpl::toAbsolute(const std::string& baseUrl) {
#else
_uri = Arabica::io::URI(baseUrl, _uri.as_string());
#endif
-
+
if (!_uri.is_absolute())
return false;
return true;
diff --git a/src/uscxml/URL.h b/src/uscxml/URL.h
index 37b0614..402666f 100644
--- a/src/uscxml/URL.h
+++ b/src/uscxml/URL.h
@@ -177,7 +177,7 @@ public:
const std::string asLocalFile(const std::string& suffix, bool reload = false) {
return _impl->asLocalFile(suffix, reload);
}
-
+
static URL asBaseURL(const URL& url);
static void toBaseURL(URL& uri);
diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
index 22777fa..34dd524 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
+++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
@@ -339,11 +339,30 @@ uint32_t V8DataModel::getLength(const std::string& expr) {
Event exceptionEvent;
exceptionEvent.name = "error.execution";
- exceptionEvent.data.compound["exception"] = Data("'" + expr + "' does not evaluate to an array.", Data::VERBATIM);;
+ exceptionEvent.data.compound["exception"] = Data("'" + expr + "' does not evaluate to an array.", Data::VERBATIM);
throw(exceptionEvent);
}
+void V8DataModel::setForeach(const std::string& item,
+ const std::string& array,
+ const std::string& index,
+ uint32_t iteration) {
+ if (!isDeclared(item)) {
+ assign(item, Data());
+ }
+ // assign array element to item
+ std::stringstream ss;
+ ss << array << "[" << iteration << "]";
+ assign(item, ss.str());
+ if (index.length() > 0) {
+ // assign iteration element to index
+ std::stringstream ss;
+ ss << iteration;
+ assign(index, ss.str());
+ }
+}
+
void V8DataModel::eval(const std::string& expr) {
v8::Locker locker;
v8::HandleScope handleScope;
diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h
index 7c4f2b3..548cf20 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h
+++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h
@@ -36,6 +36,10 @@ public:
virtual bool validate(const std::string& location, const std::string& schema);
virtual uint32_t getLength(const std::string& expr);
+ virtual void setForeach(const std::string& item,
+ const std::string& array,
+ const std::string& index,
+ uint32_t iteration);
virtual void pushContext();
virtual void popContext();
diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.cpp
index 86fcfef..9679d74 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.cpp
+++ b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.cpp
@@ -32,6 +32,15 @@ v8::Handle<v8::Value> V8SCXMLEvent::origintypeAttrGetter(v8::Local<v8::String> p
return v8::String::New(privData->nativeObj->origintype.c_str());
}
+v8::Handle<v8::Value> V8SCXMLEvent::rawAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
+ v8::Local<v8::Object> self = info.Holder();
+ struct V8SCXMLEventPrivate* privData = V8DOM::toClassPtr<V8SCXMLEventPrivate >(self->GetInternalField(0));
+
+ if (privData->nativeObj->raw.length() == 0)
+ return v8::Undefined();
+ return v8::String::New(privData->nativeObj->raw.c_str());
+}
+
v8::Handle<v8::Value> V8SCXMLEvent::domAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
v8::Local<v8::Object> self = info.Holder();
struct V8SCXMLEventPrivate* privData = V8DOM::toClassPtr<V8SCXMLEventPrivate >(self->GetInternalField(0));
diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.h b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.h
index e7dbacc..670d818 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.h
+++ b/src/uscxml/plugins/datamodel/ecmascript/v8/dom/V8SCXMLEvent.h
@@ -45,6 +45,7 @@ public:
static v8::Handle<v8::Value> nameAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info);
static v8::Handle<v8::Value> originAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info);
static v8::Handle<v8::Value> origintypeAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info);
+ static v8::Handle<v8::Value> rawAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info);
static v8::Handle<v8::Value> domAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info);
static v8::Handle<v8::Value> sendidCustomAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info);
static v8::Handle<v8::Value> invokeidAttrGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info);
@@ -70,6 +71,8 @@ public:
v8::External::New(0), static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None));
instance->SetAccessor(v8::String::NewSymbol("origintype"), V8SCXMLEvent::origintypeAttrGetter, 0,
v8::External::New(0), static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None));
+ instance->SetAccessor(v8::String::NewSymbol("raw"), V8SCXMLEvent::rawAttrGetter, 0,
+ v8::External::New(0), static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None));
instance->SetAccessor(v8::String::NewSymbol("dom"), V8SCXMLEvent::domAttrGetter, 0,
v8::External::New(0), static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::None));
instance->SetAccessor(v8::String::NewSymbol("sendid"), V8SCXMLEvent::sendidCustomAttrGetter, 0,
diff --git a/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp b/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp
index 6911480..dac3386 100644
--- a/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp
@@ -55,6 +55,12 @@ uint32_t NULLDataModel::getLength(const std::string& expr) {
return 0;
}
+void NULLDataModel::setForeach(const std::string& item,
+ const std::string& array,
+ const std::string& index,
+ uint32_t iteration) {
+}
+
void NULLDataModel::eval(const std::string& expr) {
}
diff --git a/src/uscxml/plugins/datamodel/null/NULLDataModel.h b/src/uscxml/plugins/datamodel/null/NULLDataModel.h
index 423c5ff..3d86bf2 100644
--- a/src/uscxml/plugins/datamodel/null/NULLDataModel.h
+++ b/src/uscxml/plugins/datamodel/null/NULLDataModel.h
@@ -33,6 +33,11 @@ public:
virtual bool validate(const std::string& location, const std::string& schema);
virtual uint32_t getLength(const std::string& expr);
+ virtual void setForeach(const std::string& item,
+ const std::string& array,
+ const std::string& index,
+ uint32_t iteration);
+
virtual void pushContext();
virtual void popContext();
diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp
index cc1fb39..db91869 100644
--- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp
@@ -96,6 +96,13 @@ uint32_t SWIDataModel::getLength(const std::string& expr) {
return 0;
}
+void SWIDataModel::setForeach(const std::string& item,
+ const std::string& array,
+ const std::string& index,
+ uint32_t iteration) {
+ // std::cout << "SWIDataModel::setForeach" << std::endl;
+}
+
void SWIDataModel::eval(const std::string& expr) {
URL localPLFile = URL::toLocalFile(expr, ".pl");
PlCall("user", "load_files", PlTermv(localPLFile.asLocalFile(".pl").c_str())) || LOG(ERROR) << "Could not execute prolog from file";
diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h
index a278db8..19dc712 100644
--- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h
+++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h
@@ -33,6 +33,11 @@ public:
virtual bool validate(const std::string& location, const std::string& schema);
virtual uint32_t getLength(const std::string& expr);
+ virtual void setForeach(const std::string& item,
+ const std::string& array,
+ const std::string& index,
+ uint32_t iteration);
+
virtual void pushContext();
virtual void popContext();
diff --git a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp
index 179fded..39616f8 100644
--- a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp
@@ -59,7 +59,11 @@ boost::shared_ptr<DataModelImpl> XPathDataModel::create(InterpreterImpl* interpr
dm->_datamodel.appendChild(ioProcElem);
NodeSet<std::string> ioProcNodeSet;
- ioProcNodeSet.push_back(ioProcElem);
+ Node<std::string> node = ioProcElem.getFirstChild();
+ while(node) {
+ ioProcNodeSet.push_back(node);
+ node = node.getNextSibling();
+ }
dm->_varResolver.setVariable("_ioprocessors", ioProcNodeSet);
Element<std::string> sessIdElem = dm->_doc.createElement("data");
@@ -69,7 +73,7 @@ boost::shared_ptr<DataModelImpl> XPathDataModel::create(InterpreterImpl* interpr
dm->_datamodel.appendChild(sessIdElem);
NodeSet<std::string> sessIdNodeSet;
- sessIdNodeSet.push_back(sessIdElem);
+ sessIdNodeSet.push_back(sessIdText);
dm->_varResolver.setVariable("_sessionid", sessIdNodeSet);
@@ -80,7 +84,7 @@ boost::shared_ptr<DataModelImpl> XPathDataModel::create(InterpreterImpl* interpr
dm->_datamodel.appendChild(nameElem);
NodeSet<std::string> nameNodeSet;
- nameNodeSet.push_back(nameElem);
+ nameNodeSet.push_back(nameText);
dm->_varResolver.setVariable("_name", nameNodeSet);
return dm;
@@ -129,6 +133,13 @@ void XPathDataModel::setEvent(const Event& event) {
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);
+ eventDataElem.appendChild(eventRawElem);
+ }
+
if (event.content.size() > 0) {
Text<std::string> textNode = _doc.createTextNode(Interpreter::spaceNormalize(event.content).c_str());
eventDataElem.appendChild(textNode);
@@ -139,7 +150,7 @@ void XPathDataModel::setEvent(const Event& event) {
}
eventElem.appendChild(eventDataElem);
- eventNodeSet.push_back(eventElem);
+ eventNodeSet.push_back(eventDataElem);
// do we need to replace an existing event?
Node<std::string> oldEventElem = _datamodel.getFirstChild();
@@ -169,28 +180,103 @@ bool XPathDataModel::validate(const std::string& location, const std::string& sc
}
uint32_t XPathDataModel::getLength(const std::string& expr) {
- std::cout << _datamodel << std::endl;
+// std::cout << _datamodel << std::endl;
XPathValue<std::string> result = _xpath.evaluate_expr(expr, _doc);
switch(result.type()) {
- case NUMBER:
- return result.asNumber();
- break;
- case NODE_SET:
- return result.asNodeSet().size();
- break;
- default:
- throw Event("error.execution", Event::PLATFORM);
+ case NUMBER:
+ return result.asNumber();
+ break;
+ case NODE_SET:
+ return result.asNodeSet().size();
+ break;
+ default:
+ Event exceptionEvent("error.execution", Event::PLATFORM);
+ exceptionEvent.data.compound["exception"] = Data("'" + expr + "' does not evaluate to an array.", Data::VERBATIM);
+ throw(exceptionEvent);
}
return 0;
}
+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 (int 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))
+ throw Event("error.execution", Event::PLATFORM);
+ 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 (int i = 0; i < indexResult.asNodeSet().size(); i++) {
+ std::cout << indexResult.asNodeSet()[i] << std::endl;
+ }
+ std::cout << std::endl;
+#endif
+
+
+}
+
+bool XPathDataModel::isValidIdentifier(const std::string& identifier) {
+ if(boost::starts_with(identifier, "."))
+ return false;
+
+ return true;
+}
+
+
void XPathDataModel::eval(const std::string& expr) {
XPathValue<std::string> result = _xpath.evaluate_expr(expr, _doc);
}
bool XPathDataModel::isDeclared(const std::string& expr) {
try {
- return evalAsBool(expr);
+ return _varResolver.isDeclared(expr) || evalAsBool(expr);
} catch(...) {
return false;
}
@@ -247,7 +333,22 @@ void XPathDataModel::assign(const Element<std::string>& assignElem,
XPathValue<std::string> key = _xpath.evaluate_expr(location, _doc);
NodeSet<std::string> nodeSet;
if (doc) {
- nodeSet.push_back(doc.getDocumentElement());
+ if (doc.getDocumentElement()) {
+ Node<std::string> data = doc.getDocumentElement().getFirstChild();
+ 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(Interpreter::spaceNormalize(content));
@@ -292,11 +393,26 @@ void XPathDataModel::init(const Element<std::string>& dataElem,
Text<std::string> textNode = _doc.createTextNode(Interpreter::spaceNormalize(content));
container.appendChild(textNode);
} else if (HAS_ATTR(dataElem, "expr")) {
- XPathValue<std::string> expr = _xpath.evaluate_expr(ATTR(dataElem, "expr"), _doc);
- XPathValue<std::string> key = _xpath.evaluate_expr(location, _doc);
- assign(key, expr, dataElem);
- for (int i = 0; expr.asNodeSet().size(); i++)
- container.appendChild(expr.asNodeSet()[i]);
+ try {
+ XPathValue<std::string> expr = _xpath.evaluate_expr(ATTR(dataElem, "expr"), _doc);
+ switch (expr.type()) {
+ case NODE_SET:
+ for (int i = 0; expr.asNodeSet().size(); i++)
+ container.appendChild(expr.asNodeSet()[i]);
+ break;
+ case STRING:
+ container.appendChild(_doc.createTextNode(expr.asString()));
+ break;
+ case NUMBER:
+ container.appendChild(_doc.createTextNode(toStr(expr.asNumber())));
+ break;
+ case BOOL:
+ case ANY:
+ throw Event("error.execution", Event::PLATFORM);
+ }
+ } catch (SyntaxException e) {
+ throw Event("error.execution", Event::PLATFORM);
+ }
} else {
LOG(ERROR) << "data element has no content";
}
@@ -307,7 +423,7 @@ void XPathDataModel::init(const Element<std::string>& dataElem,
nodeSet.push_back(container);
_varResolver.setVariable(location, nodeSet);
- std::cout << _datamodel << std::endl;
+// std::cout << _datamodel << std::endl;
}
void XPathDataModel::init(const std::string& location, const Data& data) {
@@ -320,46 +436,49 @@ void XPathDataModel::assign(const XPathValue<std::string>& key,
const XPathValue<std::string>& value,
const Element<std::string>& assignElem) {
switch (key.type()) {
- case NODE_SET: {
- switch (value.type()) {
- case STRING:
- assign(key.asNodeSet(), value.asString(), assignElem);
- break;
- case BOOL:
- assign(key.asNodeSet(), value.asBool(), assignElem);
- break;
- case NUMBER:
- assign(key.asNodeSet(), value.asNumber(), assignElem);
- break;
- case NODE_SET:
- assign(key.asNodeSet(), value.asNodeSet(), assignElem);
- break;
- case ANY:
- throw Event("error.execution", Event::PLATFORM);
- }
- break;
+ case NODE_SET: {
+ if (key.asNodeSet().size() == 0) {
+ throw Event("error.execution", Event::PLATFORM);
}
+ switch (value.type()) {
case STRING:
+ assign(key.asNodeSet(), value.asString(), assignElem);
+ break;
case BOOL:
+ assign(key.asNodeSet(), value.asBool(), assignElem);
+ break;
case NUMBER:
+ assign(key.asNodeSet(), value.asNumber(), assignElem);
+ break;
+ case NODE_SET:
+ assign(key.asNodeSet(), value.asNodeSet(), assignElem);
+ break;
case ANY:
throw Event("error.execution", Event::PLATFORM);
+ }
+ break;
+ }
+ case STRING:
+ case BOOL:
+ case NUMBER:
+ case ANY:
+ throw Event("error.execution", Event::PLATFORM);
}
}
void XPathDataModel::assign(const XPathValue<std::string>& key,
- const NodeSet<std::string>& value,
- const Element<std::string>& assignElem) {
+ const NodeSet<std::string>& value,
+ const Element<std::string>& assignElem) {
switch (key.type()) {
- case NODE_SET: {
- assign(key.asNodeSet(), value, assignElem);
- break;
- }
- case STRING:
- case BOOL:
- case NUMBER:
- case ANY:
- throw Event("error.execution", Event::PLATFORM);
+ case NODE_SET: {
+ assign(key.asNodeSet(), value, assignElem);
+ break;
+ }
+ case STRING:
+ case BOOL:
+ case NUMBER:
+ case ANY:
+ throw Event("error.execution", Event::PLATFORM);
}
}
@@ -404,7 +523,7 @@ void XPathDataModel::assign(const NodeSet<std::string>& key,
}
}
}
-
+
void XPathDataModel::assign(const NodeSet<std::string>& key,
const double value,
const Element<std::string>& assignElem) {
@@ -429,6 +548,7 @@ void XPathDataModel::assign(const NodeSet<std::string>& key,
break;
}
default:
+// std::cout << key[i].getNodeType() << std::endl;
throw Event("error.execution", Event::PLATFORM);
break;
}
@@ -436,23 +556,23 @@ void XPathDataModel::assign(const NodeSet<std::string>& key,
}
void XPathDataModel::assign(const Element<std::string>& key,
- const NodeSet<std::string>& value,
- const Element<std::string>& assignElem) {
+ const NodeSet<std::string>& value,
+ const Element<std::string>& assignElem) {
Element<std::string> element(key);
if (false) {
- } else if (HAS_ATTR(assignElem, "type") && boost::iequals(ATTR(assignElem, "type"), "firstchild")) {
+ } else if (assignElem && HAS_ATTR(assignElem, "type") && boost::iequals(ATTR(assignElem, "type"), "firstchild")) {
// firstchild: Insert the value specified by 'expr' before all of the children at 'location'.
for (int i = value.size(); i; i--) {
Node<std::string> importedNode = _doc.importNode(value[i-1], true);
element.insertBefore(importedNode, element.getFirstChild());
}
- } else if (HAS_ATTR(assignElem, "type") && boost::iequals(ATTR(assignElem, "type"), "lastchild")) {
+ } else if (assignElem && HAS_ATTR(assignElem, "type") && boost::iequals(ATTR(assignElem, "type"), "lastchild")) {
// lastchild: Insert the value specified by 'expr' after all of the children at 'location'.
for (int i = 0; i < value.size(); i++) {
Node<std::string> importedNode = _doc.importNode(value[i], true);
element.appendChild(importedNode);
}
- } else if (HAS_ATTR(assignElem, "type") && boost::iequals(ATTR(assignElem, "type"), "previoussibling")) {
+ } else if (assignElem && HAS_ATTR(assignElem, "type") && boost::iequals(ATTR(assignElem, "type"), "previoussibling")) {
// previoussibling: Insert the value specified by 'expr' before the
// node specified by 'location', keeping the same parent.
Node<std::string> parent = element.getParentNode();
@@ -462,7 +582,7 @@ void XPathDataModel::assign(const Element<std::string>& key,
Node<std::string> importedNode = _doc.importNode(value[i], true);
parent.insertBefore(importedNode, element);
}
- } else if (HAS_ATTR(assignElem, "type") && boost::iequals(ATTR(assignElem, "type"), "nextsibling")) {
+ } else if (assignElem && HAS_ATTR(assignElem, "type") && boost::iequals(ATTR(assignElem, "type"), "nextsibling")) {
// nextsibling: Insert the value specified by 'expr' after the node
// specified by 'location', keeping the same parent.
Node<std::string> parent = element.getParentNode();
@@ -477,7 +597,7 @@ void XPathDataModel::assign(const Element<std::string>& key,
parent.appendChild(importedNode);
}
}
- } else if (HAS_ATTR(assignElem, "type") && boost::iequals(ATTR(assignElem, "type"), "replace")) {
+ } else if (assignElem && HAS_ATTR(assignElem, "type") && boost::iequals(ATTR(assignElem, "type"), "replace")) {
// replace: Replace the node specified by 'location' by the value specified by 'expr'.
Node<std::string> parent = element.getParentNode();
if (!parent)
@@ -486,7 +606,7 @@ void XPathDataModel::assign(const Element<std::string>& key,
throw Event("error.execution", Event::PLATFORM);
Node<std::string> importedNode = _doc.importNode(value[0], true);
parent.replaceChild(importedNode, element);
- } else if (HAS_ATTR(assignElem, "type") && boost::iequals(ATTR(assignElem, "type"), "delete")) {
+ } else if (assignElem && HAS_ATTR(assignElem, "type") && boost::iequals(ATTR(assignElem, "type"), "delete")) {
// delete: Delete the node specified by 'location'. ('expr' is ignored.).
Node<std::string> parent = element.getParentNode();
if (!parent)
@@ -510,6 +630,13 @@ NodeSetVariableResolver::resolveVariable(const std::string& namepaceUri,
if(n == _variables.end()) {
throw Event("error.execution");
}
+#if 0
+ std::cout << std::endl << name << ":" << std::endl;
+ for (int i = 0; i < n->second.size(); i++) {
+ std::cout << n->second[i].getNodeType() << " | " << n->second[i] << std::endl;
+ }
+ std::cout << std::endl;
+#endif
return XPathValue<std::string>(new NodeSetValue<std::string>(n->second));
}
diff --git a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.h b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.h
index 391af0b..7140b2f 100644
--- a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.h
+++ b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.h
@@ -58,7 +58,7 @@ public:
bool isDeclared(const std::string& name) {
return _variables.find(name) != _variables.end();
}
-
+
private:
std::map<std::string, Arabica::XPath::NodeSet<std::string> > _variables;
friend class XPathDataModel;
@@ -82,6 +82,11 @@ public:
virtual bool validate(const std::string& location, const std::string& schema);
virtual uint32_t getLength(const std::string& expr);
+ virtual void setForeach(const std::string& item,
+ const std::string& array,
+ const std::string& index,
+ uint32_t iteration);
+
virtual void pushContext();
virtual void popContext();
@@ -109,6 +114,8 @@ protected:
Arabica::DOM::Element<std::string> _datamodel;
Arabica::DOM::Document<std::string> _doc;
+ bool isValidIdentifier(const std::string& identifier);
+
// resolve value to its type
void assign(const Arabica::XPath::XPathValue<std::string>& key,
const Arabica::XPath::XPathValue<std::string>& value,
@@ -116,7 +123,7 @@ protected:
void assign(const Arabica::XPath::XPathValue<std::string>& key,
const Arabica::XPath::NodeSet<std::string>& value,
const Arabica::DOM::Element<std::string>& assignElem);
-
+
// assign value to a nodeset key
void assign(const Arabica::XPath::NodeSet<std::string>& key,
const std::string& value,
@@ -130,12 +137,19 @@ protected:
void assign(const Arabica::XPath::NodeSet<std::string>& key,
const Arabica::XPath::NodeSet<std::string>& value,
const Arabica::DOM::Element<std::string>& assignElem);
-
+
// assign value to an element key (from nodeset)
void assign(const Arabica::DOM::Element<std::string>& key,
const Arabica::XPath::NodeSet<std::string>& value,
const Arabica::DOM::Element<std::string>& assignElem);
+
+ // assign value to a text node key (from nodeset)
+ void assign(const Arabica::DOM::Text<std::string>& key,
+ const Arabica::XPath::NodeSet<std::string>& value,
+ const Arabica::DOM::Element<std::string>& assignElem);
+
+
NodeSetVariableResolver _varResolver;
XPathFunctionResolver _funcResolver;
diff --git a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp
index 09195bf..1d6394e 100644
--- a/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp
+++ b/src/uscxml/plugins/ioprocessor/basichttp/BasicHTTPIOProcessor.cpp
@@ -73,15 +73,32 @@ void BasicHTTPIOProcessor::httpRecvRequest(const HTTPServer::Request& req) {
reqEvent.type = Event::EXTERNAL;
bool scxmlStructFound = false;
- if (reqEvent.data.compound["header"].compound.find("_scxmleventstruct") != reqEvent.data.compound["header"].compound.end()) {
- // TODO: this looses all other information
- reqEvent = Event::fromXML(evhttp_decode_uri(reqEvent.data.compound["header"].compound["_scxmleventstruct"].atom.c_str()));
- scxmlStructFound = true;
- }
- if (reqEvent.data.compound["header"].compound.find("_scxmleventname") != reqEvent.data.compound["header"].compound.end()) {
- reqEvent.name = evhttp_decode_uri(reqEvent.data.compound["header"].compound["_scxmleventname"].atom.c_str());
+ if (reqEvent.data.compound["header"].compound.find("Content-Type") != reqEvent.data.compound["header"].compound.end() &&
+ boost::iequals(reqEvent.data.compound["header"].compound["Content-Type"].atom, "application/x-www-form-urlencoded")) {
+ std::stringstream ss(reqEvent.data.compound["content"].atom);
+ std::string term;
+ while(std::getline(ss, term, '&')) {
+ size_t split = term.find_first_of("=");
+ if (split != std::string::npos) {
+ std::string key = evhttp_decode_uri(term.substr(0, split).c_str());
+ std::string value = evhttp_decode_uri(term.substr(split + 1).c_str());
+ if (boost::iequals(key, "_scxmleventname")) {
+ reqEvent.name = value;
+ } else {
+ reqEvent.data.compound[key] = value;
+ }
+ }
+ }
+ } else {
+ if (reqEvent.data.compound["header"].compound.find("_scxmleventstruct") != reqEvent.data.compound["header"].compound.end()) {
+ // TODO: this looses all other information
+ reqEvent = Event::fromXML(evhttp_decode_uri(reqEvent.data.compound["header"].compound["_scxmleventstruct"].atom.c_str()));
+ scxmlStructFound = true;
+ }
+ if (reqEvent.data.compound["header"].compound.find("_scxmleventname") != reqEvent.data.compound["header"].compound.end()) {
+ reqEvent.name = evhttp_decode_uri(reqEvent.data.compound["header"].compound["_scxmleventname"].atom.c_str());
+ }
}
-
std::map<std::string, Data>::iterator headerIter = reqEvent.data.compound["header"].compound.begin();
while(headerIter != reqEvent.data.compound["header"].compound.end()) {
reqEvent.data.compound[headerIter->first] = Data(evhttp_decode_uri(headerIter->second.atom.c_str()), Data::VERBATIM);
@@ -118,12 +135,12 @@ void BasicHTTPIOProcessor::httpRecvRequest(const HTTPServer::Request& req) {
}
void BasicHTTPIOProcessor::send(const SendRequest& req) {
-
+
if (req.target.length() == 0) {
_interpreter->receiveInternal(Event("error.communication", Event::PLATFORM));
return;
}
-
+
bool isLocal = false;
std::string target;
if (!boost::equals(req.target, _url)) {
@@ -133,17 +150,23 @@ void BasicHTTPIOProcessor::send(const SendRequest& req) {
target = _url;
}
URL targetURL(target);
+ std::stringstream kvps;
+ std::string kvpSeperator;
// event name
if (req.name.size() > 0) {
- targetURL.addOutHeader("_scxmleventname", evhttp_encode_uri(req.name.c_str()));
+ kvps << kvpSeperator << evhttp_encode_uri("_scxmleventname") << "=" << evhttp_encode_uri(req.name.c_str());
+ kvpSeperator = "&";
+// targetURL.addOutHeader("_scxmleventname", evhttp_encode_uri(req.name.c_str()));
}
// event namelist
if (req.namelist.size() > 0) {
std::map<std::string, std::string>::const_iterator namelistIter = req.namelist.begin();
while (namelistIter != req.namelist.end()) {
- targetURL.addOutHeader(namelistIter->first, namelistIter->second);
+ kvps << kvpSeperator << evhttp_encode_uri(namelistIter->first.c_str()) << "=" << evhttp_encode_uri(namelistIter->second.c_str());
+ kvpSeperator = "&";
+// targetURL.addOutHeader(namelistIter->first, namelistIter->second);
namelistIter++;
}
}
@@ -152,15 +175,19 @@ void BasicHTTPIOProcessor::send(const SendRequest& req) {
if (req.params.size() > 0) {
std::multimap<std::string, std::string>::const_iterator paramIter = req.params.begin();
while (paramIter != req.params.end()) {
- targetURL.addOutHeader(paramIter->first, paramIter->second);
+ kvps << kvpSeperator << evhttp_encode_uri(paramIter->first.c_str()) << "=" << evhttp_encode_uri(paramIter->second.c_str());
+ kvpSeperator = "&";
+// targetURL.addOutHeader(paramIter->first, paramIter->second);
paramIter++;
}
}
// content
- if (req.content.size() > 0)
+ if (kvps.str().size() > 0) {
+ targetURL.setOutContent(kvps.str());
+ } else if (req.content.size() > 0) {
targetURL.setOutContent(req.content);
-
+ }
targetURL.setRequestType("post");
targetURL.addMonitor(this);
diff --git a/src/uscxml/plugins/ioprocessor/modality/MMIComponent.h b/src/uscxml/plugins/ioprocessor/modality/MMIComponent.h
index bee568b..ba3f2c8 100644
--- a/src/uscxml/plugins/ioprocessor/modality/MMIComponent.h
+++ b/src/uscxml/plugins/ioprocessor/modality/MMIComponent.h
@@ -19,7 +19,7 @@ public:
virtual std::set<std::string> getNames() {
return std::set<std::string>();
};
-
+
virtual Data getDataModelVariables();
virtual void send(const SendRequest& req);
@@ -37,7 +37,7 @@ public:
virtual NewContextResponse newContext(const NewContextRequest&);
virtual DoneNotification done(const DoneNotification&);
// virtual ExtensionNotification extension(const ExtensionNotification&);
-
+
};
diff --git a/src/uscxml/plugins/ioprocessor/modality/MMIMessages.cpp b/src/uscxml/plugins/ioprocessor/modality/MMIMessages.cpp
index ed92fac..717e174 100644
--- a/src/uscxml/plugins/ioprocessor/modality/MMIMessages.cpp
+++ b/src/uscxml/plugins/ioprocessor/modality/MMIMessages.cpp
@@ -24,14 +24,14 @@ Arabica::DOM::Document<std::string> MMIMessage::toXML() {
if (data.size() > 0) {
Element<std::string> dataElem = doc.createElementNS(nameSpace, "data");
-
+
// try to parse content
std::stringstream* ss = new std::stringstream();
(*ss) << data;
std::auto_ptr<std::istream> ssPtr(ss);
Arabica::SAX::InputSource<std::string> inputSource;
inputSource.setByteStream(ssPtr);
-
+
Arabica::SAX2DOM::Parser<std::string> parser;
if(parser.parse(inputSource)) {
Node<std::string> importedNode = doc.importNode(parser.getDocument().getDocumentElement(), true);
@@ -40,9 +40,9 @@ Arabica::DOM::Document<std::string> MMIMessage::toXML() {
Text<std::string> textElem = doc.createTextNode(data);
dataElem.appendChild(textElem);
}
- msgElem.appendChild(dataElem);
+ msgElem.appendChild(dataElem);
}
-
+
mmiElem.appendChild(msgElem);
doc.appendChild(mmiElem);
std::cout << doc;
@@ -67,7 +67,7 @@ Arabica::DOM::Document<std::string> ContentRequest::toXML() {
contentURLElem.setAttributeNS(nameSpace, "max-age", contentURL.maxAge);
msgElem.appendChild(contentURLElem);
}
-
+
if (content.size() > 0) {
Element<std::string> contentElem = doc.createElementNS(nameSpace, "content");
@@ -77,7 +77,7 @@ Arabica::DOM::Document<std::string> ContentRequest::toXML() {
std::auto_ptr<std::istream> ssPtr(ss);
Arabica::SAX::InputSource<std::string> inputSource;
inputSource.setByteStream(ssPtr);
-
+
Arabica::SAX2DOM::Parser<std::string> parser;
if(parser.parse(inputSource)) {
Node<std::string> importedNode = doc.importNode(parser.getDocument().getDocumentElement(), true);
@@ -117,12 +117,12 @@ Arabica::DOM::Document<std::string> StatusResponse::toXML() {
Arabica::DOM::Document<std::string> StatusInfoResponse::toXML() {
Document<std::string> doc = StatusResponse::toXML();
Element<std::string> msgElem = Element<std::string>(doc.getDocumentElement().getFirstChild());
-
+
Element<std::string> statusInfoElem = doc.createElementNS(nameSpace, "StatusInfo");
Text<std::string> statusInfoText = doc.createTextNode(statusInfo);
statusInfoElem.appendChild(statusInfoText);
msgElem.appendChild(statusInfoElem);
-
+
return doc;
}
@@ -135,7 +135,7 @@ Arabica::DOM::Document<std::string> StatusRequest::toXML() {
} else {
msgElem.setAttributeNS(nameSpace, "RequestAutomaticUpdate", "false");
}
-
+
return doc;
}
@@ -153,14 +153,14 @@ MMIMessage MMIMessage::fromXML(const Arabica::DOM::Document<std::string>& doc) {
// msg.data = msgElem.getAttributeNS("http://www.w3.org/2008/04/mmi-arch", "Data");
msg.requestId = msgElem.getAttributeNS("http://www.w3.org/2008/04/mmi-arch", "RequestID");
msg.tagName = msgElem.getLocalName();
-
+
Element<std::string> dataElem;
node = msgElem.getFirstChild();
while (node) {
if (node.getNodeType() == Node_base::ELEMENT_NODE)
dataElem = Element<std::string>(node);
- if (dataElem && boost::iequals(dataElem.getLocalName(), "data"))
- break;
+ if (dataElem && boost::iequals(dataElem.getLocalName(), "data"))
+ break;
node = node.getNextSibling();
}
@@ -176,7 +176,7 @@ MMIMessage MMIMessage::fromXML(const Arabica::DOM::Document<std::string>& doc) {
}
msg.data = ss.str();
}
-
+
return msg;
}
@@ -203,13 +203,13 @@ ContentRequest ContentRequest::fromXML(const Arabica::DOM::Document<std::string>
}
Element<std::string> msgElem(node);
Element<std::string> contentElem;
-
+
node = msgElem.getFirstChild();
while (node) {
if (node.getNodeType() == Node_base::ELEMENT_NODE) {
contentElem = Element<std::string>(node);
if (boost::iequals(contentElem.getLocalName(), "content") ||
- boost::iequals(contentElem.getLocalName(), "contentURL"))
+ boost::iequals(contentElem.getLocalName(), "contentURL"))
break;
}
node = node.getNextSibling();
@@ -233,7 +233,7 @@ ContentRequest ContentRequest::fromXML(const Arabica::DOM::Document<std::string>
msg.contentURL.fetchTimeout = contentElem.getAttributeNS("http://www.w3.org/2008/04/mmi-arch", "fetchtimeout");
}
}
-
+
//msg.content = msgElem.getAttributeNS("http://www.w3.org/2008/04/mmi-arch", "Context");
return msg;
}
@@ -294,7 +294,7 @@ StatusInfoResponse StatusInfoResponse::fromXML(const Arabica::DOM::Document<std:
}
node = node.getNextSibling();
}
-
+
if (statusInfoElem && boost::iequals(statusInfoElem.getLocalName(), "statusInfo")) {
node = statusInfoElem.getFirstChild();
while (node) {
@@ -305,11 +305,11 @@ StatusInfoResponse StatusInfoResponse::fromXML(const Arabica::DOM::Document<std:
node = node.getNextSibling();
}
}
-
+
return msg;
}
-
+
StatusRequest StatusRequest::fromXML(const Arabica::DOM::Document<std::string>& doc) {
StatusRequest msg(ContextualizedRequest::fromXML(doc));
Node<std::string> node = doc.getDocumentElement().getFirstChild();
@@ -320,7 +320,7 @@ StatusRequest StatusRequest::fromXML(const Arabica::DOM::Document<std::string>&
}
Element<std::string> msgElem(node);
std::string autoUpdate = msgElem.getAttributeNS("http://www.w3.org/2008/04/mmi-arch", "RequestAutomaticUpdate");
-
+
if (boost::iequals(autoUpdate, "true")) {
msg.automaticUpdate = true;
} else if(boost::iequals(autoUpdate, "on")) {
diff --git a/src/uscxml/plugins/ioprocessor/modality/MMIMessages.h b/src/uscxml/plugins/ioprocessor/modality/MMIMessages.h
index af31efe..a5328ac 100644
--- a/src/uscxml/plugins/ioprocessor/modality/MMIMessages.h
+++ b/src/uscxml/plugins/ioprocessor/modality/MMIMessages.h
@@ -18,11 +18,11 @@ public:
std::string tagName;
static std::string nameSpace;
-
+
protected:
MMIMessage() {}
};
-
+
class NewContextRequest : public MMIMessage {
public:
NewContextRequest() {
@@ -56,7 +56,7 @@ public:
return ContextualizedRequest::fromXML(doc);
}
};
-class ResumeRequest : public ContextualizedRequest {
+class ResumeRequest : public ContextualizedRequest {
public:
ResumeRequest() {
tagName = "ResumeRequest";
@@ -67,7 +67,7 @@ public:
}
};
-class CancelRequest : public ContextualizedRequest {
+class CancelRequest : public ContextualizedRequest {
public:
CancelRequest() {
tagName = "CancelRequest";
@@ -78,7 +78,7 @@ public:
}
};
-class ClearContextRequest : public ContextualizedRequest {
+class ClearContextRequest : public ContextualizedRequest {
public:
ClearContextRequest() {
tagName = "ClearContextRequest";
@@ -89,7 +89,7 @@ public:
}
};
-class StatusRequest : public ContextualizedRequest {
+class StatusRequest : public ContextualizedRequest {
public:
StatusRequest() {
tagName = "StatusRequest";
@@ -109,7 +109,7 @@ public:
std::string maxAge;
std::string fetchTimeout;
};
-
+
virtual Arabica::DOM::Document<std::string> toXML();
static ContentRequest fromXML(const Arabica::DOM::Document<std::string>& doc);
std::string content;
@@ -119,7 +119,7 @@ protected:
ContentRequest(const ContextualizedRequest& father) : ContextualizedRequest(father) {}
};
-class PrepareRequest : public ContentRequest {
+class PrepareRequest : public ContentRequest {
public:
PrepareRequest() {
tagName = "PrepareRequest";
@@ -130,7 +130,7 @@ public:
}
};
-class StartRequest : public ContentRequest {
+class StartRequest : public ContentRequest {
public:
StartRequest() {
tagName = "StartRequest";
@@ -159,10 +159,10 @@ protected:
class StatusResponse : public ContextualizedRequest {
public:
enum Status {
- ALIVE = 0,
- DEAD = 1,
- SUCCESS = 2,
- FAILURE = 3
+ ALIVE = 0,
+ DEAD = 1,
+ SUCCESS = 2,
+ FAILURE = 3
};
StatusResponse() {
@@ -196,7 +196,7 @@ public:
return StatusInfoResponse::fromXML(doc);
}
};
-
+
class StartResponse : public StatusInfoResponse {
public:
StartResponse() {
@@ -207,7 +207,7 @@ public:
return StatusInfoResponse::fromXML(doc);
}
};
-
+
class CancelResponse : public StatusInfoResponse {
public:
CancelResponse() {
@@ -218,7 +218,7 @@ public:
return StatusInfoResponse::fromXML(doc);
}
};
-
+
class PauseResponse : public StatusInfoResponse {
public:
PauseResponse() {
@@ -229,7 +229,7 @@ public:
return StatusInfoResponse::fromXML(doc);
}
};
-
+
class ResumeResponse : public StatusInfoResponse {
public:
ResumeResponse() {
@@ -240,7 +240,7 @@ public:
return StatusInfoResponse::fromXML(doc);
}
};
-
+
class ClearContextResponse : public StatusInfoResponse {
public:
ClearContextResponse() {
@@ -251,7 +251,7 @@ public:
return StatusInfoResponse::fromXML(doc);
}
};
-
+
class NewContextResponse : public StatusInfoResponse {
public:
NewContextResponse() {
@@ -263,7 +263,7 @@ public:
}
};
-
+
class DoneNotification : public StatusInfoResponse {
public:
DoneNotification() {
diff --git a/src/uscxml/server/HTTPServer.cpp b/src/uscxml/server/HTTPServer.cpp
index 0d5feee..70b272f 100644
--- a/src/uscxml/server/HTTPServer.cpp
+++ b/src/uscxml/server/HTTPServer.cpp
@@ -114,10 +114,14 @@ void HTTPServer::httpRecvReqCallback(struct evhttp_request *req, void *callbackD
// evhttp_send_error(req, 404, NULL);
// return;
+ std::stringstream raw;
+
evhttp_request_own(req);
Request request;
request.curlReq = req;
+
+
switch (evhttp_request_get_command(req)) {
case EVHTTP_REQ_GET:
request.data.compound["type"] = Data("get", Data::VERBATIM);
@@ -150,6 +154,18 @@ void HTTPServer::httpRecvReqCallback(struct evhttp_request *req, void *callbackD
request.data.compound["type"] = Data("unknown", Data::VERBATIM);
break;
}
+ raw << boost::to_upper_copy(request.data.compound["type"].atom);
+
+ request.data.compound["remoteHost"] = Data(req->remote_host, Data::VERBATIM);
+ request.data.compound["remotePort"] = Data(toStr(req->remote_port), Data::VERBATIM);
+ request.data.compound["httpMajor"] = Data(toStr((unsigned short)req->major), Data::VERBATIM);
+ request.data.compound["httpMinor"] = Data(toStr((unsigned short)req->minor), Data::VERBATIM);
+ request.data.compound["uri"] = Data(HTTPServer::getBaseURL() + req->uri, Data::VERBATIM);
+ request.data.compound["path"] = Data(evhttp_uri_get_path(evhttp_request_get_evhttp_uri(req)), Data::VERBATIM);
+
+ raw << " " << request.data.compound["path"].atom;
+ raw << " HTTP/" << request.data.compound["httpMajor"].atom << "." << request.data.compound["httpMinor"].atom;
+ raw << std::endl;
struct evkeyvalq *headers;
struct evkeyval *header;
@@ -159,14 +175,9 @@ void HTTPServer::httpRecvReqCallback(struct evhttp_request *req, void *callbackD
headers = evhttp_request_get_input_headers(req);
for (header = headers->tqh_first; header; header = header->next.tqe_next) {
request.data.compound["header"].compound[header->key] = Data(header->value, Data::VERBATIM);
+ raw << header->key << ": " << header->value << std::endl;
}
-
- request.data.compound["remoteHost"] = Data(req->remote_host, Data::VERBATIM);
- request.data.compound["remotePort"] = Data(toStr(req->remote_port), Data::VERBATIM);
- request.data.compound["httpMajor"] = Data(toStr((unsigned short)req->major), Data::VERBATIM);
- request.data.compound["httpMinor"] = Data(toStr((unsigned short)req->minor), Data::VERBATIM);
- request.data.compound["uri"] = Data(HTTPServer::getBaseURL() + req->uri, Data::VERBATIM);
- request.data.compound["path"] = Data(evhttp_uri_get_path(evhttp_request_get_evhttp_uri(req)), Data::VERBATIM);
+ raw << std::endl;
// This was used for debugging
// if (boost::ends_with(request.data.compound["path"].atom, ".png")) {
@@ -207,6 +218,8 @@ void HTTPServer::httpRecvReqCallback(struct evhttp_request *req, void *callbackD
}
}
+ raw << request.data.compound["content"].atom;
+
// decode content
if (request.data.compound.find("content") != request.data.compound.end() &&
request.data.compound["header"].compound.find("Content-Type") != request.data.compound["header"].compound.end()) {
@@ -219,6 +232,8 @@ void HTTPServer::httpRecvReqCallback(struct evhttp_request *req, void *callbackD
}
}
+ request.raw = raw.str();
+
if (callbackData == NULL) {
HTTPServer::getInstance()->processByMatchingServlet(request);
} else {