542fb7a83751326e713de484dd5c4d53d2ce855a
[platform/upstream/iotivity.git] / service / resource-container / src / ResourceContainerImpl.cpp
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include "ResourceContainerImpl.h"
22
23 #include <dlfcn.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <fstream>
27 #include <iostream>
28 #include <stdio.h>
29 #include <thread>
30 #include <mutex>
31 #include <algorithm>
32
33 #include "BundleActivator.h"
34 #include "SoftSensorResource.h"
35 #include "InternalTypes.h"
36
37 using namespace OIC::Service;
38 using namespace std;
39
40 namespace OIC
41 {
42     namespace Service
43     {
44         ResourceContainerImpl::ResourceContainerImpl()
45         {
46             m_config = nullptr;
47         }
48
49         ResourceContainerImpl::~ResourceContainerImpl()
50         {
51             m_config = nullptr;
52         }
53
54         bool has_suffix(const std::string &str, const std::string &suffix)
55         {
56             return str.size() >= suffix.size()
57                    && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
58         }
59
60         void ResourceContainerImpl::startContainer(const std::string &configFile)
61         {
62             OC_LOG(INFO, CONTAINER_TAG, "Starting resource container.");
63 #if (JAVA_SUPPORT)
64             OC_LOG(INFO, CONTAINER_TAG, "Resource container has Java support.");
65 #else
66             OC_LOG(INFO, CONTAINER_TAG, "Resource container without Java support.");
67 #endif
68
69
70             activationLock.lock();
71             if (!configFile.empty())
72             {
73                 m_config = new Configuration(configFile);
74
75                 if (m_config->isLoaded())
76                 {
77                     configInfo bundles;
78                     m_config->getConfiguredBundles(&bundles);
79
80                     for (unsigned int i = 0; i < bundles.size(); i++)
81                     {
82                         BundleInfoInternal *bundleInfo = new BundleInfoInternal();
83                         bundleInfo->setPath(bundles[i][BUNDLE_PATH]);
84                         bundleInfo->setVersion(bundles[i][BUNDLE_VERSION]);
85                         bundleInfo->setID(bundles[i][BUNDLE_ID]);
86                         if (!bundles[i][BUNDLE_ACTIVATOR].empty())
87                         {
88                             string activatorName = bundles[i][BUNDLE_ACTIVATOR];
89                             std::replace(activatorName.begin(), activatorName.end(), '.', '/');
90                             ((BundleInfoInternal *) bundleInfo)->setActivatorName(activatorName);
91                             ((BundleInfoInternal *) bundleInfo)->setLibraryPath(
92                                 bundles[i][BUNDLE_LIBRARY_PATH]);
93                         }
94
95                         OC_LOG_V(INFO, CONTAINER_TAG, "Init Bundle:(%s)",
96                                  std::string(bundles[i][BUNDLE_ID] + ";" +
97                                              bundles[i][BUNDLE_PATH]).c_str());
98
99                         registerBundle(bundleInfo);
100                         activateBundle(bundleInfo);
101                     }
102                 }
103                 else
104                 {
105                     OC_LOG_V(ERROR, CONTAINER_TAG, "Container started with invalid configfile path.");
106                 }
107             }
108             else
109             {
110                 OC_LOG_V(INFO, CONTAINER_TAG, "No configuration file for the container provided.");
111             }
112
113             map<std::string, boost::thread >::iterator activatorIterator;
114
115             for (activatorIterator = m_activators.begin(); activatorIterator != m_activators.end();
116                  activatorIterator++)
117             {
118                 activatorIterator->second.timed_join(
119                     boost::posix_time::seconds(BUNDLE_ACTIVATION_WAIT_SEC));
120                 // wait for bundles to be activated
121             }
122             activationLock.unlock();
123         }
124
125         void ResourceContainerImpl::stopContainer()
126         {
127             OC_LOG(INFO, CONTAINER_TAG, "Stopping resource container.");
128
129             for (std::map< std::string, BundleInfoInternal * >::iterator it = m_bundles.begin();
130                  it != m_bundles.end(); ++it)
131             {
132                 BundleInfoInternal *bundleInfo = it->second;
133                 deactivateBundle(bundleInfo);
134                 unregisterBundle(bundleInfo);
135             }
136
137             if (!m_mapServers.empty())
138             {
139                 map< std::string, RCSResourceObject::Ptr >::iterator itor = m_mapServers.begin();
140
141                 while (itor != m_mapServers.end())
142                 {
143                     (itor++)->second.reset();
144                 }
145
146                 m_mapResources.clear();
147                 m_mapBundleResources.clear();
148             }
149
150             if (m_config)
151                 delete m_config;
152         }
153
154         void ResourceContainerImpl::activateBundle(RCSBundleInfo *bundleInfo)
155         {
156             activationLock.lock();
157             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) bundleInfo;
158
159             if (bundleInfoInternal->isLoaded())
160             {
161                 activateBundle(bundleInfo->getID());
162             }
163             activationLock.unlock();
164         }
165
166         void ResourceContainerImpl::deactivateBundle(RCSBundleInfo *bundleInfo)
167         {
168             if (((BundleInfoInternal *) bundleInfo)->isActivated())
169             {
170                 deactivateBundle(bundleInfo->getID());
171             }
172         }
173
174         void ResourceContainerImpl::activateBundle(const std::string &id)
175         {
176             OC_LOG_V(INFO, CONTAINER_TAG, "Activating bundle: (%s)",
177                      std::string(m_bundles[id]->getID()).c_str());
178             activationLock.lock();
179             auto f = std::bind(&ResourceContainerImpl::activateBundleThread, this,
180                                id);
181             boost::thread activator(f);
182             activator.timed_join(boost::posix_time::seconds(BUNDLE_SET_GET_WAIT_SEC));
183             activationLock.unlock();
184             OC_LOG_V(INFO, CONTAINER_TAG, "Bundle activated: (%s)",
185                      std::string(m_bundles[id]->getID()).c_str());
186         }
187
188         void ResourceContainerImpl::deactivateBundle(const std::string &id)
189         {
190             if (m_bundles[id]->getJavaBundle())
191             {
192 #if(JAVA_SUPPORT)
193                 deactivateJavaBundle(id);
194 #endif
195             }
196             else
197             {
198                 deactivateSoBundle(id);
199             }
200         }
201
202         // loads the bundle
203         void ResourceContainerImpl::registerBundle(RCSBundleInfo *bundleInfo)
204         {
205             OC_LOG_V(INFO, CONTAINER_TAG, "Registering bundle: (%s)",
206                      std::string(bundleInfo->getPath()).c_str());
207
208             if (has_suffix(bundleInfo->getPath(), ".jar"))
209             {
210 #if(JAVA_SUPPORT)
211                 ((BundleInfoInternal *) bundleInfo)->setJavaBundle(true);
212                 registerJavaBundle(bundleInfo);
213 #endif
214             }
215             else
216             {
217                 ((BundleInfoInternal *) bundleInfo)->setJavaBundle(false);
218                 registerSoBundle(bundleInfo);
219             }
220         }
221
222         void ResourceContainerImpl::unregisterBundle(RCSBundleInfo *bundleInfo)
223         {
224             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) bundleInfo;
225             if (bundleInfoInternal->isLoaded() && !bundleInfoInternal->isActivated())
226             {
227                 if (!bundleInfoInternal->getJavaBundle())
228                 {
229                     unregisterBundleSo(bundleInfo->getID());
230                 }
231                 else
232                 {
233 #if(JAVA_SUPPORT)
234                     unregisterBundleJava(bundleInfo->getID());
235 #endif
236                 }
237             }
238         }
239
240         void ResourceContainerImpl::unregisterBundleSo(const std::string &id)
241         {
242             void *bundleHandle = m_bundles[id]->getBundleHandle();
243
244             OC_LOG_V(INFO, CONTAINER_TAG, "Unregister bundle: (%s)",
245                      std::string(m_bundles[id]->getID()).c_str());
246
247             const char *error;
248             dlclose(bundleHandle);
249
250             if ((error = dlerror()) != NULL)
251             {
252                 OC_LOG_V(ERROR, CONTAINER_TAG, "Error (%s)", error);
253             }
254             else
255             {
256                 delete m_bundles[id];
257                 m_bundles.erase(id);
258             }
259         }
260
261         int ResourceContainerImpl::registerResource(BundleResource::Ptr resource)
262         {
263             string strUri = resource->m_uri;
264             string strResourceType = resource->m_resourceType;
265             string strInterface = resource->m_interface;
266             RCSResourceObject::Ptr server = nullptr;
267             int ret = EINVAL;
268
269             OC_LOG_V(INFO, CONTAINER_TAG, "Registration of resource (%s)" ,
270                      std::string(strUri + ", " + strResourceType).c_str());
271
272             registrationLock.lock();
273             if (m_mapResources.find(strUri) == m_mapResources.end())
274             {
275                 if (strInterface.empty()) {
276                     strInterface = "oic.if.baseline";
277                 }
278
279                 server = buildResourceObject(strUri, strResourceType, strInterface);
280
281                 if (server != nullptr)
282                 {
283                     m_mapServers[strUri] = server;
284                     m_mapResources[strUri] = resource;
285                     m_mapBundleResources[resource->m_bundleId].push_back(strUri);
286
287                     server->setGetRequestHandler(
288                         std::bind(&ResourceContainerImpl::getRequestHandler, this,
289                                   std::placeholders::_1, std::placeholders::_2));
290
291                     server->setSetRequestHandler(
292                         std::bind(&ResourceContainerImpl::setRequestHandler, this,
293                                   std::placeholders::_1, std::placeholders::_2));
294
295                     OC_LOG_V(INFO, CONTAINER_TAG, "Registration finished (%s)",
296                              std::string(strUri + ", " +
297                                          strResourceType).c_str());
298
299                     if (m_config && m_config->isHasInput(resource->m_bundleId))
300                     {
301                         discoverInputResource(strUri);
302                     }
303
304                     // to get notified if bundle resource attributes are updated
305                     resource->registerObserver((NotificationReceiver *) this);
306                     ret = 0;
307                 }
308             }
309             else
310             {
311                 OC_LOG_V(ERROR, CONTAINER_TAG, "resource with (%s)",
312                          std::string(strUri + " already exists.").c_str());
313                 ret = -EEXIST;
314             }
315             registrationLock.unlock();
316
317             return ret;
318         }
319
320         void ResourceContainerImpl::unregisterResource(BundleResource::Ptr resource)
321         {
322             string strUri = resource->m_uri;
323             string strResourceType = resource->m_resourceType;
324
325             OC_LOG_V(INFO, CONTAINER_TAG, "Unregistration of resource (%s)",
326                      std::string(resource->m_uri + ", " +
327                                  resource->m_resourceType).c_str());
328
329             if (m_config && m_config->isHasInput(resource->m_bundleId))
330             {
331                 undiscoverInputResource(strUri);
332             }
333
334             if (m_mapServers.find(strUri) != m_mapServers.end())
335             {
336                 m_mapServers[strUri].reset();
337
338                 m_mapResources.erase(m_mapResources.find(strUri));
339                 m_mapBundleResources[resource->m_bundleId].remove(strUri);
340             }
341         }
342
343         void ResourceContainerImpl::getBundleConfiguration(const std::string &bundleId,
344                 configInfo *configOutput)
345         {
346             if (m_config)
347             {
348                 m_config->getBundleConfiguration(bundleId, (configInfo *) configOutput);
349             }
350         }
351
352         void ResourceContainerImpl::getResourceConfiguration(const std::string &bundleId,
353                 std::vector< resourceInfo > *configOutput)
354         {
355             if (m_config)
356             {
357                 m_config->getResourceConfiguration(bundleId, configOutput);
358             }
359         }
360
361         RCSGetResponse ResourceContainerImpl::getRequestHandler(const RCSRequest &request,
362                 const RCSResourceAttributes &)
363         {
364             RCSResourceAttributes attr;
365             std::string strResourceUri = request.getResourceUri();
366
367             if (m_mapServers.find(strResourceUri) != m_mapServers.end()
368                 && m_mapResources.find(strResourceUri) != m_mapResources.end())
369             {
370                 if (m_mapResources[strResourceUri])
371                 {
372                     auto getFunction = [this, &attr, &strResourceUri]()
373                     {
374                         attr = m_mapResources[strResourceUri]->handleGetAttributesRequest();
375                     };
376                     boost::thread getThread(getFunction);
377                     getThread.timed_join(boost::posix_time::seconds(BUNDLE_SET_GET_WAIT_SEC));
378
379                 }
380             }
381
382             return RCSGetResponse::create(std::move(attr), 200);
383         }
384
385         RCSSetResponse ResourceContainerImpl::setRequestHandler(const RCSRequest &request,
386                 const RCSResourceAttributes &attributes)
387         {
388             RCSResourceAttributes attr;
389             std::list<std::string> lstAttributes;
390             std::string strResourceUri = request.getResourceUri();
391
392             if (m_mapServers.find(strResourceUri) != m_mapServers.end()
393                 && m_mapResources.find(strResourceUri) != m_mapResources.end())
394             {
395                 if (m_mapResources[strResourceUri])
396                 {
397                     auto setFunction = [this, &lstAttributes, &strResourceUri, &attributes, &attr]()
398                     {
399                         lstAttributes = m_mapResources[strResourceUri]->getAttributeNames();
400
401                         for (RCSResourceAttributes::const_iterator itor = attributes.begin();
402                              itor != attributes.end(); itor++)
403                         {
404                             if (std::find(lstAttributes.begin(), lstAttributes.end(), itor->key())
405                                 != lstAttributes.end())
406                             {
407                                 attr[itor->key()] = itor->value();
408                             }
409                         }
410
411                         m_mapResources[strResourceUri]->handleSetAttributesRequest(attr);
412                     };
413                     boost::thread setThread(setFunction);
414                     setThread.timed_join(boost::posix_time::seconds(BUNDLE_SET_GET_WAIT_SEC));
415                 }
416             }
417
418             return RCSSetResponse::create(std::move(attr), 200);
419         }
420
421         void ResourceContainerImpl::onNotificationReceived(const std::string &strResourceUri)
422         {
423             OC_LOG_V(INFO, CONTAINER_TAG,
424                      "notification from (%s)", std::string(strResourceUri + ".").c_str());
425
426             if (m_mapServers.find(strResourceUri) != m_mapServers.end())
427             {
428                 m_mapServers[strResourceUri]->notify();
429             }
430         }
431
432         ResourceContainerImpl *ResourceContainerImpl::getImplInstance()
433         {
434             static ResourceContainerImpl m_instance;
435             return &m_instance;
436         }
437
438         RCSResourceObject::Ptr ResourceContainerImpl::buildResourceObject(const std::string &strUri,
439                 const std::string &strResourceType, const std::string &strInterface)
440         {
441             return RCSResourceObject::Builder(strUri, strResourceType,
442                                               strInterface).setObservable(
443                        true).setDiscoverable(true).build();
444         }
445
446         void ResourceContainerImpl::startBundle(const std::string &bundleId)
447         {
448             if (m_bundles.find(bundleId) != m_bundles.end())
449             {
450                 if (!m_bundles[bundleId]->isActivated())
451                     activateBundle(m_bundles[bundleId]);
452                 else
453                 {
454                     OC_LOG(ERROR, CONTAINER_TAG, "Bundle already started");
455                 }
456             }
457             else
458             {
459                 OC_LOG_V(ERROR, CONTAINER_TAG, "Bundle with ID \'(%s)",
460                          std::string(bundleId + "\' is not registered.").c_str());
461             }
462         }
463
464         void ResourceContainerImpl::stopBundle(const std::string &bundleId)
465         {
466             if (m_bundles.find(bundleId) != m_bundles.end())
467             {
468                 if (m_bundles[bundleId]->isActivated())
469                     deactivateBundle(m_bundles[bundleId]);
470                 else
471                 {
472                     OC_LOG(ERROR, CONTAINER_TAG, "Bundle not activated");
473                 }
474             }
475             else
476             {
477                 OC_LOG_V(ERROR, CONTAINER_TAG, "Bundle with ID \'(%s)",
478                          std::string(bundleId + "\' is not registered.").c_str());
479             }
480         }
481
482         void ResourceContainerImpl::addBundle(const std::string &bundleId,
483                                               const std::string &bundleUri, const std::string &bundlePath,
484                                               const std::string &activator, std::map< string, string > params)
485         {
486             (void) bundleUri;
487
488             if (m_bundles.find(bundleId) != m_bundles.end())
489                 OC_LOG(ERROR, CONTAINER_TAG, "BundleId already exist");
490
491             else
492             {
493                 BundleInfoInternal *bundleInfo = new BundleInfoInternal();
494                 bundleInfo->setID(bundleId);
495                 bundleInfo->setPath(bundlePath);
496                 bundleInfo->setActivatorName(activator);
497                 if (params.find("libraryPath") != params.end())
498                 {
499                     string activatorName = activator; // modify activator for Java bundle
500                     std::replace(activatorName.begin(), activatorName.end(), '.', '/');
501                     ((BundleInfoInternal *) bundleInfo)->setActivatorName(activatorName);
502                     ((BundleInfoInternal *)bundleInfo)->setLibraryPath(params[BUNDLE_LIBRARY_PATH]);
503                 }
504
505                 OC_LOG_V(INFO, CONTAINER_TAG, "Add Bundle: (%s)",
506                          std::string(bundleInfo->getID() + "; " +
507                                      bundleInfo->getPath()).c_str());
508
509                 registerBundle(bundleInfo);
510             }
511         }
512
513         void ResourceContainerImpl::removeBundle(const std::string &bundleId)
514         {
515             if (m_bundles.find(bundleId) != m_bundles.end())
516             {
517                 BundleInfoInternal *bundleInfo = m_bundles[bundleId];
518                 if (bundleInfo->isActivated())
519                     deactivateBundle(bundleInfo);
520
521                 if (bundleInfo->isLoaded())
522                     unregisterBundle(bundleInfo);
523             }
524             else
525             {
526                 OC_LOG_V(ERROR, CONTAINER_TAG, "Bundle with ID \'(%s)",
527                          std::string(bundleId + "\' is not registered.").c_str());
528             }
529         }
530
531         std::list<std::unique_ptr<RCSBundleInfo>> ResourceContainerImpl::listBundles()
532         {
533             std::list<std::unique_ptr<RCSBundleInfo> > ret;
534             for (std::map< std::string, BundleInfoInternal * >::iterator it = m_bundles.begin();
535                  it != m_bundles.end(); ++it)
536             {
537                 {
538                     std::unique_ptr<BundleInfoInternal> bundleInfo(new BundleInfoInternal);
539                     (bundleInfo)->setBundleInfo(it->second);
540                     ret.push_back(std::move(bundleInfo));
541                 }
542             }
543             return ret;
544         }
545
546         void ResourceContainerImpl::addResourceConfig(const std::string &bundleId,
547                 const std::string &resourceUri, std::map< string, string > params)
548         {
549             if (m_bundles.find(bundleId) != m_bundles.end())
550             {
551                 if (!m_bundles[bundleId]->getJavaBundle())
552                 {
553                     resourceInfo newResourceInfo;
554                     newResourceInfo.uri = resourceUri;
555
556                     if (params.find(OUTPUT_RESOURCE_NAME) != params.end())
557                         newResourceInfo.name = params[OUTPUT_RESOURCE_NAME];
558                     if (params.find(OUTPUT_RESOURCE_TYPE) != params.end())
559                         newResourceInfo.resourceType = params[OUTPUT_RESOURCE_TYPE];
560                     if (params.find(OUTPUT_RESOURCE_ADDR) != params.end())
561                         newResourceInfo.address = params[OUTPUT_RESOURCE_ADDR];
562
563                     addSoBundleResource(bundleId, newResourceInfo);
564                 }
565             }
566             else
567             {
568                 OC_LOG_V(ERROR, CONTAINER_TAG, "Bundle with ID \'(%s)",
569                          std::string(bundleId + "\' is not registered.").c_str());
570             }
571         }
572
573         void ResourceContainerImpl::removeResourceConfig(const std::string &bundleId,
574                 const std::string &resourceUri)
575         {
576             if (m_bundles.find(bundleId) != m_bundles.end())
577             {
578                 if (!m_bundles[bundleId]->getJavaBundle())
579                 {
580                     removeSoBundleResource(bundleId, resourceUri);
581                 }
582             }
583             else
584             {
585                 OC_LOG_V(ERROR, CONTAINER_TAG, "Bundle with ID \'(%s)",
586                          std::string(bundleId + "\' is not registered.").c_str());
587             }
588         }
589
590         std::list< string > ResourceContainerImpl::listBundleResources(const std::string &bundleId)
591         {
592             std::list < string > ret;
593
594             if (m_mapBundleResources.find(bundleId) != m_mapBundleResources.end())
595             {
596                 ret = m_mapBundleResources[bundleId];
597             }
598
599             return ret;
600
601         }
602
603         void ResourceContainerImpl::registerSoBundle(RCSBundleInfo *bundleInfo)
604         {
605             const char *error;
606
607             activator_t *bundleActivator = NULL;
608             deactivator_t *bundleDeactivator = NULL;
609             resourceCreator_t *resourceCreator = NULL;
610             resourceDestroyer_t *resourceDestroyer = NULL;
611             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) bundleInfo;
612             void *bundleHandle = NULL;
613             bundleHandle = dlopen(bundleInfo->getPath().c_str(), RTLD_LAZY);
614
615             if (bundleHandle != NULL)
616             {
617                 bundleActivator =
618                     (activator_t *) dlsym(bundleHandle,
619                                           ("" + bundleInfoInternal->getActivatorName()
620                                            + "_externalActivateBundle").c_str());
621                 bundleDeactivator =
622                     (deactivator_t *) dlsym(bundleHandle,
623                                             ("" + bundleInfoInternal->getActivatorName()
624                                              + "_externalDeactivateBundle").c_str());
625                 resourceCreator =
626                     (resourceCreator_t *) dlsym(bundleHandle,
627                                                 ("" + bundleInfoInternal->getActivatorName()
628                                                  + "_externalCreateResource").c_str());
629                 resourceDestroyer =
630                     (resourceDestroyer_t *) dlsym(bundleHandle,
631                                                   ("" + bundleInfoInternal->getActivatorName()
632                                                    + "_externalDestroyResource").c_str());
633
634
635                 if ((error = dlerror()) != NULL)
636                 {
637                     OC_LOG_V(ERROR, CONTAINER_TAG, "Error : (%s)", error);
638                 }
639                 else
640                 {
641                     ((BundleInfoInternal *) bundleInfo)->setBundleActivator(bundleActivator);
642                     ((BundleInfoInternal *) bundleInfo)->setBundleDeactivator(bundleDeactivator);
643                     ((BundleInfoInternal *) bundleInfo)->setResourceCreator(resourceCreator);
644                     ((BundleInfoInternal *) bundleInfo)->setResourceDestroyer(resourceDestroyer);
645                     ((BundleInfoInternal *) bundleInfo)->setLoaded(true);
646                     ((BundleInfoInternal *) bundleInfo)->setBundleHandle(bundleHandle);
647
648                     m_bundles[bundleInfo->getID()] = ((BundleInfoInternal *) bundleInfo);
649                 }
650             }
651             else
652             {
653                 if ((error = dlerror()) != NULL)
654                 {
655                     OC_LOG_V(ERROR, CONTAINER_TAG, "Error : (%s)", error);
656                 }
657             }
658         }
659
660         void ResourceContainerImpl::activateSoBundle(const std::string &bundleId)
661         {
662             activator_t *bundleActivator = m_bundles[bundleId]->getBundleActivator();
663
664             if (bundleActivator != NULL)
665             {
666                 bundleActivator(this, m_bundles[bundleId]->getID());
667                 m_bundles[bundleId]->setActivated(true);
668             }
669             else
670             {
671                 //Unload module and return error
672                 OC_LOG(ERROR, CONTAINER_TAG, "Activation unsuccessful.");
673             }
674
675             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) m_bundles[bundleId];
676             bundleInfoInternal->setActivated(true);
677
678         }
679
680         void ResourceContainerImpl::undiscoverInputResource(const std::string &outputResourceUri)
681         {
682             auto foundDiscoverResource = m_mapDiscoverResourceUnits.find(outputResourceUri);
683             if (foundDiscoverResource != m_mapDiscoverResourceUnits.end())
684             {
685                 m_mapDiscoverResourceUnits.erase(foundDiscoverResource);
686             }
687         }
688
689         void ResourceContainerImpl::discoverInputResource(const std::string &outputResourceUri)
690         {
691             auto foundOutputResource = m_mapResources.find(outputResourceUri);
692             auto resourceProperty = foundOutputResource->second->m_mapResourceProperty;
693
694             try
695             {
696                 resourceProperty.at(INPUT_RESOURCE);
697             }
698             catch (std::out_of_range &e)
699             {
700                 return;
701             }
702
703             for (auto iter : resourceProperty)
704             {
705                 if (iter.first.compare(INPUT_RESOURCE) == 0)
706                 {
707                     for (auto it : iter.second)
708                     {
709                         auto makeValue = [&](const std::string & reference) mutable -> std::string
710                         {
711                             std::string retStr = "";
712                             try
713                             {
714                                 retStr = it.at(reference);
715                             }
716                             catch (std::out_of_range &e)
717                             {
718                                 return "";
719                             }
720                             return retStr;
721                         };
722                         std::string uri = makeValue(INPUT_RESOURCE_URI);
723                         std::string type = makeValue(INPUT_RESOURCE_TYPE);
724                         std::string attributeName = makeValue(INPUT_RESOURCE_ATTRIBUTENAME);
725
726                         DiscoverResourceUnit::Ptr newDiscoverUnit = std::make_shared
727                                 < DiscoverResourceUnit > (outputResourceUri);
728                         newDiscoverUnit->startDiscover(
729                             DiscoverResourceUnit::DiscoverResourceInfo(uri, type,
730                                     attributeName),
731                             std::bind(&SoftSensorResource::onUpdatedInputResource,
732                                       std::static_pointer_cast< SoftSensorResource > (foundOutputResource->second),
733                                       std::placeholders::_1, std::placeholders::_2));
734
735                         auto foundDiscoverResource = m_mapDiscoverResourceUnits.find(
736                                                          outputResourceUri);
737                         if (foundDiscoverResource != m_mapDiscoverResourceUnits.end())
738                         {
739                             foundDiscoverResource->second.push_back(newDiscoverUnit);
740                         }
741                         else
742                         {
743                             m_mapDiscoverResourceUnits.insert(
744                                 std::make_pair(outputResourceUri,
745                                                std::list< DiscoverResourceUnit::Ptr >
746                             { newDiscoverUnit }));
747                         }
748                     }
749                 }
750             }
751         }
752
753         void ResourceContainerImpl::deactivateSoBundle(const std::string &id)
754         {
755             deactivator_t *bundleDeactivator = m_bundles[id]->getBundleDeactivator();
756
757             OC_LOG_V(INFO, CONTAINER_TAG, "De-activating bundle: (%s)", std::string(
758                          m_bundles[id]->getID()).c_str());
759
760             if (bundleDeactivator != NULL)
761             {
762                 bundleDeactivator();
763                 m_bundles[id]->setActivated(false);
764             }
765             else
766             {
767                 //Unload module and return error
768                 OC_LOG(ERROR, CONTAINER_TAG, "De-activation unsuccessful.");
769             }
770         }
771
772         void ResourceContainerImpl::addSoBundleResource(const std::string &bundleId,
773                 resourceInfo newResourceInfo)
774         {
775             resourceCreator_t *resourceCreator;
776
777             resourceCreator = m_bundles[bundleId]->getResourceCreator();
778
779             if (resourceCreator != NULL)
780             {
781                 resourceCreator(newResourceInfo);
782             }
783             else
784             {
785                 OC_LOG(ERROR, CONTAINER_TAG, "addResource unsuccessful.");
786             }
787         }
788
789         void ResourceContainerImpl::removeSoBundleResource(const std::string &bundleId,
790                 const std::string &resourceUri)
791         {
792             if (m_mapResources.find(resourceUri) != m_mapResources.end())
793             {
794                 resourceDestroyer_t *resourceDestroyer =
795                     m_bundles[bundleId]->getResourceDestroyer();
796
797                 if (resourceDestroyer != NULL)
798                 {
799                     resourceDestroyer(m_mapResources[resourceUri]);
800                 }
801                 else
802                 {
803                     OC_LOG(ERROR, CONTAINER_TAG, "removeResource unsuccessful.");
804                 }
805             }
806         }
807
808         void ResourceContainerImpl::activateBundleThread(const std::string &id)
809         {
810             OC_LOG_V(INFO, CONTAINER_TAG, "Activating bundle: (%s)",
811                      std::string(m_bundles[id]->getID()).c_str());
812
813             if (m_bundles[id]->getJavaBundle())
814             {
815 #if(JAVA_SUPPORT)
816                 activateJavaBundle(id);
817 #endif
818             }
819             else
820             {
821                 activateSoBundle (id);
822             }
823
824             OC_LOG_V(INFO, CONTAINER_TAG, "Bundle activated: (%s)",
825                      std::string(m_bundles[id]->getID()).c_str());
826         }
827
828 #if(JAVA_SUPPORT)
829         JavaVM *ResourceContainerImpl::getJavaVM(string bundleId)
830         {
831             return m_bundleVM[bundleId];
832         }
833
834         void ResourceContainerImpl::registerJavaBundle(RCSBundleInfo *bundleInfo)
835         {
836             OC_LOG_V(INFO, CONTAINER_TAG, "Registering Java bundle (%s)",
837                      std::string(bundleInfo->getID()).c_str());
838             JavaVM *jvm;
839             JNIEnv *env;
840             JavaVMInitArgs vm_args;
841             JavaVMOption options[3];
842
843             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) bundleInfo;
844
845             if (FILE *file = fopen(bundleInfo->getPath().c_str(), "r"))
846             {
847                 fclose(file);
848
849                 OC_LOG_V(INFO, CONTAINER_TAG, "Resource bundle (%s)",
850                          std::string(bundleInfo->getPath() +
851                                      " available.").c_str());
852             }
853             else
854             {
855                 OC_LOG_V(ERROR, CONTAINER_TAG, "Resource bundle (%s)",
856                          std::string(bundleInfo->getPath() + " not available.").c_str());
857
858                 return;
859             }
860
861             char optionString[] = "-Djava.compiler=NONE";
862             options[0].optionString = optionString;
863             char classpath[1000];
864             strcpy(classpath, "-Djava.class.path=");
865             strcat(classpath, bundleInfo->getPath().c_str());
866
867             OC_LOG(INFO, CONTAINER_TAG,
868                    std::string("Configured classpath: ").append(classpath).c_str());
869
870             options[1].optionString = classpath;
871
872             char libraryPath[1000];
873             strcpy(libraryPath, "-Djava.library.path=");
874             strcat(libraryPath, bundleInfo->getLibraryPath().c_str());
875             options[2].optionString = libraryPath;
876
877             OC_LOG(INFO, CONTAINER_TAG,
878                    std::string("Configured library path: ").append(libraryPath).c_str());
879
880             vm_args.version = JNI_VERSION_1_4;
881             vm_args.options = options;
882             vm_args.nOptions = 3;
883             vm_args.ignoreUnrecognized = 1;
884
885             int res;
886             res = JNI_CreateJavaVM(&jvm, (void **) &env, &vm_args);
887
888             if (res < 0)
889             {
890                 OC_LOG(ERROR, CONTAINER_TAG, "cannot create JavaVM.");
891                 return;
892             }
893             else
894             {
895                 OC_LOG(INFO, CONTAINER_TAG, "JVM successfully created.");
896             }
897
898             m_bundleVM.insert(std::pair< string, JavaVM * >(bundleInfo->getID(), jvm));
899
900             const char *className = bundleInfoInternal->getActivatorName().c_str();
901
902             OC_LOG_V(INFO, CONTAINER_TAG, "Looking up class: (%s)", std::string(
903                          bundleInfoInternal->getActivatorName() + "|").c_str());
904
905             jclass bundleActivatorClass = env->FindClass(className);
906
907             if (bundleActivatorClass == NULL)
908             {
909                 OC_LOG_V(ERROR, CONTAINER_TAG, "Cannot register bundle (%s)",
910                          std::string( bundleInfoInternal->getID()
911                                       + " bundle activator(" + bundleInfoInternal->getActivatorName()
912                                       + ") not found ").c_str());
913                 return;
914             }
915
916             jmethodID activateMethod = env->GetMethodID(bundleActivatorClass, "activateBundle",
917                                        "()V");
918
919             if (activateMethod == NULL)
920             {
921                 OC_LOG_V(ERROR, CONTAINER_TAG, "Cannot register bundle (%s)",
922                          std::string( bundleInfoInternal->getID()
923                                       + " activate bundle method not found ").c_str());
924                 return;
925             }
926             bundleInfoInternal->setJavaBundleActivatorMethod(activateMethod);
927
928             jmethodID deactivateMethod = env->GetMethodID(bundleActivatorClass, "deactivateBundle",
929                                          "()V");
930
931             if (deactivateMethod == NULL)
932             {
933                 OC_LOG_V(ERROR, CONTAINER_TAG, "Cannot register bundle (%s)",
934                          std::string( bundleInfoInternal->getID()
935                                       + " deactivate bundle method not found ").c_str());
936                 return;
937             }
938
939             bundleInfoInternal->setJavaBundleDeactivatorMethod(deactivateMethod);
940
941             jmethodID constructor;
942
943             constructor = env->GetMethodID(bundleActivatorClass, "<init>", "(Ljava/lang/String;)V");
944
945             jstring bundleID = env->NewStringUTF(bundleInfoInternal->getID().c_str());
946
947             jobject bundleActivator = env->NewObject(bundleActivatorClass, constructor, bundleID);
948
949             bundleInfoInternal->setJavaBundleActivatorObject(bundleActivator);
950
951             bundleInfoInternal->setLoaded(true);
952
953             m_bundles[bundleInfo->getID()] = ((BundleInfoInternal *)bundleInfo);
954
955
956             OC_LOG(INFO, CONTAINER_TAG, "Bundle registered");
957         }
958
959         void ResourceContainerImpl::activateJavaBundle(string bundleId)
960         {
961             OC_LOG(INFO, CONTAINER_TAG, "Activating java bundle");
962
963             JavaVM *vm = getJavaVM(bundleId);
964             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) m_bundles[bundleId];
965             JNIEnv *env;
966             int envStat = vm->GetEnv((void **) &env, JNI_VERSION_1_4);
967
968             if (envStat == JNI_EDETACHED)
969             {
970                 if (vm->AttachCurrentThread((void **) &env, NULL) != 0)
971                 {
972                     OC_LOG(ERROR, CONTAINER_TAG, "Failed to attach ");
973                 }
974             }
975             else if (envStat == JNI_EVERSION)
976             {
977                 OC_LOG(ERROR, CONTAINER_TAG, "Env: version not supported ");
978             }
979
980             env->CallVoidMethod(bundleInfoInternal->getJavaBundleActivatorObject(),
981                                 bundleInfoInternal->getJavaBundleActivatorMethod());
982
983             m_bundles[bundleId]->setActivated(true);
984         }
985
986         void ResourceContainerImpl::deactivateJavaBundle(string bundleId)
987         {
988             OC_LOG(INFO, CONTAINER_TAG, "Deactivating java bundle");
989
990             JavaVM *vm = getJavaVM(bundleId);
991             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) m_bundles[bundleId];
992             JNIEnv *env;
993             int envStat = vm->GetEnv((void **) &env, JNI_VERSION_1_4);
994
995             if (envStat == JNI_EDETACHED)
996             {
997                 if (vm->AttachCurrentThread((void **) &env, NULL) != 0)
998                 {
999                     OC_LOG(ERROR, CONTAINER_TAG, "Failed to attach ");
1000                 }
1001             }
1002             else if (envStat == JNI_EVERSION)
1003             {
1004                 OC_LOG(ERROR, CONTAINER_TAG, "Env: version not supported ");
1005             }
1006
1007             env->CallVoidMethod(bundleInfoInternal->getJavaBundleActivatorObject(),
1008                                 bundleInfoInternal->getJavaBundleDeactivatorMethod());
1009
1010             m_bundles[bundleId]->setActivated(false);
1011         }
1012
1013         void ResourceContainerImpl::unregisterBundleJava(string id)
1014         {
1015             OC_LOG_V(INFO, CONTAINER_TAG, "Unregister Java bundle: (%s)", std::string(
1016                          m_bundles[id]->getID()).c_str());
1017
1018             OC_LOG(INFO, CONTAINER_TAG, "Destroying JVM");
1019
1020             m_bundleVM[id]->DestroyJavaVM();
1021
1022             delete m_bundles[id];
1023             m_bundles.erase(id);
1024         }
1025 #endif
1026     }
1027 }