Hi free software hackers!!
Here is the spanish translation of Mr.Miguel de Icaza´s "Monikers" (primates.ximian.com/~miguel/).
There will be a definitive 1.0 release next week available in several formats such as PostScript and HTML downloadable from www.gcubo.org, but that will be next week. Till then please send me all the comments and critics that you may consider interesting.
Enjoy!
Jaime.
"Microsoft te da las ventanas, GNU/Linux te da la casa completa."
Monikers en el sistema GNOME Miguel de Icaza _____________________________________________ (miguel@ximian.com) 1.- Introducción Recientemente hemos reimplementado y completamente reorganizado el soporte de Moniker en Bonobo. Este trabajo ha abierto una amplia gama de posibilidades: desde la unificación del espacio de la nomenclatura de objetos, hasta proveer una mejor integración en el sistema. Nota: en este documento he omitido el manejo de entornos de excepción para una mejor explicación de la tecnología. 2.- Monikers - una perspectiva de usuario Los monikers se usan para nombrar objetos, ellos implementan de forma efectiva un espacio de nomenclatura de objetos. Podéis obtener monikers bien porque los habéis creado manualmente o mediante una representación STRINGIFIED de un moniker. Aquí hay una lista de los monikers STRINGIFIED y una interpretación: * file:quake-scores.gnumeric Esto sería un moniker que representa el fichero quake-scores.gnumeric. * oafid:GNOME:Gnumeric:WorkbookFactory:1.0 Este moniker representa el objeto Gnumeric Workbook factory. * oafid:GNOME:Gnumeric:WorkbookFactory:1.0:new: Este moniker representa una instancia Gnumeric Workbook. Notar que hemos usado exactamente el mismo OAFID que en el ejemplo de antes, pero aquí hay un sufijo "new": al final. * file:/tmp/a.gz Este representa el fichero en /tmp/a.gz * file:/tmp/a.gz#gunzip Este representa la hebra de datos descomprimida de a.gz * file:/tmp/a.gz#gunzip:streamcache Este provee uan cache sobre la hebra de datos descomprimida de a.gz (el moniker streamcache es un componente in-proc.). * http://ww.gnome.org Este representa la página de GNOME. * evolution:Mail/Inbox Este representa el directorio Evolution Mail/Inbox. * file:quake-scores.gnumeric!January Este representa la hoja de Enero en el libro de trabajo quake-scores.gnumeric. * file:quake-scores.gnumeric!January!Winner Este representa le celda cuyo nombre es "Winner" en la hoja de Enero del libro de trabajo quake-scores.gnumeric. * file:quake-scores.gnumeric!January!Winner!Style!Font Este representa la interfaz de fuente del estilo adjunto a la celda Winner. * file:quake-scores.gnumeric!January!Winner!Style!BackgroundColor Este representa el color de fondo de la celda. * http://www.gnome.org/index.html!title Este representa el elemento de título en la página basada en HTML de www.gnome.org * file:toyota.xml!cars/car/model/ El "cars/car/model/" es una expresión XPath que localiza un nodo específico en el archivo toyota.xml. * config:*/Session/Calendar Este representa una PropertyBag para el GNOME Calendar usando el sistema de configuración local y la configuración guardada en el dominio de sesion. * oafid:Helix:Evolution:Wombat:1.0 Este representa el servidor de modelos Evolution que almacena toda la información per-user. * queue:oafid:Helix:Evolution:Wombat Este representa una interfaz que pone en cola las peticiones CORBA al Evolution Wombat: cualquier llamada enviada será puesta en cola: si el Wombat está ocupado o no acepta conexiones, todas las invocaciones por el método CORBA serán puestas en cola sin detener la ejecución del código cliente. * http://www.gnome.org/index.html.gz#gunzip#html:title Esto devuelve el elemento de título de un fichero HTML comprimido en http://www.gnome.org/index.html.gz * ftp://ftp.gnome.org/gnome-core-1.0.tar.gz#utar/gnome-core-1.0/ChangeLog Una referencia al fichero ChangeLog contenido en el fichero tar comprimido gnome-core-1.0.tar.gz en ftp://ftp.gnome.org * desktop:Background El objeto de fondo del escritorio del usuario. * trashscan: La papelera del sistema. * file:logo.png Este representa el fichero logo.png. * oafid:OAFID:eog_viewer_factory:file:logo.png Este representa un visor de imagen específico para mostrar el fichero "logo.png", en este caso el programa "EOG". * file:logo.png!Zoom=2.0 Este representa al fichero logo.png en EOG a un zoom de 2.0. * file:logo.png!Zoom=2.0,dither=max,notransparency La imagen logo.png está configurada para que se le haga zoom a un nivel de 2.0, para hacer un DITHERING máximo y no usar ninguna transparencia. Lo que acabamos de ver son algunos ejemplos de representaciones STRINGIFIED de monikers. Esto significa que no son realmente monikers, sino el modo en que estos se representan en una forma de cadena. Los monikers se suelen crear mediante el empleo de una llamada al API Bonobo que transforma la representación STRINGIFIED en un objeto (que exporta la interfaz IDL:Bonobo/Moniker:1.0), tal como sigue: moniker = bonobo_moniker_client_new_from_name (moniker_string); El moniker solo es interesante porque puede producir otros objetos cuando es resuelto. Durante el proceso de resolución, especificas que interfaz te interesa que corra el moniker. Esto se logra mediante la invocación del método ::resolve en el moniker y pasándole la REPOID de la interfaz que deseas, tal que así: Bonobo::Unknown control; control = moniker->resolve ("Bonobo/Control") Esto le pide al moniker devolver un objeto que implemente la interfaz IDL:Bonobo/Control:1.0. Esto significa que el objeto podría ser embutido como un control Bonobo regular en las aplicaciones. Puede que no desees obtener un control, pero sí resolver el moniker contra una intefaz diferente, por instancia en la interfaz Bonobo::PropertyBag: properties = moniker->resolve ("Bonobo/PropertyBag"); El proceso de resolución puede generar objetos completamente diferentes. El proceso de PARSING y de resolución se empaquetan en una simple llamada al API para tu conveniencia: la función bonobo_get_object: Bonobo::Unknown bonobo_object_get (char *moniker_string, char *interface); Como he dicho, el proceso de resolución puede generar diferentes objetos dependiendo del interfaz que haya sido solicitado, por ejemplo: x = bonobo_object_get ("http://www.gnome.org", "Bonobo/Control") y = bonobo_object_get ("http://www.gnome.org", "Bonobo/Stream") El objeto "x" bien puede ser lanzado por Mozilla que cargará www.gnome.org, el objeto devuelto puede ser usado como un control de Bonobo y usado en tu aplicación como widget. Por otra parte, el objeto "y" no necesita todo el poder de Mozilla, cuando solo se le solicita una interfaz Stream muy simple, así que quizás podremos implementar esto con una implementación de HTTP que sea ligera: quizás un servidor bonobo basado en wget o un servidor libghttp. Conviene darse cuenta de que las versiones STRINGIFIED de los monikers fueron las mismas (i.e. "http://www.gnome.org") y los objetos resultantes pueden diferir ampliamente dependiendo de la interfaz que solicitemos. 3.- El sistema de análisis de Moniker. Durante el análisis del moniker STRINGIFIED, Bonobo usará el prefijo terminado en dos puntos como el moniker de máximo nivel que será invocado en el proceso de resolución. Para el prefijo: "file:" el moniker file es el que será usado; para el prefijo "oafid", se usará el moniker oafid; para el prefijo "queue:", se usará el moniker queue. Una vez que el moniker que maneja un prefijo específico ha sido activado, al moniker se le solicitará para que analice el resto de la cadena de especificación y devolver un moniker válido. Cada moniker consumirá generalmente un número de bytes hasta el punto que su dominio se detenga, que supondremos que es el siguiente moniker. Así que activará al siguiente moniker y le pasará el resto de la versión STRINGIFIED del moniker hasta que el análisis finalice. Cada moniker tiene libertad para definir su propio mecanismo de análisis, sus caracteres especiales se usan para indicar el final del espacio del moniker y el principio del nuevo (como los caracteres "#" y "!" en algunos de los ejemplos que vimos más arriba.). Esta flexibilidad es posible gracias a que cada moniker debe definir sus propias reglas (y es importante, si queremos integrarlos con estándares como el http y el file.). 4.- Monikers como un esquema de nomenclatura de objetos. Como se puede ver, los monikers se usan para implementar un sistema de nomenclatura que puede ser usado para referenciar y manipular objetos. Quizás hayas notado que el método ::resolve en la interfaz moniker devuelve una interfaz Bonobo::Unknown y por definición, bonobo_get_object también devuelve una Bonobo::Unknown. Esto significa que el objeto resultante de la resolución del moniker siempre soportará los métodos ref, unref y query_interface. El esquema de nomenclatura "monikeriana" es: * Extensible. nuevo punto de entrada al espacio de nomenclatura de objetos que puede ser creado e instalado en el sistema. Esto se logra instalando un nuevo componente. * Jerárquico. Monikers FIXME. 5.- Creando Monikers. Los monikers se suelen crear mediante llamadas API a la rutina Bonobo o por tus propias clases que implementen monikers. FIXME: más. 6.- Espacio de nombres de objetos. * Comparando el espacio de los nombres de Moniker con el espacio de nombres de Unix. Empecemos por lo fácil. Un moniker es una referencia a un objeto[1]. Para usar el objeto, tienes que "resolver" el moniker. El término usado por la literatura es "uniendo el objeto" ("binding the object".). El resultado de resolver el moniker es un objeto Bonobo::Unknown. Piensa en un moniker como en una ruta. Y piensa en el proceso de unir como en la llamada "abierta" de sistema en Unix. Ficheros Unix Monikers Nombraciones de objetos: nombre de ruta representación de cuerda del moniker. Función de unir: open(2) bonobo_get_object Valor de salida: kernel file descriptor Bonobo::Unknown CORBA reference. Binder: kernel VFS+each FS bonobo_get_object+Bonobo::Moniker Persisting: none Moniker::QI(Persist) En el caso del sistema de ficheros, el kernel hace la "resolución" de cada elemento de ruta analizando un elemento del sistema de ficheros y el interruptor VFS (Sistema de Ficheros Virtual) usa el sistema de ficheros actual más los puntos de montaje para resolver el último nombre del fichero. 7.- Enlace de ficheros. Los monikers fueron implementados originalmente como una parte del del sistema de documentación de componentes de Microsoft OLE2. Pueden ser usados de manera efectiva por las aplicaciones durante las operaciones de arrastrar y soltar y de cortar y pegar para pasar objetos que tienen que estar enlazados por otras aplicaciones. La aplicación fuente crearía un moniker para un objeto dado que lo identificaría plenamente y lo pasaría através de una operación arrastrar y soltar o en una de cortar y pegar a la aplicación recipiente. La aplicación recipiente puede entonces resolver el moniker contra la interfaz requerida (en el caso de Bonobo, Bonobo/Embeddable, o Bonobo/Control serían una elección corriente.). Las aplicaciones no tienen porque almacenar los contenidos enteros de la información enlazada, pueden guardar una representación STRINGIFIED del moniker y resolverla otra vez en tiempo de carga. 8.- Inicialización de instancia. Los monikers pueden ser usados para inicializar objetos, como una manera de pasarle argumentos a tu objeto. Esto es emparejado con la interfaz Bonobo/ItemContainer y el Item Moniker. El Item Moniker es cubierto más tarde. 9.- Resolución de un moniker contra una interfaz. Un moniker puede ser resuelto contra interfaces diferentes. El objeto resultante puede ser distinto dependiendo de la interfaz que está siendo resuelta. Para ilustrar ésto, aquí tenemos un ejemplo, digamos que tenemos la representación de cadena de un moniker: "http://www.ximian.com". La representación de cadena de un moniker puede ser resuelta contra la interfaz "Bonobo/Control": bonobo_get_object ("http://www.ximian.com", "Bonobo/Control"); Esto podría devolver un componente Mozilla embutido que es capaz de ser encajado en nuestra aplicación como un widget (porque le estamos pidiendo al moniker que devuelva una interfaz Bonobo/Control.). Si la interfaz es resuelta contra la interfaz "Bonobo/Stream", quizás Mozilla no sea requerido y el proceso podría usar otro más pequeño que simplemente provea Bonobo/Streams, como puede ser un wget "corbificado". La lógica para ésto reside en el manejador de moniker http:. 10.- Monikers core. Bonobo se distribuye con un número de manejadores de monikers: el moniker file, el moniker item, el oafid moniker y el new moniker. 10.1- El moniker file. El moniker file es usado para referenciar ficheros. Por ejemplo: file:sales.gnumeric El moniker file escaneará su argumento hasta que alcance los caracteres especiales '#' o '!' que indican el final del nombre del fichero. El moniker file usará el tipo de mime asociado con el fichero para encontrar un componente que maneje el fichero. Una vez el manejador del objeto ha sido invocado, el moniker tratará de alimentar el fichero al componente, primero solicitando la interfaz PersistFile y luego, si no es soportada, mendiante la interfaz PersistStream. 10.2- El moniker item. El moniker item generalmente se TRIGGERED por un "!" en el medio. El moniker item puede ser usado para implementar una nomenclatura de objetos cliente, o manejo de argumentos. El item moniker analiza el texto que sigue a '!' hasta el siguiente '!', ésto es llamado argumento de un moniker item. Durante el proceso de resolución, el moniker item solicitará a su padre la interfaz de Bonobo/ItemContainer e invocará el getObject en esa interfaz con ese argumento. Por ejemplo, en una hoja de cálculo de Gnumeric esto permite a los programadores referenciar sub-objetos por nombre. Los libros de trabajo pueden localizar objetos de hoja (Sheet); las hojas pueden localizar nombres de rango, nombres de celda o referencias de celda. Este moniker referiría la hoja llamada 'Ventas'en el libro de trabajo contenido en la hoja ventas.gnumeric: sheet = bonobo_get_object ("ventas.gnumeric!Ventas", "Gnumeric/Sheet"); Este otro referiría la celda que ha sido llamada 'Total'dentro de la hoja "Ventas": cell = bonobo_get_object ("ventas.gnumeric!Ventas!Total", "Gnumeric/Cell"); El modo en que esto funciona desde la perspectiva del contenedor es que el contenedor implementaría el método (cadena) getObject y respondería a la petición getObject. Los monikers item pueden, a su vez, ser usados para la llevar a cabo la inicialización. El componente que desee soportar la inicialización necesita soportar la interfaz Bonobo/ItemContainer e implementar un método getObject que devolviera el objeto propiamente inicializado. Por ejemplo, consideremos un componente visor de imágenes que pueda ser configurado, como este: image = bonobo_get_object ("file.jpg!convert_to_gray=on", "Bonobo/Control"); El ejemplo de arriba activaría el componente EOG (Ojo de GNOME) porque el file.jpg encaja y entonces invocaría la implementación EOG's ItemContainer con el argumento "convert_to_gray=on". getObject debería devolver un objeto (que sería ella misma) pero modificaría los datos de la instancia para ajustar la bandera "convert_to_gray" a "on". Como esto: Bonobo_Unknown eog_item_container_get_object (BonoboObject *o, char *name) { if (command_is (name, "convert_to_gray", &v)) image_set_convert_to_gray (o, v); ... bonobo_object_ref (o); return bonobo_object_corba_objref (o); } 10.3. El moniker oafid El moniker oafid maneja la activación usando el entorno de trabajo de activación de objetos (Object Activation Framework). Esto permite a los programadores activar objetos por sus ID OAF, como sigue: gnumeric = bonobo_object_get ("oafid:GNOME_Gnumeric_Workbook", iface); 10.4. El moniker "new:" El moniker new solicita de su padre la interfaz "Bonobo/GenericFactory" e invoca el método de create_instance en la interfaz. Generalmente este moniker se invocaría tal que así: bonobo_get_object ("oafid:RandomFactory:new:", iface); En este ejemplo "RandomFactory" es el OAFID para la creación de un determinado objeto. Durante el proceso de resolución, el moniker "new:" pediría a su padre que resuelva contra la interfaz IDL:GNOME/ObjectFactory:1.0 (que es la interfaz tradicional de creación en GNOME para generar nuevas instancias de objetos) y entonces llamar al método new_instance sobre él. Historicamente GNORBA (el antiguo sistema de activación de objetos de GNOME) y OAF (el nuevo sistema de activación de objetos) implementaban un "hack" especial para hacer este mismo proceso. Básicamente, los ficheros de descripción para el sistema de activación de objetos estaba sobrecargado, había tres tipos de mecanismos de activación definidos: * Implementación de activación de objetos desde un ejecutable. * Implementación de activación de objetos desde una librería. * Implementación de activación de objetos mediante lanzamiento de otro objeto y solicitando al nuevo objeto la intefaz de ObjectFactory. El moniker "new:" básicamente obvia la necesidad del último paso en el sistema de activación. Con OAF, usando la aproximación OAF se demuestra que es más útil, desde que es posible pedir a los componentes OAF que tengan ciertos atributos y para el objeto creación, no son interesantes estos atributos para las instancias mismas. Aparte de esto, el moniker "new:" puede ser usado para realizar una operación de inicialización en escenarios más complejos que los que podría tratarse mediante activación por OAF. 11.- Añadiendo manejadores de monikers al sistema. 12.- Monikers ideales: Hay dos manejadores de monikers que podrían ser interesantes de implementar: el Moniker de Configuración y el Moniker de VFS. Ambos ayudan al sistema más que ningún otro, porque añaden la sencillez de tener una manera estándar de activar servicios en el sistema y si la API a esos servicios está basada en CORBA, cualquier lenguaje de programación con soporte CORBA/Bonobo podrá hacer uso de ellos si la necesidad de que vaya ligado a un lenguaje particular. Estoy convencido de que esto ayuda a dar consistencia interna al sistema. 12.1- El Moniker de Configuración El moniker de configuración es llamado usando el prefijo "config:". La cadena, después de todo, es el localizador de la configuración. El moniker debería soportar ser requerido contra la interfaz "Bonobo/Property" o "Bonobo/PropertyBag", dependiendo de si solicitamos un atributo o un conjunto de ellos. Por ejemplo, recuperar la información de configuración de una propiedad específica de configuración de Gnumeric sería hacer lo siguiente: Bonobo_Property auto_save; CORBA_Any value; auto_save = bonobo_get_object ( "config:gnumeric/auto-save", "/Bonobo/Property"); value = bonobo_property_get_value (auto_save, &ev); if (value->tc->kind == CORBA_tk_bool) printf ("Value: %s\n", (CORBA_bool) value->_value ? "true" : "false"); else printf ("Property is not boolean\n"); En el ejemplo anterior, primero usamos la rutina bonobo_get_object para localizar el objeto através de su moniker. El valor devuelto de la bonobo_get_object es del tipo Bonobo_Property que es la manera estándar de Bonobo para manipular propiedades. Esto tiene dos ventajas: * Accediendo al motor de configuración através de la interfaz de moniker hemos eliminado la necesidad de definir una API específica de C para el manejo de la configuración. La configuración podría ser realizada mediante cualquier lenguaje que soporte CORBA. El proyecto GNOME siempre ha tratado de definir APIs que pudieran ser fácilmente accesibles y cubiertas desde varios lenguajes (particularmente, hemos hecho esto con este grupo de herramientas y con los enlaces CORBA). Pero aún cuando hemos tenido especialmente cuidado de conseguir ésto y nos hemos esforzado continuamente en cubrir las últimas y mejores APIs, widgets y herramientas, los enlaces generalmente se retrasan desde unas pocas semanas hasta algunos meses detrás del API de C del momento. Moviéndonos hacia CORBA, solo necesitamos soportar CORBA en el grupo de lenguajes de programación y obtenemos acceso a las nuevas APIs definidas por él. * Cualesquiera herramientas en el sistema que puedan manipular Bonobo::PropertyBag (una GUI en un diseñador visual o un motor de configuración que persiste/hidrata objetos o una herramienta de búsqueda) pueden comunicarse directamente con el motor de configuración, ya que estamos usando el mismo método de interfaz a lo largo de todos los lenguajes en el sistema. La interfaz Bonobo::Property es bastante intuitiva y debería solventar la mayoría de las necesidades, los métodos son: string get_name (); TypeCode get_type (); any get_value (); void set_value (); any get_default (); string get_doc_string (); long get_flags (); Como se puede ver, esta interfaz no especifica una implementación para el fondo actual. Dado que esto es solo una interfaz, no necesitamos preocuparnos de a que moniker nos conectaremos, solo debemos preocuparnos del hecho de que podremos usar las interfaces Property y PropertyBag. 12.1.1. Transacciones de configuración. El manejo de cambios de transacciones al sistema de configuración puede ser logrado mediante el uso de la interfaz setValues en la PropertyBag. La implementación de la PropertyBag puede aceptar el conjunto de valores o puede efectuar comprobaciones de consistencia al conjunto de valores (por ejemplo, para evitar que la configuración se contradiga a sí misma o que acepte valores incorrectos.). Si el conjunto de valores es incorrecto, una excepción es devuelta. También sería posible enganchar un componente de comprobación de consistencia en el medio, insertando la comprobación en el medio de la cadena como sigue: bonobo_get_object ("config:gnumeric/auto-save:gnumeric-consistency-check:", "Bonobo/Property"); Notar el manejador moniker 'gnumeric-consistency-check:' Esto podría ser un componente de comprobación de consistencia de librerías compartidas si es lo que se necesita que sea. 12.1.2. Escuchando a los cambios. Uno de los requerimientos que se le debe pedir a un escritorio moderno es que reaccione conjuntamente cuando se le hacen cambios a propiedades globales. Por ejemplo, en el escritorio GNOME, cuando un tema es cambiado, un protocolo especial dentro de Gtk+ es usado para avisar a todas las aplicaciones que deben recargar su configuración de tema. Hay muchos otros ejemplos donde las aplicaciones necesitan mantener un seguimiento de su configuración. Por ejemplo, cuando una preferencia se cambia, queremos que la preferencia escoga el camino correcto, sin que para ello tengamos que reiniciar o correr aplicaciones. Esto de consigue de manera sencilla registrando un Listener con el Bonobo/EventSource en la PropertyBag. 12.1.3. ¿Qué pasa con GConf?. GConf es una infraestructura de manejo de configuración que provee las siguientes ventajas: * Un sistema de schemes para especificar los distintos tipos de opciones de configuración, así como su documentación y valores inciales (valores por defecto.). * Una forma para el administrador del sistema para cambiar valores en un sistema grande (como pueda ser una gran red si lo deseamos.). * Un sistema de aviso de cambios: las aplicaciones pueden ser avisadas de los diversos cambios de los que quizás se quiera hacer un seguimiento. GConf tiene dos pegas en estos momentos: * GConf provee mucho más de lo que se suele necesitar, pero es un API basado en C que necesita ser portado a cualquier lenguaje que desee soportar GConf. * GConf está limitado en el tipo que de datos que puede almacenar en su base de datos. Una BonoboProperty almacena una CORBA_Any que puede contener cualquiera de los tipos simples de CORBA (cadenas, enteros, puntos flotantes, booleanos), estructuras, arrays y uniones. El motor actual y el fondo para GConf puede convertirse en el manejador moniker de configuración, solo el API sería reemplazado así como el sistema actual de alamacenamiento para soportar la más completa CORBA_Any y la interfaz adhoc CORBA puede ser reemplazada con un sistema más potente. 12.1.4. Manejo de configuraciones: Open Issues. 12.1.4.1. Especificando la localización para la configuración. La sistaxis para acceder a la configuración no ha sido definida, pero podemos confeccionarnosla de forma fácil. Forzando a los datos de configuración para que sean cargados desde una localización específica. Como los argumentos al moniker pueden ser usados para codificar una localización específica, por ejemplo: config:~/file.config!auto-save Parece más natural usar el moniker fichero para que nos de esa información, por ejemplo: file:~/file.config!config:auto-save El moniker de configuración puede hacer un análisis para buscar la presencia de padre, si el padre existe, entonces podrá solicitar una de las interfaces Persist de él para cargar el archivo actual de configuración y proveer acceso a él. 12.1.4.2. Configuración transaccional de valores. Puede que tenga sentido poner a modo de "batch" (poner por lotes) un número de cambios realizado bajo un prefijo para evitar a los que están pendientes de claves de que se reinicien ellos mismos. Consideremos el caso en el que una herramienta de línea de comando haga varios cambios en las propiedades de fondo, digamos que los cambios se hacen en este orden: background = bonobo_get_object ("config:desktop/background", "PropertyBag"); bonobo_property_bag_set_values (background, bonobo_property_list_new ( "gradient", "string", "true", "color1", "string", "red", "color2", "string", "blue", &ev); Si el programa que debería hacer esa configuración para manejar el fondo está corriendo en ese punto, habrá registrado o habrá sido avisado de los cambios hechos a todos esos valores. Los cambios quizás sean muy costosos. Por ejemplo el código puede reaccionar a cada cambio y recalcular todo el contenido de la imagen en cada cambio. Una optimización sería poner el principio de la transacción al final de ella en el código cliente para permitir a los que permanecen a la escucha que obtengan avisos de los cambios: background = bonobo_get_object ("config:desktop/background", iface); bonobo_property_bag_batch_push (background); bonobo_property_set (background, "gradient", "true"); bonobo_property_set (background, "color1", "red"); bonobo_property_set (background, "color2", "blue"); bonobo_property_bag_batch_pop (background); Esto permitiría al código que está a la escucha procesar por lotes todas las llamadas costosas de resolver en un único paso. 12.1.4.3. Manejadores de configuración Consideremos el ejemplo anterior, querríamos ser capaces de cambiar las propiedades en el sistema y que los cambios tuviesen efecto independientemente de si hay un cliente a la escucha o no. Un manejador de propiedades podría registrar con el moniker de configuración para ser lanzado cuando una propiedad cambia. Esto podría ser llevado a cabo en un fichero en una localización especial. 12.2. EL GNOME VFS se deprecia. El GNOME VFS provee una abstracción de interfaz de sistema de ficheros asíncrono que puede ser usada para acceder a ficheros locales, ficheros remotos, ficheros dentro de ficheros comprimidos y demás. El problema con el GNOME VFS es que está muy limitado: solo puede exponer un sistema de ficheros como interfaz a sus clientes (mucho más como la interfaz Unix después de la cuál fue modelada). Como se trató antes en el `Espacio de Nomenclatura de Objetos', los monikers definen un espacio de nomeclatura de objetos y pueden ser definidos para cualquier tipo de recurso que el GNOME VFS soporta (una trayectoria de transición puede incluir un conjunto de monikers implementados sobre el actual GNOME VFS). Un diálogo de ficheros puede solicitar al moniker que se resuelva contra una interfaz "Listadora Gráfica de Ficheros", que puede resultar en una ventana miniaturizada de Nautilus para ser empotrada en una caja de diálogo. Sería posible reusar enteramente al código existente de GNOME VFS proveiendo de monikers para varios métodos de acceso que pudieran manejar los casos especiales "Stream", "Storage" y "FileListing". Otras interfaces serán añadidas al manejador de monikers para soportar el contexto más rico. Por ejemplo, consideremos el moniker "trashcan:". El moniker trashcan puede ser resuelto contra varias interfaces. Un gestor de ficheros podría resolverlo contra una interfaz de listado de directorios para mostrar el contenido de éste; podría resolverlo contra una interfaz "Control" para obtener una vista de la papelera (para configurar los valores en la papelera); una interfaz PropertyBag podría ser usada para configurar programadamente las distintas opciones de ella. 13. Otros monikers. Hay otra familia de manejadores de monikers que merecen la pena ser estudiados. Los manejadores de monikers de filtrado y los manejadores de monikers de CACHING. 13.1 El moniker streamcache:. La idea del moniker streamcache es ser (fundamentalmente) un manejador de moniker de librerías compartidas que provea una caché para la interfaz IDL:Bonobo/Stream:1.0. Este moniker es muy simple, durante su solución pide la interfaz IDL:Bonobo/ Stream:1.0 a su padre y solo puede exponerla a sus clientes. La ventaja es: es un componente de librería compartida, que correrá en la dirección de espacio de la aplicación que usará la Stream y provee una caché a la Stream padre (así que podemos usar llamadas pequeñas del método granular y la stream caché puede hacer el buffering tradicional). Piénsese en esta diferencia como la que hay entre una aplicación usando write()/read y una que usa fwrite/fread/getc/putc: aunque muchas aplicaciones pueden implementar su propio buffering, la mayoría del tiempo usando solamente las que proveen la librería libc (fwrite/fread/getc/putc) lo harán. Esto es exactamente lo que hará el moniker streamcache: Añadiéndo esto a una representación STRINGIFIED de un moniker, podréis obtener una Stream caché gratuitamente. 13.2 Los monikers de filtrado #gunzip y #utar. El moniker #utar es un moniker que implementaría la decodificación de ficheros tar (el mismo concepto puede ser usado con otros formatos de archivo). Este moniker usa un manejador auxiliar de componentes tar. El moniker conecta el manejador de componentes tar a la interfaz padre de Stream de objetos y devuelve el objeto resultante. El resultado del moniker #utar puede ser una Bonobo/Stream (para una referencia de ficheros) o bien una Bonobo/Storage (para una referencia de directorios). Como esto: file://home/miguel/mail-backup.tar#utar:2000/may/1001 ftp://ftp.ximian.com/pub/sources/gnome-libs-1.2.tar.gz#gunzip#utar:/README Lo bonito de este sistema es que si dos aplicaciones usan el mismo moniker, estarán compartiendo los mismos datos sin tener que ser descomprimido dos veces el mismo fichero tar. Todo esto se cosigue transparentemente. Esto sucedería en unas pocas instancias, por ejemplo, si estás explorando un fichero tar en el gestor de ficheros y te pasas a otra aplicación con "Disponibilidad Monikeriana", por caso, Gnumeric, Gnumeric estará usando el mismo fichero que fue abierto por el gestor de ficheros en lugar de tener dos ficheros descomprimidos en el sistema. El escenario visto arriba es particularmente útil si no dispones de mucho espacio o si el proceso de descompresión de un fichero toma mucho tiempo. 13.3. El moniker propertycache:. Acceder una y otra vez a las propiedades individuales puede requerir algún tiempo debido a los viajes de CORBA. El moniker propertycache: también sería un manejador de librería compartida que podría básicamente activar el moniker property y podría configurar los clientes de propiedades (que serían avisados de los cambios en la base de datos de las propiedades). Esto no está implementado, ya que conlleva que se escriba el moniker property. 14. La invención accidental. Los monikers fueron inventados en OLE2 para implementar el enlazado de objetos. Los programadores de OLE2 inventaron de forma accidental un sistema de nomenclatura de objetos. Este sistema de nomenclatura de objetos no es solo muy potente, sino que además es extensible y ayuda a dar una mayor consistencia al sistema. 15. Los Monikers y el GNOME VFS. Alguna gente pregunta: parece que los monikers solo fueran una reimplementación del GNOME-VFS, ¿por qué eso?. Para un fondo de almacenaje siempre puedes usar algo como bonobo_storage_new ("gnome-vfs") y seguir con tu vida. La mayor diferencia entre gnome-vfs y los monikers radica en que los monikers son utilizados para implementar un espacio de nombres basado en objetos, mientras que el gnome-vfs es una abstracción sutil para nombrar ficheros y directorios. El espacio moniker va mucho más allá de esto. Cuando Ettore, Nat y yo diseñamos el GNOME-VFS en Paris, Ettore tenía una visión superior a la que teníamos Nat y yo. Yo quería exactamente lo que el GNOME-VFS es: una implementación de sistema de ficheros virtual, añadible y asíncrona. Ettore quería algo más general, algo que podría implementar espacio de nomenclatura de objetos. Y algunas de las decisiones de diseño en el gnome-vfs reflejan algo de esa mentalidad, pero la API y la infraestructura estaba limitada al manejo de ficheros. Varios meses más tarde, finalmente comprendimos por completo el sistema de monikers y nos dimos cuenta de que los monikers eran un espacio de nomenclatura de objetos y que si se hacía correctamente, los monikers serían capaces de implementar la visión inicial de Ettore para tener un espacio de nombres basado en objetos. 16. Puntos inconclusos. Necesitaremos investigar los requerimientos de implementación para un parsing y una resolución de los monikers asíncronas. Actualmente, tanto el Framework de Actiaciòn de Objetos como Bonobo, soportan activación asíncrona. Implementando esto para los monikers no debería ser complicado, pero puede necesitar unos cambios en la interfaz Moniker. 17. Conclusión. Los monikers son mecanismos muy poderosos que pueden unificar el espacio de nomenclatura de objetos y pueden ser usados para proveer un método uniforme de acceso para una gran variedad de tareas: * Inicialización de componentes. * Asignación de direcciones de objetos. * Asignación de direcciones de sub-objetos en un documento compuesto. * Implementación de Enlazado de Objetos. * Implementación de objetos anidados y manejadores anidados para sistemas de ficheros. 18. Méritos y agradecimientos. La implementación del Bonobo moniker fue realizada por Michael Meeks. El diseño del sistema de monikers Bonobo fue hecha por Ettore Perazzoli, Michael Meeks y yo mismo. ________________________________________________________________________________________________ NOTA SOBRE LA TRADUCCIÓN * Esta es la primera (no revisada) traducción del documento original de Miguel de Icaza que se encuentra en: http://primates.ximian.com/~miguel/monikers.html Está disponible en versión ASCII (txt), PostScript, LaTeX, DVI y HTML. Se puede encontrar en www.gcubo.org. * Se cambiaron sobre la marcha los que se suponen que son errores al teclear en el texto original del autor. No cabe duda de que se habrán introducido otros nuevos. * Comparando con lo que aparece en el texto de Miguel, vemos ximian donde debería ser helixcode, ésto es una mera actualización del contenido pero no cambia nada de lo importante. Lo mismo se ha hecho con la dirección de correo del autor del texto original. Esta traducción viene sin ninguna garantía y es un documento libre cuya distribución sigue las normas de la GPL (para informarte sobre ellas acude a www.gnu.org.). ____________________________________________________________________________________________________________ Esta traducción está dedicada a toda la gente involucrada en la evolución del software libre. En especial a las personas y máquinas de los proyectos GNU (www.gnu.org), GNOME (www.gnome.org) y GNU/Linux Sin Fronteras (www.linuxsinfronteras.org). Un agradecimiento especial a Miguel, Michelle y a toda la gente de Ximian que tan desinteresadamente han querido colaborar con GCubo (www.gcubo.org). Gracias. Si tienes alguna duda, sugerencia o queja escríbeme a jaime@gcubo.org o ponte en contacto con Miguel. (C) 2001, Miguel de Icaza (Autor) (C) 2001, Jaime Anguiano Olarra (Traducción al castellano)