1 /*=============================================================================
2
3 Library: CTK
4
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics
7
8 Licensed under the Apache License, Version 2.0 (the "License");
9 you may not use this file except in compliance with the License.
10 You may obtain a copy of the License at
11
12 http://www.apache.org/licenses/LICENSE-2.0
13
14 Unless required by applicable law or agreed to in writing, software
15 distributed under the License is distributed on an "AS IS" BASIS,
16 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 See the License for the specific language governing permissions and
18 limitations under the License.
19
20 =============================================================================*/
21
22
23 #include "ctkConfigurationImpl_p.h"
24
25 #include "ctkConfigurationAdminFactory_p.h"
26 #include "ctkConfigurationStore_p.h"
27
28 #include <service/cm/ctkConfigurationAdmin.h>
29 #include <ctkPluginConstants.h>
30
31 #include <QThread>
32
ctkConfigurationImpl(ctkConfigurationAdminFactory * configurationAdminFactory,ctkConfigurationStore * configurationStore,const QString & factoryPid,const QString & pid,const QString & pluginLocation)33 ctkConfigurationImpl::ctkConfigurationImpl(ctkConfigurationAdminFactory* configurationAdminFactory,
34 ctkConfigurationStore* configurationStore,
35 const QString& factoryPid, const QString& pid,
36 const QString& pluginLocation)
37 : configurationAdminFactory(configurationAdminFactory),
38 configurationStore(configurationStore), pluginLocation(pluginLocation),
39 factoryPid(factoryPid), pid(pid), deleted(false), lockedCount(0), lockHolder(0)
40 {
41
42 }
43
ctkConfigurationImpl(ctkConfigurationAdminFactory * configurationAdminFactory,ctkConfigurationStore * configurationStore,const ctkDictionary & dictionary)44 ctkConfigurationImpl::ctkConfigurationImpl(ctkConfigurationAdminFactory* configurationAdminFactory,
45 ctkConfigurationStore* configurationStore,
46 const ctkDictionary& dictionary)
47 : configurationAdminFactory(configurationAdminFactory),
48 configurationStore(configurationStore), deleted(false), lockedCount(0),
49 lockHolder(0)
50 {
51 pid = dictionary.value(ctkPluginConstants::SERVICE_PID).toString();
52 factoryPid = dictionary.value(ctkConfigurationAdmin::SERVICE_FACTORYPID).toString();
53 pluginLocation = dictionary.value(ctkConfigurationAdmin::SERVICE_PLUGINLOCATION).toString();
54 updateDictionary(dictionary);
55 }
56
remove()57 void ctkConfigurationImpl::remove()
58 {
59 {
60 ctkConfigurationImplLocker l(this);
61 checkDeleted();
62 deleted = true;
63 configurationAdminFactory->notifyConfigurationDeleted(this, !factoryPid.isEmpty());
64 configurationAdminFactory->dispatchEvent(ctkConfigurationEvent::CM_DELETED, factoryPid, pid);
65 }
66 configurationStore->removeConfiguration(pid);
67 }
68
getPluginLocation() const69 QString ctkConfigurationImpl::getPluginLocation() const
70 {
71 return getPluginLocation(true);
72 }
73
getFactoryPid() const74 QString ctkConfigurationImpl::getFactoryPid() const
75 {
76 return getFactoryPid(true);
77 }
78
getPid() const79 QString ctkConfigurationImpl::getPid() const
80 {
81 return getPid(true);
82 }
83
getProperties() const84 ctkDictionary ctkConfigurationImpl::getProperties() const
85 {
86 ctkConfigurationImplLocker l(this);
87 checkDeleted();
88 if (dictionary.isEmpty())
89 return dictionary;
90
91 ctkDictionary copy = dictionary;
92 copy.insert(ctkPluginConstants::SERVICE_PID, pid);
93 if (!factoryPid.isEmpty())
94 {
95 copy.insert(ctkConfigurationAdmin::SERVICE_FACTORYPID, factoryPid);
96 }
97
98 return copy;
99 }
100
setPluginLocation(const QString & pluginLocation)101 void ctkConfigurationImpl::setPluginLocation(const QString& pluginLocation)
102 {
103 ctkConfigurationImplLocker l(this);
104 checkDeleted();
105 configurationAdminFactory->checkConfigurationPermission();
106 this->pluginLocation = pluginLocation;
107 boundPlugin.clear(); // always reset the boundPlugin when setPluginLocation is called
108 }
109
update()110 void ctkConfigurationImpl::update()
111 {
112 ctkConfigurationImplLocker l(this);
113 checkDeleted();
114 configurationStore->saveConfiguration(pid, this);
115 configurationAdminFactory->notifyConfigurationUpdated(this, !factoryPid.isEmpty());
116 }
117
update(const ctkDictionary & properties)118 void ctkConfigurationImpl::update(const ctkDictionary& properties)
119 {
120 ctkConfigurationImplLocker l(this);
121 checkDeleted();
122 updateDictionary(properties);
123 configurationStore->saveConfiguration(pid, this);
124 configurationAdminFactory->notifyConfigurationUpdated(this, !factoryPid.isEmpty());
125 configurationAdminFactory->dispatchEvent(ctkConfigurationEvent::CM_UPDATED, factoryPid, pid);
126 }
127
lock() const128 void ctkConfigurationImpl::lock() const
129 {
130 QMutexLocker lock(&mutex);
131 QThread* current = QThread::currentThread();
132 if (lockHolder != current)
133 {
134 while (lockedCount != 0)
135 {
136 waitCond.wait(&mutex);
137 }
138 }
139 ++lockedCount;
140 lockHolder = current;
141 }
142
unlock() const143 void ctkConfigurationImpl::unlock() const
144 {
145 QMutexLocker lock(&mutex);
146 QThread* current = QThread::currentThread();
147 if (lockHolder != current)
148 {
149 throw ctkIllegalStateException("Thread not lock owner");
150 }
151
152 --lockedCount;
153 if (lockedCount == 0)
154 {
155 lockHolder = 0;
156 waitCond.wakeOne();
157 }
158 }
159
checkLocked() const160 void ctkConfigurationImpl::checkLocked() const
161 {
162 QMutexLocker lock(&mutex);
163 QThread* current = QThread::currentThread();
164 if (lockHolder != current)
165 {
166 throw ctkIllegalStateException("Thread not lock owner");
167 }
168 }
169
bind(QSharedPointer<ctkPlugin> plugin)170 bool ctkConfigurationImpl::bind(QSharedPointer<ctkPlugin> plugin)
171 {
172 ctkConfigurationImplLocker l(this);
173 if (boundPlugin.isNull() && (pluginLocation.isEmpty() || pluginLocation == plugin->getLocation()))
174 {
175 boundPlugin = plugin;
176 }
177 return (boundPlugin == plugin);
178 }
179
unbind(QSharedPointer<ctkPlugin> plugin)180 void ctkConfigurationImpl::unbind(QSharedPointer<ctkPlugin> plugin)
181 {
182 ctkConfigurationImplLocker l(this);
183 if (boundPlugin == plugin)
184 {
185 boundPlugin.clear();
186 }
187 }
188
getPluginLocation(bool checkPermission) const189 QString ctkConfigurationImpl::getPluginLocation(bool checkPermission) const
190 {
191 ctkConfigurationImplLocker l(this);
192 checkDeleted();
193 if (checkPermission)
194 {
195 configurationAdminFactory->checkConfigurationPermission();
196 }
197
198 if (!pluginLocation.isEmpty())
199 {
200 return pluginLocation;
201 }
202
203 if (boundPlugin)
204 {
205 return boundPlugin->getLocation();
206 }
207
208 return QString();
209 }
210
getFactoryPid(bool checkDel) const211 QString ctkConfigurationImpl::getFactoryPid(bool checkDel) const
212 {
213 ctkConfigurationImplLocker l(this);
214 if (checkDel)
215 {
216 checkDeleted();
217 }
218 return factoryPid;
219 }
220
getPid(bool checkDel) const221 QString ctkConfigurationImpl::getPid(bool checkDel) const
222 {
223 ctkConfigurationImplLocker l(this);
224 if (checkDel)
225 {
226 checkDeleted();
227 }
228 return pid;
229 }
230
getAllProperties() const231 ctkDictionary ctkConfigurationImpl::getAllProperties() const
232 {
233 ctkConfigurationImplLocker l(this);
234 if (deleted)
235 {
236 return ctkDictionary();
237 }
238 ctkDictionary copy = getProperties();
239 if (copy.isEmpty())
240 {
241 return copy;
242 }
243
244 QString boundLocation = getPluginLocation(false);
245 if (!boundLocation.isEmpty())
246 {
247 copy.insert(ctkConfigurationAdmin::SERVICE_PLUGINLOCATION, boundLocation);
248 }
249 return copy;
250 }
251
isDeleted() const252 bool ctkConfigurationImpl::isDeleted() const
253 {
254 ctkConfigurationImplLocker l(this);
255 return deleted;
256 }
257
checkDeleted() const258 void ctkConfigurationImpl::checkDeleted() const
259 {
260 if (deleted)
261 throw ctkIllegalStateException("deleted");
262 }
263
updateDictionary(const ctkDictionary & properties)264 void ctkConfigurationImpl::updateDictionary(const ctkDictionary& properties)
265 {
266 ctkConfigurationDictionary newDictionary = properties;
267 newDictionary.remove(ctkPluginConstants::SERVICE_PID);
268 newDictionary.remove(ctkConfigurationAdmin::SERVICE_FACTORYPID);
269 newDictionary.remove(ctkConfigurationAdmin::SERVICE_PLUGINLOCATION);
270 dictionary = newDictionary;
271 }
272
ctkConfigurationImplLocker(const ctkConfigurationImpl * impl)273 ctkConfigurationImplLocker::ctkConfigurationImplLocker(const ctkConfigurationImpl* impl)
274 : impl(impl)
275 {
276 if (impl) impl->lock();
277 }
278
ctkConfigurationImplLocker(const QList<ctkConfigurationImplPtr> & implList)279 ctkConfigurationImplLocker::ctkConfigurationImplLocker(const QList<ctkConfigurationImplPtr>& implList)
280 : impl(0), implList(implList)
281 {
282 foreach(ctkConfigurationImplPtr i, this->implList)
283 {
284 if (i) i->lock();
285 }
286 }
287
~ctkConfigurationImplLocker()288 ctkConfigurationImplLocker::~ctkConfigurationImplLocker()
289 {
290 if (impl) impl->unlock();
291 foreach(ctkConfigurationImplPtr i, implList)
292 {
293 if (i) i->unlock();
294 }
295 }
296