r2842 - in trunk/topia-persistence/src/main/java/org/nuiton/topia: . framework
Author: bleny Date: 2013-10-11 18:53:04 +0200 (Fri, 11 Oct 2013) New Revision: 2842 Url: http://nuiton.org/projects/topia/repository/revisions/2842 Log: implements TopiaReplicationSupport and move it on PersitenceContext Added: trunk/topia-persistence/src/main/java/org/nuiton/topia/HibernateTopiaReplicationSupport.java trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaReplicationDestination.java Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/AbstractTopiaApplicationContext.java trunk/topia-persistence/src/main/java/org/nuiton/topia/AbstractTopiaPersistenceContext.java trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaContext.java trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaPersistenceContext.java trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaReplicationSupport.java trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/AbstractTopiaContext.java Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/AbstractTopiaApplicationContext.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/AbstractTopiaApplicationContext.java 2013-10-11 16:47:08 UTC (rev 2841) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/AbstractTopiaApplicationContext.java 2013-10-11 16:53:04 UTC (rev 2842) @@ -60,7 +60,7 @@ * @author Arnaud Thimel <thimel@codelutin.com> * @since 3.0 */ -public abstract class AbstractTopiaApplicationContext<K extends TopiaPersistenceContext> implements TopiaReplicationSupport, TopiaListenableSupport, TopiaServiceSupport { +public abstract class AbstractTopiaApplicationContext<K extends TopiaPersistenceContext> implements TopiaListenableSupport, TopiaServiceSupport { private static final Log log = LogFactory.getLog(AbstractTopiaApplicationContext.class); @@ -68,8 +68,6 @@ protected ImmutableMap<String, String> configuration; - protected TopiaReplicationSupport topiaReplicationSupport; - protected TopiaFiresSupport topiaFiresSupport = new TopiaFiresSupport(); protected TopiaServiceSupport topiaServiceSupport; @@ -146,21 +144,6 @@ } @Override - public void replicate(TopiaContext destinationContext, Object... entityAndCondition) throws IllegalArgumentException { - topiaReplicationSupport.replicate(destinationContext, entityAndCondition); - } - - @Override - public <T extends TopiaEntity> void replicateEntity(TopiaContext destinationContext, T entity) throws IllegalArgumentException { - topiaReplicationSupport.replicateEntity(destinationContext, entity); - } - - @Override - public <T extends TopiaEntity> void replicateEntities(TopiaContext destinationContext, List<T> entities) throws IllegalArgumentException { - topiaReplicationSupport.replicateEntities(destinationContext, entities); - } - - @Override public void addTopiaEntityListener(TopiaEntityListener listener) { topiaFiresSupport.addTopiaEntityListener(listener); } Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/AbstractTopiaPersistenceContext.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/AbstractTopiaPersistenceContext.java 2013-10-11 16:47:08 UTC (rev 2841) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/AbstractTopiaPersistenceContext.java 2013-10-11 16:53:04 UTC (rev 2842) @@ -24,9 +24,8 @@ * #L% */ -import java.lang.reflect.InvocationTargetException; -import java.util.Map; - +import com.google.common.base.Preconditions; +import com.google.common.collect.Maps; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.FlushMode; @@ -41,8 +40,9 @@ import org.nuiton.topia.persistence.TopiaEntity; import org.nuiton.topia.persistence.TopiaIdFactory; -import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; +import java.lang.reflect.InvocationTargetException; +import java.util.List; +import java.util.Map; /** * Abstract implementation of the TopiaPersistenceContext. This class will be extended by a generated one in order to @@ -60,6 +60,8 @@ */ protected Map<Class<? extends TopiaEntity>, TopiaDAO<? extends TopiaEntity>> daoCache = Maps.newConcurrentMap(); + protected HibernateTopiaReplicationSupport hibernateTopiaReplicationSupport; + // TODO AThimel 27/09/13 Javadoc protected TopiaListenableSupport listenableSupport; @@ -366,4 +368,30 @@ return closed; } + protected HibernateTopiaReplicationSupport getHibernateTopiaReplicationSupport() { + if (hibernateTopiaReplicationSupport == null) { + hibernateTopiaReplicationSupport = new HibernateTopiaReplicationSupport(hibernateSupport); + } + return hibernateTopiaReplicationSupport; + } + + @Override + public void replicate(TopiaEntity entity) { + getHibernateTopiaReplicationSupport().replicate(entity); + } + + @Override + public <T extends TopiaEntity> void replicateEntities(TopiaReplicationDestination topiaReplicationDestination, List<T> entities) throws IllegalArgumentException { + getHibernateTopiaReplicationSupport().replicateEntities(topiaReplicationDestination, entities); + } + + @Override + public <T extends TopiaEntity> void replicateEntity(TopiaReplicationDestination topiaReplicationDestination, T entity) throws IllegalArgumentException { + getHibernateTopiaReplicationSupport().replicateEntity(topiaReplicationDestination, entity); + } + + @Override + public void replicate(TopiaReplicationDestination topiaReplicationDestination, Object... entityAndCondition) throws IllegalArgumentException { + getHibernateTopiaReplicationSupport().replicate(topiaReplicationDestination, entityAndCondition); + } } Added: trunk/topia-persistence/src/main/java/org/nuiton/topia/HibernateTopiaReplicationSupport.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/HibernateTopiaReplicationSupport.java (rev 0) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/HibernateTopiaReplicationSupport.java 2013-10-11 16:53:04 UTC (rev 2842) @@ -0,0 +1,156 @@ +package org.nuiton.topia; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.HibernateException; +import org.hibernate.ReplicationMode; +import org.nuiton.topia.persistence.TopiaEntity; + +import java.util.List; +import java.util.Map; + +public class HibernateTopiaReplicationSupport implements TopiaReplicationSupport, TopiaReplicationDestination { + + private static final Log log = LogFactory.getLog(HibernateTopiaReplicationSupport.class); + + protected TopiaHibernateSupport topiaHibernateSupport; + + public HibernateTopiaReplicationSupport(TopiaHibernateSupport topiaHibernateSupport) { + this.topiaHibernateSupport = topiaHibernateSupport; + } + + @Override + public void replicate( + TopiaReplicationDestination topiaReplicationDestination, + Object... entityAndCondition) throws IllegalArgumentException { + + String[] queries = buildQueries(entityAndCondition); + + try { + for (String query : queries) { + if (log.isDebugEnabled()) { + log.debug("acquire entities " + query); + } + // acquire data to replicate + List<?> entities = topiaHibernateSupport.getHibernateSession().createQuery(query).list(); + replicate0(topiaReplicationDestination, 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( + TopiaReplicationDestination topiaReplicationDestination, + T entity) throws IllegalArgumentException { + + replicate0(topiaReplicationDestination, entity); + + } + + @Override + public <T extends TopiaEntity> void replicateEntities( + TopiaReplicationDestination topiaReplicationDestination, + List<T> entities) throws IllegalArgumentException { + + replicate0(topiaReplicationDestination, entities.toArray()); + + } + + protected void replicate0(TopiaReplicationDestination topiaReplicationDestination, + Object... entities) { + 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...) + topiaHibernateSupport.getHibernateSession().evict(entity); + topiaReplicationDestination.replicate((TopiaEntity) entity); + } + + } catch (HibernateException eee) { + throw new TopiaException(String.format("An error occurs while a replication operation : %s", + eee.getMessage()), eee); + } + } + + /** + * 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 = topiaHibernateSupport.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; + } + + @Override + public void replicate(TopiaEntity entity) { + topiaHibernateSupport.getHibernateSession().replicate(entity, ReplicationMode.EXCEPTION); + } + +} Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaContext.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaContext.java 2013-10-11 16:47:08 UTC (rev 2841) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaContext.java 2013-10-11 16:53:04 UTC (rev 2842) @@ -25,10 +25,6 @@ package org.nuiton.topia; -import java.beans.PropertyChangeListener; -import java.io.File; -import java.util.List; - import org.nuiton.topia.event.TopiaContextListener; import org.nuiton.topia.event.TopiaEntitiesVetoable; import org.nuiton.topia.event.TopiaEntityListener; @@ -38,6 +34,10 @@ import org.nuiton.topia.framework.TopiaService; import org.nuiton.topia.persistence.TopiaEntity; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.util.List; + /** * The TopiaContext is the most important class of ToPIA. It contains all the * methods to manipulate data : transaction management, entities querying, event @@ -54,7 +54,7 @@ * @version $Id$ */ public interface TopiaContext extends TopiaTransaction, TopiaListenableSupport, TopiaSqlSupport, TopiaJpaSupport, - TopiaPersistenceContext, TopiaServiceSupport, TopiaReplicationSupport, TopiaHibernateSupport { + TopiaPersistenceContext, TopiaServiceSupport, TopiaReplicationSupport, TopiaReplicationDestination, TopiaHibernateSupport { /* -------------------- TRANSACTION MANAGEMENT --------------------------*/ Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaPersistenceContext.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaPersistenceContext.java 2013-10-11 16:47:08 UTC (rev 2841) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaPersistenceContext.java 2013-10-11 16:53:04 UTC (rev 2842) @@ -38,7 +38,7 @@ * @author Arnaud Thimel <thimel@codelutin.com> * @since 3.0 */ -public interface TopiaPersistenceContext extends TopiaDAOSupplier, TopiaTransaction { +public interface TopiaPersistenceContext extends TopiaReplicationSupport, TopiaReplicationDestination, TopiaDAOSupplier, TopiaTransaction { /** * Retrieve {@link org.nuiton.topia.persistence.TopiaEntity} using its unique {@code topiaId}. Added: trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaReplicationDestination.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaReplicationDestination.java (rev 0) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaReplicationDestination.java 2013-10-11 16:53:04 UTC (rev 2842) @@ -0,0 +1,19 @@ +package org.nuiton.topia; + +import org.nuiton.topia.persistence.TopiaEntity; + +/** + * Represent the destination of a replciation process. The source is + * {@link TopiaReplicationSupport} + */ +public interface TopiaReplicationDestination { + + /** + * Must replicate given entity in current database + * + * @since 3.0 + * @param entity + */ + void replicate(TopiaEntity entity); + +} Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaReplicationSupport.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaReplicationSupport.java 2013-10-11 16:47:08 UTC (rev 2841) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaReplicationSupport.java 2013-10-11 16:53:04 UTC (rev 2842) @@ -24,12 +24,12 @@ * #L% */ +import org.nuiton.topia.persistence.TopiaEntity; + import java.util.List; -import org.nuiton.topia.persistence.TopiaEntity; - /** - * This API provides methods about entities replication + * This API provides methods about entities replication to a destination * * @author Arnaud Thimel <thimel@codelutin.com> * @since 3.0 @@ -45,9 +45,9 @@ * <p/> * <b>Note 2:</b> The simple replication may not be sufficent. You may want * to replicate only a part of some entities : use the method {@link - * #replicateEntities(TopiaContext, java.util.List)}. + * #replicateEntities(TopiaReplicationDestination, java.util.List)}. * - * @param destinationContext the destination context + * @param topiaReplicationDestination the destination context * @param entityAndCondition [key;value;...] parameter which key is the * entity class to replicate, and value the * "where" condition to use when querying entities @@ -55,32 +55,32 @@ * trying to replicate within the same * database */ - void replicate(TopiaContext destinationContext, + void replicate(TopiaReplicationDestination topiaReplicationDestination, Object... entityAndCondition) throws IllegalArgumentException; /** * Replicate a given entity from this context to the given context. * - * @param destinationContext the destination context + * @param topiaReplicationDestination the destination context * @param entity the entity instance to replicate * @throws IllegalArgumentException if one of the context is closed or if * trying to replicate within the same * database */ - <T extends TopiaEntity> void replicateEntity(TopiaContext destinationContext, + <T extends TopiaEntity> void replicateEntity(TopiaReplicationDestination topiaReplicationDestination, T entity) throws IllegalArgumentException; /** * Makes a replication of some entities from this context to the given * context without any entity modification. * - * @param destinationContext the destination context + * @param topiaReplicationDestination the destination context * @param entities the list of entities instance to replicate * @throws IllegalArgumentException if one of the context is closed or if * trying to replicate within the same * database */ - <T extends TopiaEntity> void replicateEntities(TopiaContext destinationContext, + <T extends TopiaEntity> void replicateEntities(TopiaReplicationDestination topiaReplicationDestination, List<T> entities) throws IllegalArgumentException; } Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/AbstractTopiaContext.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/AbstractTopiaContext.java 2013-10-11 16:47:08 UTC (rev 2841) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/AbstractTopiaContext.java 2013-10-11 16:53:04 UTC (rev 2842) @@ -51,6 +51,7 @@ import org.nuiton.topia.TopiaContextFactory; import org.nuiton.topia.TopiaException; import org.nuiton.topia.TopiaNotFoundException; +import org.nuiton.topia.TopiaReplicationDestination; import org.nuiton.topia.event.TopiaContextListener; import org.nuiton.topia.event.TopiaEntitiesVetoable; import org.nuiton.topia.event.TopiaEntityListener; @@ -1203,6 +1204,26 @@ } @Override + public void replicate(TopiaEntity entity) { + getHibernateSession().replicate(entity, ReplicationMode.EXCEPTION); + } + + @Override + public void replicate(TopiaReplicationDestination topiaReplicationDestination, Object... entityAndCondition) throws IllegalArgumentException { + replicate((TopiaContext) topiaReplicationDestination, entityAndCondition); + } + + @Override + public <T extends TopiaEntity> void replicateEntity(TopiaReplicationDestination topiaReplicationDestination, T entity) throws IllegalArgumentException { + replicateEntity((TopiaContext) topiaReplicationDestination, entity); + } + + @Override + public <T extends TopiaEntity> void replicateEntities(TopiaReplicationDestination topiaReplicationDestination, List<T> entities) throws IllegalArgumentException { + replicateEntities((TopiaContext) topiaReplicationDestination, entities); + } + + @Override public TopiaFiresSupport getFiresSupport() { return firesSupport; }
participants (1)
-
bleny@users.nuiton.org