f9b504d0985345ed4964664b849eb03a60f6f48b
[platform/upstream/iotivity.git] / service / resource-encapsulation / src / resourceContainer / 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 <dlfcn.h>
22 #include <unistd.h>
23 #include <string.h>
24 #include <iostream>
25 #include <fstream>
26 #include <iostream>
27 #include <fstream>
28 #include <stdio.h>
29
30 #include "ResourceContainerImpl.h"
31 #include "BundleActivator.h"
32 #include "RCSResourceContainer.h"
33 #include "BundleInfoInternal.h"
34 #include "logger.h"
35 #include "oc_logger.hpp"
36
37 using OC::oc_log_stream;
38 using namespace OIC::Service;
39
40 auto error_logger = []() -> boost::iostreams::stream<OC::oc_log_stream> &
41 {
42     static OC::oc_log_stream ols(oc_make_ostream_logger);
43     static boost::iostreams::stream<OC::oc_log_stream> os(ols);
44     os->set_level(OC_LOG_ERROR);
45     os->set_module("ResourceContainerImpl");
46     return os;
47 };
48
49 auto info_logger = []() -> boost::iostreams::stream<OC::oc_log_stream> &
50 {
51     static OC::oc_log_stream ols(oc_make_ostream_logger);
52     static boost::iostreams::stream<OC::oc_log_stream> os(ols);
53     os->set_level(OC_LOG_INFO);
54     os->set_module("ResourceContainerImpl");
55     return os;
56 };
57
58 using namespace std;
59 using namespace OIC::Service;
60
61 namespace OIC
62 {
63     namespace Service
64     {
65
66         ResourceContainerImpl::ResourceContainerImpl()
67         {
68             m_config = nullptr;
69         }
70
71         ResourceContainerImpl::~ResourceContainerImpl()
72         {
73             m_config = nullptr;
74         }
75
76         bool has_suffix(const std::string &str, const std::string &suffix)
77         {
78             return str.size() >= suffix.size()
79                    && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
80         }
81
82         void ResourceContainerImpl::startContainer(const std::string &configFile)
83         {
84             info_logger() << "Starting resource container " << endl;
85 #if (JAVA_SUPPORT)
86             info_logger() << "Resource container has Java support" << endl;
87 #else
88             info_logger() << "Resource container without Java support" << endl;
89 #endif
90
91             if(!configFile.empty()){
92                 m_config = new Configuration(configFile);
93
94                 if (m_config->isLoaded())
95                 {
96                     configInfo bundles;
97                     m_config->getConfiguredBundles(&bundles);
98
99                     for (unsigned int i = 0; i < bundles.size(); i++)
100                     {
101                         RCSBundleInfo *bundleInfo = RCSBundleInfo::build();
102                         bundleInfo->setPath(bundles[i]["path"]);
103                         bundleInfo->setVersion(bundles[i]["version"]);
104                         bundleInfo->setID(bundles[i]["id"]);
105                         if (!bundles[i]["activator"].empty())
106                         {
107                             string activatorName = bundles[i]["activator"];
108                             std::replace(activatorName.begin(), activatorName.end(), '.', '/');
109                             ((BundleInfoInternal *) bundleInfo)->setActivatorName(activatorName);
110                             ((BundleInfoInternal *) bundleInfo)->setLibraryPath(
111                                 bundles[i]["libraryPath"]);
112
113                         }
114                         info_logger() << "Init Bundle:" << bundles[i]["id"] << ";" << bundles[i]["path"]
115                                       << endl;
116                         registerBundle(bundleInfo);
117                         activateBundle(bundleInfo);
118                     }
119                 }
120                 else
121                 {
122                     error_logger() << "Container started with invalid configfile path" << endl;
123                 }
124             }
125             else{
126                 info_logger() << "No configuration file for the container provided" << endl;
127             }
128         }
129
130         void ResourceContainerImpl::stopContainer()
131         {
132             info_logger() << "Stopping resource container.";
133             for (std::map< std::string, BundleInfoInternal * >::iterator it = m_bundles.begin();
134                  it != m_bundles.end(); ++it)
135             {
136                 BundleInfoInternal *bundleInfo = it->second;
137                 deactivateBundle(bundleInfo);
138                 unregisterBundle(bundleInfo);
139             }
140
141             if (!m_mapServers.empty())
142             {
143                 map< std::string, RCSResourceObject::Ptr >::iterator itor = m_mapServers.begin();
144
145                 while (itor != m_mapServers.end())
146                 {
147                     (itor++)->second.reset();
148                 }
149
150                 m_mapResources.clear();
151                 m_mapBundleResources.clear();
152             }
153
154             delete m_config;
155         }
156
157         void ResourceContainerImpl::activateBundle(RCSBundleInfo *bundleInfo)
158         {
159             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) bundleInfo;
160
161             if (bundleInfoInternal->isLoaded())
162             {
163                 activateBundle(bundleInfo->getID());
164             }
165         }
166
167         void ResourceContainerImpl::deactivateBundle(RCSBundleInfo *bundleInfo)
168         {
169             if (((BundleInfoInternal *) bundleInfo)->isActivated())
170             {
171                 deactivateBundle(bundleInfo->getID());
172             }
173         }
174
175         void ResourceContainerImpl::activateBundle(const std::string &id)
176         {
177
178             info_logger() << "Activating bundle: " << m_bundles[id]->getID() << endl;
179
180             if (m_bundles[id]->getJavaBundle())
181             {
182 #if(JAVA_SUPPORT)
183                 activateJavaBundle(id);
184 #endif
185             }
186             else
187             {
188                 activateSoBundle(id);
189             }
190
191             info_logger() << "Bundle activated: " << m_bundles[id]->getID() << endl;
192
193         }
194
195         void ResourceContainerImpl::deactivateBundle(const std::string &id)
196         {
197
198             if (m_bundles[id]->getJavaBundle())
199             {
200 #if(JAVA_SUPPORT)
201                 deactivateJavaBundle(id);
202 #endif
203             }
204             else
205             {
206                 deactivateSoBundle(id);
207             }
208         }
209
210         // loads the bundle
211         void ResourceContainerImpl::registerBundle(RCSBundleInfo *bundleInfo)
212         {
213             info_logger() << "Registering bundle: " << bundleInfo->getPath() << endl;
214
215             if (has_suffix(bundleInfo->getPath(), ".jar"))
216             {
217 #if(JAVA_SUPPORT)
218                 ((BundleInfoInternal *) bundleInfo)->setJavaBundle(true);
219                 registerJavaBundle(bundleInfo);
220 #endif
221             }
222             else
223             {
224                 ((BundleInfoInternal *) bundleInfo)->setJavaBundle(false);
225                 registerSoBundle(bundleInfo);
226             }
227         }
228
229         void ResourceContainerImpl::unregisterBundle(RCSBundleInfo *bundleInfo)
230         {
231             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) bundleInfo;
232             if (bundleInfoInternal->isLoaded() && !bundleInfoInternal->isActivated())
233             {
234                 if (!bundleInfoInternal->getJavaBundle())
235                 {
236                     unregisterBundleSo(bundleInfo->getID());
237                 }
238                 else
239                 {
240 #if(JAVA_SUPPORT)
241                     unregisterBundleJava(bundleInfo->getID());
242 #endif
243                 }
244             }
245         }
246
247         void ResourceContainerImpl::unregisterBundleSo(const std::string &id)
248         {
249             void *bundleHandle = m_bundles[id]->getBundleHandle();
250             info_logger() << "Unregister bundle: " << m_bundles[id]->getID() << ", "
251                           << m_bundles[id]->getID() << endl;
252             char *error;
253             dlclose(bundleHandle);
254             if ((error = dlerror()) != NULL)
255             {
256                 error_logger() << error << endl;
257             }
258             else
259             {
260                 delete m_bundles[id];
261                 m_bundles.erase(id);
262             }
263         }
264
265         void ResourceContainerImpl::registerResource(BundleResource *resource)
266         {
267             string strUri = resource->m_uri;
268             string strResourceType = resource->m_resourceType;
269             RCSResourceObject::Ptr server = nullptr;
270
271             info_logger() << "Registration of resource " << strUri << "," << strResourceType << endl;
272
273             if (m_mapResources.find(strUri) == m_mapResources.end())
274             {
275                 server = buildResourceObject(strUri, strResourceType);
276
277                 if (server != nullptr)
278                 {
279                     m_mapServers[strUri] = server;
280                     m_mapResources[strUri] = resource;
281                     m_mapBundleResources[resource->m_bundleId].push_back(strUri);
282
283                     resource->registerObserver(this);
284
285                     server->setGetRequestHandler(
286                         std::bind(&ResourceContainerImpl::getRequestHandler, this,
287                                   std::placeholders::_1, std::placeholders::_2));
288
289                     server->setSetRequestHandler(
290                         std::bind(&ResourceContainerImpl::setRequestHandler, this,
291                                   std::placeholders::_1, std::placeholders::_2));
292
293                     info_logger() << "Registration finished " << strUri << "," << strResourceType
294                                   << endl;
295                 }
296             }
297             else
298             {
299                 error_logger() << "resource with " << strUri << " already exists." << endl;
300             }
301         }
302
303         void ResourceContainerImpl::unregisterResource(BundleResource *resource)
304         {
305             string strUri = resource->m_uri;
306             string strResourceType = resource->m_resourceType;
307
308             info_logger() << "Unregistration of resource " << resource->m_uri << "," << resource->m_resourceType
309                           << endl;
310
311             if (m_mapServers.find(strUri) != m_mapServers.end())
312             {
313                 m_mapServers[strUri].reset();
314
315                 m_mapResources.erase(m_mapResources.find(strUri));
316                 m_mapBundleResources[resource->m_bundleId].remove(strUri);
317             }
318         }
319
320         void ResourceContainerImpl::getBundleConfiguration(const std::string &bundleId,
321                 configInfo *configOutput)
322         {
323             if (m_config)
324             {
325                 m_config->getBundleConfiguration(bundleId, (configInfo *) configOutput);
326             }
327         }
328
329         void ResourceContainerImpl::getResourceConfiguration(const std::string &bundleId,
330                 std::vector< resourceInfo > *configOutput)
331         {
332             if (m_config)
333             {
334                 m_config->getResourceConfiguration(bundleId, configOutput);
335             }
336         }
337
338         RCSGetResponse ResourceContainerImpl::getRequestHandler(const RCSRequest &request,
339                 const RCSResourceAttributes &attributes)
340         {
341             RCSResourceAttributes attr;
342
343             if (m_mapServers.find(request.getResourceUri()) != m_mapServers.end()
344                 && m_mapResources.find(request.getResourceUri()) != m_mapResources.end())
345             {
346                 for (string attrName : m_mapResources[request.getResourceUri()]->getAttributeNames())
347                 {
348                     attr[attrName] = m_mapResources[request.getResourceUri()]->getAttribute(
349                                          attrName);
350                 }
351             }
352
353             return RCSGetResponse::create(attr);
354         }
355
356         RCSSetResponse ResourceContainerImpl::setRequestHandler(const RCSRequest &request,
357                 const RCSResourceAttributes &attributes)
358         {
359             RCSResourceAttributes attr = attributes;
360
361             if (m_mapServers.find(request.getResourceUri()) != m_mapServers.end()
362                 && m_mapResources.find(request.getResourceUri()) != m_mapResources.end())
363             {
364                 for (string attrName : m_mapResources[request.getResourceUri()]->getAttributeNames())
365                 {
366                     if (!attr[attrName].toString().empty())
367                     {
368                         m_mapResources[request.getResourceUri()]->setAttribute(attrName,
369                                 attr[attrName].toString());
370                     }
371                 }
372             }
373
374             return RCSSetResponse::create(attr);
375         }
376
377         void ResourceContainerImpl::onNotificationReceived(const std::string &strResourceUri)
378         {
379             info_logger() << "ResourceContainerImpl::onNotificationReceived\n\tnotification from "
380                           << strResourceUri << ".\n";
381
382             if (m_mapServers.find(strResourceUri) != m_mapServers.end())
383             {
384                 m_mapServers[strResourceUri]->notify();
385             }
386         }
387
388         ResourceContainerImpl *ResourceContainerImpl::getImplInstance()
389         {
390             static ResourceContainerImpl m_instance;
391             return &m_instance;
392         }
393
394         RCSResourceObject::Ptr ResourceContainerImpl::buildResourceObject(const std::string & strUri,
395                 const std::string & strResourceType)
396         {
397             return RCSResourceObject::Builder(strUri, strResourceType, "DEFAULT_INTERFACE").setObservable(
398                        true).setDiscoverable(true).build();
399         }
400
401         void ResourceContainerImpl::startBundle(const std::string &bundleId)
402         {
403             if (m_bundles.find(bundleId) != m_bundles.end())
404             {
405                 if (!m_bundles[bundleId]->isActivated())
406                     activateBundle(m_bundles[bundleId]);
407                 else
408                     error_logger() << "Bundle already started" << endl;
409             }
410             else
411             {
412                 error_logger() << "Bundle with ID \'" << bundleId << "\' is not registered." << endl;
413             }
414         }
415
416         void ResourceContainerImpl::stopBundle(const std::string &bundleId)
417         {
418             if (m_bundles.find(bundleId) != m_bundles.end())
419             {
420                 if (m_bundles[bundleId]->isActivated())
421                     deactivateBundle(m_bundles[bundleId]);
422                 else
423                     error_logger() << "Bundle not activated" << endl;
424             }
425             else
426             {
427                 error_logger() << "Bundle with ID \'" << bundleId << "\' is not registered." << endl;
428             }
429         }
430
431         void ResourceContainerImpl::addBundle(const std::string &bundleId, const std::string &bundleUri, const std::string &bundlePath,
432                                               std::map< string, string > params)
433         {
434             if (m_bundles.find(bundleId) != m_bundles.end())
435                 error_logger() << "BundleId already exist" << endl;
436
437             else
438             {
439                 RCSBundleInfo *bundleInfo = RCSBundleInfo::build();
440                 bundleInfo->setID(bundleId);
441                 bundleInfo->setPath(bundlePath);
442                 if (params.find("activator") != params.end())
443                 {
444                     string activatorName = params["activator"];
445                     std::replace(activatorName.begin(), activatorName.end(), '.', '/');
446                     ((BundleInfoInternal *) bundleInfo)->setActivatorName(activatorName);
447                     ((BundleInfoInternal *) bundleInfo)->setLibraryPath(params["libraryPath"]);
448                 }
449
450                 info_logger() << "Add Bundle:" << bundleInfo->getID().c_str() << ";"
451                               << bundleInfo->getPath().c_str() << endl;
452
453                 registerBundle(bundleInfo);
454             }
455         }
456
457         void ResourceContainerImpl::removeBundle(const std::string &bundleId)
458         {
459             if (m_bundles.find(bundleId) != m_bundles.end())
460             {
461                 BundleInfoInternal *bundleInfo = m_bundles[bundleId];
462                 if (bundleInfo->isActivated())
463                     deactivateBundle(bundleInfo);
464
465                 if (bundleInfo->isLoaded())
466                     unregisterBundle(bundleInfo);
467             }
468             else
469             {
470                 error_logger() << "Bundle with ID \'" << bundleId << "\' is not registered."
471                                << endl;
472             }
473         }
474
475         std::list< RCSBundleInfo * > ResourceContainerImpl::listBundles()
476         {
477             std::list< RCSBundleInfo * > ret;
478             for (std::map< std::string, BundleInfoInternal * >::iterator it = m_bundles.begin();
479                  it != m_bundles.end(); ++it)
480             {
481                 {
482                     RCSBundleInfo *bundleInfo = RCSBundleInfo::build();
483                     ((BundleInfoInternal *) bundleInfo)->setBundleInfo((RCSBundleInfo *) it->second);
484                     ret.push_back(it->second);
485                 }
486             }
487             return ret;
488         }
489
490         void ResourceContainerImpl::addResourceConfig(const std::string &bundleId, const std::string &resourceUri,
491                 std::map< string, string > params)
492         {
493             if (m_bundles.find(bundleId) != m_bundles.end())
494             {
495                 if (!m_bundles[bundleId]->getJavaBundle())
496                 {
497                     resourceInfo newResourceInfo;
498                     newResourceInfo.uri = resourceUri;
499
500                     if (params.find("name") != params.end())
501                         newResourceInfo.name = params["name"];
502                     if (params.find("resourceType") != params.end())
503                         newResourceInfo.resourceType = params["resourceType"];
504                     if (params.find("address") != params.end())
505                         newResourceInfo.address = params["address"];
506
507                     addSoBundleResource(bundleId, newResourceInfo);
508                 }
509             }
510             else
511             {
512                 error_logger() << "Bundle with ID \'" << bundleId << "\' is not registered."
513                                << endl;
514             }
515         }
516
517         void ResourceContainerImpl::removeResourceConfig(const std::string &bundleId, const std::string &resourceUri)
518         {
519             if (m_bundles.find(bundleId) != m_bundles.end())
520             {
521                 if (!m_bundles[bundleId]->getJavaBundle())
522                 {
523                     removeSoBundleResource(bundleId, resourceUri);
524                 }
525             }
526             else
527             {
528                 error_logger() << "Bundle with ID \'" << bundleId << "\' is not registered."
529                                << endl;
530             }
531         }
532
533         std::list< string > ResourceContainerImpl::listBundleResources(const std::string &bundleId)
534         {
535             std::list< string > ret;
536
537             if (m_mapBundleResources.find(bundleId) != m_mapBundleResources.end())
538             {
539                 ret = m_mapBundleResources[bundleId];
540             }
541
542             return ret;
543
544         }
545
546         void ResourceContainerImpl::registerSoBundle(RCSBundleInfo *bundleInfo)
547         {
548             char *error;
549
550             activator_t *bundleActivator = NULL;
551             deactivator_t *bundleDeactivator = NULL;
552             resourceCreator_t *resourceCreator = NULL;
553             resourceDestroyer_t *resourceDestroyer = NULL;
554
555             //sstream << bundleInfo.path << std::ends;
556
557             void *bundleHandle = NULL;
558             bundleHandle = dlopen(bundleInfo->getPath().c_str(), RTLD_LAZY);
559
560             if (bundleHandle != NULL)
561             {
562                 bundleActivator = (activator_t *) dlsym(bundleHandle, "externalActivateBundle");
563                 bundleDeactivator = (deactivator_t *) dlsym(bundleHandle,
564                                     "externalDeactivateBundle");
565                 resourceCreator = (resourceCreator_t *) dlsym(bundleHandle,
566                                   "externalCreateResource");
567                 resourceDestroyer = (resourceDestroyer_t *) dlsym(bundleHandle,
568                                     "externalDestroyResource");
569
570                 if ((error = dlerror()) != NULL)
571                 {
572                     error_logger() << error << endl;
573                 }
574                 else
575                 {
576                     ((BundleInfoInternal *) bundleInfo)->setBundleActivator(bundleActivator);
577                     ((BundleInfoInternal *) bundleInfo)->setBundleDeactivator(bundleDeactivator);
578                     ((BundleInfoInternal *) bundleInfo)->setResourceCreator(resourceCreator);
579                     ((BundleInfoInternal *) bundleInfo)->setResourceDestroyer(resourceDestroyer);
580                     ((BundleInfoInternal *) bundleInfo)->setLoaded(true);
581                     ((BundleInfoInternal *) bundleInfo)->setBundleHandle(bundleHandle);
582
583                     m_bundles[bundleInfo->getID()] = ((BundleInfoInternal *) bundleInfo);
584                 }
585             }
586             else
587             {
588                 if ((error = dlerror()) != NULL)
589                 {
590                     error_logger() << error << endl;
591                 }
592             }
593         }
594
595         void ResourceContainerImpl::activateSoBundle(const std::string &bundleId)
596         {
597             activator_t *bundleActivator = m_bundles[bundleId]->getBundleActivator();
598
599             if (bundleActivator != NULL)
600             {
601                 bundleActivator(this, m_bundles[bundleId]->getID());
602                 m_bundles[bundleId]->setActivated(true);
603             }
604             else
605             {
606                 //Unload module and return error
607                 error_logger() << "Activation unsuccessful." << endl;
608             }
609
610             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) m_bundles[bundleId];
611             bundleInfoInternal->setActivated(true);
612         }
613
614         void ResourceContainerImpl::deactivateSoBundle(const std::string &id)
615         {
616             deactivator_t *bundleDeactivator = m_bundles[id]->getBundleDeactivator();
617             info_logger() << "De-activating bundle: " << m_bundles[id]->getID() << endl;
618
619             if (bundleDeactivator != NULL)
620             {
621                 bundleDeactivator();
622                 m_bundles[id]->setActivated(false);
623             }
624             else
625             {
626                 //Unload module and return error
627                 error_logger() << "De-activation unsuccessful." << endl;
628             }
629         }
630
631         void ResourceContainerImpl::addSoBundleResource(const std::string &bundleId,
632                 resourceInfo newResourceInfo)
633         {
634             resourceCreator_t *resourceCreator;
635
636             resourceCreator = m_bundles[bundleId]->getResourceCreator();
637
638             if (resourceCreator != NULL)
639             {
640                 resourceCreator(newResourceInfo);
641             }
642             else
643             {
644                 error_logger() << "addResource unsuccessful." << endl;
645             }
646         }
647
648         void ResourceContainerImpl::removeSoBundleResource(const std::string &bundleId, const std::string &resourceUri)
649         {
650             if (m_mapResources.find(resourceUri) != m_mapResources.end())
651             {
652                 resourceDestroyer_t *resourceDestroyer =
653                     m_bundles[bundleId]->getResourceDestroyer();
654
655                 if (resourceDestroyer != NULL)
656                 {
657                     resourceDestroyer(m_mapResources[resourceUri]);
658                 }
659                 else
660                 {
661                     error_logger() << "removeResource unsuccessful." << endl;
662                 }
663             }
664         }
665
666 #if(JAVA_SUPPORT)
667         JavaVM *ResourceContainerImpl::getJavaVM(string bundleId)
668         {
669             return m_bundleVM[bundleId];
670         }
671
672         void ResourceContainerImpl::registerJavaBundle(RCSBundleInfo *bundleInfo)
673         {
674             info_logger() << "Registering Java bundle " << bundleInfo->getID() << endl;
675             JavaVM *jvm;
676             JNIEnv *env;
677             JavaVMInitArgs vm_args;
678             JavaVMOption options[3];
679
680             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) bundleInfo;
681
682             if (FILE *file = fopen(bundleInfo->getPath().c_str(), "r"))
683             {
684                 fclose(file);
685                 info_logger() << "Resource bundle " << bundleInfo->getPath().c_str() << " available." << endl;
686                 //return true;
687             }
688             else
689             {
690                 error_logger() << "Resource bundle " << bundleInfo->getPath().c_str() << " not available" << endl;
691                 return;
692             }
693
694             char optionString[] = "-Djava.compiler=NONE";
695             options[0].optionString = optionString;
696             char classpath[1000];
697             strcpy(classpath, "-Djava.class.path=");
698             strcat(classpath, bundleInfo->getPath().c_str());
699
700             info_logger() << "Configured classpath: " << classpath << "|" << endl;
701
702             options[1].optionString = classpath;
703
704             char libraryPath[1000];
705             strcpy(libraryPath, "-Djava.library.path=");
706             strcat(libraryPath, bundleInfo->getLibraryPath().c_str());
707             options[2].optionString = libraryPath;
708
709             info_logger() << "Configured library path: " << libraryPath << "|" << endl;
710
711             vm_args.version = JNI_VERSION_1_4;
712             vm_args.options = options;
713             vm_args.nOptions = 3;
714             vm_args.ignoreUnrecognized = 1;
715
716             int res;
717             res = JNI_CreateJavaVM(&jvm, (void **) &env, &vm_args);
718
719             if (res < 0)
720             {
721                 error_logger() << " cannot create JavaVM." << endl;
722                 return;
723             }
724             else
725             {
726                 info_logger() << "JVM successfully created " << endl;
727             }
728
729             m_bundleVM.insert(std::pair< string, JavaVM * >(bundleInfo->getID(), jvm));
730
731             const char *className = bundleInfoInternal->getActivatorName().c_str();
732
733             info_logger() << "Looking up class: " << bundleInfoInternal->getActivatorName() << "|" << endl;
734
735             jclass bundleActivatorClass = env->FindClass(className);
736
737             if (bundleActivatorClass == NULL)
738             {
739                 error_logger() << "Cannot register bundle " << bundleInfoInternal->getID()
740                                << " bundle activator(" << bundleInfoInternal->getActivatorName()
741                                << ") not found " << endl;
742                 return;
743             }
744
745             jmethodID activateMethod = env->GetMethodID(bundleActivatorClass, "activateBundle",
746                                        "()V");
747
748             if (activateMethod == NULL)
749             {
750                 error_logger() << "Cannot register bundle " << bundleInfoInternal->getID()
751                                << " activate bundle method not found " << endl;
752                 return;
753             }
754             bundleInfoInternal->setJavaBundleActivatorMethod(activateMethod);
755
756             jmethodID deactivateMethod = env->GetMethodID(bundleActivatorClass, "deactivateBundle",
757                                          "()V");
758
759             if (deactivateMethod == NULL)
760             {
761                 error_logger() << "Cannot register bundle " << bundleInfoInternal->getID()
762                                << " deactivate bundle method not found " << endl;
763                 return;
764             }
765
766             bundleInfoInternal->setJavaBundleDeactivatorMethod(deactivateMethod);
767
768             jmethodID constructor;
769
770             constructor = env->GetMethodID(bundleActivatorClass, "<init>", "(Ljava/lang/String;)V");
771
772             jstring bundleID = env->NewStringUTF(bundleInfoInternal->getID().c_str());
773
774             jobject bundleActivator = env->NewObject(bundleActivatorClass, constructor, bundleID);
775
776             bundleInfoInternal->setJavaBundleActivatorObject(bundleActivator);
777
778             bundleInfoInternal->setLoaded(true);
779
780             m_bundles[bundleInfo->getID()] = ((BundleInfoInternal *)bundleInfo);
781
782             info_logger() << "Bundle registered" << endl;
783         }
784
785         void ResourceContainerImpl::activateJavaBundle(string bundleId)
786         {
787             info_logger() << "Activating java bundle" << endl;
788             JavaVM *vm = getJavaVM(bundleId);
789             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) m_bundles[bundleId];
790             JNIEnv *env;
791             int envStat = vm->GetEnv((void **) &env, JNI_VERSION_1_4);
792
793             if (envStat == JNI_EDETACHED)
794             {
795                 if (vm->AttachCurrentThread((void **) &env, NULL) != 0)
796                 {
797                     error_logger() << "Failed to attach " << endl;
798                 }
799             }
800             else if (envStat == JNI_EVERSION)
801             {
802                 error_logger() << "Env: version not supported " << endl;
803             }
804
805             env->CallVoidMethod(bundleInfoInternal->getJavaBundleActivatorObject(),
806                                 bundleInfoInternal->getJavaBundleActivatorMethod());
807
808             m_bundles[bundleId]->setActivated(true);
809         }
810
811         void ResourceContainerImpl::deactivateJavaBundle(string bundleId)
812         {
813             info_logger() << "Deactivating java bundle" << endl;
814             JavaVM *vm = getJavaVM(bundleId);
815             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) m_bundles[bundleId];
816             JNIEnv *env;
817             int envStat = vm->GetEnv((void **) &env, JNI_VERSION_1_4);
818
819             if (envStat == JNI_EDETACHED)
820             {
821                 if (vm->AttachCurrentThread((void **) &env, NULL) != 0)
822                 {
823                     error_logger() << "Failed to attach " << endl;
824                 }
825             }
826             else if (envStat == JNI_EVERSION)
827             {
828                 error_logger() << "Env: version not supported " << endl;
829             }
830
831             env->CallVoidMethod(bundleInfoInternal->getJavaBundleActivatorObject(),
832                                 bundleInfoInternal->getJavaBundleDeactivatorMethod());
833
834             m_bundles[bundleId]->setActivated(false);
835         }
836
837         void ResourceContainerImpl::unregisterBundleJava(string id)
838         {
839             info_logger() << "Unregister Java bundle: " << m_bundles[id]->getID() << ", "
840                           << m_bundles[id]->getID() << endl;
841
842             info_logger() << "Destroying JVM" << endl;
843             m_bundleVM[id]->DestroyJavaVM();
844
845             delete m_bundles[id];
846             m_bundles.erase(id);
847         }
848 #endif
849     }
850
851 }
852