diff options
author | Esteban Dugueperoux | 2014-11-02 21:40:42 +0000 |
---|---|---|
committer | Esteban DUGUEPEROUX | 2014-11-03 10:39:16 +0000 |
commit | 58844da05c944cc00220ab4a35924fa83e60a24e (patch) | |
tree | 34e115822776cd83e46dfdfcc8d833e90f96c4cb | |
parent | 43fe7cfded275cd7857112cc91d85b8f6fc52783 (diff) | |
download | cdo-58844da05c944cc00220ab4a35924fa83e60a24e.tar.gz cdo-58844da05c944cc00220ab4a35924fa83e60a24e.tar.xz cdo-58844da05c944cc00220ab4a35924fa83e60a24e.zip |
[449665] IllegalArgumentException on CDOResource.cdoLockState()
IllegalArgumentException is thrown when calling
CDOResource.cdoLockState() in Adapter notification when calling
transaction.getResource(); because the CDOResource is in CDOState.PROXY
before CDOResource.load() is called.
Change-Id: Ia7f0cf2619857f7d787df28cdaa8ae368e8bbe28
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=449665
Signed-off-by: Esteban Dugueperoux <esteban.dugueperoux@obeo.fr>
4 files changed, 137 insertions, 40 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_449665_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_449665_Test.java new file mode 100644 index 0000000000..b410a2058d --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_449665_Test.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2014 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: + * Esteban Dugueperoux - 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.lock.CDOLockState; +import org.eclipse.emf.cdo.eresource.CDOResource; +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.transaction.CDOTransaction; +import org.eclipse.emf.cdo.util.CDOUtil; + +import org.eclipse.emf.common.notify.Notifier; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EContentAdapter; + +import org.junit.Assert; + +/** + * Bug 449665 about {@link CDOLockState} on {@link CDOResource} in {@link CDOState#PROXY} state. + * + * @author Esteban Dugueperoux + */ +public class Bugzilla_449665_Test extends AbstractCDOTest +{ + private static final String RESOURCE_NAME = "test1.model1"; + + /** + * Test {@link CDOObject#cdoLockState()} on a simple {@link CDOObject} in {@link CDOState#PROXY} state. + */ + public void testCDOObject_GetLockState() throws Exception + { + CDOSession session1 = openSession(); + CDOTransaction transaction1 = session1.openTransaction(); + CDOResource resource1 = transaction1.createResource(getResourcePath(RESOURCE_NAME)); + Company company = getModel1Factory().createCompany(); + resource1.getContents().add(company); + transaction1.commit(); + + CDOSession session2 = openSession(); + CDOTransaction transaction2 = session2.openTransaction(); + transaction2.getResourceSet().eAdapters().add(new EContentAdapterQueringCDOLockState()); + CDOResource resource2 = transaction2.getResource(getResourcePath(RESOURCE_NAME)); + + // Make company in CDOState.PROXY by remote change + company.setName("oneChange"); + resource1.getContents().add(getModel1Factory().createCategory()); + commitAndSync(transaction1, transaction2); + + company = (Company)resource2.getContents().get(0); + CDOObject companyCDOObject = CDOUtil.getCDOObject(company); + CDOLockState lockState = companyCDOObject.cdoLockState(); + assertEquals(companyCDOObject.cdoID(), lockState.getLockedObject()); + Assert.assertTrue(lockState.getReadLockOwners().isEmpty()); + assertNull(lockState.getWriteLockOwner()); + assertNull(lockState.getWriteOptionOwner()); + } + + /** + * Test {@link CDOObject#cdoLockState()} on a {@link CDOResource} in {@link CDOState#PROXY} state. + */ + public void testCDOResource_GetLockState() throws Exception + { + CDOSession session1 = openSession(); + CDOTransaction transaction1 = session1.openTransaction(); + CDOResource resource1 = transaction1.createResource(getResourcePath(RESOURCE_NAME)); + transaction1.commit(); + + CDOSession session2 = openSession(); + CDOTransaction transaction2 = session2.openTransaction(); + transaction2.getResourceSet().eAdapters().add(new EContentAdapterQueringCDOLockState()); + CDOResource resource2 = transaction2.getResource(getResourcePath(RESOURCE_NAME)); + + // Make CDOResouce in CDOState.PROXY by remote change + resource1.getContents().add(getModel1Factory().createCategory()); + commitAndSync(transaction1, transaction2); + + CDOLockState lockState = resource2.cdoLockState(); + assertEquals(resource2.cdoID(), lockState.getLockedObject()); + Assert.assertTrue(lockState.getReadLockOwners().isEmpty()); + assertNull(lockState.getWriteLockOwner()); + assertNull(lockState.getWriteOptionOwner()); + } + + /** + * A {@link EContentAdapter} to get {@link CDOLockState} for each loaded object. + */ + private static class EContentAdapterQueringCDOLockState extends EContentAdapter + { + + @Override + protected void addAdapter(Notifier notifier) + { + if (notifier instanceof EObject) + { + EObject eObject = (EObject)notifier; + CDOObject cdoObject = CDOUtil.getCDOObject(eObject); + if (cdoObject != null) + { + cdoObject.cdoLockState(); + } + } + + super.addAdapter(notifier); + + } + } +} 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 6852e2516a..9e5cd5b99e 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 @@ -30,7 +30,6 @@ import org.eclipse.emf.cdo.view.CDOView; import org.eclipse.emf.cdo.view.CDOViewProvider; import org.eclipse.emf.cdo.view.CDOViewProviderRegistry; -import org.eclipse.emf.internal.cdo.bundle.OM; import org.eclipse.emf.internal.cdo.view.CDOStateMachine; import org.eclipse.net4j.util.WrappedException; @@ -1096,26 +1095,6 @@ public class CDOResourceImpl extends CDOResourceLeafImpl implements CDOResource, { if (!isLoaded()) { - InternalCDOView view = cdoView(); - if (!FSMUtil.isTransient(this)) - { - CDOID id = cdoID(); - if (id == null) - { - registerProxy(view); - } - else - { - synchronized (view) - { - if (!view.isObjectRegistered(id)) - { - registerProxy(view); - } - } - } - } - if (initialURI != null) { String query = initialURI.query(); @@ -1192,21 +1171,6 @@ public class CDOResourceImpl extends CDOResourceLeafImpl implements CDOResource, } } - private void registerProxy(InternalCDOView view) throws IOWrappedException - { - try - { - view.registerProxyResource(this); - } - catch (Exception ex) - { - OM.LOG.error(ex); - setExisting(false); - cdoInternalSetState(CDOState.TRANSIENT); - throw new IOWrappedException(ex); - } - } - /** * Returns the URI converter. This typically gets the {@link ResourceSet#getURIConverter converter} from the * {@link #getResourceSet containing} resource set, but it calls {@link #getDefaultURIConverter} when there is no @@ -1589,11 +1553,15 @@ public class CDOResourceImpl extends CDOResourceLeafImpl implements CDOResource, catch (RuntimeException ex) { resourceSet.getResources().remove(this); + setExisting(false); + cdoInternalSetState(CDOState.TRANSIENT); throw ex; } catch (Error ex) { resourceSet.getResources().remove(this); + setExisting(false); + cdoInternalSetState(CDOState.TRANSIENT); throw ex; } 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 5bd8ec4b46..d873e8406f 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 @@ -1438,12 +1438,10 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb // ResourceSet.getResource(uri, true) was called!! resource.cdoInternalSetView(this); resource.cdoInternalSetState(CDOState.PROXY); + registerProxyResource2(resource); } - /** - * @since 2.0 - */ - public synchronized void registerProxyResource(CDOResourceImpl resource) + private synchronized void registerProxyResource2(CDOResourceImpl resource) { URI uri = resource.getURI(); String path = CDOURIUtil.extractResourcePath(uri); @@ -1480,6 +1478,15 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb } /** + * @deprecated No longer supported. + */ + @Deprecated + public synchronized void registerProxyResource(CDOResourceImpl resource) + { + registerProxyResource2(resource); + } + + /** * Does the same as {@link AbstractCDOView#registerObject(InternalCDOObject)}, but without * throwing any exception if object is already registered (in that case it will simply do nothing). * diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java index 7a7d12c8ab..d21cb63618 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java @@ -120,6 +120,10 @@ public interface InternalCDOView extends CDOView, CDOIDProvider, ILifecycle public CDOID getResourceNodeID(String path); + /** + * @deprecated No longer supported. + */ + @Deprecated public void registerProxyResource(CDOResourceImpl resource); public void registerObject(InternalCDOObject object); |