Topia-commits
Threads by month
- ----- 2026 -----
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
August 2010
- 2 participants
- 19 discussions
r2111 - in trunk: . topia-persistence topia-service-migration topia-service-replication topia-service-security
by hudson@users.nuiton.org Aug. 29, 2010
by hudson@users.nuiton.org Aug. 29, 2010
Aug. 29, 2010
Author: hudson
Date: 2010-08-29 18:14:07 +0200 (Sun, 29 Aug 2010)
New Revision: 2111
Url: http://nuiton.org/repositories/revision/topia/2111
Log:
[maven-release-plugin] prepare for next development iteration
Modified:
trunk/pom.xml
trunk/topia-persistence/pom.xml
trunk/topia-service-migration/pom.xml
trunk/topia-service-replication/pom.xml
trunk/topia-service-security/pom.xml
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2010-08-29 16:14:06 UTC (rev 2110)
+++ trunk/pom.xml 2010-08-29 16:14:07 UTC (rev 2111)
@@ -37,7 +37,7 @@
</parent>
<artifactId>topia</artifactId>
- <version>2.4.3</version>
+ <version>2.4.4-SNAPSHOT</version>
<modules>
<module>topia-persistence</module>
@@ -319,9 +319,9 @@
<!-- Source control management. -->
<scm>
- <connection>scm:svn:http://svn.nuiton.org/svn/topia/tags/topia-2.4.3</connection>
- <developerConnection>scm:svn:http://svn.nuiton.org/svn/topia/tags/topia-2.4.3</developerConnection>
- <url>http://www.nuiton.org/repositories/browse/topia/tags/topia-2.4.3</url>
+ <connection>scm:svn:http://svn.nuiton.org/svn/topia/trunk</connection>
+ <developerConnection>scm:svn:http://svn.nuiton.org/svn/topia/trunk</developerConnection>
+ <url>http://www.nuiton.org/repositories/browse/topia/trunk</url>
</scm>
</project>
Modified: trunk/topia-persistence/pom.xml
===================================================================
--- trunk/topia-persistence/pom.xml 2010-08-29 16:14:06 UTC (rev 2110)
+++ trunk/topia-persistence/pom.xml 2010-08-29 16:14:07 UTC (rev 2111)
@@ -35,7 +35,7 @@
<parent>
<groupId>org.nuiton</groupId>
<artifactId>topia</artifactId>
- <version>2.4.3</version>
+ <version>2.4.4-SNAPSHOT</version>
</parent>
<groupId>org.nuiton.topia</groupId>
Modified: trunk/topia-service-migration/pom.xml
===================================================================
--- trunk/topia-service-migration/pom.xml 2010-08-29 16:14:06 UTC (rev 2110)
+++ trunk/topia-service-migration/pom.xml 2010-08-29 16:14:07 UTC (rev 2111)
@@ -35,7 +35,7 @@
<parent>
<groupId>org.nuiton</groupId>
<artifactId>topia</artifactId>
- <version>2.4.3</version>
+ <version>2.4.4-SNAPSHOT</version>
</parent>
<groupId>org.nuiton.topia</groupId>
Modified: trunk/topia-service-replication/pom.xml
===================================================================
--- trunk/topia-service-replication/pom.xml 2010-08-29 16:14:06 UTC (rev 2110)
+++ trunk/topia-service-replication/pom.xml 2010-08-29 16:14:07 UTC (rev 2111)
@@ -35,7 +35,7 @@
<parent>
<groupId>org.nuiton</groupId>
<artifactId>topia</artifactId>
- <version>2.4.3</version>
+ <version>2.4.4-SNAPSHOT</version>
</parent>
<groupId>org.nuiton.topia</groupId>
Modified: trunk/topia-service-security/pom.xml
===================================================================
--- trunk/topia-service-security/pom.xml 2010-08-29 16:14:06 UTC (rev 2110)
+++ trunk/topia-service-security/pom.xml 2010-08-29 16:14:07 UTC (rev 2111)
@@ -35,7 +35,7 @@
<parent>
<groupId>org.nuiton</groupId>
<artifactId>topia</artifactId>
- <version>2.4.3</version>
+ <version>2.4.4-SNAPSHOT</version>
</parent>
<groupId>org.nuiton.topia</groupId>
1
0
Author: hudson
Date: 2010-08-29 18:14:06 +0200 (Sun, 29 Aug 2010)
New Revision: 2110
Url: http://nuiton.org/repositories/revision/topia/2110
Log:
[maven-release-plugin] copy for tag topia-2.4.3
Added:
tags/topia-2.4.3/
Property changes on: tags/topia-2.4.3
___________________________________________________________________
Added: svn:ignore
+ *.ipr
*.iws
.classpath
*.iml
.project
target
.settings
Added: svn:mergeinfo
+ /branches/from2.2.2-eugene2-beta:1662-1714
1
0
r2109 - in trunk: . topia-persistence topia-service-migration topia-service-replication topia-service-security
by hudson@users.nuiton.org Aug. 29, 2010
by hudson@users.nuiton.org Aug. 29, 2010
Aug. 29, 2010
Author: hudson
Date: 2010-08-29 18:14:05 +0200 (Sun, 29 Aug 2010)
New Revision: 2109
Url: http://nuiton.org/repositories/revision/topia/2109
Log:
[maven-release-plugin] prepare release topia-2.4.3
Modified:
trunk/pom.xml
trunk/topia-persistence/pom.xml
trunk/topia-service-migration/pom.xml
trunk/topia-service-replication/pom.xml
trunk/topia-service-security/pom.xml
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2010-08-29 15:58:37 UTC (rev 2108)
+++ trunk/pom.xml 2010-08-29 16:14:05 UTC (rev 2109)
@@ -37,7 +37,7 @@
</parent>
<artifactId>topia</artifactId>
- <version>2.4.3-SNAPSHOT</version>
+ <version>2.4.3</version>
<modules>
<module>topia-persistence</module>
@@ -319,9 +319,9 @@
<!-- Source control management. -->
<scm>
- <connection>scm:svn:http://svn.nuiton.org/svn/topia/trunk</connection>
- <developerConnection>scm:svn:http://svn.nuiton.org/svn/topia/trunk</developerConnection>
- <url>http://www.nuiton.org/repositories/browse/topia/trunk</url>
+ <connection>scm:svn:http://svn.nuiton.org/svn/topia/tags/topia-2.4.3</connection>
+ <developerConnection>scm:svn:http://svn.nuiton.org/svn/topia/tags/topia-2.4.3</developerConnection>
+ <url>http://www.nuiton.org/repositories/browse/topia/tags/topia-2.4.3</url>
</scm>
</project>
Modified: trunk/topia-persistence/pom.xml
===================================================================
--- trunk/topia-persistence/pom.xml 2010-08-29 15:58:37 UTC (rev 2108)
+++ trunk/topia-persistence/pom.xml 2010-08-29 16:14:05 UTC (rev 2109)
@@ -35,7 +35,7 @@
<parent>
<groupId>org.nuiton</groupId>
<artifactId>topia</artifactId>
- <version>2.4.3-SNAPSHOT</version>
+ <version>2.4.3</version>
</parent>
<groupId>org.nuiton.topia</groupId>
Modified: trunk/topia-service-migration/pom.xml
===================================================================
--- trunk/topia-service-migration/pom.xml 2010-08-29 15:58:37 UTC (rev 2108)
+++ trunk/topia-service-migration/pom.xml 2010-08-29 16:14:05 UTC (rev 2109)
@@ -35,7 +35,7 @@
<parent>
<groupId>org.nuiton</groupId>
<artifactId>topia</artifactId>
- <version>2.4.3-SNAPSHOT</version>
+ <version>2.4.3</version>
</parent>
<groupId>org.nuiton.topia</groupId>
Modified: trunk/topia-service-replication/pom.xml
===================================================================
--- trunk/topia-service-replication/pom.xml 2010-08-29 15:58:37 UTC (rev 2108)
+++ trunk/topia-service-replication/pom.xml 2010-08-29 16:14:05 UTC (rev 2109)
@@ -35,7 +35,7 @@
<parent>
<groupId>org.nuiton</groupId>
<artifactId>topia</artifactId>
- <version>2.4.3-SNAPSHOT</version>
+ <version>2.4.3</version>
</parent>
<groupId>org.nuiton.topia</groupId>
Modified: trunk/topia-service-security/pom.xml
===================================================================
--- trunk/topia-service-security/pom.xml 2010-08-29 15:58:37 UTC (rev 2108)
+++ trunk/topia-service-security/pom.xml 2010-08-29 16:14:05 UTC (rev 2109)
@@ -35,7 +35,7 @@
<parent>
<groupId>org.nuiton</groupId>
<artifactId>topia</artifactId>
- <version>2.4.3-SNAPSHOT</version>
+ <version>2.4.3</version>
</parent>
<groupId>org.nuiton.topia</groupId>
1
0
Author: tchemit
Date: 2010-08-29 17:58:37 +0200 (Sun, 29 Aug 2010)
New Revision: 2108
Url: http://nuiton.org/repositories/revision/topia/2108
Log:
Evolution #802: Use eugene 2.1.2
Modified:
trunk/pom.xml
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2010-08-29 15:28:46 UTC (rev 2107)
+++ trunk/pom.xml 2010-08-29 15:58:37 UTC (rev 2108)
@@ -230,7 +230,7 @@
<projectId>topia</projectId>
<!-- libs version -->
- <eugene.version>2.1.2-SNAPSHOT</eugene.version>
+ <eugene.version>2.1.2</eugene.version>
<lutinutil.version>1.4.1</lutinutil.version>
<processor.version>1.0.3</processor.version>
<i18n.version>1.2.2</i18n.version>
1
0
Author: tchemit
Date: 2010-08-29 17:28:46 +0200 (Sun, 29 Aug 2010)
New Revision: 2107
Url: http://nuiton.org/repositories/revision/topia/2107
Log:
Update nuiton-utils to 1.4.1
Modified:
trunk/pom.xml
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2010-08-29 14:21:56 UTC (rev 2106)
+++ trunk/pom.xml 2010-08-29 15:28:46 UTC (rev 2107)
@@ -231,7 +231,7 @@
<!-- libs version -->
<eugene.version>2.1.2-SNAPSHOT</eugene.version>
- <lutinutil.version>1.4</lutinutil.version>
+ <lutinutil.version>1.4.1</lutinutil.version>
<processor.version>1.0.3</processor.version>
<i18n.version>1.2.2</i18n.version>
<xmlrpc.version>3.1.2</xmlrpc.version>
1
0
Author: tchemit
Date: 2010-08-29 16:21:56 +0200 (Sun, 29 Aug 2010)
New Revision: 2106
Url: http://nuiton.org/repositories/revision/topia/2106
Log:
Utilisation de mavenpom4redmine 2.2.4
Modified:
trunk/pom.xml
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2010-08-21 16:05:12 UTC (rev 2105)
+++ trunk/pom.xml 2010-08-29 14:21:56 UTC (rev 2106)
@@ -33,7 +33,7 @@
<parent>
<groupId>org.nuiton</groupId>
<artifactId>mavenpom4redmine</artifactId>
- <version>2.2.3</version>
+ <version>2.2.4</version>
</parent>
<artifactId>topia</artifactId>
1
0
r2105 - in trunk/topia-service-replication/src: main/java/org/nuiton/topia/replication main/java/org/nuiton/topia/replication/model main/java/org/nuiton/topia/replication/operation main/resources/i18n test/java/org/nuiton/topia/replication test/java/org/nuiton/topia/replication/operation
by tchemit@users.nuiton.org Aug. 21, 2010
by tchemit@users.nuiton.org Aug. 21, 2010
Aug. 21, 2010
Author: tchemit
Date: 2010-08-21 18:05:12 +0200 (Sat, 21 Aug 2010)
New Revision: 2105
Url: http://nuiton.org/repositories/revision/topia/2105
Log:
- Anomalie #779: Replication is not atomic
- Evolution #815: Rethink replication service
Added:
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationContext.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilder.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProvider.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationUndoable.java
Removed:
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilder.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilderImpl.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProvider.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProviderImpl.java
Modified:
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperation.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationService.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationServiceImpl.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationLink.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationModel.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationNode.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationOperationDef.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachAssociation.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachLink.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/DettachAssociation.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/Duplicate.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/LoadLink.java
trunk/topia-service-replication/src/main/resources/i18n/topia-service-replication-en_GB.properties
trunk/topia-service-replication/src/main/resources/i18n/topia-service-replication-fr_FR.properties
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/AbstractTopiaReplicationServiceTest.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationOperationTest.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationServiceImplAllTest.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationServiceImplTest.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/FakeOperation.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UncreatableOperation.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UnregistredOperation.java
Added: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationContext.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationContext.java (rev 0)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationContext.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -0,0 +1,247 @@
+package org.nuiton.topia.replication;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nuiton.topia.TopiaContext;
+import org.nuiton.topia.TopiaException;
+import org.nuiton.topia.framework.TopiaContextImplementor;
+import org.nuiton.topia.persistence.TopiaEntity;
+import org.nuiton.topia.persistence.TopiaEntityEnum;
+import org.nuiton.topia.persistence.util.TopiaEntityHelper;
+import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
+import org.nuiton.topia.replication.model.ReplicationModel;
+import org.nuiton.topia.replication.model.ReplicationNode;
+import org.nuiton.topia.replication.model.ReplicationOperationDef;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Defines the context used to replicate.
+ * <p/>
+ * It contains :
+ * <ul>
+ * <li>the {@link #replicationModel}</li>
+ * <li>data sources involved ([@link #sourceTx}, {@link #targetTx})</li>
+ * <li>universe of data to replicate {@link #data}</li>
+ * <li>nodes that has been treated successfully {@link #treated}</li>
+ * </ul>
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.4.3
+ */
+public class TopiaReplicationContext {
+
+ /** Logger */
+ private static final Log log =
+ LogFactory.getLog(TopiaReplicationContext.class);
+
+ /** Replication model. */
+ protected final ReplicationModel replicationModel;
+
+ /**
+ * root context of incoming data source (says where to obtain entities
+ * to replicate).
+ */
+ protected final TopiaContext sourceTx;
+
+ /**
+ * root context of outcmoing data source (says where to replicate
+ * entities).
+ */
+ protected final TopiaContext targetTx;
+
+ /** dictionnary of data to replicate. */
+ protected TopiaEntityIdsMap data;
+
+ /**
+ * List of nodes that has been replicated with success (used to
+ * rollback them if something was wrong).
+ */
+ protected List<ReplicationNode> treated;
+
+ protected TopiaReplicationOperationProvider operationProvider;
+
+ public TopiaReplicationContext(TopiaReplicationOperationProvider operationProvider,
+ ReplicationModel replicationModel,
+ TopiaContext sourceTx,
+ TopiaContext targetTx) {
+ this.operationProvider = operationProvider;
+ this.replicationModel = replicationModel;
+ this.sourceTx = sourceTx;
+ this.targetTx = targetTx;
+ }
+
+ public TopiaReplicationOperation getOperation(ReplicationOperationDef operationDef) {
+ TopiaReplicationOperation operation =
+ operationProvider.getOperation(operationDef);
+ return operation;
+ }
+
+ public TopiaReplicationOperationUndoable getUndoableOperation(ReplicationOperationDef operationDef) throws IllegalArgumentException {
+ TopiaReplicationOperationUndoable operation =
+ operationProvider.getUndoableOperation(operationDef);
+ return operation;
+ }
+
+ public ReplicationModel getReplicationModel() {
+ return replicationModel;
+ }
+
+ public void addTreatedNode(ReplicationNode node) {
+ getTreated().add(node);
+ }
+
+ public ReplicationNode[] getReverseTreated() {
+
+ List<ReplicationNode> result =
+ new ArrayList<ReplicationNode>(getTreated());
+
+ // reverse nodes treated
+ Collections.reverse(result);
+
+ return result.toArray(new ReplicationNode[result.size()]);
+ }
+
+
+ /**
+ * Init the replication context.
+ * <p/>
+ * Comptute the universe to replicate and store it in {@link #data}.
+ *
+ * @throws TopiaException for any error when initializing the replication context
+ */
+ public void init() throws TopiaException {
+
+ TopiaContextImplementor srcCtxt = newSourceTx();
+ try {
+
+ // obtain all data to replicate
+ data = getIds(srcCtxt);
+
+ // adjust operation according to this data (some operations can be
+ // skipped if no data is associated to the given nodes)
+ // will also sort for each node his operations (according to
+ // their respective phase)
+ getReplicationModel().adjustOperations(data);
+
+ } finally {
+ close(srcCtxt, true);
+ }
+ }
+
+ public List<String> getEntityIds(Class<? extends TopiaEntity> type) throws TopiaException {
+
+ List<String> nodeEntityIds = data.get(type);
+ return nodeEntityIds;
+ }
+
+ public List<String> getEntityIds(ReplicationNode node) throws TopiaException {
+
+ List<String> nodeEntityIds = getEntityIds(node.getEntityType());
+ return nodeEntityIds;
+ }
+
+ public List<? extends TopiaEntity> getEntities(TopiaContextImplementor tx,
+ ReplicationNode node) throws TopiaException {
+
+ List<String> nodeEntityIds = getEntityIds(node);
+
+ if (log.isDebugEnabled()) {
+ log.debug("Will load " + nodeEntityIds.size() + " entities");
+ }
+
+ List<? extends TopiaEntity> nodeEntities =
+ TopiaEntityHelper.getEntitiesList(
+ tx,
+ nodeEntityIds.toArray(new String[nodeEntityIds.size()])
+ );
+ return nodeEntities;
+
+ }
+
+ public TopiaContextImplementor newSourceTx() throws TopiaException {
+ return (TopiaContextImplementor) sourceTx.beginTransaction();
+ }
+
+ public TopiaContextImplementor newTargetTx() throws TopiaException {
+ return (TopiaContextImplementor) targetTx.beginTransaction();
+ }
+
+ public static void close(TopiaContext tx, boolean rollback) throws TopiaException {
+
+ try {
+ if (rollback) {
+ tx.rollbackTransaction();
+ }
+ } finally {
+ tx.closeContext();
+ }
+ }
+
+ public void clear() {
+ if (data != null) {
+ data.clear();
+ }
+ if (treated != null) {
+ treated.clear();
+ }
+ }
+
+ protected TopiaEntityIdsMap getIds(TopiaContextImplementor srcCtxt) throws TopiaException {
+
+ TopiaEntityIdsMap data;
+
+ // on recupere les objets a repliquer par type
+ if (replicationModel.isReplicateAll()) {
+
+ // on recupere pour chaque type tous les ids des entites a repliquer
+ data = new TopiaEntityIdsMap();
+ for (TopiaEntityEnum e : replicationModel.getContracts()) {
+ List<String> ids = srcCtxt.getDAO(e.getContract()).findAllIds();
+ data.put(e.getContract(), ids);
+ }
+ } else {
+
+ // on recupere les entites specifies a repliquer
+ TopiaEntity[] entities = TopiaEntityHelper.getEntities(
+ srcCtxt,
+ replicationModel.getTopiaIds()
+ );
+
+ // on calcule toutes les ids des entites a repliquer
+ data = TopiaEntityHelper.detectEntityIds(
+ replicationModel.getContracts(),
+ replicationModel.getTypes(),
+ entities
+ );
+ }
+ return data;
+ }
+
+ protected List<ReplicationNode> getTreated() {
+ if (treated == null) {
+ treated = new ArrayList<ReplicationNode>();
+ }
+ return treated;
+ }
+
+ protected TopiaContext getSourceTx() {
+ return sourceTx;
+ }
+
+ protected TopiaContext getTargetTx() {
+ return targetTx;
+ }
+
+ protected TopiaEntityIdsMap getData() {
+ return data;
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ clear();
+ }
+}
Deleted: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilder.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilder.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilder.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -1,146 +0,0 @@
-/*
- * #%L
- * ToPIA :: Service Replication
- *
- * $Id$
- * $HeadURL$
- * %%
- * Copyright (C) 2004 - 2010 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%
- */
-package org.nuiton.topia.replication;
-
-import org.nuiton.topia.TopiaContext;
-import org.nuiton.topia.TopiaException;
-import org.nuiton.topia.persistence.TopiaEntity;
-import org.nuiton.topia.persistence.TopiaEntityEnum;
-import org.nuiton.topia.replication.model.ReplicationModel;
-import org.nuiton.topia.replication.model.ReplicationOperationPhase;
-
-import java.util.Set;
-
-/**
- * Helper to create {@link ReplicationModel}.
- *
- * @author tchemit <chemit(a)codelutin.com>
- * @since 2.4.3
- */
-public interface TopiaReplicationModelBuilder {
-
- TopiaReplicationOperationProvider getOperationProvider();
-
- TopiaReplicationOperation getOperation(Class<? extends TopiaReplicationOperation> operationClass);
-
- TopiaReplicationOperation[] getOperations();
-
- /**
- * Creation d'un modele de replication non initialise.
- *
- * @param context topia context on which entities are loaded
- * @param contracts le contrats d'entites autorises
- * @param topiaIds les ids des entites a repliquer
- * @return le modele instancie mais non initialise
- * @throws TopiaException pour toute erreur
- */
- ReplicationModel createModel(TopiaContext context,
- TopiaEntityEnum[] contracts,
- String... topiaIds) throws TopiaException;
-
- /**
- * Creation d'un modele de replication non initialise avec un ordre fixe
- * (celui des contrats donnés).
- *
- * @param contracts le contrats d'entites autorises
- * @param topiaIds les ids des entities a repliquer
- * @return le modele instancie mais non initialise
- * @throws TopiaException pour toute erreur
- */
- ReplicationModel createModelWithComputedOrder(
- TopiaEntityEnum[] contracts,
- String... topiaIds) throws TopiaException;
-
- /**
- * Creation d'un modele de replication (en mode tout dupliquer) non initialise.
- *
- * @param contracts le contrats d'entites autorises
- * @return le modele instancie mais non initialise
- * @throws TopiaException pour toute erreur
- */
- ReplicationModel createModelForAll(TopiaEntityEnum[] contracts)
- throws TopiaException;
-
-
- ReplicationModel prepare(TopiaContext context,
- TopiaEntityEnum[] contracts,
- String... entities) throws TopiaException;
-
- /**
- * Prepare le modele de replication pour toutes les entites des types
- * donnes.
- * <p/>
- * La méthode calcule l'ordre de replication des données.
- * <p/>
- * Actuellement, on n'est pas capable de calculer l'ordre si le graphe des
- * entités contient des cycles.
- * <p/>
- * TODO : faire en sorte de pouvoir gérer les cycles.
- *
- * @param contracts les contrats des types a repliquer
- * @return le modele pour la replication
- * @throws TopiaException pour toute erreur rencontree
- */
- ReplicationModel prepareForAll(TopiaEntityEnum[] contracts) throws TopiaException;
-
- /**
- * Prepare le modele de replication pour les entites données en ne faisant
- * pas de calcul sur l'ordre des entités à répliquer.
- * <p/>
- * L'ordre des types donnees sera celui utilisé.
- *
- * @param contracts les contrats a repliquer (dans l'ordre donnée)
- * @param topiaIds les ids des entites a repliquer
- * @return le model de replication initialise
- * @throws TopiaException pour toute erreur recontree
- */
- ReplicationModel prepareWithComputedOrder(TopiaEntityEnum[] contracts,
- String... topiaIds) throws TopiaException;
-
- Set<Class<? extends TopiaEntity>> detectTypes(
- TopiaContext context,
- TopiaEntityEnum[] contracts, String... ids) throws TopiaException;
-
- ReplicationModel initModel(ReplicationModel model,
- boolean computeOrder)
- throws TopiaException;
-
- void addBeforeOperation(ReplicationModel model,
- TopiaEntityEnum type,
- Class<? extends TopiaReplicationOperation> operationClass,
- Object... parameters);
-
- void addAfterOperation(ReplicationModel model,
- TopiaEntityEnum type,
- Class<? extends TopiaReplicationOperation> operationClass,
- Object... parameters);
-
- void createOperation(
- ReplicationModel model,
- TopiaEntityEnum type,
- ReplicationOperationPhase phase,
- Class<? extends TopiaReplicationOperation> operationClass,
- Object... parameters);
-}
Copied: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilder.java (from rev 2101, trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilderImpl.java)
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilder.java (rev 0)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilder.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -0,0 +1,304 @@
+/*
+ * #%L
+ * ToPIA :: Service Replication
+ *
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2004 - 2010 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%
+ */
+package org.nuiton.topia.replication;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nuiton.topia.TopiaContext;
+import org.nuiton.topia.TopiaException;
+import org.nuiton.topia.persistence.TopiaEntity;
+import org.nuiton.topia.persistence.TopiaEntityEnum;
+import org.nuiton.topia.persistence.util.TopiaEntityHelper;
+import org.nuiton.topia.replication.model.ReplicationModel;
+import org.nuiton.topia.replication.model.ReplicationNode;
+import org.nuiton.topia.replication.model.ReplicationOperationPhase;
+
+import java.util.Arrays;
+import java.util.Set;
+
+import static org.nuiton.i18n.I18n._;
+
+/**
+ * Builder of {@link ReplicationModel}.
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.4.3
+ */
+public class TopiaReplicationModelBuilder {
+
+ /** Logger */
+ private static final Log log =
+ LogFactory.getLog(TopiaReplicationModelBuilder.class);
+
+ /** Provider of {@link TopiaReplicationOperation}. */
+ protected TopiaReplicationOperationProvider operationProvider;
+
+ public TopiaReplicationOperationProvider getOperationProvider() {
+ if (operationProvider == null) {
+ operationProvider = new TopiaReplicationOperationProvider();
+ }
+ return operationProvider;
+ }
+
+ /**
+ * Prepare le modele de replication pour les entites données dans
+ * {@code topiaIds} et de leur couverture.
+ * <p/>
+ * Le paramètre {@code computeOrder} détermine si on doit calculer l'ordre
+ * de replication des données (valeur à {@code true}), sinon (valeur
+ * à {@code false}) on utilise l'ordre induit par le paramètre
+ * {@code contracts}.
+ *
+ * @param context le context de la base source (peut être utilisé
+ * pour calculer l'ordre)
+ * @param contracts les contrats des types a repliquer
+ * @param computeOrder drapeau positionné à {@code true} si on doit calculer
+ * l'ordre de réplication, {@code false} si on utilise
+ * l'ordre induit par le paramètre {@code contracts}.
+ * @param topiaIds les ids des entités à répliquer
+ * @return le modele pour la replication
+ * @throws TopiaException pour toute erreur rencontree
+ */
+ public ReplicationModel prepare(TopiaContext context,
+ TopiaEntityEnum[] contracts,
+ boolean computeOrder,
+ String... topiaIds) throws TopiaException {
+ ReplicationModel model =
+ createModel(context, contracts, computeOrder, topiaIds);
+ initModel(model, computeOrder);
+ return model;
+ }
+
+ /**
+ * Prepare le modele de replication pour toutes les entites des types
+ * donnes.
+ * <p/>
+ * La méthode calcule l'ordre de replication des données.
+ * <p/>
+ * Actuellement, on n'est pas capable de calculer l'ordre si le graphe des
+ * entités contient des cycles.
+ * <p/>
+ * TODO : faire en sorte de pouvoir gérer les cycles.
+ *
+ * @param contracts les contrats des types a repliquer
+ * @return le modele pour la replication
+ * @throws TopiaException pour toute erreur rencontree
+ */
+ public ReplicationModel prepareForAll(TopiaEntityEnum[] contracts) throws TopiaException {
+ ReplicationModel model = createModelForAll(contracts);
+ initModel(model, true);
+ return model;
+ }
+
+ public void createOperation(ReplicationModel model,
+ TopiaEntityEnum type,
+ ReplicationOperationPhase phase,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... parameters) {
+
+ TopiaEntityHelper.checkNotNull("createOperation", "model", model);
+ TopiaEntityHelper.checkNotNull("createOperation", "type", type);
+ TopiaEntityHelper.checkNotNull("createOperation", "phase", phase);
+ TopiaEntityHelper.checkNotNull("createOperation", "operationClass", operationClass);
+
+ TopiaReplicationOperation operation =
+ getOperationProvider().getOperation(operationClass);
+
+ if (operation == null) {
+ throw new IllegalArgumentException(
+ _("topia.replication.error.unkown.operation",
+ operationClass.getSimpleName(),
+ Arrays.toString(getOperationProvider().getOperations()))
+ );
+ }
+
+ ReplicationNode node = model.getNode(type);
+ if (node == null) {
+ throw new IllegalArgumentException(
+ _("topia.replication.error.unkown.owner.node",
+ type,
+ operationClass.getSimpleName(),
+ model.getNodes())
+ );
+ }
+ operation.register(model, node, phase, parameters);
+ }
+
+ /**
+ * Ajouter une nouvelle operation pre-replication, sur un type de donnee.
+ *
+ * @param model le modele de replication
+ * @param type le type du noeud de replication
+ * @param operationClass l'implantation de l'operation
+ * @param parameters les parametres supplementaires pour l'operation
+ */
+ public void addBeforeOperation(ReplicationModel model,
+ TopiaEntityEnum type,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... parameters) {
+ createOperation(
+ model,
+ type,
+ ReplicationOperationPhase.before,
+ operationClass,
+ parameters
+ );
+ }
+
+ /**
+ * Ajouter une nouvelle operation post-replication, sur un type de donnee.
+ *
+ * @param model le modele de replication
+ * @param type le type du noeud de replication
+ * @param operationClass l'implantation de l'operation
+ * @param parameters les parametres supplementaires pour l'operation
+ */
+ public void addAfterOperation(ReplicationModel model,
+ TopiaEntityEnum type,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... parameters) {
+ createOperation(
+ model,
+ type,
+ ReplicationOperationPhase.after,
+ operationClass,
+ parameters
+ );
+ }
+
+ /**
+ * Instantie un nouveau modèle de réplication pour les entités données par
+ * leur ids.
+ * <p/>
+ * L'ordre de réplication dépend du paramètre {@code computeOrder}. Si
+ * celui-ci vaut {@code true}, on calcule l'ordre de réplication, sinon on
+ * utilise l'ordre induit par les {@code contracts}.
+ *
+ * @param context le context Topia pour récupérer certainnes
+ * informations de la base source si nécessaire.
+ * @param contracts les types d'entités
+ * @param computeOrder drapeau pour calculer l'ordre de réplication
+ * (valeur à {@code true}), sinon on utilise l'ordre
+ * induit par les {@code contracts}.
+ * @param topiaIds les ids à dupliquer
+ * @return le modèle crée mais non initialisé.
+ * @throws TopiaException pour toute erreur lors de la création du modèle
+ */
+ public ReplicationModel createModel(TopiaContext context,
+ TopiaEntityEnum[] contracts,
+ boolean computeOrder,
+ String... topiaIds)
+ throws TopiaException {
+
+ ReplicationModel model;
+
+ if (computeOrder) {
+ // determines types to use
+ Set<Class<? extends TopiaEntity>> detectTypes =
+ detectTypes(context, contracts, topiaIds);
+ model = new ReplicationModel(contracts, detectTypes, topiaIds);
+ } else {
+ model = new ReplicationModel(contracts, false, topiaIds);
+
+ }
+ return model;
+ }
+
+ /**
+ * Instantie un nouveau modèle de réplication en respectant l'ordre induit
+ * par les {@code contracts}.
+ *
+ * @param contracts les types d'entités
+ * @param topiaIds les ids à dupliquer
+ * @return le modèle crée mais non initialisé.
+ * @throws TopiaException pour toute erreur lors de la création du modèle
+ * @deprecated since 2.4.3, prefer use method {@link #createModel(TopiaContext, TopiaEntityEnum[], boolean, String...)}
+ */
+ @Deprecated
+ public ReplicationModel createModelWithComputedOrder(TopiaEntityEnum[] contracts,
+ String... topiaIds)
+ throws TopiaException {
+
+ ReplicationModel model;
+
+
+ model = new ReplicationModel(contracts, false, topiaIds);
+ return model;
+ }
+
+ /**
+ * Instantie un nouveau modèle de réplication pour toutes les entitées.
+ * <p/>
+ * Ici, l'ordre est toujours calculé.
+ *
+ * @param contracts les types d'entités
+ * @return le modèle crée mais non initialisé.
+ * @throws TopiaException pour toute erreur lors de la création du modèle
+ */
+ public ReplicationModel createModelForAll(TopiaEntityEnum[] contracts)
+ throws TopiaException {
+ ReplicationModel model = new ReplicationModel(contracts, true);
+ return model;
+ }
+
+ public ReplicationModel initModel(ReplicationModel model,
+ boolean computeOrder) throws TopiaException {
+ TopiaEntityHelper.checkNotNull("initModel", "model", model);
+
+ model.detectAssociations();
+ model.detectDirectDependencies();
+ if (computeOrder) {
+ model.detectShell();
+ model.detectDependencies();
+ }
+ model.detectObjectsToDettach();
+ model.detectOperations();
+ return model;
+ }
+
+ protected Set<Class<? extends TopiaEntity>> detectTypes(TopiaContext context,
+ TopiaEntityEnum[] contracts,
+ String... ids) throws TopiaException {
+
+ TopiaContext ctxt = context.beginTransaction();
+ try {
+ TopiaEntity[] entities = TopiaEntityHelper.getEntities(ctxt, ids);
+
+ // on detecte tous les types connus pour les entites données
+ Set<Class<? extends TopiaEntity>> types =
+ TopiaEntityHelper.detectTypes(contracts, entities);
+
+ if (log.isDebugEnabled()) {
+ log.debug("for type : " + entities.getClass());
+ for (Class<? extends TopiaEntity> k : types) {
+ log.debug(k);
+ }
+ }
+ return types;
+ } finally {
+ ctxt.closeContext();
+ }
+ }
+}
Deleted: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilderImpl.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilderImpl.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilderImpl.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -1,258 +0,0 @@
-/*
- * #%L
- * ToPIA :: Service Replication
- *
- * $Id$
- * $HeadURL$
- * %%
- * Copyright (C) 2004 - 2010 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%
- */
-package org.nuiton.topia.replication;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.nuiton.topia.TopiaContext;
-import org.nuiton.topia.TopiaException;
-import org.nuiton.topia.persistence.TopiaEntity;
-import org.nuiton.topia.persistence.TopiaEntityEnum;
-import org.nuiton.topia.persistence.util.TopiaEntityHelper;
-import org.nuiton.topia.replication.model.ReplicationModel;
-import org.nuiton.topia.replication.model.ReplicationNode;
-import org.nuiton.topia.replication.model.ReplicationOperationPhase;
-
-import java.util.Arrays;
-import java.util.Set;
-
-import static org.nuiton.i18n.I18n._;
-
-/**
- * Default implementation of {@link TopiaReplicationModelBuilder}.
- *
- * @author tchemit <chemit(a)codelutin.com>
- * @since 2.4.3
- */
-public class TopiaReplicationModelBuilderImpl implements TopiaReplicationModelBuilder {
-
- /** Logger */
- private static final Log log =
- LogFactory.getLog(TopiaReplicationModelBuilderImpl.class);
-
- protected TopiaReplicationOperationProvider operationProvider;
-
- @Override
- public TopiaReplicationOperationProvider getOperationProvider() {
- if (operationProvider == null) {
- operationProvider = new TopiaReplicationOperationProviderImpl();
- }
- return operationProvider;
- }
-
- @Override
- public TopiaReplicationOperation getOperation(Class<? extends TopiaReplicationOperation> operationClass) {
- return getOperationProvider().getOperation(operationClass);
- }
-
- @Override
- public TopiaReplicationOperation[] getOperations() {
- return getOperationProvider().getOperations();
- }
-
-
- @Override
- public ReplicationModel createModel(TopiaContext context,
- TopiaEntityEnum[] contracts,
- String... topiaIds)
- throws TopiaException {
-
- Set<Class<? extends TopiaEntity>> detectTypes =
- detectTypes(context, contracts, topiaIds);
- ReplicationModel model =
- new ReplicationModel(contracts, detectTypes, topiaIds);
- return model;
- }
-
-
- @Override
- public ReplicationModel createModelWithComputedOrder(
- TopiaEntityEnum[] contracts,
- String... topiaIds)
- throws TopiaException {
- ReplicationModel model =
- new ReplicationModel(contracts, false, topiaIds);
- return model;
- }
-
-
- @Override
- public ReplicationModel createModelForAll(TopiaEntityEnum[] contracts)
- throws TopiaException {
- ReplicationModel model = new ReplicationModel(contracts, true);
- return model;
- }
-
- @Override
- public void createOperation(
- ReplicationModel model,
- TopiaEntityEnum type,
- ReplicationOperationPhase phase,
- Class<? extends TopiaReplicationOperation> operationClass,
- Object... parameters) {
-
- TopiaEntityHelper.checkNotNull("createOperation", "provider", operationProvider);
- TopiaEntityHelper.checkNotNull("createOperation", "model", model);
- TopiaEntityHelper.checkNotNull("createOperation", "type", type);
- TopiaEntityHelper.checkNotNull("createOperation", "phase", phase);
- TopiaEntityHelper.checkNotNull("createOperation", "operationClass", operationClass);
-
- TopiaReplicationOperation operation = operationProvider.getOperation(operationClass);
-
- if (operation == null) {
- throw new IllegalArgumentException(
- _("topia.replication.engine.error.unkown.operation",
- operationClass.getSimpleName(),
- Arrays.toString(operationProvider.getOperations()))
- );
- }
-
- ReplicationNode node = model.getNode(type);
- if (node == null) {
- throw new IllegalArgumentException(
- _("topia.replication.engine.error.unkown.owner.node",
- type,
- operationClass.getSimpleName(),
- model.getNodes())
- );
- }
- operation.register(model, node, phase, parameters);
- }
-
-
- @Override
- public ReplicationModel prepare(TopiaContext context,
- TopiaEntityEnum[] contracts,
- String... entities) throws TopiaException {
- ReplicationModel model =
- createModel(context, contracts, entities);
- initModel(model, true);
- return model;
- }
-
-
- @Override
- public ReplicationModel prepareForAll(TopiaEntityEnum[] contracts) throws TopiaException {
- ReplicationModel model = createModelForAll(contracts);
- initModel(model, true);
- return model;
- }
-
-
- @Override
- public ReplicationModel prepareWithComputedOrder(TopiaEntityEnum[] contracts,
- String... topiaIds) throws TopiaException {
- ReplicationModel model =
- createModelWithComputedOrder(contracts, topiaIds);
- initModel(model, false);
- return model;
- }
-
- @Override
- public Set<Class<? extends TopiaEntity>> detectTypes(TopiaContext context,
- TopiaEntityEnum[] contracts,
- String... ids) throws TopiaException {
-
- TopiaContext ctxt = context.beginTransaction();
- try {
- TopiaEntity[] entities = TopiaEntityHelper.getEntities(ctxt, ids);
-
- // on detecte tous les types connus pour les entites données
- Set<Class<? extends TopiaEntity>> types =
- TopiaEntityHelper.detectTypes(contracts, entities);
-
- if (log.isDebugEnabled()) {
- log.debug("for type : " + entities.getClass());
- for (Class<? extends TopiaEntity> k : types) {
- log.debug(k);
- }
- }
- return types;
- } finally {
- ctxt.closeContext();
- }
- }
-
- @Override
- public ReplicationModel initModel(ReplicationModel model,
- boolean computeOrder) throws TopiaException {
- TopiaEntityHelper.checkNotNull("initModel", "model", model);
-
- model.detectAssociations();
- model.detectDirectDependencies();
- if (computeOrder) {
- model.detectShell();
- model.detectDependencies();
- }
- model.detectObjectsToDettach();
- model.detectOperations();
- return model;
- }
-
-
- /**
- * Ajouter une nouvelle operation pre-replication, sur un type de donnee.
- *
- * @param model le modele de replication
- * @param type le type du noeud de replication
- * @param operationClass l'implantation de l'operation
- * @param parameters les parametres supplementaires pour l'operation
- */
- @Override
- public void addBeforeOperation(ReplicationModel model,
- TopiaEntityEnum type,
- Class<? extends TopiaReplicationOperation> operationClass,
- Object... parameters) {
- createOperation(
- model,
- type,
- ReplicationOperationPhase.before,
- operationClass,
- parameters
- );
- }
-
- /**
- * Ajouter une nouvelle operation post-replication, sur un type de donnee.
- *
- * @param model le modele de replication
- * @param type le type du noeud de replication
- * @param operationClass l'implantation de l'operation
- * @param parameters les parametres supplementaires pour l'operation
- */
- @Override
- public void addAfterOperation(ReplicationModel model,
- TopiaEntityEnum type,
- Class<? extends TopiaReplicationOperation> operationClass,
- Object... parameters) {
- createOperation(
- model,
- type,
- ReplicationOperationPhase.after,
- operationClass,
- parameters
- );
- }
-}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperation.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperation.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperation.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -28,7 +28,6 @@
import org.nuiton.topia.framework.TopiaContextImplementor;
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.persistence.TopiaEntityEnum;
-import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
import org.nuiton.topia.replication.model.ReplicationOperationDef;
@@ -41,13 +40,13 @@
* Le contrat d'une operation a effectuer lors de la replication.
* <p/>
* Le module propose des operations de base dans le paquetage
- * <code>org.nuiton.topia.replication.operation</code>.
+ * {@code org.nuiton.topia.replication.operation}.
* <p/>
* <p/>
* Pour definir une nouvelle implantation d'operation, il faut l'enregister
* en tant que service (au sens de la classe {@link ServiceLoader},
* c'est à dire ajouter dans un fichier (du class-path)
- * <code>META-INF/services/org.nuiton.topia.replication.TopiaReplicationOperation</code>
+ * {@code META-INF/services/org.nuiton.topia.replication.TopiaReplicationOperation}
* <p/>
* une ligne avec le nom qualifie de votre implantation.
* <p/>
@@ -62,54 +61,38 @@
* Creer et enregister une operation utilisateur apres la creation du
* modele via la methode
* <p/>
- * {@link TopiaReplicationService#prepare(TopiaEntityEnum[], String...)}.
+ * {@link TopiaReplicationService#prepare(TopiaEntityEnum[],boolean, String...)}.
*
* @param model le modele de replication
* @param ownerNode le noeud proprietaire de l'operation
* @param phase la phase ou positionner l'operation
* @param parameters les parametres de l'operation
+ * @throws UnsupportedOperationException if can not register this operation
+ * (says when operation is only internal)
* @see ReplicationModel
* @see ReplicationOperationPhase
*/
void register(ReplicationModel model,
ReplicationNode ownerNode,
ReplicationOperationPhase phase,
- Object... parameters);
+ Object... parameters) throws UnsupportedOperationException;
/**
* Execute l'operation avec le parametrage donnee.
* <p/>
* Note : le commit sur le context cible doit etre geree dans la methode.
*
- * @param operationDef la definition de l'operation a realiser
- * @param srcCtxt le context source
- * @param dstCtxt le context destination
- * @param entities la liste des
- * @param data le dictionnaire de toutes les donnees a repliquer
+ * @param replicationContext le contexte de replication
+ * @param operationDef la definition de l'operation a realiser
+ * @param srcCtxt le context source
+ * @param dstCtxt le context destination
+ * @param entities la liste des entités à traiter
* @throws Exception pour toute erreur
*/
- void run(ReplicationOperationDef operationDef,
+ void run(TopiaReplicationContext replicationContext,
+ ReplicationOperationDef operationDef,
TopiaContextImplementor srcCtxt,
TopiaContextImplementor dstCtxt,
- List<? extends TopiaEntity> entities,
- TopiaEntityIdsMap data) throws Exception;
+ List<? extends TopiaEntity> entities) throws Exception;
- /**
- * Execute l'operation inverse avec le parametrage donnee
- * (pour annuler l'opération).
- * <p/>
- * Note : le commit sur le context cible doit etre geree dans la methode.
- *
- * @param operationDef la definition de l'operation a realiser
- * @param srcCtxt le context source
- * @param dstCtxt le context destination
- * @param entities la liste des
- * @param data le dictionnaire de toutes les donnees a repliquer
- * @throws Exception pour toute erreur
- */
- void rollback(ReplicationOperationDef operationDef,
- TopiaContextImplementor srcCtxt,
- TopiaContextImplementor dstCtxt,
- List<? extends TopiaEntity> entities,
- TopiaEntityIdsMap data) throws Exception;
}
Deleted: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProvider.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProvider.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProvider.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -1,53 +0,0 @@
-/*
- * #%L
- * ToPIA :: Service Replication
- *
- * $Id$
- * $HeadURL$
- * %%
- * Copyright (C) 2004 - 2010 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%
- */
-package org.nuiton.topia.replication;
-
-import java.util.ServiceLoader;
-
-/**
- * Provider of {@link TopiaReplicationOperation}.
- *
- * @author tchemit <chemit(a)codelutin.com>
- * @since 2.4.3
- */
-public interface TopiaReplicationOperationProvider {
-
- /**
- * Obtains all {@link TopiaReplicationOperation} available
- * via {@link ServiceLoader}.
- *
- * @return the array of available operations
- */
- TopiaReplicationOperation[] getOperations();
-
- /**
- * Obtains the instanciated (and initialized) operation of the given type.
- *
- * @param operationClass type of searched operation
- * @return the found operation, or {@code null} if not found.
- */
- TopiaReplicationOperation getOperation(
- Class<? extends TopiaReplicationOperation> operationClass);
-}
Copied: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProvider.java (from rev 2101, trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProviderImpl.java)
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProvider.java (rev 0)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProvider.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -0,0 +1,128 @@
+/*
+ * #%L
+ * ToPIA :: Service Replication
+ *
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2004 - 2010 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%
+ */
+package org.nuiton.topia.replication;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nuiton.topia.persistence.util.TopiaEntityHelper;
+import org.nuiton.topia.replication.model.ReplicationOperationDef;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ServiceLoader;
+
+/**
+ * Provider of {@link TopiaReplicationOperation}.
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.4.3
+ */
+public class TopiaReplicationOperationProvider {
+
+ /** Logger */
+ private static final Log log =
+ LogFactory.getLog(TopiaReplicationOperationProvider.class);
+
+ /**
+ * All available operations detected via a {@link ServiceLoader} on
+ * contract {@link TopiaReplicationOperation}.
+ */
+ protected TopiaReplicationOperation[] operations;
+
+ /**
+ * Obtains all {@link TopiaReplicationOperation} available
+ * via {@link ServiceLoader}.
+ * <p/>
+ * If {@link #operations} is null, then load operations, otherwise just
+ * return the already computed result.
+ *
+ * @return the array of all available operations
+ */
+ public TopiaReplicationOperation[] getOperations() {
+ if (operations == null) {
+ // chargement des operations disponibles une seule fois
+
+ ServiceLoader<TopiaReplicationOperation> loader =
+ ServiceLoader.load(TopiaReplicationOperation.class);
+
+ List<TopiaReplicationOperation> operations =
+ new ArrayList<TopiaReplicationOperation>();
+
+ for (TopiaReplicationOperation op : loader) {
+ if (log.isDebugEnabled()) {
+ log.debug("detected operation " + op);
+ }
+ operations.add(op);
+ }
+ this.operations = operations.toArray(
+ new TopiaReplicationOperation[operations.size()]);
+ }
+ return operations;
+ }
+
+ /**
+ * Obtains the instanciated (and initialized) operation of the given type.
+ *
+ * @param operationClass type of searched operation
+ * @return the found operation, or {@code null} if not found.
+ */
+ public TopiaReplicationOperation getOperation(
+ Class<? extends TopiaReplicationOperation> operationClass) {
+
+ TopiaEntityHelper.checkNotNull("getOperation", "operationClass",
+ operationClass);
+ TopiaReplicationOperation result = null;
+
+ for (TopiaReplicationOperation op : getOperations()) {
+ if (operationClass.isAssignableFrom(op.getClass())) {
+ result = op;
+ break;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Obtains the instanciated (and initialized) operation of the given
+ * operation definition.
+ *
+ * @param operationDef operation definition of searched operation
+ * @return the found operation, or {@code null} if not found.
+ */
+ public TopiaReplicationOperation getOperation(ReplicationOperationDef operationDef) {
+ TopiaEntityHelper.checkNotNull("getOperation", "operationDef",
+ operationDef);
+ return getOperation(operationDef.getOperationClass());
+ }
+
+ public TopiaReplicationOperationUndoable getUndoableOperation(ReplicationOperationDef operationDef) throws IllegalArgumentException {
+ TopiaReplicationOperation operation = getOperation(operationDef);
+ if (!(operation instanceof TopiaReplicationOperationUndoable)) {
+ throw new IllegalArgumentException(
+ "the operation " + operation + " is not undoable");
+ }
+ return (TopiaReplicationOperationUndoable) operation;
+ }
+}
Deleted: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProviderImpl.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProviderImpl.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProviderImpl.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -1,92 +0,0 @@
-/*
- * #%L
- * ToPIA :: Service Replication
- *
- * $Id$
- * $HeadURL$
- * %%
- * Copyright (C) 2004 - 2010 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%
- */
-package org.nuiton.topia.replication;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.nuiton.topia.persistence.util.TopiaEntityHelper;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.ServiceLoader;
-
-/**
- * Default implementation of {@link TopiaReplicationOperationProvider}.
- *
- * @author tchemit <chemit(a)codelutin.com>
- * @since 2.4.3
- */
-public class TopiaReplicationOperationProviderImpl implements TopiaReplicationOperationProvider {
-
- /** Logger */
- private static final Log log =
- LogFactory.getLog(TopiaReplicationOperationProviderImpl.class);
-
- /**
- * la liste des operations disponibles (chargee automatiquement via un
- * ServiceLoader sur le contract {@link TopiaReplicationOperation})
- */
- protected TopiaReplicationOperation[] operations;
-
- @Override
- public TopiaReplicationOperation[] getOperations() {
- if (operations == null) {
- // chargement des operations disponibles une seule fois
-
- ServiceLoader<TopiaReplicationOperation> loader =
- ServiceLoader.load(TopiaReplicationOperation.class);
-
- List<TopiaReplicationOperation> operations =
- new ArrayList<TopiaReplicationOperation>();
-
- for (TopiaReplicationOperation op : loader) {
- if (log.isDebugEnabled()) {
- log.debug("detected operation " + op);
- }
- operations.add(op);
- }
- this.operations = operations.toArray(
- new TopiaReplicationOperation[operations.size()]);
- }
- return operations;
- }
-
- @Override
- public TopiaReplicationOperation getOperation(
- Class<? extends TopiaReplicationOperation> operationClass) {
-
- TopiaEntityHelper.checkNotNull("getOperation", "operationClass",
- operationClass);
- TopiaReplicationOperation result = null;
-
- for (TopiaReplicationOperation op : getOperations()) {
- if (operationClass.isAssignableFrom(op.getClass())) {
- result = op;
- break;
- }
- }
- return result;
- }
-}
Added: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationUndoable.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationUndoable.java (rev 0)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationUndoable.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -0,0 +1,56 @@
+/*
+ * #%L
+ * ToPIA :: Service Replication
+ *
+ * $Id: TopiaReplicationOperation.java 2098 2010-08-14 13:54:40Z tchemit $
+ * $HeadURL: http://svn.nuiton.org/svn/topia/trunk/topia-service-replication/src/main/ja… $
+ * %%
+ * Copyright (C) 2004 - 2010 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%
+ */
+
+package org.nuiton.topia.replication;
+
+import org.nuiton.topia.framework.TopiaContextImplementor;
+import org.nuiton.topia.replication.model.ReplicationOperationDef;
+
+/**
+ * Le contrat d'une operation {@link TopiaReplicationOperation} qui peut être
+ * rollbacker lorsque la replication a échouée.
+ * <p/>
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.4.3
+ */
+public interface TopiaReplicationOperationUndoable extends TopiaReplicationOperation {
+
+ /**
+ * Execute l'operation inverse avec le parametrage donnee
+ * (pour annuler l'opération).
+ * <p/>
+ * Note : le commit sur le context cible doit etre geree dans la methode.
+ *
+ * @param operationDef la definition de l'operation a realiser
+ * @param replicationContext le context de replication
+ * @param dstCtxt le context destination
+ * @throws Exception pour toute erreur
+ */
+ void rollback(ReplicationOperationDef operationDef,
+ TopiaReplicationContext replicationContext,
+ TopiaContextImplementor dstCtxt
+ ) throws Exception;
+}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationService.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationService.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationService.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -28,12 +28,8 @@
import org.nuiton.topia.TopiaException;
import org.nuiton.topia.framework.TopiaService;
import org.nuiton.topia.persistence.TopiaEntityEnum;
-import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
import org.nuiton.topia.replication.model.ReplicationModel;
-import org.nuiton.topia.replication.model.ReplicationNode;
-import java.util.List;
-
/**
* User visible interface for replication engin
* <p/>
@@ -43,8 +39,7 @@
* <p/>
* The replication is always done in two phases :
* <p/>
- * <li> - prepare the replication model - ({@link #prepare(TopiaEntityEnum[],
- * String...)} - ({@link #prepareForAll(TopiaEntityEnum[])}
+ * <li> - prepare the replication model - ({@link #prepare(TopiaEntityEnum[],boolean, String...)} - ({@link #prepareForAll(TopiaEntityEnum[])}
* <p/>
* <li> - lanch replication {@link #doReplicate(ReplicationModel,
* TopiaContext)}
@@ -60,21 +55,48 @@
/** Nom du service topia */
String TOPIA_SERVICE_NAME = "topia.service.replication";
+ /**
+ * Obtains the {@code model builder} use to creat the replication's model.
+ *
+ * @return the model builder
+ * @since 2.4.3
+ */
TopiaReplicationModelBuilder getModelBuilder();
/**
* Prepare le modele de replication pour les entites dans les topiaIds sont
* donnes.
*
- * @param contracts les contrats a repliquer
- * @param topiaIds la liste des ids d'entites a repliquer
+ * @param contracts les contrats a repliquer
+ * @param computeOrder drapeau positionné à {@code true} si on doit calculer
+ * l'ordre des entités à repliquer, sinon on utilise
+ * l'ordre induit par les {@code contracts}.
+ * @param topiaIds la liste des ids d'entites a repliquer
* @return le model de replication initialise
* @throws TopiaException pour toute erreur recontree
*/
ReplicationModel prepare(TopiaEntityEnum[] contracts,
+ boolean computeOrder,
String... topiaIds) throws TopiaException;
/**
+ * Prepare le modele de replication pour les entites dans les topiaIds sont
+ * donnes en utilisant l'ordre des {@code contracts} donné pour l'ordre de
+ * replication.
+ *
+ * @param contracts les contrats a repliquer
+ * l'ordre des entités à repliquer, sinon on utilise
+ * l'ordre induit par les {@code contracts}.
+ * @param topiaIds la liste des ids d'entites a repliquer
+ * @return le model de replication initialise
+ * @throws TopiaException pour toute erreur recontree
+ * @deprecated since 2.4.3, prefer use the method {@link #prepare(TopiaEntityEnum[], boolean, String...)} with flag setted to {@code false}.
+ */
+ @Deprecated
+ ReplicationModel prepareWithComputedOrder(TopiaEntityEnum[] contracts,
+ String... topiaIds) throws TopiaException;
+
+ /**
* Prepare le modele de replication pour toutes les entites des types
* donnes.
* <p/>
@@ -92,27 +114,15 @@
ReplicationModel prepareForAll(TopiaEntityEnum[] contracts) throws TopiaException;
/**
- * Prepare le modele de replication pour les entites données en ne faisant
- * pas de calcul sur l'ordre des entités à répliquer.
- * <p/>
- * L'ordre des types donnees sera celui utilisé.
- *
- * @param contracts les contrats a repliquer (dans l'ordre donnée)
- * @param topiaIds les ids des entites a repliquer
- * @return le model de replication initialise
- * @throws TopiaException pour toute erreur recontree
- */
- ReplicationModel prepareWithComputedOrder(TopiaEntityEnum[] contracts,
- String... topiaIds) throws TopiaException;
-
- /**
* Ajouter une nouvelle operation pre-replication, sur un type de donnee.
*
* @param model le modele de replication
* @param type le type du noeud de replication
* @param operationClass l'implantation de l'operation
* @param parameters les parametres supplementaires pour l'operation
+ * @deprecated since 2.4.3, prefer use the method {@link TopiaReplicationModelBuilder#addBeforeOperation(ReplicationModel, TopiaEntityEnum, Class, Object...)}
*/
+ @Deprecated
void addBeforeOperation(ReplicationModel model,
TopiaEntityEnum type,
Class<? extends TopiaReplicationOperation> operationClass,
@@ -125,7 +135,9 @@
* @param type le type du noeud de replication
* @param operationClass l'implantation de l'operation
* @param parameters les parametres supplementaires pour l'operation
+ * @deprecated since 2.4.3, prefer use the method {@link TopiaReplicationModelBuilder#addAfterOperation(ReplicationModel, TopiaEntityEnum, Class, Object...)}
*/
+ @Deprecated
void addAfterOperation(ReplicationModel model,
TopiaEntityEnum type,
Class<? extends TopiaReplicationOperation> operationClass,
@@ -133,9 +145,9 @@
/**
* Lance l'operation de replication a partir du context source vers le
- * context de destination sur les entites donnees et en utilisant le model
+ * context de destination sur les entites donnees et en utilisant le modele
* de replication precedemment construit via la methode {@link
- * #prepare(TopiaEntityEnum[], String...)} ou {@link
+ * #prepare(TopiaEntityEnum[],boolean, String...)} ou {@link
* #prepareForAll(TopiaEntityEnum[])}.
*
* @param model le modele de replication
@@ -148,16 +160,10 @@
/**
* Pour revenir en arrière lorsque la réplication a échouée .
*
- * @param model le modele de replication
- * @param data le dictionnaire des données à repliquer par type d'entités
- * @param nodes les nodes déjà traités que l'on doit reverter
- * @param dstCtxt le context sur la source de donnees ou repliquer
+ * @param replicationContext the replication's context used to start replication.
* @throws Exception pour toute erreur pendant la replication
*/
- void doRollback(ReplicationModel model,
- TopiaEntityIdsMap data,
- List<ReplicationNode> nodes,
- TopiaContext dstCtxt) throws Exception;
+ void doRollback(TopiaReplicationContext replicationContext) throws Exception;
}
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 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationServiceImpl.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -33,12 +33,10 @@
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.persistence.TopiaEntityEnum;
import org.nuiton.topia.persistence.util.TopiaEntityHelper;
-import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
import org.nuiton.topia.replication.model.ReplicationOperationDef;
-import java.util.ArrayList;
import java.util.List;
/**
@@ -50,11 +48,17 @@
public class TopiaReplicationServiceImpl implements TopiaReplicationService {
/** Logger */
- private static final Log log = LogFactory.getLog(TopiaReplicationServiceImpl.class);
+ private static final Log log =
+ LogFactory.getLog(TopiaReplicationServiceImpl.class);
/** le contexte sur la base source de la replication */
protected TopiaContextImplementor context;
+ /**
+ * le constructeur de modèle de réplication.
+ *
+ * @since 2.4.3
+ */
protected TopiaReplicationModelBuilder modelBuilder;
//--------------------------------------------------------------------------
@@ -98,38 +102,23 @@
@Override
public ReplicationModel prepare(TopiaEntityEnum[] contracts,
- String... entities) throws TopiaException {
- ReplicationModel model = getModelBuilder().prepare(context, contracts, entities);
+ boolean computeOrder,
+ String... topiaIds) throws TopiaException {
+ ReplicationModel model =
+ getModelBuilder().prepare(context, contracts, computeOrder, topiaIds);
return model;
-// ReplicationModel model =
-// createModel(contracts, entities);
-//
-// initModel(model, true);
-//
-// return model;
}
@Override
- public ReplicationModel prepareForAll(TopiaEntityEnum[] contracts) throws TopiaException {
- ReplicationModel model = getModelBuilder().prepareForAll(contracts);
- return model;
-// ReplicationModel model = createModelForAll(contracts);
-//
-// initModel(model, true);
-//
-// return model;
+ public ReplicationModel prepareWithComputedOrder(TopiaEntityEnum[] contracts,
+ String... topiaIds) throws TopiaException {
+ return prepare(contracts, false, topiaIds);
}
@Override
- public ReplicationModel prepareWithComputedOrder(TopiaEntityEnum[] contracts,
- String... topiaIds) throws TopiaException {
- ReplicationModel model = getModelBuilder().prepareWithComputedOrder(contracts);
+ public ReplicationModel prepareForAll(TopiaEntityEnum[] contracts) throws TopiaException {
+ ReplicationModel model = getModelBuilder().prepareForAll(contracts);
return model;
-// ReplicationModel model = createModelWithComputedOrder(contracts, topiaIds);
-//
-// initModel(model, false);
-//
-// return model;
}
@Override
@@ -137,13 +126,12 @@
TopiaEntityEnum type,
Class<? extends TopiaReplicationOperation> operationClass,
Object... parameters) {
- getModelBuilder().addBeforeOperation(model, type, operationClass, parameters);
-// createOperation(model,
-// type,
-// ReplicationOperationPhase.before,
-// operationClass,
-// parameters
-// );
+
+ getModelBuilder().addBeforeOperation(model,
+ type,
+ operationClass,
+ parameters
+ );
}
@Override
@@ -151,425 +139,209 @@
TopiaEntityEnum type,
Class<? extends TopiaReplicationOperation> operationClass,
Object... parameters) {
- getModelBuilder().addAfterOperation(model, type, operationClass, parameters);
-// createOperation(model,
-// type,
-// ReplicationOperationPhase.after,
-// operationClass,
-// parameters
-// );
+
+ getModelBuilder().addAfterOperation(model,
+ type,
+ operationClass,
+ parameters
+ );
}
@Override
+ public TopiaReplicationModelBuilder getModelBuilder() {
+ if (modelBuilder == null) {
+ modelBuilder = new TopiaReplicationModelBuilder();
+ }
+ return modelBuilder;
+ }
+
+ @Override
public void doReplicate(ReplicationModel model,
- TopiaContext dstCtxt) throws Exception {
+ TopiaContext targetTx) throws Exception {
TopiaEntityHelper.checkNotNull("doReplicate", "model", model);
- TopiaEntityHelper.checkNotNull("doReplicate", "dstCtxt", dstCtxt);
+ TopiaEntityHelper.checkNotNull("doReplicate", "dstCtxt", targetTx);
- TopiaContextImplementor srcCtxt = null;
+ // create a replication context
+ TopiaReplicationContext replicationContext =
+ new TopiaReplicationContext(getModelBuilder().getOperationProvider(),
+ model,
+ context,
+ targetTx);
- TopiaEntityIdsMap data = null;
+ // init replication context
+ replicationContext.init();
- // keep the list of treated nodes (to roolback them if something
- // is wrong).
- List<ReplicationNode> treated = new ArrayList<ReplicationNode>();
try {
- srcCtxt = (TopiaContextImplementor) context.beginTransaction();
-
- data = getIds(model, srcCtxt);
-
- srcCtxt.closeContext();
-
- model.adjustOperations(data);
-
- //FIXME tchemit 2077-07-26, should use next line when
- // http://nuiton.org/issues/show/779 is closed
- boolean needTransaction = true;
-// boolean needTransaction = ((TopiaContextImplementor) dstCtxt).getRootContext().equals(dstCtxt);
-
- TopiaContext tx;
-
for (ReplicationNode node : model.getOrder()) {
- srcCtxt = (TopiaContextImplementor) context.beginTransaction();
+ // start replication of current node
+ doReplicateNode(replicationContext, node);
- if (needTransaction) {
- tx = dstCtxt.beginTransaction();
- } else {
- tx = dstCtxt;
- }
- try {
- doReplicateNode(node, srcCtxt, tx, data, treated);
- } catch (Exception e) {
+ // node was sucessfull replicated, mark it
+ replicationContext.addTreatedNode(node);
+ }
+ } catch (Exception e) {
- // un erreur est survenu sur le noeud de réplication
- // on rollback la transaction de ce noeud
- try {
- tx.rollbackTransaction();
- } finally {
+ // an error occurs, rollback all sucessfull replicated nodes.
+ doRollback(replicationContext);
- // on revert les noeuds deja commite
- doRollback(model, data, treated, dstCtxt);
- }
-
- throw e;
- } finally {
- srcCtxt.closeContext();
- if (needTransaction) {
- // on doit fermer la transaction car on l'a ouverte dans
- // cette méthode, sinon c'est de la responsabilite du
- // code appellant
- tx.closeContext();
- }
- }
- }
-// } catch (Exception e) {
-// dstCtxt.rollbackTransaction();
-// throw e;
+ // then throw the original error
+ throw e;
} finally {
- if (data != null) {
- data.clear();
- }
- if (treated != null) {
- treated.clear();
- }
- // on ne doit jamais commiter sur la base source
- if (srcCtxt != null && !srcCtxt.isClosed()) {
- srcCtxt.rollbackTransaction();
- srcCtxt.closeContext();
- }
-// dstCtxt.closeContext();
+ replicationContext.clear();
}
}
@Override
- public void doRollback(ReplicationModel model,
- TopiaEntityIdsMap data,
- List<ReplicationNode> nodes,
- TopiaContext dstCtxt) throws Exception {
- if (nodes.isEmpty()) {
+ public void doRollback(TopiaReplicationContext replicationContext) throws Exception {
+ TopiaEntityHelper.checkNotNull("doRollback", "replicationContext", replicationContext);
+
+ ReplicationNode[] treated = replicationContext.getReverseTreated();
+
+ if (treated.length == 0) {
+
// aucun noeud de réplication commités
return;
}
- TopiaContextImplementor srcCtxt;
+ log.info("Will rollback " + treated.length + " nodes...");
- TopiaContext tx;
+ for (ReplicationNode node : treated) {
- boolean needTransaction = true;
-
- log.info("Will rollback " + nodes.size() + " nodes...");
-
- for (ReplicationNode node : nodes) {
-
- log.info("Rollback node " + node);
- srcCtxt = (TopiaContextImplementor) context.beginTransaction();
-
- if (needTransaction) {
- tx = dstCtxt.beginTransaction();
- } else {
- tx = dstCtxt;
- }
try {
- doRollbackNode(node, srcCtxt, tx, data);
+ doRollbackNode(replicationContext, node);
} catch (Exception e) {
- // un erreur est survenu sur le noeud de réplication
- // on rollback la transaction de ce noeud
+ log.error("Could not rollback node " + node, e);
- tx.rollbackTransaction();
-
- } finally {
- srcCtxt.rollbackTransaction();
- srcCtxt.closeContext();
-
- if (needTransaction) {
- // on doit fermer la transaction car on l'a ouverte dans
- // cette méthode, sinon c'est de la responsabilite du
- // code appellant
- tx.closeContext();
- }
+ //tchemit 2010-08-17 perharps we should not throw the exception
+ // and try to rollback other nodes ?
+ throw e;
}
-
}
}
- @Override
- public TopiaReplicationModelBuilder getModelBuilder() {
- if (modelBuilder == null) {
- modelBuilder = new TopiaReplicationModelBuilderImpl();
- }
- return modelBuilder;
- }
+ public void doReplicateNode(TopiaReplicationContext replicationContext,
+ ReplicationNode node) throws Exception {
- //--------------------------------------------------------------------------
- //-- TopiaReplicationImplementor implementation ----------------------------
- //--------------------------------------------------------------------------
+ ReplicationOperationDef[] defs = node.getOperations();
-// @Override
-// public ReplicationModel createModel(TopiaEntityEnum[] contracts,
-// String... topiaIds)
-// throws TopiaException {
-//
-// Set<Class<? extends TopiaEntity>> detectTypes =
-// detectTypes(contracts, topiaIds);
-// ReplicationModel model =
-// new ReplicationModel(contracts, detectTypes, topiaIds);
-// return model;
-// }
-//
-// @Override
-// public ReplicationModel createModelWithComputedOrder(
-// TopiaEntityEnum[] contracts, String... topiaIds)
-// throws TopiaException {
-// ReplicationModel model =
-// new ReplicationModel(contracts, false, topiaIds);
-// return model;
-// }
-//
-// @Override
-// public ReplicationModel createModelForAll(TopiaEntityEnum[] contracts)
-// throws TopiaException {
-// ReplicationModel model = new ReplicationModel(contracts, true);
-// return model;
-// }
-//
-// @Override
-// public ReplicationModel initModel(ReplicationModel model,
-// boolean computeOrder)
-// throws TopiaException {
-// checkNotNull("initModel", "model", model);
-//
-// model.detectAssociations();
-// model.detectDirectDependencies();
-// if (computeOrder) {
-// model.detectShell();
-// model.detectDependencies();
-// }
-// model.detectObjectsToDettach();
-// model.detectOperations();
-// return model;
-// }
-//
-// @Override
-// public TopiaReplicationOperation getOperation(
-// Class<? extends TopiaReplicationOperation> operationClass) {
-// checkNotNull("getOperation", "operationClass", operationClass);
-//
-// if (operations == null) {
-// throw new IllegalStateException("service was not init!");
-// }
-// TopiaReplicationOperation result = null;
-//
-// for (TopiaReplicationOperation op : operations) {
-// if (operationClass.isAssignableFrom(op.getClass())) {
-// result = op;
-// break;
-// }
-// }
-// return result;
-// }
-//
-// @Override
-// public void createOperation(ReplicationModel model,
-// TopiaEntityEnum type,
-// ReplicationOperationPhase phase,
-// Class<? extends TopiaReplicationOperation> operationClass,
-// Object... parameters) {
-//
-// checkNotNull("createOperation", "model", model);
-// checkNotNull("createOperation", "type", type);
-// checkNotNull("createOperation", "phase", phase);
-// checkNotNull("createOperation", "operationClass", operationClass);
-//
-// TopiaReplicationOperation operation = getOperation(operationClass);
-//
-// if (operation == null) {
-// throw new IllegalArgumentException(
-// _("topia.replication.engine.error.unkown.operation",
-// operationClass.getSimpleName(),
-// Arrays.toString(operations))
-// );
-// }
-//
-// ReplicationNode node = model.getNode(type);
-// if (node == null) {
-// throw new IllegalArgumentException(
-// _("topia.replication.engine.error.unkown.owner.node",
-// type,
-// operationClass.getSimpleName(),
-// model.getNodes())
-// );
-// }
-// operation.register(model, node, phase, parameters);
-// }
-
-// @Override
-
- public TopiaEntityIdsMap getIds(ReplicationModel model,
- TopiaContextImplementor srcCtxt)
- throws TopiaException {
-
- TopiaEntityIdsMap data;
-
- // on recupere les objets a repliquer par type
- if (model.isReplicateAll()) {
-
- // on recupere pour chaque type tous les ids des entites a repliquer
- data = new TopiaEntityIdsMap();
- for (TopiaEntityEnum e : model.getContracts()) {
- List<String> ids = srcCtxt.getDAO(e.getContract()).findAllIds();
- data.put(e.getContract(), ids);
- }
- } else {
-
- // on recupere les entites specifies a repliquer
- TopiaEntity[] entities = TopiaEntityHelper.getEntities(srcCtxt,
- model.getTopiaIds()
- );
-
- // on calcule toutes les ids des entites a repliquer
- data = TopiaEntityHelper.detectEntityIds(model.getContracts(),
- model.getTypes(),
- entities
- );
+ if (defs.length == 0) {
+ log.info("skip node " + node + " - no operation detected.");
+ return;
}
- return data;
- }
-// protected void checkServiceIsInit() {
-// if (modelBuilder == null) {
-// throw new IllegalStateException("service was not init!");
-// }
-// }
+ // destination transaction will be opened at the last moment to avoid
+ // to open it if something was wrong before...
+ TopiaContextImplementor dstCtxt = null;
-// @Override
+ // open transaction on source db (to obtain entities to treate).
+ // this transaction must stay open the time of all operations of the
+ // node in order to make lazy association loaded by hibernate
+ TopiaContextImplementor srcCtxt = replicationContext.newSourceTx();
- public void doReplicateNode(
- ReplicationNode node,
- TopiaContext srcCtxt,
- TopiaContext dstCtxt,
- TopiaEntityIdsMap data,
- List<ReplicationNode> treated) throws Exception {
-
- // on trie toujours les operations a realiser selon leur phase
- // (avant ou apres la duplication)
- node.sortOperations();
-
- List<ReplicationOperationDef> operationDefs = node.getOperations();
-
- if (operationDefs.isEmpty()) {
- log.info("skip node " + node + " - no operation detected.");
- } else {
-
- log.info("start for " + node + " : " + operationDefs.size() +
+ try {
+ log.info("start replication for " + node + " : " + defs.length +
" operation(s)");
- List<String> nodeEntityIds =
- data.get(node.getContract().getContract());
+ // get from source db the entities to treate for this node
+ List<? extends TopiaEntity> entities =
+ replicationContext.getEntities(srcCtxt, node);
if (log.isInfoEnabled()) {
- log.info("will replicate on " + nodeEntityIds.size() +
+ log.info("will replicate on " + entities.size() +
" entity(ies)");
}
if (log.isDebugEnabled()) {
- for (String id : nodeEntityIds) {
- log.debug(id);
+ for (TopiaEntity entity : entities) {
+ log.debug(entity.getTopiaId());
}
}
- List<? extends TopiaEntity> nodeEntities = TopiaEntityHelper.getEntitiesList(
- srcCtxt,
- nodeEntityIds.toArray(new String[nodeEntityIds.size()])
- );
+ // open transaction on target db (the transaction is common to all
+ // operations of the node). Each operation must do his own commit
+ // if needed
+ dstCtxt = replicationContext.newTargetTx();
- for (ReplicationOperationDef operationDef : operationDefs) {
+ for (ReplicationOperationDef def : defs) {
- log.info("start " + operationDef);
+ log.info("start operation " + def);
TopiaReplicationOperation operation =
- getModelBuilder().getOperation(operationDef.getOperationClass());
+ replicationContext.getOperation(def);
- operation.run(operationDef,
- (TopiaContextImplementor) srcCtxt,
- (TopiaContextImplementor) dstCtxt,
- nodeEntities,
- data
+ operation.run(replicationContext,
+ def,
+ srcCtxt,
+ dstCtxt,
+ entities
);
+ }
+ } finally {
+
+ try {
+ // on rollback le context source (car on a peut-etre modifie
+ // des associations ou des dependances mais on ne veut rien
+ // retenir au niveau d'hibernate, sinon on s'expose a des erreurs
+ // lorsque l'on veut recharger des objets dans le context...)
+ TopiaReplicationContext.close(srcCtxt, true);
+ } finally {
+ if (dstCtxt != null) {
+ // on ferme la transaction sur la base destination
+ // on rollback toujours la transaction, ainsi si une erreur
+ // est survenue la session reste dans un état cohérent.
+ // De plus si les actions n'ont pas fait de commit, la
+ // session reste aussi dans un état incohérent. Le commit
+ // reste toujours à la charge de l'opération
+ TopiaReplicationContext.close(dstCtxt, true);
+ }
}
- // on rollback le context source (car on a peut-etre modifie
- // des associations ou des dependances mais on ne veut rien
- // retenir au niveau d'hibernate, sinon on s'expose a des erreurs
- // lorsque l'on veut recharger des objets dans le context...)
- srcCtxt.rollbackTransaction();
}
-
- treated.add(node);
}
+ public void doRollbackNode(TopiaReplicationContext replicationContext,
+ ReplicationNode node) throws Exception {
-// @Override
+ // recuperation des operations reversibles
+ ReplicationOperationDef[] defs = node.getUndoableOperations();
- public void doRollbackNode(
- ReplicationNode node,
- TopiaContext srcCtxt,
- TopiaContext dstCtxt,
- TopiaEntityIdsMap data) throws Exception {
+ if (defs.length == 0) {
- // on trie toujours les operations a realiser selon leur phase
- // (avant ou apres la duplication)
- node.sortOperations();
+ // pas d'operation reversible, donc rien a faire sur ce noeud.
+ log.info("skip node " + node + " - no reversible operation detected.");
+ return;
+ }
- List<ReplicationOperationDef> operationDefs = node.getOperations();
+ log.info("start rollback for " + node + " : " + defs.length +
+ " reversible operation(s)");
- if (operationDefs.isEmpty()) {
- log.info("skip node " + node + " - no operation detected.");
- } else {
+ // open transaction on target db
+ TopiaContextImplementor dstCtxt = replicationContext.newTargetTx();
- log.info("start for " + node + " : " + operationDefs.size() +
- " operation(s)");
+ try {
- List<String> nodeEntityIds =
- data.get(node.getContract().getContract());
- if (log.isInfoEnabled()) {
- log.info("will replicate on " + nodeEntityIds.size() +
- " entity(ies)");
- }
- if (log.isDebugEnabled()) {
- for (String id : nodeEntityIds) {
- log.debug(id);
- }
- }
+ for (ReplicationOperationDef def : defs) {
- List<? extends TopiaEntity> nodeEntities = TopiaEntityHelper.getEntitiesList(
- srcCtxt,
- nodeEntityIds.toArray(new String[nodeEntityIds.size()])
- );
+ log.info("start rollback operation " + def);
- for (ReplicationOperationDef operationDef : operationDefs) {
-
- log.info("start " + operationDef);
-
- TopiaReplicationOperation operation =
- getModelBuilder().getOperation(operationDef.getOperationClass());
-
- operation.rollback(operationDef,
- (TopiaContextImplementor) srcCtxt,
- (TopiaContextImplementor) dstCtxt,
- nodeEntities,
- data
- );
-
+ TopiaReplicationOperationUndoable operation =
+ replicationContext.getUndoableOperation(def);
+ operation.rollback(def, replicationContext, dstCtxt);
}
- // on rollback le context source (car on a peut-etre modifie
- // des associations ou des dependances mais on ne veut rien
- // retenir au niveau d'hibernate, sinon on s'expose a des erreurs
- // lorsque l'on veut recharger des objets dans le context...)
- srcCtxt.rollbackTransaction();
+ } finally {
+ if (dstCtxt != null) {
+ // on ferme la transaction sur la base destination
+ // on rollback toujours la transaction, ainsi si une erreur
+ // est survenue la session reste dans un état cohérent.
+ // De plus si les actions n'ont pas fait de commit, la
+ // session reste aussi dans un état incohérent. Le commit
+ // reste toujours à la charge de l'opération
+ TopiaReplicationContext.close(dstCtxt, true);
+ }
}
}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationLink.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationLink.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationLink.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -98,7 +98,7 @@
*
* @param universe l'univers des noeuds disponibles
* @param currentNode le noeud qui vient d'etre replique
- * @return <code>true</code> si on peut reattacher ce lien
+ * @return {@code true} si on peut reattacher ce lien
*/
public boolean canReattach(Set<ReplicationNode> universe,
ReplicationNode currentNode) {
@@ -111,6 +111,7 @@
@Override
public String toString() {
- return "<source:" + source + ", target:" + target + ", name:" + name + ", association:" + association + ">";
+ return "<source:" + source + ", target:" + target + ", name:" + name +
+ ", association:" + association + ">";
}
}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationModel.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationModel.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationModel.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -25,6 +25,7 @@
package org.nuiton.topia.replication.model;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.topia.TopiaException;
@@ -44,14 +45,20 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/**
- * Model of a replication operation.
+ * Model of replication.
+ * <p/>
+ * the object contains the required {@link #nodes} to replicate :
+ * <ul>
+ * <li>all entities for the given {@code nodes} if flag {@link #replicateAll} is
+ * setted to {@code true}</li>
+ * <li>the entities given by the field {@link #topiaIds}</li>
+ * </ul>
*
* @author tchemit <chemit(a)codelutin.com>
* @since 2.2.0
@@ -62,55 +69,69 @@
private static final Log log = LogFactory.getLog(ReplicationModel.class);
/** l'ensemble des contrats d'entites a repliquer */
- final protected TopiaEntityEnum[] contracts;
+ protected final TopiaEntityEnum[] contracts;
/** les ids des entites a repliquer (non utilise en mode replicateAll) */
- final protected String[] topiaIds;
+ protected final String[] topiaIds;
/** le dictionnaire des noeuds a repliquer associes a leur type */
- protected Map<Class<? extends TopiaEntity>, ReplicationNode> nodes;
+ protected final Map<TopiaEntityEnum, ReplicationNode> nodes;
/** la liste des noeuds a repliquer (dans l'ordre de replication) */
- protected List<ReplicationNode> order;
+ protected final List<ReplicationNode> order;
/**
- * un drapeau pour savoir si on effectue une replication de toutes les donnees
- * des contrats.
+ * un drapeau pour savoir si on effectue une replication de toutes les
+ * donnees des contrats.
*/
- final protected boolean replicateAll;
+ protected final boolean replicateAll;
- public ReplicationModel(TopiaEntityEnum[] contracts, Set<Class<? extends TopiaEntity>> types, String... topiaIds) {
+ public ReplicationModel(TopiaEntityEnum[] contracts,
+ Set<Class<? extends TopiaEntity>> types,
+ String... topiaIds) {
this.contracts = contracts;
this.topiaIds = topiaIds;
replicateAll = false;
- nodes = new LinkedHashMap<Class<? extends TopiaEntity>, ReplicationNode>();
order = new ArrayList<ReplicationNode>();
- Map<Class<? extends TopiaEntity>, ReplicationNode> tmpNodes = new HashMap<Class<? extends TopiaEntity>, ReplicationNode>();
+ Map<TopiaEntityEnum, ReplicationNode> tmpNodes =
+ new HashMap<TopiaEntityEnum, ReplicationNode>();
for (Class<? extends TopiaEntity> k : types) {
- TopiaEntityEnum e = TopiaEntityHelper.getEntityEnum(k, contracts);
+ TopiaEntityEnum e = getContract(k);
ReplicationNode replicationNode = new ReplicationNode(e);
- tmpNodes.put(k, replicationNode);
+ tmpNodes.put(e, replicationNode);
}
nodes = Collections.unmodifiableMap(tmpNodes);
}
- public ReplicationModel(TopiaEntityEnum[] contracts, boolean replicateAll, String... topiaIds) {
+ public ReplicationModel(TopiaEntityEnum[] contracts,
+ boolean replicateAll,
+ String... topiaIds) {
this.contracts = contracts;
this.topiaIds = topiaIds;
this.replicateAll = replicateAll;
- nodes = new LinkedHashMap<Class<? extends TopiaEntity>, ReplicationNode>();
order = new ArrayList<ReplicationNode>();
- Map<Class<? extends TopiaEntity>, ReplicationNode> tmpNodes = new HashMap<Class<? extends TopiaEntity>, ReplicationNode>();
+ Map<TopiaEntityEnum, ReplicationNode> tmpNodes =
+ new HashMap<TopiaEntityEnum, ReplicationNode>();
for (TopiaEntityEnum e : contracts) {
ReplicationNode replicationNode = new ReplicationNode(e);
- tmpNodes.put(e.getContract(), replicationNode);
+ tmpNodes.put(e, replicationNode);
if (!replicateAll) {
- // mode restreint : l'ordre est induit par l'ordre sur les contrats passes
+ // mode restreint : l'ordre est induit par l'ordre sur les
+ // contrats passes
order.add(replicationNode);
}
}
nodes = Collections.unmodifiableMap(tmpNodes);
+ }
+ @SuppressWarnings({"unchecked"})
+ public TopiaEntityEnum getContract(Class<?> type) {
+ TopiaEntityEnum e = null;
+ if (TopiaEntity.class.isAssignableFrom(type)) {
+ e = TopiaEntityHelper.getEntityEnum(
+ (Class<? extends TopiaEntity>) type, contracts);
+ }
+ return e;
}
public Collection<ReplicationNode> getNodes() {
@@ -118,19 +139,30 @@
}
public Set<Class<? extends TopiaEntity>> getTypes() {
- return nodes.keySet();
+ Set<Class<? extends TopiaEntity>> result =
+ new HashSet<Class<? extends TopiaEntity>>();
+ for (TopiaEntityEnum e : nodes.keySet()) {
+ result.add(e.getContract());
+ }
+ return result;
}
- public ReplicationNode getNode(Class<? extends TopiaEntity> clazz) {
- return nodes.get(clazz);
- }
-
public ReplicationNode getNode(TopiaEntityEnum contract) {
- return nodes.get(contract.getContract());
+ return nodes.get(contract);
}
public void addDependency(List<ReplicationNode> nodes) {
- order.addAll(nodes);
+ if (log.isDebugEnabled()) {
+ log.debug("Try to add nodes : " + nodes + " in universe : " + order);
+ }
+ for (ReplicationNode node : nodes) {
+ if (order.contains(node)) {
+ // can not be done
+ throw new IllegalStateException(
+ "Node " + node + " is already registred : " + order);
+ }
+ order.add(node);
+ }
}
public TopiaEntityEnum[] getContracts() {
@@ -152,11 +184,11 @@
@SuppressWarnings("unchecked")
public ReplicationNode getNode(String propertyName, Class<?> propertyType) {
if (TopiaEntity.class.isAssignableFrom(propertyType)) {
- //TODO on devrait repasser par le contracts pour etre sur d'etre
- //TODO sur d'etre sur une interface d'entite ?
- Class<? extends TopiaEntity> t = (Class<? extends TopiaEntity>) propertyType;
- if (nodes.containsKey(t)) {
- ReplicationNode dep = getNode(t);
+ Class<? extends TopiaEntity> t =
+ (Class<? extends TopiaEntity>) propertyType;
+ TopiaEntityEnum e = getContract(t);
+ if (nodes.containsKey(e)) {
+ ReplicationNode dep = getNode(e);
return dep;
}
}
@@ -164,17 +196,23 @@
}
public void detectAssociations(TopiaEntityEnum... filter) throws TopiaException {
- for (Class<? extends TopiaEntity> type : nodes.keySet()) {
+ for (TopiaEntityEnum type : nodes.keySet()) {
ReplicationNode node = getNode(type);
EntityOperator<? super TopiaEntity> operator = node.getOperator();
- List<String> associationProperties = operator.getAssociationProperties();
+ List<String> associationProperties =
+ operator.getAssociationProperties();
if (!associationProperties.isEmpty()) {
for (String p : associationProperties) {
- ReplicationNode dep = getNode(p, operator.getAssociationPropertyType(p));
+ ReplicationNode dep = getNode(
+ p,
+ operator.getAssociationPropertyType(p)
+ );
if (dep != null) {
if (log.isDebugEnabled()) {
- log.debug("from type - " + type.getSimpleName() + " [" + p + ":" + dep + "]");
+ log.debug("from type - " +
+ type.getContract().getSimpleName() +
+ " [" + p + ":" + dep + "]");
}
node.addAssociation(p, dep);
}
@@ -184,16 +222,19 @@
}
public void detectDirectDependencies() throws TopiaException {
- for (Class<? extends TopiaEntity> type : nodes.keySet()) {
+ for (TopiaEntityEnum type : nodes.keySet()) {
ReplicationNode node = getNode(type);
EntityOperator<? super TopiaEntity> operator = node.getOperator();
List<String> properties = operator.getProperties();
if (!properties.isEmpty()) {
for (String p : properties) {
- ReplicationNode dep = getNode(p, operator.getPropertyType(p));
+ ReplicationNode dep =
+ getNode(p, operator.getPropertyType(p));
if (dep != null) {
if (log.isDebugEnabled()) {
- log.debug("from type - " + type.getSimpleName() + " [" + p + ":" + dep + "]");
+ log.debug("from type - " +
+ type.getContract().getSimpleName() +
+ " [" + p + ":" + dep + "]");
}
node.addDependency(p, dep);
}
@@ -203,18 +244,21 @@
}
public void detectDependencies() throws TopiaException {
- Set<ReplicationNode> toResolved = new HashSet<ReplicationNode>(nodes.values());
+ Set<ReplicationNode> toResolved =
+ new HashSet<ReplicationNode>(nodes.values());
Set<ReplicationNode> resolved = new HashSet<ReplicationNode>();
- List<Set<ReplicationNode>> levels = new ArrayList<Set<ReplicationNode>>();
+ List<Set<ReplicationNode>> levels =
+ new ArrayList<Set<ReplicationNode>>();
+
// premiere passe pour detecter les niveaux de replications
- // on ne regarde que les dependences directe et pas les associations
+ // on ne regarde que les dependences directes et pas les associations
// si A -> B alors B doit etre dans un niveau inferieure (i.e replique
// avant).
//TODO Il faut pouvoir gerer les cycles (pour cela on doit avoir
- // un dictionnaire pour les compositions qui peuvent etre nulle
- // ainsi on doit etre capable de ne pas tenir compte d'une composition
- // si c'est nullable, sinon cela veut dire obligatoirement
- // que B doit etre replique avant A...
+ //TODO un dictionnaire pour les compositions qui peuvent etre nulle
+ //TODO ainsi on doit etre capable de ne pas tenir compte d'une composition
+ //TODO si c'est nullable, sinon cela veut dire obligatoirement
+ //TODO que B doit etre replique avant A...
while (!toResolved.isEmpty()) {
Set<ReplicationNode> level = new HashSet<ReplicationNode>();
for (ReplicationNode node : toResolved) {
@@ -237,20 +281,26 @@
}
if (safeLevel.isEmpty()) {
// on a detecte un cycle sur les dependences, on ne peut rien faire pour le moment
- throw new IllegalStateException("un cycle dans les dependences a été détecté, l\'algorithme necessite plus de donnes... \n niveau courant : " + level + "\n resolus : " + getOrder());
+ throw new IllegalStateException(
+ "un cycle dans les dependences a été détecté, " +
+ "l\'algorithme necessite plus de donnes... " +
+ "\n niveau courant : " + level + "\n resolus : " +
+ getOrder());
}
}
if (log.isDebugEnabled()) {
- log.debug("level [" + levels.size() + "] resolved : " + safeLevel);
+ log.debug("level [" + levels.size() + "] resolved : " +
+ safeLevel);
}
toResolved.removeAll(safeLevel);
resolved.addAll(safeLevel);
levels.add(safeLevel);
level.clear();
}
+
// seconde passe : on recherche le meilleur ordre possible pour
// les types de chaque niveau
- // on ne base desormais que sur les associations
+ // on se base desormais que sur les associations
// si A -*> B alors on va essayer de repliquer B avant A
// si on detecte un cycle alors on ne peut pas imposer un ordre optimal
// et on devra dettacher B de A pendant la replication puis reattacher B
@@ -258,7 +308,7 @@
// l'ordre optimal permet de ne pas effectuer
// calcul des ordres de replications pour les ensembles de chaque niveau
// pour trouver le bon ordre, on travaille sur les couvertures
- // des noeuds.;
+ // des noeuds.
HashSet<ReplicationNode> done = new HashSet<ReplicationNode>();
for (Set<ReplicationNode> level : levels) {
detectDependenciesOrder(level, done);
@@ -281,19 +331,22 @@
}
dico.put(n, shell);
}
- List<Set<ReplicationNode>> levels = new ArrayList<Set<ReplicationNode>>();
+ List<Set<ReplicationNode>> levels =
+ new ArrayList<Set<ReplicationNode>>();
while (!dico.isEmpty()) {
if (log.isDebugEnabled()) {
log.debug("level [" + levels.size() + "] on " + safeLevel);
- for (Entry<ReplicationNode, Set<ReplicationNode>> entry : dico.entrySet()) {
- log.debug("node " + entry.getKey() + " : " + entry.getValue());
+ for (Entry<ReplicationNode, Set<ReplicationNode>> entry :
+ dico.entrySet()) {
+ log.debug("node " + entry.getKey() + " : " +
+ entry.getValue());
}
}
-
// detection des noeud libres
Set<ReplicationNode> free = new HashSet<ReplicationNode>();
- for (Entry<ReplicationNode, Set<ReplicationNode>> e : dico.entrySet()) {
+ for (Entry<ReplicationNode, Set<ReplicationNode>> e :
+ dico.entrySet()) {
if (e.getValue().isEmpty()) {
free.add(e.getKey());
}
@@ -303,13 +356,17 @@
// un cycle a ete detectee
// on ne peut plus rien predire pour cet ensemble
if (log.isWarnEnabled()) {
- log.warn("level [" + levels.size() + "] cycle detecte : " + dico.keySet());
+ log.warn("level [" + levels.size() +
+ "] cycle detecte : " + dico.keySet());
}
- throw new IllegalStateException("un cycle n'a pas pu etre resoud entre l'ensemble " + dico.keySet());
+ throw new IllegalStateException(
+ "un cycle n'a pas pu etre resoud entre l'ensemble " +
+ dico.keySet());
}
log.info("there is some free node(s) to resolve : " + free);
- for (Entry<ReplicationNode, Set<ReplicationNode>> e : dico.entrySet()) {
+ for (Entry<ReplicationNode, Set<ReplicationNode>> e :
+ dico.entrySet()) {
Set<ReplicationNode> list = e.getValue();
list.removeAll(free);
}
@@ -341,11 +398,13 @@
// sortants de l'universe deja replique
// si oui, alors on marque l'association pour un dettachement
if (node.hasAssociation()) {
- for (Entry<String, ReplicationNode> e : node.getAssociations().entrySet()) {
+ for (Entry<String, ReplicationNode> e :
+ node.getAssociations().entrySet()) {
ReplicationNode nodeDst = e.getValue();
if (!universe.contains(nodeDst)) {
if (log.isDebugEnabled()) {
- log.debug("association to dettach " + e.getKey() + " for " + node);
+ log.debug("association to dettach " + e.getKey() +
+ " for " + node);
}
// association sortant
node.addAssociationToDettach(e.getKey());
@@ -356,11 +415,13 @@
//TODO la resolution des conflits sur dependences n'est pas encore
//TODO en place
if (node.hasDependency()) {
- for (Entry<String, ReplicationNode> e : node.getDependencies().entrySet()) {
+ for (Entry<String, ReplicationNode> e :
+ node.getDependencies().entrySet()) {
ReplicationNode nodeDst = e.getValue();
if (!universe.contains(nodeDst)) {
if (log.isDebugEnabled()) {
- log.debug("dependency to dettach " + e.getKey() + " for " + node);
+ log.debug("dependency to dettach " + e.getKey() +
+ " for " + node);
}
// association sortant
node.addDependencyToDettach(e.getKey());
@@ -380,11 +441,13 @@
for (ReplicationNode node : order) {
if (node.hasAssociation()) {
- for (Entry<String, ReplicationNode> entry : node.getAssociations().entrySet()) {
+ for (Entry<String, ReplicationNode> entry :
+ node.getAssociations().entrySet()) {
String name = entry.getKey();
// dans tous les cas, on ajoute un link d'association a reattacher
ReplicationNode target = node.getAssociations().get(name);
- ReplicationLink link = new ReplicationLink(node, target, name, true);
+ ReplicationLink link =
+ new ReplicationLink(node, target, name, true);
if (nodes.containsValue(target)) {
// on a trouve une association que l'on doit gerer
links.add(link);
@@ -394,17 +457,22 @@
} else {
}
}
- List<String> associationProperties = node.getOperator().getAssociationProperties();
+ List<String> associationProperties =
+ node.getOperator().getAssociationProperties();
for (String name : associationProperties) {
Class<?> associationPropertyType = node.getOperator().getAssociationPropertyType(name);
- if (!TopiaEntity.class.isAssignableFrom(associationPropertyType) ||
- !nodes.containsKey(associationPropertyType)) {
+ TopiaEntityEnum contract = getContract(associationPropertyType);
+ if (contract == null || !nodes.containsKey(contract)) {
+// if (!TopiaEntity.class.isAssignableFrom(associationPropertyType) ||
+// !nodes.containsKey(associationPropertyType)) {
- ReplicationLink link = new ReplicationLink(node, null, name, true);
+ ReplicationLink link =
+ new ReplicationLink(node, null, name, true);
linksToLoad.add(link);
if (log.isDebugEnabled()) {
- log.debug("link to load before replication : " + link);
+ log.debug("link to load before replication : " +
+ link);
}
}
}
@@ -421,7 +489,6 @@
Set<String> names = node.getAssociationsToDettach();
// operations de dettachement d'association
for (String name : names) {
-// addOperation(node, node, ReplicationOperationPhase.before, DettachAssociation.class, name);
addPreOperation(node, node, DettachAssociation.class, name);
}
}
@@ -438,15 +505,12 @@
// on a des associations a charger avant replication
for (ReplicationLink link : tmpLinks) {
addPreOperation(node, node, LoadLink.class, link);
-// ReplicationOperationDef op = new ReplicationOperationDef(ReplicationOperationPhase.before, LoadLink.class, node, link);
-// node.addOperation(op);
}
linksToLoad.removeAll(links);
tmpLinks.clear();
}
// operation de duplication
-// addOperation(node, node, ReplicationOperationPhase.duplicate, Duplicate.class);
addDuplicateOperation(node, node, Duplicate.class);
universe.add(node);
@@ -462,8 +526,6 @@
// on a trouve des liens a reattacher
for (ReplicationLink link : tmpLinks) {
addPostOperation(node, node, AttachLink.class, link);
-// ReplicationOperationDef op = new ReplicationOperationDef(ReplicationOperationPhase.after, AttachLink.class, node, link);
-// node.addOperation(op);
}
// ces liens ne sont plus a traiter
links.removeAll(tmpLinks);
@@ -473,22 +535,23 @@
public void adjustOperations(TopiaEntityIdsMap data) {
for (TopiaEntityEnum e : getContracts()) {
- Class<? extends TopiaEntity> contract = e.getContract();
- List<String> ids = data.get(contract);
- ReplicationNode node = getNode(contract);
+ List<String> ids = data.get(e.getContract());
+ ReplicationNode node = getNode(e);
if (node == null) {
// le noeud n'est pas connu (ce n'est pas normal!)
continue;
}
- if (ids == null || ids.isEmpty()) {
- List<ReplicationOperationDef> operations = node.getOperations();
- log.info("skip operations on node " + node + " (no data associated)");
+ if (CollectionUtils.isEmpty(ids)) {
+ ReplicationOperationDef[] operations = node.getOperations();
+ log.info("skip operations on node " + node +
+ " (no data associated)");
for (ReplicationOperationDef op : operations) {
log.info(" skip " + op);
}
- operations.clear();
+ node.clearOperations();
+ } else {
+ node.sortOperations();
}
-
}
}
@@ -501,7 +564,8 @@
}
}
- protected void getShell(ReplicationNode node, Set<ReplicationNode> explored) {
+ protected void getShell(ReplicationNode node,
+ Set<ReplicationNode> explored) {
if (!explored.contains(node)) {
explored.add(node);
}
@@ -525,21 +589,36 @@
ReplicationNode node,
Class<? extends TopiaReplicationOperation> operationClass,
Object... params) {
- addOperation(ownerNode, node, ReplicationOperationPhase.before, operationClass, params);
+ addOperation(ownerNode,
+ node,
+ ReplicationOperationPhase.before,
+ operationClass,
+ params
+ );
}
protected void addDuplicateOperation(ReplicationNode ownerNode,
ReplicationNode node,
Class<? extends TopiaReplicationOperation> operationClass,
Object... params) {
- addOperation(ownerNode, node, ReplicationOperationPhase.duplicate, operationClass, params);
+ addOperation(ownerNode,
+ node,
+ ReplicationOperationPhase.duplicate,
+ operationClass,
+ params
+ );
}
protected void addPostOperation(ReplicationNode ownerNode,
ReplicationNode node,
Class<? extends TopiaReplicationOperation> operationClass,
Object... params) {
- addOperation(ownerNode, node, ReplicationOperationPhase.after, operationClass, params);
+ addOperation(ownerNode,
+ node,
+ ReplicationOperationPhase.after,
+ operationClass,
+ params
+ );
}
protected void addOperation(ReplicationNode ownerNode,
@@ -547,7 +626,9 @@
ReplicationOperationPhase phase,
Class<? extends TopiaReplicationOperation> operationClass,
Object... params) {
- ReplicationOperationDef op = new ReplicationOperationDef(phase, operationClass, node, params);
+
+ ReplicationOperationDef op;
+ op = new ReplicationOperationDef(phase, operationClass, node, params);
ownerNode.addOperation(op);
}
}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationNode.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationNode.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationNode.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -31,10 +31,10 @@
import org.nuiton.topia.persistence.TopiaEntityEnum;
import org.nuiton.topia.persistence.util.EntityOperator;
import org.nuiton.topia.persistence.util.EntityOperatorStore;
+import org.nuiton.topia.replication.TopiaReplicationOperationUndoable;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -56,34 +56,34 @@
private static final Log log = LogFactory.getLog(ReplicationNode.class);
/** contract of entity of the node. */
- final TopiaEntityEnum contract;
+ protected final TopiaEntityEnum contract;
/** entity operator. */
- final EntityOperator<? super TopiaEntity> operator;
+ protected final EntityOperator<? super TopiaEntity> operator;
/** shell of the node. */
- Set<ReplicationNode> shell;
+ protected Set<ReplicationNode> shell;
/**
* dictionnary of associations defined on the node (keys are association
* name, and values are target node).
*/
- Map<String, ReplicationNode> associations;
+ protected final Map<String, ReplicationNode> associations;
/** names of association to dettach while replication. */
- Set<String> associationsToDettach;
+ protected final Set<String> associationsToDettach;
/**
* compositions defined on the node (keys are association name,
* and values are target node).
*/
- Map<String, ReplicationNode> dependencies;
+ protected final Map<String, ReplicationNode> dependencies;
/** names of dependency to dettach while replication. */
- Set<String> dependenciesToDettach;
+ protected final Set<String> dependenciesToDettach;
/** operations to fire when replication pass on this node. */
- List<ReplicationOperationDef> operations;
+ protected final List<ReplicationOperationDef> operations;
public ReplicationNode(TopiaEntityEnum contract) {
this.contract = contract;
@@ -117,10 +117,23 @@
}
}
- public List<ReplicationOperationDef> getOperations() {
- return operations;
+ public ReplicationOperationDef[] getOperations() {
+ return operations.toArray(
+ new ReplicationOperationDef[operations.size()]);
}
+ public ReplicationOperationDef[] getUndoableOperations() {
+ List<ReplicationOperationDef> result =
+ new ArrayList<ReplicationOperationDef>();
+ for (ReplicationOperationDef operation : operations) {
+ if (TopiaReplicationOperationUndoable.class.isAssignableFrom(
+ operation.getOperationClass())) {
+ result.add(operation);
+ }
+ }
+ return result.toArray(new ReplicationOperationDef[result.size()]);
+ }
+
public boolean hasAssociation() {
return !associations.isEmpty();
}
@@ -187,6 +200,10 @@
return contract;
}
+ public Class<? extends TopiaEntity> getEntityType() {
+ return contract.getContract();
+ }
+
public EntityOperator<? super TopiaEntity> getOperator() {
return operator;
}
@@ -204,15 +221,22 @@
}
/**
- * Les operations sont triees sur leur phase.
+ * sort operation by their phase.
*
* @see ReplicationOperationPhase
- * @see ReplicationNode#OPERATION_COMPARATOR
*/
public void sortOperations() {
- Collections.sort(operations, OPERATION_COMPARATOR);
+ Collections.sort(operations);
}
+ /**
+ * Remove all operation of the node (for example when no data is associated
+ * with the type of the node, then no needed operations).
+ */
+ public void clearOperations() {
+ operations.clear();
+ }
+
@Override
public boolean equals(Object obj) {
if (obj == null) {
@@ -236,20 +260,4 @@
public String toString() {
return contract.toString();
}
-
- /**
- * {@link ReplicationOperationDef} comparator based on operation's phase.
- *
- * @see ReplicationOperationDef#getPhase()
- */
- public static final Comparator<ReplicationOperationDef>
- OPERATION_COMPARATOR = new Comparator<ReplicationOperationDef>() {
-
- @Override
- public int compare(ReplicationOperationDef o1,
- ReplicationOperationDef o2) {
- int result = o1.getPhase().compareTo(o2.getPhase());
- return result;
- }
- };
}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationOperationDef.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationOperationDef.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationOperationDef.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -25,6 +25,8 @@
package org.nuiton.topia.replication.model;
+import org.nuiton.topia.persistence.TopiaEntity;
+import org.nuiton.topia.persistence.TopiaEntityEnum;
import org.nuiton.topia.replication.TopiaReplicationOperation;
import java.util.Arrays;
@@ -42,21 +44,23 @@
* <p/>
* This definition is detected when building replication model.
* <p/>
- * Then when starting replication, base on this definition, we can build the
- * operation to fire.
+ * Then when starting replication, based on this definition, we can instanciate
+ * the operation to execute.
+ * <p/>
+ * <b>Note:</b> Such objects can be comparable via their {@link #phase}.
*
* @author tchemit <chemit(a)codelutin.com>
* @since 2.2.0
*/
-public class ReplicationOperationDef {
+public class ReplicationOperationDef implements Comparable<ReplicationOperationDef> {
- final ReplicationOperationPhase phase;
+ protected final ReplicationOperationPhase phase;
- final Class<? extends TopiaReplicationOperation> operationClass;
+ protected final Class<? extends TopiaReplicationOperation> operationClass;
- final ReplicationNode node;
+ protected final ReplicationNode node;
- final Object[] parameters;
+ protected final Object[] parameters;
public ReplicationOperationDef(
ReplicationOperationPhase phase,
@@ -85,10 +89,44 @@
return phase;
}
+ public TopiaEntityEnum getContract() {
+ return node.getContract();
+ }
+
+ public Class<? extends TopiaEntity> getEntityType() {
+ return node.getEntityType();
+ }
+
@Override
public String toString() {
return " <" + operationClass.getSimpleName() + " on " + node +
(parameters.length == 0 ? "" :
", params:" + Arrays.toString(parameters)) + ">";
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ReplicationOperationDef that = (ReplicationOperationDef) o;
+
+ if (!node.equals(that.node)) return false;
+ if (!operationClass.equals(that.operationClass)) return false;
+ return phase == that.phase;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = phase.hashCode();
+ result = 31 * result + operationClass.hashCode();
+ result = 31 * result + node.hashCode();
+ return result;
+ }
+
+ @Override
+ public int compareTo(ReplicationOperationDef o) {
+ int result = getPhase().compareTo(o.getPhase());
+ return result;
+ }
}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachAssociation.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachAssociation.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachAssociation.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -32,7 +32,7 @@
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.persistence.util.EntityOperator;
import org.nuiton.topia.persistence.util.TopiaEntityHelper;
-import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
+import org.nuiton.topia.replication.TopiaReplicationContext;
import org.nuiton.topia.replication.TopiaReplicationOperation;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
@@ -48,18 +48,28 @@
/**
* Pour attacher une association.
* <p/>
+ * L'opération requière 2 ou 3 paramètres :
+ * <ul>
+ * <li>{@code parameters[0]} : le nom de l'association à traiter</li>
+ * <li>{@code parameters[1]} : un drapeau pour savoir si on est sur le reverse
+ * de l'association</li>
+ * <li>{@code parameters[2]} : le noeud source de l'association
+ * (uniquement utilisé si on est sur le reverse d'une association)</li>
+ * </ul>
+ * <p/>
* Deux cas peuvent se produire :
* <p/>
* - le noeud de l'operation est la source de l'association, dans ce cas la
- * <code>nodeEntities</code> contient les entites sources de l'association et on
+ * {@code entities} contient les entites sources de l'association et on
* retrouve les entites associes a partir du type de l'association
* <p/>
- * Ce premier cas est verifie quand reverse (le econd parametre) est a false
+ * Ce premier cas est verifie quand {@code reverse} (le second parametre) est
+ * à {@code false}.
* <p/>
* - le noeud de l'operation est la cible de l'association, dans ce cas la
- * <code>nodeEntities</code> contient les entities associes (cibles) de
+ * {@code entities} contient les entities associées (cibles) de
* l'assocation et on retrouve les entities a partir d'un troisieme parametre
- * qui donne le node source des entities sources.
+ * qui donne le node source de l'association.
* <p/>
* Note : cette operation est interne, et n'est pas creable par l'utilisateur
* via la methode {@link #register(ReplicationModel, ReplicationNode,
@@ -80,22 +90,22 @@
Object... parameters) {
throw new UnsupportedOperationException(
- _("topia.replication.operation.error.uncreatable", getClass()));
+ _("topia.replication.error.operation.uncreatable", getClass()));
}
@Override
- public void run(ReplicationOperationDef operationDef,
+ public void run(TopiaReplicationContext replicationContext,
+ ReplicationOperationDef operationDef,
TopiaContextImplementor srcCtxt,
TopiaContextImplementor dstCtxt,
- List<? extends TopiaEntity> nodeEntities,
- TopiaEntityIdsMap data) throws TopiaException {
+ List<? extends TopiaEntity> entities) throws TopiaException {
String name = (String) operationDef.getParameters()[0];
Boolean reverse = (Boolean) operationDef.getParameters()[1];
if (log.isDebugEnabled()) {
log.debug("currentNode : " + operationDef.getNode() +
- " , association name : " + name + " reverse ? " + reverse);
+ ", association name : " + name + " reverse ? " + reverse);
}
ReplicationNode ownerNode;
@@ -120,8 +130,8 @@
cibleNode = operationDef.getNode();
- ownerIds = TopiaEntityHelper.getTopiaIdList(nodeEntities);
- associationsId = data.get(cibleNode.getContract().getContract());
+ ownerIds = TopiaEntityHelper.getTopiaIdList(entities);
+ associationsId = replicationContext.getEntityIds(cibleNode);
} else {
@@ -135,8 +145,8 @@
cibleNode = ownerNode.getAssociations().get(name);
- ownerIds = data.get(ownerOperator.getClazz());
- associationsId = TopiaEntityHelper.getTopiaIdList(nodeEntities);
+ ownerIds = replicationContext.getEntityIds(cibleNode);
+ associationsId = TopiaEntityHelper.getTopiaIdList(entities);
}
if (ownerIds == null || ownerIds.isEmpty()) {
@@ -160,7 +170,6 @@
boolean shouldCommit = false;
-
if (log.isInfoEnabled()) {
log.info("ownerNode : " + ownerNode + " , targetNode : " +
cibleNode + ", association : " + name);
@@ -173,11 +182,13 @@
for (TopiaEntity src : ownerEntities) {
// les association cibles connues pour l'entite sur la base source
- Collection<?> targetEntities = (Collection<?>) ownerOperator.get(name, src);
+ Collection<?> targetEntities =
+ (Collection<?>) ownerOperator.get(name, src);
if (targetEntities == null || targetEntities.isEmpty()) {
if (log.isDebugEnabled()) {
- log.debug("no association '" + name + "' attached to " + src);
+ log.debug("no association '" + name + "' attached to " +
+ src);
}
// pas de donnees dans l'association
continue;
@@ -191,7 +202,8 @@
TopiaEntity dst = dstCtxt.findByTopiaId(src.getTopiaId());
- // les association cibles connues pour l'entite sur la base destination
+ // les association cibles connues pour l'entite sur la base
+ // destination
Collection<?> dstTargetEntities = (Collection<?>)
ownerOperator.get(name, dst);
@@ -209,7 +221,8 @@
// on verifie que l'association doit etre rattachee
if (associationsId.contains(assosiationSrc.getTopiaId())) {
- if (dstTargetAssociationsId.contains(assosiationSrc.getTopiaId())) {
+ if (dstTargetAssociationsId.contains(
+ assosiationSrc.getTopiaId())) {
// deja attache
if (log.isDebugEnabled()) {
log.debug("already attached association '" + name +
@@ -249,14 +262,4 @@
dstCtxt.commitTransaction();
}
}
-
- @Override
- public void rollback(ReplicationOperationDef operationDef,
- TopiaContextImplementor srcCtxt,
- TopiaContextImplementor dstCtxt,
- List<? extends TopiaEntity> entities,
- TopiaEntityIdsMap data) throws Exception {
-
- // il faut dettacher les associations
- }
}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachLink.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachLink.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachLink.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -32,7 +32,7 @@
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.persistence.util.EntityOperator;
import org.nuiton.topia.persistence.util.TopiaEntityHelper;
-import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
+import org.nuiton.topia.replication.TopiaReplicationContext;
import org.nuiton.topia.replication.TopiaReplicationOperation;
import org.nuiton.topia.replication.model.ReplicationLink;
import org.nuiton.topia.replication.model.ReplicationModel;
@@ -81,17 +81,19 @@
Object... parameters) {
throw new UnsupportedOperationException(
- _("topia.replication.operation.error.uncreatable", getClass()));
+ _("topia.replication.error.operation.uncreatable", getClass()));
}
@Override
- public void run(ReplicationOperationDef operationDef,
+ public void run(TopiaReplicationContext replicationContext,
+ ReplicationOperationDef operationDef,
TopiaContextImplementor srcCtxt,
TopiaContextImplementor dstCtxt,
- List<? extends TopiaEntity> nodeEntities,
- TopiaEntityIdsMap data) throws TopiaException {
+ List<? extends TopiaEntity> nodeEntities
+ ) throws TopiaException {
- ReplicationLink link = (ReplicationLink) operationDef.getParameters()[0];
+ ReplicationLink link =
+ (ReplicationLink) operationDef.getParameters()[0];
String name = link.getName();
@@ -112,9 +114,6 @@
// contient la liste des ids des entite source de l'association
List<String> ownerIds = null;
- // contient la liste des entites sources de l'association
- List<? extends TopiaEntity> ownerEntities = null;
-
if (ownerNode.equals(operationDef.getNode())) {
ownerIds = TopiaEntityHelper.getTopiaIdList(nodeEntities);
}
@@ -124,11 +123,11 @@
}
if (ownerIds == null) {
- ownerIds = data.get(ownerNode.getContract().getContract());
+ ownerIds = replicationContext.getEntityIds(ownerNode);
}
if (associationIds == null) {
- associationIds = data.get(cibleNode.getContract().getContract());
+ associationIds = replicationContext.getEntityIds(cibleNode);
}
if (ownerIds == null || ownerIds.isEmpty()) {
@@ -142,10 +141,12 @@
// modifiees (dettachement d'association ou autres)
// ils nous faut les entites telles qu'elles sont en base source
- ownerEntities = TopiaEntityHelper.getEntitiesList(
- srcCtxt,
- ownerIds.toArray(new String[ownerIds.size()])
- );
+ // contient la liste des entites sources de l'association
+ List<? extends TopiaEntity> ownerEntities =
+ TopiaEntityHelper.getEntitiesList(
+ srcCtxt,
+ ownerIds.toArray(new String[ownerIds.size()])
+ );
boolean shouldCommit = false;
@@ -167,7 +168,8 @@
if (targetEntities == null || targetEntities.isEmpty()) {
if (log.isDebugEnabled()) {
- log.debug("no association '" + name + "' attached to " + src);
+ log.debug("no association '" + name + "' attached to " +
+ src);
}
// pas de donnees dans l'association
continue;
@@ -181,7 +183,8 @@
TopiaEntity dst = dstCtxt.findByTopiaId(src.getTopiaId());
- // les association cibles connues pour l'entite sur la base destination
+ // les association cibles connues pour l'entite sur la base
+ // destination
Collection<?> dstTargetEntities = (Collection<?>)
ownerOperator.get(name, dst);
@@ -239,14 +242,4 @@
dstCtxt.commitTransaction();
}
}
-
- @Override
- public void rollback(ReplicationOperationDef operationDef,
- TopiaContextImplementor srcCtxt,
- TopiaContextImplementor dstCtxt,
- List<? extends TopiaEntity> entities,
- TopiaEntityIdsMap data) throws Exception {
-
- // il faut dettacher les liens
- }
}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/DettachAssociation.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/DettachAssociation.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/DettachAssociation.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -31,7 +31,7 @@
import org.nuiton.topia.framework.TopiaContextImplementor;
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.persistence.util.EntityOperator;
-import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
+import org.nuiton.topia.replication.TopiaReplicationContext;
import org.nuiton.topia.replication.TopiaReplicationOperation;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
@@ -64,20 +64,21 @@
Object... parameters) {
throw new UnsupportedOperationException(
- _("topia.replication.operation.error.uncreatable", getClass()));
+ _("topia.replication.error.operation.uncreatable", getClass()));
}
@Override
- public void run(ReplicationOperationDef operationDef,
+ public void run(TopiaReplicationContext replicationContext,
+ ReplicationOperationDef operationDef,
TopiaContextImplementor srcCtxt,
TopiaContextImplementor dstCtxt,
- List<? extends TopiaEntity> entities,
- TopiaEntityIdsMap data) throws TopiaException {
+ List<? extends TopiaEntity> entities
+ ) throws TopiaException {
String name = (String) operationDef.getParameters()[0];
- EntityOperator<? super TopiaEntity> operator =
- operationDef.getNode().getOperator();
+ EntityOperator<? super TopiaEntity> operator;
+ operator = operationDef.getNode().getOperator();
// dettach les associations
for (TopiaEntity e : entities) {
@@ -92,15 +93,4 @@
}
}
}
-
-
- @Override
- public void rollback(ReplicationOperationDef operationDef,
- TopiaContextImplementor srcCtxt,
- TopiaContextImplementor dstCtxt,
- List<? extends TopiaEntity> entities,
- TopiaEntityIdsMap data) throws Exception {
-
- // il faut attacher les associations ? ou bien ne rien faire ?
- }
}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/Duplicate.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/Duplicate.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/Duplicate.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -25,11 +25,15 @@
package org.nuiton.topia.replication.operation;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.nuiton.topia.TopiaException;
import org.nuiton.topia.framework.TopiaContextImplementor;
+import org.nuiton.topia.persistence.TopiaDAO;
import org.nuiton.topia.persistence.TopiaEntity;
-import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
-import org.nuiton.topia.replication.TopiaReplicationOperation;
+import org.nuiton.topia.replication.TopiaReplicationContext;
+import org.nuiton.topia.replication.TopiaReplicationOperationUndoable;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
import org.nuiton.topia.replication.model.ReplicationOperationDef;
@@ -49,40 +53,71 @@
* @author tchemit <chemit(a)codelutin.com>
* @since 2.2.0
*/
-public class Duplicate implements TopiaReplicationOperation {
+public class Duplicate implements TopiaReplicationOperationUndoable {
+
+ /** Logger */
+ private static final Log log =
+ LogFactory.getLog(Duplicate.class);
+
@Override
public void register(ReplicationModel model,
ReplicationNode ownerNode,
ReplicationOperationPhase phase,
- Object... parameters) {
+ Object... parameters) throws UnsupportedOperationException {
throw new UnsupportedOperationException(
- _("topia.replication.operation.error.uncreatable", getClass()));
+ _("topia.replication.error.operation.uncreatable", getClass()));
}
@Override
- public void run(ReplicationOperationDef operationDef,
+ public void run(TopiaReplicationContext replicationContext,
+ ReplicationOperationDef operationDef,
TopiaContextImplementor srcCtxt,
TopiaContextImplementor dstCtxt,
- List<? extends TopiaEntity> entities,
- TopiaEntityIdsMap data) throws TopiaException {
+ List<? extends TopiaEntity> entities) throws TopiaException {
// replication des donnees vers la destination
srcCtxt.replicateEntities(dstCtxt, entities);
// sauvegarde de la destination
dstCtxt.commitTransaction();
-
}
@Override
public void rollback(ReplicationOperationDef operationDef,
- TopiaContextImplementor srcCtxt,
- TopiaContextImplementor dstCtxt,
- List<? extends TopiaEntity> entities,
- TopiaEntityIdsMap data) throws Exception {
+ TopiaReplicationContext replicationContext,
+ TopiaContextImplementor dstCtxt) throws Exception {
- // il faut supprimer les entities
+ List<String> ids =
+ replicationContext.getEntityIds(operationDef.getNode());
+
+ if (CollectionUtils.isEmpty(ids)) {
+
+ // rien a supprimer
+ return;
+ }
+
+ Class<? extends TopiaEntity> entityClass = operationDef.getEntityType();
+ TopiaDAO<TopiaEntity> dao =
+ (TopiaDAO<TopiaEntity>) dstCtxt.getDAO(entityClass);
+
+ List<String> allIds = dao.findAllIds();
+ try {
+ for (String id : ids) {
+ if (allIds.contains(id)) {
+
+ // on peut supprimer cette entité
+ log.info("Will delete " + id);
+ TopiaEntity entity = dao.findByTopiaId(id);
+ dao.delete(entity);
+ }
+ }
+ } finally {
+ allIds.clear();
+
+ // commit des suppressions
+ dstCtxt.commitTransaction();
+ }
}
}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/LoadLink.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/LoadLink.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/LoadLink.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -31,7 +31,7 @@
import org.nuiton.topia.framework.TopiaContextImplementor;
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.persistence.util.EntityOperator;
-import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
+import org.nuiton.topia.replication.TopiaReplicationContext;
import org.nuiton.topia.replication.TopiaReplicationOperation;
import org.nuiton.topia.replication.model.ReplicationLink;
import org.nuiton.topia.replication.model.ReplicationModel;
@@ -65,15 +65,16 @@
Object... parameters) {
throw new UnsupportedOperationException(
- _("topia.replication.operation.error.uncreatable", getClass()));
+ _("topia.replication.error.operation.uncreatable", getClass()));
}
@Override
- public void run(ReplicationOperationDef operationDef,
+ public void run(TopiaReplicationContext replicationContext,
+ ReplicationOperationDef operationDef,
TopiaContextImplementor srcCtxt,
TopiaContextImplementor dstCtxt,
- List<? extends TopiaEntity> nodeEntities,
- TopiaEntityIdsMap data) throws TopiaException {
+ List<? extends TopiaEntity> nodeEntities
+ ) throws TopiaException {
ReplicationLink link = (ReplicationLink) operationDef.getParameters()[0];
@@ -83,7 +84,7 @@
if (!ownerNode.equals(operationDef.getNode())) {
throw new IllegalStateException(
- _("topia.replication.operation.loadLink.illegalSource",
+ _("topia.replication.error.operation.loadLink.illegalSource",
operationDef.getNode(), ownerNode));
}
@@ -105,15 +106,4 @@
}
}
}
-
-
- @Override
- public void rollback(ReplicationOperationDef operationDef,
- TopiaContextImplementor srcCtxt,
- TopiaContextImplementor dstCtxt,
- List<? extends TopiaEntity> entities,
- TopiaEntityIdsMap data) throws Exception {
-
- // rien a faire ici
- }
}
Modified: trunk/topia-service-replication/src/main/resources/i18n/topia-service-replication-en_GB.properties
===================================================================
--- trunk/topia-service-replication/src/main/resources/i18n/topia-service-replication-en_GB.properties 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/main/resources/i18n/topia-service-replication-en_GB.properties 2010-08-21 16:05:12 UTC (rev 2105)
@@ -1,7 +1,5 @@
-topia.replication.attachAssociation.nothing.to.do=
-topia.replication.engine.error.null.param=
-topia.replication.engine.error.unkown.operation=
-topia.replication.engine.error.unkown.owner.node=
-topia.replication.operation.error.notImplemented=
-topia.replication.operation.error.uncreatable=
-topia.replication.operation.loadLink.illegalSource=
+topia.replication.attachAssociation.nothing.to.do=Nothing to attach...
+topia.replication.error.operation.loadLink.illegalSource=The source node of loading association requires the node %1$s, but was %2$s.
+topia.replication.error.operation.uncreatable=The operation %1$s is internal and can not be added using the api.
+topia.replication.error.unkown.operation=The operation %1$s is unknown, known operations are \: %2$s
+topia.replication.error.unkown.owner.node=The target node (of type %1$s) for operation %2$s is unknown, known nodes are \: %3$s
Modified: trunk/topia-service-replication/src/main/resources/i18n/topia-service-replication-fr_FR.properties
===================================================================
--- trunk/topia-service-replication/src/main/resources/i18n/topia-service-replication-fr_FR.properties 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/main/resources/i18n/topia-service-replication-fr_FR.properties 2010-08-21 16:05:12 UTC (rev 2105)
@@ -1,7 +1,5 @@
topia.replication.attachAssociation.nothing.to.do=Rien a attacher...
-topia.replication.engine.error.null.param=Le param\u00E8tre '%1$s' de la methode '%2$s' ne peut pas etre null\!
-topia.replication.engine.error.unkown.operation=L'op\u00E9ration %1$s est inconnue, op\u00E9rations connues \: %2$s
-topia.replication.engine.error.unkown.owner.node=Le noeud de rattachement (de type %1$s) pour l'op\u00E9ration %2$s n'a pas \u00E9t\u00E9 trouv\u00E9, noeuds connus \: %3$s
-topia.replication.operation.error.notImplemented=L'operation %1$s n'est pas encore implant\u00E9e...
-topia.replication.operation.error.uncreatable=L'operation %1$s est interne et ne peut pas \u00EAtre cr\u00E9\u00E9e par l'api d'ajout d'op\u00E9ration.
-topia.replication.operation.loadLink.illegalSource=Le noeud source de l'op\u00E9ration de chargement d'association attendait un noeud %1$s mais a trouv\u00E9 le noeud %2$s.
+topia.replication.error.operation.loadLink.illegalSource=Le noeud source de l'op\u00E9ration de chargement d'association attendait un noeud %1$s mais a trouv\u00E9 le noeud %2$s.
+topia.replication.error.operation.uncreatable=L'operation %1$s est interne et ne peut pas \u00EAtre cr\u00E9\u00E9e par l'api d'ajout d'op\u00E9ration.
+topia.replication.error.unkown.operation=L'op\u00E9ration %1$s est inconnue, op\u00E9rations connues \: %2$s
+topia.replication.error.unkown.owner.node=Le noeud de rattachement (de type %1$s) pour l'op\u00E9ration %2$s n'a pas \u00E9t\u00E9 trouv\u00E9, noeuds connus \: %3$s
Modified: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/AbstractTopiaReplicationServiceTest.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/AbstractTopiaReplicationServiceTest.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/AbstractTopiaReplicationServiceTest.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -122,6 +122,11 @@
service = null;
}
+
+ protected TopiaReplicationModelBuilder getModelBuilder() {
+ return (TopiaReplicationModelBuilder) service.getModelBuilder();
+ }
+
protected abstract TopiaContext createDb2(String name) throws Exception;
protected abstract TopiaContext createDb(String name) throws Exception;
@@ -215,7 +220,7 @@
Set<?> detectTypes;
- detectTypes = service.getModelBuilder().detectTypes(context, getContracts(), entity.getTopiaId());
+ detectTypes = ((TopiaReplicationModelBuilder) service.getModelBuilder()).detectTypes(context, getContracts(), entity.getTopiaId());
assertEquals("expected types : " +
Arrays.toString(expectedCouple) +
" but was " + detectTypes,
@@ -226,7 +231,7 @@
}
protected void getOperation(Class<? extends TopiaReplicationOperation> operationClass, boolean shouldExist) throws TopiaException {
- TopiaReplicationOperation operation = service.getModelBuilder().getOperation(operationClass);
+ TopiaReplicationOperation operation = getModelBuilder().getOperationProvider().getOperation(operationClass);
assertEquals(shouldExist, operation != null);
}
@@ -280,14 +285,14 @@
TopiaEntityEnum c = TopiaEntityHelper.getEntityEnum(
entity.getClass(), getContracts());
assertNotNull(c);
- shell = model.getNode(c.getContract()).getShell();
+ shell = model.getNode(c).getShell();
assertEquals(
"expected shell : " + Arrays.toString(expected) + ", but was " +
shell, expected.length, shell.size());
for (int i = 0, j = expected.length; i < j; i++) {
TopiaEntityEnum type = expected[i];
- ReplicationNode node = model.getNode(type.getContract());
+ ReplicationNode node = model.getNode(type);
assertTrue(shell.contains(node));
assertEquals(type, node.getContract());
}
@@ -388,7 +393,7 @@
}
for (ReplicationNode node : model.getOrder()) {
- List<ReplicationOperationDef> operations = node.getOperations();
+ ReplicationOperationDef[] operations = node.getOperations();
for (ReplicationOperationDef op : operations) {
getLog().info("[" + node + "] : operation " + op);
}
@@ -399,7 +404,8 @@
private static int dbCounter;
- protected void doReplicate(TopiaEntityEnum contract, TopiaEntity... entity) throws Exception {
+ protected void doReplicate(TopiaEntityEnum contract,
+ TopiaEntity... entity) throws Exception {
TopiaContext rootCtxt = createReplicateDb("doReplicate_" + contract);
@@ -596,21 +602,22 @@
getLog().info("entity " + entity.getTopiaId());
prepareModel(entity.getTopiaId());
- service.addBeforeOperation(model, contract, operationClass, parameters);
+ getModelBuilder().addBeforeOperation(model, contract, operationClass, parameters);
// on ne doit pas avoir le droit de creer cette operation
fail();
}
- protected void createUnsupportedAfterOperation(TopiaEntityEnum contract,
- TopiaEntity entity,
- Class<? extends TopiaReplicationOperation> operationClass,
- Object... parameters) throws Exception {
+ protected void createUnsupportedAfterOperation(
+ TopiaEntityEnum contract,
+ TopiaEntity entity,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... parameters) throws Exception {
getLog().info("entity " + entity.getTopiaId());
prepareModel(entity.getTopiaId());
// model = service.createModel(getContracts());
// model.detectDirectDependencies();
- service.addAfterOperation(model, contract, operationClass, parameters);
+ getModelBuilder().addAfterOperation(model, contract, operationClass, parameters);
// on ne doit pas avoir le droit de creer cette operation
fail();
}
@@ -637,11 +644,15 @@
}
protected void createModel(TopiaEntity entity) throws TopiaException {
- model = service.getModelBuilder().createModel(context, getContracts(), entity.getTopiaId());
+ model = getModelBuilder().createModel(context,
+ getContracts(),
+ true,
+ entity.getTopiaId()
+ );
}
protected void prepareModel(String... ids) throws TopiaException {
- model = service.prepare(getContracts(), ids);
+ model = service.prepare(getContracts(), true, ids);
}
protected void prepareModelAll() throws TopiaException {
@@ -649,6 +660,6 @@
}
protected void prepareModelWithComputedOrder(String... ids) throws TopiaException {
- model = service.prepareWithComputedOrder(getContracts(), ids);
+ model = service.prepare(getContracts(), false, ids);
}
}
Modified: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationOperationTest.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationOperationTest.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationOperationTest.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -67,9 +67,16 @@
private static final Log log =
LogFactory.getLog(TopiaReplicationOperationTest.class);
- protected static final TopiaEntityEnum[] contracts = {TopiaTestEntityEnum.Person, TopiaTestEntityEnum.Pet, TopiaTestEntityEnum.Race};
+ protected static final TopiaEntityEnum[] contracts = {
+ TopiaTestEntityEnum.Person,
+ TopiaTestEntityEnum.Pet,
+ TopiaTestEntityEnum.Race
+ };
- protected static final String entitiesList = PersonImpl.class.getName() + "," + PetImpl.class.getName() + "," + RaceImpl.class.getName();
+ protected static final String entitiesList =
+ PersonImpl.class.getName() + "," +
+ PetImpl.class.getName() + "," +
+ RaceImpl.class.getName();
static protected Person person, person2;
@@ -107,7 +114,7 @@
@Test(expected = NullPointerException.class)
public void testGetOperation_nullOperationClass() throws Exception {
- getModelBuilder().getOperation(null);
+ getModelBuilder().getOperationProvider().getOperation((Class<? extends TopiaReplicationOperation>) null);
}
protected TopiaReplicationModelBuilder getModelBuilder() {
@@ -134,38 +141,38 @@
@Test(expected = NullPointerException.class)
public void testCreateOperation_nullType() throws Exception {
- model = getModelBuilder().createModel(context, contracts);
+ model = getModelBuilder().createModel(context, contracts, true);
getModelBuilder().createOperation(model, null, null, null);
}
@Test(expected = NullPointerException.class)
public void testCreateOperation_nullPhase() throws Exception {
- model = getModelBuilder().createModel(context, contracts);
+ model = getModelBuilder().createModel(context, contracts, true);
getModelBuilder().createOperation(model, TopiaTestEntityEnum.Pet, null, null);
}
@Test(expected = NullPointerException.class)
public void testCreateOperation_nullOperationClass() throws Exception {
- model = getModelBuilder().createModel(context, contracts);
+ model = getModelBuilder().createModel(context, contracts, true);
getModelBuilder().createOperation(model, TopiaTestEntityEnum.Pet, ReplicationOperationPhase.before, null);
}
@Test(expected = IllegalArgumentException.class)
public void testCreateOperation_noNode() throws Exception {
- model = getModelBuilder().createModel(context, contracts);
+ model = getModelBuilder().createModel(context, contracts, true);
// le noeud Pet n'existe pas
- service.addAfterOperation(model, TopiaTestEntityEnum.Pet, Duplicate.class);
+ getModelBuilder().addAfterOperation(model, TopiaTestEntityEnum.Pet, Duplicate.class);
}
@Test(expected = IllegalArgumentException.class)
public void testCreateOperation_noOperation() throws Exception {
- model = getModelBuilder().createModel(context, contracts);
+ model = getModelBuilder().createModel(context, contracts, true);
// le noeud Pet n'existe pas
- service.addAfterOperation(model, TopiaTestEntityEnum.Pet, UnregistredOperation.class);
+ getModelBuilder().addAfterOperation(model, TopiaTestEntityEnum.Pet, UnregistredOperation.class);
}
@Test(expected = UnsupportedOperationException.class)
@@ -211,37 +218,37 @@
@Test(expected = IllegalArgumentException.class)
public void testCreateOperation_wrongParameterNumber() throws Exception {
- model = getModelBuilder().createModel(context, contracts, pet.getTopiaId());
- service.addBeforeOperation(model, TopiaTestEntityEnum.Pet, FakeOperation.class);
+ model = getModelBuilder().createModel(context, contracts, true, pet.getTopiaId());
+ getModelBuilder().addBeforeOperation(model, TopiaTestEntityEnum.Pet, FakeOperation.class);
}
@Test(expected = IllegalArgumentException.class)
public void testCreateOperation_wrongParameterNumber2() throws Exception {
- model = getModelBuilder().createModel(context, contracts, pet.getTopiaId());
- service.addBeforeOperation(model, TopiaTestEntityEnum.Pet, FakeOperation.class, String.class, String.class);
+ model = getModelBuilder().createModel(context, contracts, true, pet.getTopiaId());
+ getModelBuilder().addBeforeOperation(model, TopiaTestEntityEnum.Pet, FakeOperation.class, String.class, String.class);
}
@Test(expected = IllegalArgumentException.class)
public void testCreateOperation_wrongParameterType() throws Exception {
- model = getModelBuilder().createModel(context, contracts, pet.getTopiaId());
- service.addBeforeOperation(model, TopiaTestEntityEnum.Pet, FakeOperation.class, Integer.class);
+ model = getModelBuilder().createModel(context, contracts, true, pet.getTopiaId());
+ getModelBuilder().addBeforeOperation(model, TopiaTestEntityEnum.Pet, FakeOperation.class, Integer.class);
}
@Test(expected = IllegalArgumentException.class)
public void testCreateOperation_nullParameter() throws Exception {
- model = getModelBuilder().createModel(context, contracts, pet.getTopiaId());
- service.addBeforeOperation(model, TopiaTestEntityEnum.Pet, FakeOperation.class, (Object) null);
+ model = getModelBuilder().createModel(context, contracts, true, pet.getTopiaId());
+ getModelBuilder().addBeforeOperation(model, TopiaTestEntityEnum.Pet, FakeOperation.class, (Object) null);
}
@Test
public void testCreateOperation() throws Exception {
- model = getModelBuilder().createModel(context, contracts, pet.getTopiaId());
- service.addBeforeOperation(model, TopiaTestEntityEnum.Pet, FakeOperation.class, "before");
- service.addAfterOperation(model, TopiaTestEntityEnum.Race, FakeOperation.class, "after");
+ model = getModelBuilder().createModel(context, contracts, true, pet.getTopiaId());
+ getModelBuilder().addBeforeOperation(model, TopiaTestEntityEnum.Pet, FakeOperation.class, "before");
+ getModelBuilder().addAfterOperation(model, TopiaTestEntityEnum.Race, FakeOperation.class, "after");
}
@Test(expected = NullPointerException.class)
@@ -253,7 +260,7 @@
@Test(expected = NullPointerException.class)
public void testDoReplicate_nullDstCtxt() throws Exception {
- model = getModelBuilder().createModel(context, contracts);
+ model = getModelBuilder().createModel(context, contracts, true);
service.doReplicate(model, null);
}
Modified: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationServiceImplAllTest.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationServiceImplAllTest.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationServiceImplAllTest.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -283,7 +283,7 @@
@Override
protected void createModel(TopiaEntity entity) throws TopiaException {
- model = service.getModelBuilder().createModelForAll(getContracts());
+ model = getModelBuilder().createModelForAll(getContracts());
}
@Override
Modified: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationServiceImplTest.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationServiceImplTest.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationServiceImplTest.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -66,7 +66,8 @@
public class TopiaReplicationServiceImplTest extends AbstractTopiaReplicationServiceTest {
/** Logger */
- private static final Log log = LogFactory.getLog(TopiaReplicationServiceImplTest.class);
+ private static final Log log =
+ LogFactory.getLog(TopiaReplicationServiceImplTest.class);
protected static final TopiaEntityEnum[] contracts = {TopiaTestEntityEnum.Person, TopiaTestEntityEnum.Pet, TopiaTestEntityEnum.Race};
@@ -146,7 +147,6 @@
detectAssociations(person2);
detectAssociations(race2);
detectAssociations(pet2);
-
}
@Test
Modified: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/FakeOperation.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/FakeOperation.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/FakeOperation.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -25,13 +25,11 @@
package org.nuiton.topia.replication.operation;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.nuiton.topia.TopiaException;
import org.nuiton.topia.framework.TopiaContextImplementor;
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.persistence.util.TopiaEntityHelper;
-import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
+import org.nuiton.topia.replication.TopiaReplicationContext;
import org.nuiton.topia.replication.TopiaReplicationOperation;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
@@ -46,11 +44,9 @@
*/
public class FakeOperation implements TopiaReplicationOperation {
- /** Logger */
- private static final Log log = LogFactory.getLog(FakeOperation.class);
+ public static final Class<?>[] PARAMETERS_CLASSES =
+ new Class<?>[]{String.class};
- public static final Class<?>[] PARAMETERS_CLASSES = new Class<?>[]{String.class};
-
@Override
public void register(ReplicationModel model,
ReplicationNode ownerNode,
@@ -68,17 +64,14 @@
}
@Override
- public void run(ReplicationOperationDef operationDef,
+ public void run(TopiaReplicationContext replicationContext,
+ ReplicationOperationDef operationDef,
TopiaContextImplementor srcCtxt,
TopiaContextImplementor dstCtxt,
- List<? extends TopiaEntity> nodeEntities,
- TopiaEntityIdsMap data)
+ List<? extends TopiaEntity> nodeEntities
+ )
throws TopiaException {
}
- @Override
- public void rollback(ReplicationOperationDef operationDef, TopiaContextImplementor srcCtxt, TopiaContextImplementor dstCtxt, List<? extends TopiaEntity> entities, TopiaEntityIdsMap data) throws Exception {
- // rien a faire
- }
}
Modified: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UncreatableOperation.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UncreatableOperation.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UncreatableOperation.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -25,12 +25,10 @@
package org.nuiton.topia.replication.operation;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.nuiton.topia.TopiaException;
import org.nuiton.topia.framework.TopiaContextImplementor;
import org.nuiton.topia.persistence.TopiaEntity;
-import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
+import org.nuiton.topia.replication.TopiaReplicationContext;
import org.nuiton.topia.replication.TopiaReplicationOperation;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
@@ -47,10 +45,6 @@
*/
public class UncreatableOperation implements TopiaReplicationOperation {
- /** Logger */
- private static final Log log =
- LogFactory.getLog(UncreatableOperation.class);
-
@Override
public void register(ReplicationModel model,
ReplicationNode ownerNode,
@@ -58,20 +52,17 @@
Object... parameters) {
throw new UnsupportedOperationException(
- _("topia.replication.operation.error.uncreatable", getClass()));
+ _("topia.replication.error.operation.uncreatable", getClass()));
}
@Override
- public void run(ReplicationOperationDef operationDef,
+ public void run(TopiaReplicationContext replicationContext,
+ ReplicationOperationDef operationDef,
TopiaContextImplementor srcCtxt,
TopiaContextImplementor dstCtxt,
- List<? extends TopiaEntity> nodeEntities,
- TopiaEntityIdsMap data)
+ List<? extends TopiaEntity> nodeEntities
+ )
throws TopiaException {
}
- @Override
- public void rollback(ReplicationOperationDef operationDef, TopiaContextImplementor srcCtxt, TopiaContextImplementor dstCtxt, List<? extends TopiaEntity> entities, TopiaEntityIdsMap data) throws Exception {
- // rien a faire
- }
}
Modified: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UnregistredOperation.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UnregistredOperation.java 2010-08-21 16:02:52 UTC (rev 2104)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UnregistredOperation.java 2010-08-21 16:05:12 UTC (rev 2105)
@@ -25,12 +25,10 @@
package org.nuiton.topia.replication.operation;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.nuiton.topia.TopiaException;
import org.nuiton.topia.framework.TopiaContextImplementor;
import org.nuiton.topia.persistence.TopiaEntity;
-import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
+import org.nuiton.topia.replication.TopiaReplicationContext;
import org.nuiton.topia.replication.TopiaReplicationOperation;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
@@ -45,9 +43,6 @@
*/
public class UnregistredOperation implements TopiaReplicationOperation {
- /** Logger */
- private static final Log log = LogFactory.getLog(UnregistredOperation.class);
-
@Override
public void register(ReplicationModel model,
ReplicationNode ownerNode,
@@ -58,16 +53,13 @@
@Override
public void run(
+ TopiaReplicationContext replicationContext,
ReplicationOperationDef operationDef,
TopiaContextImplementor srcCtxt,
TopiaContextImplementor dstCtxt,
- List<? extends TopiaEntity> nodeEntities,
- TopiaEntityIdsMap data)
+ List<? extends TopiaEntity> nodeEntities
+ )
throws TopiaException {
}
- @Override
- public void rollback(ReplicationOperationDef operationDef, TopiaContextImplementor srcCtxt, TopiaContextImplementor dstCtxt, List<? extends TopiaEntity> entities, TopiaEntityIdsMap data) throws Exception {
- // rien a faire
- }
}
1
0
r2104 - in trunk/topia-persistence/src/main: java/org/nuiton/topia/framework java/org/nuiton/topia/generator java/org/nuiton/topia/persistence java/org/nuiton/topia/persistence/util resources/i18n
by tchemit@users.nuiton.org Aug. 21, 2010
by tchemit@users.nuiton.org Aug. 21, 2010
Aug. 21, 2010
Author: tchemit
Date: 2010-08-21 18:02:52 +0200 (Sat, 21 Aug 2010)
New Revision: 2104
Url: http://nuiton.org/repositories/revision/topia/2104
Log:
- do english i18n
- change <code>true|false</code> by {@code XXX} in javadoc
- add some suppressWarning
- clean code
Modified:
trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java
trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/TopiaGeneratorUtil.java
trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaEntityEnum.java
trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/EntityOperator.java
trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/TopiaEntityHelper.java
trunk/topia-persistence/src/main/resources/i18n/topia-persistence-en_GB.properties
trunk/topia-persistence/src/main/resources/i18n/topia-persistence-fr_FR.properties
Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java
===================================================================
--- trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java 2010-08-21 16:01:23 UTC (rev 2103)
+++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaContextImpl.java 2010-08-21 16:02:52 UTC (rev 2104)
@@ -663,13 +663,14 @@
/* -------------------- 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(
- I18n._("topia.persistence.error.null.parameter",
- "getDAO", "entityClass"));
+ I18n._("topia.persistence.error.null.param",
+ "entityClass", "getDAO"));
}
if (getRootContext() == this) {
throw new TopiaException(
@@ -712,6 +713,7 @@
return result;
}
+ @SuppressWarnings({"unchecked"})
@Override
public <E extends TopiaEntity, D extends TopiaDAO<E>> D getDAO(Class<E> entityClass,
Class<D> daoClass) throws TopiaException {
@@ -806,7 +808,7 @@
@Override
public void rollbackTransaction() throws TopiaException {
- if (getRootContext() == this) {
+ if (this.equals(getRootContext())) {
throw new TopiaException(I18n._(
"topia.persistence.error.unsupported.operation.on.root.context",
"rollback"));
@@ -865,7 +867,7 @@
// on se desenregistre du context pere et on ferme les connexions si
// on est pas le root context
- if (getRootContext() != this) {
+ if (!this.equals(getRootContext())) {
closed = true;
hibernate.close();
getParentContext().removeChildContext(this);
@@ -908,6 +910,7 @@
/* -------------------- GLOBAL OPERATIONS ON SCHEMA ----------------------*/
+ @SuppressWarnings({"unchecked"})
@Override
public TopiaEntity findByTopiaId(String id) throws TopiaException {
checkClosed(I18n._(
@@ -925,6 +928,7 @@
return query.execute(this);
}
+ @SuppressWarnings({"unchecked"})
@Override
public TopiaQuery createQuery(Class<?> entityClass, String alias) {
return new TopiaQuery((Class<? extends TopiaEntity>)entityClass, alias);
Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/TopiaGeneratorUtil.java
===================================================================
--- trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/TopiaGeneratorUtil.java 2010-08-21 16:01:23 UTC (rev 2103)
+++ trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/TopiaGeneratorUtil.java 2010-08-21 16:02:52 UTC (rev 2104)
@@ -510,7 +510,7 @@
* Detecte si un attribut fait partie d'une clef metier.
*
* @param attribute l'attribut à tester
- * @return <code>true</code> si l'attribut fait partie d'une clef metier,
+ * @return {@code true} si l'attribut fait partie d'une clef metier,
* <code>false</cdoe> sinon.
*/
public static boolean isNaturalId(ObjectModelAttribute attribute) {
@@ -901,8 +901,8 @@
* une clef metier est non mutable.
*
* @param clazz la classe a tester
- * @return <code>true</code> si le tag value a ete positionne sur la classe
- * via le tag {@link #TAG_NATURAL_ID_MUTABLE}, <code>false</code>
+ * @return {@code true} si le tag value a ete positionne sur la classe
+ * via le tag {@link #TAG_NATURAL_ID_MUTABLE}, {@code false}
* sinon.
*/
public static boolean isNaturalIdMutable(ObjectModelClass clazz) {
Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaEntityEnum.java
===================================================================
--- trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaEntityEnum.java 2010-08-21 16:01:23 UTC (rev 2103)
+++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/TopiaEntityEnum.java 2010-08-21 16:02:52 UTC (rev 2104)
@@ -101,8 +101,8 @@
* </pre>
*
* @param klass the type of an entity to test.
- * @return <code>true</code> if given type is dealed directly by this entity,
- * <code>false</code> otherwise.
+ * @return {@code true} if given type is dealed directly by this entity,
+ * {@code false} otherwise.
*/
boolean accept(Class<? extends TopiaEntity> klass);
}
Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/EntityOperator.java
===================================================================
--- trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/EntityOperator.java 2010-08-21 16:01:23 UTC (rev 2103)
+++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/EntityOperator.java 2010-08-21 16:02:52 UTC (rev 2104)
@@ -229,7 +229,7 @@
*
* @param name le nom de la propriete d'association
* @param bean l'instance a interroger
- * @return <code>true</code> si pas d'entite d'association
+ * @return {@code true} si pas d'entite d'association
*/
public boolean isChildEmpty(String name, B bean) {
int index = checkAssociationPropertyIndex(name);
Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/TopiaEntityHelper.java
===================================================================
--- trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/TopiaEntityHelper.java 2010-08-21 16:01:23 UTC (rev 2103)
+++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/TopiaEntityHelper.java 2010-08-21 16:02:52 UTC (rev 2104)
@@ -443,6 +443,7 @@
* @return l'ensemble des contrats d'entites
* @since 2.2.0
*/
+ @SuppressWarnings({"unchecked"})
public static Class<? extends TopiaEntity>[] getContracts(
TopiaEntityEnum[] contracts) {
Class<?>[] result = new Class<?>[contracts.length];
@@ -1023,6 +1024,7 @@
return result;
}
+ @SuppressWarnings({"unchecked"})
public static Set<Class<? extends TopiaEntity>> getInterfaces(
Class<? extends TopiaEntity> klass,
Set<Class<? extends TopiaEntity>> klassInterfaces) {
@@ -1090,10 +1092,6 @@
for (E e : entityList) {
E e2 = (E) srcCtxt.findByTopiaId(e.getTopiaId());
if (e2 == null && !canBeNull) {
-// if (!canBeNull) {
-// throw new IllegalStateException(
-// "topia.replication.engine.error.entity.must.exists");
-// }
continue;
}
srcList.add(e2);
@@ -1129,8 +1127,8 @@
Object value) {
if (value == null) {
throw new NullPointerException(
- _("topia.replication.engine.error.null.param",
- parameterName, methodName));
+ _("topia.persistence.error.null.param",
+ methodName, parameterName));
}
}
@@ -1145,8 +1143,7 @@
public static void checkSize(int size, Object[] params) {
if (params.length != size) {
throw new IllegalArgumentException(
- "l'operation requiere " + size + " parametres mais en a " +
- params.length);
+ _("topia.persistence.error.invalid.size", size, params.length));
}
}
@@ -1157,15 +1154,14 @@
Object value = params[index];
if (value == null) {
throw new IllegalArgumentException(
- "le parametre de positiion" + index + " est null!");
+ _("topia.persistence.error.null.param.in.array", index));
}
Class<?> foundType = value.getClass();
if (!requiredType.isAssignableFrom(foundType)) {
throw new IllegalArgumentException(
- "le paremetre de position " + index +
- " requiere un parametre de type " + requiredType +
- " mais est de type " + foundType);
+ _("topia.persistence.error.invalid.type.in.array",
+ index, requiredType, foundType));
}
}
}
Modified: trunk/topia-persistence/src/main/resources/i18n/topia-persistence-en_GB.properties
===================================================================
--- trunk/topia-persistence/src/main/resources/i18n/topia-persistence-en_GB.properties 2010-08-21 16:01:23 UTC (rev 2103)
+++ trunk/topia-persistence/src/main/resources/i18n/topia-persistence-en_GB.properties 2010-08-21 16:02:52 UTC (rev 2104)
@@ -1,35 +1,32 @@
-topia.persistence.error.class.not.found=
-topia.persistence.error.context.already.closed=
-topia.persistence.error.context.is.closed=
-topia.persistence.error.create.schema=
-topia.persistence.error.empty.doc=
-topia.persistence.error.no.hibernate.session=
-topia.persistence.error.null.parameter=
-topia.persistence.error.on.backup=
-topia.persistence.error.on.clear=
-topia.persistence.error.on.commit=
-topia.persistence.error.on.export=
-topia.persistence.error.on.loding.xml.doc=
-topia.persistence.error.on.operation=
-topia.persistence.error.on.query=
-topia.persistence.error.on.replicate=
-topia.persistence.error.on.restore=
-topia.persistence.error.on.rollback=
-topia.persistence.error.query.dao.notDefined=DAO not defined in TopiaQuery, can't execute it without TopiaContext
-topia.persistence.error.replicate.entity=
-topia.persistence.error.replicate.on.same.context=
-topia.persistence.error.rootContext.access=
-topia.persistence.error.service.not.found=
-topia.persistence.error.service.not.retreaved=
-topia.persistence.error.service.unknown=
-topia.persistence.error.unsupported.class=
-topia.persistence.error.unsupported.operation.on.closed.context=
-topia.persistence.error.unsupported.operation.on.root.context=
-topia.persistence.error.update.schema=
-topia.persistence.service.loaded=
-topia.persistence.supported.classes.for.context=
-topia.persistence.warn.service.not.find=
-topia.persistence.warn.service.not.found=
-topia.persistence.warn.service.not.loaded=
-topia.persistence.warn.service.not.postInit=
-topia.persistence.warn.service.not.preInit=
+topia.persistence.error.class.not.found=Persistence class %1$s not found
+topia.persistence.error.context.already.closed=Context was alredy closed
+topia.persistence.error.context.is.closed=Context is closed, no operation is possible.
+topia.persistence.error.create.schema=Schema could not be created for following reason \: %1$s
+topia.persistence.error.empty.doc=Empty document
+topia.persistence.error.no.hibernate.session=No hinernate session found, you must at first, open a new transaction via 'beaginTransaction' method.
+topia.persistence.error.null.param=The method '%1$s' requires a non null parameter '%2$s'.
+topia.persistence.error.on.backup=An error occurs while backup operation \: %1$s
+topia.persistence.error.on.clear=An error occurs while clear operation \: %1$s
+topia.persistence.error.on.commit=An error occurs while commit operation \: %1$s
+topia.persistence.error.on.export=An error occurs while export operation \: %1$s
+topia.persistence.error.on.loding.xml.doc=Could not read xml document for following reason \: %1$s
+topia.persistence.error.on.query=An error occurs while query operation \: %1$s
+topia.persistence.error.on.replicate=An error occurs while replicate operation \: %1$s
+topia.persistence.error.on.restore=An error occurs while restore operation \: %1$s
+topia.persistence.error.on.rollback=An error occurs while rollback operation \: %1$s
+topia.persistence.error.replicate.entity=Could not replicate entity '%1$s' pour following reason \: %2$s
+topia.persistence.error.replicate.on.same.context=Can not do a replication operation on same database.
+topia.persistence.error.rootContext.access=You are on root context, you MUST open a transaction to perform any database access.
+topia.persistence.error.service.not.found=The service %1$s was not found.
+topia.persistence.error.service.not.retreaved=Could not retrive service %1$s for following reason \: %2$s
+topia.persistence.error.service.unknown=The service %1$s of type %2$s was not found.
+topia.persistence.error.unsupported.class=The following entity type %1$s is not managed by this context, you probably forgot to declare it.
+topia.persistence.error.unsupported.operation.on.closed.context=This context is closed, it is not possible to release the operation '%1$s'
+topia.persistence.error.unsupported.operation.on.root.context=Operation '%1$s' not possible on root context (use a sub transaction).
+topia.persistence.error.update.schema=Schema could not be updated for following reason \: %1$s
+topia.persistence.service.loaded=Service '%1$s' loaded (implementation %2$s)
+topia.persistence.supported.classes.for.context=List of supported persistence classes \: %1$s
+topia.persistence.warn.service.not.found=The service named '%1$s' could not be found for following reason \: \: %2$s
+topia.persistence.warn.service.not.loaded=The service with key '%1$s' has a different name '%2$s' \! (service not activated)
+topia.persistence.warn.service.not.postInit=The service named '%1$s' could not be pre-initialized (service not activated)
+topia.persistence.warn.service.not.preInit=The service named '%1$s' could not be post-initialized (service not activated)
Modified: trunk/topia-persistence/src/main/resources/i18n/topia-persistence-fr_FR.properties
===================================================================
--- trunk/topia-persistence/src/main/resources/i18n/topia-persistence-fr_FR.properties 2010-08-21 16:01:23 UTC (rev 2103)
+++ trunk/topia-persistence/src/main/resources/i18n/topia-persistence-fr_FR.properties 2010-08-21 16:02:52 UTC (rev 2104)
@@ -4,7 +4,7 @@
topia.persistence.error.create.schema=Le sch\u00E9ma n'a pas pu \u00EAtre cr\u00E9e pour la raison suivante \: %2$s
topia.persistence.error.empty.doc=Document vide
topia.persistence.error.no.hibernate.session=Aucune session hibernate trouv\u00E9e, vous devez d\u00E9marr\u00E9 une transaction avec la m\u00E9thode 'beginTransaction'
-topia.persistence.error.null.parameter=Le param\u00E8tre %1$s de la m\u00E9thode %2$s ne peut pas \u00EAtre null\!
+topia.persistence.error.null.param=La m\u00E9thode '%1$s' requi\u00E8re un param\u00E8tre '%2$s' non null.
topia.persistence.error.on.backup=Une erreur est apparue pendant la sauvegarde \: %1$s
topia.persistence.error.on.clear=Une erreur est apparue pendant le nettoyage \: %1$s
topia.persistence.error.on.commit=Une erreur est apparue pendant le commit \: %1$s
@@ -14,7 +14,6 @@
topia.persistence.error.on.replicate=Une erreur est apparue pendant la replication \: %1$s
topia.persistence.error.on.restore=Une erreur est apparue pendant le restore \: %1$s
topia.persistence.error.on.rollback=Une erreur est apparue pendant le rollback \: %1$s
-topia.persistence.error.query.dao.notDefined=Aucun dao n'est d\u00E9fini dans la TopiaQuery, impossible de l'ex\u00E9cuter sans TopiaContext.
topia.persistence.error.replicate.entity=Echec de replication de l'entite %1$s\npour la raison suivante \: %2$s
topia.persistence.error.replicate.on.same.context=Impossible de dupliquer dans la m\u00EAme base
topia.persistence.error.rootContext.access=Vous \u00EAtes sur le root context, vous devez ouvrir une transaction pour pouvoir acc\u00E9der aux donn\u00E9es.
1
0
r2103 - trunk/topia-service-migration/src/main/java/org/nuiton/topia/migration
by tchemit@users.nuiton.org Aug. 21, 2010
by tchemit@users.nuiton.org Aug. 21, 2010
Aug. 21, 2010
Author: tchemit
Date: 2010-08-21 18:01:23 +0200 (Sat, 21 Aug 2010)
New Revision: 2103
Url: http://nuiton.org/repositories/revision/topia/2103
Log:
Anomalie #814: Migration must be controlled when restoring database
Modified:
trunk/topia-service-migration/src/main/java/org/nuiton/topia/migration/TopiaMigrationCallback.java
trunk/topia-service-migration/src/main/java/org/nuiton/topia/migration/TopiaMigrationEngine.java
Modified: trunk/topia-service-migration/src/main/java/org/nuiton/topia/migration/TopiaMigrationCallback.java
===================================================================
--- trunk/topia-service-migration/src/main/java/org/nuiton/topia/migration/TopiaMigrationCallback.java 2010-08-15 11:58:44 UTC (rev 2102)
+++ trunk/topia-service-migration/src/main/java/org/nuiton/topia/migration/TopiaMigrationCallback.java 2010-08-21 16:01:23 UTC (rev 2103)
@@ -100,53 +100,54 @@
List<Version> versions) {
boolean doMigrate = askUser(dbVersion, versions);
+ if (!doMigrate) {
+ // l'utilisateur a refuse la migration
+ return false;
+ }
+ TopiaContextImplementor tx;
- if (doMigrate) {
- TopiaContextImplementor tx;
+ for (Version v : versions) {
+ // ouverture d'une connexion direct JDBC sur la base
+ try {
- for (Version v : versions) {
- // ouverture d'une connexion direct JDBC sur la base
+ tx = (TopiaContextImplementor) ctxt.beginTransaction();
+
try {
- tx = (TopiaContextImplementor) ctxt.beginTransaction();
+ Method m = getMigrationMethod(v);
- try {
+ m.setAccessible(true);
- Method m = getMigrationMethod(v);
+ log.info(_("topia.migration.start.migrate", v));
- m.setAccessible(true);
+ if (log.isDebugEnabled()) {
+ log.debug("launch method " + m.getName());
+ }
- log.info(_("topia.migration.start.migrate", v));
+ m.invoke(this, tx, showSql, showProgression);
- if (log.isDebugEnabled()) {
- log.debug("launch method " + m.getName());
- }
+ // commit des modifs
+ tx.commitTransaction();
- m.invoke(this, tx, showSql, showProgression);
-
- // commit des modifs
- tx.commitTransaction();
-
- } catch (Exception eee) {
- // en cas d'erreur
- log.error("Migration impossible de la base", eee);
- // rollback du travail en cours
- tx.rollbackTransaction();
- // propagation de l'erreur
- throw eee;
- } finally {
- // close database connexion
- if (tx != null) {
- tx.closeContext();
- }
+ } catch (Exception eee) {
+ // en cas d'erreur
+ log.error("Migration impossible de la base", eee);
+ // rollback du travail en cours
+ tx.rollbackTransaction();
+ // propagation de l'erreur
+ throw eee;
+ } finally {
+ // close database connexion
+ if (tx != null) {
+ tx.closeContext();
}
+ }
- } catch (Exception eee) {
- log.error("Error lors de la tentative de migration", eee);
- doMigrate = false;
- // toute erreur arrête la mgration
- break;
- }
+ } catch (Exception eee) {
+ log.error("Error lors de la tentative de migration", eee);
+ doMigrate = false;
+ // toute erreur arrête la mgration
+ break;
}
}
return doMigrate;
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 2010-08-15 11:58:44 UTC (rev 2102)
+++ trunk/topia-service-migration/src/main/java/org/nuiton/topia/migration/TopiaMigrationEngine.java 2010-08-21 16:01:23 UTC (rev 2103)
@@ -156,12 +156,18 @@
if (log.isDebugEnabled()) {
log.debug("postRestoreSchema event detected, redo, schema migration");
}
- try {
- doMigrateSchema();
- } catch (Exception e) {
- if (log.isErrorEnabled()) {
- log.error("postRestoreSchema schema migration failed for reason " + e.getMessage(), e);
+ if (migrateOnInit) {
+ // do automatic migration
+ if (log.isDebugEnabled()) {
+ log.debug("Starts Migrate from postRestoreSchema...");
}
+ try {
+ doMigrateSchema();
+ } catch (Exception e) {
+ if (log.isErrorEnabled()) {
+ log.error("postRestoreSchema schema migration failed for reason " + e.getMessage(), e);
+ }
+ }
}
}
};
@@ -235,6 +241,7 @@
}
if (migrateOnInit) {
+ // do automatic migration
try {
if (log.isDebugEnabled()) {
@@ -339,7 +346,8 @@
log.info(_("topia.migration.skip.migration.no.version.to.apply"));
} else {
log.info(_("topia.migration.migrate.versions", versionsToApply));
- // ask handler for migration
+
+ // perform the migration
needToMigrate = callback.doMigration(rootContext,
dbVersion,
showSql,
@@ -367,7 +375,7 @@
saveApplicationVersion();
}
- // return succes flag
+ // return success flag
// - no migration needed
// - or migration needed and accepted
return true;
1
0
r2102 - trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication
by tchemit@users.nuiton.org Aug. 15, 2010
by tchemit@users.nuiton.org Aug. 15, 2010
Aug. 15, 2010
Author: tchemit
Date: 2010-08-15 13:58:44 +0200 (Sun, 15 Aug 2010)
New Revision: 2102
Url: http://nuiton.org/repositories/revision/topia/2102
Log:
remove TopiaReplicationImplementor
Removed:
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationImplementor.java
Deleted: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationImplementor.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationImplementor.java 2010-08-15 11:58:21 UTC (rev 2101)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationImplementor.java 2010-08-15 11:58:44 UTC (rev 2102)
@@ -1,180 +0,0 @@
-/*
- * #%L
- * ToPIA :: Service Replication
- *
- * $Id$
- * $HeadURL$
- * %%
- * Copyright (C) 2004 - 2010 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%
- */
-
-/* *
- * TopiaReplicationImplementor.java
- *
- * Created: 13 oct. 06 11:38:28
- *
- * @author tchemit
- * @version $Revision$
- *
- * Last update: $Date$
- * by : $Author$
- */
-package org.nuiton.topia.replication;
-
-import org.nuiton.topia.TopiaContext;
-import org.nuiton.topia.TopiaException;
-import org.nuiton.topia.framework.TopiaContextImplementor;
-import org.nuiton.topia.persistence.TopiaEntity;
-import org.nuiton.topia.persistence.TopiaEntityEnum;
-import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
-import org.nuiton.topia.replication.model.ReplicationModel;
-import org.nuiton.topia.replication.model.ReplicationNode;
-import org.nuiton.topia.replication.model.ReplicationOperationPhase;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * Class <b>previously</b> used internaly in framework, when you wanted
- * to implement new replication engine.
- * <p/>
- * Now we are using a {@link TopiaReplicationModelBuilderImpl} insde the implemented
- * service.
- *
- * @author tchemit <chemit(a)codelutin.com>
- * @since 2.2.0
- * @deprecated since 2.4.3, no more need of it, prefer use a {@link TopiaReplicationModelBuilderImpl}.
- */
-@Deprecated
-public interface TopiaReplicationImplementor extends TopiaReplicationService {
-
- /**
- * Creation d'un modele de replication non initialise.
- *
- * @param contracts le contrats d'entites autorises
- * @param topiaIds les ids des entites a repliquer
- * @return le modele instancie mais non initialise
- * @throws TopiaException pour toute erreur
- */
- ReplicationModel createModel(TopiaEntityEnum[] contracts, String... topiaIds) throws TopiaException;
-
- /**
- * Creation d'un modele de replication (en mode tout dupliquer) non initialise.
- *
- * @param contracts le contrats d'entites autorises
- * @return le modele instancie mais non initialise
- * @throws TopiaException pour toute erreur
- */
- ReplicationModel createModelForAll(TopiaEntityEnum[] contracts) throws TopiaException;
-
- /**
- * Creation d'un modele de replication non initialise avec un ordre fixe
- * (celui des contrats donnés).
- *
- * @param contracts le contrats d'entites autorises
- * @param topiaIds les ids des entities a repliquer
- * @return le modele instancie mais non initialise
- * @throws TopiaException pour toute erreur
- */
- ReplicationModel createModelWithComputedOrder(TopiaEntityEnum[] contracts, String... topiaIds) throws TopiaException;
-
- /**
- * Initialisation du modele de replication.
- * <p/>
- * Cette methode realise les calculs sur le modele pour obtenir l'ordre
- * de replication des entites {@link ReplicationModel#getOrder()}
- * et les operations a realiser lors de la replication sur chaque noeud
- * de replication {@link ReplicationNode#getOperations()}.
- *
- * @param model le modele a initialise
- * @param computeOrder drapeau pour effectuer le calcul d'ordre des
- * entites a repliquer, sinon on utilise l'ordre de creation des
- * noeuds dans le model.
- * @return le modele initialise
- * @throws TopiaException pour toute erreur
- */
- ReplicationModel initModel(ReplicationModel model, boolean computeOrder) throws TopiaException;
-
- Set<Class<? extends TopiaEntity>> detectTypes(TopiaEntityEnum[] contracts, String... ids) throws TopiaException;
-
- /**
- * Récupération d'une opération de réplication à partir de son type.
- *
- * @param operationClass le type de l'opération
- * @return l'opération du type donne
- */
- TopiaReplicationOperation getOperation(Class<? extends TopiaReplicationOperation> operationClass);
-
- /**
- * @param model le modele en cours
- * @param type le contrat de l'entite concerne
- * @param phase la phase de l'operation
- * @param operationClass le type de l'operation
- * @param parameters les parametres dynamiques de l'operation
- */
- void createOperation(ReplicationModel model,
- TopiaEntityEnum type,
- ReplicationOperationPhase phase,
- Class<? extends TopiaReplicationOperation> operationClass,
- Object... parameters);
-
- /**
- * Recupere les ids des entites a repliquer.
- *
- * @param model le modele utilise
- * @param srcCtxt le context de la base source
- * @return les ids des donnes a repliquer.
- * @throws TopiaException pour toute erreur de recuperation d'ids en base
- */
- TopiaEntityIdsMap getIds(
- ReplicationModel model,
- TopiaContextImplementor srcCtxt) throws TopiaException;
-
- /**
- * Lance la replication d'un noeud.
- *
- * @param node le noeud de replication
- * @param srcCtxt la base source
- * @param dstCtxt la base destination
- * @param data le dictionnaire des ids a repliquer
- * @param treated l'ensemble des noeuds deja repliques
- * @throws Exception pour tout erreur
- */
- void doReplicateNode(
- ReplicationNode node,
- TopiaContext srcCtxt,
- TopiaContext dstCtxt,
- TopiaEntityIdsMap data,
- List<ReplicationNode> treated) throws Exception;
-
- /**
- * Annule la replication d'un noeud.
- *
- * @param node le noeud de replication
- * @param srcCtxt la base source
- * @param dstCtxt la base destination
- * @param data le dictionnaire des ids a repliquer
- * @throws Exception pour toute erreur
- * @since 2.4.3
- */
- void doRollbackNode(
- ReplicationNode node,
- TopiaContext srcCtxt,
- TopiaContext dstCtxt,
- TopiaEntityIdsMap data) throws Exception;
-}
1
0
r2101 - in trunk/topia-service-replication/src: main/java/org/nuiton/topia/replication main/java/org/nuiton/topia/replication/model main/java/org/nuiton/topia/replication/operation main/resources/META-INF/services test/java/org/nuiton/topia/replication test/java/org/nuiton/topia/replication/operation test/resources/META-INF/services
by tchemit@users.nuiton.org Aug. 15, 2010
by tchemit@users.nuiton.org Aug. 15, 2010
Aug. 15, 2010
Author: tchemit
Date: 2010-08-15 13:58:21 +0200 (Sun, 15 Aug 2010)
New Revision: 2101
Url: http://nuiton.org/repositories/revision/topia/2101
Log:
- sanitize replication api
- decouple replication service and replication model builder
Added:
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilder.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilderImpl.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProvider.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProviderImpl.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationServiceImpl.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationLink.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/AbstractTopiaReplicationServiceTest.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationServiceImplAllTest.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationServiceImplTest.java
Removed:
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/ReplicationEngine.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/Link.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/AbstractReplicationEngineTest.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/ReplicationEngineAllTest.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/ReplicationEngineTest.java
Modified:
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationImplementor.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationService.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationModel.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachAssociation.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachLink.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/DettachAssociation.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/Duplicate.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/LoadLink.java
trunk/topia-service-replication/src/main/resources/META-INF/services/org.nuiton.topia.replication.TopiaReplicationOperation
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationOperationTest.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/FakeOperation.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UncreatableOperation.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UnregistredOperation.java
trunk/topia-service-replication/src/test/resources/META-INF/services/org.nuiton.topia.replication.TopiaReplicationOperation
Deleted: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/ReplicationEngine.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/ReplicationEngine.java 2010-08-15 11:51:20 UTC (rev 2100)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/ReplicationEngine.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -1,688 +0,0 @@
-/*
- * #%L
- * ToPIA :: Service Replication
- *
- * $Id$
- * $HeadURL$
- * %%
- * Copyright (C) 2004 - 2010 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%
- */
-
-package org.nuiton.topia.replication;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.nuiton.topia.TopiaContext;
-import org.nuiton.topia.TopiaException;
-import org.nuiton.topia.framework.TopiaContextImplementor;
-import org.nuiton.topia.persistence.TopiaEntity;
-import org.nuiton.topia.persistence.TopiaEntityEnum;
-import org.nuiton.topia.persistence.util.TopiaEntityHelper;
-import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
-import org.nuiton.topia.replication.model.ReplicationModel;
-import org.nuiton.topia.replication.model.ReplicationNode;
-import org.nuiton.topia.replication.model.ReplicationOperationDef;
-import org.nuiton.topia.replication.model.ReplicationOperationPhase;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.ServiceLoader;
-import java.util.Set;
-
-import static org.nuiton.i18n.I18n._;
-
-/**
- * Implantation du service de replication.
- *
- * @author tchemit <chemit(a)codelutin.com>
- * @since 2.2.0
- */
-public class ReplicationEngine implements TopiaReplicationImplementor {
-
- /** Logger */
- private static final Log log = LogFactory.getLog(ReplicationEngine.class);
-
- /** le contexte sur la base source de la replication */
- protected TopiaContextImplementor context;
-
- /**
- * la liste des operations disponibles (chargee automatiquement via un
- * ServiceLoader sur le contract {@link TopiaReplicationOperation})
- *
- * @see #preInit(TopiaContextImplementor)
- */
- protected TopiaReplicationOperation[] operations;
-
- //--------------------------------------------------------------------------
- //-- TopiaService implementation -------------------------------------------
- //--------------------------------------------------------------------------
-
- @Override
- public String getServiceName() {
- return SERVICE_NAME;
- }
-
- @Override
- public Class<?>[] getPersistenceClasses() {
- // pas de classes persistentes pour ce service
- return null;
- }
-
- @Override
- public boolean preInit(TopiaContextImplementor context) {
- if (operations == null) {
- // chargement des operations disponibles une seule fois
-
- ServiceLoader<TopiaReplicationOperation> loader =
- ServiceLoader.load(TopiaReplicationOperation.class);
-
- List<TopiaReplicationOperation> operations =
- new ArrayList<TopiaReplicationOperation>();
-
- for (TopiaReplicationOperation op : loader) {
- if (log.isDebugEnabled()) {
- log.debug("detected operation " + op);
- }
- operations.add(op);
- }
- this.operations = operations.toArray(
- new TopiaReplicationOperation[operations.size()]);
- }
- return true;
- }
-
- @Override
- public boolean postInit(TopiaContextImplementor context) {
- this.context = context;
- //TODO avoir un objet pour lire les contrainte de resolution de cycle
- //TODO sur les dependances (par exemple, une dependance marquee comme
- // non nulle : ne peut jamais etre dettache, alors que dans le cas
- // contraire on peut dettacher la dependance
- // Cela permet de traiter plus de cas...
-
- //Properties prop = context.getConfig();
- return true;
- }
-
- //--------------------------------------------------------------------------
- //-- TopiaReplicationService implementation --------------------------------
- //--------------------------------------------------------------------------
-
- @Override
- public ReplicationModel prepare(TopiaEntityEnum[] contracts,
- String... entities) throws TopiaException {
- ReplicationModel model = createModel(contracts, entities);
-
- initModel(model, true);
-
- return model;
- }
-
- @Override
- public ReplicationModel prepareForAll(TopiaEntityEnum[] contracts) throws TopiaException {
- ReplicationModel model = createModelForAll(contracts);
-
- initModel(model, true);
-
- return model;
- }
-
- @Override
- public ReplicationModel prepareWithComputedOrder(TopiaEntityEnum[] contracts,
- String... topiaIds) throws TopiaException {
- ReplicationModel model = createModelWithComputedOrder(contracts, topiaIds);
-
- initModel(model, false);
-
- return model;
- }
-
- @Override
- public void addBeforeOperation(ReplicationModel model,
- TopiaEntityEnum type,
- Class<? extends TopiaReplicationOperation> operationClass,
- Object... parameters) {
- createOperation(model,
- type,
- ReplicationOperationPhase.before,
- operationClass,
- parameters
- );
- }
-
- @Override
- public void addAfterOperation(ReplicationModel model,
- TopiaEntityEnum type,
- Class<? extends TopiaReplicationOperation> operationClass,
- Object... parameters) {
- createOperation(model,
- type,
- ReplicationOperationPhase.after,
- operationClass,
- parameters
- );
- }
-
- @Override
- public void doReplicate(ReplicationModel model,
- TopiaContext dstCtxt) throws Exception {
-
- checkNotNull("doReplicate", "model", model);
- checkNotNull("doReplicate", "dstCtxt", dstCtxt);
-
- TopiaContextImplementor srcCtxt = null;
-
- TopiaEntityIdsMap data = null;
-
- // keep the list of treated nodes (to roolback them if something
- // is wrong).
- List<ReplicationNode> treated = new ArrayList<ReplicationNode>();
- try {
-
- srcCtxt = (TopiaContextImplementor) context.beginTransaction();
-
- data = getIds(model, srcCtxt);
-
- srcCtxt.closeContext();
-
- model.adjustOperations(data);
-
- //FIXME tchemit 2077-07-26, should use next line when
- // http://nuiton.org/issues/show/779 is closed
- boolean needTransaction = true;
-// boolean needTransaction = ((TopiaContextImplementor) dstCtxt).getRootContext().equals(dstCtxt);
-
- TopiaContext tx;
-
- for (ReplicationNode node : model.getOrder()) {
-
- srcCtxt = (TopiaContextImplementor) context.beginTransaction();
-
- if (needTransaction) {
- tx = dstCtxt.beginTransaction();
- } else {
- tx = dstCtxt;
- }
- try {
- doReplicateNode(node, srcCtxt, tx, data, treated);
- } catch (Exception e) {
-
- // un erreur est survenu sur le noeud de réplication
- // on rollback la transaction de ce noeud
- try {
- tx.rollbackTransaction();
- } finally {
-
- // on revert les noeuds deja commite
- doRollback(model, data, treated, dstCtxt);
- }
-
- throw e;
- } finally {
- srcCtxt.closeContext();
- if (needTransaction) {
- // on doit fermer la transaction car on l'a ouverte dans
- // cette méthode, sinon c'est de la responsabilite du
- // code appellant
- tx.closeContext();
- }
- }
- }
-// } catch (Exception e) {
-// dstCtxt.rollbackTransaction();
-// throw e;
- } finally {
- if (data != null) {
- data.clear();
- }
- if (treated != null) {
- treated.clear();
- }
- // on ne doit jamais commiter sur la base source
- if (srcCtxt != null && !srcCtxt.isClosed()) {
- srcCtxt.rollbackTransaction();
- srcCtxt.closeContext();
- }
-// dstCtxt.closeContext();
- }
- }
-
- @Override
- public void doRollback(ReplicationModel model,
- TopiaEntityIdsMap data,
- List<ReplicationNode> nodes,
- TopiaContext dstCtxt) throws Exception {
- if (nodes.isEmpty()) {
-
- // aucun noeud de réplication commités
- return;
- }
-
- TopiaContextImplementor srcCtxt;
-
- TopiaContext tx;
-
- boolean needTransaction = true;
-
- log.info("Will rollback " + nodes.size() + " nodes...");
-
- for (ReplicationNode node : nodes) {
-
- log.info("Rollback node " + node);
- srcCtxt = (TopiaContextImplementor) context.beginTransaction();
-
- if (needTransaction) {
- tx = dstCtxt.beginTransaction();
- } else {
- tx = dstCtxt;
- }
- try {
- doRollbackNode(node, srcCtxt, tx, data);
- } catch (Exception e) {
-
- // un erreur est survenu sur le noeud de réplication
- // on rollback la transaction de ce noeud
-
- tx.rollbackTransaction();
-
- } finally {
- srcCtxt.rollbackTransaction();
- srcCtxt.closeContext();
-
- if (needTransaction) {
- // on doit fermer la transaction car on l'a ouverte dans
- // cette méthode, sinon c'est de la responsabilite du
- // code appellant
- tx.closeContext();
- }
- }
-
- }
- }
-
- //--------------------------------------------------------------------------
- //-- TopiaReplicationImplementor implementation ----------------------------
- //--------------------------------------------------------------------------
-
- @Override
- public ReplicationModel createModel(TopiaEntityEnum[] contracts,
- String... topiaIds)
- throws TopiaException {
-
- Set<Class<? extends TopiaEntity>> detectTypes =
- detectTypes(contracts, topiaIds);
- ReplicationModel model =
- new ReplicationModel(contracts, detectTypes, topiaIds);
- return model;
- }
-
- @Override
- public ReplicationModel createModelWithComputedOrder(
- TopiaEntityEnum[] contracts, String... topiaIds)
- throws TopiaException {
- ReplicationModel model =
- new ReplicationModel(contracts, false, topiaIds);
- return model;
- }
-
- @Override
- public ReplicationModel createModelForAll(TopiaEntityEnum[] contracts)
- throws TopiaException {
- ReplicationModel model = new ReplicationModel(contracts, true);
- return model;
- }
-
- @Override
- public ReplicationModel initModel(ReplicationModel model,
- boolean computeOrder)
- throws TopiaException {
- checkNotNull("initModel", "model", model);
-
- model.detectAssociations();
- model.detectDirectDependencies();
- if (computeOrder) {
- model.detectShell();
- model.detectDependencies();
- }
- model.detectObjectsToDettach();
- model.detectOperations();
- return model;
- }
-
- @Override
- public TopiaReplicationOperation getOperation(
- Class<? extends TopiaReplicationOperation> operationClass) {
- checkNotNull("getOperation", "operationClass", operationClass);
-
- if (operations == null) {
- throw new IllegalStateException("service was not init!");
- }
- TopiaReplicationOperation result = null;
-
- for (TopiaReplicationOperation op : operations) {
- if (operationClass.isAssignableFrom(op.getClass())) {
- result = op;
- break;
- }
- }
- return result;
- }
-
- @Override
- public void createOperation(ReplicationModel model,
- TopiaEntityEnum type,
- ReplicationOperationPhase phase,
- Class<? extends TopiaReplicationOperation> operationClass,
- Object... parameters) {
-
- checkNotNull("createOperation", "model", model);
- checkNotNull("createOperation", "type", type);
- checkNotNull("createOperation", "phase", phase);
- checkNotNull("createOperation", "operationClass", operationClass);
-
- TopiaReplicationOperation operation = getOperation(operationClass);
-
- if (operation == null) {
- throw new IllegalArgumentException(
- _("topia.replication.engine.error.unkown.operation",
- operationClass.getSimpleName(),
- Arrays.toString(operations))
- );
- }
-
- ReplicationNode node = model.getNode(type);
- if (node == null) {
- throw new IllegalArgumentException(
- _("topia.replication.engine.error.unkown.owner.node",
- type,
- operationClass.getSimpleName(),
- model.getNodes())
- );
- }
- operation.register(model, node, phase, parameters);
- }
-
- @Override
- public Set<Class<? extends TopiaEntity>> detectTypes(
- TopiaEntityEnum[] contracts, String... ids) throws TopiaException {
- TopiaContext ctxt = context.beginTransaction();
- try {
- TopiaEntity[] entities = getEntities(ctxt, ids);
-
- // on detecte tous les types connus pour les entites données
- Set<Class<? extends TopiaEntity>> types =
- TopiaEntityHelper.detectTypes(contracts, entities);
-
- if (log.isDebugEnabled()) {
- log.debug("for type : " + entities.getClass());
- for (Class<? extends TopiaEntity> k : types) {
- log.debug(k);
- }
- }
- return types;
- } finally {
- ctxt.closeContext();
- }
- }
-
- @Override
- public TopiaEntityIdsMap getIds(ReplicationModel model,
- TopiaContextImplementor srcCtxt)
- throws TopiaException {
-
- TopiaEntityIdsMap data;
-
- // on recupere les objets a repliquer par type
- if (model.isReplicateAll()) {
-
- // on recupere pour chaque type tous les ids des entites a repliquer
- data = new TopiaEntityIdsMap();
- for (TopiaEntityEnum e : model.getContracts()) {
- List<String> ids = srcCtxt.getDAO(e.getContract()).findAllIds();
- data.put(e.getContract(), ids);
- }
- } else {
-
- // on recupere les entites specifies a repliquer
- TopiaEntity[] entities = getEntities(srcCtxt,
- model.getTopiaIds()
- );
-
- // on calcule toutes les ids des entites a repliquer
- data = TopiaEntityHelper.detectEntityIds(model.getContracts(),
- model.getTypes(),
- entities
- );
- }
- return data;
- }
-
- @Override
- public void doReplicateNode(
- ReplicationNode node,
- TopiaContext srcCtxt,
- TopiaContext dstCtxt,
- TopiaEntityIdsMap data,
- List<ReplicationNode> treated) throws Exception {
-
- // on trie toujours les operations a realiser selon leur phase
- // (avant ou apres la duplication)
- node.sortOperations();
-
- List<ReplicationOperationDef> operationDefs = node.getOperations();
-
- if (operationDefs.isEmpty()) {
- log.info("skip node " + node + " - no operation detected.");
- } else {
-
- log.info("start for " + node + " : " + operationDefs.size() +
- " operation(s)");
-
- List<String> nodeEntityIds =
- data.get(node.getContract().getContract());
-
- if (log.isInfoEnabled()) {
- log.info("will replicate on " + nodeEntityIds.size() +
- " entity(ies)");
- }
- if (log.isDebugEnabled()) {
- for (String id : nodeEntityIds) {
- log.debug(id);
- }
- }
-
- List<? extends TopiaEntity> nodeEntities = getEntitiesList(
- srcCtxt,
- nodeEntityIds.toArray(new String[nodeEntityIds.size()])
- );
-
- for (ReplicationOperationDef operationDef : operationDefs) {
-
- log.info("start " + operationDef);
-
- TopiaReplicationOperation operation =
- getOperation(operationDef.getOperationClass());
-
- operation.run(operationDef,
- (TopiaContextImplementor) srcCtxt,
- (TopiaContextImplementor) dstCtxt,
- nodeEntities,
- data
- );
-
- }
- // on rollback le context source (car on a peut-etre modifie
- // des associations ou des dependances mais on ne veut rien
- // retenir au niveau d'hibernate, sinon on s'expose a des erreurs
- // lorsque l'on veut recharger des objets dans le context...)
- srcCtxt.rollbackTransaction();
- }
-
- treated.add(node);
- }
-
-
- @Override
- public void doRollbackNode(
- ReplicationNode node,
- TopiaContext srcCtxt,
- TopiaContext dstCtxt,
- TopiaEntityIdsMap data) throws Exception {
-
- // on trie toujours les operations a realiser selon leur phase
- // (avant ou apres la duplication)
- node.sortOperations();
-
- List<ReplicationOperationDef> operationDefs = node.getOperations();
-
- if (operationDefs.isEmpty()) {
- log.info("skip node " + node + " - no operation detected.");
- } else {
-
- log.info("start for " + node + " : " + operationDefs.size() +
- " operation(s)");
-
- List<String> nodeEntityIds =
- data.get(node.getContract().getContract());
- if (log.isInfoEnabled()) {
- log.info("will replicate on " + nodeEntityIds.size() +
- " entity(ies)");
- }
- if (log.isDebugEnabled()) {
- for (String id : nodeEntityIds) {
- log.debug(id);
- }
- }
-
- List<? extends TopiaEntity> nodeEntities = getEntitiesList(
- srcCtxt,
- nodeEntityIds.toArray(new String[nodeEntityIds.size()])
- );
-
- for (ReplicationOperationDef operationDef : operationDefs) {
-
- log.info("start " + operationDef);
-
- TopiaReplicationOperation operation =
- getOperation(operationDef.getOperationClass());
-
- operation.rollback(operationDef,
- (TopiaContextImplementor) srcCtxt,
- (TopiaContextImplementor) dstCtxt,
- nodeEntities,
- data
- );
-
- }
- // on rollback le context source (car on a peut-etre modifie
- // des associations ou des dependances mais on ne veut rien
- // retenir au niveau d'hibernate, sinon on s'expose a des erreurs
- // lorsque l'on veut recharger des objets dans le context...)
- srcCtxt.rollbackTransaction();
- }
- }
-
- @SuppressWarnings({"unchecked"})
- public static <E extends TopiaEntity> List<E> getEntities(
- TopiaContextImplementor srcCtxt,
- List<E> entityList,
- boolean canBeNull) throws TopiaException {
- List<E> srcList = new ArrayList<E>(entityList.size());
- for (E e : entityList) {
- E e2 = (E) srcCtxt.findByTopiaId(e.getTopiaId());
- if (e2 == null && !canBeNull) {
-// if (!canBeNull) {
-// throw new IllegalStateException(
-// "topia.replication.engine.error.entity.must.exists");
-// }
- continue;
- }
- srcList.add(e2);
- }
- return srcList;
- }
-
- public static TopiaEntity[] getEntities(TopiaContext srcCtxt,
- String... entityList)
- throws TopiaException {
- TopiaEntity[] srcList = new TopiaEntity[entityList.length];
- int index = 0;
- for (String id : entityList) {
- TopiaEntity e2 = srcCtxt.findByTopiaId(id);
- srcList[index++] = e2;
- }
- return srcList;
- }
-
- public static List<? extends TopiaEntity> getEntitiesList(
- TopiaContext srcCtxt,
- String... entityList) throws TopiaException {
- List<TopiaEntity> srcList = new ArrayList<TopiaEntity>(entityList.length);
- for (String id : entityList) {
- TopiaEntity e2 = srcCtxt.findByTopiaId(id);
- srcList.add(e2);
- }
- return srcList;
- }
-
- public static void checkNotNull(String methodName,
- String parameterName,
- Object value) {
- if (value == null) {
- throw new NullPointerException(
- _("topia.replication.engine.error.null.param",
- parameterName, methodName));
- }
- }
-
- public static void checkParameters(Class<?>[] paramsType,
- Object... params) {
- checkSize(paramsType.length, params);
- for (int i = 0, j = paramsType.length; i < j; i++) {
- checkType(paramsType, i, params);
- }
- }
-
- public static void checkSize(int size, Object[] params) {
- if (params.length != size) {
- throw new IllegalArgumentException(
- "l'operation requiere " + size + " parametres mais en a " +
- params.length);
- }
- }
-
- public static void checkType(Class<?>[] paramsType,
- int index,
- Object[] params) {
- Class<?> requiredType = paramsType[index];
- Object value = params[index];
- if (value == null) {
- throw new IllegalArgumentException(
- "le parametre de positiion" + index + " est null!");
- }
- Class<?> foundType = value.getClass();
-
- if (!requiredType.isAssignableFrom(foundType)) {
- throw new IllegalArgumentException(
- "le paremetre de position " + index +
- " requiere un parametre de type " + requiredType +
- " mais est de type " + foundType);
- }
- }
-}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationImplementor.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationImplementor.java 2010-08-15 11:51:20 UTC (rev 2100)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationImplementor.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -50,12 +50,17 @@
import java.util.Set;
/**
- * Class used internaly in framework, when you want implement new replication
- * engin, you must used this interface
+ * Class <b>previously</b> used internaly in framework, when you wanted
+ * to implement new replication engine.
+ * <p/>
+ * Now we are using a {@link TopiaReplicationModelBuilderImpl} insde the implemented
+ * service.
*
* @author tchemit <chemit(a)codelutin.com>
* @since 2.2.0
+ * @deprecated since 2.4.3, no more need of it, prefer use a {@link TopiaReplicationModelBuilderImpl}.
*/
+@Deprecated
public interface TopiaReplicationImplementor extends TopiaReplicationService {
/**
@@ -171,5 +176,5 @@
ReplicationNode node,
TopiaContext srcCtxt,
TopiaContext dstCtxt,
- TopiaEntityIdsMap data) throws Exception;
+ TopiaEntityIdsMap data) throws Exception;
}
Added: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilder.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilder.java (rev 0)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilder.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -0,0 +1,146 @@
+/*
+ * #%L
+ * ToPIA :: Service Replication
+ *
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2004 - 2010 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%
+ */
+package org.nuiton.topia.replication;
+
+import org.nuiton.topia.TopiaContext;
+import org.nuiton.topia.TopiaException;
+import org.nuiton.topia.persistence.TopiaEntity;
+import org.nuiton.topia.persistence.TopiaEntityEnum;
+import org.nuiton.topia.replication.model.ReplicationModel;
+import org.nuiton.topia.replication.model.ReplicationOperationPhase;
+
+import java.util.Set;
+
+/**
+ * Helper to create {@link ReplicationModel}.
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.4.3
+ */
+public interface TopiaReplicationModelBuilder {
+
+ TopiaReplicationOperationProvider getOperationProvider();
+
+ TopiaReplicationOperation getOperation(Class<? extends TopiaReplicationOperation> operationClass);
+
+ TopiaReplicationOperation[] getOperations();
+
+ /**
+ * Creation d'un modele de replication non initialise.
+ *
+ * @param context topia context on which entities are loaded
+ * @param contracts le contrats d'entites autorises
+ * @param topiaIds les ids des entites a repliquer
+ * @return le modele instancie mais non initialise
+ * @throws TopiaException pour toute erreur
+ */
+ ReplicationModel createModel(TopiaContext context,
+ TopiaEntityEnum[] contracts,
+ String... topiaIds) throws TopiaException;
+
+ /**
+ * Creation d'un modele de replication non initialise avec un ordre fixe
+ * (celui des contrats donnés).
+ *
+ * @param contracts le contrats d'entites autorises
+ * @param topiaIds les ids des entities a repliquer
+ * @return le modele instancie mais non initialise
+ * @throws TopiaException pour toute erreur
+ */
+ ReplicationModel createModelWithComputedOrder(
+ TopiaEntityEnum[] contracts,
+ String... topiaIds) throws TopiaException;
+
+ /**
+ * Creation d'un modele de replication (en mode tout dupliquer) non initialise.
+ *
+ * @param contracts le contrats d'entites autorises
+ * @return le modele instancie mais non initialise
+ * @throws TopiaException pour toute erreur
+ */
+ ReplicationModel createModelForAll(TopiaEntityEnum[] contracts)
+ throws TopiaException;
+
+
+ ReplicationModel prepare(TopiaContext context,
+ TopiaEntityEnum[] contracts,
+ String... entities) throws TopiaException;
+
+ /**
+ * Prepare le modele de replication pour toutes les entites des types
+ * donnes.
+ * <p/>
+ * La méthode calcule l'ordre de replication des données.
+ * <p/>
+ * Actuellement, on n'est pas capable de calculer l'ordre si le graphe des
+ * entités contient des cycles.
+ * <p/>
+ * TODO : faire en sorte de pouvoir gérer les cycles.
+ *
+ * @param contracts les contrats des types a repliquer
+ * @return le modele pour la replication
+ * @throws TopiaException pour toute erreur rencontree
+ */
+ ReplicationModel prepareForAll(TopiaEntityEnum[] contracts) throws TopiaException;
+
+ /**
+ * Prepare le modele de replication pour les entites données en ne faisant
+ * pas de calcul sur l'ordre des entités à répliquer.
+ * <p/>
+ * L'ordre des types donnees sera celui utilisé.
+ *
+ * @param contracts les contrats a repliquer (dans l'ordre donnée)
+ * @param topiaIds les ids des entites a repliquer
+ * @return le model de replication initialise
+ * @throws TopiaException pour toute erreur recontree
+ */
+ ReplicationModel prepareWithComputedOrder(TopiaEntityEnum[] contracts,
+ String... topiaIds) throws TopiaException;
+
+ Set<Class<? extends TopiaEntity>> detectTypes(
+ TopiaContext context,
+ TopiaEntityEnum[] contracts, String... ids) throws TopiaException;
+
+ ReplicationModel initModel(ReplicationModel model,
+ boolean computeOrder)
+ throws TopiaException;
+
+ void addBeforeOperation(ReplicationModel model,
+ TopiaEntityEnum type,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... parameters);
+
+ void addAfterOperation(ReplicationModel model,
+ TopiaEntityEnum type,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... parameters);
+
+ void createOperation(
+ ReplicationModel model,
+ TopiaEntityEnum type,
+ ReplicationOperationPhase phase,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... parameters);
+}
Added: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilderImpl.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilderImpl.java (rev 0)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationModelBuilderImpl.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -0,0 +1,258 @@
+/*
+ * #%L
+ * ToPIA :: Service Replication
+ *
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2004 - 2010 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%
+ */
+package org.nuiton.topia.replication;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nuiton.topia.TopiaContext;
+import org.nuiton.topia.TopiaException;
+import org.nuiton.topia.persistence.TopiaEntity;
+import org.nuiton.topia.persistence.TopiaEntityEnum;
+import org.nuiton.topia.persistence.util.TopiaEntityHelper;
+import org.nuiton.topia.replication.model.ReplicationModel;
+import org.nuiton.topia.replication.model.ReplicationNode;
+import org.nuiton.topia.replication.model.ReplicationOperationPhase;
+
+import java.util.Arrays;
+import java.util.Set;
+
+import static org.nuiton.i18n.I18n._;
+
+/**
+ * Default implementation of {@link TopiaReplicationModelBuilder}.
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.4.3
+ */
+public class TopiaReplicationModelBuilderImpl implements TopiaReplicationModelBuilder {
+
+ /** Logger */
+ private static final Log log =
+ LogFactory.getLog(TopiaReplicationModelBuilderImpl.class);
+
+ protected TopiaReplicationOperationProvider operationProvider;
+
+ @Override
+ public TopiaReplicationOperationProvider getOperationProvider() {
+ if (operationProvider == null) {
+ operationProvider = new TopiaReplicationOperationProviderImpl();
+ }
+ return operationProvider;
+ }
+
+ @Override
+ public TopiaReplicationOperation getOperation(Class<? extends TopiaReplicationOperation> operationClass) {
+ return getOperationProvider().getOperation(operationClass);
+ }
+
+ @Override
+ public TopiaReplicationOperation[] getOperations() {
+ return getOperationProvider().getOperations();
+ }
+
+
+ @Override
+ public ReplicationModel createModel(TopiaContext context,
+ TopiaEntityEnum[] contracts,
+ String... topiaIds)
+ throws TopiaException {
+
+ Set<Class<? extends TopiaEntity>> detectTypes =
+ detectTypes(context, contracts, topiaIds);
+ ReplicationModel model =
+ new ReplicationModel(contracts, detectTypes, topiaIds);
+ return model;
+ }
+
+
+ @Override
+ public ReplicationModel createModelWithComputedOrder(
+ TopiaEntityEnum[] contracts,
+ String... topiaIds)
+ throws TopiaException {
+ ReplicationModel model =
+ new ReplicationModel(contracts, false, topiaIds);
+ return model;
+ }
+
+
+ @Override
+ public ReplicationModel createModelForAll(TopiaEntityEnum[] contracts)
+ throws TopiaException {
+ ReplicationModel model = new ReplicationModel(contracts, true);
+ return model;
+ }
+
+ @Override
+ public void createOperation(
+ ReplicationModel model,
+ TopiaEntityEnum type,
+ ReplicationOperationPhase phase,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... parameters) {
+
+ TopiaEntityHelper.checkNotNull("createOperation", "provider", operationProvider);
+ TopiaEntityHelper.checkNotNull("createOperation", "model", model);
+ TopiaEntityHelper.checkNotNull("createOperation", "type", type);
+ TopiaEntityHelper.checkNotNull("createOperation", "phase", phase);
+ TopiaEntityHelper.checkNotNull("createOperation", "operationClass", operationClass);
+
+ TopiaReplicationOperation operation = operationProvider.getOperation(operationClass);
+
+ if (operation == null) {
+ throw new IllegalArgumentException(
+ _("topia.replication.engine.error.unkown.operation",
+ operationClass.getSimpleName(),
+ Arrays.toString(operationProvider.getOperations()))
+ );
+ }
+
+ ReplicationNode node = model.getNode(type);
+ if (node == null) {
+ throw new IllegalArgumentException(
+ _("topia.replication.engine.error.unkown.owner.node",
+ type,
+ operationClass.getSimpleName(),
+ model.getNodes())
+ );
+ }
+ operation.register(model, node, phase, parameters);
+ }
+
+
+ @Override
+ public ReplicationModel prepare(TopiaContext context,
+ TopiaEntityEnum[] contracts,
+ String... entities) throws TopiaException {
+ ReplicationModel model =
+ createModel(context, contracts, entities);
+ initModel(model, true);
+ return model;
+ }
+
+
+ @Override
+ public ReplicationModel prepareForAll(TopiaEntityEnum[] contracts) throws TopiaException {
+ ReplicationModel model = createModelForAll(contracts);
+ initModel(model, true);
+ return model;
+ }
+
+
+ @Override
+ public ReplicationModel prepareWithComputedOrder(TopiaEntityEnum[] contracts,
+ String... topiaIds) throws TopiaException {
+ ReplicationModel model =
+ createModelWithComputedOrder(contracts, topiaIds);
+ initModel(model, false);
+ return model;
+ }
+
+ @Override
+ public Set<Class<? extends TopiaEntity>> detectTypes(TopiaContext context,
+ TopiaEntityEnum[] contracts,
+ String... ids) throws TopiaException {
+
+ TopiaContext ctxt = context.beginTransaction();
+ try {
+ TopiaEntity[] entities = TopiaEntityHelper.getEntities(ctxt, ids);
+
+ // on detecte tous les types connus pour les entites données
+ Set<Class<? extends TopiaEntity>> types =
+ TopiaEntityHelper.detectTypes(contracts, entities);
+
+ if (log.isDebugEnabled()) {
+ log.debug("for type : " + entities.getClass());
+ for (Class<? extends TopiaEntity> k : types) {
+ log.debug(k);
+ }
+ }
+ return types;
+ } finally {
+ ctxt.closeContext();
+ }
+ }
+
+ @Override
+ public ReplicationModel initModel(ReplicationModel model,
+ boolean computeOrder) throws TopiaException {
+ TopiaEntityHelper.checkNotNull("initModel", "model", model);
+
+ model.detectAssociations();
+ model.detectDirectDependencies();
+ if (computeOrder) {
+ model.detectShell();
+ model.detectDependencies();
+ }
+ model.detectObjectsToDettach();
+ model.detectOperations();
+ return model;
+ }
+
+
+ /**
+ * Ajouter une nouvelle operation pre-replication, sur un type de donnee.
+ *
+ * @param model le modele de replication
+ * @param type le type du noeud de replication
+ * @param operationClass l'implantation de l'operation
+ * @param parameters les parametres supplementaires pour l'operation
+ */
+ @Override
+ public void addBeforeOperation(ReplicationModel model,
+ TopiaEntityEnum type,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... parameters) {
+ createOperation(
+ model,
+ type,
+ ReplicationOperationPhase.before,
+ operationClass,
+ parameters
+ );
+ }
+
+ /**
+ * Ajouter une nouvelle operation post-replication, sur un type de donnee.
+ *
+ * @param model le modele de replication
+ * @param type le type du noeud de replication
+ * @param operationClass l'implantation de l'operation
+ * @param parameters les parametres supplementaires pour l'operation
+ */
+ @Override
+ public void addAfterOperation(ReplicationModel model,
+ TopiaEntityEnum type,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... parameters) {
+ createOperation(
+ model,
+ type,
+ ReplicationOperationPhase.after,
+ operationClass,
+ parameters
+ );
+ }
+}
Added: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProvider.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProvider.java (rev 0)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProvider.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -0,0 +1,53 @@
+/*
+ * #%L
+ * ToPIA :: Service Replication
+ *
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2004 - 2010 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%
+ */
+package org.nuiton.topia.replication;
+
+import java.util.ServiceLoader;
+
+/**
+ * Provider of {@link TopiaReplicationOperation}.
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.4.3
+ */
+public interface TopiaReplicationOperationProvider {
+
+ /**
+ * Obtains all {@link TopiaReplicationOperation} available
+ * via {@link ServiceLoader}.
+ *
+ * @return the array of available operations
+ */
+ TopiaReplicationOperation[] getOperations();
+
+ /**
+ * Obtains the instanciated (and initialized) operation of the given type.
+ *
+ * @param operationClass type of searched operation
+ * @return the found operation, or {@code null} if not found.
+ */
+ TopiaReplicationOperation getOperation(
+ Class<? extends TopiaReplicationOperation> operationClass);
+}
Added: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProviderImpl.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProviderImpl.java (rev 0)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperationProviderImpl.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -0,0 +1,92 @@
+/*
+ * #%L
+ * ToPIA :: Service Replication
+ *
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2004 - 2010 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%
+ */
+package org.nuiton.topia.replication;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nuiton.topia.persistence.util.TopiaEntityHelper;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ServiceLoader;
+
+/**
+ * Default implementation of {@link TopiaReplicationOperationProvider}.
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.4.3
+ */
+public class TopiaReplicationOperationProviderImpl implements TopiaReplicationOperationProvider {
+
+ /** Logger */
+ private static final Log log =
+ LogFactory.getLog(TopiaReplicationOperationProviderImpl.class);
+
+ /**
+ * la liste des operations disponibles (chargee automatiquement via un
+ * ServiceLoader sur le contract {@link TopiaReplicationOperation})
+ */
+ protected TopiaReplicationOperation[] operations;
+
+ @Override
+ public TopiaReplicationOperation[] getOperations() {
+ if (operations == null) {
+ // chargement des operations disponibles une seule fois
+
+ ServiceLoader<TopiaReplicationOperation> loader =
+ ServiceLoader.load(TopiaReplicationOperation.class);
+
+ List<TopiaReplicationOperation> operations =
+ new ArrayList<TopiaReplicationOperation>();
+
+ for (TopiaReplicationOperation op : loader) {
+ if (log.isDebugEnabled()) {
+ log.debug("detected operation " + op);
+ }
+ operations.add(op);
+ }
+ this.operations = operations.toArray(
+ new TopiaReplicationOperation[operations.size()]);
+ }
+ return operations;
+ }
+
+ @Override
+ public TopiaReplicationOperation getOperation(
+ Class<? extends TopiaReplicationOperation> operationClass) {
+
+ TopiaEntityHelper.checkNotNull("getOperation", "operationClass",
+ operationClass);
+ TopiaReplicationOperation result = null;
+
+ for (TopiaReplicationOperation op : getOperations()) {
+ if (operationClass.isAssignableFrom(op.getClass())) {
+ result = op;
+ break;
+ }
+ }
+ return result;
+ }
+}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationService.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationService.java 2010-08-15 11:51:20 UTC (rev 2100)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationService.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -22,18 +22,6 @@
* <http://www.gnu.org/licenses/lgpl-3.0.html>.
* #L%
*/
-
-/* *
- * IndexEngin.java
- *
- * Created: 8 oct. 06 17:15:00
- *
- * @author poussin <poussin(a)codelutin.com>
- * @version $Revision$
- *
- * Last update: $Date$
- * by : $Author$
- */
package org.nuiton.topia.replication;
import org.nuiton.topia.TopiaContext;
@@ -72,6 +60,8 @@
/** Nom du service topia */
String TOPIA_SERVICE_NAME = "topia.service.replication";
+ TopiaReplicationModelBuilder getModelBuilder();
+
/**
* Prepare le modele de replication pour les entites dans les topiaIds sont
* donnes.
Copied: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationServiceImpl.java (from rev 2098, trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/ReplicationEngine.java)
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationServiceImpl.java (rev 0)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationServiceImpl.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -0,0 +1,576 @@
+/*
+ * #%L
+ * ToPIA :: Service Replication
+ *
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2004 - 2010 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%
+ */
+
+package org.nuiton.topia.replication;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nuiton.topia.TopiaContext;
+import org.nuiton.topia.TopiaException;
+import org.nuiton.topia.framework.TopiaContextImplementor;
+import org.nuiton.topia.persistence.TopiaEntity;
+import org.nuiton.topia.persistence.TopiaEntityEnum;
+import org.nuiton.topia.persistence.util.TopiaEntityHelper;
+import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
+import org.nuiton.topia.replication.model.ReplicationModel;
+import org.nuiton.topia.replication.model.ReplicationNode;
+import org.nuiton.topia.replication.model.ReplicationOperationDef;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Implantation du service de replication.
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
+ */
+public class TopiaReplicationServiceImpl implements TopiaReplicationService {
+
+ /** Logger */
+ private static final Log log = LogFactory.getLog(TopiaReplicationServiceImpl.class);
+
+ /** le contexte sur la base source de la replication */
+ protected TopiaContextImplementor context;
+
+ protected TopiaReplicationModelBuilder modelBuilder;
+
+ //--------------------------------------------------------------------------
+ //-- TopiaService implementation -------------------------------------------
+ //--------------------------------------------------------------------------
+
+ @Override
+ public String getServiceName() {
+ return SERVICE_NAME;
+ }
+
+ @Override
+ public Class<?>[] getPersistenceClasses() {
+ // pas de classes persistentes pour ce service
+ return null;
+ }
+
+ @Override
+ public boolean preInit(TopiaContextImplementor context) {
+ // nothing to init
+ return true;
+ }
+
+ @Override
+ public boolean postInit(TopiaContextImplementor context) {
+ // set the incoming root context from topia
+ this.context = context;
+ //TODO avoir un objet pour lire les contrainte de resolution de cycle
+ //TODO sur les dependances (par exemple, une dependance marquee comme
+ // non nulle : ne peut jamais etre dettache, alors que dans le cas
+ // contraire on peut dettacher la dependance
+ // Cela permet de traiter plus de cas...
+
+ //Properties prop = context.getConfig();
+ return true;
+ }
+
+ //--------------------------------------------------------------------------
+ //-- TopiaReplicationService implementation --------------------------------
+ //--------------------------------------------------------------------------
+
+ @Override
+ public ReplicationModel prepare(TopiaEntityEnum[] contracts,
+ String... entities) throws TopiaException {
+ ReplicationModel model = getModelBuilder().prepare(context, contracts, entities);
+ return model;
+// ReplicationModel model =
+// createModel(contracts, entities);
+//
+// initModel(model, true);
+//
+// return model;
+ }
+
+ @Override
+ public ReplicationModel prepareForAll(TopiaEntityEnum[] contracts) throws TopiaException {
+ ReplicationModel model = getModelBuilder().prepareForAll(contracts);
+ return model;
+// ReplicationModel model = createModelForAll(contracts);
+//
+// initModel(model, true);
+//
+// return model;
+ }
+
+ @Override
+ public ReplicationModel prepareWithComputedOrder(TopiaEntityEnum[] contracts,
+ String... topiaIds) throws TopiaException {
+ ReplicationModel model = getModelBuilder().prepareWithComputedOrder(contracts);
+ return model;
+// ReplicationModel model = createModelWithComputedOrder(contracts, topiaIds);
+//
+// initModel(model, false);
+//
+// return model;
+ }
+
+ @Override
+ public void addBeforeOperation(ReplicationModel model,
+ TopiaEntityEnum type,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... parameters) {
+ getModelBuilder().addBeforeOperation(model, type, operationClass, parameters);
+// createOperation(model,
+// type,
+// ReplicationOperationPhase.before,
+// operationClass,
+// parameters
+// );
+ }
+
+ @Override
+ public void addAfterOperation(ReplicationModel model,
+ TopiaEntityEnum type,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... parameters) {
+ getModelBuilder().addAfterOperation(model, type, operationClass, parameters);
+// createOperation(model,
+// type,
+// ReplicationOperationPhase.after,
+// operationClass,
+// parameters
+// );
+ }
+
+ @Override
+ public void doReplicate(ReplicationModel model,
+ TopiaContext dstCtxt) throws Exception {
+
+ TopiaEntityHelper.checkNotNull("doReplicate", "model", model);
+ TopiaEntityHelper.checkNotNull("doReplicate", "dstCtxt", dstCtxt);
+
+ TopiaContextImplementor srcCtxt = null;
+
+ TopiaEntityIdsMap data = null;
+
+ // keep the list of treated nodes (to roolback them if something
+ // is wrong).
+ List<ReplicationNode> treated = new ArrayList<ReplicationNode>();
+ try {
+
+ srcCtxt = (TopiaContextImplementor) context.beginTransaction();
+
+ data = getIds(model, srcCtxt);
+
+ srcCtxt.closeContext();
+
+ model.adjustOperations(data);
+
+ //FIXME tchemit 2077-07-26, should use next line when
+ // http://nuiton.org/issues/show/779 is closed
+ boolean needTransaction = true;
+// boolean needTransaction = ((TopiaContextImplementor) dstCtxt).getRootContext().equals(dstCtxt);
+
+ TopiaContext tx;
+
+ for (ReplicationNode node : model.getOrder()) {
+
+ srcCtxt = (TopiaContextImplementor) context.beginTransaction();
+
+ if (needTransaction) {
+ tx = dstCtxt.beginTransaction();
+ } else {
+ tx = dstCtxt;
+ }
+ try {
+ doReplicateNode(node, srcCtxt, tx, data, treated);
+ } catch (Exception e) {
+
+ // un erreur est survenu sur le noeud de réplication
+ // on rollback la transaction de ce noeud
+ try {
+ tx.rollbackTransaction();
+ } finally {
+
+ // on revert les noeuds deja commite
+ doRollback(model, data, treated, dstCtxt);
+ }
+
+ throw e;
+ } finally {
+ srcCtxt.closeContext();
+ if (needTransaction) {
+ // on doit fermer la transaction car on l'a ouverte dans
+ // cette méthode, sinon c'est de la responsabilite du
+ // code appellant
+ tx.closeContext();
+ }
+ }
+ }
+// } catch (Exception e) {
+// dstCtxt.rollbackTransaction();
+// throw e;
+ } finally {
+ if (data != null) {
+ data.clear();
+ }
+ if (treated != null) {
+ treated.clear();
+ }
+ // on ne doit jamais commiter sur la base source
+ if (srcCtxt != null && !srcCtxt.isClosed()) {
+ srcCtxt.rollbackTransaction();
+ srcCtxt.closeContext();
+ }
+// dstCtxt.closeContext();
+ }
+ }
+
+ @Override
+ public void doRollback(ReplicationModel model,
+ TopiaEntityIdsMap data,
+ List<ReplicationNode> nodes,
+ TopiaContext dstCtxt) throws Exception {
+ if (nodes.isEmpty()) {
+
+ // aucun noeud de réplication commités
+ return;
+ }
+
+ TopiaContextImplementor srcCtxt;
+
+ TopiaContext tx;
+
+ boolean needTransaction = true;
+
+ log.info("Will rollback " + nodes.size() + " nodes...");
+
+ for (ReplicationNode node : nodes) {
+
+ log.info("Rollback node " + node);
+ srcCtxt = (TopiaContextImplementor) context.beginTransaction();
+
+ if (needTransaction) {
+ tx = dstCtxt.beginTransaction();
+ } else {
+ tx = dstCtxt;
+ }
+ try {
+ doRollbackNode(node, srcCtxt, tx, data);
+ } catch (Exception e) {
+
+ // un erreur est survenu sur le noeud de réplication
+ // on rollback la transaction de ce noeud
+
+ tx.rollbackTransaction();
+
+ } finally {
+ srcCtxt.rollbackTransaction();
+ srcCtxt.closeContext();
+
+ if (needTransaction) {
+ // on doit fermer la transaction car on l'a ouverte dans
+ // cette méthode, sinon c'est de la responsabilite du
+ // code appellant
+ tx.closeContext();
+ }
+ }
+
+ }
+ }
+
+ @Override
+ public TopiaReplicationModelBuilder getModelBuilder() {
+ if (modelBuilder == null) {
+ modelBuilder = new TopiaReplicationModelBuilderImpl();
+ }
+ return modelBuilder;
+ }
+
+ //--------------------------------------------------------------------------
+ //-- TopiaReplicationImplementor implementation ----------------------------
+ //--------------------------------------------------------------------------
+
+// @Override
+// public ReplicationModel createModel(TopiaEntityEnum[] contracts,
+// String... topiaIds)
+// throws TopiaException {
+//
+// Set<Class<? extends TopiaEntity>> detectTypes =
+// detectTypes(contracts, topiaIds);
+// ReplicationModel model =
+// new ReplicationModel(contracts, detectTypes, topiaIds);
+// return model;
+// }
+//
+// @Override
+// public ReplicationModel createModelWithComputedOrder(
+// TopiaEntityEnum[] contracts, String... topiaIds)
+// throws TopiaException {
+// ReplicationModel model =
+// new ReplicationModel(contracts, false, topiaIds);
+// return model;
+// }
+//
+// @Override
+// public ReplicationModel createModelForAll(TopiaEntityEnum[] contracts)
+// throws TopiaException {
+// ReplicationModel model = new ReplicationModel(contracts, true);
+// return model;
+// }
+//
+// @Override
+// public ReplicationModel initModel(ReplicationModel model,
+// boolean computeOrder)
+// throws TopiaException {
+// checkNotNull("initModel", "model", model);
+//
+// model.detectAssociations();
+// model.detectDirectDependencies();
+// if (computeOrder) {
+// model.detectShell();
+// model.detectDependencies();
+// }
+// model.detectObjectsToDettach();
+// model.detectOperations();
+// return model;
+// }
+//
+// @Override
+// public TopiaReplicationOperation getOperation(
+// Class<? extends TopiaReplicationOperation> operationClass) {
+// checkNotNull("getOperation", "operationClass", operationClass);
+//
+// if (operations == null) {
+// throw new IllegalStateException("service was not init!");
+// }
+// TopiaReplicationOperation result = null;
+//
+// for (TopiaReplicationOperation op : operations) {
+// if (operationClass.isAssignableFrom(op.getClass())) {
+// result = op;
+// break;
+// }
+// }
+// return result;
+// }
+//
+// @Override
+// public void createOperation(ReplicationModel model,
+// TopiaEntityEnum type,
+// ReplicationOperationPhase phase,
+// Class<? extends TopiaReplicationOperation> operationClass,
+// Object... parameters) {
+//
+// checkNotNull("createOperation", "model", model);
+// checkNotNull("createOperation", "type", type);
+// checkNotNull("createOperation", "phase", phase);
+// checkNotNull("createOperation", "operationClass", operationClass);
+//
+// TopiaReplicationOperation operation = getOperation(operationClass);
+//
+// if (operation == null) {
+// throw new IllegalArgumentException(
+// _("topia.replication.engine.error.unkown.operation",
+// operationClass.getSimpleName(),
+// Arrays.toString(operations))
+// );
+// }
+//
+// ReplicationNode node = model.getNode(type);
+// if (node == null) {
+// throw new IllegalArgumentException(
+// _("topia.replication.engine.error.unkown.owner.node",
+// type,
+// operationClass.getSimpleName(),
+// model.getNodes())
+// );
+// }
+// operation.register(model, node, phase, parameters);
+// }
+
+// @Override
+
+ public TopiaEntityIdsMap getIds(ReplicationModel model,
+ TopiaContextImplementor srcCtxt)
+ throws TopiaException {
+
+ TopiaEntityIdsMap data;
+
+ // on recupere les objets a repliquer par type
+ if (model.isReplicateAll()) {
+
+ // on recupere pour chaque type tous les ids des entites a repliquer
+ data = new TopiaEntityIdsMap();
+ for (TopiaEntityEnum e : model.getContracts()) {
+ List<String> ids = srcCtxt.getDAO(e.getContract()).findAllIds();
+ data.put(e.getContract(), ids);
+ }
+ } else {
+
+ // on recupere les entites specifies a repliquer
+ TopiaEntity[] entities = TopiaEntityHelper.getEntities(srcCtxt,
+ model.getTopiaIds()
+ );
+
+ // on calcule toutes les ids des entites a repliquer
+ data = TopiaEntityHelper.detectEntityIds(model.getContracts(),
+ model.getTypes(),
+ entities
+ );
+ }
+ return data;
+ }
+
+// protected void checkServiceIsInit() {
+// if (modelBuilder == null) {
+// throw new IllegalStateException("service was not init!");
+// }
+// }
+
+// @Override
+
+ public void doReplicateNode(
+ ReplicationNode node,
+ TopiaContext srcCtxt,
+ TopiaContext dstCtxt,
+ TopiaEntityIdsMap data,
+ List<ReplicationNode> treated) throws Exception {
+
+ // on trie toujours les operations a realiser selon leur phase
+ // (avant ou apres la duplication)
+ node.sortOperations();
+
+ List<ReplicationOperationDef> operationDefs = node.getOperations();
+
+ if (operationDefs.isEmpty()) {
+ log.info("skip node " + node + " - no operation detected.");
+ } else {
+
+ log.info("start for " + node + " : " + operationDefs.size() +
+ " operation(s)");
+
+ List<String> nodeEntityIds =
+ data.get(node.getContract().getContract());
+
+ if (log.isInfoEnabled()) {
+ log.info("will replicate on " + nodeEntityIds.size() +
+ " entity(ies)");
+ }
+ if (log.isDebugEnabled()) {
+ for (String id : nodeEntityIds) {
+ log.debug(id);
+ }
+ }
+
+ List<? extends TopiaEntity> nodeEntities = TopiaEntityHelper.getEntitiesList(
+ srcCtxt,
+ nodeEntityIds.toArray(new String[nodeEntityIds.size()])
+ );
+
+ for (ReplicationOperationDef operationDef : operationDefs) {
+
+ log.info("start " + operationDef);
+
+ TopiaReplicationOperation operation =
+ getModelBuilder().getOperation(operationDef.getOperationClass());
+
+ operation.run(operationDef,
+ (TopiaContextImplementor) srcCtxt,
+ (TopiaContextImplementor) dstCtxt,
+ nodeEntities,
+ data
+ );
+
+ }
+ // on rollback le context source (car on a peut-etre modifie
+ // des associations ou des dependances mais on ne veut rien
+ // retenir au niveau d'hibernate, sinon on s'expose a des erreurs
+ // lorsque l'on veut recharger des objets dans le context...)
+ srcCtxt.rollbackTransaction();
+ }
+
+ treated.add(node);
+ }
+
+
+// @Override
+
+ public void doRollbackNode(
+ ReplicationNode node,
+ TopiaContext srcCtxt,
+ TopiaContext dstCtxt,
+ TopiaEntityIdsMap data) throws Exception {
+
+ // on trie toujours les operations a realiser selon leur phase
+ // (avant ou apres la duplication)
+ node.sortOperations();
+
+ List<ReplicationOperationDef> operationDefs = node.getOperations();
+
+ if (operationDefs.isEmpty()) {
+ log.info("skip node " + node + " - no operation detected.");
+ } else {
+
+ log.info("start for " + node + " : " + operationDefs.size() +
+ " operation(s)");
+
+ List<String> nodeEntityIds =
+ data.get(node.getContract().getContract());
+ if (log.isInfoEnabled()) {
+ log.info("will replicate on " + nodeEntityIds.size() +
+ " entity(ies)");
+ }
+ if (log.isDebugEnabled()) {
+ for (String id : nodeEntityIds) {
+ log.debug(id);
+ }
+ }
+
+ List<? extends TopiaEntity> nodeEntities = TopiaEntityHelper.getEntitiesList(
+ srcCtxt,
+ nodeEntityIds.toArray(new String[nodeEntityIds.size()])
+ );
+
+ for (ReplicationOperationDef operationDef : operationDefs) {
+
+ log.info("start " + operationDef);
+
+ TopiaReplicationOperation operation =
+ getModelBuilder().getOperation(operationDef.getOperationClass());
+
+ operation.rollback(operationDef,
+ (TopiaContextImplementor) srcCtxt,
+ (TopiaContextImplementor) dstCtxt,
+ nodeEntities,
+ data
+ );
+
+ }
+ // on rollback le context source (car on a peut-etre modifie
+ // des associations ou des dependances mais on ne veut rien
+ // retenir au niveau d'hibernate, sinon on s'expose a des erreurs
+ // lorsque l'on veut recharger des objets dans le context...)
+ srcCtxt.rollbackTransaction();
+ }
+ }
+
+}
Property changes on: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationServiceImpl.java
___________________________________________________________________
Added: svn:keywords
+ HeadURL Id Date Revision Author
Deleted: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/Link.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/Link.java 2010-08-15 11:51:20 UTC (rev 2100)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/Link.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -1,116 +0,0 @@
-/*
- * #%L
- * ToPIA :: Service Replication
- *
- * $Id$
- * $HeadURL$
- * %%
- * Copyright (C) 2004 - 2010 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%
- */
-
-package org.nuiton.topia.replication.model;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Pour definir un lien entre deux entites (deux noeuds de replication).
- *
- * @author tchemit <chemit(a)codelutin.com>
- * @since 2.2.0
- */
-public class Link {
-
- /** le noeud source du lien */
- protected final ReplicationNode source;
-
- /** le noeud destination du lien */
- protected final ReplicationNode target;
-
- /**
- * liste des noeuds requis.
- * <p/>
- * TODO tchemit 2010-08-14 Expliquer à quoi ça sert vraiment...
- */
- protected final Set<ReplicationNode> requires;
-
- /** nom du lien */
- protected final String name;
-
- /** drapeau positionné à {@code true} lorsque le lien est une association. */
- protected final boolean association;
-
- public Link(ReplicationNode source,
- ReplicationNode target,
- String name,
- boolean association) {
- this.source = source;
- this.target = target;
- this.name = name;
- this.association = association;
- Set<ReplicationNode> tmpSet = new HashSet<ReplicationNode>();
- tmpSet.add(source);
- tmpSet.addAll(source.getAssociations().values());
- tmpSet.addAll(source.getDependencies().values());
- tmpSet.remove(target);
- requires = Collections.unmodifiableSet(tmpSet);
- }
-
- public String getName() {
- return name;
- }
-
- public ReplicationNode getSource() {
- return source;
- }
-
- public ReplicationNode getTarget() {
- return target;
- }
-
- public boolean isAssociation() {
- return association;
- }
-
- /**
- * Teste si on peut reattacher le lien en connaissant l'univers des
- * noeuds disponibles.
- * <p/>
- * On teste si toutes les pre-requis sont disponibles.
- * <p/>
- * Si oui, on peut reattacher.
- *
- * @param universe l'univers des noeuds disponibles
- * @param currentNode le noeud qui vient d'etre replique
- * @return <code>true</code> si on peut reattacher ce lien
- */
- public boolean canReattach(Set<ReplicationNode> universe,
- ReplicationNode currentNode) {
- boolean result = universe.containsAll(requires);
- if (result) {
- result = currentNode.equals(target) || universe.contains(target);
- }
- return result;
- }
-
- @Override
- public String toString() {
- return "<source:" + source + ", target:" + target + ", name:" + name + ", association:" + association + ">";
- }
-}
Copied: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationLink.java (from rev 2098, trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/Link.java)
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationLink.java (rev 0)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationLink.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -0,0 +1,116 @@
+/*
+ * #%L
+ * ToPIA :: Service Replication
+ *
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2004 - 2010 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%
+ */
+
+package org.nuiton.topia.replication.model;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Pour definir un lien entre deux entites (deux noeuds de replication).
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
+ */
+public class ReplicationLink {
+
+ /** le noeud source du lien */
+ protected final ReplicationNode source;
+
+ /** le noeud destination du lien */
+ protected final ReplicationNode target;
+
+ /**
+ * liste des noeuds requis.
+ * <p/>
+ * TODO tchemit 2010-08-14 Expliquer à quoi ça sert vraiment...
+ */
+ protected final Set<ReplicationNode> requires;
+
+ /** nom du lien */
+ protected final String name;
+
+ /** drapeau positionné à {@code true} lorsque le lien est une association. */
+ protected final boolean association;
+
+ public ReplicationLink(ReplicationNode source,
+ ReplicationNode target,
+ String name,
+ boolean association) {
+ this.source = source;
+ this.target = target;
+ this.name = name;
+ this.association = association;
+ Set<ReplicationNode> tmpSet = new HashSet<ReplicationNode>();
+ tmpSet.add(source);
+ tmpSet.addAll(source.getAssociations().values());
+ tmpSet.addAll(source.getDependencies().values());
+ tmpSet.remove(target);
+ requires = Collections.unmodifiableSet(tmpSet);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public ReplicationNode getSource() {
+ return source;
+ }
+
+ public ReplicationNode getTarget() {
+ return target;
+ }
+
+ public boolean isAssociation() {
+ return association;
+ }
+
+ /**
+ * Teste si on peut reattacher le lien en connaissant l'univers des
+ * noeuds disponibles.
+ * <p/>
+ * On teste si toutes les pre-requis sont disponibles.
+ * <p/>
+ * Si oui, on peut reattacher.
+ *
+ * @param universe l'univers des noeuds disponibles
+ * @param currentNode le noeud qui vient d'etre replique
+ * @return <code>true</code> si on peut reattacher ce lien
+ */
+ public boolean canReattach(Set<ReplicationNode> universe,
+ ReplicationNode currentNode) {
+ boolean result = universe.containsAll(requires);
+ if (result) {
+ result = currentNode.equals(target) || universe.contains(target);
+ }
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "<source:" + source + ", target:" + target + ", name:" + name + ", association:" + association + ">";
+ }
+}
Property changes on: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationLink.java
___________________________________________________________________
Added: svn:keywords
+ HeadURL Id Date Revision Author
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationModel.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationModel.java 2010-08-15 11:51:20 UTC (rev 2100)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationModel.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -373,8 +373,8 @@
public void detectOperations() {
Set<ReplicationNode> universe = new HashSet<ReplicationNode>();
- Set<Link> links = new HashSet<Link>();
- Set<Link> linksToLoad = new HashSet<Link>();
+ Set<ReplicationLink> links = new HashSet<ReplicationLink>();
+ Set<ReplicationLink> linksToLoad = new HashSet<ReplicationLink>();
// premiere passe pour recuperer toutes les associations
@@ -384,7 +384,7 @@
String name = entry.getKey();
// dans tous les cas, on ajoute un link d'association a reattacher
ReplicationNode target = node.getAssociations().get(name);
- Link link = new Link(node, target, name, true);
+ ReplicationLink link = new ReplicationLink(node, target, name, true);
if (nodes.containsValue(target)) {
// on a trouve une association que l'on doit gerer
links.add(link);
@@ -400,7 +400,7 @@
if (!TopiaEntity.class.isAssignableFrom(associationPropertyType) ||
!nodes.containsKey(associationPropertyType)) {
- Link link = new Link(node, null, name, true);
+ ReplicationLink link = new ReplicationLink(node, null, name, true);
linksToLoad.add(link);
if (log.isDebugEnabled()) {
@@ -425,18 +425,18 @@
addPreOperation(node, node, DettachAssociation.class, name);
}
}
- Set<Link> tmpLinks = new HashSet<Link>();
+ Set<ReplicationLink> tmpLinks = new HashSet<ReplicationLink>();
// recherche des associations a charger avant replication
- for (Link link : linksToLoad) {
+ for (ReplicationLink link : linksToLoad) {
if (node.equals(link.getSource())) {
tmpLinks.add(link);
}
}
if (!tmpLinks.isEmpty()) {
// on a des associations a charger avant replication
- for (Link link : tmpLinks) {
+ for (ReplicationLink link : tmpLinks) {
addPreOperation(node, node, LoadLink.class, link);
// ReplicationOperationDef op = new ReplicationOperationDef(ReplicationOperationPhase.before, LoadLink.class, node, link);
// node.addOperation(op);
@@ -452,7 +452,7 @@
universe.add(node);
// operations de reattachement
- for (Link link : links) {
+ for (ReplicationLink link : links) {
if (link.canReattach(universe, node)) {
// lien reattachable
tmpLinks.add(link);
@@ -460,7 +460,7 @@
}
if (!tmpLinks.isEmpty()) {
// on a trouve des liens a reattacher
- for (Link link : tmpLinks) {
+ for (ReplicationLink link : tmpLinks) {
addPostOperation(node, node, AttachLink.class, link);
// ReplicationOperationDef op = new ReplicationOperationDef(ReplicationOperationPhase.after, AttachLink.class, node, link);
// node.addOperation(op);
@@ -522,9 +522,9 @@
}
protected void addPreOperation(ReplicationNode ownerNode,
- ReplicationNode node,
- Class<? extends TopiaReplicationOperation> operationClass,
- Object... params) {
+ ReplicationNode node,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... params) {
addOperation(ownerNode, node, ReplicationOperationPhase.before, operationClass, params);
}
@@ -536,9 +536,9 @@
}
protected void addPostOperation(ReplicationNode ownerNode,
- ReplicationNode node,
- Class<? extends TopiaReplicationOperation> operationClass,
- Object... params) {
+ ReplicationNode node,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... params) {
addOperation(ownerNode, node, ReplicationOperationPhase.after, operationClass, params);
}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachAssociation.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachAssociation.java 2010-08-15 11:51:20 UTC (rev 2100)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachAssociation.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -33,7 +33,6 @@
import org.nuiton.topia.persistence.util.EntityOperator;
import org.nuiton.topia.persistence.util.TopiaEntityHelper;
import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
-import org.nuiton.topia.replication.ReplicationEngine;
import org.nuiton.topia.replication.TopiaReplicationOperation;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
@@ -71,13 +70,17 @@
*/
public class AttachAssociation implements TopiaReplicationOperation {
- /** to use log facility, just put in your code: log.info(\"...\"); */
+ /** Logger */
private static final Log log = LogFactory.getLog(AttachAssociation.class);
@Override
- public void register(ReplicationModel model, ReplicationNode ownerNode, ReplicationOperationPhase phase, Object... parameters) {
+ public void register(ReplicationModel model,
+ ReplicationNode ownerNode,
+ ReplicationOperationPhase phase,
+ Object... parameters) {
- throw new UnsupportedOperationException(_("topia.replication.operation.error.uncreatable", getClass()));
+ throw new UnsupportedOperationException(
+ _("topia.replication.operation.error.uncreatable", getClass()));
}
@Override
@@ -91,7 +94,8 @@
Boolean reverse = (Boolean) operationDef.getParameters()[1];
if (log.isDebugEnabled()) {
- log.debug("currentNode : " + operationDef.getNode() + " , association name : " + name + " reverse ? " + reverse);
+ log.debug("currentNode : " + operationDef.getNode() +
+ " , association name : " + name + " reverse ? " + reverse);
}
ReplicationNode ownerNode;
@@ -137,7 +141,8 @@
if (ownerIds == null || ownerIds.isEmpty()) {
// pas de donnees a traiter
- log.info(_("topia.replication.attachAssociation.nothing.to.do", ownerOperator));
+ log.info(_("topia.replication.attachAssociation.nothing.to.do",
+ ownerOperator));
return;
}
@@ -148,13 +153,17 @@
// modifiees (dettachement d'association ou autres)
// ils nous faut les entites telles qu'elles sont en base source
- ownerEntities = ReplicationEngine.getEntitiesList(srcCtxt, ownerIds.toArray(new String[ownerIds.size()]));
+ ownerEntities = TopiaEntityHelper.getEntitiesList(
+ srcCtxt,
+ ownerIds.toArray(new String[ownerIds.size()])
+ );
boolean shouldCommit = false;
if (log.isInfoEnabled()) {
- log.info("ownerNode : " + ownerNode + " , targetNode : " + cibleNode + ", association : " + name);
+ log.info("ownerNode : " + ownerNode + " , targetNode : " +
+ cibleNode + ", association : " + name);
}
if (log.isDebugEnabled()) {
log.debug("owner ids : " + ownerIds);
@@ -174,7 +183,8 @@
continue;
}
if (log.isDebugEnabled()) {
- log.debug("will try to attach " + targetEntities.size() + " association(s) '" + name + "' to " + src);
+ log.debug("will try to attach " + targetEntities.size() +
+ " association(s) '" + name + "' to " + src);
}
// l'entite repliquee a laquelle on veut attacher l'association
@@ -182,10 +192,16 @@
TopiaEntity dst = dstCtxt.findByTopiaId(src.getTopiaId());
// les association cibles connues pour l'entite sur la base destination
- Collection<?> dstTargetEntities = (Collection<?>) ownerOperator.get(name, dst);
+ Collection<?> dstTargetEntities = (Collection<?>)
+ ownerOperator.get(name, dst);
// les ids des entities deja associees
- List<String> dstTargetAssociationsId = dstTargetEntities == null ? Collections.EMPTY_LIST : TopiaEntityHelper.getTopiaIdList((List<? extends TopiaEntity>) dstTargetEntities);
+ List<String> dstTargetAssociationsId =
+ dstTargetEntities == null ?
+ Collections.<String>emptyList() :
+ TopiaEntityHelper.getTopiaIdList(
+ (List<? extends TopiaEntity>) dstTargetEntities);
+
boolean shouldUpdate = false;
for (Object a : targetEntities) {
@@ -196,7 +212,8 @@
if (dstTargetAssociationsId.contains(assosiationSrc.getTopiaId())) {
// deja attache
if (log.isDebugEnabled()) {
- log.debug("already attached association '" + name + "' : " + assosiationSrc);
+ log.debug("already attached association '" + name +
+ "' : " + assosiationSrc);
}
continue;
@@ -204,10 +221,12 @@
// la donnees doit etre attachee
- TopiaEntity assosiationDst = dstCtxt.findByTopiaId(assosiationSrc.getTopiaId());
+ TopiaEntity assosiationDst =
+ dstCtxt.findByTopiaId(assosiationSrc.getTopiaId());
ownerOperator.addChild(name, dst, assosiationDst);
if (log.isDebugEnabled()) {
- log.debug("will attach association '" + name + "' : " + assosiationDst);
+ log.debug("will attach association '" + name + "' : " +
+ assosiationDst);
}
shouldUpdate = true;
}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachLink.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachLink.java 2010-08-15 11:51:20 UTC (rev 2100)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachLink.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -33,9 +33,8 @@
import org.nuiton.topia.persistence.util.EntityOperator;
import org.nuiton.topia.persistence.util.TopiaEntityHelper;
import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
-import org.nuiton.topia.replication.ReplicationEngine;
import org.nuiton.topia.replication.TopiaReplicationOperation;
-import org.nuiton.topia.replication.model.Link;
+import org.nuiton.topia.replication.model.ReplicationLink;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
import org.nuiton.topia.replication.model.ReplicationOperationDef;
@@ -72,13 +71,17 @@
*/
public class AttachLink implements TopiaReplicationOperation {
- /** to use log facility, just put in your code: log.info(\"...\"); */
+ /** Logger */
private static final Log log = LogFactory.getLog(AttachLink.class);
@Override
- public void register(ReplicationModel model, ReplicationNode ownerNode, ReplicationOperationPhase phase, Object... parameters) {
+ public void register(ReplicationModel model,
+ ReplicationNode ownerNode,
+ ReplicationOperationPhase phase,
+ Object... parameters) {
- throw new UnsupportedOperationException(_("topia.replication.operation.error.uncreatable", getClass()));
+ throw new UnsupportedOperationException(
+ _("topia.replication.operation.error.uncreatable", getClass()));
}
@Override
@@ -88,18 +91,20 @@
List<? extends TopiaEntity> nodeEntities,
TopiaEntityIdsMap data) throws TopiaException {
- Link link = (Link) operationDef.getParameters()[0];
+ ReplicationLink link = (ReplicationLink) operationDef.getParameters()[0];
String name = link.getName();
if (log.isDebugEnabled()) {
- log.debug("currentNode : " + operationDef.getNode() + " , link to attach : " + link);
+ log.debug("currentNode : " + operationDef.getNode() +
+ " , link to attach : " + link);
}
ReplicationNode ownerNode = link.getSource();
ReplicationNode cibleNode = link.getTarget();
- EntityOperator<? super TopiaEntity> ownerOperator = ownerNode.getOperator();
+ EntityOperator<? super TopiaEntity> ownerOperator =
+ ownerNode.getOperator();
// contient la liste des ids d'association autorisees ici
List<String> associationIds = null;
@@ -128,7 +133,8 @@
if (ownerIds == null || ownerIds.isEmpty()) {
// pas de donnees a traiter
- log.info(_("topia.replication.attachAssociation.nothing.to.do", ownerOperator));
+ log.info(_("topia.replication.attachAssociation.nothing.to.do",
+ ownerOperator));
return;
}
@@ -136,13 +142,17 @@
// modifiees (dettachement d'association ou autres)
// ils nous faut les entites telles qu'elles sont en base source
- ownerEntities = ReplicationEngine.getEntitiesList(srcCtxt, ownerIds.toArray(new String[ownerIds.size()]));
+ ownerEntities = TopiaEntityHelper.getEntitiesList(
+ srcCtxt,
+ ownerIds.toArray(new String[ownerIds.size()])
+ );
boolean shouldCommit = false;
if (log.isInfoEnabled()) {
- log.info("ownerNode : " + ownerNode + " , targetNode : " + cibleNode + ", association : " + name);
+ log.info("ownerNode : " + ownerNode + " , targetNode : " +
+ cibleNode + ", association : " + name);
}
if (log.isDebugEnabled()) {
log.debug("owner ids : " + ownerIds);
@@ -152,7 +162,8 @@
for (TopiaEntity src : ownerEntities) {
// les association cibles connues pour l'entite sur la base source
- Collection<?> targetEntities = (Collection<?>) ownerOperator.get(name, src);
+ Collection<?> targetEntities = (Collection<?>)
+ ownerOperator.get(name, src);
if (targetEntities == null || targetEntities.isEmpty()) {
if (log.isDebugEnabled()) {
@@ -162,7 +173,8 @@
continue;
}
if (log.isDebugEnabled()) {
- log.debug("will try to attach " + targetEntities.size() + " association(s) '" + name + "' to " + src);
+ log.debug("will try to attach " + targetEntities.size() +
+ " association(s) '" + name + "' to " + src);
}
// l'entite repliquee a laquelle on veut attacher l'association
@@ -170,10 +182,15 @@
TopiaEntity dst = dstCtxt.findByTopiaId(src.getTopiaId());
// les association cibles connues pour l'entite sur la base destination
- Collection<?> dstTargetEntities = (Collection<?>) ownerOperator.get(name, dst);
+ Collection<?> dstTargetEntities = (Collection<?>)
+ ownerOperator.get(name, dst);
// les ids des entities deja associees
- List<String> dstTargetAssociationsId = dstTargetEntities == null ? Collections.EMPTY_LIST : TopiaEntityHelper.getTopiaIdList((List<? extends TopiaEntity>) dstTargetEntities);
+ List<String> dstTargetAssociationsId =
+ dstTargetEntities == null ?
+ Collections.<String>emptyList() :
+ TopiaEntityHelper.getTopiaIdList(
+ (List<? extends TopiaEntity>) dstTargetEntities);
boolean shouldUpdate = false;
for (Object a : targetEntities) {
@@ -181,10 +198,12 @@
// on verifie que l'association doit etre rattachee
if (associationIds.contains(assosiationSrc.getTopiaId())) {
- if (dstTargetAssociationsId.contains(assosiationSrc.getTopiaId())) {
+ if (dstTargetAssociationsId.contains(
+ assosiationSrc.getTopiaId())) {
// deja attache
if (log.isDebugEnabled()) {
- log.debug("already attached association '" + name + "' : " + assosiationSrc);
+ log.debug("already attached association '" +
+ name + "' : " + assosiationSrc);
}
continue;
@@ -192,10 +211,12 @@
// la donnees doit etre attachee
- TopiaEntity assosiationDst = dstCtxt.findByTopiaId(assosiationSrc.getTopiaId());
+ TopiaEntity assosiationDst =
+ dstCtxt.findByTopiaId(assosiationSrc.getTopiaId());
ownerOperator.addChild(name, dst, assosiationDst);
if (log.isDebugEnabled()) {
- log.debug("will attach association '" + name + "' : " + assosiationDst);
+ log.debug("will attach association '" + name +
+ "' : " + assosiationDst);
}
shouldUpdate = true;
}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/DettachAssociation.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/DettachAssociation.java 2010-08-15 11:51:20 UTC (rev 2100)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/DettachAssociation.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -54,13 +54,17 @@
*/
public class DettachAssociation implements TopiaReplicationOperation {
- /** to use log facility, just put in your code: log.info(\"...\"); */
+ /** Logger */
private static final Log log = LogFactory.getLog(DettachAssociation.class);
@Override
- public void register(ReplicationModel model, ReplicationNode ownerNode, ReplicationOperationPhase phase, Object... parameters) {
+ public void register(ReplicationModel model,
+ ReplicationNode ownerNode,
+ ReplicationOperationPhase phase,
+ Object... parameters) {
- throw new UnsupportedOperationException(_("topia.replication.operation.error.uncreatable", getClass()));
+ throw new UnsupportedOperationException(
+ _("topia.replication.operation.error.uncreatable", getClass()));
}
@Override
@@ -72,7 +76,8 @@
String name = (String) operationDef.getParameters()[0];
- EntityOperator<? super TopiaEntity> operator = operationDef.getNode().getOperator();
+ EntityOperator<? super TopiaEntity> operator =
+ operationDef.getNode().getOperator();
// dettach les associations
for (TopiaEntity e : entities) {
@@ -80,7 +85,8 @@
if (size > 0) {
if (log.isDebugEnabled()) {
- log.debug("will dettach " + size + " association(s) '" + name + "' from " + e);
+ log.debug("will dettach " + size + " association(s) '" +
+ name + "' from " + e);
}
operator.setNull(name, e);
}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/Duplicate.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/Duplicate.java 2010-08-15 11:51:20 UTC (rev 2100)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/Duplicate.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -52,8 +52,12 @@
public class Duplicate implements TopiaReplicationOperation {
@Override
- public void register(ReplicationModel model, ReplicationNode ownerNode, ReplicationOperationPhase phase, Object... parameters) {
- throw new UnsupportedOperationException(_("topia.replication.operation.error.uncreatable", getClass()));
+ public void register(ReplicationModel model,
+ ReplicationNode ownerNode,
+ ReplicationOperationPhase phase,
+ Object... parameters) {
+ throw new UnsupportedOperationException(
+ _("topia.replication.operation.error.uncreatable", getClass()));
}
@Override
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/LoadLink.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/LoadLink.java 2010-08-15 11:51:20 UTC (rev 2100)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/LoadLink.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -33,7 +33,7 @@
import org.nuiton.topia.persistence.util.EntityOperator;
import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
import org.nuiton.topia.replication.TopiaReplicationOperation;
-import org.nuiton.topia.replication.model.Link;
+import org.nuiton.topia.replication.model.ReplicationLink;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
import org.nuiton.topia.replication.model.ReplicationOperationDef;
@@ -55,13 +55,17 @@
*/
public class LoadLink implements TopiaReplicationOperation {
- /** to use log facility, just put in your code: log.info(\"...\"); */
+ /** Logger */
private static final Log log = LogFactory.getLog(LoadLink.class);
@Override
- public void register(ReplicationModel model, ReplicationNode ownerNode, ReplicationOperationPhase phase, Object... parameters) {
+ public void register(ReplicationModel model,
+ ReplicationNode ownerNode,
+ ReplicationOperationPhase phase,
+ Object... parameters) {
- throw new UnsupportedOperationException(_("topia.replication.operation.error.uncreatable", getClass()));
+ throw new UnsupportedOperationException(
+ _("topia.replication.operation.error.uncreatable", getClass()));
}
@Override
@@ -71,28 +75,33 @@
List<? extends TopiaEntity> nodeEntities,
TopiaEntityIdsMap data) throws TopiaException {
- Link link = (Link) operationDef.getParameters()[0];
+ ReplicationLink link = (ReplicationLink) operationDef.getParameters()[0];
String name = link.getName();
ReplicationNode ownerNode = link.getSource();
if (!ownerNode.equals(operationDef.getNode())) {
- throw new IllegalStateException(_("topia.replication.operation.loadLink.illegalSource", operationDef.getNode(), ownerNode));
+ throw new IllegalStateException(
+ _("topia.replication.operation.loadLink.illegalSource",
+ operationDef.getNode(), ownerNode));
}
if (log.isDebugEnabled()) {
- log.debug("currentNode : " + operationDef.getNode() + " , link to load : " + link);
+ log.debug("currentNode : " + operationDef.getNode() +
+ " , link to load : " + link);
}
- EntityOperator<? super TopiaEntity> ownerOperator = ownerNode.getOperator();
+ EntityOperator<? super TopiaEntity> ownerOperator =
+ ownerNode.getOperator();
for (TopiaEntity src : nodeEntities) {
// on se contente de charger l'association
int size = ownerOperator.sizeChild(name, src);
if (log.isDebugEnabled()) {
- log.debug("load association '" + name + "' on " + src + " : " + size);
+ log.debug("load association '" + name + "' on " + src +
+ " : " + size);
}
}
}
Modified: trunk/topia-service-replication/src/main/resources/META-INF/services/org.nuiton.topia.replication.TopiaReplicationOperation
===================================================================
--- trunk/topia-service-replication/src/main/resources/META-INF/services/org.nuiton.topia.replication.TopiaReplicationOperation 2010-08-15 11:51:20 UTC (rev 2100)
+++ trunk/topia-service-replication/src/main/resources/META-INF/services/org.nuiton.topia.replication.TopiaReplicationOperation 2010-08-15 11:58:21 UTC (rev 2101)
@@ -1,6 +1,5 @@
#
-# la liste des operations disponibles pour le moteur de replication
-# voir la classe org.nuiton.topia.replication.ReplicationEngine
+# la liste des operations disponibles pour le moteur de replication.
#
org.nuiton.topia.replication.operation.AttachLink
org.nuiton.topia.replication.operation.LoadLink
Deleted: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/AbstractReplicationEngineTest.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/AbstractReplicationEngineTest.java 2010-08-15 11:51:20 UTC (rev 2100)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/AbstractReplicationEngineTest.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -1,646 +0,0 @@
-/*
- * #%L
- * ToPIA :: Service Replication
- *
- * $Id$
- * $HeadURL$
- * %%
- * Copyright (C) 2004 - 2010 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%
- */
-
-package org.nuiton.topia.replication;
-
-import org.apache.commons.logging.Log;
-import org.junit.Assert;
-import org.nuiton.i18n.I18n;
-import org.nuiton.topia.TopiaContext;
-import org.nuiton.topia.TopiaException;
-import org.nuiton.topia.framework.TopiaContextImplementor;
-import org.nuiton.topia.persistence.TopiaDAO;
-import org.nuiton.topia.persistence.TopiaEntity;
-import org.nuiton.topia.persistence.TopiaEntityEnum;
-import org.nuiton.topia.persistence.util.EntityOperator;
-import org.nuiton.topia.persistence.util.EntityOperatorStore;
-import org.nuiton.topia.persistence.util.TopiaEntityHelper;
-import org.nuiton.topia.replication.model.ReplicationModel;
-import org.nuiton.topia.replication.model.ReplicationNode;
-import org.nuiton.topia.replication.model.ReplicationOperationDef;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Set;
-
-/**
- * ReplicationEngineTest.
- * <p/>
- * Created: 07 jun. 09 17:14:22
- *
- * @author tchemit <chemit(a)codelutin.com>
- * @version $Id$
- * @since 2.2.0
- */
-public abstract class AbstractReplicationEngineTest extends Assert {
-
- static protected TopiaContext context;
-
- static protected TopiaContext ctxt;
-
- protected TopiaContextImplementor dstCtxt;
-
- protected TopiaReplicationImplementor service;
-
- protected ReplicationModel model;
-
- static protected boolean init;
-
- static private Long testsTimeStamp;
-
- static private File testsBasedir;
-
- static private final String TEST_BASEDIR = "target%1$ssurefire-tests%1$s%2$td_%2$tm_%2$tY%1$s%2$tH_%2$tM_%2$tS";
-
- public static void after() throws Exception {
- if (context != null && !context.isClosed()) {
- try {
- context.closeContext();
- } catch (TopiaException e) {
- // cela peut arriver si on demande la fermeture dans un thread
- // ailleurs...
- }
- }
- init = false;
- }
-
- public void setUp() throws Exception {
-
- if (!init) {
-
- I18n.init(Locale.FRANCE);
-
- try {
- context = createDb("source");
- } catch (Exception e) {
- getLog().error("could not create db source.", e);
- throw e;
- }
- init = true;
- }
-
- ctxt = context.beginTransaction();
-
- service = (TopiaReplicationImplementor) context.getService(TopiaReplicationService.class);
- }
-
- public void tearDown() throws Exception {
- if (ctxt != null) {
- ctxt.rollbackTransaction();
- ctxt.closeContext();
- ctxt = null;
- }
- service = null;
- }
-
- protected abstract TopiaContext createDb2(String name) throws Exception;
-
- protected abstract TopiaContext createDb(String name) throws Exception;
-
- protected TopiaContext createReplicateDb(Object contract) throws Exception {
- TopiaContext rootCtxt = createDb2(contract.toString() + dbCounter++);
- return rootCtxt;
- }
-
- protected abstract TopiaEntityEnum[] getContracts();
-
- protected abstract Log getLog();
-
- protected <E extends TopiaEntity> E update(E e) throws TopiaException {
- return (E) ((TopiaContextImplementor) ctxt).findByTopiaId(e.getTopiaId());
- }
-
- /**
- * Test of detectTypes method, of class ReplicationServiceImplementor.
- *
- * @throws Exception if any error
- */
- public void testDetectTypes() throws Exception {
- }
-
- /**
- * Test of getOperation method, of class ReplicationServiceImplementor.
- *
- * @throws Exception if any error
- */
- public void testGetOperation() throws Exception {
- }
-
- /**
- * Test of detectAssociations method, of class ReplicationModel.
- *
- * @throws Exception if any error
- */
- public void testDetectAssociations() throws Exception {
- }
-
- /**
- * Test of detectDirectDependencies method, of class ReplicationModel.
- *
- * @throws Exception if any error
- */
- public void testDetectDirectDependencies() throws Exception {
- }
-
- /**
- * Test of detectShell method, of class ReplicationModel.
- *
- * @throws Exception if any error
- */
- public void testDetectShell() throws Exception {
- }
-
- /**
- * Test of detectDependencies method, of class ReplicationModel.
- *
- * @throws Exception if any error
- */
- public void testDetectDependencies() throws Exception {
- }
-
- /**
- * Test of detectObjectsToDettach method, of class ReplicationModel.
- *
- * @throws Exception if any error
- */
- public void testDetectObjectsToDettach() throws Exception {
- }
-
- /**
- * Test of detectOperations method, of class ReplicationModel.
- *
- * @throws Exception if any error
- */
- public void testDetectOperations() throws Exception {
- }
-
- /**
- * Test of doReplicate method, of class ReplicationService.
- *
- * @throws Exception if any error
- */
- public void testDoReplicate() throws Exception {
- }
-
- protected void detectTypes(TopiaEntity entity, Object... expectedCouple) throws TopiaException {
-
- Set<?> detectTypes;
-
- detectTypes = service.detectTypes(getContracts(), entity.getTopiaId());
- assertEquals("expected types : " +
- Arrays.toString(expectedCouple) +
- " but was " + detectTypes,
- expectedCouple.length, detectTypes.size());
- for (Object o : expectedCouple) {
- assertTrue(detectTypes.contains(o));
- }
- }
-
- protected void getOperation(Class<? extends TopiaReplicationOperation> operationClass, boolean shouldExist) throws TopiaException {
- TopiaReplicationOperation operation = service.getOperation(operationClass);
- assertEquals(shouldExist, operation != null);
- }
-
- protected void detectAssociations(TopiaEntity entity,
- Object... expectedCouple)
- throws TopiaException {
-
- createModel(entity);
- model.detectAssociations();
-
- assertEquals(0, expectedCouple.length % 2);
-
- for (int i = 0, j = expectedCouple.length / 2; i < j; i++) {
- TopiaEntityEnum src = (TopiaEntityEnum) expectedCouple[2 * i];
- String name = (String) expectedCouple[2 * i + 1];
- ReplicationNode nodeSrc = model.getNode(src);
- assertNotNull("association " + name + " not found", nodeSrc);
- assertTrue(nodeSrc.hasAssociation());
- assertTrue(nodeSrc.getAssociations().containsKey(name));
- }
- }
-
- protected void detectDirectDependencies(TopiaEntity entity,
- Object... expectedCouple)
- throws TopiaException {
-
- createModel(entity);
- model.detectDirectDependencies();
-
- assertEquals(0, expectedCouple.length % 2);
-
- for (int i = 0, j = expectedCouple.length / 2; i < j; i++) {
- TopiaEntityEnum src = (TopiaEntityEnum) expectedCouple[2 * i];
- String name = (String) expectedCouple[2 * i + 1];
- ReplicationNode nodeSrc = model.getNode(src);
- assertTrue(nodeSrc + " should have dependency but was not!", nodeSrc.hasDependency());
- assertTrue(nodeSrc + " should contain dependency " + name + "but was not! (" + nodeSrc.getDependencies() + ")", nodeSrc.getDependencies().containsKey(name));
- }
- }
-
- protected void detectShell(TopiaEntity entity,
- TopiaEntityEnum... expected) throws
- TopiaException {
- Set<ReplicationNode> shell;
-
- createModel(entity);
- model.detectAssociations();
- model.detectDirectDependencies();
- model.detectShell();
-
- TopiaEntityEnum c = TopiaEntityHelper.getEntityEnum(
- entity.getClass(), getContracts());
- assertNotNull(c);
- shell = model.getNode(c.getContract()).getShell();
- assertEquals(
- "expected shell : " + Arrays.toString(expected) + ", but was " +
- shell, expected.length, shell.size());
-
- for (int i = 0, j = expected.length; i < j; i++) {
- TopiaEntityEnum type = expected[i];
- ReplicationNode node = model.getNode(type.getContract());
- assertTrue(shell.contains(node));
- assertEquals(type, node.getContract());
- }
- }
-
- protected void detectDependencies(
- TopiaEntity entity,
- TopiaEntityEnum[]... expected) throws TopiaException {
-
- createModel(entity);
- model.detectAssociations();
- model.detectDirectDependencies();
- model.detectShell();
- model.detectDependencies();
- List<ReplicationNode> dependencies = model.getOrder();
-
- int i = 0;
- for (ReplicationNode level : dependencies) {
- getLog().info("level " + level + " = " + level);
- }
-
-// assertEquals("expected " + expected.length + " levels but had " + dependencies.size(), expected.length, dependencies.size());
-//
-// Iterator<List<ReplicationNode>> order = dependencies.iterator();
-// if (entity != null) {
-// getLog().info("for " + entity.getTopiaId());
-// }
-// int index = 0;
-// for (TopiaEntityEnum[] expectedLevel : expected) {
-//
-// List<ReplicationNode> next = order.next();
-// getLog().info("level " + (index++) + " : " + next);
-// for (TopiaEntityEnum ee : expectedLevel) {
-// ReplicationNode expectedNode = model.getNode(ee);
-//
-// assertTrue("should have contains node " + expectedNode, next.contains(expectedNode));
-// }
-//
-// }
- }
-
- protected void detectObjectsToDettach(TopiaEntity entity, Object... expected) throws TopiaException {
-
- assertEquals(0, expected.length % 2);
-
- createModel(entity);
- model.detectAssociations();
- model.detectDirectDependencies();
- model.detectShell();
- model.detectDependencies();
- model.detectObjectsToDettach();
- Set<ReplicationNode> nodes = new HashSet<ReplicationNode>();
-
- for (int i = 0, j = expected.length / 2; i < j; i++) {
- TopiaEntityEnum e = (TopiaEntityEnum) expected[2 * i];
- ReplicationNode node = model.getNode(e);
- String[] ids = (String[]) expected[2 * i + 1];
- assertEquals(ids.length > 0, node.hasAssociationsToDettach());
- for (String id : ids) {
- assertTrue(node.getAssociationsToDettach().contains(id));
- }
- nodes.add(node);
- }
-
- for (ReplicationNode node : model.getNodes()) {
- if (!nodes.contains(node)) {
- // on verifie bien qu'il n' y a pas d'associations dettachee
- assertFalse(node.hasAssociationsToDettach());
- }
- }
-
- }
-
- protected void detectOperations(TopiaEntity entity, Object... expected) throws TopiaException {
-
- assertEquals(0, expected.length % 2);
-
- if (entity == null) {
- prepareModel();
- } else {
- prepareModel(entity.getTopiaId());
- }
-// createModel(entity);
-// model.detectAssociations();
-// model.detectDirectDependencies();
-// model.detectShell();
-// model.detectDependencies();
-// model.detectObjectsToDettach();
-// model.detectOperations();
-
- if (getLog().isInfoEnabled()) {
- getLog().info("==========================================================================");
- if (entity == null) {
-
- getLog().info("resume of operations for all ");
- } else {
- getLog().info("resume of operations for entity " + entity.getTopiaId());
- }
-
- for (ReplicationNode node : model.getOrder()) {
- List<ReplicationOperationDef> operations = node.getOperations();
- for (ReplicationOperationDef op : operations) {
- getLog().info("[" + node + "] : operation " + op);
- }
- }
- getLog().info("==========================================================================");
- }
- }
-
- private static int dbCounter;
-
- protected void doReplicate(TopiaEntityEnum contract, TopiaEntity... entity) throws Exception {
-
- TopiaContext rootCtxt = createReplicateDb("doReplicate_" + contract);
-
- List<String> ids = TopiaEntityHelper.getTopiaIdList(Arrays.asList(entity));
- getLog().info("entity " + ids);
-
- prepareModel(ids.toArray(new String[ids.size()]));
-
- dstCtxt = (TopiaContextImplementor) rootCtxt;
-
- service.doReplicate(model, dstCtxt);
-
- //dstCtxt.closeContext();
-
- if (entity.length == 0) {
-
- return;
- }
- dstCtxt = (TopiaContextImplementor) rootCtxt.beginTransaction();
-
- for (TopiaEntity e : entity) {
- TopiaEntity actual = dstCtxt.findByTopiaId(e.getTopiaId());
- assertNotNull(actual);
- assertEquals(e, actual);
- }
-
- dstCtxt.closeContext();
-
- dstCtxt = (TopiaContextImplementor) rootCtxt;
- }
-
- protected void doReplicateAll() throws Exception {
-
- TopiaContext rootCtxt = createReplicateDb("doReplicateAll");
-
- prepareModelAll();
-
- dstCtxt = (TopiaContextImplementor) rootCtxt;
-
- service.doReplicate(model, dstCtxt);
-
- TopiaContextImplementor ctxt2 = (TopiaContextImplementor) ctxt;
- dstCtxt = (TopiaContextImplementor) rootCtxt.beginTransaction();
-
- assertDbEquals(model.getContracts(), (TopiaContextImplementor) ctxt, ctxt2);
-
- dstCtxt.closeContext();
-
- dstCtxt = (TopiaContextImplementor) rootCtxt;
- }
-
- protected void doReplicateWithComputedOrder(TopiaEntity... entity) throws Exception {
-
- TopiaContext rootCtxt = createReplicateDb("doReplicateWithComputedOrder");
-
- List<String> ids = TopiaEntityHelper.getTopiaIdList(Arrays.asList(entity));
-
- prepareModelWithComputedOrder(ids.toArray(new String[ids.size()]));
-
- dstCtxt = (TopiaContextImplementor) rootCtxt;
-
- service.doReplicate(model, dstCtxt);
-
- getLog().info("replication is done for " + Arrays.toString(entity) + ", will verify data...");
-
- TopiaContextImplementor ctxt2 = (TopiaContextImplementor) ctxt;
- dstCtxt = (TopiaContextImplementor) rootCtxt.beginTransaction();
-
- assertDbEquals(model.getContracts(), (TopiaContextImplementor) ctxt, ctxt2);
-
- dstCtxt.closeContext();
-
- dstCtxt = (TopiaContextImplementor) rootCtxt;
- }
-
- protected void assertDbEquals(TopiaEntityEnum[] contracts, TopiaContextImplementor ctxt, TopiaContextImplementor ctxt2) throws TopiaException {
- Set<String> ids = new HashSet<String>();
-
- if (getLog().isInfoEnabled()) {
- getLog().info("will verify db for contracts " + Arrays.toString(contracts));
- }
- for (TopiaEntityEnum c : contracts) {
- if (getLog().isDebugEnabled()) {
- getLog().debug("verify for contract " + c);
- }
- TopiaDAO<? extends TopiaEntity> daoSrc = ctxt.getDAO(c.getContract());
- TopiaDAO<? extends TopiaEntity> daoDst = ctxt2.getDAO(c.getContract());
- long nbSrc = daoSrc.count();
- long nbDst = daoDst.count();
- assertEquals("le nombres d'entites de type " + c + " devrait etre " + nbSrc + " mais est " + nbDst, nbSrc, nbDst);
- List<String> idsSrc = daoSrc.findAllIds();
- List<String> idsDst = daoDst.findAllIds();
- Collections.sort(idsSrc);
- Collections.sort(idsDst);
- assertEquals(idsSrc, idsDst);
- for (String id : idsSrc) {
- if (getLog().isDebugEnabled()) {
- getLog().debug("verify for entity " + id);
- }
- TopiaEntity eSrc = daoSrc.findByTopiaId(id);
- TopiaEntity eDst = daoDst.findByTopiaId(id);
- assertEquals(eSrc, eDst);
- assertEntityEquals(eSrc, eDst, ids);
- }
- }
- }
-
- protected void assertEntityEquals(TopiaEntity expected, TopiaEntity actual, Set<String> treated) {
- if (treated == null) {
- treated = new HashSet<String>();
- }
- if (treated.contains(actual.getTopiaId())) {
- return;
- }
- if (getLog().isDebugEnabled()) {
- getLog().debug(expected);
- }
- assertEquals(actual.getTopiaId(), expected.getTopiaId());
- treated.add(actual.getTopiaId());
- if (getLog().isDebugEnabled()) {
- getLog().debug("expected : " + expected + " / actual " + actual);
- }
- TopiaEntityEnum contract = TopiaEntityHelper.getEntityEnum(expected.getClass(), getContracts());
- if (contract == null) {
- // this type of entity in not dealed here...
- getLog().debug("untested property type " + expected.getClass());
- return;
- }
- Assert.assertNotNull(
- "contract not found for " + expected.getClass() + " in " +
- Arrays.toString(getContracts()), contract);
- EntityOperator<TopiaEntity> operator = EntityOperatorStore.getOperator(contract);
- List<String> associationProperties = operator.getAssociationProperties();
- for (String name : associationProperties) {
- if (getLog().isDebugEnabled()) {
- getLog().debug("association " + name);
- }
- if (operator.isChildEmpty(name, expected)) {
- assertTrue("l'association " + name + " devrait etre vide mais possede " + operator.sizeChild(name, actual) + " entrees", operator.isChildEmpty(name, actual));
- } else {
- assertFalse("l'association " + name + " devrait posseder " + operator.isChildEmpty(name, expected) + " mais est vide", operator.isChildEmpty(name, actual));
-
- }
- assertEquals(operator.isChildEmpty(name, actual), operator.isChildEmpty(name, expected));
-
- Class<?> type = operator.getAssociationPropertyType(name);
- Collection<?> src = (Collection<?>) operator.get(name, expected);
- Collection<?> dst = (Collection<?>) operator.get(name, actual);
-// assertEquals(src, dst);
- Iterator<?> itrSrc = src.iterator();
- Iterator<?> itrDst = dst.iterator();
- while (itrSrc.hasNext()) {
- if (TopiaEntity.class.isAssignableFrom(type)) {
- assertEntityEquals((TopiaEntity) itrSrc.next(), (TopiaEntity) itrDst.next(), treated);
- } else {
- assertEquals(itrSrc.next(), itrDst.next());
- }
- }
- }
-
- for (String name : operator.getProperties()) {
- if (getLog().isDebugEnabled()) {
- getLog().debug("dependency " + name);
- }
- if (associationProperties.contains(name)) {
- // deja traite au dessus
- continue;
- }
- Class<?> type = operator.getPropertyType(name);
- Object src = operator.get(name, expected);
- Object dst = operator.get(name, actual);
- assertFalse(src == null && dst != null);
- assertFalse(src != null && dst == null);
- if (src == null) {
- continue;
- }
- if (TopiaEntity.class.isAssignableFrom(type)) {
- assertEntityEquals((TopiaEntity) src, (TopiaEntity) dst, treated);
- } else {
- assertEquals(src, dst);
- }
- }
- }
-
- protected void createUnsupportedBeforeOperation(TopiaEntityEnum contract, TopiaEntity entity, Class<? extends TopiaReplicationOperation> operationClass, Object... parameters) throws Exception {
-
- getLog().info("entity " + entity.getTopiaId());
- prepareModel(entity.getTopiaId());
-
- service.addBeforeOperation(model, contract, operationClass, parameters);
- // on ne doit pas avoir le droit de creer cette operation
- fail();
- }
-
- protected void createUnsupportedAfterOperation(TopiaEntityEnum contract, TopiaEntity entity, Class<? extends TopiaReplicationOperation> operationClass, Object... parameters) throws Exception {
-
- getLog().info("entity " + entity.getTopiaId());
- prepareModel(entity.getTopiaId());
-// model = service.createModel(getContracts());
-// model.detectDirectDependencies();
- service.addAfterOperation(model, contract, operationClass, parameters);
- // on ne doit pas avoir le droit de creer cette operation
- fail();
- }
-
- protected Long getTestsTimeStamp() {
- if (testsTimeStamp == null) {
- testsTimeStamp = System.currentTimeMillis();
- getLog().info("tests timestamp : " + testsTimeStamp);
- }
- return testsTimeStamp;
- }
-
- protected File getTestDir(Class<?> testClass) {
- if (testsBasedir == null) {
- String tmp = System.getProperty("basedir");
- if (tmp == null) {
- tmp = new File("").getAbsolutePath();
- }
- String name = String.format(TEST_BASEDIR, File.separator, new Date(getTestsTimeStamp()));
- testsBasedir = new File(new File(tmp), name);
- getLog().info("tests basedir : " + testsBasedir);
- }
- return new File(testsBasedir, testClass.getSimpleName());
- }
-
- protected void createModel(TopiaEntity entity) throws TopiaException {
- model = service.createModel(getContracts(), entity.getTopiaId());
- }
-
- protected void prepareModel(String... ids) throws TopiaException {
- model = service.prepare(getContracts(), ids);
- }
-
- protected void prepareModelAll() throws TopiaException {
- model = service.prepareForAll(getContracts());
- }
-
- protected void prepareModelWithComputedOrder(String... ids) throws TopiaException {
- model = service.prepareWithComputedOrder(getContracts(), ids);
- }
-}
-
-
Copied: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/AbstractTopiaReplicationServiceTest.java (from rev 2098, trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/AbstractReplicationEngineTest.java)
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/AbstractTopiaReplicationServiceTest.java (rev 0)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/AbstractTopiaReplicationServiceTest.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -0,0 +1,654 @@
+/*
+ * #%L
+ * ToPIA :: Service Replication
+ *
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2004 - 2010 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%
+ */
+
+package org.nuiton.topia.replication;
+
+import org.apache.commons.logging.Log;
+import org.junit.Assert;
+import org.nuiton.i18n.I18n;
+import org.nuiton.topia.TopiaContext;
+import org.nuiton.topia.TopiaException;
+import org.nuiton.topia.framework.TopiaContextImplementor;
+import org.nuiton.topia.persistence.TopiaDAO;
+import org.nuiton.topia.persistence.TopiaEntity;
+import org.nuiton.topia.persistence.TopiaEntityEnum;
+import org.nuiton.topia.persistence.util.EntityOperator;
+import org.nuiton.topia.persistence.util.EntityOperatorStore;
+import org.nuiton.topia.persistence.util.TopiaEntityHelper;
+import org.nuiton.topia.replication.model.ReplicationModel;
+import org.nuiton.topia.replication.model.ReplicationNode;
+import org.nuiton.topia.replication.model.ReplicationOperationDef;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+/**
+ * TopiaReplicationServiceImplTest.
+ * <p/>
+ * Created: 07 jun. 09 17:14:22
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @version $Id$
+ * @since 2.2.0
+ */
+public abstract class AbstractTopiaReplicationServiceTest extends Assert {
+
+ static protected TopiaContext context;
+
+ static protected TopiaContext ctxt;
+
+ protected TopiaContextImplementor dstCtxt;
+
+ protected TopiaReplicationService service;
+
+ protected ReplicationModel model;
+
+ static protected boolean init;
+
+ static private Long testsTimeStamp;
+
+ static private File testsBasedir;
+
+ static private final String TEST_BASEDIR = "target%1$ssurefire-tests%1$s%2$td_%2$tm_%2$tY%1$s%2$tH_%2$tM_%2$tS";
+
+ public static void after() throws Exception {
+ if (context != null && !context.isClosed()) {
+ try {
+ context.closeContext();
+ } catch (TopiaException e) {
+ // cela peut arriver si on demande la fermeture dans un thread
+ // ailleurs...
+ }
+ }
+ init = false;
+ }
+
+ public void setUp() throws Exception {
+
+ if (!init) {
+
+ I18n.init(Locale.FRANCE);
+
+ try {
+ context = createDb("source");
+ } catch (Exception e) {
+ getLog().error("could not create db source.", e);
+ throw e;
+ }
+ init = true;
+ }
+
+ ctxt = context.beginTransaction();
+
+ service = context.getService(TopiaReplicationService.class);
+ }
+
+ public void tearDown() throws Exception {
+ if (ctxt != null) {
+ ctxt.rollbackTransaction();
+ ctxt.closeContext();
+ ctxt = null;
+ }
+ service = null;
+ }
+
+ protected abstract TopiaContext createDb2(String name) throws Exception;
+
+ protected abstract TopiaContext createDb(String name) throws Exception;
+
+ protected TopiaContext createReplicateDb(Object contract) throws Exception {
+ TopiaContext rootCtxt = createDb2(contract.toString() + dbCounter++);
+ return rootCtxt;
+ }
+
+ protected abstract TopiaEntityEnum[] getContracts();
+
+ protected abstract Log getLog();
+
+ protected <E extends TopiaEntity> E update(E e) throws TopiaException {
+ return (E) ((TopiaContextImplementor) ctxt).findByTopiaId(e.getTopiaId());
+ }
+
+ /**
+ * Test of detectTypes method, of class ReplicationServiceImplementor.
+ *
+ * @throws Exception if any error
+ */
+ public void testDetectTypes() throws Exception {
+ }
+
+ /**
+ * Test of getOperation method, of class ReplicationServiceImplementor.
+ *
+ * @throws Exception if any error
+ */
+ public void testGetOperation() throws Exception {
+ }
+
+ /**
+ * Test of detectAssociations method, of class ReplicationModel.
+ *
+ * @throws Exception if any error
+ */
+ public void testDetectAssociations() throws Exception {
+ }
+
+ /**
+ * Test of detectDirectDependencies method, of class ReplicationModel.
+ *
+ * @throws Exception if any error
+ */
+ public void testDetectDirectDependencies() throws Exception {
+ }
+
+ /**
+ * Test of detectShell method, of class ReplicationModel.
+ *
+ * @throws Exception if any error
+ */
+ public void testDetectShell() throws Exception {
+ }
+
+ /**
+ * Test of detectDependencies method, of class ReplicationModel.
+ *
+ * @throws Exception if any error
+ */
+ public void testDetectDependencies() throws Exception {
+ }
+
+ /**
+ * Test of detectObjectsToDettach method, of class ReplicationModel.
+ *
+ * @throws Exception if any error
+ */
+ public void testDetectObjectsToDettach() throws Exception {
+ }
+
+ /**
+ * Test of detectOperations method, of class ReplicationModel.
+ *
+ * @throws Exception if any error
+ */
+ public void testDetectOperations() throws Exception {
+ }
+
+ /**
+ * Test of doReplicate method, of class ReplicationService.
+ *
+ * @throws Exception if any error
+ */
+ public void testDoReplicate() throws Exception {
+ }
+
+ protected void detectTypes(TopiaEntity entity, Object... expectedCouple) throws TopiaException {
+
+ Set<?> detectTypes;
+
+ detectTypes = service.getModelBuilder().detectTypes(context, getContracts(), entity.getTopiaId());
+ assertEquals("expected types : " +
+ Arrays.toString(expectedCouple) +
+ " but was " + detectTypes,
+ expectedCouple.length, detectTypes.size());
+ for (Object o : expectedCouple) {
+ assertTrue(detectTypes.contains(o));
+ }
+ }
+
+ protected void getOperation(Class<? extends TopiaReplicationOperation> operationClass, boolean shouldExist) throws TopiaException {
+ TopiaReplicationOperation operation = service.getModelBuilder().getOperation(operationClass);
+ assertEquals(shouldExist, operation != null);
+ }
+
+ protected void detectAssociations(TopiaEntity entity,
+ Object... expectedCouple)
+ throws TopiaException {
+
+ createModel(entity);
+ model.detectAssociations();
+
+ assertEquals(0, expectedCouple.length % 2);
+
+ for (int i = 0, j = expectedCouple.length / 2; i < j; i++) {
+ TopiaEntityEnum src = (TopiaEntityEnum) expectedCouple[2 * i];
+ String name = (String) expectedCouple[2 * i + 1];
+ ReplicationNode nodeSrc = model.getNode(src);
+ assertNotNull("association " + name + " not found", nodeSrc);
+ assertTrue(nodeSrc.hasAssociation());
+ assertTrue(nodeSrc.getAssociations().containsKey(name));
+ }
+ }
+
+ protected void detectDirectDependencies(TopiaEntity entity,
+ Object... expectedCouple)
+ throws TopiaException {
+
+ createModel(entity);
+ model.detectDirectDependencies();
+
+ assertEquals(0, expectedCouple.length % 2);
+
+ for (int i = 0, j = expectedCouple.length / 2; i < j; i++) {
+ TopiaEntityEnum src = (TopiaEntityEnum) expectedCouple[2 * i];
+ String name = (String) expectedCouple[2 * i + 1];
+ ReplicationNode nodeSrc = model.getNode(src);
+ assertTrue(nodeSrc + " should have dependency but was not!", nodeSrc.hasDependency());
+ assertTrue(nodeSrc + " should contain dependency " + name + "but was not! (" + nodeSrc.getDependencies() + ")", nodeSrc.getDependencies().containsKey(name));
+ }
+ }
+
+ protected void detectShell(TopiaEntity entity,
+ TopiaEntityEnum... expected) throws
+ TopiaException {
+ Set<ReplicationNode> shell;
+
+ createModel(entity);
+ model.detectAssociations();
+ model.detectDirectDependencies();
+ model.detectShell();
+
+ TopiaEntityEnum c = TopiaEntityHelper.getEntityEnum(
+ entity.getClass(), getContracts());
+ assertNotNull(c);
+ shell = model.getNode(c.getContract()).getShell();
+ assertEquals(
+ "expected shell : " + Arrays.toString(expected) + ", but was " +
+ shell, expected.length, shell.size());
+
+ for (int i = 0, j = expected.length; i < j; i++) {
+ TopiaEntityEnum type = expected[i];
+ ReplicationNode node = model.getNode(type.getContract());
+ assertTrue(shell.contains(node));
+ assertEquals(type, node.getContract());
+ }
+ }
+
+ protected void detectDependencies(
+ TopiaEntity entity,
+ TopiaEntityEnum[]... expected) throws TopiaException {
+
+ createModel(entity);
+ model.detectAssociations();
+ model.detectDirectDependencies();
+ model.detectShell();
+ model.detectDependencies();
+ List<ReplicationNode> dependencies = model.getOrder();
+
+ int i = 0;
+ for (ReplicationNode level : dependencies) {
+ getLog().info("level " + level + " = " + level);
+ }
+
+// assertEquals("expected " + expected.length + " levels but had " + dependencies.size(), expected.length, dependencies.size());
+//
+// Iterator<List<ReplicationNode>> order = dependencies.iterator();
+// if (entity != null) {
+// getLog().info("for " + entity.getTopiaId());
+// }
+// int index = 0;
+// for (TopiaEntityEnum[] expectedLevel : expected) {
+//
+// List<ReplicationNode> next = order.next();
+// getLog().info("level " + (index++) + " : " + next);
+// for (TopiaEntityEnum ee : expectedLevel) {
+// ReplicationNode expectedNode = model.getNode(ee);
+//
+// assertTrue("should have contains node " + expectedNode, next.contains(expectedNode));
+// }
+//
+// }
+ }
+
+ protected void detectObjectsToDettach(TopiaEntity entity, Object... expected) throws TopiaException {
+
+ assertEquals(0, expected.length % 2);
+
+ createModel(entity);
+ model.detectAssociations();
+ model.detectDirectDependencies();
+ model.detectShell();
+ model.detectDependencies();
+ model.detectObjectsToDettach();
+ Set<ReplicationNode> nodes = new HashSet<ReplicationNode>();
+
+ for (int i = 0, j = expected.length / 2; i < j; i++) {
+ TopiaEntityEnum e = (TopiaEntityEnum) expected[2 * i];
+ ReplicationNode node = model.getNode(e);
+ String[] ids = (String[]) expected[2 * i + 1];
+ assertEquals(ids.length > 0, node.hasAssociationsToDettach());
+ for (String id : ids) {
+ assertTrue(node.getAssociationsToDettach().contains(id));
+ }
+ nodes.add(node);
+ }
+
+ for (ReplicationNode node : model.getNodes()) {
+ if (!nodes.contains(node)) {
+ // on verifie bien qu'il n' y a pas d'associations dettachee
+ assertFalse(node.hasAssociationsToDettach());
+ }
+ }
+
+ }
+
+ protected void detectOperations(TopiaEntity entity, Object... expected) throws TopiaException {
+
+ assertEquals(0, expected.length % 2);
+
+ if (entity == null) {
+ prepareModel();
+ } else {
+ prepareModel(entity.getTopiaId());
+ }
+// createModel(entity);
+// model.detectAssociations();
+// model.detectDirectDependencies();
+// model.detectShell();
+// model.detectDependencies();
+// model.detectObjectsToDettach();
+// model.detectOperations();
+
+ if (getLog().isInfoEnabled()) {
+ getLog().info("==========================================================================");
+ if (entity == null) {
+
+ getLog().info("resume of operations for all ");
+ } else {
+ getLog().info("resume of operations for entity " + entity.getTopiaId());
+ }
+
+ for (ReplicationNode node : model.getOrder()) {
+ List<ReplicationOperationDef> operations = node.getOperations();
+ for (ReplicationOperationDef op : operations) {
+ getLog().info("[" + node + "] : operation " + op);
+ }
+ }
+ getLog().info("==========================================================================");
+ }
+ }
+
+ private static int dbCounter;
+
+ protected void doReplicate(TopiaEntityEnum contract, TopiaEntity... entity) throws Exception {
+
+ TopiaContext rootCtxt = createReplicateDb("doReplicate_" + contract);
+
+ List<String> ids = TopiaEntityHelper.getTopiaIdList(Arrays.asList(entity));
+ getLog().info("entity " + ids);
+
+ prepareModel(ids.toArray(new String[ids.size()]));
+
+ dstCtxt = (TopiaContextImplementor) rootCtxt;
+
+ service.doReplicate(model, dstCtxt);
+
+ //dstCtxt.closeContext();
+
+ if (entity.length == 0) {
+
+ return;
+ }
+ dstCtxt = (TopiaContextImplementor) rootCtxt.beginTransaction();
+
+ for (TopiaEntity e : entity) {
+ TopiaEntity actual = dstCtxt.findByTopiaId(e.getTopiaId());
+ assertNotNull(actual);
+ assertEquals(e, actual);
+ }
+
+ dstCtxt.closeContext();
+
+ dstCtxt = (TopiaContextImplementor) rootCtxt;
+ }
+
+ protected void doReplicateAll() throws Exception {
+
+ TopiaContext rootCtxt = createReplicateDb("doReplicateAll");
+
+ prepareModelAll();
+
+ dstCtxt = (TopiaContextImplementor) rootCtxt;
+
+ service.doReplicate(model, dstCtxt);
+
+ TopiaContextImplementor ctxt2 = (TopiaContextImplementor) ctxt;
+ dstCtxt = (TopiaContextImplementor) rootCtxt.beginTransaction();
+
+ assertDbEquals(model.getContracts(), (TopiaContextImplementor) ctxt, ctxt2);
+
+ dstCtxt.closeContext();
+
+ dstCtxt = (TopiaContextImplementor) rootCtxt;
+ }
+
+ protected void doReplicateWithComputedOrder(TopiaEntity... entity) throws Exception {
+
+ TopiaContext rootCtxt = createReplicateDb("doReplicateWithComputedOrder");
+
+ List<String> ids = TopiaEntityHelper.getTopiaIdList(Arrays.asList(entity));
+
+ prepareModelWithComputedOrder(ids.toArray(new String[ids.size()]));
+
+ dstCtxt = (TopiaContextImplementor) rootCtxt;
+
+ service.doReplicate(model, dstCtxt);
+
+ getLog().info("replication is done for " + Arrays.toString(entity) + ", will verify data...");
+
+ TopiaContextImplementor ctxt2 = (TopiaContextImplementor) ctxt;
+ dstCtxt = (TopiaContextImplementor) rootCtxt.beginTransaction();
+
+ assertDbEquals(model.getContracts(), (TopiaContextImplementor) ctxt, ctxt2);
+
+ dstCtxt.closeContext();
+
+ dstCtxt = (TopiaContextImplementor) rootCtxt;
+ }
+
+ protected void assertDbEquals(TopiaEntityEnum[] contracts,
+ TopiaContextImplementor ctxt,
+ TopiaContextImplementor ctxt2) throws TopiaException {
+ Set<String> ids = new HashSet<String>();
+
+ if (getLog().isInfoEnabled()) {
+ getLog().info("will verify db for contracts " + Arrays.toString(contracts));
+ }
+ for (TopiaEntityEnum c : contracts) {
+ if (getLog().isDebugEnabled()) {
+ getLog().debug("verify for contract " + c);
+ }
+ TopiaDAO<? extends TopiaEntity> daoSrc = ctxt.getDAO(c.getContract());
+ TopiaDAO<? extends TopiaEntity> daoDst = ctxt2.getDAO(c.getContract());
+ long nbSrc = daoSrc.count();
+ long nbDst = daoDst.count();
+ assertEquals("le nombres d'entites de type " + c + " devrait etre " + nbSrc + " mais est " + nbDst, nbSrc, nbDst);
+ List<String> idsSrc = daoSrc.findAllIds();
+ List<String> idsDst = daoDst.findAllIds();
+ Collections.sort(idsSrc);
+ Collections.sort(idsDst);
+ assertEquals(idsSrc, idsDst);
+ for (String id : idsSrc) {
+ if (getLog().isDebugEnabled()) {
+ getLog().debug("verify for entity " + id);
+ }
+ TopiaEntity eSrc = daoSrc.findByTopiaId(id);
+ TopiaEntity eDst = daoDst.findByTopiaId(id);
+ assertEquals(eSrc, eDst);
+ assertEntityEquals(eSrc, eDst, ids);
+ }
+ }
+ }
+
+ protected void assertEntityEquals(TopiaEntity expected,
+ TopiaEntity actual,
+ Set<String> treated) {
+ if (treated == null) {
+ treated = new HashSet<String>();
+ }
+ if (treated.contains(actual.getTopiaId())) {
+ return;
+ }
+ if (getLog().isDebugEnabled()) {
+ getLog().debug(expected);
+ }
+ assertEquals(actual.getTopiaId(), expected.getTopiaId());
+ treated.add(actual.getTopiaId());
+ if (getLog().isDebugEnabled()) {
+ getLog().debug("expected : " + expected + " / actual " + actual);
+ }
+ TopiaEntityEnum contract = TopiaEntityHelper.getEntityEnum(expected.getClass(), getContracts());
+ if (contract == null) {
+ // this type of entity in not dealed here...
+ getLog().debug("untested property type " + expected.getClass());
+ return;
+ }
+ Assert.assertNotNull(
+ "contract not found for " + expected.getClass() + " in " +
+ Arrays.toString(getContracts()), contract);
+ EntityOperator<TopiaEntity> operator = EntityOperatorStore.getOperator(contract);
+ List<String> associationProperties = operator.getAssociationProperties();
+ for (String name : associationProperties) {
+ if (getLog().isDebugEnabled()) {
+ getLog().debug("association " + name);
+ }
+ if (operator.isChildEmpty(name, expected)) {
+ assertTrue("l'association " + name + " devrait etre vide mais possede " + operator.sizeChild(name, actual) + " entrees", operator.isChildEmpty(name, actual));
+ } else {
+ assertFalse("l'association " + name + " devrait posseder " + operator.isChildEmpty(name, expected) + " mais est vide", operator.isChildEmpty(name, actual));
+
+ }
+ assertEquals(operator.isChildEmpty(name, actual), operator.isChildEmpty(name, expected));
+
+ Class<?> type = operator.getAssociationPropertyType(name);
+ Collection<?> src = (Collection<?>) operator.get(name, expected);
+ Collection<?> dst = (Collection<?>) operator.get(name, actual);
+// assertEquals(src, dst);
+ Iterator<?> itrSrc = src.iterator();
+ Iterator<?> itrDst = dst.iterator();
+ while (itrSrc.hasNext()) {
+ if (TopiaEntity.class.isAssignableFrom(type)) {
+ assertEntityEquals((TopiaEntity) itrSrc.next(), (TopiaEntity) itrDst.next(), treated);
+ } else {
+ assertEquals(itrSrc.next(), itrDst.next());
+ }
+ }
+ }
+
+ for (String name : operator.getProperties()) {
+ if (getLog().isDebugEnabled()) {
+ getLog().debug("dependency " + name);
+ }
+ if (associationProperties.contains(name)) {
+ // deja traite au dessus
+ continue;
+ }
+ Class<?> type = operator.getPropertyType(name);
+ Object src = operator.get(name, expected);
+ Object dst = operator.get(name, actual);
+ assertFalse(src == null && dst != null);
+ assertFalse(src != null && dst == null);
+ if (src == null) {
+ continue;
+ }
+ if (TopiaEntity.class.isAssignableFrom(type)) {
+ assertEntityEquals((TopiaEntity) src, (TopiaEntity) dst, treated);
+ } else {
+ assertEquals(src, dst);
+ }
+ }
+ }
+
+ protected void createUnsupportedBeforeOperation(TopiaEntityEnum contract,
+ TopiaEntity entity,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... parameters) throws Exception {
+
+ getLog().info("entity " + entity.getTopiaId());
+ prepareModel(entity.getTopiaId());
+
+ service.addBeforeOperation(model, contract, operationClass, parameters);
+ // on ne doit pas avoir le droit de creer cette operation
+ fail();
+ }
+
+ protected void createUnsupportedAfterOperation(TopiaEntityEnum contract,
+ TopiaEntity entity,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... parameters) throws Exception {
+
+ getLog().info("entity " + entity.getTopiaId());
+ prepareModel(entity.getTopiaId());
+// model = service.createModel(getContracts());
+// model.detectDirectDependencies();
+ service.addAfterOperation(model, contract, operationClass, parameters);
+ // on ne doit pas avoir le droit de creer cette operation
+ fail();
+ }
+
+ protected Long getTestsTimeStamp() {
+ if (testsTimeStamp == null) {
+ testsTimeStamp = System.currentTimeMillis();
+ getLog().info("tests timestamp : " + testsTimeStamp);
+ }
+ return testsTimeStamp;
+ }
+
+ protected File getTestDir(Class<?> testClass) {
+ if (testsBasedir == null) {
+ String tmp = System.getProperty("basedir");
+ if (tmp == null) {
+ tmp = new File("").getAbsolutePath();
+ }
+ String name = String.format(TEST_BASEDIR, File.separator, new Date(getTestsTimeStamp()));
+ testsBasedir = new File(new File(tmp), name);
+ getLog().info("tests basedir : " + testsBasedir);
+ }
+ return new File(testsBasedir, testClass.getSimpleName());
+ }
+
+ protected void createModel(TopiaEntity entity) throws TopiaException {
+ model = service.getModelBuilder().createModel(context, getContracts(), entity.getTopiaId());
+ }
+
+ protected void prepareModel(String... ids) throws TopiaException {
+ model = service.prepare(getContracts(), ids);
+ }
+
+ protected void prepareModelAll() throws TopiaException {
+ model = service.prepareForAll(getContracts());
+ }
+
+ protected void prepareModelWithComputedOrder(String... ids) throws TopiaException {
+ model = service.prepareWithComputedOrder(getContracts(), ids);
+ }
+}
Property changes on: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/AbstractTopiaReplicationServiceTest.java
___________________________________________________________________
Added: svn:keywords
+ HeadURL Id Date Revision Author
Deleted: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/ReplicationEngineAllTest.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/ReplicationEngineAllTest.java 2010-08-15 11:51:20 UTC (rev 2100)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/ReplicationEngineAllTest.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -1,296 +0,0 @@
-/*
- * #%L
- * ToPIA :: Service Replication
- *
- * $Id$
- * $HeadURL$
- * %%
- * Copyright (C) 2004 - 2010 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%
- */
-
-package org.nuiton.topia.replication;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.Test;
-import org.nuiton.topia.TopiaContext;
-import org.nuiton.topia.TopiaContextFactory;
-import org.nuiton.topia.TopiaException;
-import org.nuiton.topia.TopiaTestDAOHelper.TopiaTestEntityEnum;
-import org.nuiton.topia.framework.TopiaContextImplementor;
-import org.nuiton.topia.persistence.TopiaEntity;
-import org.nuiton.topia.persistence.TopiaEntityEnum;
-import org.nuiton.topia.test.entities.Person;
-import org.nuiton.topia.test.entities.PersonImpl;
-import org.nuiton.topia.test.entities.Pet;
-import org.nuiton.topia.test.entities.PetImpl;
-import org.nuiton.topia.test.entities.Race;
-import org.nuiton.topia.test.entities.RaceImpl;
-
-import java.io.File;
-import java.util.Properties;
-
-/**
- * ReplicationEngineTest on model TopiaTest
- * <p/>
- * Created: 07 jun. 09 17:14:22
- *
- * @author tchemit <chemit(a)codelutin.com>
- * @since 2.2.0
- */
-public class ReplicationEngineAllTest extends AbstractReplicationEngineTest {
-
- /** to use log facility, just put in your code: log.info(\"...\"); */
- private static final Log log = LogFactory.getLog(ReplicationEngineTest.class);
-
- protected static final TopiaEntityEnum[] contracts = {
- TopiaTestEntityEnum.Person,
- TopiaTestEntityEnum.Pet,
- TopiaTestEntityEnum.Race
- };
-
- protected static final String entitiesList =
- PersonImpl.class.getName() + "," +
- PetImpl.class.getName() + "," +
- RaceImpl.class.getName();
-
- static protected Person person, person2;
-
- static protected Pet pet, pet2, pet3;
-
- static protected Race race, race2, race3;
-
- @AfterClass
- public static void after() throws Exception {
- AbstractReplicationEngineTest.after();
- }
-
- @Before
- @Override
- public void setUp() throws Exception {
-
- super.setUp();
-
- person = update(person);
- person2 = update(person2);
- pet = update(pet);
- pet2 = update(pet2);
- race = update(race);
- race2 = update(race2);
- race3 = update(race3);
- }
-
- @After
- @Override
- public void tearDown() throws Exception {
- super.tearDown();
- if (dstCtxt != null && !dstCtxt.isClosed()) {
- dstCtxt.closeContext();
- }
- }
-
-// @Ignore
-
- @Test
- @Override
- public void testDetectTypes() throws Exception {
-
- detectTypes(race, Race.class);
- detectTypes(pet, Pet.class, Person.class, Race.class);
- detectTypes(person, Pet.class, Person.class, Race.class);
-
- detectTypes(pet2, Pet.class);
- detectTypes(person2, Person.class);
- detectTypes(race2, Race.class);
-
- detectTypes(race3, Race.class);
- detectTypes(pet3, Pet.class, Race.class);
- }
-
-// @Ignore
-
- @Test
- @Override
- public void testGetOperation() throws Exception {
- }
-
-// @Ignore
-
- @Test
- @Override
- public void testDetectAssociations() throws Exception {
-
- detectAssociations(person, TopiaTestEntityEnum.Person, Person.PROPERTY_PET);
- detectAssociations(race);
- detectAssociations(pet);
-
- detectAssociations(person2);
- detectAssociations(race2);
- detectAssociations(pet2);
-
- }
-
-// @Ignore
-
- @Test
- @Override
- public void testDetectDirectDependencies() throws Exception {
-
- detectDirectDependencies(person);
- detectDirectDependencies(race);
- detectDirectDependencies(pet, TopiaTestEntityEnum.Pet, Pet.PROPERTY_PERSON, TopiaTestEntityEnum.Pet, Pet.PROPERTY_RACE);
-
- detectDirectDependencies(person2);
- detectDirectDependencies(race2);
- detectDirectDependencies(pet2);
- }
-
-// @Ignore
-
- @Test
- @Override
- public void testDetectShell() throws Exception {
-
- detectShell(person, TopiaTestEntityEnum.Pet, TopiaTestEntityEnum.Race);
- detectShell(race);
- detectShell(pet, TopiaTestEntityEnum.Person, TopiaTestEntityEnum.Race);
- detectShell(person2, TopiaTestEntityEnum.Pet, TopiaTestEntityEnum.Race);
- detectShell(race2);
- detectShell(pet2, TopiaTestEntityEnum.Person, TopiaTestEntityEnum.Race);
- }
-
-// @Ignore
-
- @Test
- @Override
- public void testDetectDependencies() throws Exception {
-
- detectDependencies(null,
- new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Race}, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Person}, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Pet});
- }
-
-// @Ignore
-
- @Test
- @Override
- public void testDetectObjectsToDettach() throws Exception {
-
- detectObjectsToDettach(null, TopiaTestEntityEnum.Person, new String[]{Person.PROPERTY_PET});
- }
-
-// @Ignore
-
- @Test
- @Override
- public void testDetectOperations() throws Exception {
-
- detectOperations(null);
- }
-
-// @Ignore
-
- @Test
- @Override
- public void testDoReplicate() throws Exception {
-
- doReplicateAll();
-
- }
-
- @Override
- protected TopiaContext createDb(String name) throws Exception {
-
- File localDB = new File(getTestDir(getClass()), "db_" + name);
-
- Properties config = getH2Properties(localDB);
-
- context = TopiaContextFactory.getContext(config);
-
- TopiaContextImplementor tx = (TopiaContextImplementor) context.beginTransaction();
-
- person = tx.getDAO(Person.class).create(Person.PROPERTY_NAME, "pudding master");
- race = tx.getDAO(Race.class).create(Race.PROPERTY_NAME, "race I");
- pet = tx.getDAO(Pet.class).create(Pet.PROPERTY_NAME, "pudding", Pet.PROPERTY_PERSON, person, Pet.PROPERTY_RACE, race);
-
- person2 = tx.getDAO(Person.class).create(Person.PROPERTY_NAME, "pudding II master");
- pet2 = tx.getDAO(Pet.class).create(Pet.PROPERTY_NAME, "pudding II");
- race2 = tx.getDAO(Race.class).create(Race.PROPERTY_NAME, "race II");
-
- race3 = tx.getDAO(Race.class).create(Race.PROPERTY_NAME, "race III");
- pet3 = tx.getDAO(Pet.class).create(Pet.PROPERTY_NAME, "pudding III", Pet.PROPERTY_RACE, race3);
-
- tx.commitTransaction();
- tx.closeContext();
- return context;
- }
-
- @Override
- protected TopiaContext createDb2(String name) throws Exception {
-
- File localDB = new File(getTestDir(getClass()), "db_" + name);
-
- Properties config = getH2Properties(localDB);
-
- return TopiaContextFactory.getContext(config);
- }
-
- @Override
- protected TopiaEntityEnum[] getContracts() {
- return contracts;
- }
-
- @Override
- protected Log getLog() {
- return log;
- }
-
- protected Properties getH2Properties(File f) {
-
- Properties config = new Properties();
- config.setProperty("hibernate.show_sql", "false");
- config.setProperty("hibernate.hbm2ddl.auto", "create");
-
- config.setProperty("topia.persistence.classes", entitiesList);
- config.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
- config.setProperty("hibernate.connection.driver_class", "org.h2.Driver");
- config.setProperty("hibernate.connection.url", "jdbc:h2:file:" + f.getAbsolutePath() + ";create=true");
- config.setProperty("hibernate.connection.username", "sa");
- config.setProperty("hibernate.connection.password", "");
-
- config.setProperty("topia.service.replication", ReplicationEngine.class.getName());
-
- return config;
- }
-
-
- @Override
- protected void createModel(TopiaEntity entity) throws TopiaException {
- model = service.createModelForAll(getContracts());
- }
-
- @Override
- protected void prepareModel(String... ids) throws TopiaException {
- model = service.prepareForAll(getContracts());
- }
-
-}
-
-
Deleted: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/ReplicationEngineTest.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/ReplicationEngineTest.java 2010-08-15 11:51:20 UTC (rev 2100)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/ReplicationEngineTest.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -1,445 +0,0 @@
-/*
- * #%L
- * ToPIA :: Service Replication
- *
- * $Id$
- * $HeadURL$
- * %%
- * Copyright (C) 2004 - 2010 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%
- */
-
-package org.nuiton.topia.replication;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.Test;
-import org.nuiton.topia.TopiaContext;
-import org.nuiton.topia.TopiaContextFactory;
-import org.nuiton.topia.TopiaException;
-import org.nuiton.topia.TopiaTestDAOHelper.TopiaTestEntityEnum;
-import org.nuiton.topia.framework.TopiaContextImplementor;
-import org.nuiton.topia.persistence.TopiaEntityEnum;
-import org.nuiton.topia.replication.model.ReplicationModel;
-import org.nuiton.topia.replication.operation.AttachAssociation;
-import org.nuiton.topia.replication.operation.DettachAssociation;
-import org.nuiton.topia.replication.operation.Duplicate;
-import org.nuiton.topia.replication.operation.FakeOperation;
-import org.nuiton.topia.replication.operation.UncreatableOperation;
-import org.nuiton.topia.replication.operation.UnregistredOperation;
-import org.nuiton.topia.test.entities.Person;
-import org.nuiton.topia.test.entities.PersonImpl;
-import org.nuiton.topia.test.entities.Pet;
-import org.nuiton.topia.test.entities.PetImpl;
-import org.nuiton.topia.test.entities.Race;
-import org.nuiton.topia.test.entities.RaceImpl;
-
-import java.io.File;
-import java.util.Properties;
-
-/**
- * ReplicationEngineTest on model TopiaTest
- * <p/>
- * Created: 07 jun. 09 17:14:22
- *
- * @author tchemit <chemit(a)codelutin.com>
- * @since 2.2.0
- */
-public class ReplicationEngineTest extends AbstractReplicationEngineTest {
-
- /** to use log facility, just put in your code: log.info(\"...\"); */
- private static final Log log = LogFactory.getLog(ReplicationEngineTest.class);
-
- protected static final TopiaEntityEnum[] contracts = {TopiaTestEntityEnum.Person, TopiaTestEntityEnum.Pet, TopiaTestEntityEnum.Race};
-
- protected static final String entitiesList = PersonImpl.class.getName() + "," + PetImpl.class.getName() + "," + RaceImpl.class.getName();
-
- static protected Person person, person2;
-
- static protected Pet pet, pet2, pet3;
-
- static protected Race race, race2, race3;
-
- @AfterClass
- public static void after() throws Exception {
- AbstractReplicationEngineTest.after();
- }
-
- @Before
- @Override
- public void setUp() throws Exception {
-
- super.setUp();
-
- person = update(person);
- person2 = update(person2);
- pet = update(pet);
- pet2 = update(pet2);
- race = update(race);
- race2 = update(race2);
- race3 = update(race3);
- }
-
- @After
- @Override
- public void tearDown() throws Exception {
- super.tearDown();
- if (dstCtxt != null && !dstCtxt.isClosed()) {
- dstCtxt.closeContext();
- }
- }
-
- @Test
- @Override
- public void testDetectTypes() throws Exception {
-
- detectTypes(race, Race.class);
- detectTypes(pet, Pet.class, Person.class, Race.class);
- detectTypes(person, Pet.class, Person.class, Race.class);
-
- detectTypes(pet2, Pet.class);
- detectTypes(person2, Person.class);
- detectTypes(race2, Race.class);
-
- detectTypes(race3, Race.class);
- detectTypes(pet3, Pet.class, Race.class);
- }
-
- @Test
- @Override
- public void testGetOperation() throws Exception {
-
- getOperation(UnregistredOperation.class, false);
- getOperation(UncreatableOperation.class, true);
- getOperation(FakeOperation.class, true);
- getOperation(Duplicate.class, true);
- getOperation(AttachAssociation.class, true);
- getOperation(DettachAssociation.class, true);
- }
-
- @Test
- @Override
- public void testDetectAssociations() throws Exception {
-
- detectAssociations(person, TopiaTestEntityEnum.Person, Person.PROPERTY_PET);
- detectAssociations(race);
- detectAssociations(pet);
-
- detectAssociations(person2);
- detectAssociations(race2);
- detectAssociations(pet2);
-
- }
-
- @Test
- @Override
- public void testDetectDirectDependencies() throws Exception {
-
- detectDirectDependencies(person);
- detectDirectDependencies(race);
- detectDirectDependencies(pet, TopiaTestEntityEnum.Pet, Pet.PROPERTY_PERSON, TopiaTestEntityEnum.Pet, Pet.PROPERTY_RACE);
-
- detectDirectDependencies(person2);
- detectDirectDependencies(race2);
- detectDirectDependencies(pet2);
- }
-
- @Test
- @Override
- public void testDetectShell() throws Exception {
-
- detectShell(person, TopiaTestEntityEnum.Pet, TopiaTestEntityEnum.Race);
- detectShell(race);
- detectShell(pet, TopiaTestEntityEnum.Person, TopiaTestEntityEnum.Race);
- detectShell(person2);
- detectShell(race2);
- detectShell(pet2);
- }
-
- @Test
- @Override
- public void testDetectDependencies() throws Exception {
-
- detectDependencies(person, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Race}, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Person}, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Pet});
- detectDependencies(race, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Race});
- detectDependencies(pet, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Race}, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Person}, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Pet});
-
- detectDependencies(person2, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Person});
- detectDependencies(race2, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Race});
- detectDependencies(pet2, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Pet});
- }
-
- @Test
- @Override
- public void testDetectObjectsToDettach() throws Exception {
-
- detectObjectsToDettach(person, TopiaTestEntityEnum.Person, new String[]{Person.PROPERTY_PET});
- detectObjectsToDettach(race);
- detectObjectsToDettach(pet, TopiaTestEntityEnum.Person, new String[]{Person.PROPERTY_PET});
-
- detectObjectsToDettach(person2);
- detectObjectsToDettach(race2);
- detectObjectsToDettach(pet2);
-
- detectObjectsToDettach(race3);
- detectObjectsToDettach(pet3);
- }
-
- @Test
- @Override
- public void testDetectOperations() throws Exception {
-
- //TODO Make some real test on detected operations...
-
- detectOperations(person);
- detectOperations(pet);
- detectOperations(race);
-
- detectOperations(person2);
- detectOperations(pet2);
- detectOperations(race2);
-
- detectOperations(race3);
- detectOperations(pet3);
- }
-
- @Test
- @Override
- public void testDoReplicate() throws Exception {
-
- doReplicate(TopiaTestEntityEnum.Person, person);
- doReplicate(TopiaTestEntityEnum.Person, person2);
- doReplicate(TopiaTestEntityEnum.Person, person, person2);
-
- doReplicate(TopiaTestEntityEnum.Pet, pet);
- doReplicate(TopiaTestEntityEnum.Pet, pet2);
- doReplicate(TopiaTestEntityEnum.Pet, pet, pet2, pet3);
- doReplicate(TopiaTestEntityEnum.Pet, person2, pet3);
-
- doReplicate(TopiaTestEntityEnum.Race, race);
- doReplicate(TopiaTestEntityEnum.Race, race2);
- doReplicate(TopiaTestEntityEnum.Race, race, race2);
-
- }
-
- /**
- * Cette methode montre pourquoi la simple replication ne peut pas
- * fonctionne :)
- * <p/>
- * Le replicateur ne deplique pas dans le bon ordre et on a donc des
- * violations de clef etrangeres...
- *
- * @throws Exception pour toute erreur
- */
- @Test(expected = TopiaException.class)
- public void testSimpleReplicateFailed() throws Exception {
-
- TopiaContext dstRootCtxt = createDb2("testSimpleReplicateFailed");
-
- //model = service.prepare(contracts, pet.getTopiaId());
-
- TopiaContext srcCtxt = ctxt.beginTransaction();
- dstCtxt = (TopiaContextImplementor) dstRootCtxt.beginTransaction();
-
- try {
-
- srcCtxt.replicateEntity(dstCtxt, pet);
-
- dstCtxt.commitTransaction();
-
- } finally {
- srcCtxt.rollbackTransaction();
- srcCtxt.closeContext();
- dstCtxt.closeContext();
- }
- }
-
- /**
- * Cette methode montre comment manuellement on peut effectuer la
- * replication (en dettachant les dependances qui forment des cycles)
- * <p/>
- * La methode utilisee ici peut ne pas fonctionner : si une clef metier est
- * posee sur une dependance alors cela ne fonctionne pas.
- *
- * @throws Exception pour toute erreur
- */
- @Test
- public void testSimpleReplicateNotSure() throws Exception {
-
- TopiaContext dstRootCtxt = createDb2("testSimpleReplicateNotSure");
-
- //model = service.prepare(contracts, pet.getTopiaId());
-
- TopiaContext srcCtxt = ctxt;
- dstCtxt = (TopiaContextImplementor) dstRootCtxt.beginTransaction();
-
- try {
-
-
- srcCtxt.replicateEntity(dstCtxt, race);
-
- // on dettache l'entite qui pose probleme
-
- pet.setPerson(null);
- srcCtxt.replicateEntity(dstCtxt, pet);
- srcCtxt.rollbackTransaction();
-
- srcCtxt.replicateEntity(dstCtxt, person);
-
- dstCtxt.commitTransaction();
- ((Pet) dstCtxt.findByTopiaId(pet.getTopiaId())).setPerson((Person) dstCtxt.findByTopiaId(person.getTopiaId()));
- dstCtxt.commitTransaction();
-
- srcCtxt.rollbackTransaction();
- person = update(person);
-
- assertEntityEquals(person, dstCtxt.findByTopiaId(person.getTopiaId()), null);
- } finally {
- srcCtxt.rollbackTransaction();
- //srcCtxt.closeContext();
- dstCtxt.closeContext();
- }
- }
-
- /**
- * Cette methode montre comment manuellement on peut effectuer la
- * replication (en dettachant les associations qui forment des cycles)
- * <p/>
- * La methode utilisee ici fonctionne mieux que la precedante : il parrait
- * dificille de pose une une clef metier sur une association :).
- * <p/>
- * On remarque que l'on dettache l'assocation qui forme un cycle et que l'on
- * est pas obligee de la reattachee car elle est bi-directionnelle.
- * <p/>
- * On doit optimiser l'algorithme dans la methode {@link
- * ReplicationModel#adjustOperations(org.nuiton.topia.persistence.util.TopiaEntityIdsMap)}.
- *
- * @throws Exception pour toute erreur
- */
- @Test
- public void testSimpleReplicateSure() throws Exception {
-
- TopiaContext dstRootCtxt = createDb2("testSimpleReplicateSure");
-
- //model = service.prepare(contracts, pet.getTopiaId());
-
- TopiaContext srcCtxt = ctxt;
- dstCtxt = (TopiaContextImplementor) dstRootCtxt.beginTransaction();
-
- try {
-
- srcCtxt.replicateEntity(dstCtxt, race);
- // on dettache l'association qui pose probleme
- person.setPet(null);
- srcCtxt.replicateEntity(dstCtxt, person);
-
- srcCtxt.replicateEntity(dstCtxt, pet);
- srcCtxt.rollbackTransaction();
- dstCtxt.commitTransaction();
-
- //((Person) dstCtxt.findByTopiaId(person.getTopiaId())).addPet(((Pet) dstCtxt.findByTopiaId(pet.getTopiaId())));
- //dstCtxt.commitTransaction();
-
- srcCtxt.rollbackTransaction();
-
- srcCtxt.closeContext();
- dstCtxt.closeContext();
-
- ctxt = context.beginTransaction();
- dstCtxt = (TopiaContextImplementor) dstRootCtxt.beginTransaction();
-
- person = update(person);
-
- assertEntityEquals(person, dstCtxt.findByTopiaId(person.getTopiaId()), null);
-
- } finally {
- dstCtxt.closeContext();
- }
- }
-
- @Override
- protected TopiaContext createDb(String name) throws Exception {
-
- File localDB = new File(getTestDir(getClass()), "db_" + name);
-
- Properties config = getH2Properties(localDB);
-
- context = TopiaContextFactory.getContext(config);
-
- TopiaContextImplementor tx = (TopiaContextImplementor) context.beginTransaction();
-
- person = tx.getDAO(Person.class).create(Person.PROPERTY_NAME, "pudding master");
- race = tx.getDAO(Race.class).create(Race.PROPERTY_NAME, "race I");
- pet = tx.getDAO(Pet.class).create(Pet.PROPERTY_NAME, "pudding", Pet.PROPERTY_PERSON, person, Pet.PROPERTY_RACE, race);
-
- person2 = tx.getDAO(Person.class).create(Person.PROPERTY_NAME, "pudding II master");
- pet2 = tx.getDAO(Pet.class).create(Pet.PROPERTY_NAME, "pudding II");
- race2 = tx.getDAO(Race.class).create(Race.PROPERTY_NAME, "race II");
-
- race3 = tx.getDAO(Race.class).create(Race.PROPERTY_NAME, "race III");
- pet3 = tx.getDAO(Pet.class).create(Pet.PROPERTY_NAME, "pudding III", Pet.PROPERTY_RACE, race3);
-
- tx.commitTransaction();
- tx.closeContext();
- return context;
- }
-
- @Override
- protected TopiaContext createDb2(String name) throws Exception {
-
- File localDB = new File(getTestDir(getClass()), "db_" + name);
-
- log.info("db dir :\n" + localDB.getAbsolutePath());
-
- Properties config = getH2Properties(localDB);
-
- return TopiaContextFactory.getContext(config);
- }
-
- @Override
- protected TopiaEntityEnum[] getContracts() {
- return contracts;
- }
-
- @Override
- protected Log getLog() {
- return log;
- }
-
- protected Properties getH2Properties(File f) {
-
- Properties config = new Properties();
- config.setProperty("hibernate.show_sql", "false");
- config.setProperty("hibernate.hbm2ddl.auto", "create");
-
- config.setProperty("topia.persistence.classes", entitiesList);
- config.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
- config.setProperty("hibernate.connection.driver_class", "org.h2.Driver");
- config.setProperty("hibernate.connection.url", "jdbc:h2:file:" + f.getAbsolutePath() + "/db;create=true");
- config.setProperty("hibernate.connection.username", "sa");
- config.setProperty("hibernate.connection.password", "");
-
- config.setProperty("topia.service.replication", ReplicationEngine.class.getName());
-
- return config;
- }
-}
-
-
Modified: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationOperationTest.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationOperationTest.java 2010-08-15 11:51:20 UTC (rev 2100)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationOperationTest.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -54,17 +54,18 @@
import java.util.Properties;
/**
- * ReplicationEngineTest on model TopiaTest
+ * TopiaReplicationServiceImplTest on model TopiaTest
* <p/>
* Created: 07 jun. 09 17:14:22
*
* @author tchemit <chemit(a)codelutin.com>
* @since 2.2.0
*/
-public class TopiaReplicationOperationTest extends AbstractReplicationEngineTest {
+public class TopiaReplicationOperationTest extends AbstractTopiaReplicationServiceTest {
- /** to use log facility, just put in your code: log.info(\"...\"); */
- private static final Log log = LogFactory.getLog(ReplicationEngineTest.class);
+ /** Logger */
+ private static final Log log =
+ LogFactory.getLog(TopiaReplicationOperationTest.class);
protected static final TopiaEntityEnum[] contracts = {TopiaTestEntityEnum.Person, TopiaTestEntityEnum.Pet, TopiaTestEntityEnum.Race};
@@ -78,7 +79,7 @@
@AfterClass
public static void after() throws Exception {
- AbstractReplicationEngineTest.after();
+ AbstractTopiaReplicationServiceTest.after();
}
@Before
@@ -106,23 +107,11 @@
@Test(expected = NullPointerException.class)
public void testGetOperation_nullOperationClass() throws Exception {
- service.getOperation(null);
+ getModelBuilder().getOperation(null);
}
- @Test(expected = IllegalStateException.class)
- public void testGetOperation_serviceNotInit() throws Exception {
-// ReplicationEngine.operations = null;
- try {
- new ReplicationEngine().getOperation(Duplicate.class);
- } catch (IllegalStateException e) {
- if (log.isErrorEnabled()) {
- log.error(e);
- }
- throw e;
- } finally {
-
- service.preInit((TopiaContextImplementor) context);
- }
+ protected TopiaReplicationModelBuilder getModelBuilder() {
+ return service.getModelBuilder();
}
@Test
@@ -139,34 +128,34 @@
@Test(expected = NullPointerException.class)
public void testCreateOperation_nullModel() throws Exception {
- service.createOperation(null, null, null, null);
+ getModelBuilder().createOperation(null, null, null, null);
}
@Test(expected = NullPointerException.class)
public void testCreateOperation_nullType() throws Exception {
- model = service.createModel(contracts);
- service.createOperation(model, null, null, null);
+ model = getModelBuilder().createModel(context, contracts);
+ getModelBuilder().createOperation(model, null, null, null);
}
@Test(expected = NullPointerException.class)
public void testCreateOperation_nullPhase() throws Exception {
- model = service.createModel(contracts);
- service.createOperation(model, TopiaTestEntityEnum.Pet, null, null);
+ model = getModelBuilder().createModel(context, contracts);
+ getModelBuilder().createOperation(model, TopiaTestEntityEnum.Pet, null, null);
}
@Test(expected = NullPointerException.class)
public void testCreateOperation_nullOperationClass() throws Exception {
- model = service.createModel(contracts);
- service.createOperation(model, TopiaTestEntityEnum.Pet, ReplicationOperationPhase.before, null);
+ model = getModelBuilder().createModel(context, contracts);
+ getModelBuilder().createOperation(model, TopiaTestEntityEnum.Pet, ReplicationOperationPhase.before, null);
}
@Test(expected = IllegalArgumentException.class)
public void testCreateOperation_noNode() throws Exception {
- model = service.createModel(contracts);
+ model = getModelBuilder().createModel(context, contracts);
// le noeud Pet n'existe pas
service.addAfterOperation(model, TopiaTestEntityEnum.Pet, Duplicate.class);
}
@@ -174,7 +163,7 @@
@Test(expected = IllegalArgumentException.class)
public void testCreateOperation_noOperation() throws Exception {
- model = service.createModel(contracts);
+ model = getModelBuilder().createModel(context, contracts);
// le noeud Pet n'existe pas
service.addAfterOperation(model, TopiaTestEntityEnum.Pet, UnregistredOperation.class);
}
@@ -222,35 +211,35 @@
@Test(expected = IllegalArgumentException.class)
public void testCreateOperation_wrongParameterNumber() throws Exception {
- model = service.createModel(contracts, pet.getTopiaId());
+ model = getModelBuilder().createModel(context, contracts, pet.getTopiaId());
service.addBeforeOperation(model, TopiaTestEntityEnum.Pet, FakeOperation.class);
}
@Test(expected = IllegalArgumentException.class)
public void testCreateOperation_wrongParameterNumber2() throws Exception {
- model = service.createModel(contracts, pet.getTopiaId());
+ model = getModelBuilder().createModel(context, contracts, pet.getTopiaId());
service.addBeforeOperation(model, TopiaTestEntityEnum.Pet, FakeOperation.class, String.class, String.class);
}
@Test(expected = IllegalArgumentException.class)
public void testCreateOperation_wrongParameterType() throws Exception {
- model = service.createModel(contracts, pet.getTopiaId());
+ model = getModelBuilder().createModel(context, contracts, pet.getTopiaId());
service.addBeforeOperation(model, TopiaTestEntityEnum.Pet, FakeOperation.class, Integer.class);
}
@Test(expected = IllegalArgumentException.class)
public void testCreateOperation_nullParameter() throws Exception {
- model = service.createModel(contracts, pet.getTopiaId());
+ model = getModelBuilder().createModel(context, contracts, pet.getTopiaId());
service.addBeforeOperation(model, TopiaTestEntityEnum.Pet, FakeOperation.class, (Object) null);
}
@Test
public void testCreateOperation() throws Exception {
- model = service.createModel(contracts, pet.getTopiaId());
+ model = getModelBuilder().createModel(context, contracts, pet.getTopiaId());
service.addBeforeOperation(model, TopiaTestEntityEnum.Pet, FakeOperation.class, "before");
service.addAfterOperation(model, TopiaTestEntityEnum.Race, FakeOperation.class, "after");
}
@@ -264,7 +253,7 @@
@Test(expected = NullPointerException.class)
public void testDoReplicate_nullDstCtxt() throws Exception {
- model = service.createModel(contracts);
+ model = getModelBuilder().createModel(context, contracts);
service.doReplicate(model, null);
}
@@ -277,7 +266,8 @@
context = TopiaContextFactory.getContext(config);
- TopiaContextImplementor tx = (TopiaContextImplementor) context.beginTransaction();
+ TopiaContextImplementor tx =
+ (TopiaContextImplementor) context.beginTransaction();
person = tx.getDAO(Person.class).create(Person.PROPERTY_NAME, "pudding master");
race = tx.getDAO(Race.class).create(Race.PROPERTY_NAME, "race I");
@@ -315,7 +305,7 @@
config.setProperty("hibernate.connection.username", "sa");
config.setProperty("hibernate.connection.password", "");
- config.setProperty("topia.service.replication", ReplicationEngine.class.getName());
+ config.setProperty("topia.service.replication", TopiaReplicationServiceImpl.class.getName());
return config;
}
Copied: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationServiceImplAllTest.java (from rev 2098, trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/ReplicationEngineAllTest.java)
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationServiceImplAllTest.java (rev 0)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationServiceImplAllTest.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -0,0 +1,296 @@
+/*
+ * #%L
+ * ToPIA :: Service Replication
+ *
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2004 - 2010 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%
+ */
+
+package org.nuiton.topia.replication;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+import org.nuiton.topia.TopiaContext;
+import org.nuiton.topia.TopiaContextFactory;
+import org.nuiton.topia.TopiaException;
+import org.nuiton.topia.TopiaTestDAOHelper.TopiaTestEntityEnum;
+import org.nuiton.topia.framework.TopiaContextImplementor;
+import org.nuiton.topia.persistence.TopiaEntity;
+import org.nuiton.topia.persistence.TopiaEntityEnum;
+import org.nuiton.topia.test.entities.Person;
+import org.nuiton.topia.test.entities.PersonImpl;
+import org.nuiton.topia.test.entities.Pet;
+import org.nuiton.topia.test.entities.PetImpl;
+import org.nuiton.topia.test.entities.Race;
+import org.nuiton.topia.test.entities.RaceImpl;
+
+import java.io.File;
+import java.util.Properties;
+
+/**
+ * TopiaReplicationServiceImplTest on model TopiaTest
+ * <p/>
+ * Created: 07 jun. 09 17:14:22
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
+ */
+public class TopiaReplicationServiceImplAllTest extends AbstractTopiaReplicationServiceTest {
+
+ /** Logger */
+ private static final Log log = LogFactory.getLog(TopiaReplicationServiceImplTest.class);
+
+ protected static final TopiaEntityEnum[] contracts = {
+ TopiaTestEntityEnum.Person,
+ TopiaTestEntityEnum.Pet,
+ TopiaTestEntityEnum.Race
+ };
+
+ protected static final String entitiesList =
+ PersonImpl.class.getName() + "," +
+ PetImpl.class.getName() + "," +
+ RaceImpl.class.getName();
+
+ static protected Person person, person2;
+
+ static protected Pet pet, pet2, pet3;
+
+ static protected Race race, race2, race3;
+
+ @AfterClass
+ public static void after() throws Exception {
+ AbstractTopiaReplicationServiceTest.after();
+ }
+
+ @Before
+ @Override
+ public void setUp() throws Exception {
+
+ super.setUp();
+
+ person = update(person);
+ person2 = update(person2);
+ pet = update(pet);
+ pet2 = update(pet2);
+ race = update(race);
+ race2 = update(race2);
+ race3 = update(race3);
+ }
+
+ @After
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ if (dstCtxt != null && !dstCtxt.isClosed()) {
+ dstCtxt.closeContext();
+ }
+ }
+
+// @Ignore
+
+ @Test
+ @Override
+ public void testDetectTypes() throws Exception {
+
+ detectTypes(race, Race.class);
+ detectTypes(pet, Pet.class, Person.class, Race.class);
+ detectTypes(person, Pet.class, Person.class, Race.class);
+
+ detectTypes(pet2, Pet.class);
+ detectTypes(person2, Person.class);
+ detectTypes(race2, Race.class);
+
+ detectTypes(race3, Race.class);
+ detectTypes(pet3, Pet.class, Race.class);
+ }
+
+// @Ignore
+
+ @Test
+ @Override
+ public void testGetOperation() throws Exception {
+ }
+
+// @Ignore
+
+ @Test
+ @Override
+ public void testDetectAssociations() throws Exception {
+
+ detectAssociations(person, TopiaTestEntityEnum.Person, Person.PROPERTY_PET);
+ detectAssociations(race);
+ detectAssociations(pet);
+
+ detectAssociations(person2);
+ detectAssociations(race2);
+ detectAssociations(pet2);
+
+ }
+
+// @Ignore
+
+ @Test
+ @Override
+ public void testDetectDirectDependencies() throws Exception {
+
+ detectDirectDependencies(person);
+ detectDirectDependencies(race);
+ detectDirectDependencies(pet, TopiaTestEntityEnum.Pet, Pet.PROPERTY_PERSON, TopiaTestEntityEnum.Pet, Pet.PROPERTY_RACE);
+
+ detectDirectDependencies(person2);
+ detectDirectDependencies(race2);
+ detectDirectDependencies(pet2);
+ }
+
+// @Ignore
+
+ @Test
+ @Override
+ public void testDetectShell() throws Exception {
+
+ detectShell(person, TopiaTestEntityEnum.Pet, TopiaTestEntityEnum.Race);
+ detectShell(race);
+ detectShell(pet, TopiaTestEntityEnum.Person, TopiaTestEntityEnum.Race);
+ detectShell(person2, TopiaTestEntityEnum.Pet, TopiaTestEntityEnum.Race);
+ detectShell(race2);
+ detectShell(pet2, TopiaTestEntityEnum.Person, TopiaTestEntityEnum.Race);
+ }
+
+// @Ignore
+
+ @Test
+ @Override
+ public void testDetectDependencies() throws Exception {
+
+ detectDependencies(null,
+ new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Race}, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Person}, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Pet});
+ }
+
+// @Ignore
+
+ @Test
+ @Override
+ public void testDetectObjectsToDettach() throws Exception {
+
+ detectObjectsToDettach(null, TopiaTestEntityEnum.Person, new String[]{Person.PROPERTY_PET});
+ }
+
+// @Ignore
+
+ @Test
+ @Override
+ public void testDetectOperations() throws Exception {
+
+ detectOperations(null);
+ }
+
+// @Ignore
+
+ @Test
+ @Override
+ public void testDoReplicate() throws Exception {
+
+ doReplicateAll();
+
+ }
+
+ @Override
+ protected TopiaContext createDb(String name) throws Exception {
+
+ File localDB = new File(getTestDir(getClass()), "db_" + name);
+
+ Properties config = getH2Properties(localDB);
+
+ context = TopiaContextFactory.getContext(config);
+
+ TopiaContextImplementor tx = (TopiaContextImplementor) context.beginTransaction();
+
+ person = tx.getDAO(Person.class).create(Person.PROPERTY_NAME, "pudding master");
+ race = tx.getDAO(Race.class).create(Race.PROPERTY_NAME, "race I");
+ pet = tx.getDAO(Pet.class).create(Pet.PROPERTY_NAME, "pudding", Pet.PROPERTY_PERSON, person, Pet.PROPERTY_RACE, race);
+
+ person2 = tx.getDAO(Person.class).create(Person.PROPERTY_NAME, "pudding II master");
+ pet2 = tx.getDAO(Pet.class).create(Pet.PROPERTY_NAME, "pudding II");
+ race2 = tx.getDAO(Race.class).create(Race.PROPERTY_NAME, "race II");
+
+ race3 = tx.getDAO(Race.class).create(Race.PROPERTY_NAME, "race III");
+ pet3 = tx.getDAO(Pet.class).create(Pet.PROPERTY_NAME, "pudding III", Pet.PROPERTY_RACE, race3);
+
+ tx.commitTransaction();
+ tx.closeContext();
+ return context;
+ }
+
+ @Override
+ protected TopiaContext createDb2(String name) throws Exception {
+
+ File localDB = new File(getTestDir(getClass()), "db_" + name);
+
+ Properties config = getH2Properties(localDB);
+
+ return TopiaContextFactory.getContext(config);
+ }
+
+ @Override
+ protected TopiaEntityEnum[] getContracts() {
+ return contracts;
+ }
+
+ @Override
+ protected Log getLog() {
+ return log;
+ }
+
+ protected Properties getH2Properties(File f) {
+
+ Properties config = new Properties();
+ config.setProperty("hibernate.show_sql", "false");
+ config.setProperty("hibernate.hbm2ddl.auto", "create");
+
+ config.setProperty("topia.persistence.classes", entitiesList);
+ config.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
+ config.setProperty("hibernate.connection.driver_class", "org.h2.Driver");
+ config.setProperty("hibernate.connection.url", "jdbc:h2:file:" + f.getAbsolutePath() + ";create=true");
+ config.setProperty("hibernate.connection.username", "sa");
+ config.setProperty("hibernate.connection.password", "");
+
+ config.setProperty(TopiaReplicationServiceImpl.TOPIA_SERVICE_NAME, TopiaReplicationServiceImpl.class.getName());
+
+ return config;
+ }
+
+
+ @Override
+ protected void createModel(TopiaEntity entity) throws TopiaException {
+ model = service.getModelBuilder().createModelForAll(getContracts());
+ }
+
+ @Override
+ protected void prepareModel(String... ids) throws TopiaException {
+ model = service.prepareForAll(getContracts());
+ }
+
+}
+
+
Property changes on: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationServiceImplAllTest.java
___________________________________________________________________
Added: svn:keywords
+ HeadURL Id Date Revision Author
Copied: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationServiceImplTest.java (from rev 2098, trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/ReplicationEngineTest.java)
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationServiceImplTest.java (rev 0)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationServiceImplTest.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -0,0 +1,446 @@
+/*
+ * #%L
+ * ToPIA :: Service Replication
+ *
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2004 - 2010 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%
+ */
+
+package org.nuiton.topia.replication;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+import org.nuiton.topia.TopiaContext;
+import org.nuiton.topia.TopiaContextFactory;
+import org.nuiton.topia.TopiaException;
+import org.nuiton.topia.TopiaTestDAOHelper.TopiaTestEntityEnum;
+import org.nuiton.topia.framework.TopiaContextImplementor;
+import org.nuiton.topia.persistence.TopiaEntityEnum;
+import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
+import org.nuiton.topia.replication.model.ReplicationModel;
+import org.nuiton.topia.replication.operation.AttachAssociation;
+import org.nuiton.topia.replication.operation.DettachAssociation;
+import org.nuiton.topia.replication.operation.Duplicate;
+import org.nuiton.topia.replication.operation.FakeOperation;
+import org.nuiton.topia.replication.operation.UncreatableOperation;
+import org.nuiton.topia.replication.operation.UnregistredOperation;
+import org.nuiton.topia.test.entities.Person;
+import org.nuiton.topia.test.entities.PersonImpl;
+import org.nuiton.topia.test.entities.Pet;
+import org.nuiton.topia.test.entities.PetImpl;
+import org.nuiton.topia.test.entities.Race;
+import org.nuiton.topia.test.entities.RaceImpl;
+
+import java.io.File;
+import java.util.Properties;
+
+/**
+ * TopiaReplicationServiceImplTest on model TopiaTest
+ * <p/>
+ * Created: 07 jun. 09 17:14:22
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
+ */
+public class TopiaReplicationServiceImplTest extends AbstractTopiaReplicationServiceTest {
+
+ /** Logger */
+ private static final Log log = LogFactory.getLog(TopiaReplicationServiceImplTest.class);
+
+ protected static final TopiaEntityEnum[] contracts = {TopiaTestEntityEnum.Person, TopiaTestEntityEnum.Pet, TopiaTestEntityEnum.Race};
+
+ protected static final String entitiesList = PersonImpl.class.getName() + "," + PetImpl.class.getName() + "," + RaceImpl.class.getName();
+
+ static protected Person person, person2;
+
+ static protected Pet pet, pet2, pet3;
+
+ static protected Race race, race2, race3;
+
+ @AfterClass
+ public static void after() throws Exception {
+ AbstractTopiaReplicationServiceTest.after();
+ }
+
+ @Before
+ @Override
+ public void setUp() throws Exception {
+
+ super.setUp();
+
+ person = update(person);
+ person2 = update(person2);
+ pet = update(pet);
+ pet2 = update(pet2);
+ race = update(race);
+ race2 = update(race2);
+ race3 = update(race3);
+ }
+
+ @After
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ if (dstCtxt != null && !dstCtxt.isClosed()) {
+ dstCtxt.closeContext();
+ }
+ }
+
+ @Test
+ @Override
+ public void testDetectTypes() throws Exception {
+
+ detectTypes(race, Race.class);
+ detectTypes(pet, Pet.class, Person.class, Race.class);
+ detectTypes(person, Pet.class, Person.class, Race.class);
+
+ detectTypes(pet2, Pet.class);
+ detectTypes(person2, Person.class);
+ detectTypes(race2, Race.class);
+
+ detectTypes(race3, Race.class);
+ detectTypes(pet3, Pet.class, Race.class);
+ }
+
+ @Test
+ @Override
+ public void testGetOperation() throws Exception {
+
+ getOperation(UnregistredOperation.class, false);
+ getOperation(UncreatableOperation.class, true);
+ getOperation(FakeOperation.class, true);
+ getOperation(Duplicate.class, true);
+ getOperation(AttachAssociation.class, true);
+ getOperation(DettachAssociation.class, true);
+ }
+
+ @Test
+ @Override
+ public void testDetectAssociations() throws Exception {
+
+ detectAssociations(person, TopiaTestEntityEnum.Person, Person.PROPERTY_PET);
+ detectAssociations(race);
+ detectAssociations(pet);
+
+ detectAssociations(person2);
+ detectAssociations(race2);
+ detectAssociations(pet2);
+
+ }
+
+ @Test
+ @Override
+ public void testDetectDirectDependencies() throws Exception {
+
+ detectDirectDependencies(person);
+ detectDirectDependencies(race);
+ detectDirectDependencies(pet, TopiaTestEntityEnum.Pet, Pet.PROPERTY_PERSON, TopiaTestEntityEnum.Pet, Pet.PROPERTY_RACE);
+
+ detectDirectDependencies(person2);
+ detectDirectDependencies(race2);
+ detectDirectDependencies(pet2);
+ }
+
+ @Test
+ @Override
+ public void testDetectShell() throws Exception {
+
+ detectShell(person, TopiaTestEntityEnum.Pet, TopiaTestEntityEnum.Race);
+ detectShell(race);
+ detectShell(pet, TopiaTestEntityEnum.Person, TopiaTestEntityEnum.Race);
+ detectShell(person2);
+ detectShell(race2);
+ detectShell(pet2);
+ }
+
+ @Test
+ @Override
+ public void testDetectDependencies() throws Exception {
+
+ detectDependencies(person, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Race}, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Person}, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Pet});
+ detectDependencies(race, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Race});
+ detectDependencies(pet, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Race}, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Person}, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Pet});
+
+ detectDependencies(person2, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Person});
+ detectDependencies(race2, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Race});
+ detectDependencies(pet2, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Pet});
+ }
+
+ @Test
+ @Override
+ public void testDetectObjectsToDettach() throws Exception {
+
+ detectObjectsToDettach(person, TopiaTestEntityEnum.Person, new String[]{Person.PROPERTY_PET});
+ detectObjectsToDettach(race);
+ detectObjectsToDettach(pet, TopiaTestEntityEnum.Person, new String[]{Person.PROPERTY_PET});
+
+ detectObjectsToDettach(person2);
+ detectObjectsToDettach(race2);
+ detectObjectsToDettach(pet2);
+
+ detectObjectsToDettach(race3);
+ detectObjectsToDettach(pet3);
+ }
+
+ @Test
+ @Override
+ public void testDetectOperations() throws Exception {
+
+ //TODO Make some real test on detected operations...
+
+ detectOperations(person);
+ detectOperations(pet);
+ detectOperations(race);
+
+ detectOperations(person2);
+ detectOperations(pet2);
+ detectOperations(race2);
+
+ detectOperations(race3);
+ detectOperations(pet3);
+ }
+
+ @Test
+ @Override
+ public void testDoReplicate() throws Exception {
+
+ doReplicate(TopiaTestEntityEnum.Person, person);
+ doReplicate(TopiaTestEntityEnum.Person, person2);
+ doReplicate(TopiaTestEntityEnum.Person, person, person2);
+
+ doReplicate(TopiaTestEntityEnum.Pet, pet);
+ doReplicate(TopiaTestEntityEnum.Pet, pet2);
+ doReplicate(TopiaTestEntityEnum.Pet, pet, pet2, pet3);
+ doReplicate(TopiaTestEntityEnum.Pet, person2, pet3);
+
+ doReplicate(TopiaTestEntityEnum.Race, race);
+ doReplicate(TopiaTestEntityEnum.Race, race2);
+ doReplicate(TopiaTestEntityEnum.Race, race, race2);
+
+ }
+
+ /**
+ * Cette methode montre pourquoi la simple replication ne peut pas
+ * fonctionne :)
+ * <p/>
+ * Le replicateur ne deplique pas dans le bon ordre et on a donc des
+ * violations de clef etrangeres...
+ *
+ * @throws Exception pour toute erreur
+ */
+ @Test(expected = TopiaException.class)
+ public void testSimpleReplicateFailed() throws Exception {
+
+ TopiaContext dstRootCtxt = createDb2("testSimpleReplicateFailed");
+
+ //model = service.prepare(contracts, pet.getTopiaId());
+
+ TopiaContext srcCtxt = ctxt.beginTransaction();
+ dstCtxt = (TopiaContextImplementor) dstRootCtxt.beginTransaction();
+
+ try {
+
+ srcCtxt.replicateEntity(dstCtxt, pet);
+
+ dstCtxt.commitTransaction();
+
+ } finally {
+ srcCtxt.rollbackTransaction();
+ srcCtxt.closeContext();
+ dstCtxt.closeContext();
+ }
+ }
+
+ /**
+ * Cette methode montre comment manuellement on peut effectuer la
+ * replication (en dettachant les dependances qui forment des cycles)
+ * <p/>
+ * La methode utilisee ici peut ne pas fonctionner : si une clef metier est
+ * posee sur une dependance alors cela ne fonctionne pas.
+ *
+ * @throws Exception pour toute erreur
+ */
+ @Test
+ public void testSimpleReplicateNotSure() throws Exception {
+
+ TopiaContext dstRootCtxt = createDb2("testSimpleReplicateNotSure");
+
+ //model = service.prepare(contracts, pet.getTopiaId());
+
+ TopiaContext srcCtxt = ctxt;
+ dstCtxt = (TopiaContextImplementor) dstRootCtxt.beginTransaction();
+
+ try {
+
+
+ srcCtxt.replicateEntity(dstCtxt, race);
+
+ // on dettache l'entite qui pose probleme
+
+ pet.setPerson(null);
+ srcCtxt.replicateEntity(dstCtxt, pet);
+ srcCtxt.rollbackTransaction();
+
+ srcCtxt.replicateEntity(dstCtxt, person);
+
+ dstCtxt.commitTransaction();
+ ((Pet) dstCtxt.findByTopiaId(pet.getTopiaId())).setPerson((Person) dstCtxt.findByTopiaId(person.getTopiaId()));
+ dstCtxt.commitTransaction();
+
+ srcCtxt.rollbackTransaction();
+ person = update(person);
+
+ assertEntityEquals(person, dstCtxt.findByTopiaId(person.getTopiaId()), null);
+ } finally {
+ srcCtxt.rollbackTransaction();
+ //srcCtxt.closeContext();
+ dstCtxt.closeContext();
+ }
+ }
+
+ /**
+ * Cette methode montre comment manuellement on peut effectuer la
+ * replication (en dettachant les associations qui forment des cycles)
+ * <p/>
+ * La methode utilisee ici fonctionne mieux que la precedante : il parrait
+ * dificille de pose une une clef metier sur une association :).
+ * <p/>
+ * On remarque que l'on dettache l'assocation qui forme un cycle et que l'on
+ * est pas obligee de la reattachee car elle est bi-directionnelle.
+ * <p/>
+ * On doit optimiser l'algorithme dans la methode {@link
+ * ReplicationModel#adjustOperations(TopiaEntityIdsMap)}.
+ *
+ * @throws Exception pour toute erreur
+ */
+ @Test
+ public void testSimpleReplicateSure() throws Exception {
+
+ TopiaContext dstRootCtxt = createDb2("testSimpleReplicateSure");
+
+ //model = service.prepare(contracts, pet.getTopiaId());
+
+ TopiaContext srcCtxt = ctxt;
+ dstCtxt = (TopiaContextImplementor) dstRootCtxt.beginTransaction();
+
+ try {
+
+ srcCtxt.replicateEntity(dstCtxt, race);
+ // on dettache l'association qui pose probleme
+ person.setPet(null);
+ srcCtxt.replicateEntity(dstCtxt, person);
+
+ srcCtxt.replicateEntity(dstCtxt, pet);
+ srcCtxt.rollbackTransaction();
+ dstCtxt.commitTransaction();
+
+ //((Person) dstCtxt.findByTopiaId(person.getTopiaId())).addPet(((Pet) dstCtxt.findByTopiaId(pet.getTopiaId())));
+ //dstCtxt.commitTransaction();
+
+ srcCtxt.rollbackTransaction();
+
+ srcCtxt.closeContext();
+ dstCtxt.closeContext();
+
+ ctxt = context.beginTransaction();
+ dstCtxt = (TopiaContextImplementor) dstRootCtxt.beginTransaction();
+
+ person = update(person);
+
+ assertEntityEquals(person, dstCtxt.findByTopiaId(person.getTopiaId()), null);
+
+ } finally {
+ dstCtxt.closeContext();
+ }
+ }
+
+ @Override
+ protected TopiaContext createDb(String name) throws Exception {
+
+ File localDB = new File(getTestDir(getClass()), "db_" + name);
+
+ Properties config = getH2Properties(localDB);
+
+ context = TopiaContextFactory.getContext(config);
+
+ TopiaContextImplementor tx = (TopiaContextImplementor) context.beginTransaction();
+
+ person = tx.getDAO(Person.class).create(Person.PROPERTY_NAME, "pudding master");
+ race = tx.getDAO(Race.class).create(Race.PROPERTY_NAME, "race I");
+ pet = tx.getDAO(Pet.class).create(Pet.PROPERTY_NAME, "pudding", Pet.PROPERTY_PERSON, person, Pet.PROPERTY_RACE, race);
+
+ person2 = tx.getDAO(Person.class).create(Person.PROPERTY_NAME, "pudding II master");
+ pet2 = tx.getDAO(Pet.class).create(Pet.PROPERTY_NAME, "pudding II");
+ race2 = tx.getDAO(Race.class).create(Race.PROPERTY_NAME, "race II");
+
+ race3 = tx.getDAO(Race.class).create(Race.PROPERTY_NAME, "race III");
+ pet3 = tx.getDAO(Pet.class).create(Pet.PROPERTY_NAME, "pudding III", Pet.PROPERTY_RACE, race3);
+
+ tx.commitTransaction();
+ tx.closeContext();
+ return context;
+ }
+
+ @Override
+ protected TopiaContext createDb2(String name) throws Exception {
+
+ File localDB = new File(getTestDir(getClass()), "db_" + name);
+
+ log.info("db dir :\n" + localDB.getAbsolutePath());
+
+ Properties config = getH2Properties(localDB);
+
+ return TopiaContextFactory.getContext(config);
+ }
+
+ @Override
+ protected TopiaEntityEnum[] getContracts() {
+ return contracts;
+ }
+
+ @Override
+ protected Log getLog() {
+ return log;
+ }
+
+ protected Properties getH2Properties(File f) {
+
+ Properties config = new Properties();
+ config.setProperty("hibernate.show_sql", "false");
+ config.setProperty("hibernate.hbm2ddl.auto", "create");
+
+ config.setProperty("topia.persistence.classes", entitiesList);
+ config.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
+ config.setProperty("hibernate.connection.driver_class", "org.h2.Driver");
+ config.setProperty("hibernate.connection.url", "jdbc:h2:file:" + f.getAbsolutePath() + "/db;create=true");
+ config.setProperty("hibernate.connection.username", "sa");
+ config.setProperty("hibernate.connection.password", "");
+
+ config.setProperty(TopiaReplicationServiceImpl.TOPIA_SERVICE_NAME, TopiaReplicationServiceImpl.class.getName());
+
+ return config;
+ }
+}
+
+
Property changes on: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationServiceImplTest.java
___________________________________________________________________
Added: svn:keywords
+ HeadURL Id Date Revision Author
Modified: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/FakeOperation.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/FakeOperation.java 2010-08-15 11:51:20 UTC (rev 2100)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/FakeOperation.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -30,8 +30,8 @@
import org.nuiton.topia.TopiaException;
import org.nuiton.topia.framework.TopiaContextImplementor;
import org.nuiton.topia.persistence.TopiaEntity;
+import org.nuiton.topia.persistence.util.TopiaEntityHelper;
import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
-import org.nuiton.topia.replication.ReplicationEngine;
import org.nuiton.topia.replication.TopiaReplicationOperation;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
@@ -46,7 +46,7 @@
*/
public class FakeOperation implements TopiaReplicationOperation {
- /** to use log facility, just put in your code: log.info(\"...\"); */
+ /** Logger */
private static final Log log = LogFactory.getLog(FakeOperation.class);
public static final Class<?>[] PARAMETERS_CLASSES = new Class<?>[]{String.class};
@@ -57,7 +57,7 @@
ReplicationOperationPhase phase,
Object... parameters) {
- ReplicationEngine.checkParameters(PARAMETERS_CLASSES, parameters);
+ TopiaEntityHelper.checkParameters(PARAMETERS_CLASSES, parameters);
ReplicationOperationDef op = new ReplicationOperationDef(
phase,
getClass(),
Modified: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UncreatableOperation.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UncreatableOperation.java 2010-08-15 11:51:20 UTC (rev 2100)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UncreatableOperation.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -47,7 +47,7 @@
*/
public class UncreatableOperation implements TopiaReplicationOperation {
- /** to use log facility, just put in your code: log.info(\"...\"); */
+ /** Logger */
private static final Log log =
LogFactory.getLog(UncreatableOperation.class);
Modified: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UnregistredOperation.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UnregistredOperation.java 2010-08-15 11:51:20 UTC (rev 2100)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UnregistredOperation.java 2010-08-15 11:58:21 UTC (rev 2101)
@@ -45,7 +45,7 @@
*/
public class UnregistredOperation implements TopiaReplicationOperation {
- /** to use log facility, just put in your code: log.info(\"...\"); */
+ /** Logger */
private static final Log log = LogFactory.getLog(UnregistredOperation.class);
@Override
Modified: trunk/topia-service-replication/src/test/resources/META-INF/services/org.nuiton.topia.replication.TopiaReplicationOperation
===================================================================
--- trunk/topia-service-replication/src/test/resources/META-INF/services/org.nuiton.topia.replication.TopiaReplicationOperation 2010-08-15 11:51:20 UTC (rev 2100)
+++ trunk/topia-service-replication/src/test/resources/META-INF/services/org.nuiton.topia.replication.TopiaReplicationOperation 2010-08-15 11:58:21 UTC (rev 2101)
@@ -1,6 +1,6 @@
#
# la liste des operations disponibles pour le moteur de replication
-# voir la classe org.nuiton.topia.replication.ReplicationEngine
+# voir la classe org.nuiton.topia.replication.TopiaReplicationServiceImpl
#
org.nuiton.topia.replication.operation.FakeOperation
org.nuiton.topia.replication.operation.UncreatableOperation
\ No newline at end of file
1
0
r2100 - trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util
by tchemit@users.nuiton.org Aug. 15, 2010
by tchemit@users.nuiton.org Aug. 15, 2010
Aug. 15, 2010
Author: tchemit
Date: 2010-08-15 13:51:20 +0200 (Sun, 15 Aug 2010)
New Revision: 2100
Url: http://nuiton.org/repositories/revision/topia/2100
Log:
add header
Modified:
trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/TopiaEntityIdsMap.java
Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/TopiaEntityIdsMap.java
===================================================================
--- trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/TopiaEntityIdsMap.java 2010-08-14 19:56:03 UTC (rev 2099)
+++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/TopiaEntityIdsMap.java 2010-08-15 11:51:20 UTC (rev 2100)
@@ -1,3 +1,27 @@
+/*
+ * #%L
+ * ToPIA :: Persistence
+ *
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2004 - 2010 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%
+ */
package org.nuiton.topia.persistence.util;
import org.nuiton.topia.persistence.TopiaEntity;
1
0
r2099 - trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util
by tchemit@users.nuiton.org Aug. 14, 2010
by tchemit@users.nuiton.org Aug. 14, 2010
Aug. 14, 2010
Author: tchemit
Date: 2010-08-14 21:56:03 +0200 (Sat, 14 Aug 2010)
New Revision: 2099
Url: http://nuiton.org/repositories/revision/topia/2099
Log:
transfer usefull methods from replication service (must do javadoc + i18n)
Modified:
trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/TopiaEntityHelper.java
Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/TopiaEntityHelper.java
===================================================================
--- trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/TopiaEntityHelper.java 2010-08-14 13:54:40 UTC (rev 2098)
+++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/TopiaEntityHelper.java 2010-08-14 19:56:03 UTC (rev 2099)
@@ -29,6 +29,7 @@
import org.apache.commons.logging.LogFactory;
import org.nuiton.topia.TopiaContext;
import org.nuiton.topia.TopiaException;
+import org.nuiton.topia.framework.TopiaContextImplementor;
import org.nuiton.topia.persistence.TopiaDAO;
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.persistence.TopiaEntityEnum;
@@ -55,6 +56,8 @@
import java.util.SortedMap;
import java.util.TreeMap;
+import static org.nuiton.i18n.I18n._;
+
/**
* Une classe avec des méthodes utiles sur les entités.
*
@@ -1077,4 +1080,92 @@
}
interfaces.add(klass);
}
+
+ @SuppressWarnings({"unchecked"})
+ public static <E extends TopiaEntity> List<E> getEntities(
+ TopiaContextImplementor srcCtxt,
+ List<E> entityList,
+ boolean canBeNull) throws TopiaException {
+ List<E> srcList = new ArrayList<E>(entityList.size());
+ for (E e : entityList) {
+ E e2 = (E) srcCtxt.findByTopiaId(e.getTopiaId());
+ if (e2 == null && !canBeNull) {
+// if (!canBeNull) {
+// throw new IllegalStateException(
+// "topia.replication.engine.error.entity.must.exists");
+// }
+ continue;
+ }
+ srcList.add(e2);
+ }
+ return srcList;
+ }
+
+ public static TopiaEntity[] getEntities(TopiaContext srcCtxt,
+ String... entityList)
+ throws TopiaException {
+ TopiaEntity[] srcList = new TopiaEntity[entityList.length];
+ int index = 0;
+ for (String id : entityList) {
+ TopiaEntity e2 = srcCtxt.findByTopiaId(id);
+ srcList[index++] = e2;
+ }
+ return srcList;
+ }
+
+ public static List<? extends TopiaEntity> getEntitiesList(
+ TopiaContext srcCtxt,
+ String... entityList) throws TopiaException {
+ List<TopiaEntity> srcList = new ArrayList<TopiaEntity>(entityList.length);
+ for (String id : entityList) {
+ TopiaEntity e2 = srcCtxt.findByTopiaId(id);
+ srcList.add(e2);
+ }
+ return srcList;
+ }
+
+ public static void checkNotNull(String methodName,
+ String parameterName,
+ Object value) {
+ if (value == null) {
+ throw new NullPointerException(
+ _("topia.replication.engine.error.null.param",
+ parameterName, methodName));
+ }
+ }
+
+ public static void checkParameters(Class<?>[] paramsType,
+ Object... params) {
+ checkSize(paramsType.length, params);
+ for (int i = 0, j = paramsType.length; i < j; i++) {
+ checkType(paramsType, i, params);
+ }
+ }
+
+ public static void checkSize(int size, Object[] params) {
+ if (params.length != size) {
+ throw new IllegalArgumentException(
+ "l'operation requiere " + size + " parametres mais en a " +
+ params.length);
+ }
+ }
+
+ public static void checkType(Class<?>[] paramsType,
+ int index,
+ Object[] params) {
+ Class<?> requiredType = paramsType[index];
+ Object value = params[index];
+ if (value == null) {
+ throw new IllegalArgumentException(
+ "le parametre de positiion" + index + " est null!");
+ }
+ Class<?> foundType = value.getClass();
+
+ if (!requiredType.isAssignableFrom(foundType)) {
+ throw new IllegalArgumentException(
+ "le paremetre de position " + index +
+ " requiere un parametre de type " + requiredType +
+ " mais est de type " + foundType);
+ }
+ }
}
1
0
r2098 - in trunk/topia-service-replication/src: main/java/org/nuiton/topia/replication main/java/org/nuiton/topia/replication/model main/java/org/nuiton/topia/replication/operation main/resources/META-INF/services test/java/org/nuiton/topia/replication test/java/org/nuiton/topia/replication/operation
by tchemit@users.nuiton.org Aug. 14, 2010
by tchemit@users.nuiton.org Aug. 14, 2010
Aug. 14, 2010
Author: tchemit
Date: 2010-08-14 15:54:40 +0200 (Sat, 14 Aug 2010)
New Revision: 2098
Url: http://nuiton.org/repositories/revision/topia/2098
Log:
clean code
reformat code
add javadoc + project informations (author, since,...)
remove Dependencies-like operation
improve Engine code
use TopiaEntityIdsMap
Removed:
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachDependency.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/DettachDependency.java
Modified:
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/ReplicationEngine.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationImplementor.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperation.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationService.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/Link.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationModel.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationNode.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationOperationDef.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationOperationPhase.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachAssociation.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachLink.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/DettachAssociation.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/Duplicate.java
trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/LoadLink.java
trunk/topia-service-replication/src/main/resources/META-INF/services/org.nuiton.topia.replication.TopiaReplicationOperation
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/AbstractReplicationEngineTest.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/ReplicationEngineAllTest.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/ReplicationEngineTest.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationOperationTest.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/FakeOperation.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UncreatableOperation.java
trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UnregistredOperation.java
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/ReplicationEngine.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/ReplicationEngine.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/ReplicationEngine.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -33,6 +33,7 @@
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.persistence.TopiaEntityEnum;
import org.nuiton.topia.persistence.util.TopiaEntityHelper;
+import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
import org.nuiton.topia.replication.model.ReplicationOperationDef;
@@ -40,9 +41,7 @@
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
@@ -51,11 +50,12 @@
/**
* Implantation du service de replication.
*
- * @author chemit
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
*/
public class ReplicationEngine implements TopiaReplicationImplementor {
- /** to use log facility, just put in your code: log.info(\"...\"); */
+ /** Logger */
private static final Log log = LogFactory.getLog(ReplicationEngine.class);
/** le contexte sur la base source de la replication */
@@ -67,7 +67,7 @@
*
* @see #preInit(TopiaContextImplementor)
*/
- protected static TopiaReplicationOperation[] operations;
+ protected TopiaReplicationOperation[] operations;
//--------------------------------------------------------------------------
//-- TopiaService implementation -------------------------------------------
@@ -87,24 +87,22 @@
@Override
public boolean preInit(TopiaContextImplementor context) {
if (operations == null) {
+ // chargement des operations disponibles une seule fois
- // on effectue cette rechercher une seule fois par jvm
- synchronized (this) {
- // chargement des operations disponibles une seule fois
+ ServiceLoader<TopiaReplicationOperation> loader =
+ ServiceLoader.load(TopiaReplicationOperation.class);
- ServiceLoader<TopiaReplicationOperation> loader = ServiceLoader.load(TopiaReplicationOperation.class);
+ List<TopiaReplicationOperation> operations =
+ new ArrayList<TopiaReplicationOperation>();
- List<TopiaReplicationOperation> discoveredOperations = new ArrayList<TopiaReplicationOperation>();
-
- for (TopiaReplicationOperation op : loader) {
- if (log.isDebugEnabled()) {
- log.debug("detected operation " + op);
- }
- discoveredOperations.add(op);
-
+ for (TopiaReplicationOperation op : loader) {
+ if (log.isDebugEnabled()) {
+ log.debug("detected operation " + op);
}
- operations = discoveredOperations.toArray(new TopiaReplicationOperation[discoveredOperations.size()]);
+ operations.add(op);
}
+ this.operations = operations.toArray(
+ new TopiaReplicationOperation[operations.size()]);
}
return true;
}
@@ -127,7 +125,8 @@
//--------------------------------------------------------------------------
@Override
- public ReplicationModel prepare(TopiaEntityEnum[] contracts, String... entities) throws TopiaException {
+ public ReplicationModel prepare(TopiaEntityEnum[] contracts,
+ String... entities) throws TopiaException {
ReplicationModel model = createModel(contracts, entities);
initModel(model, true);
@@ -145,7 +144,8 @@
}
@Override
- public ReplicationModel prepareWithComputedOrder(TopiaEntityEnum[] contracts, String... topiaIds) throws TopiaException {
+ public ReplicationModel prepareWithComputedOrder(TopiaEntityEnum[] contracts,
+ String... topiaIds) throws TopiaException {
ReplicationModel model = createModelWithComputedOrder(contracts, topiaIds);
initModel(model, false);
@@ -154,24 +154,41 @@
}
@Override
- public void addBeforeOperation(ReplicationModel model, TopiaEntityEnum type, Class<? extends TopiaReplicationOperation> operationClass, Object... parameters) {
- createOperation(model, type, ReplicationOperationPhase.before, operationClass, parameters);
+ public void addBeforeOperation(ReplicationModel model,
+ TopiaEntityEnum type,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... parameters) {
+ createOperation(model,
+ type,
+ ReplicationOperationPhase.before,
+ operationClass,
+ parameters
+ );
}
@Override
- public void addAfterOperation(ReplicationModel model, TopiaEntityEnum type, Class<? extends TopiaReplicationOperation> operationClass, Object... parameters) {
- createOperation(model, type, ReplicationOperationPhase.after, operationClass, parameters);
+ public void addAfterOperation(ReplicationModel model,
+ TopiaEntityEnum type,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... parameters) {
+ createOperation(model,
+ type,
+ ReplicationOperationPhase.after,
+ operationClass,
+ parameters
+ );
}
@Override
- public void doReplicate(ReplicationModel model, TopiaContext dstCtxt) throws Exception {
+ public void doReplicate(ReplicationModel model,
+ TopiaContext dstCtxt) throws Exception {
checkNotNull("doReplicate", "model", model);
checkNotNull("doReplicate", "dstCtxt", dstCtxt);
TopiaContextImplementor srcCtxt = null;
- Map<Class<? extends TopiaEntity>, List<String>> data = null;
+ TopiaEntityIdsMap data = null;
// keep the list of treated nodes (to roolback them if something
// is wrong).
@@ -205,7 +222,17 @@
try {
doReplicateNode(node, srcCtxt, tx, data, treated);
} catch (Exception e) {
- tx.rollbackTransaction();
+
+ // un erreur est survenu sur le noeud de réplication
+ // on rollback la transaction de ce noeud
+ try {
+ tx.rollbackTransaction();
+ } finally {
+
+ // on revert les noeuds deja commite
+ doRollback(model, data, treated, dstCtxt);
+ }
+
throw e;
} finally {
srcCtxt.closeContext();
@@ -236,34 +263,95 @@
}
}
+ @Override
+ public void doRollback(ReplicationModel model,
+ TopiaEntityIdsMap data,
+ List<ReplicationNode> nodes,
+ TopiaContext dstCtxt) throws Exception {
+ if (nodes.isEmpty()) {
+
+ // aucun noeud de réplication commités
+ return;
+ }
+
+ TopiaContextImplementor srcCtxt;
+
+ TopiaContext tx;
+
+ boolean needTransaction = true;
+
+ log.info("Will rollback " + nodes.size() + " nodes...");
+
+ for (ReplicationNode node : nodes) {
+
+ log.info("Rollback node " + node);
+ srcCtxt = (TopiaContextImplementor) context.beginTransaction();
+
+ if (needTransaction) {
+ tx = dstCtxt.beginTransaction();
+ } else {
+ tx = dstCtxt;
+ }
+ try {
+ doRollbackNode(node, srcCtxt, tx, data);
+ } catch (Exception e) {
+
+ // un erreur est survenu sur le noeud de réplication
+ // on rollback la transaction de ce noeud
+
+ tx.rollbackTransaction();
+
+ } finally {
+ srcCtxt.rollbackTransaction();
+ srcCtxt.closeContext();
+
+ if (needTransaction) {
+ // on doit fermer la transaction car on l'a ouverte dans
+ // cette méthode, sinon c'est de la responsabilite du
+ // code appellant
+ tx.closeContext();
+ }
+ }
+
+ }
+ }
+
//--------------------------------------------------------------------------
//-- TopiaReplicationImplementor implementation ----------------------------
//--------------------------------------------------------------------------
@Override
public ReplicationModel createModel(TopiaEntityEnum[] contracts,
- String... topiaIds) throws TopiaException {
- Set<Class<? extends TopiaEntity>> detectTypes = detectTypes(contracts, topiaIds);
- ReplicationModel model = new ReplicationModel(contracts, detectTypes, topiaIds);
+ String... topiaIds)
+ throws TopiaException {
+
+ Set<Class<? extends TopiaEntity>> detectTypes =
+ detectTypes(contracts, topiaIds);
+ ReplicationModel model =
+ new ReplicationModel(contracts, detectTypes, topiaIds);
return model;
}
@Override
- public ReplicationModel createModelWithComputedOrder(TopiaEntityEnum[] contracts,
- String... topiaIds) throws TopiaException {
- ReplicationModel model = new ReplicationModel(contracts, false, topiaIds);
+ public ReplicationModel createModelWithComputedOrder(
+ TopiaEntityEnum[] contracts, String... topiaIds)
+ throws TopiaException {
+ ReplicationModel model =
+ new ReplicationModel(contracts, false, topiaIds);
return model;
}
@Override
- public ReplicationModel createModelForAll(TopiaEntityEnum[] contracts) throws TopiaException {
+ public ReplicationModel createModelForAll(TopiaEntityEnum[] contracts)
+ throws TopiaException {
ReplicationModel model = new ReplicationModel(contracts, true);
return model;
}
@Override
public ReplicationModel initModel(ReplicationModel model,
- boolean computeOrder) throws TopiaException {
+ boolean computeOrder)
+ throws TopiaException {
checkNotNull("initModel", "model", model);
model.detectAssociations();
@@ -278,7 +366,8 @@
}
@Override
- public TopiaReplicationOperation getOperation(Class<? extends TopiaReplicationOperation> operationClass) {
+ public TopiaReplicationOperation getOperation(
+ Class<? extends TopiaReplicationOperation> operationClass) {
checkNotNull("getOperation", "operationClass", operationClass);
if (operations == null) {
@@ -310,24 +399,35 @@
TopiaReplicationOperation operation = getOperation(operationClass);
if (operation == null) {
- throw new IllegalArgumentException(_("topia.replication.engine.error.unkown.operation", operationClass.getSimpleName(), Arrays.toString(operations)));
+ throw new IllegalArgumentException(
+ _("topia.replication.engine.error.unkown.operation",
+ operationClass.getSimpleName(),
+ Arrays.toString(operations))
+ );
}
ReplicationNode node = model.getNode(type);
if (node == null) {
- throw new IllegalArgumentException(_("topia.replication.engine.error.unkown.owner.node", type, operationClass.getSimpleName(), model.getNodes()));
+ throw new IllegalArgumentException(
+ _("topia.replication.engine.error.unkown.owner.node",
+ type,
+ operationClass.getSimpleName(),
+ model.getNodes())
+ );
}
operation.register(model, node, phase, parameters);
}
@Override
- public Set<Class<? extends TopiaEntity>> detectTypes(TopiaEntityEnum[] contracts, String... ids) throws TopiaException {
+ public Set<Class<? extends TopiaEntity>> detectTypes(
+ TopiaEntityEnum[] contracts, String... ids) throws TopiaException {
TopiaContext ctxt = context.beginTransaction();
try {
TopiaEntity[] entities = getEntities(ctxt, ids);
// on detecte tous les types connus pour les entites données
- Set<Class<? extends TopiaEntity>> types = TopiaEntityHelper.detectTypes(contracts, entities);
+ Set<Class<? extends TopiaEntity>> types =
+ TopiaEntityHelper.detectTypes(contracts, entities);
if (log.isDebugEnabled()) {
log.debug("for type : " + entities.getClass());
@@ -342,21 +442,33 @@
}
@Override
- public Map<Class<? extends TopiaEntity>, List<String>> getIds(ReplicationModel model, TopiaContextImplementor srcCtxt) throws TopiaException {
- Map<Class<? extends TopiaEntity>, List<String>> data;
+ public TopiaEntityIdsMap getIds(ReplicationModel model,
+ TopiaContextImplementor srcCtxt)
+ throws TopiaException {
+
+ TopiaEntityIdsMap data;
+
// on recupere les objets a repliquer par type
if (model.isReplicateAll()) {
+
// on recupere pour chaque type tous les ids des entites a repliquer
- data = new HashMap<Class<? extends TopiaEntity>, List<String>>();
+ data = new TopiaEntityIdsMap();
for (TopiaEntityEnum e : model.getContracts()) {
List<String> ids = srcCtxt.getDAO(e.getContract()).findAllIds();
data.put(e.getContract(), ids);
}
} else {
+
// on recupere les entites specifies a repliquer
- TopiaEntity[] entities = getEntities(srcCtxt, model.getTopiaIds());
+ TopiaEntity[] entities = getEntities(srcCtxt,
+ model.getTopiaIds()
+ );
+
// on calcule toutes les ids des entites a repliquer
- data = TopiaEntityHelper.detectEntityIds(model.getContracts(), model.getTypes(), entities);
+ data = TopiaEntityHelper.detectEntityIds(model.getContracts(),
+ model.getTypes(),
+ entities
+ );
}
return data;
}
@@ -366,10 +478,11 @@
ReplicationNode node,
TopiaContext srcCtxt,
TopiaContext dstCtxt,
- Map<Class<? extends TopiaEntity>, List<String>> data,
+ TopiaEntityIdsMap data,
List<ReplicationNode> treated) throws Exception {
- // on trie toujours les operations a realiser selon leur phase (avant ou apres la duplication)
+ // on trie toujours les operations a realiser selon leur phase
+ // (avant ou apres la duplication)
node.sortOperations();
List<ReplicationOperationDef> operationDefs = node.getOperations();
@@ -378,11 +491,15 @@
log.info("skip node " + node + " - no operation detected.");
} else {
- log.info("start for " + node + " : " + operationDefs.size() + " operation(s)");
+ log.info("start for " + node + " : " + operationDefs.size() +
+ " operation(s)");
- List<String> nodeEntityIds = data.get(node.getContract().getContract());
+ List<String> nodeEntityIds =
+ data.get(node.getContract().getContract());
+
if (log.isInfoEnabled()) {
- log.info("will replicate on " + nodeEntityIds.size() + " entity(ies)");
+ log.info("will replicate on " + nodeEntityIds.size() +
+ " entity(ies)");
}
if (log.isDebugEnabled()) {
for (String id : nodeEntityIds) {
@@ -390,7 +507,10 @@
}
}
- List<? extends TopiaEntity> nodeEntities = getEntitiesList(srcCtxt, nodeEntityIds.toArray(new String[nodeEntityIds.size()]));
+ List<? extends TopiaEntity> nodeEntities = getEntitiesList(
+ srcCtxt,
+ nodeEntityIds.toArray(new String[nodeEntityIds.size()])
+ );
for (ReplicationOperationDef operationDef : operationDefs) {
@@ -417,14 +537,80 @@
treated.add(node);
}
- public static <E extends TopiaEntity> List<E> getEntities(TopiaContextImplementor srcCtxt, List<E> entityList, boolean canBeNull) throws TopiaException {
+
+ @Override
+ public void doRollbackNode(
+ ReplicationNode node,
+ TopiaContext srcCtxt,
+ TopiaContext dstCtxt,
+ TopiaEntityIdsMap data) throws Exception {
+
+ // on trie toujours les operations a realiser selon leur phase
+ // (avant ou apres la duplication)
+ node.sortOperations();
+
+ List<ReplicationOperationDef> operationDefs = node.getOperations();
+
+ if (operationDefs.isEmpty()) {
+ log.info("skip node " + node + " - no operation detected.");
+ } else {
+
+ log.info("start for " + node + " : " + operationDefs.size() +
+ " operation(s)");
+
+ List<String> nodeEntityIds =
+ data.get(node.getContract().getContract());
+ if (log.isInfoEnabled()) {
+ log.info("will replicate on " + nodeEntityIds.size() +
+ " entity(ies)");
+ }
+ if (log.isDebugEnabled()) {
+ for (String id : nodeEntityIds) {
+ log.debug(id);
+ }
+ }
+
+ List<? extends TopiaEntity> nodeEntities = getEntitiesList(
+ srcCtxt,
+ nodeEntityIds.toArray(new String[nodeEntityIds.size()])
+ );
+
+ for (ReplicationOperationDef operationDef : operationDefs) {
+
+ log.info("start " + operationDef);
+
+ TopiaReplicationOperation operation =
+ getOperation(operationDef.getOperationClass());
+
+ operation.rollback(operationDef,
+ (TopiaContextImplementor) srcCtxt,
+ (TopiaContextImplementor) dstCtxt,
+ nodeEntities,
+ data
+ );
+
+ }
+ // on rollback le context source (car on a peut-etre modifie
+ // des associations ou des dependances mais on ne veut rien
+ // retenir au niveau d'hibernate, sinon on s'expose a des erreurs
+ // lorsque l'on veut recharger des objets dans le context...)
+ srcCtxt.rollbackTransaction();
+ }
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public static <E extends TopiaEntity> List<E> getEntities(
+ TopiaContextImplementor srcCtxt,
+ List<E> entityList,
+ boolean canBeNull) throws TopiaException {
List<E> srcList = new ArrayList<E>(entityList.size());
for (E e : entityList) {
E e2 = (E) srcCtxt.findByTopiaId(e.getTopiaId());
if (e2 == null && !canBeNull) {
- if (!canBeNull) {
- throw new IllegalStateException("topia.replication.engine.error.entity.must.exists");
- }
+// if (!canBeNull) {
+// throw new IllegalStateException(
+// "topia.replication.engine.error.entity.must.exists");
+// }
continue;
}
srcList.add(e2);
@@ -432,7 +618,9 @@
return srcList;
}
- public static TopiaEntity[] getEntities(TopiaContext srcCtxt, String... entityList) throws TopiaException {
+ public static TopiaEntity[] getEntities(TopiaContext srcCtxt,
+ String... entityList)
+ throws TopiaException {
TopiaEntity[] srcList = new TopiaEntity[entityList.length];
int index = 0;
for (String id : entityList) {
@@ -442,7 +630,9 @@
return srcList;
}
- public static List<? extends TopiaEntity> getEntitiesList(TopiaContext srcCtxt, String... entityList) throws TopiaException {
+ public static List<? extends TopiaEntity> getEntitiesList(
+ TopiaContext srcCtxt,
+ String... entityList) throws TopiaException {
List<TopiaEntity> srcList = new ArrayList<TopiaEntity>(entityList.length);
for (String id : entityList) {
TopiaEntity e2 = srcCtxt.findByTopiaId(id);
@@ -451,13 +641,18 @@
return srcList;
}
- public static void checkNotNull(String methodName, String parameterName, Object value) {
+ public static void checkNotNull(String methodName,
+ String parameterName,
+ Object value) {
if (value == null) {
- throw new NullPointerException(_("topia.replication.engine.error.null.param", parameterName, methodName));
+ throw new NullPointerException(
+ _("topia.replication.engine.error.null.param",
+ parameterName, methodName));
}
}
- public static void checkParameters(Class<?>[] paramsType, Object... params) {
+ public static void checkParameters(Class<?>[] paramsType,
+ Object... params) {
checkSize(paramsType.length, params);
for (int i = 0, j = paramsType.length; i < j; i++) {
checkType(paramsType, i, params);
@@ -466,20 +661,28 @@
public static void checkSize(int size, Object[] params) {
if (params.length != size) {
- throw new IllegalArgumentException("l'operation requiere " + size + " parametres mais en a " + params.length);
+ throw new IllegalArgumentException(
+ "l'operation requiere " + size + " parametres mais en a " +
+ params.length);
}
}
- public static void checkType(Class<?>[] paramsType, int index, Object[] params) {
+ public static void checkType(Class<?>[] paramsType,
+ int index,
+ Object[] params) {
Class<?> requiredType = paramsType[index];
Object value = params[index];
if (value == null) {
- throw new IllegalArgumentException("le parametre de positiion" + index + " est null!");
+ throw new IllegalArgumentException(
+ "le parametre de positiion" + index + " est null!");
}
Class<?> foundType = value.getClass();
if (!requiredType.isAssignableFrom(foundType)) {
- throw new IllegalArgumentException("le paremetre de position " + index + " requiere un parametre de type " + requiredType + " mais est de type " + foundType);
+ throw new IllegalArgumentException(
+ "le paremetre de position " + index +
+ " requiere un parametre de type " + requiredType +
+ " mais est de type " + foundType);
}
}
}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationImplementor.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationImplementor.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationImplementor.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -41,19 +41,19 @@
import org.nuiton.topia.framework.TopiaContextImplementor;
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.persistence.TopiaEntityEnum;
+import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
import org.nuiton.topia.replication.model.ReplicationOperationPhase;
import java.util.List;
-import java.util.Map;
import java.util.Set;
/**
* Class used internaly in framework, when you want implement new replication
* engin, you must used this interface
*
- * @author chemit
+ * @author tchemit <chemit(a)codelutin.com>
* @since 2.2.0
*/
public interface TopiaReplicationImplementor extends TopiaReplicationService {
@@ -136,11 +136,13 @@
* @return les ids des donnes a repliquer.
* @throws TopiaException pour toute erreur de recuperation d'ids en base
*/
- Map<Class<? extends TopiaEntity>, List<String>> getIds(
+ TopiaEntityIdsMap getIds(
ReplicationModel model,
TopiaContextImplementor srcCtxt) throws TopiaException;
/**
+ * Lance la replication d'un noeud.
+ *
* @param node le noeud de replication
* @param srcCtxt la base source
* @param dstCtxt la base destination
@@ -152,6 +154,22 @@
ReplicationNode node,
TopiaContext srcCtxt,
TopiaContext dstCtxt,
- Map<Class<? extends TopiaEntity>, List<String>> data,
+ TopiaEntityIdsMap data,
List<ReplicationNode> treated) throws Exception;
+
+ /**
+ * Annule la replication d'un noeud.
+ *
+ * @param node le noeud de replication
+ * @param srcCtxt la base source
+ * @param dstCtxt la base destination
+ * @param data le dictionnaire des ids a repliquer
+ * @throws Exception pour toute erreur
+ * @since 2.4.3
+ */
+ void doRollbackNode(
+ ReplicationNode node,
+ TopiaContext srcCtxt,
+ TopiaContext dstCtxt,
+ TopiaEntityIdsMap data) throws Exception;
}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperation.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperation.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationOperation.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -28,13 +28,13 @@
import org.nuiton.topia.framework.TopiaContextImplementor;
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.persistence.TopiaEntityEnum;
+import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
import org.nuiton.topia.replication.model.ReplicationOperationDef;
import org.nuiton.topia.replication.model.ReplicationOperationPhase;
import java.util.List;
-import java.util.Map;
import java.util.ServiceLoader;
/**
@@ -53,7 +53,7 @@
* <p/>
* Lors du chargement du service, on detecte toutes les operations disponibles.
*
- * @author chemit
+ * @author tchemit <chemit(a)codelutin.com>
* @since 2.2.0
*/
public interface TopiaReplicationOperation {
@@ -92,5 +92,24 @@
TopiaContextImplementor srcCtxt,
TopiaContextImplementor dstCtxt,
List<? extends TopiaEntity> entities,
- Map<Class<? extends TopiaEntity>, List<String>> data) throws Exception;
+ TopiaEntityIdsMap data) throws Exception;
+
+ /**
+ * Execute l'operation inverse avec le parametrage donnee
+ * (pour annuler l'opération).
+ * <p/>
+ * Note : le commit sur le context cible doit etre geree dans la methode.
+ *
+ * @param operationDef la definition de l'operation a realiser
+ * @param srcCtxt le context source
+ * @param dstCtxt le context destination
+ * @param entities la liste des
+ * @param data le dictionnaire de toutes les donnees a repliquer
+ * @throws Exception pour toute erreur
+ */
+ void rollback(ReplicationOperationDef operationDef,
+ TopiaContextImplementor srcCtxt,
+ TopiaContextImplementor dstCtxt,
+ List<? extends TopiaEntity> entities,
+ TopiaEntityIdsMap data) throws Exception;
}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationService.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationService.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/TopiaReplicationService.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -40,8 +40,12 @@
import org.nuiton.topia.TopiaException;
import org.nuiton.topia.framework.TopiaService;
import org.nuiton.topia.persistence.TopiaEntityEnum;
+import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
import org.nuiton.topia.replication.model.ReplicationModel;
+import org.nuiton.topia.replication.model.ReplicationNode;
+import java.util.List;
+
/**
* User visible interface for replication engin
* <p/>
@@ -57,7 +61,7 @@
* <li> - lanch replication {@link #doReplicate(ReplicationModel,
* TopiaContext)}
*
- * @author chemit
+ * @author tchemit <chemit(a)codelutin.com>
* @since 2.2.0
*/
public interface TopiaReplicationService extends TopiaService {
@@ -148,7 +152,22 @@
* @param dstCtxt le context sur la source de donnees ou repliquer
* @throws Exception pour toute erreur pendant la replication
*/
- void doReplicate(ReplicationModel model, TopiaContext dstCtxt) throws Exception;
+ void doReplicate(ReplicationModel model,
+ TopiaContext dstCtxt) throws Exception;
+
+ /**
+ * Pour revenir en arrière lorsque la réplication a échouée .
+ *
+ * @param model le modele de replication
+ * @param data le dictionnaire des données à repliquer par type d'entités
+ * @param nodes les nodes déjà traités que l'on doit reverter
+ * @param dstCtxt le context sur la source de donnees ou repliquer
+ * @throws Exception pour toute erreur pendant la replication
+ */
+ void doRollback(ReplicationModel model,
+ TopiaEntityIdsMap data,
+ List<ReplicationNode> nodes,
+ TopiaContext dstCtxt) throws Exception;
}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/Link.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/Link.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/Link.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -32,21 +32,34 @@
/**
* Pour definir un lien entre deux entites (deux noeuds de replication).
*
- * @author chemit
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
*/
public class Link {
+ /** le noeud source du lien */
protected final ReplicationNode source;
+ /** le noeud destination du lien */
+ protected final ReplicationNode target;
+
+ /**
+ * liste des noeuds requis.
+ * <p/>
+ * TODO tchemit 2010-08-14 Expliquer à quoi ça sert vraiment...
+ */
protected final Set<ReplicationNode> requires;
- protected final ReplicationNode target;
-
+ /** nom du lien */
protected final String name;
+ /** drapeau positionné à {@code true} lorsque le lien est une association. */
protected final boolean association;
- public Link(ReplicationNode source, ReplicationNode target, String name, boolean association) {
+ public Link(ReplicationNode source,
+ ReplicationNode target,
+ String name,
+ boolean association) {
this.source = source;
this.target = target;
this.name = name;
@@ -87,7 +100,8 @@
* @param currentNode le noeud qui vient d'etre replique
* @return <code>true</code> si on peut reattacher ce lien
*/
- public boolean canReattach(Set<ReplicationNode> universe, ReplicationNode currentNode) {
+ public boolean canReattach(Set<ReplicationNode> universe,
+ ReplicationNode currentNode) {
boolean result = universe.containsAll(requires);
if (result) {
result = currentNode.equals(target) || universe.contains(target);
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationModel.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationModel.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationModel.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -32,6 +32,7 @@
import org.nuiton.topia.persistence.TopiaEntityEnum;
import org.nuiton.topia.persistence.util.EntityOperator;
import org.nuiton.topia.persistence.util.TopiaEntityHelper;
+import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
import org.nuiton.topia.replication.TopiaReplicationOperation;
import org.nuiton.topia.replication.operation.AttachLink;
import org.nuiton.topia.replication.operation.DettachAssociation;
@@ -49,9 +50,15 @@
import java.util.Map.Entry;
import java.util.Set;
+/**
+ * Model of a replication operation.
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
+ */
public class ReplicationModel {
- /** to use log facility, just put in your code: log.info(\"...\"); */
+ /** Logger */
private static final Log log = LogFactory.getLog(ReplicationModel.class);
/** l'ensemble des contrats d'entites a repliquer */
@@ -159,7 +166,7 @@
public void detectAssociations(TopiaEntityEnum... filter) throws TopiaException {
for (Class<? extends TopiaEntity> type : nodes.keySet()) {
ReplicationNode node = getNode(type);
- EntityOperator<? extends TopiaEntity> operator = node.getOperator();
+ EntityOperator<? super TopiaEntity> operator = node.getOperator();
List<String> associationProperties = operator.getAssociationProperties();
if (!associationProperties.isEmpty()) {
@@ -179,7 +186,7 @@
public void detectDirectDependencies() throws TopiaException {
for (Class<? extends TopiaEntity> type : nodes.keySet()) {
ReplicationNode node = getNode(type);
- EntityOperator<? extends TopiaEntity> operator = node.getOperator();
+ EntityOperator<? super TopiaEntity> operator = node.getOperator();
List<String> properties = operator.getProperties();
if (!properties.isEmpty()) {
for (String p : properties) {
@@ -258,13 +265,16 @@
}
}
- public void detectDependenciesOrder(Set<ReplicationNode> safeLevel, Set<ReplicationNode> doned) {
+ public void detectDependenciesOrder(Set<ReplicationNode> safeLevel,
+ Set<ReplicationNode> doned) {
if (log.isDebugEnabled()) {
log.debug("will detect " + safeLevel);
}
- Map<ReplicationNode, Set<ReplicationNode>> dico = new HashMap<ReplicationNode, Set<ReplicationNode>>();
+ Map<ReplicationNode, Set<ReplicationNode>> dico =
+ new HashMap<ReplicationNode, Set<ReplicationNode>>();
for (ReplicationNode n : safeLevel) {
- Set<ReplicationNode> shell = new HashSet<ReplicationNode>(n.getShell());
+ Set<ReplicationNode> shell =
+ new HashSet<ReplicationNode>(n.getShell());
shell.retainAll(safeLevel);
if (log.isDebugEnabled()) {
log.debug("shell to use for " + n + " : " + shell);
@@ -411,7 +421,8 @@
Set<String> names = node.getAssociationsToDettach();
// operations de dettachement d'association
for (String name : names) {
- addOperation(node, node, ReplicationOperationPhase.before, DettachAssociation.class, name);
+// addOperation(node, node, ReplicationOperationPhase.before, DettachAssociation.class, name);
+ addPreOperation(node, node, DettachAssociation.class, name);
}
}
Set<Link> tmpLinks = new HashSet<Link>();
@@ -426,26 +437,17 @@
if (!tmpLinks.isEmpty()) {
// on a des associations a charger avant replication
for (Link link : tmpLinks) {
- ReplicationOperationDef op = new ReplicationOperationDef(ReplicationOperationPhase.before, LoadLink.class, node, link);
- node.addOperation(op);
+ addPreOperation(node, node, LoadLink.class, link);
+// ReplicationOperationDef op = new ReplicationOperationDef(ReplicationOperationPhase.before, LoadLink.class, node, link);
+// node.addOperation(op);
}
linksToLoad.removeAll(links);
tmpLinks.clear();
}
- // on fait de meme pour les dependences directes
- //TODO la resolution des conflits sur dependences n'est pas encore
- //TODO en place (mais cela ne devrait pas etre necessaire... pour le moment)
-
-// if (node.hasDependenciesToDettach()) {
-// Set<String> names = node.getDependenciesToDettach();
-// // operations de dettachement d'association
-// for (String name : names) {
-// addOperation(node, node, ReplicationOperationPhase.before, DettachDependency.class, name);
-// }
-// }
// operation de duplication
- addOperation(node, node, ReplicationOperationPhase.duplicate, Duplicate.class);
+// addOperation(node, node, ReplicationOperationPhase.duplicate, Duplicate.class);
+ addDuplicateOperation(node, node, Duplicate.class);
universe.add(node);
@@ -459,8 +461,9 @@
if (!tmpLinks.isEmpty()) {
// on a trouve des liens a reattacher
for (Link link : tmpLinks) {
- ReplicationOperationDef op = new ReplicationOperationDef(ReplicationOperationPhase.after, AttachLink.class, node, link);
- node.addOperation(op);
+ addPostOperation(node, node, AttachLink.class, link);
+// ReplicationOperationDef op = new ReplicationOperationDef(ReplicationOperationPhase.after, AttachLink.class, node, link);
+// node.addOperation(op);
}
// ces liens ne sont plus a traiter
links.removeAll(tmpLinks);
@@ -468,7 +471,7 @@
}
}
- public void adjustOperations(Map<Class<? extends TopiaEntity>, List<String>> data) {
+ public void adjustOperations(TopiaEntityIdsMap data) {
for (TopiaEntityEnum e : getContracts()) {
Class<? extends TopiaEntity> contract = e.getContract();
List<String> ids = data.get(contract);
@@ -518,7 +521,32 @@
}
}
- protected void addOperation(ReplicationNode ownerNode, ReplicationNode node, ReplicationOperationPhase phase, Class<? extends TopiaReplicationOperation> operationClass, Object... params) {
+ protected void addPreOperation(ReplicationNode ownerNode,
+ ReplicationNode node,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... params) {
+ addOperation(ownerNode, node, ReplicationOperationPhase.before, operationClass, params);
+ }
+
+ protected void addDuplicateOperation(ReplicationNode ownerNode,
+ ReplicationNode node,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... params) {
+ addOperation(ownerNode, node, ReplicationOperationPhase.duplicate, operationClass, params);
+ }
+
+ protected void addPostOperation(ReplicationNode ownerNode,
+ ReplicationNode node,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... params) {
+ addOperation(ownerNode, node, ReplicationOperationPhase.after, operationClass, params);
+ }
+
+ protected void addOperation(ReplicationNode ownerNode,
+ ReplicationNode node,
+ ReplicationOperationPhase phase,
+ Class<? extends TopiaReplicationOperation> operationClass,
+ Object... params) {
ReplicationOperationDef op = new ReplicationOperationDef(phase, operationClass, node, params);
ownerNode.addOperation(op);
}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationNode.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationNode.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationNode.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -42,42 +42,52 @@
import java.util.Set;
/**
- * Le modele d'un noeud de replication.
+ * Model of a replication's node.
* <p/>
- * Un noeud represente exactement un type d'entite a repliquer
+ * The invariant of a replication's node is his {@link #contract}, means the
+ * type of entity to replicate.
*
- * @author chemit
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
*/
public class ReplicationNode {
- /** to use log facility, just put in your code: log.info(\"...\"); */
+ /** Logger */
private static final Log log = LogFactory.getLog(ReplicationNode.class);
+ /** contract of entity of the node. */
final TopiaEntityEnum contract;
+ /** entity operator. */
final EntityOperator<? super TopiaEntity> operator;
- /** les couples d'association a partir de ce noeud */
+ /** shell of the node. */
+ Set<ReplicationNode> shell;
+
+ /**
+ * dictionnary of associations defined on the node (keys are association
+ * name, and values are target node).
+ */
Map<String, ReplicationNode> associations;
- /** les couples de composition a partir de ce noeud */
+ /** names of association to dettach while replication. */
+ Set<String> associationsToDettach;
+
+ /**
+ * compositions defined on the node (keys are association name,
+ * and values are target node).
+ */
Map<String, ReplicationNode> dependencies;
- /** l'ensemble des associations a dettacher pendant la replication */
- Set<String> associationsToDettach;
-
- /** l'ensemble des dependences a dettacher pendant la replication */
+ /** names of dependency to dettach while replication. */
Set<String> dependenciesToDettach;
- /** la couverture de ce noeud */
- Set<ReplicationNode> shell;
-
- /** la sequences d'operations a realiser lors de la replication de ce node */
+ /** operations to fire when replication pass on this node. */
List<ReplicationOperationDef> operations;
public ReplicationNode(TopiaEntityEnum contract) {
this.contract = contract;
- operator = EntityOperatorStore.getOperator(contract);
+ operator = EntityOperatorStore.<TopiaEntity>getOperator(contract);
associations = new HashMap<String, ReplicationNode>();
dependencies = new HashMap<String, ReplicationNode>();
shell = new HashSet<ReplicationNode>();
@@ -123,7 +133,7 @@
Set<String> result = new HashSet<String>();
for (String name : associationsToDettach) {
ReplicationNode get = associations.get(name);
- if (get == node) {
+ if (node.equals(get)) {
result.add(name);
}
}
@@ -134,7 +144,7 @@
Set<String> result = new HashSet<String>();
for (String name : dependenciesToDettach) {
ReplicationNode get = dependencies.get(name);
- if (get == node) {
+ if (node.equals(get)) {
result.add(name);
}
}
@@ -227,6 +237,11 @@
return contract.toString();
}
+ /**
+ * {@link ReplicationOperationDef} comparator based on operation's phase.
+ *
+ * @see ReplicationOperationDef#getPhase()
+ */
public static final Comparator<ReplicationOperationDef>
OPERATION_COMPARATOR = new Comparator<ReplicationOperationDef>() {
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationOperationDef.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationOperationDef.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationOperationDef.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -29,6 +29,25 @@
import java.util.Arrays;
+/**
+ * Definition of a concrete operation to execute.
+ * <p/>
+ * A such operation involves :
+ * <ul>
+ * <li>the replication node</li>
+ * <li>the replication phase</li>
+ * <li>the replication operation type</li>
+ * <li>the replication operation arguments</li>
+ * </ul>
+ * <p/>
+ * This definition is detected when building replication model.
+ * <p/>
+ * Then when starting replication, base on this definition, we can build the
+ * operation to fire.
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
+ */
public class ReplicationOperationDef {
final ReplicationOperationPhase phase;
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationOperationPhase.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationOperationPhase.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/model/ReplicationOperationPhase.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -30,10 +30,11 @@
/**
* Une enumeration pour definir quand appliquer une operation.
* <p/>
- * L'ordre induit par cette enumeration sera utiliser pour trier les operations
+ * L'ordre induit par cette enumeration sera utilisé pour trier les operations
* a realiser sur chaque noeud de replication.
*
- * @author chemit
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
*/
public enum ReplicationOperationPhase {
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachAssociation.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachAssociation.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachAssociation.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -32,6 +32,7 @@
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.persistence.util.EntityOperator;
import org.nuiton.topia.persistence.util.TopiaEntityHelper;
+import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
import org.nuiton.topia.replication.ReplicationEngine;
import org.nuiton.topia.replication.TopiaReplicationOperation;
import org.nuiton.topia.replication.model.ReplicationModel;
@@ -42,7 +43,6 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
import static org.nuiton.i18n.I18n._;
@@ -66,7 +66,8 @@
* via la methode {@link #register(ReplicationModel, ReplicationNode,
* ReplicationOperationPhase, Object...)}.
*
- * @author chemit
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
*/
public class AttachAssociation implements TopiaReplicationOperation {
@@ -84,7 +85,7 @@
TopiaContextImplementor srcCtxt,
TopiaContextImplementor dstCtxt,
List<? extends TopiaEntity> nodeEntities,
- Map<Class<? extends TopiaEntity>, List<String>> data) throws TopiaException {
+ TopiaEntityIdsMap data) throws TopiaException {
String name = (String) operationDef.getParameters()[0];
Boolean reverse = (Boolean) operationDef.getParameters()[1];
@@ -229,4 +230,14 @@
dstCtxt.commitTransaction();
}
}
+
+ @Override
+ public void rollback(ReplicationOperationDef operationDef,
+ TopiaContextImplementor srcCtxt,
+ TopiaContextImplementor dstCtxt,
+ List<? extends TopiaEntity> entities,
+ TopiaEntityIdsMap data) throws Exception {
+
+ // il faut dettacher les associations
+ }
}
Deleted: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachDependency.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachDependency.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachDependency.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -1,125 +0,0 @@
-/*
- * #%L
- * ToPIA :: Service Replication
- *
- * $Id$
- * $HeadURL$
- * %%
- * Copyright (C) 2004 - 2010 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%
- */
-
-package org.nuiton.topia.replication.operation;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.nuiton.topia.TopiaException;
-import org.nuiton.topia.framework.TopiaContextImplementor;
-import org.nuiton.topia.persistence.TopiaEntity;
-import org.nuiton.topia.replication.TopiaReplicationOperation;
-import org.nuiton.topia.replication.model.ReplicationModel;
-import org.nuiton.topia.replication.model.ReplicationNode;
-import org.nuiton.topia.replication.model.ReplicationOperationDef;
-import org.nuiton.topia.replication.model.ReplicationOperationPhase;
-
-import java.util.List;
-import java.util.Map;
-
-import static org.nuiton.i18n.I18n._;
-
-/**
- * Pour attacher une dependance.
- * <p/>
- * TODO non implante pour le moment
- * <p/>
- * Note : cette operation est interne, et n'est pas creable par l'utilisateur
- * via la methode {@link #register(ReplicationModel, ReplicationNode,
- * ReplicationOperationPhase, Object...)}.
- *
- * @author chemit
- */
-public class AttachDependency implements TopiaReplicationOperation {
-
- private static final Log log = LogFactory.getLog(AttachDependency.class);
-
- @Override
- public void register(ReplicationModel model, ReplicationNode ownerNode, ReplicationOperationPhase phase, Object... parameters) {
- throw new UnsupportedOperationException(_("topia.replication.operation.error.uncreatable", getClass()));
- }
-
- @Override
- public void run(ReplicationOperationDef operationDef,
- TopiaContextImplementor srcCtxt,
- TopiaContextImplementor dstCtxt,
- List<? extends TopiaEntity> nodeEntities,
- Map<Class<? extends TopiaEntity>, List<String>> data) throws TopiaException {
-
- throw new UnsupportedOperationException(_("topia.replication.operation.error.notImplemented", getClass()));
-
- //TODO non implante pour le moment
-// ReplicationNode ownerNode = operationDef.getNode();
-//
-// String[] names = (String[]) operationDef.getParameters();
-//
-// EntityOperator<? super TopiaEntity> ownerOperator = ownerNode.getOperator();
-//
-// List<? extends TopiaEntity> ownerEntities = data.get(ownerOperator.getClazz());
-//
-// if (ownerEntities == null || ownerEntities.isEmpty()) {
-// // pas de donnees a traiter
-// log.info(_("topia.replication.attachAssociation.nothing.to.do", ownerOperator));
-// return;
-// }
-//
-// boolean shouldCommit = false;
-// for (String name : names) {
-//
-// // le noeud de l'entite dont on veut reattacher des associations
-// ReplicationNode targetNode = ownerNode.getAssociations().get(name);
-//
-// List<TopiaEntity> targets = data.get(targetNode.getContract().getContract());
-// List<String> targetIds = TopiaEntityHelper.getTopiaIdList(targets);
-// targets.clear();
-//
-//
-// for (TopiaEntity src : ownerEntities) {
-//
-// // les association connues
-// TopiaEntity target = (TopiaEntity) ownerOperator.get(name, src);
-//
-// if (target == null || !targetIds.contains(target.getTopiaId())) {
-// // pas de donnees a attacher, ou pas pour ce src
-// continue;
-// }
-//
-// // l'entite cible
-// TopiaEntity dst = dstCtxt.findByTopiaId(src.getTopiaId());
-//
-// target = dstCtxt.findByTopiaId(target.getTopiaId());
-//
-// ownerOperator.set(name, dst, target);
-//
-// dst.update();
-// shouldCommit = true;
-//
-// }
-// }
-// if (shouldCommit) {
-// dstCtxt.commitTransaction();
-// }
- }
-}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachLink.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachLink.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/AttachLink.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -32,6 +32,7 @@
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.persistence.util.EntityOperator;
import org.nuiton.topia.persistence.util.TopiaEntityHelper;
+import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
import org.nuiton.topia.replication.ReplicationEngine;
import org.nuiton.topia.replication.TopiaReplicationOperation;
import org.nuiton.topia.replication.model.Link;
@@ -43,7 +44,6 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
import static org.nuiton.i18n.I18n._;
@@ -67,7 +67,8 @@
* via la methode {@link #register(ReplicationModel, ReplicationNode,
* ReplicationOperationPhase, Object...)}.
*
- * @author chemit
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
*/
public class AttachLink implements TopiaReplicationOperation {
@@ -85,7 +86,7 @@
TopiaContextImplementor srcCtxt,
TopiaContextImplementor dstCtxt,
List<? extends TopiaEntity> nodeEntities,
- Map<Class<? extends TopiaEntity>, List<String>> data) throws TopiaException {
+ TopiaEntityIdsMap data) throws TopiaException {
Link link = (Link) operationDef.getParameters()[0];
@@ -217,4 +218,14 @@
dstCtxt.commitTransaction();
}
}
+
+ @Override
+ public void rollback(ReplicationOperationDef operationDef,
+ TopiaContextImplementor srcCtxt,
+ TopiaContextImplementor dstCtxt,
+ List<? extends TopiaEntity> entities,
+ TopiaEntityIdsMap data) throws Exception {
+
+ // il faut dettacher les liens
+ }
}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/DettachAssociation.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/DettachAssociation.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/DettachAssociation.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -31,6 +31,7 @@
import org.nuiton.topia.framework.TopiaContextImplementor;
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.persistence.util.EntityOperator;
+import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
import org.nuiton.topia.replication.TopiaReplicationOperation;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
@@ -38,7 +39,6 @@
import org.nuiton.topia.replication.model.ReplicationOperationPhase;
import java.util.List;
-import java.util.Map;
import static org.nuiton.i18n.I18n._;
@@ -49,7 +49,8 @@
* l'utilisateur via la methode
* {@link #register(ReplicationModel, ReplicationNode, ReplicationOperationPhase, Object...)}.
*
- * @author chemit
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
*/
public class DettachAssociation implements TopiaReplicationOperation {
@@ -67,7 +68,7 @@
TopiaContextImplementor srcCtxt,
TopiaContextImplementor dstCtxt,
List<? extends TopiaEntity> entities,
- Map<Class<? extends TopiaEntity>, List<String>> data) throws TopiaException {
+ TopiaEntityIdsMap data) throws TopiaException {
String name = (String) operationDef.getParameters()[0];
@@ -84,6 +85,16 @@
operator.setNull(name, e);
}
}
+ }
+
+ @Override
+ public void rollback(ReplicationOperationDef operationDef,
+ TopiaContextImplementor srcCtxt,
+ TopiaContextImplementor dstCtxt,
+ List<? extends TopiaEntity> entities,
+ TopiaEntityIdsMap data) throws Exception {
+
+ // il faut attacher les associations ? ou bien ne rien faire ?
}
}
Deleted: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/DettachDependency.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/DettachDependency.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/DettachDependency.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -1,90 +0,0 @@
-/*
- * #%L
- * ToPIA :: Service Replication
- *
- * $Id$
- * $HeadURL$
- * %%
- * Copyright (C) 2004 - 2010 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%
- */
-
-package org.nuiton.topia.replication.operation;
-
-import org.nuiton.topia.TopiaException;
-import org.nuiton.topia.framework.TopiaContextImplementor;
-import org.nuiton.topia.persistence.TopiaEntity;
-import org.nuiton.topia.replication.TopiaReplicationOperation;
-import org.nuiton.topia.replication.model.ReplicationModel;
-import org.nuiton.topia.replication.model.ReplicationNode;
-import org.nuiton.topia.replication.model.ReplicationOperationDef;
-import org.nuiton.topia.replication.model.ReplicationOperationPhase;
-
-import java.util.List;
-import java.util.Map;
-
-import static org.nuiton.i18n.I18n._;
-
-/**
- * Pour dettacher une dependance.
- * <p/>
- * TODO Pas implante pour le moment
- * <p/>
- * Note : cette operation est interne, et n'est pas creable par
- * l'utilisateur via la methode
- * {@link #register(ReplicationModel, ReplicationNode, ReplicationOperationPhase, Object...)}.
- *
- * @author chemit
- */
-public class DettachDependency implements TopiaReplicationOperation {
-
- @Override
- public void register(ReplicationModel model, ReplicationNode ownerNode, ReplicationOperationPhase phase, Object... parameters) {
-
- throw new UnsupportedOperationException(_("topia.replication.operation.error.uncreatable", getClass()));
- }
-
- @Override
- public void run(ReplicationOperationDef operationDef,
- TopiaContextImplementor srcCtxt,
- TopiaContextImplementor dstCtxt,
- List<? extends TopiaEntity> nodeEntities,
- Map<Class<? extends TopiaEntity>, List<String>> data) throws TopiaException {
-
- throw new UnsupportedOperationException(_("topia.replication.operation.error.notImplemented", getClass()));
- //TODO non implante pour le moment
-//
-// ReplicationNode node = operationDef.getNode();
-//
-// String[] names = (String[]) operationDef.getParameters();
-//
-// EntityOperator<? super TopiaEntity> operator = node.getOperator();
-//
-//// // recuperation des donnees a traiter
-//// List<TopiaEntity> entities = data.get(operator.getClazz());
-////
-//// // recuperation de la liste sur le context actuel
-//// entities = ReplicationEngine.getEntities(srcCtxt, entities, false);
-//
-// // dettach les attributs
-// for (TopiaEntity e : nodeEntities) {
-// for (String name : names) {
-// operator.setNull(name, e);
-// }
-// }
- }
-}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/Duplicate.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/Duplicate.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/Duplicate.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -28,6 +28,7 @@
import org.nuiton.topia.TopiaException;
import org.nuiton.topia.framework.TopiaContextImplementor;
import org.nuiton.topia.persistence.TopiaEntity;
+import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
import org.nuiton.topia.replication.TopiaReplicationOperation;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
@@ -35,7 +36,6 @@
import org.nuiton.topia.replication.model.ReplicationOperationPhase;
import java.util.List;
-import java.util.Map;
import static org.nuiton.i18n.I18n._;
@@ -46,7 +46,8 @@
* l'utilisateur via la methode
* {@link #register(ReplicationModel, ReplicationNode, ReplicationOperationPhase, Object...)}.
*
- * @author chemit
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
*/
public class Duplicate implements TopiaReplicationOperation {
@@ -60,7 +61,7 @@
TopiaContextImplementor srcCtxt,
TopiaContextImplementor dstCtxt,
List<? extends TopiaEntity> entities,
- Map<Class<? extends TopiaEntity>, List<String>> data) throws TopiaException {
+ TopiaEntityIdsMap data) throws TopiaException {
// replication des donnees vers la destination
srcCtxt.replicateEntities(dstCtxt, entities);
@@ -69,4 +70,15 @@
dstCtxt.commitTransaction();
}
+
+
+ @Override
+ public void rollback(ReplicationOperationDef operationDef,
+ TopiaContextImplementor srcCtxt,
+ TopiaContextImplementor dstCtxt,
+ List<? extends TopiaEntity> entities,
+ TopiaEntityIdsMap data) throws Exception {
+
+ // il faut supprimer les entities
+ }
}
Modified: trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/LoadLink.java
===================================================================
--- trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/LoadLink.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/main/java/org/nuiton/topia/replication/operation/LoadLink.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -31,6 +31,7 @@
import org.nuiton.topia.framework.TopiaContextImplementor;
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.persistence.util.EntityOperator;
+import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
import org.nuiton.topia.replication.TopiaReplicationOperation;
import org.nuiton.topia.replication.model.Link;
import org.nuiton.topia.replication.model.ReplicationModel;
@@ -39,7 +40,6 @@
import org.nuiton.topia.replication.model.ReplicationOperationPhase;
import java.util.List;
-import java.util.Map;
import static org.nuiton.i18n.I18n._;
@@ -50,7 +50,8 @@
* l'utilisateur via la methode
* {@link #register(ReplicationModel, ReplicationNode, ReplicationOperationPhase, Object...)}.
*
- * @author chemit
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
*/
public class LoadLink implements TopiaReplicationOperation {
@@ -68,7 +69,7 @@
TopiaContextImplementor srcCtxt,
TopiaContextImplementor dstCtxt,
List<? extends TopiaEntity> nodeEntities,
- Map<Class<? extends TopiaEntity>, List<String>> data) throws TopiaException {
+ TopiaEntityIdsMap data) throws TopiaException {
Link link = (Link) operationDef.getParameters()[0];
@@ -95,4 +96,15 @@
}
}
}
+
+
+ @Override
+ public void rollback(ReplicationOperationDef operationDef,
+ TopiaContextImplementor srcCtxt,
+ TopiaContextImplementor dstCtxt,
+ List<? extends TopiaEntity> entities,
+ TopiaEntityIdsMap data) throws Exception {
+
+ // rien a faire ici
+ }
}
Modified: trunk/topia-service-replication/src/main/resources/META-INF/services/org.nuiton.topia.replication.TopiaReplicationOperation
===================================================================
--- trunk/topia-service-replication/src/main/resources/META-INF/services/org.nuiton.topia.replication.TopiaReplicationOperation 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/main/resources/META-INF/services/org.nuiton.topia.replication.TopiaReplicationOperation 2010-08-14 13:54:40 UTC (rev 2098)
@@ -6,6 +6,4 @@
org.nuiton.topia.replication.operation.LoadLink
org.nuiton.topia.replication.operation.AttachAssociation
org.nuiton.topia.replication.operation.DettachAssociation
-org.nuiton.topia.replication.operation.AttachDependency
-org.nuiton.topia.replication.operation.DettachDependency
org.nuiton.topia.replication.operation.Duplicate
Modified: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/AbstractReplicationEngineTest.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/AbstractReplicationEngineTest.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/AbstractReplicationEngineTest.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -57,11 +57,9 @@
* <p/>
* Created: 07 jun. 09 17:14:22
*
- * @author tchemit
- * @version $Revision$
- * <p/>
- * Last update: $Date$
- * by :
+ * @author tchemit <chemit(a)codelutin.com>
+ * @version $Id$
+ * @since 2.2.0
*/
public abstract class AbstractReplicationEngineTest extends Assert {
@@ -219,9 +217,9 @@
detectTypes = service.detectTypes(getContracts(), entity.getTopiaId());
assertEquals("expected types : " +
- Arrays.toString(expectedCouple) +
- " but was " + detectTypes,
- expectedCouple.length, detectTypes.size());
+ Arrays.toString(expectedCouple) +
+ " but was " + detectTypes,
+ expectedCouple.length, detectTypes.size());
for (Object o : expectedCouple) {
assertTrue(detectTypes.contains(o));
}
@@ -285,7 +283,7 @@
shell = model.getNode(c.getContract()).getShell();
assertEquals(
"expected shell : " + Arrays.toString(expected) + ", but was " +
- shell, expected.length, shell.size());
+ shell, expected.length, shell.size());
for (int i = 0, j = expected.length; i < j; i++) {
TopiaEntityEnum type = expected[i];
@@ -532,7 +530,7 @@
}
Assert.assertNotNull(
"contract not found for " + expected.getClass() + " in " +
- Arrays.toString(getContracts()), contract);
+ Arrays.toString(getContracts()), contract);
EntityOperator<TopiaEntity> operator = EntityOperatorStore.getOperator(contract);
List<String> associationProperties = operator.getAssociationProperties();
for (String name : associationProperties) {
Modified: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/ReplicationEngineAllTest.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/ReplicationEngineAllTest.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/ReplicationEngineAllTest.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -25,50 +25,57 @@
package org.nuiton.topia.replication;
-import java.io.File;
-import org.nuiton.topia.TopiaContext;
-import org.nuiton.topia.TopiaContextFactory;
-import org.nuiton.topia.framework.TopiaContextImplementor;
-import org.nuiton.topia.test.entities.*;
-import org.junit.Test;
-
-import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
+import org.junit.Test;
+import org.nuiton.topia.TopiaContext;
+import org.nuiton.topia.TopiaContextFactory;
import org.nuiton.topia.TopiaException;
import org.nuiton.topia.TopiaTestDAOHelper.TopiaTestEntityEnum;
+import org.nuiton.topia.framework.TopiaContextImplementor;
import org.nuiton.topia.persistence.TopiaEntity;
import org.nuiton.topia.persistence.TopiaEntityEnum;
+import org.nuiton.topia.test.entities.Person;
+import org.nuiton.topia.test.entities.PersonImpl;
+import org.nuiton.topia.test.entities.Pet;
+import org.nuiton.topia.test.entities.PetImpl;
+import org.nuiton.topia.test.entities.Race;
+import org.nuiton.topia.test.entities.RaceImpl;
+import java.io.File;
+import java.util.Properties;
+
/**
* ReplicationEngineTest on model TopiaTest
- *
+ * <p/>
* Created: 07 jun. 09 17:14:22
*
- * @author tchemit
- * @version $Revision$
- *
- * Last update: $Date$
- * by : */
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
+ */
public class ReplicationEngineAllTest extends AbstractReplicationEngineTest {
/** to use log facility, just put in your code: log.info(\"...\"); */
private static final Log log = LogFactory.getLog(ReplicationEngineTest.class);
+
protected static final TopiaEntityEnum[] contracts = {
TopiaTestEntityEnum.Person,
TopiaTestEntityEnum.Pet,
TopiaTestEntityEnum.Race
};
+
protected static final String entitiesList =
PersonImpl.class.getName() + "," +
PetImpl.class.getName() + "," +
RaceImpl.class.getName();
-
+
static protected Person person, person2;
+
static protected Pet pet, pet2, pet3;
+
static protected Race race, race2, race3;
@AfterClass
@@ -101,6 +108,7 @@
}
// @Ignore
+
@Test
@Override
public void testDetectTypes() throws Exception {
@@ -118,12 +126,14 @@
}
// @Ignore
+
@Test
@Override
public void testGetOperation() throws Exception {
}
// @Ignore
+
@Test
@Override
public void testDetectAssociations() throws Exception {
@@ -139,6 +149,7 @@
}
// @Ignore
+
@Test
@Override
public void testDetectDirectDependencies() throws Exception {
@@ -153,6 +164,7 @@
}
// @Ignore
+
@Test
@Override
public void testDetectShell() throws Exception {
@@ -166,15 +178,17 @@
}
// @Ignore
+
@Test
@Override
public void testDetectDependencies() throws Exception {
detectDependencies(null,
- new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Race}, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Person}, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Pet});
+ new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Race}, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Person}, new TopiaTestEntityEnum[]{TopiaTestEntityEnum.Pet});
}
// @Ignore
+
@Test
@Override
public void testDetectObjectsToDettach() throws Exception {
@@ -183,6 +197,7 @@
}
// @Ignore
+
@Test
@Override
public void testDetectOperations() throws Exception {
@@ -191,6 +206,7 @@
}
// @Ignore
+
@Test
@Override
public void testDoReplicate() throws Exception {
Modified: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/ReplicationEngineTest.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/ReplicationEngineTest.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/ReplicationEngineTest.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -39,9 +39,7 @@
import org.nuiton.topia.persistence.TopiaEntityEnum;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.operation.AttachAssociation;
-import org.nuiton.topia.replication.operation.AttachDependency;
import org.nuiton.topia.replication.operation.DettachAssociation;
-import org.nuiton.topia.replication.operation.DettachDependency;
import org.nuiton.topia.replication.operation.Duplicate;
import org.nuiton.topia.replication.operation.FakeOperation;
import org.nuiton.topia.replication.operation.UncreatableOperation;
@@ -54,7 +52,6 @@
import org.nuiton.topia.test.entities.RaceImpl;
import java.io.File;
-import java.util.Map;
import java.util.Properties;
/**
@@ -62,11 +59,8 @@
* <p/>
* Created: 07 jun. 09 17:14:22
*
- * @author tchemit
- * @version $Revision$
- * <p/>
- * Last update: $Date$
- * by :
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
*/
public class ReplicationEngineTest extends AbstractReplicationEngineTest {
@@ -138,8 +132,6 @@
getOperation(Duplicate.class, true);
getOperation(AttachAssociation.class, true);
getOperation(DettachAssociation.class, true);
- getOperation(AttachDependency.class, true);
- getOperation(DettachDependency.class, true);
}
@Test
@@ -281,7 +273,7 @@
/**
* Cette methode montre comment manuellement on peut effectuer la
- * replication (en dettachant les dependances qui forment des cyles)
+ * replication (en dettachant les dependances qui forment des cycles)
* <p/>
* La methode utilisee ici peut ne pas fonctionner : si une clef metier est
* posee sur une dependance alors cela ne fonctionne pas.
@@ -328,7 +320,7 @@
/**
* Cette methode montre comment manuellement on peut effectuer la
- * replication (en dettachant les associations qui forment des cyles)
+ * replication (en dettachant les associations qui forment des cycles)
* <p/>
* La methode utilisee ici fonctionne mieux que la precedante : il parrait
* dificille de pose une une clef metier sur une association :).
@@ -337,7 +329,7 @@
* est pas obligee de la reattachee car elle est bi-directionnelle.
* <p/>
* On doit optimiser l'algorithme dans la methode {@link
- * ReplicationModel#adjustOperations(Map)}.
+ * ReplicationModel#adjustOperations(org.nuiton.topia.persistence.util.TopiaEntityIdsMap)}.
*
* @throws Exception pour toute erreur
*/
Modified: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationOperationTest.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationOperationTest.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/TopiaReplicationOperationTest.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -38,9 +38,7 @@
import org.nuiton.topia.persistence.TopiaEntityEnum;
import org.nuiton.topia.replication.model.ReplicationOperationPhase;
import org.nuiton.topia.replication.operation.AttachAssociation;
-import org.nuiton.topia.replication.operation.AttachDependency;
import org.nuiton.topia.replication.operation.DettachAssociation;
-import org.nuiton.topia.replication.operation.DettachDependency;
import org.nuiton.topia.replication.operation.Duplicate;
import org.nuiton.topia.replication.operation.FakeOperation;
import org.nuiton.topia.replication.operation.UncreatableOperation;
@@ -60,11 +58,8 @@
* <p/>
* Created: 07 jun. 09 17:14:22
*
- * @author tchemit
- * @version $Revision$
- * <p/>
- * Last update: $Date$
- * by : $Author$
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
*/
public class TopiaReplicationOperationTest extends AbstractReplicationEngineTest {
@@ -109,18 +104,14 @@
}
}
-// @Ignore
-
@Test(expected = NullPointerException.class)
public void testGetOperation_nullOperationClass() throws Exception {
service.getOperation(null);
}
-// @Ignore
-
@Test(expected = IllegalStateException.class)
public void testGetOperation_serviceNotInit() throws Exception {
- ReplicationEngine.operations = null;
+// ReplicationEngine.operations = null;
try {
new ReplicationEngine().getOperation(Duplicate.class);
} catch (IllegalStateException e) {
@@ -134,8 +125,6 @@
}
}
-// @Ignore
-
@Test
@Override
public void testGetOperation() throws Exception {
@@ -146,19 +135,13 @@
getOperation(Duplicate.class, true);
getOperation(AttachAssociation.class, true);
getOperation(DettachAssociation.class, true);
- getOperation(AttachDependency.class, true);
- getOperation(DettachDependency.class, true);
}
-// @Ignore
-
@Test(expected = NullPointerException.class)
public void testCreateOperation_nullModel() throws Exception {
service.createOperation(null, null, null, null);
}
-// @Ignore
-
@Test(expected = NullPointerException.class)
public void testCreateOperation_nullType() throws Exception {
@@ -166,8 +149,6 @@
service.createOperation(model, null, null, null);
}
-// @Ignore
-
@Test(expected = NullPointerException.class)
public void testCreateOperation_nullPhase() throws Exception {
@@ -175,8 +156,6 @@
service.createOperation(model, TopiaTestEntityEnum.Pet, null, null);
}
-// @Ignore
-
@Test(expected = NullPointerException.class)
public void testCreateOperation_nullOperationClass() throws Exception {
@@ -184,8 +163,6 @@
service.createOperation(model, TopiaTestEntityEnum.Pet, ReplicationOperationPhase.before, null);
}
-// @Ignore
-
@Test(expected = IllegalArgumentException.class)
public void testCreateOperation_noNode() throws Exception {
@@ -194,8 +171,6 @@
service.addAfterOperation(model, TopiaTestEntityEnum.Pet, Duplicate.class);
}
-// @Ignore
-
@Test(expected = IllegalArgumentException.class)
public void testCreateOperation_noOperation() throws Exception {
@@ -204,92 +179,46 @@
service.addAfterOperation(model, TopiaTestEntityEnum.Pet, UnregistredOperation.class);
}
-// @Ignore
-
@Test(expected = UnsupportedOperationException.class)
public void testCreateUnsupportedBeforeOperation_Duplicate() throws Exception {
createUnsupportedBeforeOperation(TopiaTestEntityEnum.Person, person, Duplicate.class);
}
-// @Ignore
-
@Test(expected = UnsupportedOperationException.class)
public void testCreateUnsupportedBeforeOperation_AttachAssociation() throws Exception {
createUnsupportedBeforeOperation(TopiaTestEntityEnum.Person, person, AttachAssociation.class);
}
-// @Ignore
-
@Test(expected = UnsupportedOperationException.class)
public void testCreateUnsupportedBeforeOperation_DetachAssociation() throws Exception {
createUnsupportedBeforeOperation(TopiaTestEntityEnum.Person, person, DettachAssociation.class);
}
-// @Ignore
-
@Test(expected = UnsupportedOperationException.class)
- public void testCreateUnsupportedBeforeOperation_AttachDependency() throws Exception {
- createUnsupportedBeforeOperation(TopiaTestEntityEnum.Person, person, AttachDependency.class);
- }
-
-// @Ignore
-
- @Test(expected = UnsupportedOperationException.class)
- public void testCreateUnsupportedBeforeOperation_DetachDependency() throws Exception {
- createUnsupportedBeforeOperation(TopiaTestEntityEnum.Person, person, DettachDependency.class);
- }
-
-// @Ignore
-
- @Test(expected = UnsupportedOperationException.class)
public void testCreateUnsupportedAfterOperation_Duplicate() throws Exception {
createUnsupportedAfterOperation(TopiaTestEntityEnum.Person, person, Duplicate.class);
}
-// @Ignore
-
@Test(expected = UnsupportedOperationException.class)
public void testCreateUnsupportedAfterOperation_AttachAssociation() throws Exception {
createUnsupportedAfterOperation(TopiaTestEntityEnum.Person, person, AttachAssociation.class);
}
-// @Ignore
-
@Test(expected = UnsupportedOperationException.class)
public void testCreateUnsupportedAfterOperation_DetachAssociation() throws Exception {
createUnsupportedAfterOperation(TopiaTestEntityEnum.Person, person, DettachAssociation.class);
}
-// @Ignore
-
@Test(expected = UnsupportedOperationException.class)
- public void testCreateUnsupportedAfterOperation_AttachDependency() throws Exception {
- createUnsupportedAfterOperation(TopiaTestEntityEnum.Person, person, AttachDependency.class);
- }
-
-// @Ignore
-
- @Test(expected = UnsupportedOperationException.class)
- public void testCreateUnsupportedAfterOperation_DetachDependency() throws Exception {
- createUnsupportedAfterOperation(TopiaTestEntityEnum.Person, person, DettachDependency.class);
- }
-
-// @Ignore
-
- @Test(expected = UnsupportedOperationException.class)
public void testCreateUnsupportedBeforeOperation_UncreatableOperation() throws Exception {
createUnsupportedBeforeOperation(TopiaTestEntityEnum.Person, person, UncreatableOperation.class);
}
-// @Ignore
-
@Test(expected = UnsupportedOperationException.class)
public void testCreateUnsupportedAfterOperation_UncreatableOperation() throws Exception {
createUnsupportedAfterOperation(TopiaTestEntityEnum.Person, person, UncreatableOperation.class);
}
-// @Ignore
-
@Test(expected = IllegalArgumentException.class)
public void testCreateOperation_wrongParameterNumber() throws Exception {
@@ -297,8 +226,6 @@
service.addBeforeOperation(model, TopiaTestEntityEnum.Pet, FakeOperation.class);
}
-// @Ignore
-
@Test(expected = IllegalArgumentException.class)
public void testCreateOperation_wrongParameterNumber2() throws Exception {
@@ -306,8 +233,6 @@
service.addBeforeOperation(model, TopiaTestEntityEnum.Pet, FakeOperation.class, String.class, String.class);
}
-// @Ignore
-
@Test(expected = IllegalArgumentException.class)
public void testCreateOperation_wrongParameterType() throws Exception {
@@ -315,8 +240,6 @@
service.addBeforeOperation(model, TopiaTestEntityEnum.Pet, FakeOperation.class, Integer.class);
}
-// @Ignore
-
@Test(expected = IllegalArgumentException.class)
public void testCreateOperation_nullParameter() throws Exception {
@@ -324,8 +247,6 @@
service.addBeforeOperation(model, TopiaTestEntityEnum.Pet, FakeOperation.class, (Object) null);
}
-// @Ignore
-
@Test
public void testCreateOperation() throws Exception {
@@ -334,16 +255,12 @@
service.addAfterOperation(model, TopiaTestEntityEnum.Race, FakeOperation.class, "after");
}
-// @Ignore
-
@Test(expected = NullPointerException.class)
public void testDoReplicate_nullModel() throws Exception {
service.doReplicate(null, null);
}
-// @Ignore
-
@Test(expected = NullPointerException.class)
public void testDoReplicate_nullDstCtxt() throws Exception {
Modified: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/FakeOperation.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/FakeOperation.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/FakeOperation.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -25,22 +25,24 @@
package org.nuiton.topia.replication.operation;
-import org.nuiton.topia.replication.*;
-import java.util.List;
-import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.topia.TopiaException;
import org.nuiton.topia.framework.TopiaContextImplementor;
import org.nuiton.topia.persistence.TopiaEntity;
+import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
+import org.nuiton.topia.replication.ReplicationEngine;
+import org.nuiton.topia.replication.TopiaReplicationOperation;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
import org.nuiton.topia.replication.model.ReplicationOperationDef;
import org.nuiton.topia.replication.model.ReplicationOperationPhase;
+import java.util.List;
+
/**
- *
- * @author chemit
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
*/
public class FakeOperation implements TopiaReplicationOperation {
@@ -48,7 +50,7 @@
private static final Log log = LogFactory.getLog(FakeOperation.class);
public static final Class<?>[] PARAMETERS_CLASSES = new Class<?>[]{String.class};
-
+
@Override
public void register(ReplicationModel model,
ReplicationNode ownerNode,
@@ -67,11 +69,16 @@
@Override
public void run(ReplicationOperationDef operationDef,
- TopiaContextImplementor srcCtxt,
- TopiaContextImplementor dstCtxt,
- List<? extends TopiaEntity> nodeEntities,
- Map<Class<? extends TopiaEntity>, List<String>> data)
+ TopiaContextImplementor srcCtxt,
+ TopiaContextImplementor dstCtxt,
+ List<? extends TopiaEntity> nodeEntities,
+ TopiaEntityIdsMap data)
throws TopiaException {
}
+
+ @Override
+ public void rollback(ReplicationOperationDef operationDef, TopiaContextImplementor srcCtxt, TopiaContextImplementor dstCtxt, List<? extends TopiaEntity> entities, TopiaEntityIdsMap data) throws Exception {
+ // rien a faire
+ }
}
Modified: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UncreatableOperation.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UncreatableOperation.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UncreatableOperation.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -25,23 +25,25 @@
package org.nuiton.topia.replication.operation;
-import org.nuiton.topia.replication.*;
-import java.util.List;
-import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.topia.TopiaException;
import org.nuiton.topia.framework.TopiaContextImplementor;
import org.nuiton.topia.persistence.TopiaEntity;
+import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
+import org.nuiton.topia.replication.TopiaReplicationOperation;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
import org.nuiton.topia.replication.model.ReplicationOperationDef;
import org.nuiton.topia.replication.model.ReplicationOperationPhase;
+
+import java.util.List;
+
import static org.nuiton.i18n.I18n._;
/**
- *
- * @author chemit
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
*/
public class UncreatableOperation implements TopiaReplicationOperation {
@@ -61,10 +63,15 @@
@Override
public void run(ReplicationOperationDef operationDef,
- TopiaContextImplementor srcCtxt,
- TopiaContextImplementor dstCtxt,
- List<? extends TopiaEntity> nodeEntities,
- Map<Class<? extends TopiaEntity>, List<String>> data)
+ TopiaContextImplementor srcCtxt,
+ TopiaContextImplementor dstCtxt,
+ List<? extends TopiaEntity> nodeEntities,
+ TopiaEntityIdsMap data)
throws TopiaException {
}
+
+ @Override
+ public void rollback(ReplicationOperationDef operationDef, TopiaContextImplementor srcCtxt, TopiaContextImplementor dstCtxt, List<? extends TopiaEntity> entities, TopiaEntityIdsMap data) throws Exception {
+ // rien a faire
+ }
}
Modified: trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UnregistredOperation.java
===================================================================
--- trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UnregistredOperation.java 2010-08-14 13:53:11 UTC (rev 2097)
+++ trunk/topia-service-replication/src/test/java/org/nuiton/topia/replication/operation/UnregistredOperation.java 2010-08-14 13:54:40 UTC (rev 2098)
@@ -30,6 +30,7 @@
import org.nuiton.topia.TopiaException;
import org.nuiton.topia.framework.TopiaContextImplementor;
import org.nuiton.topia.persistence.TopiaEntity;
+import org.nuiton.topia.persistence.util.TopiaEntityIdsMap;
import org.nuiton.topia.replication.TopiaReplicationOperation;
import org.nuiton.topia.replication.model.ReplicationModel;
import org.nuiton.topia.replication.model.ReplicationNode;
@@ -37,9 +38,11 @@
import org.nuiton.topia.replication.model.ReplicationOperationPhase;
import java.util.List;
-import java.util.Map;
-/** @author chemit */
+/**
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.2.0
+ */
public class UnregistredOperation implements TopiaReplicationOperation {
/** to use log facility, just put in your code: log.info(\"...\"); */
@@ -59,7 +62,12 @@
TopiaContextImplementor srcCtxt,
TopiaContextImplementor dstCtxt,
List<? extends TopiaEntity> nodeEntities,
- Map<Class<? extends TopiaEntity>, List<String>> data)
+ TopiaEntityIdsMap data)
throws TopiaException {
}
+
+ @Override
+ public void rollback(ReplicationOperationDef operationDef, TopiaContextImplementor srcCtxt, TopiaContextImplementor dstCtxt, List<? extends TopiaEntity> entities, TopiaEntityIdsMap data) throws Exception {
+ // rien a faire
+ }
}
1
0
r2097 - trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util
by tchemit@users.nuiton.org Aug. 14, 2010
by tchemit@users.nuiton.org Aug. 14, 2010
Aug. 14, 2010
Author: tchemit
Date: 2010-08-14 15:53:11 +0200 (Sat, 14 Aug 2010)
New Revision: 2097
Url: http://nuiton.org/repositories/revision/topia/2097
Log:
introduce a TopiaEntityIdsMap + use it + reformat code
Added:
trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/TopiaEntityIdsMap.java
Modified:
trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/TopiaEntityHelper.java
Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/TopiaEntityHelper.java
===================================================================
--- trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/TopiaEntityHelper.java 2010-08-11 14:47:08 UTC (rev 2096)
+++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/TopiaEntityHelper.java 2010-08-14 13:53:11 UTC (rev 2097)
@@ -233,7 +233,7 @@
}
log.info("create database from [" + databaseDump + "] at [" +
- dbDirectory + "]");
+ dbDirectory + "]");
TopiaContext ctxt = topiaContext.beginTransaction();
@@ -270,7 +270,7 @@
if (!gzipFile.getParentFile().exists()) {
if (!gzipFile.getParentFile().mkdirs()) {
throw new IOException("could not create directory " +
- gzipFile.getParentFile());
+ gzipFile.getParentFile());
}
}
log.info("store database to [" + gzipFile + "]");
@@ -577,19 +577,20 @@
* les entites dont le contract est dans l'ensemble voulu).
* @throws TopiaException if a pb while visiting entities
*/
- public static Map<Class<? extends TopiaEntity>, List<String>>
+ public static TopiaEntityIdsMap
detectEntityIds(final TopiaEntityEnum[] contracts,
final Set<Class<? extends TopiaEntity>> types,
TopiaEntity... entities) throws TopiaException {
- Collector<Map<Class<? extends TopiaEntity>, List<String>>> collector;
- collector = new Collector<Map<Class<? extends TopiaEntity>, List<String>>>(contracts) {
+ Collector<TopiaEntityIdsMap> collector;
+ collector = new Collector<TopiaEntityIdsMap>(contracts) {
+
/**
* le dictionnaire des références détectées indexées par leur type
*/
- protected Map<Class<? extends TopiaEntity>, List<String>> detectedRefs =
- new HashMap<Class<? extends TopiaEntity>, List<String>>();
+ protected TopiaEntityIdsMap detectedRefs =
+ new TopiaEntityIdsMap();
@Override
protected void onStarted(TopiaEntity e, boolean enter) {
@@ -614,14 +615,13 @@
}
@Override
- protected Map<Class<? extends TopiaEntity>, List<String>>
+ protected TopiaEntityIdsMap
afterAll(CollectorVisitor visitor, TopiaEntity... entities) {
return detectedRefs;
}
};
- Map<Class<? extends TopiaEntity>, List<String>> result =
- collector.detect(entities);
+ TopiaEntityIdsMap result = collector.detect(entities);
return result;
}
@@ -641,7 +641,7 @@
String[] expressions,
TopiaEntity entities) throws TopiaException {
return detectReferences(contracts, expressions,
- Collections.singleton(entities));
+ Collections.singleton(entities));
}
/**
@@ -735,7 +735,7 @@
boolean contains = visitor.getStack().contains(e1);
if (log.isDebugEnabled()) {
log.debug("already enter " + e1.getTopiaId() +
- ", can reenter ? " + !contains);
+ ", can reenter ? " + !contains);
}
if (!contains) {
try {
@@ -787,7 +787,7 @@
boolean contains = visitor.getStack().contains(e1);
if (log.isDebugEnabled()) {
log.debug("already enter " + e1.getTopiaId() +
- ", can reenter ? " + !contains);
+ ", can reenter ? " + !contains);
}
if (!contains) {
try {
@@ -815,7 +815,7 @@
Class<?> type,
int index, Object value, boolean enter) {
super.onVisited(e, name, collectionType, type, index, value,
- enter);
+ enter);
if (enter) {
removePath();
}
@@ -860,8 +860,8 @@
// }
if (log.isTraceEnabled()) {
log.trace("add to stack : " + e.getTopiaId() +
- ", new size : " + path.size() + ", path : " +
- accessorExpression.toString());
+ ", new size : " + path.size() + ", path : " +
+ accessorExpression.toString());
}
}
@@ -874,13 +874,13 @@
TopiaEntityRef.SEPARATOR);
if (index > -1) {
accessorExpression.delete(index,
- accessorExpression.length());
+ accessorExpression.length());
}
}
if (log.isTraceEnabled()) {
log.trace("remove from stack : " + e.getTopiaId() +
- ", new size : " + path.size() + ", path : " +
- accessorExpression.toString());
+ ", new size : " + path.size() + ", path : " +
+ accessorExpression.toString());
}
}
@@ -905,11 +905,11 @@
if (log.isDebugEnabled()) {
log.debug(expression + " (" + e.getTopiaId() + ") - " +
- list.size() + " , root:" + root.getTopiaId());
+ list.size() + " , root:" + root.getTopiaId());
}
if (log.isTraceEnabled()) {
log.trace(e.getTopiaId() + " : new size " + list.size() +
- ", path : " + expression);
+ ", path : " + expression);
}
}
};
@@ -995,7 +995,7 @@
}
}
boolean wasModified = referentielEntity.getTopiaVersion() >
- localeEntity.getTopiaVersion();
+ localeEntity.getTopiaVersion();
if (wasModified) {
result.get(DiffState.MODIFIED).add(refId);
@@ -1047,7 +1047,7 @@
}
if (klass.getSuperclass() != null &&
- TopiaEntity.class.isAssignableFrom(klass.getSuperclass())) {
+ TopiaEntity.class.isAssignableFrom(klass.getSuperclass())) {
getInterfaces(
(Class<? extends TopiaEntity>) klass.getSuperclass(),
klassInterfaces
Added: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/TopiaEntityIdsMap.java
===================================================================
--- trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/TopiaEntityIdsMap.java (rev 0)
+++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/util/TopiaEntityIdsMap.java 2010-08-14 13:53:11 UTC (rev 2097)
@@ -0,0 +1,30 @@
+package org.nuiton.topia.persistence.util;
+
+import org.nuiton.topia.persistence.TopiaEntity;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * A map of ids of entities grouped by their type.
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 2.4.3
+ */
+public class TopiaEntityIdsMap extends HashMap<Class<? extends TopiaEntity>, List<String>> {
+ private static final long serialVersionUID = 1L;
+
+ public void addIds(Class<? extends TopiaEntity> type, Iterable<String> ids) {
+ List<String> list = get(type);
+ if (list == null) {
+ list = new ArrayList<String>();
+ put(type, list);
+ }
+ for (String id : ids) {
+ if (!list.contains(id)) {
+ list.add(id);
+ }
+ }
+ }
+}
1
0
Author: tchemit
Date: 2010-08-11 16:47:08 +0200 (Wed, 11 Aug 2010)
New Revision: 2096
Url: http://nuiton.org/repositories/revision/topia/2096
Log:
Utilisation de mavenpom4redmine 2.2.3
Modified:
trunk/pom.xml
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2010-08-07 16:21:52 UTC (rev 2095)
+++ trunk/pom.xml 2010-08-11 14:47:08 UTC (rev 2096)
@@ -33,7 +33,7 @@
<parent>
<groupId>org.nuiton</groupId>
<artifactId>mavenpom4redmine</artifactId>
- <version>2.2.2.1</version>
+ <version>2.2.3</version>
</parent>
<artifactId>topia</artifactId>
1
0
r2095 - trunk/topia-persistence/src/main/java/org/nuiton/topia/generator
by tchemit@users.nuiton.org Aug. 7, 2010
by tchemit@users.nuiton.org Aug. 7, 2010
Aug. 7, 2010
Author: tchemit
Date: 2010-08-07 18:21:52 +0200 (Sat, 07 Aug 2010)
New Revision: 2095
Url: http://nuiton.org/repositories/revision/topia/2095
Log:
do NOT generate BinderHelper if no entity in model
Modified:
trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/BinderHelperTransformer.java
Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/BinderHelperTransformer.java
===================================================================
--- trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/BinderHelperTransformer.java 2010-08-07 14:14:28 UTC (rev 2094)
+++ trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/BinderHelperTransformer.java 2010-08-07 16:21:52 UTC (rev 2095)
@@ -25,6 +25,7 @@
package org.nuiton.topia.generator;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -58,9 +59,20 @@
private static final Log log =
LogFactory.getLog(BinderHelperTransformer.class);
+
@Override
public void transformFromModel(ObjectModel model) {
ObjectModelClass resultClass;
+
+ List<ObjectModelClass> classes = TopiaGeneratorUtil.getEntityClasses(model, true);
+
+ if (CollectionUtils.isEmpty(classes)) {
+
+ // no entity classes, so no generation
+ log.warn("No entity to generate, " + getClass().getName() + " is skipped");
+ return;
+ }
+
String packageName = getOutputProperties().getProperty(PROP_DEFAULT_PACKAGE);
String modelName = model.getName();
String binderHelperClazzName = modelName + "BinderHelper";
@@ -70,7 +82,6 @@
setSuperClass(resultClass, BinderProvider.class);
- List<ObjectModelClass> classes = TopiaGeneratorUtil.getEntityClasses(model, true);
addImport(resultClass, TopiaEntityBinder.class);
addImport(resultClass, TopiaEntityHelper.class);
1
0
r2094 - trunk/topia-persistence/src/main/java/org/nuiton/topia/generator
by tchemit@users.nuiton.org Aug. 7, 2010
by tchemit@users.nuiton.org Aug. 7, 2010
Aug. 7, 2010
Author: tchemit
Date: 2010-08-07 16:14:28 +0200 (Sat, 07 Aug 2010)
New Revision: 2094
Url: http://nuiton.org/repositories/revision/topia/2094
Log:
format code
Modified:
trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/BinderHelperTransformer.java
Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/BinderHelperTransformer.java
===================================================================
--- trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/BinderHelperTransformer.java 2010-08-07 14:14:18 UTC (rev 2093)
+++ trunk/topia-persistence/src/main/java/org/nuiton/topia/generator/BinderHelperTransformer.java 2010-08-07 14:14:28 UTC (rev 2094)
@@ -43,7 +43,6 @@
/*{generator option: parentheses = false}*/
-
/*{generator option: writeString = +}*/
/**
1
0
Author: tchemit
Date: 2010-08-07 16:14:18 +0200 (Sat, 07 Aug 2010)
New Revision: 2093
Url: http://nuiton.org/repositories/revision/topia/2093
Log:
Evolution #802: Use eugene 2.1.2
Modified:
trunk/pom.xml
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2010-07-26 14:35:54 UTC (rev 2092)
+++ trunk/pom.xml 2010-08-07 14:14:18 UTC (rev 2093)
@@ -230,7 +230,7 @@
<projectId>topia</projectId>
<!-- libs version -->
- <eugene.version>2.1.1</eugene.version>
+ <eugene.version>2.1.2-SNAPSHOT</eugene.version>
<lutinutil.version>1.4</lutinutil.version>
<processor.version>1.0.3</processor.version>
<i18n.version>1.2.2</i18n.version>
1
0