This commit is contained in:
2015-10-20 02:25:46 +02:00
parent a2cfb17ed4
commit 6c35229ffe
5 changed files with 238 additions and 45 deletions
+9 -4
View File
@@ -8,23 +8,28 @@
{
"type": "sitemap/sitemap_template#/definitions/text_element",
"label": "Switch0 Text",
"icon" : "some_icon01",
"format" : "Format: %1%",
"device": {
"id": "dummySwitch0",
"pointer": ""
"pointer": "/switch/value"
}
}, {
"type": "sitemap/sitemap_template#/definitions/switch_element",
"label": "Switch0",
"icon" : "some_icon02",
"format" : "bla: %1%",
"device": {
"id": "dummySwitch0",
"pointer": ""
"pointer": "/switch/value"
}
}, {
"type": "sitemap/sitemap_template#/definitions/slider_element",
"label": "Slider0",
"icon" : "some_icon03",
"device": {
"id": "dummySlider0",
"pointer": ""
"id": "dummyDimmer0",
"pointer": "/dimmer/value"
},
"min": 0,
"max": 1,
@@ -34,6 +34,8 @@ class SitemapTemplate
public:
virtual SitemapService* getParent() noexcept = 0;
virtual std::weak_ptr<Page> getRootPage() noexcept = 0;
virtual libvariant::Variant renderSitemap() = 0;
};
@@ -47,6 +49,8 @@ public:
virtual size_t elementCount() noexcept = 0;
virtual std::weak_ptr<Element> getElement(size_t index) noexcept = 0;
virtual std::vector<std::weak_ptr<Element>> getElements() noexcept = 0;
virtual libvariant::Variant renderSitemap() = 0;
};
@@ -72,6 +76,9 @@ public:
virtual bool isComposite() noexcept = 0;
virtual ElementType getType() noexcept = 0;
virtual const std::string& getTypeString() noexcept = 0;
virtual libvariant::Variant renderSitemap() = 0;
};
@@ -103,6 +110,7 @@ public:
virtual const std::string& getDeviceID() noexcept = 0;
virtual std::weak_ptr<devicerepository::Device> getDevice() noexcept = 0;
virtual const std::string& getPointer() noexcept = 0;
virtual bool deviceExists() noexcept = 0;
};
@@ -61,15 +61,16 @@ namespace {
struct _elementTypeInfo {
std::string typeName;
std::string typeString;
ElementType type;
bool isComposite;
};
_elementTypeInfo elementTypeInfo[] = {
{ "sitemap/sitemap_template#/definitions/frame_element", ElementType::Frame, true },
{ "sitemap/sitemap_template#/definitions/text_element", ElementType::Text, false },
{ "sitemap/sitemap_template#/definitions/slider_element", ElementType::Slider, false },
{ "sitemap/sitemap_template#/definitions/switch_element", ElementType::Switch, false }
{ "sitemap/sitemap_template#/definitions/frame_element", "sitemap/sitemap#/definitions/frame_element", ElementType::Frame, true },
{ "sitemap/sitemap_template#/definitions/text_element", "sitemap/sitemap#/definitions/text_element", ElementType::Text, false },
{ "sitemap/sitemap_template#/definitions/slider_element", "sitemap/sitemap#/definitions/slider_element", ElementType::Slider, false },
{ "sitemap/sitemap_template#/definitions/switch_element", "sitemap/sitemap#/definitions/switch_element", ElementType::Switch, false }
};
}
@@ -104,7 +105,7 @@ std::shared_ptr<ElementImpl> PageImpl::createElement(const libvariant::Variant&
addParams.Erase("type");
_elementTypeInfo* info = nullptr;
for (auto& e : elementTypeInfo) {
if (typeStr.compare(e.typeName)) {
if (typeStr.compare(e.typeName) == 0) {
info = &e;
break;
}
@@ -132,33 +133,58 @@ std::shared_ptr<ElementImpl> PageImpl::createElement(const libvariant::Variant&
addParams.Erase("icon");
}
}
if (info->isComposite) {
newElement = std::make_shared<CompositeElementImpl>(*this, info->type, label, icon, parent);
switch (info->type) {
case ElementType::Frame:
newElement = std::make_shared<FrameElementImpl>(*this, info->typeString, label, icon, parent);
break;
default:
throw std::runtime_error((boost::format("Registered element type %1% is unknown.") % info->typeName).str());
}
} else {
std::string format;
auto formatRaw = param["format"];
if (!formatRaw.IsNull() && !formatRaw.IsString()) {
throw std::runtime_error("format is not a string.");
} else if (formatRaw.IsString()) {
format = formatRaw.AsString();
addParams.Erase("format");
if (param.Contains("format")) {
auto formatRaw = param["format"];
if (!formatRaw.IsString()) {
throw std::runtime_error("format is not a string.");
} else {
format = formatRaw.AsString();
addParams.Erase("format");
}
}
std::shared_ptr<DeviceImpl> device;
auto deviceRaw = param["device"];
if (!deviceRaw.IsNull() && !deviceRaw.IsMap()) {
throw std::runtime_error("device is not a map.");
} else if (deviceRaw.IsMap()) {
device = sitemap.createDevice(deviceRaw);
addParams.Erase("device");
if (param.Contains("device")) {
auto deviceRaw = param["device"];
if (!deviceRaw.IsMap()) {
throw std::runtime_error("device is not a map.");
} else {
device = sitemap.createDevice(deviceRaw);
addParams.Erase("device");
}
}
auto pageRaw = param["page"];
if (!pageRaw.IsNull() && !pageRaw.IsMap()) {
throw std::runtime_error("page is not a map.");
} else if (pageRaw.IsMap()) {
addParams.Erase("page");
libvariant::Variant pageRaw;
if (param.Contains("page")) {
pageRaw = param["page"];
if (!pageRaw.IsMap()) {
throw std::runtime_error("page is not a map.");
} else {
addParams.Erase("page");
}
}
std::shared_ptr<AtomicElementImpl> newAElement;
switch (info->type) {
case ElementType::Text:
newAElement = std::make_shared<TextElementImpl>(*this, info->typeString, label, icon, format, device, addParams, parent);
break;
case ElementType::Slider:
newAElement = std::make_shared<SliderElementImpl>(*this, info->typeString, label, icon, format, device, addParams, parent);
break;
case ElementType::Switch:
newAElement = std::make_shared<SwitchElementImpl>(*this, info->typeString, label, icon, format, device, addParams, parent);
break;
default:
throw std::runtime_error((boost::format("Registered element type %1% is unknown.") % info->typeName).str());
}
std::shared_ptr<AtomicElementImpl> newAElement = std::make_shared<AtomicElementImpl>(*this, info->type, label, icon, format, device, addParams, parent);
if (pageRaw.IsMap()) {
newAElement->createLinkedToPage(pageRaw);
}
@@ -188,6 +214,114 @@ std::shared_ptr<PageImpl> AtomicElementImpl::createLinkedToPage(const libvariant
}
libvariant::Variant SitemapTemplateImpl::renderSitemap() {
libvariant::Variant retval = libvariant::Variant::Map();
retval["title"] = title;
retval["rootpage"] = rootPage->renderSitemap();
retval["type"] = "sitemap/sitemap";
return retval;
}
libvariant::Variant PageImpl::renderSitemap() {
libvariant::Variant retval = libvariant::Variant::Map();
retval["title"] = title;
libvariant::Variant elements = libvariant::Variant::List();
for (auto i : this->elements) {
elements.Append(i->renderSitemap());
}
retval["elements"] = elements;
retval["type"] = "sitemap/sitemap#/definitions/page";
return retval;
}
libvariant::Variant CompositeElementImpl::renderSitemap() {
libvariant::Variant retval = libvariant::Variant::Map();
retval["label"] = label;
if (!icon.empty()) {
retval["icon"] = icon;
}
libvariant::Variant elements = libvariant::Variant::List();
for (auto i : this->elements) {
elements.Append(i->renderSitemap());
}
retval["elements"] = elements;
retval["type"] = typeString;
return retval;
}
libvariant::Variant AtomicElementImpl::renderSitemap() {
libvariant::Variant retval = libvariant::Variant::Map();
retval["label"] = label;
if (!icon.empty()) {
retval["icon"] = icon;
}
if (linkedToPage) {
retval["page"] = linkedToPage->renderSitemap();
}
retval["value"] = _getDeviceValue();
retval["type"] = typeString;
retval.Merge(additionalParams);
return retval;
}
libvariant::Variant AtomicElementImpl::_getDeviceValue() {
libvariant::Variant devState;
if (device->deviceExists()) {
try {
devState = device->getDevice().lock()->getCurrentState();
if (!device->getPointer().empty()) {
devState = devState.GetPath(device->getPointer());
}
} catch (...) {
devState = "NaN";
}
} else {
devState = "NaN";
}
if (!format.empty()) {
devState = (boost::format(format) % devState.AsString()).str();
}
return devState;
}
libvariant::Variant SliderElementImpl::_getDeviceValue() {
libvariant::Variant devState;
if (device->deviceExists()) {
try {
devState = device->getDevice().lock()->getCurrentState();
if (!device->getPointer().empty()) {
devState = devState.GetPath(device->getPointer());
}
devState = devState.AsDouble();
} catch (...) {
devState = "NaN";
}
} else {
devState = "NaN";
}
return devState;
}
libvariant::Variant SwitchElementImpl::_getDeviceValue() {
libvariant::Variant devState;
if (device->deviceExists()) {
try {
devState = device->getDevice().lock()->getCurrentState();
if (!device->getPointer().empty()) {
devState = devState.GetPath(device->getPointer());
}
devState = devState.AsBool();
} catch (...) {
devState = "NaN";
}
} else {
devState = "NaN";
}
return devState;
}
} // namespace sitemaptemplate
} // namespace sitemap
} // namespace service
@@ -49,6 +49,8 @@ public:
virtual SitemapService* getParent() noexcept override { return dynamic_cast<SitemapService*>(&parent); }
virtual std::weak_ptr<Page> getRootPage() noexcept override { return std::static_pointer_cast<Page>(rootPage); };
virtual libvariant::Variant renderSitemap() override;
};
@@ -76,6 +78,8 @@ public:
virtual std::weak_ptr<Element> getElement(size_t index) noexcept override
{ return std::static_pointer_cast<Element>(elements.at(index)); };
virtual std::vector<std::weak_ptr<Element>> getElements() noexcept override;
virtual libvariant::Variant renderSitemap() override;
};
@@ -88,6 +92,7 @@ protected:
uint64_t id;
bool compositeFlag;
ElementType type;
std::string typeString;
PageImpl& page;
CompositeElementImpl* parent;
@@ -98,10 +103,12 @@ public:
ElementImpl( PageImpl& page,
bool isComposite,
ElementType type,
std::string typeStr,
CompositeElementImpl* parent,
const std::string& label,
const std::string& icon )
: id(nextID.fetch_add(1)), compositeFlag(isComposite), type(type), page(page), parent(parent), label(label), icon(icon) {}
: id(nextID.fetch_add(1)), compositeFlag(isComposite), type(type), typeString(typeStr),
page(page), parent(parent), label(label), icon(icon) {}
virtual uint64_t getID() noexcept override { return id; }
virtual const std::string& getLabel() noexcept override { return label; }
@@ -112,6 +119,7 @@ public:
virtual bool isComposite() noexcept override { return compositeFlag; };
virtual ElementType getType() noexcept override { return type; }
virtual const std::string& getTypeString() noexcept override { return typeString; }
};
@@ -119,19 +127,21 @@ public:
class CompositeElementImpl
: public virtual CompositeElement,
public ElementImpl {
private:
protected:
std::vector<std::shared_ptr<ElementImpl>> elements;
public:
CompositeElementImpl(PageImpl& page, ElementType etype, const std::string& label, const std::string& icon,
CompositeElementImpl(PageImpl& page, ElementType etype, std::string typeStr, const std::string& label, const std::string& icon,
CompositeElementImpl* parent = nullptr)
: ElementImpl(page, true, etype, parent, label, icon) {}
: ElementImpl(page, true, etype, typeStr, parent, label, icon) {}
std::shared_ptr<ElementImpl> createElement(const libvariant::Variant& param);
virtual size_t elementCount() noexcept override { return elements.size(); }
virtual std::weak_ptr<Element> getElement(size_t index) noexcept override { return std::static_pointer_cast<Element>(elements.at(index)); }
virtual std::vector<std::weak_ptr<Element>> getElements() noexcept override;
virtual libvariant::Variant renderSitemap() override;
};
@@ -139,25 +149,64 @@ public:
class AtomicElementImpl
: public virtual AtomicElement,
public ElementImpl {
private:
protected:
std::string format;
std::shared_ptr<DeviceImpl> device;
libvariant::Variant additionalParams;
std::shared_ptr<PageImpl> linkedToPage;
virtual libvariant::Variant _getDeviceValue();
public:
AtomicElementImpl(PageImpl& page, ElementType etype, const std::string& label, const std::string& icon,
AtomicElementImpl(PageImpl& page, ElementType etype, std::string typeStr, const std::string& label, const std::string& icon,
const std::string& format, std::shared_ptr<DeviceImpl> device, libvariant::Variant additionalParams,
CompositeElementImpl* parent = nullptr)
: ElementImpl(page, false, etype, parent, label, icon), format(format), device(device), additionalParams(additionalParams) {}
: ElementImpl(page, false, etype, typeStr, parent, label, icon), format(format), device(device), additionalParams(additionalParams) {}
std::shared_ptr<PageImpl> createLinkedToPage(const libvariant::Variant& param);
virtual const std::string& getFormat() noexcept override { return format; }
virtual std::weak_ptr<Device> getDevice() noexcept override;
virtual const libvariant::Variant& getAdditionalParams() noexcept override { return additionalParams; }
virtual std::weak_ptr<Page> getLinkedToPage() noexcept override { return linkedToPage; }
virtual libvariant::Variant renderSitemap() override;
};
class FrameElementImpl : public CompositeElementImpl {
public:
FrameElementImpl(PageImpl& page, std::string typeStr, const std::string& label, const std::string& icon, CompositeElementImpl* parent = nullptr)
: CompositeElementImpl(page, ElementType::Frame, typeStr, label, icon, parent) {}
};
class TextElementImpl : public AtomicElementImpl {
public:
TextElementImpl(PageImpl& page, std::string typeStr, const std::string& label, const std::string& icon, const std::string& format,
std::shared_ptr<DeviceImpl> device, libvariant::Variant additionalParams, CompositeElementImpl* parent = nullptr)
: AtomicElementImpl(page, ElementType::Text, typeStr, label, icon, format, device, additionalParams, parent) {}
};
class SliderElementImpl : public AtomicElementImpl {
private:
virtual libvariant::Variant _getDeviceValue() override;
public:
SliderElementImpl(PageImpl& page, std::string typeStr, const std::string& label, const std::string& icon, const std::string& format,
std::shared_ptr<DeviceImpl> device, libvariant::Variant additionalParams, CompositeElementImpl* parent = nullptr)
: AtomicElementImpl(page, ElementType::Slider, typeStr, label, icon, format, device, additionalParams, parent) {}
};
class SwitchElementImpl : public AtomicElementImpl {
private:
virtual libvariant::Variant _getDeviceValue() override;
public:
SwitchElementImpl(PageImpl& page, std::string typeStr, const std::string& label, const std::string& icon, const std::string& format,
std::shared_ptr<DeviceImpl> device, libvariant::Variant additionalParams, CompositeElementImpl* parent = nullptr)
: AtomicElementImpl(page, ElementType::Switch, typeStr, label, icon, format, device, additionalParams, parent) {}
};
@@ -177,6 +226,7 @@ public:
virtual const std::string& getDeviceID() noexcept override { return deviceID; }
virtual std::weak_ptr<devicerepository::Device> getDevice() noexcept override { return device; }
virtual const std::string& getPointer() noexcept override { return pointer; }
virtual bool deviceExists() noexcept override { return !device.expired(); }
};
@@ -12,6 +12,7 @@
#include <Poco/Net/WebSocket.h>
#include "Poco/Net/NetException.h"
#include <Poco/Net/StreamSocket.h>
#include <hos/cosgi/service/sitemap/sitemap_template/SitemapTemplate.h>
namespace hos {
@@ -93,14 +94,9 @@ void SitemapHandler::__handleInfo(Poco::Net::HTTPServerRequest &req, Poco::Net::
std::string sitemapName = pathPieces[matchPieces.size()];
auto sitemap = service->getSitemap(sitemapName);
if (!sitemap.expired()) {
// Get info category
std::string category;
if (pathPieces.size() > matchPieces.size() + 1) {
category = pathPieces[matchPieces.size() + 1];
}
// Get path from url and append pointer parameter
std::stringstream path;
for (int i = matchPieces.size() + 2; i < pathPieces.size(); i++) {
for (int i = matchPieces.size() + 1; i < pathPieces.size(); i++) {
path << "/" << pathPieces[i];
}
std::string pointer;
@@ -110,8 +106,8 @@ void SitemapHandler::__handleInfo(Poco::Net::HTTPServerRequest &req, Poco::Net::
}
path << pointer;
}
// Get device info
Variant result = libvariant::Variant("ToDo: Do something");
// Render sitemap
Variant result = sitemap.lock()->renderSitemap();
// Return device info
handleResponse(req, resp, form, result);
} else {