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 #include "ctkPlugin_p.h"
23 #include "ctkPluginContext.h"
24 #include "ctkPluginContext_p.h"
25 #include "ctkPluginFrameworkContext_p.h"
26
27 #include "ctkServices_p.h"
28 #include "ctkServiceRegistration.h"
29 #include "ctkServiceReference.h"
30 #include "ctkServiceReference_p.h"
31
32 #include <stdexcept>
33
34 //----------------------------------------------------------------------------
ctkPluginContextPrivate(ctkPluginPrivate * plugin)35 ctkPluginContextPrivate::ctkPluginContextPrivate(ctkPluginPrivate* plugin)
36 : plugin(plugin)
37 {}
38
39 //----------------------------------------------------------------------------
isPluginContextValid() const40 void ctkPluginContextPrivate::isPluginContextValid() const
41 {
42 if (!plugin) {
43 throw ctkIllegalStateException("This plugin context is no longer valid");
44 }
45 }
46
47 //----------------------------------------------------------------------------
invalidate()48 void ctkPluginContextPrivate::invalidate()
49 {
50 plugin = 0;
51 }
52
53 //----------------------------------------------------------------------------
ctkPluginContext(ctkPluginPrivate * plugin)54 ctkPluginContext::ctkPluginContext(ctkPluginPrivate* plugin)
55 : d_ptr(new ctkPluginContextPrivate(plugin))
56 {}
57
58 //----------------------------------------------------------------------------
~ctkPluginContext()59 ctkPluginContext::~ctkPluginContext()
60 {
61 Q_D(ctkPluginContext);
62 delete d;
63 }
64
65 //----------------------------------------------------------------------------
getProperty(const QString & key) const66 QVariant ctkPluginContext::getProperty(const QString& key) const
67 {
68 Q_D(const ctkPluginContext);
69 d->isPluginContextValid();
70 return d->plugin->fwCtx->props.value(key);
71 }
72
73 //----------------------------------------------------------------------------
getPlugin() const74 QSharedPointer<ctkPlugin> ctkPluginContext::getPlugin() const
75 {
76 Q_D(const ctkPluginContext);
77 d->isPluginContextValid();
78 return d->plugin->q_func();
79 }
80
81 //----------------------------------------------------------------------------
getPlugin(long id) const82 QSharedPointer<ctkPlugin> ctkPluginContext::getPlugin(long id) const
83 {
84 Q_D(const ctkPluginContext);
85 return d->plugin->fwCtx->plugins->getPlugin(id);
86 }
87
88 //----------------------------------------------------------------------------
getPlugins() const89 QList<QSharedPointer<ctkPlugin> > ctkPluginContext::getPlugins() const
90 {
91 Q_D(const ctkPluginContext);
92 d->isPluginContextValid();
93 return d->plugin->fwCtx->plugins->getPlugins();
94 }
95
96 //----------------------------------------------------------------------------
installPlugin(const QUrl & location,QIODevice * in)97 QSharedPointer<ctkPlugin> ctkPluginContext::installPlugin(const QUrl& location, QIODevice* in)
98 {
99 Q_D(ctkPluginContext);
100 d->isPluginContextValid();
101 return d->plugin->fwCtx->plugins->install(location, in);
102 }
103
104 //----------------------------------------------------------------------------
getDataFile(const QString & filename)105 QFileInfo ctkPluginContext::getDataFile(const QString& filename)
106 {
107 Q_D(ctkPluginContext);
108 d->isPluginContextValid();
109 QDir dataRoot(d->plugin->getDataRoot().absolutePath());
110 if (!dataRoot.exists())
111 {
112 if (!dataRoot.mkpath(dataRoot.absolutePath()))
113 {
114 qWarning() << "Could not create persistent storage area:" << dataRoot.absolutePath();
115 }
116 }
117 return QFileInfo(dataRoot.absolutePath() + '/' + filename);
118 }
119
120 //----------------------------------------------------------------------------
registerService(const QStringList & clazzes,QObject * service,const ctkDictionary & properties)121 ctkServiceRegistration ctkPluginContext::registerService(const QStringList& clazzes, QObject* service, const ctkDictionary& properties)
122 {
123 Q_D(ctkPluginContext);
124 d->isPluginContextValid();
125 return d->plugin->fwCtx->services->registerService(d->plugin, clazzes, service, properties);
126 }
127
128 //----------------------------------------------------------------------------
registerService(const char * clazz,QObject * service,const ctkDictionary & properties)129 ctkServiceRegistration ctkPluginContext::registerService(const char* clazz, QObject* service, const ctkDictionary& properties)
130 {
131 Q_D(ctkPluginContext);
132 d->isPluginContextValid();
133 QStringList clazzes;
134 clazzes.append(clazz);
135 return d->plugin->fwCtx->services->registerService(d->plugin, clazzes, service, properties);
136 }
137
138 //----------------------------------------------------------------------------
getServiceReferences(const QString & clazz,const QString & filter)139 QList<ctkServiceReference> ctkPluginContext::getServiceReferences(const QString& clazz, const QString& filter)
140 {
141 Q_D(ctkPluginContext);
142 d->isPluginContextValid();
143 return d->plugin->fwCtx->services->get(clazz, filter, 0);
144 }
145
146 //----------------------------------------------------------------------------
getServiceReference(const QString & clazz)147 ctkServiceReference ctkPluginContext::getServiceReference(const QString& clazz)
148 {
149 Q_D(ctkPluginContext);
150 d->isPluginContextValid();
151 return d->plugin->fwCtx->services->get(d->plugin, clazz);
152 }
153
154 //----------------------------------------------------------------------------
getService(const ctkServiceReference & reference)155 QObject* ctkPluginContext::getService(const ctkServiceReference& reference)
156 {
157 Q_D(ctkPluginContext);
158 d->isPluginContextValid();
159
160 if (!reference)
161 {
162 throw ctkInvalidArgumentException("Default constructed ctkServiceReference is not a valid input to getService()");
163 }
164 ctkServiceReference internalRef(reference);
165 return internalRef.d_func()->getService(d->plugin->q_func());
166 }
167
168 //----------------------------------------------------------------------------
ungetService(const ctkServiceReference & reference)169 bool ctkPluginContext::ungetService(const ctkServiceReference& reference)
170 {
171 Q_D(ctkPluginContext);
172 d->isPluginContextValid();
173 ctkServiceReference ref = reference;
174 return ref.d_func()->ungetService(d->plugin->q_func(), true);
175 }
176
177 //----------------------------------------------------------------------------
connectPluginListener(const QObject * receiver,const char * slot,Qt::ConnectionType type)178 bool ctkPluginContext::connectPluginListener(const QObject* receiver, const char* slot,
179 Qt::ConnectionType type)
180 {
181 Q_D(ctkPluginContext);
182 d->isPluginContextValid();
183 // TODO check permissions for a direct connection
184 if (type == Qt::DirectConnection || type == Qt::BlockingQueuedConnection)
185 {
186 return receiver->connect(&(d->plugin->fwCtx->listeners), SIGNAL(pluginChangedDirect(ctkPluginEvent)), slot, type);
187 }
188 else if (type == Qt::QueuedConnection)
189 {
190 return receiver->connect(&(d->plugin->fwCtx->listeners), SIGNAL(pluginChangedQueued(ctkPluginEvent)), slot, type);
191 }
192 else
193 {
194 throw ctkInvalidArgumentException("Only Qt::DirectConnection, Qt::QueuedConnection, or Qt::BlockingQueuedConnection are allowed as type argument.");
195 }
196 }
197
198 //----------------------------------------------------------------------------
disconnectPluginListener(const QObject * receiver,const char * slot)199 void ctkPluginContext::disconnectPluginListener(const QObject *receiver, const char* slot)
200 {
201 Q_D(ctkPluginContext);
202 d->isPluginContextValid();
203
204 QObject::disconnect(&(d->plugin->fwCtx->listeners), SIGNAL(pluginChangedDirect(ctkPluginEvent)), receiver, slot);
205 QObject::disconnect(&(d->plugin->fwCtx->listeners), SIGNAL(pluginChangedQueued(ctkPluginEvent)), receiver, slot);
206 }
207
208 //----------------------------------------------------------------------------
connectFrameworkListener(const QObject * receiver,const char * slot,Qt::ConnectionType type)209 bool ctkPluginContext::connectFrameworkListener(const QObject* receiver, const char* slot, Qt::ConnectionType type)
210 {
211 Q_D(ctkPluginContext);
212 d->isPluginContextValid();
213 // TODO check permissions for a direct connection
214 return receiver->connect(&(d->plugin->fwCtx->listeners), SIGNAL(frameworkEvent(ctkPluginFrameworkEvent)), slot, type);
215 }
216
217 //----------------------------------------------------------------------------
disconnectFrameworkListener(const QObject * receiver,const char * slot)218 void ctkPluginContext::disconnectFrameworkListener(const QObject *receiver, const char* slot)
219 {
220 Q_D(ctkPluginContext);
221 d->isPluginContextValid();
222
223 QObject::disconnect(&(d->plugin->fwCtx->listeners), SIGNAL(frameworkEvent(ctkPluginFrameworkEvent)), receiver, slot);
224 }
225
226 //----------------------------------------------------------------------------
connectServiceListener(QObject * receiver,const char * slot,const QString & filter)227 void ctkPluginContext::connectServiceListener(QObject* receiver, const char* slot,
228 const QString& filter)
229 {
230 Q_D(ctkPluginContext);
231 d->isPluginContextValid();
232 d->plugin->fwCtx->listeners.addServiceSlot(getPlugin(), receiver, slot, filter);
233 }
234
235 //----------------------------------------------------------------------------
disconnectServiceListener(QObject * receiver,const char * slot)236 void ctkPluginContext::disconnectServiceListener(QObject* receiver,
237 const char* slot)
238 {
239 Q_D(ctkPluginContext);
240 d->isPluginContextValid();
241 d->plugin->fwCtx->listeners.removeServiceSlot(getPlugin(), receiver, slot);
242 }
243