Index: topia2/src/java/org/codelutin/topia/persistence/flatfile/TopiaDAOFlatFile.java diff -u topia2/src/java/org/codelutin/topia/persistence/flatfile/TopiaDAOFlatFile.java:1.2 topia2/src/java/org/codelutin/topia/persistence/flatfile/TopiaDAOFlatFile.java:1.3 --- topia2/src/java/org/codelutin/topia/persistence/flatfile/TopiaDAOFlatFile.java:1.2 Wed Jan 4 13:21:51 2006 +++ topia2/src/java/org/codelutin/topia/persistence/flatfile/TopiaDAOFlatFile.java Thu Jan 5 04:50:47 2006 @@ -23,9 +23,9 @@ * * @author poussin * - * @version $Revision: 1.2 $ + * @version $Revision: 1.3 $ * - * Last update: $Date: 2006/01/04 13:21:51 $ by : $Author: bpoussin $ + * Last update: $Date: 2006/01/05 04:50:47 $ by : $Author: bpoussin $ */ package org.codelutin.topia.persistence.flatfile; @@ -40,9 +40,12 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Date; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; @@ -51,6 +54,7 @@ import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.collections.map.AbstractReferenceMap; import org.apache.commons.collections.map.ReferenceMap; +import org.apache.commons.lang.ClassUtils; import org.apache.commons.lang.ObjectUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -64,19 +68,18 @@ /** *

* ATTENTION: Le rollback des transactions n'est pas du tout pris en - * compte. Et l'implantation n'est pas fait pour les supporter un jour. - * Il faudrait pour cela que le context préviennent les DAO, lors d'un + * compte. Et l'implantation n'est pas fait pour les supporter un jour. Il + * faudrait pour cela que le context préviennent les DAO, lors d'un * commit/rollback. *

- * REMARQUE: pour l'instant on ne sauve que les types que l'on sait convertir en - * chaine et inversement. Si on souhaite aller plus loin il faudrait plutot - * regarde du cote d'hibernate et customiser les objets ClassPersistence ou - * autre responsable de la sauvegarde des entités, sauvegarde qui pourrait avoir - * lieu dans un fichier texte, ldap, ... + * REMARQUE: pour l'instant on ne sauve que les types que l'on sait + * convertir en chaine et inversement. Si on souhaite aller plus loin il + * faudrait plutot regarde du cote d'hibernate et customiser les objets + * ClassPersistence ou autre responsable de la sauvegarde des entités, + * sauvegarde qui pourrait avoir lieu dans un fichier texte, ldap, ... *

- * Si on souhaite tout de meme ameliorer cette classe, elle utilise BeanUtils - * de commons-beanutils. Il est possible d'ajouter des convertisseurs par - * ce moyen. + * Si on souhaite tout de meme ameliorer cette classe, elle utilise BeanUtils de + * commons-beanutils. Il est possible d'ajouter des convertisseurs par ce moyen. *

* Permet de sauver les entités dans des fichiers au lieu d'une base de données * il est possible de configurer la sauvegarde de différent moyen. @@ -119,26 +122,26 @@ * l'entity. Si body est présent seul cet attribut sera sauvé. * *

- *     topia.dao.flatfile.mapping.key=topiaId
- *     
- *     topia.dao.flatfile.mapping.fr.ifremer.isisfish.entities.Script.key=name
- *     topia.dao.flatfile.mapping.fr.ifremer.isisfish.entities.Script.body=script
+ *      topia.dao.flatfile.mapping.key=topiaId
+ *      
+ *      topia.dao.flatfile.mapping.fr.ifremer.isisfish.entities.Script.key=name
+ *      topia.dao.flatfile.mapping.fr.ifremer.isisfish.entities.Script.body=script
  * 
* *
- * TODO: auto généré un id pour TopiaId si dans le mapping il n'y a pas de key
- * TODO: Pour la version si presence d'un rep CVS on utilise la version
- *       du fichier a l'interieur de Entries comme valeur initial
- * TODO: modifier le champs version lors d'un update
- * TODO: permettre dans mapping.body de mettre une liste d'attribute dans ce cas
- *       on sauve toujours sous forme de propriétés mais que les champs demandés
- * 
- * NOTE: autre idee 
- * - si on a un body avec un champs unique sauver les autres propriétés
- *   dans une fichier .properties
- * - peut-etre ameliorer le mapping pour pouvoir mapper une entite sur plusieurs
- *   fichiers
- * 
+ *  TODO: auto généré un id pour TopiaId si dans le mapping il n'y a pas de key
+ *  TODO: Pour la version si presence d'un rep CVS on utilise la version
+ *        du fichier a l'interieur de Entries comme valeur initial
+ *  TODO: modifier le champs version lors d'un update
+ *  TODO: permettre dans mapping.body de mettre une liste d'attribute dans ce cas
+ *        on sauve toujours sous forme de propriétés mais que les champs demandés
+ *  
+ *  NOTE: autre idee 
+ *  - si on a un body avec un champs unique sauver les autres propriétés
+ *    dans une fichier <id>.properties
+ *  - peut-etre ameliorer le mapping pour pouvoir mapper une entite sur plusieurs
+ *    fichiers
+ *  
  * 
* * @author poussin @@ -196,7 +199,7 @@ } directory = new File(dirname); directory.mkdirs(); - + ext = getProperty("mapping." + entityClass.getName() + ".ext"); if (ext == null) { ext = getProperty("mapping.ext", ""); @@ -239,7 +242,9 @@ public void rollbackTransaction() throws TopiaException { } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see org.codelutin.topia.persistence.TopiaDAOAbstract#create(java.lang.Object...) */ @Override @@ -249,29 +254,29 @@ getContext().fireOnCreated(result); return result; } - + /** * Sauve l'entity dans le fichier * * @see org.codelutin.topia.TopiaDAO#update() */ public Entity update(Entity e) throws TopiaException { - // le topiaId contient le nom du fichier a partir duquel l'entity + // le topiaId contient le nom du fichier a partir duquel l'entity // a ete chargé try { String oldId = e.getTopiaId(); - String newId = (String)PropertyUtils.getProperty(e, key); - + String newId = (String) PropertyUtils.getProperty(e, key); + // Si l'identifiant a changé alors il faut aussi changer le nom // du fichier, on supprime donc l'ancien nom - if (ObjectUtils.equals(oldId, newId) == false) { + if (ObjectUtils.equals(oldId, newId) == false) { File f = new File(directory, getFilename(oldId)); if (f.exists()) { f.delete(); } e.setTopiaId(newId); } - + File f = new File(directory, getFilename(newId)); if (body != null) { String bodyValue = BeanUtils.getProperty(e, body); @@ -280,15 +285,43 @@ out.close(); } else { Properties prop = new Properties(); - Map propMap = (Map)BeanUtils.describe(e); + Map propMap = (Map) BeanUtils + .describe(e); + + // remove transient field property + // we search field that match exactly get/set name only + Class clazz = e.getClass(); + for (Iterator i = propMap.keySet().iterator(); i + .hasNext();) { + String propName = i.next(); + List classes = ClassUtils.getAllSuperclasses(clazz); + classes.add(0, clazz); + for (Class c : classes) { + try { + Field field = c.getDeclaredField(propName); + if (Modifier.isTransient(field.getModifiers())) { + i.remove(); + } + break; + } catch (Exception eee) { + if (log.isWarnEnabled()) { + log.trace("Unable to find field " + propName + + " on " + c.getName());//, eee); + } + } + + } + + } + prop.putAll(propMap); FileOutputStream out = new FileOutputStream(f); prop.store(out, "flatfile topia persistence entity"); out.close(); } - + getContext().fireOnUpdated(e); - + return e; } catch (IllegalAccessException eee) { throw new TopiaException("Impossible de sauver l'entity: " + e, eee); @@ -307,7 +340,7 @@ * @see org.codelutin.topia.TopiaDAO#delete() */ public void delete(Entity e) throws TopiaException { - // le topiaId contient le nom du fichier a partir duquel l'entity + // le topiaId contient le nom du fichier a partir duquel l'entity // a ete chargé String oldId = e.getTopiaId(); File f = new File(directory, getFilename(oldId)); @@ -326,12 +359,12 @@ */ @Override public Entity findByTopiaId(Object k) throws TopiaException { - String keyValue = (String)k; + String keyValue = (String) k; File f = new File(directory, getFilename(keyValue)); Entity result = findByFile(f); return result; } - + protected String getFilename(String id) { String result = ext; if (ext != null && !"".equals(ext)) { @@ -340,18 +373,18 @@ result = id + result; return result; } - + protected Entity findByFile(File f) throws TopiaException { try { long lastModified = f.lastModified(); Entity e = cache.get(f); // si on a pas encore l'entity ou que le fichier est plus recent // il faut relire l'entité - if (e == null) { + if (e == null) { // en fait il ne faut pas recharger s'il est plus recent - // sur le disque car on est dans une transaction, + // sur le disque car on est dans une transaction, // si on veut la nouvelle version il faut ouvrire une - // nouvelle transaction + // nouvelle transaction // || e.getTopiaCreateDate().getTime() < lastModified) { if (e == null) { e = instanciateNew(); @@ -361,11 +394,11 @@ // on met le topiaCreateDate a lastModified maintenant // pour qu'il puisse etre ecrassé si on arrive a lire // une meilleur information dans le fichier. - // FIXME: voir comment en Java recuperer la date de creation d'un fichier + // FIXME: voir comment en Java recuperer la date de creation + // d'un fichier prop.put("topiaCreateDate", new Date(lastModified)); - InputStream in = new BufferedInputStream( - new FileInputStream(f)); + InputStream in = new BufferedInputStream(new FileInputStream(f)); if (body == null) { prop.load(in); } else { @@ -391,14 +424,16 @@ } return e; } catch (IOException eee) { - throw new TopiaException("Impossible de lire l'entity du fichier: " + f, - eee); + throw new TopiaException("Impossible de lire l'entity du fichier: " + + f, eee); } catch (IllegalAccessException eee) { - throw new TopiaException("Impossible de mettre le contenu du fichier dans l'entity: " - + f, eee); + throw new TopiaException( + "Impossible de mettre le contenu du fichier dans l'entity: " + + f, eee); } catch (InvocationTargetException eee) { - throw new TopiaException("Impossible de mettre le contenu du fichier dans l'entity: " - + f, eee); + throw new TopiaException( + "Impossible de mettre le contenu du fichier dans l'entity: " + + f, eee); } }