Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2012-05-01 15:45:31 +0000
committerEike Stepper2012-05-01 15:45:31 +0000
commit5b576d6563e340f01b169e608f5e0596202a1230 (patch)
treeaaf1b02c3463dcbedd55212dc82a34bfa86528a5
parentb4d78150e6b5b2277fa70ee3df3ccc1c2e6d2b48 (diff)
downloadcdo-5b576d6563e340f01b169e608f5e0596202a1230.tar.gz
cdo-5b576d6563e340f01b169e608f5e0596202a1230.tar.xz
cdo-5b576d6563e340f01b169e608f5e0596202a1230.zip
[369646] [DB] ClassCastException after setBranch when server cache contains partially loaded collections
https://bugs.eclipse.org/bugs/show_bug.cgi?id=369646
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java1105
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java29
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java16
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java16
-rw-r--r--plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java2241
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/DelegatingRepository.java829
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java3966
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java9
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/View.java620
-rw-r--r--plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java485
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java3265
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java2
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java3708
14 files changed, 8317 insertions, 7984 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java
index 24124dcb4d..a5265ea4b0 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java
@@ -1,553 +1,552 @@
-/*
- * Copyright (c) 2004 - 2012 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
- * Simon McDuff - bug 201266
- * Simon McDuff - bug 204890
- */
-package org.eclipse.emf.cdo.internal.common.revision.delta;
-
-import org.eclipse.emf.cdo.common.branch.CDOBranch;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.id.CDOWithID;
-import org.eclipse.emf.cdo.common.model.CDOModelUtil;
-import org.eclipse.emf.cdo.common.protocol.CDODataInput;
-import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
-import org.eclipse.emf.cdo.common.revision.CDOElementProxy;
-import org.eclipse.emf.cdo.common.revision.CDOList;
-import org.eclipse.emf.cdo.common.revision.CDORevisable;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.CDORevisionData;
-import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
-import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
-import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta;
-import org.eclipse.emf.cdo.common.util.PartialCollectionLoadingNotSupportedException;
-import org.eclipse.emf.cdo.internal.common.revision.CDOListImpl;
-import org.eclipse.emf.cdo.internal.common.revision.CDORevisionImpl;
-import org.eclipse.emf.cdo.spi.common.revision.CDOReferenceAdjuster;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDOFeatureDelta;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
-
-import org.eclipse.emf.common.util.ECollections;
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.change.ListChange;
-import org.eclipse.emf.ecore.change.util.ListDifferenceAnalyzer;
-
-import java.io.IOException;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-
-/**
- * @author Eike Stepper
- */
-public class CDORevisionDeltaImpl implements InternalCDORevisionDelta
-{
- private EClass eClass;
-
- private CDOID id;
-
- private CDOBranch branch;
-
- private int version;
-
- private CDORevisable target;
-
- private Map<EStructuralFeature, CDOFeatureDelta> featureDeltas = new HashMap<EStructuralFeature, CDOFeatureDelta>();
-
- public CDORevisionDeltaImpl(CDORevision revision)
- {
- eClass = revision.getEClass();
- id = revision.getID();
- branch = revision.getBranch();
- version = revision.getVersion();
- }
-
- public CDORevisionDeltaImpl(CDORevisionDelta revisionDelta, boolean copyFeatureDeltas)
- {
- eClass = revisionDelta.getEClass();
- id = revisionDelta.getID();
- branch = revisionDelta.getBranch();
- version = revisionDelta.getVersion();
-
- if (copyFeatureDeltas)
- {
- for (CDOFeatureDelta delta : revisionDelta.getFeatureDeltas())
- {
- addFeatureDelta(((InternalCDOFeatureDelta)delta).copy());
- }
- }
- }
-
- public CDORevisionDeltaImpl(CDORevision sourceRevision, CDORevision targetRevision)
- {
- if (sourceRevision.getEClass() != targetRevision.getEClass())
- {
- throw new IllegalArgumentException();
- }
-
- eClass = sourceRevision.getEClass();
- id = sourceRevision.getID();
- branch = sourceRevision.getBranch();
- version = sourceRevision.getVersion();
- target = CDORevisionUtil.copyRevisable(targetRevision);
-
- compare(sourceRevision, targetRevision);
-
- CDORevisionData originData = sourceRevision.data();
- CDORevisionData dirtyData = targetRevision.data();
-
- Object dirtyContainerID = dirtyData.getContainerID();
- if (dirtyContainerID instanceof CDOWithID)
- {
- dirtyContainerID = ((CDOWithID)dirtyContainerID).cdoID();
- }
-
- if (!compare(originData.getContainerID(), dirtyContainerID)
- || !compare(originData.getContainingFeatureID(), dirtyData.getContainingFeatureID())
- || !compare(originData.getResourceID(), dirtyData.getResourceID()))
- {
- addFeatureDelta(new CDOContainerFeatureDeltaImpl(dirtyData.getResourceID(), dirtyContainerID,
- dirtyData.getContainingFeatureID()));
- }
- }
-
- public CDORevisionDeltaImpl(CDODataInput in) throws IOException
- {
- eClass = (EClass)in.readCDOClassifierRefAndResolve();
- id = in.readCDOID();
- branch = in.readCDOBranch();
- version = in.readInt();
- if (version < 0)
- {
- version = -version;
- target = in.readCDORevisable();
- }
-
- int size = in.readInt();
- for (int i = 0; i < size; i++)
- {
- CDOFeatureDelta featureDelta = in.readCDOFeatureDelta(eClass);
- featureDeltas.put(featureDelta.getFeature(), featureDelta);
- }
- }
-
- public void write(CDODataOutput out) throws IOException
- {
- out.writeCDOClassifierRef(eClass);
- out.writeCDOID(id);
- out.writeCDOBranch(branch);
- if (target == null)
- {
- out.writeInt(version);
- }
- else
- {
- out.writeInt(-version);
- out.writeCDORevisable(target);
- }
-
- out.writeInt(featureDeltas.size());
- for (CDOFeatureDelta featureDelta : featureDeltas.values())
- {
- out.writeCDOFeatureDelta(eClass, featureDelta);
- }
- }
-
- public EClass getEClass()
- {
- return eClass;
- }
-
- public CDOID getID()
- {
- return id;
- }
-
- public CDOBranch getBranch()
- {
- return branch;
- }
-
- public void setBranch(CDOBranch branch)
- {
- this.branch = branch;
- }
-
- public int getVersion()
- {
- return version;
- }
-
- public void setVersion(int version)
- {
- this.version = version;
- }
-
- public CDORevisable getTarget()
- {
- return target;
- }
-
- public void setTarget(CDORevisable target)
- {
- this.target = target;
- }
-
- public boolean isEmpty()
- {
- return featureDeltas.isEmpty();
- }
-
- public CDORevisionDelta copy()
- {
- return new CDORevisionDeltaImpl(this, true);
- }
-
- public Map<EStructuralFeature, CDOFeatureDelta> getFeatureDeltaMap()
- {
- return featureDeltas;
- }
-
- public CDOFeatureDelta getFeatureDelta(EStructuralFeature feature)
- {
- return featureDeltas.get(feature);
- }
-
- public List<CDOFeatureDelta> getFeatureDeltas()
- {
- return new ArrayList<CDOFeatureDelta>(featureDeltas.values());
- }
-
- public void apply(CDORevision revision)
- {
- for (CDOFeatureDelta featureDelta : featureDeltas.values())
- {
- ((CDOFeatureDeltaImpl)featureDelta).apply(revision);
- }
- }
-
- public void addFeatureDelta(CDOFeatureDelta delta)
- {
- if (delta instanceof CDOListFeatureDelta)
- {
- CDOListFeatureDelta deltas = (CDOListFeatureDelta)delta;
- for (CDOFeatureDelta childDelta : deltas.getListChanges())
- {
- addFeatureDelta(childDelta);
- }
- }
- else
- {
- addSingleFeatureDelta(delta);
- }
- }
-
- private void addSingleFeatureDelta(CDOFeatureDelta delta)
- {
- EStructuralFeature feature = delta.getFeature();
- if (feature.isMany())
- {
- CDOListFeatureDeltaImpl listDelta = (CDOListFeatureDeltaImpl)featureDeltas.get(feature);
- if (listDelta == null)
- {
- listDelta = new CDOListFeatureDeltaImpl(feature);
- featureDeltas.put(listDelta.getFeature(), listDelta);
- }
-
- // Remove all previous changes
- if (delta instanceof CDOClearFeatureDelta || delta instanceof CDOUnsetFeatureDelta)
- {
- listDelta.getListChanges().clear();
- }
-
- listDelta.add(delta);
- }
- else
- {
- featureDeltas.put(feature, delta);
- }
- }
-
- public boolean adjustReferences(CDOReferenceAdjuster referenceAdjuster)
- {
- boolean changed = false;
- for (CDOFeatureDelta featureDelta : featureDeltas.values())
- {
- changed |= ((CDOFeatureDeltaImpl)featureDelta).adjustReferences(referenceAdjuster);
- }
-
- return changed;
- }
-
- public void accept(CDOFeatureDeltaVisitor visitor)
- {
- for (CDOFeatureDelta featureDelta : featureDeltas.values())
- {
- ((CDOFeatureDeltaImpl)featureDelta).accept(visitor);
- }
- }
-
- private void compare(CDORevision originRevision, CDORevision dirtyRevision)
- {
- CDORevisionData originData = originRevision.data();
- CDORevisionData dirtyData = dirtyRevision.data();
-
- for (final EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(eClass))
- {
- if (feature.isMany())
- {
- if (originData.size(feature) > 0 && dirtyData.size(feature) == 0)
- {
- addFeatureDelta(new CDOClearFeatureDeltaImpl(feature));
- }
- else
- {
- CDOListFeatureDelta listFeatureDelta = new CDOListFeatureDeltaImpl(feature);
- final List<CDOFeatureDelta> changes = listFeatureDelta.getListChanges();
-
- ListDifferenceAnalyzer analyzer = new ListDifferenceAnalyzer()
- {
- @Override
- public void analyzeLists(EList<Object> oldList, EList<?> newList, EList<ListChange> listChanges)
- {
- checkNoProxies(oldList);
- checkNoProxies(newList);
- super.analyzeLists(oldList, newList, listChanges);
- }
-
- @Override
- protected void createAddListChange(EList<Object> oldList, EList<ListChange> listChanges, Object value,
- int index)
- {
- CDOFeatureDelta delta = new CDOAddFeatureDeltaImpl(feature, index, value);
- changes.add(delta);
- oldList.add(index, value);
- }
-
- @Override
- protected void createRemoveListChange(EList<?> oldList, EList<ListChange> listChanges, Object value,
- int index)
- {
- CDORemoveFeatureDeltaImpl delta = new CDORemoveFeatureDeltaImpl(feature, index);
- // fix until ListDifferenceAnalyzer delivers the correct value (bug #308618).
- delta.setValue(oldList.get(index));
- changes.add(delta);
- oldList.remove(index);
- }
-
- @Override
- protected void createMoveListChange(EList<?> oldList, EList<ListChange> listChanges, Object value,
- int index, int toIndex)
- {
- CDOMoveFeatureDeltaImpl delta = new CDOMoveFeatureDeltaImpl(feature, toIndex, index);
- // fix until ListDifferenceAnalyzer delivers the correct value (same problem as bug #308618).
- delta.setValue(oldList.get(index));
- changes.add(delta);
- oldList.move(toIndex, index);
- }
-
- private void checkNoProxies(EList<?> list)
- {
- for (Object element : list)
- {
- if (element instanceof CDOElementProxy || element == CDOListImpl.UNINITIALIZED)
- {
- throw new PartialCollectionLoadingNotSupportedException("List contains proxy elements");
- }
- }
- }
- };
-
- CDOList originList = ((InternalCDORevision)originRevision).getList(feature);
- CDOList dirtyList = ((InternalCDORevision)dirtyRevision).getList(feature);
-
- analyzer.analyzeLists(originList, dirtyList, new NOOPList());
- if (!changes.isEmpty())
- {
- featureDeltas.put(feature, listFeatureDelta);
- }
- }
- }
- else
- {
- Object originValue = originData.get(feature, 0);
- Object dirtyValue = dirtyData.get(feature, 0);
- if (!compare(originValue, dirtyValue))
- {
- if (dirtyValue == null)
- {
- addFeatureDelta(new CDOUnsetFeatureDeltaImpl(feature));
- }
- else
- {
- addFeatureDelta(new CDOSetFeatureDeltaImpl(feature, 0, dirtyValue, originValue));
- }
- }
- }
- }
- }
-
- private boolean compare(Object originValue, Object dirtyValue)
- {
- return originValue == dirtyValue || originValue != null && dirtyValue != null && originValue.equals(dirtyValue);
- }
-
- @Override
- public String toString()
- {
- return MessageFormat.format("CDORevisionDelta[{0}@{1}:{2}v{3} --> {4}]", eClass.getName(), id, branch.getID(),
- version, featureDeltas.values());
- }
-
- /**
- * @author Eike Stepper
- */
- public static class NOOPList implements EList<ListChange>
- {
- private static final EList<ListChange> LIST = ECollections.emptyEList();
-
- public NOOPList()
- {
- }
-
- public int size()
- {
- return 0;
- }
-
- public boolean isEmpty()
- {
- return true;
- }
-
- public boolean contains(Object o)
- {
- return false;
- }
-
- public Iterator<ListChange> iterator()
- {
- return LIST.iterator();
- }
-
- public Object[] toArray()
- {
- return LIST.toArray();
- }
-
- public <T> T[] toArray(T[] a)
- {
- return LIST.toArray(a);
- }
-
- public boolean add(ListChange o)
- {
- return false;
- }
-
- public boolean remove(Object o)
- {
- return false;
- }
-
- public boolean containsAll(Collection<?> c)
- {
- return false;
- }
-
- public boolean addAll(Collection<? extends ListChange> c)
- {
- return false;
- }
-
- public boolean addAll(int index, Collection<? extends ListChange> c)
- {
- return false;
- }
-
- public boolean removeAll(Collection<?> c)
- {
- return false;
- }
-
- public boolean retainAll(Collection<?> c)
- {
- return false;
- }
-
- public void clear()
- {
- }
-
- public ListChange get(int index)
- {
- return LIST.get(index);
- }
-
- public ListChange set(int index, ListChange element)
- {
- return null;
- }
-
- public void add(int index, ListChange element)
- {
- }
-
- public ListChange remove(int index)
- {
- return null;
- }
-
- public int indexOf(Object o)
- {
- return LIST.indexOf(o);
- }
-
- public int lastIndexOf(Object o)
- {
- return LIST.lastIndexOf(o);
- }
-
- public ListIterator<ListChange> listIterator()
- {
- return LIST.listIterator();
- }
-
- public ListIterator<ListChange> listIterator(int index)
- {
- return LIST.listIterator(index);
- }
-
- public List<ListChange> subList(int fromIndex, int toIndex)
- {
- return LIST.subList(fromIndex, toIndex);
- }
-
- public void move(int newPosition, ListChange object)
- {
- }
-
- public ListChange move(int newPosition, int oldPosition)
- {
- return null;
- }
- }
-}
+/*
+ * Copyright (c) 2004 - 2012 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
+ * Simon McDuff - bug 201266
+ * Simon McDuff - bug 204890
+ */
+package org.eclipse.emf.cdo.internal.common.revision.delta;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOWithID;
+import org.eclipse.emf.cdo.common.model.CDOModelUtil;
+import org.eclipse.emf.cdo.common.protocol.CDODataInput;
+import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
+import org.eclipse.emf.cdo.common.revision.CDOElementProxy;
+import org.eclipse.emf.cdo.common.revision.CDOList;
+import org.eclipse.emf.cdo.common.revision.CDORevisable;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionData;
+import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
+import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
+import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta;
+import org.eclipse.emf.cdo.common.util.PartialCollectionLoadingNotSupportedException;
+import org.eclipse.emf.cdo.internal.common.revision.CDOListImpl;
+import org.eclipse.emf.cdo.spi.common.revision.CDOReferenceAdjuster;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDOFeatureDelta;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
+
+import org.eclipse.emf.common.util.ECollections;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.change.ListChange;
+import org.eclipse.emf.ecore.change.util.ListDifferenceAnalyzer;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDORevisionDeltaImpl implements InternalCDORevisionDelta
+{
+ private EClass eClass;
+
+ private CDOID id;
+
+ private CDOBranch branch;
+
+ private int version;
+
+ private CDORevisable target;
+
+ private Map<EStructuralFeature, CDOFeatureDelta> featureDeltas = new HashMap<EStructuralFeature, CDOFeatureDelta>();
+
+ public CDORevisionDeltaImpl(CDORevision revision)
+ {
+ eClass = revision.getEClass();
+ id = revision.getID();
+ branch = revision.getBranch();
+ version = revision.getVersion();
+ }
+
+ public CDORevisionDeltaImpl(CDORevisionDelta revisionDelta, boolean copyFeatureDeltas)
+ {
+ eClass = revisionDelta.getEClass();
+ id = revisionDelta.getID();
+ branch = revisionDelta.getBranch();
+ version = revisionDelta.getVersion();
+
+ if (copyFeatureDeltas)
+ {
+ for (CDOFeatureDelta delta : revisionDelta.getFeatureDeltas())
+ {
+ addFeatureDelta(((InternalCDOFeatureDelta)delta).copy());
+ }
+ }
+ }
+
+ public CDORevisionDeltaImpl(CDORevision sourceRevision, CDORevision targetRevision)
+ {
+ if (sourceRevision.getEClass() != targetRevision.getEClass())
+ {
+ throw new IllegalArgumentException();
+ }
+
+ eClass = sourceRevision.getEClass();
+ id = sourceRevision.getID();
+ branch = sourceRevision.getBranch();
+ version = sourceRevision.getVersion();
+ target = CDORevisionUtil.copyRevisable(targetRevision);
+
+ compare(sourceRevision, targetRevision);
+
+ CDORevisionData originData = sourceRevision.data();
+ CDORevisionData dirtyData = targetRevision.data();
+
+ Object dirtyContainerID = dirtyData.getContainerID();
+ if (dirtyContainerID instanceof CDOWithID)
+ {
+ dirtyContainerID = ((CDOWithID)dirtyContainerID).cdoID();
+ }
+
+ if (!compare(originData.getContainerID(), dirtyContainerID)
+ || !compare(originData.getContainingFeatureID(), dirtyData.getContainingFeatureID())
+ || !compare(originData.getResourceID(), dirtyData.getResourceID()))
+ {
+ addFeatureDelta(new CDOContainerFeatureDeltaImpl(dirtyData.getResourceID(), dirtyContainerID,
+ dirtyData.getContainingFeatureID()));
+ }
+ }
+
+ public CDORevisionDeltaImpl(CDODataInput in) throws IOException
+ {
+ eClass = (EClass)in.readCDOClassifierRefAndResolve();
+ id = in.readCDOID();
+ branch = in.readCDOBranch();
+ version = in.readInt();
+ if (version < 0)
+ {
+ version = -version;
+ target = in.readCDORevisable();
+ }
+
+ int size = in.readInt();
+ for (int i = 0; i < size; i++)
+ {
+ CDOFeatureDelta featureDelta = in.readCDOFeatureDelta(eClass);
+ featureDeltas.put(featureDelta.getFeature(), featureDelta);
+ }
+ }
+
+ public void write(CDODataOutput out) throws IOException
+ {
+ out.writeCDOClassifierRef(eClass);
+ out.writeCDOID(id);
+ out.writeCDOBranch(branch);
+ if (target == null)
+ {
+ out.writeInt(version);
+ }
+ else
+ {
+ out.writeInt(-version);
+ out.writeCDORevisable(target);
+ }
+
+ out.writeInt(featureDeltas.size());
+ for (CDOFeatureDelta featureDelta : featureDeltas.values())
+ {
+ out.writeCDOFeatureDelta(eClass, featureDelta);
+ }
+ }
+
+ public EClass getEClass()
+ {
+ return eClass;
+ }
+
+ public CDOID getID()
+ {
+ return id;
+ }
+
+ public CDOBranch getBranch()
+ {
+ return branch;
+ }
+
+ public void setBranch(CDOBranch branch)
+ {
+ this.branch = branch;
+ }
+
+ public int getVersion()
+ {
+ return version;
+ }
+
+ public void setVersion(int version)
+ {
+ this.version = version;
+ }
+
+ public CDORevisable getTarget()
+ {
+ return target;
+ }
+
+ public void setTarget(CDORevisable target)
+ {
+ this.target = target;
+ }
+
+ public boolean isEmpty()
+ {
+ return featureDeltas.isEmpty();
+ }
+
+ public CDORevisionDelta copy()
+ {
+ return new CDORevisionDeltaImpl(this, true);
+ }
+
+ public Map<EStructuralFeature, CDOFeatureDelta> getFeatureDeltaMap()
+ {
+ return featureDeltas;
+ }
+
+ public CDOFeatureDelta getFeatureDelta(EStructuralFeature feature)
+ {
+ return featureDeltas.get(feature);
+ }
+
+ public List<CDOFeatureDelta> getFeatureDeltas()
+ {
+ return new ArrayList<CDOFeatureDelta>(featureDeltas.values());
+ }
+
+ public void apply(CDORevision revision)
+ {
+ for (CDOFeatureDelta featureDelta : featureDeltas.values())
+ {
+ ((CDOFeatureDeltaImpl)featureDelta).apply(revision);
+ }
+ }
+
+ public void addFeatureDelta(CDOFeatureDelta delta)
+ {
+ if (delta instanceof CDOListFeatureDelta)
+ {
+ CDOListFeatureDelta deltas = (CDOListFeatureDelta)delta;
+ for (CDOFeatureDelta childDelta : deltas.getListChanges())
+ {
+ addFeatureDelta(childDelta);
+ }
+ }
+ else
+ {
+ addSingleFeatureDelta(delta);
+ }
+ }
+
+ private void addSingleFeatureDelta(CDOFeatureDelta delta)
+ {
+ EStructuralFeature feature = delta.getFeature();
+ if (feature.isMany())
+ {
+ CDOListFeatureDeltaImpl listDelta = (CDOListFeatureDeltaImpl)featureDeltas.get(feature);
+ if (listDelta == null)
+ {
+ listDelta = new CDOListFeatureDeltaImpl(feature);
+ featureDeltas.put(listDelta.getFeature(), listDelta);
+ }
+
+ // Remove all previous changes
+ if (delta instanceof CDOClearFeatureDelta || delta instanceof CDOUnsetFeatureDelta)
+ {
+ listDelta.getListChanges().clear();
+ }
+
+ listDelta.add(delta);
+ }
+ else
+ {
+ featureDeltas.put(feature, delta);
+ }
+ }
+
+ public boolean adjustReferences(CDOReferenceAdjuster referenceAdjuster)
+ {
+ boolean changed = false;
+ for (CDOFeatureDelta featureDelta : featureDeltas.values())
+ {
+ changed |= ((CDOFeatureDeltaImpl)featureDelta).adjustReferences(referenceAdjuster);
+ }
+
+ return changed;
+ }
+
+ public void accept(CDOFeatureDeltaVisitor visitor)
+ {
+ for (CDOFeatureDelta featureDelta : featureDeltas.values())
+ {
+ ((CDOFeatureDeltaImpl)featureDelta).accept(visitor);
+ }
+ }
+
+ private void compare(CDORevision originRevision, CDORevision dirtyRevision)
+ {
+ CDORevisionData originData = originRevision.data();
+ CDORevisionData dirtyData = dirtyRevision.data();
+
+ for (final EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(eClass))
+ {
+ if (feature.isMany())
+ {
+ if (originData.size(feature) > 0 && dirtyData.size(feature) == 0)
+ {
+ addFeatureDelta(new CDOClearFeatureDeltaImpl(feature));
+ }
+ else
+ {
+ CDOListFeatureDelta listFeatureDelta = new CDOListFeatureDeltaImpl(feature);
+ final List<CDOFeatureDelta> changes = listFeatureDelta.getListChanges();
+
+ ListDifferenceAnalyzer analyzer = new ListDifferenceAnalyzer()
+ {
+ @Override
+ public void analyzeLists(EList<Object> oldList, EList<?> newList, EList<ListChange> listChanges)
+ {
+ checkNoProxies(oldList);
+ checkNoProxies(newList);
+ super.analyzeLists(oldList, newList, listChanges);
+ }
+
+ @Override
+ protected void createAddListChange(EList<Object> oldList, EList<ListChange> listChanges, Object value,
+ int index)
+ {
+ CDOFeatureDelta delta = new CDOAddFeatureDeltaImpl(feature, index, value);
+ changes.add(delta);
+ oldList.add(index, value);
+ }
+
+ @Override
+ protected void createRemoveListChange(EList<?> oldList, EList<ListChange> listChanges, Object value,
+ int index)
+ {
+ CDORemoveFeatureDeltaImpl delta = new CDORemoveFeatureDeltaImpl(feature, index);
+ // fix until ListDifferenceAnalyzer delivers the correct value (bug #308618).
+ delta.setValue(oldList.get(index));
+ changes.add(delta);
+ oldList.remove(index);
+ }
+
+ @Override
+ protected void createMoveListChange(EList<?> oldList, EList<ListChange> listChanges, Object value,
+ int index, int toIndex)
+ {
+ CDOMoveFeatureDeltaImpl delta = new CDOMoveFeatureDeltaImpl(feature, toIndex, index);
+ // fix until ListDifferenceAnalyzer delivers the correct value (same problem as bug #308618).
+ delta.setValue(oldList.get(index));
+ changes.add(delta);
+ oldList.move(toIndex, index);
+ }
+
+ private void checkNoProxies(EList<?> list)
+ {
+ for (Object element : list)
+ {
+ if (element instanceof CDOElementProxy || element == CDOListImpl.UNINITIALIZED)
+ {
+ throw new PartialCollectionLoadingNotSupportedException("List contains proxy elements");
+ }
+ }
+ }
+ };
+
+ CDOList originList = ((InternalCDORevision)originRevision).getList(feature);
+ CDOList dirtyList = ((InternalCDORevision)dirtyRevision).getList(feature);
+
+ analyzer.analyzeLists(originList, dirtyList, new NOOPList());
+ if (!changes.isEmpty())
+ {
+ featureDeltas.put(feature, listFeatureDelta);
+ }
+ }
+ }
+ else
+ {
+ Object originValue = originData.get(feature, 0);
+ Object dirtyValue = dirtyData.get(feature, 0);
+ if (!compare(originValue, dirtyValue))
+ {
+ if (dirtyValue == null)
+ {
+ addFeatureDelta(new CDOUnsetFeatureDeltaImpl(feature));
+ }
+ else
+ {
+ addFeatureDelta(new CDOSetFeatureDeltaImpl(feature, 0, dirtyValue, originValue));
+ }
+ }
+ }
+ }
+ }
+
+ private boolean compare(Object originValue, Object dirtyValue)
+ {
+ return originValue == dirtyValue || originValue != null && dirtyValue != null && originValue.equals(dirtyValue);
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("CDORevisionDelta[{0}@{1}:{2}v{3} --> {4}]", eClass.getName(), id, branch.getID(),
+ version, featureDeltas.values());
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class NOOPList implements EList<ListChange>
+ {
+ private static final EList<ListChange> LIST = ECollections.emptyEList();
+
+ public NOOPList()
+ {
+ }
+
+ public int size()
+ {
+ return 0;
+ }
+
+ public boolean isEmpty()
+ {
+ return true;
+ }
+
+ public boolean contains(Object o)
+ {
+ return false;
+ }
+
+ public Iterator<ListChange> iterator()
+ {
+ return LIST.iterator();
+ }
+
+ public Object[] toArray()
+ {
+ return LIST.toArray();
+ }
+
+ public <T> T[] toArray(T[] a)
+ {
+ return LIST.toArray(a);
+ }
+
+ public boolean add(ListChange o)
+ {
+ return false;
+ }
+
+ public boolean remove(Object o)
+ {
+ return false;
+ }
+
+ public boolean containsAll(Collection<?> c)
+ {
+ return false;
+ }
+
+ public boolean addAll(Collection<? extends ListChange> c)
+ {
+ return false;
+ }
+
+ public boolean addAll(int index, Collection<? extends ListChange> c)
+ {
+ return false;
+ }
+
+ public boolean removeAll(Collection<?> c)
+ {
+ return false;
+ }
+
+ public boolean retainAll(Collection<?> c)
+ {
+ return false;
+ }
+
+ public void clear()
+ {
+ }
+
+ public ListChange get(int index)
+ {
+ return LIST.get(index);
+ }
+
+ public ListChange set(int index, ListChange element)
+ {
+ return null;
+ }
+
+ public void add(int index, ListChange element)
+ {
+ }
+
+ public ListChange remove(int index)
+ {
+ return null;
+ }
+
+ public int indexOf(Object o)
+ {
+ return LIST.indexOf(o);
+ }
+
+ public int lastIndexOf(Object o)
+ {
+ return LIST.lastIndexOf(o);
+ }
+
+ public ListIterator<ListChange> listIterator()
+ {
+ return LIST.listIterator();
+ }
+
+ public ListIterator<ListChange> listIterator(int index)
+ {
+ return LIST.listIterator(index);
+ }
+
+ public List<ListChange> subList(int fromIndex, int toIndex)
+ {
+ return LIST.subList(fromIndex, toIndex);
+ }
+
+ public void move(int newPosition, ListChange object)
+ {
+ }
+
+ public ListChange move(int newPosition, int oldPosition)
+ {
+ return null;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java
index 2608cd2f68..7ad3215886 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java
@@ -65,7 +65,6 @@ import java.util.Map;
*/
public abstract class BaseCDORevision extends AbstractCDORevision
{
-
private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_REVISION, BaseCDORevision.class);
private static final PerfTracer READING = new PerfTracer(OM.PERF_REVISION_READING, BaseCDORevision.class);
@@ -78,9 +77,11 @@ public abstract class BaseCDORevision extends AbstractCDORevision
private static final byte SET_NOT_NULL = 2;
+ private static final byte PERMISSION_MASK = 0x03;
+
private static final byte FROZEN_FLAG = 0x04;
- private static final byte PERMISSION_MASK = 0x03;
+ private static final byte UNCHUNKED_FLAG = 0x08;
private CDOID id;
@@ -145,13 +146,13 @@ public abstract class BaseCDORevision extends AbstractCDORevision
readSystemValues(in);
- byte permissionBits = (byte)(in.readByte() & PERMISSION_MASK);
- if (permissionBits != CDOPermission.NONE.ordinal())
+ byte flagBits = (byte)(in.readByte() & ~FROZEN_FLAG);
+ if ((flagBits & PERMISSION_MASK) != CDOPermission.NONE.ordinal())
{
readValues(in);
}
- flags = permissionBits;
+ flags = flagBits;
if (READING.isEnabled())
{
@@ -203,7 +204,7 @@ public abstract class BaseCDORevision extends AbstractCDORevision
CDOPermissionProvider permissionProvider = out.getPermissionProvider();
CDOPermission permission = permissionProvider.getPermission(this);
- out.writeByte(permission.getBits());
+ out.writeByte(permission.getBits() | flags & UNCHUNKED_FLAG);
if (permission != CDOPermission.NONE)
{
@@ -732,6 +733,22 @@ public abstract class BaseCDORevision extends AbstractCDORevision
}
}
+ /**
+ * @since 4.1
+ */
+ public boolean isUnchunked()
+ {
+ return (flags & UNCHUNKED_FLAG) != 0;
+ }
+
+ /**
+ * @since 4.1
+ */
+ public void setUnchunked()
+ {
+ flags |= UNCHUNKED_FLAG;
+ }
+
protected Object getValue(int featureIndex)
{
checkReadable();
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java
index 031f06eb0a..f743b2bbb1 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java
@@ -354,4 +354,20 @@ public abstract class DelegatingCDORevision implements InternalCDORevision
{
getDelegate().freeze();
}
+
+ /**
+ * @since 4.1
+ */
+ public boolean isUnchunked()
+ {
+ return getDelegate().isUnchunked();
+ }
+
+ /**
+ * @since 4.1
+ */
+ public void setUnchunked()
+ {
+ getDelegate().setUnchunked();
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java
index 9d646837ba..985b397ec4 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java
@@ -126,4 +126,14 @@ public interface InternalCDORevision extends CDORevision, CDORevisionData, CDORe
* @since 4.0
*/
public void freeze();
+
+ /**
+ * @since 4.1
+ */
+ public boolean isUnchunked();
+
+ /**
+ * @since 4.1
+ */
+ public void setUnchunked();
}
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 72ffca1b96..06d958dfd1 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
@@ -279,6 +279,22 @@ public class StubCDORevision extends AbstractCDORevision
throw new UnsupportedOperationException(getExceptionMessage());
}
+ /**
+ * @since 4.1
+ */
+ public boolean isUnchunked()
+ {
+ throw new UnsupportedOperationException(getExceptionMessage());
+ }
+
+ /**
+ * @since 4.1
+ */
+ public void setUnchunked()
+ {
+ throw new UnsupportedOperationException(getExceptionMessage());
+ }
+
private String getExceptionMessage()
{
return "Unsupported operation in " + this;
diff --git a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java
index 2ac02db01c..b3b1ca7d79 100644
--- a/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java
+++ b/plugins/org.eclipse.emf.cdo.server.db/src/org/eclipse/emf/cdo/server/internal/db/mapping/horizontal/HorizontalBranchingClassMapping.java
@@ -1,1124 +1,1117 @@
-/*
- * Copyright (c) 2004 - 2012 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
- * Stefan Winkler - major refactoring
- * Stefan Winkler - 249610: [DB] Support external references (Implementation)
- * Stefan Winkler - derived branch mapping from audit mapping
- * Stefan Winkler - Bug 329025: [DB] Support branching for range-based mapping strategy
- */
-package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
-
-import org.eclipse.emf.cdo.common.branch.CDOBranch;
-import org.eclipse.emf.cdo.common.branch.CDOBranchManager;
-import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
-import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.model.CDOModelUtil;
-import org.eclipse.emf.cdo.common.revision.CDOList;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
-import org.eclipse.emf.cdo.common.revision.CDORevisionManager;
-import org.eclipse.emf.cdo.common.revision.delta.CDOAddFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOContainerFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
-import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOMoveFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDORemoveFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta;
-import org.eclipse.emf.cdo.eresource.EresourcePackage;
-import org.eclipse.emf.cdo.server.IRepository;
-import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext;
-import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
-import org.eclipse.emf.cdo.server.db.IIDHandler;
-import org.eclipse.emf.cdo.server.db.IPreparedStatementCache;
-import org.eclipse.emf.cdo.server.db.IPreparedStatementCache.ReuseProbability;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMappingAuditSupport;
-import org.eclipse.emf.cdo.server.db.mapping.IClassMappingDeltaSupport;
-import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
-import org.eclipse.emf.cdo.server.db.mapping.IListMappingDeltaSupport;
-import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
-import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
-import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
-import org.eclipse.emf.cdo.spi.common.commit.CDOChangeSetSegment;
-import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
-import org.eclipse.emf.cdo.spi.server.InternalRepository;
-
-import org.eclipse.net4j.db.DBException;
-import org.eclipse.net4j.db.DBType;
-import org.eclipse.net4j.db.DBUtil;
-import org.eclipse.net4j.db.ddl.IDBField;
-import org.eclipse.net4j.db.ddl.IDBTable;
-import org.eclipse.net4j.util.ImplementationError;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
-import org.eclipse.net4j.util.om.trace.ContextTracer;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * @author Eike Stepper
- * @author Stefan Winkler
- * @since 3.0
- */
-public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapping implements
- IClassMappingAuditSupport, IClassMappingDeltaSupport
-{
- /**
- * @author Stefan Winkler
- */
- private class FeatureDeltaWriter implements CDOFeatureDeltaVisitor
- {
- private IDBStoreAccessor accessor;
-
- private long created;
-
- private CDOID id;
-
- private CDOBranch targetBranch;
-
- private int oldVersion;
-
- private int newVersion;
-
- private InternalCDORevision newRevision;
-
- public void process(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created)
- {
- this.accessor = accessor;
- this.created = created;
- id = delta.getID();
- oldVersion = delta.getVersion();
-
- if (TRACER.isEnabled())
- {
- TRACER.format("FeatureDeltaWriter: old version: {0}, new version: {1}", oldVersion, oldVersion + 1); //$NON-NLS-1$
- }
-
- InternalCDORevision originalRevision = (InternalCDORevision)accessor.getTransaction().getRevision(id);
- newRevision = originalRevision.copy();
- targetBranch = accessor.getTransaction().getBranch();
- newRevision.adjustForCommit(targetBranch, created);
-
- newVersion = newRevision.getVersion();
-
- // process revision delta tree
- delta.accept(this);
-
- if (newVersion != CDORevision.FIRST_VERSION)
- {
- reviseOldRevision(accessor, id, delta.getBranch(), newRevision.getTimeStamp() - 1);
- }
-
- writeValues(accessor, newRevision);
- }
-
- public void visit(CDOMoveFeatureDelta delta)
- {
- throw new ImplementationError("Should not be called"); //$NON-NLS-1$
- }
-
- public void visit(CDOAddFeatureDelta delta)
- {
- throw new ImplementationError("Should not be called"); //$NON-NLS-1$
- }
-
- public void visit(CDORemoveFeatureDelta delta)
- {
- throw new ImplementationError("Should not be called"); //$NON-NLS-1$
- }
-
- public void visit(CDOSetFeatureDelta delta)
- {
- delta.apply(newRevision);
- }
-
- public void visit(CDOUnsetFeatureDelta delta)
- {
- delta.apply(newRevision);
- }
-
- public void visit(CDOListFeatureDelta delta)
- {
- delta.apply(newRevision);
- IListMappingDeltaSupport listMapping = (IListMappingDeltaSupport)getListMapping(delta.getFeature());
- listMapping.processDelta(accessor, id, targetBranch.getID(), oldVersion, newVersion, created, delta);
- }
-
- public void visit(CDOClearFeatureDelta delta)
- {
- throw new ImplementationError("Should not be called"); //$NON-NLS-1$
- }
-
- public void visit(CDOContainerFeatureDelta delta)
- {
- delta.apply(newRevision);
- }
- }
-
- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, HorizontalBranchingClassMapping.class);
-
- private String sqlInsertAttributes;
-
- private String sqlSelectCurrentAttributes;
-
- private String sqlSelectAllObjectIDs;
-
- private String sqlSelectAttributesByTime;
-
- private String sqlSelectAttributesByVersion;
-
- private String sqlReviseAttributes;
-
- private String sqlSelectForHandle;
-
- private String sqlSelectForChangeSet;
-
- private ThreadLocal<FeatureDeltaWriter> deltaWriter = new ThreadLocal<FeatureDeltaWriter>()
- {
- @Override
- protected FeatureDeltaWriter initialValue()
- {
- return new FeatureDeltaWriter();
- }
- };
-
- public HorizontalBranchingClassMapping(AbstractHorizontalMappingStrategy mappingStrategy, EClass eClass)
- {
- super(mappingStrategy, eClass);
-
- initSQLStrings();
- }
-
- @Override
- protected IDBField addBranchingField(IDBTable table)
- {
- return table.addField(CDODBSchema.ATTRIBUTES_BRANCH, DBType.INTEGER, true);
- }
-
- private void initSQLStrings()
- {
- Map<EStructuralFeature, String> unsettableFields = getUnsettableFields();
- Map<EStructuralFeature, String> listSizeFields = getListSizeFields();
-
- // ----------- Select Revision ---------------------------
- StringBuilder builder = new StringBuilder();
-
- builder.append("SELECT "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_VERSION);
- builder.append(", "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_CREATED);
- builder.append(", "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append(", "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_RESOURCE);
- builder.append(", "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
- builder.append(", "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_FEATURE);
-
- for (ITypeMapping singleMapping : getValueMappings())
- {
- builder.append(", "); //$NON-NLS-1$
- builder.append(singleMapping.getField());
- }
-
- if (unsettableFields != null)
- {
- for (String fieldName : unsettableFields.values())
- {
- builder.append(", "); //$NON-NLS-1$
- builder.append(fieldName);
- }
- }
-
- if (listSizeFields != null)
- {
- for (String fieldName : listSizeFields.values())
- {
- builder.append(", "); //$NON-NLS-1$
- builder.append(fieldName);
- }
- }
-
- builder.append(" FROM "); //$NON-NLS-1$
- builder.append(getTable());
- builder.append(" WHERE "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_ID);
- builder.append("=? AND "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
- builder.append("=? AND ("); //$NON-NLS-1$
- String sqlSelectAttributesPrefix = builder.toString();
-
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append("=0)"); //$NON-NLS-1$
-
- sqlSelectCurrentAttributes = builder.toString();
-
- builder = new StringBuilder(sqlSelectAttributesPrefix);
-
- builder.append(CDODBSchema.ATTRIBUTES_CREATED);
- builder.append("<=? AND ("); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append("=0 OR "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append(">=?))"); //$NON-NLS-1$
-
- sqlSelectAttributesByTime = builder.toString();
-
- builder = new StringBuilder(sqlSelectAttributesPrefix);
-
- builder.append("ABS("); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_VERSION);
- builder.append(")=?)"); //$NON-NLS-1$
-
- sqlSelectAttributesByVersion = builder.toString();
-
- // ----------- Insert Attributes -------------------------
- builder = new StringBuilder();
- builder.append("INSERT INTO "); //$NON-NLS-1$
- builder.append(getTable());
-
- builder.append("("); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_ID);
- builder.append(", "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_VERSION);
- builder.append(", "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
- builder.append(", "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_CREATED);
- builder.append(", "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append(", "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_RESOURCE);
- builder.append(", "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
- builder.append(", "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_FEATURE);
-
- for (ITypeMapping singleMapping : getValueMappings())
- {
- builder.append(", "); //$NON-NLS-1$
- builder.append(singleMapping.getField());
- }
-
- if (unsettableFields != null)
- {
- for (String fieldName : unsettableFields.values())
- {
- builder.append(", "); //$NON-NLS-1$
- builder.append(fieldName);
- }
- }
-
- if (listSizeFields != null)
- {
- for (String fieldName : listSizeFields.values())
- {
- builder.append(", "); //$NON-NLS-1$
- builder.append(fieldName);
- }
- }
-
- builder.append(") VALUES (?, ?, ?, ?, ?, ?, ?, ?"); //$NON-NLS-1$
-
- for (int i = 0; i < getValueMappings().size(); i++)
- {
- builder.append(", ?"); //$NON-NLS-1$
- }
-
- if (unsettableFields != null)
- {
- for (int i = 0; i < unsettableFields.size(); i++)
- {
- builder.append(", ?"); //$NON-NLS-1$
- }
- }
-
- if (listSizeFields != null)
- {
- for (int i = 0; i < listSizeFields.size(); i++)
- {
- builder.append(", ?"); //$NON-NLS-1$
- }
- }
-
- builder.append(")"); //$NON-NLS-1$
- sqlInsertAttributes = builder.toString();
-
- // ----------- Update to set revised ----------------
- builder = new StringBuilder("UPDATE "); //$NON-NLS-1$
- builder.append(getTable());
- builder.append(" SET "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append("=? WHERE "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_ID);
- builder.append("=? AND "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
- builder.append("=? AND "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append("=0"); //$NON-NLS-1$
- sqlReviseAttributes = builder.toString();
-
- // ----------- Select all unrevised Object IDs ------
- builder = new StringBuilder("SELECT "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_ID);
- builder.append(" FROM "); //$NON-NLS-1$
- builder.append(getTable());
- builder.append(" WHERE "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append("=0"); //$NON-NLS-1$
- sqlSelectAllObjectIDs = builder.toString();
-
- // ----------- Select all revisions (for handleRevision) ---
- builder = new StringBuilder("SELECT "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_ID);
- builder.append(", "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_VERSION);
- builder.append(", "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
- builder.append(" FROM "); //$NON-NLS-1$
- builder.append(getTable());
- sqlSelectForHandle = builder.toString();
-
- // ----------- Select all revisions (for handleRevision) ---
- builder = new StringBuilder("SELECT DISTINCT "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_ID);
- builder.append(" FROM "); //$NON-NLS-1$
- builder.append(getTable());
- builder.append(" WHERE "); //$NON-NLS-1$
- sqlSelectForChangeSet = builder.toString();
- }
-
- public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk)
- {
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- IPreparedStatementCache statementCache = accessor.getStatementCache();
- PreparedStatement stmt = null;
-
- long timeStamp = revision.getTimeStamp();
- int branchID = revision.getBranch().getID();
-
- try
- {
- if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE)
- {
- stmt = statementCache.getPreparedStatement(sqlSelectAttributesByTime, ReuseProbability.MEDIUM);
- idHandler.setCDOID(stmt, 1, revision.getID());
- stmt.setInt(2, branchID);
- stmt.setLong(3, timeStamp);
- stmt.setLong(4, timeStamp);
- }
- else
- {
- stmt = statementCache.getPreparedStatement(sqlSelectCurrentAttributes, ReuseProbability.HIGH);
- idHandler.setCDOID(stmt, 1, revision.getID());
- stmt.setInt(2, branchID);
- }
-
- // Read singleval-attribute table always (even without modeled attributes!)
- boolean success = readValuesFromStatement(stmt, revision, accessor);
-
- // Read multival tables only if revision exists
- if (success && revision.getVersion() >= CDOBranchVersion.FIRST_VERSION)
- {
- readLists(accessor, revision, listChunk);
- }
-
- return success;
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- statementCache.releasePreparedStatement(stmt);
- }
- }
-
- public boolean readRevisionByVersion(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk)
- {
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- IPreparedStatementCache statementCache = accessor.getStatementCache();
- PreparedStatement stmt = null;
-
- try
- {
- stmt = statementCache.getPreparedStatement(sqlSelectAttributesByVersion, ReuseProbability.HIGH);
- idHandler.setCDOID(stmt, 1, revision.getID());
- stmt.setInt(2, revision.getBranch().getID());
- stmt.setInt(3, revision.getVersion());
-
- // Read singleval-attribute table always (even without modeled attributes!)
- boolean success = readValuesFromStatement(stmt, revision, accessor);
-
- // Read multival tables only if revision exists
- if (success)
- {
- readLists(accessor, revision, listChunk);
- }
-
- return success;
- }
- catch (SQLException ex)
- {
- throw new DBException(ex);
- }
- finally
- {
- statementCache.releasePreparedStatement(stmt);
- }
- }
-
- public PreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name,
- boolean exactMatch, CDOBranchPoint branchPoint)
- {
- EStructuralFeature nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name();
-
- ITypeMapping nameValueMapping = getValueMapping(nameFeature);
- if (nameValueMapping == null)
- {
- throw new ImplementationError(nameFeature + " not found in ClassMapping " + this); //$NON-NLS-1$
- }
-
- int branchID = branchPoint.getBranch().getID();
- long timeStamp = branchPoint.getTimeStamp();
-
- StringBuilder builder = new StringBuilder();
- builder.append("SELECT "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_ID);
- builder.append(" FROM "); //$NON-NLS-1$
- builder.append(getTable());
- builder.append(" WHERE "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_VERSION);
- builder.append(">0 AND "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
- builder.append("=? AND "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
- builder.append("=? AND "); //$NON-NLS-1$
- builder.append(nameValueMapping.getField());
- if (name == null)
- {
- builder.append(" IS NULL"); //$NON-NLS-1$
- }
- else
- {
- builder.append(exactMatch ? " =?" : " LIKE ?"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- builder.append(" AND ("); //$NON-NLS-1$
-
- if (timeStamp == CDORevision.UNSPECIFIED_DATE)
- {
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append("=0)"); //$NON-NLS-1$
- }
- else
- {
- builder.append(CDODBSchema.ATTRIBUTES_CREATED);
- builder.append("<=? AND ("); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append("=0 OR "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append(">=?))"); //$NON-NLS-1$
- }
-
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- IPreparedStatementCache statementCache = accessor.getStatementCache();
- PreparedStatement stmt = null;
-
- try
- {
- int column = 1;
-
- stmt = statementCache.getPreparedStatement(builder.toString(), ReuseProbability.MEDIUM);
- stmt.setInt(column++, branchID);
- idHandler.setCDOID(stmt, column++, folderId);
-
- if (name != null)
- {
- String queryName = exactMatch ? name : name + "%"; //$NON-NLS-1$
- nameValueMapping.setValue(stmt, column++, queryName);
- }
-
- if (timeStamp != CDORevision.UNSPECIFIED_DATE)
- {
- stmt.setLong(column++, timeStamp);
- stmt.setLong(column++, timeStamp);
- }
-
- if (TRACER.isEnabled())
- {
- TRACER.format("Created Resource Query: {0}", stmt.toString()); //$NON-NLS-1$
- }
-
- return stmt;
- }
- catch (SQLException ex)
- {
- statementCache.releasePreparedStatement(stmt); // only release on error
- throw new DBException(ex);
- }
- }
-
- public PreparedStatement createObjectIDStatement(IDBStoreAccessor accessor)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Created ObjectID Statement : {0}", sqlSelectAllObjectIDs); //$NON-NLS-1$
- }
-
- IPreparedStatementCache statementCache = accessor.getStatementCache();
- return statementCache.getPreparedStatement(sqlSelectAllObjectIDs, ReuseProbability.HIGH);
- }
-
- @Override
- protected final void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision)
- {
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- IPreparedStatementCache statementCache = accessor.getStatementCache();
- PreparedStatement stmt = null;
-
- try
- {
- int column = 1;
- stmt = statementCache.getPreparedStatement(sqlInsertAttributes, ReuseProbability.HIGH);
- idHandler.setCDOID(stmt, column++, revision.getID());
- stmt.setInt(column++, revision.getVersion());
- stmt.setInt(column++, revision.getBranch().getID());
- stmt.setLong(column++, revision.getTimeStamp());
- stmt.setLong(column++, revision.getRevised());
- idHandler.setCDOID(stmt, column++, revision.getResourceID());
- idHandler.setCDOID(stmt, column++, (CDOID)revision.getContainerID());
- stmt.setInt(column++, revision.getContainingFeatureID());
-
- int isSetCol = column + getValueMappings().size();
-
- for (ITypeMapping mapping : getValueMappings())
- {
- EStructuralFeature feature = mapping.getFeature();
- if (feature.isUnsettable())
- {
- if (revision.getValue(feature) == null)
- {
- stmt.setBoolean(isSetCol++, false);
-
- // also set value column to default value
- mapping.setDefaultValue(stmt, column++);
- continue;
- }
-
- stmt.setBoolean(isSetCol++, true);
- }
-
- mapping.setValueFromRevision(stmt, column++, revision);
- }
-
- Map<EStructuralFeature, String> listSizeFields = getListSizeFields();
- if (listSizeFields != null)
- {
- // isSetCol now points to the first listTableSize-column
- column = isSetCol;
-
- for (EStructuralFeature feature : listSizeFields.keySet())
- {
- CDOList list = revision.getList(feature);
- stmt.setInt(column++, list.size());
- }
- }
-
- DBUtil.update(stmt, true);
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- statementCache.releasePreparedStatement(stmt);
- }
- }
-
- @Override
- protected void detachAttributes(IDBStoreAccessor accessor, CDOID id, int version, CDOBranch branch, long timeStamp,
- OMMonitor mon)
- {
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- IPreparedStatementCache statementCache = accessor.getStatementCache();
- PreparedStatement stmt = null;
-
- try
- {
- stmt = statementCache.getPreparedStatement(sqlInsertAttributes, ReuseProbability.HIGH);
-
- int column = 1;
- idHandler.setCDOID(stmt, column++, id);
- stmt.setInt(column++, -version); // cdo_version
- stmt.setInt(column++, branch.getID());
- stmt.setLong(column++, timeStamp); // cdo_created
- stmt.setLong(column++, CDOBranchPoint.UNSPECIFIED_DATE); // cdo_revised
- idHandler.setCDOID(stmt, column++, CDOID.NULL); // resource
- idHandler.setCDOID(stmt, column++, CDOID.NULL); // container
- stmt.setInt(column++, 0); // containing feature ID
-
- int isSetCol = column + getValueMappings().size();
-
- for (ITypeMapping mapping : getValueMappings())
- {
- EStructuralFeature feature = mapping.getFeature();
- if (feature.isUnsettable())
- {
- stmt.setBoolean(isSetCol++, false);
- }
-
- mapping.setDefaultValue(stmt, column++);
- }
-
- Map<EStructuralFeature, String> listSizeFields = getListSizeFields();
- if (listSizeFields != null)
- {
- // list size columns begin after isSet-columns
- column = isSetCol;
-
- for (int i = 0; i < listSizeFields.size(); i++)
- {
- stmt.setInt(column++, 0);
- }
- }
-
- DBUtil.update(stmt, true);
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- statementCache.releasePreparedStatement(stmt);
- }
- }
-
- @Override
- protected void reviseOldRevision(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, long revised)
- {
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- IPreparedStatementCache statementCache = accessor.getStatementCache();
- PreparedStatement stmt = null;
-
- try
- {
- stmt = statementCache.getPreparedStatement(sqlReviseAttributes, ReuseProbability.HIGH);
-
- stmt.setLong(1, revised);
- idHandler.setCDOID(stmt, 2, id);
- stmt.setInt(3, branch.getID());
-
- DBUtil.update(stmt, false); // No row affected if old revision from other branch!
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- statementCache.releasePreparedStatement(stmt);
- }
- }
-
- @Override
- public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, boolean mapType, boolean revise,
- OMMonitor monitor)
- {
- Async async = null;
- monitor.begin(10);
-
- try
- {
- try
- {
- async = monitor.forkAsync();
- CDOID id = revision.getID();
- if (mapType)
- {
- // put new objects into objectTypeMapper
- long timeStamp = revision.getTimeStamp();
- AbstractHorizontalMappingStrategy mappingStrategy = (AbstractHorizontalMappingStrategy)getMappingStrategy();
- mappingStrategy.putObjectType(accessor, timeStamp, id, getEClass());
- }
- else if (revise && revision.getVersion() > CDOBranchVersion.FIRST_VERSION)
- {
- // if revision is not the first one, revise the old revision
- long revised = revision.getTimeStamp() - 1;
- reviseOldRevision(accessor, id, revision.getBranch(), revised);
- for (IListMapping mapping : getListMappings())
- {
- mapping.objectDetached(accessor, id, revised);
- }
- }
- }
- finally
- {
- if (async != null)
- {
- async.stop();
- }
- }
-
- try
- {
- async = monitor.forkAsync();
- if (revision.isResourceFolder() || revision.isResource())
- {
- checkDuplicateResources(accessor, revision);
- }
- }
- finally
- {
- if (async != null)
- {
- async.stop();
- }
- }
-
- try
- {
- // Write attribute table always (even without modeled attributes!)
- async = monitor.forkAsync();
- writeValues(accessor, revision);
- }
- finally
- {
- if (async != null)
- {
- async.stop();
- }
- }
-
- try
- {
- // Write list tables only if they exist
- async = monitor.forkAsync(7);
- if (getListMappings() != null)
- {
- writeLists(accessor, revision);
- }
- }
- finally
- {
- if (async != null)
- {
- async.stop();
- }
- }
- }
- finally
- {
- monitor.done();
- }
- }
-
- @Override
- public void handleRevisions(IDBStoreAccessor accessor, CDOBranch branch, long timeStamp, boolean exactTime,
- CDORevisionHandler handler)
- {
- StringBuilder builder = new StringBuilder(sqlSelectForHandle);
- boolean whereAppend = false;
-
- if (branch != null)
- {
- // TODO: Prepare this string literal
- builder.append(" WHERE "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
- builder.append("=?"); //$NON-NLS-1$
-
- whereAppend = true;
- }
-
- int timeParameters = 0;
- if (timeStamp != CDOBranchPoint.INVALID_DATE)
- {
- if (exactTime)
- {
- if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE)
- {
- builder.append(whereAppend ? " AND " : " WHERE "); //$NON-NLS-1$ //$NON-NLS-2$
- builder.append(CDODBSchema.ATTRIBUTES_CREATED);
- builder.append("=?"); //$NON-NLS-1$
- timeParameters = 1;
- }
- }
- else
- {
- builder.append(whereAppend ? " AND " : " WHERE "); //$NON-NLS-1$ //$NON-NLS-2$
- if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE)
- {
- builder.append(CDODBSchema.ATTRIBUTES_CREATED);
- builder.append("<=? AND ("); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append("=0 OR "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append(">=?)"); //$NON-NLS-1$
- timeParameters = 2;
- }
- else
- {
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append("="); //$NON-NLS-1$
- builder.append(CDOBranchPoint.UNSPECIFIED_DATE);
- }
- }
- }
-
- IRepository repository = accessor.getStore().getRepository();
- CDORevisionManager revisionManager = repository.getRevisionManager();
- CDOBranchManager branchManager = repository.getBranchManager();
-
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- IPreparedStatementCache statementCache = accessor.getStatementCache();
- PreparedStatement stmt = null;
- ResultSet resultSet = null;
-
- try
- {
- stmt = statementCache.getPreparedStatement(builder.toString(), ReuseProbability.LOW);
-
- int column = 1;
- if (branch != null)
- {
- stmt.setInt(column++, branch.getID());
- }
-
- for (int i = 0; i < timeParameters; i++)
- {
- stmt.setLong(column++, timeStamp);
- }
-
- resultSet = stmt.executeQuery();
- while (resultSet.next())
- {
- CDOID id = idHandler.getCDOID(resultSet, 1);
- int version = resultSet.getInt(2);
-
- if (version >= CDOBranchVersion.FIRST_VERSION)
- {
- int branchID = resultSet.getInt(3);
- CDOBranchVersion branchVersion = branchManager.getBranch(branchID).getVersion(Math.abs(version));
- InternalCDORevision revision = (InternalCDORevision)revisionManager.getRevisionByVersion(id, branchVersion,
- CDORevision.UNCHUNKED, true);
-
- if (!handler.handleRevision(revision))
- {
- break;
- }
- }
- else
- {
- // Tell handler about detached IDs
- InternalCDORevision revision = new DetachedCDORevision(null, id, null, version, 0);
- handler.handleRevision(revision);
- }
- }
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- DBUtil.close(resultSet);
- statementCache.releasePreparedStatement(stmt);
- }
- }
-
- @Override
- public Set<CDOID> readChangeSet(IDBStoreAccessor accessor, CDOChangeSetSegment[] segments)
- {
- StringBuilder builder = new StringBuilder(sqlSelectForChangeSet);
- boolean isFirst = true;
-
- for (int i = 0; i < segments.length; i++)
- {
- if (isFirst)
- {
- isFirst = false;
- }
- else
- {
- builder.append(" OR "); //$NON-NLS-1$
- }
-
- builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
- builder.append("=? AND "); //$NON-NLS-1$
-
- builder.append(CDODBSchema.ATTRIBUTES_CREATED);
- builder.append(">=?"); //$NON-NLS-1$
- builder.append(" AND ("); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append("<=? OR "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append("="); //$NON-NLS-1$
- builder.append(CDOBranchPoint.UNSPECIFIED_DATE);
- builder.append(")"); //$NON-NLS-1$
- }
-
- IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
- IPreparedStatementCache statementCache = accessor.getStatementCache();
- PreparedStatement stmt = null;
- ResultSet resultSet = null;
-
- Set<CDOID> result = new HashSet<CDOID>();
-
- try
- {
- stmt = statementCache.getPreparedStatement(builder.toString(), ReuseProbability.LOW);
- int column = 1;
- for (CDOChangeSetSegment segment : segments)
- {
- stmt.setInt(column++, segment.getBranch().getID());
- stmt.setLong(column++, segment.getTimeStamp());
- stmt.setLong(column++, segment.getEndTime());
- }
-
- resultSet = stmt.executeQuery();
- while (resultSet.next())
- {
- CDOID id = idHandler.getCDOID(resultSet, 1);
- result.add(id);
- }
-
- return result;
- }
- catch (SQLException e)
- {
- throw new DBException(e);
- }
- finally
- {
- DBUtil.close(resultSet);
- statementCache.releasePreparedStatement(stmt);
- }
- }
-
- @Override
- protected String getListXRefsWhere(QueryXRefsContext context)
- {
- StringBuilder builder = new StringBuilder();
- builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
- builder.append("=");
- builder.append(context.getBranch().getID());
- builder.append(" AND (");
-
- long timeStamp = context.getTimeStamp();
- if (timeStamp == CDORevision.UNSPECIFIED_DATE)
- {
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append("=0)"); //$NON-NLS-1$
- }
- else
- {
- builder.append(CDODBSchema.ATTRIBUTES_CREATED);
- builder.append("<=");
- builder.append(timeStamp);
- builder.append(" AND ("); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append("=0 OR "); //$NON-NLS-1$
- builder.append(CDODBSchema.ATTRIBUTES_REVISED);
- builder.append(">=");
- builder.append(timeStamp);
- builder.append("))"); //$NON-NLS-1$
- }
-
- return builder.toString();
- }
-
- public void writeRevisionDelta(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created,
- OMMonitor monitor)
- {
- monitor.begin();
-
- try
- {
- if (accessor.getTransaction().getBranch() != delta.getBranch())
- {
- // new branch -> decide, if branch should be copied
- if (((HorizontalBranchingMappingStrategyWithRanges)getMappingStrategy()).shallCopyOnBranch())
- {
- doCopyOnBranch(accessor, delta, created, monitor.fork());
- return;
- }
- }
-
- Async async = null;
-
- try
- {
- async = monitor.forkAsync();
- FeatureDeltaWriter writer = deltaWriter.get();
- writer.process(accessor, delta, created);
- }
- finally
- {
- if (async != null)
- {
- async.stop();
- }
- }
- }
- finally
- {
- monitor.done();
- }
- }
-
- private void doCopyOnBranch(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created, OMMonitor monitor)
- {
- monitor.begin(2);
- try
- {
- InternalRepository repository = (InternalRepository)accessor.getStore().getRepository();
-
- InternalCDORevision oldRevision = (InternalCDORevision)accessor.getTransaction().getRevision(delta.getID());
- if (oldRevision == null)
- {
- throw new IllegalStateException("Origin revision not found for " + delta);
- }
-
- // Make sure all chunks are loaded
- for (EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(oldRevision.getEClass()))
- {
- if (feature.isMany())
- {
- repository.ensureChunk(oldRevision, feature, 0, oldRevision.getList(feature).size());
- }
- }
-
- InternalCDORevision newRevision = oldRevision.copy();
- newRevision.adjustForCommit(accessor.getTransaction().getBranch(), created);
- delta.apply(newRevision);
- monitor.worked();
- writeRevision(accessor, newRevision, false, true, monitor.fork());
- }
- finally
- {
- monitor.done();
- }
- }
-}
+/*
+ * Copyright (c) 2004 - 2012 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
+ * Stefan Winkler - major refactoring
+ * Stefan Winkler - 249610: [DB] Support external references (Implementation)
+ * Stefan Winkler - derived branch mapping from audit mapping
+ * Stefan Winkler - Bug 329025: [DB] Support branching for range-based mapping strategy
+ */
+package org.eclipse.emf.cdo.server.internal.db.mapping.horizontal;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchManager;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.revision.CDOList;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
+import org.eclipse.emf.cdo.common.revision.CDORevisionManager;
+import org.eclipse.emf.cdo.common.revision.delta.CDOAddFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOContainerFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
+import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOMoveFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDORemoveFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta;
+import org.eclipse.emf.cdo.eresource.EresourcePackage;
+import org.eclipse.emf.cdo.server.IRepository;
+import org.eclipse.emf.cdo.server.IStoreAccessor.QueryXRefsContext;
+import org.eclipse.emf.cdo.server.db.IDBStoreAccessor;
+import org.eclipse.emf.cdo.server.db.IIDHandler;
+import org.eclipse.emf.cdo.server.db.IPreparedStatementCache;
+import org.eclipse.emf.cdo.server.db.IPreparedStatementCache.ReuseProbability;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMappingAuditSupport;
+import org.eclipse.emf.cdo.server.db.mapping.IClassMappingDeltaSupport;
+import org.eclipse.emf.cdo.server.db.mapping.IListMapping;
+import org.eclipse.emf.cdo.server.db.mapping.IListMappingDeltaSupport;
+import org.eclipse.emf.cdo.server.db.mapping.ITypeMapping;
+import org.eclipse.emf.cdo.server.internal.db.CDODBSchema;
+import org.eclipse.emf.cdo.server.internal.db.bundle.OM;
+import org.eclipse.emf.cdo.spi.common.commit.CDOChangeSetSegment;
+import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
+import org.eclipse.emf.cdo.spi.server.InternalRepository;
+
+import org.eclipse.net4j.db.DBException;
+import org.eclipse.net4j.db.DBType;
+import org.eclipse.net4j.db.DBUtil;
+import org.eclipse.net4j.db.ddl.IDBField;
+import org.eclipse.net4j.db.ddl.IDBTable;
+import org.eclipse.net4j.util.ImplementationError;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+import org.eclipse.net4j.util.om.monitor.OMMonitor.Async;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Eike Stepper
+ * @author Stefan Winkler
+ * @since 3.0
+ */
+public class HorizontalBranchingClassMapping extends AbstractHorizontalClassMapping implements
+ IClassMappingAuditSupport, IClassMappingDeltaSupport
+{
+ /**
+ * @author Stefan Winkler
+ */
+ private class FeatureDeltaWriter implements CDOFeatureDeltaVisitor
+ {
+ private IDBStoreAccessor accessor;
+
+ private long created;
+
+ private CDOID id;
+
+ private CDOBranch targetBranch;
+
+ private int oldVersion;
+
+ private int newVersion;
+
+ private InternalCDORevision newRevision;
+
+ public void process(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created)
+ {
+ this.accessor = accessor;
+ this.created = created;
+ id = delta.getID();
+ oldVersion = delta.getVersion();
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("FeatureDeltaWriter: old version: {0}, new version: {1}", oldVersion, oldVersion + 1); //$NON-NLS-1$
+ }
+
+ InternalCDORevision originalRevision = (InternalCDORevision)accessor.getTransaction().getRevision(id);
+ newRevision = originalRevision.copy();
+ targetBranch = accessor.getTransaction().getBranch();
+ newRevision.adjustForCommit(targetBranch, created);
+
+ newVersion = newRevision.getVersion();
+
+ // process revision delta tree
+ delta.accept(this);
+
+ if (newVersion != CDORevision.FIRST_VERSION)
+ {
+ reviseOldRevision(accessor, id, delta.getBranch(), newRevision.getTimeStamp() - 1);
+ }
+
+ writeValues(accessor, newRevision);
+ }
+
+ public void visit(CDOMoveFeatureDelta delta)
+ {
+ throw new ImplementationError("Should not be called"); //$NON-NLS-1$
+ }
+
+ public void visit(CDOAddFeatureDelta delta)
+ {
+ throw new ImplementationError("Should not be called"); //$NON-NLS-1$
+ }
+
+ public void visit(CDORemoveFeatureDelta delta)
+ {
+ throw new ImplementationError("Should not be called"); //$NON-NLS-1$
+ }
+
+ public void visit(CDOSetFeatureDelta delta)
+ {
+ delta.apply(newRevision);
+ }
+
+ public void visit(CDOUnsetFeatureDelta delta)
+ {
+ delta.apply(newRevision);
+ }
+
+ public void visit(CDOListFeatureDelta delta)
+ {
+ delta.apply(newRevision);
+ IListMappingDeltaSupport listMapping = (IListMappingDeltaSupport)getListMapping(delta.getFeature());
+ listMapping.processDelta(accessor, id, targetBranch.getID(), oldVersion, newVersion, created, delta);
+ }
+
+ public void visit(CDOClearFeatureDelta delta)
+ {
+ throw new ImplementationError("Should not be called"); //$NON-NLS-1$
+ }
+
+ public void visit(CDOContainerFeatureDelta delta)
+ {
+ delta.apply(newRevision);
+ }
+ }
+
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, HorizontalBranchingClassMapping.class);
+
+ private String sqlInsertAttributes;
+
+ private String sqlSelectCurrentAttributes;
+
+ private String sqlSelectAllObjectIDs;
+
+ private String sqlSelectAttributesByTime;
+
+ private String sqlSelectAttributesByVersion;
+
+ private String sqlReviseAttributes;
+
+ private String sqlSelectForHandle;
+
+ private String sqlSelectForChangeSet;
+
+ private ThreadLocal<FeatureDeltaWriter> deltaWriter = new ThreadLocal<FeatureDeltaWriter>()
+ {
+ @Override
+ protected FeatureDeltaWriter initialValue()
+ {
+ return new FeatureDeltaWriter();
+ }
+ };
+
+ public HorizontalBranchingClassMapping(AbstractHorizontalMappingStrategy mappingStrategy, EClass eClass)
+ {
+ super(mappingStrategy, eClass);
+
+ initSQLStrings();
+ }
+
+ @Override
+ protected IDBField addBranchingField(IDBTable table)
+ {
+ return table.addField(CDODBSchema.ATTRIBUTES_BRANCH, DBType.INTEGER, true);
+ }
+
+ private void initSQLStrings()
+ {
+ Map<EStructuralFeature, String> unsettableFields = getUnsettableFields();
+ Map<EStructuralFeature, String> listSizeFields = getListSizeFields();
+
+ // ----------- Select Revision ---------------------------
+ StringBuilder builder = new StringBuilder();
+
+ builder.append("SELECT "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_VERSION);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_RESOURCE);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_FEATURE);
+
+ for (ITypeMapping singleMapping : getValueMappings())
+ {
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(singleMapping.getField());
+ }
+
+ if (unsettableFields != null)
+ {
+ for (String fieldName : unsettableFields.values())
+ {
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(fieldName);
+ }
+ }
+
+ if (listSizeFields != null)
+ {
+ for (String fieldName : listSizeFields.values())
+ {
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(fieldName);
+ }
+ }
+
+ builder.append(" FROM "); //$NON-NLS-1$
+ builder.append(getTable());
+ builder.append(" WHERE "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append("=? AND "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
+ builder.append("=? AND ("); //$NON-NLS-1$
+ String sqlSelectAttributesPrefix = builder.toString();
+
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append("=0)"); //$NON-NLS-1$
+
+ sqlSelectCurrentAttributes = builder.toString();
+
+ builder = new StringBuilder(sqlSelectAttributesPrefix);
+
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append("<=? AND ("); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append("=0 OR "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(">=?))"); //$NON-NLS-1$
+
+ sqlSelectAttributesByTime = builder.toString();
+
+ builder = new StringBuilder(sqlSelectAttributesPrefix);
+
+ builder.append("ABS("); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_VERSION);
+ builder.append(")=?)"); //$NON-NLS-1$
+
+ sqlSelectAttributesByVersion = builder.toString();
+
+ // ----------- Insert Attributes -------------------------
+ builder = new StringBuilder();
+ builder.append("INSERT INTO "); //$NON-NLS-1$
+ builder.append(getTable());
+
+ builder.append("("); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_VERSION);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_RESOURCE);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_FEATURE);
+
+ for (ITypeMapping singleMapping : getValueMappings())
+ {
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(singleMapping.getField());
+ }
+
+ if (unsettableFields != null)
+ {
+ for (String fieldName : unsettableFields.values())
+ {
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(fieldName);
+ }
+ }
+
+ if (listSizeFields != null)
+ {
+ for (String fieldName : listSizeFields.values())
+ {
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(fieldName);
+ }
+ }
+
+ builder.append(") VALUES (?, ?, ?, ?, ?, ?, ?, ?"); //$NON-NLS-1$
+
+ for (int i = 0; i < getValueMappings().size(); i++)
+ {
+ builder.append(", ?"); //$NON-NLS-1$
+ }
+
+ if (unsettableFields != null)
+ {
+ for (int i = 0; i < unsettableFields.size(); i++)
+ {
+ builder.append(", ?"); //$NON-NLS-1$
+ }
+ }
+
+ if (listSizeFields != null)
+ {
+ for (int i = 0; i < listSizeFields.size(); i++)
+ {
+ builder.append(", ?"); //$NON-NLS-1$
+ }
+ }
+
+ builder.append(")"); //$NON-NLS-1$
+ sqlInsertAttributes = builder.toString();
+
+ // ----------- Update to set revised ----------------
+ builder = new StringBuilder("UPDATE "); //$NON-NLS-1$
+ builder.append(getTable());
+ builder.append(" SET "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append("=? WHERE "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append("=? AND "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
+ builder.append("=? AND "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append("=0"); //$NON-NLS-1$
+ sqlReviseAttributes = builder.toString();
+
+ // ----------- Select all unrevised Object IDs ------
+ builder = new StringBuilder("SELECT "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(" FROM "); //$NON-NLS-1$
+ builder.append(getTable());
+ builder.append(" WHERE "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append("=0"); //$NON-NLS-1$
+ sqlSelectAllObjectIDs = builder.toString();
+
+ // ----------- Select all revisions (for handleRevision) ---
+ builder = new StringBuilder("SELECT "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_VERSION);
+ builder.append(", "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
+ builder.append(" FROM "); //$NON-NLS-1$
+ builder.append(getTable());
+ sqlSelectForHandle = builder.toString();
+
+ // ----------- Select all revisions (for handleRevision) ---
+ builder = new StringBuilder("SELECT DISTINCT "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(" FROM "); //$NON-NLS-1$
+ builder.append(getTable());
+ builder.append(" WHERE "); //$NON-NLS-1$
+ sqlSelectForChangeSet = builder.toString();
+ }
+
+ public boolean readRevision(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk)
+ {
+ IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+ IPreparedStatementCache statementCache = accessor.getStatementCache();
+ PreparedStatement stmt = null;
+
+ long timeStamp = revision.getTimeStamp();
+ int branchID = revision.getBranch().getID();
+
+ try
+ {
+ if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE)
+ {
+ stmt = statementCache.getPreparedStatement(sqlSelectAttributesByTime, ReuseProbability.MEDIUM);
+ idHandler.setCDOID(stmt, 1, revision.getID());
+ stmt.setInt(2, branchID);
+ stmt.setLong(3, timeStamp);
+ stmt.setLong(4, timeStamp);
+ }
+ else
+ {
+ stmt = statementCache.getPreparedStatement(sqlSelectCurrentAttributes, ReuseProbability.HIGH);
+ idHandler.setCDOID(stmt, 1, revision.getID());
+ stmt.setInt(2, branchID);
+ }
+
+ // Read singleval-attribute table always (even without modeled attributes!)
+ boolean success = readValuesFromStatement(stmt, revision, accessor);
+
+ // Read multival tables only if revision exists
+ if (success && revision.getVersion() >= CDOBranchVersion.FIRST_VERSION)
+ {
+ readLists(accessor, revision, listChunk);
+ }
+
+ return success;
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ statementCache.releasePreparedStatement(stmt);
+ }
+ }
+
+ public boolean readRevisionByVersion(IDBStoreAccessor accessor, InternalCDORevision revision, int listChunk)
+ {
+ IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+ IPreparedStatementCache statementCache = accessor.getStatementCache();
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = statementCache.getPreparedStatement(sqlSelectAttributesByVersion, ReuseProbability.HIGH);
+ idHandler.setCDOID(stmt, 1, revision.getID());
+ stmt.setInt(2, revision.getBranch().getID());
+ stmt.setInt(3, revision.getVersion());
+
+ // Read singleval-attribute table always (even without modeled attributes!)
+ boolean success = readValuesFromStatement(stmt, revision, accessor);
+
+ // Read multival tables only if revision exists
+ if (success)
+ {
+ readLists(accessor, revision, listChunk);
+ }
+
+ return success;
+ }
+ catch (SQLException ex)
+ {
+ throw new DBException(ex);
+ }
+ finally
+ {
+ statementCache.releasePreparedStatement(stmt);
+ }
+ }
+
+ public PreparedStatement createResourceQueryStatement(IDBStoreAccessor accessor, CDOID folderId, String name,
+ boolean exactMatch, CDOBranchPoint branchPoint)
+ {
+ EStructuralFeature nameFeature = EresourcePackage.eINSTANCE.getCDOResourceNode_Name();
+
+ ITypeMapping nameValueMapping = getValueMapping(nameFeature);
+ if (nameValueMapping == null)
+ {
+ throw new ImplementationError(nameFeature + " not found in ClassMapping " + this); //$NON-NLS-1$
+ }
+
+ int branchID = branchPoint.getBranch().getID();
+ long timeStamp = branchPoint.getTimeStamp();
+
+ StringBuilder builder = new StringBuilder();
+ builder.append("SELECT "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_ID);
+ builder.append(" FROM "); //$NON-NLS-1$
+ builder.append(getTable());
+ builder.append(" WHERE "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_VERSION);
+ builder.append(">0 AND "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
+ builder.append("=? AND "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_CONTAINER);
+ builder.append("=? AND "); //$NON-NLS-1$
+ builder.append(nameValueMapping.getField());
+ if (name == null)
+ {
+ builder.append(" IS NULL"); //$NON-NLS-1$
+ }
+ else
+ {
+ builder.append(exactMatch ? " =?" : " LIKE ?"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ builder.append(" AND ("); //$NON-NLS-1$
+
+ if (timeStamp == CDORevision.UNSPECIFIED_DATE)
+ {
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append("=0)"); //$NON-NLS-1$
+ }
+ else
+ {
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append("<=? AND ("); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append("=0 OR "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(">=?))"); //$NON-NLS-1$
+ }
+
+ IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+ IPreparedStatementCache statementCache = accessor.getStatementCache();
+ PreparedStatement stmt = null;
+
+ try
+ {
+ int column = 1;
+
+ stmt = statementCache.getPreparedStatement(builder.toString(), ReuseProbability.MEDIUM);
+ stmt.setInt(column++, branchID);
+ idHandler.setCDOID(stmt, column++, folderId);
+
+ if (name != null)
+ {
+ String queryName = exactMatch ? name : name + "%"; //$NON-NLS-1$
+ nameValueMapping.setValue(stmt, column++, queryName);
+ }
+
+ if (timeStamp != CDORevision.UNSPECIFIED_DATE)
+ {
+ stmt.setLong(column++, timeStamp);
+ stmt.setLong(column++, timeStamp);
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Created Resource Query: {0}", stmt.toString()); //$NON-NLS-1$
+ }
+
+ return stmt;
+ }
+ catch (SQLException ex)
+ {
+ statementCache.releasePreparedStatement(stmt); // only release on error
+ throw new DBException(ex);
+ }
+ }
+
+ public PreparedStatement createObjectIDStatement(IDBStoreAccessor accessor)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Created ObjectID Statement : {0}", sqlSelectAllObjectIDs); //$NON-NLS-1$
+ }
+
+ IPreparedStatementCache statementCache = accessor.getStatementCache();
+ return statementCache.getPreparedStatement(sqlSelectAllObjectIDs, ReuseProbability.HIGH);
+ }
+
+ @Override
+ protected final void writeValues(IDBStoreAccessor accessor, InternalCDORevision revision)
+ {
+ IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+ IPreparedStatementCache statementCache = accessor.getStatementCache();
+ PreparedStatement stmt = null;
+
+ try
+ {
+ int column = 1;
+ stmt = statementCache.getPreparedStatement(sqlInsertAttributes, ReuseProbability.HIGH);
+ idHandler.setCDOID(stmt, column++, revision.getID());
+ stmt.setInt(column++, revision.getVersion());
+ stmt.setInt(column++, revision.getBranch().getID());
+ stmt.setLong(column++, revision.getTimeStamp());
+ stmt.setLong(column++, revision.getRevised());
+ idHandler.setCDOID(stmt, column++, revision.getResourceID());
+ idHandler.setCDOID(stmt, column++, (CDOID)revision.getContainerID());
+ stmt.setInt(column++, revision.getContainingFeatureID());
+
+ int isSetCol = column + getValueMappings().size();
+
+ for (ITypeMapping mapping : getValueMappings())
+ {
+ EStructuralFeature feature = mapping.getFeature();
+ if (feature.isUnsettable())
+ {
+ if (revision.getValue(feature) == null)
+ {
+ stmt.setBoolean(isSetCol++, false);
+
+ // also set value column to default value
+ mapping.setDefaultValue(stmt, column++);
+ continue;
+ }
+
+ stmt.setBoolean(isSetCol++, true);
+ }
+
+ mapping.setValueFromRevision(stmt, column++, revision);
+ }
+
+ Map<EStructuralFeature, String> listSizeFields = getListSizeFields();
+ if (listSizeFields != null)
+ {
+ // isSetCol now points to the first listTableSize-column
+ column = isSetCol;
+
+ for (EStructuralFeature feature : listSizeFields.keySet())
+ {
+ CDOList list = revision.getList(feature);
+ stmt.setInt(column++, list.size());
+ }
+ }
+
+ DBUtil.update(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ statementCache.releasePreparedStatement(stmt);
+ }
+ }
+
+ @Override
+ protected void detachAttributes(IDBStoreAccessor accessor, CDOID id, int version, CDOBranch branch, long timeStamp,
+ OMMonitor mon)
+ {
+ IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+ IPreparedStatementCache statementCache = accessor.getStatementCache();
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = statementCache.getPreparedStatement(sqlInsertAttributes, ReuseProbability.HIGH);
+
+ int column = 1;
+ idHandler.setCDOID(stmt, column++, id);
+ stmt.setInt(column++, -version); // cdo_version
+ stmt.setInt(column++, branch.getID());
+ stmt.setLong(column++, timeStamp); // cdo_created
+ stmt.setLong(column++, CDOBranchPoint.UNSPECIFIED_DATE); // cdo_revised
+ idHandler.setCDOID(stmt, column++, CDOID.NULL); // resource
+ idHandler.setCDOID(stmt, column++, CDOID.NULL); // container
+ stmt.setInt(column++, 0); // containing feature ID
+
+ int isSetCol = column + getValueMappings().size();
+
+ for (ITypeMapping mapping : getValueMappings())
+ {
+ EStructuralFeature feature = mapping.getFeature();
+ if (feature.isUnsettable())
+ {
+ stmt.setBoolean(isSetCol++, false);
+ }
+
+ mapping.setDefaultValue(stmt, column++);
+ }
+
+ Map<EStructuralFeature, String> listSizeFields = getListSizeFields();
+ if (listSizeFields != null)
+ {
+ // list size columns begin after isSet-columns
+ column = isSetCol;
+
+ for (int i = 0; i < listSizeFields.size(); i++)
+ {
+ stmt.setInt(column++, 0);
+ }
+ }
+
+ DBUtil.update(stmt, true);
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ statementCache.releasePreparedStatement(stmt);
+ }
+ }
+
+ @Override
+ protected void reviseOldRevision(IDBStoreAccessor accessor, CDOID id, CDOBranch branch, long revised)
+ {
+ IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+ IPreparedStatementCache statementCache = accessor.getStatementCache();
+ PreparedStatement stmt = null;
+
+ try
+ {
+ stmt = statementCache.getPreparedStatement(sqlReviseAttributes, ReuseProbability.HIGH);
+
+ stmt.setLong(1, revised);
+ idHandler.setCDOID(stmt, 2, id);
+ stmt.setInt(3, branch.getID());
+
+ DBUtil.update(stmt, false); // No row affected if old revision from other branch!
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ statementCache.releasePreparedStatement(stmt);
+ }
+ }
+
+ @Override
+ public void writeRevision(IDBStoreAccessor accessor, InternalCDORevision revision, boolean mapType, boolean revise,
+ OMMonitor monitor)
+ {
+ Async async = null;
+ monitor.begin(10);
+
+ try
+ {
+ try
+ {
+ async = monitor.forkAsync();
+ CDOID id = revision.getID();
+ if (mapType)
+ {
+ // put new objects into objectTypeMapper
+ long timeStamp = revision.getTimeStamp();
+ AbstractHorizontalMappingStrategy mappingStrategy = (AbstractHorizontalMappingStrategy)getMappingStrategy();
+ mappingStrategy.putObjectType(accessor, timeStamp, id, getEClass());
+ }
+ else if (revise && revision.getVersion() > CDOBranchVersion.FIRST_VERSION)
+ {
+ // if revision is not the first one, revise the old revision
+ long revised = revision.getTimeStamp() - 1;
+ reviseOldRevision(accessor, id, revision.getBranch(), revised);
+ for (IListMapping mapping : getListMappings())
+ {
+ mapping.objectDetached(accessor, id, revised);
+ }
+ }
+ }
+ finally
+ {
+ if (async != null)
+ {
+ async.stop();
+ }
+ }
+
+ try
+ {
+ async = monitor.forkAsync();
+ if (revision.isResourceFolder() || revision.isResource())
+ {
+ checkDuplicateResources(accessor, revision);
+ }
+ }
+ finally
+ {
+ if (async != null)
+ {
+ async.stop();
+ }
+ }
+
+ try
+ {
+ // Write attribute table always (even without modeled attributes!)
+ async = monitor.forkAsync();
+ writeValues(accessor, revision);
+ }
+ finally
+ {
+ if (async != null)
+ {
+ async.stop();
+ }
+ }
+
+ try
+ {
+ // Write list tables only if they exist
+ async = monitor.forkAsync(7);
+ if (getListMappings() != null)
+ {
+ writeLists(accessor, revision);
+ }
+ }
+ finally
+ {
+ if (async != null)
+ {
+ async.stop();
+ }
+ }
+ }
+ finally
+ {
+ monitor.done();
+ }
+ }
+
+ @Override
+ public void handleRevisions(IDBStoreAccessor accessor, CDOBranch branch, long timeStamp, boolean exactTime,
+ CDORevisionHandler handler)
+ {
+ StringBuilder builder = new StringBuilder(sqlSelectForHandle);
+ boolean whereAppend = false;
+
+ if (branch != null)
+ {
+ // TODO: Prepare this string literal
+ builder.append(" WHERE "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
+ builder.append("=?"); //$NON-NLS-1$
+
+ whereAppend = true;
+ }
+
+ int timeParameters = 0;
+ if (timeStamp != CDOBranchPoint.INVALID_DATE)
+ {
+ if (exactTime)
+ {
+ if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE)
+ {
+ builder.append(whereAppend ? " AND " : " WHERE "); //$NON-NLS-1$ //$NON-NLS-2$
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append("=?"); //$NON-NLS-1$
+ timeParameters = 1;
+ }
+ }
+ else
+ {
+ builder.append(whereAppend ? " AND " : " WHERE "); //$NON-NLS-1$ //$NON-NLS-2$
+ if (timeStamp != CDOBranchPoint.UNSPECIFIED_DATE)
+ {
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append("<=? AND ("); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append("=0 OR "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(">=?)"); //$NON-NLS-1$
+ timeParameters = 2;
+ }
+ else
+ {
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append("="); //$NON-NLS-1$
+ builder.append(CDOBranchPoint.UNSPECIFIED_DATE);
+ }
+ }
+ }
+
+ IRepository repository = accessor.getStore().getRepository();
+ CDORevisionManager revisionManager = repository.getRevisionManager();
+ CDOBranchManager branchManager = repository.getBranchManager();
+
+ IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+ IPreparedStatementCache statementCache = accessor.getStatementCache();
+ PreparedStatement stmt = null;
+ ResultSet resultSet = null;
+
+ try
+ {
+ stmt = statementCache.getPreparedStatement(builder.toString(), ReuseProbability.LOW);
+
+ int column = 1;
+ if (branch != null)
+ {
+ stmt.setInt(column++, branch.getID());
+ }
+
+ for (int i = 0; i < timeParameters; i++)
+ {
+ stmt.setLong(column++, timeStamp);
+ }
+
+ resultSet = stmt.executeQuery();
+ while (resultSet.next())
+ {
+ CDOID id = idHandler.getCDOID(resultSet, 1);
+ int version = resultSet.getInt(2);
+
+ if (version >= CDOBranchVersion.FIRST_VERSION)
+ {
+ int branchID = resultSet.getInt(3);
+ CDOBranchVersion branchVersion = branchManager.getBranch(branchID).getVersion(Math.abs(version));
+ InternalCDORevision revision = (InternalCDORevision)revisionManager.getRevisionByVersion(id, branchVersion,
+ CDORevision.UNCHUNKED, true);
+
+ if (!handler.handleRevision(revision))
+ {
+ break;
+ }
+ }
+ else
+ {
+ // Tell handler about detached IDs
+ InternalCDORevision revision = new DetachedCDORevision(null, id, null, version, 0);
+ handler.handleRevision(revision);
+ }
+ }
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ DBUtil.close(resultSet);
+ statementCache.releasePreparedStatement(stmt);
+ }
+ }
+
+ @Override
+ public Set<CDOID> readChangeSet(IDBStoreAccessor accessor, CDOChangeSetSegment[] segments)
+ {
+ StringBuilder builder = new StringBuilder(sqlSelectForChangeSet);
+ boolean isFirst = true;
+
+ for (int i = 0; i < segments.length; i++)
+ {
+ if (isFirst)
+ {
+ isFirst = false;
+ }
+ else
+ {
+ builder.append(" OR "); //$NON-NLS-1$
+ }
+
+ builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
+ builder.append("=? AND "); //$NON-NLS-1$
+
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append(">=?"); //$NON-NLS-1$
+ builder.append(" AND ("); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append("<=? OR "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append("="); //$NON-NLS-1$
+ builder.append(CDOBranchPoint.UNSPECIFIED_DATE);
+ builder.append(")"); //$NON-NLS-1$
+ }
+
+ IIDHandler idHandler = getMappingStrategy().getStore().getIDHandler();
+ IPreparedStatementCache statementCache = accessor.getStatementCache();
+ PreparedStatement stmt = null;
+ ResultSet resultSet = null;
+
+ Set<CDOID> result = new HashSet<CDOID>();
+
+ try
+ {
+ stmt = statementCache.getPreparedStatement(builder.toString(), ReuseProbability.LOW);
+ int column = 1;
+ for (CDOChangeSetSegment segment : segments)
+ {
+ stmt.setInt(column++, segment.getBranch().getID());
+ stmt.setLong(column++, segment.getTimeStamp());
+ stmt.setLong(column++, segment.getEndTime());
+ }
+
+ resultSet = stmt.executeQuery();
+ while (resultSet.next())
+ {
+ CDOID id = idHandler.getCDOID(resultSet, 1);
+ result.add(id);
+ }
+
+ return result;
+ }
+ catch (SQLException e)
+ {
+ throw new DBException(e);
+ }
+ finally
+ {
+ DBUtil.close(resultSet);
+ statementCache.releasePreparedStatement(stmt);
+ }
+ }
+
+ @Override
+ protected String getListXRefsWhere(QueryXRefsContext context)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append(CDODBSchema.ATTRIBUTES_BRANCH);
+ builder.append("=");
+ builder.append(context.getBranch().getID());
+ builder.append(" AND (");
+
+ long timeStamp = context.getTimeStamp();
+ if (timeStamp == CDORevision.UNSPECIFIED_DATE)
+ {
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append("=0)"); //$NON-NLS-1$
+ }
+ else
+ {
+ builder.append(CDODBSchema.ATTRIBUTES_CREATED);
+ builder.append("<=");
+ builder.append(timeStamp);
+ builder.append(" AND ("); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append("=0 OR "); //$NON-NLS-1$
+ builder.append(CDODBSchema.ATTRIBUTES_REVISED);
+ builder.append(">=");
+ builder.append(timeStamp);
+ builder.append("))"); //$NON-NLS-1$
+ }
+
+ return builder.toString();
+ }
+
+ public void writeRevisionDelta(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created,
+ OMMonitor monitor)
+ {
+ monitor.begin();
+
+ try
+ {
+ if (accessor.getTransaction().getBranch() != delta.getBranch())
+ {
+ // new branch -> decide, if branch should be copied
+ if (((HorizontalBranchingMappingStrategyWithRanges)getMappingStrategy()).shallCopyOnBranch())
+ {
+ doCopyOnBranch(accessor, delta, created, monitor.fork());
+ return;
+ }
+ }
+
+ Async async = null;
+
+ try
+ {
+ async = monitor.forkAsync();
+ FeatureDeltaWriter writer = deltaWriter.get();
+ writer.process(accessor, delta, created);
+ }
+ finally
+ {
+ if (async != null)
+ {
+ async.stop();
+ }
+ }
+ }
+ finally
+ {
+ monitor.done();
+ }
+ }
+
+ private void doCopyOnBranch(IDBStoreAccessor accessor, InternalCDORevisionDelta delta, long created, OMMonitor monitor)
+ {
+ monitor.begin(2);
+ try
+ {
+ InternalRepository repository = (InternalRepository)accessor.getStore().getRepository();
+
+ InternalCDORevision oldRevision = (InternalCDORevision)accessor.getTransaction().getRevision(delta.getID());
+ if (oldRevision == null)
+ {
+ throw new IllegalStateException("Origin revision not found for " + delta);
+ }
+
+ // Make sure all chunks are loaded
+ repository.ensureChunks(oldRevision);
+
+ InternalCDORevision newRevision = oldRevision.copy();
+ newRevision.adjustForCommit(accessor.getTransaction().getBranch(), created);
+ delta.apply(newRevision);
+ monitor.worked();
+ writeRevision(accessor, newRevision, false, true, monitor.fork());
+ }
+ finally
+ {
+ monitor.done();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/DelegatingRepository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/DelegatingRepository.java
index d65e8a6b7f..9b899553c1 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/DelegatingRepository.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/DelegatingRepository.java
@@ -1,287 +1,542 @@
-/*
- * Copyright (c) 2004 - 2012 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.server;
-
-import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
-import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.util.CDOQueryInfo;
-import org.eclipse.emf.cdo.server.IQueryHandler;
-import org.eclipse.emf.cdo.server.IQueryHandlerProvider;
-import org.eclipse.emf.cdo.server.IStoreAccessor;
-import org.eclipse.emf.cdo.server.IStoreAccessor.CommitContext;
-import org.eclipse.emf.cdo.server.ITransaction;
-import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
-import org.eclipse.emf.cdo.spi.common.revision.RevisionInfo;
-import org.eclipse.emf.cdo.spi.server.InternalCommitManager;
-import org.eclipse.emf.cdo.spi.server.InternalLockManager;
-import org.eclipse.emf.cdo.spi.server.InternalQueryManager;
-import org.eclipse.emf.cdo.spi.server.InternalRepository;
-import org.eclipse.emf.cdo.spi.server.InternalSession;
-import org.eclipse.emf.cdo.spi.server.InternalSessionManager;
-import org.eclipse.emf.cdo.spi.server.InternalStore;
-
-import org.eclipse.net4j.util.collection.Pair;
-import org.eclipse.net4j.util.event.IListener;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-
-import org.eclipse.emf.ecore.EPackage;
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author Eike Stepper
- */
-public abstract class DelegatingRepository implements InternalRepository
-{
- public DelegatingRepository()
- {
- }
-
- protected abstract InternalRepository getDelegate();
-
- public void addHandler(Handler handler)
- {
- getDelegate().addHandler(handler);
- }
-
- public void addListener(IListener listener)
- {
- getDelegate().addListener(listener);
- }
-
- public long[] createCommitTimeStamp(OMMonitor monitor)
- {
- return getDelegate().createCommitTimeStamp(monitor);
- }
-
- public IStoreAccessor ensureChunk(InternalCDORevision revision, EStructuralFeature feature, int chunkStart,
- int chunkEnd)
- {
- return getDelegate().ensureChunk(revision, feature, chunkStart, chunkEnd);
- }
-
- public InternalCommitManager getCommitManager()
- {
- return getDelegate().getCommitManager();
- }
-
- public long getCreationTime()
- {
- return getDelegate().getCreationTime();
- }
-
- public Object[] getElements()
- {
- return getDelegate().getElements();
- }
-
- public long getLastCommitTimeStamp()
- {
- return getDelegate().getLastCommitTimeStamp();
- }
-
- public IListener[] getListeners()
- {
- return getDelegate().getListeners();
- }
-
- @Deprecated
- public InternalLockManager getLockManager()
- {
- return getDelegate().getLockingManager();
- }
-
- public String getName()
- {
- return getDelegate().getName();
- }
-
- public InternalCDOPackageRegistry getPackageRegistry()
- {
- return getDelegate().getPackageRegistry();
- }
-
- public InternalCDOPackageRegistry getPackageRegistry(boolean considerCommitContext)
- {
- return getDelegate().getPackageRegistry(considerCommitContext);
- }
-
- public Map<String, String> getProperties()
- {
- return getDelegate().getProperties();
- }
-
- public IQueryHandler getQueryHandler(CDOQueryInfo info)
- {
- return getDelegate().getQueryHandler(info);
- }
-
- public IQueryHandlerProvider getQueryHandlerProvider()
- {
- return getDelegate().getQueryHandlerProvider();
- }
-
- public InternalQueryManager getQueryManager()
- {
- return getDelegate().getQueryManager();
- }
-
- public InternalCDORevisionManager getRevisionManager()
- {
- return getDelegate().getRevisionManager();
- }
-
- public InternalSessionManager getSessionManager()
- {
- return getDelegate().getSessionManager();
- }
-
- public InternalStore getStore()
- {
- return getDelegate().getStore();
- }
-
- public String getUUID()
- {
- return getDelegate().getUUID();
- }
-
- public boolean hasListeners()
- {
- return getDelegate().hasListeners();
- }
-
- public boolean isEmpty()
- {
- return getDelegate().isEmpty();
- }
-
- public boolean isSupportingAudits()
- {
- return getDelegate().isSupportingAudits();
- }
-
- public boolean isSupportingBranches()
- {
- return getDelegate().isSupportingBranches();
- }
-
- public EPackage[] loadPackages(CDOPackageUnit packageUnit)
- {
- return getDelegate().loadPackages(packageUnit);
- }
-
- public InternalCDOBranchManager getBranchManager()
- {
- return getDelegate().getBranchManager();
- }
-
- public void setBranchManager(InternalCDOBranchManager branchManager)
- {
- getDelegate().setBranchManager(branchManager);
- }
-
- public Pair<Integer, Long> createBranch(int branchID, BranchInfo branchInfo)
- {
- return getDelegate().createBranch(branchID, branchInfo);
- }
-
- public BranchInfo loadBranch(int branchID)
- {
- return getDelegate().loadBranch(branchID);
- }
-
- public SubBranchInfo[] loadSubBranches(int branchID)
- {
- return getDelegate().loadSubBranches(branchID);
- }
-
- public List<InternalCDORevision> loadRevisions(List<RevisionInfo> infos, CDOBranchPoint branchPoint,
- int referenceChunk, int prefetchDepth)
- {
- return getDelegate().loadRevisions(infos, branchPoint, referenceChunk, prefetchDepth);
- }
-
- public InternalCDORevision loadRevisionByVersion(CDOID id, CDOBranchVersion branchVersion, int referenceChunk)
- {
- return getDelegate().loadRevisionByVersion(id, branchVersion, referenceChunk);
- }
-
- public void notifyReadAccessHandlers(InternalSession session, CDORevision[] revisions,
- List<CDORevision> additionalRevisions)
- {
- getDelegate().notifyReadAccessHandlers(session, revisions, additionalRevisions);
- }
-
- public void notifyWriteAccessHandlers(ITransaction transaction, CommitContext commitContext, boolean beforeCommit,
- OMMonitor monitor)
- {
- getDelegate().notifyWriteAccessHandlers(transaction, commitContext, beforeCommit, monitor);
- }
-
- public void removeHandler(Handler handler)
- {
- getDelegate().removeHandler(handler);
- }
-
- public void removeListener(IListener listener)
- {
- getDelegate().removeListener(listener);
- }
-
- public void setName(String name)
- {
- getDelegate().setName(name);
- }
-
- public void setProperties(Map<String, String> properties)
- {
- getDelegate().setProperties(properties);
- }
-
- public void setQueryHandlerProvider(IQueryHandlerProvider queryHandlerProvider)
- {
- getDelegate().setQueryHandlerProvider(queryHandlerProvider);
- }
-
- public void setRevisionManager(InternalCDORevisionManager revisionManager)
- {
- getDelegate().setRevisionManager(revisionManager);
- }
-
- public void setSessionManager(InternalSessionManager sessionManager)
- {
- getDelegate().setSessionManager(sessionManager);
- }
-
- public void setStore(InternalStore store)
- {
- getDelegate().setStore(store);
- }
-
- public long getTimeStamp()
- {
- return getDelegate().getTimeStamp();
- }
-
- public void validateTimeStamp(long timeStamp) throws IllegalArgumentException
- {
- getDelegate().validateTimeStamp(timeStamp);
- }
-}
+/*
+ * Copyright (c) 2004 - 2012 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.server;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchHandler;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
+import org.eclipse.emf.cdo.common.commit.CDOCommitData;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOID.ObjectType;
+import org.eclipse.emf.cdo.common.lob.CDOLobHandler;
+import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
+import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
+import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
+import org.eclipse.emf.cdo.common.util.CDOQueryInfo;
+import org.eclipse.emf.cdo.server.IQueryHandler;
+import org.eclipse.emf.cdo.server.IQueryHandlerProvider;
+import org.eclipse.emf.cdo.server.IStoreAccessor;
+import org.eclipse.emf.cdo.server.IStoreAccessor.CommitContext;
+import org.eclipse.emf.cdo.server.ITransaction;
+import org.eclipse.emf.cdo.spi.common.CDOReplicationContext;
+import org.eclipse.emf.cdo.spi.common.CDOReplicationInfo;
+import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
+import org.eclipse.emf.cdo.spi.common.commit.CDORevisionAvailabilityInfo;
+import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
+import org.eclipse.emf.cdo.spi.common.revision.RevisionInfo;
+import org.eclipse.emf.cdo.spi.server.InternalCommitContext;
+import org.eclipse.emf.cdo.spi.server.InternalCommitManager;
+import org.eclipse.emf.cdo.spi.server.InternalLockManager;
+import org.eclipse.emf.cdo.spi.server.InternalQueryManager;
+import org.eclipse.emf.cdo.spi.server.InternalRepository;
+import org.eclipse.emf.cdo.spi.server.InternalSession;
+import org.eclipse.emf.cdo.spi.server.InternalSessionManager;
+import org.eclipse.emf.cdo.spi.server.InternalStore;
+import org.eclipse.emf.cdo.spi.server.InternalTransaction;
+import org.eclipse.emf.cdo.spi.server.InternalView;
+
+import org.eclipse.net4j.util.collection.Pair;
+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
+import org.eclipse.net4j.util.event.IListener;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.spi.cdo.CDOSessionProtocol.LockObjectsResult;
+import org.eclipse.emf.spi.cdo.CDOSessionProtocol.UnlockObjectsResult;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Semaphore;
+
+/**
+ * @author Eike Stepper
+ */
+public abstract class DelegatingRepository implements InternalRepository
+{
+ public DelegatingRepository()
+ {
+ }
+
+ protected abstract InternalRepository getDelegate();
+
+ public void addHandler(Handler handler)
+ {
+ getDelegate().addHandler(handler);
+ }
+
+ public void addListener(IListener listener)
+ {
+ getDelegate().addListener(listener);
+ }
+
+ public long[] createCommitTimeStamp(OMMonitor monitor)
+ {
+ return getDelegate().createCommitTimeStamp(monitor);
+ }
+
+ public IStoreAccessor ensureChunk(InternalCDORevision revision, EStructuralFeature feature, int chunkStart,
+ int chunkEnd)
+ {
+ return getDelegate().ensureChunk(revision, feature, chunkStart, chunkEnd);
+ }
+
+ public InternalCommitManager getCommitManager()
+ {
+ return getDelegate().getCommitManager();
+ }
+
+ public long getCreationTime()
+ {
+ return getDelegate().getCreationTime();
+ }
+
+ public Object[] getElements()
+ {
+ return getDelegate().getElements();
+ }
+
+ public long getLastCommitTimeStamp()
+ {
+ return getDelegate().getLastCommitTimeStamp();
+ }
+
+ public IListener[] getListeners()
+ {
+ return getDelegate().getListeners();
+ }
+
+ @Deprecated
+ public InternalLockManager getLockManager()
+ {
+ return getDelegate().getLockingManager();
+ }
+
+ public String getName()
+ {
+ return getDelegate().getName();
+ }
+
+ public InternalCDOPackageRegistry getPackageRegistry()
+ {
+ return getDelegate().getPackageRegistry();
+ }
+
+ public InternalCDOPackageRegistry getPackageRegistry(boolean considerCommitContext)
+ {
+ return getDelegate().getPackageRegistry(considerCommitContext);
+ }
+
+ public Map<String, String> getProperties()
+ {
+ return getDelegate().getProperties();
+ }
+
+ public IQueryHandler getQueryHandler(CDOQueryInfo info)
+ {
+ return getDelegate().getQueryHandler(info);
+ }
+
+ public IQueryHandlerProvider getQueryHandlerProvider()
+ {
+ return getDelegate().getQueryHandlerProvider();
+ }
+
+ public InternalQueryManager getQueryManager()
+ {
+ return getDelegate().getQueryManager();
+ }
+
+ public InternalCDORevisionManager getRevisionManager()
+ {
+ return getDelegate().getRevisionManager();
+ }
+
+ public InternalSessionManager getSessionManager()
+ {
+ return getDelegate().getSessionManager();
+ }
+
+ public InternalStore getStore()
+ {
+ return getDelegate().getStore();
+ }
+
+ public String getUUID()
+ {
+ return getDelegate().getUUID();
+ }
+
+ public boolean hasListeners()
+ {
+ return getDelegate().hasListeners();
+ }
+
+ public boolean isEmpty()
+ {
+ return getDelegate().isEmpty();
+ }
+
+ public boolean isSupportingAudits()
+ {
+ return getDelegate().isSupportingAudits();
+ }
+
+ public boolean isSupportingBranches()
+ {
+ return getDelegate().isSupportingBranches();
+ }
+
+ public EPackage[] loadPackages(CDOPackageUnit packageUnit)
+ {
+ return getDelegate().loadPackages(packageUnit);
+ }
+
+ public InternalCDOBranchManager getBranchManager()
+ {
+ return getDelegate().getBranchManager();
+ }
+
+ public void setBranchManager(InternalCDOBranchManager branchManager)
+ {
+ getDelegate().setBranchManager(branchManager);
+ }
+
+ public Pair<Integer, Long> createBranch(int branchID, BranchInfo branchInfo)
+ {
+ return getDelegate().createBranch(branchID, branchInfo);
+ }
+
+ public BranchInfo loadBranch(int branchID)
+ {
+ return getDelegate().loadBranch(branchID);
+ }
+
+ public SubBranchInfo[] loadSubBranches(int branchID)
+ {
+ return getDelegate().loadSubBranches(branchID);
+ }
+
+ public List<InternalCDORevision> loadRevisions(List<RevisionInfo> infos, CDOBranchPoint branchPoint,
+ int referenceChunk, int prefetchDepth)
+ {
+ return getDelegate().loadRevisions(infos, branchPoint, referenceChunk, prefetchDepth);
+ }
+
+ public InternalCDORevision loadRevisionByVersion(CDOID id, CDOBranchVersion branchVersion, int referenceChunk)
+ {
+ return getDelegate().loadRevisionByVersion(id, branchVersion, referenceChunk);
+ }
+
+ public void notifyReadAccessHandlers(InternalSession session, CDORevision[] revisions,
+ List<CDORevision> additionalRevisions)
+ {
+ getDelegate().notifyReadAccessHandlers(session, revisions, additionalRevisions);
+ }
+
+ public void notifyWriteAccessHandlers(ITransaction transaction, CommitContext commitContext, boolean beforeCommit,
+ OMMonitor monitor)
+ {
+ getDelegate().notifyWriteAccessHandlers(transaction, commitContext, beforeCommit, monitor);
+ }
+
+ public void removeHandler(Handler handler)
+ {
+ getDelegate().removeHandler(handler);
+ }
+
+ public void removeListener(IListener listener)
+ {
+ getDelegate().removeListener(listener);
+ }
+
+ public void setName(String name)
+ {
+ getDelegate().setName(name);
+ }
+
+ public void setProperties(Map<String, String> properties)
+ {
+ getDelegate().setProperties(properties);
+ }
+
+ public void setQueryHandlerProvider(IQueryHandlerProvider queryHandlerProvider)
+ {
+ getDelegate().setQueryHandlerProvider(queryHandlerProvider);
+ }
+
+ public void setRevisionManager(InternalCDORevisionManager revisionManager)
+ {
+ getDelegate().setRevisionManager(revisionManager);
+ }
+
+ public void setSessionManager(InternalSessionManager sessionManager)
+ {
+ getDelegate().setSessionManager(sessionManager);
+ }
+
+ public void setStore(InternalStore store)
+ {
+ getDelegate().setStore(store);
+ }
+
+ public long getTimeStamp()
+ {
+ return getDelegate().getTimeStamp();
+ }
+
+ public void validateTimeStamp(long timeStamp) throws IllegalArgumentException
+ {
+ getDelegate().validateTimeStamp(timeStamp);
+ }
+
+ public void loadCommitInfos(CDOBranch branch, long startTime, long endTime, CDOCommitInfoHandler handler)
+ {
+ getDelegate().loadCommitInfos(branch, startTime, endTime, handler);
+ }
+
+ public CDOCommitData loadCommitData(long timeStamp)
+ {
+ return getDelegate().loadCommitData(timeStamp);
+ }
+
+ public Type getType()
+ {
+ return getDelegate().getType();
+ }
+
+ public State getState()
+ {
+ return getDelegate().getState();
+ }
+
+ public String getStoreType()
+ {
+ return getDelegate().getStoreType();
+ }
+
+ public Set<ObjectType> getObjectIDTypes()
+ {
+ return getDelegate().getObjectIDTypes();
+ }
+
+ public IDGenerationLocation getIDGenerationLocation()
+ {
+ return getDelegate().getIDGenerationLocation();
+ }
+
+ public CDOID getRootResourceID()
+ {
+ return getDelegate().getRootResourceID();
+ }
+
+ public Object processPackage(Object value)
+ {
+ return getDelegate().processPackage(value);
+ }
+
+ public boolean isSupportingEcore()
+ {
+ return getDelegate().isSupportingEcore();
+ }
+
+ public boolean isEnsuringReferentialIntegrity()
+ {
+ return getDelegate().isEnsuringReferentialIntegrity();
+ }
+
+ public void setType(Type type)
+ {
+ getDelegate().setType(type);
+ }
+
+ public long waitForCommit(long timeout)
+ {
+ return getDelegate().waitForCommit(timeout);
+ }
+
+ public void setState(State state)
+ {
+ getDelegate().setState(state);
+ }
+
+ public int loadBranches(int startID, int endID, CDOBranchHandler branchHandler)
+ {
+ return getDelegate().loadBranches(startID, endID, branchHandler);
+ }
+
+ public Semaphore getPackageRegistryCommitLock()
+ {
+ return getDelegate().getPackageRegistryCommitLock();
+ }
+
+ public CDOCommitInfoHandler[] getCommitInfoHandlers()
+ {
+ return getDelegate().getCommitInfoHandlers();
+ }
+
+ public void addCommitInfoHandler(CDOCommitInfoHandler handler)
+ {
+ getDelegate().addCommitInfoHandler(handler);
+ }
+
+ public void removeCommitInfoHandler(CDOCommitInfoHandler handler)
+ {
+ getDelegate().removeCommitInfoHandler(handler);
+ }
+
+ public InternalCDOCommitInfoManager getCommitInfoManager()
+ {
+ return getDelegate().getCommitInfoManager();
+ }
+
+ public Set<Handler> getHandlers()
+ {
+ return getDelegate().getHandlers();
+ }
+
+ public void setInitialPackages(EPackage... initialPackages)
+ {
+ getDelegate().setInitialPackages(initialPackages);
+ }
+
+ public InternalLockManager getLockingManager()
+ {
+ return getDelegate().getLockingManager();
+ }
+
+ public InternalCommitContext createCommitContext(InternalTransaction transaction)
+ {
+ return getDelegate().createCommitContext(transaction);
+ }
+
+ public long[] forceCommitTimeStamp(long timestamp, OMMonitor monitor)
+ {
+ return getDelegate().forceCommitTimeStamp(timestamp, monitor);
+ }
+
+ public void endCommit(long timeStamp)
+ {
+ getDelegate().endCommit(timeStamp);
+ }
+
+ public void failCommit(long timeStamp)
+ {
+ getDelegate().failCommit(timeStamp);
+ }
+
+ public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo)
+ {
+ getDelegate().sendCommitNotification(sender, commitInfo);
+ }
+
+ public void setRootResourceID(CDOID rootResourceID)
+ {
+ getDelegate().setRootResourceID(rootResourceID);
+ }
+
+ public void setLastCommitTimeStamp(long commitTimeStamp)
+ {
+ getDelegate().setLastCommitTimeStamp(commitTimeStamp);
+ }
+
+ public void ensureChunks(InternalCDORevision revision)
+ {
+ getDelegate().ensureChunks(revision);
+ }
+
+ public void replicate(CDOReplicationContext context)
+ {
+ getDelegate().replicate(context);
+ }
+
+ public CDOReplicationInfo replicateRaw(CDODataOutput out, int lastReplicatedBranchID, long lastReplicatedCommitTime)
+ throws IOException
+ {
+ return getDelegate().replicateRaw(out, lastReplicatedBranchID, lastReplicatedCommitTime);
+ }
+
+ public CDOChangeSetData getChangeSet(CDOBranchPoint startPoint, CDOBranchPoint endPoint)
+ {
+ return getDelegate().getChangeSet(startPoint, endPoint);
+ }
+
+ public Set<CDOID> getMergeData(CDORevisionAvailabilityInfo targetInfo, CDORevisionAvailabilityInfo sourceInfo,
+ CDORevisionAvailabilityInfo targetBaseInfo, CDORevisionAvailabilityInfo sourceBaseInfo, OMMonitor monitor)
+ {
+ return getDelegate().getMergeData(targetInfo, sourceInfo, targetBaseInfo, sourceBaseInfo, monitor);
+ }
+
+ public void queryLobs(List<byte[]> ids)
+ {
+ getDelegate().queryLobs(ids);
+ }
+
+ public void handleLobs(long fromTime, long toTime, CDOLobHandler handler) throws IOException
+ {
+ getDelegate().handleLobs(fromTime, toTime, handler);
+ }
+
+ public void loadLob(byte[] id, OutputStream out) throws IOException
+ {
+ getDelegate().loadLob(id, out);
+ }
+
+ public void handleRevisions(EClass eClass, CDOBranch branch, boolean exactBranch, long timeStamp, boolean exactTime,
+ CDORevisionHandler handler)
+ {
+ getDelegate().handleRevisions(eClass, branch, exactBranch, timeStamp, exactTime, handler);
+ }
+
+ public boolean isSkipInitialization()
+ {
+ return getDelegate().isSkipInitialization();
+ }
+
+ public void setSkipInitialization(boolean skipInitialization)
+ {
+ getDelegate().setSkipInitialization(skipInitialization);
+ }
+
+ public void initSystemPackages()
+ {
+ getDelegate().initSystemPackages();
+ }
+
+ public void initMainBranch(InternalCDOBranchManager branchManager, long timeStamp)
+ {
+ getDelegate().initMainBranch(branchManager, timeStamp);
+ }
+
+ public LockObjectsResult lock(InternalView view, LockType type, List<CDORevisionKey> keys, boolean recursive,
+ long timeout)
+ {
+ return getDelegate().lock(view, type, keys, recursive, timeout);
+ }
+
+ public UnlockObjectsResult unlock(InternalView view, LockType type, List<CDOID> ids, boolean recursive)
+ {
+ return getDelegate().unlock(view, type, ids, recursive);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
index 669bf76b9d..8347f99acc 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/Repository.java
@@ -1,1966 +1,2000 @@
-/*
- * Copyright (c) 2004 - 2012 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
- * Simon McDuff - bug 201266
- * Simon McDuff - bug 233273
- * Simon McDuff - bug 233490
- * Stefan Winkler - changed order of determining audit and revision delta support.
- * Andre Dietisheim - bug 256649
- */
-package org.eclipse.emf.cdo.internal.server;
-
-import org.eclipse.emf.cdo.common.CDOCommonView;
-import org.eclipse.emf.cdo.common.branch.CDOBranch;
-import org.eclipse.emf.cdo.common.branch.CDOBranchHandler;
-import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
-import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
-import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
-import org.eclipse.emf.cdo.common.commit.CDOCommitData;
-import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
-import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.id.CDOIDGenerator;
-import org.eclipse.emf.cdo.common.id.CDOIDTemp;
-import org.eclipse.emf.cdo.common.id.CDOIDUtil;
-import org.eclipse.emf.cdo.common.lob.CDOLobHandler;
-import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
-import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo.Operation;
-import org.eclipse.emf.cdo.common.lock.CDOLockState;
-import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
-import org.eclipse.emf.cdo.common.model.CDOModelUtil;
-import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
-import org.eclipse.emf.cdo.common.model.EMFUtil;
-import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
-import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.CDORevisionFactory;
-import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
-import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
-import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
-import org.eclipse.emf.cdo.common.util.CDOCommonUtil;
-import org.eclipse.emf.cdo.common.util.CDOQueryInfo;
-import org.eclipse.emf.cdo.common.util.RepositoryStateChangedEvent;
-import org.eclipse.emf.cdo.common.util.RepositoryTypeChangedEvent;
-import org.eclipse.emf.cdo.eresource.EresourcePackage;
-import org.eclipse.emf.cdo.etypes.EtypesPackage;
-import org.eclipse.emf.cdo.internal.common.model.CDOPackageRegistryImpl;
-import org.eclipse.emf.cdo.internal.server.bundle.OM;
-import org.eclipse.emf.cdo.server.IQueryHandler;
-import org.eclipse.emf.cdo.server.IQueryHandlerProvider;
-import org.eclipse.emf.cdo.server.IStore;
-import org.eclipse.emf.cdo.server.IStore.CanHandleClientAssignedIDs;
-import org.eclipse.emf.cdo.server.IStoreAccessor;
-import org.eclipse.emf.cdo.server.IStoreChunkReader;
-import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk;
-import org.eclipse.emf.cdo.server.ITransaction;
-import org.eclipse.emf.cdo.server.IView;
-import org.eclipse.emf.cdo.server.StoreThreadLocal;
-import org.eclipse.emf.cdo.spi.common.CDOReplicationContext;
-import org.eclipse.emf.cdo.spi.common.CDOReplicationInfo;
-import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
-import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
-import org.eclipse.emf.cdo.spi.common.commit.CDOChangeSetSegment;
-import org.eclipse.emf.cdo.spi.common.commit.CDOCommitInfoUtil;
-import org.eclipse.emf.cdo.spi.common.commit.CDORevisionAvailabilityInfo;
-import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
-import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDOList;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
-import org.eclipse.emf.cdo.spi.common.revision.PointerCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.RevisionInfo;
-import org.eclipse.emf.cdo.spi.server.ContainerQueryHandlerProvider;
-import org.eclipse.emf.cdo.spi.server.InternalCommitContext;
-import org.eclipse.emf.cdo.spi.server.InternalCommitManager;
-import org.eclipse.emf.cdo.spi.server.InternalLockManager;
-import org.eclipse.emf.cdo.spi.server.InternalQueryManager;
-import org.eclipse.emf.cdo.spi.server.InternalRepository;
-import org.eclipse.emf.cdo.spi.server.InternalSession;
-import org.eclipse.emf.cdo.spi.server.InternalSessionManager;
-import org.eclipse.emf.cdo.spi.server.InternalStore;
-import org.eclipse.emf.cdo.spi.server.InternalTransaction;
-import org.eclipse.emf.cdo.spi.server.InternalView;
-
-import org.eclipse.emf.internal.cdo.object.CDOFactoryImpl;
-
-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.MoveableList;
-import org.eclipse.net4j.util.collection.Pair;
-import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
-import org.eclipse.net4j.util.concurrent.RWOLockManager.LockState;
-import org.eclipse.net4j.util.concurrent.TimeoutRuntimeException;
-import org.eclipse.net4j.util.container.Container;
-import org.eclipse.net4j.util.container.IPluginContainer;
-import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
-import org.eclipse.net4j.util.om.monitor.Monitor;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-import org.eclipse.net4j.util.transaction.TransactionException;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EPackage;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.EcorePackage;
-import org.eclipse.emf.spi.cdo.CDOSessionProtocol.LockObjectsResult;
-import org.eclipse.emf.spi.cdo.CDOSessionProtocol.UnlockObjectsResult;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.Semaphore;
-
-/**
- * @author Eike Stepper
- * @since 2.0
- */
-public class Repository extends Container<Object> implements InternalRepository
-{
- private String name;
-
- private String uuid;
-
- private InternalStore store;
-
- private Type type = Type.MASTER;
-
- private State state = State.ONLINE;
-
- private Map<String, String> properties;
-
- private boolean supportingAudits;
-
- private boolean supportingBranches;
-
- private boolean supportingEcore;
-
- private boolean ensuringReferentialIntegrity;
-
- private IDGenerationLocation idGenerationLocation;
-
- /**
- * Must not be thread-bound to support XA commits.
- */
- private Semaphore packageRegistryCommitLock = new Semaphore(1);
-
- private InternalCDOPackageRegistry packageRegistry;
-
- private InternalCDOBranchManager branchManager;
-
- private InternalCDORevisionManager revisionManager;
-
- private InternalCDOCommitInfoManager commitInfoManager;
-
- private InternalSessionManager sessionManager;
-
- private InternalQueryManager queryManager;
-
- private InternalCommitManager commitManager;
-
- private InternalLockManager lockingManager;
-
- private IQueryHandlerProvider queryHandlerProvider;
-
- private List<ReadAccessHandler> readAccessHandlers = new ArrayList<ReadAccessHandler>();
-
- private List<WriteAccessHandler> writeAccessHandlers = new ArrayList<WriteAccessHandler>();
-
- private List<CDOCommitInfoHandler> commitInfoHandlers = new ArrayList<CDOCommitInfoHandler>();
-
- private EPackage[] initialPackages;
-
- // Bugzilla 297940
- private TimeStampAuthority timeStampAuthority = new TimeStampAuthority(this);
-
- @ExcludeFromDump
- private transient Object createBranchLock = new Object();
-
- private boolean skipInitialization;
-
- private CDOID rootResourceID;
-
- public Repository()
- {
- }
-
- public String getName()
- {
- return name;
- }
-
- public void setName(String name)
- {
- this.name = name;
- }
-
- public String getUUID()
- {
- if (uuid == null)
- {
- uuid = getProperties().get(Props.OVERRIDE_UUID);
- if (uuid == null)
- {
- uuid = UUID.randomUUID().toString();
- }
- else if (uuid.length() == 0)
- {
- uuid = getName();
- }
- }
-
- return uuid;
- }
-
- public InternalStore getStore()
- {
- return store;
- }
-
- public void setStore(InternalStore store)
- {
- this.store = store;
- }
-
- public Type getType()
- {
- return type;
- }
-
- public void setType(Type type)
- {
- checkArg(type, "type"); //$NON-NLS-1$
- if (this.type != type)
- {
- changingType(this.type, type);
- }
- }
-
- protected void changingType(Type oldType, Type newType)
- {
- type = newType;
- fireEvent(new RepositoryTypeChangedEvent(this, oldType, newType));
-
- if (sessionManager != null)
- {
- sessionManager.sendRepositoryTypeNotification(oldType, newType);
- }
- }
-
- public State getState()
- {
- return state;
- }
-
- public void setState(State state)
- {
- checkArg(state, "state"); //$NON-NLS-1$
- if (this.state != state)
- {
- changingState(this.state, state);
- }
- }
-
- protected void changingState(State oldState, State newState)
- {
- state = newState;
- fireEvent(new RepositoryStateChangedEvent(this, oldState, newState));
-
- if (sessionManager != null)
- {
- sessionManager.sendRepositoryStateNotification(oldState, newState, getRootResourceID());
- }
- }
-
- public synchronized Map<String, String> getProperties()
- {
- if (properties == null)
- {
- properties = new HashMap<String, String>();
- }
-
- return properties;
- }
-
- public synchronized void setProperties(Map<String, String> properties)
- {
- this.properties = properties;
- }
-
- public boolean isSupportingAudits()
- {
- return supportingAudits;
- }
-
- public boolean isSupportingBranches()
- {
- return supportingBranches;
- }
-
- public boolean isSupportingEcore()
- {
- return supportingEcore;
- }
-
- public boolean isEnsuringReferentialIntegrity()
- {
- return ensuringReferentialIntegrity;
- }
-
- public IDGenerationLocation getIDGenerationLocation()
- {
- return idGenerationLocation;
- }
-
- public String getStoreType()
- {
- return store.getType();
- }
-
- public Set<CDOID.ObjectType> getObjectIDTypes()
- {
- return store.getObjectIDTypes();
- }
-
- public CDOID getRootResourceID()
- {
- return rootResourceID;
- }
-
- public void setRootResourceID(CDOID rootResourceID)
- {
- this.rootResourceID = rootResourceID;
- }
-
- public Object processPackage(Object value)
- {
- CDOFactoryImpl.prepareDynamicEPackage(value);
- return value;
- }
-
- public EPackage[] loadPackages(CDOPackageUnit packageUnit)
- {
- IStoreAccessor accessor = StoreThreadLocal.getAccessor();
- return accessor.loadPackageUnit((InternalCDOPackageUnit)packageUnit);
- }
-
- public Pair<Integer, Long> createBranch(int branchID, BranchInfo branchInfo)
- {
- if (!isSupportingBranches())
- {
- throw new IllegalStateException("Branching is not supported by " + this);
- }
-
- long baseTimeStamp = branchInfo.getBaseTimeStamp();
- if (baseTimeStamp == CDOBranchPoint.UNSPECIFIED_DATE)
- {
- baseTimeStamp = getTimeStamp();
- branchInfo = new BranchInfo(branchInfo.getName(), branchInfo.getBaseBranchID(), baseTimeStamp);
- }
-
- synchronized (createBranchLock)
- {
- IStoreAccessor accessor = StoreThreadLocal.getAccessor();
- return accessor.createBranch(branchID, branchInfo);
- }
- }
-
- public BranchInfo loadBranch(int branchID)
- {
- IStoreAccessor accessor = StoreThreadLocal.getAccessor();
- return accessor.loadBranch(branchID);
- }
-
- public SubBranchInfo[] loadSubBranches(int branchID)
- {
- IStoreAccessor accessor = StoreThreadLocal.getAccessor();
- return accessor.loadSubBranches(branchID);
- }
-
- public int loadBranches(int startID, int endID, CDOBranchHandler branchHandler)
- {
- IStoreAccessor accessor = StoreThreadLocal.getAccessor();
- return accessor.loadBranches(startID, endID, branchHandler);
- }
-
- public void loadCommitInfos(CDOBranch branch, long startTime, long endTime, CDOCommitInfoHandler handler)
- {
- IStoreAccessor accessor = StoreThreadLocal.getAccessor();
- accessor.loadCommitInfos(branch, startTime, endTime, handler);
- }
-
- public CDOCommitData loadCommitData(long timeStamp)
- {
- IStoreAccessor accessor = StoreThreadLocal.getAccessor();
- return accessor.loadCommitData(timeStamp);
- }
-
- public List<InternalCDORevision> loadRevisions(List<RevisionInfo> infos, CDOBranchPoint branchPoint,
- int referenceChunk, int prefetchDepth)
- {
- for (RevisionInfo info : infos)
- {
- CDOID id = info.getID();
- RevisionInfo.Type type = info.getType();
- switch (type)
- {
- case AVAILABLE_NORMAL: // direct == false
- {
- RevisionInfo.Available.Normal availableInfo = (RevisionInfo.Available.Normal)info;
- checkArg(availableInfo.isDirect() == false, "Load is not needed");
- break;
- }
-
- case AVAILABLE_POINTER: // direct == false || target == null
- {
- RevisionInfo.Available.Pointer pointerInfo = (RevisionInfo.Available.Pointer)info;
- boolean needsTarget = !pointerInfo.hasTarget();
- checkArg(pointerInfo.isDirect() == false || needsTarget, "Load is not needed");
-
- if (needsTarget)
- {
- CDOBranchVersion targetBranchVersion = pointerInfo.getTargetBranchVersion();
- InternalCDORevision target = loadRevisionByVersion(id, targetBranchVersion, referenceChunk);
- PointerCDORevision pointer = new PointerCDORevision(target.getEClass(), id, pointerInfo
- .getAvailableBranchVersion().getBranch(), CDORevision.UNSPECIFIED_DATE, target);
-
- info.setResult(target);
- info.setSynthetic(pointer);
- continue;
- }
-
- break;
- }
-
- case AVAILABLE_DETACHED: // direct == false
- {
- RevisionInfo.Available.Detached detachedInfo = (RevisionInfo.Available.Detached)info;
- checkArg(detachedInfo.isDirect() == false, "Load is not needed");
- break;
- }
-
- case MISSING:
- {
- break;
- }
-
- default:
- throw new IllegalStateException("Invalid revision info type: " + type);
- }
-
- IStoreAccessor accessor = StoreThreadLocal.getAccessor();
- InternalCDORevision revision = accessor.readRevision(id, branchPoint, referenceChunk, revisionManager);
- if (revision == null)
- {
- if (isSupportingAudits())
- {
- // Case "Pointer"?
- InternalCDORevision target = loadRevisionTarget(id, branchPoint, referenceChunk, accessor);
- if (target != null)
- {
- CDOBranch branch = branchPoint.getBranch();
- long revised = loadRevisionRevised(id, branch);
- PointerCDORevision pointer = new PointerCDORevision(target.getEClass(), id, branch, revised, target);
- info.setSynthetic(pointer);
- }
-
- info.setResult(target);
- }
- else
- {
- DetachedCDORevision detachedRevision = new DetachedCDORevision(EcorePackage.Literals.ECLASS, id,
- branchPoint.getBranch(), 0, CDORevision.UNSPECIFIED_DATE);
- info.setSynthetic(detachedRevision);
- }
- }
- else if (revision instanceof DetachedCDORevision)
- {
- DetachedCDORevision detached = (DetachedCDORevision)revision;
- info.setSynthetic(detached);
- }
- else
- {
- revision.freeze();
- info.setResult(revision);
- }
- }
-
- return null;
- }
-
- private InternalCDORevision loadRevisionTarget(CDOID id, CDOBranchPoint branchPoint, int referenceChunk,
- IStoreAccessor accessor)
- {
- CDOBranch branch = branchPoint.getBranch();
- while (!branch.isMainBranch())
- {
- branchPoint = branch.getBase();
- branch = branchPoint.getBranch();
-
- InternalCDORevision revision = accessor.readRevision(id, branchPoint, referenceChunk, revisionManager);
- if (revision != null)
- {
- revision.freeze();
- return revision;
- }
- }
-
- return null;
- }
-
- private long loadRevisionRevised(CDOID id, CDOBranch branch)
- {
- InternalCDORevision revision = loadRevisionByVersion(id, branch.getVersion(CDORevision.FIRST_VERSION),
- CDORevision.UNCHUNKED);
- if (revision != null)
- {
- return revision.getTimeStamp() - 1;
- }
-
- return CDORevision.UNSPECIFIED_DATE;
- }
-
- public InternalCDORevision loadRevisionByVersion(CDOID id, CDOBranchVersion branchVersion, int referenceChunk)
- {
- IStoreAccessor accessor = StoreThreadLocal.getAccessor();
- return accessor.readRevisionByVersion(id, branchVersion, referenceChunk, revisionManager);
- }
-
- protected void ensureChunks(InternalCDORevision revision, int referenceChunk, IStoreAccessor accessor)
- {
- EClass eClass = revision.getEClass();
- EStructuralFeature[] features = CDOModelUtil.getAllPersistentFeatures(eClass);
- for (int i = 0; i < features.length; i++)
- {
- EStructuralFeature feature = features[i];
- if (feature.isMany())
- {
- MoveableList<Object> list = revision.getList(feature);
- int chunkEnd = Math.min(referenceChunk, list.size());
- accessor = ensureChunk(revision, feature, accessor, list, 0, chunkEnd);
- }
- }
- }
-
- public IStoreAccessor ensureChunk(InternalCDORevision revision, EStructuralFeature feature, int chunkStart,
- int chunkEnd)
- {
- MoveableList<Object> list = revision.getList(feature);
- chunkEnd = Math.min(chunkEnd, list.size());
- return ensureChunk(revision, feature, StoreThreadLocal.getAccessor(), list, chunkStart, chunkEnd);
- }
-
- protected IStoreAccessor ensureChunk(InternalCDORevision revision, EStructuralFeature feature,
- IStoreAccessor accessor, MoveableList<Object> list, int chunkStart, int chunkEnd)
- {
- IStoreChunkReader chunkReader = null;
- int fromIndex = -1;
- for (int j = chunkStart; j < chunkEnd; j++)
- {
- if (list.get(j) == InternalCDOList.UNINITIALIZED)
- {
- if (fromIndex == -1)
- {
- fromIndex = j;
- }
- }
- else
- {
- if (fromIndex != -1)
- {
- if (chunkReader == null)
- {
- if (accessor == null)
- {
- accessor = StoreThreadLocal.getAccessor();
- }
-
- chunkReader = accessor.createChunkReader(revision, feature);
- }
-
- int toIndex = j;
- if (fromIndex == toIndex - 1)
- {
- chunkReader.addSimpleChunk(fromIndex);
- }
- else
- {
- chunkReader.addRangedChunk(fromIndex, toIndex);
- }
-
- fromIndex = -1;
- }
- }
- }
-
- // Add last chunk
- if (fromIndex != -1)
- {
- if (chunkReader == null)
- {
- if (accessor == null)
- {
- accessor = StoreThreadLocal.getAccessor();
- }
-
- chunkReader = accessor.createChunkReader(revision, feature);
- }
-
- int toIndex = chunkEnd;
- if (fromIndex == toIndex - 1)
- {
- chunkReader.addSimpleChunk(fromIndex);
- }
- else
- {
- chunkReader.addRangedChunk(fromIndex, toIndex);
- }
- }
-
- if (chunkReader != null)
- {
- InternalCDOList cdoList = list instanceof InternalCDOList ? (InternalCDOList)list : null;
-
- List<Chunk> chunks = chunkReader.executeRead();
- for (Chunk chunk : chunks)
- {
- int startIndex = chunk.getStartIndex();
- for (int indexInChunk = 0; indexInChunk < chunk.size(); indexInChunk++)
- {
- Object id = chunk.get(indexInChunk);
- if (cdoList != null)
- {
- cdoList.setWithoutFrozenCheck(startIndex + indexInChunk, id);
- }
- else
- {
- list.set(startIndex + indexInChunk, id);
- }
- }
- }
- }
-
- return accessor;
- }
-
- public InternalCDOPackageRegistry getPackageRegistry(boolean considerCommitContext)
- {
- if (considerCommitContext)
- {
- IStoreAccessor.CommitContext commitContext = StoreThreadLocal.getCommitContext();
- if (commitContext != null)
- {
- InternalCDOPackageRegistry contextualPackageRegistry = commitContext.getPackageRegistry();
- if (contextualPackageRegistry != null)
- {
- return contextualPackageRegistry;
- }
- }
- }
-
- return packageRegistry;
- }
-
- public Semaphore getPackageRegistryCommitLock()
- {
- return packageRegistryCommitLock;
- }
-
- public InternalCDOPackageRegistry getPackageRegistry()
- {
- return getPackageRegistry(true);
- }
-
- public void setPackageRegistry(InternalCDOPackageRegistry packageRegistry)
- {
- checkInactive();
- this.packageRegistry = packageRegistry;
- }
-
- public InternalSessionManager getSessionManager()
- {
- return sessionManager;
- }
-
- /**
- * @since 2.0
- */
- public void setSessionManager(InternalSessionManager sessionManager)
- {
- checkInactive();
- this.sessionManager = sessionManager;
- }
-
- public InternalCDOBranchManager getBranchManager()
- {
- return branchManager;
- }
-
- public void setBranchManager(InternalCDOBranchManager branchManager)
- {
- checkInactive();
- this.branchManager = branchManager;
- }
-
- public InternalCDOCommitInfoManager getCommitInfoManager()
- {
- return commitInfoManager;
- }
-
- public void setCommitInfoManager(InternalCDOCommitInfoManager commitInfoManager)
- {
- checkInactive();
- this.commitInfoManager = commitInfoManager;
- }
-
- public InternalCDORevisionManager getRevisionManager()
- {
- return revisionManager;
- }
-
- /**
- * @since 2.0
- */
- public void setRevisionManager(InternalCDORevisionManager revisionManager)
- {
- checkInactive();
- this.revisionManager = revisionManager;
- }
-
- /**
- * @since 2.0
- */
- public InternalQueryManager getQueryManager()
- {
- return queryManager;
- }
-
- /**
- * @since 2.0
- */
- public void setQueryManager(InternalQueryManager queryManager)
- {
- checkInactive();
- this.queryManager = queryManager;
- }
-
- /**
- * @since 2.0
- */
- public InternalCommitManager getCommitManager()
- {
- return commitManager;
- }
-
- /**
- * @since 2.0
- */
- public void setCommitManager(InternalCommitManager commitManager)
- {
- checkInactive();
- this.commitManager = commitManager;
- }
-
- /**
- * @since 2.0
- * @deprecated
- */
- @Deprecated
- public InternalLockManager getLockManager()
- {
- return getLockingManager();
- }
-
- public InternalLockManager getLockingManager()
- {
- return lockingManager;
- }
-
- /**
- * @since 2.0
- */
- public void setLockingManager(InternalLockManager lockingManager)
- {
- checkInactive();
- this.lockingManager = lockingManager;
- }
-
- public InternalCommitContext createCommitContext(InternalTransaction transaction)
- {
- return new TransactionCommitContext(transaction);
- }
-
- public long getLastCommitTimeStamp()
- {
- return timeStampAuthority.getLastFinishedTimeStamp();
- }
-
- public void setLastCommitTimeStamp(long lastCommitTimeStamp)
- {
- timeStampAuthority.setLastFinishedTimeStamp(lastCommitTimeStamp);
- }
-
- public long waitForCommit(long timeout)
- {
- return timeStampAuthority.waitForCommit(timeout);
- }
-
- public long[] createCommitTimeStamp(OMMonitor monitor)
- {
- return timeStampAuthority.startCommit(CDOBranchPoint.UNSPECIFIED_DATE, monitor);
- }
-
- public long[] forceCommitTimeStamp(long override, OMMonitor monitor)
- {
- return timeStampAuthority.startCommit(override, monitor);
- }
-
- public void endCommit(long timestamp)
- {
- timeStampAuthority.endCommit(timestamp);
- }
-
- public void failCommit(long timestamp)
- {
- timeStampAuthority.failCommit(timestamp);
- }
-
- public CDOCommitInfoHandler[] getCommitInfoHandlers()
- {
- synchronized (commitInfoHandlers)
- {
- return commitInfoHandlers.toArray(new CDOCommitInfoHandler[commitInfoHandlers.size()]);
- }
- }
-
- /**
- * @since 4.0
- */
- public void addCommitInfoHandler(CDOCommitInfoHandler handler)
- {
- synchronized (commitInfoHandlers)
- {
- if (!commitInfoHandlers.contains(handler))
- {
- commitInfoHandlers.add(handler);
- }
- }
- }
-
- /**
- * @since 4.0
- */
- public void removeCommitInfoHandler(CDOCommitInfoHandler handler)
- {
- synchronized (commitInfoHandlers)
- {
- commitInfoHandlers.remove(handler);
- }
- }
-
- public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo)
- {
- sessionManager.sendCommitNotification(sender, commitInfo);
-
- for (CDOCommitInfoHandler handler : getCommitInfoHandlers())
- {
- try
- {
- handler.handleCommitInfo(commitInfo);
- }
- catch (Exception ex)
- {
- OM.LOG.error(ex);
- }
- }
- }
-
- /**
- * @since 2.0
- */
- public IQueryHandlerProvider getQueryHandlerProvider()
- {
- return queryHandlerProvider;
- }
-
- /**
- * @since 2.0
- */
- public void setQueryHandlerProvider(IQueryHandlerProvider queryHandlerProvider)
- {
- this.queryHandlerProvider = queryHandlerProvider;
- }
-
- /**
- * @since 2.0
- */
- public synchronized IQueryHandler getQueryHandler(CDOQueryInfo info)
- {
- String language = info.getQueryLanguage();
- if (CDOProtocolConstants.QUERY_LANGUAGE_RESOURCES.equals(language))
- {
- return new ResourcesQueryHandler();
- }
-
- if (CDOProtocolConstants.QUERY_LANGUAGE_XREFS.equals(language))
- {
- return new XRefsQueryHandler();
- }
-
- IStoreAccessor storeAccessor = StoreThreadLocal.getAccessor();
- if (storeAccessor != null)
- {
- IQueryHandler handler = storeAccessor.getQueryHandler(info);
- if (handler != null)
- {
- return handler;
- }
- }
-
- if (queryHandlerProvider == null)
- {
- queryHandlerProvider = new ContainerQueryHandlerProvider(IPluginContainer.INSTANCE);
- }
-
- IQueryHandler handler = queryHandlerProvider.getQueryHandler(info);
- if (handler != null)
- {
- return handler;
- }
-
- return null;
- }
-
- public Object[] getElements()
- {
- final Object[] elements = { packageRegistry, branchManager, revisionManager, sessionManager, queryManager,
- commitManager, commitInfoManager, getLockingManager(), store };
- return elements;
- }
-
- @Override
- public boolean isEmpty()
- {
- return false;
- }
-
- /**
- * @since 2.0
- */
- public long getCreationTime()
- {
- return store.getCreationTime();
- }
-
- /**
- * @since 2.0
- */
- public void validateTimeStamp(long timeStamp) throws IllegalArgumentException
- {
- long creationTimeStamp = getCreationTime();
- if (timeStamp < creationTimeStamp)
- {
- throw new IllegalArgumentException(
- MessageFormat
- .format(
- "timeStamp ({0}) < repository creation time ({1})", CDOCommonUtil.formatTimeStamp(timeStamp), CDOCommonUtil.formatTimeStamp(creationTimeStamp))); //$NON-NLS-1$
- }
-
- long currentTimeStamp = getTimeStamp();
- if (timeStamp > currentTimeStamp)
- {
- throw new IllegalArgumentException(
- MessageFormat
- .format(
- "timeStamp ({0}) > current time ({1})", CDOCommonUtil.formatTimeStamp(timeStamp), CDOCommonUtil.formatTimeStamp(currentTimeStamp))); //$NON-NLS-1$
- }
- }
-
- public long getTimeStamp()
- {
- return System.currentTimeMillis();
- }
-
- public Set<Handler> getHandlers()
- {
- Set<Handler> handlers = new HashSet<Handler>();
-
- synchronized (readAccessHandlers)
- {
- handlers.addAll(readAccessHandlers);
- }
-
- synchronized (writeAccessHandlers)
- {
- handlers.addAll(writeAccessHandlers);
- }
-
- return handlers;
- }
-
- /**
- * @since 2.0
- */
- public void addHandler(Handler handler)
- {
- if (handler instanceof ReadAccessHandler)
- {
- synchronized (readAccessHandlers)
- {
- if (!readAccessHandlers.contains(handler))
- {
- readAccessHandlers.add((ReadAccessHandler)handler);
- }
- }
- }
-
- if (handler instanceof WriteAccessHandler)
- {
- synchronized (writeAccessHandlers)
- {
- if (!writeAccessHandlers.contains(handler))
- {
- writeAccessHandlers.add((WriteAccessHandler)handler);
- }
- }
- }
- }
-
- /**
- * @since 2.0
- */
- public void removeHandler(Handler handler)
- {
- if (handler instanceof ReadAccessHandler)
- {
- synchronized (readAccessHandlers)
- {
- readAccessHandlers.remove(handler);
- }
- }
-
- if (handler instanceof WriteAccessHandler)
- {
- synchronized (writeAccessHandlers)
- {
- writeAccessHandlers.remove(handler);
- }
- }
- }
-
- /**
- * @since 2.0
- */
- public void notifyReadAccessHandlers(InternalSession session, CDORevision[] revisions,
- List<CDORevision> additionalRevisions)
- {
- ReadAccessHandler[] handlers;
- synchronized (readAccessHandlers)
- {
- int size = readAccessHandlers.size();
- if (size == 0)
- {
- return;
- }
-
- handlers = readAccessHandlers.toArray(new ReadAccessHandler[size]);
- }
-
- for (ReadAccessHandler handler : handlers)
- {
- // Do *not* protect against unchecked exceptions from handlers!
- handler.handleRevisionsBeforeSending(session, revisions, additionalRevisions);
- }
- }
-
- public void notifyWriteAccessHandlers(ITransaction transaction, IStoreAccessor.CommitContext commitContext,
- boolean beforeCommit, OMMonitor monitor)
- {
- WriteAccessHandler[] handlers;
- synchronized (writeAccessHandlers)
- {
- int size = writeAccessHandlers.size();
- if (size == 0)
- {
- return;
- }
-
- handlers = writeAccessHandlers.toArray(new WriteAccessHandler[size]);
- }
-
- try
- {
- monitor.begin(handlers.length);
- for (WriteAccessHandler handler : handlers)
- {
- try
- {
- if (beforeCommit)
- {
- handler.handleTransactionBeforeCommitting(transaction, commitContext, monitor.fork());
- }
- else
- {
- handler.handleTransactionAfterCommitted(transaction, commitContext, monitor.fork());
- }
- }
- catch (RuntimeException ex)
- {
- if (!beforeCommit)
- {
- OM.LOG.error(ex);
- }
- else
- {
- // Do *not* protect against unchecked exceptions from handlers on before case!
- throw ex;
- }
- }
- }
- }
- finally
- {
- monitor.done();
- }
- }
-
- public void setInitialPackages(EPackage... initialPackages)
- {
- checkInactive();
- this.initialPackages = initialPackages;
- }
-
- public CDOReplicationInfo replicateRaw(CDODataOutput out, int lastReplicatedBranchID, long lastReplicatedCommitTime)
- throws IOException
- {
- final int fromBranchID = lastReplicatedBranchID + 1;
- final int toBranchID = getStore().getLastBranchID();
-
- final long fromCommitTime = lastReplicatedCommitTime + 1L;
- final long toCommitTime = getStore().getLastCommitTime();
-
- out.writeInt(toBranchID);
- out.writeLong(toCommitTime);
-
- IStoreAccessor.Raw accessor = (IStoreAccessor.Raw)StoreThreadLocal.getAccessor();
- accessor.rawExport(out, fromBranchID, toBranchID, fromCommitTime, toCommitTime);
-
- return new CDOReplicationInfo()
- {
- public int getLastReplicatedBranchID()
- {
- return toBranchID;
- }
-
- public long getLastReplicatedCommitTime()
- {
- return toCommitTime;
- }
-
- public String[] getLockAreaIDs()
- {
- return null; // TODO (CD) Raw replication of lockAreas
- }
- };
- }
-
- public void replicate(CDOReplicationContext context)
- {
- int startID = context.getLastReplicatedBranchID() + 1;
- branchManager.getBranches(startID, 0, context);
-
- long startTime = context.getLastReplicatedCommitTime();
- commitInfoManager.getCommitInfos(null, startTime + 1L, CDOBranchPoint.UNSPECIFIED_DATE, context);
-
- getLockingManager().getLockAreas(null, context);
- }
-
- public CDOChangeSetData getChangeSet(CDOBranchPoint startPoint, CDOBranchPoint endPoint)
- {
- CDOChangeSetSegment[] segments = CDOChangeSetSegment.createFrom(startPoint, endPoint);
-
- IStoreAccessor accessor = StoreThreadLocal.getAccessor();
- Set<CDOID> ids = accessor.readChangeSet(new Monitor(), segments);
-
- return CDORevisionUtil.createChangeSetData(ids, startPoint, endPoint, revisionManager);
- }
-
- public Set<CDOID> getMergeData(CDORevisionAvailabilityInfo targetInfo, CDORevisionAvailabilityInfo sourceInfo,
- CDORevisionAvailabilityInfo targetBaseInfo, CDORevisionAvailabilityInfo sourceBaseInfo, OMMonitor monitor)
- {
- CDOBranchPoint target = targetInfo.getBranchPoint();
- CDOBranchPoint source = sourceInfo.getBranchPoint();
-
- monitor.begin(5);
-
- try
- {
- IStoreAccessor accessor = StoreThreadLocal.getAccessor();
- Set<CDOID> ids = new HashSet<CDOID>();
-
- if (targetBaseInfo == null && sourceBaseInfo == null)
- {
- if (CDOBranchUtil.isContainedBy(source, target))
- {
- ids.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(source, target)));
- }
- else if (CDOBranchUtil.isContainedBy(target, source))
- {
- ids.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(target, source)));
- }
- else
- {
- CDOBranchPoint ancestor = CDOBranchUtil.getAncestor(target, source);
- ids.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(ancestor, target)));
- ids.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(ancestor, source)));
- }
- }
- else
- {
- CDORevisionAvailabilityInfo sourceBaseInfoToUse = sourceBaseInfo == null ? targetBaseInfo : sourceBaseInfo;
-
- ids.addAll(accessor.readChangeSet(monitor.fork(),
- CDOChangeSetSegment.createFrom(targetBaseInfo.getBranchPoint(), target)));
-
- ids.addAll(accessor.readChangeSet(monitor.fork(),
- CDOChangeSetSegment.createFrom(sourceBaseInfoToUse.getBranchPoint(), source)));
- }
-
- loadMergeData(ids, targetInfo, monitor.fork());
- loadMergeData(ids, sourceInfo, monitor.fork());
-
- if (targetBaseInfo != null)
- {
- loadMergeData(ids, targetBaseInfo, monitor.fork());
- }
-
- if (sourceBaseInfo != null)
- {
- loadMergeData(ids, sourceBaseInfo, monitor.fork());
- }
-
- return ids;
- }
- finally
- {
- monitor.done();
- }
- }
-
- private void loadMergeData(Set<CDOID> ids, CDORevisionAvailabilityInfo info, OMMonitor monitor)
- {
- int size = ids.size();
- monitor.begin(size);
-
- try
- {
- CDOBranchPoint branchPoint = info.getBranchPoint();
- for (CDOID id : ids)
- {
- if (info.containsRevision(id))
- {
- info.removeRevision(id);
- }
- else
- {
- InternalCDORevision revision = getRevisionFromBranch(id, branchPoint);
- if (revision != null)
- {
- info.addRevision(revision);
- }
- else
- {
- info.removeRevision(id);
- }
- }
-
- monitor.worked();
- }
- }
- finally
- {
- monitor.done();
- }
- }
-
- private InternalCDORevision getRevisionFromBranch(CDOID id, CDOBranchPoint branchPoint)
- {
- InternalCDORevision revision = revisionManager.getRevision(id, branchPoint, CDORevision.UNCHUNKED,
- CDORevision.DEPTH_NONE, true);
- // if (revision == null || !ObjectUtil.equals(revision.getBranch(), branchPoint.getBranch()))
- // {
- // return null;
- // }
-
- return revision;
- }
-
- public void queryLobs(List<byte[]> ids)
- {
- IStoreAccessor accessor = StoreThreadLocal.getAccessor();
- accessor.queryLobs(ids);
- }
-
- public void handleLobs(long fromTime, long toTime, CDOLobHandler handler) throws IOException
- {
- IStoreAccessor accessor = StoreThreadLocal.getAccessor();
- accessor.handleLobs(fromTime, toTime, handler);
- }
-
- public void loadLob(byte[] id, OutputStream out) throws IOException
- {
- IStoreAccessor accessor = StoreThreadLocal.getAccessor();
- accessor.loadLob(id, out);
- }
-
- public void handleRevisions(EClass eClass, CDOBranch branch, boolean exactBranch, long timeStamp, boolean exactTime,
- final CDORevisionHandler handler)
- {
- CDORevisionHandler wrapper = handler;
- if (!exactBranch && !branch.isMainBranch())
- {
- if (exactTime && timeStamp == CDOBranchPoint.UNSPECIFIED_DATE)
- {
- throw new IllegalArgumentException("Time stamp must be specified if exactBranch==false and exactTime==true");
- }
-
- wrapper = new CDORevisionHandler()
- {
- private Set<CDOID> handled = new HashSet<CDOID>();
-
- public boolean handleRevision(CDORevision revision)
- {
- CDOID id = revision.getID();
- if (handled.add(id))
- {
- return handler.handleRevision(revision);
- }
-
- return true;
- }
- };
- }
-
- IStoreAccessor accessor = StoreThreadLocal.getAccessor();
- while (branch != null)
- {
- accessor.handleRevisions(eClass, branch, timeStamp, exactTime, wrapper);
- if (exactBranch)
- {
- break;
- }
-
- CDOBranchPoint base = branch.getBase();
- branch = base.getBranch();
- timeStamp = base.getTimeStamp();
- }
- }
-
- public static List<Object> revisionKeysToObjects(List<CDORevisionKey> revisionKeys, CDOBranch viewedBranch,
- boolean isSupportingBranches)
- {
- List<Object> lockables = new ArrayList<Object>();
- for (CDORevisionKey revKey : revisionKeys)
- {
- CDOID id = revKey.getID();
- if (isSupportingBranches)
- {
- lockables.add(CDOIDUtil.createIDAndBranch(id, viewedBranch));
- }
- else
- {
- lockables.add(id);
- }
- }
- return lockables;
- }
-
- public LockObjectsResult lock(InternalView view, LockType lockType, List<CDORevisionKey> revKeys, boolean recursive,
- long timeout)
- {
- List<Object> lockables = revisionKeysToObjects(revKeys, view.getBranch(), isSupportingBranches());
- return lock(view, lockType, lockables, revKeys, recursive, timeout);
- }
-
- protected LockObjectsResult lock(InternalView view, LockType type, List<Object> lockables,
- List<CDORevisionKey> loadedRevs, boolean recursive, long timeout)
- {
- List<LockState<Object, IView>> newLockStates = null;
- try
- {
- newLockStates = getLockingManager().lock2(true, type, view, lockables, recursive, timeout);
- }
- catch (TimeoutRuntimeException ex)
- {
- return new LockObjectsResult(false, true, false, 0, new CDORevisionKey[0], new CDOLockState[0], getTimeStamp());
- }
- catch (InterruptedException ex)
- {
- throw WrappedException.wrap(ex);
- }
-
- long[] requiredTimestamp = { 0L };
- CDORevisionKey[] staleRevisionsArray = null;
-
- try
- {
- staleRevisionsArray = checkStaleRevisions(view, loadedRevs, lockables, type, requiredTimestamp);
- }
- catch (IllegalArgumentException e)
- {
- getLockingManager().unlock2(true, type, view, lockables, recursive);
- throw e;
- }
-
- // If some of the clients' revisions are stale and it has passiveUpdates disabled,
- // then the locks are useless so we release them and report the stale revisions
- //
- InternalSession session = view.getSession();
- boolean staleNoUpdate = staleRevisionsArray.length > 0 && !session.isPassiveUpdateEnabled();
- if (staleNoUpdate)
- {
- getLockingManager().unlock2(true, type, view, lockables, recursive);
- return new LockObjectsResult(false, false, false, requiredTimestamp[0], staleRevisionsArray, new CDOLockState[0],
- getTimeStamp());
- }
-
- CDOLockState[] cdoLockStates = toCDOLockStates(newLockStates);
- sendLockNotifications(view, Operation.LOCK, type, cdoLockStates);
-
- boolean waitForUpdate = staleRevisionsArray.length > 0;
- return new LockObjectsResult(true, false, waitForUpdate, requiredTimestamp[0], staleRevisionsArray, cdoLockStates,
- getTimeStamp());
- }
-
- private CDORevisionKey[] checkStaleRevisions(InternalView view, List<CDORevisionKey> revisionKeys,
- List<Object> objectsToLock, LockType lockType, long[] requiredTimestamp)
- {
- List<CDORevisionKey> staleRevisions = new LinkedList<CDORevisionKey>();
- if (revisionKeys != null)
- {
- InternalCDORevisionManager revManager = getRevisionManager();
- CDOBranch viewedBranch = view.getBranch();
- for (CDORevisionKey revKey : revisionKeys)
- {
- CDOID id = revKey.getID();
- InternalCDORevision rev = revManager.getRevision(id, viewedBranch.getHead(), CDORevision.UNCHUNKED,
- CDORevision.DEPTH_NONE, true);
-
- if (rev == null)
- {
- throw new IllegalArgumentException(String.format("Object %s not found in branch %s (possibly detached)", id,
- viewedBranch));
- }
-
- if (!revKey.equals(rev))
- {
- staleRevisions.add(revKey);
- requiredTimestamp[0] = Math.max(requiredTimestamp[0], rev.getTimeStamp());
- }
- }
- }
-
- // Convert the list to an array, to satisfy the API later
- //
- CDORevisionKey[] staleRevisionsArray = new CDORevisionKey[staleRevisions.size()];
- staleRevisions.toArray(staleRevisionsArray);
-
- return staleRevisionsArray;
- }
-
- private void sendLockNotifications(IView view, Operation operation, LockType lockType, CDOLockState[] cdoLockStates)
- {
- long timestamp = getTimeStamp();
- CDOLockChangeInfo lockChangeInfo = CDOLockUtil.createLockChangeInfo(timestamp, view, view.getBranch(), operation,
- lockType, cdoLockStates);
- getSessionManager().sendLockNotification((InternalSession)view.getSession(), lockChangeInfo);
- }
-
- // TODO (CD) This doesn't really belong here.. but getting it into CDOLockUtil isn't possible
- public static CDOLockState[] toCDOLockStates(List<LockState<Object, IView>> lockStates)
- {
- CDOLockState[] cdoLockStates = new CDOLockState[lockStates.size()];
- int i = 0;
-
- for (LockState<Object, ? extends CDOCommonView> lockState : lockStates)
- {
- CDOLockState cdoLockState = CDOLockUtil.createLockState(lockState);
- cdoLockStates[i++] = cdoLockState;
- }
-
- return cdoLockStates;
- }
-
- public UnlockObjectsResult unlock(InternalView view, LockType lockType, List<CDOID> objectIDs, boolean recursive)
- {
- List<Object> unlockables = null;
- if (objectIDs != null)
- {
- unlockables = new ArrayList<Object>(objectIDs.size());
- CDOBranch branch = view.getBranch();
- for (CDOID id : objectIDs)
- {
- Object key = supportingBranches ? CDOIDUtil.createIDAndBranch(id, branch) : id;
- unlockables.add(key);
- }
- }
-
- return doUnlock(view, lockType, unlockables, recursive);
- }
-
- protected UnlockObjectsResult doUnlock(InternalView view, LockType lockType, List<Object> unlockables,
- boolean recursive)
- {
- List<LockState<Object, IView>> newLockStates = null;
- if (lockType == null) // Signals an unlock-all operation
- {
- newLockStates = getLockingManager().unlock2(true, view);
- }
- else
- {
- newLockStates = getLockingManager().unlock2(true, lockType, view, unlockables, recursive);
- }
-
- long timestamp = getTimeStamp();
- CDOLockState[] cdoLockStates = toCDOLockStates(newLockStates);
- sendLockNotifications(view, Operation.UNLOCK, lockType, cdoLockStates);
-
- return new UnlockObjectsResult(cdoLockStates, timestamp);
- }
-
- @Override
- public String toString()
- {
- return MessageFormat.format("Repository[{0}]", name); //$NON-NLS-1$
- }
-
- public boolean isSkipInitialization()
- {
- return skipInitialization;
- }
-
- public void setSkipInitialization(boolean skipInitialization)
- {
- this.skipInitialization = skipInitialization;
- }
-
- protected void initProperties()
- {
- String valueAudits = properties.get(Props.SUPPORTING_AUDITS);
- if (valueAudits != null)
- {
- supportingAudits = Boolean.valueOf(valueAudits);
- }
- else
- {
- supportingAudits = store.getRevisionTemporality() == IStore.RevisionTemporality.AUDITING;
- }
-
- String valueBranches = properties.get(Props.SUPPORTING_BRANCHES);
- if (valueBranches != null)
- {
- supportingBranches = Boolean.valueOf(valueBranches);
- }
- else
- {
- supportingBranches = store.getRevisionParallelism() == IStore.RevisionParallelism.BRANCHING;
- }
-
- String valueEcore = properties.get(Props.SUPPORTING_ECORE);
- if (valueEcore != null)
- {
- supportingEcore = Boolean.valueOf(valueEcore);
- }
-
- String valueIntegrity = properties.get(Props.ENSURE_REFERENTIAL_INTEGRITY);
- if (valueIntegrity != null)
- {
- ensuringReferentialIntegrity = Boolean.valueOf(valueIntegrity);
- }
-
- String valueIDLocation = properties.get(Props.ID_GENERATION_LOCATION);
- if (valueIDLocation != null)
- {
- idGenerationLocation = IDGenerationLocation.valueOf(valueIDLocation);
- }
-
- if (idGenerationLocation == null)
- {
- idGenerationLocation = IDGenerationLocation.STORE;
- }
- }
-
- public void initSystemPackages()
- {
- IStoreAccessor writer = store.getWriter(null);
- StoreThreadLocal.setAccessor(writer);
-
- try
- {
- List<InternalCDOPackageUnit> units = new ArrayList<InternalCDOPackageUnit>();
- units.add(initSystemPackage(EcorePackage.eINSTANCE));
- units.add(initSystemPackage(EresourcePackage.eINSTANCE));
- units.add(initSystemPackage(EtypesPackage.eINSTANCE));
-
- if (initialPackages != null)
- {
- for (EPackage initialPackage : initialPackages)
- {
- if (!packageRegistry.containsKey(initialPackage.getNsURI()))
- {
- units.add(initSystemPackage(initialPackage));
- }
- }
- }
-
- InternalCDOPackageUnit[] systemUnits = units.toArray(new InternalCDOPackageUnit[units.size()]);
- writer.writePackageUnits(systemUnits, new Monitor());
- writer.commit(new Monitor());
- }
- finally
- {
- StoreThreadLocal.release();
- }
- }
-
- protected InternalCDOPackageUnit initSystemPackage(EPackage ePackage)
- {
- EMFUtil.registerPackage(ePackage, packageRegistry);
- InternalCDOPackageInfo packageInfo = packageRegistry.getPackageInfo(ePackage);
-
- InternalCDOPackageUnit packageUnit = packageInfo.getPackageUnit();
- packageUnit.setTimeStamp(store.getCreationTime());
- packageUnit.setState(CDOPackageUnit.State.LOADED);
- return packageUnit;
- }
-
- public void initMainBranch(InternalCDOBranchManager branchManager, long timeStamp)
- {
- branchManager.initMainBranch(false, timeStamp);
- }
-
- protected void initRootResource()
- {
- CDOBranchPoint head = branchManager.getMainBranch().getHead();
-
- CDORevisionFactory factory = getRevisionManager().getFactory();
- InternalCDORevision rootResource = (InternalCDORevision)factory
- .createRevision(EresourcePackage.Literals.CDO_RESOURCE);
-
- rootResource.setBranchPoint(head);
- rootResource.setContainerID(CDOID.NULL);
- rootResource.setContainingFeatureID(0);
-
- CDOID id = createRootResourceID();
- rootResource.setID(id);
- rootResource.setResourceID(id);
-
- InternalSession session = getSessionManager().openSession(null);
- InternalTransaction transaction = session.openTransaction(1, head);
- InternalCommitContext commitContext = new TransactionCommitContext(transaction)
- {
- @Override
- protected long[] createTimeStamp(OMMonitor monitor)
- {
- InternalRepository repository = getTransaction().getSession().getManager().getRepository();
- return repository.forceCommitTimeStamp(store.getCreationTime(), monitor);
- }
-
- @Override
- public String getUserID()
- {
- return SYSTEM_USER_ID;
- }
-
- @Override
- public String getCommitComment()
- {
- return "<initialize>"; //$NON-NLS-1$
- }
- };
-
- commitContext.setNewObjects(new InternalCDORevision[] { rootResource });
- commitContext.preWrite();
-
- commitContext.write(new Monitor());
- commitContext.commit(new Monitor());
-
- String rollbackMessage = commitContext.getRollbackMessage();
- if (rollbackMessage != null)
- {
- throw new TransactionException(rollbackMessage);
- }
-
- rootResourceID = id instanceof CDOIDTemp ? commitContext.getIDMappings().get(id) : id;
-
- commitContext.postCommit(true);
- session.close();
- }
-
- protected CDOID createRootResourceID()
- {
- if (getIDGenerationLocation() == IDGenerationLocation.STORE)
- {
- return CDOIDUtil.createTempObject(1);
- }
-
- return CDOIDGenerator.UUID.generateCDOID(null);
- }
-
- protected void readRootResource()
- {
- IStoreAccessor reader = store.getReader(null);
- StoreThreadLocal.setAccessor(reader);
-
- try
- {
- CDOBranchPoint head = branchManager.getMainBranch().getHead();
- rootResourceID = reader.readResourceID(CDOID.NULL, null, head);
- }
- finally
- {
- StoreThreadLocal.release();
- }
- }
-
- protected void readPackageUnits()
- {
- IStoreAccessor reader = store.getReader(null);
- StoreThreadLocal.setAccessor(reader);
-
- try
- {
- Collection<InternalCDOPackageUnit> packageUnits = reader.readPackageUnits();
- for (InternalCDOPackageUnit packageUnit : packageUnits)
- {
- packageRegistry.putPackageUnit(packageUnit);
- }
- }
- finally
- {
- StoreThreadLocal.release();
- }
- }
-
- @Override
- protected void doBeforeActivate() throws Exception
- {
- super.doBeforeActivate();
- checkState(store, "store"); //$NON-NLS-1$
- checkState(!StringUtil.isEmpty(name), "name is empty"); //$NON-NLS-1$
- checkState(packageRegistry, "packageRegistry"); //$NON-NLS-1$
- checkState(sessionManager, "sessionManager"); //$NON-NLS-1$
- checkState(branchManager, "branchManager"); //$NON-NLS-1$
- checkState(revisionManager, "revisionManager"); //$NON-NLS-1$
- checkState(queryManager, "queryManager"); //$NON-NLS-1$
- checkState(commitInfoManager, "commitInfoManager"); //$NON-NLS-1$
- checkState(commitManager, "commitManager"); //$NON-NLS-1$
- checkState(getLockingManager(), "lockingManager"); //$NON-NLS-1$
-
- packageRegistry.setReplacingDescriptors(true);
- packageRegistry.setPackageProcessor(this);
- packageRegistry.setPackageLoader(this);
-
- branchManager.setBranchLoader(this);
- branchManager.setTimeProvider(this);
-
- revisionManager.setRevisionLoader(this);
- sessionManager.setRepository(this);
- queryManager.setRepository(this);
- commitInfoManager.setCommitInfoLoader(this);
- commitManager.setRepository(this);
- getLockingManager().setRepository(this);
- store.setRepository(this);
- }
-
- @Override
- protected void doActivate() throws Exception
- {
- super.doActivate();
-
- initProperties();
- if (idGenerationLocation == IDGenerationLocation.CLIENT && !(store instanceof CanHandleClientAssignedIDs))
- {
- throw new IllegalStateException("Store can not handle client assigned IDs: " + store);
- }
-
- store.setRevisionTemporality(supportingAudits ? IStore.RevisionTemporality.AUDITING
- : IStore.RevisionTemporality.NONE);
- store.setRevisionParallelism(supportingBranches ? IStore.RevisionParallelism.BRANCHING
- : IStore.RevisionParallelism.NONE);
- revisionManager.setSupportingAudits(supportingAudits);
- revisionManager.setSupportingBranches(supportingBranches);
-
- LifecycleUtil.activate(store);
- LifecycleUtil.activate(packageRegistry);
- LifecycleUtil.activate(sessionManager);
- LifecycleUtil.activate(revisionManager);
- LifecycleUtil.activate(branchManager);
- LifecycleUtil.activate(queryManager);
- LifecycleUtil.activate(commitInfoManager);
- LifecycleUtil.activate(commitManager);
- LifecycleUtil.activate(queryHandlerProvider);
-
- if (!skipInitialization)
- {
- long lastCommitTimeStamp = Math.max(store.getCreationTime(), store.getLastCommitTime());
- timeStampAuthority.setLastFinishedTimeStamp(lastCommitTimeStamp);
- initMainBranch(branchManager, lastCommitTimeStamp);
-
- if (store.isFirstStart())
- {
- initSystemPackages();
- initRootResource();
- }
- else
- {
- readPackageUnits();
- readRootResource();
- }
-
- // This check does not work for CDOWorkspace:
- // if (CDOIDUtil.isNull(rootResourceID))
- // {
- // throw new IllegalStateException("Root resource ID is null");
- // }
- }
-
- LifecycleUtil.activate(getLockingManager()); // Needs an initialized main branch / branch manager
- }
-
- @Override
- protected void doDeactivate() throws Exception
- {
- LifecycleUtil.deactivate(getLockingManager());
- LifecycleUtil.deactivate(queryHandlerProvider);
- LifecycleUtil.deactivate(commitManager);
- LifecycleUtil.deactivate(commitInfoManager);
- LifecycleUtil.deactivate(queryManager);
- LifecycleUtil.deactivate(revisionManager);
- LifecycleUtil.deactivate(sessionManager);
- LifecycleUtil.deactivate(store);
- LifecycleUtil.deactivate(branchManager);
- LifecycleUtil.deactivate(packageRegistry);
- super.doDeactivate();
- }
-
- /**
- * @author Eike Stepper
- * @since 2.0
- */
- public static class Default extends Repository
- {
- public Default()
- {
- }
-
- @Override
- protected void doBeforeActivate() throws Exception
- {
- if (getPackageRegistry(false) == null)
- {
- setPackageRegistry(createPackageRegistry());
- }
-
- if (getSessionManager() == null)
- {
- setSessionManager(createSessionManager());
- }
-
- if (getBranchManager() == null)
- {
- setBranchManager(createBranchManager());
- }
-
- if (getRevisionManager() == null)
- {
- setRevisionManager(createRevisionManager());
- }
-
- if (getQueryManager() == null)
- {
- setQueryManager(createQueryManager());
- }
-
- if (getCommitInfoManager() == null)
- {
- setCommitInfoManager(createCommitInfoManager());
- }
-
- if (getCommitManager() == null)
- {
- setCommitManager(createCommitManager());
- }
-
- if (getLockManager() == null)
- {
- setLockingManager(createLockManager());
- }
-
- super.doBeforeActivate();
- }
-
- protected InternalCDOPackageRegistry createPackageRegistry()
- {
- return new CDOPackageRegistryImpl();
- }
-
- protected InternalSessionManager createSessionManager()
- {
- return new SessionManager();
- }
-
- protected InternalCDOBranchManager createBranchManager()
- {
- return CDOBranchUtil.createBranchManager();
- }
-
- protected InternalCDORevisionManager createRevisionManager()
- {
- return (InternalCDORevisionManager)CDORevisionUtil.createRevisionManager();
- }
-
- protected InternalQueryManager createQueryManager()
- {
- return new QueryManager();
- }
-
- protected InternalCDOCommitInfoManager createCommitInfoManager()
- {
- return CDOCommitInfoUtil.createCommitInfoManager();
- }
-
- protected InternalCommitManager createCommitManager()
- {
- return new CommitManager();
- }
-
- @Deprecated
- protected InternalLockManager createLockManager()
- {
- return createLockingManager();
- }
-
- public LockingManager createLockingManager()
- {
- return new LockingManager();
- }
- }
-}
+/*
+ * Copyright (c) 2004 - 2012 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
+ * Simon McDuff - bug 201266
+ * Simon McDuff - bug 233273
+ * Simon McDuff - bug 233490
+ * Stefan Winkler - changed order of determining audit and revision delta support.
+ * Andre Dietisheim - bug 256649
+ */
+package org.eclipse.emf.cdo.internal.server;
+
+import org.eclipse.emf.cdo.common.CDOCommonView;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchHandler;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
+import org.eclipse.emf.cdo.common.commit.CDOCommitData;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDGenerator;
+import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.lob.CDOLobHandler;
+import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
+import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo.Operation;
+import org.eclipse.emf.cdo.common.lock.CDOLockState;
+import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
+import org.eclipse.emf.cdo.common.model.CDOModelUtil;
+import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
+import org.eclipse.emf.cdo.common.model.EMFUtil;
+import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
+import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionFactory;
+import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
+import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
+import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
+import org.eclipse.emf.cdo.common.util.CDOCommonUtil;
+import org.eclipse.emf.cdo.common.util.CDOQueryInfo;
+import org.eclipse.emf.cdo.common.util.RepositoryStateChangedEvent;
+import org.eclipse.emf.cdo.common.util.RepositoryTypeChangedEvent;
+import org.eclipse.emf.cdo.eresource.EresourcePackage;
+import org.eclipse.emf.cdo.etypes.EtypesPackage;
+import org.eclipse.emf.cdo.internal.common.model.CDOPackageRegistryImpl;
+import org.eclipse.emf.cdo.internal.server.bundle.OM;
+import org.eclipse.emf.cdo.server.IQueryHandler;
+import org.eclipse.emf.cdo.server.IQueryHandlerProvider;
+import org.eclipse.emf.cdo.server.IStore;
+import org.eclipse.emf.cdo.server.IStore.CanHandleClientAssignedIDs;
+import org.eclipse.emf.cdo.server.IStoreAccessor;
+import org.eclipse.emf.cdo.server.IStoreChunkReader;
+import org.eclipse.emf.cdo.server.IStoreChunkReader.Chunk;
+import org.eclipse.emf.cdo.server.ITransaction;
+import org.eclipse.emf.cdo.server.IView;
+import org.eclipse.emf.cdo.server.StoreThreadLocal;
+import org.eclipse.emf.cdo.spi.common.CDOReplicationContext;
+import org.eclipse.emf.cdo.spi.common.CDOReplicationInfo;
+import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
+import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
+import org.eclipse.emf.cdo.spi.common.commit.CDOChangeSetSegment;
+import org.eclipse.emf.cdo.spi.common.commit.CDOCommitInfoUtil;
+import org.eclipse.emf.cdo.spi.common.commit.CDORevisionAvailabilityInfo;
+import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageInfo;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
+import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDOList;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
+import org.eclipse.emf.cdo.spi.common.revision.PointerCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.RevisionInfo;
+import org.eclipse.emf.cdo.spi.server.ContainerQueryHandlerProvider;
+import org.eclipse.emf.cdo.spi.server.InternalCommitContext;
+import org.eclipse.emf.cdo.spi.server.InternalCommitManager;
+import org.eclipse.emf.cdo.spi.server.InternalLockManager;
+import org.eclipse.emf.cdo.spi.server.InternalQueryManager;
+import org.eclipse.emf.cdo.spi.server.InternalRepository;
+import org.eclipse.emf.cdo.spi.server.InternalSession;
+import org.eclipse.emf.cdo.spi.server.InternalSessionManager;
+import org.eclipse.emf.cdo.spi.server.InternalStore;
+import org.eclipse.emf.cdo.spi.server.InternalTransaction;
+import org.eclipse.emf.cdo.spi.server.InternalView;
+
+import org.eclipse.emf.internal.cdo.object.CDOFactoryImpl;
+
+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.MoveableList;
+import org.eclipse.net4j.util.collection.Pair;
+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
+import org.eclipse.net4j.util.concurrent.RWOLockManager.LockState;
+import org.eclipse.net4j.util.concurrent.TimeoutRuntimeException;
+import org.eclipse.net4j.util.container.Container;
+import org.eclipse.net4j.util.container.IPluginContainer;
+import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
+import org.eclipse.net4j.util.om.monitor.Monitor;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+import org.eclipse.net4j.util.transaction.TransactionException;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.spi.cdo.CDOSessionProtocol.LockObjectsResult;
+import org.eclipse.emf.spi.cdo.CDOSessionProtocol.UnlockObjectsResult;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.Semaphore;
+
+/**
+ * @author Eike Stepper
+ * @since 2.0
+ */
+public class Repository extends Container<Object> implements InternalRepository
+{
+ private String name;
+
+ private String uuid;
+
+ private InternalStore store;
+
+ private Type type = Type.MASTER;
+
+ private State state = State.ONLINE;
+
+ private Map<String, String> properties;
+
+ private boolean supportingAudits;
+
+ private boolean supportingBranches;
+
+ private boolean supportingEcore;
+
+ private boolean ensuringReferentialIntegrity;
+
+ private IDGenerationLocation idGenerationLocation;
+
+ /**
+ * Must not be thread-bound to support XA commits.
+ */
+ private Semaphore packageRegistryCommitLock = new Semaphore(1);
+
+ private InternalCDOPackageRegistry packageRegistry;
+
+ private InternalCDOBranchManager branchManager;
+
+ private InternalCDORevisionManager revisionManager;
+
+ private InternalCDOCommitInfoManager commitInfoManager;
+
+ private InternalSessionManager sessionManager;
+
+ private InternalQueryManager queryManager;
+
+ private InternalCommitManager commitManager;
+
+ private InternalLockManager lockingManager;
+
+ private IQueryHandlerProvider queryHandlerProvider;
+
+ private List<ReadAccessHandler> readAccessHandlers = new ArrayList<ReadAccessHandler>();
+
+ private List<WriteAccessHandler> writeAccessHandlers = new ArrayList<WriteAccessHandler>();
+
+ private List<CDOCommitInfoHandler> commitInfoHandlers = new ArrayList<CDOCommitInfoHandler>();
+
+ private EPackage[] initialPackages;
+
+ // Bugzilla 297940
+ private TimeStampAuthority timeStampAuthority = new TimeStampAuthority(this);
+
+ @ExcludeFromDump
+ private transient Object createBranchLock = new Object();
+
+ private boolean skipInitialization;
+
+ private CDOID rootResourceID;
+
+ public Repository()
+ {
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public String getUUID()
+ {
+ if (uuid == null)
+ {
+ uuid = getProperties().get(Props.OVERRIDE_UUID);
+ if (uuid == null)
+ {
+ uuid = UUID.randomUUID().toString();
+ }
+ else if (uuid.length() == 0)
+ {
+ uuid = getName();
+ }
+ }
+
+ return uuid;
+ }
+
+ public InternalStore getStore()
+ {
+ return store;
+ }
+
+ public void setStore(InternalStore store)
+ {
+ this.store = store;
+ }
+
+ public Type getType()
+ {
+ return type;
+ }
+
+ public void setType(Type type)
+ {
+ checkArg(type, "type"); //$NON-NLS-1$
+ if (this.type != type)
+ {
+ changingType(this.type, type);
+ }
+ }
+
+ protected void changingType(Type oldType, Type newType)
+ {
+ type = newType;
+ fireEvent(new RepositoryTypeChangedEvent(this, oldType, newType));
+
+ if (sessionManager != null)
+ {
+ sessionManager.sendRepositoryTypeNotification(oldType, newType);
+ }
+ }
+
+ public State getState()
+ {
+ return state;
+ }
+
+ public void setState(State state)
+ {
+ checkArg(state, "state"); //$NON-NLS-1$
+ if (this.state != state)
+ {
+ changingState(this.state, state);
+ }
+ }
+
+ protected void changingState(State oldState, State newState)
+ {
+ state = newState;
+ fireEvent(new RepositoryStateChangedEvent(this, oldState, newState));
+
+ if (sessionManager != null)
+ {
+ sessionManager.sendRepositoryStateNotification(oldState, newState, getRootResourceID());
+ }
+ }
+
+ public synchronized Map<String, String> getProperties()
+ {
+ if (properties == null)
+ {
+ properties = new HashMap<String, String>();
+ }
+
+ return properties;
+ }
+
+ public synchronized void setProperties(Map<String, String> properties)
+ {
+ this.properties = properties;
+ }
+
+ public boolean isSupportingAudits()
+ {
+ return supportingAudits;
+ }
+
+ public boolean isSupportingBranches()
+ {
+ return supportingBranches;
+ }
+
+ public boolean isSupportingEcore()
+ {
+ return supportingEcore;
+ }
+
+ public boolean isEnsuringReferentialIntegrity()
+ {
+ return ensuringReferentialIntegrity;
+ }
+
+ public IDGenerationLocation getIDGenerationLocation()
+ {
+ return idGenerationLocation;
+ }
+
+ public String getStoreType()
+ {
+ return store.getType();
+ }
+
+ public Set<CDOID.ObjectType> getObjectIDTypes()
+ {
+ return store.getObjectIDTypes();
+ }
+
+ public CDOID getRootResourceID()
+ {
+ return rootResourceID;
+ }
+
+ public void setRootResourceID(CDOID rootResourceID)
+ {
+ this.rootResourceID = rootResourceID;
+ }
+
+ public Object processPackage(Object value)
+ {
+ CDOFactoryImpl.prepareDynamicEPackage(value);
+ return value;
+ }
+
+ public EPackage[] loadPackages(CDOPackageUnit packageUnit)
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ return accessor.loadPackageUnit((InternalCDOPackageUnit)packageUnit);
+ }
+
+ public Pair<Integer, Long> createBranch(int branchID, BranchInfo branchInfo)
+ {
+ if (!isSupportingBranches())
+ {
+ throw new IllegalStateException("Branching is not supported by " + this);
+ }
+
+ long baseTimeStamp = branchInfo.getBaseTimeStamp();
+ if (baseTimeStamp == CDOBranchPoint.UNSPECIFIED_DATE)
+ {
+ baseTimeStamp = getTimeStamp();
+ branchInfo = new BranchInfo(branchInfo.getName(), branchInfo.getBaseBranchID(), baseTimeStamp);
+ }
+
+ synchronized (createBranchLock)
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ return accessor.createBranch(branchID, branchInfo);
+ }
+ }
+
+ public BranchInfo loadBranch(int branchID)
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ return accessor.loadBranch(branchID);
+ }
+
+ public SubBranchInfo[] loadSubBranches(int branchID)
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ return accessor.loadSubBranches(branchID);
+ }
+
+ public int loadBranches(int startID, int endID, CDOBranchHandler branchHandler)
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ return accessor.loadBranches(startID, endID, branchHandler);
+ }
+
+ public void loadCommitInfos(CDOBranch branch, long startTime, long endTime, CDOCommitInfoHandler handler)
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ accessor.loadCommitInfos(branch, startTime, endTime, handler);
+ }
+
+ public CDOCommitData loadCommitData(long timeStamp)
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ return accessor.loadCommitData(timeStamp);
+ }
+
+ public List<InternalCDORevision> loadRevisions(List<RevisionInfo> infos, CDOBranchPoint branchPoint,
+ int referenceChunk, int prefetchDepth)
+ {
+ for (RevisionInfo info : infos)
+ {
+ CDOID id = info.getID();
+ RevisionInfo.Type type = info.getType();
+ switch (type)
+ {
+ case AVAILABLE_NORMAL: // direct == false
+ {
+ RevisionInfo.Available.Normal availableInfo = (RevisionInfo.Available.Normal)info;
+ checkArg(availableInfo.isDirect() == false, "Load is not needed");
+ break;
+ }
+
+ case AVAILABLE_POINTER: // direct == false || target == null
+ {
+ RevisionInfo.Available.Pointer pointerInfo = (RevisionInfo.Available.Pointer)info;
+ boolean needsTarget = !pointerInfo.hasTarget();
+ checkArg(pointerInfo.isDirect() == false || needsTarget, "Load is not needed");
+
+ if (needsTarget)
+ {
+ CDOBranchVersion targetBranchVersion = pointerInfo.getTargetBranchVersion();
+ InternalCDORevision target = loadRevisionByVersion(id, targetBranchVersion, referenceChunk);
+ PointerCDORevision pointer = new PointerCDORevision(target.getEClass(), id, pointerInfo
+ .getAvailableBranchVersion().getBranch(), CDORevision.UNSPECIFIED_DATE, target);
+
+ info.setResult(target);
+ info.setSynthetic(pointer);
+ continue;
+ }
+
+ break;
+ }
+
+ case AVAILABLE_DETACHED: // direct == false
+ {
+ RevisionInfo.Available.Detached detachedInfo = (RevisionInfo.Available.Detached)info;
+ checkArg(detachedInfo.isDirect() == false, "Load is not needed");
+ break;
+ }
+
+ case MISSING:
+ {
+ break;
+ }
+
+ default:
+ throw new IllegalStateException("Invalid revision info type: " + type);
+ }
+
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ InternalCDORevision revision = accessor.readRevision(id, branchPoint, referenceChunk, revisionManager);
+ if (revision == null)
+ {
+ if (isSupportingAudits())
+ {
+ InternalCDORevision target = loadRevisionTarget(id, branchPoint, referenceChunk, accessor);
+ if (target != null)
+ {
+ if (referenceChunk == CDORevision.UNCHUNKED)
+ {
+ target.setUnchunked();
+ }
+
+ CDOBranch branch = branchPoint.getBranch();
+ long revised = loadRevisionRevised(id, branch);
+ PointerCDORevision pointer = new PointerCDORevision(target.getEClass(), id, branch, revised, target);
+ info.setSynthetic(pointer);
+ }
+
+ info.setResult(target);
+ }
+ else
+ {
+ DetachedCDORevision detachedRevision = new DetachedCDORevision(EcorePackage.Literals.ECLASS, id,
+ branchPoint.getBranch(), 0, CDORevision.UNSPECIFIED_DATE);
+ info.setSynthetic(detachedRevision);
+ }
+ }
+ else if (revision instanceof DetachedCDORevision)
+ {
+ DetachedCDORevision detached = (DetachedCDORevision)revision;
+ info.setSynthetic(detached);
+ }
+ else
+ {
+ if (referenceChunk == CDORevision.UNCHUNKED)
+ {
+ revision.setUnchunked();
+ }
+
+ revision.freeze();
+ info.setResult(revision);
+ }
+ }
+
+ return null;
+ }
+
+ private InternalCDORevision loadRevisionTarget(CDOID id, CDOBranchPoint branchPoint, int referenceChunk,
+ IStoreAccessor accessor)
+ {
+ CDOBranch branch = branchPoint.getBranch();
+ while (!branch.isMainBranch())
+ {
+ branchPoint = branch.getBase();
+ branch = branchPoint.getBranch();
+
+ InternalCDORevision revision = accessor.readRevision(id, branchPoint, referenceChunk, revisionManager);
+ if (revision != null)
+ {
+ revision.freeze();
+ return revision;
+ }
+ }
+
+ return null;
+ }
+
+ private long loadRevisionRevised(CDOID id, CDOBranch branch)
+ {
+ InternalCDORevision revision = loadRevisionByVersion(id, branch.getVersion(CDORevision.FIRST_VERSION),
+ CDORevision.UNCHUNKED);
+ if (revision != null)
+ {
+ return revision.getTimeStamp() - 1;
+ }
+
+ return CDORevision.UNSPECIFIED_DATE;
+ }
+
+ public InternalCDORevision loadRevisionByVersion(CDOID id, CDOBranchVersion branchVersion, int referenceChunk)
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ return accessor.readRevisionByVersion(id, branchVersion, referenceChunk, revisionManager);
+ }
+
+ /**
+ * @deprecated Not used.
+ */
+ @Deprecated
+ protected void ensureChunks(InternalCDORevision revision, int referenceChunk, IStoreAccessor accessor)
+ {
+ EClass eClass = revision.getEClass();
+ EStructuralFeature[] features = CDOModelUtil.getAllPersistentFeatures(eClass);
+ for (int i = 0; i < features.length; i++)
+ {
+ EStructuralFeature feature = features[i];
+ if (feature.isMany())
+ {
+ MoveableList<Object> list = revision.getList(feature);
+ int chunkEnd = Math.min(referenceChunk, list.size());
+ accessor = ensureChunk(revision, feature, accessor, list, 0, chunkEnd);
+ }
+ }
+ }
+
+ public void ensureChunks(InternalCDORevision revision)
+ {
+ if (!revision.isUnchunked())
+ {
+ for (EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(revision.getEClass()))
+ {
+ if (feature.isMany())
+ {
+ ensureChunk(revision, feature, 0, revision.getList(feature).size());
+ }
+ }
+
+ revision.setUnchunked();
+ }
+ }
+
+ public IStoreAccessor ensureChunk(InternalCDORevision revision, EStructuralFeature feature, int chunkStart,
+ int chunkEnd)
+ {
+ if (!revision.isUnchunked())
+ {
+ MoveableList<Object> list = revision.getList(feature);
+ chunkEnd = Math.min(chunkEnd, list.size());
+ return ensureChunk(revision, feature, StoreThreadLocal.getAccessor(), list, chunkStart, chunkEnd);
+ }
+
+ return null;
+ }
+
+ protected IStoreAccessor ensureChunk(InternalCDORevision revision, EStructuralFeature feature,
+ IStoreAccessor accessor, MoveableList<Object> list, int chunkStart, int chunkEnd)
+ {
+ IStoreChunkReader chunkReader = null;
+ int fromIndex = -1;
+ for (int j = chunkStart; j < chunkEnd; j++)
+ {
+ if (list.get(j) == InternalCDOList.UNINITIALIZED)
+ {
+ if (fromIndex == -1)
+ {
+ fromIndex = j;
+ }
+ }
+ else
+ {
+ if (fromIndex != -1)
+ {
+ if (chunkReader == null)
+ {
+ if (accessor == null)
+ {
+ accessor = StoreThreadLocal.getAccessor();
+ }
+
+ chunkReader = accessor.createChunkReader(revision, feature);
+ }
+
+ int toIndex = j;
+ if (fromIndex == toIndex - 1)
+ {
+ chunkReader.addSimpleChunk(fromIndex);
+ }
+ else
+ {
+ chunkReader.addRangedChunk(fromIndex, toIndex);
+ }
+
+ fromIndex = -1;
+ }
+ }
+ }
+
+ // Add last chunk
+ if (fromIndex != -1)
+ {
+ if (chunkReader == null)
+ {
+ if (accessor == null)
+ {
+ accessor = StoreThreadLocal.getAccessor();
+ }
+
+ chunkReader = accessor.createChunkReader(revision, feature);
+ }
+
+ int toIndex = chunkEnd;
+ if (fromIndex == toIndex - 1)
+ {
+ chunkReader.addSimpleChunk(fromIndex);
+ }
+ else
+ {
+ chunkReader.addRangedChunk(fromIndex, toIndex);
+ }
+ }
+
+ if (chunkReader != null)
+ {
+ InternalCDOList cdoList = list instanceof InternalCDOList ? (InternalCDOList)list : null;
+
+ List<Chunk> chunks = chunkReader.executeRead();
+ for (Chunk chunk : chunks)
+ {
+ int startIndex = chunk.getStartIndex();
+ for (int indexInChunk = 0; indexInChunk < chunk.size(); indexInChunk++)
+ {
+ Object id = chunk.get(indexInChunk);
+ if (cdoList != null)
+ {
+ cdoList.setWithoutFrozenCheck(startIndex + indexInChunk, id);
+ }
+ else
+ {
+ list.set(startIndex + indexInChunk, id);
+ }
+ }
+ }
+ }
+
+ return accessor;
+ }
+
+ public InternalCDOPackageRegistry getPackageRegistry(boolean considerCommitContext)
+ {
+ if (considerCommitContext)
+ {
+ IStoreAccessor.CommitContext commitContext = StoreThreadLocal.getCommitContext();
+ if (commitContext != null)
+ {
+ InternalCDOPackageRegistry contextualPackageRegistry = commitContext.getPackageRegistry();
+ if (contextualPackageRegistry != null)
+ {
+ return contextualPackageRegistry;
+ }
+ }
+ }
+
+ return packageRegistry;
+ }
+
+ public Semaphore getPackageRegistryCommitLock()
+ {
+ return packageRegistryCommitLock;
+ }
+
+ public InternalCDOPackageRegistry getPackageRegistry()
+ {
+ return getPackageRegistry(true);
+ }
+
+ public void setPackageRegistry(InternalCDOPackageRegistry packageRegistry)
+ {
+ checkInactive();
+ this.packageRegistry = packageRegistry;
+ }
+
+ public InternalSessionManager getSessionManager()
+ {
+ return sessionManager;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void setSessionManager(InternalSessionManager sessionManager)
+ {
+ checkInactive();
+ this.sessionManager = sessionManager;
+ }
+
+ public InternalCDOBranchManager getBranchManager()
+ {
+ return branchManager;
+ }
+
+ public void setBranchManager(InternalCDOBranchManager branchManager)
+ {
+ checkInactive();
+ this.branchManager = branchManager;
+ }
+
+ public InternalCDOCommitInfoManager getCommitInfoManager()
+ {
+ return commitInfoManager;
+ }
+
+ public void setCommitInfoManager(InternalCDOCommitInfoManager commitInfoManager)
+ {
+ checkInactive();
+ this.commitInfoManager = commitInfoManager;
+ }
+
+ public InternalCDORevisionManager getRevisionManager()
+ {
+ return revisionManager;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void setRevisionManager(InternalCDORevisionManager revisionManager)
+ {
+ checkInactive();
+ this.revisionManager = revisionManager;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public InternalQueryManager getQueryManager()
+ {
+ return queryManager;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void setQueryManager(InternalQueryManager queryManager)
+ {
+ checkInactive();
+ this.queryManager = queryManager;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public InternalCommitManager getCommitManager()
+ {
+ return commitManager;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void setCommitManager(InternalCommitManager commitManager)
+ {
+ checkInactive();
+ this.commitManager = commitManager;
+ }
+
+ /**
+ * @since 2.0
+ * @deprecated
+ */
+ @Deprecated
+ public InternalLockManager getLockManager()
+ {
+ return getLockingManager();
+ }
+
+ public InternalLockManager getLockingManager()
+ {
+ return lockingManager;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void setLockingManager(InternalLockManager lockingManager)
+ {
+ checkInactive();
+ this.lockingManager = lockingManager;
+ }
+
+ public InternalCommitContext createCommitContext(InternalTransaction transaction)
+ {
+ return new TransactionCommitContext(transaction);
+ }
+
+ public long getLastCommitTimeStamp()
+ {
+ return timeStampAuthority.getLastFinishedTimeStamp();
+ }
+
+ public void setLastCommitTimeStamp(long lastCommitTimeStamp)
+ {
+ timeStampAuthority.setLastFinishedTimeStamp(lastCommitTimeStamp);
+ }
+
+ public long waitForCommit(long timeout)
+ {
+ return timeStampAuthority.waitForCommit(timeout);
+ }
+
+ public long[] createCommitTimeStamp(OMMonitor monitor)
+ {
+ return timeStampAuthority.startCommit(CDOBranchPoint.UNSPECIFIED_DATE, monitor);
+ }
+
+ public long[] forceCommitTimeStamp(long override, OMMonitor monitor)
+ {
+ return timeStampAuthority.startCommit(override, monitor);
+ }
+
+ public void endCommit(long timestamp)
+ {
+ timeStampAuthority.endCommit(timestamp);
+ }
+
+ public void failCommit(long timestamp)
+ {
+ timeStampAuthority.failCommit(timestamp);
+ }
+
+ public CDOCommitInfoHandler[] getCommitInfoHandlers()
+ {
+ synchronized (commitInfoHandlers)
+ {
+ return commitInfoHandlers.toArray(new CDOCommitInfoHandler[commitInfoHandlers.size()]);
+ }
+ }
+
+ /**
+ * @since 4.0
+ */
+ public void addCommitInfoHandler(CDOCommitInfoHandler handler)
+ {
+ synchronized (commitInfoHandlers)
+ {
+ if (!commitInfoHandlers.contains(handler))
+ {
+ commitInfoHandlers.add(handler);
+ }
+ }
+ }
+
+ /**
+ * @since 4.0
+ */
+ public void removeCommitInfoHandler(CDOCommitInfoHandler handler)
+ {
+ synchronized (commitInfoHandlers)
+ {
+ commitInfoHandlers.remove(handler);
+ }
+ }
+
+ public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo)
+ {
+ sessionManager.sendCommitNotification(sender, commitInfo);
+
+ for (CDOCommitInfoHandler handler : getCommitInfoHandlers())
+ {
+ try
+ {
+ handler.handleCommitInfo(commitInfo);
+ }
+ catch (Exception ex)
+ {
+ OM.LOG.error(ex);
+ }
+ }
+ }
+
+ /**
+ * @since 2.0
+ */
+ public IQueryHandlerProvider getQueryHandlerProvider()
+ {
+ return queryHandlerProvider;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void setQueryHandlerProvider(IQueryHandlerProvider queryHandlerProvider)
+ {
+ this.queryHandlerProvider = queryHandlerProvider;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public synchronized IQueryHandler getQueryHandler(CDOQueryInfo info)
+ {
+ String language = info.getQueryLanguage();
+ if (CDOProtocolConstants.QUERY_LANGUAGE_RESOURCES.equals(language))
+ {
+ return new ResourcesQueryHandler();
+ }
+
+ if (CDOProtocolConstants.QUERY_LANGUAGE_XREFS.equals(language))
+ {
+ return new XRefsQueryHandler();
+ }
+
+ IStoreAccessor storeAccessor = StoreThreadLocal.getAccessor();
+ if (storeAccessor != null)
+ {
+ IQueryHandler handler = storeAccessor.getQueryHandler(info);
+ if (handler != null)
+ {
+ return handler;
+ }
+ }
+
+ if (queryHandlerProvider == null)
+ {
+ queryHandlerProvider = new ContainerQueryHandlerProvider(IPluginContainer.INSTANCE);
+ }
+
+ IQueryHandler handler = queryHandlerProvider.getQueryHandler(info);
+ if (handler != null)
+ {
+ return handler;
+ }
+
+ return null;
+ }
+
+ public Object[] getElements()
+ {
+ final Object[] elements = { packageRegistry, branchManager, revisionManager, sessionManager, queryManager,
+ commitManager, commitInfoManager, getLockingManager(), store };
+ return elements;
+ }
+
+ @Override
+ public boolean isEmpty()
+ {
+ return false;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public long getCreationTime()
+ {
+ return store.getCreationTime();
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void validateTimeStamp(long timeStamp) throws IllegalArgumentException
+ {
+ long creationTimeStamp = getCreationTime();
+ if (timeStamp < creationTimeStamp)
+ {
+ throw new IllegalArgumentException(
+ MessageFormat
+ .format(
+ "timeStamp ({0}) < repository creation time ({1})", CDOCommonUtil.formatTimeStamp(timeStamp), CDOCommonUtil.formatTimeStamp(creationTimeStamp))); //$NON-NLS-1$
+ }
+
+ long currentTimeStamp = getTimeStamp();
+ if (timeStamp > currentTimeStamp)
+ {
+ throw new IllegalArgumentException(
+ MessageFormat
+ .format(
+ "timeStamp ({0}) > current time ({1})", CDOCommonUtil.formatTimeStamp(timeStamp), CDOCommonUtil.formatTimeStamp(currentTimeStamp))); //$NON-NLS-1$
+ }
+ }
+
+ public long getTimeStamp()
+ {
+ return System.currentTimeMillis();
+ }
+
+ public Set<Handler> getHandlers()
+ {
+ Set<Handler> handlers = new HashSet<Handler>();
+
+ synchronized (readAccessHandlers)
+ {
+ handlers.addAll(readAccessHandlers);
+ }
+
+ synchronized (writeAccessHandlers)
+ {
+ handlers.addAll(writeAccessHandlers);
+ }
+
+ return handlers;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void addHandler(Handler handler)
+ {
+ if (handler instanceof ReadAccessHandler)
+ {
+ synchronized (readAccessHandlers)
+ {
+ if (!readAccessHandlers.contains(handler))
+ {
+ readAccessHandlers.add((ReadAccessHandler)handler);
+ }
+ }
+ }
+
+ if (handler instanceof WriteAccessHandler)
+ {
+ synchronized (writeAccessHandlers)
+ {
+ if (!writeAccessHandlers.contains(handler))
+ {
+ writeAccessHandlers.add((WriteAccessHandler)handler);
+ }
+ }
+ }
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void removeHandler(Handler handler)
+ {
+ if (handler instanceof ReadAccessHandler)
+ {
+ synchronized (readAccessHandlers)
+ {
+ readAccessHandlers.remove(handler);
+ }
+ }
+
+ if (handler instanceof WriteAccessHandler)
+ {
+ synchronized (writeAccessHandlers)
+ {
+ writeAccessHandlers.remove(handler);
+ }
+ }
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void notifyReadAccessHandlers(InternalSession session, CDORevision[] revisions,
+ List<CDORevision> additionalRevisions)
+ {
+ ReadAccessHandler[] handlers;
+ synchronized (readAccessHandlers)
+ {
+ int size = readAccessHandlers.size();
+ if (size == 0)
+ {
+ return;
+ }
+
+ handlers = readAccessHandlers.toArray(new ReadAccessHandler[size]);
+ }
+
+ for (ReadAccessHandler handler : handlers)
+ {
+ // Do *not* protect against unchecked exceptions from handlers!
+ handler.handleRevisionsBeforeSending(session, revisions, additionalRevisions);
+ }
+ }
+
+ public void notifyWriteAccessHandlers(ITransaction transaction, IStoreAccessor.CommitContext commitContext,
+ boolean beforeCommit, OMMonitor monitor)
+ {
+ WriteAccessHandler[] handlers;
+ synchronized (writeAccessHandlers)
+ {
+ int size = writeAccessHandlers.size();
+ if (size == 0)
+ {
+ return;
+ }
+
+ handlers = writeAccessHandlers.toArray(new WriteAccessHandler[size]);
+ }
+
+ try
+ {
+ monitor.begin(handlers.length);
+ for (WriteAccessHandler handler : handlers)
+ {
+ try
+ {
+ if (beforeCommit)
+ {
+ handler.handleTransactionBeforeCommitting(transaction, commitContext, monitor.fork());
+ }
+ else
+ {
+ handler.handleTransactionAfterCommitted(transaction, commitContext, monitor.fork());
+ }
+ }
+ catch (RuntimeException ex)
+ {
+ if (!beforeCommit)
+ {
+ OM.LOG.error(ex);
+ }
+ else
+ {
+ // Do *not* protect against unchecked exceptions from handlers on before case!
+ throw ex;
+ }
+ }
+ }
+ }
+ finally
+ {
+ monitor.done();
+ }
+ }
+
+ public void setInitialPackages(EPackage... initialPackages)
+ {
+ checkInactive();
+ this.initialPackages = initialPackages;
+ }
+
+ public CDOReplicationInfo replicateRaw(CDODataOutput out, int lastReplicatedBranchID, long lastReplicatedCommitTime)
+ throws IOException
+ {
+ final int fromBranchID = lastReplicatedBranchID + 1;
+ final int toBranchID = getStore().getLastBranchID();
+
+ final long fromCommitTime = lastReplicatedCommitTime + 1L;
+ final long toCommitTime = getStore().getLastCommitTime();
+
+ out.writeInt(toBranchID);
+ out.writeLong(toCommitTime);
+
+ IStoreAccessor.Raw accessor = (IStoreAccessor.Raw)StoreThreadLocal.getAccessor();
+ accessor.rawExport(out, fromBranchID, toBranchID, fromCommitTime, toCommitTime);
+
+ return new CDOReplicationInfo()
+ {
+ public int getLastReplicatedBranchID()
+ {
+ return toBranchID;
+ }
+
+ public long getLastReplicatedCommitTime()
+ {
+ return toCommitTime;
+ }
+
+ public String[] getLockAreaIDs()
+ {
+ return null; // TODO (CD) Raw replication of lockAreas
+ }
+ };
+ }
+
+ public void replicate(CDOReplicationContext context)
+ {
+ int startID = context.getLastReplicatedBranchID() + 1;
+ branchManager.getBranches(startID, 0, context);
+
+ long startTime = context.getLastReplicatedCommitTime();
+ commitInfoManager.getCommitInfos(null, startTime + 1L, CDOBranchPoint.UNSPECIFIED_DATE, context);
+
+ getLockingManager().getLockAreas(null, context);
+ }
+
+ public CDOChangeSetData getChangeSet(CDOBranchPoint startPoint, CDOBranchPoint endPoint)
+ {
+ CDOChangeSetSegment[] segments = CDOChangeSetSegment.createFrom(startPoint, endPoint);
+
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ Set<CDOID> ids = accessor.readChangeSet(new Monitor(), segments);
+
+ return CDORevisionUtil.createChangeSetData(ids, startPoint, endPoint, revisionManager);
+ }
+
+ public Set<CDOID> getMergeData(CDORevisionAvailabilityInfo targetInfo, CDORevisionAvailabilityInfo sourceInfo,
+ CDORevisionAvailabilityInfo targetBaseInfo, CDORevisionAvailabilityInfo sourceBaseInfo, OMMonitor monitor)
+ {
+ CDOBranchPoint target = targetInfo.getBranchPoint();
+ CDOBranchPoint source = sourceInfo.getBranchPoint();
+
+ monitor.begin(5);
+
+ try
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ Set<CDOID> ids = new HashSet<CDOID>();
+
+ if (targetBaseInfo == null && sourceBaseInfo == null)
+ {
+ if (CDOBranchUtil.isContainedBy(source, target))
+ {
+ ids.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(source, target)));
+ }
+ else if (CDOBranchUtil.isContainedBy(target, source))
+ {
+ ids.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(target, source)));
+ }
+ else
+ {
+ CDOBranchPoint ancestor = CDOBranchUtil.getAncestor(target, source);
+ ids.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(ancestor, target)));
+ ids.addAll(accessor.readChangeSet(monitor.fork(), CDOChangeSetSegment.createFrom(ancestor, source)));
+ }
+ }
+ else
+ {
+ CDORevisionAvailabilityInfo sourceBaseInfoToUse = sourceBaseInfo == null ? targetBaseInfo : sourceBaseInfo;
+
+ ids.addAll(accessor.readChangeSet(monitor.fork(),
+ CDOChangeSetSegment.createFrom(targetBaseInfo.getBranchPoint(), target)));
+
+ ids.addAll(accessor.readChangeSet(monitor.fork(),
+ CDOChangeSetSegment.createFrom(sourceBaseInfoToUse.getBranchPoint(), source)));
+ }
+
+ loadMergeData(ids, targetInfo, monitor.fork());
+ loadMergeData(ids, sourceInfo, monitor.fork());
+
+ if (targetBaseInfo != null)
+ {
+ loadMergeData(ids, targetBaseInfo, monitor.fork());
+ }
+
+ if (sourceBaseInfo != null)
+ {
+ loadMergeData(ids, sourceBaseInfo, monitor.fork());
+ }
+
+ return ids;
+ }
+ finally
+ {
+ monitor.done();
+ }
+ }
+
+ private void loadMergeData(Set<CDOID> ids, CDORevisionAvailabilityInfo info, OMMonitor monitor)
+ {
+ int size = ids.size();
+ monitor.begin(size);
+
+ try
+ {
+ CDOBranchPoint branchPoint = info.getBranchPoint();
+ for (CDOID id : ids)
+ {
+ if (info.containsRevision(id))
+ {
+ info.removeRevision(id);
+ }
+ else
+ {
+ InternalCDORevision revision = getRevisionFromBranch(id, branchPoint);
+ if (revision != null)
+ {
+ info.addRevision(revision);
+ }
+ else
+ {
+ info.removeRevision(id);
+ }
+ }
+
+ monitor.worked();
+ }
+ }
+ finally
+ {
+ monitor.done();
+ }
+ }
+
+ private InternalCDORevision getRevisionFromBranch(CDOID id, CDOBranchPoint branchPoint)
+ {
+ InternalCDORevision revision = revisionManager.getRevision(id, branchPoint, CDORevision.UNCHUNKED,
+ CDORevision.DEPTH_NONE, true);
+ // if (revision == null || !ObjectUtil.equals(revision.getBranch(), branchPoint.getBranch()))
+ // {
+ // return null;
+ // }
+
+ return revision;
+ }
+
+ public void queryLobs(List<byte[]> ids)
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ accessor.queryLobs(ids);
+ }
+
+ public void handleLobs(long fromTime, long toTime, CDOLobHandler handler) throws IOException
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ accessor.handleLobs(fromTime, toTime, handler);
+ }
+
+ public void loadLob(byte[] id, OutputStream out) throws IOException
+ {
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ accessor.loadLob(id, out);
+ }
+
+ public void handleRevisions(EClass eClass, CDOBranch branch, boolean exactBranch, long timeStamp, boolean exactTime,
+ final CDORevisionHandler handler)
+ {
+ CDORevisionHandler wrapper = handler;
+ if (!exactBranch && !branch.isMainBranch())
+ {
+ if (exactTime && timeStamp == CDOBranchPoint.UNSPECIFIED_DATE)
+ {
+ throw new IllegalArgumentException("Time stamp must be specified if exactBranch==false and exactTime==true");
+ }
+
+ wrapper = new CDORevisionHandler()
+ {
+ private Set<CDOID> handled = new HashSet<CDOID>();
+
+ public boolean handleRevision(CDORevision revision)
+ {
+ CDOID id = revision.getID();
+ if (handled.add(id))
+ {
+ return handler.handleRevision(revision);
+ }
+
+ return true;
+ }
+ };
+ }
+
+ IStoreAccessor accessor = StoreThreadLocal.getAccessor();
+ while (branch != null)
+ {
+ accessor.handleRevisions(eClass, branch, timeStamp, exactTime, wrapper);
+ if (exactBranch)
+ {
+ break;
+ }
+
+ CDOBranchPoint base = branch.getBase();
+ branch = base.getBranch();
+ timeStamp = base.getTimeStamp();
+ }
+ }
+
+ public static List<Object> revisionKeysToObjects(List<CDORevisionKey> revisionKeys, CDOBranch viewedBranch,
+ boolean isSupportingBranches)
+ {
+ List<Object> lockables = new ArrayList<Object>();
+ for (CDORevisionKey revKey : revisionKeys)
+ {
+ CDOID id = revKey.getID();
+ if (isSupportingBranches)
+ {
+ lockables.add(CDOIDUtil.createIDAndBranch(id, viewedBranch));
+ }
+ else
+ {
+ lockables.add(id);
+ }
+ }
+ return lockables;
+ }
+
+ public LockObjectsResult lock(InternalView view, LockType lockType, List<CDORevisionKey> revKeys, boolean recursive,
+ long timeout)
+ {
+ List<Object> lockables = revisionKeysToObjects(revKeys, view.getBranch(), isSupportingBranches());
+ return lock(view, lockType, lockables, revKeys, recursive, timeout);
+ }
+
+ protected LockObjectsResult lock(InternalView view, LockType type, List<Object> lockables,
+ List<CDORevisionKey> loadedRevs, boolean recursive, long timeout)
+ {
+ List<LockState<Object, IView>> newLockStates = null;
+ try
+ {
+ newLockStates = getLockingManager().lock2(true, type, view, lockables, recursive, timeout);
+ }
+ catch (TimeoutRuntimeException ex)
+ {
+ return new LockObjectsResult(false, true, false, 0, new CDORevisionKey[0], new CDOLockState[0], getTimeStamp());
+ }
+ catch (InterruptedException ex)
+ {
+ throw WrappedException.wrap(ex);
+ }
+
+ long[] requiredTimestamp = { 0L };
+ CDORevisionKey[] staleRevisionsArray = null;
+
+ try
+ {
+ staleRevisionsArray = checkStaleRevisions(view, loadedRevs, lockables, type, requiredTimestamp);
+ }
+ catch (IllegalArgumentException e)
+ {
+ getLockingManager().unlock2(true, type, view, lockables, recursive);
+ throw e;
+ }
+
+ // If some of the clients' revisions are stale and it has passiveUpdates disabled,
+ // then the locks are useless so we release them and report the stale revisions
+ //
+ InternalSession session = view.getSession();
+ boolean staleNoUpdate = staleRevisionsArray.length > 0 && !session.isPassiveUpdateEnabled();
+ if (staleNoUpdate)
+ {
+ getLockingManager().unlock2(true, type, view, lockables, recursive);
+ return new LockObjectsResult(false, false, false, requiredTimestamp[0], staleRevisionsArray, new CDOLockState[0],
+ getTimeStamp());
+ }
+
+ CDOLockState[] cdoLockStates = toCDOLockStates(newLockStates);
+ sendLockNotifications(view, Operation.LOCK, type, cdoLockStates);
+
+ boolean waitForUpdate = staleRevisionsArray.length > 0;
+ return new LockObjectsResult(true, false, waitForUpdate, requiredTimestamp[0], staleRevisionsArray, cdoLockStates,
+ getTimeStamp());
+ }
+
+ private CDORevisionKey[] checkStaleRevisions(InternalView view, List<CDORevisionKey> revisionKeys,
+ List<Object> objectsToLock, LockType lockType, long[] requiredTimestamp)
+ {
+ List<CDORevisionKey> staleRevisions = new LinkedList<CDORevisionKey>();
+ if (revisionKeys != null)
+ {
+ InternalCDORevisionManager revManager = getRevisionManager();
+ CDOBranch viewedBranch = view.getBranch();
+ for (CDORevisionKey revKey : revisionKeys)
+ {
+ CDOID id = revKey.getID();
+ InternalCDORevision rev = revManager.getRevision(id, viewedBranch.getHead(), CDORevision.UNCHUNKED,
+ CDORevision.DEPTH_NONE, true);
+
+ if (rev == null)
+ {
+ throw new IllegalArgumentException(String.format("Object %s not found in branch %s (possibly detached)", id,
+ viewedBranch));
+ }
+
+ if (!revKey.equals(rev))
+ {
+ staleRevisions.add(revKey);
+ requiredTimestamp[0] = Math.max(requiredTimestamp[0], rev.getTimeStamp());
+ }
+ }
+ }
+
+ // Convert the list to an array, to satisfy the API later
+ //
+ CDORevisionKey[] staleRevisionsArray = new CDORevisionKey[staleRevisions.size()];
+ staleRevisions.toArray(staleRevisionsArray);
+
+ return staleRevisionsArray;
+ }
+
+ private void sendLockNotifications(IView view, Operation operation, LockType lockType, CDOLockState[] cdoLockStates)
+ {
+ long timestamp = getTimeStamp();
+ CDOLockChangeInfo lockChangeInfo = CDOLockUtil.createLockChangeInfo(timestamp, view, view.getBranch(), operation,
+ lockType, cdoLockStates);
+ getSessionManager().sendLockNotification((InternalSession)view.getSession(), lockChangeInfo);
+ }
+
+ // TODO (CD) This doesn't really belong here.. but getting it into CDOLockUtil isn't possible
+ public static CDOLockState[] toCDOLockStates(List<LockState<Object, IView>> lockStates)
+ {
+ CDOLockState[] cdoLockStates = new CDOLockState[lockStates.size()];
+ int i = 0;
+
+ for (LockState<Object, ? extends CDOCommonView> lockState : lockStates)
+ {
+ CDOLockState cdoLockState = CDOLockUtil.createLockState(lockState);
+ cdoLockStates[i++] = cdoLockState;
+ }
+
+ return cdoLockStates;
+ }
+
+ public UnlockObjectsResult unlock(InternalView view, LockType lockType, List<CDOID> objectIDs, boolean recursive)
+ {
+ List<Object> unlockables = null;
+ if (objectIDs != null)
+ {
+ unlockables = new ArrayList<Object>(objectIDs.size());
+ CDOBranch branch = view.getBranch();
+ for (CDOID id : objectIDs)
+ {
+ Object key = supportingBranches ? CDOIDUtil.createIDAndBranch(id, branch) : id;
+ unlockables.add(key);
+ }
+ }
+
+ return doUnlock(view, lockType, unlockables, recursive);
+ }
+
+ protected UnlockObjectsResult doUnlock(InternalView view, LockType lockType, List<Object> unlockables,
+ boolean recursive)
+ {
+ List<LockState<Object, IView>> newLockStates = null;
+ if (lockType == null) // Signals an unlock-all operation
+ {
+ newLockStates = getLockingManager().unlock2(true, view);
+ }
+ else
+ {
+ newLockStates = getLockingManager().unlock2(true, lockType, view, unlockables, recursive);
+ }
+
+ long timestamp = getTimeStamp();
+ CDOLockState[] cdoLockStates = toCDOLockStates(newLockStates);
+ sendLockNotifications(view, Operation.UNLOCK, lockType, cdoLockStates);
+
+ return new UnlockObjectsResult(cdoLockStates, timestamp);
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("Repository[{0}]", name); //$NON-NLS-1$
+ }
+
+ public boolean isSkipInitialization()
+ {
+ return skipInitialization;
+ }
+
+ public void setSkipInitialization(boolean skipInitialization)
+ {
+ this.skipInitialization = skipInitialization;
+ }
+
+ protected void initProperties()
+ {
+ String valueAudits = properties.get(Props.SUPPORTING_AUDITS);
+ if (valueAudits != null)
+ {
+ supportingAudits = Boolean.valueOf(valueAudits);
+ }
+ else
+ {
+ supportingAudits = store.getRevisionTemporality() == IStore.RevisionTemporality.AUDITING;
+ }
+
+ String valueBranches = properties.get(Props.SUPPORTING_BRANCHES);
+ if (valueBranches != null)
+ {
+ supportingBranches = Boolean.valueOf(valueBranches);
+ }
+ else
+ {
+ supportingBranches = store.getRevisionParallelism() == IStore.RevisionParallelism.BRANCHING;
+ }
+
+ String valueEcore = properties.get(Props.SUPPORTING_ECORE);
+ if (valueEcore != null)
+ {
+ supportingEcore = Boolean.valueOf(valueEcore);
+ }
+
+ String valueIntegrity = properties.get(Props.ENSURE_REFERENTIAL_INTEGRITY);
+ if (valueIntegrity != null)
+ {
+ ensuringReferentialIntegrity = Boolean.valueOf(valueIntegrity);
+ }
+
+ String valueIDLocation = properties.get(Props.ID_GENERATION_LOCATION);
+ if (valueIDLocation != null)
+ {
+ idGenerationLocation = IDGenerationLocation.valueOf(valueIDLocation);
+ }
+
+ if (idGenerationLocation == null)
+ {
+ idGenerationLocation = IDGenerationLocation.STORE;
+ }
+ }
+
+ public void initSystemPackages()
+ {
+ IStoreAccessor writer = store.getWriter(null);
+ StoreThreadLocal.setAccessor(writer);
+
+ try
+ {
+ List<InternalCDOPackageUnit> units = new ArrayList<InternalCDOPackageUnit>();
+ units.add(initSystemPackage(EcorePackage.eINSTANCE));
+ units.add(initSystemPackage(EresourcePackage.eINSTANCE));
+ units.add(initSystemPackage(EtypesPackage.eINSTANCE));
+
+ if (initialPackages != null)
+ {
+ for (EPackage initialPackage : initialPackages)
+ {
+ if (!packageRegistry.containsKey(initialPackage.getNsURI()))
+ {
+ units.add(initSystemPackage(initialPackage));
+ }
+ }
+ }
+
+ InternalCDOPackageUnit[] systemUnits = units.toArray(new InternalCDOPackageUnit[units.size()]);
+ writer.writePackageUnits(systemUnits, new Monitor());
+ writer.commit(new Monitor());
+ }
+ finally
+ {
+ StoreThreadLocal.release();
+ }
+ }
+
+ protected InternalCDOPackageUnit initSystemPackage(EPackage ePackage)
+ {
+ EMFUtil.registerPackage(ePackage, packageRegistry);
+ InternalCDOPackageInfo packageInfo = packageRegistry.getPackageInfo(ePackage);
+
+ InternalCDOPackageUnit packageUnit = packageInfo.getPackageUnit();
+ packageUnit.setTimeStamp(store.getCreationTime());
+ packageUnit.setState(CDOPackageUnit.State.LOADED);
+ return packageUnit;
+ }
+
+ public void initMainBranch(InternalCDOBranchManager branchManager, long timeStamp)
+ {
+ branchManager.initMainBranch(false, timeStamp);
+ }
+
+ protected void initRootResource()
+ {
+ CDOBranchPoint head = branchManager.getMainBranch().getHead();
+
+ CDORevisionFactory factory = getRevisionManager().getFactory();
+ InternalCDORevision rootResource = (InternalCDORevision)factory
+ .createRevision(EresourcePackage.Literals.CDO_RESOURCE);
+
+ rootResource.setBranchPoint(head);
+ rootResource.setContainerID(CDOID.NULL);
+ rootResource.setContainingFeatureID(0);
+
+ CDOID id = createRootResourceID();
+ rootResource.setID(id);
+ rootResource.setResourceID(id);
+
+ InternalSession session = getSessionManager().openSession(null);
+ InternalTransaction transaction = session.openTransaction(1, head);
+ InternalCommitContext commitContext = new TransactionCommitContext(transaction)
+ {
+ @Override
+ protected long[] createTimeStamp(OMMonitor monitor)
+ {
+ InternalRepository repository = getTransaction().getSession().getManager().getRepository();
+ return repository.forceCommitTimeStamp(store.getCreationTime(), monitor);
+ }
+
+ @Override
+ public String getUserID()
+ {
+ return SYSTEM_USER_ID;
+ }
+
+ @Override
+ public String getCommitComment()
+ {
+ return "<initialize>"; //$NON-NLS-1$
+ }
+ };
+
+ commitContext.setNewObjects(new InternalCDORevision[] { rootResource });
+ commitContext.preWrite();
+
+ commitContext.write(new Monitor());
+ commitContext.commit(new Monitor());
+
+ String rollbackMessage = commitContext.getRollbackMessage();
+ if (rollbackMessage != null)
+ {
+ throw new TransactionException(rollbackMessage);
+ }
+
+ rootResourceID = id instanceof CDOIDTemp ? commitContext.getIDMappings().get(id) : id;
+
+ commitContext.postCommit(true);
+ session.close();
+ }
+
+ protected CDOID createRootResourceID()
+ {
+ if (getIDGenerationLocation() == IDGenerationLocation.STORE)
+ {
+ return CDOIDUtil.createTempObject(1);
+ }
+
+ return CDOIDGenerator.UUID.generateCDOID(null);
+ }
+
+ protected void readRootResource()
+ {
+ IStoreAccessor reader = store.getReader(null);
+ StoreThreadLocal.setAccessor(reader);
+
+ try
+ {
+ CDOBranchPoint head = branchManager.getMainBranch().getHead();
+ rootResourceID = reader.readResourceID(CDOID.NULL, null, head);
+ }
+ finally
+ {
+ StoreThreadLocal.release();
+ }
+ }
+
+ protected void readPackageUnits()
+ {
+ IStoreAccessor reader = store.getReader(null);
+ StoreThreadLocal.setAccessor(reader);
+
+ try
+ {
+ Collection<InternalCDOPackageUnit> packageUnits = reader.readPackageUnits();
+ for (InternalCDOPackageUnit packageUnit : packageUnits)
+ {
+ packageRegistry.putPackageUnit(packageUnit);
+ }
+ }
+ finally
+ {
+ StoreThreadLocal.release();
+ }
+ }
+
+ @Override
+ protected void doBeforeActivate() throws Exception
+ {
+ super.doBeforeActivate();
+ checkState(store, "store"); //$NON-NLS-1$
+ checkState(!StringUtil.isEmpty(name), "name is empty"); //$NON-NLS-1$
+ checkState(packageRegistry, "packageRegistry"); //$NON-NLS-1$
+ checkState(sessionManager, "sessionManager"); //$NON-NLS-1$
+ checkState(branchManager, "branchManager"); //$NON-NLS-1$
+ checkState(revisionManager, "revisionManager"); //$NON-NLS-1$
+ checkState(queryManager, "queryManager"); //$NON-NLS-1$
+ checkState(commitInfoManager, "commitInfoManager"); //$NON-NLS-1$
+ checkState(commitManager, "commitManager"); //$NON-NLS-1$
+ checkState(getLockingManager(), "lockingManager"); //$NON-NLS-1$
+
+ packageRegistry.setReplacingDescriptors(true);
+ packageRegistry.setPackageProcessor(this);
+ packageRegistry.setPackageLoader(this);
+
+ branchManager.setBranchLoader(this);
+ branchManager.setTimeProvider(this);
+
+ revisionManager.setRevisionLoader(this);
+ sessionManager.setRepository(this);
+ queryManager.setRepository(this);
+ commitInfoManager.setCommitInfoLoader(this);
+ commitManager.setRepository(this);
+ getLockingManager().setRepository(this);
+ store.setRepository(this);
+ }
+
+ @Override
+ protected void doActivate() throws Exception
+ {
+ super.doActivate();
+
+ initProperties();
+ if (idGenerationLocation == IDGenerationLocation.CLIENT && !(store instanceof CanHandleClientAssignedIDs))
+ {
+ throw new IllegalStateException("Store can not handle client assigned IDs: " + store);
+ }
+
+ store.setRevisionTemporality(supportingAudits ? IStore.RevisionTemporality.AUDITING
+ : IStore.RevisionTemporality.NONE);
+ store.setRevisionParallelism(supportingBranches ? IStore.RevisionParallelism.BRANCHING
+ : IStore.RevisionParallelism.NONE);
+ revisionManager.setSupportingAudits(supportingAudits);
+ revisionManager.setSupportingBranches(supportingBranches);
+
+ LifecycleUtil.activate(store);
+ LifecycleUtil.activate(packageRegistry);
+ LifecycleUtil.activate(sessionManager);
+ LifecycleUtil.activate(revisionManager);
+ LifecycleUtil.activate(branchManager);
+ LifecycleUtil.activate(queryManager);
+ LifecycleUtil.activate(commitInfoManager);
+ LifecycleUtil.activate(commitManager);
+ LifecycleUtil.activate(queryHandlerProvider);
+
+ if (!skipInitialization)
+ {
+ long lastCommitTimeStamp = Math.max(store.getCreationTime(), store.getLastCommitTime());
+ timeStampAuthority.setLastFinishedTimeStamp(lastCommitTimeStamp);
+ initMainBranch(branchManager, lastCommitTimeStamp);
+
+ if (store.isFirstStart())
+ {
+ initSystemPackages();
+ initRootResource();
+ }
+ else
+ {
+ readPackageUnits();
+ readRootResource();
+ }
+
+ // This check does not work for CDOWorkspace:
+ // if (CDOIDUtil.isNull(rootResourceID))
+ // {
+ // throw new IllegalStateException("Root resource ID is null");
+ // }
+ }
+
+ LifecycleUtil.activate(getLockingManager()); // Needs an initialized main branch / branch manager
+ }
+
+ @Override
+ protected void doDeactivate() throws Exception
+ {
+ LifecycleUtil.deactivate(getLockingManager());
+ LifecycleUtil.deactivate(queryHandlerProvider);
+ LifecycleUtil.deactivate(commitManager);
+ LifecycleUtil.deactivate(commitInfoManager);
+ LifecycleUtil.deactivate(queryManager);
+ LifecycleUtil.deactivate(revisionManager);
+ LifecycleUtil.deactivate(sessionManager);
+ LifecycleUtil.deactivate(store);
+ LifecycleUtil.deactivate(branchManager);
+ LifecycleUtil.deactivate(packageRegistry);
+ super.doDeactivate();
+ }
+
+ /**
+ * @author Eike Stepper
+ * @since 2.0
+ */
+ public static class Default extends Repository
+ {
+ public Default()
+ {
+ }
+
+ @Override
+ protected void doBeforeActivate() throws Exception
+ {
+ if (getPackageRegistry(false) == null)
+ {
+ setPackageRegistry(createPackageRegistry());
+ }
+
+ if (getSessionManager() == null)
+ {
+ setSessionManager(createSessionManager());
+ }
+
+ if (getBranchManager() == null)
+ {
+ setBranchManager(createBranchManager());
+ }
+
+ if (getRevisionManager() == null)
+ {
+ setRevisionManager(createRevisionManager());
+ }
+
+ if (getQueryManager() == null)
+ {
+ setQueryManager(createQueryManager());
+ }
+
+ if (getCommitInfoManager() == null)
+ {
+ setCommitInfoManager(createCommitInfoManager());
+ }
+
+ if (getCommitManager() == null)
+ {
+ setCommitManager(createCommitManager());
+ }
+
+ if (getLockManager() == null)
+ {
+ setLockingManager(createLockManager());
+ }
+
+ super.doBeforeActivate();
+ }
+
+ protected InternalCDOPackageRegistry createPackageRegistry()
+ {
+ return new CDOPackageRegistryImpl();
+ }
+
+ protected InternalSessionManager createSessionManager()
+ {
+ return new SessionManager();
+ }
+
+ protected InternalCDOBranchManager createBranchManager()
+ {
+ return CDOBranchUtil.createBranchManager();
+ }
+
+ protected InternalCDORevisionManager createRevisionManager()
+ {
+ return (InternalCDORevisionManager)CDORevisionUtil.createRevisionManager();
+ }
+
+ protected InternalQueryManager createQueryManager()
+ {
+ return new QueryManager();
+ }
+
+ protected InternalCDOCommitInfoManager createCommitInfoManager()
+ {
+ return CDOCommitInfoUtil.createCommitInfoManager();
+ }
+
+ protected InternalCommitManager createCommitManager()
+ {
+ return new CommitManager();
+ }
+
+ @Deprecated
+ protected InternalLockManager createLockManager()
+ {
+ return createLockingManager();
+ }
+
+ public LockingManager createLockingManager()
+ {
+ return new LockingManager();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java
index 2644eae146..a7c41b81e6 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java
@@ -26,7 +26,6 @@ import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo.Operation;
import org.eclipse.emf.cdo.common.lock.CDOLockOwner;
import org.eclipse.emf.cdo.common.lock.CDOLockState;
import org.eclipse.emf.cdo.common.lock.CDOLockUtil;
-import org.eclipse.emf.cdo.common.model.CDOModelUtil;
import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
import org.eclipse.emf.cdo.common.revision.CDOIDAndBranch;
import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion;
@@ -1038,13 +1037,7 @@ public class TransactionCommitContext implements InternalCommitContext
}
// Make sure all chunks are loaded
- for (EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(oldRevision.getEClass()))
- {
- if (feature.isMany())
- {
- repository.ensureChunk(oldRevision, feature, 0, oldRevision.getList(feature).size());
- }
- }
+ repository.ensureChunks(oldRevision);
InternalCDORevision newRevision = oldRevision.copy();
newRevision.adjustForCommit(branch, timeStamp);
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/View.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/View.java
index 55ad08cb15..07bf2e1403 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/View.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/View.java
@@ -1,319 +1,301 @@
-/*
- * Copyright (c) 2004 - 2012 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
- * Simon McDuff - bug 233490
- */
-package org.eclipse.emf.cdo.internal.server;
-
-import org.eclipse.emf.cdo.common.CDOCommonView;
-import org.eclipse.emf.cdo.common.branch.CDOBranch;
-import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.model.CDOModelUtil;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.CDORevisionManager;
-import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.spi.server.InternalRepository;
-import org.eclipse.emf.cdo.spi.server.InternalSession;
-import org.eclipse.emf.cdo.spi.server.InternalView;
-
-import org.eclipse.net4j.util.ObjectUtil;
-import org.eclipse.net4j.util.lifecycle.Lifecycle;
-import org.eclipse.net4j.util.options.IOptionsContainer;
-
-import org.eclipse.emf.ecore.EStructuralFeature;
-
-import java.text.MessageFormat;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-/**
- * @author Eike Stepper
- */
-public class View extends Lifecycle implements InternalView, CDOCommonView.Options
-{
- private InternalSession session;
-
- private final int viewID;
-
- private final int sessionID; // Needed here so we can compute the hashCode even after session becomes null due to
- // deactivation!
-
- private CDOBranchPoint branchPoint;
-
- private String durableLockingID;
-
- private InternalRepository repository;
-
- private Set<CDOID> changeSubscriptionIDs = new HashSet<CDOID>();
-
- private boolean lockNotificationsEnabled;
-
- /**
- * @since 2.0
- */
- public View(InternalSession session, int viewID, CDOBranchPoint branchPoint)
- {
- this.session = session;
- this.viewID = viewID;
- sessionID = session.getSessionID();
-
- repository = session.getManager().getRepository();
- setBranchPoint(branchPoint);
- }
-
- public InternalSession getSession()
- {
- return session;
- }
-
- public int getSessionID()
- {
- return session.getSessionID();
- }
-
- public int getViewID()
- {
- return viewID;
- }
-
- public CDOBranch getBranch()
- {
- return branchPoint.getBranch();
- }
-
- public long getTimeStamp()
- {
- return branchPoint.getTimeStamp();
- }
-
- public boolean isReadOnly()
- {
- return true;
- }
-
- public boolean isDurableView()
- {
- return durableLockingID != null;
- }
-
- public String getDurableLockingID()
- {
- return durableLockingID;
- }
-
- /**
- * @since 2.0
- */
- public InternalRepository getRepository()
- {
- checkOpen();
- return repository;
- }
-
- public InternalCDORevision getRevision(CDOID id)
- {
- CDORevisionManager revisionManager = repository.getRevisionManager();
- return (InternalCDORevision)revisionManager.getRevision(id, this, CDORevision.UNCHUNKED, CDORevision.DEPTH_NONE,
- true);
- }
-
- public void changeTarget(CDOBranchPoint branchPoint, List<CDOID> invalidObjects,
- List<CDORevisionDelta> allChangedObjects, List<CDOID> allDetachedObjects)
- {
- List<CDORevision> oldRevisions = getRevisions(invalidObjects);
- setBranchPoint(branchPoint);
- List<CDORevision> newRevisions = getRevisions(invalidObjects);
-
- Iterator<CDORevision> it = newRevisions.iterator();
- for (CDORevision oldRevision : oldRevisions)
- {
- CDORevision newRevision = it.next();
- if (newRevision == null)
- {
- allDetachedObjects.add(oldRevision.getID());
- }
- else if (newRevision != oldRevision)
- {
- // Fix for Bugzilla 369646: ensure that revisions are fully loaded
- ensureRevisionChunks((InternalCDORevision)newRevision);
- ensureRevisionChunks((InternalCDORevision)oldRevision);
-
- CDORevisionDelta delta = newRevision.compare(oldRevision);
- allChangedObjects.add(delta);
- }
- }
- }
-
- // TODO: Eike can this be put in the Repository class?
- /**
- * Make sure that all lists of the given revision are fully loaded.
- */
- private void ensureRevisionChunks(InternalCDORevision revision)
- {
- for (EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(revision.getEClass()))
- {
- if (feature.isMany())
- {
- getRepository().ensureChunk(revision, feature, 0, revision.getList(feature).size());
- }
- }
- }
-
- private List<CDORevision> getRevisions(List<CDOID> ids)
- {
- return repository.getRevisionManager().getRevisions(ids, branchPoint, CDORevision.UNCHUNKED,
- CDORevision.DEPTH_NONE, true);
- }
-
- public void setBranchPoint(CDOBranchPoint branchPoint)
- {
- checkOpen();
- long timeStamp = branchPoint.getTimeStamp();
- branchPoint = branchPoint.getBranch().getPoint(timeStamp);
- validateTimeStamp(timeStamp);
- this.branchPoint = branchPoint;
- }
-
- protected void validateTimeStamp(long timeStamp) throws IllegalArgumentException
- {
- if (timeStamp != UNSPECIFIED_DATE)
- {
- repository.validateTimeStamp(timeStamp);
- }
- }
-
- public void setDurableLockingID(String durableLockingID)
- {
- this.durableLockingID = durableLockingID;
- }
-
- /**
- * @since 2.0
- */
- public synchronized void subscribe(CDOID id)
- {
- checkOpen();
- changeSubscriptionIDs.add(id);
- }
-
- /**
- * @since 2.0
- */
- public synchronized void unsubscribe(CDOID id)
- {
- checkOpen();
- changeSubscriptionIDs.remove(id);
- }
-
- /**
- * @since 2.0
- */
- public synchronized boolean hasSubscription(CDOID id)
- {
- checkOpen();
- return changeSubscriptionIDs.contains(id);
- }
-
- /**
- * @since 2.0
- */
- public synchronized void clearChangeSubscription()
- {
- checkOpen();
- changeSubscriptionIDs.clear();
- }
-
- @Override
- public int hashCode()
- {
- return ObjectUtil.hashCode(sessionID, viewID);
- }
-
- @Override
- public String toString()
- {
- int sessionID = session == null ? 0 : session.getSessionID();
- return MessageFormat.format("{0}[{1}:{2}]", getClassName(), sessionID, viewID); //$NON-NLS-1$
- }
-
- protected String getClassName()
- {
- return "View"; //$NON-NLS-1$
- }
-
- /**
- * @since 2.0
- */
- public void close()
- {
- deactivate();
- }
-
- @Override
- protected void doDeactivate() throws Exception
- {
- if (!isClosed())
- {
- session.viewClosed(this);
- }
-
- super.doDeactivate();
- }
-
- /**
- * @since 2.0
- */
- public void doClose()
- {
- clearChangeSubscription();
- changeSubscriptionIDs = null;
- session = null;
- repository = null;
- }
-
- /**
- * @since 2.0
- */
- public boolean isClosed()
- {
- return repository == null;
- }
-
- private void checkOpen()
- {
- if (isClosed())
- {
- throw new IllegalStateException("View closed"); //$NON-NLS-1$
- }
- }
-
- public IOptionsContainer getContainer()
- {
- return this;
- }
-
- public Options options()
- {
- return this;
- }
-
- public boolean isLockNotificationEnabled()
- {
- return lockNotificationsEnabled;
- }
-
- public void setLockNotificationEnabled(boolean enable)
- {
- lockNotificationsEnabled = enable;
- }
-}
+/*
+ * Copyright (c) 2004 - 2012 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
+ * Simon McDuff - bug 233490
+ */
+package org.eclipse.emf.cdo.internal.server;
+
+import org.eclipse.emf.cdo.common.CDOCommonView;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionManager;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.server.InternalRepository;
+import org.eclipse.emf.cdo.spi.server.InternalSession;
+import org.eclipse.emf.cdo.spi.server.InternalView;
+
+import org.eclipse.net4j.util.ObjectUtil;
+import org.eclipse.net4j.util.lifecycle.Lifecycle;
+import org.eclipse.net4j.util.options.IOptionsContainer;
+
+import java.text.MessageFormat;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Eike Stepper
+ */
+public class View extends Lifecycle implements InternalView, CDOCommonView.Options
+{
+ private InternalSession session;
+
+ private final int viewID;
+
+ private final int sessionID; // Needed here so we can compute the hashCode even after session becomes null due to
+ // deactivation!
+
+ private CDOBranchPoint branchPoint;
+
+ private String durableLockingID;
+
+ private InternalRepository repository;
+
+ private Set<CDOID> changeSubscriptionIDs = new HashSet<CDOID>();
+
+ private boolean lockNotificationsEnabled;
+
+ /**
+ * @since 2.0
+ */
+ public View(InternalSession session, int viewID, CDOBranchPoint branchPoint)
+ {
+ this.session = session;
+ this.viewID = viewID;
+ sessionID = session.getSessionID();
+
+ repository = session.getManager().getRepository();
+ setBranchPoint(branchPoint);
+ }
+
+ public InternalSession getSession()
+ {
+ return session;
+ }
+
+ public int getSessionID()
+ {
+ return session.getSessionID();
+ }
+
+ public int getViewID()
+ {
+ return viewID;
+ }
+
+ public CDOBranch getBranch()
+ {
+ return branchPoint.getBranch();
+ }
+
+ public long getTimeStamp()
+ {
+ return branchPoint.getTimeStamp();
+ }
+
+ public boolean isReadOnly()
+ {
+ return true;
+ }
+
+ public boolean isDurableView()
+ {
+ return durableLockingID != null;
+ }
+
+ public String getDurableLockingID()
+ {
+ return durableLockingID;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public InternalRepository getRepository()
+ {
+ checkOpen();
+ return repository;
+ }
+
+ public InternalCDORevision getRevision(CDOID id)
+ {
+ CDORevisionManager revisionManager = repository.getRevisionManager();
+ return (InternalCDORevision)revisionManager.getRevision(id, this, CDORevision.UNCHUNKED, CDORevision.DEPTH_NONE,
+ true);
+ }
+
+ public void changeTarget(CDOBranchPoint branchPoint, List<CDOID> invalidObjects,
+ List<CDORevisionDelta> allChangedObjects, List<CDOID> allDetachedObjects)
+ {
+ List<CDORevision> oldRevisions = getRevisions(invalidObjects);
+ setBranchPoint(branchPoint);
+ List<CDORevision> newRevisions = getRevisions(invalidObjects);
+
+ Iterator<CDORevision> it = newRevisions.iterator();
+ for (CDORevision oldRevision : oldRevisions)
+ {
+ CDORevision newRevision = it.next();
+ if (newRevision == null)
+ {
+ allDetachedObjects.add(oldRevision.getID());
+ }
+ else if (newRevision != oldRevision)
+ {
+ // Fix for Bugzilla 369646: ensure that revisions are fully loaded
+ repository.ensureChunks((InternalCDORevision)newRevision);
+ repository.ensureChunks((InternalCDORevision)oldRevision);
+
+ CDORevisionDelta delta = newRevision.compare(oldRevision);
+ allChangedObjects.add(delta);
+ }
+ }
+ }
+
+ private List<CDORevision> getRevisions(List<CDOID> ids)
+ {
+ return repository.getRevisionManager().getRevisions(ids, branchPoint, CDORevision.UNCHUNKED,
+ CDORevision.DEPTH_NONE, true);
+ }
+
+ public void setBranchPoint(CDOBranchPoint branchPoint)
+ {
+ checkOpen();
+ long timeStamp = branchPoint.getTimeStamp();
+ branchPoint = branchPoint.getBranch().getPoint(timeStamp);
+ validateTimeStamp(timeStamp);
+ this.branchPoint = branchPoint;
+ }
+
+ protected void validateTimeStamp(long timeStamp) throws IllegalArgumentException
+ {
+ if (timeStamp != UNSPECIFIED_DATE)
+ {
+ repository.validateTimeStamp(timeStamp);
+ }
+ }
+
+ public void setDurableLockingID(String durableLockingID)
+ {
+ this.durableLockingID = durableLockingID;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public synchronized void subscribe(CDOID id)
+ {
+ checkOpen();
+ changeSubscriptionIDs.add(id);
+ }
+
+ /**
+ * @since 2.0
+ */
+ public synchronized void unsubscribe(CDOID id)
+ {
+ checkOpen();
+ changeSubscriptionIDs.remove(id);
+ }
+
+ /**
+ * @since 2.0
+ */
+ public synchronized boolean hasSubscription(CDOID id)
+ {
+ checkOpen();
+ return changeSubscriptionIDs.contains(id);
+ }
+
+ /**
+ * @since 2.0
+ */
+ public synchronized void clearChangeSubscription()
+ {
+ checkOpen();
+ changeSubscriptionIDs.clear();
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return ObjectUtil.hashCode(sessionID, viewID);
+ }
+
+ @Override
+ public String toString()
+ {
+ int sessionID = session == null ? 0 : session.getSessionID();
+ return MessageFormat.format("{0}[{1}:{2}]", getClassName(), sessionID, viewID); //$NON-NLS-1$
+ }
+
+ protected String getClassName()
+ {
+ return "View"; //$NON-NLS-1$
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void close()
+ {
+ deactivate();
+ }
+
+ @Override
+ protected void doDeactivate() throws Exception
+ {
+ if (!isClosed())
+ {
+ session.viewClosed(this);
+ }
+
+ super.doDeactivate();
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void doClose()
+ {
+ clearChangeSubscription();
+ changeSubscriptionIDs = null;
+ session = null;
+ repository = null;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public boolean isClosed()
+ {
+ return repository == null;
+ }
+
+ private void checkOpen()
+ {
+ if (isClosed())
+ {
+ throw new IllegalStateException("View closed"); //$NON-NLS-1$
+ }
+ }
+
+ public IOptionsContainer getContainer()
+ {
+ return this;
+ }
+
+ public Options options()
+ {
+ return this;
+ }
+
+ public boolean isLockNotificationEnabled()
+ {
+ return lockNotificationsEnabled;
+ }
+
+ public void setLockNotificationEnabled(boolean enable)
+ {
+ lockNotificationsEnabled = enable;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java
index 562881acdb..a3c652424a 100644
--- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java
+++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/spi/server/InternalRepository.java
@@ -1,240 +1,245 @@
-/*
- * Copyright (c) 2004 - 2012 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.spi.server;
-
-import org.eclipse.emf.cdo.common.branch.CDOBranch;
-import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
-import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
-import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.lob.CDOLobHandler;
-import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
-import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
-import org.eclipse.emf.cdo.server.IQueryHandlerProvider;
-import org.eclipse.emf.cdo.server.IRepository;
-import org.eclipse.emf.cdo.server.IStoreAccessor;
-import org.eclipse.emf.cdo.server.ITransaction;
-import org.eclipse.emf.cdo.spi.common.CDOReplicationContext;
-import org.eclipse.emf.cdo.spi.common.CDOReplicationInfo;
-import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
-import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager.BranchLoader;
-import org.eclipse.emf.cdo.spi.common.commit.CDORevisionAvailabilityInfo;
-import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
-import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager.CommitInfoLoader;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry.PackageLoader;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry.PackageProcessor;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager.RevisionLoader;
-
-import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
-import org.eclipse.net4j.util.om.monitor.OMMonitor;
-
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.spi.cdo.CDOSessionProtocol.LockObjectsResult;
-import org.eclipse.emf.spi.cdo.CDOSessionProtocol.UnlockObjectsResult;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Semaphore;
-
-/**
- * @author Eike Stepper
- * @since 3.0
- * @noextend This interface is not intended to be extended by clients.
- * @noimplement This interface is not intended to be implemented by clients.
- */
-public interface InternalRepository extends IRepository, PackageProcessor, PackageLoader, BranchLoader, RevisionLoader,
- CommitInfoLoader
-{
- public void setName(String name);
-
- public void setType(Type type);
-
- public void setState(State state);
-
- public InternalStore getStore();
-
- public void setStore(InternalStore store);
-
- public void setProperties(Map<String, String> properties);
-
- public InternalCDOBranchManager getBranchManager();
-
- public void setBranchManager(InternalCDOBranchManager branchManager);
-
- /**
- * @since 4.1
- */
- public Semaphore getPackageRegistryCommitLock();
-
- /**
- * Same as calling {@link #getPackageRegistry(boolean) getPackageRegistry(true)}.
- */
- public InternalCDOPackageRegistry getPackageRegistry();
-
- public InternalCDOPackageRegistry getPackageRegistry(boolean considerCommitContext);
-
- public InternalCDORevisionManager getRevisionManager();
-
- public void setRevisionManager(InternalCDORevisionManager revisionManager);
-
- public InternalCDOCommitInfoManager getCommitInfoManager();
-
- public InternalSessionManager getSessionManager();
-
- public void setSessionManager(InternalSessionManager sessionManager);
-
- /**
- * @deprecated As of 4.1 use {@link #getLockingManager()}.
- */
- @Deprecated
- public InternalLockManager getLockManager();
-
- /**
- * @since 4.1
- */
- public InternalLockManager getLockingManager();
-
- public InternalQueryManager getQueryManager();
-
- public void setQueryHandlerProvider(IQueryHandlerProvider queryHandlerProvider);
-
- public InternalCommitManager getCommitManager();
-
- public InternalCommitContext createCommitContext(InternalTransaction transaction);
-
- /**
- * Returns a commit time stamp that is guaranteed to be unique in this repository. At index 1 of the returned
- * <code>long</code> array is the previous commit time.
- *
- * @since 4.0
- */
- public long[] createCommitTimeStamp(OMMonitor monitor);
-
- /**
- * Like {@link #createCommitTimeStamp(OMMonitor)}, but forces the repository to use the timestamp value passed in as
- * the argument. This should be called only to force the timestamp of the first commit of a new repository to be equal
- * to its creation time.
- *
- * @since 4.0
- */
- public long[] forceCommitTimeStamp(long timestamp, OMMonitor monitor);
-
- /**
- * Notifies the repository of the completion of a commit. The value passed in must be a value obtained earlier through
- * {@link #createCommitTimeStamp(OMMonitor)}
- *
- * @since 4.0
- */
- public void endCommit(long timeStamp);
-
- /**
- * Notifies the repository of the failure of a commit. The value passed in must be a value obtained earlier through
- * {@link #createCommitTimeStamp(OMMonitor)}
- *
- * @since 4.0
- */
- public void failCommit(long timeStamp);
-
- /**
- * @since 4.0
- */
- public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo);
-
- public void setRootResourceID(CDOID rootResourceID);
-
- /**
- * @since 4.0
- */
- public void setLastCommitTimeStamp(long commitTimeStamp);
-
- public IStoreAccessor ensureChunk(InternalCDORevision revision, EStructuralFeature feature, int chunkStart,
- int chunkEnd);
-
- public void notifyReadAccessHandlers(InternalSession session, CDORevision[] revisions,
- List<CDORevision> additionalRevisions);
-
- public void notifyWriteAccessHandlers(ITransaction transaction, IStoreAccessor.CommitContext commitContext,
- boolean beforeCommit, OMMonitor monitor);
-
- public void replicate(CDOReplicationContext context);
-
- public CDOReplicationInfo replicateRaw(CDODataOutput out, int lastReplicatedBranchID, long lastReplicatedCommitTime)
- throws IOException;
-
- public CDOChangeSetData getChangeSet(CDOBranchPoint startPoint, CDOBranchPoint endPoint);
-
- /**
- * @since 4.0
- */
- public Set<CDOID> getMergeData(CDORevisionAvailabilityInfo targetInfo, CDORevisionAvailabilityInfo sourceInfo,
- CDORevisionAvailabilityInfo targetBaseInfo, CDORevisionAvailabilityInfo sourceBaseInfo, OMMonitor monitor);
-
- /**
- * @since 4.0
- */
- public void queryLobs(List<byte[]> ids);
-
- /**
- * @since 4.0
- */
- public void handleLobs(long fromTime, long toTime, CDOLobHandler handler) throws IOException;
-
- /**
- * @since 4.0
- */
- public void loadLob(byte[] id, OutputStream out) throws IOException;
-
- /**
- * @since 4.0
- */
- public void handleRevisions(EClass eClass, CDOBranch branch, boolean exactBranch, long timeStamp, boolean exactTime,
- CDORevisionHandler handler);
-
- /**
- * @since 4.0
- */
- public boolean isSkipInitialization();
-
- /**
- * @since 4.0
- */
- public void setSkipInitialization(boolean skipInitialization);
-
- /**
- * @since 4.0
- */
- public void initSystemPackages();
-
- /**
- * @since 4.0
- */
- public void initMainBranch(InternalCDOBranchManager branchManager, long timeStamp);
-
- /**
- * @since 4.1
- */
- public LockObjectsResult lock(InternalView view, LockType type, List<CDORevisionKey> keys, boolean recursive,
- long timeout);
-
- /**
- * @since 4.1
- */
- public UnlockObjectsResult unlock(InternalView view, LockType type, List<CDOID> ids, boolean recursive);
-}
+/*
+ * Copyright (c) 2004 - 2012 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.spi.server;
+
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.lob.CDOLobHandler;
+import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
+import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
+import org.eclipse.emf.cdo.server.IQueryHandlerProvider;
+import org.eclipse.emf.cdo.server.IRepository;
+import org.eclipse.emf.cdo.server.IStoreAccessor;
+import org.eclipse.emf.cdo.server.ITransaction;
+import org.eclipse.emf.cdo.spi.common.CDOReplicationContext;
+import org.eclipse.emf.cdo.spi.common.CDOReplicationInfo;
+import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
+import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager.BranchLoader;
+import org.eclipse.emf.cdo.spi.common.commit.CDORevisionAvailabilityInfo;
+import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
+import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager.CommitInfoLoader;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry.PackageLoader;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry.PackageProcessor;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager.RevisionLoader;
+
+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
+import org.eclipse.net4j.util.om.monitor.OMMonitor;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.spi.cdo.CDOSessionProtocol.LockObjectsResult;
+import org.eclipse.emf.spi.cdo.CDOSessionProtocol.UnlockObjectsResult;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Semaphore;
+
+/**
+ * @author Eike Stepper
+ * @since 3.0
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface InternalRepository extends IRepository, PackageProcessor, PackageLoader, BranchLoader, RevisionLoader,
+ CommitInfoLoader
+{
+ public void setName(String name);
+
+ public void setType(Type type);
+
+ public void setState(State state);
+
+ public InternalStore getStore();
+
+ public void setStore(InternalStore store);
+
+ public void setProperties(Map<String, String> properties);
+
+ public InternalCDOBranchManager getBranchManager();
+
+ public void setBranchManager(InternalCDOBranchManager branchManager);
+
+ /**
+ * @since 4.1
+ */
+ public Semaphore getPackageRegistryCommitLock();
+
+ /**
+ * Same as calling {@link #getPackageRegistry(boolean) getPackageRegistry(true)}.
+ */
+ public InternalCDOPackageRegistry getPackageRegistry();
+
+ public InternalCDOPackageRegistry getPackageRegistry(boolean considerCommitContext);
+
+ public InternalCDORevisionManager getRevisionManager();
+
+ public void setRevisionManager(InternalCDORevisionManager revisionManager);
+
+ public InternalCDOCommitInfoManager getCommitInfoManager();
+
+ public InternalSessionManager getSessionManager();
+
+ public void setSessionManager(InternalSessionManager sessionManager);
+
+ /**
+ * @deprecated As of 4.1 use {@link #getLockingManager()}.
+ */
+ @Deprecated
+ public InternalLockManager getLockManager();
+
+ /**
+ * @since 4.1
+ */
+ public InternalLockManager getLockingManager();
+
+ public InternalQueryManager getQueryManager();
+
+ public void setQueryHandlerProvider(IQueryHandlerProvider queryHandlerProvider);
+
+ public InternalCommitManager getCommitManager();
+
+ public InternalCommitContext createCommitContext(InternalTransaction transaction);
+
+ /**
+ * Returns a commit time stamp that is guaranteed to be unique in this repository. At index 1 of the returned
+ * <code>long</code> array is the previous commit time.
+ *
+ * @since 4.0
+ */
+ public long[] createCommitTimeStamp(OMMonitor monitor);
+
+ /**
+ * Like {@link #createCommitTimeStamp(OMMonitor)}, but forces the repository to use the timestamp value passed in as
+ * the argument. This should be called only to force the timestamp of the first commit of a new repository to be equal
+ * to its creation time.
+ *
+ * @since 4.0
+ */
+ public long[] forceCommitTimeStamp(long timestamp, OMMonitor monitor);
+
+ /**
+ * Notifies the repository of the completion of a commit. The value passed in must be a value obtained earlier through
+ * {@link #createCommitTimeStamp(OMMonitor)}
+ *
+ * @since 4.0
+ */
+ public void endCommit(long timeStamp);
+
+ /**
+ * Notifies the repository of the failure of a commit. The value passed in must be a value obtained earlier through
+ * {@link #createCommitTimeStamp(OMMonitor)}
+ *
+ * @since 4.0
+ */
+ public void failCommit(long timeStamp);
+
+ /**
+ * @since 4.0
+ */
+ public void sendCommitNotification(InternalSession sender, CDOCommitInfo commitInfo);
+
+ public void setRootResourceID(CDOID rootResourceID);
+
+ /**
+ * @since 4.0
+ */
+ public void setLastCommitTimeStamp(long commitTimeStamp);
+
+ /**
+ * @since 4.1
+ */
+ public void ensureChunks(InternalCDORevision revision);
+
+ public IStoreAccessor ensureChunk(InternalCDORevision revision, EStructuralFeature feature, int chunkStart,
+ int chunkEnd);
+
+ public void notifyReadAccessHandlers(InternalSession session, CDORevision[] revisions,
+ List<CDORevision> additionalRevisions);
+
+ public void notifyWriteAccessHandlers(ITransaction transaction, IStoreAccessor.CommitContext commitContext,
+ boolean beforeCommit, OMMonitor monitor);
+
+ public void replicate(CDOReplicationContext context);
+
+ public CDOReplicationInfo replicateRaw(CDODataOutput out, int lastReplicatedBranchID, long lastReplicatedCommitTime)
+ throws IOException;
+
+ public CDOChangeSetData getChangeSet(CDOBranchPoint startPoint, CDOBranchPoint endPoint);
+
+ /**
+ * @since 4.0
+ */
+ public Set<CDOID> getMergeData(CDORevisionAvailabilityInfo targetInfo, CDORevisionAvailabilityInfo sourceInfo,
+ CDORevisionAvailabilityInfo targetBaseInfo, CDORevisionAvailabilityInfo sourceBaseInfo, OMMonitor monitor);
+
+ /**
+ * @since 4.0
+ */
+ public void queryLobs(List<byte[]> ids);
+
+ /**
+ * @since 4.0
+ */
+ public void handleLobs(long fromTime, long toTime, CDOLobHandler handler) throws IOException;
+
+ /**
+ * @since 4.0
+ */
+ public void loadLob(byte[] id, OutputStream out) throws IOException;
+
+ /**
+ * @since 4.0
+ */
+ public void handleRevisions(EClass eClass, CDOBranch branch, boolean exactBranch, long timeStamp, boolean exactTime,
+ CDORevisionHandler handler);
+
+ /**
+ * @since 4.0
+ */
+ public boolean isSkipInitialization();
+
+ /**
+ * @since 4.0
+ */
+ public void setSkipInitialization(boolean skipInitialization);
+
+ /**
+ * @since 4.0
+ */
+ public void initSystemPackages();
+
+ /**
+ * @since 4.0
+ */
+ public void initMainBranch(InternalCDOBranchManager branchManager, long timeStamp);
+
+ /**
+ * @since 4.1
+ */
+ public LockObjectsResult lock(InternalView view, LockType type, List<CDORevisionKey> keys, boolean recursive,
+ long timeout);
+
+ /**
+ * @since 4.1
+ */
+ public UnlockObjectsResult unlock(InternalView view, LockType type, List<CDOID> ids, boolean recursive);
+}
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 b9fef3935e..ce4235b5f9 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
@@ -1,1632 +1,1633 @@
-/*
- * Copyright (c) 2004 - 2012 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
- * Simon McDuff - maintenance
- */
-package org.eclipse.emf.internal.cdo;
-
-import org.eclipse.emf.cdo.CDOLock;
-import org.eclipse.emf.cdo.CDOObject;
-import org.eclipse.emf.cdo.CDOState;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.lock.CDOLockState;
-import org.eclipse.emf.cdo.common.model.EMFUtil;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.eresource.CDOResource;
-import org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.util.CDOUtil;
-import org.eclipse.emf.cdo.view.CDOView;
-
-import org.eclipse.emf.internal.cdo.bundle.OM;
-import org.eclipse.emf.internal.cdo.messages.Messages;
-import org.eclipse.emf.internal.cdo.object.CDOLockImpl;
-import org.eclipse.emf.internal.cdo.view.CDOStateMachine;
-
-import org.eclipse.net4j.util.ObjectUtil;
-import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
-import org.eclipse.net4j.util.om.trace.ContextTracer;
-
-import org.eclipse.emf.common.notify.Adapter;
-import org.eclipse.emf.common.notify.Notification;
-import org.eclipse.emf.common.notify.NotificationChain;
-import org.eclipse.emf.common.util.BasicEList;
-import org.eclipse.emf.common.util.BasicEMap;
-import org.eclipse.emf.common.util.ECollections;
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.InternalEObject;
-import org.eclipse.emf.ecore.impl.BasicEObjectImpl;
-import org.eclipse.emf.ecore.impl.ENotificationImpl;
-import org.eclipse.emf.ecore.impl.EStoreEObjectImpl;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.resource.Resource.Internal;
-import org.eclipse.emf.ecore.util.DelegatingFeatureMap;
-import org.eclipse.emf.ecore.util.EcoreEList;
-import org.eclipse.emf.ecore.util.EcoreEMap;
-import org.eclipse.emf.ecore.util.FeatureMap;
-import org.eclipse.emf.ecore.util.FeatureMapUtil;
-import org.eclipse.emf.ecore.util.InternalEList;
-import org.eclipse.emf.spi.cdo.CDOStore;
-import org.eclipse.emf.spi.cdo.FSMUtil;
-import org.eclipse.emf.spi.cdo.InternalCDOLoadable;
-import org.eclipse.emf.spi.cdo.InternalCDOObject;
-import org.eclipse.emf.spi.cdo.InternalCDOView;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-
-/**
- * The base class of all <em>native</em> {@link CDOObject objects}.
- *
- * @author Eike Stepper
- */
-public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObject
-{
- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_OBJECT, CDOObjectImpl.class);
-
- private CDOID id;
-
- private CDOState state;
-
- private InternalCDOView view;
-
- private InternalCDORevision revision;
-
- /**
- * CDO uses this list instead of eSettings for transient objects. EMF uses eSettings as cache. CDO deactivates the
- * cache but EMF still used eSettings to store list wrappers. CDO needs another place to store the real list with the
- * actual data (transient mode) and accessible through EStore. This allows CDO to always use the same instance of the
- * list wrapper.
- */
- private transient Object[] cdoSettings;
-
- public CDOObjectImpl()
- {
- state = CDOState.TRANSIENT;
- eContainer = null;
- cdoSettings = null;
- }
-
- public CDOID cdoID()
- {
- return id;
- }
-
- public CDOState cdoState()
- {
- return state;
- }
-
- /**
- * @since 2.0
- */
- public InternalCDORevision cdoRevision()
- {
- return revision;
- }
-
- /**
- * @since 2.0
- */
- public InternalCDOView cdoView()
- {
- return view;
- }
-
- public CDOResourceImpl cdoResource()
- {
- Resource resource = eResource();
- if (resource instanceof CDOResourceImpl)
- {
- return (CDOResourceImpl)resource;
- }
-
- return null;
- }
-
- /**
- * @since 2.0
- */
- public CDOResourceImpl cdoDirectResource()
- {
- Resource.Internal resource = eDirectResource();
- if (resource instanceof CDOResourceImpl)
- {
- return (CDOResourceImpl)resource;
- }
-
- return null;
- }
-
- /**
- * @since 3.0
- */
- public void cdoPrefetch(int depth)
- {
- view.prefetchRevisions(id, depth);
- }
-
- public void cdoReload()
- {
- CDOStateMachine.INSTANCE.reload(this);
- }
-
- /**
- * @since 2.0
- */
- public boolean cdoConflict()
- {
- return FSMUtil.isConflict(this);
- }
-
- /**
- * @since 2.0
- */
- public boolean cdoInvalid()
- {
- return FSMUtil.isInvalid(this);
- }
-
- /**
- * @since 2.0
- */
- public CDOLock cdoReadLock()
- {
- return createLock(this, LockType.READ);
- }
-
- /**
- * @since 2.0
- */
- public CDOLock cdoWriteLock()
- {
- return createLock(this, LockType.WRITE);
- }
-
- /**
- * @since 4.1
- */
- public CDOLock cdoWriteOption()
- {
- return createLock(this, LockType.OPTION);
- }
-
- /**
- * @since 4.1
- */
- public CDOLockState cdoLockState()
- {
- return getLockState(this);
- }
-
- public void cdoInternalSetID(CDOID id)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Setting ID: {0}", id); //$NON-NLS-1$
- }
-
- this.id = id;
- }
-
- public CDOState cdoInternalSetState(CDOState state)
- {
- CDOState oldState = this.state;
- if (oldState != state)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Setting state {0} for {1}", state, this); //$NON-NLS-1$
- }
-
- this.state = state;
- if (view != null)
- {
- view.handleObjectStateChanged(this, oldState, state);
- }
-
- return oldState;
- }
-
- return null;
- }
-
- /**
- * @since 2.0
- */
- public void cdoInternalSetRevision(CDORevision revision)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Setting revision: {0}", revision); //$NON-NLS-1$
- }
-
- this.revision = (InternalCDORevision)revision;
- }
-
- /**
- * @since 2.0
- */
- public void cdoInternalSetView(CDOView view)
- {
- this.view = (InternalCDOView)view;
- if (this.view != null)
- {
- eSetStore(this.view.getStore());
- }
- else
- {
- eSetStore(null);
- }
- }
-
- public void cdoInternalSetResource(CDOResource resource)
- {
- throw new UnsupportedOperationException();
- }
-
- /**
- * @since 2.0
- */
- public void cdoInternalPreLoad()
- {
- // Do nothing
- }
-
- public void cdoInternalPostLoad()
- {
- // Reset EMAP objects
- if (eSettings != null)
- {
- // Make sure transient features are kept but persisted values are not cached.
- EClass eClass = eClass();
- for (int i = 0; i < eClass.getFeatureCount(); i++)
- {
- EStructuralFeature eFeature = cdoInternalDynamicFeature(i);
-
- // We need to keep the existing list if possible.
- if (EMFUtil.isPersistent(eFeature) && eSettings[i] instanceof InternalCDOLoadable)
- {
- ((InternalCDOLoadable)eSettings[i]).cdoInternalPostLoad();
- }
- }
- }
- }
-
- /**
- * @since 2.0
- */
- public void cdoInternalPostInvalidate()
- {
- // Do nothing
- }
-
- public void cdoInternalPostAttach()
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Populating revision for {0}", this); //$NON-NLS-1$
- }
-
- revision.setContainerID(eContainer == null ? CDOID.NULL : view.convertObjectToID(eContainer, true));
- revision.setContainingFeatureID(eContainerFeatureID);
-
- Resource directResource = eDirectResource();
- if (directResource instanceof CDOResource)
- {
- CDOResource cdoResource = (CDOResource)directResource;
- revision.setResourceID(cdoResource.cdoID());
- }
-
- if (cdoSettings != null)
- {
- EClass eClass = eClass();
- for (int i = 0; i < eClass.getFeatureCount(); i++)
- {
- EStructuralFeature eFeature = cdoInternalDynamicFeature(i);
- if (EMFUtil.isPersistent(eFeature))
- {
- instanceToRevisionFeature(view, this, eFeature, cdoSettings[i]);
- }
- }
-
- cdoSettings = null;
- }
- }
-
- /**
- * It is really important for accessing the data to go through {@link #cdoStore()}. {@link #eStore()} will redirect
- * you to the transient data.
- *
- * @since 2.0
- */
- public void cdoInternalPostDetach(boolean remote)
- {
- if (remote)
- {
- // Do nothing
- return;
- }
-
- if (TRACER.isEnabled())
- {
- TRACER.format("Depopulating revision for {0}", this); //$NON-NLS-1$
- }
-
- CDOStore store = cdoStore();
- super.eSetDirectResource((Resource.Internal)store.getResource(this));
- eContainer = store.getContainer(this);
- eContainerFeatureID = store.getContainingFeatureID(this);
-
- // Ensure that the internal eSettings array is initialized;
- resetSettings();
-
- EClass eClass = eClass();
- for (int i = 0; i < eClass.getFeatureCount(); i++)
- {
- EStructuralFeature eFeature = cdoInternalDynamicFeature(i);
- if (EMFUtil.isPersistent(eFeature))
- {
- revisionToInstanceFeature(this, revision, eFeature);
- }
- }
- }
-
- /**
- * @since 3.0
- */
- public void cdoInternalPostRollback()
- {
- // Do nothing
- }
-
- public void cdoInternalPreCommit()
- {
- // Do nothing
- }
-
- public InternalEObject cdoInternalInstance()
- {
- return this;
- }
-
- public EStructuralFeature cdoInternalDynamicFeature(int dynamicFeatureID)
- {
- return eDynamicFeature(dynamicFeatureID);
- }
-
- /**
- * @since 2.0
- */
- @Override
- public synchronized EList<Adapter> eAdapters()
- {
- if (eAdapters == null)
- {
- // TODO Adjust for EObjectEAdapterList (see bug #247130)
- eAdapters = new EAdapterList<Adapter>(this)
- {
- private static final long serialVersionUID = 1L;
-
- @Override
- protected void didAdd(int index, Adapter newObject)
- {
- if (view == null || view.isActive())
- {
- super.didAdd(index, newObject);
- if (!FSMUtil.isTransient(CDOObjectImpl.this))
- {
- view.handleAddAdapter(CDOObjectImpl.this, newObject);
- }
- }
- }
-
- @Override
- protected void didRemove(int index, Adapter oldObject)
- {
- if (view == null || view.isActive())
- {
- super.didRemove(index, oldObject);
- if (!FSMUtil.isTransient(CDOObjectImpl.this))
- {
- view.handleRemoveAdapter(CDOObjectImpl.this, oldObject);
- }
- }
- }
- };
- }
-
- return eAdapters;
- }
-
- /**
- * @since 2.0
- */
- @Override
- public Resource.Internal eDirectResource()
- {
- if (FSMUtil.isTransient(this))
- {
- return super.eDirectResource();
- }
-
- return (Resource.Internal)cdoStore().getResource(this);
- }
-
- @Override
- public Resource.Internal eInternalResource()
- {
- if (FSMUtil.isInvalid(this))
- {
- return null;
- }
-
- return super.eInternalResource();
- }
-
- @Override
- public Object dynamicGet(int dynamicFeatureID)
- {
- Object result = eSettings[dynamicFeatureID];
- if (result == null)
- {
- EStructuralFeature eStructuralFeature = eDynamicFeature(dynamicFeatureID);
- if (EMFUtil.isPersistent(eStructuralFeature))
- {
- if (FeatureMapUtil.isFeatureMap(eStructuralFeature))
- {
- eSettings[dynamicFeatureID] = result = createFeatureMap(eStructuralFeature);
- }
- else if (eStructuralFeature.isMany())
- {
- eSettings[dynamicFeatureID] = result = createList(eStructuralFeature);
- }
- else
- {
- result = eStore().get(this, eStructuralFeature, EStore.NO_INDEX);
- if (eIsCaching())
- {
- eSettings[dynamicFeatureID] = result;
- }
- }
- }
- }
-
- return result;
- }
-
- @Override
- public void dynamicSet(int dynamicFeatureID, Object value)
- {
- EStructuralFeature eStructuralFeature = eDynamicFeature(dynamicFeatureID);
- if (!EMFUtil.isPersistent(eStructuralFeature))
- {
- eSettings[dynamicFeatureID] = value;
- }
- else
- {
- eStore().set(this, eStructuralFeature, EStore.NO_INDEX, value);
- if (eIsCaching())
- {
- eSettings[dynamicFeatureID] = value;
- }
- }
- }
-
- @Override
- public void dynamicUnset(int dynamicFeatureID)
- {
- EStructuralFeature eStructuralFeature = eDynamicFeature(dynamicFeatureID);
- if (!EMFUtil.isPersistent(eStructuralFeature))
- {
- eSettings[dynamicFeatureID] = null;
- }
- else
- {
- eStore().unset(this, eDynamicFeature(dynamicFeatureID));
- if (eIsCaching())
- {
- eSettings[dynamicFeatureID] = null;
- }
- }
- }
-
- /**
- * @since 2.0
- */
- @Override
- protected boolean eDynamicIsSet(int dynamicFeatureID, EStructuralFeature eFeature)
- {
- if (dynamicFeatureID < 0)
- {
- return eOpenIsSet(eFeature);
- }
-
- if (EMFUtil.isPersistent(eFeature))
- {
- return eStore().isSet(this, eFeature);
- }
-
- return eSettingDelegate(eFeature).dynamicIsSet(this, eSettings(), dynamicFeatureID);
- }
-
- /**
- * @since 2.0
- */
- @Override
- public EStore eStore()
- {
- if (FSMUtil.isTransient(this))
- {
- return CDOStoreSettingsImpl.INSTANCE;
- }
-
- return cdoStore();
- }
-
- @Override
- public InternalEObject eInternalContainer()
- {
- InternalEObject container;
- if (FSMUtil.isTransient(this))
- {
- container = eContainer;
- }
- else
- {
- // Delegate to CDOStore
- container = cdoStore().getContainer(this);
- }
-
- return container;
- }
-
- @Override
- public int eContainerFeatureID()
- {
- if (FSMUtil.isTransient(this))
- {
- return eContainerFeatureID;
- }
-
- // Delegate to CDOStore
- return cdoStore().getContainingFeatureID(this);
- }
-
- /**
- * Code took from {@link BasicEObjectImpl#eBasicSetContainer} and modify it to detect when object are moved in the
- * same context. (E.g.: An object is moved from resA to resB. resA and resB belongs to the same CDORepositoryInfo.
- * Without this special handling, a detach and newObject will be generated for the object moved)
- *
- * @since 2.0
- */
- @Override
- public NotificationChain eBasicSetContainer(InternalEObject newContainer, int newContainerFeatureID,
- NotificationChain msgs)
- {
- boolean isResourceRoot = this instanceof CDOResource && ((CDOResource)this).isRoot();
-
- InternalEObject oldContainer = eInternalContainer();
- Resource.Internal oldResource = eDirectResource();
- Resource.Internal newResource = null;
- if (oldResource != null)
- {
- if (newContainer != null && !eContainmentFeature(this, newContainer, newContainerFeatureID).isResolveProxies())
- {
- msgs = ((InternalEList<?>)oldResource.getContents()).basicRemove(this, msgs);
- eSetDirectResource(null);
- newResource = newContainer.eInternalResource();
- }
- else
- {
- oldResource = null;
- }
- }
- else
- {
- if (oldContainer != null)
- {
- oldResource = oldContainer.eInternalResource();
- }
-
- if (newContainer != null)
- {
- newResource = newContainer.eInternalResource();
- }
- }
-
- CDOView oldView = view;
- CDOView newView = newResource != null && newResource instanceof CDOResource ? ((CDOResource)newResource).cdoView()
- : null;
-
- boolean moved = oldView != null && oldView == newView;
- if (!moved && oldResource != null && !isResourceRoot)
- {
- oldResource.detached(this);
- }
-
- int oldContainerFeatureID = eContainerFeatureID();
- eBasicSetContainer(newContainer, newContainerFeatureID);
-
- if (!moved && oldResource != newResource && newResource != null)
- {
- newResource.attached(this);
- }
-
- if (eNotificationRequired())
- {
- if (oldContainer != null && oldContainerFeatureID >= 0 && oldContainerFeatureID != newContainerFeatureID)
- {
- ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, oldContainerFeatureID,
- oldContainer, null);
- if (msgs == null)
- {
- msgs = notification;
- }
- else
- {
- msgs.add(notification);
- }
- }
-
- if (newContainerFeatureID >= 0)
- {
- ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, newContainerFeatureID,
- oldContainerFeatureID == newContainerFeatureID ? oldContainer : null, newContainer);
- if (msgs == null)
- {
- msgs = notification;
- }
- else
- {
- msgs.add(notification);
- }
- }
- }
-
- return msgs;
- }
-
- /**
- * Code took from {@link BasicEObjectImpl#eSetResource} and modify it to detect when object are moved in the same
- * context.
- *
- * @since 2.0
- */
- @Override
- public NotificationChain eSetResource(Resource.Internal resource, NotificationChain notifications)
- {
- Resource.Internal oldResource = eDirectResource();
-
- CDOView oldView = view;
- CDOView newView = resource != null && resource instanceof CDOResource ? ((CDOResource)resource).cdoView() : null;
-
- boolean isSameView;
- if (state == CDOState.NEW)
- {
- isSameView = false;
- }
- else
- {
- isSameView = oldView != null && oldView == newView;
- }
-
- if (oldResource != null)
- {
- notifications = ((InternalEList<?>)oldResource.getContents()).basicRemove(this, notifications);
-
- // When setting the resource to null we assume that detach has already been called in the resource implementation
- if (!isSameView && resource != null)
- {
- oldResource.detached(this);
- }
- }
-
- InternalEObject oldContainer = eInternalContainer();
- if (oldContainer != null && !isSameView)
- {
- if (eContainmentFeature().isResolveProxies())
- {
- Resource.Internal oldContainerResource = oldContainer.eInternalResource();
- if (oldContainerResource != null)
- {
- // If we're not setting a new resource, attach it to the old container's resource.
- if (resource == null)
- {
- oldContainerResource.attached(this);
- }
-
- // If we didn't detach it from an old resource already, detach it from the old container's resource.
- //
- else if (oldResource == null)
- {
- oldContainerResource.detached(this);
- }
- }
- }
- else
- {
- notifications = eBasicRemoveFromContainer(notifications);
- notifications = eBasicSetContainer(null, -1, notifications);
- }
- }
-
- eSetDirectResource(resource);
-
- return notifications;
- }
-
- /**
- * Specializing the behaviour of {@link #hashCode()} is not permitted as per {@link EObject} specification.
- */
- @Override
- public final int hashCode()
- {
- return super.hashCode();
- }
-
- /**
- * Specializing the behaviour of {@link #equals(Object)} is not permitted as per {@link EObject} specification.
- */
- @Override
- public final boolean equals(Object obj)
- {
- return super.equals(obj);
- }
-
- @Override
- public String toString()
- {
- if (id == null)
- {
- return eClass().getName() + "?"; //$NON-NLS-1$
- }
-
- return eClass().getName() + "@" + id; //$NON-NLS-1$
- }
-
- /**
- * @since 2.0
- */
- protected Object[] cdoSettings()
- {
- if (cdoSettings == null)
- {
- int size = eClass().getFeatureCount() - eStaticFeatureCount();
- if (size == 0)
- {
- cdoSettings = ENO_SETTINGS;
- }
- else
- {
- cdoSettings = new Object[size];
- }
- }
-
- return cdoSettings;
- }
-
- /**
- * @since 2.0
- */
- protected Object[] cdoBasicSettings()
- {
- return cdoSettings;
- }
-
- @Override
- protected FeatureMap createFeatureMap(EStructuralFeature eStructuralFeature)
- {
- return new CDOStoreFeatureMap(eStructuralFeature);
- }
-
- /**
- * @since 4.1
- */
- protected CDOStoreEcoreEMap createMap(EStructuralFeature eStructuralFeature)
- {
- return new CDOStoreEcoreEMap(eStructuralFeature);
- }
-
- /**
- * @since 4.1
- */
- protected CDOStoreUnorderedEList<Object> createUnorderedList(EStructuralFeature eStructuralFeature)
- {
- return new CDOStoreUnorderedEList<Object>(eStructuralFeature);
- }
-
- @Override
- protected EList<?> createList(EStructuralFeature eStructuralFeature)
- {
- if (isMap(eStructuralFeature))
- {
- return createMap(eStructuralFeature);
- }
-
- if (!eStructuralFeature.isOrdered())
- {
- return createUnorderedList(eStructuralFeature);
- }
-
- return super.createList(eStructuralFeature);
- }
-
- private boolean isMap(EStructuralFeature eStructuralFeature)
- {
- // Answer from Christian Damus:
- // Java ensures that string constants are interned, so this is actually
- // more efficient than .equals() and it's correct
- return eStructuralFeature.getEType().getInstanceClassName() == "java.util.Map$Entry"; //$NON-NLS-1$
- }
-
- @Override
- protected void eInitializeContainer()
- {
- throw new UnsupportedOperationException();
- }
-
- @Override
- protected void eSetDirectResource(Internal resource)
- {
- if (FSMUtil.isTransient(this))
- {
- super.eSetDirectResource(resource);
- }
- else if (resource instanceof CDOResourceImpl || resource == null)
- {
- cdoStore().setContainer(this, (CDOResourceImpl)resource, eInternalContainer(), eContainerFeatureID());
- }
- else
- {
- throw new IllegalArgumentException(Messages.getString("CDOObjectImpl.8")); //$NON-NLS-1$
- }
- }
-
- /**
- * Don't cache non-transient features in this CDOObject's {@link #eSettings()}.
- */
- @Override
- protected boolean eIsCaching()
- {
- return false;
- }
-
- @Override
- protected void eBasicSetContainer(InternalEObject newEContainer, int newContainerFeatureID)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Setting container: {0}, featureID={1}", newEContainer, newContainerFeatureID); //$NON-NLS-1$
- }
-
- if (FSMUtil.isTransient(this))
- {
- super.eBasicSetContainer(newEContainer, newContainerFeatureID);
- }
- else
- {
- cdoStore().setContainer(this, cdoDirectResource(), newEContainer, newContainerFeatureID);
- }
- }
-
- private CDOStore cdoStore()
- {
- return view.getStore();
- }
-
- private void resetSettings()
- {
- cdoSettings = null;
- cdoSettings();
- }
-
- /**
- * Adjust the reference ONLY if the opposite reference used CDOID. This is true ONLY if the state of <cdo>this</code>
- * was not {@link CDOState#NEW}.
- */
- private static void adjustOppositeReference(InternalCDOObject instance, InternalEObject object, EReference feature)
- {
- if (object != null)
- {
- InternalCDOObject cdoObject = (InternalCDOObject)CDOUtil.getCDOObject(object);
- if (cdoObject != null && !FSMUtil.isTransient(cdoObject))
- {
- if (feature.isMany())
- {
- int index = cdoObject.eStore().indexOf(cdoObject, feature, instance.cdoID());
-
- // TODO Simon Log an error in the new view.getErrors() in the case we are not able to find the object.
- // Cannot throw an exception, the detach process is too far.
- if (index != -1)
- {
- cdoObject.eStore().set(cdoObject, feature, index, instance);
- }
- }
- else
- {
- cdoObject.eStore().set(cdoObject, feature, 0, instance);
- }
- }
- else
- {
- if (feature.isResolveProxies())
- {
- // We should not trigger events. But we have no choice :-(.
- if (feature.isMany())
- {
- @SuppressWarnings("unchecked")
- InternalEList<Object> list = (InternalEList<Object>)object.eGet(feature);
- int index = list.indexOf(instance);
- if (index != -1)
- {
- list.set(index, instance);
- }
- }
- else
- {
- object.eSet(feature, instance);
- }
- }
- }
- }
- }
-
- /**
- * @since 2.0
- */
- public static void revisionToInstanceFeature(InternalCDOObject instance, InternalCDORevision revision,
- EStructuralFeature eFeature)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Depopulating feature {0}", eFeature); //$NON-NLS-1$
- }
-
- EStructuralFeature.Internal internalFeature = (EStructuralFeature.Internal)eFeature;
- InternalCDOView view = instance.cdoView();
- EReference oppositeReference = view.isObjectNew(instance.cdoID()) ? null : internalFeature.getEOpposite();
-
- CDOStore cdoStore = view.getStore();
- EStore eStore = instance.eStore();
-
- if (eFeature.isMany())
- {
- int size = cdoStore.size(instance, eFeature);
- for (int index = 0; index < size; index++)
- {
- // Do not trigger events
- // Do not trigger inverse updates
- Object object = cdoStore.get(instance, eFeature, index);
- eStore.add(instance, eFeature, index, object);
- if (oppositeReference != null)
- {
- adjustOppositeReference(instance, (InternalEObject)object, oppositeReference);
- }
- }
- }
- else
- {
- Object object = cdoStore.get(instance, eFeature, EStore.NO_INDEX);
- eStore.set(instance, eFeature, EStore.NO_INDEX, object);
- if (oppositeReference != null)
- {
- adjustOppositeReference(instance, (InternalEObject)object, oppositeReference);
- }
- }
- }
-
- /**
- * @since 3.0
- */
- public static void instanceToRevisionFeature(InternalCDOView view, InternalCDOObject object,
- EStructuralFeature feature, Object setting)
- {
- if (TRACER.isEnabled())
- {
- TRACER.format("Populating feature {0}", feature); //$NON-NLS-1$
- }
-
- CDOStore cdoStore = view.getStore();
- InternalCDORevision revision = object.cdoRevision();
-
- if (feature.isMany())
- {
- if (setting != null)
- {
- int index = 0;
- @SuppressWarnings("unchecked")
- EList<Object> list = (EList<Object>)setting;
- for (Object value : list)
- {
- value = cdoStore.convertToCDO(object, feature, value);
- revision.add(feature, index++, value);
- }
- }
- }
- else
- {
- setting = cdoStore.convertToCDO(object, feature, setting);
- revision.set(feature, 0, setting);
- }
- }
-
- /**
- * @since 4.1
- */
- public static CDOLock createLock(InternalCDOObject object, LockType type)
- {
- if (FSMUtil.isTransient(object))
- {
- throw new IllegalStateException("Call CDOView.lockObjects() for transient object " + object);
- }
-
- return new CDOLockImpl(object, type);
- }
-
- /**
- * @since 4.1
- */
- public static CDOLockState getLockState(InternalCDOObject object)
- {
- if (!FSMUtil.isTransient(object))
- {
- InternalCDOView view = object.cdoView();
- CDOID id = object.cdoID();
-
- return view.getLockStates(Collections.singletonList(id))[0];
- }
-
- return null;
- }
-
- /**
- * For internal use only.
- *
- * @author Simon McDuff
- * @since 2.0
- */
- public static class CDOStoreSettingsImpl implements InternalEObject.EStore
- {
- public static CDOStoreSettingsImpl INSTANCE = new CDOStoreSettingsImpl();
-
- private CDOStoreSettingsImpl()
- {
- }
-
- protected Object getValue(InternalEObject eObject, int dynamicFeatureID)
- {
- Object value = ((CDOObjectImpl)eObject).cdoSettings()[dynamicFeatureID];
- return value;
- }
-
- protected EList<Object> getValueAsList(InternalEObject eObject, int dynamicFeatureID)
- {
- @SuppressWarnings("unchecked")
- EList<Object> result = (EList<Object>)getValue(eObject, dynamicFeatureID);
- if (result == null)
- {
- result = new BasicEList<Object>();
- ((CDOObjectImpl)eObject).cdoSettings()[dynamicFeatureID] = result;
- }
-
- return result;
- }
-
- protected Object setValue(InternalEObject eObject, int dynamicFeatureID, Object newValue)
- {
- Object settings[] = ((CDOObjectImpl)eObject).cdoSettings();
- Object oldSetting = settings[dynamicFeatureID];
- settings[dynamicFeatureID] = newValue;
- return oldSetting;
- }
-
- protected int eDynamicFeatureID(InternalEObject eObject, EStructuralFeature feature)
- {
- return ((CDOObjectImpl)eObject).eDynamicFeatureID(feature);
- }
-
- public Object get(InternalEObject eObject, EStructuralFeature feature, int index)
- {
- int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
- if (index != NO_INDEX)
- {
- return getValueAsList(eObject, dynamicFeatureID).get(index);
- }
-
- return getValue(eObject, dynamicFeatureID);
- }
-
- public Object set(InternalEObject eObject, EStructuralFeature feature, int index, Object value)
- {
- int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
- if (index != NO_INDEX)
- {
- return getValueAsList(eObject, dynamicFeatureID).set(index, value);
- }
-
- return setValue(eObject, dynamicFeatureID, value);
- }
-
- public void add(InternalEObject eObject, EStructuralFeature feature, int index, Object value)
- {
- int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
- getValueAsList(eObject, dynamicFeatureID).add(index, value);
- }
-
- public Object remove(InternalEObject eObject, EStructuralFeature feature, int index)
- {
- int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
- return getValueAsList(eObject, dynamicFeatureID).remove(index);
- }
-
- public Object move(InternalEObject eObject, EStructuralFeature feature, int targetIndex, int sourceIndex)
- {
- int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
- return getValueAsList(eObject, dynamicFeatureID).move(targetIndex, sourceIndex);
- }
-
- public void clear(InternalEObject eObject, EStructuralFeature feature)
- {
- int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
- if (feature.isMany())
- {
- getValueAsList(eObject, dynamicFeatureID).clear();
- }
-
- setValue(eObject, dynamicFeatureID, null);
- }
-
- public int size(InternalEObject eObject, EStructuralFeature feature)
- {
- int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
- return getValueAsList(eObject, dynamicFeatureID).size();
- }
-
- public int indexOf(InternalEObject eObject, EStructuralFeature feature, Object value)
- {
- int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
- return getValueAsList(eObject, dynamicFeatureID).indexOf(value);
- }
-
- public int lastIndexOf(InternalEObject eObject, EStructuralFeature feature, Object value)
- {
- int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
- return getValueAsList(eObject, dynamicFeatureID).lastIndexOf(value);
- }
-
- public Object[] toArray(InternalEObject eObject, EStructuralFeature feature)
- {
- int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
- return getValueAsList(eObject, dynamicFeatureID).toArray();
- }
-
- public <T> T[] toArray(InternalEObject eObject, EStructuralFeature feature, T[] array)
- {
- int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
- return getValueAsList(eObject, dynamicFeatureID).toArray(array);
- }
-
- public boolean isEmpty(InternalEObject eObject, EStructuralFeature feature)
- {
- int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
- return getValueAsList(eObject, dynamicFeatureID).isEmpty();
- }
-
- public boolean contains(InternalEObject eObject, EStructuralFeature feature, Object value)
- {
- int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
- return getValueAsList(eObject, dynamicFeatureID).contains(value);
- }
-
- public int hashCode(InternalEObject eObject, EStructuralFeature feature)
- {
- int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
- return getValueAsList(eObject, dynamicFeatureID).hashCode();
- }
-
- public InternalEObject getContainer(InternalEObject eObject)
- {
- return null;
- }
-
- public EStructuralFeature getContainingFeature(InternalEObject eObject)
- {
- throw new UnsupportedOperationException("Should never be called");
- }
-
- public EObject create(EClass eClass)
- {
- return new EStoreEObjectImpl(eClass, this);
- }
-
- public boolean isSet(InternalEObject eObject, EStructuralFeature feature)
- {
- if (!feature.isUnsettable())
- {
- if (feature.isMany())
- {
- @SuppressWarnings("unchecked")
- InternalEList<Object> list = (InternalEList<Object>)eObject.eGet(feature);
- return list != null && !list.isEmpty();
- }
-
- return !ObjectUtil.equals(eObject.eGet(feature), feature.getDefaultValue());
- }
-
- Object[] settings = ((CDOObjectImpl)eObject).cdoBasicSettings();
- if (settings == null)
- {
- return false;
- }
-
- int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
- return settings[dynamicFeatureID] != null;
- }
-
- public void unset(InternalEObject eObject, EStructuralFeature feature)
- {
- Object[] settings = ((CDOObjectImpl)eObject).cdoBasicSettings();
- if (settings == null)
- {
- // Is already unset
- return;
- }
-
- int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
- if (feature.isUnsettable())
- {
- settings[dynamicFeatureID] = null;
- }
- else
- {
- settings[dynamicFeatureID] = feature.getDefaultValue();
- }
- }
- }
-
- /**
- * @author Eike Stepper
- * @since 4.1
- */
- public class CDOStoreEcoreEMap extends EcoreEMap<Object, Object> implements InternalCDOLoadable
- {
- private static final long serialVersionUID = 1L;
-
- public CDOStoreEcoreEMap(EStructuralFeature eStructuralFeature)
- {
- super((EClass)eStructuralFeature.getEType(), BasicEMap.Entry.class, null);
- delegateEList = new BasicEStoreEList<BasicEMap.Entry<Object, Object>>(CDOObjectImpl.this, eStructuralFeature)
- {
- private static final long serialVersionUID = 1L;
-
- @Override
- public void unset()
- {
- super.unset();
- doClear();
- }
-
- @Override
- protected void didAdd(int index, BasicEMap.Entry<Object, Object> newObject)
- {
- CDOStoreEcoreEMap.this.doPut(newObject);
- }
-
- @Override
- protected void didSet(int index, BasicEMap.Entry<Object, Object> newObject,
- BasicEMap.Entry<Object, Object> oldObject)
- {
- didRemove(index, oldObject);
- didAdd(index, newObject);
- }
-
- @Override
- protected void didRemove(int index, BasicEMap.Entry<Object, Object> oldObject)
- {
- CDOStoreEcoreEMap.this.doRemove(oldObject);
- }
-
- @Override
- protected void didClear(int size, Object[] oldObjects)
- {
- CDOStoreEcoreEMap.this.doClear();
- }
-
- @Override
- protected void didMove(int index, BasicEMap.Entry<Object, Object> movedObject, int oldIndex)
- {
- CDOStoreEcoreEMap.this.doMove(movedObject);
- }
- };
-
- size = delegateEList.size();
- }
-
- private void checkListForReading()
- {
- if (!FSMUtil.isTransient(CDOObjectImpl.this))
- {
- CDOStateMachine.INSTANCE.read(CDOObjectImpl.this);
- }
- }
-
- /**
- * Ensures that the entry data is created and is populated with contents of the delegate list.
- */
- @Override
- protected synchronized void ensureEntryDataExists()
- {
- checkListForReading();
- super.ensureEntryDataExists();
- }
-
- @Override
- public int size()
- {
- checkListForReading();
- return size;
- }
-
- @Override
- public boolean isEmpty()
- {
- checkListForReading();
- return size == 0;
- }
-
- @Override
- public boolean contains(Object object)
- {
- checkListForReading();
- return super.contains(object);
- }
-
- @Override
- public boolean containsAll(Collection<?> collection)
- {
- checkListForReading();
- return super.containsAll(collection);
- }
-
- @Override
- public boolean containsKey(Object key)
- {
- checkListForReading();
- return super.containsKey(key);
- }
-
- @Override
- public boolean containsValue(Object value)
- {
- checkListForReading();
- return super.containsValue(value);
- }
-
- public void cdoInternalPostLoad()
- {
- entryData = null;
- size = delegateEList.size();
- }
-
- public void cdoInternalPreLoad()
- {
- }
- }
-
- /**
- * @author Andras Peteri
- * @since 4.1
- */
- public class CDOStoreUnorderedEList<E> extends BasicEStoreEList<E>
- {
- private static final long serialVersionUID = 1L;
-
- public CDOStoreUnorderedEList(EStructuralFeature feature)
- {
- super(CDOObjectImpl.this, feature);
- }
-
- @Override
- public E remove(int index)
- {
- boolean oldObjectIsLast = index == size() - 1;
- E oldObject = super.remove(index);
-
- if (!oldObjectIsLast)
- {
- move(index, size() - 1);
- }
-
- return oldObject;
- }
- }
-
- /**
- * TODO Remove this when EMF has fixed bug 197487
- *
- * @author Eike Stepper
- */
- public class CDOStoreFeatureMap extends DelegatingFeatureMap
- {
- private static final long serialVersionUID = 1L;
-
- public CDOStoreFeatureMap(EStructuralFeature eStructuralFeature)
- {
- super(CDOObjectImpl.this, eStructuralFeature);
- }
-
- @Override
- protected List<FeatureMap.Entry> delegateList()
- {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public EStructuralFeature getEStructuralFeature()
- {
- return eStructuralFeature;
- }
-
- @Override
- protected void delegateAdd(int index, Entry object)
- {
- eStore().add(owner, eStructuralFeature, index, object);
- }
-
- @Override
- protected void delegateAdd(Entry object)
- {
- delegateAdd(delegateSize(), object);
- }
-
- @Override
- protected List<FeatureMap.Entry> delegateBasicList()
- {
- int size = delegateSize();
- if (size == 0)
- {
- return ECollections.emptyEList();
- }
-
- Object[] data = cdoStore().toArray(owner, eStructuralFeature);
- return new EcoreEList.UnmodifiableEList<FeatureMap.Entry>(owner, eStructuralFeature, data.length, data);
- }
-
- @Override
- protected void delegateClear()
- {
- eStore().clear(owner, eStructuralFeature);
- }
-
- @Override
- protected boolean delegateContains(Object object)
- {
- return eStore().contains(owner, eStructuralFeature, object);
- }
-
- @Override
- protected boolean delegateContainsAll(Collection<?> collection)
- {
- for (Object o : collection)
- {
- if (!delegateContains(o))
- {
- return false;
- }
- }
-
- return true;
- }
-
- @Override
- protected Entry delegateGet(int index)
- {
- return (Entry)eStore().get(owner, eStructuralFeature, index);
- }
-
- @Override
- protected int delegateHashCode()
- {
- return eStore().hashCode(owner, eStructuralFeature);
- }
-
- @Override
- protected int delegateIndexOf(Object object)
- {
- return eStore().indexOf(owner, eStructuralFeature, object);
- }
-
- @Override
- protected boolean delegateIsEmpty()
- {
- return eStore().isEmpty(owner, eStructuralFeature);
- }
-
- @Override
- protected Iterator<FeatureMap.Entry> delegateIterator()
- {
- return iterator();
- }
-
- @Override
- protected int delegateLastIndexOf(Object object)
- {
- return eStore().lastIndexOf(owner, eStructuralFeature, object);
- }
-
- @Override
- protected ListIterator<FeatureMap.Entry> delegateListIterator()
- {
- return listIterator();
- }
-
- @Override
- protected Entry delegateRemove(int index)
- {
- return (Entry)eStore().remove(owner, eStructuralFeature, index);
- }
-
- @Override
- protected Entry delegateSet(int index, Entry object)
- {
- return (Entry)eStore().set(owner, eStructuralFeature, index, object);
- }
-
- @Override
- protected int delegateSize()
- {
- return eStore().size(owner, eStructuralFeature);
- }
-
- @Override
- protected Object[] delegateToArray()
- {
- return eStore().toArray(owner, eStructuralFeature);
- }
-
- @Override
- protected <T> T[] delegateToArray(T[] array)
- {
- return eStore().toArray(owner, eStructuralFeature, array);
- }
-
- @Override
- protected Entry delegateMove(int targetIndex, int sourceIndex)
- {
- return (Entry)eStore().move(owner, eStructuralFeature, targetIndex, sourceIndex);
- }
-
- @Override
- protected String delegateToString()
- {
- StringBuffer stringBuffer = new StringBuffer();
- stringBuffer.append("["); //$NON-NLS-1$
- for (int i = 0, size = size(); i < size;)
- {
- Object value = delegateGet(i);
- stringBuffer.append(String.valueOf(value));
- if (++i < size)
- {
- stringBuffer.append(", "); //$NON-NLS-1$
- }
- }
-
- stringBuffer.append("]"); //$NON-NLS-1$
- return stringBuffer.toString();
- }
- }
-}
+/*
+ * Copyright (c) 2004 - 2012 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
+ * Simon McDuff - maintenance
+ */
+package org.eclipse.emf.internal.cdo;
+
+import org.eclipse.emf.cdo.CDOLock;
+import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.CDOState;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.lock.CDOLockState;
+import org.eclipse.emf.cdo.common.model.EMFUtil;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.util.CDOUtil;
+import org.eclipse.emf.cdo.view.CDOView;
+
+import org.eclipse.emf.internal.cdo.bundle.OM;
+import org.eclipse.emf.internal.cdo.messages.Messages;
+import org.eclipse.emf.internal.cdo.object.CDOLockImpl;
+import org.eclipse.emf.internal.cdo.view.CDOStateMachine;
+
+import org.eclipse.net4j.util.ObjectUtil;
+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.NotificationChain;
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.BasicEMap;
+import org.eclipse.emf.common.util.ECollections;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.impl.BasicEObjectImpl;
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
+import org.eclipse.emf.ecore.impl.EStoreEObjectImpl;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.Resource.Internal;
+import org.eclipse.emf.ecore.util.DelegatingFeatureMap;
+import org.eclipse.emf.ecore.util.EcoreEList;
+import org.eclipse.emf.ecore.util.EcoreEMap;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.ecore.util.FeatureMapUtil;
+import org.eclipse.emf.ecore.util.InternalEList;
+import org.eclipse.emf.spi.cdo.CDOStore;
+import org.eclipse.emf.spi.cdo.FSMUtil;
+import org.eclipse.emf.spi.cdo.InternalCDOLoadable;
+import org.eclipse.emf.spi.cdo.InternalCDOObject;
+import org.eclipse.emf.spi.cdo.InternalCDOView;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * The base class of all <em>native</em> {@link CDOObject objects}.
+ *
+ * @author Eike Stepper
+ */
+public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObject
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_OBJECT, CDOObjectImpl.class);
+
+ private CDOID id;
+
+ private CDOState state;
+
+ private InternalCDOView view;
+
+ private InternalCDORevision revision;
+
+ /**
+ * CDO uses this list instead of eSettings for transient objects. EMF uses eSettings as cache. CDO deactivates the
+ * cache but EMF still used eSettings to store list wrappers. CDO needs another place to store the real list with the
+ * actual data (transient mode) and accessible through EStore. This allows CDO to always use the same instance of the
+ * list wrapper.
+ */
+ private transient Object[] cdoSettings;
+
+ public CDOObjectImpl()
+ {
+ state = CDOState.TRANSIENT;
+ eContainer = null;
+ cdoSettings = null;
+ }
+
+ public CDOID cdoID()
+ {
+ return id;
+ }
+
+ public CDOState cdoState()
+ {
+ return state;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public InternalCDORevision cdoRevision()
+ {
+ return revision;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public InternalCDOView cdoView()
+ {
+ return view;
+ }
+
+ public CDOResourceImpl cdoResource()
+ {
+ Resource resource = eResource();
+ if (resource instanceof CDOResourceImpl)
+ {
+ return (CDOResourceImpl)resource;
+ }
+
+ return null;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public CDOResourceImpl cdoDirectResource()
+ {
+ Resource.Internal resource = eDirectResource();
+ if (resource instanceof CDOResourceImpl)
+ {
+ return (CDOResourceImpl)resource;
+ }
+
+ return null;
+ }
+
+ /**
+ * @since 3.0
+ */
+ public void cdoPrefetch(int depth)
+ {
+ view.prefetchRevisions(id, depth);
+ }
+
+ public void cdoReload()
+ {
+ CDOStateMachine.INSTANCE.reload(this);
+ }
+
+ /**
+ * @since 2.0
+ */
+ public boolean cdoConflict()
+ {
+ return FSMUtil.isConflict(this);
+ }
+
+ /**
+ * @since 2.0
+ */
+ public boolean cdoInvalid()
+ {
+ return FSMUtil.isInvalid(this);
+ }
+
+ /**
+ * @since 2.0
+ */
+ public CDOLock cdoReadLock()
+ {
+ return createLock(this, LockType.READ);
+ }
+
+ /**
+ * @since 2.0
+ */
+ public CDOLock cdoWriteLock()
+ {
+ return createLock(this, LockType.WRITE);
+ }
+
+ /**
+ * @since 4.1
+ */
+ public CDOLock cdoWriteOption()
+ {
+ return createLock(this, LockType.OPTION);
+ }
+
+ /**
+ * @since 4.1
+ */
+ public CDOLockState cdoLockState()
+ {
+ return getLockState(this);
+ }
+
+ public void cdoInternalSetID(CDOID id)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Setting ID: {0}", id); //$NON-NLS-1$
+ }
+
+ this.id = id;
+ }
+
+ public CDOState cdoInternalSetState(CDOState state)
+ {
+ CDOState oldState = this.state;
+ if (oldState != state)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Setting state {0} for {1}", state, this); //$NON-NLS-1$
+ }
+
+ this.state = state;
+ if (view != null)
+ {
+ view.handleObjectStateChanged(this, oldState, state);
+ }
+
+ return oldState;
+ }
+
+ return null;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void cdoInternalSetRevision(CDORevision revision)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Setting revision: {0}", revision); //$NON-NLS-1$
+ }
+
+ this.revision = (InternalCDORevision)revision;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void cdoInternalSetView(CDOView view)
+ {
+ this.view = (InternalCDOView)view;
+ if (this.view != null)
+ {
+ eSetStore(this.view.getStore());
+ }
+ else
+ {
+ eSetStore(null);
+ }
+ }
+
+ public void cdoInternalSetResource(CDOResource resource)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void cdoInternalPreLoad()
+ {
+ // Do nothing
+ }
+
+ public void cdoInternalPostLoad()
+ {
+ // Reset EMAP objects
+ if (eSettings != null)
+ {
+ // Make sure transient features are kept but persisted values are not cached.
+ EClass eClass = eClass();
+ for (int i = 0; i < eClass.getFeatureCount(); i++)
+ {
+ EStructuralFeature eFeature = cdoInternalDynamicFeature(i);
+
+ // We need to keep the existing list if possible.
+ if (EMFUtil.isPersistent(eFeature) && eSettings[i] instanceof InternalCDOLoadable)
+ {
+ ((InternalCDOLoadable)eSettings[i]).cdoInternalPostLoad();
+ }
+ }
+ }
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void cdoInternalPostInvalidate()
+ {
+ // Do nothing
+ }
+
+ public void cdoInternalPostAttach()
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Populating revision for {0}", this); //$NON-NLS-1$
+ }
+
+ revision.setContainerID(eContainer == null ? CDOID.NULL : view.convertObjectToID(eContainer, true));
+ revision.setContainingFeatureID(eContainerFeatureID);
+
+ Resource directResource = eDirectResource();
+ if (directResource instanceof CDOResource)
+ {
+ CDOResource cdoResource = (CDOResource)directResource;
+ revision.setResourceID(cdoResource.cdoID());
+ }
+
+ if (cdoSettings != null)
+ {
+ EClass eClass = eClass();
+ for (int i = 0; i < eClass.getFeatureCount(); i++)
+ {
+ EStructuralFeature eFeature = cdoInternalDynamicFeature(i);
+ if (EMFUtil.isPersistent(eFeature))
+ {
+ instanceToRevisionFeature(view, this, eFeature, cdoSettings[i]);
+ }
+ }
+
+ cdoRevision().setUnchunked();
+ cdoSettings = null;
+ }
+ }
+
+ /**
+ * It is really important for accessing the data to go through {@link #cdoStore()}. {@link #eStore()} will redirect
+ * you to the transient data.
+ *
+ * @since 2.0
+ */
+ public void cdoInternalPostDetach(boolean remote)
+ {
+ if (remote)
+ {
+ // Do nothing
+ return;
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Depopulating revision for {0}", this); //$NON-NLS-1$
+ }
+
+ CDOStore store = cdoStore();
+ super.eSetDirectResource((Resource.Internal)store.getResource(this));
+ eContainer = store.getContainer(this);
+ eContainerFeatureID = store.getContainingFeatureID(this);
+
+ // Ensure that the internal eSettings array is initialized;
+ resetSettings();
+
+ EClass eClass = eClass();
+ for (int i = 0; i < eClass.getFeatureCount(); i++)
+ {
+ EStructuralFeature eFeature = cdoInternalDynamicFeature(i);
+ if (EMFUtil.isPersistent(eFeature))
+ {
+ revisionToInstanceFeature(this, revision, eFeature);
+ }
+ }
+ }
+
+ /**
+ * @since 3.0
+ */
+ public void cdoInternalPostRollback()
+ {
+ // Do nothing
+ }
+
+ public void cdoInternalPreCommit()
+ {
+ // Do nothing
+ }
+
+ public InternalEObject cdoInternalInstance()
+ {
+ return this;
+ }
+
+ public EStructuralFeature cdoInternalDynamicFeature(int dynamicFeatureID)
+ {
+ return eDynamicFeature(dynamicFeatureID);
+ }
+
+ /**
+ * @since 2.0
+ */
+ @Override
+ public synchronized EList<Adapter> eAdapters()
+ {
+ if (eAdapters == null)
+ {
+ // TODO Adjust for EObjectEAdapterList (see bug #247130)
+ eAdapters = new EAdapterList<Adapter>(this)
+ {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected void didAdd(int index, Adapter newObject)
+ {
+ if (view == null || view.isActive())
+ {
+ super.didAdd(index, newObject);
+ if (!FSMUtil.isTransient(CDOObjectImpl.this))
+ {
+ view.handleAddAdapter(CDOObjectImpl.this, newObject);
+ }
+ }
+ }
+
+ @Override
+ protected void didRemove(int index, Adapter oldObject)
+ {
+ if (view == null || view.isActive())
+ {
+ super.didRemove(index, oldObject);
+ if (!FSMUtil.isTransient(CDOObjectImpl.this))
+ {
+ view.handleRemoveAdapter(CDOObjectImpl.this, oldObject);
+ }
+ }
+ }
+ };
+ }
+
+ return eAdapters;
+ }
+
+ /**
+ * @since 2.0
+ */
+ @Override
+ public Resource.Internal eDirectResource()
+ {
+ if (FSMUtil.isTransient(this))
+ {
+ return super.eDirectResource();
+ }
+
+ return (Resource.Internal)cdoStore().getResource(this);
+ }
+
+ @Override
+ public Resource.Internal eInternalResource()
+ {
+ if (FSMUtil.isInvalid(this))
+ {
+ return null;
+ }
+
+ return super.eInternalResource();
+ }
+
+ @Override
+ public Object dynamicGet(int dynamicFeatureID)
+ {
+ Object result = eSettings[dynamicFeatureID];
+ if (result == null)
+ {
+ EStructuralFeature eStructuralFeature = eDynamicFeature(dynamicFeatureID);
+ if (EMFUtil.isPersistent(eStructuralFeature))
+ {
+ if (FeatureMapUtil.isFeatureMap(eStructuralFeature))
+ {
+ eSettings[dynamicFeatureID] = result = createFeatureMap(eStructuralFeature);
+ }
+ else if (eStructuralFeature.isMany())
+ {
+ eSettings[dynamicFeatureID] = result = createList(eStructuralFeature);
+ }
+ else
+ {
+ result = eStore().get(this, eStructuralFeature, EStore.NO_INDEX);
+ if (eIsCaching())
+ {
+ eSettings[dynamicFeatureID] = result;
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public void dynamicSet(int dynamicFeatureID, Object value)
+ {
+ EStructuralFeature eStructuralFeature = eDynamicFeature(dynamicFeatureID);
+ if (!EMFUtil.isPersistent(eStructuralFeature))
+ {
+ eSettings[dynamicFeatureID] = value;
+ }
+ else
+ {
+ eStore().set(this, eStructuralFeature, EStore.NO_INDEX, value);
+ if (eIsCaching())
+ {
+ eSettings[dynamicFeatureID] = value;
+ }
+ }
+ }
+
+ @Override
+ public void dynamicUnset(int dynamicFeatureID)
+ {
+ EStructuralFeature eStructuralFeature = eDynamicFeature(dynamicFeatureID);
+ if (!EMFUtil.isPersistent(eStructuralFeature))
+ {
+ eSettings[dynamicFeatureID] = null;
+ }
+ else
+ {
+ eStore().unset(this, eDynamicFeature(dynamicFeatureID));
+ if (eIsCaching())
+ {
+ eSettings[dynamicFeatureID] = null;
+ }
+ }
+ }
+
+ /**
+ * @since 2.0
+ */
+ @Override
+ protected boolean eDynamicIsSet(int dynamicFeatureID, EStructuralFeature eFeature)
+ {
+ if (dynamicFeatureID < 0)
+ {
+ return eOpenIsSet(eFeature);
+ }
+
+ if (EMFUtil.isPersistent(eFeature))
+ {
+ return eStore().isSet(this, eFeature);
+ }
+
+ return eSettingDelegate(eFeature).dynamicIsSet(this, eSettings(), dynamicFeatureID);
+ }
+
+ /**
+ * @since 2.0
+ */
+ @Override
+ public EStore eStore()
+ {
+ if (FSMUtil.isTransient(this))
+ {
+ return CDOStoreSettingsImpl.INSTANCE;
+ }
+
+ return cdoStore();
+ }
+
+ @Override
+ public InternalEObject eInternalContainer()
+ {
+ InternalEObject container;
+ if (FSMUtil.isTransient(this))
+ {
+ container = eContainer;
+ }
+ else
+ {
+ // Delegate to CDOStore
+ container = cdoStore().getContainer(this);
+ }
+
+ return container;
+ }
+
+ @Override
+ public int eContainerFeatureID()
+ {
+ if (FSMUtil.isTransient(this))
+ {
+ return eContainerFeatureID;
+ }
+
+ // Delegate to CDOStore
+ return cdoStore().getContainingFeatureID(this);
+ }
+
+ /**
+ * Code took from {@link BasicEObjectImpl#eBasicSetContainer} and modify it to detect when object are moved in the
+ * same context. (E.g.: An object is moved from resA to resB. resA and resB belongs to the same CDORepositoryInfo.
+ * Without this special handling, a detach and newObject will be generated for the object moved)
+ *
+ * @since 2.0
+ */
+ @Override
+ public NotificationChain eBasicSetContainer(InternalEObject newContainer, int newContainerFeatureID,
+ NotificationChain msgs)
+ {
+ boolean isResourceRoot = this instanceof CDOResource && ((CDOResource)this).isRoot();
+
+ InternalEObject oldContainer = eInternalContainer();
+ Resource.Internal oldResource = eDirectResource();
+ Resource.Internal newResource = null;
+ if (oldResource != null)
+ {
+ if (newContainer != null && !eContainmentFeature(this, newContainer, newContainerFeatureID).isResolveProxies())
+ {
+ msgs = ((InternalEList<?>)oldResource.getContents()).basicRemove(this, msgs);
+ eSetDirectResource(null);
+ newResource = newContainer.eInternalResource();
+ }
+ else
+ {
+ oldResource = null;
+ }
+ }
+ else
+ {
+ if (oldContainer != null)
+ {
+ oldResource = oldContainer.eInternalResource();
+ }
+
+ if (newContainer != null)
+ {
+ newResource = newContainer.eInternalResource();
+ }
+ }
+
+ CDOView oldView = view;
+ CDOView newView = newResource != null && newResource instanceof CDOResource ? ((CDOResource)newResource).cdoView()
+ : null;
+
+ boolean moved = oldView != null && oldView == newView;
+ if (!moved && oldResource != null && !isResourceRoot)
+ {
+ oldResource.detached(this);
+ }
+
+ int oldContainerFeatureID = eContainerFeatureID();
+ eBasicSetContainer(newContainer, newContainerFeatureID);
+
+ if (!moved && oldResource != newResource && newResource != null)
+ {
+ newResource.attached(this);
+ }
+
+ if (eNotificationRequired())
+ {
+ if (oldContainer != null && oldContainerFeatureID >= 0 && oldContainerFeatureID != newContainerFeatureID)
+ {
+ ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, oldContainerFeatureID,
+ oldContainer, null);
+ if (msgs == null)
+ {
+ msgs = notification;
+ }
+ else
+ {
+ msgs.add(notification);
+ }
+ }
+
+ if (newContainerFeatureID >= 0)
+ {
+ ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, newContainerFeatureID,
+ oldContainerFeatureID == newContainerFeatureID ? oldContainer : null, newContainer);
+ if (msgs == null)
+ {
+ msgs = notification;
+ }
+ else
+ {
+ msgs.add(notification);
+ }
+ }
+ }
+
+ return msgs;
+ }
+
+ /**
+ * Code took from {@link BasicEObjectImpl#eSetResource} and modify it to detect when object are moved in the same
+ * context.
+ *
+ * @since 2.0
+ */
+ @Override
+ public NotificationChain eSetResource(Resource.Internal resource, NotificationChain notifications)
+ {
+ Resource.Internal oldResource = eDirectResource();
+
+ CDOView oldView = view;
+ CDOView newView = resource != null && resource instanceof CDOResource ? ((CDOResource)resource).cdoView() : null;
+
+ boolean isSameView;
+ if (state == CDOState.NEW)
+ {
+ isSameView = false;
+ }
+ else
+ {
+ isSameView = oldView != null && oldView == newView;
+ }
+
+ if (oldResource != null)
+ {
+ notifications = ((InternalEList<?>)oldResource.getContents()).basicRemove(this, notifications);
+
+ // When setting the resource to null we assume that detach has already been called in the resource implementation
+ if (!isSameView && resource != null)
+ {
+ oldResource.detached(this);
+ }
+ }
+
+ InternalEObject oldContainer = eInternalContainer();
+ if (oldContainer != null && !isSameView)
+ {
+ if (eContainmentFeature().isResolveProxies())
+ {
+ Resource.Internal oldContainerResource = oldContainer.eInternalResource();
+ if (oldContainerResource != null)
+ {
+ // If we're not setting a new resource, attach it to the old container's resource.
+ if (resource == null)
+ {
+ oldContainerResource.attached(this);
+ }
+
+ // If we didn't detach it from an old resource already, detach it from the old container's resource.
+ //
+ else if (oldResource == null)
+ {
+ oldContainerResource.detached(this);
+ }
+ }
+ }
+ else
+ {
+ notifications = eBasicRemoveFromContainer(notifications);
+ notifications = eBasicSetContainer(null, -1, notifications);
+ }
+ }
+
+ eSetDirectResource(resource);
+
+ return notifications;
+ }
+
+ /**
+ * Specializing the behaviour of {@link #hashCode()} is not permitted as per {@link EObject} specification.
+ */
+ @Override
+ public final int hashCode()
+ {
+ return super.hashCode();
+ }
+
+ /**
+ * Specializing the behaviour of {@link #equals(Object)} is not permitted as per {@link EObject} specification.
+ */
+ @Override
+ public final boolean equals(Object obj)
+ {
+ return super.equals(obj);
+ }
+
+ @Override
+ public String toString()
+ {
+ if (id == null)
+ {
+ return eClass().getName() + "?"; //$NON-NLS-1$
+ }
+
+ return eClass().getName() + "@" + id; //$NON-NLS-1$
+ }
+
+ /**
+ * @since 2.0
+ */
+ protected Object[] cdoSettings()
+ {
+ if (cdoSettings == null)
+ {
+ int size = eClass().getFeatureCount() - eStaticFeatureCount();
+ if (size == 0)
+ {
+ cdoSettings = ENO_SETTINGS;
+ }
+ else
+ {
+ cdoSettings = new Object[size];
+ }
+ }
+
+ return cdoSettings;
+ }
+
+ /**
+ * @since 2.0
+ */
+ protected Object[] cdoBasicSettings()
+ {
+ return cdoSettings;
+ }
+
+ @Override
+ protected FeatureMap createFeatureMap(EStructuralFeature eStructuralFeature)
+ {
+ return new CDOStoreFeatureMap(eStructuralFeature);
+ }
+
+ /**
+ * @since 4.1
+ */
+ protected CDOStoreEcoreEMap createMap(EStructuralFeature eStructuralFeature)
+ {
+ return new CDOStoreEcoreEMap(eStructuralFeature);
+ }
+
+ /**
+ * @since 4.1
+ */
+ protected CDOStoreUnorderedEList<Object> createUnorderedList(EStructuralFeature eStructuralFeature)
+ {
+ return new CDOStoreUnorderedEList<Object>(eStructuralFeature);
+ }
+
+ @Override
+ protected EList<?> createList(EStructuralFeature eStructuralFeature)
+ {
+ if (isMap(eStructuralFeature))
+ {
+ return createMap(eStructuralFeature);
+ }
+
+ if (!eStructuralFeature.isOrdered())
+ {
+ return createUnorderedList(eStructuralFeature);
+ }
+
+ return super.createList(eStructuralFeature);
+ }
+
+ private boolean isMap(EStructuralFeature eStructuralFeature)
+ {
+ // Answer from Christian Damus:
+ // Java ensures that string constants are interned, so this is actually
+ // more efficient than .equals() and it's correct
+ return eStructuralFeature.getEType().getInstanceClassName() == "java.util.Map$Entry"; //$NON-NLS-1$
+ }
+
+ @Override
+ protected void eInitializeContainer()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected void eSetDirectResource(Internal resource)
+ {
+ if (FSMUtil.isTransient(this))
+ {
+ super.eSetDirectResource(resource);
+ }
+ else if (resource instanceof CDOResourceImpl || resource == null)
+ {
+ cdoStore().setContainer(this, (CDOResourceImpl)resource, eInternalContainer(), eContainerFeatureID());
+ }
+ else
+ {
+ throw new IllegalArgumentException(Messages.getString("CDOObjectImpl.8")); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Don't cache non-transient features in this CDOObject's {@link #eSettings()}.
+ */
+ @Override
+ protected boolean eIsCaching()
+ {
+ return false;
+ }
+
+ @Override
+ protected void eBasicSetContainer(InternalEObject newEContainer, int newContainerFeatureID)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Setting container: {0}, featureID={1}", newEContainer, newContainerFeatureID); //$NON-NLS-1$
+ }
+
+ if (FSMUtil.isTransient(this))
+ {
+ super.eBasicSetContainer(newEContainer, newContainerFeatureID);
+ }
+ else
+ {
+ cdoStore().setContainer(this, cdoDirectResource(), newEContainer, newContainerFeatureID);
+ }
+ }
+
+ private CDOStore cdoStore()
+ {
+ return view.getStore();
+ }
+
+ private void resetSettings()
+ {
+ cdoSettings = null;
+ cdoSettings();
+ }
+
+ /**
+ * Adjust the reference ONLY if the opposite reference used CDOID. This is true ONLY if the state of <cdo>this</code>
+ * was not {@link CDOState#NEW}.
+ */
+ private static void adjustOppositeReference(InternalCDOObject instance, InternalEObject object, EReference feature)
+ {
+ if (object != null)
+ {
+ InternalCDOObject cdoObject = (InternalCDOObject)CDOUtil.getCDOObject(object);
+ if (cdoObject != null && !FSMUtil.isTransient(cdoObject))
+ {
+ if (feature.isMany())
+ {
+ int index = cdoObject.eStore().indexOf(cdoObject, feature, instance.cdoID());
+
+ // TODO Simon Log an error in the new view.getErrors() in the case we are not able to find the object.
+ // Cannot throw an exception, the detach process is too far.
+ if (index != -1)
+ {
+ cdoObject.eStore().set(cdoObject, feature, index, instance);
+ }
+ }
+ else
+ {
+ cdoObject.eStore().set(cdoObject, feature, 0, instance);
+ }
+ }
+ else
+ {
+ if (feature.isResolveProxies())
+ {
+ // We should not trigger events. But we have no choice :-(.
+ if (feature.isMany())
+ {
+ @SuppressWarnings("unchecked")
+ InternalEList<Object> list = (InternalEList<Object>)object.eGet(feature);
+ int index = list.indexOf(instance);
+ if (index != -1)
+ {
+ list.set(index, instance);
+ }
+ }
+ else
+ {
+ object.eSet(feature, instance);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * @since 2.0
+ */
+ public static void revisionToInstanceFeature(InternalCDOObject instance, InternalCDORevision revision,
+ EStructuralFeature eFeature)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Depopulating feature {0}", eFeature); //$NON-NLS-1$
+ }
+
+ EStructuralFeature.Internal internalFeature = (EStructuralFeature.Internal)eFeature;
+ InternalCDOView view = instance.cdoView();
+ EReference oppositeReference = view.isObjectNew(instance.cdoID()) ? null : internalFeature.getEOpposite();
+
+ CDOStore cdoStore = view.getStore();
+ EStore eStore = instance.eStore();
+
+ if (eFeature.isMany())
+ {
+ int size = cdoStore.size(instance, eFeature);
+ for (int index = 0; index < size; index++)
+ {
+ // Do not trigger events
+ // Do not trigger inverse updates
+ Object object = cdoStore.get(instance, eFeature, index);
+ eStore.add(instance, eFeature, index, object);
+ if (oppositeReference != null)
+ {
+ adjustOppositeReference(instance, (InternalEObject)object, oppositeReference);
+ }
+ }
+ }
+ else
+ {
+ Object object = cdoStore.get(instance, eFeature, EStore.NO_INDEX);
+ eStore.set(instance, eFeature, EStore.NO_INDEX, object);
+ if (oppositeReference != null)
+ {
+ adjustOppositeReference(instance, (InternalEObject)object, oppositeReference);
+ }
+ }
+ }
+
+ /**
+ * @since 3.0
+ */
+ public static void instanceToRevisionFeature(InternalCDOView view, InternalCDOObject object,
+ EStructuralFeature feature, Object setting)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Populating feature {0}", feature); //$NON-NLS-1$
+ }
+
+ CDOStore cdoStore = view.getStore();
+ InternalCDORevision revision = object.cdoRevision();
+
+ if (feature.isMany())
+ {
+ if (setting != null)
+ {
+ int index = 0;
+ @SuppressWarnings("unchecked")
+ EList<Object> list = (EList<Object>)setting;
+ for (Object value : list)
+ {
+ value = cdoStore.convertToCDO(object, feature, value);
+ revision.add(feature, index++, value);
+ }
+ }
+ }
+ else
+ {
+ setting = cdoStore.convertToCDO(object, feature, setting);
+ revision.set(feature, 0, setting);
+ }
+ }
+
+ /**
+ * @since 4.1
+ */
+ public static CDOLock createLock(InternalCDOObject object, LockType type)
+ {
+ if (FSMUtil.isTransient(object))
+ {
+ throw new IllegalStateException("Call CDOView.lockObjects() for transient object " + object);
+ }
+
+ return new CDOLockImpl(object, type);
+ }
+
+ /**
+ * @since 4.1
+ */
+ public static CDOLockState getLockState(InternalCDOObject object)
+ {
+ if (!FSMUtil.isTransient(object))
+ {
+ InternalCDOView view = object.cdoView();
+ CDOID id = object.cdoID();
+
+ return view.getLockStates(Collections.singletonList(id))[0];
+ }
+
+ return null;
+ }
+
+ /**
+ * For internal use only.
+ *
+ * @author Simon McDuff
+ * @since 2.0
+ */
+ public static class CDOStoreSettingsImpl implements InternalEObject.EStore
+ {
+ public static CDOStoreSettingsImpl INSTANCE = new CDOStoreSettingsImpl();
+
+ private CDOStoreSettingsImpl()
+ {
+ }
+
+ protected Object getValue(InternalEObject eObject, int dynamicFeatureID)
+ {
+ Object value = ((CDOObjectImpl)eObject).cdoSettings()[dynamicFeatureID];
+ return value;
+ }
+
+ protected EList<Object> getValueAsList(InternalEObject eObject, int dynamicFeatureID)
+ {
+ @SuppressWarnings("unchecked")
+ EList<Object> result = (EList<Object>)getValue(eObject, dynamicFeatureID);
+ if (result == null)
+ {
+ result = new BasicEList<Object>();
+ ((CDOObjectImpl)eObject).cdoSettings()[dynamicFeatureID] = result;
+ }
+
+ return result;
+ }
+
+ protected Object setValue(InternalEObject eObject, int dynamicFeatureID, Object newValue)
+ {
+ Object settings[] = ((CDOObjectImpl)eObject).cdoSettings();
+ Object oldSetting = settings[dynamicFeatureID];
+ settings[dynamicFeatureID] = newValue;
+ return oldSetting;
+ }
+
+ protected int eDynamicFeatureID(InternalEObject eObject, EStructuralFeature feature)
+ {
+ return ((CDOObjectImpl)eObject).eDynamicFeatureID(feature);
+ }
+
+ public Object get(InternalEObject eObject, EStructuralFeature feature, int index)
+ {
+ int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+ if (index != NO_INDEX)
+ {
+ return getValueAsList(eObject, dynamicFeatureID).get(index);
+ }
+
+ return getValue(eObject, dynamicFeatureID);
+ }
+
+ public Object set(InternalEObject eObject, EStructuralFeature feature, int index, Object value)
+ {
+ int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+ if (index != NO_INDEX)
+ {
+ return getValueAsList(eObject, dynamicFeatureID).set(index, value);
+ }
+
+ return setValue(eObject, dynamicFeatureID, value);
+ }
+
+ public void add(InternalEObject eObject, EStructuralFeature feature, int index, Object value)
+ {
+ int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+ getValueAsList(eObject, dynamicFeatureID).add(index, value);
+ }
+
+ public Object remove(InternalEObject eObject, EStructuralFeature feature, int index)
+ {
+ int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+ return getValueAsList(eObject, dynamicFeatureID).remove(index);
+ }
+
+ public Object move(InternalEObject eObject, EStructuralFeature feature, int targetIndex, int sourceIndex)
+ {
+ int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+ return getValueAsList(eObject, dynamicFeatureID).move(targetIndex, sourceIndex);
+ }
+
+ public void clear(InternalEObject eObject, EStructuralFeature feature)
+ {
+ int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+ if (feature.isMany())
+ {
+ getValueAsList(eObject, dynamicFeatureID).clear();
+ }
+
+ setValue(eObject, dynamicFeatureID, null);
+ }
+
+ public int size(InternalEObject eObject, EStructuralFeature feature)
+ {
+ int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+ return getValueAsList(eObject, dynamicFeatureID).size();
+ }
+
+ public int indexOf(InternalEObject eObject, EStructuralFeature feature, Object value)
+ {
+ int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+ return getValueAsList(eObject, dynamicFeatureID).indexOf(value);
+ }
+
+ public int lastIndexOf(InternalEObject eObject, EStructuralFeature feature, Object value)
+ {
+ int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+ return getValueAsList(eObject, dynamicFeatureID).lastIndexOf(value);
+ }
+
+ public Object[] toArray(InternalEObject eObject, EStructuralFeature feature)
+ {
+ int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+ return getValueAsList(eObject, dynamicFeatureID).toArray();
+ }
+
+ public <T> T[] toArray(InternalEObject eObject, EStructuralFeature feature, T[] array)
+ {
+ int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+ return getValueAsList(eObject, dynamicFeatureID).toArray(array);
+ }
+
+ public boolean isEmpty(InternalEObject eObject, EStructuralFeature feature)
+ {
+ int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+ return getValueAsList(eObject, dynamicFeatureID).isEmpty();
+ }
+
+ public boolean contains(InternalEObject eObject, EStructuralFeature feature, Object value)
+ {
+ int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+ return getValueAsList(eObject, dynamicFeatureID).contains(value);
+ }
+
+ public int hashCode(InternalEObject eObject, EStructuralFeature feature)
+ {
+ int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+ return getValueAsList(eObject, dynamicFeatureID).hashCode();
+ }
+
+ public InternalEObject getContainer(InternalEObject eObject)
+ {
+ return null;
+ }
+
+ public EStructuralFeature getContainingFeature(InternalEObject eObject)
+ {
+ throw new UnsupportedOperationException("Should never be called");
+ }
+
+ public EObject create(EClass eClass)
+ {
+ return new EStoreEObjectImpl(eClass, this);
+ }
+
+ public boolean isSet(InternalEObject eObject, EStructuralFeature feature)
+ {
+ if (!feature.isUnsettable())
+ {
+ if (feature.isMany())
+ {
+ @SuppressWarnings("unchecked")
+ InternalEList<Object> list = (InternalEList<Object>)eObject.eGet(feature);
+ return list != null && !list.isEmpty();
+ }
+
+ return !ObjectUtil.equals(eObject.eGet(feature), feature.getDefaultValue());
+ }
+
+ Object[] settings = ((CDOObjectImpl)eObject).cdoBasicSettings();
+ if (settings == null)
+ {
+ return false;
+ }
+
+ int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+ return settings[dynamicFeatureID] != null;
+ }
+
+ public void unset(InternalEObject eObject, EStructuralFeature feature)
+ {
+ Object[] settings = ((CDOObjectImpl)eObject).cdoBasicSettings();
+ if (settings == null)
+ {
+ // Is already unset
+ return;
+ }
+
+ int dynamicFeatureID = eDynamicFeatureID(eObject, feature);
+ if (feature.isUnsettable())
+ {
+ settings[dynamicFeatureID] = null;
+ }
+ else
+ {
+ settings[dynamicFeatureID] = feature.getDefaultValue();
+ }
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ * @since 4.1
+ */
+ public class CDOStoreEcoreEMap extends EcoreEMap<Object, Object> implements InternalCDOLoadable
+ {
+ private static final long serialVersionUID = 1L;
+
+ public CDOStoreEcoreEMap(EStructuralFeature eStructuralFeature)
+ {
+ super((EClass)eStructuralFeature.getEType(), BasicEMap.Entry.class, null);
+ delegateEList = new BasicEStoreEList<BasicEMap.Entry<Object, Object>>(CDOObjectImpl.this, eStructuralFeature)
+ {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void unset()
+ {
+ super.unset();
+ doClear();
+ }
+
+ @Override
+ protected void didAdd(int index, BasicEMap.Entry<Object, Object> newObject)
+ {
+ CDOStoreEcoreEMap.this.doPut(newObject);
+ }
+
+ @Override
+ protected void didSet(int index, BasicEMap.Entry<Object, Object> newObject,
+ BasicEMap.Entry<Object, Object> oldObject)
+ {
+ didRemove(index, oldObject);
+ didAdd(index, newObject);
+ }
+
+ @Override
+ protected void didRemove(int index, BasicEMap.Entry<Object, Object> oldObject)
+ {
+ CDOStoreEcoreEMap.this.doRemove(oldObject);
+ }
+
+ @Override
+ protected void didClear(int size, Object[] oldObjects)
+ {
+ CDOStoreEcoreEMap.this.doClear();
+ }
+
+ @Override
+ protected void didMove(int index, BasicEMap.Entry<Object, Object> movedObject, int oldIndex)
+ {
+ CDOStoreEcoreEMap.this.doMove(movedObject);
+ }
+ };
+
+ size = delegateEList.size();
+ }
+
+ private void checkListForReading()
+ {
+ if (!FSMUtil.isTransient(CDOObjectImpl.this))
+ {
+ CDOStateMachine.INSTANCE.read(CDOObjectImpl.this);
+ }
+ }
+
+ /**
+ * Ensures that the entry data is created and is populated with contents of the delegate list.
+ */
+ @Override
+ protected synchronized void ensureEntryDataExists()
+ {
+ checkListForReading();
+ super.ensureEntryDataExists();
+ }
+
+ @Override
+ public int size()
+ {
+ checkListForReading();
+ return size;
+ }
+
+ @Override
+ public boolean isEmpty()
+ {
+ checkListForReading();
+ return size == 0;
+ }
+
+ @Override
+ public boolean contains(Object object)
+ {
+ checkListForReading();
+ return super.contains(object);
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> collection)
+ {
+ checkListForReading();
+ return super.containsAll(collection);
+ }
+
+ @Override
+ public boolean containsKey(Object key)
+ {
+ checkListForReading();
+ return super.containsKey(key);
+ }
+
+ @Override
+ public boolean containsValue(Object value)
+ {
+ checkListForReading();
+ return super.containsValue(value);
+ }
+
+ public void cdoInternalPostLoad()
+ {
+ entryData = null;
+ size = delegateEList.size();
+ }
+
+ public void cdoInternalPreLoad()
+ {
+ }
+ }
+
+ /**
+ * @author Andras Peteri
+ * @since 4.1
+ */
+ public class CDOStoreUnorderedEList<E> extends BasicEStoreEList<E>
+ {
+ private static final long serialVersionUID = 1L;
+
+ public CDOStoreUnorderedEList(EStructuralFeature feature)
+ {
+ super(CDOObjectImpl.this, feature);
+ }
+
+ @Override
+ public E remove(int index)
+ {
+ boolean oldObjectIsLast = index == size() - 1;
+ E oldObject = super.remove(index);
+
+ if (!oldObjectIsLast)
+ {
+ move(index, size() - 1);
+ }
+
+ return oldObject;
+ }
+ }
+
+ /**
+ * TODO Remove this when EMF has fixed bug 197487
+ *
+ * @author Eike Stepper
+ */
+ public class CDOStoreFeatureMap extends DelegatingFeatureMap
+ {
+ private static final long serialVersionUID = 1L;
+
+ public CDOStoreFeatureMap(EStructuralFeature eStructuralFeature)
+ {
+ super(CDOObjectImpl.this, eStructuralFeature);
+ }
+
+ @Override
+ protected List<FeatureMap.Entry> delegateList()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public EStructuralFeature getEStructuralFeature()
+ {
+ return eStructuralFeature;
+ }
+
+ @Override
+ protected void delegateAdd(int index, Entry object)
+ {
+ eStore().add(owner, eStructuralFeature, index, object);
+ }
+
+ @Override
+ protected void delegateAdd(Entry object)
+ {
+ delegateAdd(delegateSize(), object);
+ }
+
+ @Override
+ protected List<FeatureMap.Entry> delegateBasicList()
+ {
+ int size = delegateSize();
+ if (size == 0)
+ {
+ return ECollections.emptyEList();
+ }
+
+ Object[] data = cdoStore().toArray(owner, eStructuralFeature);
+ return new EcoreEList.UnmodifiableEList<FeatureMap.Entry>(owner, eStructuralFeature, data.length, data);
+ }
+
+ @Override
+ protected void delegateClear()
+ {
+ eStore().clear(owner, eStructuralFeature);
+ }
+
+ @Override
+ protected boolean delegateContains(Object object)
+ {
+ return eStore().contains(owner, eStructuralFeature, object);
+ }
+
+ @Override
+ protected boolean delegateContainsAll(Collection<?> collection)
+ {
+ for (Object o : collection)
+ {
+ if (!delegateContains(o))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ protected Entry delegateGet(int index)
+ {
+ return (Entry)eStore().get(owner, eStructuralFeature, index);
+ }
+
+ @Override
+ protected int delegateHashCode()
+ {
+ return eStore().hashCode(owner, eStructuralFeature);
+ }
+
+ @Override
+ protected int delegateIndexOf(Object object)
+ {
+ return eStore().indexOf(owner, eStructuralFeature, object);
+ }
+
+ @Override
+ protected boolean delegateIsEmpty()
+ {
+ return eStore().isEmpty(owner, eStructuralFeature);
+ }
+
+ @Override
+ protected Iterator<FeatureMap.Entry> delegateIterator()
+ {
+ return iterator();
+ }
+
+ @Override
+ protected int delegateLastIndexOf(Object object)
+ {
+ return eStore().lastIndexOf(owner, eStructuralFeature, object);
+ }
+
+ @Override
+ protected ListIterator<FeatureMap.Entry> delegateListIterator()
+ {
+ return listIterator();
+ }
+
+ @Override
+ protected Entry delegateRemove(int index)
+ {
+ return (Entry)eStore().remove(owner, eStructuralFeature, index);
+ }
+
+ @Override
+ protected Entry delegateSet(int index, Entry object)
+ {
+ return (Entry)eStore().set(owner, eStructuralFeature, index, object);
+ }
+
+ @Override
+ protected int delegateSize()
+ {
+ return eStore().size(owner, eStructuralFeature);
+ }
+
+ @Override
+ protected Object[] delegateToArray()
+ {
+ return eStore().toArray(owner, eStructuralFeature);
+ }
+
+ @Override
+ protected <T> T[] delegateToArray(T[] array)
+ {
+ return eStore().toArray(owner, eStructuralFeature, array);
+ }
+
+ @Override
+ protected Entry delegateMove(int targetIndex, int sourceIndex)
+ {
+ return (Entry)eStore().move(owner, eStructuralFeature, targetIndex, sourceIndex);
+ }
+
+ @Override
+ protected String delegateToString()
+ {
+ StringBuffer stringBuffer = new StringBuffer();
+ stringBuffer.append("["); //$NON-NLS-1$
+ for (int i = 0, size = size(); i < size;)
+ {
+ Object value = delegateGet(i);
+ stringBuffer.append(String.valueOf(value));
+ if (++i < size)
+ {
+ stringBuffer.append(", "); //$NON-NLS-1$
+ }
+ }
+
+ stringBuffer.append("]"); //$NON-NLS-1$
+ return stringBuffer.toString();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java
index 1d93cabcbd..36e51ebf6a 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java
@@ -331,6 +331,8 @@ public abstract class CDOLegacyWrapper extends CDOObjectWrapper
{
instanceToRevisionFeature(feature, packageRegistry);
}
+
+ revision.setUnchunked();
}
protected void instanceToRevisionContainment()
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
index f8541bf747..708f06e23f 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
@@ -1,1849 +1,1859 @@
-/*
- * Copyright (c) 2004 - 2012 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
- * Simon McDuff - bug 226778
- * Simon McDuff - bug 230832
- * Simon McDuff - bug 233490
- * Simon McDuff - bug 213402
- * Victor Roldan Betancort - maintenance
- */
-package org.eclipse.emf.internal.cdo.session;
-
-import org.eclipse.emf.cdo.common.CDOCommonRepository;
-import org.eclipse.emf.cdo.common.branch.CDOBranch;
-import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
-import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
-import org.eclipse.emf.cdo.common.commit.CDOChangeKind;
-import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
-import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
-import org.eclipse.emf.cdo.common.commit.CDOCommitInfoManager;
-import org.eclipse.emf.cdo.common.id.CDOID;
-import org.eclipse.emf.cdo.common.id.CDOIDGenerator;
-import org.eclipse.emf.cdo.common.lob.CDOLobInfo;
-import org.eclipse.emf.cdo.common.lob.CDOLobStore;
-import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
-import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
-import org.eclipse.emf.cdo.common.model.EMFUtil;
-import org.eclipse.emf.cdo.common.protocol.CDOAuthenticator;
-import org.eclipse.emf.cdo.common.revision.CDOElementProxy;
-import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion;
-import org.eclipse.emf.cdo.common.revision.CDOList;
-import org.eclipse.emf.cdo.common.revision.CDORevisable;
-import org.eclipse.emf.cdo.common.revision.CDORevision;
-import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
-import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
-import org.eclipse.emf.cdo.common.revision.delta.CDOAddFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
-import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOMoveFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDORemoveFeatureDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
-import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta;
-import org.eclipse.emf.cdo.common.util.CDOException;
-import org.eclipse.emf.cdo.common.util.RepositoryStateChangedEvent;
-import org.eclipse.emf.cdo.common.util.RepositoryTypeChangedEvent;
-import org.eclipse.emf.cdo.eresource.EresourcePackage;
-import org.eclipse.emf.cdo.etypes.EtypesPackage;
-import org.eclipse.emf.cdo.internal.common.revision.delta.CDOMoveFeatureDeltaImpl;
-import org.eclipse.emf.cdo.internal.common.revision.delta.CDOSetFeatureDeltaImpl;
-import org.eclipse.emf.cdo.internal.common.revision.delta.CDOSingleValueFeatureDeltaImpl;
-import org.eclipse.emf.cdo.session.CDOCollectionLoadingPolicy;
-import org.eclipse.emf.cdo.session.CDORepositoryInfo;
-import org.eclipse.emf.cdo.session.CDOSession;
-import org.eclipse.emf.cdo.session.CDOSessionInvalidationEvent;
-import org.eclipse.emf.cdo.session.CDOSessionLocksChangedEvent;
-import org.eclipse.emf.cdo.session.remote.CDORemoteSessionManager;
-import org.eclipse.emf.cdo.spi.common.CDOLobStoreImpl;
-import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
-import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranch;
-import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
-import org.eclipse.emf.cdo.spi.common.commit.CDORevisionAvailabilityInfo;
-import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
-import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
-import org.eclipse.emf.cdo.spi.common.revision.CDOFeatureDeltaVisitorImpl;
-import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionCache;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
-import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
-import org.eclipse.emf.cdo.spi.common.revision.PointerCDORevision;
-import org.eclipse.emf.cdo.transaction.CDOTransaction;
-import org.eclipse.emf.cdo.util.CDOUtil;
-import org.eclipse.emf.cdo.view.CDOFetchRuleManager;
-import org.eclipse.emf.cdo.view.CDOView;
-
-import org.eclipse.emf.internal.cdo.analyzer.NOOPFetchRuleManager;
-import org.eclipse.emf.internal.cdo.bundle.OM;
-import org.eclipse.emf.internal.cdo.messages.Messages;
-import org.eclipse.emf.internal.cdo.object.CDOFactoryImpl;
-import org.eclipse.emf.internal.cdo.session.remote.CDORemoteSessionManagerImpl;
-import org.eclipse.emf.internal.cdo.util.DefaultLocksChangedEvent;
-
-import org.eclipse.net4j.util.ObjectUtil;
-import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
-import org.eclipse.net4j.util.WrappedException;
-import org.eclipse.net4j.util.collection.Pair;
-import org.eclipse.net4j.util.concurrent.IRWLockManager;
-import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
-import org.eclipse.net4j.util.concurrent.IRWOLockManager;
-import org.eclipse.net4j.util.concurrent.QueueRunner;
-import org.eclipse.net4j.util.concurrent.RWOLockManager;
-import org.eclipse.net4j.util.event.Event;
-import org.eclipse.net4j.util.event.EventUtil;
-import org.eclipse.net4j.util.event.IEvent;
-import org.eclipse.net4j.util.event.IListener;
-import org.eclipse.net4j.util.event.Notifier;
-import org.eclipse.net4j.util.io.IOUtil;
-import org.eclipse.net4j.util.lifecycle.ILifecycle;
-import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter;
-import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
-import org.eclipse.net4j.util.om.log.OMLogger;
-import org.eclipse.net4j.util.options.OptionsEvent;
-
-import org.eclipse.emf.common.util.ECollections;
-import org.eclipse.emf.ecore.EPackage;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.EcorePackage;
-import org.eclipse.emf.spi.cdo.CDOSessionProtocol;
-import org.eclipse.emf.spi.cdo.CDOSessionProtocol.RefreshSessionResult;
-import org.eclipse.emf.spi.cdo.InternalCDORemoteSessionManager;
-import org.eclipse.emf.spi.cdo.InternalCDOSession;
-import org.eclipse.emf.spi.cdo.InternalCDOTransaction;
-import org.eclipse.emf.spi.cdo.InternalCDOView;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * @author Eike Stepper
- */
-public abstract class CDOSessionImpl extends CDOTransactionContainerImpl implements InternalCDOSession
-{
- private ExceptionHandler exceptionHandler;
-
- private CDOIDGenerator idGenerator;
-
- private InternalCDOPackageRegistry packageRegistry;
-
- private InternalCDOBranchManager branchManager;
-
- private InternalCDORevisionManager revisionManager;
-
- private InternalCDOCommitInfoManager commitInfoManager;
-
- private CDOSessionProtocol sessionProtocol;
-
- @ExcludeFromDump
- private IListener sessionProtocolListener = new LifecycleEventAdapter()
- {
- @Override
- protected void onDeactivated(ILifecycle lifecycle)
- {
- sessionProtocolDeactivated();
- }
- };
-
- private int sessionID;
-
- private String userID;
-
- private long lastUpdateTime;
-
- @ExcludeFromDump
- private LastUpdateTimeLock lastUpdateTimeLock = new LastUpdateTimeLock();
-
- private CDOSession.Options options = createOptions();
-
- private OutOfSequenceInvalidations outOfSequenceInvalidations = new OutOfSequenceInvalidations();
-
- private QueueRunner invalidationRunner;
-
- private CDORepositoryInfo repositoryInfo;
-
- private CDOFetchRuleManager fetchRuleManager;
-
- private IRWOLockManager<CDOSessionImpl, Object> lockManager = new RWOLockManager<CDOSessionImpl, Object>();
-
- @ExcludeFromDump
- private Set<CDOSessionImpl> singletonCollection = Collections.singleton(this);
-
- private boolean mainBranchLocal;
-
- private CDOAuthenticator authenticator;
-
- private InternalCDORemoteSessionManager remoteSessionManager;
-
- /**
- * A map to track for every object that was committed since this session's last refresh, onto what CDOBranchPoint it
- * was committed. (Used only for sticky transactions, see bug 290032 - Sticky views.)
- */
- private Map<CDOID, CDOBranchPoint> committedSinceLastRefresh = new HashMap<CDOID, CDOBranchPoint>();
-
- static
- {
- // Ensure that these 3 packages are registered with the global package registry in stand-alone
- EcorePackage.eINSTANCE.getClass();
- EresourcePackage.eINSTANCE.getClass();
- EtypesPackage.eINSTANCE.getClass();
- }
-
- public CDOSessionImpl()
- {
- }
-
- public CDORepositoryInfo getRepositoryInfo()
- {
- return repositoryInfo;
- }
-
- public void setRepositoryInfo(CDORepositoryInfo repositoryInfo)
- {
- this.repositoryInfo = repositoryInfo;
- }
-
- public int getSessionID()
- {
- return sessionID;
- }
-
- public void setSessionID(int sessionID)
- {
- this.sessionID = sessionID;
- }
-
- public String getUserID()
- {
- return userID;
- }
-
- public void setUserID(String userID)
- {
- this.userID = userID;
- }
-
- public ExceptionHandler getExceptionHandler()
- {
- return exceptionHandler;
- }
-
- public void setExceptionHandler(ExceptionHandler exceptionHandler)
- {
- checkInactive();
- this.exceptionHandler = exceptionHandler;
- }
-
- public CDOIDGenerator getIDGenerator()
- {
- return idGenerator;
- }
-
- public void setIDGenerator(CDOIDGenerator idGenerator)
- {
- checkInactive();
- this.idGenerator = idGenerator;
- }
-
- public InternalCDOPackageRegistry getPackageRegistry()
- {
- return packageRegistry;
- }
-
- public void setPackageRegistry(InternalCDOPackageRegistry packageRegistry)
- {
- this.packageRegistry = packageRegistry;
- }
-
- public InternalCDOBranchManager getBranchManager()
- {
- return branchManager;
- }
-
- public void setBranchManager(InternalCDOBranchManager branchManager)
- {
- checkInactive();
- this.branchManager = branchManager;
- }
-
- public InternalCDORevisionManager getRevisionManager()
- {
- return revisionManager;
- }
-
- public void setRevisionManager(InternalCDORevisionManager revisionManager)
- {
- checkInactive();
- this.revisionManager = revisionManager;
- }
-
- public InternalCDOCommitInfoManager getCommitInfoManager()
- {
- return commitInfoManager;
- }
-
- public void setCommitInfoManager(InternalCDOCommitInfoManager commitInfoManager)
- {
- checkInactive();
- this.commitInfoManager = commitInfoManager;
- }
-
- public CDOSessionProtocol getSessionProtocol()
- {
- return sessionProtocol;
- }
-
- public void setSessionProtocol(CDOSessionProtocol sessionProtocol)
- {
- checkInactive();
- if (exceptionHandler == null)
- {
- this.sessionProtocol = sessionProtocol;
- }
- else
- {
- if (this.sessionProtocol instanceof DelegatingSessionProtocol)
- {
- ((DelegatingSessionProtocol)this.sessionProtocol).setDelegate(sessionProtocol);
- }
- else
- {
- this.sessionProtocol = new DelegatingSessionProtocol(sessionProtocol, exceptionHandler);
- }
- }
- }
-
- /**
- * @since 3.0
- */
- public CDOFetchRuleManager getFetchRuleManager()
- {
- return fetchRuleManager;
- }
-
- /**
- * @since 3.0
- */
- public void setFetchRuleManager(CDOFetchRuleManager fetchRuleManager)
- {
- if (fetchRuleManager == null)
- {
- fetchRuleManager = new NOOPFetchRuleManager()
- {
- public CDOCollectionLoadingPolicy getCollectionLoadingPolicy()
- {
- return options().getCollectionLoadingPolicy();
- }
- };
- }
-
- this.fetchRuleManager = fetchRuleManager;
- }
-
- public CDOAuthenticator getAuthenticator()
- {
- return authenticator;
- }
-
- public void setAuthenticator(CDOAuthenticator authenticator)
- {
- this.authenticator = authenticator;
- }
-
- public boolean isMainBranchLocal()
- {
- return mainBranchLocal;
- }
-
- public void setMainBranchLocal(boolean mainBranchLocal)
- {
- this.mainBranchLocal = mainBranchLocal;
- }
-
- public InternalCDORemoteSessionManager getRemoteSessionManager()
- {
- return remoteSessionManager;
- }
-
- public void setRemoteSessionManager(InternalCDORemoteSessionManager remoteSessionManager)
- {
- this.remoteSessionManager = remoteSessionManager;
- }
-
- public CDOLobStore getLobStore()
- {
- final CDOLobStore cache = options().getLobCache();
- return new CDOLobStore.Delegating()
- {
- @Override
- public InputStream getBinary(final CDOLobInfo info) throws IOException
- {
- for (;;)
- {
- try
- {
- return super.getBinary(info);
- }
- catch (FileNotFoundException couldNotBeRead)
- {
- try
- {
- loadBinary(info);
- }
- catch (FileNotFoundException couldNotBeCreated)
- {
- // Try to read again
- }
- }
- }
- }
-
- @Override
- public Reader getCharacter(CDOLobInfo info) throws IOException
- {
- for (;;)
- {
- try
- {
- return super.getCharacter(info);
- }
- catch (FileNotFoundException couldNotBeRead)
- {
- try
- {
- loadCharacter(info);
- }
- catch (FileNotFoundException couldNotBeCreated)
- {
- // Try to read again
- }
- }
- }
- }
-
- private void loadBinary(final CDOLobInfo info) throws IOException
- {
- final File file = getDelegate().getBinaryFile(info.getID());
- final FileOutputStream out = new FileOutputStream(file);
-
- loadLobAsync(info, new Runnable()
- {
- public void run()
- {
- try
- {
- getSessionProtocol().loadLob(info, out);
- }
- catch (Throwable t)
- {
- OM.LOG.error(t);
- IOUtil.delete(file);
- }
- }
- });
- }
-
- private void loadCharacter(final CDOLobInfo info) throws IOException
- {
- final File file = getDelegate().getCharacterFile(info.getID());
- final FileWriter out = new FileWriter(file);
-
- loadLobAsync(info, new Runnable()
- {
- public void run()
- {
- try
- {
- getSessionProtocol().loadLob(info, out);
- }
- catch (Throwable t)
- {
- OM.LOG.error(t);
- IOUtil.delete(file);
- }
- }
- });
- }
-
- @Override
- protected CDOLobStore getDelegate()
- {
- return cache;
- }
- };
- }
-
- protected void loadLobAsync(CDOLobInfo info, Runnable runnable)
- {
- new Thread(runnable, "LobLoader").start();
- }
-
- public void close()
- {
- LifecycleUtil.deactivate(this, OMLogger.Level.DEBUG);
- }
-
- /**
- * @since 2.0
- */
- public boolean isClosed()
- {
- return !isActive();
- }
-
- /**
- * @since 2.0
- */
- public CDOSession.Options options()
- {
- return options;
- }
-
- /**
- * @since 2.0
- */
- protected CDOSession.Options createOptions()
- {
- return new OptionsImpl();
- }
-
- public Object processPackage(Object value)
- {
- CDOFactoryImpl.prepareDynamicEPackage(value);
- return value;
- }
-
- public EPackage[] loadPackages(CDOPackageUnit packageUnit)
- {
- if (packageUnit.getOriginalType().isGenerated())
- {
- if (!options().isGeneratedPackageEmulationEnabled())
- {
- throw new CDOException(MessageFormat.format(Messages.getString("CDOSessionImpl.0"), packageUnit)); //$NON-NLS-1$
- }
- }
-
- return getSessionProtocol().loadPackages(packageUnit);
- }
-
- public void acquireAtomicRequestLock(Object key)
- {
- try
- {
- lockManager.lock(LockType.WRITE, key, this, IRWLockManager.WAIT);
- }
- catch (InterruptedException ex)
- {
- throw WrappedException.wrap(ex);
- }
- }
-
- public void releaseAtomicRequestLock(Object key)
- {
- lockManager.unlock(LockType.WRITE, key, singletonCollection);
- }
-
- @Override
- protected void initViewSynced(InternalCDOView view)
- {
- view.setSession(this);
- view.setLastUpdateTime(getLastUpdateTime());
- }
-
- @Override
- protected CDOBranch getMainBranch()
- {
- return getBranchManager().getMainBranch();
- }
-
- /**
- * @since 2.0
- */
- public long refresh()
- {
- checkActive();
- if (options().isPassiveUpdateEnabled())
- {
- return CDOBranchPoint.UNSPECIFIED_DATE;
- }
-
- return refresh(false);
- }
-
- private long refresh(boolean enablePassiveUpdates)
- {
- Map<CDOBranch, List<InternalCDOView>> views = new HashMap<CDOBranch, List<InternalCDOView>>();
- Map<CDOBranch, Map<CDOID, InternalCDORevision>> viewedRevisions = new HashMap<CDOBranch, Map<CDOID, InternalCDORevision>>();
- collectViewedRevisions(views, viewedRevisions);
- cleanupRevisionCache(viewedRevisions);
-
- CDOSessionProtocol sessionProtocol = getSessionProtocol();
- long lastUpdateTime = getLastUpdateTime();
- int initialChunkSize = options().getCollectionLoadingPolicy().getInitialChunkSize();
-
- RefreshSessionResult result = sessionProtocol.refresh(lastUpdateTime, viewedRevisions, initialChunkSize,
- enablePassiveUpdates);
-
- setLastUpdateTime(result.getLastUpdateTime());
- registerPackageUnits(result.getPackageUnits());
-
- for (Entry<CDOBranch, List<InternalCDOView>> entry : views.entrySet())
- {
- CDOBranch branch = entry.getKey();
- List<InternalCDOView> branchViews = entry.getValue();
- processRefreshSessionResult(result, branch, branchViews, viewedRevisions);
- }
-
- return result.getLastUpdateTime();
- }
-
- public void processRefreshSessionResult(RefreshSessionResult result, CDOBranch branch,
- List<InternalCDOView> branchViews, Map<CDOBranch, Map<CDOID, InternalCDORevision>> viewedRevisions)
- {
- Map<CDOID, InternalCDORevision> oldRevisions = viewedRevisions.get(branch);
-
- List<CDORevisionKey> changedObjects = new ArrayList<CDORevisionKey>();
- List<InternalCDORevision> newRevisions = result.getChangedObjects(branch);
- for (InternalCDORevision newRevision : newRevisions)
- {
- getRevisionManager().addRevision(newRevision);
-
- InternalCDORevision oldRevision = oldRevisions.get(newRevision.getID());
- InternalCDORevisionDelta delta = newRevision.compare(oldRevision);
- changedObjects.add(delta);
- }
-
- List<CDOIDAndVersion> detachedObjects = result.getDetachedObjects(branch);
- for (CDOIDAndVersion detachedObject : detachedObjects)
- {
- getRevisionManager().reviseLatest(detachedObject.getID(), branch);
- }
-
- for (InternalCDOView view : branchViews)
- {
- view.invalidate(view.getBranch(), result.getLastUpdateTime(), changedObjects, detachedObjects, oldRevisions,
- false);
- }
- }
-
- private void collectViewedRevisions(Map<CDOBranch, List<InternalCDOView>> views,
- Map<CDOBranch, Map<CDOID, InternalCDORevision>> viewedRevisions)
- {
- for (InternalCDOView view : getViews())
- {
- if (view.getTimeStamp() == CDOView.UNSPECIFIED_DATE)
- {
- CDOBranch branch = view.getBranch();
- Map<CDOID, InternalCDORevision> revisions = viewedRevisions.get(branch);
- boolean needNewMap = revisions == null;
- if (needNewMap)
- {
- revisions = new HashMap<CDOID, InternalCDORevision>();
- }
-
- view.collectViewedRevisions(revisions);
- if (!revisions.isEmpty())
- {
- List<InternalCDOView> list = views.get(branch);
- if (list == null)
- {
- list = new ArrayList<InternalCDOView>();
- views.put(branch, list);
- }
-
- list.add(view);
-
- if (needNewMap)
- {
- viewedRevisions.put(branch, revisions);
- }
- }
- }
- }
- }
-
- private void cleanupRevisionCache(Map<CDOBranch, Map<CDOID, InternalCDORevision>> viewedRevisions)
- {
- Set<InternalCDORevision> set = new HashSet<InternalCDORevision>();
- for (Map<CDOID, InternalCDORevision> revisions : viewedRevisions.values())
- {
- for (InternalCDORevision revision : revisions.values())
- {
- set.add(revision);
- }
- }
-
- InternalCDORevisionCache cache = getRevisionManager().getCache();
- List<CDORevision> currentRevisions = cache.getCurrentRevisions();
- for (CDORevision revision : currentRevisions)
- {
- if (!set.contains(revision))
- {
- cache.removeRevision(revision.getID(), revision);
- }
- }
- }
-
- public long getLastUpdateTime()
- {
- synchronized (lastUpdateTimeLock)
- {
- return lastUpdateTime;
- }
- }
-
- public void setLastUpdateTime(long lastUpdateTime)
- {
- synchronized (lastUpdateTimeLock)
- {
- if (this.lastUpdateTime < lastUpdateTime)
- {
- this.lastUpdateTime = lastUpdateTime;
- }
-
- lastUpdateTimeLock.notifyAll();
- }
- }
-
- public void waitForUpdate(long updateTime)
- {
- waitForUpdate(updateTime, NO_TIMEOUT);
- }
-
- public boolean waitForUpdate(long updateTime, long timeoutMillis)
- {
- long end = timeoutMillis == NO_TIMEOUT ? Long.MAX_VALUE : System.currentTimeMillis() + timeoutMillis;
- InternalCDOView views[] = getViews();
- if (views.length > 0)
- {
- for (CDOView view : views)
- {
- long viewTimeoutMillis = timeoutMillis == NO_TIMEOUT ? NO_TIMEOUT : end - System.currentTimeMillis();
- boolean ok = view.waitForUpdate(updateTime, viewTimeoutMillis);
- if (!ok)
- {
- return false;
- }
- }
-
- return true;
- }
-
- // Session without views
- for (;;)
- {
- synchronized (lastUpdateTimeLock)
- {
- if (lastUpdateTime >= updateTime)
- {
- return true;
- }
-
- long now = System.currentTimeMillis();
- if (now >= end)
- {
- return false;
- }
-
- try
- {
- lastUpdateTimeLock.wait(end - now);
- }
- catch (InterruptedException ex)
- {
- throw WrappedException.wrap(ex);
- }
- }
- }
- }
-
- /**
- * @since 3.0
- */
- public Object resolveElementProxy(CDORevision revision, EStructuralFeature feature, int accessIndex, int serverIndex)
- {
- CDOCollectionLoadingPolicy policy = options().getCollectionLoadingPolicy();
- return policy.resolveProxy(revision, feature, accessIndex, serverIndex);
- }
-
- /**
- * @since 4.0
- */
- public void resolveAllElementProxies(CDORevision revision)
- {
- CDOCollectionLoadingPolicy policy = options().getCollectionLoadingPolicy();
- for (EStructuralFeature feature : revision.getEClass().getEAllStructuralFeatures())
- {
- if (feature instanceof EReference)
- {
- EReference reference = (EReference)feature;
- if (reference.isMany() && EMFUtil.isPersistent(reference))
- {
- CDOList list = ((InternalCDORevision)revision).getList(reference);
- for (Iterator<Object> it = list.iterator(); it.hasNext();)
- {
- Object element = it.next();
- if (element instanceof CDOElementProxy)
- {
- policy.resolveAllProxies(revision, reference);
- break;
- }
- }
- }
- }
- }
- }
-
- public void handleRepositoryTypeChanged(CDOCommonRepository.Type oldType, CDOCommonRepository.Type newType)
- {
- fireEvent(new RepositoryTypeChangedEvent(this, oldType, newType));
- }
-
- public void handleRepositoryStateChanged(CDOCommonRepository.State oldState, CDOCommonRepository.State newState)
- {
- fireEvent(new RepositoryStateChangedEvent(this, oldState, newState));
- }
-
- public void handleBranchNotification(InternalCDOBranch branch)
- {
- getBranchManager().handleBranchCreated(branch);
- }
-
- public void handleCommitNotification(CDOCommitInfo commitInfo)
- {
- try
- {
- registerPackageUnits(commitInfo.getNewPackageUnits());
- invalidate(commitInfo, null);
- }
- catch (RuntimeException ex)
- {
- if (isActive())
- {
- OM.LOG.error(ex);
- }
- else
- {
- OM.LOG.info(Messages.getString("CDOSessionImpl.2")); //$NON-NLS-1$
- }
- }
- }
-
- public void handleLockNotification(CDOLockChangeInfo lockChangeInfo, InternalCDOView sender)
- {
- for (InternalCDOView view : getViews())
- {
- if (view != sender)
- {
- view.handleLockNotification(sender, lockChangeInfo);
- }
- }
-
- fireEvent(new LocksChangedEvent(sender, lockChangeInfo));
- }
-
- private void registerPackageUnits(List<CDOPackageUnit> packageUnits)
- {
- InternalCDOPackageRegistry packageRegistry = getPackageRegistry();
- for (CDOPackageUnit newPackageUnit : packageUnits)
- {
- packageRegistry.putPackageUnit((InternalCDOPackageUnit)newPackageUnit);
- }
- }
-
- private Map<CDOID, InternalCDORevision> reviseRevisions(CDOCommitInfo commitInfo)
- {
- Map<CDOID, InternalCDORevision> oldRevisions = null;
- CDOBranch newBranch = commitInfo.getBranch();
- long timeStamp = commitInfo.getTimeStamp();
- InternalCDORevisionManager revisionManager = getRevisionManager();
-
- // Cache new revisions
- for (CDOIDAndVersion key : commitInfo.getNewObjects())
- {
- if (key instanceof InternalCDORevision)
- {
- InternalCDORevision newRevision = (InternalCDORevision)key;
- revisionManager.addRevision(newRevision);
- }
- }
-
- // Apply deltas and cache the resulting new revisions, if possible...
- for (CDORevisionKey key : commitInfo.getChangedObjects())
- {
- // Add old values to revision deltas.
- if (key instanceof CDORevisionDelta)
- {
- final CDORevisionDelta revisionDelta = (CDORevisionDelta)key;
- final CDORevision oldRevision = revisionManager.getRevisionByVersion(revisionDelta.getID(), revisionDelta,
- CDORevision.UNCHUNKED, false);
-
- if (oldRevision != null)
- {
- CDOFeatureDeltaVisitor visitor = new CDOFeatureDeltaVisitorImpl()
- {
- private List<Object> workList;
-
- @Override
- public void visit(CDOAddFeatureDelta delta)
- {
- workList.add(delta.getIndex(), delta.getValue());
- }
-
- @Override
- public void visit(CDOClearFeatureDelta delta)
- {
- workList.clear();
- }
-
- @Override
- public void visit(CDOListFeatureDelta deltas)
- {
- @SuppressWarnings("unchecked")
- List<Object> list = (List<Object>)((InternalCDORevision)oldRevision).getValue(deltas.getFeature());
- if (list != null)
- {
- workList = new ArrayList<Object>(list);
- super.visit(deltas);
- }
- }
-
- @Override
- public void visit(CDOMoveFeatureDelta delta)
- {
- Object value = workList.get(delta.getOldPosition());
- ((CDOMoveFeatureDeltaImpl)delta).setValue(value);
- ECollections.move(workList, delta.getNewPosition(), delta.getOldPosition());
- }
-
- @Override
- public void visit(CDORemoveFeatureDelta delta)
- {
- Object oldValue = workList.remove(delta.getIndex());
- ((CDOSingleValueFeatureDeltaImpl)delta).setValue(oldValue);
- }
-
- @Override
- public void visit(CDOSetFeatureDelta delta)
- {
- EStructuralFeature feature = delta.getFeature();
- Object value = null;
- if (feature.isMany())
- {
- value = workList.set(delta.getIndex(), delta.getValue());
- }
- else
- {
- value = ((InternalCDORevision)oldRevision).getValue(feature);
- }
-
- ((CDOSetFeatureDeltaImpl)delta).setOldValue(value);
- }
- };
-
- for (CDOFeatureDelta featureDelta : revisionDelta.getFeatureDeltas())
- {
- featureDelta.accept(visitor);
- }
- }
- }
-
- CDOID id = key.getID();
- Pair<InternalCDORevision, InternalCDORevision> pair = createNewRevision(key, commitInfo);
- if (pair != null)
- {
- InternalCDORevision newRevision = pair.getElement2();
- revisionManager.addRevision(newRevision);
- if (oldRevisions == null)
- {
- oldRevisions = new HashMap<CDOID, InternalCDORevision>();
- }
-
- InternalCDORevision oldRevision = pair.getElement1();
- oldRevisions.put(id, oldRevision);
- }
- else
- {
- // ... otherwise try to revise old revision if it is in the same branch
- if (ObjectUtil.equals(key.getBranch(), newBranch))
- {
- revisionManager.reviseVersion(id, key, timeStamp);
- }
- }
- }
-
- // Revise old revisions
- for (CDOIDAndVersion key : commitInfo.getDetachedObjects())
- {
- CDOID id = key.getID();
- int version = key.getVersion();
- if (version == CDOBranchVersion.UNSPECIFIED_VERSION)
- {
- revisionManager.reviseLatest(id, newBranch);
- }
- else
- {
- CDOBranchVersion branchVersion = newBranch.getVersion(version);
- revisionManager.reviseVersion(id, branchVersion, timeStamp);
- }
- }
-
- return oldRevisions;
- }
-
- private Pair<InternalCDORevision, InternalCDORevision> createNewRevision(CDORevisionKey potentialDelta,
- CDOCommitInfo commitInfo)
- {
- if (potentialDelta instanceof CDORevisionDelta)
- {
- CDORevisionDelta delta = (CDORevisionDelta)potentialDelta;
- CDOID id = delta.getID();
-
- InternalCDORevisionManager revisionManager = getRevisionManager();
- InternalCDORevision oldRevision = revisionManager.getRevisionByVersion(id, potentialDelta, CDORevision.UNCHUNKED,
- false);
- if (oldRevision != null)
- {
- InternalCDORevision newRevision = oldRevision.copy();
- newRevision.adjustForCommit(commitInfo.getBranch(), commitInfo.getTimeStamp());
-
- CDORevisable target = delta.getTarget();
- if (target != null)
- {
- newRevision.setVersion(target.getVersion());
- }
-
- delta.apply(newRevision);
- newRevision.freeze();
- return new Pair<InternalCDORevision, InternalCDORevision>(oldRevision, newRevision);
- }
- }
-
- return null;
- }
-
- /**
- * @since 2.0
- */
- public void invalidate(CDOCommitInfo commitInfo, InternalCDOTransaction sender)
- {
- long previousTimeStamp = commitInfo.getPreviousTimeStamp();
- long lastUpdateTime = getLastUpdateTime();
-
- if (previousTimeStamp < lastUpdateTime)
- {
- previousTimeStamp = lastUpdateTime;
- }
-
- synchronized (outOfSequenceInvalidations)
- {
- outOfSequenceInvalidations.put(previousTimeStamp, new Pair<CDOCommitInfo, InternalCDOTransaction>(commitInfo,
- sender));
- }
-
- long nextPreviousTimeStamp = lastUpdateTime;
- for (;;)
- {
- synchronized (outOfSequenceInvalidations)
- {
- Pair<CDOCommitInfo, InternalCDOTransaction> currentPair = outOfSequenceInvalidations
- .remove(nextPreviousTimeStamp);
-
- // If we don't have the invalidation that follows the last one we processed,
- // then there is nothing we can do right now
- if (currentPair == null)
- {
- break;
- }
-
- final CDOCommitInfo currentCommitInfo = currentPair.getElement1();
- final InternalCDOTransaction currentSender = currentPair.getElement2();
- nextPreviousTimeStamp = currentCommitInfo.getTimeStamp();
-
- if (sender == null)
- {
- QueueRunner invalidationRunner = getInvalidationRunner();
- invalidationRunner.addWork(new Runnable()
- {
- public void run()
- {
- invalidateOrdered(currentCommitInfo, currentSender);
- }
- });
- }
- else
- {
- invalidateOrdered(currentCommitInfo, currentSender);
- }
- }
- }
- }
-
- /**
- * This method is synchronized on outOfSequenceInvalidations by the caller!
- */
- private QueueRunner getInvalidationRunner()
- {
- if (invalidationRunner == null)
- {
- invalidationRunner = new QueueRunner();
- invalidationRunner.activate();
- }
-
- return invalidationRunner;
- }
-
- private void invalidateOrdered(CDOCommitInfo commitInfo, InternalCDOTransaction sender)
- {
- Map<CDOID, InternalCDORevision> oldRevisions = null;
- boolean success = commitInfo.getBranch() != null;
- if (success)
- {
- oldRevisions = reviseRevisions(commitInfo);
- }
-
- if (options.isPassiveUpdateEnabled())
- {
- setLastUpdateTime(commitInfo.getTimeStamp());
- }
-
- if (success)
- {
- fireInvalidationEvent(sender, commitInfo);
- }
-
- for (InternalCDOView view : getViews())
- {
- if (view != sender)
- {
- invalidateView(commitInfo, view, oldRevisions);
- }
- else
- {
- view.setLastUpdateTime(commitInfo.getTimeStamp());
- }
- }
- }
-
- private void invalidateView(CDOCommitInfo commitInfo, InternalCDOView view,
- Map<CDOID, InternalCDORevision> oldRevisions)
- {
- try
- {
- CDOBranch branch = commitInfo.getBranch();
- long lastUpdateTime = commitInfo.getTimeStamp();
- List<CDORevisionKey> allChangedObjects = commitInfo.getChangedObjects();
- List<CDOIDAndVersion> allDetachedObjects = commitInfo.getDetachedObjects();
- view.invalidate(branch, lastUpdateTime, allChangedObjects, allDetachedObjects, oldRevisions, true);
- }
- catch (RuntimeException ex)
- {
- if (view.isActive())
- {
- OM.LOG.error(ex);
- }
- else
- {
- OM.LOG.info(Messages.getString("CDOSessionImpl.1")); //$NON-NLS-1$
- }
- }
- }
-
- /**
- * @since 2.0
- */
- public void fireInvalidationEvent(InternalCDOTransaction sender, CDOCommitInfo commitInfo)
- {
- fireEvent(new InvalidationEvent(sender, commitInfo));
- }
-
- @Override
- public String toString()
- {
- String name = repositoryInfo == null ? "?" : repositoryInfo.getName(); //$NON-NLS-1$
- return MessageFormat.format("Session{0} [{1}]", sessionID, name); //$NON-NLS-1$
- }
-
- public CDOBranchPoint getCommittedSinceLastRefresh(CDOID id)
- {
- if (isSticky())
- {
- return committedSinceLastRefresh.get(id);
- }
-
- return null;
- }
-
- public void setCommittedSinceLastRefresh(CDOID id, CDOBranchPoint branchPoint)
- {
- if (isSticky())
- {
- committedSinceLastRefresh.put(id, branchPoint);
- }
- }
-
- public void clearCommittedSinceLastRefresh()
- {
- if (isSticky())
- {
- committedSinceLastRefresh.clear();
- }
- }
-
- public boolean isSticky()
- {
- return !options().isPassiveUpdateEnabled() && getRepositoryInfo().isSupportingAudits();
- }
-
- public CDOChangeSetData compareRevisions(CDOBranchPoint source, CDOBranchPoint target)
- {
- long now = getLastUpdateTime();
-
- if (target.getTimeStamp() == CDOBranchPoint.UNSPECIFIED_DATE)
- {
- target = target.getBranch().getPoint(now);
- }
-
- if (source.getTimeStamp() == CDOBranchPoint.UNSPECIFIED_DATE)
- {
- source = source.getBranch().getPoint(now);
- }
-
- CDORevisionAvailabilityInfo targetInfo = createRevisionAvailabilityInfo(target);
- CDORevisionAvailabilityInfo sourceInfo = createRevisionAvailabilityInfo(source);
-
- Set<CDOID> ids = sessionProtocol.loadMergeData(targetInfo, sourceInfo, null, null);
-
- cacheRevisions(targetInfo);
- cacheRevisions(sourceInfo);
-
- return CDORevisionUtil.createChangeSetData(ids, sourceInfo, targetInfo);
- }
-
- public CDORevisionAvailabilityInfo createRevisionAvailabilityInfo(CDOBranchPoint branchPoint)
- {
- CDORevisionAvailabilityInfo info = new CDORevisionAvailabilityInfo(branchPoint);
-
- InternalCDORevisionManager revisionManager = getRevisionManager();
- InternalCDORevisionCache cache = revisionManager.getCache();
-
- List<CDORevision> revisions = cache.getRevisions(branchPoint);
- for (CDORevision revision : revisions)
- {
- if (revision instanceof PointerCDORevision)
- {
- PointerCDORevision pointer = (PointerCDORevision)revision;
- CDOBranchVersion target = pointer.getTarget();
- if (target != null)
- {
- revision = cache.getRevisionByVersion(pointer.getID(), target);
- }
- }
- else if (revision instanceof DetachedCDORevision)
- {
- revision = null;
- }
-
- if (revision != null)
- {
- resolveAllElementProxies(revision);
- info.addRevision(revision);
- }
- }
-
- return info;
- }
-
- public void cacheRevisions(CDORevisionAvailabilityInfo info)
- {
- InternalCDORevisionManager revisionManager = getRevisionManager();
- CDOBranch branch = info.getBranchPoint().getBranch();
- for (CDORevisionKey key : info.getAvailableRevisions().values())
- {
- CDORevision revision = (CDORevision)key;
- revisionManager.addRevision(revision);
-
- if (!ObjectUtil.equals(revision.getBranch(), branch))
- {
- CDOID id = revision.getID();
- CDORevision firstRevision = revisionManager.getCache().getRevisionByVersion(id,
- branch.getVersion(CDOBranchVersion.FIRST_VERSION));
- if (firstRevision != null)
- {
- long revised = firstRevision.getTimeStamp() - 1L;
- CDOBranchVersion target = CDOBranchUtil.copyBranchVersion(revision);
- PointerCDORevision pointer = new PointerCDORevision(revision.getEClass(), id, branch, revised, target);
- revisionManager.addRevision(pointer);
- }
- }
- }
- }
-
- @Override
- protected void doActivate() throws Exception
- {
- super.doActivate();
-
- InternalCDORemoteSessionManager remoteSessionManager = new CDORemoteSessionManagerImpl();
- remoteSessionManager.setLocalSession(this);
- setRemoteSessionManager(remoteSessionManager);
- remoteSessionManager.activate();
-
- checkState(sessionProtocol, "sessionProtocol"); //$NON-NLS-1$
- checkState(remoteSessionManager, "remoteSessionManager"); //$NON-NLS-1$
- }
-
- @Override
- protected void doDeactivate() throws Exception
- {
- super.doDeactivate();
-
- LifecycleUtil.deactivate(invalidationRunner);
- outOfSequenceInvalidations.clear();
-
- unhookSessionProtocol();
-
- CDORemoteSessionManager remoteSessionManager = getRemoteSessionManager();
- setRemoteSessionManager(null);
- LifecycleUtil.deactivate(remoteSessionManager);
-
- CDOSessionProtocol sessionProtocol = getSessionProtocol();
- LifecycleUtil.deactivate(sessionProtocol);
- setSessionProtocol(null);
- }
-
- /**
- * Makes this session start listening to its protocol
- */
- protected CDOSessionProtocol hookSessionProtocol()
- {
- EventUtil.addListener(sessionProtocol, sessionProtocolListener);
- return sessionProtocol;
- }
-
- /**
- * Makes this session stop listening to its protocol
- */
- protected void unhookSessionProtocol()
- {
- EventUtil.removeListener(sessionProtocol, sessionProtocolListener);
- }
-
- protected void sessionProtocolDeactivated()
- {
- deactivate();
- }
-
- /**
- * A separate class for better monitor debugging.
- *
- * @author Eike Stepper
- */
- private static final class LastUpdateTimeLock
- {
- }
-
- /**
- * @author Eike Stepper
- */
- private static final class OutOfSequenceInvalidations extends
- HashMap<Long, Pair<CDOCommitInfo, InternalCDOTransaction>>
- {
- private static final long serialVersionUID = 1L;
- }
-
- /**
- * @author Eike Stepper
- * @since 2.0
- */
- protected class OptionsImpl extends Notifier implements Options
- {
- private boolean generatedPackageEmulationEnabled;
-
- private boolean passiveUpdateEnabled = true;
-
- private PassiveUpdateMode passiveUpdateMode = PassiveUpdateMode.INVALIDATIONS;
-
- private LockNotificationMode lockNotificationMode = LockNotificationMode.IF_REQUIRED_BY_VIEWS;
-
- private CDOCollectionLoadingPolicy collectionLoadingPolicy;
-
- private CDOLobStore lobCache = CDOLobStoreImpl.INSTANCE;
-
- public OptionsImpl()
- {
- setCollectionLoadingPolicy(null); // Init default
- }
-
- public CDOSession getContainer()
- {
- return CDOSessionImpl.this;
- }
-
- public boolean isGeneratedPackageEmulationEnabled()
- {
- return generatedPackageEmulationEnabled;
- }
-
- public synchronized void setGeneratedPackageEmulationEnabled(boolean generatedPackageEmulationEnabled)
- {
- this.generatedPackageEmulationEnabled = generatedPackageEmulationEnabled;
- if (this.generatedPackageEmulationEnabled != generatedPackageEmulationEnabled)
- {
- this.generatedPackageEmulationEnabled = generatedPackageEmulationEnabled;
- // TODO Check inconsistent state if switching off?
-
- IListener[] listeners = getListeners();
- if (listeners != null)
- {
- fireEvent(new GeneratedPackageEmulationEventImpl(), listeners);
- }
- }
- }
-
- public boolean isPassiveUpdateEnabled()
- {
- return passiveUpdateEnabled;
- }
-
- public synchronized void setPassiveUpdateEnabled(boolean passiveUpdateEnabled)
- {
- if (this.passiveUpdateEnabled != passiveUpdateEnabled)
- {
- this.passiveUpdateEnabled = passiveUpdateEnabled;
- CDOSessionProtocol protocol = getSessionProtocol();
- if (protocol != null)
- {
- if (passiveUpdateEnabled)
- {
- refresh(true);
- }
- else
- {
- protocol.disablePassiveUpdate();
- }
-
- IListener[] listeners = getListeners();
- if (listeners != null)
- {
- fireEvent(new PassiveUpdateEventImpl(!passiveUpdateEnabled, passiveUpdateEnabled, passiveUpdateMode,
- passiveUpdateMode), listeners);
- }
- }
- }
- }
-
- public PassiveUpdateMode getPassiveUpdateMode()
- {
- return passiveUpdateMode;
- }
-
- public void setPassiveUpdateMode(PassiveUpdateMode passiveUpdateMode)
- {
- checkArg(passiveUpdateMode, "passiveUpdateMode"); //$NON-NLS-1$
- if (this.passiveUpdateMode != passiveUpdateMode)
- {
- PassiveUpdateMode oldMode = this.passiveUpdateMode;
- this.passiveUpdateMode = passiveUpdateMode;
- CDOSessionProtocol protocol = getSessionProtocol();
- if (protocol != null)
- {
- protocol.setPassiveUpdateMode(passiveUpdateMode);
-
- IListener[] listeners = getListeners();
- if (listeners != null)
- {
- fireEvent(
- new PassiveUpdateEventImpl(passiveUpdateEnabled, passiveUpdateEnabled, oldMode, passiveUpdateMode),
- listeners);
- }
- }
- }
- }
-
- public LockNotificationMode getLockNotificationMode()
- {
- return lockNotificationMode;
- }
-
- public void setLockNotificationMode(LockNotificationMode lockNotificationMode)
- {
- checkArg(lockNotificationMode, "lockNotificationMode"); //$NON-NLS-1$
- if (this.lockNotificationMode != lockNotificationMode)
- {
- LockNotificationMode oldMode = this.lockNotificationMode;
- this.lockNotificationMode = lockNotificationMode;
- CDOSessionProtocol protocol = getSessionProtocol();
- if (protocol != null)
- {
- protocol.setLockNotificationMode(lockNotificationMode);
-
- IListener[] listeners = getListeners();
- if (listeners != null)
- {
- fireEvent(new LockNotificationModeEventImpl(oldMode, lockNotificationMode), listeners);
- }
- }
- }
- this.lockNotificationMode = lockNotificationMode;
- }
-
- public CDOCollectionLoadingPolicy getCollectionLoadingPolicy()
- {
- synchronized (this)
- {
- return collectionLoadingPolicy;
- }
- }
-
- public void setCollectionLoadingPolicy(CDOCollectionLoadingPolicy policy)
- {
- if (policy == null)
- {
- policy = CDOUtil.createCollectionLoadingPolicy(CDORevision.UNCHUNKED, CDORevision.UNCHUNKED);
- }
-
- CDOSession oldSession = policy.getSession();
- if (oldSession != null)
- {
- throw new IllegalArgumentException("Policy is already associated with " + oldSession);
- }
-
- policy.setSession(CDOSessionImpl.this);
-
- IListener[] listeners = getListeners();
- IEvent event = null;
-
- synchronized (this)
- {
- if (collectionLoadingPolicy != policy)
- {
- collectionLoadingPolicy = policy;
- if (listeners != null)
- {
- event = new CollectionLoadingPolicyEventImpl();
- }
- }
- }
-
- if (event != null)
- {
- fireEvent(event, listeners);
- }
- }
-
- public CDOLobStore getLobCache()
- {
- synchronized (this)
- {
- return lobCache;
- }
- }
-
- public void setLobCache(CDOLobStore cache)
- {
- if (cache == null)
- {
- cache = CDOLobStoreImpl.INSTANCE;
- }
-
- IListener[] listeners = getListeners();
- IEvent event = null;
-
- synchronized (this)
- {
- if (lobCache != cache)
- {
- lobCache = cache;
- if (listeners != null)
- {
- event = new LobCacheEventImpl();
- }
- }
- }
-
- if (event != null)
- {
- fireEvent(event, listeners);
- }
- }
-
- /**
- * @author Eike Stepper
- */
- private final class GeneratedPackageEmulationEventImpl extends OptionsEvent implements
- GeneratedPackageEmulationEvent
- {
- private static final long serialVersionUID = 1L;
-
- public GeneratedPackageEmulationEventImpl()
- {
- super(OptionsImpl.this);
- }
- }
-
- /**
- * @author Eike Stepper
- */
- private final class PassiveUpdateEventImpl extends OptionsEvent implements PassiveUpdateEvent
- {
- private static final long serialVersionUID = 1L;
-
- private boolean oldEnabled;
-
- private boolean newEnabled;
-
- private PassiveUpdateMode oldMode;
-
- private PassiveUpdateMode newMode;
-
- public PassiveUpdateEventImpl(boolean oldEnabled, boolean newEnabled, PassiveUpdateMode oldMode,
- PassiveUpdateMode newMode)
- {
- super(OptionsImpl.this);
- this.oldEnabled = oldEnabled;
- this.newEnabled = newEnabled;
- this.oldMode = oldMode;
- this.newMode = newMode;
- }
-
- public boolean getOldEnabled()
- {
- return oldEnabled;
- }
-
- public boolean getNewEnabled()
- {
- return newEnabled;
- }
-
- public PassiveUpdateMode getOldMode()
- {
- return oldMode;
- }
-
- public PassiveUpdateMode getNewMode()
- {
- return newMode;
- }
- }
-
- /**
- * @author Caspar De Groot
- */
- private final class LockNotificationModeEventImpl extends OptionsEvent implements LockNotificationModeEvent
- {
- private static final long serialVersionUID = 1L;
-
- private LockNotificationMode oldMode, newMode;
-
- public LockNotificationModeEventImpl(LockNotificationMode oldMode, LockNotificationMode newMode)
- {
- super(OptionsImpl.this);
- this.oldMode = oldMode;
- this.newMode = newMode;
- }
-
- public LockNotificationMode getOldMode()
- {
- return oldMode;
- }
-
- public LockNotificationMode getNewMode()
- {
- return newMode;
- }
- }
-
- /**
- * @author Eike Stepper
- */
- private final class CollectionLoadingPolicyEventImpl extends OptionsEvent implements CollectionLoadingPolicyEvent
- {
- private static final long serialVersionUID = 1L;
-
- public CollectionLoadingPolicyEventImpl()
- {
- super(OptionsImpl.this);
- }
- }
-
- /**
- * @author Eike Stepper
- */
- private final class LobCacheEventImpl extends OptionsEvent implements LobCacheEvent
- {
- private static final long serialVersionUID = 1L;
-
- public LobCacheEventImpl()
- {
- super(OptionsImpl.this);
- }
- }
- }
-
- /**
- * @author Eike Stepper
- */
- private final class InvalidationEvent extends Event implements CDOSessionInvalidationEvent
- {
- private static final long serialVersionUID = 1L;
-
- private InternalCDOTransaction sender;
-
- private CDOCommitInfo commitInfo;
-
- public InvalidationEvent(InternalCDOTransaction sender, CDOCommitInfo commitInfo)
- {
- super(CDOSessionImpl.this);
- this.sender = sender;
- this.commitInfo = commitInfo;
- }
-
- @Override
- public CDOSession getSource()
- {
- return (CDOSession)super.getSource();
- }
-
- public CDOCommitInfoManager getCommitInfoManager()
- {
- return commitInfo.getCommitInfoManager();
- }
-
- public CDOTransaction getLocalTransaction()
- {
- return sender;
- }
-
- @Deprecated
- public InternalCDOView getView()
- {
- return sender;
- }
-
- public boolean isRemote()
- {
- return sender == null;
- }
-
- public CDOBranch getBranch()
- {
- return commitInfo.getBranch();
- }
-
- public long getTimeStamp()
- {
- return commitInfo.getTimeStamp();
- }
-
- public long getPreviousTimeStamp()
- {
- return commitInfo.getPreviousTimeStamp();
- }
-
- public String getUserID()
- {
- return commitInfo.getUserID();
- }
-
- public String getComment()
- {
- return commitInfo.getComment();
- }
-
- public boolean isEmpty()
- {
- return false;
- }
-
- public CDOChangeSetData copy()
- {
- return commitInfo.copy();
- }
-
- public void merge(CDOChangeSetData changeSetData)
- {
- commitInfo.merge(changeSetData);
- }
-
- public List<CDOPackageUnit> getNewPackageUnits()
- {
- return commitInfo.getNewPackageUnits();
- }
-
- public List<CDOIDAndVersion> getNewObjects()
- {
- return commitInfo.getNewObjects();
- }
-
- public List<CDORevisionKey> getChangedObjects()
- {
- return commitInfo.getChangedObjects();
- }
-
- public List<CDOIDAndVersion> getDetachedObjects()
- {
- return commitInfo.getDetachedObjects();
- }
-
- public Map<CDOID, CDOChangeKind> getChangeKinds()
- {
- return commitInfo.getChangeKinds();
- }
-
- public CDOChangeKind getChangeKind(CDOID id)
- {
- return commitInfo.getChangeKind(id);
- }
-
- @Override
- public String toString()
- {
- return "CDOSessionInvalidationEvent[" + commitInfo + "]"; //$NON-NLS-1$ //$NON-NLS-2$
- }
- }
-
- /**
- * @author Caspar De Groot
- * @since 4.1
- */
- private final class LocksChangedEvent extends DefaultLocksChangedEvent implements CDOSessionLocksChangedEvent
- {
- private static final long serialVersionUID = 1L;
-
- public LocksChangedEvent(InternalCDOView sender, CDOLockChangeInfo lockChangeInfo)
- {
- super(CDOSessionImpl.this, sender, lockChangeInfo);
- }
-
- @Override
- public CDOSession getSource()
- {
- return (CDOSession)super.getSource();
- }
- }
-}
+/*
+ * Copyright (c) 2004 - 2012 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
+ * Simon McDuff - bug 226778
+ * Simon McDuff - bug 230832
+ * Simon McDuff - bug 233490
+ * Simon McDuff - bug 213402
+ * Victor Roldan Betancort - maintenance
+ */
+package org.eclipse.emf.internal.cdo.session;
+
+import org.eclipse.emf.cdo.common.CDOCommonRepository;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
+import org.eclipse.emf.cdo.common.branch.CDOBranchVersion;
+import org.eclipse.emf.cdo.common.commit.CDOChangeKind;
+import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfoManager;
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDGenerator;
+import org.eclipse.emf.cdo.common.lob.CDOLobInfo;
+import org.eclipse.emf.cdo.common.lob.CDOLobStore;
+import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
+import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
+import org.eclipse.emf.cdo.common.model.EMFUtil;
+import org.eclipse.emf.cdo.common.protocol.CDOAuthenticator;
+import org.eclipse.emf.cdo.common.revision.CDOElementProxy;
+import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion;
+import org.eclipse.emf.cdo.common.revision.CDOList;
+import org.eclipse.emf.cdo.common.revision.CDORevisable;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
+import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
+import org.eclipse.emf.cdo.common.revision.delta.CDOAddFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
+import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOMoveFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDORemoveFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta;
+import org.eclipse.emf.cdo.common.util.CDOException;
+import org.eclipse.emf.cdo.common.util.RepositoryStateChangedEvent;
+import org.eclipse.emf.cdo.common.util.RepositoryTypeChangedEvent;
+import org.eclipse.emf.cdo.eresource.EresourcePackage;
+import org.eclipse.emf.cdo.etypes.EtypesPackage;
+import org.eclipse.emf.cdo.internal.common.revision.delta.CDOMoveFeatureDeltaImpl;
+import org.eclipse.emf.cdo.internal.common.revision.delta.CDOSetFeatureDeltaImpl;
+import org.eclipse.emf.cdo.internal.common.revision.delta.CDOSingleValueFeatureDeltaImpl;
+import org.eclipse.emf.cdo.session.CDOCollectionLoadingPolicy;
+import org.eclipse.emf.cdo.session.CDORepositoryInfo;
+import org.eclipse.emf.cdo.session.CDOSession;
+import org.eclipse.emf.cdo.session.CDOSessionInvalidationEvent;
+import org.eclipse.emf.cdo.session.CDOSessionLocksChangedEvent;
+import org.eclipse.emf.cdo.session.remote.CDORemoteSessionManager;
+import org.eclipse.emf.cdo.spi.common.CDOLobStoreImpl;
+import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
+import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranch;
+import org.eclipse.emf.cdo.spi.common.branch.InternalCDOBranchManager;
+import org.eclipse.emf.cdo.spi.common.commit.CDORevisionAvailabilityInfo;
+import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
+import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
+import org.eclipse.emf.cdo.spi.common.revision.CDOFeatureDeltaVisitorImpl;
+import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionCache;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionManager;
+import org.eclipse.emf.cdo.spi.common.revision.PointerCDORevision;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+import org.eclipse.emf.cdo.util.CDOUtil;
+import org.eclipse.emf.cdo.view.CDOFetchRuleManager;
+import org.eclipse.emf.cdo.view.CDOView;
+
+import org.eclipse.emf.internal.cdo.analyzer.NOOPFetchRuleManager;
+import org.eclipse.emf.internal.cdo.bundle.OM;
+import org.eclipse.emf.internal.cdo.messages.Messages;
+import org.eclipse.emf.internal.cdo.object.CDOFactoryImpl;
+import org.eclipse.emf.internal.cdo.session.remote.CDORemoteSessionManagerImpl;
+import org.eclipse.emf.internal.cdo.util.DefaultLocksChangedEvent;
+
+import org.eclipse.net4j.util.ObjectUtil;
+import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
+import org.eclipse.net4j.util.WrappedException;
+import org.eclipse.net4j.util.collection.Pair;
+import org.eclipse.net4j.util.concurrent.IRWLockManager;
+import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;
+import org.eclipse.net4j.util.concurrent.IRWOLockManager;
+import org.eclipse.net4j.util.concurrent.QueueRunner;
+import org.eclipse.net4j.util.concurrent.RWOLockManager;
+import org.eclipse.net4j.util.event.Event;
+import org.eclipse.net4j.util.event.EventUtil;
+import org.eclipse.net4j.util.event.IEvent;
+import org.eclipse.net4j.util.event.IListener;
+import org.eclipse.net4j.util.event.Notifier;
+import org.eclipse.net4j.util.io.IOUtil;
+import org.eclipse.net4j.util.lifecycle.ILifecycle;
+import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter;
+import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
+import org.eclipse.net4j.util.om.log.OMLogger;
+import org.eclipse.net4j.util.options.OptionsEvent;
+
+import org.eclipse.emf.common.util.ECollections;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.spi.cdo.CDOSessionProtocol;
+import org.eclipse.emf.spi.cdo.CDOSessionProtocol.RefreshSessionResult;
+import org.eclipse.emf.spi.cdo.InternalCDORemoteSessionManager;
+import org.eclipse.emf.spi.cdo.InternalCDOSession;
+import org.eclipse.emf.spi.cdo.InternalCDOTransaction;
+import org.eclipse.emf.spi.cdo.InternalCDOView;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * @author Eike Stepper
+ */
+public abstract class CDOSessionImpl extends CDOTransactionContainerImpl implements InternalCDOSession
+{
+ private ExceptionHandler exceptionHandler;
+
+ private CDOIDGenerator idGenerator;
+
+ private InternalCDOPackageRegistry packageRegistry;
+
+ private InternalCDOBranchManager branchManager;
+
+ private InternalCDORevisionManager revisionManager;
+
+ private InternalCDOCommitInfoManager commitInfoManager;
+
+ private CDOSessionProtocol sessionProtocol;
+
+ @ExcludeFromDump
+ private IListener sessionProtocolListener = new LifecycleEventAdapter()
+ {
+ @Override
+ protected void onDeactivated(ILifecycle lifecycle)
+ {
+ sessionProtocolDeactivated();
+ }
+ };
+
+ private int sessionID;
+
+ private String userID;
+
+ private long lastUpdateTime;
+
+ @ExcludeFromDump
+ private LastUpdateTimeLock lastUpdateTimeLock = new LastUpdateTimeLock();
+
+ private CDOSession.Options options = createOptions();
+
+ private OutOfSequenceInvalidations outOfSequenceInvalidations = new OutOfSequenceInvalidations();
+
+ private QueueRunner invalidationRunner;
+
+ private CDORepositoryInfo repositoryInfo;
+
+ private CDOFetchRuleManager fetchRuleManager;
+
+ private IRWOLockManager<CDOSessionImpl, Object> lockManager = new RWOLockManager<CDOSessionImpl, Object>();
+
+ @ExcludeFromDump
+ private Set<CDOSessionImpl> singletonCollection = Collections.singleton(this);
+
+ private boolean mainBranchLocal;
+
+ private CDOAuthenticator authenticator;
+
+ private InternalCDORemoteSessionManager remoteSessionManager;
+
+ /**
+ * A map to track for every object that was committed since this session's last refresh, onto what CDOBranchPoint it
+ * was committed. (Used only for sticky transactions, see bug 290032 - Sticky views.)
+ */
+ private Map<CDOID, CDOBranchPoint> committedSinceLastRefresh = new HashMap<CDOID, CDOBranchPoint>();
+
+ static
+ {
+ // Ensure that these 3 packages are registered with the global package registry in stand-alone
+ EcorePackage.eINSTANCE.getClass();
+ EresourcePackage.eINSTANCE.getClass();
+ EtypesPackage.eINSTANCE.getClass();
+ }
+
+ public CDOSessionImpl()
+ {
+ }
+
+ public CDORepositoryInfo getRepositoryInfo()
+ {
+ return repositoryInfo;
+ }
+
+ public void setRepositoryInfo(CDORepositoryInfo repositoryInfo)
+ {
+ this.repositoryInfo = repositoryInfo;
+ }
+
+ public int getSessionID()
+ {
+ return sessionID;
+ }
+
+ public void setSessionID(int sessionID)
+ {
+ this.sessionID = sessionID;
+ }
+
+ public String getUserID()
+ {
+ return userID;
+ }
+
+ public void setUserID(String userID)
+ {
+ this.userID = userID;
+ }
+
+ public ExceptionHandler getExceptionHandler()
+ {
+ return exceptionHandler;
+ }
+
+ public void setExceptionHandler(ExceptionHandler exceptionHandler)
+ {
+ checkInactive();
+ this.exceptionHandler = exceptionHandler;
+ }
+
+ public CDOIDGenerator getIDGenerator()
+ {
+ return idGenerator;
+ }
+
+ public void setIDGenerator(CDOIDGenerator idGenerator)
+ {
+ checkInactive();
+ this.idGenerator = idGenerator;
+ }
+
+ public InternalCDOPackageRegistry getPackageRegistry()
+ {
+ return packageRegistry;
+ }
+
+ public void setPackageRegistry(InternalCDOPackageRegistry packageRegistry)
+ {
+ this.packageRegistry = packageRegistry;
+ }
+
+ public InternalCDOBranchManager getBranchManager()
+ {
+ return branchManager;
+ }
+
+ public void setBranchManager(InternalCDOBranchManager branchManager)
+ {
+ checkInactive();
+ this.branchManager = branchManager;
+ }
+
+ public InternalCDORevisionManager getRevisionManager()
+ {
+ return revisionManager;
+ }
+
+ public void setRevisionManager(InternalCDORevisionManager revisionManager)
+ {
+ checkInactive();
+ this.revisionManager = revisionManager;
+ }
+
+ public InternalCDOCommitInfoManager getCommitInfoManager()
+ {
+ return commitInfoManager;
+ }
+
+ public void setCommitInfoManager(InternalCDOCommitInfoManager commitInfoManager)
+ {
+ checkInactive();
+ this.commitInfoManager = commitInfoManager;
+ }
+
+ public CDOSessionProtocol getSessionProtocol()
+ {
+ return sessionProtocol;
+ }
+
+ public void setSessionProtocol(CDOSessionProtocol sessionProtocol)
+ {
+ checkInactive();
+ if (exceptionHandler == null)
+ {
+ this.sessionProtocol = sessionProtocol;
+ }
+ else
+ {
+ if (this.sessionProtocol instanceof DelegatingSessionProtocol)
+ {
+ ((DelegatingSessionProtocol)this.sessionProtocol).setDelegate(sessionProtocol);
+ }
+ else
+ {
+ this.sessionProtocol = new DelegatingSessionProtocol(sessionProtocol, exceptionHandler);
+ }
+ }
+ }
+
+ /**
+ * @since 3.0
+ */
+ public CDOFetchRuleManager getFetchRuleManager()
+ {
+ return fetchRuleManager;
+ }
+
+ /**
+ * @since 3.0
+ */
+ public void setFetchRuleManager(CDOFetchRuleManager fetchRuleManager)
+ {
+ if (fetchRuleManager == null)
+ {
+ fetchRuleManager = new NOOPFetchRuleManager()
+ {
+ public CDOCollectionLoadingPolicy getCollectionLoadingPolicy()
+ {
+ return options().getCollectionLoadingPolicy();
+ }
+ };
+ }
+
+ this.fetchRuleManager = fetchRuleManager;
+ }
+
+ public CDOAuthenticator getAuthenticator()
+ {
+ return authenticator;
+ }
+
+ public void setAuthenticator(CDOAuthenticator authenticator)
+ {
+ this.authenticator = authenticator;
+ }
+
+ public boolean isMainBranchLocal()
+ {
+ return mainBranchLocal;
+ }
+
+ public void setMainBranchLocal(boolean mainBranchLocal)
+ {
+ this.mainBranchLocal = mainBranchLocal;
+ }
+
+ public InternalCDORemoteSessionManager getRemoteSessionManager()
+ {
+ return remoteSessionManager;
+ }
+
+ public void setRemoteSessionManager(InternalCDORemoteSessionManager remoteSessionManager)
+ {
+ this.remoteSessionManager = remoteSessionManager;
+ }
+
+ public CDOLobStore getLobStore()
+ {
+ final CDOLobStore cache = options().getLobCache();
+ return new CDOLobStore.Delegating()
+ {
+ @Override
+ public InputStream getBinary(final CDOLobInfo info) throws IOException
+ {
+ for (;;)
+ {
+ try
+ {
+ return super.getBinary(info);
+ }
+ catch (FileNotFoundException couldNotBeRead)
+ {
+ try
+ {
+ loadBinary(info);
+ }
+ catch (FileNotFoundException couldNotBeCreated)
+ {
+ // Try to read again
+ }
+ }
+ }
+ }
+
+ @Override
+ public Reader getCharacter(CDOLobInfo info) throws IOException
+ {
+ for (;;)
+ {
+ try
+ {
+ return super.getCharacter(info);
+ }
+ catch (FileNotFoundException couldNotBeRead)
+ {
+ try
+ {
+ loadCharacter(info);
+ }
+ catch (FileNotFoundException couldNotBeCreated)
+ {
+ // Try to read again
+ }
+ }
+ }
+ }
+
+ private void loadBinary(final CDOLobInfo info) throws IOException
+ {
+ final File file = getDelegate().getBinaryFile(info.getID());
+ final FileOutputStream out = new FileOutputStream(file);
+
+ loadLobAsync(info, new Runnable()
+ {
+ public void run()
+ {
+ try
+ {
+ getSessionProtocol().loadLob(info, out);
+ }
+ catch (Throwable t)
+ {
+ OM.LOG.error(t);
+ IOUtil.delete(file);
+ }
+ }
+ });
+ }
+
+ private void loadCharacter(final CDOLobInfo info) throws IOException
+ {
+ final File file = getDelegate().getCharacterFile(info.getID());
+ final FileWriter out = new FileWriter(file);
+
+ loadLobAsync(info, new Runnable()
+ {
+ public void run()
+ {
+ try
+ {
+ getSessionProtocol().loadLob(info, out);
+ }
+ catch (Throwable t)
+ {
+ OM.LOG.error(t);
+ IOUtil.delete(file);
+ }
+ }
+ });
+ }
+
+ @Override
+ protected CDOLobStore getDelegate()
+ {
+ return cache;
+ }
+ };
+ }
+
+ protected void loadLobAsync(CDOLobInfo info, Runnable runnable)
+ {
+ new Thread(runnable, "LobLoader").start();
+ }
+
+ public void close()
+ {
+ LifecycleUtil.deactivate(this, OMLogger.Level.DEBUG);
+ }
+
+ /**
+ * @since 2.0
+ */
+ public boolean isClosed()
+ {
+ return !isActive();
+ }
+
+ /**
+ * @since 2.0
+ */
+ public CDOSession.Options options()
+ {
+ return options;
+ }
+
+ /**
+ * @since 2.0
+ */
+ protected CDOSession.Options createOptions()
+ {
+ return new OptionsImpl();
+ }
+
+ public Object processPackage(Object value)
+ {
+ CDOFactoryImpl.prepareDynamicEPackage(value);
+ return value;
+ }
+
+ public EPackage[] loadPackages(CDOPackageUnit packageUnit)
+ {
+ if (packageUnit.getOriginalType().isGenerated())
+ {
+ if (!options().isGeneratedPackageEmulationEnabled())
+ {
+ throw new CDOException(MessageFormat.format(Messages.getString("CDOSessionImpl.0"), packageUnit)); //$NON-NLS-1$
+ }
+ }
+
+ return getSessionProtocol().loadPackages(packageUnit);
+ }
+
+ public void acquireAtomicRequestLock(Object key)
+ {
+ try
+ {
+ lockManager.lock(LockType.WRITE, key, this, IRWLockManager.WAIT);
+ }
+ catch (InterruptedException ex)
+ {
+ throw WrappedException.wrap(ex);
+ }
+ }
+
+ public void releaseAtomicRequestLock(Object key)
+ {
+ lockManager.unlock(LockType.WRITE, key, singletonCollection);
+ }
+
+ @Override
+ protected void initViewSynced(InternalCDOView view)
+ {
+ view.setSession(this);
+ view.setLastUpdateTime(getLastUpdateTime());
+ }
+
+ @Override
+ protected CDOBranch getMainBranch()
+ {
+ return getBranchManager().getMainBranch();
+ }
+
+ /**
+ * @since 2.0
+ */
+ public long refresh()
+ {
+ checkActive();
+ if (options().isPassiveUpdateEnabled())
+ {
+ return CDOBranchPoint.UNSPECIFIED_DATE;
+ }
+
+ return refresh(false);
+ }
+
+ private long refresh(boolean enablePassiveUpdates)
+ {
+ Map<CDOBranch, List<InternalCDOView>> views = new HashMap<CDOBranch, List<InternalCDOView>>();
+ Map<CDOBranch, Map<CDOID, InternalCDORevision>> viewedRevisions = new HashMap<CDOBranch, Map<CDOID, InternalCDORevision>>();
+ collectViewedRevisions(views, viewedRevisions);
+ cleanupRevisionCache(viewedRevisions);
+
+ CDOSessionProtocol sessionProtocol = getSessionProtocol();
+ long lastUpdateTime = getLastUpdateTime();
+ int initialChunkSize = options().getCollectionLoadingPolicy().getInitialChunkSize();
+
+ RefreshSessionResult result = sessionProtocol.refresh(lastUpdateTime, viewedRevisions, initialChunkSize,
+ enablePassiveUpdates);
+
+ setLastUpdateTime(result.getLastUpdateTime());
+ registerPackageUnits(result.getPackageUnits());
+
+ for (Entry<CDOBranch, List<InternalCDOView>> entry : views.entrySet())
+ {
+ CDOBranch branch = entry.getKey();
+ List<InternalCDOView> branchViews = entry.getValue();
+ processRefreshSessionResult(result, branch, branchViews, viewedRevisions);
+ }
+
+ return result.getLastUpdateTime();
+ }
+
+ public void processRefreshSessionResult(RefreshSessionResult result, CDOBranch branch,
+ List<InternalCDOView> branchViews, Map<CDOBranch, Map<CDOID, InternalCDORevision>> viewedRevisions)
+ {
+ Map<CDOID, InternalCDORevision> oldRevisions = viewedRevisions.get(branch);
+
+ List<CDORevisionKey> changedObjects = new ArrayList<CDORevisionKey>();
+ List<InternalCDORevision> newRevisions = result.getChangedObjects(branch);
+ for (InternalCDORevision newRevision : newRevisions)
+ {
+ getRevisionManager().addRevision(newRevision);
+
+ InternalCDORevision oldRevision = oldRevisions.get(newRevision.getID());
+ InternalCDORevisionDelta delta = newRevision.compare(oldRevision);
+ changedObjects.add(delta);
+ }
+
+ List<CDOIDAndVersion> detachedObjects = result.getDetachedObjects(branch);
+ for (CDOIDAndVersion detachedObject : detachedObjects)
+ {
+ getRevisionManager().reviseLatest(detachedObject.getID(), branch);
+ }
+
+ for (InternalCDOView view : branchViews)
+ {
+ view.invalidate(view.getBranch(), result.getLastUpdateTime(), changedObjects, detachedObjects, oldRevisions,
+ false);
+ }
+ }
+
+ private void collectViewedRevisions(Map<CDOBranch, List<InternalCDOView>> views,
+ Map<CDOBranch, Map<CDOID, InternalCDORevision>> viewedRevisions)
+ {
+ for (InternalCDOView view : getViews())
+ {
+ if (view.getTimeStamp() == CDOView.UNSPECIFIED_DATE)
+ {
+ CDOBranch branch = view.getBranch();
+ Map<CDOID, InternalCDORevision> revisions = viewedRevisions.get(branch);
+ boolean needNewMap = revisions == null;
+ if (needNewMap)
+ {
+ revisions = new HashMap<CDOID, InternalCDORevision>();
+ }
+
+ view.collectViewedRevisions(revisions);
+ if (!revisions.isEmpty())
+ {
+ List<InternalCDOView> list = views.get(branch);
+ if (list == null)
+ {
+ list = new ArrayList<InternalCDOView>();
+ views.put(branch, list);
+ }
+
+ list.add(view);
+
+ if (needNewMap)
+ {
+ viewedRevisions.put(branch, revisions);
+ }
+ }
+ }
+ }
+ }
+
+ private void cleanupRevisionCache(Map<CDOBranch, Map<CDOID, InternalCDORevision>> viewedRevisions)
+ {
+ Set<InternalCDORevision> set = new HashSet<InternalCDORevision>();
+ for (Map<CDOID, InternalCDORevision> revisions : viewedRevisions.values())
+ {
+ for (InternalCDORevision revision : revisions.values())
+ {
+ set.add(revision);
+ }
+ }
+
+ InternalCDORevisionCache cache = getRevisionManager().getCache();
+ List<CDORevision> currentRevisions = cache.getCurrentRevisions();
+ for (CDORevision revision : currentRevisions)
+ {
+ if (!set.contains(revision))
+ {
+ cache.removeRevision(revision.getID(), revision);
+ }
+ }
+ }
+
+ public long getLastUpdateTime()
+ {
+ synchronized (lastUpdateTimeLock)
+ {
+ return lastUpdateTime;
+ }
+ }
+
+ public void setLastUpdateTime(long lastUpdateTime)
+ {
+ synchronized (lastUpdateTimeLock)
+ {
+ if (this.lastUpdateTime < lastUpdateTime)
+ {
+ this.lastUpdateTime = lastUpdateTime;
+ }
+
+ lastUpdateTimeLock.notifyAll();
+ }
+ }
+
+ public void waitForUpdate(long updateTime)
+ {
+ waitForUpdate(updateTime, NO_TIMEOUT);
+ }
+
+ public boolean waitForUpdate(long updateTime, long timeoutMillis)
+ {
+ long end = timeoutMillis == NO_TIMEOUT ? Long.MAX_VALUE : System.currentTimeMillis() + timeoutMillis;
+ InternalCDOView views[] = getViews();
+ if (views.length > 0)
+ {
+ for (CDOView view : views)
+ {
+ long viewTimeoutMillis = timeoutMillis == NO_TIMEOUT ? NO_TIMEOUT : end - System.currentTimeMillis();
+ boolean ok = view.waitForUpdate(updateTime, viewTimeoutMillis);
+ if (!ok)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ // Session without views
+ for (;;)
+ {
+ synchronized (lastUpdateTimeLock)
+ {
+ if (lastUpdateTime >= updateTime)
+ {
+ return true;
+ }
+
+ long now = System.currentTimeMillis();
+ if (now >= end)
+ {
+ return false;
+ }
+
+ try
+ {
+ lastUpdateTimeLock.wait(end - now);
+ }
+ catch (InterruptedException ex)
+ {
+ throw WrappedException.wrap(ex);
+ }
+ }
+ }
+ }
+
+ /**
+ * @since 3.0
+ */
+ public Object resolveElementProxy(CDORevision revision, EStructuralFeature feature, int accessIndex, int serverIndex)
+ {
+ if (!((InternalCDORevision)revision).isUnchunked())
+ {
+ CDOCollectionLoadingPolicy policy = options().getCollectionLoadingPolicy();
+ return policy.resolveProxy(revision, feature, accessIndex, serverIndex);
+ }
+
+ return revision.data().get(feature, accessIndex);
+ }
+
+ /**
+ * @since 4.0
+ */
+ public void resolveAllElementProxies(CDORevision revision)
+ {
+ if (!((InternalCDORevision)revision).isUnchunked())
+ {
+ CDOCollectionLoadingPolicy policy = options().getCollectionLoadingPolicy();
+ for (EStructuralFeature feature : revision.getEClass().getEAllStructuralFeatures())
+ {
+ if (feature instanceof EReference)
+ {
+ EReference reference = (EReference)feature;
+ if (reference.isMany() && EMFUtil.isPersistent(reference))
+ {
+ CDOList list = ((InternalCDORevision)revision).getList(reference);
+ for (Iterator<Object> it = list.iterator(); it.hasNext();)
+ {
+ Object element = it.next();
+ if (element instanceof CDOElementProxy)
+ {
+ policy.resolveAllProxies(revision, reference);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ ((InternalCDORevision)revision).setUnchunked();
+ }
+ }
+
+ public void handleRepositoryTypeChanged(CDOCommonRepository.Type oldType, CDOCommonRepository.Type newType)
+ {
+ fireEvent(new RepositoryTypeChangedEvent(this, oldType, newType));
+ }
+
+ public void handleRepositoryStateChanged(CDOCommonRepository.State oldState, CDOCommonRepository.State newState)
+ {
+ fireEvent(new RepositoryStateChangedEvent(this, oldState, newState));
+ }
+
+ public void handleBranchNotification(InternalCDOBranch branch)
+ {
+ getBranchManager().handleBranchCreated(branch);
+ }
+
+ public void handleCommitNotification(CDOCommitInfo commitInfo)
+ {
+ try
+ {
+ registerPackageUnits(commitInfo.getNewPackageUnits());
+ invalidate(commitInfo, null);
+ }
+ catch (RuntimeException ex)
+ {
+ if (isActive())
+ {
+ OM.LOG.error(ex);
+ }
+ else
+ {
+ OM.LOG.info(Messages.getString("CDOSessionImpl.2")); //$NON-NLS-1$
+ }
+ }
+ }
+
+ public void handleLockNotification(CDOLockChangeInfo lockChangeInfo, InternalCDOView sender)
+ {
+ for (InternalCDOView view : getViews())
+ {
+ if (view != sender)
+ {
+ view.handleLockNotification(sender, lockChangeInfo);
+ }
+ }
+
+ fireEvent(new LocksChangedEvent(sender, lockChangeInfo));
+ }
+
+ private void registerPackageUnits(List<CDOPackageUnit> packageUnits)
+ {
+ InternalCDOPackageRegistry packageRegistry = getPackageRegistry();
+ for (CDOPackageUnit newPackageUnit : packageUnits)
+ {
+ packageRegistry.putPackageUnit((InternalCDOPackageUnit)newPackageUnit);
+ }
+ }
+
+ private Map<CDOID, InternalCDORevision> reviseRevisions(CDOCommitInfo commitInfo)
+ {
+ Map<CDOID, InternalCDORevision> oldRevisions = null;
+ CDOBranch newBranch = commitInfo.getBranch();
+ long timeStamp = commitInfo.getTimeStamp();
+ InternalCDORevisionManager revisionManager = getRevisionManager();
+
+ // Cache new revisions
+ for (CDOIDAndVersion key : commitInfo.getNewObjects())
+ {
+ if (key instanceof InternalCDORevision)
+ {
+ InternalCDORevision newRevision = (InternalCDORevision)key;
+ revisionManager.addRevision(newRevision);
+ }
+ }
+
+ // Apply deltas and cache the resulting new revisions, if possible...
+ for (CDORevisionKey key : commitInfo.getChangedObjects())
+ {
+ // Add old values to revision deltas.
+ if (key instanceof CDORevisionDelta)
+ {
+ final CDORevisionDelta revisionDelta = (CDORevisionDelta)key;
+ final CDORevision oldRevision = revisionManager.getRevisionByVersion(revisionDelta.getID(), revisionDelta,
+ CDORevision.UNCHUNKED, false);
+
+ if (oldRevision != null)
+ {
+ CDOFeatureDeltaVisitor visitor = new CDOFeatureDeltaVisitorImpl()
+ {
+ private List<Object> workList;
+
+ @Override
+ public void visit(CDOAddFeatureDelta delta)
+ {
+ workList.add(delta.getIndex(), delta.getValue());
+ }
+
+ @Override
+ public void visit(CDOClearFeatureDelta delta)
+ {
+ workList.clear();
+ }
+
+ @Override
+ public void visit(CDOListFeatureDelta deltas)
+ {
+ @SuppressWarnings("unchecked")
+ List<Object> list = (List<Object>)((InternalCDORevision)oldRevision).getValue(deltas.getFeature());
+ if (list != null)
+ {
+ workList = new ArrayList<Object>(list);
+ super.visit(deltas);
+ }
+ }
+
+ @Override
+ public void visit(CDOMoveFeatureDelta delta)
+ {
+ Object value = workList.get(delta.getOldPosition());
+ ((CDOMoveFeatureDeltaImpl)delta).setValue(value);
+ ECollections.move(workList, delta.getNewPosition(), delta.getOldPosition());
+ }
+
+ @Override
+ public void visit(CDORemoveFeatureDelta delta)
+ {
+ Object oldValue = workList.remove(delta.getIndex());
+ ((CDOSingleValueFeatureDeltaImpl)delta).setValue(oldValue);
+ }
+
+ @Override
+ public void visit(CDOSetFeatureDelta delta)
+ {
+ EStructuralFeature feature = delta.getFeature();
+ Object value = null;
+ if (feature.isMany())
+ {
+ value = workList.set(delta.getIndex(), delta.getValue());
+ }
+ else
+ {
+ value = ((InternalCDORevision)oldRevision).getValue(feature);
+ }
+
+ ((CDOSetFeatureDeltaImpl)delta).setOldValue(value);
+ }
+ };
+
+ for (CDOFeatureDelta featureDelta : revisionDelta.getFeatureDeltas())
+ {
+ featureDelta.accept(visitor);
+ }
+ }
+ }
+
+ CDOID id = key.getID();
+ Pair<InternalCDORevision, InternalCDORevision> pair = createNewRevision(key, commitInfo);
+ if (pair != null)
+ {
+ InternalCDORevision newRevision = pair.getElement2();
+ revisionManager.addRevision(newRevision);
+ if (oldRevisions == null)
+ {
+ oldRevisions = new HashMap<CDOID, InternalCDORevision>();
+ }
+
+ InternalCDORevision oldRevision = pair.getElement1();
+ oldRevisions.put(id, oldRevision);
+ }
+ else
+ {
+ // ... otherwise try to revise old revision if it is in the same branch
+ if (ObjectUtil.equals(key.getBranch(), newBranch))
+ {
+ revisionManager.reviseVersion(id, key, timeStamp);
+ }
+ }
+ }
+
+ // Revise old revisions
+ for (CDOIDAndVersion key : commitInfo.getDetachedObjects())
+ {
+ CDOID id = key.getID();
+ int version = key.getVersion();
+ if (version == CDOBranchVersion.UNSPECIFIED_VERSION)
+ {
+ revisionManager.reviseLatest(id, newBranch);
+ }
+ else
+ {
+ CDOBranchVersion branchVersion = newBranch.getVersion(version);
+ revisionManager.reviseVersion(id, branchVersion, timeStamp);
+ }
+ }
+
+ return oldRevisions;
+ }
+
+ private Pair<InternalCDORevision, InternalCDORevision> createNewRevision(CDORevisionKey potentialDelta,
+ CDOCommitInfo commitInfo)
+ {
+ if (potentialDelta instanceof CDORevisionDelta)
+ {
+ CDORevisionDelta delta = (CDORevisionDelta)potentialDelta;
+ CDOID id = delta.getID();
+
+ InternalCDORevisionManager revisionManager = getRevisionManager();
+ InternalCDORevision oldRevision = revisionManager.getRevisionByVersion(id, potentialDelta, CDORevision.UNCHUNKED,
+ false);
+ if (oldRevision != null)
+ {
+ InternalCDORevision newRevision = oldRevision.copy();
+ newRevision.adjustForCommit(commitInfo.getBranch(), commitInfo.getTimeStamp());
+
+ CDORevisable target = delta.getTarget();
+ if (target != null)
+ {
+ newRevision.setVersion(target.getVersion());
+ }
+
+ delta.apply(newRevision);
+ newRevision.freeze();
+ return new Pair<InternalCDORevision, InternalCDORevision>(oldRevision, newRevision);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void invalidate(CDOCommitInfo commitInfo, InternalCDOTransaction sender)
+ {
+ long previousTimeStamp = commitInfo.getPreviousTimeStamp();
+ long lastUpdateTime = getLastUpdateTime();
+
+ if (previousTimeStamp < lastUpdateTime)
+ {
+ previousTimeStamp = lastUpdateTime;
+ }
+
+ synchronized (outOfSequenceInvalidations)
+ {
+ outOfSequenceInvalidations.put(previousTimeStamp, new Pair<CDOCommitInfo, InternalCDOTransaction>(commitInfo,
+ sender));
+ }
+
+ long nextPreviousTimeStamp = lastUpdateTime;
+ for (;;)
+ {
+ synchronized (outOfSequenceInvalidations)
+ {
+ Pair<CDOCommitInfo, InternalCDOTransaction> currentPair = outOfSequenceInvalidations
+ .remove(nextPreviousTimeStamp);
+
+ // If we don't have the invalidation that follows the last one we processed,
+ // then there is nothing we can do right now
+ if (currentPair == null)
+ {
+ break;
+ }
+
+ final CDOCommitInfo currentCommitInfo = currentPair.getElement1();
+ final InternalCDOTransaction currentSender = currentPair.getElement2();
+ nextPreviousTimeStamp = currentCommitInfo.getTimeStamp();
+
+ if (sender == null)
+ {
+ QueueRunner invalidationRunner = getInvalidationRunner();
+ invalidationRunner.addWork(new Runnable()
+ {
+ public void run()
+ {
+ invalidateOrdered(currentCommitInfo, currentSender);
+ }
+ });
+ }
+ else
+ {
+ invalidateOrdered(currentCommitInfo, currentSender);
+ }
+ }
+ }
+ }
+
+ /**
+ * This method is synchronized on outOfSequenceInvalidations by the caller!
+ */
+ private QueueRunner getInvalidationRunner()
+ {
+ if (invalidationRunner == null)
+ {
+ invalidationRunner = new QueueRunner();
+ invalidationRunner.activate();
+ }
+
+ return invalidationRunner;
+ }
+
+ private void invalidateOrdered(CDOCommitInfo commitInfo, InternalCDOTransaction sender)
+ {
+ Map<CDOID, InternalCDORevision> oldRevisions = null;
+ boolean success = commitInfo.getBranch() != null;
+ if (success)
+ {
+ oldRevisions = reviseRevisions(commitInfo);
+ }
+
+ if (options.isPassiveUpdateEnabled())
+ {
+ setLastUpdateTime(commitInfo.getTimeStamp());
+ }
+
+ if (success)
+ {
+ fireInvalidationEvent(sender, commitInfo);
+ }
+
+ for (InternalCDOView view : getViews())
+ {
+ if (view != sender)
+ {
+ invalidateView(commitInfo, view, oldRevisions);
+ }
+ else
+ {
+ view.setLastUpdateTime(commitInfo.getTimeStamp());
+ }
+ }
+ }
+
+ private void invalidateView(CDOCommitInfo commitInfo, InternalCDOView view,
+ Map<CDOID, InternalCDORevision> oldRevisions)
+ {
+ try
+ {
+ CDOBranch branch = commitInfo.getBranch();
+ long lastUpdateTime = commitInfo.getTimeStamp();
+ List<CDORevisionKey> allChangedObjects = commitInfo.getChangedObjects();
+ List<CDOIDAndVersion> allDetachedObjects = commitInfo.getDetachedObjects();
+ view.invalidate(branch, lastUpdateTime, allChangedObjects, allDetachedObjects, oldRevisions, true);
+ }
+ catch (RuntimeException ex)
+ {
+ if (view.isActive())
+ {
+ OM.LOG.error(ex);
+ }
+ else
+ {
+ OM.LOG.info(Messages.getString("CDOSessionImpl.1")); //$NON-NLS-1$
+ }
+ }
+ }
+
+ /**
+ * @since 2.0
+ */
+ public void fireInvalidationEvent(InternalCDOTransaction sender, CDOCommitInfo commitInfo)
+ {
+ fireEvent(new InvalidationEvent(sender, commitInfo));
+ }
+
+ @Override
+ public String toString()
+ {
+ String name = repositoryInfo == null ? "?" : repositoryInfo.getName(); //$NON-NLS-1$
+ return MessageFormat.format("Session{0} [{1}]", sessionID, name); //$NON-NLS-1$
+ }
+
+ public CDOBranchPoint getCommittedSinceLastRefresh(CDOID id)
+ {
+ if (isSticky())
+ {
+ return committedSinceLastRefresh.get(id);
+ }
+
+ return null;
+ }
+
+ public void setCommittedSinceLastRefresh(CDOID id, CDOBranchPoint branchPoint)
+ {
+ if (isSticky())
+ {
+ committedSinceLastRefresh.put(id, branchPoint);
+ }
+ }
+
+ public void clearCommittedSinceLastRefresh()
+ {
+ if (isSticky())
+ {
+ committedSinceLastRefresh.clear();
+ }
+ }
+
+ public boolean isSticky()
+ {
+ return !options().isPassiveUpdateEnabled() && getRepositoryInfo().isSupportingAudits();
+ }
+
+ public CDOChangeSetData compareRevisions(CDOBranchPoint source, CDOBranchPoint target)
+ {
+ long now = getLastUpdateTime();
+
+ if (target.getTimeStamp() == CDOBranchPoint.UNSPECIFIED_DATE)
+ {
+ target = target.getBranch().getPoint(now);
+ }
+
+ if (source.getTimeStamp() == CDOBranchPoint.UNSPECIFIED_DATE)
+ {
+ source = source.getBranch().getPoint(now);
+ }
+
+ CDORevisionAvailabilityInfo targetInfo = createRevisionAvailabilityInfo(target);
+ CDORevisionAvailabilityInfo sourceInfo = createRevisionAvailabilityInfo(source);
+
+ Set<CDOID> ids = sessionProtocol.loadMergeData(targetInfo, sourceInfo, null, null);
+
+ cacheRevisions(targetInfo);
+ cacheRevisions(sourceInfo);
+
+ return CDORevisionUtil.createChangeSetData(ids, sourceInfo, targetInfo);
+ }
+
+ public CDORevisionAvailabilityInfo createRevisionAvailabilityInfo(CDOBranchPoint branchPoint)
+ {
+ CDORevisionAvailabilityInfo info = new CDORevisionAvailabilityInfo(branchPoint);
+
+ InternalCDORevisionManager revisionManager = getRevisionManager();
+ InternalCDORevisionCache cache = revisionManager.getCache();
+
+ List<CDORevision> revisions = cache.getRevisions(branchPoint);
+ for (CDORevision revision : revisions)
+ {
+ if (revision instanceof PointerCDORevision)
+ {
+ PointerCDORevision pointer = (PointerCDORevision)revision;
+ CDOBranchVersion target = pointer.getTarget();
+ if (target != null)
+ {
+ revision = cache.getRevisionByVersion(pointer.getID(), target);
+ }
+ }
+ else if (revision instanceof DetachedCDORevision)
+ {
+ revision = null;
+ }
+
+ if (revision != null)
+ {
+ resolveAllElementProxies(revision);
+ info.addRevision(revision);
+ }
+ }
+
+ return info;
+ }
+
+ public void cacheRevisions(CDORevisionAvailabilityInfo info)
+ {
+ InternalCDORevisionManager revisionManager = getRevisionManager();
+ CDOBranch branch = info.getBranchPoint().getBranch();
+ for (CDORevisionKey key : info.getAvailableRevisions().values())
+ {
+ CDORevision revision = (CDORevision)key;
+ revisionManager.addRevision(revision);
+
+ if (!ObjectUtil.equals(revision.getBranch(), branch))
+ {
+ CDOID id = revision.getID();
+ CDORevision firstRevision = revisionManager.getCache().getRevisionByVersion(id,
+ branch.getVersion(CDOBranchVersion.FIRST_VERSION));
+ if (firstRevision != null)
+ {
+ long revised = firstRevision.getTimeStamp() - 1L;
+ CDOBranchVersion target = CDOBranchUtil.copyBranchVersion(revision);
+ PointerCDORevision pointer = new PointerCDORevision(revision.getEClass(), id, branch, revised, target);
+ revisionManager.addRevision(pointer);
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void doActivate() throws Exception
+ {
+ super.doActivate();
+
+ InternalCDORemoteSessionManager remoteSessionManager = new CDORemoteSessionManagerImpl();
+ remoteSessionManager.setLocalSession(this);
+ setRemoteSessionManager(remoteSessionManager);
+ remoteSessionManager.activate();
+
+ checkState(sessionProtocol, "sessionProtocol"); //$NON-NLS-1$
+ checkState(remoteSessionManager, "remoteSessionManager"); //$NON-NLS-1$
+ }
+
+ @Override
+ protected void doDeactivate() throws Exception
+ {
+ super.doDeactivate();
+
+ LifecycleUtil.deactivate(invalidationRunner);
+ outOfSequenceInvalidations.clear();
+
+ unhookSessionProtocol();
+
+ CDORemoteSessionManager remoteSessionManager = getRemoteSessionManager();
+ setRemoteSessionManager(null);
+ LifecycleUtil.deactivate(remoteSessionManager);
+
+ CDOSessionProtocol sessionProtocol = getSessionProtocol();
+ LifecycleUtil.deactivate(sessionProtocol);
+ setSessionProtocol(null);
+ }
+
+ /**
+ * Makes this session start listening to its protocol
+ */
+ protected CDOSessionProtocol hookSessionProtocol()
+ {
+ EventUtil.addListener(sessionProtocol, sessionProtocolListener);
+ return sessionProtocol;
+ }
+
+ /**
+ * Makes this session stop listening to its protocol
+ */
+ protected void unhookSessionProtocol()
+ {
+ EventUtil.removeListener(sessionProtocol, sessionProtocolListener);
+ }
+
+ protected void sessionProtocolDeactivated()
+ {
+ deactivate();
+ }
+
+ /**
+ * A separate class for better monitor debugging.
+ *
+ * @author Eike Stepper
+ */
+ private static final class LastUpdateTimeLock
+ {
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private static final class OutOfSequenceInvalidations extends
+ HashMap<Long, Pair<CDOCommitInfo, InternalCDOTransaction>>
+ {
+ private static final long serialVersionUID = 1L;
+ }
+
+ /**
+ * @author Eike Stepper
+ * @since 2.0
+ */
+ protected class OptionsImpl extends Notifier implements Options
+ {
+ private boolean generatedPackageEmulationEnabled;
+
+ private boolean passiveUpdateEnabled = true;
+
+ private PassiveUpdateMode passiveUpdateMode = PassiveUpdateMode.INVALIDATIONS;
+
+ private LockNotificationMode lockNotificationMode = LockNotificationMode.IF_REQUIRED_BY_VIEWS;
+
+ private CDOCollectionLoadingPolicy collectionLoadingPolicy;
+
+ private CDOLobStore lobCache = CDOLobStoreImpl.INSTANCE;
+
+ public OptionsImpl()
+ {
+ setCollectionLoadingPolicy(null); // Init default
+ }
+
+ public CDOSession getContainer()
+ {
+ return CDOSessionImpl.this;
+ }
+
+ public boolean isGeneratedPackageEmulationEnabled()
+ {
+ return generatedPackageEmulationEnabled;
+ }
+
+ public synchronized void setGeneratedPackageEmulationEnabled(boolean generatedPackageEmulationEnabled)
+ {
+ this.generatedPackageEmulationEnabled = generatedPackageEmulationEnabled;
+ if (this.generatedPackageEmulationEnabled != generatedPackageEmulationEnabled)
+ {
+ this.generatedPackageEmulationEnabled = generatedPackageEmulationEnabled;
+ // TODO Check inconsistent state if switching off?
+
+ IListener[] listeners = getListeners();
+ if (listeners != null)
+ {
+ fireEvent(new GeneratedPackageEmulationEventImpl(), listeners);
+ }
+ }
+ }
+
+ public boolean isPassiveUpdateEnabled()
+ {
+ return passiveUpdateEnabled;
+ }
+
+ public synchronized void setPassiveUpdateEnabled(boolean passiveUpdateEnabled)
+ {
+ if (this.passiveUpdateEnabled != passiveUpdateEnabled)
+ {
+ this.passiveUpdateEnabled = passiveUpdateEnabled;
+ CDOSessionProtocol protocol = getSessionProtocol();
+ if (protocol != null)
+ {
+ if (passiveUpdateEnabled)
+ {
+ refresh(true);
+ }
+ else
+ {
+ protocol.disablePassiveUpdate();
+ }
+
+ IListener[] listeners = getListeners();
+ if (listeners != null)
+ {
+ fireEvent(new PassiveUpdateEventImpl(!passiveUpdateEnabled, passiveUpdateEnabled, passiveUpdateMode,
+ passiveUpdateMode), listeners);
+ }
+ }
+ }
+ }
+
+ public PassiveUpdateMode getPassiveUpdateMode()
+ {
+ return passiveUpdateMode;
+ }
+
+ public void setPassiveUpdateMode(PassiveUpdateMode passiveUpdateMode)
+ {
+ checkArg(passiveUpdateMode, "passiveUpdateMode"); //$NON-NLS-1$
+ if (this.passiveUpdateMode != passiveUpdateMode)
+ {
+ PassiveUpdateMode oldMode = this.passiveUpdateMode;
+ this.passiveUpdateMode = passiveUpdateMode;
+ CDOSessionProtocol protocol = getSessionProtocol();
+ if (protocol != null)
+ {
+ protocol.setPassiveUpdateMode(passiveUpdateMode);
+
+ IListener[] listeners = getListeners();
+ if (listeners != null)
+ {
+ fireEvent(
+ new PassiveUpdateEventImpl(passiveUpdateEnabled, passiveUpdateEnabled, oldMode, passiveUpdateMode),
+ listeners);
+ }
+ }
+ }
+ }
+
+ public LockNotificationMode getLockNotificationMode()
+ {
+ return lockNotificationMode;
+ }
+
+ public void setLockNotificationMode(LockNotificationMode lockNotificationMode)
+ {
+ checkArg(lockNotificationMode, "lockNotificationMode"); //$NON-NLS-1$
+ if (this.lockNotificationMode != lockNotificationMode)
+ {
+ LockNotificationMode oldMode = this.lockNotificationMode;
+ this.lockNotificationMode = lockNotificationMode;
+ CDOSessionProtocol protocol = getSessionProtocol();
+ if (protocol != null)
+ {
+ protocol.setLockNotificationMode(lockNotificationMode);
+
+ IListener[] listeners = getListeners();
+ if (listeners != null)
+ {
+ fireEvent(new LockNotificationModeEventImpl(oldMode, lockNotificationMode), listeners);
+ }
+ }
+ }
+ this.lockNotificationMode = lockNotificationMode;
+ }
+
+ public CDOCollectionLoadingPolicy getCollectionLoadingPolicy()
+ {
+ synchronized (this)
+ {
+ return collectionLoadingPolicy;
+ }
+ }
+
+ public void setCollectionLoadingPolicy(CDOCollectionLoadingPolicy policy)
+ {
+ if (policy == null)
+ {
+ policy = CDOUtil.createCollectionLoadingPolicy(CDORevision.UNCHUNKED, CDORevision.UNCHUNKED);
+ }
+
+ CDOSession oldSession = policy.getSession();
+ if (oldSession != null)
+ {
+ throw new IllegalArgumentException("Policy is already associated with " + oldSession);
+ }
+
+ policy.setSession(CDOSessionImpl.this);
+
+ IListener[] listeners = getListeners();
+ IEvent event = null;
+
+ synchronized (this)
+ {
+ if (collectionLoadingPolicy != policy)
+ {
+ collectionLoadingPolicy = policy;
+ if (listeners != null)
+ {
+ event = new CollectionLoadingPolicyEventImpl();
+ }
+ }
+ }
+
+ if (event != null)
+ {
+ fireEvent(event, listeners);
+ }
+ }
+
+ public CDOLobStore getLobCache()
+ {
+ synchronized (this)
+ {
+ return lobCache;
+ }
+ }
+
+ public void setLobCache(CDOLobStore cache)
+ {
+ if (cache == null)
+ {
+ cache = CDOLobStoreImpl.INSTANCE;
+ }
+
+ IListener[] listeners = getListeners();
+ IEvent event = null;
+
+ synchronized (this)
+ {
+ if (lobCache != cache)
+ {
+ lobCache = cache;
+ if (listeners != null)
+ {
+ event = new LobCacheEventImpl();
+ }
+ }
+ }
+
+ if (event != null)
+ {
+ fireEvent(event, listeners);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private final class GeneratedPackageEmulationEventImpl extends OptionsEvent implements
+ GeneratedPackageEmulationEvent
+ {
+ private static final long serialVersionUID = 1L;
+
+ public GeneratedPackageEmulationEventImpl()
+ {
+ super(OptionsImpl.this);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private final class PassiveUpdateEventImpl extends OptionsEvent implements PassiveUpdateEvent
+ {
+ private static final long serialVersionUID = 1L;
+
+ private boolean oldEnabled;
+
+ private boolean newEnabled;
+
+ private PassiveUpdateMode oldMode;
+
+ private PassiveUpdateMode newMode;
+
+ public PassiveUpdateEventImpl(boolean oldEnabled, boolean newEnabled, PassiveUpdateMode oldMode,
+ PassiveUpdateMode newMode)
+ {
+ super(OptionsImpl.this);
+ this.oldEnabled = oldEnabled;
+ this.newEnabled = newEnabled;
+ this.oldMode = oldMode;
+ this.newMode = newMode;
+ }
+
+ public boolean getOldEnabled()
+ {
+ return oldEnabled;
+ }
+
+ public boolean getNewEnabled()
+ {
+ return newEnabled;
+ }
+
+ public PassiveUpdateMode getOldMode()
+ {
+ return oldMode;
+ }
+
+ public PassiveUpdateMode getNewMode()
+ {
+ return newMode;
+ }
+ }
+
+ /**
+ * @author Caspar De Groot
+ */
+ private final class LockNotificationModeEventImpl extends OptionsEvent implements LockNotificationModeEvent
+ {
+ private static final long serialVersionUID = 1L;
+
+ private LockNotificationMode oldMode, newMode;
+
+ public LockNotificationModeEventImpl(LockNotificationMode oldMode, LockNotificationMode newMode)
+ {
+ super(OptionsImpl.this);
+ this.oldMode = oldMode;
+ this.newMode = newMode;
+ }
+
+ public LockNotificationMode getOldMode()
+ {
+ return oldMode;
+ }
+
+ public LockNotificationMode getNewMode()
+ {
+ return newMode;
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private final class CollectionLoadingPolicyEventImpl extends OptionsEvent implements CollectionLoadingPolicyEvent
+ {
+ private static final long serialVersionUID = 1L;
+
+ public CollectionLoadingPolicyEventImpl()
+ {
+ super(OptionsImpl.this);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private final class LobCacheEventImpl extends OptionsEvent implements LobCacheEvent
+ {
+ private static final long serialVersionUID = 1L;
+
+ public LobCacheEventImpl()
+ {
+ super(OptionsImpl.this);
+ }
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private final class InvalidationEvent extends Event implements CDOSessionInvalidationEvent
+ {
+ private static final long serialVersionUID = 1L;
+
+ private InternalCDOTransaction sender;
+
+ private CDOCommitInfo commitInfo;
+
+ public InvalidationEvent(InternalCDOTransaction sender, CDOCommitInfo commitInfo)
+ {
+ super(CDOSessionImpl.this);
+ this.sender = sender;
+ this.commitInfo = commitInfo;
+ }
+
+ @Override
+ public CDOSession getSource()
+ {
+ return (CDOSession)super.getSource();
+ }
+
+ public CDOCommitInfoManager getCommitInfoManager()
+ {
+ return commitInfo.getCommitInfoManager();
+ }
+
+ public CDOTransaction getLocalTransaction()
+ {
+ return sender;
+ }
+
+ @Deprecated
+ public InternalCDOView getView()
+ {
+ return sender;
+ }
+
+ public boolean isRemote()
+ {
+ return sender == null;
+ }
+
+ public CDOBranch getBranch()
+ {
+ return commitInfo.getBranch();
+ }
+
+ public long getTimeStamp()
+ {
+ return commitInfo.getTimeStamp();
+ }
+
+ public long getPreviousTimeStamp()
+ {
+ return commitInfo.getPreviousTimeStamp();
+ }
+
+ public String getUserID()
+ {
+ return commitInfo.getUserID();
+ }
+
+ public String getComment()
+ {
+ return commitInfo.getComment();
+ }
+
+ public boolean isEmpty()
+ {
+ return false;
+ }
+
+ public CDOChangeSetData copy()
+ {
+ return commitInfo.copy();
+ }
+
+ public void merge(CDOChangeSetData changeSetData)
+ {
+ commitInfo.merge(changeSetData);
+ }
+
+ public List<CDOPackageUnit> getNewPackageUnits()
+ {
+ return commitInfo.getNewPackageUnits();
+ }
+
+ public List<CDOIDAndVersion> getNewObjects()
+ {
+ return commitInfo.getNewObjects();
+ }
+
+ public List<CDORevisionKey> getChangedObjects()
+ {
+ return commitInfo.getChangedObjects();
+ }
+
+ public List<CDOIDAndVersion> getDetachedObjects()
+ {
+ return commitInfo.getDetachedObjects();
+ }
+
+ public Map<CDOID, CDOChangeKind> getChangeKinds()
+ {
+ return commitInfo.getChangeKinds();
+ }
+
+ public CDOChangeKind getChangeKind(CDOID id)
+ {
+ return commitInfo.getChangeKind(id);
+ }
+
+ @Override
+ public String toString()
+ {
+ return "CDOSessionInvalidationEvent[" + commitInfo + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ /**
+ * @author Caspar De Groot
+ * @since 4.1
+ */
+ private final class LocksChangedEvent extends DefaultLocksChangedEvent implements CDOSessionLocksChangedEvent
+ {
+ private static final long serialVersionUID = 1L;
+
+ public LocksChangedEvent(InternalCDOView sender, CDOLockChangeInfo lockChangeInfo)
+ {
+ super(CDOSessionImpl.this, sender, lockChangeInfo);
+ }
+
+ @Override
+ public CDOSession getSource()
+ {
+ return (CDOSession)super.getSource();
+ }
+ }
+}

Back to the top