Le principe de l'héritage est de mutualiser les ressources qui sont partagées par de multiples contextes ou entités. TIBCO EBX® propose des mécanismes pour définir, factoriser et résoudre les valeurs de données : héritage de jeu de données et champs hérités.
De plus, des fonctions peuvent être définies pour calculer des valeurs.
Les mécanismes d'héritage décrit dans ce chapitre ne doivent pas être confondus avec l'héritage structurel, lequel s'applique généralement aux modèles et est proposé dans des diagrammes de classes UML par exemple.
L'héritage de jeu de données est particulièrement utile quand les données s'appliquent à des contextes globaux d'entreprise, tels que filiales ou partenaires.
En se basant sur une hiérarchie de jeux de données, il est possible de factoriser les données communes au niveau de la racine ou des jeux de données intermédiaires et de définir des données spécialisées dans des contextes donnés.
Les mécanismes d'héritage du jeu de données sont détaillés ci-dessous dans Héritage de jeu de données.
Contrairement à l'héritage de jeu de données, qui utilise les relations globales entre jeux de données, les champs hérités utilisent des dépendances plus fines qui sont spécifiques à la structure des données. Cela permet de factoriser et de spécialiser les données au niveau des entités métier.
Par exemple, si le modèle précise qu'un "Produit" est associé à une "FamilleDeProduits", il est possible que certains attributs du "Produit" héritent leurs valeurs des attributs définis dans sa "FamilleDeProduits" associée.
Lors de l'utilisation des deux héritages sur un même jeu de données, l'héritage de champ est prioritaire sur celui du jeu de données.
Dans le modèle de données, il est aussi possible de définir qu'un noeud contient une valeur calculée. Dans ce cas, la fonction JavaBean spécifiée sera exécutée chaque fois que la valeur est requêtée.
La fonction peut prendre en compte le contexte courant, tel que les valeurs de l'enregistrement courant ou des calculs utilisant une autre table et envoyer des requêtes à des systèmes tiers.
Le mécanisme d'héritage du jeu de données est déclaré dans un modèle de données de la façon suivante :
xmlns:ebxbnd = "urn:ebx-schemas:binding_1.0" > < xs:annotation > < xs:appinfo > < osd:inheritance > < dataSetInheritance >all</ dataSetInheritance > </ osd:inheritance > </ xs:appinfo > </ xs:annotation > ... </ xs:schema > |
L'élément osd:inheritance
définit la propriété dataSetInheritance
qui permet d'activer ou non l'héritage pour les jeux de données utilisant ce modèle de données. Les valeurs suivantes peuvent être spécifiées :
all
, indique que l'héritage est activé pour tous les jeux de données qui instancient le modèle de données.
none
, indique que l'héritage est désactivé pour tous les jeux de données qui instancient le modèle de données.
Si rien n'est spécifié, le mécanisme d'héritage est désactivé.
Le mécanisme de résolution des valeurs héritées du jeu de données a le comportement suivant :
Si la valeur est définie localement, elle est retournée.
Elle peut être explicitement null
.
Sinon, la première valeur définie localement est recherchée en remontant la relation enfant-parent dans la hiérarchie des jeux de données.
Si aucune valeur définie n'est trouvée, la valeur par défaut est retournée.
Si aucune valeur par défaut n'est définie, null
est retourné.
Note : Les valeurs par défaut ne peuvent pas être définies sur :
Un noeud de clé primaire unique
Des noeuds auto-incrémentés
Des noeuds définissant une valeur calculée
Tout comme les valeurs, les enregistrements d'une table peuvent aussi être hérités en tant qu'unité par des contextes multiples, mais aussi être partiellement redéfinis (écrasé), définis pour un contexte spécifique (mode racine), ou être occultés.
Un enregistrement se définit suivant l'un des quatre modes de définition distincts :
enregistrement racine | Défini localement dans la table et n'a aucun parent. Cela signifie qu'aucun enregistrement ayant la même clé primaire n'existe dans la table parente, ou que ce parent est un enregistrement occulté. |
enregistrement surchargé | Défini localement dans la table et possède un enregistrement parent. Cela signifie qu'un enregistrement ayant la même clé primaire existe dans la table parente et que ce parent n'est pas un enregistrement occulté. Les valeurs de l'enregistrement surchargé sont héritées de son parent, sauf pour les valeurs qu'il redéfinit explicitement. |
enregistrement hérité | Non défini localement dans la table courante et possède un enregistrement parent. Toutes les valeurs sont héritées. Les fonctions sont toujours résolues dans le contexte de l'enregistrement courant et ne sont pas héritées. |
enregistrement occulté | Précise que si un parent ayant la même clé primaire est défini, ce parent ne sera pas visible dans les descendants de la table. |
Il est aussi possible de définir des règles de gestion dans la déclaration d'une table dans le modèle de données.
Le mécanisme d'héritage spécifique permet de récupérer la valeur d'un champ selon ses liens avec les autres tables.
L'héritage spécifique doit être défini sur les noeuds terminaux dans le modèle de données sous-jacent et est déclaré de cette façon :
< xs:element name = "sampleInheritance" type = "xs:string" > < xs:annotation > < xs:appinfo > < osd:inheritance > < sourceRecord > /root/table1/fkTable2, /root/table2/fkTable3 </ sourceRecord > < sourceNode >color</ sourceNode > </ osd:inheritance > </ xs:appinfo > </ xs:annotation > </ xs:element > |
L'élément sourceRecord
est une expression qui décrit comment retrouver l'enregistrement à partir duquel la valeur est héritée. Il s'agit d'une clé étrangère, ou d'une séquence de clés étrangères, de l'élément courant à la table source.
Si sourceRecord
n'est pas défini dans le modèle de données, les champs hérités sont récupérés à partir de l'enregistrement courant.
L'élément sourceNode
est le chemin du noeud à partir duquel hériter dans l'enregistrement source.
Les conditions suivantes doivent être remplies pour l'héritage spécifique :
L'élément sourceNode
est obligatoire.
L'expression du chemin de l'enregistrement source doit être un chemin de clés étrangères cohérent, à partir de l'élément courant vers l'enregistrement source. Cette expression doit impliquer uniquement des relations un-à-un et zéro-à-un.
Le sourceRecord
ne peut pas contenir d'éléments de liste agrégée.
Chaque élément du sourceRecord
doit être une clé étrangère.
Si le champ hérité est aussi une clé étrangère, le sourceRecord
ne peut pas faire référence à lui même pour obtenir le chemin vers l'enregistrement source de la valeur héritée.
Chaque élément du sourceRecord
doit exister.
Le noeud source doit appartenir à la table contenant l'enregistrement source.
Le noeud source doit être terminal.
Le noeud source doit être accessible en écriture.
Le type de noeud source doit être compatible avec le type de noeud courant.
Les cardinalités du noeud source doivent être compatibles avec celles du noeud courant.
Le noeud source ne peut être le même que celui du champ hérité si les champs desquels on hérite sont récupérés dans le même enregistrement.
Le mécanisme de résolution pour les valeurs de champs hérités a le comportement suivant :
Si la valeur est définie localement, elle est retournée.
Elle peut être explicitement null
.
Autrement, résolution de l'enregistrement source ainsi que la valeur à hériter, en fonction des propriétés définies dans le modèle de données.
Le processus est récursif ; si le noeud source ne définit pas de valeur localement, elle est alors résolue en accord avec le comportement d'héritage du noeud source.
EBX® offre un service IU intégré pour optimiser l'héritage des jeux de données dans la hiérarchie des jeux de données. Ce service permet les fonctions suivantes :
Gestion des valeurs en doublon : Détecte et supprime toutes les valeurs qui sont des doublons de la valeur héritée.
Mutualisation des valeurs communes : Détecte et mutualise les valeurs communes parmi les descendants du même ancêtre.
Les jeux de données sont traités de bas en haut, ce qui signifie que si le service est exécuté sur le jeu de données à un niveau N, avec N+1 étant le niveau de ses enfants et N+2 étant le niveau des petits-enfants, le service traitera d'abord les jeux de données au niveau N+2 afin de déterminer s'ils peuvent être optimisés par rapport aux jeux de données du niveau N+1. Ensuite, une optimisation du niveau N+1 sera exécutée par rapport au niveau N.
Ces fonctions d'optimisation et de refactoring ne gèrent pas les valeurs par défaut qui sont déclarées dans le modèle de données.
Le niveau le plus élevé pris en compte pendant la procédure d'optimisation est toujours le jeu de données sur lequel s'exécute le service. Cela signifie que l'optimisation et le refactoring ne sont pas réalisés entre le jeu de données cible et ses propres ancêtres.
L'optimisation de table est réalisée sur des enregistrements ayant la même clé primaire.
Les champs hérités ne sont pas optimisés.
Les fonctions d'optimisation et de refactoring ne modifient pas la vue résolue d'un jeu de données, si celle-ci est activée.
Le service 'Optimize & Refactor' est disponible sur les jeux de données qui ont des jeux de données enfants et dont la propriété 'Activée' est réglée sur 'Non' dans les informations du jeu de données.
Le service est disponible pour tout profil ayant des droits en écriture sur les valeurs du jeu de données courant. Il peut être désactivé en limitant les droits d'accès d'un profil.
Pour des raisons de performance, les droits d'accès ne sont pas vérifiés pour chaque noeud et enregistrement de table.