composite_plugin_provider.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011, Dirk Thomas, TU Darmstadt
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following
13  * disclaimer in the documentation and/or other materials provided
14  * with the distribution.
15  * * Neither the name of the TU Darmstadt nor the names of its
16  * contributors may be used to endorse or promote products derived
17  * from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
34 
35 #include <stdexcept>
36 
37 namespace qt_gui_cpp {
38 
39 CompositePluginProvider::CompositePluginProvider(const QList<PluginProvider*>& plugin_providers)
40  : PluginProvider()
41  , plugin_providers_(plugin_providers)
42 {}
43 
45 {
46  for (QList<PluginProvider*>::iterator it = plugin_providers_.begin(); it != plugin_providers_.end(); it++)
47  {
48  delete *it;
49  }
50 }
51 
52 void CompositePluginProvider::set_plugin_providers(const QList<PluginProvider*>& plugin_providers)
53 {
54  // garbage old plugin providers
55  for (QList<PluginProvider*>::iterator it = plugin_providers_.begin(); it != plugin_providers_.end(); it++)
56  {
57  delete *it;
58  }
59  plugin_providers_ = plugin_providers;
60 }
61 
62 QList<PluginDescriptor*> CompositePluginProvider::discover_descriptors(QObject* discovery_data)
63 {
64  // discover plugins from all providers
65  QList<PluginDescriptor*> descriptors;
66  for (QList<PluginProvider*>::iterator it = plugin_providers_.begin(); it != plugin_providers_.end(); it++)
67  {
68  QList<PluginDescriptor*> sub_descriptors;
69  try
70  {
71  sub_descriptors = (*it)->discover_descriptors(discovery_data);
72  }
73  catch (std::runtime_error e)
74  {
75  // TODO: add name of plugin provider to error message
76  qCritical("CompositePluginProvider::discover() could not discover plugins from provider - runtime_error:\n%s", e.what());
77  continue;
78  }
79  catch (...)
80  {
81  // TODO: add name of plugin provider to error message
82  qCritical("CompositePluginProvider::discover() could not discover plugins from provider");
83  continue;
84  }
85 
86  QSet<QString> plugin_ids;
87  for (QList<PluginDescriptor*>::iterator jt = sub_descriptors.begin(); jt != sub_descriptors.end(); jt++)
88  {
89  PluginDescriptor* descriptor = *jt;
90  descriptors.append(descriptor);
91  plugin_ids.insert(descriptor->pluginId());
92  }
93  discovered_plugins_[*it] = plugin_ids;
94  }
95  return descriptors;
96 }
97 
98 void* CompositePluginProvider::load(const QString& plugin_id, PluginContext* plugin_context)
99 {
100  // dispatch load to appropriate provider
101  for (QMap<PluginProvider*, QSet<QString> >::iterator it = discovered_plugins_.begin(); it != discovered_plugins_.end(); it++)
102  {
103  if (it.value().contains(plugin_id))
104  {
105  PluginProvider* plugin_provider = it.key();
106  try
107  {
108  void* instance = plugin_provider->load(plugin_id, plugin_context);
109  running_plugins_[instance] = plugin_provider;
110  return instance;
111  }
112  catch (std::exception& e)
113  {
114  qWarning("CompositePluginProvider::load(%s) failed loading plugin (%s)", plugin_id.toStdString().c_str(), e.what());
115  return 0;
116  }
117  }
118  }
119  return 0;
120 }
121 
122 Plugin* CompositePluginProvider::load_plugin(const QString& plugin_id, PluginContext* plugin_context)
123 {
124  // dispatch load to appropriate provider
125  for (QMap<PluginProvider*, QSet<QString> >::iterator it = discovered_plugins_.begin(); it != discovered_plugins_.end(); it++)
126  {
127  if (it.value().contains(plugin_id))
128  {
129  PluginProvider* plugin_provider = it.key();
130  try
131  {
132  Plugin* instance = plugin_provider->load_plugin(plugin_id, plugin_context);
133  running_plugins_[instance] = plugin_provider;
134  return instance;
135  }
136  catch (std::exception& e)
137  {
138  // error message will be generated by python
139  }
140  }
141  }
142  return 0;
143 }
144 
145 void CompositePluginProvider::unload(void* plugin_instance)
146 {
147  // dispatch unload to appropriate provider
148  QMap<void*, PluginProvider*>::iterator it = running_plugins_.find(plugin_instance);
149  if (it != running_plugins_.end())
150  {
151  (*it)->unload(plugin_instance);
152  running_plugins_.remove(it.key());
153  return;
154  }
155  throw std::runtime_error("plugin_instance not found");
156 }
157 
159 {
160  for (QList<PluginProvider*>::iterator it = plugin_providers_.begin(); it != plugin_providers_.end(); it++)
161  {
162  (*it)->shutdown();
163  }
164 }
165 
166 } // namespace
virtual Plugin * load_plugin(const QString &plugin_id, PluginContext *plugin_context)
CompositePluginProvider(const QList< PluginProvider * > &plugin_providers=QList< PluginProvider * >())
const QString & pluginId() const
QMap< void *, PluginProvider * > running_plugins_
QMap< PluginProvider *, QSet< QString > > discovered_plugins_
virtual void unload(void *plugin_instance)
virtual void * load(const QString &plugin_id, PluginContext *plugin_context)
virtual void * load(const QString &plugin_id, PluginContext *plugin_context)
virtual void set_plugin_providers(const QList< PluginProvider * > &plugin_providers)
virtual QList< PluginDescriptor * > discover_descriptors(QObject *discovery_data)
virtual Plugin * load_plugin(const QString &plugin_id, PluginContext *plugin_context)


qt_gui_cpp
Author(s): Dirk Thomas
autogenerated on Tue Apr 13 2021 03:03:14