composite_plugin_provider.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2011, Dirk Thomas, TU Darmstadt
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  *   * Redistributions of source code must retain the above copyright
00010  *     notice, this list of conditions and the following disclaimer.
00011  *   * Redistributions in binary form must reproduce the above
00012  *     copyright notice, this list of conditions and the following
00013  *     disclaimer in the documentation and/or other materials provided
00014  *     with the distribution.
00015  *   * Neither the name of the TU Darmstadt nor the names of its
00016  *     contributors may be used to endorse or promote products derived
00017  *     from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00020  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00022  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00023  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00024  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00025  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00026  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00027  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00028  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00029  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00030  * POSSIBILITY OF SUCH DAMAGE.
00031  */
00032 
00033 #include <qt_gui_cpp/composite_plugin_provider.h>
00034 
00035 #include <stdexcept>
00036 
00037 namespace qt_gui_cpp {
00038 
00039 CompositePluginProvider::CompositePluginProvider(const QList<PluginProvider*>& plugin_providers)
00040   : PluginProvider()
00041   , plugin_providers_(plugin_providers)
00042 {}
00043 
00044 CompositePluginProvider::~CompositePluginProvider()
00045 {
00046   for (QList<PluginProvider*>::iterator it = plugin_providers_.begin(); it != plugin_providers_.end(); it++)
00047   {
00048     delete *it;
00049   }
00050 }
00051 
00052 void CompositePluginProvider::set_plugin_providers(const QList<PluginProvider*>& plugin_providers)
00053 {
00054   // garbage old plugin providers
00055   for (QList<PluginProvider*>::iterator it = plugin_providers_.begin(); it != plugin_providers_.end(); it++)
00056   {
00057     delete *it;
00058   }
00059   plugin_providers_ = plugin_providers;
00060 }
00061 
00062 QList<PluginDescriptor*> CompositePluginProvider::discover_descriptors(QObject* discovery_data)
00063 {
00064   // discover plugins from all providers
00065   QList<PluginDescriptor*> descriptors;
00066   for (QList<PluginProvider*>::iterator it = plugin_providers_.begin(); it != plugin_providers_.end(); it++)
00067   {
00068     QList<PluginDescriptor*> sub_descriptors;
00069     try
00070     {
00071       sub_descriptors = (*it)->discover_descriptors(discovery_data);
00072     }
00073     catch (std::runtime_error e)
00074     {
00075       // TODO: add name of plugin provider to error message
00076       qCritical("CompositePluginProvider::discover() could not discover plugins from provider - runtime_error:\n%s", e.what());
00077       continue;
00078     }
00079     catch (...)
00080     {
00081       // TODO: add name of plugin provider to error message
00082       qCritical("CompositePluginProvider::discover() could not discover plugins from provider");
00083       continue;
00084     }
00085 
00086     QSet<QString> plugin_ids;
00087     for (QList<PluginDescriptor*>::iterator jt = sub_descriptors.begin(); jt != sub_descriptors.end(); jt++)
00088     {
00089       PluginDescriptor* descriptor = *jt;
00090       descriptors.append(descriptor);
00091       plugin_ids.insert(descriptor->pluginId());
00092     }
00093     discovered_plugins_[*it] = plugin_ids;
00094   }
00095   return descriptors;
00096 }
00097 
00098 void* CompositePluginProvider::load(const QString& plugin_id, PluginContext* plugin_context)
00099 {
00100   // dispatch load to appropriate provider
00101   for (QMap<PluginProvider*, QSet<QString> >::iterator it = discovered_plugins_.begin(); it != discovered_plugins_.end(); it++)
00102   {
00103     if (it.value().contains(plugin_id))
00104     {
00105       PluginProvider* plugin_provider = it.key();
00106       try
00107       {
00108         void* instance = plugin_provider->load(plugin_id, plugin_context);
00109         running_plugins_[instance] = plugin_provider;
00110         return instance;
00111       }
00112       catch (std::exception& e)
00113       {
00114         qWarning("CompositePluginProvider::load(%s) failed loading plugin (%s)", plugin_id.toStdString().c_str(), e.what());
00115         return 0;
00116       }
00117     }
00118   }
00119   return 0;
00120 }
00121 
00122 Plugin* CompositePluginProvider::load_plugin(const QString& plugin_id, PluginContext* plugin_context)
00123 {
00124   // dispatch load to appropriate provider
00125   for (QMap<PluginProvider*, QSet<QString> >::iterator it = discovered_plugins_.begin(); it != discovered_plugins_.end(); it++)
00126   {
00127     if (it.value().contains(plugin_id))
00128     {
00129       PluginProvider* plugin_provider = it.key();
00130       try
00131       {
00132         Plugin* instance = plugin_provider->load_plugin(plugin_id, plugin_context);
00133         running_plugins_[instance] = plugin_provider;
00134         return instance;
00135       }
00136       catch (std::exception& e)
00137       {
00138         // error message will be generated by python
00139       }
00140     }
00141   }
00142   return 0;
00143 }
00144 
00145 void CompositePluginProvider::unload(void* plugin_instance)
00146 {
00147   // dispatch unload to appropriate provider
00148   QMap<void*, PluginProvider*>::iterator it = running_plugins_.find(plugin_instance);
00149   if (it != running_plugins_.end())
00150   {
00151     (*it)->unload(plugin_instance);
00152     running_plugins_.remove(it);
00153     return;
00154   }
00155   throw std::runtime_error("plugin_instance not found");
00156 }
00157 
00158 void CompositePluginProvider::shutdown()
00159 {
00160   for (QList<PluginProvider*>::iterator it = plugin_providers_.begin(); it != plugin_providers_.end(); it++)
00161   {
00162     (*it)->shutdown();
00163   }
00164 }
00165 
00166 } // namespace


qt_gui_cpp
Author(s): Dirk Thomas
autogenerated on Fri Aug 28 2015 12:15:44