Bug 500513 - Provide possibility to alter copy process during operation
recording
Change-Id: I3811ab38f645ff355fed0ca5aaaf472f275b0f86
diff --git a/bundles/org.eclipse.emf.emfstore.client/schema/changeRecordingOptions.exsd b/bundles/org.eclipse.emf.emfstore.client/schema/changeRecordingOptions.exsd
index 46cae92..4f7a59d 100644
--- a/bundles/org.eclipse.emf.emfstore.client/schema/changeRecordingOptions.exsd
+++ b/bundles/org.eclipse.emf.emfstore.client/schema/changeRecordingOptions.exsd
@@ -110,6 +110,16 @@
</appInfo>
</annotation>
</attribute>
+ <attribute name="copier" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.emf.emfstore.client.util.ESCopier"/>
+ </appInfo>
+ </annotation>
+ </attribute>
</complexType>
</element>
diff --git a/bundles/org.eclipse.emf.emfstore.client/src/org/eclipse/emf/emfstore/client/util/ESCopier.java b/bundles/org.eclipse.emf.emfstore.client/src/org/eclipse/emf/emfstore/client/util/ESCopier.java
new file mode 100644
index 0000000..064eb92
--- /dev/null
+++ b/bundles/org.eclipse.emf.emfstore.client/src/org/eclipse/emf/emfstore/client/util/ESCopier.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2011-2016 EclipseSource Muenchen GmbH and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Edgar Mueller - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.emf.emfstore.client.util;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+
+/**
+ * An interface that enables to specify a different copy behavior
+ * than standard {@link EcoreUtil#copy(EObject)}.
+ * The copy of an {@link EObject} should be self-contained, if possible, i.e.
+ * there should be no references pointing outside the copied containment tree.
+ *
+ * @since 1.8
+ *
+ */
+public interface ESCopier {
+
+ /**
+ * Whether this copier wants to copy the given {@link EObject}.
+ *
+ * @param eObject the {@link EObject} to be copied
+ * @return an integer that specifies how critical it is that the copier handles the given
+ * object. The copier that specifies the highest priority will be used to copy the object.
+ */
+ int shouldHandle(EObject eObject);
+
+ /**
+ * Copy the given {@link EObject}.
+ *
+ * @param eObject the {@link EObject} to be copied
+ * @return the copied {@link EObject}
+ */
+ EObject copy(EObject eObject);
+
+}
diff --git a/bundles/org.eclipse.emf.emfstore.client/src/org/eclipse/emf/emfstore/internal/client/configuration/Behavior.java b/bundles/org.eclipse.emf.emfstore.client/src/org/eclipse/emf/emfstore/internal/client/configuration/Behavior.java
index 1d84561..83e6bb4 100644
--- a/bundles/org.eclipse.emf.emfstore.client/src/org/eclipse/emf/emfstore/internal/client/configuration/Behavior.java
+++ b/bundles/org.eclipse.emf.emfstore.client/src/org/eclipse/emf/emfstore/internal/client/configuration/Behavior.java
@@ -15,10 +15,12 @@
import java.util.List;
import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.emfstore.client.ESServer;
import org.eclipse.emf.emfstore.client.handler.ESChecksumErrorHandler;
import org.eclipse.emf.emfstore.client.handler.ESOperationModifier;
import org.eclipse.emf.emfstore.client.provider.ESClientConfigurationProvider;
+import org.eclipse.emf.emfstore.client.util.ESCopier;
import org.eclipse.emf.emfstore.common.extensionpoint.ESExtensionElement;
import org.eclipse.emf.emfstore.common.extensionpoint.ESExtensionPoint;
import org.eclipse.emf.emfstore.common.extensionpoint.ESExtensionPointException;
@@ -26,6 +28,7 @@
import org.eclipse.emf.emfstore.internal.client.model.ServerInfo;
import org.eclipse.emf.emfstore.internal.client.model.Usersession;
import org.eclipse.emf.emfstore.internal.client.model.connectionmanager.KeyStoreManager;
+import org.eclipse.emf.emfstore.internal.client.model.impl.api.DefaultCopier;
import org.eclipse.emf.emfstore.internal.client.model.impl.api.ESServerImpl;
import org.eclipse.emf.emfstore.internal.client.model.util.ChecksumErrorHandler;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.AbstractOperation;
@@ -91,6 +94,11 @@
*/
public static final String OPERATION_MODIFIER = "operationModifier"; //$NON-NLS-1$
+ /**
+ * Copier option identifier.
+ */
+ public static final String COPIER = "copier"; //$NON-NLS-1$
+
private static Boolean isAutoSaveActive;
private static Boolean isRerecordingActive;
private static Boolean isCutOffIncomingCrossReferencesActive;
@@ -99,6 +107,7 @@
private static Boolean isUseMemoryChangePackageActive;
private static Optional<Integer> changePackageFragmentSize;
private static ESOperationModifier operationModifier;
+ private static List<ESCopier> copierList;
private ESChecksumErrorHandler checksumErrorHandler;
@@ -306,6 +315,29 @@
}
/**
+ * Returns the copier that is used to copy {@link EObject}s.
+ *
+ * @param eObject the {@link EObject} to be copied
+ *
+ * @return the copier
+ */
+ public ESCopier getESCopierFor(EObject eObject) {
+ if (copierList == null) {
+ copierList = new ESExtensionPoint(RESOURCE_OPTIONS_EXTENSION_POINT_NAME).getClasses(COPIER, ESCopier.class);
+ }
+
+ ESCopier selectedCopier = new DefaultCopier();
+ final int maxPriority = -1;
+ for (final ESCopier copier : copierList) {
+ if (copier.shouldHandle(eObject) > maxPriority) {
+ selectedCopier = copier;
+ }
+ }
+
+ return selectedCopier;
+ }
+
+ /**
* Sets the fragment size to be used when splitting change packages.
*
* @param fragmentSize
diff --git a/bundles/org.eclipse.emf.emfstore.client/src/org/eclipse/emf/emfstore/internal/client/model/impl/OperationRecorder.java b/bundles/org.eclipse.emf.emfstore.client/src/org/eclipse/emf/emfstore/internal/client/model/impl/OperationRecorder.java
index 0721b65..58507b9 100644
--- a/bundles/org.eclipse.emf.emfstore.client/src/org/eclipse/emf/emfstore/internal/client/model/impl/OperationRecorder.java
+++ b/bundles/org.eclipse.emf.emfstore.client/src/org/eclipse/emf/emfstore/internal/client/model/impl/OperationRecorder.java
@@ -35,14 +35,15 @@
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
-import org.eclipse.emf.ecore.util.EcoreUtil.Copier;
import org.eclipse.emf.emfstore.client.ESLocalProject;
import org.eclipse.emf.emfstore.client.changetracking.ESCommandObserver;
import org.eclipse.emf.emfstore.client.observer.ESCommitObserver;
import org.eclipse.emf.emfstore.client.observer.ESPostCreationObserver;
import org.eclipse.emf.emfstore.client.observer.ESShareObserver;
import org.eclipse.emf.emfstore.client.observer.ESUpdateObserver;
+import org.eclipse.emf.emfstore.client.util.ESCopier;
import org.eclipse.emf.emfstore.internal.client.model.CompositeOperationHandle;
+import org.eclipse.emf.emfstore.internal.client.model.Configuration;
import org.eclipse.emf.emfstore.internal.client.model.ESWorkspaceProviderImpl;
import org.eclipse.emf.emfstore.internal.client.model.ProjectSpace;
import org.eclipse.emf.emfstore.internal.client.model.changeTracking.NotificationToOperationConverter;
@@ -402,9 +403,8 @@
final List<EObject> allContainedModelElements = ModelUtil.getAllContainedModelElementsAsList(element, false);
allContainedModelElements.add(element);
- final Copier copier = new Copier(true, false);
+ final ESCopier copier = Configuration.getClientBehavior().getESCopierFor(element);
final EObject copiedElement = copier.copy(element);
- copier.copyReferences();
final List<EObject> copiedAllContainedModelElements = ModelUtil.getAllContainedModelElementsAsList(
copiedElement,
@@ -426,8 +426,8 @@
createDeleteOperation.setModelElement(copiedElement);
createDeleteOperation.setModelElementId(collection.getModelElementId(modelElement));
-
createDeleteOperation.setClientDate(new Date());
+
return createDeleteOperation;
}
@@ -1078,7 +1078,7 @@
* @param setting
* a setting consisting of an {@link EObject} and a non-many reference
*/
- public SettingWithElementsToRemove(Setting setting) {
+ SettingWithElementsToRemove(Setting setting) {
this.setting = setting;
}
@@ -1090,7 +1090,7 @@
* @param elementsToRemove
* the elemets to be removed from the many reference
*/
- public SettingWithElementsToRemove(Setting setting, Set<EObject> elementsToRemove) {
+ SettingWithElementsToRemove(Setting setting, Set<EObject> elementsToRemove) {
this.setting = setting;
this.elementsToRemove.addAll(elementsToRemove);
}
diff --git a/bundles/org.eclipse.emf.emfstore.client/src/org/eclipse/emf/emfstore/internal/client/model/impl/api/DefaultCopier.java b/bundles/org.eclipse.emf.emfstore.client/src/org/eclipse/emf/emfstore/internal/client/model/impl/api/DefaultCopier.java
new file mode 100644
index 0000000..69e2d7c
--- /dev/null
+++ b/bundles/org.eclipse.emf.emfstore.client/src/org/eclipse/emf/emfstore/internal/client/model/impl/api/DefaultCopier.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2011-2016 EclipseSource Muenchen GmbH and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Edgar Mueller - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.emf.emfstore.internal.client.model.impl.api;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EcoreUtil.Copier;
+import org.eclipse.emf.emfstore.client.util.ESCopier;
+
+/**
+ * The default {@link ESCopier} that does not copy by using
+ * original references.
+ *
+ */
+public class DefaultCopier implements ESCopier {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.emfstore.client.util.ESCopier#shouldHandle(org.eclipse.emf.ecore.EObject)
+ */
+ public int shouldHandle(EObject eObject) {
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.emfstore.client.util.ESCopier#copy(org.eclipse.emf.ecore.EObject)
+ */
+ public EObject copy(EObject eObject) {
+ final Copier copier = new Copier(true, false);
+ final EObject copiedElement = copier.copy(eObject);
+ copier.copyReferences();
+ return copiedElement;
+ }
+
+}