TODO

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

    1. 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 utile)

  • 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