diff options
19 files changed, 368 insertions, 93 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_419962_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_419962_Test.java new file mode 100644 index 0000000000..8bdad83f9c --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_419962_Test.java @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2013 Eike Stepper (Berlin, Germany) 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: + * Eike Stepper - initial API and implementation + */ +package org.eclipse.emf.cdo.tests.bugzilla; + +import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.CDOState; +import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode; +import org.eclipse.emf.cdo.session.CDOSession; +import org.eclipse.emf.cdo.tests.AbstractCDOTest; +import org.eclipse.emf.cdo.tests.model1.Company; +import org.eclipse.emf.cdo.tests.model1.Customer; +import org.eclipse.emf.cdo.tests.model1.SalesOrder; +import org.eclipse.emf.cdo.transaction.CDOConflictResolver; +import org.eclipse.emf.cdo.transaction.CDOTransaction; +import org.eclipse.emf.cdo.util.CDOUtil; +import org.eclipse.emf.cdo.view.CDOAdapterPolicy; + +import org.eclipse.net4j.util.om.OMPlatform; +import org.eclipse.net4j.util.om.trace.PrintTraceHandler; + +import org.eclipse.emf.spi.cdo.CDOMergingConflictResolver; +import org.eclipse.emf.spi.cdo.DefaultCDOMerger; + +/** + * Bug 419962 - CommitConflictException after CDOMergingConflictResolver.resolveConflicts(). + * + * @author Eike Stepper + */ +public class Bugzilla_419962_Test extends AbstractCDOTest +{ + private CDOSession sessionA; + + private CDOSession sessionB; + + private CDOTransaction transactionA; + + private CDOTransaction transactionB; + + private Company companyA; + + private Company companyB; + + public Bugzilla_419962_Test() + { + } + + @Override + public CDOSession openSession() + { + CDOSession session = super.openSession(); + session.options().setPassiveUpdateMode(PassiveUpdateMode.CHANGES); + return session; + } + + @Override + protected void doSetUp() throws Exception + { + OMPlatform.INSTANCE.removeTraceHandler(PrintTraceHandler.CONSOLE); + super.doSetUp(); + + CDOSession session = openSession(); + CDOTransaction transaction = session.openTransaction(); + + Company company = getModel1Factory().createCompany(); + company.setName("Central"); + + transaction.getOrCreateResource(getResourcePath("/res1")).getContents().add(company); + transaction.commit(); + + transaction.close(); + session.close(); + + sessionA = openSession(); + sessionB = openSession(); + + transactionA = sessionA.openTransaction(); + transactionA.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL); + + transactionB = sessionB.openTransaction(); + transactionB.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL); + + transactionA.options().addConflictResolver(createCdoConflictResolver()); + transactionB.options().addConflictResolver(createCdoConflictResolver()); + + companyA = (Company)transactionA.getOrCreateResource(getResourcePath("/res1")).getContents().get(0); + companyB = (Company)transactionB.getOrCreateResource(getResourcePath("/res1")).getContents().get(0); + } + + @Override + public void tearDown() throws Exception + { + transactionA.close(); + transactionB.close(); + sessionA.close(); + sessionB.close(); + + super.tearDown(); + } + + public void testConflict() throws Exception + { + Customer customer5A = getModel1Factory().createCustomer(); + companyA.getCustomers().add(customer5A); + + Customer customer6B = getModel1Factory().createCustomer(); + companyB.getCustomers().add(customer6B); + + commitAndSync(transactionA, transactionB); + commitAndSync(transactionB, transactionA); + + Customer customer5B = transactionB.getObject(customer5A); + Customer customer6A = transactionA.getObject(customer6B); + + SalesOrder s1 = getModel1Factory().createSalesOrder(); + companyA.getSalesOrders().add(s1); + customer5A.getSalesOrders().add(s1); + + SalesOrder s2 = getModel1Factory().createSalesOrder(); + companyB.getSalesOrders().add(s2); + customer6B.getSalesOrders().add(s2); + + commitAndSync(transactionA, transactionB); + assertEquals(1, companyA.getSalesOrders().size()); // Not yet committed + assertEquals(2, companyB.getSalesOrders().size()); + checkCustomer(customer5A, 1, 2, CDOState.CLEAN); + checkCustomer(customer6B, 1, 1, CDOState.DIRTY); + checkCustomer(customer5B, 1, 2, CDOState.CLEAN); + checkCustomer(customer6A, 0, 1, CDOState.CLEAN); // Not yet committed + + commitAndSync(transactionB, transactionA); + assertEquals(2, companyA.getSalesOrders().size()); + assertEquals(2, companyB.getSalesOrders().size()); + checkCustomer(customer5A, 1, 2, CDOState.CLEAN); + checkCustomer(customer6B, 1, 2, CDOState.CLEAN); + checkCustomer(customer5B, 1, 2, CDOState.CLEAN); + checkCustomer(customer6A, 1, 2, CDOState.CLEAN); + + SalesOrder s3 = getModel1Factory().createSalesOrder(); + companyA.getSalesOrders().add(s3); + customer5A.getSalesOrders().add(s3); + + SalesOrder s4 = getModel1Factory().createSalesOrder(); + companyB.getSalesOrders().add(s4); + customer6B.getSalesOrders().add(s4); + + commitAndSync(transactionA, transactionB); + assertEquals(3, companyA.getSalesOrders().size()); // Not yet committed + assertEquals(4, companyB.getSalesOrders().size()); + checkCustomer(customer5A, 2, 3, CDOState.CLEAN); + checkCustomer(customer6B, 2, 2, CDOState.DIRTY); + checkCustomer(customer5B, 2, 3, CDOState.CLEAN); + checkCustomer(customer6A, 1, 2, CDOState.CLEAN); // Not yet committed + + commitAndSync(transactionB, transactionA); + assertEquals(4, companyA.getSalesOrders().size()); + assertEquals(4, companyB.getSalesOrders().size()); + checkCustomer(customer5A, 2, 3, CDOState.CLEAN); + checkCustomer(customer6B, 2, 3, CDOState.CLEAN); + checkCustomer(customer5B, 2, 3, CDOState.CLEAN); + checkCustomer(customer6A, 2, 3, CDOState.CLEAN); + } + + private static void checkCustomer(Customer customer, int salesOrders, int version, CDOState state) + { + assertEquals("Wrong number of sales orders", salesOrders, customer.getSalesOrders().size()); + + CDOObject object = CDOUtil.getCDOObject(customer); + assertEquals("Wrong version", version, object.cdoRevision(true).getVersion()); + assertEquals("Wrong state", state, object.cdoState()); + } + + private CDOConflictResolver createCdoConflictResolver() + { + return new CDOMergingConflictResolver(new DefaultCDOMerger.PerFeature.ManyValued()); + } +} diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/ViewAction.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/AbstractViewAction.java index 1996fa7864..7b81d773c2 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/ViewAction.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/AbstractViewAction.java @@ -23,13 +23,13 @@ import org.eclipse.ui.IWorkbenchPage; /** * @author Eike Stepper */ -public abstract class ViewAction extends LongRunningAction +public abstract class AbstractViewAction extends LongRunningAction { protected static int lastResourceNumber = 0; private CDOView view; - public ViewAction(IWorkbenchPage page, String text, String toolTipText, ImageDescriptor image, CDOView view) + public AbstractViewAction(IWorkbenchPage page, String text, String toolTipText, ImageDescriptor image, CDOView view) { super(page, text, toolTipText, image); this.view = view; diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/CloseViewAction.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/CloseViewAction.java index 691a5378d0..1243415f68 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/CloseViewAction.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/CloseViewAction.java @@ -22,7 +22,7 @@ import org.eclipse.ui.IWorkbenchPage; /** * @author Eike Stepper */ -public final class CloseViewAction extends ViewAction +public final class CloseViewAction extends AbstractViewAction { private static final String TITLE = Messages.getString("CloseViewAction.0"); //$NON-NLS-1$ diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/CommitTransactionAction.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/CommitTransactionAction.java index 75bcdf516b..e922ce28e3 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/CommitTransactionAction.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/CommitTransactionAction.java @@ -21,7 +21,7 @@ import org.eclipse.ui.IWorkbenchPage; /** * @author Eike Stepper */ -public final class CommitTransactionAction extends ViewAction +public final class CommitTransactionAction extends AbstractViewAction { private static final String TITLE = Messages.getString("CommitTransactionAction.0"); //$NON-NLS-1$ diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/DisableViewDurabilityAction.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/DisableViewDurabilityAction.java index 4130a3776e..0be65f68ef 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/DisableViewDurabilityAction.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/DisableViewDurabilityAction.java @@ -20,7 +20,7 @@ import org.eclipse.ui.IWorkbenchPage; /** * @author Eike Stepper */ -public final class DisableViewDurabilityAction extends ViewAction +public final class DisableViewDurabilityAction extends AbstractViewAction { private static final String TITLE = Messages.getString("DisableViewDurabilityAction.0"); //$NON-NLS-1$ diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/EnableViewDurabilityAction.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/EnableViewDurabilityAction.java index bc572c5caa..9dd7effb17 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/EnableViewDurabilityAction.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/EnableViewDurabilityAction.java @@ -24,7 +24,7 @@ import org.eclipse.ui.IWorkbenchPage; /** * @author Eike Stepper */ -public final class EnableViewDurabilityAction extends ViewAction +public final class EnableViewDurabilityAction extends AbstractViewAction { private static final String TITLE = Messages.getString("EnableViewDurabilityAction.0"); //$NON-NLS-1$ diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/ExportResourceAction.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/ExportResourceAction.java index 813bad8cb6..2718e8c249 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/ExportResourceAction.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/ExportResourceAction.java @@ -39,7 +39,7 @@ import java.util.List; /** * @author Eike Stepper */ -public class ExportResourceAction extends ViewAction +public class ExportResourceAction extends AbstractViewAction { public static final String ID = "export-resource"; //$NON-NLS-1$ diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/ImportResourceAction.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/ImportResourceAction.java index b07076efd7..dc484a1fcf 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/ImportResourceAction.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/ImportResourceAction.java @@ -36,7 +36,7 @@ import java.util.List; /** * @author Eike Stepper */ -public class ImportResourceAction extends ViewAction +public class ImportResourceAction extends AbstractViewAction { public static final String ID = "import-resource"; //$NON-NLS-1$ diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/LoadResourceAction.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/LoadResourceAction.java index 6aa15d046e..69a668529f 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/LoadResourceAction.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/LoadResourceAction.java @@ -26,7 +26,7 @@ import java.text.MessageFormat; /** * @author Eike Stepper */ -public final class LoadResourceAction extends ViewAction +public final class LoadResourceAction extends AbstractViewAction { private static final String TITLE = Messages.getString("LoadResourceAction.0"); //$NON-NLS-1$ @@ -40,7 +40,7 @@ public final class LoadResourceAction extends ViewAction @Override protected void preRun() throws Exception { - String uri = ViewAction.lastResourceNumber == 0 ? "" : "/res" + ViewAction.lastResourceNumber; //$NON-NLS-1$ //$NON-NLS-2$ + String uri = AbstractViewAction.lastResourceNumber == 0 ? "" : "/res" + AbstractViewAction.lastResourceNumber; //$NON-NLS-1$ //$NON-NLS-2$ InputDialog dialog = new InputDialog(getShell(), TITLE, Messages.getString("LoadResourceAction.4"), uri, null); //$NON-NLS-1$ if (dialog.open() == InputDialog.OK) { diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/MergeConflictsAction.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/MergeConflictsAction.java new file mode 100644 index 0000000000..88132c4f33 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/MergeConflictsAction.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013 Eike Stepper (Berlin, Germany) 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: + * Eike Stepper - initial API and implementation + */ +package org.eclipse.emf.cdo.internal.ui.actions; + +import org.eclipse.emf.cdo.internal.ui.messages.Messages; +import org.eclipse.emf.cdo.transaction.CDOConflictResolver; +import org.eclipse.emf.cdo.transaction.CDOTransaction; + +import org.eclipse.net4j.util.ui.actions.SafeAction; + +import org.eclipse.emf.spi.cdo.CDOMergingConflictResolver; + +/** + * @author Eike Stepper + */ +public class MergeConflictsAction extends SafeAction +{ + private static final String TITLE = Messages.getString("MergeConflictsAction.0"); //$NON-NLS-1$ + + private static final String TOOL_TIP = Messages.getString("MergeConflictsAction.1"); //$NON-NLS-1$ + + private final CDOTransaction transaction; + + public MergeConflictsAction(CDOTransaction transaction) + { + super(TITLE, AS_CHECK_BOX); + setToolTipText(TOOL_TIP); + + this.transaction = transaction; + for (CDOConflictResolver conflictResolver : transaction.options().getConflictResolvers()) + { + setEnabled(false); + if (conflictResolver instanceof CDOMergingConflictResolver) + { + setEnabled(true); + setChecked(true); + return; + } + } + } + + @Override + protected void safeRun() throws Exception + { + for (CDOConflictResolver conflictResolver : transaction.options().getConflictResolvers()) + { + if (conflictResolver instanceof CDOMergingConflictResolver) + { + transaction.options().removeConflictResolver(conflictResolver); + return; + } + } + + CDOMergingConflictResolver conflictResolver = new CDOMergingConflictResolver(); + transaction.options().addConflictResolver(conflictResolver); + } +} diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/NewResourceNodeAction.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/NewResourceNodeAction.java index d1da655319..6be6dbcc0b 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/NewResourceNodeAction.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/NewResourceNodeAction.java @@ -30,7 +30,7 @@ import org.eclipse.ui.IWorkbenchPage; /** * @author Eike Stepper */ -public class NewResourceNodeAction extends ViewAction +public class NewResourceNodeAction extends AbstractViewAction { private CDOItemProvider itemProvider; @@ -53,12 +53,12 @@ public class NewResourceNodeAction extends ViewAction protected void preRun() throws Exception { InputDialog dialog = new InputDialog(getShell(), type.getTitle(), Messages.getString("NewResourceNodeAction.8"), - (type == Type.FOLDER ? "folder" : "resource") + (ViewAction.lastResourceNumber + 1), + (type == Type.FOLDER ? "folder" : "resource") + (AbstractViewAction.lastResourceNumber + 1), new ResourceNodeNameInputValidator(selectedNode)); if (dialog.open() == InputDialog.OK) { - ++ViewAction.lastResourceNumber; + ++AbstractViewAction.lastResourceNumber; resourceNodeName = dialog.getValue(); } else diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/OpenTransactionAction.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/OpenTransactionAction.java index 5123c5cd5b..fd66c170ff 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/OpenTransactionAction.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/OpenTransactionAction.java @@ -17,8 +17,6 @@ import org.eclipse.emf.cdo.transaction.CDOTransaction; import org.eclipse.emf.cdo.transaction.CDOTransactionCommentator; import org.eclipse.emf.cdo.ui.shared.SharedIcons; -import org.eclipse.emf.spi.cdo.CDOMergingConflictResolver; - import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.ui.IWorkbenchPage; @@ -52,7 +50,6 @@ public final class OpenTransactionAction extends AbstractOpenViewAction public static void configureTransaction(CDOTransaction transaction) { - transaction.options().addConflictResolver(new CDOMergingConflictResolver()); new CDOTransactionCommentator(transaction); } } diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/OpenViewEditorAction.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/OpenViewEditorAction.java index b62d47db5a..ded68f7c3b 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/OpenViewEditorAction.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/OpenViewEditorAction.java @@ -23,7 +23,7 @@ import org.eclipse.ui.IWorkbenchPage; * @deprecated As of 4.2 */ @Deprecated -public final class OpenViewEditorAction extends ViewAction +public final class OpenViewEditorAction extends AbstractViewAction { private static final String TITLE = Messages.getString("OpenViewEditorAction.0"); //$NON-NLS-1$ diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/RollbackTransactionAction.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/RollbackTransactionAction.java index c1a3ba0eba..03f3390131 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/RollbackTransactionAction.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/RollbackTransactionAction.java @@ -22,7 +22,7 @@ import org.eclipse.ui.IWorkbenchPage; /** * @author Eike Stepper */ -public final class RollbackTransactionAction extends ViewAction +public final class RollbackTransactionAction extends AbstractViewAction { private static final String TITLE = Messages.getString("RollbackTransactionAction.0"); //$NON-NLS-1$ diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/SwitchTargetAction.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/SwitchTargetAction.java index 5bd2f7d9a8..da18ed2c75 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/SwitchTargetAction.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/SwitchTargetAction.java @@ -25,7 +25,7 @@ import org.eclipse.ui.IWorkbenchPage; /** * @author Victor Roldan Betancort */ -public class SwitchTargetAction extends ViewAction +public class SwitchTargetAction extends AbstractViewAction { public static final String ID = "switch-target"; //$NON-NLS-1$ diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/messages/messages.properties b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/messages/messages.properties index ae5d54c223..79a136db80 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/messages/messages.properties +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/messages/messages.properties @@ -96,6 +96,8 @@ CloseViewAction.1=Close the CDO view CloseViewAction.2=You have uncommitted changes. Do you want to discard them? CommitTransactionAction.0=Commit CommitTransactionAction.1=Commit this transaction +MergeConflictsAction.0=Merge Conflicts +MergeConflictsAction.1=Automatically merge conflicts when they occur CreateBranchAction.0=Create Branch CreateBranchAction.1=Create a new branch DisableViewDurabilityAction.0=Make Not Durable diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOItemProvider.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOItemProvider.java index 48527278e6..852d1a74a4 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOItemProvider.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOItemProvider.java @@ -35,6 +35,7 @@ import org.eclipse.emf.cdo.internal.ui.actions.ExportResourceAction; import org.eclipse.emf.cdo.internal.ui.actions.ImportResourceAction; import org.eclipse.emf.cdo.internal.ui.actions.LoadResourceAction; import org.eclipse.emf.cdo.internal.ui.actions.ManagePackagesAction; +import org.eclipse.emf.cdo.internal.ui.actions.MergeConflictsAction; import org.eclipse.emf.cdo.internal.ui.actions.NewResourceNodeAction; import org.eclipse.emf.cdo.internal.ui.actions.OpenAuditAction; import org.eclipse.emf.cdo.internal.ui.actions.OpenDurableViewAction; @@ -587,6 +588,7 @@ public class CDOItemProvider extends ContainerItemProvider<IContainer<Object>> { manager.add(new ImportResourceAction(page, view)); manager.add(new Separator()); + manager.add(new MergeConflictsAction((CDOTransaction)view)); manager.add(new CommitTransactionAction(page, view)); manager.add(new RollbackTransactionAction(page, view)); } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOMergingConflictResolver.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOMergingConflictResolver.java index 82df8c422a..0814783223 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOMergingConflictResolver.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/CDOMergingConflictResolver.java @@ -83,12 +83,12 @@ public class CDOMergingConflictResolver extends AbstractChangeSetsConflictResolv CDOChangeSet remoteChangeSet = getRemoteChangeSet(); while (remoteChangeSet != null) { - resolveConflicts(remoteChangeSet); + resolveConflicts(conflicts, remoteChangeSet); remoteChangeSet = getRemoteChangeSet(); } } - private void resolveConflicts(CDOChangeSet remoteChangeSet) + private void resolveConflicts(Set<CDOObject> conflicts, CDOChangeSet remoteChangeSet) { CDOChangeSet localChangeSet = getLocalChangeSet(); CDOChangeSetData result; @@ -117,11 +117,14 @@ public class CDOMergingConflictResolver extends AbstractChangeSetsConflictResolv { InternalCDORevisionDelta resultDelta = (InternalCDORevisionDelta)key; CDOID id = resultDelta.getID(); + InternalCDOObject object = (InternalCDOObject)transaction.getObject(id, false); - if (object != null) + if (object != null && conflicts.contains(object)) { + // TODO Should the merge result be compared to non-conflicting revisions, too? + int newVersion = computeNewVersion(object); - InternalCDORevision cleanRevision = computeOldCleanRevision(object, cleanRevisions); + InternalCDORevision cleanRevision = cleanRevisions.get(object); InternalCDORevision newLocalRevision = computeNewLocalRevision(resultDelta, newVersion, cleanRevision); // Adjust local object @@ -147,64 +150,7 @@ public class CDOMergingConflictResolver extends AbstractChangeSetsConflictResolv cleanRevisions.put(object, newCleanRevision); dirtyObjects.put(id, object); - newLocalDelta.accept(new CDOFeatureDeltaVisitorImpl() - { - @Override - public void visit(CDOAddFeatureDelta delta) - { - // recurse(newObjectsUpdater, (CDOID)delta.getValue()); - } - - @Override - public void visit(CDOClearFeatureDelta delta) - { - // TODO Only for reference features? - CDOList list = newCleanRevision.getList(delta.getFeature()); - for (Object id : list) - { - recurse(detachedObjectsUpdater, (CDOID)id); - } - } - - @Override - public void visit(CDORemoveFeatureDelta delta) - { - // TODO Only for reference features? - recurse(detachedObjectsUpdater, (CDOID)delta.getValue()); - } - - @Override - public void visit(CDOSetFeatureDelta delta) - { - // recurse(detachedObjectsUpdater, (CDOID)delta.getOldValue()); - // recurse(newObjectsUpdater, (CDOID)delta.getValue()); - } - - @Override - public void visit(CDOUnsetFeatureDelta delta) - { - // TODO: implement CDOMergingConflictResolver.resolveConflicts(...).new CDOFeatureDeltaVisitorImpl() - } - - private void recurse(final ObjectsMapUpdater objectsUpdater, CDOID id) - { - CDOObject object = objectsUpdater.update(id); - if (object != null) - { - InternalCDORevision revision = (InternalCDORevision)object.cdoRevision(); - if (revision != null) - { - revision.accept(new CDORevisionValueVisitor() - { - public void visit(EStructuralFeature feature, Object value, int index) - { - recurse(objectsUpdater, (CDOID)value); - } - }, EMFUtil.CONTAINMENT_REFERENCES); - } - } - } - }, EMFUtil.CONTAINMENT_REFERENCES); + updateObjects(newCleanRevision, newLocalDelta, detachedObjectsUpdater); } } } @@ -217,18 +163,6 @@ public class CDOMergingConflictResolver extends AbstractChangeSetsConflictResolv return newVersion; } - private InternalCDORevision computeOldCleanRevision(InternalCDOObject object, - Map<InternalCDOObject, InternalCDORevision> cleanRevisions) - { - InternalCDORevision cleanRevision = cleanRevisions.get(object); - if (cleanRevision == null) - { - // In this case the object revision *is clean* - cleanRevision = object.cdoRevision(); - } - return cleanRevision; - } - private InternalCDORevision computeNewLocalRevision(InternalCDORevisionDelta resultDelta, int newVersion, InternalCDORevision cleanRevision) { @@ -253,6 +187,69 @@ public class CDOMergingConflictResolver extends AbstractChangeSetsConflictResolv return cleanRevision; } + private void updateObjects(final InternalCDORevision newCleanRevision, InternalCDORevisionDelta newLocalDelta, + final ObjectsMapUpdater detachedObjectsUpdater) + { + newLocalDelta.accept(new CDOFeatureDeltaVisitorImpl() + { + @Override + public void visit(CDOAddFeatureDelta delta) + { + // recurse(newObjectsUpdater, (CDOID)delta.getValue()); + } + + @Override + public void visit(CDOClearFeatureDelta delta) + { + // TODO Only for reference features? + CDOList list = newCleanRevision.getList(delta.getFeature()); + for (Object id : list) + { + recurse(detachedObjectsUpdater, (CDOID)id); + } + } + + @Override + public void visit(CDORemoveFeatureDelta delta) + { + // TODO Only for reference features? + recurse(detachedObjectsUpdater, (CDOID)delta.getValue()); + } + + @Override + public void visit(CDOSetFeatureDelta delta) + { + // recurse(detachedObjectsUpdater, (CDOID)delta.getOldValue()); + // recurse(newObjectsUpdater, (CDOID)delta.getValue()); + } + + @Override + public void visit(CDOUnsetFeatureDelta delta) + { + // TODO: implement CDOMergingConflictResolver.resolveConflicts(...).new CDOFeatureDeltaVisitorImpl() + } + + private void recurse(final ObjectsMapUpdater objectsUpdater, CDOID id) + { + CDOObject object = objectsUpdater.update(id); + if (object != null) + { + InternalCDORevision revision = (InternalCDORevision)object.cdoRevision(); + if (revision != null) + { + revision.accept(new CDORevisionValueVisitor() + { + public void visit(EStructuralFeature feature, Object value, int index) + { + recurse(objectsUpdater, (CDOID)value); + } + }, EMFUtil.CONTAINMENT_REFERENCES); + } + } + } + }, EMFUtil.CONTAINMENT_REFERENCES); + } + private Map<CDOID, CDORevisionDelta> getRemoteDeltas(CDOChangeSet remoteChangeSet) { Map<CDOID, CDORevisionDelta> remoteDeltas = CDOIDUtil.createMap(); diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/FSMUtil.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/FSMUtil.java index 3628e4a80b..2c16dab68f 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/FSMUtil.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/FSMUtil.java @@ -13,6 +13,7 @@ package org.eclipse.emf.spi.cdo; import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.cdo.CDOState; +import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.view.CDOView; import org.eclipse.emf.internal.cdo.CDOObjectImpl; @@ -169,4 +170,31 @@ public final class FSMUtil { return iterator(instances.iterator(), view); } + + /** + * @since 4.3 + */ + public static String toString(Object object) + { + if (object instanceof CDOObject) + { + CDOObject cdoObject = (CDOObject)object; + + CDORevision revision = cdoObject.cdoRevision(); + if (revision != null) + { + String string = revision.toString(); + + CDOState cdoState = cdoObject.cdoState(); + if (cdoState != CDOState.CLEAN) + { + string += "[" + cdoState + "]"; + } + + return string; + } + } + + return String.valueOf(object); + } } |