Author: athimel Date: 2013-08-02 19:26:06 +0200 (Fri, 02 Aug 2013) New Revision: 2786 Url: http://nuiton.org/projects/topia/repository/revisions/2786 Log: refs #2748 Rename TopiaContextImpl to AbstractTopiaContext Added: trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaTransactionSupport.java trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/AbstractTopiaContext.java Removed: trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaTransaction.java trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaContext.java trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaContextFactory.java trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImplementor.java trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaFiresSupport.java trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaService.java trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/package-info.java trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/EntityDAOTransformer.java trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaDAO.java trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaDAOImpl.java trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/in/TopiaCsvImports.java trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/DBMapping.java trunk/topia-persistence/src/test/java/org/nuiton/topia/TopiaContextFactoryTest.java trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TopiaContextImplTest.java trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/FakeService.java trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/TestService.java trunk/topia-service-migration/src/main/java/org/nuiton/topia/migration/TopiaMigrationEngine.java trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationServiceImpl.java trunk/topia-service-security/src/main/java/org/nuiton/topia/security/TopiaSecurityServiceImpl.java trunk/topia-service-security/src/main/java/org/nuiton/topia/security/util/TopiaSecurityUtil.java trunk/topia-service-security/src/main/java/org/nuiton/topia/taas/TaasService.java Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaContext.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaContext.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaContext.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -53,11 +53,9 @@ * @author tchemit <tchemit@codelutin.com> * @author athimel <thimel@codelutin.com> * @version $Id$ - * @deprecated Since 3.0, TopiaContext is splitted in multiple contracts */ -@Deprecated -public interface TopiaContext extends TopiaTransaction, TopiaListenable, TopiaSqlSupport, TopiaJpaSupport, - TopiaPersistenceContext, TopiaServiceSupport, TopiaReplicationSupport { +public interface TopiaContext extends TopiaTransactionSupport, TopiaListenable, TopiaSqlSupport, TopiaJpaSupport, + TopiaPersistenceContext, TopiaServiceSupport, TopiaReplicationSupport, TopiaHibernate { /* -------------------- TRANSACTION MANAGEMENT --------------------------*/ @@ -66,7 +64,7 @@ * * @return new context with transaction * @throws TopiaException if any exception - * @deprecated use method from {@link TopiaTransaction} + * @deprecated use method from {@link TopiaTransactionSupport} */ @Deprecated TopiaContext beginTransaction() throws TopiaException; @@ -76,7 +74,7 @@ * device. Once commit is done, a new transaction is started. * * @throws TopiaException if any exception - * @deprecated use method from {@link TopiaTransaction} + * @deprecated use method from {@link TopiaTransactionSupport} */ @Deprecated void commitTransaction() throws TopiaException; @@ -87,7 +85,7 @@ * transaction is started. * * @throws TopiaException if any exception - * @deprecated use method from {@link TopiaTransaction} + * @deprecated use method from {@link TopiaTransactionSupport} */ @Deprecated void rollbackTransaction() throws TopiaException; @@ -97,7 +95,7 @@ * time. * * @throws TopiaException if any exception - * @deprecated use method from {@link TopiaTransaction} + * @deprecated use method from {@link TopiaTransactionSupport} */ @Deprecated void closeContext() throws TopiaException; @@ -106,7 +104,7 @@ * Tells if the context is closed * * @return {@code true} if the context is closed, {@code false} otherwise - * @deprecated use method from {@link TopiaTransaction} + * @deprecated use method from {@link TopiaTransactionSupport} */ @Deprecated boolean isClosed(); Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaContextFactory.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaContextFactory.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaContextFactory.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -30,7 +30,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.cfg.Environment; -import org.nuiton.topia.framework.TopiaContextImpl; +import org.nuiton.topia.framework.AbstractTopiaContext; import org.nuiton.topia.framework.TopiaUtil; import java.util.ArrayList; @@ -133,7 +133,7 @@ */ public static void removeContext(TopiaContext context) { // Properties key = null; -// for (Entry<Properties, TopiaContextImpl> e : contextCache.entrySet()) { +// for (Entry<Properties, AbstractTopiaContext> e : contextCache.entrySet()) { // if (e.getValue() == context) { // key = e.getKey(); // break; @@ -157,7 +157,7 @@ } /** - * Utilise par defaut le fichier de propriete TopiaContextImpl.properties + * Utilise par defaut le fichier de propriete AbstractTopiaContext.properties * * @return the context using the default configuration file * @throws TopiaNotFoundException Si le fichier de configuration par defaut @@ -172,7 +172,7 @@ /** * Methode static permettant de recuperer un context. Si on donne plusieurs * fois le meme objet config, on obtient la meme instance de - * TopiaContextImpl. Si le context qui devrait etre retourné est ferme, + * AbstractTopiaContext. Si le context qui devrait etre retourné est ferme, * alors un nouveau est creer et retourné. * * @param config the configuration of the context @@ -192,7 +192,7 @@ TopiaContext result = contextCache.get(cloned); // useless test, context is automatically removed from Factory when closed if (result == null/* || result.isClosed()*/) { - result = new TopiaContextImpl(cloned); + result = new AbstractTopiaContext(cloned); if (log.isDebugEnabled()) { log.debug("instantiate new topiaContext : " + result); } Deleted: trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaTransaction.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaTransaction.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaTransaction.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -1,72 +0,0 @@ -package org.nuiton.topia; - -/* - * #%L - * ToPIA :: Persistence - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2004 - 2013 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ - -/** - * @author Arnaud Thimel <thimel@codelutin.com> - */ -public interface TopiaTransaction { - - /** - * Returns a new context containing its own transaction. - * - * @return new context with transaction - * @throws TopiaException if any exception - */ - TopiaContext beginTransaction() throws TopiaException; - - /** - * Applies all the modifications made to this context on the persistence - * device. Once commit is done, a new transaction is started. - * - * @throws TopiaException if any exception - */ - void commitTransaction() throws TopiaException; - - /** - * Cancels all the modifications made to this context, coming back to the - * state on the last beginTransaction. Once rollback is done, a new - * transaction is started. - * - * @throws TopiaException if any exception - */ - void rollbackTransaction() throws TopiaException; - - /** - * Closes the context. All the children contexts will be closed in the same - * time. - * - * @throws TopiaException if any exception - */ - void closeContext() throws TopiaException; - - /** - * Tells if the context is closed - * - * @return {@code true} if the context is closed, {@code false} otherwise - */ - boolean isClosed(); - -} Copied: trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaTransactionSupport.java (from rev 2785, trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaTransaction.java) =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaTransactionSupport.java (rev 0) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaTransactionSupport.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -0,0 +1,72 @@ +package org.nuiton.topia; + +/* + * #%L + * ToPIA :: Persistence + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +/** + * @author Arnaud Thimel <thimel@codelutin.com> + */ +public interface TopiaTransactionSupport { + + /** + * Returns a new context containing its own transaction. + * + * @return new context with transaction + * @throws TopiaException if any exception + */ + TopiaContext beginTransaction() throws TopiaException; + + /** + * Applies all the modifications made to this context on the persistence + * device. Once commit is done, a new transaction is started. + * + * @throws TopiaException if any exception + */ + void commitTransaction() throws TopiaException; + + /** + * Cancels all the modifications made to this context, coming back to the + * state on the last beginTransaction. Once rollback is done, a new + * transaction is started. + * + * @throws TopiaException if any exception + */ + void rollbackTransaction() throws TopiaException; + + /** + * Closes the context. All the children contexts will be closed in the same + * time. + * + * @throws TopiaException if any exception + */ + void closeContext() throws TopiaException; + + /** + * Tells if the context is closed + * + * @return {@code true} if the context is closed, {@code false} otherwise + */ + boolean isClosed(); + +} Copied: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/AbstractTopiaContext.java (from rev 2785, trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java) =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/AbstractTopiaContext.java (rev 0) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/AbstractTopiaContext.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -0,0 +1,1542 @@ +/* + * #%L + * ToPIA :: Persistence + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin, Chatellier Eric + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +package org.nuiton.topia.framework; + +import java.beans.PropertyChangeListener; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.WeakHashMap; +import java.util.zip.GZIPInputStream; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.FlushMode; +import org.hibernate.HibernateException; +import org.hibernate.Query; +import org.hibernate.ReplicationMode; +import org.hibernate.SQLQuery; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; +import org.hibernate.cfg.Configuration; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.event.service.spi.EventListenerRegistry; +import org.hibernate.event.spi.EventType; +import org.hibernate.jdbc.Work; +import org.hibernate.service.ServiceRegistry; +import org.hibernate.service.ServiceRegistryBuilder; +import org.hibernate.service.jdbc.connections.spi.ConnectionProvider; +import org.hibernate.service.spi.Stoppable; +import org.hibernate.tool.hbm2ddl.SchemaExport; +import org.hibernate.tool.hbm2ddl.SchemaUpdate; +import org.nuiton.topia.TopiaContext; +import org.nuiton.topia.TopiaContextFactory; +import org.nuiton.topia.TopiaException; +import org.nuiton.topia.TopiaNotFoundException; +import org.nuiton.topia.event.TopiaContextListener; +import org.nuiton.topia.event.TopiaEntitiesVetoable; +import org.nuiton.topia.event.TopiaEntityListener; +import org.nuiton.topia.event.TopiaEntityVetoable; +import org.nuiton.topia.event.TopiaSchemaListener; +import org.nuiton.topia.event.TopiaTransactionListener; +import org.nuiton.topia.event.TopiaTransactionVetoable; +import org.nuiton.topia.persistence.DefaultTopiaIdFactory; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.TopiaDAOImpl; +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.persistence.TopiaIdFactory; + +/** + * Le AbstractTopiaContext est le point d'entre pour acceder aux donnees. Il est + * configurer par un fichier de propriete + * <p/> + * List des proprietes disponible <dl> <dt> topia.persistence.properties.file + * <dd> le fichier de propriété a utiliser pour configurer hibernate + * <p/> + * <dt> topia.persistence.directories <dd> la liste des repertoires contenant + * les mappings hibernates (.hbm.xml) la liste de repertoire est separer par des + * virgules ',' + * <p/> + * <dt> topia.persistence.classes <dd> 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 </dl> + * <p/> + * AbstractTopiaContext.java + * <p/> + * Created: 23 déc. 2005 16:58:50 + * + * @author bpoussin <poussin@codelutin.com> + * @author tchemit <chemit@codelutin.com> + * @author fdesbois <desbois@codelutin.com> + * @version $Id$ + */ +//TODO-fdesbois-20100507 : Need translation of javadoc. +// TODO AThimel 02/08/13 must be abstract +public class AbstractTopiaContext implements TopiaContext + , TopiaContextImplementor { + + /** + * to use log facility, just put in your code: log.info(\"...\"); + */ + private static final Log log = LogFactory.getLog(AbstractTopiaContext.class); + + /** + * Le pere de ce context, les contexts initaux n'ont pas de context pere + * + * @deprecated Hierarchical context are not supported anymore + */ + @Deprecated + protected TopiaContextImplementor parentContext; + + /** + * L'objet configuration utilisé pour la creation de la factory hibernate + */ + protected Configuration hibernateConfiguration; + + /** + * la factory permettant de recuperer la session hibernate. Seul les + * AbstractTopiaContext initiaux contiennent un hibernateFactory + */ + protected SessionFactory hibernateFactory; + + /** + * La session utilisé par le AbstractTopiaContext + */ + protected Session hibernate; + + /** + * Indique si le contexte a ete ferme + */ + protected boolean closed; + + /** + * This flag permits to use (or not) the flush mode when doing queries. + * <p/> + * The normal usage is to says yes (that's why the default value is + * {@code true}), in that case whebn doing queries (says in method + * {@link #findAll(String, Object...)} or {@link #find(String, int, int, Object...)}) + * it will use the flush mode {@link FlushMode#AUTO}). + * <p/> + * But sometimes, when doing a lot of queries (for some imports for example), + * we do NOT want the session to be flushed each time we do a find, then you + * can set this flag to {@code false} using the method {@link #setUseFlushMode(boolean)} + * + * @since 2.5 + */ + protected boolean useFlushMode = true; + + /** + * Propriete de configuration + */ + protected Properties config; + + /** + * Used to affect a new topiaId when create is called. + * + * @since 3.0 + */ + protected TopiaIdFactory topiaIdFactory; + + /** + * cache des DAO deja chargé pour ce context + */ + protected Map<Class<? extends TopiaEntity>, + TopiaDAO<? extends TopiaEntity>> daoCache = + new HashMap<Class<? extends TopiaEntity>, + TopiaDAO<? extends TopiaEntity>>(); + + /** + * Set of child context created with {@link #beginTransaction()}. We are + * listener on these context. A WeakHashMap is used to remove old context + * automically when it's not used anymore. The {@link #finalize} method will + * be executed when Garbage collector is called when reference is removed. + * The set is synchronized in case of using multi-threading. + * + * @see Collections#synchronizedSet(Set) + * @see Collections#newSetFromMap(Map) + */ + protected final Set<TopiaContextImplementor> childContext = + Collections.synchronizedSet( + Collections.newSetFromMap( + new WeakHashMap<TopiaContextImplementor, Boolean>())); + + /** + * key: service name; value: service instance + */ + protected Map<String, TopiaService> services; + + protected TopiaFiresSupport firesSupport = new TopiaFiresSupport(); + + /** + * Liste des classes perssitance + */ + protected List<Class<?>> persistenceClasses = new ArrayList<Class<?>>(); + + /** + * Default constructor, useful for tests. + */ + protected AbstractTopiaContext() { + + } + + /** + * Constructor used by {@link TopiaContextFactory} to initialize rootContext + * using {@code config}. + * + * @param config for the new root context + * @throws TopiaNotFoundException if one of persistent class from + * configuration is not found + */ + public AbstractTopiaContext(Properties config) throws TopiaNotFoundException { + this.config = config; + initTopiaIdFactory(); + services = loadServices(config); + preInitServices(services); + getHibernateConfiguration(); // force mapping loading + postInitServices(services); + } + + protected void initTopiaIdFactory() { + String configTopiaIdFactoryClassName = + getConfig().getProperty(TopiaContextFactory.CONFIG_PERSISTENCE_TOPIA_ID_FACTORY_CLASS_NAME, ""); + if (StringUtils.isEmpty(configTopiaIdFactoryClassName)) { + topiaIdFactory = new DefaultTopiaIdFactory(); + } else { + try { + Class configPersistenceTopiaIdFactoryClass = + Class.forName(configTopiaIdFactoryClassName); + if (TopiaIdFactory.class.isAssignableFrom(configPersistenceTopiaIdFactoryClass)) { + topiaIdFactory = (TopiaIdFactory) configPersistenceTopiaIdFactoryClass.newInstance(); + } else { + throw new IllegalArgumentException( + configTopiaIdFactoryClassName + " is not a valid class name. The class must implements " + + TopiaIdFactory.class.getSimpleName()); + } + } catch (ClassNotFoundException e) { + throw new TopiaException(e); + } catch (InstantiationException e) { + throw new TopiaException(e); + } catch (IllegalAccessException e) { + throw new TopiaException(e); + } + } + } + + protected String getProperExceptionMessage(Throwable eee) { + return eee.getClass().getSimpleName() + " : " + + eee.getMessage(); + } + + /* -------------------- SERVICES MANAGMENT -------------------------------*/ + + protected Map<String, TopiaService> loadServices(Properties config) { + Map<String, TopiaService> result = new HashMap<String, TopiaService>(); + // recherche des services present dans la config + for (Enumeration<?> e = config.propertyNames(); e.hasMoreElements(); ) { + String key = (String) e.nextElement(); + if (key.matches("^topia\\.service\\.\\w+$")) { + String classService = config.getProperty(key); + try { + Class<?> forName = Class.forName(classService); + Object newInstance = forName.getConstructor().newInstance(); + TopiaService service = (TopiaService) newInstance; + if (key.equals("topia.service." + service.getServiceName())) { + result.put(service.getServiceName(), service); + log.info(String.format("Service '%1$s' loaded (implementation %2$s)", + key, classService)); + } else { + log.warn(String.format("The service with key '%1$s' has a different name '%2$s'! (service not activated)", + key, service.getServiceName())); + } + } catch (Throwable eee) { + String message = + String.format("The service %1$s of type %2$s was not found.", + key, classService); + if (log.isDebugEnabled()) { + log.debug(message, eee); + } else if (log.isErrorEnabled()) { + log.error(message); + } + } + } + } + return result; + } + + protected void preInitServices(Map<String, TopiaService> services) { + for (TopiaService service : services.values()) { + if (!service.preInit(this)) { + log.warn(String.format("The service named '%1$s' could not be post-initialized (service not activated)", + service.getServiceName())); + } + } + } + + protected void postInitServices(Map<String, TopiaService> services) { + for (TopiaService service : services.values()) { + if (!service.postInit(this)) { + log.warn(String.format("The service named '%1$s' could not be pre-initialized (service not activated)", + service.getServiceName())); + } + } + } + + protected TopiaService getService(String name) { + TopiaService result = getServices().get(name); + return result; + } + + protected boolean serviceEnabled(String name) { + boolean result = getServices().containsKey(name); + return result; + } + + /** + * Retrieve service name using SERVICE_NAME static field on service + * interface. + * + * @param interfaceService class of the service + * @param <E> type of the service that extends {@link + * TopiaService} + * @return the service name + * @throws IllegalAccessException if field SERVICE_NAME can't be accessed + * @throws NoSuchFieldException if no field SERVICE_NAME is defined + */ + protected <E extends TopiaService> String getServiceName( + Class<E> interfaceService) + throws IllegalAccessException, NoSuchFieldException { + Field f = interfaceService.getField("SERVICE_NAME"); + String name = (String) f.get(null); + return name; + } + + @Override + public Map<String, TopiaService> getServices() { + TopiaContextImplementor parent = getParentContext(); + + Map<String, TopiaService> result; + if (parent != null) { + result = parent.getServices(); + } else { + result = services; + } + return result; + } + + /** + * Take one service, this service must be valid service interface with + * public static final SERVICE_NAME declaration. + * + * @param <E> type of the service that extends {@link TopiaService} + * @throws TopiaNotFoundException if an error appears or service not found. + * @see #getServiceName(Class) + */ + @Override + public <E extends TopiaService> E getService(Class<E> interfaceService) + throws TopiaNotFoundException { + E result; + try { + String name = getServiceName(interfaceService); + result = (E) getService(name); + } catch (Exception eee) { + throw new TopiaNotFoundException( + String.format("Could not retreave service %1$s for following reason: %2$s", + interfaceService, getProperExceptionMessage(eee)), + eee); + } + if (result == null) { + throw new TopiaNotFoundException( + String.format("The service %1$s was not found.", + interfaceService)); + } + return result; + } + + @Override + public <E extends TopiaService> boolean serviceEnabled( + Class<E> interfaceService) { + boolean result = false; + try { + String name = getServiceName(interfaceService); + result = serviceEnabled(name); + } catch (Exception eee) { + String message = String.format("The service named '%1$s' could not be found for following reason: %2$s", + interfaceService, getProperExceptionMessage(eee)); + if (log.isDebugEnabled()) { + log.debug(message, eee); + } else if (log.isWarnEnabled()) { + log.warn(message); + } + } + return result; + } + + /* -------------------- CONTEXT HIERARCHY MANAGMENT ----------------------*/ + + /** + * Constructor used by {@link #beginTransaction()} to instantiate child from + * {@code parentContext}. + * + * @param parentContext context parent of the new TopiaContext child + */ + protected AbstractTopiaContext(TopiaContextImplementor parentContext) { + this.parentContext = parentContext; + } + + @Override + public Set<TopiaContextImplementor> getChildContext() { + // fdesbois-20100421 : Ano #546 + // Copy the childContext into a new set + Set<TopiaContextImplementor> values; + // Synchronize copy to be thread-safe during iteration + synchronized (childContext) { + values = new HashSet<TopiaContextImplementor>(childContext); + } + return values; + } + + protected void addChildContext(TopiaContextImplementor child) { + childContext.add(child); + } + + @Override + public void removeChildContext(TopiaContext child) { + // Remove child only if this context is not already closed. + if (!closed) { + childContext.remove(child); + } + } + + @Override + public TopiaContextImplementor getParentContext() { + return parentContext; + } + + @Override + public TopiaContextImplementor getRootContext() { + TopiaContextImplementor result = this; + if (getParentContext() != null) { + result = getParentContext().getRootContext(); + } + return result; + } + + @Override + public Properties getConfig() { + if (config == null && getParentContext() != null) { + config = getParentContext().getConfig(); + } + return config; + } + + @Override + public TopiaIdFactory getTopiaIdFactory() { + if (topiaIdFactory == null) { + initTopiaIdFactory(); + } + return topiaIdFactory; + } + + /** + * Change the value of flag {@link #useFlushMode}. + * + * @param useFlushMode the new value to set + * @see #useFlushMode + * @since 2.5 + */ + public void setUseFlushMode(boolean useFlushMode) { + this.useFlushMode = useFlushMode; + } + + /* -------------------- HIBERNATE MANAGMENT -----------------------------*/ + + @Override + public void createSchema() throws TopiaException { + try { + boolean showSchema = false; + if (log.isDebugEnabled()) { + showSchema = true; + } + getFiresSupport().firePreCreateSchema(this); + new SchemaExport(getHibernateConfiguration()).execute(showSchema, true, false, true); + getFiresSupport().firePostCreateSchema(this); + } catch (HibernateException eee) { + throw new TopiaException( + String.format("Could not create schema for reason: %s", + eee.getMessage()), eee); + } + } + + @Override + public void showCreateSchema() throws TopiaException { + try { + new SchemaExport(getHibernateConfiguration()). + execute(true, false, false, true); + } catch (HibernateException eee) { + throw new TopiaException( + String.format("Could not show create schema for reason: %s", + eee.getMessage()), eee); + } + } + + @Override + public void updateSchema() throws TopiaException { + try { + boolean showSchema = false; + if (log.isDebugEnabled()) { + showSchema = true; + } + getFiresSupport().firePreUpdateSchema(this); + new SchemaUpdate(getHibernateConfiguration()).execute(showSchema, + true); + getFiresSupport().firePostUpdateSchema(this); + } catch (HibernateException eee) { + throw new TopiaException( + String.format("Could not update schema for reason: %s", + eee.getMessage()), eee); + } + } + + @Override + public void dropSchema() throws TopiaException { + try { + boolean showSchema = false; + if (log.isDebugEnabled()) { + showSchema = true; + } + getFiresSupport().firePreDropSchema(this); + new SchemaExport(getHibernateConfiguration()).execute(showSchema, true, true, false); + getFiresSupport().firePostDropSchema(this); + } catch (HibernateException eee) { + throw new TopiaException( + String.format("Could not drop schema for reason: %s", + eee.getMessage()), eee); + } + } + + @Override + public Session getHibernate() throws TopiaException { + Session result = getHibernateSession(); + return result; + } + + @Override + public SessionFactory getHibernateFactory() throws TopiaNotFoundException { + if (hibernateFactory == null) { + if (getParentContext() != null) { + hibernateFactory = getParentContext().getHibernateFactory(); + } else { + + // init service registry + ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings( + getHibernateConfiguration().getProperties()).buildServiceRegistry(); + + hibernateFactory = getHibernateConfiguration().buildSessionFactory(serviceRegistry); + + // we can't reuse original serviceRegistry instance + // we must call getServiceRegistry on factory to get a working one + ServiceRegistry serviceRegistryInit = ((SessionFactoryImplementor) hibernateFactory).getServiceRegistry(); + EventListenerRegistry eventListenerRegistry = serviceRegistryInit.getService(EventListenerRegistry.class); + TopiaFiresSupport.TopiaHibernateEvent listener = new TopiaFiresSupport.TopiaHibernateEvent(this); + eventListenerRegistry.appendListeners(EventType.PRE_INSERT, listener); + eventListenerRegistry.appendListeners(EventType.PRE_LOAD, listener); + eventListenerRegistry.appendListeners(EventType.PRE_UPDATE, listener); + eventListenerRegistry.appendListeners(EventType.PRE_DELETE, listener); + eventListenerRegistry.appendListeners(EventType.POST_INSERT, listener); + eventListenerRegistry.appendListeners(EventType.POST_LOAD, listener); + eventListenerRegistry.appendListeners(EventType.POST_UPDATE, listener); + eventListenerRegistry.appendListeners(EventType.POST_DELETE, listener); + + // following listeners must be called before hibernate + eventListenerRegistry.prependListeners(EventType.SAVE_UPDATE, listener); + } + } + return hibernateFactory; + } + + @Override + public Configuration getHibernateConfiguration() + throws TopiaNotFoundException { + if (hibernateConfiguration == null) { + if (getParentContext() != null) { + hibernateConfiguration = getParentContext().getHibernateConfiguration(); + } else { + hibernateConfiguration = new Configuration(); + + // ajout des repertoires contenant les mappings hibernate + String[] dirs = getConfig().getProperty( + TopiaContextFactory.CONFIG_PERSISTENCE_DIRECTORIES, "").split(","); + for (String dir : dirs) { + dir = dir.trim(); + if (StringUtils.isNotEmpty(dir)) { + if (log.isDebugEnabled()) { + log.debug("Load persistence from dir : " + dir); + } + hibernateConfiguration.addDirectory(new File(dir)); + } + } + + // ajout des classes dites persistentes + Set<Class<?>> hibernatePersistanceClasses = new HashSet<Class<?>>(); + for (TopiaService service : getServices().values()) { + Class<?>[] classes = service.getPersistenceClasses(); + + // certains service n'ont pas de classe persistantes + if (classes != null) { + // sletellier 20110411 : http://www.nuiton.org/issues/show/1454 + hibernatePersistanceClasses.addAll(Arrays.asList(classes)); +// for (Class<?> clazz : classes) { +// hibernateConfiguration.addClass(clazz); +// } + } + } + + String listPersistenceClasses = getConfig().getProperty( + TopiaContextFactory.CONFIG_PERSISTENCE_CLASSES, ""); + + String[] classes = listPersistenceClasses.split(","); + for (String classname : classes) { + classname = classname.trim(); + if (StringUtils.isNotEmpty(classname)) { + if (log.isDebugEnabled()) { + log.debug("Load persistent class : " + classname); + } + + // XXX echatellier 20111007 ce cqui est dommage ici, c'est + // la definition de cette classe ne sert a rien (apart security) + // car pour hibernate hibernateConfiguration.addClass(persistanceClass) + // il ne se sert pas de la classe en fait et fait seulement + // un classname.replace( '.', '/' ) + ".hbm.xml"; + // pour obtenir le mapping et la reinstancier ensuite + + Class<?> clazz; + try { + clazz = Class.forName(classname); + } catch (ClassNotFoundException eee) { + if (log.isDebugEnabled()) { + log.debug("Class " + classname + " not found"); + } + throw new TopiaNotFoundException( + String.format("Persistence class %1$s not found", + classname)); + } + persistenceClasses.add(clazz); + + // sletellier 20110411 : http://www.nuiton.org/issues/show/1454 +// hibernateConfiguration.addClass(clazz); + hibernatePersistanceClasses.add(clazz); + } + } + + // sletellier 20110411 : http://www.nuiton.org/issues/show/1454 + // Add persistance classes in hibernate config + for (Class<?> persistanceClass : hibernatePersistanceClasses) { + hibernateConfiguration.addClass(persistanceClass); + } + + Properties prop = new Properties(); + prop.putAll(hibernateConfiguration.getProperties()); + prop.putAll(getConfig()); + + // Strange behavior, all properties are already loaded from + // constructor. Difficult to use this behavior, need to have + // TOPIA_PERSISTENCE_PROPERTIES_FILE in config. + Properties propertiesFromClasspath = + TopiaUtil.getProperties(getConfig(). + getProperty(TopiaContextFactory.CONFIG_PERSISTENCE_PROPERTIES_FILE)); + + if (!propertiesFromClasspath.isEmpty()) { + if (log.isDebugEnabled()) { + log.debug("Load properties from file : " + + propertiesFromClasspath); + } + prop.putAll(propertiesFromClasspath); + } + + hibernateConfiguration.setProperties(prop); + + // tchemit 2011-05-26 When using hibernate > 3.3, need to make sure all mappings are loaded (the one from directory files are not still done). + hibernateConfiguration.buildMappings(); + } + } + return hibernateConfiguration; + } + + /* -------------------- CHILD CONTEXT AND DAOS --------------------------*/ + + @Override + public <E extends TopiaEntity> TopiaDAO<E> getDAO(Class<E> entityClass) + throws TopiaException { + if (entityClass == null) { + throw new IllegalArgumentException( + String.format("The method '%1$s' requires a non null parameter '%2$s'.", + "entityClass", "getDAO")); + } + if (equals(getRootContext())) { + throw new TopiaException( + "You are on root context, you MUST open a transaction to perform any database access."); + } + if (getHibernateFactory().getClassMetadata(entityClass) == null && + getHibernateFactory().getClassMetadata( + entityClass.getName() + "Impl") == null && + getHibernateFactory().getClassMetadata( + entityClass.getName() + "Abstract") == null) { + + log.info(String.format("List of supported persistence classes: %1$s", + getHibernateFactory().getAllClassMetadata().keySet())); + throw new TopiaException( + String.format("The following entity type %1$s is not managed by this context, you probably forgot to declare it.", + entityClass.getName())); + } + + TopiaDAOImpl<E> result = (TopiaDAOImpl<E>) daoCache.get(entityClass); + if (result == null) { + + // looking for specialized DAO + // normalement il en existe un car il est généré automatiquement + // si on utilise la génération + String daoClassname = entityClass.getName() + "DAO"; + try { + Class<TopiaDAOImpl<E>> daoClass = + (Class<TopiaDAOImpl<E>>) Class.forName(daoClassname); + TopiaDAOImpl<E> spe = daoClass.getConstructor().newInstance(); + result = spe; + } catch (Exception eee) { + log.warn("specialized DAO " + daoClassname + + " not found, use default TopiaDAOHibernate"); + result = new TopiaDAOImpl<E>(); + } + + result.init(this, entityClass, getFiresSupport()); + daoCache.put(entityClass, result); + } + return result; + } + + @SuppressWarnings({"unchecked"}) + @Override + public <E extends TopiaEntity, D extends TopiaDAO<E>> D getDAO(Class<E> entityClass, + Class<D> daoClass) throws TopiaException { + return (D) getDAO(entityClass); + } + + @Override + public TopiaContext beginTransaction() throws TopiaException { + checkClosed("Context is closed, no operation is possible."); + AbstractTopiaContext result = new AbstractTopiaContext(this); + + SessionFactory factory = getHibernateFactory(); + result.hibernate = factory.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.MANUAL); + + // tchemit 2010-12-06 propagates the value of the flag + result.useFlushMode = useFlushMode; + + // 20060926 poussin ajouter pour voir si ca regle les problemes de + // deadlock h2. Conclusion, il faut bien ouvrir une transaction + // maintenant, sinon lorsque l'on fait des acces a la base, une + // transaction par defaut est utilisé mais elle n'est jamais vraiment + // fermé ce qui pose des problemes de lock sur les tables. + try { + result.hibernate.beginTransaction(); + } catch (Exception eee) { + + // on a pas pu ouvrir la transaction, on faut donc tout fermer + // et declancher une exception + try { + result.hibernate.close(); + } catch (HibernateException e1) { + if (log.isErrorEnabled()) { + log.error("Could not close hibernate session", e1); + } + } + + throw new TopiaException( + String.format("An error occurs while asking a new transaction: %1$s", + eee.getMessage()), + eee); + } + + // 20081217 : add child AFTER hibernate session is opened + addChildContext(result); + + // fire event + getFiresSupport().fireOnBeginTransaction(result); + return result; + } + + @Override + public void commitTransaction() throws TopiaException { + if (equals(getRootContext())) { + throw new TopiaException(String.format("Unsupported operation %s on root context", + "commit")); + } + checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", + "commit")); + + try { +// for (TopiaDAO<? extends TopiaEntity> dao : daoCache.values()) { +// // TODO-fdesbois-20100507 : need to be removed for 2.5 version +// dao.commitTransaction(); +// } + Transaction tx = hibernate.getTransaction(); + // Transaction tx = hibernate.beginTransaction(); + hibernate.flush(); + tx.commit(); + + getFiresSupport().fireOnPostCommit(this); + TopiaContextImplementor parent = getParentContext(); + if (parent != null) { + parent.getFiresSupport().fireOnPostCommit(this); + } + + hibernate.beginTransaction(); + + // it's seem necessary to change session after commit + // NON, NON, NON, il ne faut surtout pas le faire, ca pose plein de + // probleme + // hibernate = getHibernateFactory().openSession(); + // hibernate.setFlushMode(FlushMode.NEVER); + } catch (Exception eee) { + throw new TopiaException(String.format("An error occurs while commit operation: %1$s", + eee.getMessage()), eee); + } + } + + @Override + public void rollbackTransaction() throws TopiaException { + if (equals(getRootContext())) { + throw new TopiaException(String.format("Unsupported operation %s on root context", + "rollback")); + } + checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", + "rollback")); + try { +// for (TopiaDAO<? extends TopiaEntity> dao : daoCache.values()) { +// // TODO-fdesbois-20100507 : need to be removed for 2.5 version +// dao.rollbackTransaction(); +// } + Transaction tx = hibernate.getTransaction(); + // Transaction tx = hibernate.beginTransaction(); + hibernate.clear(); + tx.rollback(); + hibernate.close(); + // it's very important to change the session after rollback + // otherwize there are many error during next Entity's modification + hibernate = getHibernateFactory().openSession(); + hibernate.setFlushMode(FlushMode.MANUAL); + + hibernate.beginTransaction(); + + getFiresSupport().fireOnPostRollback(this); + TopiaContextImplementor parent = getParentContext(); + if (parent != null) { + parent.getFiresSupport().fireOnPostRollback(this); + } + + } catch (HibernateException eee) { + throw new TopiaException( + String.format("An error occurs while rollback operation: %1$s", + eee.getMessage()), eee); + } + } + + @Override + public void closeContext() throws TopiaException { + // Throw exception if context is already closed + checkClosed("Context was already closed"); + + // FD-20100421 : Ano #546 : no need to copy childContext, the + // {@link #getChildContext()} provides a thread-safe copy to iterate + // on it. +// TopiaContextImplementor[] children = childContext.toArray( +// new TopiaContextImplementor[childContext.size()]); + + // Remove all children context + for (TopiaContextImplementor child : getChildContext()) { + // Avoid to have exception from checkClosed method on child + if (!child.isClosed()) { + child.closeContext(); + } + } + + // on se desenregistre du context pere et on ferme les connexions si + // on est pas le root context + if (!equals(getRootContext())) { + closed = true; + hibernate.close(); + getParentContext().removeChildContext(this); + } else { + if (hibernateFactory != null) { + hibernateFactory.close(); + // close connection provider if possible (http://nuiton.org/issues/2757) + ConnectionProvider service = ((SessionFactoryImplementor) hibernateFactory).getServiceRegistry().getService(ConnectionProvider.class); + if (service instanceof Stoppable) { + Stoppable stoppable = (Stoppable) service; + stoppable.stop(); + } + closed = true; + TopiaContextFactory.removeContext(this); + log.debug("TopiaContext removed"); + } + } + } + + /** + * Pour le context root on ferme tous les fils, et la factory hibernate. + */ + @Override + protected void finalize() throws Throwable { + if (hibernateFactory != null) { + closeContext(); + hibernateFactory.close(); + closed = true; + log.debug("TopiaContext finalized"); + } + } + + @Override + public boolean isClosed() { + return closed; + } + + @Override + public void executeSQL(String sqlScript) throws TopiaException { + SQLWork sqlWork = new SQLWork(sqlScript); + try { + getHibernate().doWork(sqlWork); + } catch (HibernateException e) { + throw new TopiaException("Could not execute sql code", e); + } + } + + protected void checkClosed(String message) throws TopiaException { + if (closed) { + throw new TopiaException(message); + } + } + + /* -------------------- GLOBAL OPERATIONS ON SCHEMA ----------------------*/ + + @Override + public <E extends TopiaEntity> E findByTopiaId(String id) throws TopiaException { + checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", + "findById")); + + Class<E> entityClass = getTopiaIdFactory().getClassName(id); + TopiaDAO<E> dao = getDAO(entityClass); + E result = dao.findByTopiaId(id); + return result; + } + + @Override + public <E> List<E> findAll(String jpaql, Object... propertyNamesAndValues) throws TopiaException { + checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", + "findAll")); + + try { + Query query = getHibernate().createQuery(jpaql); + for (int j = 0; j < propertyNamesAndValues.length; j += 2) { + String name = (String) propertyNamesAndValues[j]; + Object value = propertyNamesAndValues[j + 1]; + if (value.getClass().isArray()) { + query.setParameterList(name, (Object[]) value); + } else if (value instanceof Collection<?>) { + query.setParameterList(name, (Collection<?>) value); + } else { + query.setParameter(name, value); + } + } + // tchemit 2010-11-30 reproduce the same behaviour than before with the dao legacy + if (useFlushMode) { + query.setFlushMode(FlushMode.AUTO); + } + List result = query.list(); + result = firesSupport.fireEntitiesLoad(this, result); + return result; + } catch (HibernateException eee) { + throw new TopiaException(String.format("An error occurs while query operation: %1$s : %2$s", + jpaql, eee.getMessage()), eee); + } + } + + @Override + public <E> List<E> find(String jpaql, int startIndex, int endIndex, Object... propertyNamesAndValues) + throws TopiaException { + checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", + "find")); + + try { + Query query = getHibernate().createQuery(jpaql); + for (int j = 0; j < propertyNamesAndValues.length; j += 2) { + String name = (String) propertyNamesAndValues[j]; + Object value = propertyNamesAndValues[j + 1]; + if (value.getClass().isArray()) { + query.setParameterList(name, (Object[]) value); + } else if (value instanceof Collection<?>) { + query.setParameterList(name, (Collection<?>) value); + } else { + query.setParameter(name, value); + } + } + query.setFirstResult(startIndex); + query.setMaxResults(endIndex - startIndex + 1); + // tchemit 2010-11-30 reproduce the same behaviour than before with the dao legacy + if (useFlushMode) { + query.setFlushMode(FlushMode.AUTO); + } + List result = query.list(); + result = firesSupport.fireEntitiesLoad(this, result); + return result; + } catch (HibernateException eee) { + throw new TopiaException(String.format("An error occurs while query operation: %1$s : %2$s", + jpaql, eee.getMessage()), eee); + } + } + + @Override + public <E> E findUnique(String jpaql, Object... propertyNamesAndValues) + throws TopiaException { + checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", + "findUnique")); + + List<E> results = find(jpaql, 0, 1, propertyNamesAndValues); + + // If there is more than 1 result, throw an exception + if (results.size() > 1) { + String message = String.format( + "Query '%s' returns more than 1 unique result", jpaql); + throw new TopiaException(message); + } + + // otherwise return the first one, or null + E result = null; + if (!results.isEmpty()) { + result = results.get(0); + } + return result; + } + + /** + * Execute HQL operation on data (Update, Delete) + * + * @param jpaql HQL query + * @param propertyNamesAndValues arguments for query + * @return The number of entities updated or deleted. + * @throws TopiaException + */ + @Override + public int execute(String jpaql, Object... propertyNamesAndValues) throws TopiaException { + checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", + "find")); + + try { + Query query = getHibernate().createQuery(jpaql); + for (int j = 0; j < propertyNamesAndValues.length; j += 2) { + query.setParameter((String) propertyNamesAndValues[j], propertyNamesAndValues[j + 1]); + } + int result = query.executeUpdate(); + return result; + } catch (HibernateException eee) { + throw new TopiaException(String.format("An error occurs while query operation: %1$s : %2$s", + jpaql, eee.getMessage()), eee); + } + } + + @Override + public void add(TopiaEntity e) throws TopiaException { + update(e); + } + + @Override + public void replicate(TopiaContext dstCtxt, Object... entityAndCondition) + throws TopiaException, IllegalArgumentException { + checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", + "replicate")); + + AbstractTopiaContext dstContextImpl = (AbstractTopiaContext) dstCtxt; + dstContextImpl.checkClosed( + String.format("This context is closed, it is not possible to release the operation '%1$s'", + "replicate")); + + if (getRootContext().equals(dstContextImpl.getRootContext())) { + throw new IllegalArgumentException("Can not do a replication operation on same database."); + } + + String[] queries = buildQueries(entityAndCondition); + try { + for (String query : queries) { + if (log.isDebugEnabled()) { + log.debug("acquire entities " + query); + } + // acquire data to replicate + List<?> entities = findAll(query); + replicate0(dstContextImpl, entities.toArray()); + if (log.isDebugEnabled()) { + log.debug("replication of entities " + query + + " was sucessfully done."); + } + } + } catch (HibernateException eee) { + throw new TopiaException(String.format("An error occurs while a replication operation: %s", + eee.getMessage()), eee); + } + } + + @Override + public <T extends TopiaEntity> void replicateEntity(TopiaContext dstCtxt, + T entity) + throws TopiaException, IllegalArgumentException { + checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", + "replicateEntity")); + + AbstractTopiaContext dstContextImpl = (AbstractTopiaContext) dstCtxt; + dstContextImpl.checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", + "replicateEntity")); + + if (getRootContext().equals(dstContextImpl.getRootContext())) { + throw new IllegalArgumentException("Can not do a replication operation on same database."); + } + replicate0(dstContextImpl, entity); + } + + @Override + public <T extends TopiaEntity> void replicateEntities(TopiaContext dstCtxt, + List<T> entities) + throws TopiaException, IllegalArgumentException { + checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", + "replicateEntities")); + + AbstractTopiaContext dstContextImpl = (AbstractTopiaContext) dstCtxt; + dstContextImpl.checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", + "replicateEntities")); + + if (getRootContext().equals(dstContextImpl.getRootContext())) { + throw new IllegalArgumentException("Can not do a replication operation on same database."); + } + replicate0(dstContextImpl, entities.toArray()); + } + + @Override + public TopiaFiresSupport getFiresSupport() { + return firesSupport; + } + + /** + * Backup database in gzip compressed file. + * <p/> + * <b>Note: </b> Only works for h2 database. + * + * @param file file to write backup + * @param compress if true then use gzip to compress file + * @see TopiaContext#backup(File, boolean) + */ + @Override + public void backup(File file, boolean compress) throws TopiaException { + checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", + "backup")); + try { + String options = ""; + if (compress) { + options += " COMPRESSION GZIP"; + } + + SQLQuery query = getHibernate().createSQLQuery( + "SCRIPT TO '" + file.getAbsolutePath() + "'" + options); + query.list(); + + } catch (Exception eee) { + throw new TopiaException(String.format( + "An error occurs while backup operation: %1$s", + eee.getMessage()), eee); + } + } + + /** + * Read database from gzip compressed file + * <p/> + * Only work for h2 database + * + * @see TopiaContext#restore(File) + */ + @Override + public void restore(File file) throws TopiaException { + // send event + getFiresSupport().firePreRestoreSchema(this); + checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", + "restore")); + + String sql = null; + String options = ""; + try { + // decompresse file in temporary file + InputStream in = new BufferedInputStream(new FileInputStream(file)); + try { + in.mark(2); + + // read header to see if is compressed file + int b = in.read(); + // redundant cast : int magic = ((int) in.read() << 8) | b; + int magic = in.read() << 8 | b; + in.reset(); + + if (magic == GZIPInputStream.GZIP_MAGIC) { + options += " COMPRESSION GZIP"; + } + } finally { + + in.close(); + } + + SQLQuery query = getHibernate().createSQLQuery( + "RUNSCRIPT FROM '" + file.getAbsolutePath() + "'" + options); + + query.executeUpdate(); + + // send event AFTER restore + getFiresSupport().firePostRestoreSchema(this); + } catch (Exception eee) { + throw new TopiaException(String.format( + String.format("An error occurs while restore operation: %1$s : %2$s", + sql, eee.getMessage())), eee); + } + } + + /** + * Only h2 supported for now + * + * @see TopiaContext#clear(boolean) + */ + @Override + public void clear(boolean dropDatabase) throws TopiaException { + try { + AbstractTopiaContext root = (AbstractTopiaContext) getRootContext(); + AbstractTopiaContext tx = (AbstractTopiaContext) root.beginTransaction(); + + String sql = "DROP ALL OBJECTS"; + if (dropDatabase) { + sql += " DELETE FILES"; + } + Query query = tx.getHibernate().createSQLQuery(sql); + query.executeUpdate(); + tx.closeContext(); + root.finalize(); + } catch (Throwable eee) { + throw new TopiaException( + String.format("Error %s on clear operation", eee.getMessage()), eee); + } + } + + /** + * Clear hibernate cache to free memory. + * <p/> + * see http://docs.jboss.org/hibernate/orm/3.5/reference/en-US/html/transactions.ht... + */ + @Override + public void clearCache() throws TopiaException { + getHibernate().clear(); + } + + @Override + public List<Class<?>> getPersistenceClasses() { + return persistenceClasses; + } + + @Override + public boolean isSchemaExist(Class<?> clazz) + throws TopiaException { + checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", + "replicateEntity")); + boolean result = TopiaUtil.isSchemaExist(this, clazz.getName()); + return result; + } + + /* Listeners adders */ + + @Override + public void addTopiaEntityListener(TopiaEntityListener listener) { + getFiresSupport().addTopiaEntityListener(listener); + } + + @Override + public void addTopiaEntityListener( + Class<? extends TopiaEntity> entityClass, + TopiaEntityListener listener) { + getFiresSupport().addTopiaEntityListener(entityClass, listener); + } + + @Override + public void addTopiaEntityVetoable(TopiaEntityVetoable vetoable) { + getFiresSupport().addTopiaEntityVetoable(TopiaEntity.class, vetoable); + } + + @Override + public void addTopiaEntityVetoable( + Class<? extends TopiaEntity> entityClass, + TopiaEntityVetoable vetoable) { + getFiresSupport().addTopiaEntityVetoable(entityClass, vetoable); + } + + @Override + public void addTopiaTransactionListener(TopiaTransactionListener listener) { + getFiresSupport().addTopiaTransactionListener(listener); + } + + @Override + public void addTopiaTransactionVetoable(TopiaTransactionVetoable vetoable) { + getFiresSupport().addTopiaTransactionVetoable(vetoable); + } + + @Override + public void addPropertyChangeListener(PropertyChangeListener listener) { + getFiresSupport().addPropertyChangeListener(listener); + } + + @Override + @Deprecated + public void addTopiaContextListener(TopiaContextListener listener) { + getFiresSupport().addTopiaContextListener(listener); + } + + @Override + public void addTopiaSchemaListener(TopiaSchemaListener listener) { + getFiresSupport().addTopiaSchemaListener(listener); + } + + /* Listeners removers */ + + @Override + public void removeTopiaEntityListener(TopiaEntityListener listener) { + getFiresSupport().removeTopiaEntityListener(TopiaEntity.class, + listener); + } + + @Override + public void removeTopiaEntityListener( + Class<? extends TopiaEntity> entityClass, + TopiaEntityListener listener) { + getFiresSupport().removeTopiaEntityListener(entityClass, listener); + } + + @Override + public void removeTopiaEntityVetoable(TopiaEntityVetoable vetoable) { + getFiresSupport().removeTopiaEntityVetoable(TopiaEntity.class, + vetoable); + } + + @Override + public void removeTopiaEntityVetoable( + Class<? extends TopiaEntity> entityClass, + TopiaEntityVetoable vetoable) { + getFiresSupport().removeTopiaEntityVetoable(entityClass, vetoable); + } + + @Override + public void removeTopiaTransactionListener( + TopiaTransactionListener listener) { + getFiresSupport().removeTopiaTransactionListener(listener); + } + + @Override + public void removeTopiaTransactionVetoable( + TopiaTransactionVetoable vetoable) { + getFiresSupport().removeTopiaTransactionVetoable(vetoable); + } + + @Override + public void removePropertyChangeListener(PropertyChangeListener listener) { + getFiresSupport().removePropertyChangeListener(listener); + } + + @Override + @Deprecated + public void removeTopiaContextListener(TopiaContextListener listener) { + getFiresSupport().removeTopiaContextListener(listener); + } + + @Override + public void removeTopiaSchemaListener(TopiaSchemaListener listener) { + getFiresSupport().removeTopiaSchemaListener(listener); + } + + @Override + public void addTopiaEntitiesVetoable(TopiaEntitiesVetoable vetoable) { + getFiresSupport().addTopiaEntitiesVetoable(vetoable); + } + + @Override + public void removeTopiaEntitiesVetoable(TopiaEntitiesVetoable vetoable) { + getFiresSupport().removeTopiaEntitiesVetoable(vetoable); + } + + /** + * Build the list of queries from the given parameter + * <code>entityAndCondition</code>. + * <p/> + * If no parameter is given, then build the queries for all entities is db, + * with no condition. + * + * @param entityAndCondition the list of tuples (Class,String) + * @return the list of queries. + * @throws TopiaException if any pb of db while getting entities + * classes. + * @throws IllegalArgumentException if any pb with the given parameter + * (mainly ClassCastException). + */ + protected String[] buildQueries(Object... entityAndCondition) + throws TopiaException, IllegalArgumentException { + Class<?> entityClass; + String condition; + + // si entityAndcondition est vide alors il faut le remplir + // avec toutes les entités du mapping (class, null) + if (entityAndCondition.length == 0) { + Map<?, ?> classMetadata = getHibernateFactory().getAllClassMetadata(); + entityAndCondition = new Object[classMetadata.size() * 2]; + int i = 0; + for (Object className : classMetadata.keySet()) { + try { + entityAndCondition[i++] = Class.forName((String) className); + } catch (ClassNotFoundException e) { + // should never happen! + throw new TopiaException( + "class cast exception for entity " + className); + } + entityAndCondition[i++] = null; + + } + } + + // prepare queries to perform beofre opening any transaction + if (entityAndCondition.length % 2 != 0) { + throw new IllegalArgumentException( + "entityAndCondition must be a couple of (Class, String)"); + } + String queries[] = new String[entityAndCondition.length / 2]; + for (int i = 0; i < entityAndCondition.length; ) { + try { + entityClass = (Class<?>) entityAndCondition[i++]; + condition = (String) entityAndCondition[i++]; + String query = "from " + entityClass.getName(); + if (condition != null && !condition.isEmpty()) { + query += " where " + condition; + } + queries[(i - 1) / 2] = query; + } catch (ClassCastException e) { + if (i % 2 == 0) { + throw new IllegalArgumentException( + "Others arguement must be String not " + + entityAndCondition[i - 1], e); + } else { + throw new IllegalArgumentException( + "Others arguement must be Class not " + + entityAndCondition[i - 1], e); + } + } + } + return queries; + } + + protected void replicate0(AbstractTopiaContext dstContextImpl, + Object... entities) throws TopiaException { + try { + for (Object entity : entities) { + // dettach entity to source session, to make possible copy of + // collection without a hibernate exception (list opened in + // two session...) + getHibernate().evict(entity); + dstContextImpl.getHibernate().replicate(entity, + ReplicationMode.EXCEPTION); + } + + } catch (HibernateException eee) { + throw new TopiaException(String.format("An error occurs while a replication operation : %s", + eee.getMessage()), eee); + } + } + + public static class SQLWork implements Work { + private final String script; + + public SQLWork(String script) { + this.script = script; + } + + @Override + public void execute(Connection connection) throws SQLException { + PreparedStatement sta = connection.prepareStatement(script); + try { + sta.execute(); + } finally { + sta.close(); + } + } + } + + @Override + public Session getHibernateSession() throws TopiaException { + if (hibernate == null) { + throw new TopiaException("No hibernate session"); + } + return hibernate; + } + + @Override + public void update(TopiaEntity e) throws TopiaException { + checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", + "add")); + + String id = e.getTopiaId(); + Class<TopiaEntity> entityClass = getTopiaIdFactory().getClassName(id); + TopiaDAO<TopiaEntity> dao = getDAO(entityClass); + dao.update(e); + } + +} //AbstractTopiaContext + Deleted: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -1,1538 +0,0 @@ -/* - * #%L - * ToPIA :: Persistence - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2004 - 2013 CodeLutin, Chatellier Eric - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ - -package org.nuiton.topia.framework; - -import java.beans.PropertyChangeListener; -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.lang.reflect.Field; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.WeakHashMap; -import java.util.zip.GZIPInputStream; - -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.hibernate.FlushMode; -import org.hibernate.HibernateException; -import org.hibernate.Query; -import org.hibernate.ReplicationMode; -import org.hibernate.SQLQuery; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.Transaction; -import org.hibernate.cfg.Configuration; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.event.service.spi.EventListenerRegistry; -import org.hibernate.event.spi.EventType; -import org.hibernate.jdbc.Work; -import org.hibernate.service.ServiceRegistry; -import org.hibernate.service.ServiceRegistryBuilder; -import org.hibernate.service.jdbc.connections.spi.ConnectionProvider; -import org.hibernate.service.spi.Stoppable; -import org.hibernate.tool.hbm2ddl.SchemaExport; -import org.hibernate.tool.hbm2ddl.SchemaUpdate; -import org.nuiton.topia.TopiaContext; -import org.nuiton.topia.TopiaContextFactory; -import org.nuiton.topia.TopiaException; -import org.nuiton.topia.TopiaNotFoundException; -import org.nuiton.topia.event.TopiaContextListener; -import org.nuiton.topia.event.TopiaEntitiesVetoable; -import org.nuiton.topia.event.TopiaEntityListener; -import org.nuiton.topia.event.TopiaEntityVetoable; -import org.nuiton.topia.event.TopiaSchemaListener; -import org.nuiton.topia.event.TopiaTransactionListener; -import org.nuiton.topia.event.TopiaTransactionVetoable; -import org.nuiton.topia.persistence.DefaultTopiaIdFactory; -import org.nuiton.topia.persistence.TopiaDAO; -import org.nuiton.topia.persistence.TopiaDAOImpl; -import org.nuiton.topia.persistence.TopiaEntity; -import org.nuiton.topia.persistence.TopiaIdFactory; - -/** - * Le TopiaContextImpl est le point d'entre pour acceder aux donnees. Il est - * configurer par un fichier de propriete - * <p/> - * List des proprietes disponible <dl> <dt> topia.persistence.properties.file - * <dd> le fichier de propriété a utiliser pour configurer hibernate - * <p/> - * <dt> topia.persistence.directories <dd> la liste des repertoires contenant - * les mappings hibernates (.hbm.xml) la liste de repertoire est separer par des - * virgules ',' - * <p/> - * <dt> topia.persistence.classes <dd> 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 </dl> - * <p/> - * TopiaContextImpl.java - * <p/> - * Created: 23 déc. 2005 16:58:50 - * - * @author bpoussin <poussin@codelutin.com> - * @author tchemit <chemit@codelutin.com> - * @author fdesbois <desbois@codelutin.com> - * @version $Id$ - */ -//TODO-fdesbois-20100507 : Need translation of javadoc. -public class TopiaContextImpl implements TopiaContextImplementor { - - /** - * to use log facility, just put in your code: log.info(\"...\"); - */ - private static final Log log = LogFactory.getLog(TopiaContextImpl.class); - - /** - * Le pere de ce context, les contexts initaux n'ont pas de context pere - */ - protected TopiaContextImplementor parentContext; - - /** - * L'objet configuration utilisé pour la creation de la factory hibernate - */ - protected Configuration hibernateConfiguration; - - /** - * la factory permettant de recuperer la session hibernate. Seul les - * TopiaContextImpl initiaux contiennent un hibernateFactory - */ - protected SessionFactory hibernateFactory; - - /** - * La session utilisé par le TopiaContextImpl - */ - protected Session hibernate; - - /** - * Indique si le contexte a ete ferme - */ - protected boolean closed; - - /** - * This flag permits to use (or not) the flush mode when doing queries. - * <p/> - * The normal usage is to says yes (that's why the default value is - * {@code true}), in that case whebn doing queries (says in method - * {@link #findAll(String, Object...)} or {@link #find(String, int, int, Object...)}) - * it will use the flush mode {@link FlushMode#AUTO}). - * <p/> - * But sometimes, when doing a lot of queries (for some imports for example), - * we do NOT want the session to be flushed each time we do a find, then you - * can set this flag to {@code false} using the method {@link #setUseFlushMode(boolean)} - * - * @since 2.5 - */ - protected boolean useFlushMode = true; - - /** - * Propriete de configuration - */ - protected Properties config; - - /** - * Used to affect a new topiaId when create is called. - * - * @since 3.0 - */ - protected TopiaIdFactory topiaIdFactory; - - /** - * cache des DAO deja chargé pour ce context - */ - protected Map<Class<? extends TopiaEntity>, - TopiaDAO<? extends TopiaEntity>> daoCache = - new HashMap<Class<? extends TopiaEntity>, - TopiaDAO<? extends TopiaEntity>>(); - - /** - * Set of child context created with {@link #beginTransaction()}. We are - * listener on these context. A WeakHashMap is used to remove old context - * automically when it's not used anymore. The {@link #finalize} method will - * be executed when Garbage collector is called when reference is removed. - * The set is synchronized in case of using multi-threading. - * - * @see Collections#synchronizedSet(Set) - * @see Collections#newSetFromMap(Map) - */ - protected final Set<TopiaContextImplementor> childContext = - Collections.synchronizedSet( - Collections.newSetFromMap( - new WeakHashMap<TopiaContextImplementor, Boolean>())); - - /** - * key: service name; value: service instance - */ - protected Map<String, TopiaService> services; - - protected TopiaFiresSupport firesSupport = new TopiaFiresSupport(); - - /** - * Liste des classes perssitance - */ - protected List<Class<?>> persistenceClasses = new ArrayList<Class<?>>(); - - /** - * Default constructor, useful for tests. - */ - protected TopiaContextImpl() { - - } - - /** - * Constructor used by {@link TopiaContextFactory} to initialize rootContext - * using {@code config}. - * - * @param config for the new root context - * @throws TopiaNotFoundException if one of persistent class from - * configuration is not found - */ - public TopiaContextImpl(Properties config) throws TopiaNotFoundException { - this.config = config; - initTopiaIdFactory(); - services = loadServices(config); - preInitServices(services); - getHibernateConfiguration(); // force mapping loading - postInitServices(services); - } - - protected void initTopiaIdFactory() { - String configTopiaIdFactoryClassName = - getConfig().getProperty(TopiaContextFactory.CONFIG_PERSISTENCE_TOPIA_ID_FACTORY_CLASS_NAME, ""); - if (StringUtils.isEmpty(configTopiaIdFactoryClassName)) { - topiaIdFactory = new DefaultTopiaIdFactory(); - } else { - try { - Class configPersistenceTopiaIdFactoryClass = - Class.forName(configTopiaIdFactoryClassName); - if (TopiaIdFactory.class.isAssignableFrom(configPersistenceTopiaIdFactoryClass)) { - topiaIdFactory = (TopiaIdFactory) configPersistenceTopiaIdFactoryClass.newInstance(); - } else { - throw new IllegalArgumentException( - configTopiaIdFactoryClassName + " is not a valid class name. The class must implements " - + TopiaIdFactory.class.getSimpleName()); - } - } catch (ClassNotFoundException e) { - throw new TopiaException(e); - } catch (InstantiationException e) { - throw new TopiaException(e); - } catch (IllegalAccessException e) { - throw new TopiaException(e); - } - } - } - - protected String getProperExceptionMessage(Throwable eee) { - return eee.getClass().getSimpleName() + " : " + - eee.getMessage(); - } - - /* -------------------- SERVICES MANAGMENT -------------------------------*/ - - protected Map<String, TopiaService> loadServices(Properties config) { - Map<String, TopiaService> result = new HashMap<String, TopiaService>(); - // recherche des services present dans la config - for (Enumeration<?> e = config.propertyNames(); e.hasMoreElements(); ) { - String key = (String) e.nextElement(); - if (key.matches("^topia\\.service\\.\\w+$")) { - String classService = config.getProperty(key); - try { - Class<?> forName = Class.forName(classService); - Object newInstance = forName.getConstructor().newInstance(); - TopiaService service = (TopiaService) newInstance; - if (key.equals("topia.service." + service.getServiceName())) { - result.put(service.getServiceName(), service); - log.info(String.format("Service '%1$s' loaded (implementation %2$s)", - key, classService)); - } else { - log.warn(String.format("The service with key '%1$s' has a different name '%2$s'! (service not activated)", - key, service.getServiceName())); - } - } catch (Throwable eee) { - String message = - String.format("The service %1$s of type %2$s was not found.", - key, classService); - if (log.isDebugEnabled()) { - log.debug(message, eee); - } else if (log.isErrorEnabled()) { - log.error(message); - } - } - } - } - return result; - } - - protected void preInitServices(Map<String, TopiaService> services) { - for (TopiaService service : services.values()) { - if (!service.preInit(this)) { - log.warn(String.format("The service named '%1$s' could not be post-initialized (service not activated)", - service.getServiceName())); - } - } - } - - protected void postInitServices(Map<String, TopiaService> services) { - for (TopiaService service : services.values()) { - if (!service.postInit(this)) { - log.warn(String.format("The service named '%1$s' could not be pre-initialized (service not activated)", - service.getServiceName())); - } - } - } - - protected TopiaService getService(String name) { - TopiaService result = getServices().get(name); - return result; - } - - protected boolean serviceEnabled(String name) { - boolean result = getServices().containsKey(name); - return result; - } - - /** - * Retrieve service name using SERVICE_NAME static field on service - * interface. - * - * @param interfaceService class of the service - * @param <E> type of the service that extends {@link - * TopiaService} - * @return the service name - * @throws IllegalAccessException if field SERVICE_NAME can't be accessed - * @throws NoSuchFieldException if no field SERVICE_NAME is defined - */ - protected <E extends TopiaService> String getServiceName( - Class<E> interfaceService) - throws IllegalAccessException, NoSuchFieldException { - Field f = interfaceService.getField("SERVICE_NAME"); - String name = (String) f.get(null); - return name; - } - - @Override - public Map<String, TopiaService> getServices() { - TopiaContextImplementor parent = getParentContext(); - - Map<String, TopiaService> result; - if (parent != null) { - result = parent.getServices(); - } else { - result = services; - } - return result; - } - - /** - * Take one service, this service must be valid service interface with - * public static final SERVICE_NAME declaration. - * - * @param <E> type of the service that extends {@link TopiaService} - * @throws TopiaNotFoundException if an error appears or service not found. - * @see #getServiceName(Class) - */ - @Override - public <E extends TopiaService> E getService(Class<E> interfaceService) - throws TopiaNotFoundException { - E result; - try { - String name = getServiceName(interfaceService); - result = (E) getService(name); - } catch (Exception eee) { - throw new TopiaNotFoundException( - String.format("Could not retreave service %1$s for following reason: %2$s", - interfaceService, getProperExceptionMessage(eee)), - eee); - } - if (result == null) { - throw new TopiaNotFoundException( - String.format("The service %1$s was not found.", - interfaceService)); - } - return result; - } - - @Override - public <E extends TopiaService> boolean serviceEnabled( - Class<E> interfaceService) { - boolean result = false; - try { - String name = getServiceName(interfaceService); - result = serviceEnabled(name); - } catch (Exception eee) { - String message = String.format("The service named '%1$s' could not be found for following reason: %2$s", - interfaceService, getProperExceptionMessage(eee)); - if (log.isDebugEnabled()) { - log.debug(message, eee); - } else if (log.isWarnEnabled()) { - log.warn(message); - } - } - return result; - } - - /* -------------------- CONTEXT HIERARCHY MANAGMENT ----------------------*/ - - /** - * Constructor used by {@link #beginTransaction()} to instantiate child from - * {@code parentContext}. - * - * @param parentContext context parent of the new TopiaContext child - */ - protected TopiaContextImpl(TopiaContextImplementor parentContext) { - this.parentContext = parentContext; - } - - @Override - public Set<TopiaContextImplementor> getChildContext() { - // fdesbois-20100421 : Ano #546 - // Copy the childContext into a new set - Set<TopiaContextImplementor> values; - // Synchronize copy to be thread-safe during iteration - synchronized (childContext) { - values = new HashSet<TopiaContextImplementor>(childContext); - } - return values; - } - - protected void addChildContext(TopiaContextImplementor child) { - childContext.add(child); - } - - @Override - public void removeChildContext(TopiaContextImplementor child) { - // Remove child only if this context is not already closed. - if (!closed) { - childContext.remove(child); - } - } - - @Override - public TopiaContextImplementor getParentContext() { - return parentContext; - } - - @Override - public TopiaContextImplementor getRootContext() { - TopiaContextImplementor result = this; - if (getParentContext() != null) { - result = getParentContext().getRootContext(); - } - return result; - } - - @Override - public Properties getConfig() { - if (config == null && getParentContext() != null) { - config = getParentContext().getConfig(); - } - return config; - } - - @Override - public TopiaIdFactory getTopiaIdFactory() { - if (topiaIdFactory == null) { - initTopiaIdFactory(); - } - return topiaIdFactory; - } - - /** - * Change the value of flag {@link #useFlushMode}. - * - * @param useFlushMode the new value to set - * @see #useFlushMode - * @since 2.5 - */ - public void setUseFlushMode(boolean useFlushMode) { - this.useFlushMode = useFlushMode; - } - - /* -------------------- HIBERNATE MANAGMENT -----------------------------*/ - - @Override - public void createSchema() throws TopiaException { - try { - boolean showSchema = false; - if (log.isDebugEnabled()) { - showSchema = true; - } - getFiresSupport().firePreCreateSchema(this); - new SchemaExport(getHibernateConfiguration()).execute(showSchema, true, false, true); - getFiresSupport().firePostCreateSchema(this); - } catch (HibernateException eee) { - throw new TopiaException( - String.format("Could not create schema for reason: %s", - eee.getMessage()), eee); - } - } - - @Override - public void showCreateSchema() throws TopiaException { - try { - new SchemaExport(getHibernateConfiguration()). - execute(true, false, false, true); - } catch (HibernateException eee) { - throw new TopiaException( - String.format("Could not show create schema for reason: %s", - eee.getMessage()), eee); - } - } - - @Override - public void updateSchema() throws TopiaException { - try { - boolean showSchema = false; - if (log.isDebugEnabled()) { - showSchema = true; - } - getFiresSupport().firePreUpdateSchema(this); - new SchemaUpdate(getHibernateConfiguration()).execute(showSchema, - true); - getFiresSupport().firePostUpdateSchema(this); - } catch (HibernateException eee) { - throw new TopiaException( - String.format("Could not update schema for reason: %s", - eee.getMessage()), eee); - } - } - - @Override - public void dropSchema() throws TopiaException { - try { - boolean showSchema = false; - if (log.isDebugEnabled()) { - showSchema = true; - } - getFiresSupport().firePreDropSchema(this); - new SchemaExport(getHibernateConfiguration()).execute(showSchema, true, true, false); - getFiresSupport().firePostDropSchema(this); - } catch (HibernateException eee) { - throw new TopiaException( - String.format("Could not drop schema for reason: %s", - eee.getMessage()), eee); - } - } - - @Override - public Session getHibernate() throws TopiaException { - Session result = getHibernateSession(); - return result; - } - - @Override - public SessionFactory getHibernateFactory() throws TopiaNotFoundException { - if (hibernateFactory == null) { - if (getParentContext() != null) { - hibernateFactory = getParentContext().getHibernateFactory(); - } else { - - // init service registry - ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings( - getHibernateConfiguration().getProperties()).buildServiceRegistry(); - - hibernateFactory = getHibernateConfiguration().buildSessionFactory(serviceRegistry); - - // we can't reuse original serviceRegistry instance - // we must call getServiceRegistry on factory to get a working one - ServiceRegistry serviceRegistryInit = ((SessionFactoryImplementor) hibernateFactory).getServiceRegistry(); - EventListenerRegistry eventListenerRegistry = serviceRegistryInit.getService(EventListenerRegistry.class); - TopiaFiresSupport.TopiaHibernateEvent listener = new TopiaFiresSupport.TopiaHibernateEvent(this); - eventListenerRegistry.appendListeners(EventType.PRE_INSERT, listener); - eventListenerRegistry.appendListeners(EventType.PRE_LOAD, listener); - eventListenerRegistry.appendListeners(EventType.PRE_UPDATE, listener); - eventListenerRegistry.appendListeners(EventType.PRE_DELETE, listener); - eventListenerRegistry.appendListeners(EventType.POST_INSERT, listener); - eventListenerRegistry.appendListeners(EventType.POST_LOAD, listener); - eventListenerRegistry.appendListeners(EventType.POST_UPDATE, listener); - eventListenerRegistry.appendListeners(EventType.POST_DELETE, listener); - - // following listeners must be called before hibernate - eventListenerRegistry.prependListeners(EventType.SAVE_UPDATE, listener); - } - } - return hibernateFactory; - } - - @Override - public Configuration getHibernateConfiguration() - throws TopiaNotFoundException { - if (hibernateConfiguration == null) { - if (getParentContext() != null) { - hibernateConfiguration = getParentContext().getHibernateConfiguration(); - } else { - hibernateConfiguration = new Configuration(); - - // ajout des repertoires contenant les mappings hibernate - String[] dirs = getConfig().getProperty( - TopiaContextFactory.CONFIG_PERSISTENCE_DIRECTORIES, "").split(","); - for (String dir : dirs) { - dir = dir.trim(); - if (StringUtils.isNotEmpty(dir)) { - if (log.isDebugEnabled()) { - log.debug("Load persistence from dir : " + dir); - } - hibernateConfiguration.addDirectory(new File(dir)); - } - } - - // ajout des classes dites persistentes - Set<Class<?>> hibernatePersistanceClasses = new HashSet<Class<?>>(); - for (TopiaService service : getServices().values()) { - Class<?>[] classes = service.getPersistenceClasses(); - - // certains service n'ont pas de classe persistantes - if (classes != null) { - // sletellier 20110411 : http://www.nuiton.org/issues/show/1454 - hibernatePersistanceClasses.addAll(Arrays.asList(classes)); -// for (Class<?> clazz : classes) { -// hibernateConfiguration.addClass(clazz); -// } - } - } - - String listPersistenceClasses = getConfig().getProperty( - TopiaContextFactory.CONFIG_PERSISTENCE_CLASSES, ""); - - String[] classes = listPersistenceClasses.split(","); - for (String classname : classes) { - classname = classname.trim(); - if (StringUtils.isNotEmpty(classname)) { - if (log.isDebugEnabled()) { - log.debug("Load persistent class : " + classname); - } - - // XXX echatellier 20111007 ce cqui est dommage ici, c'est - // la definition de cette classe ne sert a rien (apart security) - // car pour hibernate hibernateConfiguration.addClass(persistanceClass) - // il ne se sert pas de la classe en fait et fait seulement - // un classname.replace( '.', '/' ) + ".hbm.xml"; - // pour obtenir le mapping et la reinstancier ensuite - - Class<?> clazz; - try { - clazz = Class.forName(classname); - } catch (ClassNotFoundException eee) { - if (log.isDebugEnabled()) { - log.debug("Class " + classname + " not found"); - } - throw new TopiaNotFoundException( - String.format("Persistence class %1$s not found", - classname)); - } - persistenceClasses.add(clazz); - - // sletellier 20110411 : http://www.nuiton.org/issues/show/1454 -// hibernateConfiguration.addClass(clazz); - hibernatePersistanceClasses.add(clazz); - } - } - - // sletellier 20110411 : http://www.nuiton.org/issues/show/1454 - // Add persistance classes in hibernate config - for (Class<?> persistanceClass : hibernatePersistanceClasses) { - hibernateConfiguration.addClass(persistanceClass); - } - - Properties prop = new Properties(); - prop.putAll(hibernateConfiguration.getProperties()); - prop.putAll(getConfig()); - - // Strange behavior, all properties are already loaded from - // constructor. Difficult to use this behavior, need to have - // TOPIA_PERSISTENCE_PROPERTIES_FILE in config. - Properties propertiesFromClasspath = - TopiaUtil.getProperties(getConfig(). - getProperty(TopiaContextFactory.CONFIG_PERSISTENCE_PROPERTIES_FILE)); - - if (!propertiesFromClasspath.isEmpty()) { - if (log.isDebugEnabled()) { - log.debug("Load properties from file : " + - propertiesFromClasspath); - } - prop.putAll(propertiesFromClasspath); - } - - hibernateConfiguration.setProperties(prop); - - // tchemit 2011-05-26 When using hibernate > 3.3, need to make sure all mappings are loaded (the one from directory files are not still done). - hibernateConfiguration.buildMappings(); - } - } - return hibernateConfiguration; - } - - /* -------------------- CHILD CONTEXT AND DAOS --------------------------*/ - - @SuppressWarnings({"unchecked"}) - @Override - public <E extends TopiaEntity> TopiaDAO<E> getDAO(Class<E> entityClass) - throws TopiaException { - if (entityClass == null) { - throw new IllegalArgumentException( - String.format("The method '%1$s' requires a non null parameter '%2$s'.", - "entityClass", "getDAO")); - } - if (equals(getRootContext())) { - throw new TopiaException( - "You are on root context, you MUST open a transaction to perform any database access."); - } - if (getHibernateFactory().getClassMetadata(entityClass) == null && - getHibernateFactory().getClassMetadata( - entityClass.getName() + "Impl") == null && - getHibernateFactory().getClassMetadata( - entityClass.getName() + "Abstract") == null) { - - log.info(String.format("List of supported persistence classes: %1$s", - getHibernateFactory().getAllClassMetadata().keySet())); - throw new TopiaException( - String.format("The following entity type %1$s is not managed by this context, you probably forgot to declare it.", - entityClass.getName())); - } - - TopiaDAO<E> result = (TopiaDAO<E>) daoCache.get(entityClass); - if (result == null) { - - // looking for specialized DAO - // normalement il en existe un car il est généré automatiquement - // si on utilise la génération - String daoClassname = entityClass.getName() + "DAO"; - try { - Class<TopiaDAO<E>> daoClass = - (Class<TopiaDAO<E>>) Class.forName(daoClassname); - TopiaDAO<E> spe = daoClass.getConstructor().newInstance(); - result = spe; - } catch (Exception eee) { - log.warn("specialized DAO " + daoClassname + - " not found, use default TopiaDAOHibernate"); - result = new TopiaDAOImpl<E>(); - } - - result.init(this, entityClass); - daoCache.put(entityClass, result); - } - return result; - } - - @SuppressWarnings({"unchecked"}) - @Override - public <E extends TopiaEntity, D extends TopiaDAO<E>> D getDAO(Class<E> entityClass, - Class<D> daoClass) throws TopiaException { - return (D) getDAO(entityClass); - } - - @Override - public TopiaContext beginTransaction() throws TopiaException { - checkClosed("Context is closed, no operation is possible."); - TopiaContextImpl result = new TopiaContextImpl(this); - - SessionFactory factory = getHibernateFactory(); - result.hibernate = factory.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.MANUAL); - - // tchemit 2010-12-06 propagates the value of the flag - result.useFlushMode = useFlushMode; - - // 20060926 poussin ajouter pour voir si ca regle les problemes de - // deadlock h2. Conclusion, il faut bien ouvrir une transaction - // maintenant, sinon lorsque l'on fait des acces a la base, une - // transaction par defaut est utilisé mais elle n'est jamais vraiment - // fermé ce qui pose des problemes de lock sur les tables. - try { - result.hibernate.beginTransaction(); - } catch (Exception eee) { - - // on a pas pu ouvrir la transaction, on faut donc tout fermer - // et declancher une exception - try { - result.hibernate.close(); - } catch (HibernateException e1) { - if (log.isErrorEnabled()) { - log.error("Could not close hibernate session", e1); - } - } - - throw new TopiaException( - String.format("An error occurs while asking a new transaction: %1$s", - eee.getMessage()), - eee); - } - - // 20081217 : add child AFTER hibernate session is opened - addChildContext(result); - - // fire event - getFiresSupport().fireOnBeginTransaction(result); - return result; - } - - @Override - public void commitTransaction() throws TopiaException { - if (equals(getRootContext())) { - throw new TopiaException(String.format("Unsupported operation %s on root context", - "commit")); - } - checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", - "commit")); - - try { -// for (TopiaDAO<? extends TopiaEntity> dao : daoCache.values()) { -// // TODO-fdesbois-20100507 : need to be removed for 2.5 version -// dao.commitTransaction(); -// } - Transaction tx = hibernate.getTransaction(); - // Transaction tx = hibernate.beginTransaction(); - hibernate.flush(); - tx.commit(); - - getFiresSupport().fireOnPostCommit(this); - TopiaContextImplementor parent = getParentContext(); - if (parent != null) { - parent.getFiresSupport().fireOnPostCommit(this); - } - - hibernate.beginTransaction(); - - // it's seem necessary to change session after commit - // NON, NON, NON, il ne faut surtout pas le faire, ca pose plein de - // probleme - // hibernate = getHibernateFactory().openSession(); - // hibernate.setFlushMode(FlushMode.NEVER); - } catch (Exception eee) { - throw new TopiaException(String.format("An error occurs while commit operation: %1$s", - eee.getMessage()), eee); - } - } - - @Override - public void rollbackTransaction() throws TopiaException { - if (equals(getRootContext())) { - throw new TopiaException(String.format("Unsupported operation %s on root context", - "rollback")); - } - checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", - "rollback")); - try { -// for (TopiaDAO<? extends TopiaEntity> dao : daoCache.values()) { -// // TODO-fdesbois-20100507 : need to be removed for 2.5 version -// dao.rollbackTransaction(); -// } - Transaction tx = hibernate.getTransaction(); - // Transaction tx = hibernate.beginTransaction(); - hibernate.clear(); - tx.rollback(); - hibernate.close(); - // it's very important to change the session after rollback - // otherwize there are many error during next Entity's modification - hibernate = getHibernateFactory().openSession(); - hibernate.setFlushMode(FlushMode.MANUAL); - - hibernate.beginTransaction(); - - getFiresSupport().fireOnPostRollback(this); - TopiaContextImplementor parent = getParentContext(); - if (parent != null) { - parent.getFiresSupport().fireOnPostRollback(this); - } - - } catch (HibernateException eee) { - throw new TopiaException( - String.format("An error occurs while rollback operation: %1$s", - eee.getMessage()), eee); - } - } - - @Override - public void closeContext() throws TopiaException { - // Throw exception if context is already closed - checkClosed("Context was already closed"); - - // FD-20100421 : Ano #546 : no need to copy childContext, the - // {@link #getChildContext()} provides a thread-safe copy to iterate - // on it. -// TopiaContextImplementor[] children = childContext.toArray( -// new TopiaContextImplementor[childContext.size()]); - - // Remove all children context - for (TopiaContextImplementor child : getChildContext()) { - // Avoid to have exception from checkClosed method on child - if (!child.isClosed()) { - child.closeContext(); - } - } - - // on se desenregistre du context pere et on ferme les connexions si - // on est pas le root context - if (!equals(getRootContext())) { - closed = true; - hibernate.close(); - getParentContext().removeChildContext(this); - } else { - if (hibernateFactory != null) { - hibernateFactory.close(); - // close connection provider if possible (http://nuiton.org/issues/2757) - ConnectionProvider service = ((SessionFactoryImplementor) hibernateFactory).getServiceRegistry().getService(ConnectionProvider.class); - if (service instanceof Stoppable) { - Stoppable stoppable = (Stoppable) service; - stoppable.stop(); - } - closed = true; - TopiaContextFactory.removeContext(this); - log.debug("TopiaContext removed"); - } - } - } - - /** - * Pour le context root on ferme tous les fils, et la factory hibernate. - */ - @Override - protected void finalize() throws Throwable { - if (hibernateFactory != null) { - closeContext(); - hibernateFactory.close(); - closed = true; - log.debug("TopiaContext finalized"); - } - } - - @Override - public boolean isClosed() { - return closed; - } - - @Override - public void executeSQL(String sqlScript) throws TopiaException { - SQLWork sqlWork = new SQLWork(sqlScript); - try { - getHibernate().doWork(sqlWork); - } catch (HibernateException e) { - throw new TopiaException("Could not execute sql code", e); - } - } - - protected void checkClosed(String message) throws TopiaException { - if (closed) { - throw new TopiaException(message); - } - } - - /* -------------------- GLOBAL OPERATIONS ON SCHEMA ----------------------*/ - - @Override - public <E extends TopiaEntity> E findByTopiaId(String id) throws TopiaException { - checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", - "findById")); - - Class<E> entityClass = getTopiaIdFactory().getClassName(id); - TopiaDAO<E> dao = getDAO(entityClass); - E result = dao.findByTopiaId(id); - return result; - } - - @Override - public <E> List<E> findAll(String jpaql, Object... propertyNamesAndValues) throws TopiaException { - checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", - "findAll")); - - try { - Query query = getHibernate().createQuery(jpaql); - for (int j = 0; j < propertyNamesAndValues.length; j += 2) { - String name = (String) propertyNamesAndValues[j]; - Object value = propertyNamesAndValues[j + 1]; - if (value.getClass().isArray()) { - query.setParameterList(name, (Object[]) value); - } else if (value instanceof Collection<?>) { - query.setParameterList(name, (Collection<?>) value); - } else { - query.setParameter(name, value); - } - } - // tchemit 2010-11-30 reproduce the same behaviour than before with the dao legacy - if (useFlushMode) { - query.setFlushMode(FlushMode.AUTO); - } - List result = query.list(); - result = firesSupport.fireEntitiesLoad(this, result); - return result; - } catch (HibernateException eee) { - throw new TopiaException(String.format("An error occurs while query operation: %1$s : %2$s", - jpaql, eee.getMessage()), eee); - } - } - - @Override - public <E> List<E> find(String jpaql, int startIndex, int endIndex, Object... propertyNamesAndValues) - throws TopiaException { - checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", - "find")); - - try { - Query query = getHibernate().createQuery(jpaql); - for (int j = 0; j < propertyNamesAndValues.length; j += 2) { - String name = (String) propertyNamesAndValues[j]; - Object value = propertyNamesAndValues[j + 1]; - if (value.getClass().isArray()) { - query.setParameterList(name, (Object[]) value); - } else if (value instanceof Collection<?>) { - query.setParameterList(name, (Collection<?>) value); - } else { - query.setParameter(name, value); - } - } - query.setFirstResult(startIndex); - query.setMaxResults(endIndex - startIndex + 1); - // tchemit 2010-11-30 reproduce the same behaviour than before with the dao legacy - if (useFlushMode) { - query.setFlushMode(FlushMode.AUTO); - } - List result = query.list(); - result = firesSupport.fireEntitiesLoad(this, result); - return result; - } catch (HibernateException eee) { - throw new TopiaException(String.format("An error occurs while query operation: %1$s : %2$s", - jpaql, eee.getMessage()), eee); - } - } - - @Override - public <E> E findUnique(String jpaql, Object... propertyNamesAndValues) - throws TopiaException { - checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", - "findUnique")); - - List<E> results = find(jpaql, 0, 1, propertyNamesAndValues); - - // If there is more than 1 result, throw an exception - if (results.size() > 1) { - String message = String.format( - "Query '%s' returns more than 1 unique result", jpaql); - throw new TopiaException(message); - } - - // otherwise return the first one, or null - E result = null; - if (!results.isEmpty()) { - result = results.get(0); - } - return result; - } - - /** - * Execute HQL operation on data (Update, Delete) - * - * @param jpaql HQL query - * @param propertyNamesAndValues arguments for query - * @return The number of entities updated or deleted. - * @throws TopiaException - */ - @Override - public int execute(String jpaql, Object... propertyNamesAndValues) throws TopiaException { - checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", - "find")); - - try { - Query query = getHibernate().createQuery(jpaql); - for (int j = 0; j < propertyNamesAndValues.length; j += 2) { - query.setParameter((String) propertyNamesAndValues[j], propertyNamesAndValues[j + 1]); - } - int result = query.executeUpdate(); - return result; - } catch (HibernateException eee) { - throw new TopiaException(String.format("An error occurs while query operation: %1$s : %2$s", - jpaql, eee.getMessage()), eee); - } - } - - @Override - public void add(TopiaEntity e) throws TopiaException { - update(e); - } - - @Override - public void replicate(TopiaContext dstCtxt, Object... entityAndCondition) - throws TopiaException, IllegalArgumentException { - checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", - "replicate")); - - TopiaContextImpl dstContextImpl = (TopiaContextImpl) dstCtxt; - dstContextImpl.checkClosed( - String.format("This context is closed, it is not possible to release the operation '%1$s'", - "replicate")); - - if (getRootContext().equals(dstContextImpl.getRootContext())) { - throw new IllegalArgumentException("Can not do a replication operation on same database."); - } - - String[] queries = buildQueries(entityAndCondition); - try { - for (String query : queries) { - if (log.isDebugEnabled()) { - log.debug("acquire entities " + query); - } - // acquire data to replicate - List<?> entities = findAll(query); - replicate0(dstContextImpl, entities.toArray()); - if (log.isDebugEnabled()) { - log.debug("replication of entities " + query + - " was sucessfully done."); - } - } - } catch (HibernateException eee) { - throw new TopiaException(String.format("An error occurs while a replication operation: %s", - eee.getMessage()), eee); - } - } - - @Override - public <T extends TopiaEntity> void replicateEntity(TopiaContext dstCtxt, - T entity) - throws TopiaException, IllegalArgumentException { - checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", - "replicateEntity")); - - TopiaContextImpl dstContextImpl = (TopiaContextImpl) dstCtxt; - dstContextImpl.checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", - "replicateEntity")); - - if (getRootContext().equals(dstContextImpl.getRootContext())) { - throw new IllegalArgumentException("Can not do a replication operation on same database."); - } - replicate0(dstContextImpl, entity); - } - - @Override - public <T extends TopiaEntity> void replicateEntities(TopiaContext dstCtxt, - List<T> entities) - throws TopiaException, IllegalArgumentException { - checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", - "replicateEntities")); - - TopiaContextImpl dstContextImpl = (TopiaContextImpl) dstCtxt; - dstContextImpl.checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", - "replicateEntities")); - - if (getRootContext().equals(dstContextImpl.getRootContext())) { - throw new IllegalArgumentException("Can not do a replication operation on same database."); - } - replicate0(dstContextImpl, entities.toArray()); - } - - @Override - public TopiaFiresSupport getFiresSupport() { - return firesSupport; - } - - /** - * Backup database in gzip compressed file. - * <p/> - * <b>Note: </b> Only works for h2 database. - * - * @param file file to write backup - * @param compress if true then use gzip to compress file - * @see TopiaContext#backup(File, boolean) - */ - @Override - public void backup(File file, boolean compress) throws TopiaException { - checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", - "backup")); - try { - String options = ""; - if (compress) { - options += " COMPRESSION GZIP"; - } - - SQLQuery query = getHibernate().createSQLQuery( - "SCRIPT TO '" + file.getAbsolutePath() + "'" + options); - query.list(); - - } catch (Exception eee) { - throw new TopiaException(String.format( - "An error occurs while backup operation: %1$s", - eee.getMessage()), eee); - } - } - - /** - * Read database from gzip compressed file - * <p/> - * Only work for h2 database - * - * @see TopiaContext#restore(File) - */ - @Override - public void restore(File file) throws TopiaException { - // send event - getFiresSupport().firePreRestoreSchema(this); - checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", - "restore")); - - String sql = null; - String options = ""; - try { - // decompresse file in temporary file - InputStream in = new BufferedInputStream(new FileInputStream(file)); - try { - in.mark(2); - - // read header to see if is compressed file - int b = in.read(); - // redundant cast : int magic = ((int) in.read() << 8) | b; - int magic = in.read() << 8 | b; - in.reset(); - - if (magic == GZIPInputStream.GZIP_MAGIC) { - options += " COMPRESSION GZIP"; - } - } finally { - - in.close(); - } - - SQLQuery query = getHibernate().createSQLQuery( - "RUNSCRIPT FROM '" + file.getAbsolutePath() + "'" + options); - - query.executeUpdate(); - - // send event AFTER restore - getFiresSupport().firePostRestoreSchema(this); - } catch (Exception eee) { - throw new TopiaException(String.format( - String.format("An error occurs while restore operation: %1$s : %2$s", - sql, eee.getMessage())), eee); - } - } - - /** - * Only h2 supported for now - * - * @see TopiaContext#clear(boolean) - */ - @Override - public void clear(boolean dropDatabase) throws TopiaException { - try { - TopiaContextImpl root = (TopiaContextImpl) getRootContext(); - TopiaContextImpl tx = (TopiaContextImpl) root.beginTransaction(); - - String sql = "DROP ALL OBJECTS"; - if (dropDatabase) { - sql += " DELETE FILES"; - } - Query query = tx.getHibernate().createSQLQuery(sql); - query.executeUpdate(); - tx.closeContext(); - root.finalize(); - } catch (Throwable eee) { - throw new TopiaException( - String.format("Error %s on clear operation", eee.getMessage()), eee); - } - } - - /** - * Clear hibernate cache to free memory. - * <p/> - * see http://docs.jboss.org/hibernate/orm/3.5/reference/en-US/html/transactions.ht... - */ - @Override - public void clearCache() throws TopiaException { - getHibernate().clear(); - } - - @Override - public List<Class<?>> getPersistenceClasses() { - return persistenceClasses; - } - - @Override - public boolean isSchemaExist(Class<?> clazz) - throws TopiaException { - checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", - "replicateEntity")); - boolean result = TopiaUtil.isSchemaExist(this, clazz.getName()); - return result; - } - - /* Listeners adders */ - - @Override - public void addTopiaEntityListener(TopiaEntityListener listener) { - getFiresSupport().addTopiaEntityListener(listener); - } - - @Override - public void addTopiaEntityListener( - Class<? extends TopiaEntity> entityClass, - TopiaEntityListener listener) { - getFiresSupport().addTopiaEntityListener(entityClass, listener); - } - - @Override - public void addTopiaEntityVetoable(TopiaEntityVetoable vetoable) { - getFiresSupport().addTopiaEntityVetoable(TopiaEntity.class, vetoable); - } - - @Override - public void addTopiaEntityVetoable( - Class<? extends TopiaEntity> entityClass, - TopiaEntityVetoable vetoable) { - getFiresSupport().addTopiaEntityVetoable(entityClass, vetoable); - } - - @Override - public void addTopiaTransactionListener(TopiaTransactionListener listener) { - getFiresSupport().addTopiaTransactionListener(listener); - } - - @Override - public void addTopiaTransactionVetoable(TopiaTransactionVetoable vetoable) { - getFiresSupport().addTopiaTransactionVetoable(vetoable); - } - - @Override - public void addPropertyChangeListener(PropertyChangeListener listener) { - getFiresSupport().addPropertyChangeListener(listener); - } - - @Override - @Deprecated - public void addTopiaContextListener(TopiaContextListener listener) { - getFiresSupport().addTopiaContextListener(listener); - } - - @Override - public void addTopiaSchemaListener(TopiaSchemaListener listener) { - getFiresSupport().addTopiaSchemaListener(listener); - } - - /* Listeners removers */ - - @Override - public void removeTopiaEntityListener(TopiaEntityListener listener) { - getFiresSupport().removeTopiaEntityListener(TopiaEntity.class, - listener); - } - - @Override - public void removeTopiaEntityListener( - Class<? extends TopiaEntity> entityClass, - TopiaEntityListener listener) { - getFiresSupport().removeTopiaEntityListener(entityClass, listener); - } - - @Override - public void removeTopiaEntityVetoable(TopiaEntityVetoable vetoable) { - getFiresSupport().removeTopiaEntityVetoable(TopiaEntity.class, - vetoable); - } - - @Override - public void removeTopiaEntityVetoable( - Class<? extends TopiaEntity> entityClass, - TopiaEntityVetoable vetoable) { - getFiresSupport().removeTopiaEntityVetoable(entityClass, vetoable); - } - - @Override - public void removeTopiaTransactionListener( - TopiaTransactionListener listener) { - getFiresSupport().removeTopiaTransactionListener(listener); - } - - @Override - public void removeTopiaTransactionVetoable( - TopiaTransactionVetoable vetoable) { - getFiresSupport().removeTopiaTransactionVetoable(vetoable); - } - - @Override - public void removePropertyChangeListener(PropertyChangeListener listener) { - getFiresSupport().removePropertyChangeListener(listener); - } - - @Override - @Deprecated - public void removeTopiaContextListener(TopiaContextListener listener) { - getFiresSupport().removeTopiaContextListener(listener); - } - - @Override - public void removeTopiaSchemaListener(TopiaSchemaListener listener) { - getFiresSupport().removeTopiaSchemaListener(listener); - } - - @Override - public void addTopiaEntitiesVetoable(TopiaEntitiesVetoable vetoable) { - getFiresSupport().addTopiaEntitiesVetoable(vetoable); - } - - @Override - public void removeTopiaEntitiesVetoable(TopiaEntitiesVetoable vetoable) { - getFiresSupport().removeTopiaEntitiesVetoable(vetoable); - } - - /** - * Build the list of queries from the given parameter - * <code>entityAndCondition</code>. - * <p/> - * If no parameter is given, then build the queries for all entities is db, - * with no condition. - * - * @param entityAndCondition the list of tuples (Class,String) - * @return the list of queries. - * @throws TopiaException if any pb of db while getting entities - * classes. - * @throws IllegalArgumentException if any pb with the given parameter - * (mainly ClassCastException). - */ - protected String[] buildQueries(Object... entityAndCondition) - throws TopiaException, IllegalArgumentException { - Class<?> entityClass; - String condition; - - // si entityAndcondition est vide alors il faut le remplir - // avec toutes les entités du mapping (class, null) - if (entityAndCondition.length == 0) { - Map<?, ?> classMetadata = getHibernateFactory().getAllClassMetadata(); - entityAndCondition = new Object[classMetadata.size() * 2]; - int i = 0; - for (Object className : classMetadata.keySet()) { - try { - entityAndCondition[i++] = Class.forName((String) className); - } catch (ClassNotFoundException e) { - // should never happen! - throw new TopiaException( - "class cast exception for entity " + className); - } - entityAndCondition[i++] = null; - - } - } - - // prepare queries to perform beofre opening any transaction - if (entityAndCondition.length % 2 != 0) { - throw new IllegalArgumentException( - "entityAndCondition must be a couple of (Class, String)"); - } - String queries[] = new String[entityAndCondition.length / 2]; - for (int i = 0; i < entityAndCondition.length; ) { - try { - entityClass = (Class<?>) entityAndCondition[i++]; - condition = (String) entityAndCondition[i++]; - String query = "from " + entityClass.getName(); - if (condition != null && !condition.isEmpty()) { - query += " where " + condition; - } - queries[(i - 1) / 2] = query; - } catch (ClassCastException e) { - if (i % 2 == 0) { - throw new IllegalArgumentException( - "Others arguement must be String not " + - entityAndCondition[i - 1], e); - } else { - throw new IllegalArgumentException( - "Others arguement must be Class not " + - entityAndCondition[i - 1], e); - } - } - } - return queries; - } - - protected void replicate0(TopiaContextImpl dstContextImpl, - Object... entities) throws TopiaException { - try { - for (Object entity : entities) { - // dettach entity to source session, to make possible copy of - // collection without a hibernate exception (list opened in - // two session...) - getHibernate().evict(entity); - dstContextImpl.getHibernate().replicate(entity, - ReplicationMode.EXCEPTION); - } - - } catch (HibernateException eee) { - throw new TopiaException(String.format("An error occurs while a replication operation : %s", - eee.getMessage()), eee); - } - } - - public static class SQLWork implements Work { - private final String script; - - public SQLWork(String script) { - this.script = script; - } - - @Override - public void execute(Connection connection) throws SQLException { - PreparedStatement sta = connection.prepareStatement(script); - try { - sta.execute(); - } finally { - sta.close(); - } - } - } - - @Override - public Session getHibernateSession() throws TopiaException { - if (hibernate == null) { - throw new TopiaException("No hibernate session"); - } - return hibernate; - } - - @Override - public void update(TopiaEntity e) throws TopiaException { - checkClosed(String.format("This context is closed, it is not possible to release the operation '%1$s'", - "add")); - - String id = e.getTopiaId(); - Class<TopiaEntity> entityClass = getTopiaIdFactory().getClassName(id); - TopiaDAO<TopiaEntity> dao = getDAO(entityClass); - dao.update(e); - } - -} //TopiaContextImpl - Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImplementor.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImplementor.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImplementor.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -52,7 +52,7 @@ */ //TODO-fdesbois-20100507 : Need more javadoc. @Deprecated -public interface TopiaContextImplementor extends TopiaContext, TopiaHibernate { +public interface TopiaContextImplementor extends TopiaContext { /** * Retrieve a thread-safe copy of children context set. @@ -80,7 +80,7 @@ * @deprecated Hierarchical context are not supported anymore */ @Deprecated - void removeChildContext(TopiaContextImplementor child); + void removeChildContext(TopiaContext child); /** @return Returns the config. * @deprecated use method from {@link org.nuiton.topia.TopiaPersistenceContext} Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaFiresSupport.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaFiresSupport.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaFiresSupport.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -928,7 +928,7 @@ * @return the list of entities loaded */ public <E extends TopiaEntity> List<E> fireEntitiesLoad( - TopiaContextImplementor context, List<E> entities) { + TopiaContext context, List<E> entities) { if (log.isDebugEnabled()) { log.debug("fireEntitiesLoad"); } Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaService.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaService.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaService.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -37,6 +37,8 @@ package org.nuiton.topia.framework; +import org.nuiton.topia.TopiaContext; + /** * Used to implement a service for Topia. You have to provide a static property * called SERVICE_NAME that identify the service : @@ -70,17 +72,17 @@ /** * Initiliaze the service before create the {@code context}. * - * @param context TopiaContextImplementor + * @param context * @return true if service need to be activated or not */ - boolean preInit(TopiaContextImplementor context); + boolean preInit(TopiaContext context); /** * Initiliaze the service after create the {@code context}. * - * @param context TopiaContextImplementor + * @param context * @return true if service need to be activated or not */ - boolean postInit(TopiaContextImplementor context); + boolean postInit(TopiaContext context); } Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/package-info.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/package-info.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/package-info.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -25,7 +25,7 @@ /** * Contains two interfaces, one {@link org.nuiton.topia.framework.TopiaContextImplementor} for internal * manipulations of {@link org.nuiton.topia.TopiaContext} and one {@link org.nuiton.topia.framework.TopiaService} for topia - * services. This package contains also the main implementation {@link org.nuiton.topia.framework.TopiaContextImpl} + * services. This package contains also the main implementation {@link org.nuiton.topia.framework.AbstractTopiaContext} * for both {@link org.nuiton.topia.TopiaContext} for final applications and * {@link org.nuiton.topia.framework.TopiaContextImplementor} for internal. * <p /> Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/EntityDAOTransformer.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/EntityDAOTransformer.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/EntityDAOTransformer.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -614,7 +614,7 @@ body.append("" /*{ { - List<<%=attrType%>> list = getContext().getHibernate().createSQLQuery( + List<<%=attrType%>> list = getContext().getHibernateSession().createSQLQuery( "SELECT main.topiaid " + "from <%=attrClassifierDBName%> main, <%=attrJoinTableName%> secondary " + "where main.topiaid=secondary.<%=attrDBName%>" + Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaDAO.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaDAO.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaDAO.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -36,6 +36,7 @@ */ package org.nuiton.topia.persistence; +import org.nuiton.topia.TopiaContext; import org.nuiton.topia.TopiaException; import org.nuiton.topia.event.TopiaEntityListener; import org.nuiton.topia.event.TopiaEntityVetoable; @@ -652,19 +653,18 @@ * Returns the context used by this DAO. * * @return Returns the context. + * @deprecated use {@link #getTopiaContext()} */ - TopiaContextImplementor getContext(); + @Deprecated + TopiaContext getContext(); /** - * Method to invoke right after instance creation. It is done by the - * TopiaContext. + * Returns the context used by this DAO. * - * @param context context - * @param entityClass entity class - * @throws TopiaException if any pb while init + * @return Returns the context. */ - void init(TopiaContextImplementor context, - Class<E> entityClass) throws TopiaException; + // TODO AThimel 02/08/13 Use only TopiaPersistenceContext and TopiaHibernate + TopiaContext getTopiaContext(); /** * Get the entityEnum of the type of entity managed by this DAO. Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaDAOImpl.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaDAOImpl.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaDAOImpl.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -53,10 +53,12 @@ import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.hibernate.metadata.ClassMetadata; +import org.nuiton.topia.TopiaContext; import org.nuiton.topia.TopiaException; import org.nuiton.topia.event.TopiaEntityListener; import org.nuiton.topia.event.TopiaEntityVetoable; import org.nuiton.topia.framework.TopiaContextImplementor; +import org.nuiton.topia.framework.TopiaFiresSupport; import org.nuiton.topia.persistence.pager.TopiaPagerBean; import org.nuiton.util.PagerBeanUtil; @@ -101,8 +103,10 @@ * * @since ever */ - protected TopiaContextImplementor context; + protected TopiaContext context; + protected TopiaFiresSupport topiaFiresSupport; + /** * Default batch size used to iterate on data. * @@ -139,7 +143,7 @@ criteria.setMaxResults(1); List<E> result = (List<E>) criteria.list(); int sizeBefore = result != null ? result.size() : 0; - result = getContext().getFiresSupport().fireEntitiesLoad(context, result); + result = topiaFiresSupport.fireEntitiesLoad(context, result); int sizeAfter = result != null ? result.size() : 0; if (sizeAfter < sizeBefore) { if (log.isDebugEnabled()) { @@ -226,24 +230,33 @@ } /** - * When TopiaContextImpl create the TopiaDAOHibernate, it must call this + * When AbstractTopiaContext create the TopiaDAOHibernate, it must call this * method just after. * * @param entityClass */ - @Override - public void init(TopiaContextImplementor context, Class<E> entityClass) + public void init(TopiaContext context, Class<E> entityClass, TopiaFiresSupport topiaFiresSupport) throws TopiaException { log.debug("init dao for " + entityClass.getName()); this.context = context; this.entityClass = entityClass; + this.topiaFiresSupport = topiaFiresSupport; } @Override - public TopiaContextImplementor getContext() { + public TopiaContext getContext() { + return getTopiaContext(); + } + + @Override + public TopiaContext getTopiaContext() { return context; } + protected TopiaFiresSupport getTopiaFiresSupport() { + return topiaFiresSupport; + } + @Override public String createSimpleQuery(String alias) { String hql = "FROM " + getTopiaEntityEnum().getImplementationFQN(); @@ -333,7 +346,7 @@ // save entity getSession().save(entity); - getContext().getFiresSupport().warnOnCreateEntity(entity); + topiaFiresSupport.warnOnCreateEntity(entity); return entity; } catch (HibernateException eee) { throw new TopiaException(eee); @@ -401,7 +414,7 @@ public E update(E e) throws TopiaException { try { getSession().saveOrUpdate(e); - getContext().getFiresSupport().warnOnUpdateEntity(e); + topiaFiresSupport.warnOnUpdateEntity(e); return e; } catch (HibernateException eee) { throw new TopiaException(eee); @@ -413,7 +426,7 @@ try { getSession().delete(e); e.notifyDeleted(); - getContext().getFiresSupport().warnOnDeleteEntity(e); + topiaFiresSupport.warnOnDeleteEntity(e); } catch (HibernateException eee) { throw new TopiaException(eee); } @@ -462,7 +475,7 @@ try { Criteria criteria = createCriteria(FlushMode.AUTO); List<E> result = (List<E>) criteria.list(); - result = getContext().getFiresSupport().fireEntitiesLoad(context, + result = topiaFiresSupport.fireEntitiesLoad(context, result); return result; } catch (HibernateException eee) { @@ -506,7 +519,7 @@ Criteria criteria = createCriteria(FlushMode.AUTO); criteria.add(criterion); List<E> result = (List<E>) criteria.list(); - result = getContext().getFiresSupport().fireEntitiesLoad(context, + result = topiaFiresSupport.fireEntitiesLoad(context, result); return result; } catch (HibernateException eee) { @@ -523,7 +536,7 @@ criteria.addOrder(Order.asc(propertyName)); } List<E> result = (List<E>) criteria.list(); - result = getContext().getFiresSupport().fireEntitiesLoad(context, + result = topiaFiresSupport.fireEntitiesLoad(context, result); return result; } catch (HibernateException eee) { @@ -808,8 +821,8 @@ } } List<R> result = findAllByQueryWithBound(type, hql, - (int) pager.getRecordStartIndex(), - (int) pager.getRecordEndIndex() - 1, + (int) pager.getRecordStartIndex(), + (int) pager.getRecordEndIndex() - 1, propertyNamesAndValues); return result; } @@ -844,7 +857,7 @@ * @throws TopiaException if any pb */ protected Session getSession() throws TopiaException { - Session result = getContext().getHibernate(); + Session result = getContext().getHibernateSession(); return result; } Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/in/TopiaCsvImports.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/in/TopiaCsvImports.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/csv/in/TopiaCsvImports.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -273,7 +273,7 @@ CsvImportResult<T> csvResult, int nbRowBuffer) throws TopiaException { - TopiaContextImplementor context = dao.getContext(); + TopiaContext context = dao.getContext(); CsvProgressModel progressModel = csvResult == null ? null : csvResult.getProgressModel(); @@ -296,7 +296,7 @@ compt++; if (compt % nbRowBuffer == 0) { // flush it - context.getHibernate().flush(); + context.getHibernateSession().flush(); } } } Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/DBMapping.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/DBMapping.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/DBMapping.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -30,7 +30,7 @@ import org.hibernate.exception.SQLGrammarException; import org.nuiton.topia.TopiaContext; import org.nuiton.topia.TopiaException; -import org.nuiton.topia.framework.TopiaContextImpl; +import org.nuiton.topia.framework.AbstractTopiaContext; import org.nuiton.topia.persistence.TopiaEntity; import org.hibernate.SQLQuery; import org.hibernate.jdbc.Work; @@ -327,7 +327,7 @@ BigInteger size = defaultSize; if (ctxt != null) { try { - SQLQuery query = ((TopiaContextImpl) ctxt).getHibernate().createSQLQuery(sql); + SQLQuery query = ((AbstractTopiaContext) ctxt).getHibernate().createSQLQuery(sql); size = (BigInteger) query.list().get(0); } catch (SQLGrammarException e) { // could not obtain sequence @@ -340,7 +340,7 @@ protected void doSQLWork(TopiaContext ctxt, final String sql) throws TopiaException { if (ctxt != null) { //ctxt.beginTransaction(); - ((TopiaContextImpl) ctxt).getHibernate().doWork(new Work() { + ((AbstractTopiaContext) ctxt).getHibernate().doWork(new Work() { public void execute(Connection connection) throws SQLException { if (log.isDebugEnabled()) { log.debug(sql); Modified: trunk/topia-persistence/src/test/java/org/nuiton/topia/TopiaContextFactoryTest.java =================================================================== --- trunk/topia-persistence/src/test/java/org/nuiton/topia/TopiaContextFactoryTest.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-persistence/src/test/java/org/nuiton/topia/TopiaContextFactoryTest.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -30,7 +30,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; -import org.nuiton.topia.framework.TopiaContextImpl; +import org.nuiton.topia.framework.AbstractTopiaContext; import java.io.File; import java.io.IOException; @@ -77,7 +77,7 @@ String url = "jdbc:h2:file:" + dbDirectory; properties.setProperty("hibernate.connection.url", url); - TopiaContextImpl test = new TopiaContextImpl(properties); + AbstractTopiaContext test = new AbstractTopiaContext(properties); TopiaContextFactory.contextCache.put(properties, test); /** EXEC METHOD **/ @@ -91,7 +91,7 @@ log.debug("## testRemoveContext"); /** PREPARE DATA **/ - TopiaContextImpl test = new TopiaContextImpl(properties); + AbstractTopiaContext test = new AbstractTopiaContext(properties); TopiaContextFactory.contextCache.put(properties, test); /** EXEC METHOD **/ Modified: trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TopiaContextImplTest.java =================================================================== --- trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TopiaContextImplTest.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-persistence/src/test/java/org/nuiton/topia/framework/TopiaContextImplTest.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -87,7 +87,7 @@ properties.setProperty("topia.service.test", TestService.class.getName()); - TopiaContextImpl context = new TopiaContextImpl(); + AbstractTopiaContext context = new AbstractTopiaContext(); /** EXEC METHOD **/ if (log.isInfoEnabled()) { @@ -134,10 +134,10 @@ TestService.class.getName()); // Calling the constructor with properties will load the services - TopiaContextImpl context = new TopiaContextImpl(properties); + AbstractTopiaContext context = new AbstractTopiaContext(properties); // Instantiate a child context and set its parent - TopiaContextImpl child = new TopiaContextImpl(context); + AbstractTopiaContext child = new AbstractTopiaContext(context); /** EXEC METHOD **/ if (log.isInfoEnabled()) { @@ -180,7 +180,7 @@ properties.clear(); properties.setProperty("topia.service.fake", FakeService.class.getName()); - TopiaContextImpl otherContext = new TopiaContextImpl(properties); + AbstractTopiaContext otherContext = new AbstractTopiaContext(properties); boolean test6 = otherContext.serviceEnabled(FakeService.class); Assert.assertFalse(test6); @@ -208,28 +208,28 @@ } /** PREPARE DATA **/ - TopiaContextImpl context = new TopiaContextImpl(properties); + AbstractTopiaContext context = new AbstractTopiaContext(properties); /** EXEC METHODS **/ if (log.isInfoEnabled()) { log.info("test 1 : constructor with parent context"); } - TopiaContextImpl test1 = new TopiaContextImpl(context); + AbstractTopiaContext test1 = new AbstractTopiaContext(context); Assert.assertEquals(context, test1.parentContext); if (log.isInfoEnabled()) { log.info("test 2 : addChildContext"); } - TopiaContextImpl test2 = new TopiaContextImpl(properties); - TopiaContextImpl child2 = new TopiaContextImpl(); + AbstractTopiaContext test2 = new AbstractTopiaContext(properties); + AbstractTopiaContext child2 = new AbstractTopiaContext(); test2.addChildContext(child2); Assert.assertEquals(1, test2.childContext.size()); if (log.isInfoEnabled()) { log.info("test 3 : removeChildContext"); } - TopiaContextImpl test3 = new TopiaContextImpl(properties); - TopiaContextImpl child3 = new TopiaContextImpl(test3); + AbstractTopiaContext test3 = new AbstractTopiaContext(properties); + AbstractTopiaContext child3 = new AbstractTopiaContext(test3); test3.childContext.add(child3); test3.removeChildContext(child3); Assert.assertEquals(0, test3.childContext.size()); @@ -274,7 +274,7 @@ } /** PREPARE DATA **/ - TopiaContextImpl context = new TopiaContextImpl(); + AbstractTopiaContext context = new AbstractTopiaContext(); context.services = new HashMap<String, TopiaService>(); String basedir = System.getenv("basedir"); @@ -325,7 +325,7 @@ log.info("test 2 : load mappings for all entities"); } //reset from previous test - context = new TopiaContextImpl(); + context = new AbstractTopiaContext(); context.services = new HashMap<String, TopiaService>(); properties.clear(); @@ -343,7 +343,7 @@ log.info("test 3 : add properties from file"); } //reset from previous test - context = new TopiaContextImpl(); + context = new AbstractTopiaContext(); context.services = new HashMap<String, TopiaService>(); properties.clear(); Modified: trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/FakeService.java =================================================================== --- trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/FakeService.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/FakeService.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -24,16 +24,15 @@ */ package org.nuiton.topiatest.service; -import org.nuiton.topia.framework.TopiaContextImpl; +import org.nuiton.topia.TopiaContext; import org.nuiton.topia.framework.TopiaContextImplTest; -import org.nuiton.topia.framework.TopiaContextImplementor; import org.nuiton.topia.framework.TopiaService; /** * FakeService which implements {@link TopiaService} to test existing service * from {@link TopiaContextImplTest#testGetServices()}. This fake service * doesn't contains property SERVICE_NAME used by {@link - * TopiaContextImpl#serviceEnabled(Class)}. + * org.nuiton.topia.framework.AbstractTopiaContext#serviceEnabled(Class)}. * <p/> * Created: 10 mai 2010 * @@ -53,12 +52,12 @@ } @Override - public boolean preInit(TopiaContextImplementor context) { + public boolean preInit(TopiaContext context) { return true; } @Override - public boolean postInit(TopiaContextImplementor context) { + public boolean postInit(TopiaContext context) { return true; } } Modified: trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/TestService.java =================================================================== --- trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/TestService.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-persistence/src/test/java/org/nuiton/topiatest/service/TestService.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -56,12 +56,12 @@ } @Override - public boolean preInit(TopiaContextImplementor context) { + public boolean preInit(TopiaContext context) { return true; } @Override - public boolean postInit(TopiaContextImplementor context) { + public boolean postInit(TopiaContext context) { return true; } } Modified: trunk/topia-service-migration/src/main/java/org/nuiton/topia/migration/TopiaMigrationEngine.java =================================================================== --- trunk/topia-service-migration/src/main/java/org/nuiton/topia/migration/TopiaMigrationEngine.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-service-migration/src/main/java/org/nuiton/topia/migration/TopiaMigrationEngine.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -101,7 +101,7 @@ protected AbstractTopiaMigrationCallback callback; /** topia root context (initialise en pre-init) */ - protected TopiaContextImplementor rootContext; + protected TopiaContext rootContext; /** Un drapeau pour savoir si le service a bien ete initialise (i.e a bien fini la methode preInit) */ protected boolean init; @@ -194,7 +194,7 @@ } @Override - public boolean preInit(TopiaContextImplementor context) { + public boolean preInit(TopiaContext context) { rootContext = context; Properties config = context.getConfig(); @@ -267,7 +267,7 @@ } @Override - public boolean postInit(TopiaContextImplementor context) { + public boolean postInit(TopiaContext context) { // nothing to do in post-init return true; } Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationServiceImpl.java =================================================================== --- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationServiceImpl.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationServiceImpl.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -52,7 +52,7 @@ LogFactory.getLog(TopiaReplicationServiceImpl.class); /** le contexte sur la base source de la replication */ - protected TopiaContextImplementor context; + protected TopiaContext context; /** * le constructeur de modèle de réplication. @@ -77,13 +77,13 @@ } @Override - public boolean preInit(TopiaContextImplementor context) { + public boolean preInit(TopiaContext context) { // nothing to init return true; } @Override - public boolean postInit(TopiaContextImplementor context) { + public boolean postInit(TopiaContext context) { // set the incoming root context from topia this.context = context; //TODO avoir un objet pour lire les contrainte de resolution de cycle Modified: trunk/topia-service-security/src/main/java/org/nuiton/topia/security/TopiaSecurityServiceImpl.java =================================================================== --- trunk/topia-service-security/src/main/java/org/nuiton/topia/security/TopiaSecurityServiceImpl.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-service-security/src/main/java/org/nuiton/topia/security/TopiaSecurityServiceImpl.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -149,7 +149,7 @@ */ @Override - public boolean preInit(TopiaContextImplementor context) { + public boolean preInit(TopiaContext context) { return true; } @@ -159,7 +159,7 @@ */ @Override - public boolean postInit(TopiaContextImplementor context) { + public boolean postInit(TopiaContext context) { rootContext = context; securityContext = null; Modified: trunk/topia-service-security/src/main/java/org/nuiton/topia/security/util/TopiaSecurityUtil.java =================================================================== --- trunk/topia-service-security/src/main/java/org/nuiton/topia/security/util/TopiaSecurityUtil.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-service-security/src/main/java/org/nuiton/topia/security/util/TopiaSecurityUtil.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -43,7 +43,7 @@ import org.nuiton.topia.TopiaContext; import org.nuiton.topia.TopiaContextFactory; import org.nuiton.topia.TopiaException; -import org.nuiton.topia.framework.TopiaContextImpl; +import org.nuiton.topia.framework.AbstractTopiaContext; import org.nuiton.topia.persistence.TopiaId; import org.nuiton.topia.security.entities.authorization.TopiaAssociationAuthorizationImpl; import org.nuiton.topia.security.entities.authorization.TopiaAuthorizationImpl; @@ -242,7 +242,7 @@ * @throws TopiaException if any topia pb */ public static TopiaContext beginTransactionWithoutSecurity(TopiaContext transaction) throws TopiaException { - TopiaContextImpl context = (TopiaContextImpl) transaction; + AbstractTopiaContext context = (AbstractTopiaContext) transaction; Properties config = context.getConfig(); config.setProperty("topia.service.security", ""); Modified: trunk/topia-service-security/src/main/java/org/nuiton/topia/taas/TaasService.java =================================================================== --- trunk/topia-service-security/src/main/java/org/nuiton/topia/taas/TaasService.java 2013-08-02 16:21:12 UTC (rev 2785) +++ trunk/topia-service-security/src/main/java/org/nuiton/topia/taas/TaasService.java 2013-08-02 17:26:06 UTC (rev 2786) @@ -108,7 +108,7 @@ private TaasPolicy policy = new TaasPolicy(this); - private TopiaContextImplementor rootContext; + private TopiaContext rootContext; private TopiaContext rootContextNoSecure; @@ -139,7 +139,7 @@ } @Override - public boolean preInit(TopiaContextImplementor context) { + public boolean preInit(TopiaContext context) { rootContext = context; try { @@ -218,7 +218,7 @@ } @Override - public boolean postInit(TopiaContextImplementor context) { + public boolean postInit(TopiaContext context) { policy.installPolicy(); // Si pas de configuration autre que celle par defaut @@ -234,7 +234,7 @@ * * @return context root */ - public TopiaContextImplementor getRootContext() { + public TopiaContext getRootContext() { return rootContext; }