1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 c-set-style: linux -*- */ |
---|
2 | /** |
---|
3 | * bonobo-object-directory.c: abstract the object directory |
---|
4 | * |
---|
5 | * Authors: |
---|
6 | * Michael Meeks (michael@helixcode.com) |
---|
7 | * Havoc Pennington (hp@redhat.com) |
---|
8 | * Anders Carlsson (andersca@gnu.org) |
---|
9 | * Maciej Stachowiak (mjs@eazel.com) |
---|
10 | * |
---|
11 | * Copyright 1999, 2000 Havoc Pennington, Anders Carlsson, |
---|
12 | * Eazel, Inc. Helix Code, Inc. |
---|
13 | */ |
---|
14 | |
---|
15 | #include "config.h" |
---|
16 | #include <glib.h> |
---|
17 | #include <libgnome/gnome-defs.h> |
---|
18 | #define GNOME_EXPLICIT_TRANSLATION_DOMAIN PACKAGE |
---|
19 | #include <libgnome/gnome-i18n.h> |
---|
20 | #include <libgnome/gnome-mime.h> |
---|
21 | #include "bonobo-object-directory.h" |
---|
22 | #include <liboaf/liboaf.h> |
---|
23 | |
---|
24 | struct _ODServerInfo { |
---|
25 | guint refcount; |
---|
26 | gchar* iid; |
---|
27 | gchar* name; |
---|
28 | gchar* desc; |
---|
29 | }; |
---|
30 | |
---|
31 | ODServerInfo* |
---|
32 | bonobo_directory_new_server_info (const gchar *iid, |
---|
33 | const gchar *name, |
---|
34 | const gchar *desc) |
---|
35 | { |
---|
36 | ODServerInfo *info; |
---|
37 | |
---|
38 | info = g_new (ODServerInfo, 1); |
---|
39 | |
---|
40 | info->refcount = 1; |
---|
41 | info->iid = iid ? g_strdup (iid) : NULL; |
---|
42 | info->name = name ? g_strdup (name) : NULL; |
---|
43 | info->desc = desc ? g_strdup (desc) : NULL; |
---|
44 | |
---|
45 | return info; |
---|
46 | } |
---|
47 | |
---|
48 | const gchar* |
---|
49 | bonobo_directory_get_server_info_id (ODServerInfo *info) |
---|
50 | { |
---|
51 | return info->iid; |
---|
52 | } |
---|
53 | |
---|
54 | const gchar* |
---|
55 | bonobo_directory_get_server_info_name (ODServerInfo *info) |
---|
56 | { |
---|
57 | return info->name; |
---|
58 | } |
---|
59 | |
---|
60 | const gchar* |
---|
61 | bonobo_directory_get_server_info_description (ODServerInfo *info) |
---|
62 | { |
---|
63 | return info->desc; |
---|
64 | } |
---|
65 | |
---|
66 | void |
---|
67 | bonobo_directory_server_info_ref (ODServerInfo *info) |
---|
68 | { |
---|
69 | info->refcount += 1; |
---|
70 | } |
---|
71 | |
---|
72 | void |
---|
73 | bonobo_directory_server_info_unref (ODServerInfo *info) |
---|
74 | { |
---|
75 | g_return_if_fail(info != NULL); |
---|
76 | g_return_if_fail(info->refcount > 0); |
---|
77 | |
---|
78 | info->refcount -= 1; |
---|
79 | |
---|
80 | if (info->refcount == 0) { |
---|
81 | g_free (info->iid); |
---|
82 | g_free (info->name); |
---|
83 | g_free (info->desc); |
---|
84 | g_free (info); |
---|
85 | } |
---|
86 | } |
---|
87 | |
---|
88 | void |
---|
89 | bonobo_directory_free_server_list (GList *list) |
---|
90 | { |
---|
91 | GList *l; |
---|
92 | |
---|
93 | for (l = list; l; l = l->next) |
---|
94 | bonobo_directory_server_info_unref (l->data); |
---|
95 | |
---|
96 | g_list_free (list); |
---|
97 | } |
---|
98 | |
---|
99 | |
---|
100 | CORBA_ORB |
---|
101 | bonobo_directory_get_orb (void) |
---|
102 | { |
---|
103 | return oaf_orb_get (); |
---|
104 | } |
---|
105 | |
---|
106 | static char * |
---|
107 | build_id_query_fragment (const char **required_ids) |
---|
108 | { |
---|
109 | const char **required_ids_iter; |
---|
110 | const char **query_components_iter; |
---|
111 | char **query_components; |
---|
112 | char *query; |
---|
113 | guint n_required = 0; |
---|
114 | |
---|
115 | /* We need to build a query up from the required_ids */ |
---|
116 | required_ids_iter = required_ids; |
---|
117 | |
---|
118 | while (required_ids && *required_ids_iter) { |
---|
119 | ++n_required; |
---|
120 | ++required_ids_iter; |
---|
121 | } |
---|
122 | |
---|
123 | query_components = g_new0 (gchar*, n_required + 1); |
---|
124 | |
---|
125 | query_components_iter = (const gchar **) query_components; |
---|
126 | required_ids_iter = required_ids; |
---|
127 | |
---|
128 | while (*required_ids_iter) { |
---|
129 | *query_components_iter = g_strconcat ("repo_ids.has('", |
---|
130 | *required_ids_iter, |
---|
131 | "')", |
---|
132 | NULL); |
---|
133 | ++query_components_iter; |
---|
134 | ++required_ids_iter; |
---|
135 | } |
---|
136 | |
---|
137 | query = g_strjoinv (" AND ", query_components); |
---|
138 | |
---|
139 | g_strfreev (query_components); |
---|
140 | |
---|
141 | return query; |
---|
142 | } |
---|
143 | |
---|
144 | GList * |
---|
145 | bonobo_directory_get_server_list (const gchar **required_ids) |
---|
146 | { |
---|
147 | GList *retval = NULL; |
---|
148 | gchar *query; |
---|
149 | OAF_ServerInfoList *servers; |
---|
150 | CORBA_Environment ev; |
---|
151 | guint i, j; |
---|
152 | |
---|
153 | g_return_val_if_fail (required_ids != NULL, NULL); |
---|
154 | g_return_val_if_fail (*required_ids != NULL, NULL); |
---|
155 | |
---|
156 | query = build_id_query_fragment (required_ids); |
---|
157 | |
---|
158 | CORBA_exception_init (&ev); |
---|
159 | servers = oaf_query (query, NULL, &ev); |
---|
160 | g_free (query); |
---|
161 | CORBA_exception_free (&ev); |
---|
162 | |
---|
163 | if (servers == NULL) |
---|
164 | return NULL; |
---|
165 | |
---|
166 | for (i = 0; i < servers->_length; i++) { |
---|
167 | OAF_ServerInfo *oafinfo = &servers->_buffer[i]; |
---|
168 | ODServerInfo *info; |
---|
169 | gchar *name = NULL, *desc = NULL; |
---|
170 | |
---|
171 | for (j = 0; j < oafinfo->props._length; j++) { |
---|
172 | if (oafinfo->props._buffer[j].v._d != OAF_P_STRING) |
---|
173 | continue; |
---|
174 | |
---|
175 | if (strcmp (oafinfo->props._buffer[j].name, "name") == 0) |
---|
176 | name = oafinfo->props._buffer[j].v._u.value_string; |
---|
177 | |
---|
178 | else if (strcmp (oafinfo->props._buffer[j].name, "description") == 0) |
---|
179 | desc = oafinfo->props._buffer[j].v._u.value_string; |
---|
180 | |
---|
181 | /* FIXME: internationalize here */ |
---|
182 | } |
---|
183 | |
---|
184 | /* |
---|
185 | * If no name attribute exists, use the description attribute. |
---|
186 | * If no description attribute exists, use the name attribute. |
---|
187 | * If neither a description attribute nor a name attribute exists, use the oafiid |
---|
188 | */ |
---|
189 | if (!name && !desc) |
---|
190 | name = desc = oafinfo->iid; |
---|
191 | |
---|
192 | if (!name) |
---|
193 | name = desc; |
---|
194 | |
---|
195 | if (!desc) |
---|
196 | desc = name; |
---|
197 | |
---|
198 | info = bonobo_directory_new_server_info (oafinfo->iid, |
---|
199 | name, |
---|
200 | desc); |
---|
201 | |
---|
202 | retval = g_list_prepend (retval, info); |
---|
203 | } |
---|
204 | |
---|
205 | CORBA_free (servers); |
---|
206 | |
---|
207 | return g_list_reverse (retval); |
---|
208 | } |
---|
209 | |
---|
210 | |
---|
211 | char * |
---|
212 | bonobo_directory_find_for_file (const char *fname, |
---|
213 | const char **required_ids, |
---|
214 | char **error) |
---|
215 | { |
---|
216 | char *query, *interfaces; |
---|
217 | const char *mime_type; |
---|
218 | char *iid; |
---|
219 | CORBA_Environment ev; |
---|
220 | OAF_ServerInfoList *servers; |
---|
221 | OAF_ServerInfo *oafinfo; |
---|
222 | |
---|
223 | if (!fname) { |
---|
224 | if (error) |
---|
225 | *error = g_strdup (_("No filename")); |
---|
226 | return NULL; |
---|
227 | } |
---|
228 | |
---|
229 | if (!(mime_type = gnome_mime_type ((char *) fname))) { |
---|
230 | if (error) |
---|
231 | *error = g_strdup_printf (_("unknown mime type for '%s'"), fname); |
---|
232 | return CORBA_OBJECT_NIL; |
---|
233 | } |
---|
234 | |
---|
235 | interfaces = build_id_query_fragment (required_ids); |
---|
236 | |
---|
237 | if (required_ids && required_ids [0] && interfaces) |
---|
238 | query = g_strdup_printf ("%s AND bonobo:supported_mime_types.has ('%s')", |
---|
239 | interfaces, mime_type); |
---|
240 | else |
---|
241 | query = g_strdup_printf ("bonobo:supported_mime_types.has ('%s')", |
---|
242 | mime_type); |
---|
243 | |
---|
244 | g_free (interfaces); |
---|
245 | |
---|
246 | CORBA_exception_init (&ev); |
---|
247 | |
---|
248 | servers = oaf_query (query, NULL, &ev); |
---|
249 | g_free (query); |
---|
250 | |
---|
251 | CORBA_exception_free (&ev); |
---|
252 | |
---|
253 | if (servers == CORBA_OBJECT_NIL || !servers->_buffer) { |
---|
254 | if (error) |
---|
255 | *error = g_strdup_printf ( |
---|
256 | _("no handlers for mime type '%s'"), mime_type); |
---|
257 | return NULL; |
---|
258 | } |
---|
259 | |
---|
260 | /* Just return the first one */ |
---|
261 | oafinfo = &servers->_buffer [0]; |
---|
262 | iid = g_strdup (oafinfo->iid); |
---|
263 | |
---|
264 | CORBA_free (servers); |
---|
265 | |
---|
266 | if (error) |
---|
267 | *error = NULL; |
---|
268 | |
---|
269 | return iid; |
---|
270 | } |
---|
271 | |
---|
272 | CORBA_Object |
---|
273 | od_server_activate_with_id (const gchar *iid, |
---|
274 | gint flags, |
---|
275 | CORBA_Environment *ev) |
---|
276 | { |
---|
277 | CORBA_Environment *real_ev, tmp_ev; |
---|
278 | CORBA_Object retval; |
---|
279 | |
---|
280 | if (ev) |
---|
281 | real_ev = ev; |
---|
282 | else { |
---|
283 | CORBA_exception_init (&tmp_ev); |
---|
284 | real_ev = &tmp_ev; |
---|
285 | } |
---|
286 | |
---|
287 | retval = oaf_activate_from_id ((gchar *) iid, 0, NULL, real_ev); |
---|
288 | |
---|
289 | if (!ev) |
---|
290 | CORBA_exception_free (&tmp_ev); |
---|
291 | |
---|
292 | return retval; |
---|
293 | } |
---|
294 | |
---|
295 | ODRegistrationResult |
---|
296 | bonobo_directory_register_server (CORBA_Object objref, |
---|
297 | const gchar *iid) |
---|
298 | { |
---|
299 | OAF_RegistrationResult result; |
---|
300 | ODRegistrationResult retval; |
---|
301 | |
---|
302 | result = oaf_active_server_register (iid, objref); |
---|
303 | |
---|
304 | switch (result) { |
---|
305 | case OAF_REG_SUCCESS: |
---|
306 | retval = OD_REG_SUCCESS; |
---|
307 | break; |
---|
308 | |
---|
309 | case OAF_REG_NOT_LISTED: |
---|
310 | retval = OD_REG_NOT_LISTED; |
---|
311 | break; |
---|
312 | |
---|
313 | case OAF_REG_ALREADY_ACTIVE: |
---|
314 | retval = OD_REG_ALREADY_ACTIVE; |
---|
315 | break; |
---|
316 | |
---|
317 | case OAF_REG_ERROR: |
---|
318 | default: |
---|
319 | retval = OD_REG_ERROR; |
---|
320 | break; |
---|
321 | } |
---|
322 | |
---|
323 | return retval; |
---|
324 | } |
---|
325 | |
---|
326 | ODRegistrationResult |
---|
327 | bonobo_directory_unregister_server (CORBA_Object objref, |
---|
328 | const gchar *iid) |
---|
329 | { |
---|
330 | oaf_active_server_unregister (iid, objref); |
---|
331 | |
---|
332 | return OD_REG_SUCCESS; |
---|
333 | } |
---|
334 | |
---|
335 | CORBA_Object |
---|
336 | bonobo_directory_get_name_service (CORBA_Environment *ev) |
---|
337 | { |
---|
338 | return oaf_name_service_get (ev); |
---|
339 | } |
---|