Fixes NB#124324, remove the original instance of "Fw:" in any of its forms ("FW:...
[modest] / src / modest-plugin-factory.c
1 /* Copyright (c) 2008, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  *   notice, this list of conditions and the following disclaimer in the
12  *   documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Nokia Corporation nor the names of its
14  *   contributors may be used to endorse or promote products derived from
15  *   this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "modest-plugin-factory.h"
31 #include "modest-protocol-registry.h"
32 #include "modest-plugin.h"
33 #include "modest-module.h"
34 #include <gmodule.h>
35 /* include other impl specific header files */
36
37 #define PLUGIN_EXT      ".modest-mail-plugin"
38
39 /* 'private'/'protected' functions */
40 static void modest_plugin_factory_class_init (ModestPluginFactoryClass *klass);
41 static void modest_plugin_factory_init       (ModestPluginFactory *obj);
42 static void modest_plugin_factory_finalize   (GObject *obj);
43
44 static ModestPlugin* modest_plugin_factory_load     (const gchar *file);
45
46 typedef GType (*ModestModuleRegisterFunc) (GTypeModule *);
47
48 typedef struct _ModestPluginFactoryPrivate ModestPluginFactoryPrivate;
49 struct _ModestPluginFactoryPrivate {
50         GSList *plugins;
51 };
52
53 #define MODEST_PLUGIN_FACTORY_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
54                                                         MODEST_TYPE_PLUGIN_FACTORY, \
55                                                         ModestPluginFactoryPrivate))
56 /* globals */
57 static GObjectClass *parent_class = NULL;
58
59 GType
60 modest_plugin_factory_get_type (void)
61 {
62         static GType my_type = 0;
63         if (!my_type) {
64                 static const GTypeInfo my_info = {
65                         sizeof(ModestPluginFactoryClass),
66                         NULL,           /* base init */
67                         NULL,           /* base finalize */
68                         (GClassInitFunc) modest_plugin_factory_class_init,
69                         NULL,           /* class finalize */
70                         NULL,           /* class data */
71                         sizeof(ModestPluginFactory),
72                         1,              /* n_preallocs */
73                         (GInstanceInitFunc) modest_plugin_factory_init,
74                         NULL
75                 };
76                 my_type = g_type_register_static (G_TYPE_OBJECT,
77                                                   "ModestPluginFactory",
78                                                   &my_info, 0);
79         }
80         return my_type;
81 }
82
83 static void
84 modest_plugin_factory_class_init (ModestPluginFactoryClass *klass)
85 {
86         GObjectClass *gobject_class;
87         gobject_class = (GObjectClass*) klass;
88
89         parent_class            = g_type_class_peek_parent (klass);
90         gobject_class->finalize = modest_plugin_factory_finalize;
91
92         g_type_class_add_private (gobject_class, sizeof(ModestPluginFactoryPrivate));
93 }
94
95 static void
96 modest_plugin_factory_init (ModestPluginFactory *obj)
97 {
98         ModestPluginFactoryPrivate *priv = MODEST_PLUGIN_FACTORY_GET_PRIVATE(obj);
99
100         if (!g_module_supported ()) {
101                 g_warning ("unable to initialize the plugin factory");
102                 return;
103         }
104
105         priv->plugins = NULL;
106         g_module_open (NULL, 0);
107 }
108
109 static void
110 modest_plugin_factory_finalize (GObject *obj)
111 {
112         ModestPluginFactoryPrivate *priv;
113         GSList *iter;
114
115         priv = MODEST_PLUGIN_FACTORY_GET_PRIVATE (obj);
116
117         /* Free the plugin list */
118         for (iter = priv->plugins; iter; iter = g_slist_next (iter))
119                 g_object_unref ((GObject *) iter->data);
120
121         g_slist_free (priv->plugins);
122         priv->plugins = NULL;
123
124         G_OBJECT_CLASS(parent_class)->finalize (obj);
125 }
126
127 ModestPluginFactory*
128 modest_plugin_factory_new (void)
129 {
130         return MODEST_PLUGIN_FACTORY (g_object_new (MODEST_TYPE_PLUGIN_FACTORY, NULL));
131 }
132
133 void
134 modest_plugin_factory_load_all (ModestPluginFactory *self) 
135 {
136         ModestPluginFactoryPrivate *priv;
137         GError *error = NULL;
138         GDir *d;
139         const gchar *dirent;
140         ModestProtocolRegistry *pr;
141
142         pr = modest_plugin_get_protocol_registry ();
143
144         priv = MODEST_PLUGIN_FACTORY_GET_PRIVATE(self);
145
146         if (!g_file_test (MODEST_MAILPLUGINDIR, G_FILE_TEST_IS_DIR)) {
147                 return;
148         }
149
150         d = g_dir_open (MODEST_MAILPLUGINDIR, 0, &error);
151
152         if (!d) {
153                 g_warning ("%s", error->message);
154                 g_error_free (error);
155
156                 return;
157         }
158
159         while ((dirent = g_dir_read_name (d))) {
160                 if (g_str_has_suffix (dirent, PLUGIN_EXT)) {
161                         gchar *plugin_file;
162                         ModestPlugin *plugin;
163
164                         plugin_file = g_build_filename (MODEST_MAILPLUGINDIR, dirent, NULL);
165                         plugin = modest_plugin_factory_load (plugin_file);
166                         g_free (plugin_file);
167
168                         if (plugin)
169                                 priv->plugins = g_slist_prepend (priv->plugins, plugin);
170                 }
171         }
172
173         priv->plugins = g_slist_reverse (priv->plugins);
174
175         g_dir_close (d);
176 }
177
178 static ModestPlugin*
179 modest_plugin_factory_load (const gchar *file)
180 {
181         ModestPlugin *plugin = NULL;
182         GKeyFile *plugin_file = NULL;
183         gchar *plugin_name, *dir, *path;
184         GTypeModule *type_module;
185
186         g_return_val_if_fail (file != NULL, NULL);
187
188         plugin_file = g_key_file_new ();
189
190         if (!g_key_file_load_from_file (plugin_file, file, G_KEY_FILE_NONE, NULL)) {
191                 g_warning ("Bad plugin file: %s", file);
192                 goto error;
193         }
194
195         /* Get Location */
196         plugin_name = g_key_file_get_string (plugin_file,
197                                              "Modest Mail Plugin",
198                                              "Module",
199                                              NULL);
200
201         if ((plugin_name == NULL) || (*plugin_name == '\0')) {
202                 g_warning ("Could not find 'Module' in %s", file);
203                 goto error;
204         }
205
206         g_key_file_free (plugin_file);
207
208         /* Build path to plugin */
209         dir = g_path_get_dirname (file);
210         path = g_module_build_path (dir, plugin_name);
211         g_free (dir);
212
213         /* plugin = g_module_open (path, G_MODULE_BIND_LAZY); */
214         type_module = G_TYPE_MODULE (modest_module_new (path));
215         if (type_module) {
216                 g_type_module_use (type_module);
217                 plugin = MODEST_PLUGIN (modest_module_new_object (MODEST_MODULE (type_module)));
218                 if (plugin)
219                         g_debug ("Plugin %s API version %s", plugin_name, modest_plugin_get_api_version (plugin));
220                 g_type_module_unuse (type_module);
221         }
222         g_free (path);
223
224         return plugin;
225 error:
226         g_key_file_free (plugin_file);
227
228         return NULL;
229 }