Index: topia2/src/java/org/codelutin/topia/TopiaContext.java diff -u topia2/src/java/org/codelutin/topia/TopiaContext.java:1.1.1.1 topia2/src/java/org/codelutin/topia/TopiaContext.java:1.2 --- topia2/src/java/org/codelutin/topia/TopiaContext.java:1.1.1.1 Mon Jan 2 13:54:35 2006 +++ topia2/src/java/org/codelutin/topia/TopiaContext.java Wed Jan 4 13:21:51 2006 @@ -1,410 +1,67 @@ -/* - * *##% Copyright (C) 2005 Code Lutin, Cédric Pineau, Benjamin Poussin - * - * 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. ##% - */ +/* *##% + * Copyright (C) 2006 + * Code Lutin, Cédric Pineau, Benjamin Poussin + * + * 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. + *##%*/ -/******************************************************************************* +/* * * TopiaContext.java - * - * Created: 23 déc. 2005 16:58:50 - * + * + * Created: 3 janv. 2006 21:18:34 + * * @author poussin - * - * @version $Revision: 1.1.1.1 $ - * - * Last update: $Date: 2006/01/02 13:54:35 $ by : $Author: bpoussin $ + * @version $Revision: 1.2 $ + * + * Last update: $Date: 2006/01/04 13:21:51 $ + * by : $Author: bpoussin $ */ package org.codelutin.topia; -import java.io.File; -import java.io.Serializable; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import org.apache.commons.collections.map.AbstractReferenceMap; -import org.apache.commons.collections.map.ReferenceMap; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.codelutin.topia.persistence.TopiaDAO; -import org.codelutin.topia.persistence.TopiaDAODelegator; -import org.codelutin.topia.persistence.TopiaEntity; -import org.hibernate.EmptyInterceptor; -import org.hibernate.FlushMode; -import org.hibernate.HibernateException; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.Transaction; -import org.hibernate.cfg.Configuration; -import org.hibernate.type.Type; +import org.codelutin.topia.event.TopiaEntityListener; /** - * Le TopiaContext est le point d'entre pour acceder aux donnees. Il est - * configurer par un fichier de propriete - *

- * List des proprietes disponible - *

- *
topia.persistence.properties.file - *
le fichier de propriété a utiliser pour configurer hibernate - * - *
topia.persistence.directories - *
la liste des repertoires contenant les mappings hibernates (.hbm.xml) la - * liste de repertoire est separer par des virgules ',' - * - *
topia.persistence.classes - *
la liste des classes que doit géré hibernate. On peut tres bien utiliser - * topia.persistence.directories pour un ensemble d'entié du meme repertoire et - * topia.persistence.classes pour d'autres classes - *
- * * @author poussin - * + * */ -public class TopiaContext { - - /** to use log facility, just put in your code: log.info(\"...\"); */ - static private Log log = LogFactory.getLog(TopiaContext.class); - - static final private String DEFAULT_CONFIG_PROPERTIES = "TopiaContext.properties"; - - static final private String TOPIA_PERSISTENCE_DIRECTORIES = "topia.persistence.directories"; - - static final private String TOPIA_PERSISTENCE_CLASSES = "topia.persistence.classes"; - - static final private String TOPIA_PERSISTENCE_PROPERTIES_FILE = "topia.persistence.properties.file"; - - /** - * Cache contenant tous les contexts deja créé. - */ - @SuppressWarnings("unchecked") - static protected Map contextCache = new ReferenceMap( - AbstractReferenceMap.HARD, AbstractReferenceMap.SOFT); - - /** - * Le pere de ce context, les contexts initaux n'ont pas de context pere - */ - protected TopiaContext parentContext = null; - /** - * la factory permettant de recuperer la session hibernate. Seul les - * TopiaContext initiaux contiennent un hibernateFactory - */ - protected SessionFactory hibernateFactory = null; - - /** - * La session utilisé par le TopiaContext - */ - protected Session hibernate = null; - - /** - * Propriete de configuration - */ - protected Properties config = null; +public interface TopiaContext { /** - * cache des DAO deja chargé pour ce context + * Adds a new TopiaEntityListener to the subscribers list. + * @param topiaEntityListener - the TopiaEntityListener to add to the subscribers list. */ - protected Map daoCache = new HashMap(); + public void addTopiaEntityListener(TopiaEntityListener l); /** - * Set des sous context creer avec un beginTransaction et donc sur lequel - * nous sommes listener + * Removes a TopiaEntityListener from the subscribers list. + * @param topiaEntityListener - the TopiaEntityListener to remove from the subscribers. */ - protected Set childContext = new HashSet(); + public void removeTopiaEntityListener(TopiaEntityListener l); - /** - * Utilise par defaut le fichier de propriete TopiaContext.properties - * - * @return - * @throws TopiaNotFoundException Si le fichier de configuration par defaut - * n'est pas retrouvé. - */ - static public TopiaContext getContext() throws TopiaNotFoundException { - Properties config = TopiaUtil.getProperties(DEFAULT_CONFIG_PROPERTIES); - TopiaContext result = getContext(config); - return result; - } - - /** - * Methode static permettant de recuperer un context. Si on donne plusieurs - * fois le meme objet config, on obtient la meme instance de TopiaContext. - * - * @param config - * @return - */ - static public TopiaContext getContext(Properties config) { - TopiaContext result = contextCache.get(config); - if (result == null) { - result = new TopiaContext(config); - contextCache.put((Properties) config.clone(), result); - } - return result; - } - - /** - * constructeur utilisé par la factory pour creer les contexts initiaux - * - * @param config - */ - protected TopiaContext(Properties config) { - this.config = config; - } - - /** - * Constructeur utilisé par le beginTransaction pour créer le context fils. - * - * @param config la configuration du - * @param parentContext - * @throws HibernateException - * @throws TopiaNotFoundException - */ - protected TopiaContext(TopiaContext parentContext) - throws HibernateException, TopiaNotFoundException { - this.parentContext = parentContext; - } - - /** - * @return Returns the parentContext. - */ - public TopiaContext getParentContext() { - return parentContext; - } - - public TopiaContext getRootContext() { - TopiaContext result = this; - if (getParentContext() != null) { - result = getParentContext().getRootContext(); - } - return result; - } - - /** - * @return Returns the config. - */ - public Properties getConfig() { - if (config == null && getParentContext() != null) { - config = getParentContext().getConfig(); - } - return config; - } - - /** - * @return Returns the hibernate. - * @throws TopiaException si aucune transaction n'est ouverte - */ - public Session getHibernate() throws TopiaException { - if (hibernate == null) { - throw new TopiaException( - "No hibernate session available, you must start transaction with beginTransaction"); - } - return hibernate; - } - - /** - * @return Returns the hibernateFactory. - * @throws TopiaNotFoundException - */ - public SessionFactory getHibernateFactory() - throws TopiaNotFoundException { - if (hibernateFactory == null) { - if (getParentContext() != null) { - hibernateFactory = getParentContext().getHibernateFactory(); - } else { - Configuration cfg = new Configuration(); - - // ajout des repertoires contenant les mappings hibernate - String[] dirs = getConfig().getProperty( - TOPIA_PERSISTENCE_DIRECTORIES, "").split(","); - for (String dir : dirs) { - dir = dir.trim(); - if (!"".equals(dir)) { - cfg.addDirectory(new File(dir)); - } - } - - // ajout des classes dites persistentes - String[] classes = getConfig().getProperty( - TOPIA_PERSISTENCE_CLASSES, "").split(","); - for (String classname : classes) { - classname = classname.trim(); - if (!"".equals(classname)) { - Class clazz; - try { - clazz = Class.forName(classname); - } catch (ClassNotFoundException eee) { - throw new TopiaNotFoundException( - "Persistent class " + classname - + " not found"); - } - cfg.addClass(clazz); - } - } - - Properties prop = new Properties(); - prop.putAll(cfg.getProperties()); - prop.putAll(getConfig()); - prop.putAll(TopiaUtil.getProperties(getConfig().getProperty( - TOPIA_PERSISTENCE_PROPERTIES_FILE))); - cfg.setProperties(prop); - - hibernateFactory = cfg.buildSessionFactory(); - } - } - return hibernateFactory; - } - - /** - * Get DAO for specified class. If Specialized DAO exists then it returned - * otherwize TopiaDAO<entityClass> is returned - * - * @param - * @param entityClass - * @return - * @throws TopiaException - */ - @SuppressWarnings("unchecked") - public TopiaDAO getDAO(Class entityClass) throws TopiaException { - if (getRootContext() == this) { - throw new TopiaException("Vous êtes sur le root context vous devez ouvrir une transaction pour pouvoir accèder aux données"); - } - TopiaDAO result = (TopiaDAO) daoCache.get(entityClass); - if (result == null) { - // recherche du type de DAO a instancier pour cette entity - String defaultDAOClassname = getConfig().getProperty("topia.dao.default.class", "hibernate"); - String daoClassname = getConfig().getProperty("topia.dao." + entityClass.getName(), defaultDAOClassname); - if ("hibernate".equals(daoClassname)) { - daoClassname = "org.codelutin.topia.persistence.hibernate.TopiaDAOHibernate"; - } else if ("flatfile".equals(daoClassname)) { - daoClassname = "org.codelutin.topia.persistence.flatfile.TopiaDAOFlatFile"; - } - - try { - Class> resultClass = (Class>)Class.forName(daoClassname); - result = resultClass.newInstance(); - result.init(this, entityClass); - } catch (ClassNotFoundException eee) { - throw new TopiaException("Can't find DAO class " + daoClassname); - } catch (InstantiationException eee) { - throw new TopiaException("Can't instanciate DAO class " + daoClassname); - } catch (IllegalAccessException eee) { - throw new TopiaException("Can't access DAO class " + daoClassname); - } - - // looking for specialized DAO - // normalement il en existe un car il est généré automatiquement - // si on utilise la génération - daoClassname = entityClass.getName() + "DAO"; - try { - Class> daoClass = (Class>) Class - .forName(daoClassname); - TopiaDAODelegator spe = daoClass.newInstance(); - spe.setParentDAO(result); - result = spe; - } catch (Exception eee) { - log.warn("specialized DAO " + daoClassname - + " not found, use default TopiaDAOHibernate"); - } - daoCache.put(entityClass, result); - } - return result; - } - - public TopiaContext beginTransaction() throws TopiaNotFoundException { - TopiaContext result = new TopiaContext(this); - childContext.add(result); - result.hibernate = getHibernateFactory().openSession(new TopiaInterceptor(result)); - // on ne synchronise jamais les données avec la base tant que - // l'utilisateur n'a pas fait de commit du context - result.hibernate.setFlushMode(FlushMode.NEVER); - - // TODO se mettre listener sur ce context - return result; - } + public TopiaContext beginTransaction() throws TopiaNotFoundException; /** * applique les modifications apporté a ce context sur la base de données. */ - public void commitTransaction() throws TopiaException { - try { - for(TopiaDAO dao : daoCache.values()) { - dao.commitTransaction(); - } - Transaction tx = hibernate.beginTransaction(); - hibernate.flush(); - tx.commit(); - fireOnCommited(); - } catch (HibernateException eee) { - throw new TopiaException(eee); - } - } + public void commitTransaction() throws TopiaException; /** * annule les modifications apporté a ce context */ - public void rollbackTransaction() throws TopiaException { - try { - for(TopiaDAO dao : daoCache.values()) { - dao.rollbackTransaction(); - } - Transaction tx = hibernate.beginTransaction(); - hibernate.clear(); - tx.rollback(); - fireOnRollbacked(); - } catch (HibernateException eee) { - throw new TopiaException(eee); - } - } - - public void fireOnDeleted(Object entity) { - log.info("onDeleted " + entity); - } - - public void fireOnUpdated(Object entity) { - log.info("onUpdated " + entity); - } - - public void fireOnCommited() { - log.info("onCommited"); - } - - public void fireOnRollbacked() { - log.info("onRollbacked"); - } - - static protected class TopiaInterceptor extends EmptyInterceptor { - - protected TopiaContext context = null; - - private static final long serialVersionUID = -6787010517746197446L; - - public TopiaInterceptor(TopiaContext context) { - this.context = context; - } - - public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types){ - super.onDelete(entity, id, state, propertyNames, types); - context.fireOnDeleted(entity); - } - public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) { - boolean result = super.onSave(entity, id, state, propertyNames, types); - context.fireOnUpdated(entity); - return result; - } - } + public void rollbackTransaction() throws TopiaException; + } Index: topia2/src/java/org/codelutin/topia/TopiaContextFactory.java diff -u /dev/null topia2/src/java/org/codelutin/topia/TopiaContextFactory.java:1.1 --- /dev/null Wed Jan 4 13:21:56 2006 +++ topia2/src/java/org/codelutin/topia/TopiaContextFactory.java Wed Jan 4 13:21:51 2006 @@ -0,0 +1,90 @@ +/* *##% + * Copyright (C) 2006 + * Code Lutin, Cédric Pineau, Benjamin Poussin + * + * 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. + *##%*/ + +/* * + * TopiaContextFactory.java + * + * Created: 3 janv. 2006 21:19:37 + * + * @author poussin + * @version $Revision: 1.1 $ + * + * Last update: $Date: 2006/01/04 13:21:51 $ + * by : $Author: bpoussin $ + */ + +package org.codelutin.topia; + +import java.util.Map; +import java.util.Properties; + +import org.apache.commons.collections.map.AbstractReferenceMap; +import org.apache.commons.collections.map.ReferenceMap; +import org.codelutin.topia.framework.TopiaContextImpl; +import org.codelutin.topia.framework.TopiaUtil; + + +/** + * @author poussin + * + */ + +public class TopiaContextFactory { + + static final private String DEFAULT_CONFIG_PROPERTIES = "TopiaContextImpl.properties"; + + /** + * Cache contenant tous les contexts deja créé. + */ + @SuppressWarnings("unchecked") + static protected Map contextCache = new ReferenceMap( + AbstractReferenceMap.HARD, AbstractReferenceMap.SOFT); + + /** + * Utilise par defaut le fichier de propriete TopiaContextImpl.properties + * + * @return + * @throws TopiaNotFoundException Si le fichier de configuration par defaut + * n'est pas retrouvé. + */ + static public TopiaContext getContext() throws TopiaNotFoundException { + Properties config = TopiaUtil.getProperties(DEFAULT_CONFIG_PROPERTIES); + TopiaContext result = getContext(config); + return result; + } + + /** + * Methode static permettant de recuperer un context. Si on donne plusieurs + * fois le meme objet config, on obtient la meme instance de TopiaContextImpl. + * + * @param config + * @return + */ + static public TopiaContext getContext(Properties config) { + TopiaContextImpl result = contextCache.get(config); + if (result == null) { + result = new TopiaContextImpl(config); + contextCache.put((Properties) config.clone(), result); + } + return result; + } + +} + +