27af1febb581faad349cea66bfa41bac11c3b75b
[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                              JSObjectRef object,
50                              JSContextRef context) :
51     m_widgetHandle(widgetHandle),
52     m_objectUri(GLOBAL_OBJECT_NAME),
53     m_shortUri(objectUri),
54     m_objectInstance(object),
55     m_context(context)
56 {
57     m_objectUri.append(SEPARATOR).append(objectUri);
58     WrtDB::WrtDatabase::attachToThreadRO();
59 }
60
61 PluginManager::~PluginManager()
62 {
63     ObjectList::iterator it = m_objectList.begin();
64     for (; it != m_objectList.end(); ++it)
65     {
66         JSValueUnprotect(m_context, it->second);
67     }
68     WrtDB::WrtDatabase::detachFromThread();
69 }
70
71 bool PluginManager::hasChild(const string &name) const
72 {
73     const PropertyList &prop = getProperties();
74     return prop.end() != find(prop.begin(), prop.end(), name);
75 }
76
77 bool PluginManager::loadChild(const string &name) const
78 {
79     LogInfo("loading " << name);
80     string localUri = m_objectUri;
81     localUri.append(SEPARATOR).append(name);
82
83     WrtDB::DbPluginHandle handle =
84         WrtDB::PluginDAOReadOnly::getPluginHandleForImplementedObject(localUri);
85     if (handle == WrtDB::INVALID_PLUGIN_HANDLE) {
86         LogError("Plugin not found");
87         return false;
88     }
89
90     WrtDB::DbWidgetFeatureSet features;
91     Try
92     {
93         WrtDB::WidgetDAOReadOnly dao(m_widgetHandle);
94         features = dao.getFeaturesList();
95     }
96     Catch(WrtDB::WidgetDAOReadOnly::Exception::Base)
97     {
98         // Error while reading database - widget handle may
99         // be invalid or some data may be missing in database
100         LogError("Cannot get feature list");
101         return false;
102     }
103
104     //check does plugin with feature was requested
105     FOREACH (it, features)
106     {
107         if (it->pluginId == handle)
108         {
109             if(it->rejected)
110             {
111                 LogWarning("Feature rejected by ACE");
112                 continue;
113             }
114
115             PluginLogic::JavaScriptObject jsObject = {m_objectInstance,
116                                                       m_shortUri};
117
118             return PluginLogicSingleton::Instance().loadPluginOnDemand(
119                 handle, jsObject);
120         }
121     }
122     LogError("Plugin not loaded");
123     return false;
124 }
125
126 JSValueRef PluginManager::getProperty(const string &name) const
127 {
128     LogDebug("getProperty " << name);
129     ObjectList::const_iterator it = m_objectList.find(name);
130     if (it != m_objectList.end()) {
131         //return already set value
132         return it->second;
133     }
134
135     if (!loadChild(name)) {
136         ThrowMsg(Commons::PlatformException, "Cannot load plugin");
137     }
138
139     it = m_objectList.find(name);
140     if (it != m_objectList.end()) {
141         //return set value
142         return it->second;
143     }
144
145     ThrowMsg(Commons::PlatformException, "Cannot obtain property");
146 }
147
148 bool PluginManager::setProperty(const string &name,
149                                 JSValueRef value)
150 {
151     LogDebug("setProperty " << name);
152     if (m_objectList.count(name) > 0) {
153         JSValueUnprotect(m_context, m_objectList[name]);
154     }
155     JSValueProtect(m_context, value);
156     m_objectList[name] = value;
157     return true;
158 }
159
160 bool PluginManager::deleteProperty(const string &name)
161 {
162     if (m_objectList.count(name) > 0) {
163         LogDebug("deleteProperty " << name);
164         JSValueUnprotect(m_context, m_objectList[name]);
165         m_objectList.erase(name);
166         return true;
167     }
168     return false;
169 }
170
171
172 Api::IPluginManager::PropertyList PluginManager::getProperties() const
173 {
174     if (!m_propertyCache.IsNull()) {
175         return *m_propertyCache;
176     }
177
178     m_propertyCache = PropertyList();
179
180     WrtDB::DbWidgetFeatureSet features;
181     Try
182     {
183         WrtDB::WidgetDAOReadOnly dao(m_widgetHandle);
184         features = dao.getFeaturesList();
185     }
186     Catch(WrtDB::WidgetDAOReadOnly::Exception::Base)
187     {
188         LogError("Cannot get feature list");
189         ReThrow(Commons::PlatformException);
190     }
191
192     string localUri = m_objectUri + SEPARATOR;
193     WrtDB::DbWidgetFeatureSet::const_iterator feature = features.begin();
194     for (; feature != features.end(); ++feature) {
195         WrtDB::ImplementedObjectsList implObjs =
196             WrtDB::PluginDAOReadOnly::getImplementedObjectsForPluginHandle(
197                 feature->pluginId);
198         FOREACH(it, implObjs) {
199             //check if implemented object stats with localUri
200             if (it->find(localUri) == 0) {
201                 string property = *it;
202                 //remove local uri that predicts property name.
203                 property.erase(0, localUri.size());
204                 //check if property has its own properties.
205                 size_t pos = property.find(SEPARATOR);
206                 if (pos != string::npos) {
207                     //if so then remove them.
208                     property.erase(pos);
209                 }
210                 m_propertyCache->push_back(property);
211             }
212         }
213     }
214     return *m_propertyCache;
215 }
216
217 void PluginManager::addPropertiesToList(
218         JSPropertyNameAccumulatorRef propertyNames) const
219 {
220     PropertyList properties = getProperties();
221     CommonsJavaScript::Converter converter(m_context);
222     FOREACH(it, properties) {
223         JSStringRef name = converter.toJSStringRef(*it);
224         JSPropertyNameAccumulatorAddName(propertyNames, name);
225         JSStringRelease(name);
226     }
227
228 }
229
230 }
231 }