Fixes NB#133838, use E_CONTACT_EMAIL instead of E_CONTACT_EMAIL_1 when creating new...
[modest] / src / modest-module.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
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #include <errno.h>
36 #include <gmodule.h>
37 #include "modest-module.h"
38
39 G_DEFINE_TYPE (ModestModule, modest_module, G_TYPE_TYPE_MODULE);
40
41
42 static gboolean modest_module_load (GTypeModule *gmodule);
43 static void modest_module_unload (GTypeModule *gmodule);
44 static void modest_module_init (ModestModule *module);
45 static void modest_module_finalize (GObject *object);
46 static void modest_module_class_init (ModestModuleClass *class);
47
48 typedef GType (*ModestModuleRegisterFunc) (GTypeModule *);
49
50 typedef struct _ModestModulePrivate ModestModulePrivate;
51 struct _ModestModulePrivate {
52         GModule *g_module;
53         gchar   *path;
54         GType    type;
55 };
56
57 #define MODEST_MODULE_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
58                                                                        MODEST_TYPE_MODULE, \
59                                                                        ModestModulePrivate))
60   
61 static gboolean
62 modest_module_load (GTypeModule *g_type_module)
63 {
64         ModestModule *module = MODEST_MODULE (g_type_module);
65         ModestModulePrivate *priv = MODEST_MODULE_GET_PRIVATE (module);
66         ModestModuleRegisterFunc register_func;
67
68         /* We don't do lazy linking to fail just if we cannot link all the symbols available */
69         priv->g_module = g_module_open (priv->path, 0);
70
71         if (priv->g_module == NULL) {
72                 g_warning ("%s", g_module_error());
73                 return FALSE;
74         }
75
76         /* Get the register function */
77         if (!g_module_symbol (priv->g_module, "register_modest_plugin", (void *) &register_func)) {
78                 g_warning ("%s", g_module_error());
79                 g_module_close (priv->g_module);
80
81                 return FALSE;
82         }
83
84         if (register_func == NULL) {
85                 g_warning ("register_modest_plugin shouldn't be NULL");
86                 g_module_close (priv->g_module);
87
88                 return FALSE;
89         }
90
91         /* call the register function to initialize the module */
92         priv->type = register_func (g_type_module);
93         if (priv->type == 0) {
94                 g_warning ("%s is not a modest plugin", priv->path);
95                 return FALSE;
96         }
97
98         return TRUE;
99 }
100
101 static void
102 modest_module_unload (GTypeModule *gmodule)
103 {
104         ModestModule *module = MODEST_MODULE (gmodule);
105         ModestModulePrivate *priv = MODEST_MODULE_GET_PRIVATE (module);
106
107         g_module_close (priv->g_module);
108
109         priv->g_module = NULL;
110         priv->type = 0;
111 }
112
113 GObject *
114 modest_module_new_object (ModestModule *module)
115 {
116         ModestModulePrivate *priv = MODEST_MODULE_GET_PRIVATE (module);
117
118         if (priv->type == 0) {
119                 return NULL;
120         }
121
122         return g_object_new (priv->type, NULL);
123 }
124
125 static void
126 modest_module_init (ModestModule *module)
127 {
128 }
129
130 static void
131 modest_module_finalize (GObject *object)
132 {
133         ModestModule *module = MODEST_MODULE (object);
134         ModestModulePrivate *priv = MODEST_MODULE_GET_PRIVATE (module);
135
136         g_free (priv->path);
137
138         G_OBJECT_CLASS (modest_module_parent_class)->finalize (object);
139 }
140
141 static void
142 modest_module_class_init (ModestModuleClass *class)
143 {
144         GObjectClass *gobject_class = G_OBJECT_CLASS (class);
145         GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
146
147         gobject_class->finalize = modest_module_finalize;
148
149         module_class->load = modest_module_load;
150         module_class->unload = modest_module_unload;
151
152         g_type_class_add_private (gobject_class, sizeof(ModestModulePrivate));
153 }
154
155 ModestModule *
156 modest_module_new (const gchar *path)
157 {
158         ModestModule *module;
159         ModestModulePrivate *priv;
160
161         if (path == NULL || path[0] == '\0') {
162                 return NULL;
163         }
164
165         module = g_object_new (MODEST_TYPE_MODULE, NULL);
166         priv = MODEST_MODULE_GET_PRIVATE (module);
167
168         g_type_module_set_name (G_TYPE_MODULE (module), path);
169
170         priv->path = g_strdup (path);
171
172         return module;
173 }