Para suministrar pleno soporte para modelos lógicos, un proveedor de repositorio puede realizar las siguientes tareas:
ResourceMapping
.ISynchronizationScope
y la API de soporte. IMergeContext
y la API de soporte. teamContentProviders
para los modelos
implicados en la fusión. Se suministra una clase ModelSynchronizeParticipant
que facilita la gestión de las relaciones entre el contenido del modelo, un contexto de
fusión y la infraestructura de comparación. IFileHistoryProvider
.ProjectSetCapability
. Subscriber
) de espacio de trabajo para utilizarlo con la API
SynchronizationStateTester
. Las secciones que siguen describen cada uno de estos puntos con mayor detalle. El plug-in org.eclipse.team.examples.filesystem contiene un ejemplo que ilustra varios de estos puntos. Puede reservar el proyecto en el repositorio CVS y utilizarlo como referencia durante la lectura de esta guía de aprendizaje. Declaración de limitación de responsabilidad: el código fuente de los plug-ins de ejemplo puede cambiar en el futuro. Para obtener una copia que coincida con la utilizada en este ejemplo, puede reservar el proyecto mediante el código de la versión 3.2 (probablemente R3_2) o el código de fecha correspondiente a 28 de Junio de 2006.
La API de correlación de recursos consta de las siguientes clases:
Object getModelObject()
: el objeto de modelo del que se ha derivado (o
adaptado) la correlación. ResourceTraversal[] getTraversals(ResourceMappingContext,
IProgressMonitor)
: el cruce de recursos que cubre los recursos que constituyen el
objeto de modelo. ResourceTraversal
contiene un conjunto de recursos y un distintivo
de profundidad que indica la profundidad a la que los recursos del cruce se asocian con
el objeto de modelo originador. Una correlación de recursos suministra los cruces de
recurso al cliente a fin de describir el contenido de un modelo de modo que el cliente
(por ejemplo, un proveedor de repositorio) pueda realizar sus operaciones con la mayor
eficacia posible. Los métodos de interés son los siguientes: getResources()
getDepth()
ResourceMappingContext
y
RemoteResourceMappingContext
es un poco más complicada y se describe en la sección
Contexto de correlación de recursos. Existen dos tipos de plugins a los que afectan las correlaciones de recursos. Son aquellos que suministran un modelo que consta de recursos del espacio de trabajo o se hace persistente en ellos, y aquellos que desean realizar operaciones sobre los recursos. El primer caso se describirá en el mapa de ruta de modelos, y el segundo se describe en la sección que sigue.
Los plug-ins que añaden extensiones a puntos de extensión adaptables deberán hacer dos
cambios para dar soporte a las nuevas API ResourceMapping
:
ResourceMapping
en lugar de a
IResource
(en aquellas para las que proceda). ResourceMapping
en lugar
de en IResource
y respetar las restricciones de profundidad indicadas en los
cruces. Los plug-ins que añaden contribuciones de objeto a IResource
pueden ahora
añadirlas a ResourceMapping
en su lugar, si la acción puede aplicarse a
varios recursos. A continuación figura un fragmento de código XML que añade una acción de
menú a los objetos que se adaptan a correlaciones de recursos:
<extension point="org.eclipse.ui.popupMenus"> <objectContribution objectClass="org.eclipse.core.resources.mapping.ResourceMapping" adaptable="true" id="org.eclipse.team.ccvs.ui.ResourceMapperContributions"> <enablement>
<adapt type="org.eclipse.core.resources.mapping.ResourceMapping">
<test
property="org.eclipse.core.resources.projectPersistentProperty"
args="org.eclipse.team.core.repository,org.eclipse.team.cvs.core.cvsnature" />
</adapt>
</enablement>
<action
label="%UpdateAction.label"
definitionId="org.eclipse.team.cvs.ui.update"
class="org.eclipse.team.internal.ccvs.ui.actions.UpdateAction"
tooltip="%UpdateAction.tooltip"
menubarPath="team.main/group2"
id="org.eclipse.team.cvs.ui.update">
</action>
...
</objectContribution>
</extension>
Las contribuciones a ResourceMapping
se aplicarán automáticamente a los
objetos que se adapten a IResource
. Esta asociación transitiva se maneja en
el entorno de trabajo. El filtrado de las contribuciones a las correlaciones de recursos
puede realizarse mediante expresiones de habilitación. Se ha añadido una expresión para
el filtrado por propiedad persistente de proyecto a fin de que los menús de los
proveedores de
repositorio aparezcan en los proyectos correlacionados con sus repositorios.
Las acciones que se hayan añadido a la clase ResourceMapping
recibirán
una selección que contiene una o varias ResourceMappings
.
Es responsabilidad de las acciones convertir la correlación de recursos en un conjunto de
recursos sobre los que pueda operarse. Esto puede realizarse llamando a
getTraversals
para obtener los cruces de la correlación. Los cruces
se utilizan para permitir a los clientes del cruce optimizar sus operaciones en función de
la profundidad de los recursos que se cruzan. Un cliente puede cruzar el recurso
manualmente o utilizar el recurso y la profundidad como entrada en una operación que la
acción delega para realizar el trabajo. Por ejemplo, si el usuario realiza una
actualización CVS en un paquete Java y la correlación de recursos del paquete Java se
correlaciona con una carpeta de profundidad uno, CVS emitirá un mandato adecuado ("cvs
update -l", para ser exactos) que realizará una actualización superficial en la
carpeta
representada por el paquete.
Aunque es posible obtener un conjunto de cruces directamente desde las correlaciones de recursos seleccionadas, existen relaciones de modelo (o relaciones de repositorio) que pueden requerir la inclusión de recursos o elementos de modelo adicionales en una operación. La sección que sigue describe cómo asegurarse de que se incluyen todos los recursos necesarios en una operación.
En operaciones de equipo, las correlaciones seleccionadas deben convertirse al conjunto de correlaciones sobre las que debe operarse. Este proceso implica consultar todos los proveedores de modelo para asegurarse de que se incluirán en las operaciones de los recursos que cumplan con sus normas de habilitación. El término utilizado para describir el conjunto completo de correlaciones de recursos sobre las que debe operarse es el ámbito de operación. Con este fin de suministra la API siguiente:
ISynchronizationScope
:
Interfaz que define la API destinada a acceder al ámbito de la operación. Proporciona
acceso a todas las correlaciones de recursos sobre las que se opera y a los cruces de
dichas correlaciones según se han calculado durante el proceso de construcción del
ámbito. ISynchronizationScopeManager
:
Interfaz que define la API destinada a crear y gestionar un ámbito.SynchronizationScopeManager
:
Clase ampliable que proporciona una implementación predeterminada de la API
ISynchronizationScopeManager
. ModelOperation
:
Clase de operación ampliable que genera un ámbito utilizando un gestor de ámbitos
suministrado y solicita si se han incluido recursos o correlaciones adicionales en la
operación debido a relaciones de proveedor de modelo. El método initialize(IProgressMonitor) de la clase SynchronizationScopeManager
maneja todo el proceso de conversión de un conjunto de correlaciones de recursos de
entrada en el conjunto completo de correlaciones sobre las que debe operarse, así como el
conjunto completo de cruces que cubren estas correlaciones. Un proveedor de repositorio
puede adaptar este proceso del siguiente modo:
RemoteResourceMappingContext
para utilizarlo al
obtener cruces de recursos desde las correlaciones de recursos.SynchronizationScopeManager
para adaptar el
proceso de gestión del ámbito según sea necesario. Las dos secciones que siguen describen estos puntos con mayor detalle.
Para garantizar que todos los recursos necesarios se incluyan en una operación de equipo, es posible que el proveedor de modelo necesite comprobar el estado de uno o varios recursos en el repositorio. Puede que en algunos modelos esto no sea necesario. Por ejemplo, un paquete Java es un contenedor visitado a una profundidad de uno, independientemente del estado remoto del modelo. Dada esta premisa, un proveedor de repositorio puede determinar fácilmente que deben incluirse supresiones de salida al comprometer o que deben incluirse adiciones de entrada al actualizar. Sin embargo, los recursos que constituyen algunos modelos lógicos pueden cambiar con el tiempo. Por ejemplo, los recursos que constituyen un elemento de modelo pueden depender del contenido de un archivo de manifiesto (o de algún otro mecanismo similar). Para que la correlación de recursos devuelva el cruce adecuado, debe acceder al contenido remoto del archivo de manifiesto (si es diferente del contenido local) a fin de comprobar si existen recursos adicionales que deban incluirse. Puede que estos recursos adicionales no existan en el espacio de trabajo, pero el proveedor de repositorio sabrá cómo asegurarse de que sí estaban allí cuando se ha realizado la acción seleccionada.
Para dar soporte a estos modelos más complejos, puede pasarse un
RemoteResourceMappingContext
al método
ResourceMapping#getTraversals
.
Si se suministra un contexto, la correlación puede utilizarlo para asegurarse de que
todos los recursos necesarios se incluyan en el cruce. Si no se suministra un contexto,
la correlación puede presuponer que sólo el estado local es de interés.
El contexto de correlación de recursos remoto proporciona tres consultas básicas:
La respuesta a la primera pregunta depende del tipo de operación que se esté realizando. Generalmente, las actualizaciones y fusiones son de tres sentidos, mientras que las comparaciones y operaciones de sustitución (como mínimo para CVS) son de dos sentidos.
La API de equipo de Eclipse incluye una clase Subscriber
que define una
API destinada a proporcionar el estado de sincronización entre la espacio de trabajo
local y un servidor remoto. Se suministra un
SubscriberResourceMappingContext
que utiliza una clase
Subscriber
para acceder al estado remoto necesario. Los clientes que tienen una clase Subscriber
no necesitan realizar tareas adicionales para obtener un contexto de correlación de
recursos.
Puede crearse una subclase de la clase SynchronizationScopeManager
para
adaptar la generación del ámbito y el proceso de gestión. Las dos razones principales
para la creación de una subclase del gestor de ámbitos son:
ISynchronizationScopeParticipant
define la API que los proveedores de modelo pueden utilizar para participar en el
proceso de gestión del ámbito. La clase
SubscriberScopeManager
class es una subclase basada en Subscriber
de
SynchronizationScopeManager
que implica a los participantes en el proceso
de gestión del ámbito. Los conjuntos de trabajo constituyen un ejemplo de la razón por la
que es necesario este tipo de proceso. Si un conjunto de trabajo es una de las
correlaciones de recursos de un ámbito, el conjunto de cruces cubierto por el ámbito
aumentará si se han añadido recursos al conjunto de trabajo. El tipo principal de operación de repositorio que requiere la participación del
modelo
es la fusión. En muchos casos, los modelos sólo necesitan participar a nivel de archivo. Para
ello se ha introducido la API IStorageMerger
, que permite a los proveedores
de modelo añadir fusionadores que deben utilizarse para fusionar archivos de una
extensión o tipo de contenido determinado. Sin embargo, en algunos casos los modelos
pueden necesitar contexto adicional para participar adecuadamente en una fusión. Con esta
finalidad, se han introducido las API IResourceMappingMerger
y IMergeContext
.
Las operaciones de fusión se siguen desencadenante mediante acciones asociadas con un proveedor de repositorio. Sin embargo, una vez que el usuario ha solicitado una operación de fusión, el proveedor de repositorio necesita implicar a los proveedores de modelo en el proceso de fusión para asegurarse de que la fusión no dañe el modelo de algún modo.
Existen dos partes principales de la API de proveedor de repositorio relacionadas con el soporte de fusión basada en modelo.
Un elemento importante de la fusión basada en modelo es la API utilizada para comunicar el estado de sincronización de los recursos implicados al proveedor de modelo. Para describir el estado de sincronización se utilizan las siguientes interfaces:
Para todas estas interfaces se suministran clases abstractas con el convenio de
que los nombres de clase deben coincidir con los nombres de interfaz, eliminando el
prefijo "I". La única clase que los proveedores de repositorio deben alterar
temporalmente es la clase ResourceDiff
, a fin de que pueden suministrarse
las revisiones anteriores y posteriores adecuadas de los archivos.
La interfaz IMergeContext amplía el contexto de sincronización con métodos adicionales que dan soporte a la fusión. Existen métodos de llamada de retorno para:
Se suministra una clase abstracta MergeContext que contiene implementaciones por omisión para gran parte del comportamiento de fusión y que también utiliza IStorageMerger para realizar fusiones de tres sentidos. También se suministra una clase SubscriberMergeContext que maneja el relleno y mantenimiento de la descripción de estado de sincronización asociada con el contexto de fusión.
Se suministra una clase de operación,
ModelMergeOperation,
que utiliza la API IResourceMappingMerger
para realizar una operación de
fusión basada en modelo. Las subclases deben alterar temporalmente el método
initializeContext(IProgressMonitor)
para devolver un contexto de fusión. La
operación utiliza este contexto para intentar una fusión autónoma basada en modelo. Si
existen conflictos, la vista previa de la fusión se deja a la
subclase. Como
veremos en la próxima sección, existe una
ModelParticipantMergeOperation
que proporciona prestaciones de vista previa mediante un
ModelSynchronizeParticipant.
El soporte para la visualización de modelos lógicos en una operación de equipo se
suministra mediante la infraestructura de Navegador común, nueva en Eclipse 3.2. Los
modelos lógicos pueden asociar una extensión de contenido con un proveedor de modelo
utilizando el punto de extensión org.eclipse.team.ui.teamContentProvider. Los
proveedores de equipo acceden a estos proveedores de contenido a través de ITeamContentProviderManager
.
Existen varias situaciones en las que un proveedor de equipo puede desear visualizar modelos lógicos:
ModelOperation
proporciona una solicitud que utiliza los
proveedores de contenido de equipo registrados para informar al usuario de una ampliación
del ámbito. ModelSynchronizeParticipant
ofrece integración en la vista Sincronizar o
en cualquier contenedor que pueda visualizar iSynchronizePages
.
El participante utiliza las prestaciones de participante de sincronización
preexistentes y las prestaciones de Navegador común para permitir que los proveedores de
equipo y los modelos adapten la barra de herramientas, el menú de contexto y otros
aspectos de la vista previa de fusión. ModelSynchronizeParticipant
suministra los siguientes elementos:
A continuación figura una lista de comprobación de los pasos necesarios para adaptar un participante de sincronización de modelo a un proveedor de equipo determinado:
ModelSynchronizeParticipant
ISynchronizePageConfiguration.P_VIEWER_ID
en el ID del
visor especificado en el paso anterior. MergeActionGroup
a fin de adaptar el aspecto de las
acciones relacionadas con la fusión. ModelParticipantMergeOperation
para manejar
la transición desde una fusión basada en modelo a una vista previa en un diálogo o en la
vista Sincronizar. Los siguientes fragmentos de código XML muestran cómo se registra la clase de participante CVS y cómo se define su visor.
<extension point="org.eclipse.team.ui.synchronizeParticipants"> <participant name="CVS" icon="$nl$/icons/full/eview16/cvs_persp.gif" class="org.eclipse.team.internal.ccvs.ui.mappings.WorkspaceModelParticipant" id="org.eclipse.team.cvs.ui.workspace-participant"> </participant> </extension> <extension point="org.eclipse.ui.navigator.viewer"> <viewer viewerId="org.eclipse.team.cvs.ui.workspaceSynchronization"> <popupMenu allowsPlatformContributions="false" id="org.eclipse.team.cvs.ui.workspaceSynchronizationMenu"> <insertionPoint name="file"/> <insertionPoint name="edit" separator="true"/> <insertionPoint name="synchronize"/> <insertionPoint name="navigate" separator="true"/> <insertionPoint name="update" separator="true"/> <insertionPoint name="commit" separator="false"/> <insertionPoint name="overrideActions" separator="true"/> <insertionPoint name="otherActions1" separator="true"/> <insertionPoint name="otherActions2" separator="true"/> <insertionPoint name="sort" separator="true"/> <insertionPoint name="additions" separator="true"/> <insertionPoint name="properties" separator="true"/> </popupMenu> </viewer> </extension>
Se ha añadido una API de historial de archivos que permite a los modelos acceder al historial de los archivos. La API de historial de archivos consta de las siguientes interfaces:
Junto con esta API, se ha añadido una vista genérica Historial de archivos. Esta permite a los proveedores de equipo visualizar su historial de archivos/recursos en una vista compartida y también permite a los modelos visualizar el historial de elementos de modelo para los elementos que no se correlacionan directamente con archivos. La vista Historial es una vista basada en páginas que obtiene una página para el elemento seleccionado del siguiente modo:
RepositoryProvider
asociado con el proyecto que contiene el recurso a un
IHistoryPageSource.
IHistoryPageSource
.Se han añadido métodos a
ProjectSetCapability
para dar soporte a la conversión entre una serie de referencia utilizada para identificar
una correlación entre un proyecto y contenido remoto y los URI que identifican un esquema
de sistema de archivos registrado con el punto de extensión
org.eclipse.core.filesystem.filesystems. Los
proveedores de equipo pueden opcionalmente suministrar soporte para esta característica a
fin de que los modelos lógicos puedan realizar examen remoto y carga de proyectos.
Los proveedores de equipo pueden decorar elementos de modelo convirtiendo sus decoradores ligeros para que funcionen en correlaciones de recursos, del mismo modo que se convierten contribuciones de objeto para que funcionen en correlaciones de recursos. Sin embargo, existe un aspecto de la decoración de elementos de modelo lógico que es problemático. Su un elemento de modelo no tiene una correlación de uno a uno con un recurso, puede que el elemento de modelo no reciba una actualización de etiqueta cuando cambie el recurso subyacente.
Para solucionar este problema, se ha introducido
ITeamStateProvider
a fin de que los proveedores de modelo tengan acceso a los cambios de estado que pueden
afectar a los decoraciones de equipo. Además, las vistas de modelo pueden utilizar
SynchronizationStateTester
para determinar cuándo deben actualizarse las etiquetas de elementos de modelo lógico.
Esta API se basa en la interfaz ITeamStateProvider
para determinar cuándo el
estado de equipo de un recurso ha cambiado y puede pasarse a un decorador de equipo como
parte de un
IDecorationContext
.