Index: topia-service/src/java/org/codelutin/topia/migration/transformation/MigrationClass.java diff -u /dev/null topia-service/src/java/org/codelutin/topia/migration/transformation/MigrationClass.java:1.1 --- /dev/null Mon Apr 2 14:24:42 2007 +++ topia-service/src/java/org/codelutin/topia/migration/transformation/MigrationClass.java Mon Apr 2 14:24:37 2007 @@ -0,0 +1,166 @@ +/* *##% + * Copyright (C) 2007 Code Lutin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *##%*/ + +package org.codelutin.topia.migration.transformation; + +import org.codelutin.topia.migration.common.ProxyClass; +import org.codelutin.topia.migration.common.SimpleProxyClass; +import org.codelutin.topia.migration.common.Version; + +/** + * MigrationClass.java + * + * @author Chatellier Eric + * @author Chevallereau Benjamin + * @author Eon Sébastien + * @author Trève Vincent + * @version $Revision: 1.1 $ + * + * Last update : $Date: 2007/04/02 14:24:37 $ + */ +public class MigrationClass implements Comparable{ + + + //private static transient Log log = LogFactory.getLog(MigrationClass.class); + + private String nameMigrationClass; + + private ProxyClass nameClass; + + private Version begin; + + private Version end; + + public MigrationClass() {} + + /** + * @param nameMigrationClass + * @param nameClass + * @param begin + * @param end + */ + public MigrationClass(String nameMigrationClass, ProxyClass nameClass, Version begin, Version end) { + super(); + this.nameMigrationClass = nameMigrationClass; + this.nameClass = nameClass; + this.begin = begin; + this.end = end; + } + + public MigrationClass(String nameMigrationClass, String nameClass, Version begin, Version end) { + this(nameMigrationClass,new SimpleProxyClass(nameClass),begin,end); + } + + /** + * @return the begin + */ + public Version getBegin() { + return begin; + } + + /** + * @param begin the begin to set + */ + public void setBegin(Version begin) { + this.begin = begin; + } + + /** + * @return the end + */ + public Version getEnd() { + return end; + } + + /** + * @param end the end to set + */ + public void setEnd(Version end) { + this.end = end; + } + + /** + * @return the nameClass + */ + public ProxyClass getNameClass() { + return nameClass; + } + + /** + * @param nameClass the nameClass to set + */ + public void setNameClass(ProxyClass nameClass) { + this.nameClass = nameClass; + } + + /** + * @return the nameMigrationClass + */ + public String getNameMigrationClass() { + return nameMigrationClass; + } + + /** + * @param nameMigrationClass the nameMigrationClass to set + */ + public void setNameMigrationClass(String nameMigrationClass) { + this.nameMigrationClass = nameMigrationClass; + } + + //DONE ? on compare sur les numero de version de departs + //posera peut etre un probleme quand on devra passer a quelque chose de plus complique + public int compareTo(MigrationClass o) { + return this.begin.compareTo(o.begin); + } + + /** + * + * @return le nom de la classe d'origine + * e.g. si la migration décrite est la migration de A vers B grace a la class MigrateBV1V2, alors cette methode renvoie A + */ + @SuppressWarnings("unchecked") + public ProxyClass getParentClassName(){ + ProxyClass result = null; + try { + //on charge la classe de migration + Class classOfMigration; + classOfMigration = (Class) ClassLoader.getSystemClassLoader().loadClass(this.nameMigrationClass); + //on si le nom de la classe n'est pas preciser, on l'invente; + result = classOfMigration.newInstance().migrateFrom(); + if (result==null) result = this.nameClass; + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + //log.debug("parent Classe : "+result); + return result; + } + + + public String toString(){ + return this.nameMigrationClass+"["+this.nameClass+":"+this.begin+"->"+this.end+"]"; + } + + + + + +} Index: topia-service/src/java/org/codelutin/topia/migration/transformation/AbstractMigration.java diff -u /dev/null topia-service/src/java/org/codelutin/topia/migration/transformation/AbstractMigration.java:1.1 --- /dev/null Mon Apr 2 14:24:43 2007 +++ topia-service/src/java/org/codelutin/topia/migration/transformation/AbstractMigration.java Mon Apr 2 14:24:37 2007 @@ -0,0 +1,62 @@ +/* *##% + * Copyright (C) 2007 Code Lutin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *##%*/ + +package org.codelutin.topia.migration.transformation; + +import java.io.Serializable; + +import org.codelutin.topia.migration.common.MapAdapter; +import org.codelutin.topia.migration.common.ProxyClass; + +/** + * AbstractMigration.java + * + * @author Chatellier Eric + * @author Chevallereau Benjamin + * @author Eon Sébastien + * @author Trève Vincent + * @version $Revision: 1.1 $ + * + * Last update : $Date: 2007/04/02 14:24:37 $ + */ +public abstract class AbstractMigration implements Migration { + + /** + * Modification de l'identifiant + * @param value L'ancienne valeur de l'identifiant + * @return La nouvelle valeur de l'identifiant + */ + public Serializable modifyId(Serializable value) { + return value; + } + + /** + * Nom de la classe depuis laquelle provient la nouvelle classe + * @return Le nom de la classe depuis laquelle provient la nouvelle classe ou null si le nom ne change pas + */ + public ProxyClass migrateFrom() { + return null; + } + + /** + * Effectue la migration + * @param map La map d'entree/sortie + * @param helper Le helper permettant d'acceder au autre tuple de la base + */ + public abstract void migrate(MapAdapter map, MapHelper helper); +} Index: topia-service/src/java/org/codelutin/topia/migration/transformation/Migration.java diff -u /dev/null topia-service/src/java/org/codelutin/topia/migration/transformation/Migration.java:1.1 --- /dev/null Mon Apr 2 14:24:43 2007 +++ topia-service/src/java/org/codelutin/topia/migration/transformation/Migration.java Mon Apr 2 14:24:37 2007 @@ -0,0 +1,57 @@ +/* *##% + * Copyright (C) 2007 Code Lutin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *##%*/ + +package org.codelutin.topia.migration.transformation; + +import java.io.Serializable; + +import org.codelutin.topia.migration.common.MapAdapter; +import org.codelutin.topia.migration.common.ProxyClass; + +/** + * Migration.java + * + * @author Chatellier Eric + * @author Chevallereau Benjamin + * @author Eon Sébastien + * @author Trève Vincent + * @version $Revision: 1.1 $ + * + * Last update : $Date: 2007/04/02 14:24:37 $ + */ +public interface Migration { + + /** + * Nom de la classe depuis laquelle provient la nouvelle classe + * @return Le nom de la classe depuis laquelle provient la nouvelle classe ou null si le nom ne change pas + */ + public ProxyClass migrateFrom(); + + /** + * Effectue la migration + * @param map La map d'entree/sortie + */ + public void migrate(MapAdapter map, MapHelper helper); + + /** + * Modification de l'identifiant + * @param value L'ancienne valeur de l'identifiant + * @return La nouvelle valeur de l'identifiant + */ + public Serializable modifyId(Serializable value); +} Index: topia-service/src/java/org/codelutin/topia/migration/transformation/MapHelper.java diff -u /dev/null topia-service/src/java/org/codelutin/topia/migration/transformation/MapHelper.java:1.1 --- /dev/null Mon Apr 2 14:24:43 2007 +++ topia-service/src/java/org/codelutin/topia/migration/transformation/MapHelper.java Mon Apr 2 14:24:37 2007 @@ -0,0 +1,103 @@ +/* *##% + * Copyright (C) 2007 Code Lutin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *##%*/ + +package org.codelutin.topia.migration.transformation; + +import java.io.Serializable; +import java.util.Collection; + +import org.codelutin.topia.migration.common.MapAdapter; +import org.codelutin.topia.migration.common.ProxyClass; +import org.codelutin.topia.migration.kernel.ObjectNotFound; + +/** + * MapHelper.java + * + * Permet d'acceder aux autres tuples, de l'etape de migration courante + * + * @author Chatellier Eric + * @author Chevallereau Benjamin + * @author Eon Sébastien + * @author Trève Vincent + * @version $Revision: 1.1 $ + * + * Last update : $Date: 2007/04/02 14:24:37 $ + */ +public interface MapHelper { + + /** + * Retourne un tuple d'une table des nouvelles bases + * @param clazz un proxy classe + * @param id l'id de l'objet + * @return le tuple + * @throws ObjectNotFound + */ + public MapAdapter getNewMap(ProxyClass clazz, Serializable id) throws ObjectNotFound; + + /** + * Retourne un tuple d'une table des nouvelles bases + * @param clazz le nom qualifié de la classe + * @param id l'id de l'objet + * @return le tuple + */ + public MapAdapter getNewMap(String clazz, Serializable id) throws ObjectNotFound; + + /** + * Retourne un tuple d'une table des annciennes bases + * @param clazz un proxy classe + * @param id l'id de l'objet + * @return le tuple + */ + public MapAdapter getOldMap(ProxyClass clazz, Serializable id) throws ObjectNotFound; + + /** + * Retourne un tuple d'une table des anciennes bases + * @param clazz le nom qualifié de la classe + * @param id l'id de l'objet + * @return le tuple + */ + public MapAdapter getOldMap(String clazz, Serializable id) throws ObjectNotFound; + + /** + * Retourne les tuples d'une table des anciennes bases + * @param clazz le nom qualifié de la classe + * @return les tuples + */ + public Collection getOldMaps(String clazz); + + /** + * Retourne les tuples d'une table des anciennes bases + * @param clazz un proxy classe + * @return les tuples + */ + public Collection getOldMaps(ProxyClass clazz); + + /** + * Retourne les tuples d'une table des nouvelles bases + * @param clazz le nom qualifié de la classe + * @return les tuples + */ + public Collection getNewMaps(String clazz); + + /** + * Retourne les tuples d'une table des nouvelles bases + * @param clazz un proxy classe + * @return les tuples + */ + public Collection getNewMaps(ProxyClass clazz); +} Index: topia-service/src/java/org/codelutin/topia/migration/transformation/MigrationNull.java diff -u /dev/null topia-service/src/java/org/codelutin/topia/migration/transformation/MigrationNull.java:1.1 --- /dev/null Mon Apr 2 14:24:43 2007 +++ topia-service/src/java/org/codelutin/topia/migration/transformation/MigrationNull.java Mon Apr 2 14:24:37 2007 @@ -0,0 +1,43 @@ +/* *##% + * Copyright (C) 2007 Code Lutin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *##%*/ + +package org.codelutin.topia.migration.transformation; + +import org.codelutin.topia.migration.common.MapAdapter; + +/** + * MigrationNull.java + * + * @author Chatellier Eric + * @author Chevallereau Benjamin + * @author Eon Sébastien + * @author Trève Vincent + * @version $Revision: 1.1 $ + * + * Last update : $Date: 2007/04/02 14:24:37 $ + */ +public class MigrationNull extends AbstractMigration { + + + /* (non-Javadoc) + * @see org.codelutin.topia.migration.transformation.Migration#migrate(org.codelutin.topia.migration.common.MapAdapter, org.codelutin.topia.migration.transformation.MapHelper) + */ + public void migrate(MapAdapter map, MapHelper helper) { + map.copyAll(); + } +} Index: topia-service/src/java/org/codelutin/topia/migration/transformation/FinderMigration.java diff -u /dev/null topia-service/src/java/org/codelutin/topia/migration/transformation/FinderMigration.java:1.1 --- /dev/null Mon Apr 2 14:24:43 2007 +++ topia-service/src/java/org/codelutin/topia/migration/transformation/FinderMigration.java Mon Apr 2 14:24:37 2007 @@ -0,0 +1,301 @@ +/* *##% + * Copyright (C) 2007 Code Lutin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *##%*/ + +package org.codelutin.topia.migration.transformation; + +import java.io.File; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.StringTokenizer; +import java.util.TreeSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.codelutin.topia.migration.common.ProxyClass; +import org.codelutin.topia.migration.common.Version; + +/** + * FinderMigration.java + * + * @author Chatellier Eric + * @author Chevallereau Benjamin + * @author Eon Sébastien + * @author Trève Vincent + * @version $Revision: 1.1 $ + * + * Last update : $Date: 2007/04/02 14:24:37 $ + */ +public class FinderMigration { + + /** + * Prefixe du nom des classes de migration. + */ + private static String prefix = "Migrate"; + + /** + * Ensemble des classes de migration + */ + private Map classes; + + /** + * Initialisé. + */ + private boolean init; + + /** + * Constructeur vide. + * + */ + public FinderMigration() { + classes = new HashMap(); + init = false; + } + + public FinderMigration(String _prefix) { + classes = new HashMap(); + FinderMigration.prefix = _prefix; + init = false; + } + + public void search() { + String classpath = System.getProperty("java.class.path"); + StringTokenizer chemins = new StringTokenizer(classpath, System + .getProperty("path.separator")); + while (chemins.hasMoreTokens()) { + searchClasses(chemins.nextToken(), true); + } + filterClasses(); + + init = true; + } + + public void search(String namePackage) { + char separator = File.separatorChar; + String path = namePackage.replace('.', separator); + String classpath = System.getProperty("java.class.path"); + StringTokenizer chemins = new StringTokenizer(classpath, System + .getProperty("path.separator")); + while (chemins.hasMoreTokens()) { + String pathTemp = new String(chemins.nextToken()); + File elementClasspath = new File(pathTemp); + if (elementClasspath.isDirectory()) { + if (pathTemp.charAt(pathTemp.length() - 1) != separator) { + pathTemp += separator; + } + pathTemp += path; + searchClasses(pathTemp, true); + } + } + filterClasses(); + + init = true; + } + + private void searchClasses(String path, boolean reccursive) { + File elementClasspath = new File(path); + if (elementClasspath.isDirectory()) { + + if (reccursive = true) { + File[] tab = elementClasspath.listFiles(); + for (int i = 0; i < tab.length; i++) { + searchClasses(tab[i].getAbsolutePath(), false); + } + } + + } else { + String name = elementClasspath.getName(); + if (name.endsWith(".class")) { + classes.put(name.substring(0, name.length() - 6), null); + } + } + } + + private void filterClasses() { + Set s = classes.keySet(); + Map classes_tmp = new HashMap(classes); + for (Iterator iter = s.iterator(); iter.hasNext();) { + String element = (String) iter.next(); + if (!(selectClasseByNameFile(element))) { + classes_tmp.remove(element); + } + } + + s = classes_tmp.keySet(); + for (Iterator iter = s.iterator(); iter.hasNext();) { + String element = (String) iter.next(); + classes_tmp.put(element, classes.get(element)); + } + + classes = classes_tmp; + } + + @SuppressWarnings("unchecked") + private boolean selectClasseByNameFile(String name) { + boolean selected = false; + + Pattern pattern = Pattern.compile(prefix + + "(.*)V([0-9]*(_[0-9]*)*)V([0-9](_*[0-9]*)*)"); + Matcher matcher = pattern.matcher(name); + + if (matcher.find()) { + selected = true; + + int inameclass = 1; + int ivdeb = 2; + int ivfin = 4; + + Version vdeb = new Version(); + Version vfin = new Version(); + String nameClass = new String(); + Map map = new HashMap(); + + if ((ivdeb <= matcher.groupCount()) + && (ivfin <= matcher.groupCount()) + && (inameclass <= matcher.groupCount())) { + vdeb.setVersion(String.valueOf(matcher.group(ivdeb).replace( + "_", "."))); + vfin.setVersion(String.valueOf(matcher.group(ivfin).replace( + "_", "."))); + nameClass = matcher.group(inameclass); + } + + map.put("begin", vdeb); + map.put("end", vfin); + map.put("class", nameClass); + + classes.put(name, map); + } + + return selected; + } + + /** + * @return the prefix + */ + public static String getPrefix() { + return prefix; + } + + /** + * @param prefix + * the prefix to set + */ + public static void setPrefix(String prefix) { + FinderMigration.prefix = prefix; + } + + /** + * + * @param nameClass + * le nom absolu de la classe + * @return les classes de migration + */ + public Set getMigrationClasses(String nameClass) { + String _nameClass = null; + String namePackage = new String(); + + StringTokenizer token = new StringTokenizer(nameClass, "."); + int nb = token.countTokens(); + int i = 1; + while (token.hasMoreTokens()) { + if (i < nb) { + namePackage += token.nextToken(); + if (i < nb - 1) { + namePackage += "."; + } + } else { + _nameClass = token.nextToken(); + } + i++; + } + + if (!init) { + search(namePackage); + init = true; + } + + Set result = new HashSet(); + Set s = classes.keySet(); + for (Iterator iter = s.iterator(); iter.hasNext();) { + String element = (String) iter.next(); + Map m = classes.get(element); + + if (m.get("class").equals(_nameClass)) { + MigrationClass mi = new MigrationClass(namePackage +"."+ element, + namePackage +"."+ String.valueOf(m.get("class")), + (Version) m.get("begin"), (Version) m.get("end")); + result.add(mi); + } + } + return result; + } + + public List loadSortedListOfMigrationFor( + String cannonicalName) { + return sortMigrations(getMigrationClasses(cannonicalName)); + } + + public List loadSortedListOfMigrationFor(String canonicalName, Version minVersion){ + SetMigrationClasses = getMigrationClasses(canonicalName); + Set temp = new HashSet(); + for(MigrationClass m : MigrationClasses){ + if(m.getBegin().compareTo(minVersion)>=0){ + temp.add(m); + } + } + List result = sortMigrations(temp); + + return result; + } + + // choisi dans la collection les modification a effectuer et les met dans + // l'ordre + private List sortMigrations( + Collection migrations) { + + // pour l'instant on trie juste les transformations selon leur n° de + // version de depart + SortedSet preresult = new TreeSet(); + List result = new LinkedList(); + preresult.addAll(migrations); + Iterator it = preresult.iterator(); + while (it.hasNext()) { + MigrationClass m = it.next(); + result.add(m); + } + return result; + } + + public MigrationClass getMigrationClass(ProxyClass klass, Version base, Version next) { + Set list = this.getMigrationClasses(klass.getCanonicalName()); + for(MigrationClass m : list){ + if(base.equals(m.getBegin()) && next.equals(m.getEnd())){ + return m; + } + } + return null; + } + +}