Création de rapprochements de porte-documents
Un rapprochement de porte-documents permet à Briefcase de rapprocher différentes versions d’un document.
- À propos des rapprochements de porte-documents
- Informations de référence sur le rapprochement de porte-documents
À propos des rapprochements de porte-documents
Un rapprochement de porte-documents combine différentes versions d’entrée d’un document pour produire une nouvelle version de sortie unique du document. Vous devrez peut-être créer un rapprochement de porte-documents pour prendre en charge votre type de document. Cette vue d’ensemble décrit les rapprochements de porte-documents et explique comment les créer.
Les rubriques suivantes sont présentées :
- Rapprochement
- Création d’un rapprochement de porte-documents
- Interaction utilisateur dans le rapprochement
- Réconciliation d’objets incorporés
- Résidus
Rapprochement
Un document est une collection d’informations qui peuvent être copiées et modifiées. Un document a des versions différentes si le contenu d’au moins deux copies du document est différent. Le rapprochement produit une version unique d’un document à partir de deux versions initiales ou plus. En règle générale, la version rapprochée est une combinaison d’informations provenant des versions initiales avec les informations les plus récentes ou les plus utiles conservées.
Le rapprochement est lancé par Briefcase lorsqu’il détermine que deux copies ou plus d’un même document sont différentes. Porte-documents, qui joue le rôle d’initiateur dans ce contexte, localise et démarre le rapprochement de porte-documents associé au type de document donné. Le rapprochement compare les documents et détermine les parties des documents à conserver. Certains rapprochements peuvent nécessiter une interaction utilisateur pour effectuer le rapprochement. D’autres peuvent effectuer le rapprochement sans intervention de l’utilisateur. Le rapprochement peut être contenu dans une application ou être une extension implémentée en tant que DLL.
Certains rapprochements de porte-documents peuvent créer des résidus. Un résidu est un document, ayant généralement le même type de fichier que le document initial, qui contient des informations non enregistrées dans la version fusionnée. Les résidus sont généralement utilisés pour donner aux auteurs un moyen rapide de déterminer quelles informations de leur document d’origine ne figurent pas dans la version fusionnée finale. Si un conciliateur prend en charge les résidus, il en crée un pour chacune des versions d’origine du document. Les résidus ne sont créés que si l’initiateur les demande.
Certains rapprochements de porte-documents fonctionnent avec Briefcase pour permettre à l’utilisateur d’arrêter le rapprochement. Il s’agit d’une fonctionnalité importante pour un utilisateur qui peut décider que le rapprochement ne doit pas se poursuivre. Un rapprochement fournit généralement un objet d’arrêt lorsque le rapprochement nécessite une interaction de l’utilisateur et peut être long. Dans certains environnements, un rapprochement peut autoriser un rapprochement partiel, ce qui permet à un utilisateur de suspendre temporairement un rapprochement et de le reprendre ultérieurement. Toutefois, le porte-documents ne prend pas en charge le rapprochement partiel.
Création d’un rapprochement de porte-documents
Vous créez un rapprochement de porte-documents en implémentant les interfaces de rapprochement. Au minimum, un conciliateur implémente l’interface IReconcilableObject et l’interface IPersistStorage ou IPersistFile . En tant qu’initiateur, Briefcase détermine quand le rapprochement est nécessaire et appelle la méthode IReconcilableObject::Reconcile pour lancer le rapprochement.
Bien que IReconcilableObject::Reconcile fournisse un large éventail de fonctionnalités de rapprochement, un rapprochement de porte-documents n’effectue que le rapprochement minimal dans la plupart des cas. En particulier, Briefcase n’a pas besoin du rapprochement pour prendre en charge la génération de résidus ou pour prendre en charge l’objet de terminaison. En outre, le conciliateur effectue un rapprochement de haut en bas unique et ne doit pas retourner la valeur REC_E_NOTCOMPLETE; c’est-à-dire qu’elle ne doit pas tenter de rapprochement partiel.
Le porte-documents fournit l’interface IReconcileInitiator . Le rapprochement de porte-documents peut utiliser la méthode IReconcileInitiator::SetAbortCallback pour définir l’objet d’arrêt. Le porte-documents n’utilise pas d’identificateurs de version et ne peut donc pas fournir les versions précédentes d’un document si un rapprochement les demande à l’aide des méthodes correspondantes dans IReconcileInitiator.
Le porte-documents passe aux monikers de fichier IReconcilableObject::Reconcile qui représentent les versions du document à rapprocher. Le rapprochement de porte-documents obtient l’accès aux versions à l’aide de la méthode IMoniker::BindToObject ou IMoniker::BindToStorage . Ce dernier est généralement plus rapide et est recommandé. Le rapprochement doit libérer tous les objets ou stockage auxquels il se lie.
Lorsque le rapprochement de porte-documents utilise IMoniker::BindToStorage, il est lié au stockage qui est un stockage plat (un flux) ou un stockage structuré défini par OLE. Si le rapprochement attend un stockage plat, il doit utiliser IMoniker::BindToStorage pour demander l’interface IStream . Si le rapprochement attend un stockage structuré, il doit demander l’interface IStorage . Dans les deux cas, il doit demander un accès direct en lecture seule (non traduit) au stockage ; L’accès en lecture/écriture peut ne pas être disponible.
Un rapprochement de porte-documents minimal examine généralement directement le stockage des autres versions et traite les objets incorporés de manière très primitive, comme la fusion de deux versions de l’objet en incluant les deux versions dans la version de sortie.
L’initiateur localise le rapprochement de porte-documents approprié à l’aide d’un sous-ensemble de la logique implémentée par la fonction GetClassFile pour déterminer le type d’un fichier donné, puis recherche dans le Registre la classe de rapprochement associée au type de fichier donné. Le porte-documents, comme d’autres composants de l’interpréteur de commandes, détermine le type d’un fichier uniquement par l’extension de nom de fichier. L’extension d’un fichier doit avoir un type de fichier inscrit pour que Briefcase appelle un rapprochement pour le fichier. Vous devez définir une entrée de Registre au format suivant lors de l’installation de votre rapprochement.
CLSID
{the file CLSID}
Roles
Reconciler
(Default) = {the reconciler-classid}
La classe doit être un chargement rapide, doit être désignée _MULTIPLEUSE et, sauf si des marshaleurs sont fournis pour l’interface de rapprochement, doit être un serveur in-process (contenu dans une DLL) plutôt qu’un serveur local (implémenté dans un fichier .exe).
Interaction utilisateur dans le rapprochement
Un rapprochement de porte-documents doit tenter d’effectuer le rapprochement sans intervention de l’utilisateur. Plus le rapprochement est automatisé, mieux l’utilisateur perçoit le processus.
Dans certains cas, l’intervention de l’utilisateur peut être utile. Par exemple, un système de documents peut demander à un utilisateur de passer en revue les modifications avant d’accepter la version fusionnée d’un document ou peut nécessiter des commentaires de l’utilisateur expliquant les modifications qui ont été apportées. Dans ce cas, l’initiateur, et non le rapprochement de porte-documents, est chargé d’interroger l’utilisateur et de suivre les instructions de l’utilisateur.
Dans d’autres cas, l’intervention de l’utilisateur peut être nécessaire, par exemple lorsque deux versions ont été modifiées de manière incompatible. Dans ce cas, l’initiateur ou le rapprochement de porte-documents doit interroger l’utilisateur pour obtenir des instructions sur la façon de résoudre le conflit. En général, aucun initiateur ne peut compter sur la réalisation d’un rapprochement sans attendre une interaction utilisateur. Les rapprochements, en revanche, ont la possibilité d’interagir avec l’utilisateur pour résoudre les conflits ou d’exiger de l’initiateur qu’il le fasse.
Réconciliation d’objets incorporés
Lors du rapprochement d’un document, le rapprochement de porte-documents lui-même peut devenir un initiateur s’il découvre un objet incorporé d’un type qu’il ne peut pas rapprocher. Dans ce cas, le conciliateur doit rapprocher de manière récursive chacun des objets incorporés et assumer toutes les responsabilités d’un initiateur.
Pour effectuer la récursivité, le rapprochement de porte-documents charge l’objet et interroge l’interface appropriée. Le gestionnaire de l’objet doit prendre en charge l’interface . Si une méthode de l’interface retourne la valeur OLE_E_NOTRUNNING, le rapprochement doit exécuter l’objet pour effectuer l’opération. Étant donné que le code pour les objets incorporés n’est pas toujours disponible, un rapprochement doit fournir une solution pour cette condition. Par exemple, le rapprochement peut inclure l’ancienne et la nouvelle version de l’objet incorporé dans la version rapprochée. Le conciliateur ne doit pas tenter de rapprocher entre les liens.
L’initiateur stocke les versions de document en cours de fusion. Dans de nombreux cas, l’initiateur a accès au stockage de chaque version et enregistre le résultat du rapprochement à l’aide d’un stockage similaire. Toutefois, l’initiateur peut parfois avoir un objet en mémoire pour lequel aucune version persistante n’est disponible. Cette situation peut se produire lorsqu’un document contenant des objets incorporés ouverts doit être rapproché avant d’être enregistré. Dans ce cas, l’initiateur enregistre le résultat du rapprochement dans la version trouvée en mémoire.
L’initiateur utilise l’interface IPersistStorage pour lier (charger) la version fusionnée. L’initiateur utilise la méthode IPersistStorage::Load si une version initiale a déjà été créée et utilise la méthode IPersistStorage::InitNew pour la version initiale. Lorsque la version fusionnée est chargée, l’initiateur utilise QueryInterface pour récupérer l’adresse de l’interface IReconcilableObject . Cette interface donne à l’initiateur un accès au stockage des résidus existants et lui permet de créer un stockage pour tous les nouveaux résidus. Ensuite, l’initiateur dirige l’interface pour effectuer le rapprochement. L’initiateur interroge en fait l’interface IPersistFile avant IPersistStorage. Si le réconciliateur prend en charge IPersistFile, l’initiateur manipule le réplica via les méthodes IPersistFile plutôt que les méthodes IPersistStorage. Cela permet de rapprochement des fichiers qui ne sont pas stockés en tant que documents composés.
Une fois le rapprochement terminé, l’initiateur peut enregistrer la version fusionnée à l’aide de l’interface IPersistStorage ou IPersistFile . Pendant le rapprochement, le réconciliateur de porte-documents crée des résidus en fonction des besoins et écrit leurs bits persistants dans le stockage. Si la version fusionnée est un flux, l’interface IStorage passée à IPersistStorage::Load contient un flux nommé « Contents » dont l’état de stockage est défini sur STATEBITS_FLAT. (Vous pouvez définir les bits d’état à l’aide de la méthode IStorage::Stat .) Après la fusion, l’initiateur enregistre la version fusionnée en écrivant les données de manière appropriée. Il doit s’assurer que STATEBITS_FLAT est défini comme approprié pour le stockage.
Résidus
L’initiateur indique s’il souhaite des résidus en définissant le paramètre pstgNewResidues sur une adresse valide lors de l’appel de la méthode IReconcilableObject::Reconcile . Si le réconciliateur ne prend pas en charge la création de résidus, il doit retourner immédiatement la valeur REC_E_NORESIDUES, sauf si le paramètre dwFlags spécifie la valeur RECONCILEF_NORESIDUESOK .
Le réconciliateur de porte-documents retourne les résidus à l’initiateur en créant de nouveaux éléments de stockage et en les copiant dans le tableau pointé par pstgNewResidues. Pour les résidus de stockage structurés, le rapprochement copie une interface IStorage et, pour les résidus de stockage plats, il copie une interface IStream ou IStorage avec l’indicateur de STATEBITS_FLAT défini. Le réconciliateur utilise IStorage pour créer le stockage nécessaire, en utilisant IStorage::CreateStream pour créer un stockage plat pour un résidu qui est un flux et IStorage::CreateStorage pour créer un stockage structuré.
L’initiateur prépare pstgNewResidues afin qu’il ne contienne aucun élément dans la partie non réservée de l’espace de noms IStorage . Le réconciliateur de porte-documents place chaque résidu dans un élément dont le nom correspond à l’ordre de sa version initiale. Par exemple, le premier résidu est contenu dans « 1 », le second dans « 2 », et ainsi de suite. Si l’objet réconcilié produit lui-même un résidu, il se trouve dans l’élément nommé « 0 ».
Le réconciliateur de porte-documents valide individuellement chacun des éléments nouvellement créés, en veillant à ce que l’initiateur ait accès aux informations. Toutefois, le réconciliateur ne valide pas pstgNewResidues lui-même. L’initiateur est responsable de la validation ou de l’élimination de celle-ci.
Informations de référence sur le réconciliateur de porte-documents
Cette section contient des informations sur les interfaces de rapprochement. Lors de la gestion des erreurs, une méthode peut retourner uniquement les valeurs d’erreur qui sont explicitement définies comme valeurs de retour possibles. En outre, la méthode doit définir toutes les variables dont les adresses sont passées en tant que paramètres sur NULL avant de retourner à partir de l’erreur.
Interfaces et méthodes du réconciliateur de porte-documents