This is an automated email from the git hooks/post-receive script. New commit to branch feature/4309_synchro_referential in repository observe. See https://gitlab.nuiton.org/codelutin/observe.git commit f3db6ce45daba355e2a6eb7702fcf42891f4e24f Author: Tony CHEMIT <chemit@codelutin.com> Date: Tue Aug 16 16:58:36 2016 +0200 On conserve les ids existant uniquement de chaque côté pour réaliser des insert en cascade si nécessaire --- .../referential/ng/ReferentialReplaceUI.jaxx | 2 +- .../ng/ReferentialReplaceUIHandler.java | 12 +-- .../referential/ng/ReferentialSynchroModel.java | 61 ++++++++++++ .../referential/ng/action/ApplyAction.java | 9 +- .../ng/action/RegisterTasksActionSupport.java | 20 ++-- .../ng/task/ReferentialSynchronizeTaskSupport.java | 18 ++-- .../ng/tree/ReferentialSynchronizeTreeModel.java | 12 ++- .../ReferentialSynchronizeTreeModelsBuilder.java | 18 +++- .../diff/ReferentialSynchronizeDiff.java | 30 +++--- .../diff/ReferentialSynchronizeDiffs.java | 8 -- .../diff/ReferentialSynchronizeDiffsEngine.java | 4 +- .../ng/ReferentialSynchronizeRequest.java | 29 +++++- ...entialSynchronizeServiceProduceSqlsRequest.java | 54 ++++++++--- .../ReferentialSynchronizeSqlsRequestBuilder.java | 91 +++++++++++++++--- .../sql/InsertSqlStatementGenerator.java | 50 +++++++--- .../InsertSqlWithCascadeStatementGenerator.java | 105 +++++++++++++++++++++ .../sql/UpdateSqlStatementGenerator.java | 45 ++++++--- .../UpdateSqlWithCascadeStatementGenerator.java | 103 ++++++++++++++++++++ 18 files changed, 557 insertions(+), 114 deletions(-) diff --git a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/ReferentialReplaceUI.jaxx b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/ReferentialReplaceUI.jaxx index f371b86..705d681 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/ReferentialReplaceUI.jaxx +++ b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/ReferentialReplaceUI.jaxx @@ -9,7 +9,7 @@ </import> <ReferentialReference id='referenceToReplace' genericType="E" - initializer="getContextValue(ReferentialReference.class)"/> + initializer="getContextValue(ReferentialReference.class, ReferentialReplaceUIHandler.CONTEXT_NAME)"/> <ReferentialReference id='replaceReference' genericType="E" javaBean="null"/> <ReferentialReplaceUIHandler id='handler' genericType="E" constructorParams="this"/> diff --git a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/ReferentialReplaceUIHandler.java b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/ReferentialReplaceUIHandler.java index 8930cd3..764143c 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/ReferentialReplaceUIHandler.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/ReferentialReplaceUIHandler.java @@ -1,11 +1,8 @@ package fr.ird.observe.ui.admin.synchronize.referential.ng; -import com.google.common.collect.Lists; -import fr.ird.observe.ObserveSwingApplicationContext; import fr.ird.observe.application.swing.decoration.decorators.ReferentialReferenceDecorator; import fr.ird.observe.services.dto.referential.ReferentialDto; import fr.ird.observe.services.dto.referential.ReferentialReference; -import fr.ird.observe.services.dto.referential.ReferentialReferenceSet; import jaxx.runtime.swing.editor.bean.BeanComboBox; import java.awt.Dimension; @@ -19,6 +16,8 @@ import java.util.List; */ public class ReferentialReplaceUIHandler<R extends ReferentialDto> { + public static final String CONTEXT_NAME = "replaceUI"; + private final ReferentialReplaceUI<R> ui; protected PropertyChangeListener listenData; @@ -30,14 +29,11 @@ public class ReferentialReplaceUIHandler<R extends ReferentialDto> { public void init() { BeanComboBox<ReferentialReference<R>> beanComboBox = ui.getList(); - ReferentialReferenceSet<R> referenceSet = ui.getContextValue(ReferentialReferenceSet.class); beanComboBox.setI18nPrefix("observe.common."); beanComboBox.setMinimumSize(new Dimension(0, 24)); beanComboBox.setBeanType((Class) ReferentialReference.class); - List<ReferentialReference<R>> references = Lists.newArrayList(referenceSet.getReferences()); - ReferentialReference<R> reference = ui.getContextValue(ReferentialReference.class); - references.remove(reference); - ReferentialReferenceDecorator<R> decorator = ObserveSwingApplicationContext.get().getDecoratorService().getReferentialReferenceDecorator(referenceSet.getType()); + List<ReferentialReference<R>> references = ui.getContextValue(List.class,CONTEXT_NAME); + ReferentialReferenceDecorator<R> decorator = ui.getContextValue(ReferentialReferenceDecorator.class,CONTEXT_NAME); beanComboBox.init(decorator, references); } diff --git a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/ReferentialSynchroModel.java b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/ReferentialSynchroModel.java index d3030d5..00e3734 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/ReferentialSynchroModel.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/ReferentialSynchroModel.java @@ -1,6 +1,9 @@ package fr.ird.observe.ui.admin.synchronize.referential.ng; import fr.ird.observe.db.ObserveSwingDataSource; +import fr.ird.observe.services.dto.referential.ReferentialDto; +import fr.ird.observe.services.dto.referential.ReferentialReference; +import fr.ird.observe.services.dto.referential.ReferentialReferenceSet; import fr.ird.observe.services.service.actions.synchro.referential.ReferentialSynchronizeMode; import fr.ird.observe.services.service.actions.synchro.referential.diff.ReferentialSynchronizeDiffService; import fr.ird.observe.services.service.actions.synchro.referential.diff.ReferentialSynchronizeDiffsEngine; @@ -8,12 +11,18 @@ import fr.ird.observe.services.service.actions.synchro.referential.ng.Referentia import fr.ird.observe.services.service.actions.synchro.referential.ng.ReferentialSynchronizeServiceEngine; import fr.ird.observe.ui.admin.AdminActionModel; import fr.ird.observe.ui.admin.AdminStep; +import fr.ird.observe.ui.admin.synchronize.referential.ng.task.AddReferentialSynchronizeTask; +import fr.ird.observe.ui.admin.synchronize.referential.ng.task.DeleteReferentialSynchronizeTask; +import fr.ird.observe.ui.admin.synchronize.referential.ng.task.DesactivateReferentialSynchronizeTask; +import fr.ird.observe.ui.admin.synchronize.referential.ng.task.ReferentialSynchronizeTaskSupport; import fr.ird.observe.ui.admin.synchronize.referential.ng.tree.ReferentialSynchronizeTreeModel; import fr.ird.observe.ui.admin.synchronize.referential.ng.tree.ReferentialSynchronizeTreeModelsBuilder; import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; /** @@ -121,6 +130,58 @@ public class ReferentialSynchroModel extends AdminActionModel { return tasks; } + public <D extends ReferentialDto> List<ReferentialReference<D>> getPossibleReplaceUniverse(boolean left, Class<D> type, ReferentialReference<D> referenceToReplace) { + + ReferentialReferenceSet<D> referencesSet; + if (left) { + referencesSet = engine.getLeftEnabledReferentialReferenceSet(type); + } else { + referencesSet = engine.getRightEnabledReferentialReferenceSet(type); + } + + List<ReferentialReference<D>> references = new ArrayList<>(referencesSet.getReferences()); + references.remove(referenceToReplace); + + for (ReferentialSynchronizeTaskSupport task : tasks) { + + if (!type.equals(task.getType())) { + continue; + } + if (left == task.isLeft()) { + + if (task instanceof DeleteReferentialSynchronizeTask) { + + // on enlève ce référentiel car il a été supprimé de ce côté + ReferentialReference<D> referential = task.getReferential(); + references.remove(referential); + } + + if (task instanceof DesactivateReferentialSynchronizeTask) { + + // on enlève ce référentiel car il a été désactivé de ce côté + ReferentialReference<D> referential = task.getReferential(); + references.remove(referential); + } + + continue; + } + + if (type.equals(task.getType())) { + + if (task instanceof AddReferentialSynchronizeTask) { + + // on ajoute ce référentiel car il a été ajouté depuis l'autre côté + ReferentialReference<D> referential = task.getReferential(); + references.add(referential); + } + + } + + } + + return references; + } + public ReferentialSynchronizeDiffsEngine getEngine() { return engine; } diff --git a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/action/ApplyAction.java b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/action/ApplyAction.java index e612058..6521a3f 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/action/ApplyAction.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/action/ApplyAction.java @@ -1,5 +1,6 @@ package fr.ird.observe.ui.admin.synchronize.referential.ng.action; +import fr.ird.observe.services.dto.referential.ReferentialDto; import fr.ird.observe.services.service.actions.synchro.referential.ReferentialSynchronizeMode; import fr.ird.observe.services.service.actions.synchro.referential.ng.ReferentialSynchronizeServiceEngine; import fr.ird.observe.services.service.actions.synchro.referential.ng.ReferentialSynchronizeServiceProduceSqlsRequest; @@ -14,6 +15,7 @@ import fr.ird.observe.ui.admin.synchronize.referential.ng.task.ReferentialSynchr import jaxx.runtime.swing.wizard.ext.WizardState; import java.awt.event.ActionEvent; +import java.util.Set; import static org.nuiton.i18n.I18n.t; @@ -51,7 +53,12 @@ public class ApplyAction extends AbstractObserveAction { boolean leftIsWrite = synchronizeMode.isLeftWrite(); boolean rightIsWrite = synchronizeMode.isRightWrite(); - ReferentialSynchronizeServiceProduceSqlsRequest.Builder builder = ReferentialSynchronizeServiceProduceSqlsRequest.builder(); + Set<Class<? extends ReferentialDto>> referentialTypesInShell = stepModel.getLeftSource().newDataSourceService().getReferentialTypesInShell(); + + ReferentialSynchronizeServiceProduceSqlsRequest.Builder builder = + ReferentialSynchronizeServiceProduceSqlsRequest.builder(stepModel.getLeftTreeModel().getIdsOnlyExistingInThisSide(), + stepModel.getRightTreeModel().getIdsOnlyExistingInThisSide(), + referentialTypesInShell); ReferentialSynchronizeTaskListModel tasks = stepModel.getTasks(); diff --git a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/action/RegisterTasksActionSupport.java b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/action/RegisterTasksActionSupport.java index 9ea8920..d5ceb86 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/action/RegisterTasksActionSupport.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/action/RegisterTasksActionSupport.java @@ -1,12 +1,14 @@ package fr.ird.observe.ui.admin.synchronize.referential.ng.action; +import fr.ird.observe.ObserveSwingApplicationContext; import fr.ird.observe.application.swing.decoration.DecoratorService; +import fr.ird.observe.application.swing.decoration.decorators.ReferentialReferenceDecorator; import fr.ird.observe.services.dto.referential.ReferentialDto; import fr.ird.observe.services.dto.referential.ReferentialReference; -import fr.ird.observe.services.dto.referential.ReferentialReferenceSet; import fr.ird.observe.ui.UIHelper; import fr.ird.observe.ui.actions.AbstractObserveAction; import fr.ird.observe.ui.admin.synchronize.referential.ng.ReferentialReplaceUI; +import fr.ird.observe.ui.admin.synchronize.referential.ng.ReferentialReplaceUIHandler; import fr.ird.observe.ui.admin.synchronize.referential.ng.ReferentialSynchroUI; import fr.ird.observe.ui.admin.synchronize.referential.ng.ReferentialSynchronizeResources; import fr.ird.observe.ui.admin.synchronize.referential.ng.task.ReferentialSynchronizeTaskSupport; @@ -24,6 +26,7 @@ import javax.swing.JOptionPane; import java.awt.event.ActionEvent; import java.util.Collection; import java.util.LinkedList; +import java.util.List; import java.util.function.Predicate; import static org.nuiton.i18n.I18n.t; @@ -107,17 +110,16 @@ public abstract class RegisterTasksActionSupport extends AbstractObserveAction { if (needReplace) { - ReferentialReferenceSet<R> references; Class<R> type = reference.getType(); - if (left) { - references = ui.getStepModel().getEngine().getLeftEnabledReferentialReferenceSet(type); - } else { - references = ui.getStepModel().getEngine().getRightEnabledReferentialReferenceSet(type); - } + + List<ReferentialReference<R>> references = ui.getStepModel().getPossibleReplaceUniverse(left, type, reference); + + ReferentialReferenceDecorator<R> decorator = ObserveSwingApplicationContext.get().getDecoratorService().getReferentialReferenceDecorator(type); ReferentialReplaceUI<R> replaceUI = new ReferentialReplaceUI<>(new JAXXInitialContext() - .add(reference) - .add(references) + .add(ReferentialReplaceUIHandler.CONTEXT_NAME, reference) + .add(ReferentialReplaceUIHandler.CONTEXT_NAME, references) + .add(ReferentialReplaceUIHandler.CONTEXT_NAME, decorator) .add(this)); typeStr = t(DecoratorService.getEntityLabel(ObserveTreeHelper.TREE_NODE_PREFIX, type)); diff --git a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/task/ReferentialSynchronizeTaskSupport.java b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/task/ReferentialSynchronizeTaskSupport.java index 2bcd7b5..2076bc2 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/task/ReferentialSynchronizeTaskSupport.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/task/ReferentialSynchronizeTaskSupport.java @@ -23,21 +23,21 @@ public abstract class ReferentialSynchronizeTaskSupport<R extends ReferentialDto protected final String dataStr; protected final String typeStr; protected final String i18nKey; - private final ReferentialReference<R> data; + private final ReferentialReference<R> referential; private final Icon icon; private final boolean left; private final ReferentialSynchronizeTaskType taskType; protected ReferentialSynchronizeTaskSupport(ReferentialSynchronizeResources resource, boolean left, - ReferentialReference<R> data) { + ReferentialReference<R> referential) { this.left = left; - this.data = data; + this.referential = referential; this.icon = resource.getIcon(left); this.i18nKey = resource.getTaskLabel(left); this.taskType = resource.getTaskType(); - this.dataStr = ObserveSwingApplicationContext.get().getDecoratorService().getReferentialReferenceDecorator(data.getType()).toString(data); - this.typeStr = t(DecoratorService.getEntityLabel(data.getType())); + this.dataStr = ObserveSwingApplicationContext.get().getDecoratorService().getReferentialReferenceDecorator(referential.getType()).toString(referential); + this.typeStr = t(DecoratorService.getEntityLabel(referential.getType())); } public boolean isLeft() { @@ -57,11 +57,15 @@ public abstract class ReferentialSynchronizeTaskSupport<R extends ReferentialDto } public Class<R> getType() { - return data.getType(); + return referential.getType(); } public String getId() { - return data.getId(); + return referential.getId(); + } + + public ReferentialReference<R> getReferential() { + return referential; } public Icon getIcon() { diff --git a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/tree/ReferentialSynchronizeTreeModel.java b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/tree/ReferentialSynchronizeTreeModel.java index c102002..2363892 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/tree/ReferentialSynchronizeTreeModel.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/tree/ReferentialSynchronizeTreeModel.java @@ -1,6 +1,8 @@ package fr.ird.observe.ui.admin.synchronize.referential.ng.tree; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSetMultimap; +import fr.ird.observe.services.dto.referential.ReferentialDto; import fr.ird.observe.ui.admin.synchronize.referential.ng.tree.node.ReferenceReferentialSynchroNodeSupport; import fr.ird.observe.ui.admin.synchronize.referential.ng.tree.node.ReferentialSynchroNodeSupport; import fr.ird.observe.ui.admin.synchronize.referential.ng.tree.node.RootReferentialSynchroNode; @@ -37,6 +39,7 @@ public class ReferentialSynchronizeTreeModel implements TreeSelectionModel, Tree private final DefaultTreeSelectionModel treeSelectionModel; private final DefaultTreeModel treeModel; + private final ImmutableSetMultimap<Class<? extends ReferentialDto>, String> idsOnlyExistOnThisSide; private boolean canAdd; private boolean canUpdate; @@ -44,12 +47,19 @@ public class ReferentialSynchronizeTreeModel implements TreeSelectionModel, Tree private boolean canRevert; private boolean valueIsAdjusting; - public ReferentialSynchronizeTreeModel(RootReferentialSynchroNode root) { + public ReferentialSynchronizeTreeModel(RootReferentialSynchroNode root, + ImmutableSetMultimap<Class<? extends ReferentialDto>, String> idsOnlyExistOnThisSide) { this.treeModel = new DefaultTreeModel(root); + this.idsOnlyExistOnThisSide = idsOnlyExistOnThisSide; this.treeSelectionModel = new DefaultTreeSelectionModel(); setSelectionMode(DISCONTIGUOUS_TREE_SELECTION); } + public ImmutableSetMultimap<Class<? extends ReferentialDto>, String> getIdsOnlyExistingInThisSide() { + return idsOnlyExistOnThisSide; + } + + public synchronized void updateSelectedActions() { canAdd = canUpdate = canDelete = canRevert = false; diff --git a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/tree/ReferentialSynchronizeTreeModelsBuilder.java b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/tree/ReferentialSynchronizeTreeModelsBuilder.java index 3af7e05..8aec5bd 100644 --- a/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/tree/ReferentialSynchronizeTreeModelsBuilder.java +++ b/observe-application-swing/src/main/java/fr/ird/observe/ui/admin/synchronize/referential/ng/tree/ReferentialSynchronizeTreeModelsBuilder.java @@ -1,6 +1,7 @@ package fr.ird.observe.ui.admin.synchronize.referential.ng.tree; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSetMultimap; import fr.ird.observe.services.dto.referential.ReferentialDto; import fr.ird.observe.services.dto.referential.ReferentialReference; import fr.ird.observe.services.dto.referential.ReferentialReferenceSet; @@ -29,6 +30,8 @@ public class ReferentialSynchronizeTreeModelsBuilder { private final ReferentialSynchronizeDiffsEngine engine; private final RootReferentialSynchroNode leftRootNode; private final RootReferentialSynchroNode rightRootNode; + private final ImmutableSetMultimap.Builder<Class<? extends ReferentialDto>, String> leftIdsBuilder = ImmutableSetMultimap.builder(); + private final ImmutableSetMultimap.Builder<Class<? extends ReferentialDto>, String> rightIdsBuilder = ImmutableSetMultimap.builder(); public ReferentialSynchronizeTreeModelsBuilder(ReferentialSynchronizeMode synchronizeMode, ReferentialSynchronizeDiffsEngine engine) { Objects.nonNull(synchronizeMode); @@ -50,8 +53,8 @@ public class ReferentialSynchronizeTreeModelsBuilder { boolean rightCanWrite = rightRootNode.isCanWrite(); boolean leftCanWrite = leftRootNode.isCanWrite(); - CreateNode leftAddNode = new CreateAddNode(rightCanWrite, leftCanWrite, false); - CreateNode rightAddNode = new CreateAddNode(leftCanWrite, rightCanWrite, false); + CreateAddNode leftAddNode = new CreateAddNode(rightCanWrite, leftCanWrite, false); + CreateAddNode rightAddNode = new CreateAddNode(leftCanWrite, rightCanWrite, false); CreateNode leftUpdateNode = new CreateUpdateNode(rightCanWrite, false, leftCanWrite); CreateNode rightUpdateNode = new CreateUpdateNode(leftCanWrite, false, rightCanWrite); @@ -88,8 +91,8 @@ public class ReferentialSynchronizeTreeModelsBuilder { } - ReferentialSynchronizeTreeModel leftTreeModel = new ReferentialSynchronizeTreeModel(leftRootNode); - ReferentialSynchronizeTreeModel rightTreeModel = new ReferentialSynchronizeTreeModel(rightRootNode); + ReferentialSynchronizeTreeModel leftTreeModel = new ReferentialSynchronizeTreeModel(leftRootNode, leftAddNode.getIds()); + ReferentialSynchronizeTreeModel rightTreeModel = new ReferentialSynchronizeTreeModel(rightRootNode, rightAddNode.getIds()); return Pair.of(leftTreeModel, rightTreeModel); } @@ -135,6 +138,8 @@ public class ReferentialSynchronizeTreeModelsBuilder { private static class CreateAddNode extends CreateNode { + private final ImmutableSetMultimap.Builder<Class<? extends ReferentialDto>, String> idsBuilder = ImmutableSetMultimap.builder(); + protected CreateAddNode(boolean canCopy, boolean canDelete, boolean canRevert) { super(canCopy, canDelete, canRevert); } @@ -143,6 +148,11 @@ public class ReferentialSynchronizeTreeModelsBuilder { public void createNode(TypeReferentialSynchroNode typeNode, ReferentialReference<?> reference) { ReferenceReferentialSynchroNodeSupport node = new AddedReferenceReferentialSynchroNode(reference, canCopy, false, canDelete, canRevert); typeNode.add(node); + idsBuilder.put(reference.getType(), reference.getId()); + } + + public ImmutableSetMultimap<Class<? extends ReferentialDto>, String> getIds() { + return idsBuilder.build(); } } diff --git a/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/diff/ReferentialSynchronizeDiff.java b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/diff/ReferentialSynchronizeDiff.java index 6faf9f0..b1d3db0 100644 --- a/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/diff/ReferentialSynchronizeDiff.java +++ b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/diff/ReferentialSynchronizeDiff.java @@ -22,11 +22,13 @@ public class ReferentialSynchronizeDiff { private final ImmutableSetMultimap.Builder<Class<? extends ReferentialDto>, ReferentialSynchronizeDiffState> addedReferentialsBuilder; private final ImmutableSetMultimap.Builder<Class<? extends ReferentialDto>, ReferentialSynchronizeDiffState> updatedReferentialsBuilder; + private final ImmutableSetMultimap.Builder<Class<? extends ReferentialDto>, String> existingIdsBuilder; public Builder() { addedReferentialsBuilder = ImmutableSetMultimap.builder(); updatedReferentialsBuilder = ImmutableSetMultimap.builder(); + existingIdsBuilder = ImmutableSetMultimap.builder(); } <R extends ReferentialDto> Builder addAddedReferential(Class<R> referentialName, ReferentialSynchronizeDiffState referentialDto) { @@ -39,10 +41,14 @@ public class ReferentialSynchronizeDiff { return this; } - public ReferentialSynchronizeDiff build() { - return new ReferentialSynchronizeDiff(addedReferentialsBuilder.build(), updatedReferentialsBuilder.build()); + public <R extends ReferentialDto> Builder addExistingId(Class<R> referentialName, String id) { + existingIdsBuilder.put(referentialName, id); + return this; } + public ReferentialSynchronizeDiff build() { + return new ReferentialSynchronizeDiff(addedReferentialsBuilder.build(), updatedReferentialsBuilder.build(), existingIdsBuilder.build()); + } } /** @@ -59,22 +65,12 @@ public class ReferentialSynchronizeDiff { */ private final ImmutableSetMultimap<Class<? extends ReferentialDto>, ReferentialSynchronizeDiffState> updatedReferentials; - public boolean isEmpty() { - return referentialNames.isEmpty(); - } - - public boolean isNotEmpty() { - return !isEmpty(); - } + private final ImmutableSetMultimap<Class<? extends ReferentialDto>, String> existingIds; public ImmutableSet<Class<? extends ReferentialDto>> getReferentialNames() { return referentialNames; } - public <R extends ReferentialDto> boolean isReferentialUsed(Class<R> referentialName) { - return referentialNames.contains(referentialName); - } - public <R extends ReferentialDto> Optional<ImmutableSet<ReferentialSynchronizeDiffState>> getAddedReferentials(Class<R> referentialName) { return Optional.ofNullable(addedReferentials.get(referentialName)); } @@ -83,10 +79,16 @@ public class ReferentialSynchronizeDiff { return Optional.ofNullable(updatedReferentials.get(referentialName)); } + public ImmutableSetMultimap<Class<? extends ReferentialDto>, String> getExistingIds() { + return existingIds; + } + private ReferentialSynchronizeDiff(ImmutableSetMultimap<Class<? extends ReferentialDto>, ReferentialSynchronizeDiffState> addedReferentials, - ImmutableSetMultimap<Class<? extends ReferentialDto>, ReferentialSynchronizeDiffState> updatedReferentials) { + ImmutableSetMultimap<Class<? extends ReferentialDto>, ReferentialSynchronizeDiffState> updatedReferentials, + ImmutableSetMultimap<Class<? extends ReferentialDto>, String> existingIds) { this.addedReferentials = addedReferentials; this.updatedReferentials = updatedReferentials; + this.existingIds = existingIds; this.referentialNames = ImmutableSet.<Class<? extends ReferentialDto>>builder() .addAll(addedReferentials.keySet()) .addAll(updatedReferentials.keySet()) diff --git a/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/diff/ReferentialSynchronizeDiffs.java b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/diff/ReferentialSynchronizeDiffs.java index ec1f0f1..9d863f6 100644 --- a/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/diff/ReferentialSynchronizeDiffs.java +++ b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/diff/ReferentialSynchronizeDiffs.java @@ -79,14 +79,6 @@ public class ReferentialSynchronizeDiffs { return referentialNames; } - public <R extends ReferentialDto> boolean isLeftReferentialUsed(Class<R> referentialName) { - return leftDiff.isReferentialUsed(referentialName); - } - - public <R extends ReferentialDto> boolean isRightReferentialUsed(Class<R> referentialName) { - return rightDiff.isReferentialUsed(referentialName); - } - public <R extends ReferentialDto> Optional<ImmutableSet<ReferentialSynchronizeDiffState>> getLeftAddedReferentials(Class<R> referentialName) { return leftDiff.getAddedReferentials(referentialName); } diff --git a/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/diff/ReferentialSynchronizeDiffsEngine.java b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/diff/ReferentialSynchronizeDiffsEngine.java index 40dbcfc..bbfc4d3 100644 --- a/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/diff/ReferentialSynchronizeDiffsEngine.java +++ b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/diff/ReferentialSynchronizeDiffsEngine.java @@ -19,7 +19,8 @@ public class ReferentialSynchronizeDiffsEngine { private final ReferentialSynchronizeDiffService leftDiffService; private final ReferentialSynchronizeDiffService rightDiffService; - public ReferentialSynchronizeDiffsEngine(ReferentialSynchronizeDiffService leftDiffService, ReferentialSynchronizeDiffService rightDiffService) { + public ReferentialSynchronizeDiffsEngine(ReferentialSynchronizeDiffService leftDiffService, + ReferentialSynchronizeDiffService rightDiffService) { this.leftDiffService = leftDiffService; this.rightDiffService = rightDiffService; } @@ -63,7 +64,6 @@ public class ReferentialSynchronizeDiffsEngine { private <R extends ReferentialDto> void build0(Class<R> referentialName, ReferentialSynchronizeDiffs.Builder result, ReferentialDataSourceState<R> leftStates, ReferentialDataSourceState<R> rightStates) { - ImmutableMap<String, ReferentialSynchronizeDiffState> leftLatestReferentialDiffState = leftStates.getReferentialStatesById(); ImmutableMap<String, ReferentialSynchronizeDiffState> rightLatestReferentialDiffState = rightStates.getReferentialStatesById(); diff --git a/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/ng/ReferentialSynchronizeRequest.java b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/ng/ReferentialSynchronizeRequest.java index c8ea1aa..240d2cb 100644 --- a/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/ng/ReferentialSynchronizeRequest.java +++ b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/ng/ReferentialSynchronizeRequest.java @@ -1,7 +1,10 @@ package fr.ird.observe.services.service.actions.synchro.referential.ng; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSetMultimap; +import com.google.common.collect.Multimap; import fr.ird.observe.services.dto.referential.ReferentialDto; import fr.ird.observe.services.service.actions.synchro.referential.ng.task.ReferentialSynchronizeTask; import fr.ird.observe.services.service.actions.synchro.referential.ng.task.ReferentialSynchronizeTaskType; @@ -24,21 +27,28 @@ public class ReferentialSynchronizeRequest { private final ImmutableMultimap<ReferentialSynchronizeTaskType, ReferentialSynchronizeTask<?>> tasks; private final ImmutableSet<Class<? extends ReferentialDto>> types; + private final Multimap<Class<? extends ReferentialDto>, String> idsOnlyExistingOnThisSide; private ReferentialSynchronizeRequest(ImmutableMultimap<ReferentialSynchronizeTaskType, ReferentialSynchronizeTask<?>> tasks, - ImmutableSet<Class<? extends ReferentialDto>> types) { + ImmutableSet<Class<? extends ReferentialDto>> types, + Multimap<Class<? extends ReferentialDto>, String> idsOnlyExistingOnThisSide) { this.tasks = tasks; this.types = types; + this.idsOnlyExistingOnThisSide = idsOnlyExistingOnThisSide; } - public static Builder builder() { - return new Builder(); + public static Builder builder(ImmutableSetMultimap<Class<? extends ReferentialDto>, String> idsOnlyExistingOnThisSide) { + return new Builder(idsOnlyExistingOnThisSide); } public boolean isNotEmpty() { return !tasks.isEmpty(); } + public Multimap<Class<? extends ReferentialDto>, String> getIdsOnlyExistingOnThisSide() { + return idsOnlyExistingOnThisSide; + } + public ImmutableMultimap<ReferentialSynchronizeTaskType, ReferentialSynchronizeTask<?>> getTasks() { return tasks; } @@ -76,9 +86,14 @@ public class ReferentialSynchronizeRequest { private final ImmutableMultimap.Builder<ReferentialSynchronizeTaskType, ReferentialSynchronizeTask<?>> tasksBuilder = ImmutableMultimap.builder(); private final ImmutableSet.Builder<Class<? extends ReferentialDto>> typesBuilder = ImmutableSet.builder(); + private final Multimap<Class<? extends ReferentialDto>, String> idsOnlyExistingOnThisSide; + + public Builder(ImmutableSetMultimap<Class<? extends ReferentialDto>, String> idsOnlyExistingOnThisSide) { + this.idsOnlyExistingOnThisSide = ArrayListMultimap.create(idsOnlyExistingOnThisSide); + } public ReferentialSynchronizeRequest build() { - return new ReferentialSynchronizeRequest(tasksBuilder.build(), typesBuilder.build()); + return new ReferentialSynchronizeRequest(tasksBuilder.build(), typesBuilder.build(), idsOnlyExistingOnThisSide); } public <R extends ReferentialDto> Builder addTask(ReferentialSynchronizeTaskType taskType, Class<R> type, String referentialId, String replaceReferentialId) { @@ -90,5 +105,11 @@ public class ReferentialSynchronizeRequest { return this; } + + public <R extends ReferentialDto> void removeIdOnlyExistOnThisSide(Class<R> type, String id) { + idsOnlyExistingOnThisSide.remove(type, id); + } + } + } diff --git a/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/ng/ReferentialSynchronizeServiceProduceSqlsRequest.java b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/ng/ReferentialSynchronizeServiceProduceSqlsRequest.java index 92e7ef8..9362c29 100644 --- a/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/ng/ReferentialSynchronizeServiceProduceSqlsRequest.java +++ b/observe-services-api/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/ng/ReferentialSynchronizeServiceProduceSqlsRequest.java @@ -1,8 +1,11 @@ package fr.ird.observe.services.service.actions.synchro.referential.ng; +import com.google.common.collect.ImmutableSetMultimap; import fr.ird.observe.services.dto.referential.ReferentialDto; import fr.ird.observe.services.service.actions.synchro.referential.ng.task.ReferentialSynchronizeTaskType; +import java.util.Set; + /** * Created on 15/08/16. * @@ -10,16 +13,22 @@ import fr.ird.observe.services.service.actions.synchro.referential.ng.task.Refer */ public class ReferentialSynchronizeServiceProduceSqlsRequest { - protected final ReferentialSynchronizeRequest leftRequest; - protected final ReferentialSynchronizeRequest rightRequest; + private final ReferentialSynchronizeRequest leftRequest; + private final ReferentialSynchronizeRequest rightRequest; + private final Set<Class<? extends ReferentialDto>> referentialTypesInShell; - private ReferentialSynchronizeServiceProduceSqlsRequest(ReferentialSynchronizeRequest leftRequest, ReferentialSynchronizeRequest rightRequest) { + private ReferentialSynchronizeServiceProduceSqlsRequest(ReferentialSynchronizeRequest leftRequest, + ReferentialSynchronizeRequest rightRequest, + Set<Class<? extends ReferentialDto>> referentialTypesInShell) { this.leftRequest = leftRequest; this.rightRequest = rightRequest; + this.referentialTypesInShell = referentialTypesInShell; } - public static Builder builder() { - return new Builder(); + public static Builder builder(ImmutableSetMultimap<Class<? extends ReferentialDto>, String> leftExistingIds, + ImmutableSetMultimap<Class<? extends ReferentialDto>, String> rightExistingIds, + Set<Class<? extends ReferentialDto>> referentialTypesInShell) { + return new Builder(leftExistingIds, rightExistingIds, referentialTypesInShell); } public ReferentialSynchronizeRequest getLeftRequest() { @@ -30,20 +39,29 @@ public class ReferentialSynchronizeServiceProduceSqlsRequest { return rightRequest; } + public Set<Class<? extends ReferentialDto>> getReferentialTypesInShell() { + return referentialTypesInShell; + } + public static class Builder { private final ReferentialSynchronizeRequest.Builder leftRequestBuilder; private final ReferentialSynchronizeRequest.Builder rightRequestBuilder; - - private Builder() { - leftRequestBuilder = ReferentialSynchronizeRequest.builder(); - rightRequestBuilder = ReferentialSynchronizeRequest.builder(); + private final Set<Class<? extends ReferentialDto>> referentialTypesInShell; + + private Builder(ImmutableSetMultimap<Class<? extends ReferentialDto>, String> leftIdsOnlyExistingOnThisSide, + ImmutableSetMultimap<Class<? extends ReferentialDto>, String> rightIdsOnlyExistingOnThisSide, + Set<Class<? extends ReferentialDto>> referentialTypesInShell) { + leftRequestBuilder = ReferentialSynchronizeRequest.builder(leftIdsOnlyExistingOnThisSide); + rightRequestBuilder = ReferentialSynchronizeRequest.builder(rightIdsOnlyExistingOnThisSide); + this.referentialTypesInShell = referentialTypesInShell; } public ReferentialSynchronizeServiceProduceSqlsRequest build() { return new ReferentialSynchronizeServiceProduceSqlsRequest(leftRequestBuilder.build(), - rightRequestBuilder.build()); + rightRequestBuilder.build(), + referentialTypesInShell); } @@ -52,7 +70,21 @@ public class ReferentialSynchronizeServiceProduceSqlsRequest { Class<R> type, String id, String replaceId) { - getRequestBuilder(left).addTask(taskType, type, id, replaceId); + + ReferentialSynchronizeRequest.Builder requestBuilder = getRequestBuilder(left); + requestBuilder.addTask(taskType, type, id, replaceId); + + if (ReferentialSynchronizeTaskType.ADD == taskType) { + + // le referentiel est à ajouter, il sera donc disponible dans les deux sources + requestBuilder.removeIdOnlyExistOnThisSide(type, id); + + } else if (ReferentialSynchronizeTaskType.DELETE == taskType) { + + // le référentiel est supprimer, il ne sera donc plus disponible du tout + getRequestBuilder(!left).removeIdOnlyExistOnThisSide(type, id); + + } return this; } diff --git a/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/ng/ReferentialSynchronizeSqlsRequestBuilder.java b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/ng/ReferentialSynchronizeSqlsRequestBuilder.java index 1de4f5a..e344d99 100644 --- a/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/ng/ReferentialSynchronizeSqlsRequestBuilder.java +++ b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/ng/ReferentialSynchronizeSqlsRequestBuilder.java @@ -10,8 +10,10 @@ import fr.ird.observe.services.service.actions.synchro.referential.ng.task.Refer import fr.ird.observe.services.service.actions.synchro.referential.sql.DeleteSqlStatementGenerator; import fr.ird.observe.services.service.actions.synchro.referential.sql.DesactivateSqlStatementGenerator; import fr.ird.observe.services.service.actions.synchro.referential.sql.InsertSqlStatementGenerator; +import fr.ird.observe.services.service.actions.synchro.referential.sql.InsertSqlWithCascadeStatementGenerator; import fr.ird.observe.services.service.actions.synchro.referential.sql.ReplaceSqlStatementGenerator; import fr.ird.observe.services.service.actions.synchro.referential.sql.UpdateSqlStatementGenerator; +import fr.ird.observe.services.service.actions.synchro.referential.sql.UpdateSqlWithCascadeStatementGenerator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuiton.topia.persistence.metadata.TopiaMetadataEntity; @@ -107,16 +109,39 @@ public class ReferentialSynchronizeSqlsRequestBuilder { ReferentialBinderSupport<E, R> binder = binderEngine.getReferentialBinder(type); Class<E> entityType = binderEngine.getReferentialEntityType(type); TopiaMetadataEntity metadata = metadataModel.getEntity(referentialName); - InsertSqlStatementGenerator<R> insertGenerator = new InsertSqlStatementGenerator<>(metadata, type); List<E> insertEntities = loadEntities(entityType, tasks); - for (E entity : insertEntities) { - R referential = binder.toDto(referentialLocale, entity); - String sql = insertGenerator.generateSql(referential); + if (metadata.withShell()) { - if (log.isInfoEnabled()) { - log.info("Insert referential: " + type.getName() + " / " + referential.getId() + " -- " + sql); + InsertSqlWithCascadeStatementGenerator<R> insertGenerator = new InsertSqlWithCascadeStatementGenerator<R>(metadata, type, request.getIdsOnlyExistingOnThisSide()) { + + @Override + protected <D extends ReferentialDto> String insertMissingReferential(Class<D> referentialType, String id) { + return addExtraInsertStatement(referentialType, id); + } + }; + + for (E entity : insertEntities) { + R referential = binder.toDto(referentialLocale, entity); + String sql = insertGenerator.generateSql(referential); + + if (log.isInfoEnabled()) { + log.info("Insert referential: " + type.getName() + " / " + referential.getId() + " -- " + sql); + } + resultBuilder.addInsertStatement(sql); + } + + } else { + + InsertSqlStatementGenerator<R> insertGenerator = new InsertSqlStatementGenerator<>(metadata, type); + for (E entity : insertEntities) { + R referential = binder.toDto(referentialLocale, entity); + String sql = insertGenerator.generateSql(referential); + + if (log.isInfoEnabled()) { + log.info("Insert referential: " + type.getName() + " / " + referential.getId() + " -- " + sql); + } + resultBuilder.addInsertStatement(sql); } - resultBuilder.addInsertStatement(sql); } } @@ -126,19 +151,41 @@ public class ReferentialSynchronizeSqlsRequestBuilder { ReferentialBinderSupport<E, R> binder = binderEngine.getReferentialBinder(type); TopiaMetadataEntity metadata = metadataModel.getEntity(referentialName); Class<E> entityType = binderEngine.getReferentialEntityType(type); - - UpdateSqlStatementGenerator<R> updateGenerator = new UpdateSqlStatementGenerator<>(metadata, type); List<E> updateEntities = loadEntities(entityType, tasks); - for (E entity : updateEntities) { - R referential = binder.toDto(referentialLocale, entity); - String sql = updateGenerator.generateSql(referential); - if (log.isInfoEnabled()) { - log.info("Update referential: " + type.getName() + " / " + referential.getId() + " -- " + sql); + if (metadata.withShell()) { + + UpdateSqlWithCascadeStatementGenerator<R> updateGenerator = new UpdateSqlWithCascadeStatementGenerator<R>(metadata, type, request.getIdsOnlyExistingOnThisSide()) { + @Override + protected <D extends ReferentialDto> String insertMissingReferential(Class<D> referentialType, String id) { + return addExtraInsertStatement(referentialType, id); + } + }; + for (E entity : updateEntities) { + R referential = binder.toDto(referentialLocale, entity); + String sql = updateGenerator.generateSql(referential); + + if (log.isInfoEnabled()) { + log.info("Update referential: " + type.getName() + " / " + referential.getId() + " -- " + sql); + } + resultBuilder.addUpdateStatement(sql); + } + + } else { + + UpdateSqlStatementGenerator<R> updateGenerator = new UpdateSqlStatementGenerator<>(metadata, type); + for (E entity : updateEntities) { + R referential = binder.toDto(referentialLocale, entity); + String sql = updateGenerator.generateSql(referential); + + if (log.isInfoEnabled()) { + log.info("Update referential: " + type.getName() + " / " + referential.getId() + " -- " + sql); + } + resultBuilder.addUpdateStatement(sql); } - resultBuilder.addUpdateStatement(sql); } + } private <R extends ReferentialDto, E extends ObserveReferentialEntity> void onRevert(String referentialName, Class<R> type, Set<ReferentialSynchronizeTask<R>> tasks) { @@ -224,6 +271,20 @@ public class ReferentialSynchronizeSqlsRequestBuilder { } + private <R extends ReferentialDto, E extends ObserveReferentialEntity> String addExtraInsertStatement(Class<R> referentialType, String id) { + + Class<E> entityType = binderEngine.getReferentialEntityType(referentialType); + String referentialName = ObserveEntityEnum.valueOf(entityType).name(); + TopiaMetadataEntity metadata = metadataModel.getEntity(referentialName); + + InsertSqlStatementGenerator<R> insertGenerator = new InsertSqlStatementGenerator<>(metadata, referentialType); + R referential = service.loadEntityToReferentialDto(referentialType, id); + + String sql = insertGenerator.generateSql(referential); + return sql; + + } + private <R extends ReferentialDto, E extends ObserveReferentialEntity> List<E> loadEntities(Class<E> entityType, Set<ReferentialSynchronizeTask<R>> tasks) { Set<String> ids = tasks.stream().map(ReferentialSynchronizeTask::getReferentialId).collect(Collectors.toSet()); diff --git a/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/sql/InsertSqlStatementGenerator.java b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/sql/InsertSqlStatementGenerator.java index 74e53cd..fd25ccd 100644 --- a/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/sql/InsertSqlStatementGenerator.java +++ b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/sql/InsertSqlStatementGenerator.java @@ -22,6 +22,8 @@ package fr.ird.observe.services.service.actions.synchro.referential.sql; * #L% */ +import fr.ird.observe.ObserveEntityEnum; +import fr.ird.observe.services.binder.BinderEngine; import fr.ird.observe.services.dto.referential.ReferentialDto; import fr.ird.observe.services.dto.referential.ReferentialReference; import org.apache.commons.collections4.CollectionUtils; @@ -85,10 +87,13 @@ public class InsertSqlStatementGenerator<R extends ReferentialDto> { */ private final String tableName; - private ManyToManyAssociationStruct(String propertyName, String dbColumnName, String tableName) { + private final Class<? extends ReferentialDto> type; + + private ManyToManyAssociationStruct(String propertyName, String dbColumnName, String tableName, Class<? extends ReferentialDto> type) { this.propertyName = propertyName; this.dbColumnName = dbColumnName; this.tableName = tableName; + this.type = type; } } @@ -111,7 +116,10 @@ public class InsertSqlStatementGenerator<R extends ReferentialDto> { String propertyName = entry.getKey(); String dbColumnName = metadataEntity.getDbColumnName(propertyName); String tableName = metadataEntity.getBdManyToManyAssociationTableName(propertyName); - ManyToManyAssociationStruct manyToManyAssociation = new ManyToManyAssociationStruct(propertyName, dbColumnName, tableName); + String typeName = entry.getValue(); + Class entityType = ObserveEntityEnum.valueOf(typeName).getContract(); + Class<? extends ReferentialDto> referentialype = BinderEngine.get().getReferentialDtoType(entityType); + ManyToManyAssociationStruct manyToManyAssociation = new ManyToManyAssociationStruct(propertyName, dbColumnName, tableName, referentialype); manyToManyAssociations.add(manyToManyAssociation); } this.columnNames = computeColumnNames(metadataEntity, simplePropertyNames, manyToOneAssociationNames); @@ -214,17 +222,7 @@ public class InsertSqlStatementGenerator<R extends ReferentialDto> { for (ReferentialReference<?> nmAssociationValue : manyToManyAssociationValues) { - String sql = String.format(NM_ASSOCIATION_INSERT_STATEMENT, - schemaName, - nmAssociationTableName, - this.tableName, - nmAssociationDbColumnName, - referentialDtoId, - nmAssociationValue.getId()); - if (log.isDebugEnabled()) { - log.debug("sql: " + sql); - } - builder.append(sql); + addMnAssociation(nmAssociationTableName, nmAssociationDbColumnName, referentialDtoId, manyToManyAssociationStruct.type, nmAssociationValue.getId(), builder); } } @@ -233,6 +231,28 @@ public class InsertSqlStatementGenerator<R extends ReferentialDto> { } + protected <D extends ReferentialDto> void addMnAssociation(String nmAssociationTableName, + String nmAssociationDbColumnName, + String referentialDtoId, + Class<D> associationType, + String associationId, + StringBuilder builder) { + + + String sql = String.format(NM_ASSOCIATION_INSERT_STATEMENT, + schemaName, + nmAssociationTableName, + this.tableName, + nmAssociationDbColumnName, + referentialDtoId, + associationId); + if (log.isDebugEnabled()) { + log.debug("sql: " + sql); + } + builder.append(sql); + + } + private Set<String> computeColumnNames(TopiaMetadataEntity metadataEntity, String[] simplePropertyNames, String[] compositionPropertyNames) { @@ -291,11 +311,11 @@ public class InsertSqlStatementGenerator<R extends ReferentialDto> { parameters.add("" + parameter); } - private void addReferentialReferenceParameter(ReferentialReference parameter, List<String> parameters) { + protected void addReferentialReferenceParameter(ReferentialReference parameter, List<String> parameters) { addStringParameter(parameter.getId(), parameters); } - private void addReferentialDtoParameter(ReferentialDto parameter, List<String> parameters) { + protected void addReferentialDtoParameter(ReferentialDto parameter, List<String> parameters) { addStringParameter(parameter.getId(), parameters); } } diff --git a/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/sql/InsertSqlWithCascadeStatementGenerator.java b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/sql/InsertSqlWithCascadeStatementGenerator.java new file mode 100644 index 0000000..95eb3d3 --- /dev/null +++ b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/sql/InsertSqlWithCascadeStatementGenerator.java @@ -0,0 +1,105 @@ +package fr.ird.observe.services.service.actions.synchro.referential.sql; + +/*- + * #%L + * ObServe :: Services ToPIA Implementation + * %% + * Copyright (C) 2008 - 2016 IRD, Codelutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 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 Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.google.common.collect.SetMultimap; +import fr.ird.observe.services.dto.referential.ReferentialDto; +import fr.ird.observe.services.dto.referential.ReferentialReference; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.topia.persistence.metadata.TopiaMetadataEntity; + +import java.util.List; + +/** + * Pour générer une requète sql d'ajout à partir d'un référentiel donné et aussi tous les inserts manquants + * + * Created on 29/06/16. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 5.0 + */ +public abstract class InsertSqlWithCascadeStatementGenerator<R extends ReferentialDto> { + + /** Logger. */ + private static final Log log = LogFactory.getLog(InsertSqlWithCascadeStatementGenerator.class); + + private final InsertSqlStatementGenerator<R> delegateGenerator; + private final SetMultimap<Class<? extends ReferentialDto>, String> idsOnlyExistingOnThisSide; + + private final StringBuilder sqlBuilder = new StringBuilder(); + + protected abstract <D extends ReferentialDto> String insertMissingReferential(Class<D> referentialType, String id); + + public InsertSqlWithCascadeStatementGenerator(TopiaMetadataEntity metadataEntity, + Class<R> dtoType, + SetMultimap<Class<? extends ReferentialDto>, String> idsOnlyExistingOnThisSide) { + this.idsOnlyExistingOnThisSide = idsOnlyExistingOnThisSide; + this.delegateGenerator = new InsertSqlStatementGenerator<R>(metadataEntity, dtoType) { + + @Override + protected <D extends ReferentialDto> void addMnAssociation(String nmAssociationTableName, String nmAssociationDbColumnName, String referentialDtoId, Class<D> associationType, String associationId, StringBuilder builder) { + super.addMnAssociation(nmAssociationTableName, nmAssociationDbColumnName, referentialDtoId, associationType, associationId, builder); + addMissingReferentialIfNecessary(associationType, associationId); + } + + @Override + protected void addReferentialReferenceParameter(ReferentialReference parameter, List<String> parameters) { + super.addReferentialReferenceParameter(parameter, parameters); + addMissingReferentialIfNecessary(parameter.getType(), parameter.getId()); + } + + @Override + protected void addReferentialDtoParameter(ReferentialDto parameter, List<String> parameters) { + super.addReferentialDtoParameter(parameter, parameters); + addMissingReferentialIfNecessary(parameter.getClass(), parameter.getId()); + } + }; + } + + public String generateSql(R referentialDto) { + + String sql = delegateGenerator.generateSql(referentialDto); + sqlBuilder.append(sql); + return sqlBuilder.toString(); + + } + + private <D extends ReferentialDto> String addMissingReferentialIfNecessary(Class<D> associationType, String associationId) { + + if (idsOnlyExistingOnThisSide.containsEntry(associationType, associationId)) { + + // il faut insérer aussi ce référentiel + String sql = insertMissingReferential(associationType, associationId); + sqlBuilder.append(sql); + + // ce référentiel est désormais présent dans les deux sources + idsOnlyExistingOnThisSide.remove(associationType, associationId); + + return sql; + + } + return null; + } + +} diff --git a/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/sql/UpdateSqlStatementGenerator.java b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/sql/UpdateSqlStatementGenerator.java index 3fbf6d7..1a0556c 100644 --- a/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/sql/UpdateSqlStatementGenerator.java +++ b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/sql/UpdateSqlStatementGenerator.java @@ -249,18 +249,14 @@ public class UpdateSqlStatementGenerator<R extends ReferentialDto> { for (ReferentialReference<?> manyToManyAssociationValue : manyToManyAssociationValues) { - String sql = String.format(MANY_TO_MANY_ASSOCIATION_INSERT_STATEMENT, - schemaName, - manyToManyAssociationTableName, - tableName, - manyToManyAssociationDbColumnName, - referentialDtoId, - manyToManyAssociationValue.getId()); - if (log.isDebugEnabled()) { - log.debug("sql: " + sql); - } - builder.append(sql); - + addMnAssociation( + manyToManyAssociationTableName, + manyToManyAssociationDbColumnName, + referentialDtoId, + manyToManyAssociationValue.getType(), + manyToManyAssociationValue.getId(), + builder + ); } } @@ -268,6 +264,27 @@ public class UpdateSqlStatementGenerator<R extends ReferentialDto> { } + protected <D extends ReferentialDto> void addMnAssociation(String nmAssociationTableName, + String nmAssociationDbColumnName, + String referentialDtoId, + Class<D> associationType, + String associationId, + StringBuilder builder) { + + String sql = String.format(MANY_TO_MANY_ASSOCIATION_INSERT_STATEMENT, + schemaName, + nmAssociationTableName, + this.tableName, + nmAssociationDbColumnName, + referentialDtoId, + associationId); + if (log.isDebugEnabled()) { + log.debug("sql: " + sql); + } + builder.append(sql); + + } + private Map<String, String> computeColumnNames(TopiaMetadataEntity metadataEntity, String[] simplePropertyNames, String[] compositionPropertyNames) { @@ -306,11 +323,11 @@ public class UpdateSqlStatementGenerator<R extends ReferentialDto> { addParameter0(columnName, "" + parameter, parameters); } - private void addReferentialReferenceParameter(String columnName, ReferentialReference parameter, StringBuilder parameters) { + protected void addReferentialReferenceParameter(String columnName, ReferentialReference parameter, StringBuilder parameters) { addStringParameter(columnName, parameter.getId(), parameters); } - private void addReferentialDtoParameter(String columnName, ReferentialDto parameter, StringBuilder parameters) { + protected void addReferentialDtoParameter(String columnName, ReferentialDto parameter, StringBuilder parameters) { addStringParameter(columnName, parameter.getId(), parameters); } diff --git a/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/sql/UpdateSqlWithCascadeStatementGenerator.java b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/sql/UpdateSqlWithCascadeStatementGenerator.java new file mode 100644 index 0000000..8493869 --- /dev/null +++ b/observe-services-topia/src/main/java/fr/ird/observe/services/service/actions/synchro/referential/sql/UpdateSqlWithCascadeStatementGenerator.java @@ -0,0 +1,103 @@ +package fr.ird.observe.services.service.actions.synchro.referential.sql; + +/*- + * #%L + * ObServe :: Services ToPIA Implementation + * %% + * Copyright (C) 2008 - 2016 IRD, Codelutin, Tony Chemit + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 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 Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.google.common.collect.SetMultimap; +import fr.ird.observe.services.dto.referential.ReferentialDto; +import fr.ird.observe.services.dto.referential.ReferentialReference; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.topia.persistence.metadata.TopiaMetadataEntity; + +/** + * Pour générer une requète sql d'ajout à partir d'un référentiel donné et aussi tous les inserts manquants. + * + * Created on 29/06/16. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 5.0 + */ +public abstract class UpdateSqlWithCascadeStatementGenerator<R extends ReferentialDto> { + + /** Logger. */ + private static final Log log = LogFactory.getLog(UpdateSqlWithCascadeStatementGenerator.class); + + private final UpdateSqlStatementGenerator<R> delegateGenerator; + private final SetMultimap<Class<? extends ReferentialDto>, String> idsOnlyExistingOnThisSide; + + private final StringBuilder sqlBuilder = new StringBuilder(); + + protected abstract <D extends ReferentialDto> String insertMissingReferential(Class<D> referentialType, String id); + + public UpdateSqlWithCascadeStatementGenerator(TopiaMetadataEntity metadataEntity, + Class<R> dtoType, + SetMultimap<Class<? extends ReferentialDto>, String> idsOnlyExistingOnThisSide) { + this.idsOnlyExistingOnThisSide = idsOnlyExistingOnThisSide; + this.delegateGenerator = new UpdateSqlStatementGenerator<R>(metadataEntity, dtoType) { + + @Override + protected <D extends ReferentialDto> void addMnAssociation(String nmAssociationTableName, String nmAssociationDbColumnName, String referentialDtoId, Class<D> associationType, String associationId, StringBuilder builder) { + super.addMnAssociation(nmAssociationTableName, nmAssociationDbColumnName, referentialDtoId, associationType, associationId, builder); + addMissingReferentialIfNecessary(associationType, associationId); + } + + @Override + protected void addReferentialReferenceParameter(String columnName, ReferentialReference parameter, StringBuilder parameters) { + super.addReferentialReferenceParameter(columnName, parameter, parameters); + addMissingReferentialIfNecessary(parameter.getType(), parameter.getId()); + } + + @Override + protected void addReferentialDtoParameter(String columnName, ReferentialDto parameter, StringBuilder parameters) { + super.addReferentialDtoParameter(columnName, parameter, parameters); + addMissingReferentialIfNecessary(parameter.getClass(), parameter.getId()); + } + }; + } + + public String generateSql(R referentialDto) { + + String sql = delegateGenerator.generateSql(referentialDto); + sqlBuilder.append(sql); + return sqlBuilder.toString(); + + } + + private <D extends ReferentialDto> String addMissingReferentialIfNecessary(Class<D> associationType, String associationId) { + + if (idsOnlyExistingOnThisSide.containsEntry(associationType, associationId)) { + + // il faut insérer aussi ce référentiel + String sql = insertMissingReferential(associationType, associationId); + sqlBuilder.append(sql); + + // ce référentiel est désormais présent dans les deux sources + idsOnlyExistingOnThisSide.remove(associationType, associationId); + + return sql; + + } + return null; + } + +} -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.