Displaying and editing the complex value types for attributes.
[platform/upstream/iotivity.git] / service / simulator / src / server / simulator_collection_resource_impl.cpp
old mode 100644 (file)
new mode 100755 (executable)
index f46f0aa..b9fcb62
@@ -31,6 +31,9 @@ SimulatorCollectionResourceImpl::SimulatorCollectionResourceImpl()
         m_resourceHandle(NULL)
 {
     m_property = static_cast<OCResourceProperty>(OC_DISCOVERABLE | OC_OBSERVABLE);
+
+    std::vector<SimulatorResourceModel> links;
+    m_resModel.add("links", links);
 }
 
 std::string SimulatorCollectionResourceImpl::getName() const
@@ -58,6 +61,11 @@ std::vector<std::string> SimulatorCollectionResourceImpl::getInterface() const
     return m_interfaces;
 }
 
+void SimulatorCollectionResourceImpl::setInterface(const std::vector<std::string> &interfaces)
+{
+    m_interfaces = interfaces;
+}
+
 void SimulatorCollectionResourceImpl::setName(const std::string &name)
 {
     VALIDATE_INPUT(name.empty(), "Name is empty!")
@@ -142,6 +150,12 @@ void SimulatorCollectionResourceImpl::setObserverCallback(ObserverCallback callb
     m_observeCallback = callback;
 }
 
+void SimulatorCollectionResourceImpl::setModelChangeCallback(ResourceModelChangedCallback callback)
+{
+    VALIDATE_CALLBACK(callback)
+    m_modelCallback = callback;
+}
+
 bool SimulatorCollectionResourceImpl::isObservable()
 {
     return (m_property & OC_OBSERVABLE);
@@ -206,6 +220,28 @@ void SimulatorCollectionResourceImpl::stop()
     m_resourceHandle = nullptr;
 }
 
+SimulatorResourceModel SimulatorCollectionResourceImpl::getResourceModel()
+{
+    std::lock_guard<std::mutex> lock(m_modelLock);
+    return m_resModel;
+}
+
+void SimulatorCollectionResourceImpl::setResourceModel(const SimulatorResourceModel &resModel)
+{
+    std::lock_guard<std::mutex> lock(m_modelLock);
+    m_resModel = resModel;
+}
+
+void SimulatorCollectionResourceImpl::setActionType(std::map<RAML::ActionType, RAML::ActionPtr> &actionType)
+{
+    m_actionTypes = actionType;
+}
+
+void SimulatorCollectionResourceImpl::setActionType(std::map<RAML::ActionType, RAML::ActionPtr> &actionType)
+{
+    m_actionTypes = actionType;
+}
+
 std::vector<ObserverInfo> SimulatorCollectionResourceImpl::getObserversList()
 {
     return m_observersList;
@@ -252,6 +288,12 @@ void SimulatorCollectionResourceImpl::addChildResource(SimulatorResourceSP &reso
     }
 
     m_childResources[resource->getURI()] = resource;
+    addLink(resource);
+
+    // Notify application and observers
+    if (m_modelCallback)
+        m_modelCallback(m_uri, m_resModel);
+    notifyAll();
 }
 
 void SimulatorCollectionResourceImpl::removeChildResource(SimulatorResourceSP &resource)
@@ -264,7 +306,13 @@ void SimulatorCollectionResourceImpl::removeChildResource(SimulatorResourceSP &r
         throw SimulatorException(SIMULATOR_ERROR, "Child resource not found in collection!");
     }
 
+    removeLink(resource->getURI());
     m_childResources.erase(m_childResources.find(resource->getURI()));
+
+    // Notify application and observers
+    if (m_modelCallback)
+        m_modelCallback(m_uri, m_resModel);
+    notifyAll();
 }
 
 void SimulatorCollectionResourceImpl::removeChildResource(const std::string &uri)
@@ -277,7 +325,13 @@ void SimulatorCollectionResourceImpl::removeChildResource(const std::string &uri
         throw SimulatorException(SIMULATOR_ERROR, "Child resource not found in collection!");
     }
 
+    removeLink(uri);
     m_childResources.erase(m_childResources.find(uri));
+
+    // Notify application and observers
+    if (m_modelCallback)
+        m_modelCallback(m_uri, m_resModel);
+    notifyAll();
 }
 
 std::vector<SimulatorResourceSP> SimulatorCollectionResourceImpl::getChildResources()
@@ -385,10 +439,19 @@ std::shared_ptr<OC::OCResourceResponse> SimulatorCollectionResourceImpl::request
     std::shared_ptr<OC::OCResourceRequest> request)
 {
     std::shared_ptr<OC::OCResourceResponse> response;
+
+    RAML::ActionType type = getActionType(request->getRequestType());
+
+    if (!m_actionTypes.empty())
+    {
+        if (m_actionTypes.end() == m_actionTypes.find(type))
+            return response;
+    }
+
     if ("GET" == request->getRequestType())
     {
         // Construct the representation
-        OC::OCRepresentation ocRep = prepareRepresentation();
+        OC::OCRepresentation ocRep = m_resModel.getOCRepresentation();
         response = std::make_shared<OC::OCResourceResponse>();
         response->setErrorCode(200);
         response->setResponseResult(OC_EH_OK);
@@ -414,17 +477,27 @@ std::shared_ptr<OC::OCResourceResponse> SimulatorCollectionResourceImpl::request
 {
     std::lock_guard<std::mutex> lock(m_childResourcesLock);
     std::shared_ptr<OC::OCResourceResponse> response;
+
+    RAML::ActionType type = getActionType(request->getRequestType());
+
+    if (!m_actionTypes.empty())
+    {
+        if (m_actionTypes.end() == m_actionTypes.find(type))
+            return response;
+    }
+
     if ("GET" == request->getRequestType())
     {
         // Construct the representation
         OC::OCRepresentation ocRep;
         std::vector<OC::OCRepresentation> links;
-        int index = 0;
         for (auto &entry : m_childResources)
         {
-            links[index].setValue("href", entry.second->getURI());
-            links[index].setValue("rt", entry.second->getResourceType());
-            links[index].setValue("if", entry.second->getInterface()[0]);
+            OC::OCRepresentation oicLink;
+            oicLink.setValue("href", entry.second->getURI());
+            oicLink.setValue("rt", entry.second->getResourceType());
+            oicLink.setValue("if", entry.second->getInterface()[0]);
+            links.push_back(oicLink);
         }
 
         ocRep.setValue("links", links);
@@ -456,7 +529,9 @@ void SimulatorCollectionResourceImpl::sendNotification(OC::ObservationIds &obser
     std::shared_ptr<OC::OCResourceResponse> response(new OC::OCResourceResponse());
     response->setErrorCode(200);
     response->setResponseResult(OC_EH_OK);
-    response->setResourceRepresentation(prepareRepresentation(), OC::DEFAULT_INTERFACE);
+
+    OC::OCRepresentation ocRep = m_resModel.getOCRepresentation();
+    response->setResourceRepresentation(ocRep, OC::DEFAULT_INTERFACE);
 
     typedef OCStackResult (*NotifyListOfObservers)(OCResourceHandle, OC::ObservationIds &,
             const std::shared_ptr<OC::OCResourceResponse>);
@@ -465,35 +540,73 @@ void SimulatorCollectionResourceImpl::sendNotification(OC::ObservationIds &obser
                      m_resourceHandle, observers, response);
 }
 
-OC::OCRepresentation SimulatorCollectionResourceImpl::prepareRepresentation()
+void SimulatorCollectionResourceImpl::addLink(SimulatorResourceSP &resource)
 {
-    OC::OCRepresentation ocRep;
+    std::lock_guard<std::mutex> lock(m_modelLock);
+    if (!m_resModel.containsAttribute("links"))
+        return;
 
-    ocRep.setValue("n", getName());
-    ocRep.setResourceTypes({m_resourceType});
-    ocRep.setResourceInterfaces(m_interfaces);
+    // Create new OIC Link
+    SimulatorResourceModel newLink;
+    newLink.add("href", resource->getURI());
+    newLink.add("rt", resource->getResourceType());
+    newLink.add("if", resource->getInterface()[0]);
+
+    // Add OIC Link if it is not present
+    bool found = false;
+    std::vector<SimulatorResourceModel> links =
+        m_resModel.get<std::vector<SimulatorResourceModel>>("links");
+    for (auto &link : links)
+    {
+        std::string linkURI = link.get<std::string>("href");
+        if (linkURI == resource->getURI())
+        {
+            break;
+            found = true;
+        }
+    }
 
-    // Add "rts" attribute
-    std::ostringstream supportedTypes;
-    for (auto &type : m_supportedTypes)
+    if (false ==  found)
     {
-        if (!supportedTypes.str().empty())
-            supportedTypes << " ,";
-        supportedTypes << type;
+        links.push_back(newLink);
+        m_resModel.updateValue("links", links);
     }
-    ocRep.setValue("rts", supportedTypes.str());
+}
 
-    // Add "links" attribute
-    std::vector<OC::OCRepresentation> links;
-    int index = 0;
-    for (auto &entry : m_childResources)
+void SimulatorCollectionResourceImpl::removeLink(std::string uri)
+{
+    std::lock_guard<std::mutex> lock(m_modelLock);
+    if (!m_resModel.containsAttribute("links"))
+        return;
+
+    // Add OIC Link if it is not present
+    std::vector<SimulatorResourceModel> links =
+        m_resModel.get<std::vector<SimulatorResourceModel>>("links");
+    for (size_t i = 0; i < links.size(); i++)
     {
-        links[index].setValue("href", entry.second->getURI());
-        links[index].setValue("rt", entry.second->getResourceType());
-        links[index].setValue("if", entry.second->getInterface()[0]);
+        std::string linkURI = links[i].get<std::string>("href");
+        if (linkURI == uri)
+        {
+            links.erase(links.begin() + i);
+            m_resModel.updateValue("links", links);
+            break;
+        }
     }
+}
+
+RAML::ActionType SimulatorCollectionResourceImpl::getActionType(std::string requestType)
+{
+    if (!requestType.compare("GET"))
+        return RAML::ActionType::GET;
 
-    ocRep.setValue("links", links);
+    if (!requestType.compare("PUT"))
+        return RAML::ActionType::PUT;
 
-    return ocRep;
-}
\ No newline at end of file
+    if (!requestType.compare("POST"))
+        return RAML::ActionType::POST;
+
+    if (!requestType.compare("DELETE"))
+        return RAML::ActionType::DELETE;
+
+    return RAML::ActionType::NONE;
+}