Fix a Gtk warning when checking path input in the log viewer.
[anjuta-git-plugin.git] / libanjuta / anjuta-c-plugin-factory.c
blob66460b0d6b8a1a6f2a473814bd2a65d56a1da6d8
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 anjuta-c-plugin-factory.c
4 Copyright (C) 2007 Sebastien Granjoux <seb.sfo@free.fr>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 /**
22 * SECTION:anjuta-c-plugin-factory
23 * @title: AnjutaCPluginFactory
24 * @short_description: Anjuta C plugin factory
25 * @see_also: #AnjutaCModule, #AnjutaPluginManager
26 * @stability: Unstable
27 * @include: libanjuta/anjuta-c-plugin-factory.h
29 * #AnjutaCPluginFactory implements the #IAnjutaPluginFactory interface. This
30 * interface is used to create new plugin objects in Anjuta.
32 * This plugin factory creates new plugin objects which have a source code
33 * written in C. This factory is always available in Anjuta. Other plugin
34 * factories can be implemented as Anjuta plugins.
36 * This plugin factory uses the GLib dynamic type support implemented in
37 * #AnjutaCModule object to allow loading and unloading of plugins code. But
38 * if the plugins itself can be unloaded, the #AnjutaCModule object must stay.
39 * If the plugin is needed later, it must be registed with the same
40 * module object. The factory take care of this and of creating the plugin
41 * object itself.
44 #include "config.h"
46 #include "anjuta-c-plugin-factory.h"
48 #include "anjuta-c-module.h"
50 #include <libanjuta/interfaces/ianjuta-plugin-factory.h>
52 #include <glib.h>
54 #include <string.h>
56 /* Types
57 *---------------------------------------------------------------------------*/
59 struct _AnjutaCPluginFactoryClass
61 GObjectClass parent;
64 struct _AnjutaCPluginFactory
66 GObject parent;
68 GHashTable* loaded_plugins;
71 static void ianjuta_c_plugin_factory_iface_init (IAnjutaPluginFactoryIface *iface);
72 G_DEFINE_TYPE_WITH_CODE (AnjutaCPluginFactory, anjuta_c_plugin_factory, G_TYPE_OBJECT, \
73 G_IMPLEMENT_INTERFACE (IANJUTA_TYPE_PLUGIN_FACTORY, ianjuta_c_plugin_factory_iface_init))
75 /* Private functions
76 *---------------------------------------------------------------------------*/
78 static AnjutaPlugin*
79 anjuta_c_plugin_factory_create_plugin (AnjutaCPluginFactory *factory,
80 AnjutaPluginHandle *handle,
81 AnjutaShell *shell,
82 GError **error)
84 const gchar *path;
85 GHashTable *plugin_in_path;
86 gchar **pieces;
87 AnjutaCModule *module;
88 GType type;
89 AnjutaPlugin *plugin;
91 g_return_val_if_fail (handle != NULL, NULL);
92 g_return_val_if_fail (shell != NULL, NULL);
94 path = anjuta_plugin_handle_get_path (handle);
95 plugin_in_path = g_hash_table_lookup (factory->loaded_plugins, path);
96 if (plugin_in_path == NULL)
98 /* No loaded plugin with this path, create sub hash */
99 plugin_in_path = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
100 g_hash_table_insert (plugin_in_path, g_strdup (path), plugin_in_path);
103 pieces = g_strsplit (anjuta_plugin_handle_get_id (handle), ":", -1);
104 if ((pieces == NULL) || (pieces[0] == NULL))
106 g_set_error (error, IANJUTA_PLUGIN_FACTORY_ERROR,
107 IANJUTA_PLUGIN_FACTORY_MISSING_LOCATION,
108 _("Missing location of plugin %s"), anjuta_plugin_handle_get_name (handle));
109 return NULL;
111 module = g_hash_table_lookup (plugin_in_path, pieces[0]);
112 if (module == NULL)
114 /* Plugin is not loaded */
115 module = anjuta_c_module_new (path, pieces[0]);
116 g_return_val_if_fail (module != NULL, NULL);
118 /* Load module */
119 g_type_module_use (G_TYPE_MODULE (module));
121 if (anjuta_c_module_get_last_error (module, error))
123 /* Avoid memory leak in case of error*/
124 g_strfreev (pieces);
126 return NULL;
128 g_hash_table_insert (plugin_in_path, g_strdup (pieces[0]), module);
130 else
132 module = NULL;
135 /* Find plugin type */
136 if (pieces[1] == NULL)
138 g_strfreev (pieces);
139 g_set_error (error, IANJUTA_PLUGIN_FACTORY_ERROR,
140 IANJUTA_PLUGIN_FACTORY_MISSING_TYPE,
141 _("Missing type defined by plugin %s"), anjuta_plugin_handle_get_name (handle));
142 return NULL;
144 type = g_type_from_name (pieces[1]);
145 if (type == G_TYPE_INVALID)
147 g_set_error (error, IANJUTA_PLUGIN_FACTORY_ERROR,
148 IANJUTA_PLUGIN_FACTORY_INVALID_TYPE,
149 _("plugin %s fails to register type %s"), anjuta_plugin_handle_get_name (handle), pieces[1]);
150 g_strfreev (pieces);
152 return NULL;
154 g_strfreev (pieces);
156 /* Create plugin */
157 plugin = (AnjutaPlugin *)g_object_new (type, "shell", shell, NULL);
159 if ((module != NULL) && (anjuta_plugin_handle_get_resident(handle) == FALSE))
161 /* This module can be unloaded when not needed */
162 g_type_module_unuse (G_TYPE_MODULE (module));
165 return plugin;
168 /* IAnjutaPluginFactory interface
169 *---------------------------------------------------------------------------*/
171 static AnjutaPlugin*
172 ianjuta_c_plugin_factory_new_plugin (IAnjutaPluginFactory *ifactory, AnjutaPluginHandle *handle, AnjutaShell *shell, GError **error)
174 AnjutaCPluginFactory *factory = ANJUTA_C_PLUGIN_FACTORY (ifactory);
176 return anjuta_c_plugin_factory_create_plugin (factory, handle, shell, error);
179 static void
180 ianjuta_c_plugin_factory_iface_init (IAnjutaPluginFactoryIface *iface)
182 iface->new_plugin = ianjuta_c_plugin_factory_new_plugin;
186 /* GObject functions
187 *---------------------------------------------------------------------------*/
189 /* dispose is the first destruction step. It is used to unref object created
190 * with instance_init in order to break reference counting cycles. This
191 * function could be called several times. All function should still work
192 * after this call. It has to called its parents.*/
194 static void
195 anjuta_c_plugin_factory_dispose (GObject *object)
197 AnjutaCPluginFactory *factory = ANJUTA_C_PLUGIN_FACTORY (object);
199 g_hash_table_unref (factory->loaded_plugins);
200 factory->loaded_plugins = NULL;
202 G_OBJECT_CLASS (anjuta_c_plugin_factory_parent_class)->dispose (object);
205 static void
206 anjuta_c_plugin_factory_class_init (AnjutaCPluginFactoryClass *klass)
208 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
210 gobject_class->dispose = anjuta_c_plugin_factory_dispose;
213 static void
214 anjuta_c_plugin_factory_init (AnjutaCPluginFactory *factory)
216 factory->loaded_plugins = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_hash_table_unref);
219 /* Creation and Destruction
220 *---------------------------------------------------------------------------*/
222 * anjuta_c_plugin_factory_new:
224 * Create a new #AnjutaCPluginFactory object.
226 * Return value: a new #AnjutaCPluginFactory object.
228 AnjutaCPluginFactory*
229 anjuta_c_plugin_factory_new (void)
231 AnjutaCPluginFactory *factory;
233 factory = g_object_new (ANJUTA_TYPE_C_PLUGIN_FACTORY, NULL);
235 return factory;
239 * anjuta_c_plugin_factory_free:
240 * @factory: a #AnjutaCPluginFactory
242 * Delete a #AnjutaCPluginFactory object.
244 void
245 anjuta_c_plugin_factory_free (AnjutaCPluginFactory *factory)
247 g_object_unref (G_OBJECT(factory));