ctkConfigurationImpl.cpp 7.6 KB

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