From 4b075b9c9fc8d05aa66d2befb0cbb6f1c82f6452 Mon Sep 17 00:00:00 2001 From: Eike Stepper Date: Thu, 17 Oct 2013 20:04:21 +0200 Subject: [419574] NPE in CDOMergingConflictResolver https://bugs.eclipse.org/bugs/show_bug.cgi?id=419574 --- .../internal/common/model/CDOClassInfoImpl.java | 13 +++++ .../cdo/spi/common/revision/StubCDORevision.java | 2 +- .../cdo/tests/bugzilla/Bugzilla_417483_Test.java | 6 +- .../emf/cdo/ui/ide/RepositoryContentProvider.java | 7 ++- .../META-INF/MANIFEST.MF | 8 +-- .../ui/internal/team/history/CDOHistoryPage.java | 4 +- .../org.eclipse.emf.cdo.ui/META-INF/MANIFEST.MF | 57 ++++++++++++++---- .../internal/ui/actions/OpenDurableViewAction.java | 3 +- .../internal/ui/actions/OpenTransactionAction.java | 20 +++++-- .../ui/actions/RemoveResourceActionDelegate.java | 10 ++-- .../TransactionalBackgroundActionDelegate.java | 8 +-- .../cdo/internal/ui/dialogs/OpenSessionDialog.java | 11 +++- .../emf/cdo/internal/ui/views/CDOSessionsView.java | 3 +- .../org/eclipse/emf/cdo/ui/CDOItemProvider.java | 8 ++- .../emf/cdo/eresource/impl/CDOResourceImpl.java | 24 ++++---- .../eclipse/emf/internal/cdo/CDOObjectImpl.java | 7 ++- .../cdo/transaction/CDOTransactionImpl.java | 12 +--- .../emf/internal/cdo/view/AbstractCDOView.java | 26 +++++++-- .../emf/internal/cdo/view/CDOStateMachine.java | 3 +- .../emf/spi/cdo/CDOMergingConflictResolver.java | 68 +++++++++++++++------- .../net4j/util/ui/views/ContainerItemProvider.java | 33 ++++++++--- .../eclipse/net4j/util/ui/views/ContainerView.java | 1 + 22 files changed, 234 insertions(+), 100 deletions(-) diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassInfoImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassInfoImpl.java index a8df0d93cd..db826a35e9 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassInfoImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassInfoImpl.java @@ -34,6 +34,7 @@ import org.eclipse.emf.ecore.impl.EClassImpl; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.ecore.util.FeatureMapUtil; +import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.BitSet; @@ -410,6 +411,12 @@ public final class CDOClassInfoImpl implements InternalCDOClassInfo, Adapter.Int { return null; } + + @Override + public String toString() + { + return MessageFormat.format("RevisionWithoutID[{0}]", getClassInfo()); + } } /** @@ -452,5 +459,11 @@ public final class CDOClassInfoImpl implements InternalCDOClassInfo, Adapter.Int { return null; } + + @Override + public String toString() + { + return MessageFormat.format("RevisionWithoutID[{0}, {1}]", getClassInfo(), id); + } } } diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java index a95435cca5..65c93e1e9f 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java @@ -367,6 +367,6 @@ public class StubCDORevision extends AbstractCDORevision private String getExceptionMessage() { - return "Unsupported operation in " + this; + return "Unsupported operation in " + getClass().getSimpleName(); } } diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_417483_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_417483_Test.java index 5522ab811c..9f18fe2559 100644 --- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_417483_Test.java +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_417483_Test.java @@ -11,7 +11,9 @@ package org.eclipse.emf.cdo.tests.bugzilla; import org.eclipse.emf.cdo.CDODeltaNotification; +import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode; +import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.security.CDOPermission; import org.eclipse.emf.cdo.eresource.CDOResource; import org.eclipse.emf.cdo.security.Access; @@ -395,6 +397,8 @@ public class Bugzilla_417483_Test extends AbstractCDOTest private boolean isWritable(EObject object) { - return CDOUtil.getCDOObject(object).cdoRevision().isWritable(); + CDOObject cdoObject = CDOUtil.getCDOObject(object); + CDORevision revision = cdoObject.cdoRevision(true); + return revision.isWritable(); } } diff --git a/plugins/org.eclipse.emf.cdo.ui.ide/src/org/eclipse/emf/cdo/ui/ide/RepositoryContentProvider.java b/plugins/org.eclipse.emf.cdo.ui.ide/src/org/eclipse/emf/cdo/ui/ide/RepositoryContentProvider.java index a924b66083..0947772ea8 100644 --- a/plugins/org.eclipse.emf.cdo.ui.ide/src/org/eclipse/emf/cdo/ui/ide/RepositoryContentProvider.java +++ b/plugins/org.eclipse.emf.cdo.ui.ide/src/org/eclipse/emf/cdo/ui/ide/RepositoryContentProvider.java @@ -15,11 +15,12 @@ import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.cdo.common.branch.CDOBranch; import org.eclipse.emf.cdo.common.branch.CDOBranchCreatedEvent; import org.eclipse.emf.cdo.eresource.CDOResource; +import org.eclipse.emf.cdo.internal.ui.actions.OpenTransactionAction; import org.eclipse.emf.cdo.internal.ui.actions.RemoveResourceActionDelegate; +import org.eclipse.emf.cdo.session.CDOSession; import org.eclipse.emf.cdo.team.IRepositoryManager; import org.eclipse.emf.cdo.team.IRepositoryProject; import org.eclipse.emf.cdo.transaction.CDOTransaction; -import org.eclipse.emf.cdo.transaction.CDOTransactionCommentator; import org.eclipse.emf.cdo.ui.CDOEditorInput; import org.eclipse.emf.cdo.ui.CDOEditorUtil; import org.eclipse.emf.cdo.ui.CDOEventHandler; @@ -493,8 +494,8 @@ public class RepositoryContentProvider extends StructuredContentProvider repositoryToTransaction = new HashMap(); for (CDOResourceNode node : nodes) { - int sessionID = node.cdoView().getSession().getSessionID(); + CDOSession session = node.cdoView().getSession(); + int sessionID = session.getSessionID(); CDOTransaction transaction = repositoryToTransaction.get(sessionID); if (transaction == null) { - transaction = node.cdoView().getSession().openTransaction(); - new CDOTransactionCommentator(transaction); + transaction = OpenTransactionAction.openTransaction(session); repositoryToTransaction.put(sessionID, transaction); } diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/TransactionalBackgroundActionDelegate.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/TransactionalBackgroundActionDelegate.java index a2d5fddd07..53bb077505 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/TransactionalBackgroundActionDelegate.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/actions/TransactionalBackgroundActionDelegate.java @@ -12,9 +12,9 @@ package org.eclipse.emf.cdo.internal.ui.actions; import org.eclipse.emf.cdo.CDOObject; -import org.eclipse.emf.cdo.transaction.CDOTransaction; -import org.eclipse.emf.cdo.transaction.CDOTransactionCommentator; import org.eclipse.emf.cdo.internal.ui.messages.Messages; +import org.eclipse.emf.cdo.session.CDOSession; +import org.eclipse.emf.cdo.transaction.CDOTransaction; import org.eclipse.emf.cdo.view.CDOView; import org.eclipse.net4j.util.AdapterUtil; @@ -104,8 +104,8 @@ public abstract class TransactionalBackgroundActionDelegate extends LongRunningA */ protected CDOObject preRun(CDOObject object) { - CDOTransaction transaction = object.cdoView().getSession().openTransaction(); - new CDOTransactionCommentator(transaction); + CDOSession session = object.cdoView().getSession(); + CDOTransaction transaction = OpenTransactionAction.openTransaction(session); CDOObject transactionalObject = transaction.getObject(object); return transactionalObject; diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/dialogs/OpenSessionDialog.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/dialogs/OpenSessionDialog.java index bf4f0a519d..d970fa7e10 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/dialogs/OpenSessionDialog.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/dialogs/OpenSessionDialog.java @@ -17,6 +17,7 @@ import org.eclipse.emf.cdo.ui.widgets.SessionComposite; import org.eclipse.jface.dialogs.TitleAreaDialog; import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Shell; @@ -29,6 +30,10 @@ public class OpenSessionDialog extends TitleAreaDialog { public static final String TITLE = Messages.getString("OpenSessionDialog.0"); //$NON-NLS-1$ + private static final int WIDTH = 380; + + private static final int HEIGHT = 240; + private IWorkbenchPage page; private SessionComposite sessionComposite; @@ -55,7 +60,11 @@ public class OpenSessionDialog extends TitleAreaDialog { super.configureShell(newShell); newShell.setText(TITLE); - newShell.setSize(380, 240); + + Rectangle bounds = page.getWorkbenchWindow().getShell().getBounds(); + int x = bounds.x + (bounds.width - WIDTH) / 2; + int y = bounds.y + (bounds.height - HEIGHT) / 2; + newShell.setBounds(x, y, WIDTH, HEIGHT); } @Override diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/views/CDOSessionsView.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/views/CDOSessionsView.java index 407b9618a0..3a171e1b5a 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/views/CDOSessionsView.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/views/CDOSessionsView.java @@ -12,6 +12,7 @@ package org.eclipse.emf.cdo.internal.ui.views; import org.eclipse.emf.cdo.eresource.CDOResourceLeaf; import org.eclipse.emf.cdo.internal.ui.actions.OpenSessionAction; +import org.eclipse.emf.cdo.internal.ui.actions.OpenTransactionAction; import org.eclipse.emf.cdo.internal.ui.transfer.RepositoryTransferDragListener; import org.eclipse.emf.cdo.session.CDOSession; import org.eclipse.emf.cdo.transfer.ui.TransferDropAdapter; @@ -100,7 +101,7 @@ public class CDOSessionsView extends ContainerView CDOSession session = (CDOSession)object; if (session.getViews().length == 0) { - session.openTransaction(); + OpenTransactionAction.openTransaction(session); return; } } 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 2c12579932..48527278e6 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 @@ -678,9 +678,12 @@ public class CDOItemProvider extends ContainerItemProvider> { super.elementAdded(element, parent); + // TODO Remove listeners? + if (element instanceof CDOSession) { - ((CDOSession)element).addListener(new IListener() + CDOSession session = (CDOSession)element; + session.addListener(new IListener() { public void notifyEvent(IEvent event) { @@ -694,7 +697,8 @@ public class CDOItemProvider extends ContainerItemProvider> if (element instanceof CDOView) { - ((CDOView)element).addListener(new IListener() + final CDOView view = (CDOView)element; + view.addListener(new IListener() { public void notifyEvent(IEvent event) { diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceImpl.java index 3ac5c5c9b5..b3d5b02813 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceImpl.java @@ -347,7 +347,6 @@ public class CDOResourceImpl extends CDOResourceLeafImpl implements InternalCDOR setPath(newPath); } - @Override public Object eGet(int featureID, boolean resolve, boolean coreType) { @@ -355,7 +354,7 @@ public class CDOResourceImpl extends CDOResourceLeafImpl implements InternalCDOR { case EresourcePackage.CDO_RESOURCE__URI: return getURI(); - + default: return super.eGet(featureID, resolve, coreType); } @@ -369,7 +368,7 @@ public class CDOResourceImpl extends CDOResourceLeafImpl implements InternalCDOR case EresourcePackage.CDO_RESOURCE__URI: setURI((URI)newValue); break; - + default: super.eSet(featureID, newValue); } @@ -1085,17 +1084,20 @@ public class CDOResourceImpl extends CDOResourceLeafImpl implements InternalCDOR } } - String query = initialURI.query(); - if (query != null && query.length() != 0) + if (initialURI != null) { - Map parameters = CDOURIUtil.getParameters(query); - String value = parameters.get(CDOResource.PREFETCH_PARAMETER); - if (value != null) + String query = initialURI.query(); + if (query != null && query.length() != 0) { - boolean prefetch = Boolean.parseBoolean(value); - if (prefetch) + Map parameters = CDOURIUtil.getParameters(query); + String value = parameters.get(CDOResource.PREFETCH_PARAMETER); + if (value != null) { - cdoPrefetch(CDORevision.DEPTH_INFINITE); + boolean prefetch = Boolean.parseBoolean(value); + if (prefetch) + { + cdoPrefetch(CDORevision.DEPTH_INFINITE); + } } } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java index 18fd7c1073..00a6bb8779 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java @@ -167,12 +167,13 @@ public class CDOObjectImpl extends MinimalEStoreEObjectImpl implements InternalC */ public final InternalCDORevision cdoRevision(boolean loadOnDemand) { - if (loadOnDemand) + InternalCDORevision revision = cdoRevision(); + if (revision == null && loadOnDemand) { - CDOStateMachine.INSTANCE.read(this); + revision = CDOStateMachine.INSTANCE.read(this); } - return cdoRevision(); + return revision; } /** diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java index 3193e5008e..1f03338766 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java @@ -789,15 +789,9 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa } conflict -= resolved; - if (conflict == 0) - { - setDirty(false); - } - else - { - Map dirtyObjects = getLastSavepoint().getDirtyObjects(); - setDirty(!dirtyObjects.isEmpty()); - } + + Map dirtyObjects = getLastSavepoint().getDirtyObjects(); + setDirty(!dirtyObjects.isEmpty()); } /** diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java index 73f451b239..116905abeb 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java @@ -58,6 +58,7 @@ import org.eclipse.emf.cdo.util.DanglingReferenceException; import org.eclipse.emf.cdo.util.InvalidURIException; import org.eclipse.emf.cdo.util.ObjectNotFoundException; import org.eclipse.emf.cdo.util.ReadOnlyException; +import org.eclipse.emf.cdo.view.CDOAdapterPolicy; import org.eclipse.emf.cdo.view.CDOObjectHandler; import org.eclipse.emf.cdo.view.CDOQuery; import org.eclipse.emf.cdo.view.CDOView; @@ -75,6 +76,7 @@ import org.eclipse.net4j.util.CheckUtil; import org.eclipse.net4j.util.ImplementationError; import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump; import org.eclipse.net4j.util.StringUtil; +import org.eclipse.net4j.util.WrappedException; import org.eclipse.net4j.util.collection.CloseableIterator; import org.eclipse.net4j.util.collection.ConcurrentArray; import org.eclipse.net4j.util.collection.Pair; @@ -111,6 +113,7 @@ import org.eclipse.emf.spi.cdo.InternalCDOViewSet; import org.eclipse.core.runtime.Platform; +import java.io.IOException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; @@ -331,6 +334,15 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl adapters = rootResource.eAdapters(); ContainerAdapter adapter = getContainerAdapter(adapters); @@ -373,6 +385,14 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl 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) + { + InternalCDORevision newLocalRevision = cleanRevision.copy(); + newLocalRevision.setVersion(newVersion); + resultDelta.apply(newLocalRevision); + return newLocalRevision; + } + + private InternalCDORevision computeNewCleanRevision(Map remoteDeltas, CDOID id, + int newVersion, InternalCDORevision cleanRevision) + { + CDORevisionDelta remoteDelta = remoteDeltas.get(id); + if (remoteDelta != null) + { + InternalCDORevision newCleanRevision = cleanRevision.copy(); + newCleanRevision.setVersion(newVersion); + remoteDelta.apply(newCleanRevision); + return newCleanRevision; + } + + return cleanRevision; + } + private Map getRemoteDeltas(CDOChangeSet remoteChangeSet) { Map remoteDeltas = CDOIDUtil.createMap(); diff --git a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/views/ContainerItemProvider.java b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/views/ContainerItemProvider.java index 761376d867..d80ea4dde8 100644 --- a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/views/ContainerItemProvider.java +++ b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/views/ContainerItemProvider.java @@ -122,14 +122,18 @@ public class ContainerItemProvider> extends } } - @Override - public void dispose() + /** + * @since 3.4 + */ + public void clearNodesCache() { - super.dispose(); + disposeRoot(); + + CONTAINER input = getInput(); + initRoot(input); } - @Override - protected void connectInput(CONTAINER input) + private void initRoot(CONTAINER input) { root = createNode(null, input); if (root != null) @@ -138,14 +142,25 @@ public class ContainerItemProvider> extends } } - @Override - protected void disconnectInput(CONTAINER input) + private void disposeRoot() { - root.dispose(); + root.dispose(); // Also disposes of all children root = null; nodes.clear(); } + @Override + protected void connectInput(CONTAINER input) + { + initRoot(input); + } + + @Override + protected void disconnectInput(CONTAINER input) + { + disposeRoot(); + } + /** * @since 2.0 */ @@ -620,8 +635,8 @@ public class ContainerItemProvider> extends if (!isDisposed()) { container.removeListener(containerListener); - container = null; super.dispose(); + container = null; } } diff --git a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/views/ContainerView.java b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/views/ContainerView.java index d1d46f218a..d752c16839 100644 --- a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/views/ContainerView.java +++ b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/views/ContainerView.java @@ -463,6 +463,7 @@ public abstract class ContainerView extends ViewPart implements ISelectionProvid */ protected void refreshPressed() { + itemProvider.clearNodesCache(); UIUtil.refreshViewer(viewer); } -- cgit v1.2.3