/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ /* * bonobo-activation-server: CORBA activation dameon. * * Copyright (C) 1999, 2000 Red Hat, Inc. * Copyright (C) 1999, 2000 Eazel, Inc. * Copyright (C) 1999, 2003 Ximian, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this library; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Authors: Elliot Lee , * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include "server.h" #include "activation-context.h" #include "bonobo-activation-id.h" #include "activation-context-query.h" #include "activation-server-corba-extensions.h" #include #undef LOCALE_DEBUG #define Bonobo_LINK_TIME_TO_LIVE 256 static GObjectClass *parent_class = NULL; static void directory_info_free (ActivationContext *actx, CORBA_Environment *ev) { CORBA_Object_release (actx->obj, ev); actx->obj = CORBA_OBJECT_NIL; if (actx->by_iid) { g_hash_table_destroy (actx->by_iid); actx->by_iid = NULL; } if (actx->list) { CORBA_sequence_set_release (actx->list, CORBA_TRUE); CORBA_free (actx->list); actx->list = NULL; } if (actx->active_servers) g_hash_table_destroy (actx->active_servers); CORBA_free (actx->active_server_list); actx->active_server_list = NULL; } static void ac_update_active (ActivationContext *actx, CORBA_Environment *ev) { int i; Bonobo_ServerStateCache *cache; cache = Bonobo_ObjectDirectory_get_active_servers ( actx->obj, actx->time_active_pulled, ev); if (ev->_major != CORBA_NO_EXCEPTION) { CORBA_Object_release (actx->obj, ev); actx->obj = CORBA_OBJECT_NIL; } if (cache->_d) { if (actx->active_servers) { g_hash_table_destroy (actx->active_servers); CORBA_free (actx->active_server_list); } actx->active_server_list = cache; actx->time_active_pulled = time (NULL); actx->active_servers = g_hash_table_new (g_str_hash, g_str_equal); for (i = 0; i < cache->_u.active_servers._length; i++) g_hash_table_insert (actx->active_servers, cache->_u. active_servers._buffer[i], GINT_TO_POINTER (1)); } else CORBA_free (cache); } static char * ac_CORBA_Context_get_value (CORBA_Context ctx, const char *propname, CORBA_Environment *ev) { return activation_server_CORBA_Context_get_value ( ctx, propname, ex_Bonobo_Activation_IncompleteContext, ev); } static void ac_update_list (ActivationContext *actx, CORBA_Environment *ev) { int i; Bonobo_ServerInfoListCache *cache; cache = Bonobo_ObjectDirectory_get_servers ( actx->obj, actx->time_list_pulled, ev); if (ev->_major != CORBA_NO_EXCEPTION) { actx->list = NULL; CORBA_Object_release (actx->obj, ev); actx->obj = CORBA_OBJECT_NIL; return; } if (cache->_d) { if (actx->by_iid) g_hash_table_destroy (actx->by_iid); if (actx->list) { CORBA_sequence_set_release (actx->list, CORBA_TRUE); CORBA_free (actx->list); actx->list = NULL; } actx->list = ORBit_copy_value (&cache->_u.server_list, TC_Bonobo_ServerInfoList); actx->time_list_pulled = time (NULL); actx->by_iid = g_hash_table_new (g_str_hash, g_str_equal); for (i = 0; i < actx->list->_length; i++) g_hash_table_insert (actx->by_iid, actx->list->_buffer[i].iid, &(actx->list->_buffer[i])); } CORBA_free (cache); } static QueryExprConst ac_query_get_var (Bonobo_ServerInfo *si, const char *id, QueryContext *qctx) { QueryExprConst retval; ActivationContext *actx = qctx->user_data; retval.value_known = FALSE; retval.needs_free = FALSE; if (!strcasecmp (id, "_active")) { CORBA_Environment ev; CORBA_exception_init (&ev); ac_update_active (actx, &ev); CORBA_exception_free (&ev); retval.value_known = TRUE; retval.type = CONST_BOOLEAN; retval.u.v_boolean = g_hash_table_lookup (actx->active_servers, si->iid) ? TRUE : FALSE; } return retval; } /* This function should only be called by * impl_Bonobo_ActivationContext_query and * impl_Bonobo_ActivationContext_activateMatching - hairy implicit preconditions * exist. */ static void ac_query_run (ActivationContext *actx, const CORBA_char *requirements, const Bonobo_StringList *selection_order, CORBA_Context ctx, Bonobo_ServerInfo **items, CORBA_Environment *ev) { int total, i; QueryContext qctx; Bonobo_ServerInfo **orig_items; int item_count, orig_item_count; char *errstr; Bonobo_Activation_ParseFailed *ex; QueryExpr *qexp_requirements; QueryExpr **qexp_sort_items; /* First, parse the query */ errstr = (char *) qexp_parse (requirements, &qexp_requirements); if (errstr) { puts (errstr); g_strstrip (errstr); ex = Bonobo_Activation_ParseFailed__alloc (); ex->description = CORBA_string_dup (errstr); CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_Bonobo_Activation_ParseFailed, ex); return; } qexp_sort_items = g_alloca (selection_order->_length * sizeof (QueryExpr *)); for (i = 0; i < selection_order->_length; i++) { errstr = (char *) qexp_parse (selection_order->_buffer[i], &qexp_sort_items[i]); if (errstr) { qexp_free (qexp_requirements); for (i--; i >= 0; i--) qexp_free (qexp_sort_items[i]); g_strstrip (errstr); ex = Bonobo_Activation_ParseFailed__alloc (); ex->description = CORBA_string_dup (errstr); CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_Bonobo_Activation_ParseFailed, ex); return; } } total = actx->total_servers; orig_items = g_alloca (total * sizeof (Bonobo_ServerInfo *)); { int i; item_count = 0; if (actx->obj != CORBA_OBJECT_NIL) for (i = 0; i < actx->list->_length; i++, item_count++) items[item_count] = &actx->list->_buffer[i]; } memcpy (orig_items, items, item_count * sizeof (Bonobo_ServerInfo *)); orig_item_count = item_count; qctx.sil = orig_items; qctx.nservers = orig_item_count; qctx.cctx = ctx; qctx.id_evaluator = ac_query_get_var; qctx.user_data = actx; for (i = 0; i < item_count; i++) { if (!qexp_matches (items[i], qexp_requirements, &qctx)) items[i] = NULL; } qexp_sort (items, item_count, qexp_sort_items, selection_order->_length, &qctx); qexp_free (qexp_requirements); for (i = 0; i < selection_order->_length; i++) qexp_free (qexp_sort_items[i]); } static void ac_update_lists (ActivationContext *actx, CORBA_Environment *ev) { int prev, new; if (actx->refs > 0) { /* FIXME: what happens on re-enterency here ? * looks like this could get seriously out of date */ return; } if (actx->list) prev = actx->list->_length; else prev = 0; ac_update_list (actx, ev); if (actx->list) new = actx->list->_length; else new = 0; actx->total_servers += (new - prev); } static GList *clients = NULL; void activation_clients_cache_notify (void) { GList *l; GSList *notify = NULL, *l2; CORBA_Environment ev; CORBA_exception_init (&ev); for (l = clients; l; l = l->next) notify = g_slist_prepend (notify, CORBA_Object_duplicate (l->data, &ev)); for (l2 = notify; l2; l2 = l2->next) { Bonobo_ActivationClient_resetCache (l2->data, &ev); if (ev._major != CORBA_NO_EXCEPTION) clients = g_list_remove (clients, l2->data); CORBA_Object_release (l2->data, &ev); CORBA_exception_free (&ev); } g_slist_free (notify); } gboolean activation_clients_is_empty_scan (void) { GList *l, *check = NULL; for (l = clients; l; l = l->next) check = g_list_prepend (check, CORBA_Object_duplicate (l->data, NULL)); for (l = check; l; l = l->next) { if (ORBit_small_get_connection_status (l->data) == ORBIT_CONNECTION_DISCONNECTED) { GList *remove; if ((remove = g_list_find (clients, l->data))) { CORBA_Object_release (remove->data, NULL); clients = g_list_delete_link (clients, remove); } } CORBA_Object_release (l->data, NULL); } g_list_free (check); return clients == NULL; } static gboolean ac_rescan (gpointer data) { static gboolean in_rescan = FALSE; static guint idle_id = 0; server_lock (); /* We tend to get a lot of 'broken' callbacks at once */ if (in_rescan) { if (!idle_id) idle_id = g_idle_add (ac_rescan, NULL); server_unlock (); return FALSE; } in_rescan = TRUE; if (activation_clients_is_empty_scan ()) { #ifdef BONOBO_ACTIVATION_DEBUG g_warning ("All clients dead"); #endif check_quit (); } in_rescan = FALSE; server_unlock (); return FALSE; } static void active_client_cnx_broken (ORBitConnection *cnx, gpointer dummy) { ac_rescan (NULL); } static void impl_Bonobo_ActivationContext_addClient (PortableServer_Servant servant, const Bonobo_ActivationClient client, const CORBA_char *locales, CORBA_Environment *ev) { GList *l; gboolean new_locale; ORBitConnection *cnx; server_lock (); new_locale = register_interest_in_locales (locales); cnx = ORBit_small_get_connection (client); for (l = clients; l; l = l->next) if (cnx == ORBit_small_get_connection (l->data)) break; clients = g_list_prepend ( clients, CORBA_Object_duplicate (client, ev)); if (!l) { ORBit_small_listen_for_broken (client, G_CALLBACK (active_client_cnx_broken), NULL); check_quit (); } if (new_locale) bonobo_object_directory_reload (); server_unlock (); } static Bonobo_ObjectDirectoryList * impl_Bonobo_ActivationContext__get_directories (PortableServer_Servant servant, CORBA_Environment *ev) { ActivationContext *actx; Bonobo_ObjectDirectoryList *retval; server_lock (); actx = ACTIVATION_CONTEXT (servant); retval = Bonobo_ObjectDirectoryList__alloc (); if (actx->obj != CORBA_OBJECT_NIL) { retval->_length = 1; retval->_buffer = CORBA_sequence_Bonobo_ObjectDirectory_allocbuf (1); retval->_buffer[0] = CORBA_Object_duplicate (actx->obj, ev); } else { retval->_length = 0; } CORBA_sequence_set_release (retval, CORBA_TRUE); server_unlock (); return retval; } static void impl_Bonobo_ActivationContext_addDirectory (PortableServer_Servant servant, Bonobo_ObjectDirectory dir, CORBA_Environment *ev) { ActivationContext *actx; server_lock (); actx = ACTIVATION_CONTEXT (servant); if (actx->obj == dir) CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_Bonobo_Activation_AlreadyListed, NULL); else { CORBA_Object_release (actx->obj, ev); actx->obj = CORBA_Object_duplicate (dir, ev); } server_unlock (); } static void impl_Bonobo_ActivationContext_removeDirectory (PortableServer_Servant servant, Bonobo_ObjectDirectory dir, CORBA_Environment *ev) { ActivationContext *actx; server_lock (); actx = ACTIVATION_CONTEXT (servant); if (dir != actx->obj) CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_Bonobo_Activation_NotListed, NULL); else { if (actx->refs) { CORBA_Object_release (actx->obj, ev); actx->obj = CORBA_OBJECT_NIL; } else directory_info_free (actx, ev); } server_unlock (); } static void ac_do_activation (ActivationContext *actx, Bonobo_ServerInfo *server, const Bonobo_ActivationEnvironment *environment, Bonobo_ActivationResult *out, Bonobo_ActivationFlags flags, const char *hostname, Bonobo_ActivationClient client, CORBA_Context ctx, CORBA_Environment *ev) { int num_layers; Bonobo_ServerInfo *activatable; gchar *aid = NULL; /* When doing checks for shlib loadability, we * have to find the info on the factory object in case * a factory is inside a shlib */ if (!actx->obj || ev->_major != CORBA_NO_EXCEPTION) { Bonobo_GeneralError *errval = Bonobo_GeneralError__alloc (); errval->description = CORBA_string_dup (_("Couldn't find which child the server was listed in")); CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_Bonobo_GeneralError, errval); return; } for (num_layers = 0, activatable = server; activatable && activatable->server_type && !strcmp (activatable->server_type, "factory") && num_layers < Bonobo_LINK_TIME_TO_LIVE; num_layers++) { activatable = g_hash_table_lookup (actx->by_iid, activatable->location_info); } if (activatable == NULL) { Bonobo_GeneralError *errval = Bonobo_GeneralError__alloc (); errval->description = CORBA_string_dup ("Couldn't find the factory server"); CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_Bonobo_GeneralError, errval); return; } else if (num_layers == Bonobo_LINK_TIME_TO_LIVE) { Bonobo_GeneralError *errval = Bonobo_GeneralError__alloc (); errval->description = CORBA_string_dup ("Location loop"); CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_Bonobo_GeneralError, errval); return; } /* A shared library must be on the same host as the activator in * order for loading to work properly (no, we're not going to * bother with loading a remote shlib into a process - it gets far too complicated * far too quickly :-) */ if (activatable) aid = g_strdup_printf ("OAFAID:[%s,%s,%s]", activatable->iid, activatable->username, activatable->hostname); if (activatable && activatable->server_type && !strcmp (activatable->server_type, "shlib") && !(flags & Bonobo_ACTIVATION_FLAG_NO_LOCAL) && (hostname && !strcmp (activatable->hostname, hostname))) { int j; out->res._d = Bonobo_ACTIVATION_RESULT_SHLIB; /* Here is an explanation as to why we add 2 to num_layers. * At the end of the string list, after all the factory iids are added * to the string list, we then add the iid of the shaed library and the * location info. This data is later used in oaf_server_activate_shlib * to activate the component */ out->res._u.res_shlib._length = num_layers + 2; out->res._u.res_shlib._buffer = CORBA_sequence_CORBA_string_allocbuf (num_layers + 2); /* Copy over factory info */ for (j = 0, activatable = server; activatable && !strcmp (activatable->server_type, "factory"); j++) { out->res._u.res_shlib._buffer[j] = CORBA_string_dup (activatable->iid); activatable = g_hash_table_lookup (actx->by_iid, activatable->location_info); } /* Copy shlib iid into buffer */ out->res._u.res_shlib._buffer[j] = CORBA_string_dup (activatable->iid); /* Copy location into last buffer slot for use in later activation */ out->res._u.res_shlib._buffer[j+1] = CORBA_string_dup (activatable->location_info); out->aid = CORBA_string_dup (aid); } else { CORBA_Object retval; char *iid = g_strdup (server->iid); retval = Bonobo_ObjectDirectory_activate ( actx->obj, iid, BONOBO_OBJREF (actx), environment, flags, client, ctx, ev); g_free (iid); if (ev->_major == CORBA_NO_EXCEPTION) { out->res._d = Bonobo_ACTIVATION_RESULT_OBJECT; out->res._u.res_object = retval; out->aid = CORBA_string_dup (aid); } #ifdef BONOBO_ACTIVATION_DEBUG else g_warning ("Activation of '%s' failed with exception '%s'", aid, ev->_id); #endif } g_free (aid); } static Bonobo_ActivationResult * impl_Bonobo_ActivationContext_activateMatchingFull ( PortableServer_Servant servant, const CORBA_char *requirements, const Bonobo_StringList *selection_order, const Bonobo_ActivationEnvironment *environment, const Bonobo_ActivationFlags flags, Bonobo_ActivationClient client, CORBA_Context ctx, CORBA_Environment *ev) { ActivationContext *actx; Bonobo_ActivationResult *retval = NULL; Bonobo_ServerInfo **items, *curitem; int i; char *hostname; server_lock (); actx = ACTIVATION_CONTEXT (servant); ac_update_lists (actx, ev); actx->refs++; items = g_alloca (actx->total_servers * sizeof (Bonobo_ServerInfo *)); ac_query_run (actx, requirements, selection_order, ctx, items, ev); if (ev->_major != CORBA_NO_EXCEPTION) goto out; hostname = ac_CORBA_Context_get_value (ctx, "hostname", ev); retval = Bonobo_ActivationResult__alloc (); retval->res._d = Bonobo_ACTIVATION_RESULT_NONE; bonobo_object_ref (actx); for (i = 0; (retval->res._d == Bonobo_ACTIVATION_RESULT_NONE) && items[i] && (i < actx->total_servers); i++) { curitem = items[i]; ac_do_activation (actx, curitem, environment, retval, flags, hostname, client, ctx, ev); } bonobo_object_unref (actx); if (retval->res._d == Bonobo_ACTIVATION_RESULT_NONE) retval->aid = CORBA_string_dup (""); g_free (hostname); out: if (ev->_major != CORBA_NO_EXCEPTION) { CORBA_free (retval); retval = NULL; } actx->refs--; server_unlock (); return retval; } static Bonobo_ActivationResult * impl_Bonobo_ActivationContext_activateMatching ( PortableServer_Servant servant, const CORBA_char *requirements, const Bonobo_StringList *selection_order, const Bonobo_ActivationEnvironment *environment, const Bonobo_ActivationFlags flags, CORBA_Context ctx, CORBA_Environment *ev) { return impl_Bonobo_ActivationContext_activateMatchingFull (servant, requirements, selection_order, environment, flags, CORBA_OBJECT_NIL, ctx, ev); } static Bonobo_ServerInfoList * impl_Bonobo_ActivationContext_query (PortableServer_Servant servant, const CORBA_char * requirements, const Bonobo_StringList * selection_order, CORBA_Context ctx, CORBA_Environment * ev) { ActivationContext *actx; Bonobo_ServerInfoList *retval; Bonobo_ServerInfo **items; int item_count; int i, j, total; server_lock (); actx = ACTIVATION_CONTEXT (servant); retval = Bonobo_ServerInfoList__alloc (); retval->_length = 0; retval->_buffer = NULL; CORBA_sequence_set_release (retval, CORBA_TRUE); /* Pull in new lists from OD servers */ ac_update_lists (actx, ev); actx->refs++; items = g_alloca (actx->total_servers * sizeof (Bonobo_ServerInfo *)); item_count = actx->total_servers; ac_query_run (actx, requirements, selection_order, ctx, items, ev); if (ev->_major == CORBA_NO_EXCEPTION) { for (total = i = 0; i < item_count; i++) { if (items[i]) total++; } retval->_length = total; retval->_buffer = CORBA_sequence_Bonobo_ServerInfo_allocbuf (total); for (i = j = 0; i < item_count; i++) { if (!items[i]) continue; Bonobo_ServerInfo_copy (&retval->_buffer[j], items[i]); j++; } } actx->refs--; server_unlock (); return retval; } static char * ac_aid_to_query_string (const CORBA_char *aid) { char *requirements; char *iid_requirement; char *username_requirement; char *hostname_requirement; BonoboActivationInfo *ainfo; ainfo = bonobo_activation_id_parse (aid); if (!ainfo) return NULL; iid_requirement = g_strconcat ("iid == \'", ainfo->iid, "\' ", NULL); if (ainfo->user) { username_requirement = g_strconcat ("AND username == \'", ainfo->user, "\'", NULL); } else { username_requirement = g_strdup (""); } if (ainfo->host) { hostname_requirement = g_strconcat ("AND hostname == \'", ainfo->host, "\'", NULL); } else { hostname_requirement = g_strdup (""); } requirements = g_strconcat (iid_requirement, username_requirement, hostname_requirement, NULL); g_free (iid_requirement); g_free (username_requirement); g_free (hostname_requirement); bonobo_activation_info_free (ainfo); return requirements; } static void ac_context_to_string_array (CORBA_Context context, char **sort_criteria, CORBA_Environment *ev) { char *context_username; char *context_hostname; context_username = ac_CORBA_Context_get_value (context, "username", ev); context_hostname = ac_CORBA_Context_get_value (context, "hostname", ev); if (ev->_major != CORBA_NO_EXCEPTION) { g_free (context_username); g_free (context_hostname); return; } sort_criteria[0] = g_strconcat ("username == \'", context_username, "\'", NULL); sort_criteria[1] = g_strconcat ("hostname == \'", context_hostname, "\'", NULL); sort_criteria[2] = NULL; g_free (context_username); g_free (context_hostname); } #define PARSE_ERROR_NOT_AN_AID (_("Not a valid Activation ID")) static Bonobo_ActivationResult * impl_Bonobo_ActivationContext_activateFromAidFull (PortableServer_Servant servant, const CORBA_char *aid, Bonobo_ActivationFlags flags, Bonobo_ActivationClient client, CORBA_Context ctx, CORBA_Environment *ev) { ActivationContext *actx; Bonobo_ActivationResult *retval = NULL; char *requirements; char *sort_criteria[3]; Bonobo_StringList selection_order; Bonobo_ActivationEnvironment environment; server_lock (); actx = ACTIVATION_CONTEXT (servant); if (strncmp ("OAFAID:", aid, 7) != 0) { Bonobo_Activation_ParseFailed *ex; ex = Bonobo_Activation_ParseFailed__alloc (); ex->description = CORBA_string_dup (PARSE_ERROR_NOT_AN_AID); CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_Bonobo_Activation_ParseFailed, ex); goto act_out; } ac_update_lists (actx, ev); if (ev->_major != CORBA_NO_EXCEPTION) goto act_out; actx->refs++; requirements = ac_aid_to_query_string (aid); if (requirements == NULL) { actx->refs--; goto act_out; } ac_context_to_string_array (ctx, sort_criteria, ev); if (ev->_major != CORBA_NO_EXCEPTION) { actx->refs--; g_free (requirements); goto act_out; } selection_order._length = 2; selection_order._buffer = sort_criteria; CORBA_sequence_set_release (&selection_order, CORBA_FALSE); memset (&environment, 0, sizeof (Bonobo_ActivationEnvironment)); retval = impl_Bonobo_ActivationContext_activateMatchingFull ( actx, requirements, &selection_order, &environment, flags, client, ctx, ev); g_free (sort_criteria[0]); g_free (sort_criteria[1]); g_free (requirements); actx->refs--; act_out: server_unlock (); return retval; } static Bonobo_ActivationResult * impl_Bonobo_ActivationContext_activateFromAid (PortableServer_Servant servant, const CORBA_char *aid, Bonobo_ActivationFlags flags, CORBA_Context ctx, CORBA_Environment *ev) { return impl_Bonobo_ActivationContext_activateFromAidFull (servant, aid, flags, CORBA_OBJECT_NIL, ctx, ev); } static CORBA_long impl_Bonobo_ActivationContext_getVersion (PortableServer_Servant servant, CORBA_Environment *ev) { return (BONOBO_ACTIVATION_MAJOR_VERSION*10000 + BONOBO_ACTIVATION_MINOR_VERSION*100 + BONOBO_ACTIVATION_MICRO_VERSION); } static ActivationContext *main_ac = NULL; void activation_context_setup (PortableServer_POA poa, Bonobo_ObjectDirectory dir, CORBA_Environment *ev) { main_ac = g_object_new (activation_context_get_type (), "poa", poa, NULL); impl_Bonobo_ActivationContext_addDirectory (BONOBO_OBJECT (main_ac), dir, ev); } void activation_context_shutdown (void) { if (main_ac) { bonobo_object_set_immortal (BONOBO_OBJECT (main_ac), FALSE); bonobo_object_unref (BONOBO_OBJECT (main_ac)); main_ac = NULL; } } Bonobo_ActivationContext activation_context_get (void) { if (!main_ac) return CORBA_OBJECT_NIL; else return BONOBO_OBJREF (main_ac); } static void activation_context_finalize (GObject *object) { CORBA_Environment ev[1]; ActivationContext *actx = (ActivationContext *) object; CORBA_exception_init (ev); directory_info_free (actx, ev); CORBA_exception_free (ev); parent_class->finalize (object); } static void activation_context_class_init (ActivationContextClass *klass) { GObjectClass *object_class = (GObjectClass *) klass; POA_Bonobo_ActivationContext__epv *epv = &klass->epv; parent_class = g_type_class_peek_parent (klass); object_class->finalize = activation_context_finalize; epv->_get_directories = impl_Bonobo_ActivationContext__get_directories; epv->addClient = impl_Bonobo_ActivationContext_addClient; epv->addDirectory = impl_Bonobo_ActivationContext_addDirectory; epv->removeDirectory = impl_Bonobo_ActivationContext_removeDirectory; epv->query = impl_Bonobo_ActivationContext_query; epv->activateMatching = impl_Bonobo_ActivationContext_activateMatching; epv->activateFromAid = impl_Bonobo_ActivationContext_activateFromAid; epv->getVersion = impl_Bonobo_ActivationContext_getVersion; epv->activateMatchingFull = impl_Bonobo_ActivationContext_activateMatchingFull; epv->activateFromAidFull = impl_Bonobo_ActivationContext_activateFromAidFull; } static void activation_context_init (ActivationContext *actx) { bonobo_object_set_immortal (BONOBO_OBJECT (actx), TRUE); } BONOBO_TYPE_FUNC_FULL (ActivationContext, Bonobo_ActivationContext, BONOBO_TYPE_OBJECT, activation_context)