Author: tchemit Date: 2009-04-20 14:15:30 +0000 (Mon, 20 Apr 2009) New Revision: 1431 Added: topia/trunk/src/site/rst/ topia/trunk/src/site/rst/index.rst topia/trunk/topia-persistence/src/site/rst/ topia/trunk/topia-persistence/src/site/rst/Devel.rst topia/trunk/topia-persistence/src/site/rst/FAQ.rst topia/trunk/topia-persistence/src/site/rst/HibernateMapping.rst topia/trunk/topia-persistence/src/site/rst/Isolation.rst topia/trunk/topia-persistence/src/site/rst/ModelGeneration.rst topia/trunk/topia-persistence/src/site/rst/SchemaMigration.rst topia/trunk/topia-persistence/src/site/rst/Todo.rst topia/trunk/topia-persistence/src/site/rst/TopiaDocumentation.rst topia/trunk/topia-persistence/src/site/rst/event.rst topia/trunk/topia-persistence/src/site/rst/howto.rst topia/trunk/topia-persistence/src/site/rst/index.rst topia/trunk/topia-persistence/src/site/rst/project.rst topia/trunk/topia-persistence/src/site/rst/security.rst topia/trunk/topia-soa/src/site/rst/ topia/trunk/topia-soa/src/site/rst/ApplicationServiceGeneration.rst topia/trunk/topia-soa/src/site/rst/ApplicationServiceUsing.rst topia/trunk/topia-soa/src/site/rst/index.rst topia/trunk/topia-ui/src/site/rst/ topia/trunk/topia-ui/src/site/rst/UseCase.rst topia/trunk/topia-ui/src/site/rst/index.rst Modified: topia/trunk/changelog.txt topia/trunk/pom.xml topia/trunk/src/site/site.xml Log: bump versions use doxia-mudle-jrst instead of maven-jrst-plugin Modified: topia/trunk/changelog.txt =================================================================== --- topia/trunk/changelog.txt 2009-04-20 14:15:27 UTC (rev 1430) +++ topia/trunk/changelog.txt 2009-04-20 14:15:30 UTC (rev 1431) @@ -1,3 +1,7 @@ +2.1.5 chemit 20090420 + * use lutinproject 3.5.3, doxia-module-jrst 1.0.0, maven-license-switcher 0.7, xom 1.1 + * fix site (reports has disappeared) + 2.1.3 chemit 20090220 * 20090126 [chemit] - refactor poms (all dependencies in parent-pom dependencyManagment) * 20090129 [chemit] - use lutinproject 3.4 Modified: topia/trunk/pom.xml =================================================================== --- topia/trunk/pom.xml 2009-04-20 14:15:27 UTC (rev 1430) +++ topia/trunk/pom.xml 2009-04-20 14:15:30 UTC (rev 1431) @@ -9,7 +9,7 @@ <parent> <groupId>org.codelutin</groupId> <artifactId>lutinproject</artifactId> - <version>3.4</version> + <version>3.5.3</version> </parent> <artifactId>topia</artifactId> @@ -80,8 +80,12 @@ <version>1.5.3</version> <scope>compile</scope> </dependency> - <dependency> + <groupId>xom</groupId> + <artifactId>xom</artifactId> + <version>1.1</version> + </dependency> + <dependency> <groupId>org.codehaus.xfire</groupId> <artifactId>xfire-java5</artifactId> <version>1.2.6</version> @@ -128,7 +132,7 @@ <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> - <version>1.1.110</version> + <version>1.1.111</version> <scope>test</scope> </dependency> @@ -166,13 +170,12 @@ <!-- libs version --> <generator.version>0.64</generator.version> <processor.version>0.17</processor.version> - <lutinutil.version>1.0.4</lutinutil.version> - <jrst.version>0.8.4</jrst.version> - <license-switcher.version>0.6</license-switcher.version> + <lutinutil.version>1.0.4</lutinutil.version> + <license-switcher.version>0.7</license-switcher.version> <topia.version>${project.version}</topia.version> <xmlrpc.version>3.1</xmlrpc.version> - <hibernate.version>3.3.1.GA</hibernate.version> + <hibernate.version>3.3.1.GA</hibernate.version> </properties> <build> @@ -220,26 +223,41 @@ </configuration> </plugin> + <plugin> + <artifactId>maven-site-plugin</artifactId> + <configuration> + <locales>fr</locales> + <siteDirectory>src/site</siteDirectory> + </configuration> + <dependencies> + <dependency> + <groupId>org.codelutin</groupId> + <artifactId>doxia-module-jrst</artifactId> + <version>1.0.0</version> + </dependency> + </dependencies> + </plugin> + </plugins> </pluginManagement> <plugins> <!-- Always process jrst files, but only called on pre-site phase --> - <plugin> + <!--plugin> <groupId>org.codelutin</groupId> <artifactId>maven-jrst-plugin</artifactId> <version>${jrst.version}</version> - <configuration> - <defaultLocale>fr</defaultLocale> + <configuration> + <defaultLocale>fr</defaultLocale> </configuration> <executions> - <execution> + <execution> <goals> <goal>jrst</goal> </goals> </execution> </executions> - </plugin> + </plugin--> </plugins> </build> Copied: topia/trunk/src/site/rst/index.rst (from rev 1429, topia/trunk/src/site/fr/rst/index.rst) =================================================================== --- topia/trunk/src/site/rst/index.rst (rev 0) +++ topia/trunk/src/site/rst/index.rst 2009-04-20 14:15:30 UTC (rev 1431) @@ -0,0 +1,21 @@ +Accueil +======= + +Présentation +------------ + +ToPIA, pour Tools for Portable and Independant Architecture, est un framework +d'abstraction des plateformes techniques. + +Constitution +------------ + +Il est actuellement composé de 3 modules : + + * `ToPIA-persistence`_ : pour la gestion de la persistance sur hibernate + * `ToPIA-soa`_ : pour le développement orienté service + * `ToPIA-ui`_ : pour la génération des interfaces + +.. _ToPIA-persistence: topia-persistence +.. _ToPIA-soa: topia-soa +.. _ToPIA-ui: topia-ui \ No newline at end of file Property changes on: topia/trunk/src/site/rst/index.rst ___________________________________________________________________ Name: svn:executable + * Name: svn:mergeinfo + Modified: topia/trunk/src/site/site.xml =================================================================== --- topia/trunk/src/site/site.xml 2009-04-20 14:15:27 UTC (rev 1430) +++ topia/trunk/src/site/site.xml 2009-04-20 14:15:30 UTC (rev 1431) @@ -33,11 +33,9 @@ <item name="Code Lutin" href="http://www.codelutin.com/"/> </links> - <menu name="Modules"> - <item name="ToPIA-persistence" href="topia-persistence"/> - <item name="ToPIA-soa" href="topia-soa"/> - <item name="ToPIA-ui" href="topia-ui"/> - </menu> + <menu ref="modules"/> + <menu ref="reports"/> + </body> </project> Copied: topia/trunk/topia-persistence/src/site/rst/Devel.rst (from rev 1429, topia/trunk/topia-persistence/src/site/fr/rst/Devel.rst) =================================================================== --- topia/trunk/topia-persistence/src/site/rst/Devel.rst (rev 0) +++ topia/trunk/topia-persistence/src/site/rst/Devel.rst 2009-04-20 14:15:30 UTC (rev 1431) @@ -0,0 +1,184 @@ +TopiaContextFactory +=================== + +Le topia context est créé en faisant la demande sur le *TopiaContextFactory*. +On peut passer en paramètre au *TopiaContextFactory* un object *Property* qui +permet de configurer le context. Si aucun fichier est passé en paramètre, un fichier de +propriété **TopiaContextImpl.properties** est recherché dans le classpath. + +Fichier de configuration +======================== + +Le fichier de configuration est un fichier lisible par un objet *Property*. +Il contient différentes informations : +- liste des entités à gérer +- type de DAO à utiliser +- option de connexion à la base de données +- les services à activer + +Liste des entités à gérer +------------------------- + +Il est possible de définir les entités soit directement en indiquant un +répertoire contenant les mappings hibernate:: + + topia.persistence.directories=<path> + +soit en indiquant une liste de classe séparé par des virgule:: + + topia.persistence.classes=<list de classe> + +Le mieux est d'utiliser la liste de classe qui est non spécifique à une +persistence ou à une plateforme. + +Type de DAO à utiliser +---------------------- + +Par défaut si cette option n'est pas spécifiée, les entités sont gérées par +hibernate. On peut préciser d'utiliser le même type de DAO pour toutes les +entités en une seule fois avec:: + + topia.dao.default.class=<DAO class name> + +On peut aussi préciser un DAO spécifique pour une entité particulière:: + + topia.dao.<fully qualified class name>=<DAO class name> + +Pour simplifer un peu l'écriture, deux alias de DAO on été fait: + +- **hibernate** est remplacé par *org.codelutin.topia.persistence.hibernate.TopiaDAOHibernate* +- **flatfile** est remplacé par *org.codelutin.topia.persistence.flatfile.TopiaDAOFlatFile* + +La plupart du temps, on ne spécifie, dans ces options, que le DAO de base (hibernate, flatfile, ...) et non pas un DAO spécifique pour l'entité qui aurait des méthodes de recherche supplémentaire. Ceci car la méthode **getDao** du *TopiaContext* encapsule automatiquement ce DAO générique par un DAO spécifique si celui-ci est trouvé. Le DAO spécifique doit avoir exactement +le même nom que l'entité avec DAO à la fin. +Si vous souhaitez implanter ce genre de DAO spécifique, il devra étendre la classe *TopiaDAODelegator*. + +Option de connexion à la base de données +---------------------------------------- + +Flatfile +~~~~~~~~ + +La seule option à renseigner est le répertoire ou les entités doivent être +sauvées:: + + topia.dao.flatfile.directory=<path> + +Hibernate +~~~~~~~~~ + +Les options pour hibernate peuvent être directement dans le fichier de configuration principal ou dans un fichier de configuration secondaire. Dans ce cas il faut indiquer dans le fichier de configuration principal le chemin de ce fichier:: + + topia.persistence.properties.file=<filesystem or classpath path> + +Les options hibernates sont les options hibernate classique : + +- hibernate.connection.username +- hibernate.connection.password +- hibernate.dialect +- hibernate.connection.driver_class +- hibernate.connection.url + +Les services à activer +---------------------- + +Il est possible d'indiquer les services à activer grâce aux options:: + + topia.service.<service name>=<class> + topia.service.security=org.codelutin.topia.security.TopiaSecurityServiceImpl + topia.service.index=org.codelutin.topia.index.LuceneIndexer + topia.service.history=org.codelutin.topia.history.TopiaHistoryServiceImpl + +<service name> doit correspondre au nom de service que <class> retourne, sinon il est désactivé. + +Les services disponibles actuellement sont: + +- Service d'indexation full text +- Service d'historisation des modifications des entités +- Service de sécurité +- Service d'upgrade automatique des données hibernates + +TopiaContext +============ + +Le *TopiaContext* permet de récupérer les services, d'ouvrir des transactions +en récupérant des nouveaux *TopiaContext* fils, de s'enregistrer en tant que +listener pour recevoir les notifications de modification sur les entités. + +Sur les *TopiaContext* fils, on peut récupérer des DAO qui permettent de +créer, modifier, rechercher les entités. + +DAO +=== + +Il est possible d'avoir plusieurs types de persistance en même temps pour un +*TopiaContext*, mais pour un même type d'entité, il ne peut y avoir qu'un +seul type de persistence en même temps. + +Par défaut il existe deux type de persistence: + +- hibernate +- flatfile + +Il est possible d'ajouter d'autres types de persistence en implantant +*TopiaDAOAbstract*. + +Il est possible de faire un DAO spécial pour un type d'entité, par exemple +pour ajouter de nouvelle méthode de recherche. Pour cela il ne faut pas +étendre *TopiaDAOHibernate* ou *TopiaDAOFlatFile* qui rendrait spécifique à +une persistance votre DAO qui n'ajoute que de nouvelle méthode de recheche +mais étendre *TopiaDAODelegator* qui utilise un modèle de délégation sur le +bon type de persistance. Le bon type de persistence est automatiquement +injecté par le *TopiaContext* lors de la récupération du DAO. + +Ce DAO spécifique à une entité doit avoir le même nom que l'entity mais se +finir par DAO. Dans ce cas le *TopiaContext* le détecte automatiquement et +l'utilise au lieu du DAO générique hibernate ou flatfile. + +Pour la configuration des DAO voir la section fichier de configuration. + +Entité +====== + +Normalement **Topia** est fait pour pouvoir générer n'importe quel type de POJO +et les rendre persistants. Mais il est plus simple d'utiliser la génération +de code fournit avec **Topia** pour générer les entités à partir d'un +diagramme UML. Dans ce cas toutes les entités héritent de *TopiaEntity* qui +contient des méthodes pour s'enregistrer sur les modifications des attributs +ou pouvoir lever un droit de veto sur une modification. Sont aussi +disponible les méthodes: + +- getTopiaId +- getTopiaVersion +- getTopiaCreationDate +- getTopiaContext +- getComposite: Retourne tous les objets qui seront effacé si cet objet est effacé +- getAggregate: Retourne les objets en lien avec celui-ci + +Lorsque l'on utilise la génération on peut implanter une classe qui hérite +du *Abstract* généré et qui se finisse par Impl. Par exemple si dans notre +modèle nous avons la classe *Toto* il sera généré une interface *Toto* et +une classe abstraite *TotoAbstract*, il faudra alors implanter *TotoImpl*:: + + extends TotoAbstract extends TopiaEntityAbstract implements Toto + extends TopiaEntityAbstract implements *TopiaEntity + +Cette classe impl permet d'ajouter des méthodes métiers à l'entité ou des +méthode d'accès différent sur les attributs. + +TopiaService +============ + +Pour implanter un TopiaService il faut absolument créer une interface qui +hériter de l'interface *TopiaService* et mettre dans cette interface un +attribut static qui définit le nom du service:: + + public static final String SERVICE_NAME = "monservice"; + +Un service peut avoir besoin de nouvelles entités pour fonctionner. Pour cela +il faut retourner la liste des entités grâce à la méthode +**getPersistenceClasses**. + +Après instanciation du service par le **TopiaContext** celui-ci est +initialisé grâce à la méthode **init(TopiaContextImplementor)**. Il peut +alors se mettre listener sur le context ou les DAO par exemple. Property changes on: topia/trunk/topia-persistence/src/site/rst/Devel.rst ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:mergeinfo + Name: svn:eol-style + native Copied: topia/trunk/topia-persistence/src/site/rst/FAQ.rst (from rev 1429, topia/trunk/topia-persistence/src/site/fr/rst/FAQ.rst) =================================================================== --- topia/trunk/topia-persistence/src/site/rst/FAQ.rst (rev 0) +++ topia/trunk/topia-persistence/src/site/rst/FAQ.rst 2009-04-20 14:15:30 UTC (rev 1431) @@ -0,0 +1,18 @@ +Problème lors du chargement d'une entity +======================================== + +Le chargement utilise les méthodes Set des propriétés, il faut donc faire +attention si on les surcharge. + +Il faut faire attention lors de l'ajout, sur l'entity, de méthodes qui ont la +même signature que des méthods Set de propriétés avec juste des arguments +différents, car elles peuvent être utilisées à la place de la vrai méthode +pour quelque valeur (par exemple null). + +Faire fonctionner les Web Services Topia via RMI +================================================ +L'utilisation des Web Services sur RMI impose la génération de classes sauvées +sur disque. +Elle sont construites à la volée et sauvées dans le dossier "./topiagen". + +Ce dossier doit donc se trouver dans le classpath. Property changes on: topia/trunk/topia-persistence/src/site/rst/FAQ.rst ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:mergeinfo + Name: svn:eol-style + native Copied: topia/trunk/topia-persistence/src/site/rst/HibernateMapping.rst (from rev 1429, topia/trunk/topia-persistence/src/site/fr/rst/HibernateMapping.rst) =================================================================== --- topia/trunk/topia-persistence/src/site/rst/HibernateMapping.rst (rev 0) +++ topia/trunk/topia-persistence/src/site/rst/HibernateMapping.rst 2009-04-20 14:15:30 UTC (rev 1431) @@ -0,0 +1,96 @@ +================= +Mapping hibernate +================= + +Ce document décrit les choix de mapping faits en fonction +du diagramme de classe UML. + +JDBC +==== + +Généralité +---------- + +- Tous les objets utilisent le versionnement dans un champs version:: + + <version name="topiaVersion" type="long" node="@topiaVersion"/> + +- On utilise les méthodes d'accès pour accêder aux propriétés + +Héritage +-------- + +- Seules les classes concrêtes ont un mapping (au travers de l'interface + impl) +- Chaque classe à un fichier de mapping séparé. + +On utilisera union-subclass + +Identifiant +----------- + +Lors de la description de la classe, on peut indiquer de ne pas générer de clé +technique. Dans ce cas, la clé métier est utilisée (tagvalue: technicalKey=false). +Par défaut une clé technique est utilisée et est de la forme uuid.hex:: + + <id name="topiaId" column="topiaId" type="string"> + <generator class="uuid.hex"/> + </id> + +La description de la clé métier est faite par un tagvalue sur la classe +(tagvalue: key=prop1,prop2,prop3). Si une clé technique est utilisée, une +contrainte d'unicité est tout de même faite sur la clé métier. + +La clé métier sert aussi pour le toString, equals, hashCode. + +Si l'id d'une entité est composé de plusieurs champs, ces champs doivent-être +rassemblés dans une classe indépendante de l'entité. Par contre le mapping +assemble l'entity et son id dans la même table:: + + <composite-id name="#field" class="#class"> + <key-property name="#field1" column="#col1"/> + <key-property name="#field2" column="#col2"/> + <key-property name="#field3" column="#col3"/> + </composite> + +Si l'id est un objet simple il peut être directement mis dans l'entité. + +Relation 1-0 +------------ + + + +Relation 1-1 +------------ + +Relation 0-N +------------ + +Relation 1-N +------------ + +Relation N-N +------------ + +Classe d'association +-------------------- + +Composition +----------- + +Le composant peut changer de propriétaire (set méthode) mais le +propriétaire perd en même temps le lien vers son composé. + +Aggregation +----------- + +Si une classe est aggrégée avec une autre, alors elle suit la vie de l'entité +à laquelle elle est aggrégée (cascade delete, update) + +Elle ne peut pas être affectée a une autre entité. Pas de set sur cette classe +vers l'autre classe. + +XML +=== + +Toutes les propriétés sont des éléments sauf la clé technique qui est un +attribut. Property changes on: topia/trunk/topia-persistence/src/site/rst/HibernateMapping.rst ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:mergeinfo + Name: svn:eol-style + native Copied: topia/trunk/topia-persistence/src/site/rst/Isolation.rst (from rev 1429, topia/trunk/topia-persistence/src/site/fr/rst/Isolation.rst) =================================================================== --- topia/trunk/topia-persistence/src/site/rst/Isolation.rst (rev 0) +++ topia/trunk/topia-persistence/src/site/rst/Isolation.rst 2009-04-20 14:15:30 UTC (rev 1431) @@ -0,0 +1,67 @@ +=========================== +Isolation des TopiaContexts +=========================== + +Remarque: les requètes ne sont pas bonnes, mais sont là pour donner l'idée +générale. + +Pour mettre en place l'isolation entre les différents TopiaContexts créés par +beginTransaction, il faut ajouter un nouvelle propriété sur les +TopiaEntity: TopiaContextId. Cette propriété prend la valeur de l'id du +TopiaContext qui a créé ou chargé l'objet. On voit donc que plusieurs objets +ayant le même id peuvent exister, le TopiaContextId doit donc faire partie +de la clé de l'objet. Il faut aussi ajouter un champs TopiaDeleted pour +savoir si un objet a été effacé ou non. + +Dans le mapping hibernate pour chaque class d'entité, on a un filtre: +where TopiaContextId == :id || (TopiaContextId > 0 && TopiaContextId <= :id) + +Ce filtre n'est pas suffisant car on a toutes les versions commités de +l'objet jusqu'a :id, il faut un autre filtre apres les recherches pour +n'avoir que les dernieres versions des entites et supprimer dans ce groupe +les entitées marquées et effacées. +where TopiaContextId = max(TopiaContextId) && isDeleted=false group by topiaId + +Lors d'un beginTransaction le nouveau TopiaContext active ce filtre pour son +propre id. + +De cette manière un TopiaContext ne voit que les objets qu'il a créé et/ou +modifié, ou les objets plus ancien que lui. + +Cet Id est: - System.nanoTime() et donc toujours négatif. + +Lors d'un commit d'un TopiaContext, on passe tous les TopiaContextId de +toutes les entités qui sont égales a l'id du TopiaContext en sa version +positive: update <table> set TopiaContextId = -:id where TopiaContextId = :id +De plus le TopiaContext renouvelle son id et modifie tous les filtres pour +qu'il aie la vision d'objets créés par d'autre TopiaContext avant son commit. + +Lors d'un rollback il suffit de faire le renouvellement de l'id et la mise à +jour des filtres. + +Sous-transaction +================ + +La gestion des TopiaContextId pourrait offrir les sous-transactions, si +dans le filtre on ajoutait comme condition, au lieu de TopiaContextId == :id, +TopiaContextId in (:idList) ou idList serait la liste des ids du +TopiaContext courant ainsi que des TopiaContext parents. + +Historisation +============= + +La gestion des TopiaContextId permet d'offrir l'historisation de tous les +objets. Car tous les objets commités sont conservés avec un TopiaContextId +différent pour chaque version. + +Implantation +============ + +- Mettre en place les champs supplémentaires: TopiaContextId, TopiaDeleted +- Modifier la clé primaire pour ajouter TopiaContextId +- Ajouter les filtres dans les mappings +- Ajouter un id sur les TopiaContext +- Modifier le comportement de DAO.delete pour qu'il marque juste l'objet + comme effacé sans l'effacer TopiaDeleted=true +- Pour toutes les recherches ajouter un filtre pour ne retourner que les + derniere version non deleted Property changes on: topia/trunk/topia-persistence/src/site/rst/Isolation.rst ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:mergeinfo + Name: svn:eol-style + native Copied: topia/trunk/topia-persistence/src/site/rst/ModelGeneration.rst (from rev 1429, topia/trunk/topia-persistence/src/site/fr/rst/ModelGeneration.rst) =================================================================== --- topia/trunk/topia-persistence/src/site/rst/ModelGeneration.rst (rev 0) +++ topia/trunk/topia-persistence/src/site/rst/ModelGeneration.rst 2009-04-20 14:15:30 UTC (rev 1431) @@ -0,0 +1,84 @@ +Génération des modèles +---------------------- + +Le module "topia-persistence" de topia est capable de +générer la persistence à partir d'un modèle UML. + +Nous allons détailler ici comme inclure la génération dans le +cycle de compilation maven. + + +Architecture maven +------------------ + ++---------------------------------+-----------------------------------------+ +| src/main/xmi/mymodel.zargo | exemple de modele UML avec argoUML | ++---------------------------------+-----------------------------------------+ +| src/main/xmi/mymodel.properties | fichier de propriétés attaché au modele | ++---------------------------------|-----------------------------------------+ + + +Configuration du pom.xml +------------------------ + +Pour générer les sources dans la phase "generate-source" de maven, et utiliser +les sources générées, et faut configurer le pom. + +Plugin lutingenerator +===================== + +:: + +<plugin> + <groupId>org.codelutin</groupId> + <artifactId>maven-generator-plugin</artifactId> + <!-- la version peut être plus récente --> + <version>0.62</version> + <executions> + <execution> + <id>Generator</id> + <phase>generate-sources</phase> + <configuration> + <srcDirUml>src/main/xmi</srcDirUml> + <srcXmiDest>target/generated-sources/xmi/</srcXmiDest> + <fullPackagePath>org.company.package</fullPackagePath> + <extractedPackages>org.company.package</extractedPackages> + <srcGenDest>target/generated-sources/objectmodel/</srcGenDest> + <includes>**/*.objectmodel</includes> + <templates>org.codelutin.topia.generator.TopiaMetaGenerator</templates> + <destDirGen>target/generated-sources/java</destDirGen> + <defaultPackage>org.company.package</defaultPackage> + </configuration> + <goals> + <goal>zargo2xmi</goal> + <goal>xmi2objectmodel</goal> + <goal>generate</goal> + </goals> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.codelutin.topia</groupId> + <artifactId>topia-persistence</artifactId> + <!-- la version peut être plus récente --> + <version>2.1.0</version> + <scope>runtime</scope> + </dependency> + </dependencies> +</plugin> + + +Dépendances du projet +===================== + +Il faut enfin ajouter "topia-persistence" en dépendance du projet : + +:: + +<dependency> + <groupId>org.codelutin.topia</groupId> + <artifactId>topia-persistence</artifactId> + <!-- la version peut être plus récente --> + <version>2.1.0</version> + <scope>compile</scope> +</dependency> Property changes on: topia/trunk/topia-persistence/src/site/rst/ModelGeneration.rst ___________________________________________________________________ Name: svn:mergeinfo + Copied: topia/trunk/topia-persistence/src/site/rst/SchemaMigration.rst (from rev 1429, topia/trunk/topia-persistence/src/site/fr/rst/SchemaMigration.rst) =================================================================== --- topia/trunk/topia-persistence/src/site/rst/SchemaMigration.rst (rev 0) +++ topia/trunk/topia-persistence/src/site/rst/SchemaMigration.rst 2009-04-20 14:15:30 UTC (rev 1431) @@ -0,0 +1,112 @@ +===================================== +Comment migrer d'un schéma à un autre +===================================== + +Une application modifie et ajoute des objets. La persistence doit donc être +adaptée à ces changements. Le problème est la migration des données +existantes dans le nouveau schéma. + +Voici quelques idées d'implantations. + +Hibernate et dynamic-map +======================== + +Hibernate permet de mapper les objets de la base de données dans des +dynamic-map. Nous n'avons donc pas besoin de pojo pour les représenter, il +nous suffit d'avoir le mapping hibernate. + +L'idée est donc, lors de la modification de schéma, de regrouper tous les +anciens mapping dans un seul fichier de mapping qui contiendra le numero de +version du schema. + +On utilisera ces mappings pour charger l'ancienne configuration et ainsi les +réenregistrer dans le nouveau schéma. + +Une classe java de migration devra être écrite pour transformer les données +d'un schéma vers un autre schéma. + +Avantage +-------- + +Le changement de schéma est fait en java + +Désavantage +----------- + +Il faut dans la base une table qui indique dans quelle version de schéma +actuelle est la base (Topia->schemaVersion). +Une autre solution est de faire une base +par version, le numero de version étant dans le nom de la base (inconveniant : +le nom de la base change a chaque version). +Une autre solution possible est de faire un +changement de schéma dans une transaction, donc on peut lire les anciennes +données dans une transaction et on écrit les nouvelles dans une autre +transaction sur la même table mais qui aurait des schéma différents. + +Il faut, dans les noms des tables, le numéro de version du schéma pour que les +les anciennes tables ne servent pas comme nom pour les nouvelles. + +Il faut soit faire l'aggrégation des mapping dans un seul fichier, soit +n'utiliser qu'un seul fichier pour les mappings, soit avoir un fichier par +classe et par version, mais il est moins simple de retrouver tous les +fichiers de mapping et surtout moins simple + +En fait il n'y a pas vraiment de desavantage. La solution parrait simple et +efficace. + +Exemple de classe de conversion +------------------------------- + +:: + + class Convert { + convert() { + // recherche de la version actuelle de la base topia->schemaVersion + // recherche de la version utilisé par l'application config->schemaVersion + // si les versions divergent, appel de toutes les méthodes convert + // pour arriver à la version de schema actuelle dans config + } + + convert_2_0_1_to_2_0_2(){ + // chargement schema 2_0_1 en utilisant les dynamic-map + // chargement schema 2_0_2 en utilisant les dynamic-map + ... + // code de migration d'un schema a un autre + // si pas de modification pour une classe, il faut au moins faire une + // copie pour remplir les nouvelles tables + ... + // modification de version dans topia->schemaVersion + // commit nouvelle données + // on peut supprimer les anciennes tables + } + + convert_2_0_2_to_2_1_0(){ + // idem + } + } + +Hibernate et XML +================ + +Il est aussi possible de lire une base en XML. On utiliserait donc la même +technique que pour les dynamic-map, mais on utiliserait du XSL pour +convertir le XML vers le schéma souhaité. De cette facon il n'y a pas besoin +de table intermédiaire ni de numéro de version de schéma dans les tables. + +- Export XML en utilisant le vieux mapping +- converion en enchainant les transformations XSL +- Import du nouveau fichier XML + +Inconvéniant +------------ + +si le volume est important il peut-etre long de tout transformer en XML. + +Kettle +====== + +Une autre idee est de ne pas utiliser hibernate mais kettle pour la +migration des données. Nous aurions de la même façon dans le nom des tables +un numero de version de schéma. Un fichier kettle decrirait la migration +d'une version à une autre. Et les différents fichiers serait chaînés pour +arriver au schéma souhaité. Property changes on: topia/trunk/topia-persistence/src/site/rst/SchemaMigration.rst ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:mergeinfo + Name: svn:eol-style + native Copied: topia/trunk/topia-persistence/src/site/rst/Todo.rst (from rev 1429, topia/trunk/topia-persistence/src/site/fr/rst/Todo.rst) =================================================================== --- topia/trunk/topia-persistence/src/site/rst/Todo.rst (rev 0) +++ topia/trunk/topia-persistence/src/site/rst/Todo.rst 2009-04-20 14:15:30 UTC (rev 1431) @@ -0,0 +1,223 @@ +Recherches à faire: +- des persistences hibernates sur LDAP ou FlatFile +- des outils de migration/evolution de schema + +Generic DAO +http://www.hibernate.org/328.html:: + + public abstract class GenericHibernateDAO<T> { + ... + Class<T> persistentClass = (Class<T>) ((ParameterizedType) getClass() + .getGenericSuperclass()).getActualTypeArguments()[0]; + + +Regarder si TopiaContext ne pourrait pas être remplacé par un PicoContainer +http://www.hibernate.org/180.html +http://www.hibernate.org/182.html + +doc sur l'optimisation des requetes HQL +http://www.jroller.com/page/wakaleo/?anchor=hibernate_optimisation + +Generation +========== + +- (2) import/export XML dans ToPIA, à mettre dans le mapping hibernate (en partie fait, mais très stable...) + + +Gestion des versions des POJO +============================= + +mettre en place serialVersionUID sur les entités + +Gestion des droits et de la sécurité +==================================== + +Le créateur de l'objet n'est pas dans l'objet lui même mais dans une table a +part. + +Owner: topiaId de l'entity, id du propriétaire + +Les droits des objets sont dans une table a part +(voir http://www.hibernate.org/140.html). + +Il serait bon que les droits s'appliquent sur un group ou un user. Et qu'un user +puisse appartenir a un group, et qu'un group puisse aussi appartenir a un group + +Il faut aussi modifier le Policy ou autre pour pouvoir lire les permissions +dans hibernate lorsqu'on nous les demandes. Mettre des méthodes statique dans +une classe contenant une session hibernate statique pour permettre l'ajout +de permission a l'execution, sans qu'on est besoin de relire toutes les +permissions a chaque fois, la session servant de cache (mais les sessions +ne sont pas multithread d'ou le synchronise) + +synchronized public void addPermission(TopiaPermission); +synchronized public List<TopiaPermission> getAllPermission(); + +Entity directement dans Topia +============================= + +- User: login, password, email +- Group: name, (User|Group)* +- Permission: action(create, load, update, delete, admin permission), classname, + principal, topiaId de l'entity ou null si le droit sur toutes les entites de ce type + + +Les services +============ + +..image: ServiceCall.png + +Les services on besoin d'avoir le context de l'appelant pour pouvoir faire +des choix: +- choix de la base de données +- droit de l'utilisateur +- ... + +Pour cela le premier argument de chaque methode generee doit etre un token +retourner par le service d'authentification. + +Le service d'authentification (LA/SSO?) permet de recuperer les informations +du TopiaClientContext qui contient des informations utiles: +- applicationId (identifiant de l'application appelant (im.codelutin.com, im.libre-entreprise.com, ...)) +- clientId (identifiant du client appelant (gaim, exodus, gabber, ...)) +- userLogin +- userPassword + +On a un TopiaServiceManager qui permet de recuperer un proxy sur le service +souhaité. Le proxy n'a pas en premier argument ce TopiaClientContext, il est +ajouté automatiquement lors de l'appel. De cette maniere cote client cela +est completement transparent. + + +# Cote client +ChoremServiceHelper csh = ChoremServiceHelper.getInstance("codelutin.chorem.com", "mentawai", "poussin", "xxxxxxxx"); +CRMService crm = csm.getCRMService(); // retourne un proxy sur le service +List<Person> persons = crm.getAllPerson(); // retourne la liste de toutes les personnes visible par poussin + +# Cote serveur dans getAllPerson(String token) +TopiaClientContext tcc = TopiaAuthenticationService.getTopiaClientContext(token); +Properties prop = ChoremUtil.getContextProperties(tcc); +ChoremContext context = ChoremContext.getContext(prop); +List<Person> result = ChoremDAOHelper.getCRMDAO(context).getAllPerson(); +return result; + +Le moyen de recuperer le TopiaAuthentificationService doit etre specifier +dans les fichiers de configuration de l'application. Il doit y avoir +plusieurs implantation pour ce service: +- class avec methode static pour les applications standalone +- EJB +- service web +- ... + +L'application doit pouvoir plugger sa propre methode d'authentification +(acces a un LDAP, a une BD, a un Liberty Alliance, ...), chaque implantation +doit utiliser cette methode d'authentification (delegation). + +De meme pour l'implantation des services, les services doivent être des +classes Java normal (sans le token en parametre) mais contenant une methode +setTopiaContext() qui permet de mettre a jour + + +Autre +===== + +- tag-value transaction sur les operations des services avec les valeurs + traditionnelles de la spec EJB (required, requiresNew, mandatory, + supports, notSupported, never ). ex auto=required +- dernier user ayant modifié une entité +- tag-value auto avec un pattern sur les attributs. ex auto=now +- tag-value mask avec un pattern sur les attributs. ex : mask=price + puis dans les fichiers de traductions : price=#+,## +- tag-value enumName avec un pattern sur les attributs. ex : + enum=projectStatus + La valeur des énumérations est conservé dans un fichier de configuration + qui peut-etre surchargé par des valeurs dans une table en base de + données : projectStatus=a faire, fait, fini +- tag-value i18n avec un pattern sur les attributs. ex : i18n=true (en partie fait :) ) +- Generation des UI par defaut (JAXX et JSP) +- prendre en compte le contenu de l'onglet doc des entités et attributs + jusqu'au -- pour les tooltips (doc tooltips/doc user/doc dev) + +A reflechir (voir si c vraiment util) +===================================== +- pouvoir monitorer un attribut (user, date, oldValue, new Value) + Ces attributs ont une valeur tagguée versioned à vrai ou faux. + -> getHistory[Attribut]():list<History> + +Amélioration templates +====================== + +- préférer définir des variables plutôt que d'injecter du code dans les templates : + +Example : + +avant +:: + + /*{table="<%=GeneratorUtil.getDBName(attr.getDeclaringElement()) + "_" + getName(attr)%>"*/ + + +après + +:: + + String dbName = GeneratorUtil.getDBName(attr.getDeclaringElement()) + "_" + getName(attr); + +ou + +:: + + String attrName = getName(attr); + String dbName = GeneratorUtil.getDBName(attr.getDeclaringElement()); + + /*{table="<%=dbName+"_"+attrName%>"}*/ + +- mettre une javadoc pour dire ce que la méthode va faire + +- incorporer des tests unitaires de génération :) + +- créer des constantes pour les stereotypes tagValues et les utiliser... + +- aller à la chasse aux constantes (exemple propertiesPattern dans DAOAbstractGenerator) + +- faire la chasse au code inutilisé + +- ajouter hasTagValue sur ObjectModelElement dans lutingenerator + +- réfléchir comment générer les imports pour ne plus utilisers les FQN + +- vérifier les javadocs générées (ajouter les exceptions,...) + +- reussir a résoudre les casts dans les DAOAbstraxct sur la méthode getEntityClass + +- réusiner les codes de génération d'attributs : + +:: + + String lazy = " lazy=\""; + if (notEmpty(attr.getTagValue(GeneratorUtil.TAG_LAZY))){ + lazy += attr.getTagValue(GeneratorUtil.TAG_LAZY); + } else { + lazy += "true"; + } + lazy += "\""; + +mais il ya d'autres cas à prévoir... : + +:: + + String fetch = ""; + if (notEmpty(attr.getTagValue(GeneratorUtil.TAG_FETCH))){ + fetch = " fetch=\"" + attr.getTagValue(GeneratorUtil.TAG_FETCH) + "\""; + } + +- Dans lutingenerator, renommer Util en GeneratorUtil et dans ToPIA, + GeneratorUtil en TopiaGeneratorUtil + +- supprimer les les boucles sur Iterator quand c'est possible et utiliser pluot des for-each + +- étudier la nécessité des GeneratorUtil.toLowerCaseFirstLetter(assocAttrName) présents dans EntityAbstractGenerator à propos des classes d'assoc + +- TODO Check wether this method could be used to generate getter and setters + +- Uniformiser et faire hériter les générateurs des interfaces et classe d'impl pour que le générateur de la classe d'impl soit capable de générer aussi l'interface Property changes on: topia/trunk/topia-persistence/src/site/rst/Todo.rst ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:mergeinfo + Name: svn:eol-style + native Copied: topia/trunk/topia-persistence/src/site/rst/TopiaDocumentation.rst (from rev 1429, topia/trunk/topia-persistence/src/site/fr/rst/TopiaDocumentation.rst) =================================================================== --- topia/trunk/topia-persistence/src/site/rst/TopiaDocumentation.rst (rev 0) +++ topia/trunk/topia-persistence/src/site/rst/TopiaDocumentation.rst 2009-04-20 14:15:30 UTC (rev 1431) @@ -0,0 +1,44 @@ +===== +ToPIA +===== + +But +=== + +- abstraction de la persistence +- sauvegarde/restauration en XML +- sécurité sur les instances d'objets +- génération de code même si non obligatoire pour utiliser ToPIA + +Ce qu'il serait bien de récuperer par rapport à la version 2 + +- support des sous-transactions + +peut-être plus tard + +- gestion des services +- distribution transparente + +La vision ToPIA +=============== + +Un point d'entre le TopiaContext sur lequel on ouvre des transactions ce qui +retourne un autre TopiaContext à partir duquel on récupère les DAO des +différentes entités qui permettent de faire les traitements que l'on souhaite. + +Ensuite on peut appeler la methode commit de ce sous TopiaContext pour mettre +à jour la base de données et permettre à d'autres TopiaContext d'avoir la +nouvelle vision de nos objets. + +Chaque TopiaContext créé sur le TopiaContext root est indépendant. + +Lorsque l'on travaille avec un objet provenant d'un TopiaContext sur lequel +on a fait un rollback, celui-ci n'est plus valide et il vaut mieux en recupérer +une version correcte sur le TopiaContext. + +Après avoir fait un commit ou un rollback sur un TopiaContext on peut continuer +a l'utiliser et refaire des commits pour synchroniser de temps en temps les +modification faites sur la base. + +Un TopiaContext peu servir aussi longtemps que l'on souhaite, il ne maintient +pas inutilement de transaction sur la base. Property changes on: topia/trunk/topia-persistence/src/site/rst/TopiaDocumentation.rst ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:mergeinfo + Name: svn:eol-style + native Copied: topia/trunk/topia-persistence/src/site/rst/event.rst (from rev 1429, topia/trunk/topia-persistence/src/site/fr/rst/event.rst) =================================================================== --- topia/trunk/topia-persistence/src/site/rst/event.rst (rev 0) +++ topia/trunk/topia-persistence/src/site/rst/event.rst 2009-04-20 14:15:30 UTC (rev 1431) @@ -0,0 +1,67 @@ +Gestion des évènements +====================== + +On peut se mettre listener sur deux sortes d'évènements : les TopiaEntityEvent et +les TopiaVetoableEntityEvent. La difference entre les deux se situe sur le moment de +l'appel. + + +TopiaVetoableEntityEvent +------------------------ + +Les TopiaVetoableEntityEvent sont appelés avant l'action, ce qui +permet de l'interdire en levant une exception (par exemple pour gérer la +sécurité). + +Les TopiaVetoableEntityEvent contiennent la classe à laquelle se rapporte l'event +et si possible l'identifiant de l'objet qui sera impacté. Cela n'est pas +toujours le cas; par exemple lors de la creation, l'identifiant n'existe pas forcément +et donc ne peut-etre donné. + +Propagation +~~~~~~~~~~~ + +Les TopiaVetoableEntityEvent sont aussi levés pour tous les contexts pères +du context qui a produit l'event et ceci juste apres avoir prévenu les +listeners du context courant. + +TopiaEntityEvent +---------------- + +Les TopiaEntityEvent sont appelés après l'action pour prévenir du changement. + +Les TopiaEntityEvent contiennent l'entity à laquelle se rapporte l'event + +Propagation +~~~~~~~~~~~ + +Les TopiaEntityEvent sont propagé au context pere lors du commit du context. + +Si un rollback est fait, alors ce sont les listeners du context eux-même qui +sont prévenus du changement. + +Implantation +============ + +Les DAO sont responsables de l'appel des méthodes fire sur le context qui les +a créés lors de l'appel sur ceux-ci des methodes create, update, delete, find +(pour le chargement). + +Le cas Hibernate +---------------- + +Dans le DAO hibernate le context est listener des différents évènements levés +par la session. Mais ces évènements ne sont levés que lors du commit. Dans Topia +on souhaite avoir directement un évènement lors d'un create, update ou delete +sur le DAO. Le DAO hibernate lève donc des évènements lorsque l'on appelle +ces méthodes. + +On a aussi des évènements lors du commit. Il est donc possible qu'on aie, +par exemple, le même évènement Update envoyé deux fois au listener si on fait +un update sur le DAO suivi du commit sur le context. + +On conserve tout de meme le mécanisme d'évènement levé au moment du commit par +hibernate car il est beaucoup plus puissant. Il permet aussi d'être prévenu de +modifications apportées aux constituants d'une entité et non pas seulement des +évènements portants sur l'entité elle-même comme c'est le cas dans le mecanisme +implanté dans les DAO. Property changes on: topia/trunk/topia-persistence/src/site/rst/event.rst ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:mergeinfo + Name: svn:eol-style + native Copied: topia/trunk/topia-persistence/src/site/rst/howto.rst (from rev 1429, topia/trunk/topia-persistence/src/site/fr/rst/howto.rst) =================================================================== --- topia/trunk/topia-persistence/src/site/rst/howto.rst (rev 0) +++ topia/trunk/topia-persistence/src/site/rst/howto.rst 2009-04-20 14:15:30 UTC (rev 1431) @@ -0,0 +1,260 @@ +How to +====== + +Ce document a pour objectif de prendre en main le framework Topia. Le document +est constitué de 4 parties, la modélisation, la génération, la configuration et +l'utilisation. + +Modélisation +------------ + +La première étape constiste à réaliser le modèle UML soit avec Argouml +(http://argouml.tigris.org) soit avec Poséidon (http://www.gentleware.com). + +Le stérotype «entity» sur les classes permet de préciser que la classe est +persistée par Topia. D'autre stérotypes (extern, service, ...) sont disponibles +mais ne sont pas présentés. + +Le fichier de modélisation peut être complété par un fichier de configuration +nommé <nom fichier modélisation>.properties. Il contient des informations +techniques propres aux librairies utilisé par Topia. + +Exemple : + +:: + + # Précise comment est mappé un type + # model.tagvalue.<type java>=<type base de donnée> + model.tagvalue.java.lang.String=text + + # Précise le schema de la base de données par défaut + # model.tagvalue.dbSchema=<nom schéma> + model.tagvalue.dbSchema=test + + # Précise l'entête de l'ensemble des fichiers générés + # model.tagvalue.copyright=<valeur> + model.tagvalue.copyright=/* *##%\n Copyright (C) 2009 Code Lutin\n *##% */ + + # Force le chargement d'un attribut + # <nom paquetage>.<nom entité>.attribute.<nom attribut>.tagvalue.lazy=false + org.codelutin.Person.attribute.association.tagvalue.lazy=false + +Génération +---------- + +La génération des fichiers Topia se font par l'utilisation d'un plugin maven. +Le plugin est disponnible sur le repository maven de Code Lutin à l'adresse +suivante http://lutinbuilder.labs.libre-entreprise.org/maven2. + +Configuration du plugin maven : + +:: + + <plugin> + <groupId>org.codelutin</groupId> + <artifactId>maven-generator-plugin</artifactId> + <version>0.64</version> + <executions> + <execution> + <phase>process-sources</phase> + <!--Configuration of model generator--> + <configuration> + <addCompileDirectory>true</addCompileDirectory> + <srcDirZuml>${maven.src.dir}/main/xmi</srcDirZuml> + <srcXmiDest>${maven.gen.dir}/xmi/</srcXmiDest> + <srcGenDest>${maven.gen.dir}/objectmodel/</srcGenDest> + <includes>**/*.objectmodel</includes> + <templates>org.codelutin.topia.generator.TopiaMetaGenerator</templates> + <destDirGen>${maven.gen.dir}/java</destDirGen> + <defaultPackage>org.codelutin</defaultPackage> + <extractedPackages>org.codelutin</extractedPackages> + <fullPackagePath>org.codelutin</fullPackagePath> + </configuration> + <goals> + <goal>zargo2xmi</goal> + <goal>xmi2objectmodel</goal> + <goal>generate</goal> + </goals> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.codelutin.topia</groupId> + <artifactId>topia-persistence</artifactId> + <version>2.1.3</version> + <scope>compile</scope> + </dependency> + </dependencies> + </plugin> + +Le plugin utilise lutin generator avec les templates de génération de Topia, le +fichier argouml ou poséidon doit se trouver dans le répertoire +${maven.src.dir}/main/xmi. Les fichiers sont générés dans le répertoire +${maven.gen.dir}/java. Il faut préciser au plugin les paquetages à traiter avec +le defaultPackage et extractedPackages. + +Ajout dans des dépendances de Topia pour la compilation des fichiers générés : + +:: + + <dependency> + <groupId>org.codelutin.topia</groupId> + <artifactId>topia-persistence</artifactId> + <version>2.1.3</version> + <scope>compile</scope> + </dependency> + +Pour une classe modélisée, nous retrouvons 6 fichiers : + * Une interface + * Une classe abstraite + * Une implantation + * Une configuration hibernate + * Un DAO abstrait + * Une implantation du DAO + +Une classe Helper est aussi générée, permettant l'accès à l'ensemble des DAO. + +Configuration +------------- + +Un fichier contenant les informations de connexion à la base de données et de +configuration de Topia doit être créé au niveau des ressources du projet. + +Exemple : + +:: + + # Permet la création, la modification, ou pas automatique de la base de données + # [create | update | none] + hibernate.hbm2ddl.auto=update + + # Affichage des requêtes dans la console + # [true | false] + hibernate.show_sql=false + + # Permet de préciser les classes a persister + topia.persistence.classes=org.codelutin.Person, org.codelutin.Pet + + # Informations de connection : + + # Dialect à utiliser + hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect + + # Driver JDBC + hibernate.connection.driver_class=org.postgresql.Driver + + # URL de connection + hibernate.connection.url=jdbc:postgresql://localhost/mydb + + # Login de l'utilisateur qui se connecte + hibernate.connection.username=user + + # Mot de passe de l'utilisateur + hibernate.connection.password=xxxx + +Utilisation +----------- + +Implantation des méthodes +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Si des méthodes ont été définies dans le modèle de données, il faut créer +l'implantation correspondante. Le paquetage doit porter le même nom que celui de +la génération. + +Gestion des transactions +~~~~~~~~~~~~~~~~~~~~~~~~ + +>>> Properties conf = new Properties(); +URL url = Resource.getURL("TopiaContextImpl.properties"); +conf.load(new FileInputStream(new File(url.toURI()))); + +Permet de charger un fichier contenant les informations de connexion à la base +et de configuration de Topia. + +>>> TopiaContext rootContext = TopiaContextFactory.getContext(conf); + +Récupère le context de départ pour la création de sous context pour la gestion +des entités. + +>>> TopiaContext transaction = rootContext.beginTransaction(); + +Création d'un sous context pour la gestion des entités. + +>>> transaction.commitTransaction(); + +Validation de l'état du context, les modifications des entités sont reportées +dans la base de données. + +>>> transaction.rollBackTransaction(); + +Invalidation de l'état du context, les modifications des entités ne sont pas +reportées dans la base de données. + +>>> transaction.closeContext(); + +Relâche la connexion JDBC d'un sous context et de ses sous contexts sans +validation de l'état des contexts. + +>>> rootContext.closeContext(); + +Relâche l'ensemble des ressources (cache, pools, ...) et relâche la connexion +JDBC des sous contexts avec validation de l'état des contexts. + +Manipulation des entités +~~~~~~~~~~~~~~~~~~~~~~~~ + +>>> PersonDAO personDAO = <nom modele>Helper.getPersonDAO(transaction); + +Récupération d'un DAO pour accéder à une entité. + +>>> Person person = personDAO.findByTopiaId(id); + +Les méthodes find permettent de récupérer une ou plusieures entités selon différents +critères. + +>>> person.setName("tutu"); + +Manipulation de l'entité par les getters et setters. + +>>> Person person = personDAO.create(); + +Création d'une entité. Si vous utilisez l'instanciation classique java avec le +new, l'entité n'est pas persistée. + +>>> personDAO.update(person); + +Modification d'un entité. + +>>> personDAO.delete(person); + +Suppression d'une entité. + +Exemple +~~~~~~~ + +:: + + Properties conf = new Properties(); + URL url = Resource.getURL("TopiaContextImpl.properties"); + conf.load(new FileInputStream(new File(url.toURI()))); + + TopiaContext rootContext = TopiaContextFactory.getContext(conf); + + TopiaContext transaction = rootContext.beginTransaction(); + PersonDAO personDAO = ModelHelper.getPersonDAO(transaction); + + Person person = personDAO.create(); + person.set...(...); + person.set...(...); + personDAO.update(person); + + person.get...(...); + person.get...(...); + + personDAO.delete(person); + + transaction.commitTransaction(); + transaction.closeContext(); + + rootContext.closeContext(); Property changes on: topia/trunk/topia-persistence/src/site/rst/howto.rst ___________________________________________________________________ Name: svn:mergeinfo + Copied: topia/trunk/topia-persistence/src/site/rst/index.rst (from rev 1429, topia/trunk/topia-persistence/src/site/fr/rst/index.rst) =================================================================== (Binary files differ) Property changes on: topia/trunk/topia-persistence/src/site/rst/index.rst ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + application/octet-stream Name: svn:mergeinfo + Copied: topia/trunk/topia-persistence/src/site/rst/project.rst (from rev 1429, topia/trunk/topia-persistence/src/site/fr/rst/project.rst) =================================================================== --- topia/trunk/topia-persistence/src/site/rst/project.rst (rev 0) +++ topia/trunk/topia-persistence/src/site/rst/project.rst 2009-04-20 14:15:30 UTC (rev 1431) @@ -0,0 +1,12 @@ +Liste de projets similaires ou se rapprochant +============================================= + +subPersistence +-------------- + +:update:20060102 + +:url: http://subpersistence.sourceforge.net/ + +Librairie d'abstraction de libraire de mapping O/R +Supporte Hibernate pour l'instant. Semble vouloir supporter aussi Castor. Property changes on: topia/trunk/topia-persistence/src/site/rst/project.rst ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:mergeinfo + Name: svn:eol-style + native Copied: topia/trunk/topia-persistence/src/site/rst/security.rst (from rev 1429, topia/trunk/topia-persistence/src/site/fr/rst/security.rst) =================================================================== --- topia/trunk/topia-persistence/src/site/rst/security.rst (rev 0) +++ topia/trunk/topia-persistence/src/site/rst/security.rst 2009-04-20 14:15:30 UTC (rev 1431) @@ -0,0 +1,24 @@ +Implantation de la sécurité +=========================== + +La sécurité est un simple objet java qui hérite de TopiaHelper + +Il se met alors listener sur tous les events vetoables et lève des exceptions +si la personne qui essaie de charger/créer/modifier/supprimer l'objet n'en a pas +le droit. + +Le service de sécurité vient avec son fichier de configuration. Dans ce fichier +il y a les paramètres utiles au service pour retrouver les informations sur les +droits. + +TopiaHelper est en fait une interface qui contient la méthode +init(TopiaContext, Properties) + + +package +------- + +:org.codelutin.topia.security: pour tout ce qui touche a la sécurité + (TopiaAuthenticationHelper, TopiaAuthorisationHelper, LoginModule, Filter, ...) +:org.codelutin.topia.security.entities: pour les entities utiles à la définition + de la sécurité (user, group, permission) Property changes on: topia/trunk/topia-persistence/src/site/rst/security.rst ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:mergeinfo + Name: svn:eol-style + native Copied: topia/trunk/topia-soa/src/site/rst/ApplicationServiceGeneration.rst (from rev 1429, topia/trunk/topia-soa/src/site/fr/rst/ApplicationServiceGeneration.rst) =================================================================== --- topia/trunk/topia-soa/src/site/rst/ApplicationServiceGeneration.rst (rev 0) +++ topia/trunk/topia-soa/src/site/rst/ApplicationServiceGeneration.rst 2009-04-20 14:15:30 UTC (rev 1431) @@ -0,0 +1,92 @@ +Génération des services +======================= + +Modèle +------ + +Stéréotype +~~~~~~~~~~ + +Topia founit des générateurs pour utiliser sa couche de +services applicatifs. + +Pour cela, il faut ajouter le stéréotype ''<<service>>'' sur +les interfaces qui seront utilisée pour fournir des services ou +acceder à des services distants. + + +Implémentation +~~~~~~~~~~~~~~ + +Vous pouvez choisir de nes générez que les interfaces des services +et de développer vous meme les implémentations. + +Le générateur est aussi capable de générer une implémentation avec +toutes les méthodes des DAO (voir topia-persistence) qui lui +sont lié. + +Configuration Maven +------------------- + +Les templates disponibles sont: +``org.codelutin.topia.generator.ServiceInterfaceGenerator`` + Meta générateur qui génere les interfaces. +``org.codelutin.topia.generator.ServiceAbstractGenerator`` + Meta générateur qui génere implémentation abstract. +``org.codelutin.topia.generator.ServiceImplGenerator`` + Meta générateur qui génere implémentation concrète. +``org.codelutin.topia.generator.TopiaApplicationServiceMetaGenerator`` + Meta générateur qui génere toutes les interfaces, abstract et Impl. + +Plugin de Génération +~~~~~~~~~~~~~~~~~~~~ + +:: + + <plugins> + <plugin> + <groupId>org.codelutin</groupId> + <artifactId>maven-generator-plugin</artifactId> + <version>0.63</version> + <executions> + <execution> + <phase>generate-sources</phase> + <configuration> + <addCompileDirectory>true</addCompileDirectory> + <srcDirZuml>${maven.src.dir}/main/xmi</srcDirZuml> + <srcXmiDest>${maven.gen.dir}/xmi/</srcXmiDest> + <srcGenDest>${maven.gen.dir}/objectmodel/</srcGenDest> + <includes>**/*.objectmodel</includes> + <templates>org.codelutin.topia.generator.TopiaApplicationServiceMetaGenerator</templates> + <destDirGen>${maven.gen.dir}/java</destDirGen> + <defaultPackage>org.codelutin.chorem</defaultPackage> + </configuration> + <goals> + <goal>zargo2xmi</goal> + <goal>xmi2objectmodel</goal> + <goal>generate</goal> + </goals> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.codelutin.topia</groupId> + <artifactId>topia-soa</artifactId> + <version>2.1.3-SNAPSHOT</version> + <scope>runtime</scope> + </dependency> + </dependencies> + </plugin> + </plugins> + +Compilation +~~~~~~~~~~~ + +:: + + <dependency> + <groupId>org.codelutin.topia</groupId> + <artifactId>topia-soa</artifactId> + <version>2.1.3-SNAPSHOT</version> + <scope>compile</scope> + </dependency> \ No newline at end of file Property changes on: topia/trunk/topia-soa/src/site/rst/ApplicationServiceGeneration.rst ___________________________________________________________________ Name: svn:mergeinfo + Copied: topia/trunk/topia-soa/src/site/rst/ApplicationServiceUsing.rst (from rev 1429, topia/trunk/topia-soa/src/site/fr/rst/ApplicationServiceUsing.rst) =================================================================== --- topia/trunk/topia-soa/src/site/rst/ApplicationServiceUsing.rst (rev 0) +++ topia/trunk/topia-soa/src/site/rst/ApplicationServiceUsing.rst 2009-04-20 14:15:30 UTC (rev 1431) @@ -0,0 +1,89 @@ +Utilisation des services +======================== + +En mode client +-------------- + +En mode client, vous n'avez besoin que des interfaces générées. + +Prenons l'exemple, d'une interface de service +''org.codelutin.service.TestService'' comportant une méthode ''getHelloWorld()''. + +Configuration +~~~~~~~~~~~~~ + +Dans le fichier de configuration de ToPIA, il faudra ajouter la configuration suivante : + +:: + + topia.application.service.org.codelutin.service.TestService=xml-rpc://localhost:8888 + +Cette configuration indique à ToPIA, que le service est accessible à l'adresse ''localhost:8888'' +sur le protocole xml-rpc. + +Les protocoles disponibles actuellement sont : + * ''soap'' : SOAP + * ''xml-rpc : XML-RPC + * ''rmi'' : Java RMI + * ''local'' : Utilisation directe d'une implémentation sans passer par un servceur distant + Utilise pour les tests. + Exemple : ''topia.application.service.org.codelutin.service.TestService=local://org.codelutin.service.TestServiceImpl/#new'' + (Le #new ici signifie qu'une instance est contruite a chaque requete) + + +Utilisation +~~~~~~~~~~~ + +Pour acceder au service distant ensuite, rien de plus simple, il suffit d'utiliser +le code suivant : + +:: + + TestService service = TopiaApplicationServiceFactory.getService(TestService.class); + service.getHelloWorld(); + +La methode getService() de ToPIA renvoie un ''proxy'' implémentant TestService +sur le service distant. + + +En mode serveur +--------------- + +En mode serveur, nous allons utiliser le même service ''org.codelutin.service.TestService'' +comportant une méthode ''getHelloWorld()''. + +Nous supposons que nous disposons également du implementation ''org.codelutin.service.TestServiceImpl'' +de ce service, soit implementée à la main, soit générée par ToPIA avec les méthodes des DAO. + +Configuration +~~~~~~~~~~~~~ + +ToPIA doit savoir comment il doit fournir les services. + +:: + + topia.application.provide.org.codelutin.service.TestService=xml-rpc + topia.application.server.port.xml-rpc=9090 + +ToPIA va ici fournir le service ''org.codelutin.service.TestService'' en utilisant automatiquement +l'implémentation ''org.codelutin.service.TestServiceImpl'' via ''xml-rpc''. +On a ici aussi surchargée la configuration, pour pouvoir choisir sur quel +port démarrer les serveurs. + + +Utilisation +~~~~~~~~~~~ + +Une fois dans votre application, il suffira de dire à ToPIA de démarrer les +serveur en utilisant la configuration. + +:: + + TopiaApplicationServiceFactory.loadServices(conf, context); + +On peut aussi ajouter manuellement les services que l'on souhaite démarrer: + +:: + + TopiaApplicationServiceFactory.addService(TestService.class, + TestServiceImpl.class, Protocol.SOAP); \ No newline at end of file Property changes on: topia/trunk/topia-soa/src/site/rst/ApplicationServiceUsing.rst ___________________________________________________________________ Name: svn:mergeinfo + Copied: topia/trunk/topia-soa/src/site/rst/index.rst (from rev 1429, topia/trunk/topia-soa/src/site/fr/rst/index.rst) =================================================================== --- topia/trunk/topia-soa/src/site/rst/index.rst (rev 0) +++ topia/trunk/topia-soa/src/site/rst/index.rst 2009-04-20 14:15:30 UTC (rev 1431) @@ -0,0 +1,10 @@ +Topia-SOA +========= + +Couche d'abtraction des services applicatifs. + + * `Generation des services`_ + * `Utilisation des services`_ + +.. _Generation des services: ApplicationServiceGeneration.html +.. _Utilisation des services: ApplicationServiceUsing.html \ No newline at end of file Property changes on: topia/trunk/topia-soa/src/site/rst/index.rst ___________________________________________________________________ Name: svn:mergeinfo + Copied: topia/trunk/topia-ui/src/site/rst/UseCase.rst (from rev 1429, topia/trunk/topia-ui/src/site/fr/rst/UseCase.rst) =================================================================== --- topia/trunk/topia-ui/src/site/rst/UseCase.rst (rev 0) +++ topia/trunk/topia-ui/src/site/rst/UseCase.rst 2009-04-20 14:15:30 UTC (rev 1431) @@ -0,0 +1,207 @@ +Topia Use Case +============== + +ToPIA permet la génération de navigation à partir du modèle UML sous forme de +diagrammes états/transitions. +Le framework fournit de plus une implémentation de cette génération basée +sur le framework MVC `Tapestry <http://tapestry.apache.org/tapestry5/>`_. + +Besoin +------ +Le besoin initial était d'utiliser au maximum les différents état du système. +Dans le cas d'un site internet par exemple, une même page peut être utilisée +pour créer un contact, et plus tard pour modifier un contact. + +Cependant, un état à un utilisation différente suivant le cas d'utilisation +utilisé. + +Ce framework permet donc de générer la navigation sous une forme quelconque, et +de baser cette navigation sur un moteur gérant les cas d'utilisation. + + +Générateur +---------- +Les générateurs de code utilisés font partie de LutinGenerator. Celui-ci permet +de charger le modèle en mémoire, mais ne fournit aucune implémentation +spécifique. +ToPIA fournit les templates de génération (notemment celui basé sur Tapestry). + + +Modèle UML +---------- +Le modèle UML de base doit respecter quelques conventions pour que la génération +se passe bien. + +En voici un exemple (ArgoUML) : + +.. image:: ContactUseCases.png + +Voici les différents points à respecter : + + * Toutes les parties réutilisables doivent appartenir à sous cas d'utilisation + spécifique. + * Tout sous cas d'utilisation doit disposer d'un état initial et d'un moins un + état final. + * Les états étant des références à des sous-cas d'utilisation doivent être + stéréotypés "UseCase" + +Comme on peut le voir sur l'image, le cas d'utilisation en bas utilise d'autre +sous use case. Mais il ne dispose pas lui même d'état final. Il n'est donc pas +réutilisable. + + +Chargement du modele +-------------------- +LutinGenerator charge le modèle en mémoire sous la forme d'un modèle d'objets +java et appelle le template de génération spécifié dans la configuration. +Le template peut ensuite parcourir ce modèle aisément et générer les données +dont il a besoin. + +Configuration ++++++++++++++ +Voici la configuration maven de déclaration des templates: + +:: + + <plugin> + <groupId>lutinplugin</groupId> + <artifactId>maven-generator-plugin</artifactId> + <version>0.xx</version> + <executions> + <execution> + <id>Generator</id> + <phase>generate-sources</phase> + <configuration> + <!-- repertoire des modeles ArgoUML --> + <srcDirZuml>src/xmi</srcDirZuml> + <!-- destination des fichiers XMI --> + <srcXmiDest>target/gen/xmi/</srcXmiDest> + <!-- destination des fichiers XML StateModel --> + <srcGenDest>target/gen/models/</srcGenDest> + <!-- Fichiers XML StateModel utilises pour la generation --> + <includes>**/*.*model</includes> + <!-- templates a utiliser --> + <templates>org.codelutin.topia.generator.TapestryWebGenerator</templates> + <!-- destination du code genere --> + <destDirGen>target/gen/java</destDirGen> + </configuration> + <goals> + <!-- ArgoUML -> XMI --> + <goal>zargo2xmi</goal> + <!-- XMI -> StateModel --> + <goal>xmi2statemodel</goal> + <!-- StateModel -> Java (selon le template) --> + <goal>generate</goal> + </goals> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>lutinlib</groupId> + <artifactId>topia</artifactId> + <version>2.0.xx</version> + <scope>compile</scope> + </dependency> + </dependencies> + </plugin> + + +Nom de package +-------------- + +Une convention est utilisée dans le nom de package pour déterminer quel est la +racine de la structure (utilisée pour la génération basée sur tapestry par +exemple). + +Le motif utilisé est "web". Il désigne la racine. + +Exemple: + org.codelutin.chorem.web.projectManagement + +Ainsi, via tapestry l'url "/projectManagement" pourra être utilisée. + + +Génération Tapestry +------------------- +La génération sur Tapestry produit une classe abstraite par état déclaré dans le +modèle. +Ces classes abstraites : + + * déclare les autres pages(états) vers lesquelles elle peuvent naviguer. + Ces sont des références traitées par tapestry (annotations). + Chaque référence à pour type la classe concrête implémentée par le + développeur. + * gère l'entrée et la sortie des Use Case. + +Le developpeur doit donc developper l'implémentation tapestry en faisant +référence aux méthodes fournies dans les classes abstraites à hériter pour +naviguer. + +Exemple issue de la génération du modèle à l'image 1, voici la classe abstraite +SocietyView générée à partir du modèle : + +:: + + public abstract class AbstractSocietyView extends UseCasePage { + + public Object onActionFromOk() { + return leaveUseCase(); + } + + @InjectPage + private SocietyForm societyForm; + + protected SocietyForm getSocietyForm() { + return societyForm; + } + + public Object onActionFromEdit() { + enterUseCase(); + return societyForm; + } + + protected final String getUseCaseName() { + return "sv"; + } + } + +Conformément à la spécification : + * cet état est lié à l'état SocietyForm (état initial du sous cas d'utilisation + utilisé) + * dispose d'une action "ok" quittant le use case courant + * dispose d'une action "edit" entrant dans un nouveau use case + +Pour la partie développeur, voici un exemple consitant à appeler une action +avant d'effectuer la réelle navigation : + +:: + + public class SocietyView extends AbstractSocietyView { + + [...] + + @Override + public Object onActionFromEdit() { + + // action + getSocietyForm.setSociety(s); + + // appele de la super methode + return super.onActionFromEdit(); + } + + [...] + } + +Hiérarchie d'héritage +--------------------- +Comme on peut le voir, les classes implémentées par le développeur héritent des +des classes abstraites générées, l'empêchant ainsi d'utiliser son propre +héritage. + +Il est possible de spécifier une classe que toutes les classes abstraites +devront hériter via le fichier de propriété associé au modèle. + +Le propriété : + model.tagvalue.usecaseengineextendedclass=BasePage +spécifie que toutes les classes générées hériteront de la classe BasePage. \ No newline at end of file Copied: topia/trunk/topia-ui/src/site/rst/index.rst (from rev 1429, topia/trunk/topia-ui/src/site/fr/rst/index.rst) =================================================================== --- topia/trunk/topia-ui/src/site/rst/index.rst (rev 0) +++ topia/trunk/topia-ui/src/site/rst/index.rst 2009-04-20 14:15:30 UTC (rev 1431) @@ -0,0 +1,4 @@ +Topia-UI +======== + +Aucune documentation n'est disponible. \ No newline at end of file Property changes on: topia/trunk/topia-ui/src/site/rst/index.rst ___________________________________________________________________ Name: svn:mergeinfo +