Index: topia-service/src/java/org/codelutin/topia/migration/DatabaseManager.java
diff -u topia-service/src/java/org/codelutin/topia/migration/DatabaseManager.java:1.4 topia-service/src/java/org/codelutin/topia/migration/DatabaseManager.java:1.5
--- topia-service/src/java/org/codelutin/topia/migration/DatabaseManager.java:1.4 Fri Nov 9 17:18:03 2007
+++ topia-service/src/java/org/codelutin/topia/migration/DatabaseManager.java Tue Nov 20 15:16:35 2007
@@ -18,6 +18,8 @@
package org.codelutin.topia.migration;
+import java.sql.Connection;
+import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
@@ -29,13 +31,19 @@
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
+import org.hibernate.connection.ConnectionProvider;
+import org.hibernate.connection.ConnectionProviderFactory;
+import org.hibernate.dialect.Dialect;
import org.hibernate.exception.JDBCConnectionException;
import org.hibernate.exception.SQLGrammarException;
import org.hibernate.mapping.ForeignKey;
import org.hibernate.mapping.Table;
+import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
import org.hibernate.tool.hbm2ddl.SchemaExport;
+import org.hibernate.tool.hbm2ddl.TableMetadata;
/**
* DatabaseManager.java
@@ -47,9 +55,9 @@
* @author Chevallereau Benjamin
* @author Eon Sébastien
* @author Trève Vincent
- * @version $Revision: 1.4 $
+ * @version $Revision: 1.5 $
*
- * Last update : $Date: 2007-11-09 17:18:03 $
+ * Last update : $Date: 2007-11-20 15:16:35 $
*/
public class DatabaseManager {
@@ -104,17 +112,18 @@
* Retourne la version de la base
* @return la version present en base, ou null si la version ne peut pas etre determinee
*/
- public Version getDataBaseVersion() throws TopiaMigrationServiceException {
+ public Version getDataBaseVersion() throws MigrationServiceException {
Version version = null;
logger.debug("Begin transaction to get version in database");
+ // get session
+ Session session = sessionFactory.openSession();
+
try {
- // get session
- Session session = sessionFactory.getCurrentSession();
-
+
// debut d'une transaction
- session.beginTransaction();
+ Transaction tx = session.beginTransaction();
// execute query
TMSVersion result = (TMSVersion)session.createCriteria(TMSVersion.class).uniqueResult();
@@ -127,10 +136,10 @@
}
// commit
- session.getTransaction().commit();
+ tx.commit();
}
catch(JDBCConnectionException e) {
- throw new TopiaMigrationServiceException("Connection to database refused, check your configuration !");
+ throw new MigrationServiceException("Connection to database refused, check your configuration !");
}
catch(SQLGrammarException e) {
// si la table n'existe pas, on obtient une exception : base non versionnee
@@ -139,6 +148,9 @@
// on retourn null
version = null;
}
+ finally {
+ session.close();
+ }
return version;
}
@@ -154,10 +166,10 @@
logger.debug("Renaming tables in configuration and database for version " + vdbVersion.getVersion());
// get session
- Session session = sessionFactory.getCurrentSession();
+ Session session = sessionFactory.openSession();
// debut d'une transaction
- session.beginTransaction();
+ Transaction tx = session.beginTransaction();
// DONE : voir si les relation *<->* sont listees par l'iterateur
// -> ok, normalement c bon, c gere
@@ -193,7 +205,10 @@
}
// commit
- session.getTransaction().commit();
+ tx.commit();
+
+ // close
+ session.close();
}
/**
@@ -293,17 +308,18 @@
/**
* Introduit la version du nouveau schema dans la base
- * @throws TopiaMigrationServiceException
+ * @param newVersion la version
*/
- public void putVersionInDatabase(Version nouvelleVersion) {
+ public void putVersionInDatabase(Version newVersion) {
// get session
- Session session = sessionFactory.getCurrentSession();
+ Session session = sessionFactory.openSession();
// debut d'une transaction
- session.beginTransaction();
+ Transaction tx = session.beginTransaction();
logger.debug("Deleting existing versions");
+
// supprime les versions existants
// au pire, on pourrait remplacer la premiere
// execute query
@@ -315,56 +331,24 @@
}
// positionne la version
- logger.debug("Setting database version to " + nouvelleVersion.getVersion());
- TMSVersion version = new TMSVersion(nouvelleVersion.getVersion());
+ logger.debug("Setting database version to " + newVersion.getVersion());
+ TMSVersion version = new TMSVersion(newVersion.getVersion());
session.save(version);
// commit
- session.getTransaction().commit();
+ tx.commit();
+
+ // session close
+ session.close();
}
/**
* Supprime les tables des l'ancien mapping
*
- * ATTENTION : pour H2 apparement, les version anterieures à 'Version 1.0 / 2007-03-04'
- * bug pour la suppression des tables (erreur de lock)
- *
- * Postgres gere les dépendances entres les tables
- * il faut les supprimer dans l'ordre...
- *
* @param oldConfiguration configuration contenant le schema
*/
public void removeTablesFromOldMapping(Configuration oldConfiguration) {
-
- /*logger.debug("Removing tables from old mapping");
- // get session
- Session session = sessionFactory.getCurrentSession();
-
- // debut d'une transaction
- session.beginTransaction();
-
- // les relations *<->* sont listees par l'iterateur
- Iterator i = oldConfiguration.getTableMappings();
- while(i.hasNext()) {
- Table table = (Table)i.next();
-
- String tableName = table.getName();
- // en fait, le nom de la table dans la configuration est deja versionne
-
- // TODO table existe pas
- logger.debug("Deleting table " + tableName);
- String sQuery = "DROP TABLE " + tableName + " cascade";
- //logger.debug("Query : " + sQuery);
-
- // TODO utilsation des dialect pour etre sur d'avoir des requete correctes ?
-
- SQLQuery sqlq = session.createSQLQuery(sQuery);
- sqlq.executeUpdate();
- }
-
- // commit
- session.getTransaction().commit();*/
if(logger.isDebugEnabled()) {
logger.debug("Removing schema");
@@ -372,16 +356,7 @@
dropSchema(oldConfiguration);
}
- /**
- * Se deconnecte
- */
- public void disconnect() {
- //nettoye
- sessionFactory.getCurrentSession().close();
- sessionFactory.close();
- }
-
- /**
+ /**
* Return table suffix name
*
* @param version version
@@ -391,4 +366,52 @@
String suffix = VERSIONNED_TABLES_SUFFIX + version.getValidName();
return suffix;
}
+
+ /**
+ * Test si les tables correspondant a une configuration existent.
+ *
+ * Test si au moins une table de la configuration existe.
+ *
+ * @param configuration la configuration
+ * @return true si le schema existe
+ */
+ public boolean isSchemaExist(Configuration configuration) {
+
+ boolean exist = false;
+
+ Dialect dialect = Dialect.getDialect(configuration.getProperties());
+ ConnectionProvider connectionProvider = ConnectionProviderFactory.newConnectionProvider( configuration.getProperties() );
+
+ try {
+
+ Iterator
tables = configuration.getTableMappings();
+
+ if(tables.hasNext()) {
+ Table testTable = tables.next();
+
+ Connection connection = connectionProvider.getConnection();
+
+ DatabaseMetadata meta = new DatabaseMetadata( connection, dialect );
+
+ TableMetadata tmd = meta.getTableMetadata(testTable.getName(), testTable.getSchema(), testTable.getCatalog(), testTable.isQuoted());
+
+ if(tmd!=null) { //table not found
+ exist = true;
+ }
+ }
+
+ } catch (SQLException e) {
+ logger.error("Cant connect to database",e);
+ }
+
+ return exist;
+ }
+
+ /**
+ * Se deconnecte
+ */
+ public void disconnect() {
+ //nettoye
+ sessionFactory.close();
+ }
}
Index: topia-service/src/java/org/codelutin/topia/migration/TopiaMigrationService.java
diff -u topia-service/src/java/org/codelutin/topia/migration/TopiaMigrationService.java:1.2 topia-service/src/java/org/codelutin/topia/migration/TopiaMigrationService.java:1.3
--- topia-service/src/java/org/codelutin/topia/migration/TopiaMigrationService.java:1.2 Wed Nov 14 17:36:11 2007
+++ topia-service/src/java/org/codelutin/topia/migration/TopiaMigrationService.java Tue Nov 20 15:16:36 2007
@@ -18,9 +18,8 @@
package org.codelutin.topia.migration;
+import org.codelutin.topia.event.TopiaContextListener;
import org.codelutin.topia.framework.TopiaService;
-import org.codelutin.topia.migration.callback.MigrationCallbackHandler;
-import org.hibernate.cfg.Configuration;
/**
* TopiaMigrationService.java
@@ -29,71 +28,14 @@
* @author Chevallereau Benjamin
* @author Eon Sébastien
* @author Trève Vincent
- * @version $Revision: 1.2 $
+ * @version $Revision: 1.3 $
*
- * Last update : $Date: 2007-11-14 17:36:11 $
+ * Last update : $Date: 2007-11-20 15:16:36 $
*/
-public interface TopiaMigrationService extends TopiaService {
+public interface TopiaMigrationService extends TopiaService, TopiaContextListener {
/**
* Nom du service
*/
public static final String SERVICE_NAME = "migration";
-
- /**
- * Renvoie le chemin du ficier de configuration utilise
- * @return Chemin du fichier de configuration
- */
- public String getConfigurationFile();
-
- /**
- * Modifie le fichier de configuration
- * @param configurationFile Chemin du fichier de configuration d'hibernate
- */
- public void setConfigurationFile(String configurationFile);
-
- /**
- * Retourne la configuration
- * @return la configuration
- * @see org.hibernate.cfg.Configuration
- */
- public Configuration getConfiguration();
-
- /**
- * Renseigne la configuration
- * @param configuration la configuration
- * @see org.hibernate.cfg.Configuration
- */
- public void setConfiguration(Configuration configuration);
-
- /**
- * Retourne le repertoire des anciens schemas
- * @return Le repertoire des anciens schemas
- */
- public String getMappingsDirectory();
-
- /**
- * Modifie le chemin du dossier des anciens schemas
- * @param mappingsDirectory Le chemin du dossier des anciens schemas
- */
- public void setMappingsDirectory(String mappingsDirectory);
-
- /**
- * Change la version courante
- * @param version la version
- */
- public void setApplicationVersion(String version);
-
- /**
- * Ajoute un callbackhandler pour la migration
- */
- public void addMigrationCallbackHandler(MigrationCallbackHandler callbackHandler);
-
- /**
- * Migrate the schema
- *
- * @return true si la migration a ete effectuee et s'est bien passee, false sinon
- * @throws TopiaMigrationServiceException dans le cas ou le schema ne peut pas etre mis a jour
- */
- public boolean migrateSchema() throws TopiaMigrationServiceException;
}
\ No newline at end of file
Index: topia-service/src/java/org/codelutin/topia/migration/TopiaMigrationServiceImpl.java
diff -u topia-service/src/java/org/codelutin/topia/migration/TopiaMigrationServiceImpl.java:1.8 topia-service/src/java/org/codelutin/topia/migration/TopiaMigrationServiceImpl.java:1.9
--- topia-service/src/java/org/codelutin/topia/migration/TopiaMigrationServiceImpl.java:1.8 Wed Nov 14 17:36:11 2007
+++ topia-service/src/java/org/codelutin/topia/migration/TopiaMigrationServiceImpl.java Tue Nov 20 15:16:36 2007
@@ -19,27 +19,16 @@
package org.codelutin.topia.migration;
import java.io.File;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
import java.util.Properties;
-import java.util.SortedMap;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.codelutin.topia.TopiaRuntimeException;
+import org.codelutin.topia.event.TopiaContextEvent;
+import org.codelutin.topia.framework.TopiaContextImpl;
import org.codelutin.topia.framework.TopiaContextImplementor;
import org.codelutin.topia.migration.callback.MigrationCallbackHandler;
import org.codelutin.topia.migration.common.Version;
-import org.codelutin.topia.migration.kernel.ConfigurationAdapter;
-import org.codelutin.topia.migration.kernel.ConfigurationHelper;
-import org.codelutin.topia.migration.kernel.Transformer;
-import org.codelutin.util.Resource;
import org.hibernate.cfg.Configuration;
/**
@@ -51,11 +40,11 @@
* @author Chevallereau Benjamin
* @author Eon S�bastien
* @author Tr�ve Vincent
- * @version $Revision: 1.8 $
+ * @version $Revision: 1.9 $
*
- * Last update : $Date: 2007-11-14 17:36:11 $
+ * Last update : $Date: 2007-11-20 15:16:36 $
*/
-public class TopiaMigrationServiceImpl implements TopiaMigrationService {
+public class TopiaMigrationServiceImpl extends MigrationServiceImpl implements TopiaMigrationService {
/**
* Nom des proprietes
@@ -72,51 +61,15 @@
static final protected String TOPIA_PERSISTENCE_CLASSES = "topia.persistence.classes";
/**
- * Nom courant du fichier de configuration.
- */
- protected String currentHibernateConfigurationFile;
-
- /**
- * Configuration hibernate courante utilisee par l'application
- */
- protected Configuration currentApplicationConfiguration;
-
- /**
- * Chemin du dossier contenant les schema de touts les versions
- */
- protected String mappingsDirectory;
-
- /**
- * Version courante de l'application
- */
- protected Version currentApplicationVersion;
-
- /**
- * CallbackHandler list
- */
- protected List migrationCallBackHandlers;
-
- /**
* Logger (common-logging)
*/
private static Log logger = LogFactory.getLog(TopiaMigrationServiceImpl.class);
/**
* Constructeur vide.
- *
- * Visibilite package (contruite par la factory).
- *
*/
public TopiaMigrationServiceImpl() {
super();
-
- // init the configuration file
- currentHibernateConfigurationFile = null;
- // init configuration
- currentApplicationConfiguration = null;
-
- // init callbask list
- migrationCallBackHandlers = new LinkedList();
}
/* (non-Javadoc)
@@ -136,7 +89,7 @@
/* (non-Javadoc)
* @see org.codelutin.topia.framework.TopiaService#preInit(org.codelutin.topia.framework.TopiaContextImplementor)
*/
- public void preInit(TopiaContextImplementor context) {
+ public boolean preInit(TopiaContextImplementor context) {
Properties config = context.getConfig();
String mappingdir = config.getProperty(MIGRATION_PREVIOUS_MAPPING_DIRECTORY, null);
@@ -230,6 +183,8 @@
}
}
+ // add topia context listener
+ context.addTopiaContextListener(this);
// test mappingdir null
if(mappingdir == null) {
@@ -247,361 +202,70 @@
for(String modelname : modelnames) {
this.setMappingsDirectory(mappingdir + File.separator + modelname);
+ boolean complete = false;
+
try {
// migration
- migrateSchema();
+ complete = migrateSchema();
}
- catch(TopiaMigrationServiceException e) {
+ catch(MigrationServiceException e) {
logger.error("Can't migrate schema", e);
}
+
+
+ if(!complete) {
+ if(logger.isDebugEnabled()) {
+ logger.error("Database migration not complete");
+ }
+ throw new TopiaRuntimeException("Database migration not succesfully ended !");
+ }
}
}
}
+
+ return true;
}
/* (non-Javadoc)
* @see org.codelutin.topia.framework.TopiaService#postInit(org.codelutin.topia.framework.TopiaContextImplementor)
*/
- public void postInit(TopiaContextImplementor context) {
-
- }
-
- /* (non-Javadoc)
- * @see org.codelutin.topia.migration.TopiaMigrationService#getConfigurationFile()
- */
- public String getConfigurationFile() {
- return currentHibernateConfigurationFile;
- }
-
- /* (non-Javadoc)
- * @see org.codelutin.topia.migration.TopiaMigrationService#setConfigurationFile(java.lang.String)
- */
- public void setConfigurationFile(String hibernateConfigurationFile) {
- this.currentHibernateConfigurationFile = hibernateConfigurationFile;
+ public boolean postInit(TopiaContextImplementor context) {
+ return true;
}
- /* (non-Javadoc)
- * @see org.codelutin.topia.migration.TopiaMigrationService#getConfiguration()
- */
- public Configuration getConfiguration() {
- return currentApplicationConfiguration;
- }
-
- /* (non-Javadoc)
- * @see org.codelutin.topia.migration.TopiaMigrationService#setConfiguration(org.hibernate.cfg.Configuration)
- */
- public void setConfiguration(Configuration configuration) {
- this.currentApplicationConfiguration = configuration;
- }
-
- /* (non-Javadoc)
- * @see org.codelutin.topia.migration.TopiaMigrationService#getMappingsDirectory()
- */
- public String getMappingsDirectory() {
- return mappingsDirectory;
- }
-
- /* (non-Javadoc)
- * @see org.codelutin.topia.migration.TopiaMigrationService#setMappingsDirectory(java.lang.String)
- */
- public void setMappingsDirectory(String mappingsDirectory) {
- this.mappingsDirectory = mappingsDirectory;
- }
-
- /* (non-Javadoc)
- * @see org.codelutin.topia.migration.TopiaMigrationService#setApplicationVersion(java.lang.String)
- */
- public void setApplicationVersion(String version) {
- currentApplicationVersion = new Version(version);
- }
-
- /* (non-Javadoc)
- * @see org.codelutin.topia.migration.TopiaMigrationService#addMigrationCallbackHandler(org.codelutin.topia.migration.callback.MigrationCallbackHandler)
+ /* (non-Javadoc)
+ * @see org.codelutin.topia.event.TopiaContextListener#postCreateSchema(org.codelutin.topia.event.TopiaContextEvent)
*/
- public void addMigrationCallbackHandler(
- MigrationCallbackHandler callbackHandler) {
- migrationCallBackHandlers.add(callbackHandler);
+ public void postCreateSchema(TopiaContextEvent event) {
+
+ if(logger.isDebugEnabled()) {
+ logger.debug("postCreateSchema event called : put version in database");
+ }
+
+ TopiaContextImplementor context = (TopiaContextImplementor)event.getSource();
+
+ Version version = new Version(context.getConfig().getProperty(MIGRATION_APPLICATION_VERSION, null));
+ putVersionInDatabase(context.getConfig(), version , true);
}
-
- /**
- * Charge la configuration locale si elle n'est pas deja ete fournit
- */
- protected void loadApplicationConfiguration() {
-
- // configuration pas deja fournit
- if(this.currentApplicationConfiguration == null) {
- // creation
- this.currentApplicationConfiguration = new Configuration();
-
- if ( this.currentHibernateConfigurationFile != null ) {
- logger.debug("Loading configuration file : " + this.currentHibernateConfigurationFile);
-
- // chargement via l'objet configuration dhibernate
- currentApplicationConfiguration.configure(this.currentHibernateConfigurationFile);
- }
- else {
- logger.debug("Loading configuration file : default hibernate configuration file");
-
- // chargement via l'objet configuration dhibernate
- currentApplicationConfiguration.configure();
- }
- }
- else {
- // log
- logger.debug("Configuration given, nothing to load");
- }
- }
-
- /* (non-Javadoc)
- * @see org.codelutin.topia.migration.TopiaMigrationService#migrateSchema()
- */
- public boolean migrateSchema() throws TopiaMigrationServiceException {
- /*temp*/long timeBegin = System.currentTimeMillis();
+ /* (non-Javadoc)
+ * @see org.codelutin.topia.event.TopiaContextListener#postUpdateSchema(org.codelutin.topia.event.TopiaContextEvent)
+ */
+ public void postUpdateSchema(TopiaContextEvent event) {
- // return flag
- boolean schemaMigrated = false;
-
- // log
- logger.info("Starting Topia Migration Service");
-
- // check that version is set
- if(this.currentApplicationVersion == null) {
- throw new TopiaMigrationServiceException("No version set");
- }
-
- // check that shema location is set
- if(this.mappingsDirectory == null) {
- throw new TopiaMigrationServiceException("No old mapping directory set");
- }
-
- // chargement de la configuration de l'application
- loadApplicationConfiguration();
-
- // initie un DatabaseManager
- // fournit les propietes de connection a la base (properties)
- DatabaseManager dbManager = new DatabaseManager(this.currentApplicationConfiguration.getProperties());
-
- // recupere la version de la base
- Version vdbVersion = dbManager.getDataBaseVersion();
-
- // si la version n'a pas ete trouvee
- if(vdbVersion == null) {
- // la base dans ce cas n'est pas versionee.
- // On dit que la version de la base est 0
- // et les schema de cette version 0 doivent
- // etre detenu en local
- vdbVersion = Version.VZERO;
-
- logger.info("Database version not found, so database schema is considered as V0");
-
- // si la base n'etait pas versionnee, la table version n'existe pas
- // creation
- dbManager.createVersionTable();
- }
-
- logger.info("Application version : " + currentApplicationVersion.getVersion() + ", database version : " + vdbVersion.getVersion());
-
- /*temp*/long timeEnd = System.currentTimeMillis();
-
- /*temp*/logger.error("[Time] get db version took : " + (timeEnd - timeBegin) + " ms");
-
- // ask handler for migration
- boolean doMigration;
- // vdbVersion < currentApplicationVersion
- if(vdbVersion.compareTo(currentApplicationVersion) < 0) {
- logger.info("Database need update");
-
- doMigration = askHandlerForMigration(vdbVersion.getVersion(),currentApplicationVersion.getVersion());
-
- schemaMigrated = doMigration;
- }
- else {
- doMigration = false;
- schemaMigrated = true; // normal behaviour
- logger.info("Database is up to date, no migration needed.");
- }
-
- // si la migration doit etre faite
- if(doMigration) {
-
- /*temp*/timeBegin = System.currentTimeMillis();
-
- logger.info("Database need update");
-
- // ici, on charge toutes les configuration, entre >= vdbVersion et < currentApplicationVersion
- Map mVersionAndConfigurationMap = loadOldConfigurations(vdbVersion);
-
- // Les configurationAdpater pour le kernel
- SortedMap smVersionAndConfigurationAdapterMap = new TreeMap();
-
- // les configurations sont chargees
- // on doit :
- // - pour la version vdbVersion, on utilise les tables deja en base
- // - pour les autres, creer les tables (suffixees avec la version)
- // - creation du schema courant
-
- logger.debug("Set old database from old mappings");
-
- // en meme temps, on construit les ConfigurationAdapter pour le noyau
- for(Map.Entry entry : mVersionAndConfigurationMap.entrySet()) {
- Version vVersion = entry.getKey();
- Configuration cConfiguration = entry.getValue();
-
- //ConfigurationHelper.getConfigurationForVersion(v)
- // ne positionne pas les properties parce qu'elle n'en a pas connaissance
- // on les met ici
- cConfiguration.setProperties(this.currentApplicationConfiguration.getProperties());
-
- // renommage des table
- // et creation des schema intermediaires
- if(!vVersion.equals(vdbVersion)) {
- cConfiguration = dbManager.setRenamedTableSchema(cConfiguration,vVersion);
- logger.debug("Creating schema for version : " + vVersion.getVersion());
- dbManager.setApplicationSchemaInDatabase(cConfiguration);
- }
-
- // on construit les ConfigurationAdpater
- ConfigurationAdapter cfgAdpater = new ConfigurationAdapter(cConfiguration,vVersion);
- smVersionAndConfigurationAdapterMap.put(vVersion, cfgAdpater);
- }
-
- // enfin, il reste la configuration de l'application
- // on va instancier le nouveau schema (le creer)
-
- // on renomme le nom des table d'abord
- this.currentApplicationConfiguration = dbManager.setRenamedTableSchema(this.currentApplicationConfiguration,this.currentApplicationVersion);
-
- logger.debug("Creating current application schema");
- dbManager.setApplicationSchemaInDatabase(this.currentApplicationConfiguration);
-
- ConfigurationAdapter appCfgAdpater = new ConfigurationAdapter(this.currentApplicationConfiguration,this.currentApplicationVersion);
- smVersionAndConfigurationAdapterMap.put(this.currentApplicationVersion, appCfgAdpater);
-
- logger.info("Data migration");
-
- // Ici, on a l'ancien schema deja present en base
- // les schemas intermediaires creer et vides
- // et le nouveau schema cree et vide
- // on doit maintenant migrer les donnees
-
- // execute la transformation
- Transformer trans = new Transformer(smVersionAndConfigurationAdapterMap);
-
- // migrate data
- trans.execute();
-
- // log
- logger.info("Data migrated");
-
- // Changement de la version en base
- dbManager.putVersionInDatabase(currentApplicationVersion);
-
- logger.debug("Deleting old database");
-
- // suppresion des anciennes tables de toutes les configuration, sauf
- // currentApplicationVersion
- // (elle n'est pas dans mVersionAndConfigurationMap)
- for(Configuration cfg : mVersionAndConfigurationMap.values()) {
- dbManager.removeTablesFromOldMapping(cfg);
- }
-
- // renommage correct du schema courant
- dbManager.renameTables(this.currentApplicationConfiguration, this.currentApplicationVersion);
-
- // il faudrait ici valider les transactions et fermer les sessions
- // vmvManager a sa propre gestion des transactions/session
- // this.remoteConfiguration doit en avoir ouverte
- // this.localConfiguration aussi
-
- // all done
- logger.info("All done, migration complete");
-
- /*temp*/timeEnd = System.currentTimeMillis();
- /*temp*/logger.error("[Time] migration took : " + (timeEnd - timeBegin) + " ms");
-
- }
-
- // ferme la connexion a la base
- dbManager.disconnect();
-
- return schemaMigrated;
- }
+ }
- /**
- * Ask handler for migration.
- *
- * Return true if all handler return true, or if there is no handler
- *
- * @return true or false
+ /* (non-Javadoc)
+ * @see org.codelutin.topia.event.TopiaContextListener#preCreateSchema(org.codelutin.topia.event.TopiaContextEvent)
*/
- protected boolean askHandlerForMigration(String databaseVersion, String applicationVersion) {
+ public void preCreateSchema(TopiaContextEvent event) {
- // true par defaut, s'il n'y a pas de handlers
- boolean result = true;
-
- for(MigrationCallbackHandler callback : migrationCallBackHandlers) {
- result &= callback.doMigration(databaseVersion, applicationVersion);
- }
-
- return result;
}
- /**
- * Charge les configurations de version a partir de vdbVersion
- * jusqu'a currentApplicationVersion "non compris"
- * @param vdbVersion la version de depart
- */
- protected Map loadOldConfigurations(Version vdbVersion) {
- // schema des noms de dossier de version
- final Pattern pattern = Pattern.compile(mappingsDirectory + File.separator + "([0-9]+(\\.[0-9]+)*)");
-
- // instancie la map ordonee
- Map mVersionAndConfigurationMap = null;
-
- List urls = null;
- urls = Resource.getURLs(".*" + mappingsDirectory + File.separator + ".*");
-
- if (urls != null && urls.size() > 0) {
-
- mVersionAndConfigurationMap = new HashMap();
-
- // ensemble ordonnee des version a charger apres
- TreeSet tsEnsembleVersionACharger = new TreeSet();
-
- for(URL url : urls) {
- Matcher matcher = pattern.matcher(url.getFile());
-
- if(matcher.find()) {
- // group(1) est ce qui match entre le premier niveau de parentheses
- String sVersion = matcher.group(1);
- //logger.debug("Directory " + fileInIt.getName() + " matches, version = " + sVersion);
-
- tsEnsembleVersionACharger.add(new Version(sVersion));
- }
- }
-
- ConfigurationHelper cfgHelper = new ConfigurationHelper();
-
- // charge les version qui conviennent
- for(Version v : tsEnsembleVersionACharger) {
- if(v.compareTo(vdbVersion) < 0) {
- logger.debug("No load needed for version " + v.getVersion());
- }
- else {
- logger.debug("Loading mapping for version " + v.getVersion());
-
- String mappingVersionDir = mappingsDirectory + File.separator + v.getVersion();
-
- Configuration cfgForVersion = cfgHelper.getConfigurationInDirectory(mappingVersionDir);
- mVersionAndConfigurationMap.put(v, cfgForVersion);
- }
- }
- }
- else {
- logger.error("No mapping found in classpath '" + mappingsDirectory + "'; can't load old mappings");
- }
-
- return mVersionAndConfigurationMap;
- }
+ /* (non-Javadoc)
+ * @see org.codelutin.topia.event.TopiaContextListener#preUpdateSchema(org.codelutin.topia.event.TopiaContextEvent)
+ */
+ public void preUpdateSchema(TopiaContextEvent event) {
+
+ }
}
Index: topia-service/src/java/org/codelutin/topia/migration/MigrationService.java
diff -u /dev/null topia-service/src/java/org/codelutin/topia/migration/MigrationService.java:1.1
--- /dev/null Tue Nov 20 15:16:42 2007
+++ topia-service/src/java/org/codelutin/topia/migration/MigrationService.java Tue Nov 20 15:16:35 2007
@@ -0,0 +1,93 @@
+/* *##%
+ * 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;
+
+import org.codelutin.topia.migration.callback.MigrationCallbackHandler;
+import org.hibernate.cfg.Configuration;
+
+/**
+ * MigrationService.java
+ *
+ * @author Chatellier Eric
+ * @author Chevallereau Benjamin
+ * @author Eon Sébastien
+ * @author Trève Vincent
+ * @version $Revision: 1.1 $
+ *
+ * Last update : $Date: 2007-11-20 15:16:35 $
+ */
+public interface MigrationService {
+
+ /**
+ * Renvoie le chemin du ficier de configuration utilise
+ * @return Chemin du fichier de configuration
+ */
+ public String getConfigurationFile();
+
+ /**
+ * Modifie le fichier de configuration
+ * @param configurationFile Chemin du fichier de configuration d'hibernate
+ */
+ public void setConfigurationFile(String configurationFile);
+
+ /**
+ * Retourne la configuration
+ * @return la configuration
+ * @see org.hibernate.cfg.Configuration
+ */
+ public Configuration getConfiguration();
+
+ /**
+ * Renseigne la configuration
+ * @param configuration la configuration
+ * @see org.hibernate.cfg.Configuration
+ */
+ public void setConfiguration(Configuration configuration);
+
+ /**
+ * Retourne le repertoire des anciens schemas
+ * @return Le repertoire des anciens schemas
+ */
+ public String getMappingsDirectory();
+
+ /**
+ * Modifie le chemin du dossier des anciens schemas
+ * @param mappingsDirectory Le chemin du dossier des anciens schemas
+ */
+ public void setMappingsDirectory(String mappingsDirectory);
+
+ /**
+ * Change la version courante
+ * @param version la version
+ */
+ public void setApplicationVersion(String version);
+
+ /**
+ * Ajoute un callbackhandler pour la migration
+ */
+ public void addMigrationCallbackHandler(MigrationCallbackHandler callbackHandler);
+
+ /**
+ * Migrate the schema
+ *
+ * @return true si la migration a ete effectuee et s'est bien passee, false sinon
+ * @throws MigrationServiceException dans le cas ou le schema ne peut pas etre mis a jour
+ */
+ public boolean migrateSchema() throws MigrationServiceException;
+}
\ No newline at end of file
Index: topia-service/src/java/org/codelutin/topia/migration/MigrationServiceException.java
diff -u /dev/null topia-service/src/java/org/codelutin/topia/migration/MigrationServiceException.java:1.1
--- /dev/null Tue Nov 20 15:16:44 2007
+++ topia-service/src/java/org/codelutin/topia/migration/MigrationServiceException.java Tue Nov 20 15:16:36 2007
@@ -0,0 +1,70 @@
+/* *##%
+ * 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;
+
+/**
+ * TopiaMigrationServiceException.java
+ *
+ * @author Chatellier Eric
+ * @author Chevallereau Benjamin
+ * @author Eon Sébastien
+ * @author Trève Vincent
+ * @version $Revision: 1.1 $
+ *
+ * Last update : $Date: 2007-11-20 15:16:36 $
+ */
+public class MigrationServiceException extends Exception {
+
+ /**
+ * Version
+ */
+ private static final long serialVersionUID = -8900901171551405745L;
+
+ /**
+ * Constructeur par defaut
+ */
+ public MigrationServiceException() {
+ super();
+ }
+
+ /**
+ * Constructeur avec message
+ * @param message Le message d'erreur
+ */
+ public MigrationServiceException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructeur avec message et exception
+ * @param message Le message d'erreur
+ * @param exception l'exception
+ */
+ public MigrationServiceException(String message, Throwable exception) {
+ super(message, exception);
+ }
+
+ /**
+ * Constructeur avec exception
+ * @param exception l'exception
+ */
+ public MigrationServiceException(Throwable exception) {
+ super(exception);
+ }
+}
Index: topia-service/src/java/org/codelutin/topia/migration/MigrationServiceImpl.java
diff -u /dev/null topia-service/src/java/org/codelutin/topia/migration/MigrationServiceImpl.java:1.1
--- /dev/null Tue Nov 20 15:16:44 2007
+++ topia-service/src/java/org/codelutin/topia/migration/MigrationServiceImpl.java Tue Nov 20 15:16:36 2007
@@ -0,0 +1,499 @@
+/* *##%
+ * 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;
+
+import java.io.File;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codelutin.topia.migration.callback.MigrationCallbackHandler;
+import org.codelutin.topia.migration.common.Version;
+import org.codelutin.topia.migration.kernel.ConfigurationAdapter;
+import org.codelutin.topia.migration.kernel.ConfigurationHelper;
+import org.codelutin.topia.migration.kernel.Transformer;
+import org.codelutin.util.Resource;
+import org.hibernate.cfg.Configuration;
+
+/**
+ * MigrationServiceImpl.java
+ *
+ * Classe principale du projet.
+ *
+ * @author Chatellier Eric
+ * @author Chevallereau Benjamin
+ * @author Eon S�bastien
+ * @author Tr�ve Vincent
+ * @version $Revision: 1.1 $
+ *
+ * Last update : $Date: 2007-11-20 15:16:36 $
+ */
+public class MigrationServiceImpl implements MigrationService {
+
+ /**
+ * Nom courant du fichier de configuration.
+ */
+ protected String currentHibernateConfigurationFile;
+
+ /**
+ * Configuration hibernate courante utilisee par l'application
+ */
+ protected Configuration currentApplicationConfiguration;
+
+ /**
+ * Chemin du dossier contenant les schema de touts les versions
+ */
+ protected String mappingsDirectory;
+
+ /**
+ * Version courante de l'application
+ */
+ protected Version currentApplicationVersion;
+
+ /**
+ * CallbackHandler list
+ */
+ protected List migrationCallBackHandlers;
+
+ /**
+ * Logger (common-logging)
+ */
+ private static Log logger = LogFactory.getLog(MigrationServiceImpl.class);
+
+ /**
+ * Constructeur vide.
+ */
+ public MigrationServiceImpl() {
+ super();
+
+ // init the configuration file
+ currentHibernateConfigurationFile = null;
+ // init configuration
+ currentApplicationConfiguration = null;
+
+ // init callbask list
+ migrationCallBackHandlers = new LinkedList();
+ }
+
+ /* (non-Javadoc)
+ * @see org.codelutin.topia.migration.TopiaMigrationService#getConfigurationFile()
+ */
+ public String getConfigurationFile() {
+ return currentHibernateConfigurationFile;
+ }
+
+ /* (non-Javadoc)
+ * @see org.codelutin.topia.migration.TopiaMigrationService#setConfigurationFile(java.lang.String)
+ */
+ public void setConfigurationFile(String hibernateConfigurationFile) {
+ this.currentHibernateConfigurationFile = hibernateConfigurationFile;
+ }
+
+ /* (non-Javadoc)
+ * @see org.codelutin.topia.migration.TopiaMigrationService#getConfiguration()
+ */
+ public Configuration getConfiguration() {
+ return currentApplicationConfiguration;
+ }
+
+ /* (non-Javadoc)
+ * @see org.codelutin.topia.migration.TopiaMigrationService#setConfiguration(org.hibernate.cfg.Configuration)
+ */
+ public void setConfiguration(Configuration configuration) {
+ this.currentApplicationConfiguration = configuration;
+ }
+
+ /* (non-Javadoc)
+ * @see org.codelutin.topia.migration.TopiaMigrationService#getMappingsDirectory()
+ */
+ public String getMappingsDirectory() {
+ return mappingsDirectory;
+ }
+
+ /* (non-Javadoc)
+ * @see org.codelutin.topia.migration.TopiaMigrationService#setMappingsDirectory(java.lang.String)
+ */
+ public void setMappingsDirectory(String mappingsDirectory) {
+ this.mappingsDirectory = mappingsDirectory;
+ }
+
+ /* (non-Javadoc)
+ * @see org.codelutin.topia.migration.TopiaMigrationService#setApplicationVersion(java.lang.String)
+ */
+ public void setApplicationVersion(String version) {
+ currentApplicationVersion = new Version(version);
+ }
+
+ /* (non-Javadoc)
+ * @see org.codelutin.topia.migration.TopiaMigrationService#addMigrationCallbackHandler(org.codelutin.topia.migration.callback.MigrationCallbackHandler)
+ */
+ public void addMigrationCallbackHandler(
+ MigrationCallbackHandler callbackHandler) {
+ migrationCallBackHandlers.add(callbackHandler);
+ }
+
+ /**
+ * Charge la configuration locale si elle n'est pas deja ete fournit
+ */
+ protected void loadApplicationConfiguration() {
+
+ // configuration pas deja fournit
+ if(this.currentApplicationConfiguration == null) {
+ // creation
+ this.currentApplicationConfiguration = new Configuration();
+
+ if ( this.currentHibernateConfigurationFile != null ) {
+ logger.debug("Loading configuration file : " + this.currentHibernateConfigurationFile);
+
+ // chargement via l'objet configuration dhibernate
+ currentApplicationConfiguration.configure(this.currentHibernateConfigurationFile);
+ }
+ else {
+ logger.debug("Loading configuration file : default hibernate configuration file");
+
+ // chargement via l'objet configuration dhibernate
+ currentApplicationConfiguration.configure();
+ }
+ }
+ else {
+ // log
+ logger.debug("Configuration given, nothing to load");
+ }
+ }
+
+ /**
+ * Verifie si les information indispensable à la migration ont été
+ * renseignee.
+ *
+ * @throws MigrationServiceException
+ */
+ protected void checkInformation() throws MigrationServiceException {
+ // check that version is set
+ if(this.currentApplicationVersion == null) {
+ throw new MigrationServiceException("No version set");
+ }
+
+ // check that shema location is set
+ if(this.mappingsDirectory == null) {
+ throw new MigrationServiceException("No old mapping directory set");
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.codelutin.topia.migration.TopiaMigrationService#migrateSchema()
+ */
+ public boolean migrateSchema() throws MigrationServiceException {
+
+ // log
+ logger.info("Starting Topia Migration Service");
+
+ // check informations
+ checkInformation();
+
+ // chargement de la configuration de l'application
+ loadApplicationConfiguration();
+
+ // initie un DatabaseManager
+ // fournit les propietes de connection a la base (properties)
+ DatabaseManager dbManager = new DatabaseManager(this.currentApplicationConfiguration.getProperties());
+
+ // recupere la version de la base
+ Version vdbVersion = dbManager.getDataBaseVersion();
+
+ // si la version n'a pas ete trouvee
+ if(vdbVersion == null) {
+ // la base dans ce cas n'est pas versionee.
+ // On dit que la version de la base est 0
+ // et les schema de cette version 0 doivent
+ // etre detenu en local
+ vdbVersion = Version.VZERO;
+
+ logger.info("Database version not found, so database schema is considered as V0");
+ }
+
+ logger.info("Application version : " + currentApplicationVersion.getVersion() + ", database version : " + vdbVersion.getVersion());
+
+ // tel if migration is needed
+ boolean bMigrationNeeded = false;
+ // tel if migration is wanted
+ boolean bMigrationWanted = true;
+
+ // test if schema exist in database...
+ // if not, the schema must be created
+ // and it will be created in version this.currentApplicationConfiguration
+ Configuration vdbConfiguration = getSingleConfiguration(vdbVersion);
+ vdbConfiguration.setProperties(currentApplicationConfiguration.getProperties());
+ bMigrationNeeded = dbManager.isSchemaExist(vdbConfiguration);
+ if(logger.isDebugEnabled()) {
+ if(bMigrationNeeded) {
+ logger.debug("Schema for version " + vdbVersion.getVersion() + " found. Can do migration.");
+ } else {
+ logger.debug("Schema for version " + vdbVersion.getVersion() + " not found. No migration needed.");
+ }
+ }
+
+ // vdbVersion < currentApplicationVersion
+ if(bMigrationNeeded && vdbVersion.compareTo(currentApplicationVersion) < 0) {
+
+ logger.info("Database need update");
+
+ bMigrationNeeded = true;
+ // ask handler for migration
+ bMigrationWanted = askHandlerForMigration(vdbVersion.getVersion(),currentApplicationVersion.getVersion());
+ }
+ else {
+ logger.info("Database is up to date, no migration needed.");
+ }
+
+ // si la migration doit etre faite
+ if(bMigrationNeeded && bMigrationWanted) {
+
+ logger.info("Beginning database migration");
+
+ // ici, on charge toutes les configuration, entre > vdbVersion et < currentApplicationVersion
+ Map mVersionAndConfigurationMap = loadIntermediateConfigurations(vdbVersion);
+
+ // vdbVersion mapping has been loaded earlier
+ // on construit les ConfigurationAdpater
+ mVersionAndConfigurationMap.put(vdbVersion, vdbConfiguration);
+
+ // Les configurationAdpater pour le kernel
+ SortedMap smVersionAndConfigurationAdapterMap = new TreeMap();
+
+ // les configurations sont chargees
+ // on doit :
+ // - pour la version vdbVersion, on utilise les tables deja en base
+ // - pour les autres, creer les tables (suffixees avec la version)
+ // - creation du schema courant
+ logger.debug("Set old database for old mappings");
+
+ // en meme temps, on construit les ConfigurationAdapter pour le noyau
+ for(Map.Entry entry : mVersionAndConfigurationMap.entrySet()) {
+ Version vVersion = entry.getKey();
+ Configuration cConfiguration = entry.getValue();
+
+ // la version vdbVersion a deja ses proprietes et ne doit pas etre renommee
+ if(!vdbVersion.equals(vVersion)) {
+ //ConfigurationHelper.getConfigurationForVersion(v)
+ // ne positionne pas les properties parce qu'elle n'en a pas connaissance
+ // on les met ici
+ cConfiguration.setProperties(this.currentApplicationConfiguration.getProperties());
+
+ // renommage des table
+ // et creation des schema intermediaires
+ cConfiguration = dbManager.setRenamedTableSchema(cConfiguration,vVersion);
+ logger.debug("Creating schema for version : " + vVersion.getVersion());
+ dbManager.setApplicationSchemaInDatabase(cConfiguration);
+ }
+
+ // on construit les ConfigurationAdpater
+ ConfigurationAdapter cfgAdpater = new ConfigurationAdapter(cConfiguration,vVersion);
+ smVersionAndConfigurationAdapterMap.put(vVersion, cfgAdpater);
+ }
+
+ // enfin, il reste la configuration de l'application
+ // on va instancier le nouveau schema (le creer)
+
+ // on renomme le nom des tables d'abord
+ this.currentApplicationConfiguration = dbManager.setRenamedTableSchema(this.currentApplicationConfiguration,this.currentApplicationVersion);
+
+ logger.debug("Creating current application schema");
+ dbManager.setApplicationSchemaInDatabase(this.currentApplicationConfiguration);
+
+ ConfigurationAdapter appCfgAdpater = new ConfigurationAdapter(this.currentApplicationConfiguration,this.currentApplicationVersion);
+ smVersionAndConfigurationAdapterMap.put(this.currentApplicationVersion, appCfgAdpater);
+
+ logger.info("Data migration");
+
+ // Ici, on a l'ancien schema deja present en base
+ // les schemas intermediaires creer et vides
+ // et le nouveau schema cree et vide
+ // on doit maintenant migrer les donnees
+
+ // execute la transformation
+ Transformer trans = new Transformer(smVersionAndConfigurationAdapterMap);
+
+ // migrate data
+ trans.execute();
+
+ // log
+ logger.info("Data migrated");
+
+ logger.debug("Deleting old database");
+
+ // suppresion des anciennes tables de toutes les configuration, sauf
+ // currentApplicationVersion
+ // (elle n'est pas dans mVersionAndConfigurationMap)
+ for(Configuration cfg : mVersionAndConfigurationMap.values()) {
+ dbManager.removeTablesFromOldMapping(cfg);
+ }
+
+ // renommage correct du schema courant
+ dbManager.renameTables(this.currentApplicationConfiguration, this.currentApplicationVersion);
+
+ // il faudrait ici valider les transactions et fermer les sessions
+ // vmvManager a sa propre gestion des transactions/session
+ // this.remoteConfiguration doit en avoir ouverte
+ // this.localConfiguration aussi
+
+ // all done
+ logger.info("All done, migration complete");
+
+ // ferme la connexion a la base
+ dbManager.disconnect();
+
+ // put version in databse
+ putVersionInDatabase(currentApplicationConfiguration.getProperties(),currentApplicationVersion,vdbVersion.equals(Version.VZERO));
+ }
+ else {
+ // ferme la connexion a la base
+ dbManager.disconnect();
+ }
+
+ // return succes flag
+ // - no migration needed
+ // - or migration needed and accepted
+ return !bMigrationNeeded || (bMigrationNeeded && bMigrationWanted);
+ }
+
+ /**
+ * Put version in database
+ *
+ * Single method because, version can be created alone...
+ *
+ * @param properties proprietes de connexion
+ * @param version version
+ */
+ protected void putVersionInDatabase(Properties properties, Version version, boolean createTable) {
+
+ DatabaseManager dbManager = new DatabaseManager(properties);
+
+ // update version even if database has not been migrated
+ // only case that database doesn't exist match this
+ if(createTable) {
+ // si la base n'etait pas versionnee, la table version n'existe pas
+ // creation
+ dbManager.createVersionTable();
+ }
+
+ // Changement de la version en base
+ dbManager.putVersionInDatabase(version);
+
+ dbManager.disconnect();
+
+ }
+
+ /**
+ * Ask handler for migration.
+ *
+ * Return true if all handler return true, or if there is no handler
+ *
+ * @return true or false
+ */
+ protected boolean askHandlerForMigration(String databaseVersion, String applicationVersion) {
+
+ // true par defaut, s'il n'y a pas de handlers
+ boolean result = true;
+
+ for(MigrationCallbackHandler callback : migrationCallBackHandlers) {
+ result &= callback.doMigration(databaseVersion, applicationVersion);
+ }
+
+ return result;
+ }
+
+ /**
+ * Charge les configurations de version a partir de vdbVersion "non compris"
+ * jusqu'a currentApplicationVersion "non compris"
+ * @param vdbVersion la version de depart
+ */
+ protected Map loadIntermediateConfigurations(Version vdbVersion) {
+ // schema des noms de dossier de version
+ final Pattern pattern = Pattern.compile(mappingsDirectory + File.separator + "([0-9]+(\\.[0-9]+)*)");
+
+ // instancie la map ordonee
+ Map mVersionAndConfigurationMap = null;
+
+ List urls = null;
+ urls = Resource.getURLs(".*" + mappingsDirectory + File.separator + ".*");
+
+ if (urls != null && urls.size() > 0) {
+
+ mVersionAndConfigurationMap = new HashMap();
+
+ // ensemble ordonnee des version a charger apres
+ TreeSet tsEnsembleVersionACharger = new TreeSet();
+
+ for(URL url : urls) {
+ Matcher matcher = pattern.matcher(url.getFile());
+
+ if(matcher.find()) {
+ // group(1) est ce qui match entre le premier niveau de parentheses
+ String sVersion = matcher.group(1);
+ //logger.debug("Directory " + fileInIt.getName() + " matches, version = " + sVersion);
+
+ tsEnsembleVersionACharger.add(new Version(sVersion));
+ }
+ }
+
+ // charge les version qui conviennent
+ for(Version v : tsEnsembleVersionACharger) {
+ if(v.compareTo(vdbVersion) <= 0) {
+ logger.debug("No load needed for version " + v.getVersion());
+ }
+ else {
+ logger.debug("Loading mapping for version " + v.getVersion());
+
+ Configuration cfgForVersion = getSingleConfiguration(v);
+ mVersionAndConfigurationMap.put(v, cfgForVersion);
+ }
+ }
+ }
+ else {
+ logger.error("No mapping found in classpath '" + mappingsDirectory + "'; can't load old mappings");
+ }
+
+ return mVersionAndConfigurationMap;
+ }
+
+ /**
+ * Recupere une configuration sur disque pour une version.
+ *
+ * @param version version
+ * @return une configuration hibernate
+ */
+ protected Configuration getSingleConfiguration(Version version) {
+ String mappingVersionDir = mappingsDirectory + File.separator + version.getVersion();
+
+ ConfigurationHelper cfgHelper = ConfigurationHelper.getInstance();
+ Configuration cfgForVersion = cfgHelper.getConfigurationInDirectory(mappingVersionDir);
+
+ return cfgForVersion;
+ }
+}