summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCaspar De Groot2010-06-14 23:54:24 (EDT)
committerCaspar De Groot2010-06-14 23:54:24 (EDT)
commite9cfb00d5f650abcebf577cb4b5049c770aadcdb (patch)
tree7c16c2aabfa553a6602e0e9640f97c92affcfb40
parent9dccc5f76e1831d335dc7ecdfbaa36cfc853ea91 (diff)
downloadcdo-e9cfb00d5f650abcebf577cb4b5049c770aadcdb.zip
cdo-e9cfb00d5f650abcebf577cb4b5049c770aadcdb.tar.gz
cdo-e9cfb00d5f650abcebf577cb4b5049c770aadcdb.tar.bz2
[302414] ArrayIndexOutOfBoundsException in CDOListFeatureDeltaImpl
https://bugs.eclipse.org/bugs/show_bug.cgi?id=302414
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOListFeatureDeltaImpl.java70
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsAllConfigs.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_302414_Test.java65
3 files changed, 104 insertions, 33 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOListFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOListFeatureDeltaImpl.java
index a839f55..e4f5b5c 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOListFeatureDeltaImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOListFeatureDeltaImpl.java
@@ -40,11 +40,11 @@ public class CDOListFeatureDeltaImpl extends CDOFeatureDeltaImpl implements CDOL
{
private List<CDOFeatureDelta> featureDeltas = new ArrayList<CDOFeatureDelta>();
- private transient int[] cacheIndices;
+ private transient int[] cachedIndices;
- private transient IListTargetAdding[] cacheSources;
+ private transient IListTargetAdding[] cachedSources;
- private transient List<CDOFeatureDelta> notProcessedFeatureDelta;
+ private transient List<CDOFeatureDelta> unprocessedFeatureDeltas;
public CDOListFeatureDeltaImpl(EStructuralFeature feature)
{
@@ -102,57 +102,61 @@ public class CDOListFeatureDeltaImpl extends CDOFeatureDeltaImpl implements CDOL
public Pair<IListTargetAdding[], int[]> reconstructAddedIndices()
{
reconstructAddedIndicesWithNoCopy();
- return new Pair<IListTargetAdding[], int[]>(copyOf(cacheSources, cacheSources.length, cacheSources.getClass()),
- copyOf(cacheIndices, cacheIndices.length));
+ return new Pair<IListTargetAdding[], int[]>(copyOf(cachedSources, cachedSources.length, cachedSources.getClass()),
+ copyOf(cachedIndices, cachedIndices.length));
}
private void reconstructAddedIndicesWithNoCopy()
{
- if (cacheIndices == null || notProcessedFeatureDelta != null)
+ if (cachedIndices == null || unprocessedFeatureDeltas != null)
{
- if (cacheIndices == null)
+ List<CDOFeatureDelta> featureDeltasToBeProcessed = unprocessedFeatureDeltas == null ? featureDeltas
+ : unprocessedFeatureDeltas;
+
+ // Actually the required capacity is the number of ListTargetAdding instances in the
+ // featureDeltasToBeProcessed.. so this is an overestimate
+ int requiredCapacity = featureDeltasToBeProcessed.size() + 1;
+
+ if (cachedIndices == null)
{
- cacheIndices = new int[1 + featureDeltas.size()];
+ cachedIndices = new int[1 + featureDeltas.size()];
}
- else if (cacheIndices.length <= 1 + featureDeltas.size())
+ else if (cachedIndices.length < requiredCapacity)
{
- int newCapacity = Math.max(10, cacheIndices.length * 3 / 2 + 1);
+ int newCapacity = Math.max(requiredCapacity, cachedIndices.length * 3 / 2);
int[] newElements = new int[newCapacity];
- System.arraycopy(cacheIndices, 0, newElements, 0, cacheIndices.length);
- cacheIndices = newElements;
+ System.arraycopy(cachedIndices, 0, newElements, 0, cachedIndices.length);
+ cachedIndices = newElements;
}
- if (cacheSources == null)
+ if (cachedSources == null)
{
- cacheSources = new IListTargetAdding[1 + featureDeltas.size()];
+ cachedSources = new IListTargetAdding[requiredCapacity];
}
- else if (cacheSources.length <= 1 + featureDeltas.size())
+ else if (cachedSources.length <= requiredCapacity)
{
- int newCapacity = Math.max(10, cacheSources.length * 3 / 2 + 1);
+ int newCapacity = Math.max(requiredCapacity, cachedSources.length * 3 / 2);
IListTargetAdding[] newElements = new IListTargetAdding[newCapacity];
- System.arraycopy(cacheSources, 0, newElements, 0, cacheSources.length);
- cacheSources = newElements;
+ System.arraycopy(cachedSources, 0, newElements, 0, cachedSources.length);
+ cachedSources = newElements;
}
- List<CDOFeatureDelta> featureDeltasToBeProcess = notProcessedFeatureDelta == null ? featureDeltas
- : notProcessedFeatureDelta;
-
- for (CDOFeatureDelta featureDelta : featureDeltasToBeProcess)
+ for (CDOFeatureDelta featureDelta : featureDeltasToBeProcessed)
{
if (featureDelta instanceof IListIndexAffecting)
{
IListIndexAffecting affecting = (IListIndexAffecting)featureDelta;
- affecting.affectIndices(cacheSources, cacheIndices);
+ affecting.affectIndices(cachedSources, cachedIndices);
}
if (featureDelta instanceof IListTargetAdding)
{
- cacheIndices[++cacheIndices[0]] = ((IListTargetAdding)featureDelta).getIndex();
- cacheSources[cacheIndices[0]] = (IListTargetAdding)featureDelta;
+ cachedIndices[++cachedIndices[0]] = ((IListTargetAdding)featureDelta).getIndex();
+ cachedSources[cachedIndices[0]] = (IListTargetAdding)featureDelta;
}
}
- notProcessedFeatureDelta = null;
+ unprocessedFeatureDeltas = null;
}
}
@@ -165,25 +169,25 @@ public class CDOListFeatureDeltaImpl extends CDOFeatureDeltaImpl implements CDOL
int indexToRemove = ((CDORemoveFeatureDelta)featureDelta).getIndex();
reconstructAddedIndicesWithNoCopy();
- for (int i = 1; i <= cacheIndices[0]; i++)
+ for (int i = 1; i <= cachedIndices[0]; i++)
{
- int index = cacheIndices[i];
+ int index = cachedIndices[i];
if (indexToRemove == index)
{
- cacheSources[i].clear();
+ cachedSources[i].clear();
break;
}
}
}
- if (cacheIndices != null)
+ if (cachedIndices != null)
{
- if (notProcessedFeatureDelta == null)
+ if (unprocessedFeatureDeltas == null)
{
- notProcessedFeatureDelta = new ArrayList<CDOFeatureDelta>();
+ unprocessedFeatureDeltas = new ArrayList<CDOFeatureDelta>();
}
- notProcessedFeatureDelta.add(featureDelta);
+ unprocessedFeatureDeltas.add(featureDelta);
}
}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsAllConfigs.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsAllConfigs.java
index bf328ca..1a56903 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsAllConfigs.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllTestsAllConfigs.java
@@ -62,6 +62,7 @@ import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_294850_Test;
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_294859_Test;
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_299190_Test;
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_301671_Test;
+import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_302414_Test;
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_316175_Test;
import org.eclipse.emf.cdo.tests.config.impl.ConfigTest;
import org.eclipse.emf.cdo.tests.config.impl.ConfigTestSuite;
@@ -173,6 +174,7 @@ public abstract class AllTestsAllConfigs extends ConfigTestSuite
testClasses.add(Bugzilla_294859_Test.class);
testClasses.add(Bugzilla_299190_Test.class);
testClasses.add(Bugzilla_301671_Test.class);
+ testClasses.add(Bugzilla_302414_Test.class);
testClasses.add(Bugzilla_316175_Test.class);
// TODO testClasses.add(NonCDOResourceTest.class);
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_302414_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_302414_Test.java
new file mode 100644
index 0000000..ab1f145
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_302414_Test.java
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2004 - 2010 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:
+ * Caspar De Groot - initial API and implementation
+ */
+package org.eclipse.emf.cdo.tests.bugzilla;
+
+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.tests.model1.Model1Factory;
+import org.eclipse.emf.cdo.tests.model1.PurchaseOrder;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+
+import java.util.List;
+
+/**
+ * @author Caspar De Groot
+ */
+public class Bugzilla_302414_Test extends AbstractCDOTest
+{
+ public void test()
+ {
+ CDOSession session = openSession();
+ CDOTransaction tx = session.openTransaction();
+ CDOResource r1 = tx.createResource("/r1"); //$NON-NLS-1$
+
+ Company company = Model1Factory.eINSTANCE.createCompany();
+ r1.getContents().add(company);
+ tx.commit();
+
+ List<PurchaseOrder> list = company.getPurchaseOrders();
+
+ PurchaseOrder foo = Model1Factory.eINSTANCE.createPurchaseOrder();
+ list.add(foo);
+ list.remove(foo);
+
+ PurchaseOrder bar = Model1Factory.eINSTANCE.createPurchaseOrder();
+ list.add(bar);
+
+ for (int i = 0; i < 10; i++)
+ {
+ company.getPurchaseOrders().add(Model1Factory.eINSTANCE.createPurchaseOrder());
+ }
+
+ try
+ {
+ list.remove(bar);
+ }
+ catch (ArrayIndexOutOfBoundsException e)
+ {
+ e.printStackTrace();
+ fail("Should not have thrown " + e.getClass().getName());
+ }
+
+ tx.close();
+ session.close();
+ }
+}