From fc1e5673bb9d91f89a851262cf5c66b50c31c18d Mon Sep 17 00:00:00 2001 From: Ettore Perazzoli Date: Fri, 5 Oct 2001 17:49:35 +0000 Subject: If setting the owner fails, print the a warning message out. Then restart * e-shell.c (set_owner_on_components): If setting the owner fails, print the a warning message out. Then restart the component. * e-component-registry.c (component_free): Return a boolean value. %FALSE if ::unsetOwner raises an exception. (register_type): New arg @override_duplicate, to avoid complaining if a component gets re-registered. (register_component): Likewise. (e_component_registry_restart_component): New. * e-uri-schema-registry.c (e_uri_schema_registry_set_handler_for_schema): Changed return type to `void'. Just remove the old handler and set up the new one. * evolution-shell-component-client.c (corba_exception_to_result): Translate ::OldOwnerHasDied into EVOLUTION_SHELL_COMPONENT_OLDOWNERHASDIED. * evolution-shell-component.h: New enum value `EVOLUTION_SHELL_COMPONENT_OLDOWNERHASDIED'. * evolution-shell-component.c (impl_setOwner): If the old owner is not alive anymore [use CORBA_Object_non_existent() to figure this out], emit OWNER_UNSET and raise `OldOwnerHasDied'. (evolution_shell_component_result_to_string): New. * Evolution-ShellComponent.idl: New exception `OldOwnerHasDied'. (ShellComponent::setOwner): Can raise it. * e-folder-type-registry.c (e_folder_type_register_type_registered): New. (e_folder_type_register_unregister_type): New. svn path=/trunk/; revision=13446 --- shell/ChangeLog | 36 ++++++++++++ shell/Evolution-ShellComponent.idl | 4 +- shell/e-component-registry.c | 95 ++++++++++++++++++++++++++++---- shell/e-component-registry.h | 3 + shell/e-folder-type-registry.c | 43 +++++++++++++++ shell/e-folder-type-registry.h | 5 ++ shell/e-shell.c | 10 +++- shell/e-uri-schema-registry.c | 16 +++--- shell/e-uri-schema-registry.h | 2 +- shell/evolution-shell-component-client.c | 10 ++++ shell/evolution-shell-component.c | 71 +++++++++++++++++++++++- shell/evolution-shell-component.h | 3 + 12 files changed, 274 insertions(+), 24 deletions(-) (limited to 'shell') diff --git a/shell/ChangeLog b/shell/ChangeLog index ffecae4ab0..004c44a304 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,3 +1,39 @@ +2001-10-05 Ettore Perazzoli + + * e-shell.c (set_owner_on_components): If setting the owner fails, + print the a warning message out. Then restart the component. + + * e-component-registry.c (component_free): Return a boolean value. + %FALSE if ::unsetOwner raises an exception. + (register_type): New arg @override_duplicate, to avoid complaining + if a component gets re-registered. + (register_component): Likewise. + (e_component_registry_restart_component): New. + + * e-uri-schema-registry.c + (e_uri_schema_registry_set_handler_for_schema): Changed return + type to `void'. Just remove the old handler and set up the new + one. + + * evolution-shell-component-client.c (corba_exception_to_result): + Translate ::OldOwnerHasDied into + EVOLUTION_SHELL_COMPONENT_OLDOWNERHASDIED. + + * evolution-shell-component.h: New enum value + `EVOLUTION_SHELL_COMPONENT_OLDOWNERHASDIED'. + + * evolution-shell-component.c (impl_setOwner): If the old owner is + not alive anymore [use CORBA_Object_non_existent() to figure this + out], emit OWNER_UNSET and raise `OldOwnerHasDied'. + (evolution_shell_component_result_to_string): New. + + * Evolution-ShellComponent.idl: New exception `OldOwnerHasDied'. + (ShellComponent::setOwner): Can raise it. + + * e-folder-type-registry.c + (e_folder_type_register_type_registered): New. + (e_folder_type_register_unregister_type): New. + 2001-10-04 Rodrigo Moya * importer/Makefile.am: added BONOBO_GNOME_CFLAGS to make it compile diff --git a/shell/Evolution-ShellComponent.idl b/shell/Evolution-ShellComponent.idl index a5601f29ab..d920e80956 100644 --- a/shell/Evolution-ShellComponent.idl +++ b/shell/Evolution-ShellComponent.idl @@ -46,11 +46,11 @@ module Evolution { readonly attribute URISchemaList externalUriSchemas ; readonly attribute UserCreatableItemTypeList userCreatableItemTypes; - /* FIXME: Can we use an attribute here? */ exception AlreadyOwned {}; + exception OldOwnerHasDied {}; void setOwner (in Shell shell, in string evolution_homedir) - raises (AlreadyOwned); + raises (AlreadyOwned, OldOwnerHasDied); exception NotOwned {}; diff --git a/shell/e-component-registry.c b/shell/e-component-registry.c index 3851821741..ffa3769000 100644 --- a/shell/e-component-registry.c +++ b/shell/e-component-registry.c @@ -77,17 +77,21 @@ component_new (const char *id, return new; } -static void +static gboolean component_free (Component *component) { GNOME_Evolution_ShellComponent corba_shell_component; CORBA_Environment ev; + gboolean retval; - CORBA_exception_init (&ev); corba_shell_component = bonobo_object_corba_objref (BONOBO_OBJECT (component->client)); + + CORBA_exception_init (&ev); GNOME_Evolution_ShellComponent_unsetOwner (corba_shell_component, &ev); - if (ev._major != CORBA_NO_EXCEPTION) - g_warning ("Cannot unregister component -- %s", component->id); + if (ev._major == CORBA_NO_EXCEPTION) + retval = TRUE; + else + retval = FALSE; CORBA_exception_free (&ev); g_free (component->id); @@ -97,6 +101,8 @@ component_free (Component *component) e_free_string_list (component->folder_type_names); g_free (component); + + return retval; } static gboolean @@ -110,7 +116,8 @@ register_type (EComponentRegistry *component_registry, const char **exported_dnd_types, int num_accepted_dnd_types, const char **accepted_dnd_types, - Component *handler) + Component *handler, + gboolean override_duplicate) { EComponentRegistryPrivate *priv; EFolderTypeRegistry *folder_type_registry; @@ -120,6 +127,10 @@ register_type (EComponentRegistry *component_registry, folder_type_registry = e_shell_get_folder_type_registry (priv->shell); g_assert (folder_type_registry != NULL); + if (override_duplicate + && e_folder_type_register_type_registered (folder_type_registry, name)) + e_folder_type_register_unregister_type (folder_type_registry, name); + if (! e_folder_type_registry_register_type (folder_type_registry, name, icon_name, display_name, description, @@ -139,7 +150,8 @@ register_type (EComponentRegistry *component_registry, static gboolean register_component (EComponentRegistry *component_registry, - const char *id) + const char *id, + gboolean override_duplicate) { EComponentRegistryPrivate *priv; GNOME_Evolution_ShellComponent component_corba_interface; @@ -153,7 +165,7 @@ register_component (EComponentRegistry *component_registry, priv = component_registry->priv; - if (g_hash_table_lookup (priv->component_id_to_component, id) != NULL) { + if (! override_duplicate && g_hash_table_lookup (priv->component_id_to_component, id) != NULL) { g_warning ("Trying to register component twice -- %s", id); return FALSE; } @@ -198,7 +210,8 @@ register_component (EComponentRegistry *component_registry, (const char **) type->exportedDndTypes._buffer, type->acceptedDndTypes._length, (const char **) type->acceptedDndTypes._buffer, - component)) { + component, + override_duplicate)) { g_warning ("Cannot register type `%s' for component %s", type->name, component->id); } @@ -218,8 +231,7 @@ register_component (EComponentRegistry *component_registry, const CORBA_char *schema; schema = supported_schemas->_buffer[i]; - if (! e_uri_schema_registry_set_handler_for_schema (uri_schema_registry, schema, component->client)) - g_warning ("Cannot register schema `%s' for component %s", schema, component->id); + e_uri_schema_registry_set_handler_for_schema (uri_schema_registry, schema, component->client); } CORBA_free (supported_schemas); @@ -324,7 +336,7 @@ e_component_registry_register_component (EComponentRegistry *component_registry, g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (component_registry), FALSE); g_return_val_if_fail (id != NULL, FALSE); - return register_component (component_registry, id); + return register_component (component_registry, id, FALSE); } @@ -398,6 +410,67 @@ e_component_registry_get_component_by_id (EComponentRegistry *component_registr return component->client; } + +EvolutionShellComponentClient * +e_component_registry_restart_component (EComponentRegistry *component_registry, + const char *id) +{ + EComponentRegistryPrivate *priv; + Component *component; + CORBA_Environment ev; + CORBA_Object corba_objref; + gboolean alive; + int count; + + g_return_val_if_fail (component_registry != NULL, NULL); + g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (component_registry), NULL); + g_return_val_if_fail (id != NULL, NULL); + + priv = component_registry->priv; + + component = g_hash_table_lookup (priv->component_id_to_component, id); + if (component == NULL) + return NULL; + + CORBA_exception_init (&ev); + + g_hash_table_remove (priv->component_id_to_component, id); + + corba_objref = CORBA_Object_duplicate (bonobo_object_corba_objref (BONOBO_OBJECT (component->client)), &ev); + + component_free (component); + + count = 1; + while (1) { + alive = bonobo_unknown_ping (corba_objref); + if (! alive) + break; + + g_print ("Waiting for component to die -- %s (%d)\n", id, count); + sleep (1); + count ++; + } + + CORBA_exception_free (&ev); + +#if 1 + if (! register_component (component_registry, id, TRUE)) + return NULL; + + return e_component_registry_get_component_by_id (component_registry, id); +#else + client = evolution_shell_component_client_new (id); + if (client == NULL) + return NULL; + + component = component_new (id, client); + g_hash_table_insert (priv->component_id_to_component, component->id, component); + bonobo_object_unref (BONOBO_OBJECT (client)); +#endif + + return component->client; +} + E_MAKE_TYPE (e_component_registry, "EComponentRegistry", EComponentRegistry, class_init, init, PARENT_TYPE) diff --git a/shell/e-component-registry.h b/shell/e-component-registry.h index 280aef74a6..6b77f56f49 100644 --- a/shell/e-component-registry.h +++ b/shell/e-component-registry.h @@ -69,6 +69,9 @@ GList *e_component_registry_get_id_list (ECompo EvolutionShellComponentClient *e_component_registry_get_component_by_id (EComponentRegistry *component_registry, const char *id); +EvolutionShellComponentClient *e_component_registry_restart_component (EComponentRegistry *component_registry, + const char *id); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/shell/e-folder-type-registry.c b/shell/e-folder-type-registry.c index 97fb7b4c25..0c7e664dd6 100644 --- a/shell/e-folder-type-registry.c +++ b/shell/e-folder-type-registry.c @@ -326,6 +326,49 @@ e_folder_type_registry_set_handler_for_type (EFolderTypeRegistry *folder_type_r return set_handler (folder_type_registry, type_name, handler); } + +gboolean +e_folder_type_register_type_registered (EFolderTypeRegistry *folder_type_registry, + const char *type_name) +{ + EFolderTypeRegistryPrivate *priv; + + g_return_val_if_fail (folder_type_registry != NULL, FALSE); + g_return_val_if_fail (E_IS_FOLDER_TYPE_REGISTRY (folder_type_registry), FALSE); + g_return_val_if_fail (type_name != NULL, FALSE); + + priv = folder_type_registry->priv; + + if (get_folder_type (folder_type_registry, type_name) == NULL) + return FALSE; + + return TRUE; +} + +void +e_folder_type_register_unregister_type (EFolderTypeRegistry *folder_type_registry, + const char *type_name) +{ + EFolderTypeRegistryPrivate *priv; + FolderType *folder_type; + + g_return_if_fail (folder_type_registry != NULL); + g_return_if_fail (E_IS_FOLDER_TYPE_REGISTRY (folder_type_registry)); + g_return_if_fail (type_name != NULL); + + priv = folder_type_registry->priv; + + folder_type = get_folder_type (folder_type_registry, type_name); + if (folder_type == NULL) { + g_warning ("e_folder_type_register_unregister_type(): cannot find type `%s'\n", + type_name); + return; + } + + g_hash_table_remove (priv->name_to_type, folder_type->name); + folder_type_free (folder_type); +} + static void get_type_names_hash_forall (void *key, diff --git a/shell/e-folder-type-registry.h b/shell/e-folder-type-registry.h index 580bba4f41..01f1ad80ec 100644 --- a/shell/e-folder-type-registry.h +++ b/shell/e-folder-type-registry.h @@ -76,6 +76,11 @@ gboolean e_folder_type_registry_set_handler_for_type (EFolderTypeRegistry GList *e_folder_type_registry_get_type_names (EFolderTypeRegistry *folder_type_registry); +gboolean e_folder_type_register_type_registered (EFolderTypeRegistry *folder_type_registry, + const char *type_name); +void e_folder_type_register_unregister_type (EFolderTypeRegistry *folder_type_registry, + const char *type_name); + GdkPixbuf *e_folder_type_registry_get_icon_for_type (EFolderTypeRegistry *folder_type_registry, const char *type_name, gboolean mini); diff --git a/shell/e-shell.c b/shell/e-shell.c index a1f47ca8b5..bafe7ea2d5 100644 --- a/shell/e-shell.c +++ b/shell/e-shell.c @@ -686,12 +686,20 @@ set_owner_on_components (EShell *shell) id_list = e_component_registry_get_id_list (priv->component_registry); for (p = id_list; p != NULL; p = p->next) { EvolutionShellComponentClient *component_client; + EvolutionShellComponentResult result; const char *id; id = (const char *) p->data; component_client = e_component_registry_get_component_by_id (priv->component_registry, id); - evolution_shell_component_client_set_owner (component_client, corba_shell, local_directory); + result = evolution_shell_component_client_set_owner (component_client, corba_shell, local_directory); + if (result != EVOLUTION_SHELL_COMPONENT_OK) { + g_warning ("Error setting owner on component %s -- %s", + id, evolution_shell_component_result_to_string (result)); + + if (result == EVOLUTION_SHELL_COMPONENT_OLDOWNERHASDIED) + e_component_registry_restart_component (priv->component_registry, id); + } } e_free_string_list (id_list); diff --git a/shell/e-uri-schema-registry.c b/shell/e-uri-schema-registry.c index 1136cb92a6..a30b9950ee 100644 --- a/shell/e-uri-schema-registry.c +++ b/shell/e-uri-schema-registry.c @@ -132,7 +132,7 @@ e_uri_schema_registry_new (void) } -gboolean +void e_uri_schema_registry_set_handler_for_schema (EUriSchemaRegistry *registry, const char *schema, EvolutionShellComponentClient *shell_component) @@ -141,16 +141,18 @@ e_uri_schema_registry_set_handler_for_schema (EUriSchemaRegistry *registry, SchemaHandler *existing_handler; SchemaHandler *new_handler; - g_return_val_if_fail (registry != NULL, FALSE); - g_return_val_if_fail (E_IS_URI_SCHEMA_REGISTRY (registry), FALSE); - g_return_val_if_fail (schema != NULL, FALSE); - g_return_val_if_fail (shell_component == NULL || EVOLUTION_IS_SHELL_COMPONENT_CLIENT (shell_component), FALSE); + g_return_if_fail (registry != NULL); + g_return_if_fail (E_IS_URI_SCHEMA_REGISTRY (registry)); + g_return_if_fail (schema != NULL); + g_return_if_fail (shell_component == NULL || EVOLUTION_IS_SHELL_COMPONENT_CLIENT (shell_component)); priv = registry->priv; existing_handler = g_hash_table_lookup (priv->schema_to_handler, schema); - if (existing_handler != NULL) - return FALSE; + if (existing_handler != NULL) { + g_hash_table_remove (priv->schema_to_handler, existing_handler->schema); + schema_handler_free (existing_handler); + } new_handler = schema_handler_new (schema, shell_component); g_hash_table_insert (priv->schema_to_handler, new_handler->schema, new_handler); diff --git a/shell/e-uri-schema-registry.h b/shell/e-uri-schema-registry.h index 458810b739..caa19ad2d9 100644 --- a/shell/e-uri-schema-registry.h +++ b/shell/e-uri-schema-registry.h @@ -58,7 +58,7 @@ struct _EUriSchemaRegistryClass { GtkType e_uri_schema_registry_get_type (void); EUriSchemaRegistry *e_uri_schema_registry_new (void); -gboolean e_uri_schema_registry_set_handler_for_schema (EUriSchemaRegistry *registry, +void e_uri_schema_registry_set_handler_for_schema (EUriSchemaRegistry *registry, const char *schema, EvolutionShellComponentClient *shell_component); EvolutionShellComponentClient *e_uri_schema_registry_get_handler_for_schema (EUriSchemaRegistry *registry, diff --git a/shell/evolution-shell-component-client.c b/shell/evolution-shell-component-client.c index bba3cb462e..b1666c2f27 100644 --- a/shell/evolution-shell-component-client.c +++ b/shell/evolution-shell-component-client.c @@ -72,6 +72,8 @@ corba_exception_to_result (const CORBA_Environment *ev) if (ev->_major == CORBA_USER_EXCEPTION) { if (strcmp (ev->_repo_id, ex_GNOME_Evolution_ShellComponent_AlreadyOwned) == 0) return EVOLUTION_SHELL_COMPONENT_ALREADYOWNED; + if (strcmp (ev->_repo_id, ex_GNOME_Evolution_ShellComponent_OldOwnerHasDied) == 0) + return EVOLUTION_SHELL_COMPONENT_OLDOWNERHASDIED; if (strcmp (ev->_repo_id, ex_GNOME_Evolution_ShellComponent_NotOwned) == 0) return EVOLUTION_SHELL_COMPONENT_NOTOWNED; if (strcmp (ev->_repo_id, ex_GNOME_Evolution_ShellComponent_NotFound) == 0) @@ -379,6 +381,7 @@ evolution_shell_component_client_new (const char *id) { CORBA_Environment ev; CORBA_Object corba_object; + char *ior; g_return_val_if_fail (id != NULL, NULL); @@ -390,6 +393,13 @@ evolution_shell_component_client_new (const char *id) g_warning ("Could not start up component for %s.", id); return NULL; } + +#if 0 + ior = CORBA_ORB_object_to_string (bonobo_orb (), corba_object, &ev); + g_print ("--- %s %s\n", id, ior); + CORBA_free (ior); +#endif + CORBA_exception_free (&ev); if (corba_object == CORBA_OBJECT_NIL) { diff --git a/shell/evolution-shell-component.c b/shell/evolution-shell-component.c index 341091dd29..6fa1210f03 100644 --- a/shell/evolution-shell-component.c +++ b/shell/evolution-shell-component.c @@ -305,8 +305,26 @@ impl_setOwner (PortableServer_Servant servant, priv = shell_component->priv; if (priv->owner_client != NULL) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_ShellComponent_AlreadyOwned, NULL); + int owner_is_dead; + + owner_is_dead = CORBA_Object_non_existent + (bonobo_object_corba_objref (BONOBO_OBJECT (priv->owner_client)), ev); + if (ev->_major != CORBA_NO_EXCEPTION) + owner_is_dead = TRUE; + + if (! owner_is_dead) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_GNOME_Evolution_ShellComponent_AlreadyOwned, NULL); + } else { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_GNOME_Evolution_ShellComponent_OldOwnerHasDied, NULL); + + bonobo_object_unref (BONOBO_OBJECT (priv->owner_client)); + priv->owner_client = NULL; + + gtk_signal_emit (GTK_OBJECT (shell_component), signals[OWNER_UNSET]); + } + return; } @@ -824,6 +842,55 @@ evolution_shell_component_add_user_creatable_item (EvolutionShellComponent *she priv->user_creatable_item_types = g_slist_prepend (priv->user_creatable_item_types, type); } + +/* Public utility functions. */ + +const char * +evolution_shell_component_result_to_string (EvolutionShellComponentResult result) +{ + switch (result) { + case EVOLUTION_SHELL_COMPONENT_OK: + return _("Success"); + case EVOLUTION_SHELL_COMPONENT_CORBAERROR: + return _("CORBA error"); + case EVOLUTION_SHELL_COMPONENT_INTERRUPTED: + return _("Interrupted"); + case EVOLUTION_SHELL_COMPONENT_INVALIDARG: + return _("Invalid argument"); + case EVOLUTION_SHELL_COMPONENT_ALREADYOWNED: + return _("Already has an owner"); + case EVOLUTION_SHELL_COMPONENT_NOTOWNED: + return _("No owner"); + case EVOLUTION_SHELL_COMPONENT_NOTFOUND: + return _("Not found"); + case EVOLUTION_SHELL_COMPONENT_UNSUPPORTEDTYPE: + return _("Unsupported type"); + case EVOLUTION_SHELL_COMPONENT_UNSUPPORTEDSCHEMA: + return _("Unsupported schema"); + case EVOLUTION_SHELL_COMPONENT_UNSUPPORTEDOPERATION: + return _("Unsupported operation"); + case EVOLUTION_SHELL_COMPONENT_INTERNALERROR: + return _("Internal error"); + case EVOLUTION_SHELL_COMPONENT_BUSY: + return _("Busy"); + case EVOLUTION_SHELL_COMPONENT_EXISTS: + return _("Exists"); + case EVOLUTION_SHELL_COMPONENT_INVALIDURI: + return _("Invalid URI"); + case EVOLUTION_SHELL_COMPONENT_PERMISSIONDENIED: + return _("Permission denied"); + case EVOLUTION_SHELL_COMPONENT_HASSUBFOLDERS: + return _("Has subfolders"); + case EVOLUTION_SHELL_COMPONENT_NOSPACE: + return _("No space left"); + case EVOLUTION_SHELL_COMPONENT_OLDOWNERHASDIED: + return _("Old owner has died"); + case EVOLUTION_SHELL_COMPONENT_UNKNOWNERROR: + default: + return _("Unknown error"); + } +} + E_MAKE_X_TYPE (evolution_shell_component, "EvolutionShellComponent", EvolutionShellComponent, class_init, init, PARENT_TYPE, diff --git a/shell/evolution-shell-component.h b/shell/evolution-shell-component.h index 6fe70ac8fe..6d273e5337 100644 --- a/shell/evolution-shell-component.h +++ b/shell/evolution-shell-component.h @@ -67,6 +67,7 @@ enum _EvolutionShellComponentResult { EVOLUTION_SHELL_COMPONENT_PERMISSIONDENIED, EVOLUTION_SHELL_COMPONENT_HASSUBFOLDERS, EVOLUTION_SHELL_COMPONENT_NOSPACE, + EVOLUTION_SHELL_COMPONENT_OLDOWNERHASDIED, EVOLUTION_SHELL_COMPONENT_UNKNOWNERROR }; typedef enum _EvolutionShellComponentResult EvolutionShellComponentResult; @@ -178,6 +179,8 @@ void evolution_shell_component_add_user_creatable_item (EvolutionShellComponen const char *menu_description, char menu_shortcut); +const char *evolution_shell_component_result_to_string (EvolutionShellComponentResult result); + #ifdef cplusplus } #endif /* cplusplus */ -- cgit v1.2.3