Créer un modèle de données personnalisé – partie I

Alfresco offre la possibilité d’étendre ses modèles de données pour correspondre à tous les besoin métier des utilisateurs. Concrètement, les modèles par défaut vous permettent de stocker dans Alfresco des dossiers, aussi appelés spaces et correspondant au modèle cm:folder, ainsi que des documents, appelés content et représentés par le modèle cm:content. Chacun dispose de ses propres propriétés (ou méta-données) comme le titre, la date de création ou le type de document pour les contenus.

Les propriétés peuvent être définies pour un modèle précis ou bien être regroupées dans un aspect. Un aspect peut être rattaché à n’importe quel type de données. L’avantage de ce système est qu’il simplifie la gestion des propriétés et évite les redondances. Alfresco fournit un jeu de modèles et d’aspects assez complet qui devrait vous permettre de travailler sur la plupart de vos données mais rien ne vous empêche d ‘étendre ces modèles ou de créer un modèle personnalisé de A à Z. Vous trouverez la définition de tous ces modèles dans le dossier /alfresco/WEB-INF/classes/alfresco/model.

Voyons en détails la déclaration du type cm:folder :

<type name="cm:folder">
	<title>Folder</title>
	<parent>cm:cmobject</parent>
	<archive>true</archive>
	<associations>
		<child-association name="cm:contains">
			<source>
				<mandatory>false</mandatory>
				<many>true</many>
			</source>
			<target>
				<class>sys:base</class>
				<mandatory>false</mandatory>
				<many>true</many>
			</target>
			<duplicate>false</duplicate>
			<propagateTimestamps>true</propagateTimestamps>
		</child-association>
	</associations>
</type>

Un modèle de données comprendre obligatoirement une propriété name. La propriété <title> correspond à ce qui sera affiché dans les différents wizards de l’interface web d’alfresco. L’attribut <parent> indique que le modèle cm:folder hérite du modèle cm:cmobject et donc de toutes ses propriétés, associations et contraintes.

Les associations permettent de lier deux noeuds entre eux, soit au même niveau, soit dans une relation parent/enfant. C’est le cas de la <child-association> qui permet concrètement à un folder de contenir tout type de contenu ayant hérité du type sys:base (autrement dit, tous les modèles). Ce type d’association peut aussi être utilisé pour définir par exemple un e-mail et ses pièces jointes ! L’attribut <many> définit si le noeud source peut contenir un ou plusieurs noeuds enfant. L’attribut <duplicate>, quant à lui, indique si deux noeuds enfants peuvent avoir le même nom. Comme son nom l’indique, <propagateTimestamps> modifie les dates de modification des noeuds parent/enfant lorsque l’un des deux est édité…

Voyons maintenant comment nous pouvons définir notre propre modèle.

1. la création du fichier xml

Pour définir notre modèle, commençons par créer un fichier xml que l’on nommera custom-model.xml (note: pensez à donner des noms plus explicites à vos modèles. Ce sera plus simple de les distinguer lorsque vous aurez plusieurs modèles à gérer !). Copiez le code suivant à l’intérieur :

<model name="custom:model" xmlns="http://www.alfresco.org/model/dictionary/1.0">

   <!-- import of alfresco model definitions -->
   <imports>
      <import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d" />
      <import uri="http://www.alfresco.org/model/content/1.0" prefix="cm" />
   </imports>

   <!-- definition of a namespace for our new custom model -->
   <namespaces>
      <namespace uri="http://www.alfresco.org/model/custom/mail/1.0" prefix="custom" />
   </namespaces>

   <types>
     <!-- put your model definition here -->
   </types>
</model>

On commence par la déclaration du nom du modèle puis on continue avec les imports des modèles alfresco qui nous serviront. Rappelez-vous que tout modèle doit être hériter au minimum de cm:cmobject pour pouvoir être utilisé dans Alfresco. Si vous voulez créer un nouveau type de contenu, vous pouvez vous baser sur  cm:content. Pour les dossiers, ce sera cm:folder. Le chois de l’uri vous revient entièrement. Vous pouvez écrire ce que vous voulez. Une bonne pratique consiste  à choisir un nom qui a du sens…

Maintenant, nous allons pouvoir entamer la description de notre modèle personnalisé :

<type name="custom:mail">
        <title>E-mail</title>
        <parent>cm:content</parent>
        <properties>
           <property name="custom:from">
              <type>d:text</type>
           </property>
           <property name="custom:to">
              <type>d:text</type>
              <multiple>true</multiple>
           </property>
        </properties>

		<associations>
			<child-association name="custom:attachment">
				<title>E-mail's attachment</title>
				<source>
					<mandatory>false</mandatory>
					<many>true</many>
				</source>
				<target>
					<class>cm:content</class>
					<mandatory>false</mandatory>
					<many>true</many>
				</target>
			</association>
		</associations>

        <mandatory-aspects>
           <aspect>cm:titled</aspect>
		   <aspect>custom:auditable</aspect>
        </mandatory-aspects>
     </type>

Nous voici donc avec un modèle représentant un e-mail et ses pièces jointes. Nous lui avons défini deux propriétés custom:from et custom:to de type d:text. custom:to peut contenir plusieurs chaines de caractère. Nous avons défini une association parent/enfant avec tout type de contenu grâce à cm:content (l’association est aussi valable pour les modèles héritant de cm:content !). Enfin, nous lui avons ajouté les aspects cm:titled (utilisable grâce à l’import du modèle cm:contentModel) et custom:auditable, que nous verrons juste après.

Notez que l’ordre est important dans la déclaration des éléments d’un modèle. D’abord le nom, la description (optionnelle) et l’héritage puis les propriétés, les associations et enfin les aspects ! Si vous ne respectez pas cet ordre, vous aurez des erreurs lors du chargement du modèle par Alfresco.

Voyons comment déclarer l’aspect custom:auditable :

<aspect name="custom:auditable">
         <title>Auditable</title>
         <properties>
            <property name="custom:created">
               <title>Created</title>
               <type>d:datetime</type>
               <mandatory enforced="true">true</mandatory>
			   <index enabled="true">
				  <atomic>true</atomic>
				  <stored>false</stored>
                  <tokenised>both</tokenised>
               </index>
            </property>
            <property name="custom:modified">
               <title>Modified</title>
               <type>d:datetime</type>
               <mandatory enforced="true">true</mandatory>
			   <index enabled="true">
				  <atomic>true</atomic>
				  <stored>false</stored>
                  <tokenised>both</tokenised>
               </index>
            </property>
         </properties>
      </aspect>

Notez que nous pouvons spécifier plusieurs attributs pour chaque propriété comme l’obligation de la remplir lors de la création d’un nouveau contenu ou bien si elle doit être indexée et de quelle façon elle doit l’être. Pour plusieurs d’informations, reportez-vous au wiki alfresco, section data dictionnary ! L’aspect custom:auditable est en fait une copie de l’aspect cm:auditable. Pourquoi créer une copie si l’aspect existe déjà me direz-vous? Eh bien c’est simple : par défaut, Alfresco utilise cet aspect pour stocker, entre autre, la date de création des documents que vous ajoutez au repository. Le problème, c’est qu’il définit cette donnée en se basant sur la date à laquelle vous ajoutez le document à Alfresco et non la date réelle de création du document. En ajoutant une copie de cet aspect à vos modèles de données, vous pourrez fournir les dates réelles de création et de modification de vos documents puis les afficher à la place de l’aspect cm:auditable ^^.

Rappelez-vous que la bonne pratique consiste à ne jamais modifier les modèles d’origine d’alfresco ! Il est préférable de les copier en utilisant vos propres modèles. Vous aurez ainsi un contrôle parfait de votre modèle et ca vous évitera des problèmes lors de mises à jour d’Alfresco.

Voici le modèle dans son intégralité :

<model name="custom:model" xmlns="http://www.alfresco.org/model/dictionary/1.0">

   <!-- import of alfresco model definitions -->
   <imports>
      <import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d" />
      <import uri="http://www.alfresco.org/model/content/1.0" prefix="cm" />
   </imports>

   <!-- definition of a namespace for our new custom model -->
   <namespaces>
      <namespace uri="http://www.alfresco.org/model/custom/mail/1.0" prefix="custom" />
   </namespaces>

   <types>
     <type name="custom:mail">
        <title>E-mail</title>
        <parent>cm:content</parent>
        <properties>
           <property name="custom:from">
              <type>d:text</type>
           </property>
           <property name="custom:to">
              <type>d:text</type>
              <multiple>true</multiple>
           </property>
        </properties>

		<associations>
			<child-association name="custom:attachment">
				<title>E-mail's attachment</title>
				<source>
					<mandatory>false</mandatory>
					<many>true</many>
				</source>
				<target>
					<class>cm:content</class>
					<mandatory>false</mandatory>
					<many>true</many>
				</target>
			</association>
		</associations>

        <mandatory-aspects>
           <aspect>cm:titled</aspect>
		   <aspect>custom:auditable</aspect>
        </mandatory-aspects>
     </type>
   </types>

   <aspect name="custom:auditable">
         <title>Auditable</title>
         <properties>
            <property name="custom:created">
               <title>Created</title>
               <type>d:datetime</type>
               <mandatory enforced="true">true</mandatory>
			   <index enabled="true">
				  <atomic>true</atomic>
				  <stored>false</stored>
                  <tokenised>both</tokenised>
               </index>
            </property>
            <property name="custom:modified">
               <title>Modified</title>
               <type>d:datetime</type>
               <mandatory enforced="true">true</mandatory>
			   <index enabled="true">
				  <atomic>true</atomic>
				  <stored>false</stored>
                  <tokenised>both</tokenised>
               </index>
            </property>
         </properties>
      </aspect>
</model>

Nous verrons dans une prochaine partie comment utiliser notre custom model dans le web client Alfresco : )

5 Comments

      1. bonjour, merci bcp pr ce tuto, je travaille en ce moment sur Alfresco et dans le cadre de la deuxième partie, j’aimerai tout de même savoir comment intégrer mon fichier XML de façon à ce qu’il soit reconnu et considéré par alfresco comme extension de méta-données, si vous avez toute fois des sites à me proposer!! je prend!! merci encore

        Répondre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *