53dae9406b4cdf5255e8a4e906648cec885df22d
[framework/web/wrt-plugins-common.git] / src / modules / tizen / PluginManager / PluginManager.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /*
17  * @file        PluginManager.cpp
18  * @author      Lukasz Marek (l.marek@samsung.com)
19  * @version     0.1
20  * @brief
21  */
22
23 #include "PluginManager.h"
24 #include <algorithm>
25 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
26 #include <dpl/wrt-dao-ro/plugin_dao_read_only.h>
27 #include <dpl/wrt-dao-ro/WrtDatabase.h>
28 #include <plugin_logic.h>
29 #include <dpl/wrt-dao-ro/common_dao_types.h>
30 #include <Commons/Exception.h>
31 #include <CommonsJavaScript/Converter.h>
32 #include <dpl/exception.h>
33 #include <dpl/log/log.h>
34 #include <dpl/foreach.h>
35
36 using namespace std;
37
38 namespace {
39 const string GLOBAL_OBJECT_NAME = "GLOBAL_OBJECT";
40 const char* SEPARATOR = ".";
41 }
42
43 namespace WrtDeviceApis {
44 namespace PluginManager {
45
46
47 PluginManager::PluginManager(int widgetHandle,
48                              const string &objectUri,
49                              JSContextRef context) :
50     m_widgetHandle(widgetHandle),
51     m_objectUri(GLOBAL_OBJECT_NAME),
52     m_context(context)
53 {
54     m_objectUri.append(SEPARATOR).append(objectUri);
55     WrtDB::WrtDatabase::attachToThread();
56 }
57
58 PluginManager::~PluginManager()
59 {
60     ObjectList::iterator it = m_objectList.begin();
61     for (; it != m_objectList.end(); ++it)
62     {
63         JSValueUnprotect(m_context, it->second);
64     }
65     WrtDB::WrtDatabase::detachFromThread();
66 }
67
68 bool PluginManager::hasChild(const string &name) const
69 {
70     const PropertyList &prop = getProperties();
71     return prop.end() != find(prop.begin(), prop.end(), name);
72 }
73
74 bool PluginManager::loadChild(const string &name) const
75 {
76     LogInfo("loading " << name);
77     string localUri = m_objectUri;
78     localUri.append(SEPARATOR).append(name);
79
80     WrtDB::DbPluginHandle handle =
81         WrtDB::PluginDAOReadOnly::getPluginHandleForImplementedObject(localUri);
82     if (handle == WrtDB::INVALID_PLUGIN_HANDLE) {
83         LogError("Plugin not found");
84         return false;
85     }
86
87     // Create dao
88     WrtDB::DbWidgetFeatureSet features;
89     Try
90     {
91         WrtDB::WidgetDAOReadOnly dao(m_widgetHandle);
92         features = dao.getFeaturesList();
93     }
94     Catch(WrtDB::WidgetDAOReadOnly::Exception::Base)
95     {
96         // Error while reading database - widget handle may
97         // be invalid or some data may be missing in database
98         LogError("Cannot get feature list");
99         return false;
100     }
101
102     FOREACH (it, features) {
103         if (it->pluginId == handle) {
104             PluginLogicSingleton::Instance().addSpecialFeatureToSession(*it);
105             return true;
106         }
107     }
108     LogError("Plugin not loaded");
109     return false;
110 }
111
112 JSValueRef PluginManager::getProperty(const string &name) const
113 {
114     LogDebug("getProperty " << name);
115     ObjectList::const_iterator it = m_objectList.find(name);
116     if (it != m_objectList.end()) {
117         //return already set value
118         return it->second;
119     }
120
121     if (!loadChild(name)) {
122         ThrowMsg(Commons::PlatformException, "Cannot load plugin");
123     }
124
125     it = m_objectList.find(name);
126     if (it != m_objectList.end()) {
127         //return set value
128         return it->second;
129     }
130
131     ThrowMsg(Commons::PlatformException, "Cannot obtain property");
132 }
133
134 bool PluginManager::setProperty(const string &name,
135                                 JSValueRef value)
136 {
137     LogDebug("setProperty " << name);
138     if (m_objectList.count(name) > 0) {
139         JSValueUnprotect(m_context, m_objectList[name]);
140     }
141     JSValueProtect(m_context, value);
142     m_objectList[name] = value;
143     return true;
144 }
145
146 bool PluginManager::deleteProperty(const string &name)
147 {
148     if (m_objectList.count(name) > 0) {
149         LogDebug("deleteProperty " << name);
150         JSValueUnprotect(m_context, m_objectList[name]);
151         m_objectList.erase(name);
152         return true;
153     }
154     return false;
155 }
156
157
158 Api::IPluginManager::PropertyList PluginManager::getProperties() const
159 {
160     if (!m_propertyCache.IsNull()) {
161         return *m_propertyCache;
162     }
163
164     m_propertyCache = PropertyList();
165
166     WrtDB::DbWidgetFeatureSet features;
167     Try
168     {
169         WrtDB::WidgetDAOReadOnly dao(m_widgetHandle);
170         features = dao.getFeaturesList();
171     }
172     Catch(WrtDB::WidgetDAOReadOnly::Exception::Base)
173     {
174         LogError("Cannot get feature list");
175         ReThrow(Commons::PlatformException);
176     }
177
178     string localUri = m_objectUri + SEPARATOR;
179     WrtDB::DbWidgetFeatureSet::const_iterator feature = features.begin();
180     for (; feature != features.end(); ++feature) {
181         WrtDB::ImplementedObjectsList implObjs =
182             WrtDB::PluginDAOReadOnly::getImplementedObjectsForPluginHandle(
183                 feature->pluginId);
184         FOREACH(it, implObjs) {
185             //check if implemented object stats with localUri
186             if (it->find(localUri) == 0) {
187                 string property = *it;
188                 //remove local uri that predicts property name.
189                 property.erase(0, localUri.size());
190                 //check if property has its own properties.
191                 size_t pos = property.find(SEPARATOR);
192                 if (pos != string::npos) {
193                     //if so then remove them.
194                     property.erase(pos);
195                 }
196                 m_propertyCache->push_back(property);
197             }
198         }
199     }
200     return *m_propertyCache;
201 }
202
203 void PluginManager::addPropertiesToList(
204         JSPropertyNameAccumulatorRef propertyNames) const
205 {
206     PropertyList properties = getProperties();
207     CommonsJavaScript::Converter converter(m_context);
208     FOREACH(it, properties) {
209         JSStringRef name = converter.toJSStringRef(*it);
210         JSPropertyNameAccumulatorAddName(propertyNames, name);
211         JSStringRelease(name);
212     }
213
214 }
215
216 }
217 }