Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2019-02-03 03:37:04 -0500
committerEike Stepper2019-02-03 03:37:04 -0500
commit9b86d2e358a5d6785be4cf1c4502fcde0f5406c0 (patch)
tree757c7a05c79ea03dbcba7cd7de92ee32ff023d8d
parent5a214bcbdf877c8f9bcca90ad5d1d09ede54fc05 (diff)
downloadcdo-9b86d2e358a5d6785be4cf1c4502fcde0f5406c0.tar.gz
cdo-9b86d2e358a5d6785be4cf1c4502fcde0f5406c0.tar.xz
cdo-9b86d2e358a5d6785be4cf1c4502fcde0f5406c0.zip
[544075] Add setBasename() and setExtension() methods to CDOResourceNode
https://bugs.eclipse.org/bugs/show_bug.cgi?id=544075
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ResourceTest.java82
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_334995_Test.java66
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/CDOResourceNode.java20
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceNodeImpl.java172
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java18
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java50
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java3
7 files changed, 371 insertions, 40 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ResourceTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ResourceTest.java
index 6e3e3630b5..ffe071c98a 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ResourceTest.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/ResourceTest.java
@@ -2218,6 +2218,88 @@ public class ResourceTest extends AbstractCDOTest
}
}
+ public void testNameChecks()
+ {
+ CDOSession session = openSession();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource1 = transaction.createResource(getResourcePath("/my/resource1"));
+
+ assertEquals("resource1", resource1.getName());
+ assertEquals("resource1", resource1.getBasename());
+ assertEquals("", resource1.getExtension());
+
+ try
+ {
+ resource1.setName("/resource1");
+ fail("IllegalArgumentException expected");
+ }
+ catch (IllegalArgumentException expected)
+ {
+ // SUCCESS
+ }
+
+ resource1.setExtension("tar.gz");
+ assertEquals("resource1.tar.gz", resource1.getName());
+ assertEquals("resource1", resource1.getBasename());
+ assertEquals("tar.gz", resource1.getExtension());
+
+ resource1.setBasename("model");
+ assertEquals("model.tar.gz", resource1.getName());
+ assertEquals("model", resource1.getBasename());
+ assertEquals("tar.gz", resource1.getExtension());
+
+ try
+ {
+ resource1.setBasename("model.xyz");
+ fail("IllegalArgumentException expected");
+ }
+ catch (IllegalArgumentException expected)
+ {
+ // SUCCESS
+ }
+
+ resource1.setExtension("");
+ assertEquals("model", resource1.getName());
+ assertEquals("model", resource1.getBasename());
+ assertEquals("", resource1.getExtension());
+
+ resource1.setExtension("ecore");
+ resource1.setBasename("");
+ assertEquals(".ecore", resource1.getName());
+ assertEquals("", resource1.getBasename());
+ assertEquals("ecore", resource1.getExtension());
+
+ try
+ {
+ resource1.setName(null);
+ fail("IllegalArgumentException expected");
+ }
+ catch (IllegalArgumentException expected)
+ {
+ // SUCCESS
+ }
+
+ try
+ {
+ resource1.setName("");
+ fail("IllegalArgumentException expected");
+ }
+ catch (IllegalArgumentException expected)
+ {
+ // SUCCESS
+ }
+
+ try
+ {
+ resource1.setName(".");
+ fail("IllegalArgumentException expected");
+ }
+ catch (IllegalArgumentException expected)
+ {
+ // SUCCESS
+ }
+ }
+
/**
* @author Eike Stepper
*/
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_334995_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_334995_Test.java
index 79ea70ff09..873eddf9d4 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_334995_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_334995_Test.java
@@ -18,6 +18,8 @@ import org.eclipse.emf.cdo.tests.AbstractCDOTest;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CommitException;
+import org.eclipse.emf.ecore.resource.Resource;
+
import java.util.Map.Entry;
/**
@@ -30,37 +32,55 @@ public class Bugzilla_334995_Test extends AbstractCDOTest
/**
* The following test seems obsolete because (as of bug xxxxxx) no local changes can create resource duplicates.
*/
- public void _test() throws CommitException
+ public void testURIClash() throws CommitException
{
- CDOID resourceID = persistResources("/res1")[0];
+ CDOSession session = openSession();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resourceA = transaction.createResource(getResourcePath("/resA"));
+ resourceA.getContents().add(getModel1Factory().createCustomer());
+ transaction.commit();
+ System.out.println("Persisted resource: " + resourceA);
- {
- CDOSession session = openSession();
- CDOTransaction transaction = session.openTransaction();
+ CDOSession session2 = openSession();
+ CDOTransaction transaction2 = session2.openTransaction();
+ CDOResource resourceB2 = transaction2.createResource(getResourcePath("/resB"));
+ resourceB2.getContents().add(getModel1Factory().createSupplier());
- CDOResource resource = transaction.createResource(getResourcePath("/res1"));
- msg("New resource: " + resource);
- msg("newObjects:");
+ resourceA.setName("resB");
+ commitAndSync(transaction, transaction2);
- for (Entry<CDOID, CDOObject> entry : transaction.getNewObjects().entrySet())
- {
- msg(" " + entry + ", state: " + entry.getValue().cdoState());
- assertNew(entry.getValue(), transaction);
- }
+ System.out.println("newObjects:");
+ for (Entry<CDOID, CDOObject> entry : transaction2.getNewObjects().entrySet())
+ {
+ System.out.println(" " + entry + ", state: " + entry.getValue().cdoState());
+ assertNew(entry.getValue(), transaction2);
+ }
- // Fetch the persisted resource that has the same URI
- CDOResource resource1 = (CDOResource)transaction.getObject(resourceID);
- msg("Persisted resource: " + resource1);
+ System.out.println("resources:");
+ for (Resource resource : transaction2.getResourceSet().getResources())
+ {
+ System.out.println(" " + resource);
+ }
- msg("newObjects:");
- for (Entry<CDOID, CDOObject> entry : transaction.getNewObjects().entrySet())
- {
- msg(" " + entry + ", state: " + entry.getValue().cdoState());
- assertNew(entry.getValue(), transaction);
- }
+ // Fetch the persisted resource that has the same URI
+ CDOResource resourceA2 = (CDOResource)transaction2.getObject(resourceA.cdoID());
+ System.out.println("Remote resource: " + resourceA2);
+ System.out.println("Local resource: " + resourceB2);
- transaction.commit();
+ System.out.println("newObjects:");
+ for (Entry<CDOID, CDOObject> entry : transaction2.getNewObjects().entrySet())
+ {
+ System.out.println(" " + entry + ", state: " + entry.getValue().cdoState());
+ assertNew(entry.getValue(), transaction2);
}
+
+ System.out.println("resources:");
+ for (Resource resource : transaction2.getResourceSet().getResources())
+ {
+ System.out.println(" " + resource);
+ }
+
+ transaction2.commit();
}
public void testRename() throws CommitException
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/CDOResourceNode.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/CDOResourceNode.java
index bcb9068078..b1ce8ba26f 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/CDOResourceNode.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/CDOResourceNode.java
@@ -144,12 +144,32 @@ public interface CDOResourceNode extends CDOObject
/**
* @ADDED
+ * @since 4.7
+ */
+ public void setExtension(String extension);
+
+ /**
+ * Same as {@link #getBasename()}.
+ *
+ * @ADDED
* @since 4.4
*/
public String trimExtension();
/**
* @ADDED
+ * @since 4.7
+ */
+ public String getBasename();
+
+ /**
+ * @ADDED
+ * @since 4.7
+ */
+ public void setBasename(String basename);
+
+ /**
+ * @ADDED
*/
public URI getURI();
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceNodeImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceNodeImpl.java
index 40eb6ebf6b..acfaf96dc8 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceNodeImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/eresource/impl/CDOResourceNodeImpl.java
@@ -24,7 +24,10 @@ import org.eclipse.emf.cdo.util.CDOURIUtil;
import org.eclipse.emf.internal.cdo.CDOObjectImpl;
import org.eclipse.emf.internal.cdo.messages.Messages;
+import org.eclipse.net4j.util.CheckUtil;
import org.eclipse.net4j.util.ObjectUtil;
+import org.eclipse.net4j.util.StringUtil;
+import org.eclipse.net4j.util.om.OMPlatform;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
@@ -52,6 +55,12 @@ import java.util.List;
*/
public abstract class CDOResourceNodeImpl extends CDOObjectImpl implements CDOResourceNode
{
+ private static final boolean disableNameChecks = OMPlatform.INSTANCE.isProperty("org.eclipse.emf.cdo.CDOResourceNode.disableNameChecks");
+
+ private static final boolean singleExtensions = OMPlatform.INSTANCE.isProperty("org.eclipse.emf.cdo.CDOResourceNode.singleExtensions");
+
+ private static final ExtensionFinder EXTENSION_FINDER = singleExtensions ? new ExtensionFinder.Single() : new ExtensionFinder.Multi();
+
/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
* @generated
@@ -171,6 +180,14 @@ public abstract class CDOResourceNodeImpl extends CDOObjectImpl implements CDORe
*/
public void basicSetName(String newName, boolean checkDuplicates)
{
+ if (!disableNameChecks)
+ {
+ CheckUtil.checkArg(newName, "Name is null");
+ CheckUtil.checkArg(newName.length() != 0, "Name is empty");
+ CheckUtil.checkArg(!".".equals(newName), "Name is a dot");
+ CheckUtil.checkArg(newName.indexOf(CDOURIUtil.SEGMENT_SEPARATOR_CHAR) == -1, "Name contains a path separator");
+ }
+
String oldName = getName();
if (!ObjectUtil.equals(oldName, newName))
{
@@ -251,33 +268,141 @@ public abstract class CDOResourceNodeImpl extends CDOObjectImpl implements CDORe
public String getExtension()
{
String name = getName();
-
- int lastDot = name.lastIndexOf('.');
- if (lastDot != -1)
+ if (name != null)
{
- return name.substring(lastDot + 1);
+ int dot = EXTENSION_FINDER.findExtension(name);
+ if (dot != -1)
+ {
+ return name.substring(dot + 1);
+ }
}
return "";
}
/**
+ * @since 4.7
+ */
+ public void setExtension(String extension)
+ {
+ InternalCDOView view = cdoView();
+ if (view != null)
+ {
+ synchronized (view.getViewMonitor())
+ {
+ view.lockView();
+
+ try
+ {
+ setExtensionSynced(extension);
+ }
+ finally
+ {
+ view.unlockView();
+ }
+ }
+ }
+ else
+ {
+ setExtensionSynced(extension);
+ }
+ }
+
+ private void setExtensionSynced(String extension)
+ {
+ if (StringUtil.isEmpty(extension))
+ {
+ setName(getBasename());
+ }
+ else
+ {
+ if (singleExtensions)
+ {
+ CheckUtil.checkArg(extension.indexOf(ExtensionFinder.DOT) == -1, "Extension contains a dot");
+ }
+
+ setName(getBasename() + ExtensionFinder.DOT + extension);
+ }
+ }
+
+ /**
* @since 4.4
*/
public String trimExtension()
{
- String name = getName();
+ return getBasename();
+ }
- int lastDot = name.lastIndexOf('.');
- if (lastDot != -1)
+ /**
+ * @since 4.7
+ */
+ public String getBasename()
+ {
+ String name = getName();
+ if (name != null)
{
- return name.substring(0, lastDot);
+ int dot = EXTENSION_FINDER.findExtension(name);
+ if (dot != -1)
+ {
+ return name.substring(0, dot);
+ }
}
return name;
}
/**
+ * @since 4.7
+ */
+ public void setBasename(String basename)
+ {
+ InternalCDOView view = cdoView();
+ if (view != null)
+ {
+ synchronized (view.getViewMonitor())
+ {
+ view.lockView();
+
+ try
+ {
+ setBasenameSynced(basename);
+ }
+ finally
+ {
+ view.unlockView();
+ }
+ }
+ }
+ else
+ {
+ setBasenameSynced(basename);
+ }
+ }
+
+ private void setBasenameSynced(String basename)
+ {
+ if (basename == null)
+ {
+ basename = StringUtil.EMPTY;
+ }
+
+ if (!singleExtensions)
+ {
+ CheckUtil.checkArg(basename.indexOf(ExtensionFinder.DOT) == -1, "Basename contains a dot");
+ }
+
+ String extension = getExtension();
+ if (StringUtil.isEmpty(extension))
+ {
+ setName(basename);
+ }
+ else
+ {
+ setName(basename + ExtensionFinder.DOT + extension);
+ }
+ }
+
+ /**
* @ADDED
*/
public URI getURI()
@@ -377,4 +502,35 @@ public abstract class CDOResourceNodeImpl extends CDOObjectImpl implements CDORe
return string;
}
+ /**
+ * @author Eike Stepper
+ */
+ private interface ExtensionFinder
+ {
+ public static final char DOT = '.';
+
+ public int findExtension(String name);
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class Single implements ExtensionFinder
+ {
+ public int findExtension(String name)
+ {
+ return name.lastIndexOf(DOT);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class Multi implements ExtensionFinder
+ {
+ public int findExtension(String name)
+ {
+ return name.indexOf(DOT);
+ }
+ }
+ }
} // CDOResourceNodeImpl
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 9532476c2a..df136ab159 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
@@ -3725,6 +3725,24 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
}
}
+ @Override
+ protected Map<String, CDOResourceNode> collectNewResourceNodes()
+ {
+ Map<String, CDOResourceNode> result = new HashMap<String, CDOResourceNode>();
+
+ for (CDOObject object : getNewObjects().values())
+ {
+ if (object instanceof CDOResourceNode)
+ {
+ CDOResourceNode node = (CDOResourceNode)object;
+ String path = node.getPath();
+ result.put(path, node);
+ }
+ }
+
+ return result;
+ }
+
private Set<CDOObject> getObjects(Collection<? extends CDOIdentifiable> identifiables)
{
Set<CDOObject> result = new HashSet<CDOObject>();
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 5869873147..7aeb0e396b 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
@@ -152,6 +152,8 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb
private static final String REPOSITORY_NAME_KEY = "cdo.repository.name";
+ private static final String SAFE_RENAME = "~renamed";
+
private static final ThreadLocal<Lock> NEXT_VIEW_LOCK = new ThreadLocal<Lock>();
private final ViewAndState[] viewAndStates = ViewAndState.create(this);
@@ -2055,16 +2057,11 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb
URI uri = CDOURIUtil.createResourceURI(this, path);
ResourceSet resourceSet = getResourceSet();
- // Bug 334995: Check if locally there is already a resource with the same URI
+ // Bug 334995: Check if locally there is already a resource with the same URI.
CDOResource existingResource = (CDOResource)resourceSet.getResource(uri, false);
if (existingResource != null && !isReadOnly())
{
- // We have no other option than to change the name of the local resource
- String oldName = existingResource.getName();
- existingResource.setName(oldName + ".renamed");
-
- OM.LOG.warn("URI clash: resource being instantiated had same URI as a resource already present " + "locally; local resource was renamed from " + oldName
- + " to " + existingResource.getName());
+ preventURIClash(existingResource);
}
return getResource(path, true);
@@ -2660,7 +2657,7 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb
}
/*
- * Synchronized through InvalidationRunner.run()
+ * Synchronized through CDOViewImpl.ViewInvalidation.run().
*/
protected Map<CDOObject, Pair<CDORevision, CDORevisionDelta>> invalidate( //
List<CDORevisionKey> allChangedObjects, //
@@ -2699,6 +2696,7 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb
}
}
+ Map<String, CDOResourceNode> newResourceNodes = null;
for (CDORevisionKey key : allChangedObjects)
{
CDORevisionDelta delta = null;
@@ -2729,6 +2727,25 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb
{
if (delta == null || isResourceNodeContainerOrNameChanged(delta))
{
+ if (!isReadOnly())
+ {
+ if (newResourceNodes == null)
+ {
+ newResourceNodes = collectNewResourceNodes();
+ }
+
+ CDOResourceNode changedNode = (CDOResourceNode)changedObject;
+ String path = changedNode.getPath();
+
+ CDOResourceNode newResourceNode = newResourceNodes.get(path);
+ if (newResourceNode != null)
+ {
+ preventURIClash(newResourceNode);
+ String oldName = newResourceNode.getBasename();
+ newResourceNode.setBasename(oldName + SAFE_RENAME);
+ }
+ }
+
((CDOResourceNodeImpl)changedObject).recacheURIs();
}
}
@@ -2764,6 +2781,11 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb
return false;
}
+ protected Map<String, CDOResourceNode> collectNewResourceNodes()
+ {
+ return Collections.emptyMap();
+ }
+
/**
* Overridden by {@link CDOTransactionImpl#handleConflicts(long, Map, List)}.
*/
@@ -3102,6 +3124,18 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb
return false;
}
+ private static void preventURIClash(CDOResourceNode node)
+ {
+ String oldName = node.getName();
+
+ // We have no other option than to change the name of the local resource.
+ String oldBasename = node.getBasename();
+ node.setBasename(oldBasename + SAFE_RENAME);
+
+ OM.LOG.warn("URI clash: resource being instantiated had same URI as a resource already present locally; local resource was renamed from " //
+ + oldName + " to " + node.getName());
+ }
+
/**
* @author Eike Stepper
*/
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
index 40cf5f71ae..1037eb216e 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
@@ -1120,6 +1120,7 @@ public class CDOViewImpl extends AbstractCDOView implements IExecutorServiceProv
public void prefetchRevisions(CDOID id, int depth)
{
checkArg(depth != CDORevision.DEPTH_NONE, "Prefetch depth must not be zero"); //$NON-NLS-1$
+
synchronized (getViewMonitor())
{
lockView();
@@ -1159,7 +1160,7 @@ public class CDOViewImpl extends AbstractCDOView implements IExecutorServiceProv
/*
* Must not by synchronized on the view!
*/
- public /* synchronized */ void invalidate(ViewInvalidationData invalidationData)
+ public void invalidate(ViewInvalidationData invalidationData)
{
if (invalidationData.isAsync())
{

Back to the top