This commit is contained in:
2015-10-19 02:06:47 +02:00
parent 8894fe5880
commit a2cfb17ed4
12 changed files with 688 additions and 232 deletions
+1 -1
View File
@@ -55,7 +55,7 @@ bundle(hos_cosgi_sitemap
${PROJECT_SOURCE_DIR}/src/BundleActivator
${PROJECT_SOURCE_DIR}/src/hos/cosgi/service/sitemap/SitemapServiceImpl
${PROJECT_SOURCE_DIR}/src/hos/cosgi/service/sitemap/webresource/SitemapHandler
${PROJECT_SOURCE_DIR}/src/hos/cosgi/service/sitemap/sitemap_template/SitemapTemplate
${PROJECT_SOURCE_DIR}/src/hos/cosgi/service/sitemap/sitemap_template/SitemapTemplateImpl
)
target_link_libraries(hos_cosgi_sitemap
@@ -4,6 +4,8 @@
#include <hos/cosgi/service/Interface.h>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <chrono>
#include <memory>
@@ -20,6 +22,7 @@ namespace devicerepository { class DeviceRepositoryService; }
// service namespace
namespace sitemap {
namespace sitemaptemplate { class SitemapTemplate; }
/**
* Public COSGI interface of the sitemap service.
@@ -48,6 +51,14 @@ public:
*/
virtual devicerepository::DeviceRepositoryService* getDeviceRepository() noexcept = 0;
virtual size_t sitemapCount() noexcept = 0;
virtual std::weak_ptr<sitemaptemplate::SitemapTemplate> getSitemap(std::string name) noexcept = 0;
virtual std::map<std::string, std::weak_ptr<sitemaptemplate::SitemapTemplate>> getSitemaps() noexcept = 0;
virtual std::vector<std::string> getSitemapNames() noexcept = 0;
};
@@ -0,0 +1,115 @@
#pragma once
#include <hos/cosgi/service/Interface.h>
#include <hos/cosgi/service/devicerepository/DeviceRepositoryService.h>
#include <Variant/Variant.h>
#include <string>
#include <chrono>
#include <vector>
#include <memory>
namespace hos {
namespace cosgi {
namespace service {
namespace sitemap {
class SitemapService;
namespace sitemaptemplate {
class Page;
class Element;
class AtomicElement;
class CompositeElement;
class Device;
class SitemapTemplate
: public virtual interface::Object {
public:
virtual SitemapService* getParent() noexcept = 0;
virtual std::weak_ptr<Page> getRootPage() noexcept = 0;
};
class Page
: public virtual interface::Object {
public:
virtual SitemapTemplate* getSiteMap() noexcept = 0;
virtual Page* getParent() noexcept = 0;
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;
};
enum class ElementType {
// composite elements
Frame,
// atomic elements
Text,
Switch,
Slider
};
class Element
: public virtual interface::Object {
public:
virtual uint64_t getID() noexcept = 0;
virtual const std::string& getLabel() noexcept = 0;
virtual const std::string& getIcon() noexcept = 0;
virtual Page* getPage() noexcept = 0;
virtual CompositeElement* getParent() noexcept = 0;
virtual bool isComposite() noexcept = 0;
virtual ElementType getType() noexcept = 0;
};
class CompositeElement
: public virtual Element {
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;
};
class AtomicElement
: public virtual Element {
public:
virtual const std::string& getFormat() noexcept = 0;
virtual std::weak_ptr<Device> getDevice() noexcept = 0;
virtual const libvariant::Variant& getAdditionalParams() noexcept = 0;
virtual std::weak_ptr<Page> getLinkedToPage() noexcept = 0;
};
class Device
: public virtual interface::Object {
public:
virtual const std::string& getDeviceID() noexcept = 0;
virtual std::weak_ptr<devicerepository::Device> getDevice() noexcept = 0;
virtual const std::string& getPointer() noexcept = 0;
};
} // namespace sitemaptemplate
} // namespace sitemap
} // namespace service
} // namespace cosgi
} // namespace hos
@@ -108,6 +108,9 @@
},
"icon": {
"type": "string"
},
"page": {
"type": "string"
}
}
},
@@ -1,5 +1,6 @@
#include "SitemapServiceImpl.h"
#include "sitemap_template/SitemapTemplateImpl.h"
// std
#include <exception>
#include <iostream>
@@ -106,7 +107,7 @@ void SitemapServiceImpl::addSitemap(const std::string& name, XmlRpc::XmlRpcValue
if (!rootpage.IsMap()) {
throw std::runtime_error("rootpage is not a map.");
}
std::shared_ptr<sitemaptemplate::SitemapTemplate> st = std::make_shared<sitemaptemplate::SitemapTemplate>(title);
std::shared_ptr<sitemaptemplate::SitemapTemplateImpl> st = std::make_shared<sitemaptemplate::SitemapTemplateImpl>(*this, title);
st->createPage(rootpage);
sitemapTemplates.insert({name, st});
} else {
@@ -117,6 +118,34 @@ void SitemapServiceImpl::addSitemap(const std::string& name, XmlRpc::XmlRpcValue
}
std::weak_ptr<sitemaptemplate::SitemapTemplate> SitemapServiceImpl::getSitemap(std::string name) noexcept {
auto i = sitemapTemplates.find(name);
if (i != sitemapTemplates.end()) {
return std::static_pointer_cast<sitemaptemplate::SitemapTemplate>(i->second);
} else {
return std::weak_ptr<sitemaptemplate::SitemapTemplate>();
}
}
std::map<std::string, std::weak_ptr<sitemaptemplate::SitemapTemplate>> SitemapServiceImpl::getSitemaps() noexcept {
std::map<std::string, std::weak_ptr<sitemaptemplate::SitemapTemplate>> retval;
for (auto i : sitemapTemplates) {
retval.insert({i.first, std::static_pointer_cast<sitemaptemplate::SitemapTemplate>(i.second)});
}
return retval;
}
std::vector<std::string> SitemapServiceImpl::getSitemapNames() noexcept {
std::vector<std::string> retval;
for (auto i : sitemapTemplates) {
retval.push_back(i.first);
}
return retval;
}
} /* namespace sitemap */
} /* namespace service */
} /* namespace cosgi */
@@ -6,7 +6,6 @@
#include <hos/cosgi/service/core/CoreService.h>
#include <hos/cosgi/service/devicerepository/DeviceRepositoryService.h>
#include <hos/cosgi/service/Implementation.h>
#include "sitemap_template/SitemapTemplate.h"
#include <ros/ros.h>
// std includes
#include <mutex>
@@ -14,12 +13,15 @@
#include <set>
#include <memory>
#include <string>
//#include "sitemap_template/SitemapTemplateImpl.h"
namespace hos {
namespace cosgi {
namespace service {
namespace sitemap {
namespace sitemaptemplate { class SitemapTemplateImpl; }
class SitemapServiceImpl
: public virtual SitemapService,
public implementation::Service<SitemapServiceImpl> {
@@ -35,7 +37,7 @@ private:
std::string hosStatusTopic = "/hos/status/updates";
bool initialized = false;
std::map<std::string, std::shared_ptr<sitemaptemplate::SitemapTemplate>> sitemapTemplates;
std::map<std::string, std::shared_ptr<sitemaptemplate::SitemapTemplateImpl>> sitemapTemplates;
void init() noexcept;
void addSitemap(const std::string& name, XmlRpc::XmlRpcValue& rawValue);
@@ -60,6 +62,17 @@ public:
}
virtual size_t sitemapCount() noexcept override {
return sitemapTemplates.size();
}
virtual std::weak_ptr<sitemaptemplate::SitemapTemplate> getSitemap(std::string name) noexcept override;
virtual std::map<std::string, std::weak_ptr<sitemaptemplate::SitemapTemplate>> getSitemaps() noexcept override;
virtual std::vector<std::string> getSitemapNames() noexcept override;
/* Internal */
bool isInitialized() noexcept { return initialized; }
@@ -1,60 +0,0 @@
#include "../sitemap_template/SitemapTemplate.h"
namespace hos {
namespace cosgi {
namespace service {
namespace sitemap {
namespace sitemaptemplate {
std::shared_ptr<Page> SitemapTemplate::createPage(const libvariant::Variant& param, std::weak_ptr<Page> parent) {
std::shared_ptr<Page> newPage;
if (parent.expired() && rootPage) {
throw std::runtime_error("There is already a root page.");
}
auto titleRaw = param["title"];
if (!titleRaw.IsString()) {
throw std::runtime_error("title is not a string.");
}
std::string title = titleRaw.AsString();
auto elements = param["elements"];
if (!elements.IsList()) {
throw std::runtime_error("elements is not a list.");
}
newPage = std::make_shared<Page>(*this, title, parent);
for ( auto e : elements.AsList()) {
newPage->createElement(e);
}
if (parent.expired()) {
rootPage = newPage;
}
return newPage;
}
std::shared_ptr<Element> Page::createElement(const libvariant::Variant& param) {
}
std::shared_ptr<Element> CompositeElement::createElement(const libvariant::Variant& param) {
}
std::shared_ptr<Page> AtomicElement::createLinkedToPage(const libvariant::Variant& param) {
}
std::shared_ptr<Device> AtomicElement::createDevice(const libvariant::Variant& param) {
}
} // namespace sitemaptemplate
} // namespace sitemap
} // namespace service
} // namespace cosgi
} // namespace hos
@@ -1,164 +0,0 @@
#pragma once
// hos includes
#include <hos/utils/SchemaLoader.h>
// libvariant
#include <Variant/Schema.h>
// std includes
#include <map>
#include <vector>
#include <memory>
#include <string>
#include <atomic>
namespace hos {
namespace cosgi {
namespace service {
namespace sitemap {
namespace sitemaptemplate {
class Page;
class Element;
class AtomicElement;
class CompositeElement;
class Device;
class SitemapTemplate {
private:
std::string title;
std::shared_ptr<Page> rootPage;
public:
SitemapTemplate(const std::string& title) : title(title) {}
std::shared_ptr<Page> createPage(const libvariant::Variant& param, std::weak_ptr<Page> parent = std::weak_ptr<Page>());
std::shared_ptr<Page> getRootPage() noexcept { return rootPage; };
};
class Page {
private:
SitemapTemplate& sitemap;
std::weak_ptr<Page> parent;
std::string title;
std::vector<std::shared_ptr<Element>> elements;
public:
Page(SitemapTemplate& sitemap, const std::string& title, std::weak_ptr<Page> parent = std::weak_ptr<Page>())
: sitemap(sitemap), title(title) {}
SitemapTemplate& getSiteMap() noexcept { return sitemap; }
std::shared_ptr<Page> getParent() noexcept { return parent.lock(); }
std::shared_ptr<Element> createElement(const libvariant::Variant& param);
const std::vector<std::shared_ptr<Element>>& getElements() noexcept { return elements; }
};
enum class ElementType {
// composite elements
Frame,
// atomic elements
Text,
Switch,
Slider
};
class Element {
private:
static std::atomic<uint64_t> nextID;
uint64_t id;
bool compositeFlag;
ElementType type;
Page& page;
std::weak_ptr<CompositeElement> parent;
std::string label;
std::string icon;
public:
Element( Page& page,
bool isComposite,
ElementType type,
std::weak_ptr<CompositeElement> 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) {}
virtual ~Element() {}
uint64_t getID() noexcept { return id; }
const std::string& getLabel() noexcept { return label; }
const std::string& getIcon() noexcept { return icon; }
Page& getPage() noexcept { return page; }
std::shared_ptr<CompositeElement> getParent() noexcept { return parent.lock(); }
bool isComposite() noexcept { return compositeFlag; };
ElementType getType() noexcept { return type; }
};
class CompositeElement : public Element {
private:
std::vector<std::shared_ptr<Element>> elements;
public:
CompositeElement(Page& page, ElementType etype, const std::string& label, const std::string& icon,
std::weak_ptr<CompositeElement> parent = std::weak_ptr<CompositeElement>())
: Element(page, true, etype, parent, label, icon) {}
std::shared_ptr<Element> createElement(const libvariant::Variant& param);
const std::vector<std::shared_ptr<Element>>& getElements() noexcept { return elements; }
};
class AtomicElement : public Element {
private:
std::string format;
std::shared_ptr<Device> device;
libvariant::Variant additionalParams;
std::shared_ptr<Page> linkedToPage;
public:
AtomicElement(Page& page, ElementType etype, const std::string& label, const std::string& icon,
const std::string& format, std::shared_ptr<Device> device, libvariant::Variant additionalParams,
std::weak_ptr<CompositeElement> parent = std::weak_ptr<CompositeElement>())
: Element(page, false, etype, parent, label, icon), format(format), device(device), additionalParams(additionalParams) {}
const std::string& getFormat() { return format; }
std::shared_ptr<Device> createDevice(const libvariant::Variant& param);
std::shared_ptr<Device> getDevice() { return device; }
const libvariant::Variant& getAdditionalParams() { return additionalParams; }
std::shared_ptr<Page> createLinkedToPage(const libvariant::Variant& param);
std::shared_ptr<Page> getLinkedToPage() { return linkedToPage; }
};
class Device {
private:
public:
};
} // namespace sitemaptemplate
} // namespace sitemap
} // namespace service
} // namespace cosgi
} // namespace hos
@@ -0,0 +1,195 @@
#include "SitemapTemplateImpl.h"
namespace hos {
namespace cosgi {
namespace service {
namespace sitemap {
namespace sitemaptemplate {
std::atomic<uint64_t> ElementImpl::nextID;
std::shared_ptr<PageImpl> SitemapTemplateImpl::createPage(const libvariant::Variant& param, PageImpl* parent) {
std::shared_ptr<PageImpl> newPage;
if (!parent && rootPage) {
throw std::runtime_error("There is already a root page.");
}
auto titleRaw = param["title"];
if (!titleRaw.IsString()) {
throw std::runtime_error("title is not a string.");
}
std::string title = titleRaw.AsString();
auto elements = param["elements"];
if (!elements.IsList()) {
throw std::runtime_error("elements is not a list.");
}
newPage = std::make_shared<PageImpl>(*this, title, parent);
for ( auto e : elements.AsList()) {
newPage->createElement(e);
}
if (!parent) {
rootPage = newPage;
}
return newPage;
}
std::shared_ptr<DeviceImpl> SitemapTemplateImpl::createDevice(const libvariant::Variant& param) {
auto idRaw = param["id"];
if (!idRaw.IsString()) {
throw std::runtime_error("id is not a string.");
}
std::string id = idRaw.AsString();
std::string pointer;
auto pointerRaw = param["pointer"];
if (!pointerRaw.IsString()) {
throw std::runtime_error("pointer is not a string.");
} else if (pointerRaw.IsString()) {
pointer = pointerRaw.AsString();
}
auto devRepo = parent.getDeviceRepository();
auto device = devRepo->getDevice(id);
std::shared_ptr<DeviceImpl> newDevice = std::make_shared<DeviceImpl>(id, device, pointer);
return newDevice;
}
namespace {
struct _elementTypeInfo {
std::string typeName;
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 }
};
}
std::vector<std::weak_ptr<Element>> PageImpl::getElements() noexcept {
std::vector<std::weak_ptr<Element>> retval;
for (auto i : elements) {
retval.push_back(std::static_pointer_cast<Element>(i));
}
return retval;
}
std::vector<std::weak_ptr<Element>> CompositeElementImpl::getElements() noexcept {
std::vector<std::weak_ptr<Element>> retval;
for (auto i : elements) {
retval.push_back(std::static_pointer_cast<Element>(i));
}
return retval;
}
std::shared_ptr<ElementImpl> PageImpl::createElement(const libvariant::Variant& param, CompositeElementImpl* parent) {
std::shared_ptr<ElementImpl> newElement;
libvariant::Variant addParams = param.Copy();
auto typeRaw = param["type"];
if (!typeRaw.IsString()) {
throw std::runtime_error("type is not a string.");
}
std::string typeStr = typeRaw.AsString();
addParams.Erase("type");
_elementTypeInfo* info = nullptr;
for (auto& e : elementTypeInfo) {
if (typeStr.compare(e.typeName)) {
info = &e;
break;
}
}
if (!info) {
std::stringstream ss;
ss << "Unknown element type " << typeStr << ".";
throw std::runtime_error(ss.str());
}
std::string label;
auto labelRaw = param["label"];
if (!labelRaw.IsNull() && !labelRaw.IsString()) {
throw std::runtime_error("label is not a string.");
} else if (labelRaw.IsString()) {
label = labelRaw.AsString();
addParams.Erase("label");
}
std::string icon;
if (param.Contains("icon")) {
auto iconRaw = param["icon"];
if (!iconRaw.IsNull() && !iconRaw.IsString()) {
throw std::runtime_error("icon is not a string.");
} else if (iconRaw.IsString()) {
icon = iconRaw.AsString();
addParams.Erase("icon");
}
}
if (info->isComposite) {
newElement = std::make_shared<CompositeElementImpl>(*this, info->type, label, icon, parent);
} 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");
}
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");
}
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");
}
std::shared_ptr<AtomicElementImpl> newAElement = std::make_shared<AtomicElementImpl>(*this, info->type, label, icon, format, device, addParams, parent);
if (pageRaw.IsMap()) {
newAElement->createLinkedToPage(pageRaw);
}
newElement = newAElement;
}
if (!parent) {
elements.push_back(newElement);
}
return newElement;
}
std::shared_ptr<ElementImpl> CompositeElementImpl::createElement(const libvariant::Variant& param) {
std::shared_ptr<ElementImpl> newElement = page.createElement(param, this);
elements.push_back(newElement);
return newElement;
}
std::shared_ptr<PageImpl> AtomicElementImpl::createLinkedToPage(const libvariant::Variant& param) {
if (linkedToPage) {
throw std::runtime_error("There is already a linked page.");
}
linkedToPage = page.sitemap.createPage(param, &page);
return linkedToPage;
}
} // namespace sitemaptemplate
} // namespace sitemap
} // namespace service
} // namespace cosgi
} // namespace hos
@@ -0,0 +1,193 @@
#pragma once
// hos includes
#include <hos/cosgi/service/sitemap/sitemap_template/SitemapTemplate.h>
#include "../SitemapServiceImpl.h"
#include <hos/utils/SchemaLoader.h>
// libvariant
#include <Variant/Schema.h>
// std includes
#include <map>
#include <vector>
#include <memory>
#include <string>
#include <atomic>
namespace hos {
namespace cosgi {
namespace service {
namespace sitemap {
class SitemapServiceImpl;
namespace sitemaptemplate {
class PageImpl;
class ElementImpl;
class AtomicElementImpl;
class CompositeElementImpl;
class DeviceImpl;
class SitemapTemplateImpl
: public virtual SitemapTemplate,
public implementation::Object {
private:
SitemapServiceImpl& parent;
std::string title;
std::shared_ptr<PageImpl> rootPage;
public:
SitemapTemplateImpl(SitemapServiceImpl& parent, const std::string& title) : parent(parent), title(title) {}
std::shared_ptr<PageImpl> createPage(const libvariant::Variant& param, PageImpl* parent = nullptr);
std::shared_ptr<DeviceImpl> createDevice(const libvariant::Variant& param);
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); };
};
class PageImpl
: public virtual Page,
public implementation::Object {
friend class AtomicElementImpl;
private:
SitemapTemplateImpl& sitemap;
PageImpl* parent;
std::string title;
std::vector<std::shared_ptr<ElementImpl>> elements;
public:
PageImpl(SitemapTemplateImpl& sitemap, const std::string& title, PageImpl* parent = nullptr)
: sitemap(sitemap), parent(parent), title(title) {}
virtual SitemapTemplate* getSiteMap() noexcept override { return static_cast<SitemapTemplate*>(&sitemap); }
virtual Page* getParent() noexcept override { return static_cast<Page*>(parent); }
std::shared_ptr<ElementImpl> createElement(const libvariant::Variant& param, CompositeElementImpl* parent = nullptr);
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;
};
class ElementImpl
: public virtual Element,
public implementation::Object {
protected:
static std::atomic<uint64_t> nextID;
uint64_t id;
bool compositeFlag;
ElementType type;
PageImpl& page;
CompositeElementImpl* parent;
std::string label;
std::string icon;
public:
ElementImpl( PageImpl& page,
bool isComposite,
ElementType type,
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) {}
virtual uint64_t getID() noexcept override { return id; }
virtual const std::string& getLabel() noexcept override { return label; }
virtual const std::string& getIcon() noexcept override { return icon; }
virtual Page* getPage() noexcept override { return static_cast<Page*>(&page); }
virtual CompositeElement* getParent() noexcept override;
virtual bool isComposite() noexcept override { return compositeFlag; };
virtual ElementType getType() noexcept override { return type; }
};
class CompositeElementImpl
: public virtual CompositeElement,
public ElementImpl {
private:
std::vector<std::shared_ptr<ElementImpl>> elements;
public:
CompositeElementImpl(PageImpl& page, ElementType etype, const std::string& label, const std::string& icon,
CompositeElementImpl* parent = nullptr)
: ElementImpl(page, true, etype, 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;
};
class AtomicElementImpl
: public virtual AtomicElement,
public ElementImpl {
private:
std::string format;
std::shared_ptr<DeviceImpl> device;
libvariant::Variant additionalParams;
std::shared_ptr<PageImpl> linkedToPage;
public:
AtomicElementImpl(PageImpl& page, ElementType etype, 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) {}
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; }
};
class DeviceImpl
: public virtual Device,
public implementation::Object {
private:
std::string deviceID;
std::weak_ptr<devicerepository::Device> device;
std::string pointer;
public:
DeviceImpl(const std::string& deviceID, std::weak_ptr<devicerepository::Device> device, const std::string& pointer)
: deviceID(deviceID), device(device), pointer(pointer) {}
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; }
};
inline CompositeElement* ElementImpl::getParent() noexcept { return static_cast<CompositeElement*>(parent); }
inline std::weak_ptr<Device> AtomicElementImpl::getDevice() noexcept { return std::static_pointer_cast<Device>(device); }
} // namespace sitemaptemplate
} // namespace sitemap
} // namespace service
} // namespace cosgi
} // namespace hos
@@ -43,14 +43,24 @@ Net::HTTPRequestHandler* SitemapHandlerFactory::createRequestHandler( Poco::URI
void SitemapHandler::_handleRequest(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp, Net::HTMLForm& form) {
if(req.find("Upgrade") != req.end() && Poco::icompare(req["Upgrade"], "websocket") == 0) {
//__handleEvent(req, resp, true);
throw webserver::webresource::WebResourceHandlerException("ToDo",
Net::HTTPResponse::HTTP_NOT_IMPLEMENTED);
__handleEvent(req, resp, form, true);
} else {
if (req.getMethod() == Net::HTTPRequest::HTTP_PUT || req.getMethod() == Net::HTTPRequest::HTTP_GET || req.getMethod() == Net::HTTPRequest::HTTP_POST) {
if (req.getMethod() == Net::HTTPRequest::HTTP_PUT) {
// Put Command
throw webserver::webresource::WebResourceHandlerException("Still a ToDo.",
Net::HTTPResponse::HTTP_NOT_IMPLEMENTED);
} else if (req.getMethod() == Net::HTTPRequest::HTTP_GET || req.getMethod() == Net::HTTPRequest::HTTP_POST) {
SitemapAPIMethod method = getSitemapAPIMethod(req, form);
if (method == SitemapAPIMethod::GET) {
__handleInfo(req, resp, form);
} else if (method == SitemapAPIMethod::COMMAND) {
__handleCommand(req, resp, method, form);
} else if (method == SitemapAPIMethod::EVENT) {
__handleEvent(req, resp, form, false);
} else {
throw webserver::webresource::WebResourceHandlerException("Could not understood request",
Net::HTTPResponse::HTTP_BAD_REQUEST);
}
} else {
throw webserver::webresource::WebResourceHandlerException("Could not understood request",
Net::HTTPResponse::HTTP_BAD_REQUEST);
@@ -59,6 +69,101 @@ void SitemapHandler::_handleRequest(Poco::Net::HTTPServerRequest &req, Poco::Net
}
void SitemapHandler::__handleInfo(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp, Net::HTMLForm& form) {
std::vector<std::string> pathPieces, matchPieces;
matchUri.getPathSegments(matchPieces);
Poco::URI uri(req.getURI());
uri.getPathSegments(pathPieces);
// No sitemap given, query mode (there is no real query functionality implemented yet though)
if (pathPieces.size() <= matchPieces.size()) {
auto sitemaps = service->getSitemapNames();
// Iterate over sitemaps
Variant result = Variant::List();
for (auto s : sitemaps) {
result.Append(s);
}
handleResponse(req, resp, form, result);
// Single sitemap mode
} else {
// Get sitemap
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++) {
path << "/" << pathPieces[i];
}
std::string pointer;
if (getPointerParameter(pointer, form)) {
if (pointer.size() > 0 && pointer[0] != '/') {
path << "/";
}
path << pointer;
}
// Get device info
Variant result = libvariant::Variant("ToDo: Do something");
// Return device info
handleResponse(req, resp, form, result);
} else {
throw webserver::webresource::WebResourceHandlerException((boost::format("Could not find sitemap \"%1%\"") % sitemapName).str(),
Poco::Net::HTTPResponse::HTTPStatus::HTTP_NOT_FOUND);
}
}
}
void SitemapHandler::__handleCommand(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp, SitemapAPIMethod method, Net::HTMLForm& form) {
throw webserver::webresource::WebResourceHandlerException("ToDo. Implement that shit.",
Poco::Net::HTTPResponse::HTTPStatus::HTTP_NOT_IMPLEMENTED);
}
void SitemapHandler::__handleEvent(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp, Net::HTMLForm& form, bool websocket) {
throw webserver::webresource::WebResourceHandlerException("ToDo. Implement that shit.",
Poco::Net::HTTPResponse::HTTPStatus::HTTP_NOT_IMPLEMENTED);
}
SitemapAPIMethod SitemapHandler::getSitemapAPIMethod(Net::HTTPServerRequest &req, Net::HTMLForm& form) noexcept {
SitemapAPIMethod retval = SitemapAPIMethod::GET; // default
std::string methodRaw;
if (form.has("method")) {
methodRaw = form.get("method");
} else if (req.has("API-Method")) {
methodRaw = req.get("API-Method");
} else if (req.has("X-API-Method")) {
methodRaw = req.get("X-API-Method");
}
if (!methodRaw.empty()) {
if (methodRaw == "get") {
retval = SitemapAPIMethod::GET;
} else if (methodRaw == "command") {
retval = SitemapAPIMethod::COMMAND;
} else if (methodRaw == "event") {
retval = SitemapAPIMethod::EVENT;
} else {
throw webserver::webresource::WebResourceHandlerException(
(boost::format("Unknown sitemap api method \"%1%\"") % methodRaw).str(),
Net::HTTPResponse::HTTPStatus::HTTP_BAD_REQUEST );
}
} else if (form.has("onevent") || req.has("On-Event") || req.has("X-On-Event")) {
retval = SitemapAPIMethod::EVENT;
}
return retval;
}
} // namespace webresource
} // namespace sitemap
} // namespace service
@@ -32,6 +32,14 @@ class SitemapHandlerFactory;
class SitemapHandler;
enum class SitemapAPIMethod {
GET,
COMMAND,
EVENT,
UNKNOWN
};
class SitemapHandlerFactory
: public webserver::webresource::WebResourceHandlerFactoryImpl<SitemapHandlerFactory, false> {
private:
@@ -63,6 +71,14 @@ public:
virtual void _handleRequest(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp, Poco::Net::HTMLForm& form) override;
void __handleInfo(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp, Poco::Net::HTMLForm& form);
void __handleCommand(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp, SitemapAPIMethod method, Poco::Net::HTMLForm& form);
void __handleEvent(Poco::Net::HTTPServerRequest &req, Poco::Net::HTTPServerResponse &resp, Poco::Net::HTMLForm& form, bool websocket);
static SitemapAPIMethod getSitemapAPIMethod(Poco::Net::HTTPServerRequest &req, Poco::Net::HTMLForm& form) noexcept;
};