Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal')
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDOProtocolImpl.java37
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/bundle/OM.java60
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDMetaImpl.java38
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDMetaRangeImpl.java118
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDNullImpl.java89
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempMetaImpl.java38
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempObjectImpl.java38
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassImpl.java455
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassRefImpl.java86
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOFeatureImpl.java270
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOModelElementImpl.java114
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOPackageImpl.java395
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOPackageManagerImpl.java144
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOTypeImpl.java472
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/core/CDOCorePackageImpl.java46
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/core/CDOObjectClassImpl.java32
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/resource/CDOContentsFeatureImpl.java29
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/resource/CDOPathFeatureImpl.java27
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/resource/CDOResourceClassImpl.java49
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/resource/CDOResourcePackageImpl.java46
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDOReferenceProxyImpl.java65
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionImpl.java814
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionResolverImpl.java528
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/DLRevisionHolder.java56
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/DLRevisionList.java222
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/LRURevisionHolder.java63
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/LRURevisionList.java66
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/RevisionHolder.java142
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOAddFeatureDeltaImpl.java72
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOClearFeatureDeltaImpl.java63
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOContainerFeatureDeltaImpl.java197
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOFeatureDeltaImpl.java87
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOFeatureDeltaVisitorImpl.java69
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOListFeatureDeltaImpl.java126
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOMoveFeatureDeltaImpl.java123
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORemoveFeatureDeltaImpl.java103
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java261
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionMerger.java84
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOSetFeatureDeltaImpl.java55
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOSingleValueFeatureDeltaImpl.java82
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOUnsetFeatureDeltaImpl.java63
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/IListIndexAffecting.java22
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/IListTargetAdding.java19
43 files changed, 5965 insertions, 0 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDOProtocolImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDOProtocolImpl.java
new file mode 100644
index 0000000000..fb7b6affca
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDOProtocolImpl.java
@@ -0,0 +1,37 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common;
+
+import org.eclipse.emf.cdo.common.CDOProtocol;
+import org.eclipse.emf.cdo.common.CDOProtocolConstants;
+import org.eclipse.emf.cdo.common.CDOProtocolSession;
+
+import org.eclipse.net4j.signal.SignalProtocol;
+
+/**
+ * @author Eike Stepper
+ */
+public abstract class CDOProtocolImpl extends SignalProtocol implements CDOProtocol
+{
+ public CDOProtocolImpl()
+ {
+ }
+
+ public String getType()
+ {
+ return CDOProtocolConstants.PROTOCOL_NAME;
+ }
+
+ public CDOProtocolSession getSession()
+ {
+ return (CDOProtocolSession)getInfraStructure();
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/bundle/OM.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/bundle/OM.java
new file mode 100644
index 0000000000..7556f5b29f
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/bundle/OM.java
@@ -0,0 +1,60 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.bundle;
+
+import org.eclipse.net4j.util.om.OMBundle;
+import org.eclipse.net4j.util.om.OMPlatform;
+import org.eclipse.net4j.util.om.OSGiActivator;
+import org.eclipse.net4j.util.om.log.OMLogger;
+import org.eclipse.net4j.util.om.trace.OMTracer;
+
+/**
+ * The <em>Operations & Maintenance</em> class of this bundle.
+ *
+ * @author Eike Stepper
+ */
+public abstract class OM
+{
+ public static final String BUNDLE_ID = "org.eclipse.emf.cdo.common"; //$NON-NLS-1$
+
+ public static final OMBundle BUNDLE = OMPlatform.INSTANCE.bundle(BUNDLE_ID, OM.class);
+
+ public static final OMTracer DEBUG = BUNDLE.tracer("debug"); //$NON-NLS-1$
+
+ public static final OMTracer DEBUG_PROTOCOL = DEBUG.tracer("protocol"); //$NON-NLS-1$
+
+ public static final OMTracer DEBUG_ID = DEBUG.tracer("id"); //$NON-NLS-1$
+
+ public static final OMTracer DEBUG_MODEL = DEBUG.tracer("model"); //$NON-NLS-1$
+
+ public static final OMTracer DEBUG_REVISION = DEBUG.tracer("revision"); //$NON-NLS-1$
+
+ public static final OMTracer PERF = BUNDLE.tracer("perf"); //$NON-NLS-1$
+
+ public static final OMTracer PERF_REVISION = PERF.tracer("revision"); //$NON-NLS-1$
+
+ public static final OMTracer PERF_REVISION_READING = PERF_REVISION.tracer("reading"); //$NON-NLS-1$
+
+ public static final OMTracer PERF_REVISION_WRITING = PERF_REVISION.tracer("writing"); //$NON-NLS-1$
+
+ public static final OMLogger LOG = BUNDLE.logger();
+
+ /**
+ * @author Eike Stepper
+ */
+ public static final class Activator extends OSGiActivator
+ {
+ public Activator()
+ {
+ super(BUNDLE);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDMetaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDMetaImpl.java
new file mode 100644
index 0000000000..12f7e56ba3
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDMetaImpl.java
@@ -0,0 +1,38 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.id;
+
+import org.eclipse.emf.cdo.common.id.CDOIDMeta;
+import org.eclipse.emf.cdo.spi.common.AbstractCDOIDLong;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOIDMetaImpl extends AbstractCDOIDLong implements CDOIDMeta
+{
+ private static final long serialVersionUID = 1L;
+
+ public CDOIDMetaImpl(long value)
+ {
+ super(value);
+ }
+
+ public Type getType()
+ {
+ return Type.META;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "MID" + getLongValue();
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDMetaRangeImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDMetaRangeImpl.java
new file mode 100644
index 0000000000..ea727a67aa
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDMetaRangeImpl.java
@@ -0,0 +1,118 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.id;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDMetaRange;
+import org.eclipse.emf.cdo.common.id.CDOID.Type;
+
+import java.text.MessageFormat;
+
+/**
+ * @author Eike Stepper
+ */
+public final class CDOIDMetaRangeImpl implements CDOIDMetaRange
+{
+ private static final long serialVersionUID = 1L;
+
+ private CDOID lowerBound;
+
+ private int size;
+
+ public CDOIDMetaRangeImpl(CDOID lowerBound, int size)
+ {
+ if (size < 0)
+ {
+ throw new IllegalArgumentException("size < 0");
+ }
+
+ this.lowerBound = lowerBound;
+ this.size = size;
+ }
+
+ public CDOID getLowerBound()
+ {
+ return lowerBound;
+ }
+
+ public CDOID getUpperBound()
+ {
+ return size > 0 ? get(size - 1) : null;
+ }
+
+ public CDOID get(int index)
+ {
+ if (index < 0 || index >= size)
+ {
+ throw new IllegalArgumentException("ids < 0 || ids >= size");
+ }
+
+ if (isTemporary())
+ {
+ return new CDOIDTempMetaImpl(((CDOIDTempMetaImpl)lowerBound).getIntValue() + index);
+ }
+
+ return new CDOIDMetaImpl(((CDOIDMetaImpl)lowerBound).getLongValue() + index);
+ }
+
+ public int size()
+ {
+ return size;
+ }
+
+ public boolean isEmpty()
+ {
+ return size == 0;
+ }
+
+ public boolean contains(CDOID id)
+ {
+ if (isTemporary())
+ {
+ if (id.getType() != Type.TEMP_META)
+ {
+ throw new IllegalArgumentException("id.getType() != Type.TEMP_META");
+ }
+
+ int index = ((CDOIDTempMetaImpl)id).getIntValue() - ((CDOIDTempMetaImpl)lowerBound).getIntValue();
+ return 0 <= index && index < size;
+ }
+
+ if (id.getType() != Type.META)
+ {
+ throw new IllegalArgumentException("id.getType() != Type.META");
+ }
+
+ long index = ((CDOIDMetaImpl)id).getLongValue() - ((CDOIDMetaImpl)lowerBound).getLongValue();
+ return 0L <= index && index < size;
+ }
+
+ public CDOIDMetaRange increase()
+ {
+ return new CDOIDMetaRangeImpl(lowerBound, size + 1);
+ }
+
+ public Type getType()
+ {
+ return lowerBound.getType();
+ }
+
+ public boolean isTemporary()
+ {
+ return lowerBound.isTemporary();
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("[{0}:{1}]", lowerBound, getUpperBound());
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDNullImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDNullImpl.java
new file mode 100644
index 0000000000..dd959a4baa
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDNullImpl.java
@@ -0,0 +1,89 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.id;
+
+import org.eclipse.emf.cdo.common.id.CDOIDMeta;
+import org.eclipse.emf.cdo.common.id.CDOIDObject;
+import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.common.model.CDOClassRef;
+import org.eclipse.emf.cdo.spi.common.AbstractCDOID;
+
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+import org.eclipse.net4j.util.io.ExtendedDataOutput;
+
+import java.io.IOException;
+
+/**
+ * @author Eike Stepper
+ */
+public final class CDOIDNullImpl extends AbstractCDOID implements CDOIDMeta, CDOIDTemp, CDOIDObject
+{
+ public static final CDOIDNullImpl INSTANCE = new CDOIDNullImpl();
+
+ private static final long serialVersionUID = 1L;
+
+ private CDOIDNullImpl()
+ {
+ }
+
+ public Type getType()
+ {
+ return Type.NULL;
+ }
+
+ public int getIntValue()
+ {
+ return 0;
+ }
+
+ public long getLongValue()
+ {
+ return 0L;
+ }
+
+ public CDOIDObject asLegacy(CDOClassRef classRef)
+ {
+ return this;
+ }
+
+ public CDOClassRef getClassRef()
+ {
+ return null;
+ }
+
+ public void read(ExtendedDataInput in) throws IOException
+ {
+ // Do nothing
+ }
+
+ public void write(ExtendedDataOutput out) throws IOException
+ {
+ // Do nothing
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ return obj == INSTANCE;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return 0;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "NULL";
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempMetaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempMetaImpl.java
new file mode 100644
index 0000000000..0d5b94a6fd
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempMetaImpl.java
@@ -0,0 +1,38 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.id;
+
+import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.spi.common.AbstractCDOIDInteger;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOIDTempMetaImpl extends AbstractCDOIDInteger implements CDOIDTemp
+{
+ private static final long serialVersionUID = 1L;
+
+ public CDOIDTempMetaImpl(int value)
+ {
+ super(value);
+ }
+
+ public Type getType()
+ {
+ return Type.TEMP_META;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "mid" + getIntValue();
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempObjectImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempObjectImpl.java
new file mode 100644
index 0000000000..09ba5432be
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempObjectImpl.java
@@ -0,0 +1,38 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.id;
+
+import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.spi.common.AbstractCDOIDInteger;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOIDTempObjectImpl extends AbstractCDOIDInteger implements CDOIDTemp
+{
+ private static final long serialVersionUID = 1L;
+
+ public CDOIDTempObjectImpl(int value)
+ {
+ super(value);
+ }
+
+ public Type getType()
+ {
+ return Type.TEMP_OBJECT;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "oid" + getIntValue();
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassImpl.java
new file mode 100644
index 0000000000..44d3608cfb
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassImpl.java
@@ -0,0 +1,455 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.model;
+
+import org.eclipse.emf.cdo.common.model.CDOClass;
+import org.eclipse.emf.cdo.common.model.CDOClassProxy;
+import org.eclipse.emf.cdo.common.model.CDOClassRef;
+import org.eclipse.emf.cdo.common.model.CDOFeature;
+import org.eclipse.emf.cdo.common.model.CDOModelUtil;
+import org.eclipse.emf.cdo.common.model.CDOPackage;
+import org.eclipse.emf.cdo.common.model.CDOPackageManager;
+import org.eclipse.emf.cdo.internal.common.bundle.OM;
+import org.eclipse.emf.cdo.spi.common.InternalCDOClass;
+import org.eclipse.emf.cdo.spi.common.InternalCDOFeature;
+
+import org.eclipse.net4j.util.ObjectUtil;
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+import org.eclipse.net4j.util.io.ExtendedDataOutput;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOClassImpl extends CDOModelElementImpl implements InternalCDOClass
+{
+ private static final ContextTracer MODEL = new ContextTracer(OM.DEBUG_MODEL, CDOClassImpl.class);
+
+ private static final ContextTracer PROTOCOL = new ContextTracer(OM.DEBUG_PROTOCOL, CDOClassImpl.class);
+
+ private CDOPackage containingPackage;
+
+ private int classifierID;
+
+ private boolean isAbstract;
+
+ private List<CDOClassProxy> superTypes = new ArrayList<CDOClassProxy>(0);
+
+ private List<CDOFeature> features = new ArrayList<CDOFeature>(0);
+
+ private transient List<Integer> indices;
+
+ private transient CDOClass[] allSuperTypes;
+
+ private transient CDOFeature[] allFeatures;
+
+ public CDOClassImpl()
+ {
+ }
+
+ public CDOClassImpl(CDOPackage containingPackage, int classifierID, String name, boolean isAbstract)
+ {
+ super(name);
+ this.containingPackage = containingPackage;
+ this.classifierID = classifierID;
+ this.isAbstract = isAbstract;
+ if (MODEL.isEnabled())
+ {
+ MODEL.format("Created {0}", this);
+ }
+ }
+
+ public CDOClassImpl(CDOPackage containingPackage, ExtendedDataInput in) throws IOException
+ {
+ this.containingPackage = containingPackage;
+ read(in);
+ }
+
+ @Override
+ public void read(ExtendedDataInput in) throws IOException
+ {
+ super.read(in);
+ classifierID = in.readInt();
+ isAbstract = in.readBoolean();
+ readSuperTypes(in);
+ readFeatures(in);
+
+ if (PROTOCOL.isEnabled())
+ {
+ PROTOCOL.format("Read class: ID={0}, name={1}, abstract={2}", classifierID, getName(), isAbstract);
+ }
+ }
+
+ @Override
+ public void write(ExtendedDataOutput out) throws IOException
+ {
+ if (PROTOCOL.isEnabled())
+ {
+ PROTOCOL.format("Writing class: ID={0}, name={1}, abstract={2}", classifierID, getName(), isAbstract);
+ }
+
+ super.write(out);
+ out.writeInt(classifierID);
+ out.writeBoolean(isAbstract);
+ writeSuperTypes(out);
+ writeFeatures(out);
+ }
+
+ public int getFeatureID(CDOFeature feature)
+ {
+ int index = feature.getFeatureIndex();
+ if (index != -1)
+ {
+ CDOFeature[] features = getAllFeatures();
+ while (index < features.length)
+ {
+ if (features[index] == feature)
+ {
+ return index;
+ }
+
+ ++index;
+ }
+ }
+
+ return -1;
+ }
+
+ public CDOPackageManager getPackageManager()
+ {
+ return containingPackage.getPackageManager();
+ }
+
+ public CDOPackage getContainingPackage()
+ {
+ return containingPackage;
+ }
+
+ public void setContainingPackage(CDOPackage containingPackage)
+ {
+ this.containingPackage = containingPackage;
+ }
+
+ public int getClassifierID()
+ {
+ return classifierID;
+ }
+
+ public void setClassifierID(int classifierID)
+ {
+ this.classifierID = classifierID;
+ }
+
+ public boolean isAbstract()
+ {
+ return isAbstract;
+ }
+
+ public void setAbstract(boolean isAbstract)
+ {
+ this.isAbstract = isAbstract;
+ }
+
+ public boolean isResource()
+ {
+ return false;
+ }
+
+ public boolean isRoot()
+ {
+ return false;
+ }
+
+ public int getSuperTypeCount()
+ {
+ return superTypes.size();
+ }
+
+ public CDOClass[] getSuperTypes()
+ {
+ int size = superTypes.size();
+ CDOClass[] result = new CDOClass[size];
+ for (int i = 0; i < size; i++)
+ {
+ result[i] = getSuperType(i);
+ }
+
+ return result;
+ }
+
+ public void setSuperTypes(List<CDOClass> superTypes)
+ {
+ this.superTypes = new ArrayList<CDOClassProxy>(superTypes.size());
+ for (CDOClass cdoClass : superTypes)
+ {
+ this.superTypes.add(new CDOClassProxy(cdoClass));
+ }
+ }
+
+ public CDOClass getSuperType(int index)
+ {
+ return superTypes.get(index).getCdoClass();
+ }
+
+ public List<CDOClassProxy> getSuperTypeProxies()
+ {
+ return Collections.unmodifiableList(superTypes);
+ }
+
+ public int getFeatureCount()
+ {
+ return features.size();
+ }
+
+ public CDOFeature[] getFeatures()
+ {
+ return features.toArray(new CDOFeature[features.size()]);
+ }
+
+ public void setFeatures(List<CDOFeature> features)
+ {
+ this.features = features;
+ for (CDOFeature feature : features)
+ {
+ ((InternalCDOFeature)feature).setContainingClass(this);
+ }
+ }
+
+ public CDOFeature lookupFeature(int featureID)
+ {
+ int i = getFeatureIndex(featureID);
+ return getAllFeatures()[i];
+ }
+
+ public CDOFeature lookupFeature(String name)
+ {
+ for (CDOFeature feature : getAllFeatures())
+ {
+ if (ObjectUtil.equals(feature.getName(), name))
+ {
+ return feature;
+ }
+ }
+
+ return null;
+ }
+
+ public CDOClassRef createClassRef()
+ {
+ return CDOModelUtil.createClassRef(containingPackage.getPackageURI(), classifierID);
+ }
+
+ public CDOClass[] getAllSuperTypes()
+ {
+ if (allSuperTypes == null)
+ {
+ List<CDOClass> result = new ArrayList<CDOClass>(0);
+ for (CDOClass superType : getSuperTypes())
+ {
+ CDOClass[] higherSupers = superType.getAllSuperTypes();
+ for (CDOClass higherSuper : higherSupers)
+ {
+ addUnique(higherSuper, result);
+ }
+
+ addUnique(superType, result);
+ }
+
+ allSuperTypes = result.toArray(new CDOClass[result.size()]);
+ }
+
+ return allSuperTypes;
+ }
+
+ public int getFeatureIndex(int featureID)
+ {
+ if (indices == null)
+ {
+ CDOFeature[] features = getAllFeatures();
+ indices = new ArrayList<Integer>(features.length);
+ int index = 0;
+ for (CDOFeature feature : features)
+ {
+ if (feature.getContainingClass() == this)
+ {
+ ((InternalCDOFeature)feature).setFeatureIndex(index);
+ }
+
+ setIndex(feature.getFeatureID(), index);
+ index++;
+ }
+ }
+
+ return indices.get(featureID);
+ }
+
+ public CDOFeature[] getAllFeatures()
+ {
+ if (allFeatures == null)
+ {
+ List<CDOFeature> result = new ArrayList<CDOFeature>(0);
+ for (CDOClass superType : getSuperTypes())
+ {
+ CDOFeature[] features = superType.getAllFeatures();
+ addAllFeatures(features, result);
+ }
+
+ addAllFeatures(getFeatures(), result);
+ allFeatures = result.toArray(new CDOFeature[result.size()]);
+ }
+
+ return allFeatures;
+ }
+
+ public void addSuperType(CDOClassRef classRef)
+ {
+ if (MODEL.isEnabled())
+ {
+ MODEL.format("Adding super type: {0}", classRef);
+ }
+
+ superTypes.add(new CDOClassProxy(classRef, containingPackage.getPackageManager()));
+ }
+
+ public void addFeature(CDOFeature cdoFeature)
+ {
+ if (MODEL.isEnabled())
+ {
+ MODEL.format("Adding feature: {0}", cdoFeature);
+ }
+
+ features.add(cdoFeature);
+ }
+
+ public int compareTo(CDOClass that)
+ {
+ return getName().compareTo(that.getName());
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("CDOClass(ID={0}, name={1})", classifierID, getName());
+ }
+
+ @Override
+ protected void onInitialize()
+ {
+ for (CDOFeature cdoFeature : features)
+ {
+ ((InternalCDOFeature)cdoFeature).initialize();
+ }
+ }
+
+ private void setIndex(int featureID, int index)
+ {
+ while (indices.size() <= featureID)
+ {
+ indices.add(null);
+ }
+
+ indices.set(featureID, index);
+ }
+
+ private void readSuperTypes(ExtendedDataInput in) throws IOException
+ {
+ int size = in.readInt();
+ if (PROTOCOL.isEnabled())
+ {
+ PROTOCOL.format("Reading {0} super types", size);
+ }
+
+ for (int i = 0; i < size; i++)
+ {
+ CDOClassRef classRef = CDOModelUtil.readClassRef(in, containingPackage.getPackageURI());
+ if (PROTOCOL.isEnabled())
+ {
+ PROTOCOL.format("Read super type: classRef={0}", classRef, classifierID);
+ }
+
+ superTypes.add(new CDOClassProxy(classRef, containingPackage.getPackageManager()));
+ }
+ }
+
+ private void readFeatures(ExtendedDataInput in) throws IOException
+ {
+ int size = in.readInt();
+ if (PROTOCOL.isEnabled())
+ {
+ PROTOCOL.format("Reading {0} features", size);
+ }
+
+ for (int i = 0; i < size; i++)
+ {
+ CDOFeature cdoFeature = CDOModelUtil.readFeature(this, in);
+ addFeature(cdoFeature);
+ }
+ }
+
+ private void writeSuperTypes(ExtendedDataOutput out) throws IOException
+ {
+ int size = superTypes.size();
+ if (PROTOCOL.isEnabled())
+ {
+ PROTOCOL.format("Writing {0} super types", size);
+ }
+
+ out.writeInt(size);
+ for (CDOClassProxy proxy : superTypes)
+ {
+ CDOClassRef classRef = proxy.getClassRef();
+ if (PROTOCOL.isEnabled())
+ {
+ PROTOCOL.format("Writing super type: classRef={0}", classRef);
+ }
+
+ CDOModelUtil.writeClassRef(out, classRef, containingPackage.getPackageURI());
+ }
+ }
+
+ private void writeFeatures(ExtendedDataOutput out) throws IOException
+ {
+ int size = features.size();
+ if (PROTOCOL.isEnabled())
+ {
+ PROTOCOL.format("Writing {0} features", size);
+ }
+
+ out.writeInt(size);
+ for (CDOFeature cdoFeature : features)
+ {
+ CDOModelUtil.writeFeature(out, cdoFeature);
+ }
+ }
+
+ private static void addAllFeatures(CDOFeature[] features, List<CDOFeature> result)
+ {
+ for (CDOFeature feature : features)
+ {
+ addUnique(feature, result);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static void addUnique(Object object, List result)
+ {
+ if (!result.contains(object))
+ {
+ result.add(object);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassRefImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassRefImpl.java
new file mode 100644
index 0000000000..6ce58cbf04
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOClassRefImpl.java
@@ -0,0 +1,86 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.model;
+
+import org.eclipse.emf.cdo.common.model.CDOClass;
+import org.eclipse.emf.cdo.common.model.CDOClassRef;
+import org.eclipse.emf.cdo.common.model.CDOPackage;
+import org.eclipse.emf.cdo.common.model.CDOPackageManager;
+
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+import org.eclipse.net4j.util.io.ExtendedDataOutput;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+
+/**
+ * TODO Optimize transfer of CDOClassRef instances
+ *
+ * @author Eike Stepper
+ */
+public final class CDOClassRefImpl implements CDOClassRef
+{
+ private String packageURI;
+
+ private int classifierID;
+
+ public CDOClassRefImpl(String packageURI, int classifierID)
+ {
+ this.packageURI = packageURI;
+ this.classifierID = classifierID;
+ }
+
+ public CDOClassRefImpl(ExtendedDataInput in, String defaultURI) throws IOException
+ {
+ // TODO Optimize transfer of URIs
+ packageURI = in.readString();
+ if (packageURI == null)
+ {
+ packageURI = defaultURI;
+ }
+
+ classifierID = in.readInt();
+ }
+
+ public void write(ExtendedDataOutput out, String defaultURI) throws IOException
+ {
+ // TODO Optimize transfer of URIs
+ out.writeString(packageURI.equals(defaultURI) ? null : packageURI);
+ out.writeInt(classifierID);
+ }
+
+ public String getPackageURI()
+ {
+ return packageURI;
+ }
+
+ public int getClassifierID()
+ {
+ return classifierID;
+ }
+
+ public CDOClass resolve(CDOPackageManager packageManager)
+ {
+ CDOPackage cdoPackage = packageManager.lookupPackage(packageURI);
+ if (cdoPackage != null)
+ {
+ return cdoPackage.lookupClass(classifierID);
+ }
+
+ return null;
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("CDOClassRef({0}, {1})", packageURI, classifierID);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOFeatureImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOFeatureImpl.java
new file mode 100644
index 0000000000..76b2a8a3dd
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOFeatureImpl.java
@@ -0,0 +1,270 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.model;
+
+import org.eclipse.emf.cdo.common.model.CDOClass;
+import org.eclipse.emf.cdo.common.model.CDOClassProxy;
+import org.eclipse.emf.cdo.common.model.CDOClassRef;
+import org.eclipse.emf.cdo.common.model.CDOModelUtil;
+import org.eclipse.emf.cdo.common.model.CDOPackage;
+import org.eclipse.emf.cdo.common.model.CDOPackageManager;
+import org.eclipse.emf.cdo.common.model.CDOType;
+import org.eclipse.emf.cdo.internal.common.bundle.OM;
+import org.eclipse.emf.cdo.spi.common.InternalCDOClass;
+import org.eclipse.emf.cdo.spi.common.InternalCDOFeature;
+
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+import org.eclipse.net4j.util.io.ExtendedDataOutput;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOFeatureImpl extends CDOModelElementImpl implements InternalCDOFeature
+{
+ private static final int UNKNOWN_FEATURE_INDEX = Integer.MIN_VALUE;
+
+ private static final ContextTracer MODEL = new ContextTracer(OM.DEBUG_MODEL, CDOFeatureImpl.class);
+
+ private static final ContextTracer PROTOCOL = new ContextTracer(OM.DEBUG_PROTOCOL, CDOFeatureImpl.class);
+
+ private CDOClass containingClass;
+
+ private int featureID;
+
+ private int featureIndex = UNKNOWN_FEATURE_INDEX;
+
+ private CDOType type;
+
+ private boolean many;
+
+ private boolean containment;
+
+ private CDOClassProxy referenceType;
+
+ public CDOFeatureImpl()
+ {
+ }
+
+ public CDOFeatureImpl(CDOClass containingClass, int featureID, String name, CDOType type, boolean many)
+ {
+ super(name);
+ if (type == CDOType.OBJECT)
+ {
+ throw new IllegalArgumentException("type == OBJECT");
+ }
+
+ this.containingClass = containingClass;
+ this.featureID = featureID;
+ this.type = type;
+ this.many = many;
+ if (MODEL.isEnabled())
+ {
+ MODEL.format("Created {0}", this);
+ }
+ }
+
+ public CDOFeatureImpl(CDOClass containingClass, int featureID, String name, CDOClassProxy referenceType,
+ boolean many, boolean containment)
+ {
+ super(name);
+ if (referenceType == null)
+ {
+ throw new IllegalArgumentException("referenceType == null");
+ }
+
+ this.containingClass = containingClass;
+ this.featureID = featureID;
+ type = CDOType.OBJECT;
+ this.many = many;
+ this.containment = containment;
+ this.referenceType = referenceType;
+ if (MODEL.isEnabled())
+ {
+ MODEL.format("Created {0}", this);
+ }
+ }
+
+ public CDOFeatureImpl(CDOClass containingClass, ExtendedDataInput in) throws IOException
+ {
+ this.containingClass = containingClass;
+ read(in);
+ }
+
+ @Override
+ public void read(ExtendedDataInput in) throws IOException
+ {
+ super.read(in);
+ featureID = in.readInt();
+ type = CDOModelUtil.readType(in);
+ many = in.readBoolean();
+ containment = in.readBoolean();
+ if (PROTOCOL.isEnabled())
+ {
+ PROTOCOL.format("Read feature: ID={0}, name={1}, type={2}, many={3}, containment={4}", featureID, getName(),
+ type, many, containment);
+ }
+
+ if (isReference())
+ {
+ String defaultURI = containingClass.getContainingPackage().getPackageURI();
+ CDOClassRef classRef = CDOModelUtil.readClassRef(in, defaultURI);
+ if (PROTOCOL.isEnabled())
+ {
+ PROTOCOL.format("Read reference type: classRef={0}", classRef);
+ }
+
+ referenceType = new CDOClassProxy(classRef, containingClass.getContainingPackage().getPackageManager());
+ }
+ }
+
+ @Override
+ public void write(ExtendedDataOutput out) throws IOException
+ {
+ if (PROTOCOL.isEnabled())
+ {
+ PROTOCOL.format("Writing feature: ID={0}, name={1}, type={2}, many={3}, containment={4}", featureID, getName(),
+ type, many, containment);
+ }
+
+ super.write(out);
+ out.writeInt(featureID);
+ CDOModelUtil.writeType(out, type);
+ out.writeBoolean(many);
+ out.writeBoolean(containment);
+
+ if (isReference())
+ {
+ CDOClassRef classRef = referenceType.getClassRef();
+ if (PROTOCOL.isEnabled())
+ {
+ PROTOCOL.format("Writing reference type: classRef={0}", classRef);
+ }
+
+ CDOModelUtil.writeClassRef(out, classRef, getContainingPackage().getPackageURI());
+ }
+ }
+
+ public CDOPackageManager getPackageManager()
+ {
+ return getContainingPackage().getPackageManager();
+ }
+
+ public CDOPackage getContainingPackage()
+ {
+ return containingClass.getContainingPackage();
+ }
+
+ public CDOClass getContainingClass()
+ {
+ return containingClass;
+ }
+
+ public void setContainingClass(CDOClass containingClass)
+ {
+ this.containingClass = containingClass;
+ }
+
+ public int getFeatureID()
+ {
+ return featureID;
+ }
+
+ public void setFeatureID(int featureID)
+ {
+ this.featureID = featureID;
+ }
+
+ public int getFeatureIndex()
+ {
+ if (featureIndex == UNKNOWN_FEATURE_INDEX)
+ {
+ featureIndex = ((InternalCDOClass)containingClass).getFeatureIndex(featureID);
+ }
+
+ return featureIndex;
+ }
+
+ public void setFeatureIndex(int featureIndex)
+ {
+ this.featureIndex = featureIndex;
+ }
+
+ public CDOType getType()
+ {
+ return type;
+ }
+
+ public void setType(CDOType type)
+ {
+ this.type = type;
+ }
+
+ public boolean isMany()
+ {
+ return many;
+ }
+
+ public void setMany(boolean many)
+ {
+ this.many = many;
+ }
+
+ public boolean isReference()
+ {
+ return type == CDOType.OBJECT;
+ }
+
+ public boolean isContainment()
+ {
+ return containment;
+ }
+
+ public void setContainment(boolean containment)
+ {
+ this.containment = containment;
+ }
+
+ public CDOClass getReferenceType()
+ {
+ if (referenceType == null)
+ {
+ return null;
+ }
+
+ return referenceType.getCdoClass();
+ }
+
+ public void setReferenceType(CDOClass cdoClass)
+ {
+ referenceType = new CDOClassProxy(cdoClass);
+ }
+
+ public CDOClassProxy getReferenceTypeProxy()
+ {
+ return referenceType;
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("CDOFeature(ID={0}, name={1}, type={2}, referenceType={3})", featureID, getName(),
+ getType(), getReferenceTypeProxy());
+ }
+
+ @Override
+ protected void onInitialize()
+ {
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOModelElementImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOModelElementImpl.java
new file mode 100644
index 0000000000..4eb233e5a2
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOModelElementImpl.java
@@ -0,0 +1,114 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.model;
+
+import org.eclipse.emf.cdo.internal.common.bundle.OM;
+import org.eclipse.emf.cdo.spi.common.InternalCDOModelElement;
+
+import org.eclipse.net4j.util.ImplementationError;
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+import org.eclipse.net4j.util.io.ExtendedDataOutput;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import java.io.IOException;
+
+/**
+ * @author Eike Stepper
+ */
+public abstract class CDOModelElementImpl implements InternalCDOModelElement
+{
+ private static final ContextTracer MODEL = new ContextTracer(OM.DEBUG_MODEL, CDOModelElementImpl.class);
+
+ private String name;
+
+ private Object clientInfo;
+
+ private Object serverInfo;
+
+ private boolean initialized;
+
+ protected CDOModelElementImpl(String name)
+ {
+ this.name = name;
+ }
+
+ protected CDOModelElementImpl()
+ {
+ }
+
+ public void read(ExtendedDataInput in) throws IOException
+ {
+ name = in.readString();
+ }
+
+ public void write(ExtendedDataOutput out) throws IOException
+ {
+ out.writeString(name);
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public Object getClientInfo()
+ {
+ return clientInfo;
+ }
+
+ public void setClientInfo(Object clientInfo)
+ {
+ if (MODEL.isEnabled())
+ {
+ MODEL.format("Setting client info: {0} --> {1}", this, clientInfo);
+ }
+
+ this.clientInfo = clientInfo;
+ }
+
+ public Object getServerInfo()
+ {
+ return serverInfo;
+ }
+
+ public void setServerInfo(Object serverInfo)
+ {
+ if (MODEL.isEnabled())
+ {
+ MODEL.format("Setting server info: {0} --> {1}", this, serverInfo);
+ }
+
+ this.serverInfo = serverInfo;
+ }
+
+ public boolean isInitialized()
+ {
+ return initialized;
+ }
+
+ public final void initialize()
+ {
+ if (initialized)
+ {
+ throw new ImplementationError("Duplicate initialization");
+ }
+
+ initialized = true;
+ onInitialize();
+ }
+
+ protected abstract void onInitialize();
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOPackageImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOPackageImpl.java
new file mode 100644
index 0000000000..ad1928e633
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOPackageImpl.java
@@ -0,0 +1,395 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.model;
+
+import org.eclipse.emf.cdo.common.id.CDOIDMetaRange;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.model.CDOClass;
+import org.eclipse.emf.cdo.common.model.CDOModelUtil;
+import org.eclipse.emf.cdo.common.model.CDOPackage;
+import org.eclipse.emf.cdo.common.model.CDOPackageManager;
+import org.eclipse.emf.cdo.internal.common.bundle.OM;
+import org.eclipse.emf.cdo.spi.common.InternalCDOClass;
+import org.eclipse.emf.cdo.spi.common.InternalCDOPackage;
+
+import org.eclipse.net4j.util.ObjectUtil;
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+import org.eclipse.net4j.util.io.ExtendedDataOutput;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOPackageImpl extends CDOModelElementImpl implements InternalCDOPackage
+{
+ private static final ContextTracer MODEL = new ContextTracer(OM.DEBUG_MODEL, CDOPackageImpl.class);
+
+ private static final ContextTracer PROTOCOL = new ContextTracer(OM.DEBUG_PROTOCOL, CDOPackageImpl.class);
+
+ private CDOPackageManager packageManager;
+
+ private String packageURI;
+
+ private List<CDOClass> classes;
+
+ private List<CDOClass> index;
+
+ private String ecore;
+
+ private boolean dynamic;
+
+ private CDOIDMetaRange metaIDRange;
+
+ private String parentURI;
+
+ /**
+ * TODO If this is only needed by the client then put it into server info
+ */
+ private transient boolean persistent = true;
+
+ public CDOPackageImpl()
+ {
+ }
+
+ public CDOPackageImpl(CDOPackageManager packageManager, String packageURI, String name, String ecore,
+ boolean dynamic, CDOIDMetaRange metaIDRange, String parentURI)
+ {
+ super(name);
+ this.packageManager = packageManager;
+ this.packageURI = packageURI;
+ this.ecore = ecore;
+ this.dynamic = dynamic;
+ this.metaIDRange = metaIDRange;
+ this.parentURI = parentURI;
+ if (MODEL.isEnabled())
+ {
+ MODEL.format("Created {0}", this);
+ }
+
+ createLists();
+ }
+
+ public CDOPackageImpl(CDOPackageManager packageManager, ExtendedDataInput in) throws IOException
+ {
+ this.packageManager = packageManager;
+ createLists();
+ read(in);
+ }
+
+ /**
+ * Creates a proxy CDO package
+ */
+ public CDOPackageImpl(CDOPackageManager packageManager, String packageURI, boolean dynamic,
+ CDOIDMetaRange metaIDRange, String parentURI)
+ {
+ this.packageManager = packageManager;
+ this.packageURI = packageURI;
+ this.dynamic = dynamic;
+ this.metaIDRange = metaIDRange;
+ this.parentURI = parentURI;
+ if (MODEL.isEnabled())
+ {
+ MODEL.format("Created proxy package {0}, dynamic={1}, metaIDRange={2}, parentURI={3}", packageURI, dynamic,
+ metaIDRange, packageURI);
+ }
+ }
+
+ @Override
+ public void read(ExtendedDataInput in) throws IOException
+ {
+ super.read(in);
+ packageURI = in.readString();
+ dynamic = in.readBoolean();
+ ecore = in.readString();
+ metaIDRange = CDOIDUtil.readMetaRange(in);
+ parentURI = in.readString();
+ if (PROTOCOL.isEnabled())
+ {
+ PROTOCOL.format("Read package: URI={0}, name={1}, dynamic={2}, metaIDRange={3}, parentURI={4}", packageURI,
+ getName(), dynamic, metaIDRange, parentURI);
+ }
+
+ int size = in.readInt();
+ if (PROTOCOL.isEnabled())
+ {
+ PROTOCOL.format("Reading {0} classes", size);
+ }
+
+ for (int i = 0; i < size; i++)
+ {
+ CDOClass cdoClass = CDOModelUtil.readClass(this, in);
+ addClass(cdoClass);
+ }
+ }
+
+ @Override
+ public void write(ExtendedDataOutput out) throws IOException
+ {
+ resolve();
+ if (PROTOCOL.isEnabled())
+ {
+ PROTOCOL.format("Writing package: URI={0}, name={1}, dynamic={2}, metaIDRange={3}, parentURI={4}", packageURI,
+ getName(), dynamic, metaIDRange, parentURI);
+ }
+
+ super.write(out);
+ out.writeString(packageURI);
+ out.writeBoolean(dynamic);
+ out.writeString(ecore);
+ CDOIDUtil.writeMetaRange(out, metaIDRange);
+ out.writeString(parentURI);
+
+ int size = classes.size();
+ if (PROTOCOL.isEnabled())
+ {
+ PROTOCOL.format("Writing {0} classes", size);
+ }
+
+ out.writeInt(size);
+ for (CDOClass cdoClass : classes)
+ {
+ CDOModelUtil.writeClass(out, cdoClass);
+ }
+ }
+
+ public void setPackageManager(CDOPackageManager packageManager)
+ {
+ this.packageManager = packageManager;
+ }
+
+ public CDOPackageManager getPackageManager()
+ {
+ return packageManager;
+ }
+
+ public String getParentURI()
+ {
+ return parentURI;
+ }
+
+ public void setParentURI(String parentURI)
+ {
+ this.parentURI = parentURI;
+ }
+
+ public CDOPackage getTopLevelPackage()
+ {
+ CDOPackage parentPackage = getParentPackage();
+ return parentPackage == null ? this : parentPackage.getTopLevelPackage();
+ }
+
+ public CDOPackage getParentPackage()
+ {
+ return packageManager.lookupPackage(parentURI);
+ }
+
+ public CDOPackage[] getSubPackages(boolean recursive)
+ {
+ List<CDOPackage> result = new ArrayList<CDOPackage>();
+ CDOPackage[] allPackages = packageManager.getPackages();
+ getSubPackages(this, allPackages, result, recursive);
+ return result.toArray(new CDOPackage[result.size()]);
+ }
+
+ private void getSubPackages(CDOPackage parentPackage, CDOPackage[] allPackages, List<CDOPackage> result,
+ boolean recursive)
+ {
+ for (CDOPackage cdoPackage : allPackages)
+ {
+ if (ObjectUtil.equals(cdoPackage.getParentURI(), parentPackage.getPackageURI()))
+ {
+ result.add(cdoPackage);
+ if (recursive)
+ {
+ getSubPackages(cdoPackage, allPackages, result, true);
+ }
+ }
+ }
+ }
+
+ public String getPackageURI()
+ {
+ return packageURI;
+ }
+
+ public void setPackageURI(String packageURI)
+ {
+ this.packageURI = packageURI;
+ }
+
+ public int getClassCount()
+ {
+ resolve();
+ return classes.size();
+ }
+
+ public CDOClass[] getClasses()
+ {
+ resolve();
+ return classes.toArray(new CDOClass[classes.size()]);
+ }
+
+ public void setClasses(List<CDOClass> classes)
+ {
+ this.classes = classes;
+ for (CDOClass cdoClass : classes)
+ {
+ ((InternalCDOClass)cdoClass).setContainingPackage(this);
+ setIndex(cdoClass.getClassifierID(), cdoClass);
+ }
+ }
+
+ /**
+ * @return All classes with <code>isAbstract() == false</code> and <code>isSystem() == false</code>.
+ */
+ public CDOClass[] getConcreteClasses()
+ {
+ resolve();
+ List<CDOClass> result = new ArrayList<CDOClass>(0);
+ for (CDOClass cdoClass : classes)
+ {
+ if (!cdoClass.isAbstract())
+ {
+ result.add(cdoClass);
+ }
+ }
+
+ return result.toArray(new CDOClass[result.size()]);
+ }
+
+ public CDOClass lookupClass(int classifierID)
+ {
+ resolve();
+ return index.get(classifierID);
+ }
+
+ public String getEcore()
+ {
+ if (ecore == null && packageManager instanceof CDOPackageManagerImpl && parentURI == null)
+ {
+ // TODO Can ecore be null?
+ ecore = ((CDOPackageManagerImpl)packageManager).provideEcore(this);
+ }
+
+ return ecore;
+ }
+
+ /**
+ * TODO Add IStore API to demand read dynamic ecore string
+ */
+ public void setEcore(String ecore)
+ {
+ this.ecore = ecore;
+ }
+
+ public CDOIDMetaRange getMetaIDRange()
+ {
+ return metaIDRange;
+ }
+
+ public void setMetaIDRange(CDOIDMetaRange metaIDRange)
+ {
+ this.metaIDRange = metaIDRange;
+ }
+
+ public boolean isDynamic()
+ {
+ return dynamic;
+ }
+
+ public void setDynamic(boolean dynamic)
+ {
+ this.dynamic = dynamic;
+ }
+
+ public boolean isSystem()
+ {
+ return false;
+ }
+
+ public boolean isProxy()
+ {
+ return classes == null;
+ }
+
+ public boolean isPersistent()
+ {
+ return persistent;
+ }
+
+ public void setPersistent(boolean persistent)
+ {
+ this.persistent = persistent;
+ }
+
+ public void addClass(CDOClass cdoClass)
+ {
+ int classifierID = cdoClass.getClassifierID();
+ if (MODEL.isEnabled())
+ {
+ MODEL.format("Adding class: {0}", cdoClass);
+ }
+
+ setIndex(classifierID, cdoClass);
+ classes.add(cdoClass);
+ }
+
+ public int compareTo(CDOPackage that)
+ {
+ return getPackageURI().compareTo(that.getPackageURI());
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("CDOPackage(URI={0}, name={1}, dynamic={2}, metaIDRange={3}, parentURI={4})",
+ packageURI, getName(), dynamic, metaIDRange, parentURI);
+ }
+
+ @Override
+ protected void onInitialize()
+ {
+ for (CDOClass cdoClass : classes)
+ {
+ ((InternalCDOClass)cdoClass).initialize();
+ }
+ }
+
+ private void setIndex(int classifierID, CDOClass cdoClass)
+ {
+ while (classifierID >= index.size())
+ {
+ index.add(null);
+ }
+
+ index.set(classifierID, cdoClass);
+ }
+
+ private void resolve()
+ {
+ if (classes == null && packageManager instanceof CDOPackageManagerImpl)
+ {
+ createLists();
+ ((CDOPackageManagerImpl)packageManager).resolve(this);
+ }
+ }
+
+ private void createLists()
+ {
+ classes = new ArrayList<CDOClass>(0);
+ index = new ArrayList<CDOClass>(0);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOPackageManagerImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOPackageManagerImpl.java
new file mode 100644
index 0000000000..b8c9c21f93
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOPackageManagerImpl.java
@@ -0,0 +1,144 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.model;
+
+import org.eclipse.emf.cdo.common.model.CDOPackage;
+import org.eclipse.emf.cdo.common.model.CDOPackageManager;
+import org.eclipse.emf.cdo.common.model.core.CDOCorePackage;
+import org.eclipse.emf.cdo.common.model.resource.CDOResourcePackage;
+import org.eclipse.emf.cdo.internal.common.bundle.OM;
+import org.eclipse.emf.cdo.internal.common.model.core.CDOCorePackageImpl;
+import org.eclipse.emf.cdo.internal.common.model.resource.CDOResourcePackageImpl;
+
+import org.eclipse.net4j.util.container.Container;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * @author Eike Stepper
+ */
+public abstract class CDOPackageManagerImpl extends Container<CDOPackage> implements CDOPackageManager
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_MODEL, CDOPackageManagerImpl.class);
+
+ private ConcurrentMap<String, CDOPackage> packages = new ConcurrentHashMap<String, CDOPackage>();
+
+ private CDOCorePackage cdoCorePackage;
+
+ private CDOResourcePackage cdoResourcePackage;
+
+ public CDOPackageManagerImpl()
+ {
+ addPackage(cdoCorePackage = new CDOCorePackageImpl(this));
+ addPackage(cdoResourcePackage = new CDOResourcePackageImpl(this));
+ }
+
+ public CDOPackage lookupPackage(String uri)
+ {
+ if (uri == null)
+ {
+ return null;
+ }
+
+ return packages.get(uri);
+ }
+
+ public int getPackageCount()
+ {
+ return packages.size();
+ }
+
+ public CDOPackage[] getPackages()
+ {
+ return packages.values().toArray(new CDOPackage[packages.size()]);
+ }
+
+ public CDOPackage[] getElements()
+ {
+ return getPackages();
+ }
+
+ @Override
+ public boolean isEmpty()
+ {
+ return packages.isEmpty();
+ }
+
+ public CDOCorePackage getCDOCorePackage()
+ {
+ return cdoCorePackage;
+ }
+
+ public CDOResourcePackage getCDOResourcePackage()
+ {
+ return cdoResourcePackage;
+ }
+
+ public List<CDOPackage> getTransientPackages()
+ {
+ List<CDOPackage> result = new ArrayList<CDOPackage>();
+ for (CDOPackage cdoPackage : packages.values())
+ {
+ if (!cdoPackage.isPersistent())
+ {
+ result.add(cdoPackage);
+ }
+ }
+
+ return result;
+ }
+
+ public void addPackage(CDOPackage cdoPackage)
+ {
+ String uri = cdoPackage.getPackageURI();
+ if (uri == null)
+ {
+ throw new IllegalArgumentException("uri == null");
+ }
+
+ CDOPackage existing = packages.putIfAbsent(uri, cdoPackage);
+ if (existing == null)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Added package: {0}", cdoPackage);
+ }
+
+ fireElementAddedEvent(cdoPackage);
+ }
+ else
+ {
+ throw new IllegalStateException("Duplicate package: " + cdoPackage);
+ }
+ }
+
+ public void removePackage(CDOPackage cdoPackage)
+ {
+ packages.remove(cdoPackage.getPackageURI());
+ fireElementRemovedEvent(cdoPackage);
+ }
+
+ /**
+ * @param cdoPackage
+ * is a proxy CDO package. The implementer of this method must only use the package URI of the cdoPackage
+ * passed in.
+ */
+ protected abstract void resolve(CDOPackage cdoPackage);
+
+ /**
+ * Only called on clients for generated models
+ */
+ protected abstract String provideEcore(CDOPackage cdoPackage);
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOTypeImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOTypeImpl.java
new file mode 100644
index 0000000000..a07448bf3a
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOTypeImpl.java
@@ -0,0 +1,472 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.model;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDObjectFactory;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.model.CDOType;
+
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+import org.eclipse.net4j.util.io.ExtendedDataOutput;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Eike Stepper
+ */
+public abstract class CDOTypeImpl implements CDOType
+{
+ public static Map<Integer, CDOTypeImpl> ids = new HashMap<Integer, CDOTypeImpl>();
+
+ private static final byte BOOLEAN_DEFAULT_PRIMITIVE = 0;
+
+ private static final char CHARACTER_DEFAULT_PRIMITIVE = 0;
+
+ private static final short SHORT_DEFAULT_PRIMITIVE = 0;
+
+ public static final Boolean BOOLEAN_DEFAULT = new Boolean(false);
+
+ public static final Byte BYTE_DEFAULT = new Byte(BOOLEAN_DEFAULT_PRIMITIVE);
+
+ public static final Character CHARACTER_DEFAULT = new Character(CHARACTER_DEFAULT_PRIMITIVE);
+
+ public static final Double DOUBLE_DEFAULT = new Double(0.0);
+
+ public static final Float FLOAT_DEFAULT = new Float(0.0);
+
+ public static final Integer INTEGER_DEFAULT = new Integer(0);
+
+ public static final Long LONG_DEFAULT = new Long(0L);
+
+ public static final Short SHORT_DEFAULT = new Short(SHORT_DEFAULT_PRIMITIVE);
+
+ public static final CDOType BOOLEAN = new CDOTypeImpl("BOOLEAN", 22, false, BOOLEAN_DEFAULT)
+ {
+ public void writeValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ boolean v = (Boolean)(value == null ? getDefaultValue() : value);
+ out.writeBoolean(v);
+ }
+
+ public Object readValue(ExtendedDataInput in, CDOIDObjectFactory factory) throws IOException
+ {
+ boolean v = in.readBoolean();
+ return new Boolean(v);
+ }
+ };
+
+ public static final CDOType BYTE = new CDOTypeImpl("BYTE", 24, false, BYTE_DEFAULT)
+ {
+ public void writeValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ out.writeByte((Byte)(value == null ? getDefaultValue() : value));
+ }
+
+ public Object readValue(ExtendedDataInput in, CDOIDObjectFactory factory) throws IOException
+ {
+ return new Byte(in.readByte());
+ }
+ };
+
+ public static final CDOType CHAR = new CDOTypeImpl("CHAR", 27, false, CHARACTER_DEFAULT)
+ {
+ public void writeValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ out.writeChar(((Character)(value == null ? getDefaultValue() : value)).charValue());
+ }
+
+ public Object readValue(ExtendedDataInput in, CDOIDObjectFactory factory) throws IOException
+ {
+ return new Character(in.readChar());
+ }
+ };
+
+ public static final CDOType DOUBLE = new CDOTypeImpl("DOUBLE", 31, false, DOUBLE_DEFAULT)
+ {
+ public void writeValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ out.writeDouble((Double)(value == null ? getDefaultValue() : value));
+ }
+
+ public Object readValue(ExtendedDataInput in, CDOIDObjectFactory factory) throws IOException
+ {
+ return new Double(in.readDouble());
+ }
+ };
+
+ public static final CDOType FLOAT = new CDOTypeImpl("FLOAT", 37, false, FLOAT_DEFAULT)
+ {
+ public void writeValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ out.writeFloat((Float)(value == null ? getDefaultValue() : value));
+ }
+
+ public Object readValue(ExtendedDataInput in, CDOIDObjectFactory factory) throws IOException
+ {
+ return new Float(in.readFloat());
+ }
+ };
+
+ public static final CDOType INT = new CDOTypeImpl("INT", 39, false, INTEGER_DEFAULT)
+ {
+ public void writeValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ out.writeInt((Integer)(value == null ? getDefaultValue() : value));
+ }
+
+ public Object readValue(ExtendedDataInput in, CDOIDObjectFactory factory) throws IOException
+ {
+ return new Integer(in.readInt());
+ }
+ };
+
+ public static final CDOType LONG = new CDOTypeImpl("LONG", 43, false, LONG_DEFAULT)
+ {
+ public void writeValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ out.writeLong((Long)(value == null ? getDefaultValue() : value));
+ }
+
+ public Object readValue(ExtendedDataInput in, CDOIDObjectFactory factory) throws IOException
+ {
+ return new Long(in.readLong());
+ }
+ };
+
+ public static final CDOType SHORT = new CDOTypeImpl("SHORT", 48, false, SHORT_DEFAULT)
+ {
+ public void writeValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ out.writeShort((Short)(value == null ? getDefaultValue() : value));
+ }
+
+ public Object readValue(ExtendedDataInput in, CDOIDObjectFactory factory) throws IOException
+ {
+ return new Short(in.readShort());
+ }
+ };
+
+ public static final CDOType OBJECT = new CDOTypeImpl("OBJECT", 10, true, CDOID.NULL)
+ {
+ public void writeValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ CDOIDUtil.write(out, (CDOID)value);
+ }
+
+ public Object readValue(ExtendedDataInput in, CDOIDObjectFactory factory) throws IOException
+ {
+ return CDOIDUtil.read(in, factory);
+ }
+ };
+
+ public static final CDOType BOOLEAN_OBJECT = new ObjectType("BOOLEAN_OBJECT", 23)
+ {
+ @Override
+ protected void doWriteValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ out.writeBoolean((Boolean)value);
+ }
+
+ @Override
+ protected Object doReadValue(ExtendedDataInput in) throws IOException
+ {
+ return in.readBoolean();
+ }
+ };
+
+ public static final CDOType BYTE_OBJECT = new ObjectType("BYTE_OBJECT", 26)
+ {
+ @Override
+ protected void doWriteValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ out.writeByte((Byte)value);
+ }
+
+ @Override
+ protected Object doReadValue(ExtendedDataInput in) throws IOException
+ {
+ return in.readByte();
+ }
+ };
+
+ public static final CDOType CHARACTER_OBJECT = new ObjectType("CHARACTER_OBJECT", 28)
+ {
+ @Override
+ protected void doWriteValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ out.writeChar((Character)value);
+ }
+
+ @Override
+ protected Object doReadValue(ExtendedDataInput in) throws IOException
+ {
+ return in.readChar();
+ }
+ };
+
+ public static final CDOType DATE = new ObjectType("DATE", 29)
+ {
+ @Override
+ protected void doWriteValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ out.writeLong(((Date)value).getTime());
+ }
+
+ @Override
+ protected Object doReadValue(ExtendedDataInput in) throws IOException
+ {
+ return new Date(in.readLong());
+ }
+ };
+
+ public static final CDOType DOUBLE_OBJECT = new ObjectType("DOUBLE_OBJECT", 32)
+ {
+ @Override
+ protected void doWriteValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ out.writeDouble((Double)value);
+ }
+
+ @Override
+ protected Object doReadValue(ExtendedDataInput in) throws IOException
+ {
+ return in.readDouble();
+ }
+ };
+
+ public static final CDOType FLOAT_OBJECT = new ObjectType("FLOAT_OBJECT", 38)
+ {
+ @Override
+ protected void doWriteValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ out.writeFloat((Float)value);
+ }
+
+ @Override
+ protected Object doReadValue(ExtendedDataInput in) throws IOException
+ {
+ return in.readFloat();
+ }
+ };
+
+ public static final CDOType INTEGER_OBJECT = new ObjectType("INTEGER_OBJECT", 40)
+ {
+ @Override
+ protected void doWriteValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ out.writeInt((Integer)value);
+ }
+
+ @Override
+ protected Object doReadValue(ExtendedDataInput in) throws IOException
+ {
+ return in.readInt();
+ }
+ };
+
+ public static final CDOType LONG_OBJECT = new ObjectType("LONG_OBJECT", 44)
+ {
+ @Override
+ protected void doWriteValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ out.writeLong((Long)value);
+ }
+
+ @Override
+ protected Object doReadValue(ExtendedDataInput in) throws IOException
+ {
+ return in.readLong();
+ }
+ };
+
+ public static final CDOType SHORT_OBJECT = new ObjectType("SHORT_OBJECT", 49)
+ {
+ @Override
+ protected void doWriteValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ out.writeShort((Short)value);
+ }
+
+ @Override
+ protected Object doReadValue(ExtendedDataInput in) throws IOException
+ {
+ return in.readShort();
+ }
+ };
+
+ public static final CDOType STRING = new CDOTypeImpl("STRING", 50, true)
+ {
+ @SuppressWarnings("cast")
+ @Override
+ public Object copyValue(Object value)
+ {
+ return (String)value;
+ }
+
+ public void writeValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ out.writeString((String)value);
+ }
+
+ public Object readValue(ExtendedDataInput in, CDOIDObjectFactory factory) throws IOException
+ {
+ return in.readString();
+ }
+ };
+
+ public static final CDOType BYTE_ARRAY = new CDOTypeImpl("BYTE_ARRAY", 25, true)
+ {
+ @Override
+ public Object copyValue(Object value)
+ {
+ if (value == null)
+ {
+ return null;
+ }
+
+ byte[] array = (byte[])value;
+ byte[] result = new byte[array.length];
+ System.arraycopy(value, 0, result, 0, array.length);
+ return result;
+ }
+
+ public void writeValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ out.writeByteArray((byte[])value);
+ }
+
+ public Object readValue(ExtendedDataInput in, CDOIDObjectFactory factory) throws IOException
+ {
+ return in.readByteArray();
+ }
+ };
+
+ public static final CDOType CUSTOM = new CDOTypeImpl("CUSTOM", 999, true)
+ {
+ @SuppressWarnings("cast")
+ @Override
+ public Object copyValue(Object value)
+ {
+ return (String)value;
+ }
+
+ public void writeValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ out.writeString((String)value);
+ }
+
+ public Object readValue(ExtendedDataInput in, CDOIDObjectFactory factory) throws IOException
+ {
+ return in.readString();
+ }
+ };
+
+ private String name;
+
+ private int typeID;
+
+ private boolean canBeNull;
+
+ private Object defaultValue;
+
+ private CDOTypeImpl(String name, int typeID, boolean canBeNull, Object defaultValue)
+ {
+ this.name = name;
+ this.typeID = typeID;
+ this.canBeNull = canBeNull;
+ this.defaultValue = defaultValue;
+ ids.put(typeID, this);
+ }
+
+ private CDOTypeImpl(String name, int typeID, boolean canBeNull)
+ {
+ this(name, typeID, canBeNull, null);
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public int getTypeID()
+ {
+ return typeID;
+ }
+
+ public boolean canBeNull()
+ {
+ return canBeNull;
+ }
+
+ public Object getDefaultValue()
+ {
+ return defaultValue;
+ }
+
+ @Override
+ public String toString()
+ {
+ return name;
+ }
+
+ public Object copyValue(Object value)
+ {
+ return value == null ? getDefaultValue() : value;
+ }
+
+ public void write(ExtendedDataOutput out) throws IOException
+ {
+ out.writeInt(typeID);
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private static abstract class ObjectType extends CDOTypeImpl
+ {
+ public ObjectType(String name, int typeID)
+ {
+ super(name, typeID, true);
+ }
+
+ public final void writeValue(ExtendedDataOutput out, Object value) throws IOException
+ {
+ if (value == null)
+ {
+ out.writeBoolean(false);
+ }
+ else
+ {
+ out.writeBoolean(true);
+ doWriteValue(out, value);
+ }
+ }
+
+ protected abstract void doWriteValue(ExtendedDataOutput out, Object value) throws IOException;
+
+ public final Object readValue(ExtendedDataInput in, CDOIDObjectFactory factory) throws IOException
+ {
+ boolean notNull = in.readBoolean();
+ if (notNull)
+ {
+ return doReadValue(in);
+ }
+
+ return null;
+ }
+
+ protected abstract Object doReadValue(ExtendedDataInput in) throws IOException;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/core/CDOCorePackageImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/core/CDOCorePackageImpl.java
new file mode 100644
index 0000000000..62c54dd0bf
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/core/CDOCorePackageImpl.java
@@ -0,0 +1,46 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.model.core;
+
+import org.eclipse.emf.cdo.common.model.core.CDOCorePackage;
+import org.eclipse.emf.cdo.internal.common.model.CDOPackageImpl;
+import org.eclipse.emf.cdo.internal.common.model.CDOPackageManagerImpl;
+
+/**
+ * @author Eike Stepper
+ */
+public final class CDOCorePackageImpl extends CDOPackageImpl implements CDOCorePackage
+{
+ private CDOObjectClassImpl cdoObjectClass;
+
+ public CDOCorePackageImpl(CDOPackageManagerImpl packageManager)
+ {
+ super(packageManager, PACKAGE_URI, NAME, null, false, null, null);
+ addClass(cdoObjectClass = new CDOObjectClassImpl(this));
+ }
+
+ public CDOObjectClassImpl getCDOObjectClass()
+ {
+ return cdoObjectClass;
+ }
+
+ @Override
+ public String getEcore()
+ {
+ return null;
+ }
+
+ @Override
+ public boolean isSystem()
+ {
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/core/CDOObjectClassImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/core/CDOObjectClassImpl.java
new file mode 100644
index 0000000000..812a9f48f8
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/core/CDOObjectClassImpl.java
@@ -0,0 +1,32 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.model.core;
+
+import org.eclipse.emf.cdo.common.model.CDOPackage;
+import org.eclipse.emf.cdo.common.model.core.CDOObjectClass;
+import org.eclipse.emf.cdo.internal.common.model.CDOClassImpl;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOObjectClassImpl extends CDOClassImpl implements CDOObjectClass
+{
+ public CDOObjectClassImpl(CDOPackage containingPackage)
+ {
+ super(containingPackage, CLASSIFIER_ID, NAME, false);
+ }
+
+ @Override
+ public boolean isRoot()
+ {
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/resource/CDOContentsFeatureImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/resource/CDOContentsFeatureImpl.java
new file mode 100644
index 0000000000..f8eed25188
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/resource/CDOContentsFeatureImpl.java
@@ -0,0 +1,29 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.model.resource;
+
+import org.eclipse.emf.cdo.common.model.CDOClass;
+import org.eclipse.emf.cdo.common.model.CDOClassProxy;
+import org.eclipse.emf.cdo.common.model.CDOPackageManager;
+import org.eclipse.emf.cdo.common.model.resource.CDOContentsFeature;
+import org.eclipse.emf.cdo.internal.common.model.CDOFeatureImpl;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOContentsFeatureImpl extends CDOFeatureImpl implements CDOContentsFeature
+{
+ public CDOContentsFeatureImpl(CDOClass containingClass, CDOPackageManager packageManager)
+ {
+ super(containingClass, FEATURE_ID, NAME, new CDOClassProxy(packageManager.getCDOCorePackage().getCDOObjectClass()),
+ true, true);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/resource/CDOPathFeatureImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/resource/CDOPathFeatureImpl.java
new file mode 100644
index 0000000000..f42709edb5
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/resource/CDOPathFeatureImpl.java
@@ -0,0 +1,27 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.model.resource;
+
+import org.eclipse.emf.cdo.common.model.CDOClass;
+import org.eclipse.emf.cdo.common.model.resource.CDOPathFeature;
+import org.eclipse.emf.cdo.internal.common.model.CDOFeatureImpl;
+import org.eclipse.emf.cdo.internal.common.model.CDOTypeImpl;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOPathFeatureImpl extends CDOFeatureImpl implements CDOPathFeature
+{
+ public CDOPathFeatureImpl(CDOClass containingClass)
+ {
+ super(containingClass, FEATURE_ID, NAME, CDOTypeImpl.STRING, false);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/resource/CDOResourceClassImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/resource/CDOResourceClassImpl.java
new file mode 100644
index 0000000000..ec747c5195
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/resource/CDOResourceClassImpl.java
@@ -0,0 +1,49 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.model.resource;
+
+import org.eclipse.emf.cdo.common.model.CDOPackage;
+import org.eclipse.emf.cdo.common.model.CDOPackageManager;
+import org.eclipse.emf.cdo.common.model.resource.CDOResourceClass;
+import org.eclipse.emf.cdo.internal.common.model.CDOClassImpl;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOResourceClassImpl extends CDOClassImpl implements CDOResourceClass
+{
+ private CDOPathFeatureImpl cdoPathFeature;
+
+ private CDOContentsFeatureImpl cdoContentsFeature;
+
+ public CDOResourceClassImpl(CDOPackage containingPackage, CDOPackageManager packageManager)
+ {
+ super(containingPackage, CLASSIFIER_ID, NAME, false);
+ addFeature(cdoPathFeature = new CDOPathFeatureImpl(this));
+ addFeature(cdoContentsFeature = new CDOContentsFeatureImpl(this, packageManager));
+ }
+
+ @Override
+ public boolean isResource()
+ {
+ return true;
+ }
+
+ public CDOPathFeatureImpl getCDOPathFeature()
+ {
+ return cdoPathFeature;
+ }
+
+ public CDOContentsFeatureImpl getCDOContentsFeature()
+ {
+ return cdoContentsFeature;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/resource/CDOResourcePackageImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/resource/CDOResourcePackageImpl.java
new file mode 100644
index 0000000000..f1ac7bf14c
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/resource/CDOResourcePackageImpl.java
@@ -0,0 +1,46 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.model.resource;
+
+import org.eclipse.emf.cdo.common.model.resource.CDOResourcePackage;
+import org.eclipse.emf.cdo.internal.common.model.CDOPackageImpl;
+import org.eclipse.emf.cdo.internal.common.model.CDOPackageManagerImpl;
+
+/**
+ * @author Eike Stepper
+ */
+public final class CDOResourcePackageImpl extends CDOPackageImpl implements CDOResourcePackage
+{
+ private CDOResourceClassImpl cdoResourceClass;
+
+ public CDOResourcePackageImpl(CDOPackageManagerImpl packageManager)
+ {
+ super(packageManager, PACKAGE_URI, NAME, null, false, null, null);
+ addClass(cdoResourceClass = new CDOResourceClassImpl(this, packageManager));
+ }
+
+ public CDOResourceClassImpl getCDOResourceClass()
+ {
+ return cdoResourceClass;
+ }
+
+ @Override
+ public String getEcore()
+ {
+ return null;
+ }
+
+ @Override
+ public boolean isSystem()
+ {
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDOReferenceProxyImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDOReferenceProxyImpl.java
new file mode 100644
index 0000000000..88a3b96de4
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDOReferenceProxyImpl.java
@@ -0,0 +1,65 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.revision;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.model.CDOFeature;
+import org.eclipse.emf.cdo.common.revision.CDOReferenceProxy;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionResolver;
+
+import java.text.MessageFormat;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDOReferenceProxyImpl implements CDOReferenceProxy
+{
+ private CDORevision revision;
+
+ private CDOFeature feature;
+
+ private int index;
+
+ public CDOReferenceProxyImpl(CDORevision revision, CDOFeature feature, int index)
+ {
+ this.revision = revision;
+ this.feature = feature;
+ this.index = index;
+ }
+
+ public CDORevision getRevision()
+ {
+ return revision;
+ }
+
+ public CDOFeature getFeature()
+ {
+ return feature;
+ }
+
+ public int getIndex()
+ {
+ return index;
+ }
+
+ public CDOID resolve()
+ {
+ CDORevisionResolver revisionResolver = revision.getRevisionResolver();
+ return revisionResolver.resolveReferenceProxy(this);
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("CDOReferenceProxy[{0}, {1}, {2}", revision, feature, index);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionImpl.java
new file mode 100644
index 0000000000..736b16755d
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionImpl.java
@@ -0,0 +1,814 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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 - https://bugs.eclipse.org/bugs/show_bug.cgi?id=201266
+ * Simon McDuff - https://bugs.eclipse.org/bugs/show_bug.cgi?id=212958
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.common.revision;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDProvider;
+import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.model.CDOClass;
+import org.eclipse.emf.cdo.common.model.CDOClassRef;
+import org.eclipse.emf.cdo.common.model.CDOFeature;
+import org.eclipse.emf.cdo.common.model.CDOModelUtil;
+import org.eclipse.emf.cdo.common.model.CDOPackageManager;
+import org.eclipse.emf.cdo.common.model.CDOType;
+import org.eclipse.emf.cdo.common.revision.CDOReferenceProxy;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionData;
+import org.eclipse.emf.cdo.common.revision.CDORevisionResolver;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDeltaUtil;
+import org.eclipse.emf.cdo.internal.common.bundle.OM;
+import org.eclipse.emf.cdo.internal.common.revision.delta.CDORevisionMerger;
+import org.eclipse.emf.cdo.spi.common.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.InternalCDORevisionDelta;
+
+import org.eclipse.net4j.util.ImplementationError;
+import org.eclipse.net4j.util.collection.MoveableArrayList;
+import org.eclipse.net4j.util.collection.MoveableList;
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+import org.eclipse.net4j.util.io.ExtendedDataOutput;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+import org.eclipse.net4j.util.om.trace.PerfTracer;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDORevisionImpl implements InternalCDORevision
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_REVISION, CDORevisionImpl.class);
+
+ private static final PerfTracer READING = new PerfTracer(OM.PERF_REVISION_READING, CDORevisionImpl.class);
+
+ private static final PerfTracer WRITING = new PerfTracer(OM.PERF_REVISION_WRITING, CDORevisionImpl.class);
+
+ private CDORevisionResolver revisionResolver;
+
+ private CDOClass cdoClass;
+
+ private CDOID id;
+
+ private int version;
+
+ private long created;
+
+ private long revised;
+
+ private CDOID resourceID;
+
+ private CDOID containerID;
+
+ private int containingFeatureID;
+
+ private Object[] values;
+
+ public CDORevisionImpl(CDORevisionResolver revisionResolver, CDOClass cdoClass, CDOID id)
+ {
+ this.revisionResolver = revisionResolver;
+ this.cdoClass = cdoClass;
+ this.id = id;
+ version = 0;
+ created = UNSPECIFIED_DATE;
+ revised = UNSPECIFIED_DATE;
+ resourceID = CDOID.NULL;
+ containerID = CDOID.NULL;
+ containingFeatureID = 0;
+ values = new Object[cdoClass.getAllFeatures().length];
+ }
+
+ public CDORevisionImpl(CDORevisionImpl source)
+ {
+ revisionResolver = source.revisionResolver;
+ cdoClass = source.cdoClass;
+ id = source.id;
+ version = source.version;
+ created = source.created;
+ revised = source.revised; // == UNSPECIFIED
+ resourceID = source.resourceID;
+ containerID = source.containerID;
+ containingFeatureID = source.containingFeatureID;
+ copyValues(source.values);
+ }
+
+ public CDORevisionImpl(ExtendedDataInput in, CDORevisionResolver revisionResolver, CDOPackageManager packageManager)
+ throws IOException
+ {
+ this.revisionResolver = revisionResolver;
+
+ READING.start(this);
+ CDOClassRef classRef = CDOModelUtil.readClassRef(in);
+ cdoClass = classRef.resolve(packageManager);
+ if (cdoClass == null)
+ {
+ throw new IllegalStateException("ClassRef unresolveable: " + classRef);
+ }
+
+ id = CDOIDUtil.read(in, revisionResolver.getCDOIDObjectFactory());
+ version = in.readInt();
+ created = in.readLong();
+ revised = in.readLong();
+ resourceID = CDOIDUtil.read(in, revisionResolver.getCDOIDObjectFactory());
+ containerID = CDOIDUtil.read(in, revisionResolver.getCDOIDObjectFactory());
+ containingFeatureID = in.readInt();
+ if (TRACER.isEnabled())
+ {
+ TRACER
+ .format(
+ "Reading revision: ID={0}, classRef={1}, className={2}, version={3}, created={4}, revised={5}, resource={6}, container={7}, feature={8}",
+ id, classRef, cdoClass.getName(), version, created, revised, resourceID, containerID, containingFeatureID);
+ }
+
+ readValues(in);
+ READING.stop(this);
+ }
+
+ public void write(ExtendedDataOutput out, CDOIDProvider idProvider, int referenceChunk) throws IOException
+ {
+ CDOClassRef classRef = cdoClass.createClassRef();
+ if (TRACER.isEnabled())
+ {
+ TRACER
+ .format(
+ "Writing revision: ID={0}, classRef={1}, className={2}, version={3}, created={4}, revised={5}, resource={6}, container={7}, feature={8}",
+ id, classRef, cdoClass.getName(), getVersion(), created, revised, resourceID, containerID,
+ containingFeatureID);
+ }
+
+ WRITING.start(this);
+ CDOModelUtil.writeClassRef(out, classRef);
+ CDOIDUtil.write(out, id);
+ out.writeInt(getVersion());
+ out.writeLong(created);
+ out.writeLong(revised);
+ CDOIDUtil.write(out, resourceID);
+ CDOIDUtil.write(out, containerID);
+ out.writeInt(containingFeatureID);
+ writeValues(out, idProvider, referenceChunk);
+ WRITING.stop(this);
+ }
+
+ public CDORevisionResolver getRevisionResolver()
+ {
+ return revisionResolver;
+ }
+
+ public CDOClass getCDOClass()
+ {
+ return cdoClass;
+ }
+
+ public CDOID getID()
+ {
+ return id;
+ }
+
+ public void setID(CDOID id)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Setting ID: {0}", id);
+ }
+
+ this.id = id;
+ }
+
+ public int getVersion()
+ {
+ return version < 0 ? -version : version;
+ }
+
+ public void setVersion(int version)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Setting version for {0}: v{1}", this, version);
+ }
+
+ this.version = version;
+ }
+
+ public boolean isTransactional()
+ {
+ return version < 0;
+ }
+
+ public int setTransactional()
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Setting transactional {0}: v{1}", this, -(version + 1));
+ }
+
+ version = -(version + 1);
+ return version;
+ }
+
+ public void setUntransactional()
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Setting untransactional {0}: v{1}", this, Math.abs(version));
+ }
+
+ version = Math.abs(version);
+ }
+
+ public long getCreated()
+ {
+ return created;
+ }
+
+ public void setCreated(long created)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Setting created {0}: {1,date} {1,time}", this, created);
+ }
+
+ this.created = created;
+ }
+
+ public long getRevised()
+ {
+ return revised;
+ }
+
+ public void setRevised(long revised)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Setting revised {0}: {1,date} {1,time}", this, revised);
+ }
+
+ this.revised = revised;
+ }
+
+ public boolean isCurrent()
+ {
+ return revised == UNSPECIFIED_DATE;
+ }
+
+ public boolean isValid(long timeStamp)
+ {
+ return (revised == UNSPECIFIED_DATE || revised >= timeStamp) && timeStamp >= created;
+ }
+
+ public boolean isResource()
+ {
+ return cdoClass.isResource();
+ }
+
+ public CDORevisionData getData()
+ {
+ return this;
+ }
+
+ public CDORevision getRevision()
+ {
+ return this;
+ }
+
+ public InternalCDORevisionDelta compare(CDORevision origin)
+ {
+ return (InternalCDORevisionDelta)CDORevisionDeltaUtil.create(origin, this);
+ }
+
+ public void merge(CDORevisionDelta delta)
+ {
+ CDORevisionMerger applier = new CDORevisionMerger();
+ applier.merge(this, delta);
+ }
+
+ public CDOID getResourceID()
+ {
+ return resourceID;
+ }
+
+ public void setResourceID(CDOID resourceID)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Setting resourceID {0}: {1}", this, resourceID);
+ }
+
+ this.resourceID = resourceID;
+ }
+
+ public CDOID getContainerID()
+ {
+ return containerID;
+ }
+
+ public void setContainerID(CDOID containerID)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Setting containerID {0}: {1}", this, containerID);
+ }
+
+ this.containerID = containerID;
+ }
+
+ public int getContainingFeatureID()
+ {
+ return containingFeatureID;
+ }
+
+ public void setContainingFeatureID(int containingFeatureID)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Setting containingFeatureID {0}: {1}", this, containingFeatureID);
+ }
+
+ this.containingFeatureID = containingFeatureID;
+ }
+
+ public int hashCode(CDOFeature feature)
+ {
+ return getValue(feature).hashCode();
+ }
+
+ public Object get(CDOFeature feature, int index)
+ {
+ if (feature.isMany())
+ {
+ return getList(feature).get(index);
+ }
+
+ return getValue(feature);
+ }
+
+ public boolean contains(CDOFeature feature, Object value)
+ {
+ return getList(feature).contains(value);
+ }
+
+ public int indexOf(CDOFeature feature, Object value)
+ {
+ return getList(feature).indexOf(value);
+ }
+
+ public boolean isEmpty(CDOFeature feature)
+ {
+ return getList(feature).isEmpty();
+ }
+
+ public boolean isSet(CDOFeature feature)
+ {
+ return getValue(feature) != null;
+ }
+
+ public int lastIndexOf(CDOFeature feature, Object value)
+ {
+ return getList(feature).lastIndexOf(value);
+ }
+
+ public int size(CDOFeature feature)
+ {
+ return getList(feature).size();
+ }
+
+ public Object[] toArray(CDOFeature feature)
+ {
+ if (!feature.isMany())
+ {
+ throw new IllegalStateException("!feature.isMany()");
+ }
+
+ return getList(feature).toArray();
+ }
+
+ public <T> T[] toArray(CDOFeature feature, T[] array)
+ {
+ if (!feature.isMany())
+ {
+ throw new IllegalStateException("!feature.isMany()");
+ }
+
+ return getList(feature).toArray(array);
+ }
+
+ public void add(CDOFeature feature, int index, Object value)
+ {
+ getList(feature).add(index, value);
+ }
+
+ public void clear(CDOFeature feature)
+ {
+ setValue(feature, null);
+ }
+
+ public Object move(CDOFeature feature, int targetIndex, int sourceIndex)
+ {
+ return getList(feature).move(targetIndex, sourceIndex);
+ }
+
+ public Object remove(CDOFeature feature, int index)
+ {
+ return getList(feature).remove(index);
+ }
+
+ public Object set(CDOFeature feature, int index, Object value)
+ {
+ if (feature.isMany())
+ {
+ return getList(feature).set(index, value);
+ }
+
+ return setValue(feature, value);
+ }
+
+ public void unset(CDOFeature feature)
+ {
+ setValue(feature, null);
+ }
+
+ public void adjustReferences(Map<CDOIDTemp, CDOID> idMappings)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Adjusting references for revision {0}", this);
+ }
+
+ resourceID = (CDOID)remapID(resourceID, idMappings);
+ containerID = (CDOID)remapID(containerID, idMappings);
+
+ CDOFeature[] features = cdoClass.getAllFeatures();
+ for (int i = 0; i < features.length; i++)
+ {
+ CDOFeature feature = features[i];
+ if (feature.isReference())
+ {
+ if (feature.isMany())
+ {
+ List<Object> list = getValueAsList(i);
+ int size = list == null ? 0 : list.size();
+ for (int j = 0; j < size; j++)
+ {
+ Object oldID = list.get(j);
+ Object newID = remapID(oldID, idMappings);
+ if (newID != oldID)
+ {
+ list.set(j, newID);
+ }
+ }
+ }
+ else
+ {
+ values[i] = remapID(values[i], idMappings);
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private List<Object> getValueAsList(int i)
+ {
+ return (List<Object>)values[i];
+ }
+
+ @Override
+ public String toString()
+ {
+ return cdoClass.getName() + "@" + id + "v" + version;
+ }
+
+ public Object getValue(CDOFeature feature)
+ {
+ int i = cdoClass.getFeatureID(feature);
+ return values[i];
+ }
+
+ public Object setValue(CDOFeature feature, Object value)
+ {
+ int i = cdoClass.getFeatureID(feature);
+ Object old = values[i];
+ values[i] = value;
+ return old;
+ }
+
+ public MoveableList<Object> getList(CDOFeature feature)
+ {
+ return getList(feature, 0);
+ }
+
+ @SuppressWarnings("unchecked")
+ public MoveableList<Object> getList(CDOFeature feature, int size)
+ {
+ int i = cdoClass.getFeatureID(feature);
+ MoveableList<Object> list = (MoveableList<Object>)values[i];
+ if (list == null)
+ {
+ list = new MoveableArrayList<Object>(size);
+ values[i] = list;
+ }
+
+ return list;
+ }
+
+ public void setListSize(CDOFeature feature, int size)
+ {
+ MoveableList<Object> list = getList(feature, size);
+ for (int j = list.size(); j < size; j++)
+ {
+ list.add(InternalCDORevision.UNINITIALIZED);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void copyValues(Object[] sourceValues)
+ {
+ CDOFeature[] features = cdoClass.getAllFeatures();
+ values = new Object[features.length];
+ for (int i = 0; i < features.length; i++)
+ {
+ CDOFeature feature = features[i];
+ CDOType type = feature.getType();
+ if (feature.isMany())
+ {
+ MoveableList<Object> sourceList = (MoveableList<Object>)sourceValues[i];
+ if (sourceList != null)
+ {
+ int size = sourceList.size();
+ MoveableList<Object> list = new MoveableArrayList<Object>(size);
+ for (int j = 0; j < size; j++)
+ {
+ Object value = sourceList.get(j);
+ if (value instanceof CDOReferenceProxy)
+ {
+ list.add(new CDOReferenceProxyImpl(this, feature, ((CDOReferenceProxy)value).getIndex()));
+ }
+ else
+ {
+ list.add(type.copyValue(value));
+ }
+ }
+
+ values[i] = list;
+ }
+ }
+ else
+ {
+ values[i] = type.copyValue(sourceValues[i]);
+ }
+ }
+ }
+
+ private void readValues(ExtendedDataInput in) throws IOException
+ {
+ CDOFeature[] features = cdoClass.getAllFeatures();
+ values = new Object[features.length];
+ for (int i = 0; i < features.length; i++)
+ {
+ CDOFeature feature = features[i];
+ CDOType type = feature.getType();
+ if (feature.isMany())
+ {
+ int referenceChunk;
+ int size = in.readInt();
+ if (size < 0)
+ {
+ size = -size;
+ referenceChunk = in.readInt();
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Read feature {0}: size={1}, referenceChunk={2}", feature, size, referenceChunk);
+ }
+ }
+ else
+ {
+ referenceChunk = size;
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Read feature {0}: size={1}", feature, size);
+ }
+ }
+
+ if (size != 0)
+ {
+ CDORevisionImpl baseRevision = null;
+ MoveableList<Object> list = new MoveableArrayList<Object>(size);
+ values[i] = list;
+ int ranges = in.readInt();
+ if (ranges != 0)
+ {
+ // This happens only on server side
+ while (ranges-- > 0)
+ {
+ int range = in.readInt();
+ if (range > 0)
+ {
+ while (range-- > 0)
+ {
+ Object value = type.readValue(in, revisionResolver.getCDOIDObjectFactory());
+ list.add(value);
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace(" " + value);
+ }
+ }
+ }
+ else
+ {
+ if (baseRevision == null)
+ {
+ baseRevision = (CDORevisionImpl)revisionResolver.getRevisionByVersion(id, CDORevision.UNCHUNKED,
+ getVersion() - 1);
+ }
+
+ MoveableList<Object> baseList = baseRevision.getList(feature);
+ int index = in.readInt();
+ while (range++ < 0)
+ {
+ Object value = baseList.get(index++);
+ list.add(value);
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace(" " + value);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ for (int j = 0; j < referenceChunk; j++)
+ {
+ Object value = type.readValue(in, revisionResolver.getCDOIDObjectFactory());
+ list.add(value);
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace(" " + value);
+ }
+ }
+
+ for (int j = referenceChunk; j < size; j++)
+ {
+ list.add(new CDOReferenceProxyImpl(this, feature, j));
+ }
+ }
+ }
+ }
+ else
+ {
+ values[i] = type.readValue(in, revisionResolver.getCDOIDObjectFactory());
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Read feature {0}: {1}", feature, values[i]);
+ }
+ }
+ }
+ }
+
+ private void writeValues(ExtendedDataOutput out, CDOIDProvider idProvider, int referenceChunk) throws IOException
+ {
+ CDOFeature[] features = cdoClass.getAllFeatures();
+ for (int i = 0; i < features.length; i++)
+ {
+ CDOFeature feature = features[i];
+ if (feature.isMany())
+ {
+ List<Object> list = getValueAsList(i);
+ int size = list == null ? 0 : list.size();
+ if (referenceChunk != CDORevision.UNCHUNKED && referenceChunk < size)
+ {
+ // This happens only on server-side
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Writing feature {0}: size={1}, referenceChunk={2}", feature, size, referenceChunk);
+ }
+
+ out.writeInt(-size);
+ out.writeInt(referenceChunk);
+ size = referenceChunk;
+ }
+ else
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Writing feature {0}: size={1}", feature, size);
+ }
+
+ out.writeInt(size);
+ }
+
+ if (size != 0)
+ {
+ List<Integer> ranges = revisionResolver.analyzeReferenceRanges(list);
+ if (ranges != null)
+ {
+ // This happens only on client-side
+ out.writeInt(ranges.size());
+ int j = 0;
+ for (int range : ranges)
+ {
+ out.writeInt(range);
+ if (range > 0)
+ {
+ // This is an id range
+ while (range-- > 0)
+ {
+ Object value = list.get(j);
+ if (value != null && feature.isReference())
+ {
+ value = idProvider.provideCDOID(value);
+ list.set(j, value);
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace(" " + value);
+ }
+
+ feature.getType().writeValue(out, value);
+ ++j;
+ }
+ }
+ else
+ {
+ // This is a proxy range
+ CDOReferenceProxy proxy = (CDOReferenceProxy)list.get(j);
+ out.writeInt(proxy.getIndex());
+ j -= range; // Increase j to next range start
+ }
+ }
+ }
+ else
+ {
+ out.writeInt(0); // No ranges -> no ref proxies
+ for (int j = 0; j < size; j++)
+ {
+ Object value = list.get(j);
+ if (value != null && feature.isReference())
+ {
+ value = idProvider.provideCDOID(value);
+ list.set(j, value);
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace(" " + value);
+ }
+
+ feature.getType().writeValue(out, value);
+ }
+ }
+ }
+ }
+ else
+ {
+ if (values[i] != null && feature.isReference())
+ {
+ values[i] = idProvider.provideCDOID(values[i]);
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Writing feature {0}: {1}", feature, values[i]);
+ }
+
+ feature.getType().writeValue(out, values[i]);
+ }
+ }
+ }
+
+ public static Object remapID(Object value, Map<CDOIDTemp, CDOID> idMappings)
+ {
+ if (value instanceof CDOIDTemp)
+ {
+ CDOIDTemp oldID = (CDOIDTemp)value;
+ if (!oldID.isNull())
+ {
+ CDOID newID = idMappings.get(oldID);
+ if (newID == null)
+ {
+ throw new ImplementationError("Missing ID mapping for " + oldID);
+ }
+
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Adjusting ID: {0} --> {1}", oldID, newID);
+ }
+
+ return newID;
+ }
+ }
+
+ return value;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionResolverImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionResolverImpl.java
new file mode 100644
index 0000000000..63b3f3d708
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/CDORevisionResolverImpl.java
@@ -0,0 +1,528 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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 - https://bugs.eclipse.org/bugs/show_bug.cgi?id=201266
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.common.revision;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.model.CDOClass;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionResolver;
+import org.eclipse.emf.cdo.internal.common.bundle.OM;
+import org.eclipse.emf.cdo.spi.common.InternalCDORevision;
+
+import org.eclipse.net4j.util.lifecycle.Lifecycle;
+import org.eclipse.net4j.util.om.trace.ContextTracer;
+
+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.Map;
+
+/**
+ * @author Eike Stepper
+ */
+public abstract class CDORevisionResolverImpl extends Lifecycle implements CDORevisionResolver
+{
+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_REVISION, CDORevisionResolverImpl.class);
+
+ private Map<CDOID, RevisionHolder> revisions = new HashMap<CDOID, RevisionHolder>();
+
+ // {
+ // private static final long serialVersionUID = 1L;
+ //
+ // @Override
+ // public String toString()
+ // {
+ // List<Entry<CDOID, RevisionHolder>> entries = new ArrayList<Entry<CDOID, RevisionHolder>>(entrySet());
+ // Collections.sort(entries, new Comparator<Entry<CDOID, RevisionHolder>>()
+ // {
+ // public int compare(Entry<CDOID, RevisionHolder> o1, Entry<CDOID, RevisionHolder> o2)
+ // {
+ // return o1.getKey().compareTo(o2.getKey());
+ // }
+ // });
+ //
+ // StringBuilder builder = new StringBuilder();
+ // for (Entry<CDOID, RevisionHolder> entry : entries)
+ // {
+ // builder.append(entry.getKey());
+ // builder.append(" -->");
+ // RevisionHolder holder = entry.getValue();
+ // while (holder != null)
+ // {
+ // builder.append(" ");
+ // builder.append(holder.getRevision(false));
+ // holder = holder.getNext();
+ // }
+ //
+ // builder.append("\n");
+ // }
+ //
+ // return builder.toString();
+ // }
+ // };
+
+ private int currentLRUCapacity;
+
+ private int revisedLRUCapacity;
+
+ private LRU currentLRU;
+
+ private LRU revisedLRU;
+
+ public CDORevisionResolverImpl()
+ {
+ }
+
+ public int getCurrentLRUCapacity()
+ {
+ return currentLRUCapacity;
+ }
+
+ public void setCurrentLRUCapacity(int capacity)
+ {
+ currentLRUCapacity = capacity;
+ if (currentLRU != null)
+ {
+ currentLRU.capacity(capacity);
+ }
+ }
+
+ public int getRevisedLRUCapacity()
+ {
+ return revisedLRUCapacity;
+ }
+
+ public void setRevisedLRUCapacity(int capacity)
+ {
+ revisedLRUCapacity = capacity;
+ if (revisedLRU != null)
+ {
+ revisedLRU.capacity(capacity);
+ }
+ }
+
+ public CDOClass getObjectType(CDOID id)
+ {
+ RevisionHolder holder = revisions.get(id);
+ if (holder == null)
+ {
+ return null;
+ }
+
+ InternalCDORevision revision = (InternalCDORevision)holder.getRevision(true);
+ return revision.getCDOClass();
+ }
+
+ public boolean containsRevision(CDOID id)
+ {
+ return revisions.containsKey(id);
+ }
+
+ public boolean containsRevisionByTime(CDOID id, long timeStamp)
+ {
+ return getRevisionByTime(id, 0, timeStamp, false) != null;
+ }
+
+ public boolean containsRevisionByVersion(CDOID id, int version)
+ {
+ return getRevisionByVersion(id, 0, version, false) != null;
+ }
+
+ public InternalCDORevision getRevision(CDOID id, int referenceChunk)
+ {
+ return getRevision(id, referenceChunk, true);
+ }
+
+ public List<CDORevision> getRevisions(Collection<CDOID> ids, int referenceChunk)
+ {
+ List<CDOID> missingIDs = new ArrayList<CDOID>(0);
+ List<CDORevision> revisions = new ArrayList<CDORevision>(ids.size());
+ for (CDOID id : ids)
+ {
+ InternalCDORevision revision = getRevision(id, referenceChunk, false);
+ revisions.add(revision);
+ if (revision == null)
+ {
+ missingIDs.add(id);
+ }
+ }
+
+ if (!missingIDs.isEmpty())
+ {
+ List<InternalCDORevision> missingRevisions = loadRevisions(missingIDs, referenceChunk);
+ handleMissingRevisions(revisions, missingRevisions);
+ }
+
+ return revisions;
+ }
+
+ public InternalCDORevision getRevisionByTime(CDOID id, int referenceChunk, long timeStamp)
+ {
+ return getRevisionByTime(id, referenceChunk, timeStamp, true);
+ }
+
+ public List<CDORevision> getRevisionsByTime(Collection<CDOID> ids, int referenceChunk, long timeStamp)
+ {
+ List<CDOID> missingIDs = new ArrayList<CDOID>(0);
+ List<CDORevision> revisions = new ArrayList<CDORevision>(ids.size());
+ for (CDOID id : ids)
+ {
+ InternalCDORevision revision = getRevisionByTime(id, referenceChunk, timeStamp, false);
+ revisions.add(revision);
+ if (revision == null)
+ {
+ missingIDs.add(id);
+ }
+ }
+
+ if (!missingIDs.isEmpty())
+ {
+ List<InternalCDORevision> missingRevisions = loadRevisions(missingIDs, referenceChunk);
+ handleMissingRevisions(revisions, missingRevisions);
+ }
+
+ return revisions;
+ }
+
+ public synchronized InternalCDORevision getRevisionByVersion(CDOID id, int referenceChunk, int version)
+ {
+ return getRevisionByVersion(id, referenceChunk, version, true);
+ }
+
+ public synchronized InternalCDORevision getRevisionByVersion(CDOID id, int referenceChunk, int version,
+ boolean loadOnDemand)
+ {
+ RevisionHolder holder = revisions.get(id);
+ while (holder != null)
+ {
+ int holderVersion = holder.getVersion();
+ if (holderVersion > version)
+ {
+ holder = holder.getNext();
+ }
+ else if (holderVersion == version)
+ {
+ return (InternalCDORevision)holder.getRevision(true);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (loadOnDemand)
+ {
+ InternalCDORevision revision = loadRevisionByVersion(id, referenceChunk, version);
+ if (revision != null)
+ {
+ addRevision(revision);
+ return revision;
+ }
+ }
+
+ return null;
+ }
+
+ public boolean addRevision(InternalCDORevision revision)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Adding revision: {0}, created={1,date} {1,time}, revised={2,date} {2,time}, current={3}",
+ revision, revision.getCreated(), revision.getRevised(), revision.isCurrent());
+ }
+
+ RevisionHolder newHolder = createHolder(revision);
+ LRU list = revision.isCurrent() ? currentLRU : revisedLRU;
+ list.add((DLRevisionHolder)newHolder);
+
+ int version = revision.getVersion();
+ RevisionHolder lastHolder = null;
+ RevisionHolder holder = revisions.get(revision.getID());
+ while (holder != null)
+ {
+ int holderVersion = holder.getVersion();
+ if (holderVersion > version)
+ {
+ lastHolder = holder;
+ holder = holder.getNext();
+ }
+ else if (holderVersion == version)
+ {
+ return false;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ adjustHolder(revision, newHolder, lastHolder, holder);
+ return true;
+ }
+
+ protected InternalCDORevision getRevision(CDOID id, int referenceChunk, boolean loadOnDemand)
+ {
+ RevisionHolder holder = revisions.get(id);
+ InternalCDORevision revision = holder == null ? null : (InternalCDORevision)holder.getRevision(true);
+ if (revision == null || !revision.isCurrent())
+ {
+ if (loadOnDemand)
+ {
+ revision = loadRevision(id, referenceChunk);
+ if (revision == null)
+ {
+ throw new IllegalStateException("Could not load revision for " + id);
+ }
+
+ addRevision(revision);
+ }
+ else
+ {
+ revision = null;
+ }
+ }
+ else
+ {
+ InternalCDORevision oldRevision = revision;
+ revision = verifyRevision(oldRevision, referenceChunk);
+ if (revision != oldRevision)
+ {
+ addRevision(revision);
+ }
+ }
+
+ return revision;
+ }
+
+ protected synchronized InternalCDORevision getRevisionByTime(CDOID id, int referenceChunk, long timeStamp,
+ boolean loadOnDemand)
+ {
+ RevisionHolder holder = revisions.get(id);
+ while (holder != null)
+ {
+ int indicator = holder.compareTo(timeStamp);
+ if (indicator == 1)
+ {
+ // timeStamp is after holder timeSpan
+ holder = holder.getNext();
+ }
+ else if (indicator == 0)
+ {
+ // timeStamp is within holder timeSpan
+ InternalCDORevision oldRevision = (InternalCDORevision)holder.getRevision(true);
+ InternalCDORevision revision = verifyRevision(oldRevision, referenceChunk);
+ if (revision != oldRevision)
+ {
+ addRevision(revision);
+ }
+
+ return revision;
+ }
+ else
+ {
+ // timeStamp is before holder timeSpan
+ break;
+ }
+ }
+
+ if (loadOnDemand)
+ {
+ InternalCDORevision revision = loadRevisionByTime(id, referenceChunk, timeStamp);
+ if (revision != null)
+ {
+ addRevision(revision);
+ return revision;
+ }
+ }
+
+ return null;
+ }
+
+ protected abstract InternalCDORevision loadRevision(CDOID id, int referenceChunk);
+
+ protected abstract InternalCDORevision loadRevisionByTime(CDOID id, int referenceChunk, long timeStamp);
+
+ protected abstract InternalCDORevision loadRevisionByVersion(CDOID id, int referenceChunk, int version);
+
+ protected abstract List<InternalCDORevision> loadRevisions(Collection<CDOID> ids, int referenceChunk);
+
+ protected abstract List<InternalCDORevision> loadRevisionsByTime(Collection<CDOID> ids, int referenceChunk,
+ long timeStamp);
+
+ protected void handleMissingRevisions(List<CDORevision> revisions, List<InternalCDORevision> missingRevisions)
+ {
+ Iterator<InternalCDORevision> it = missingRevisions.iterator();
+ for (int i = 0; i < revisions.size(); i++)
+ {
+ CDORevision revision = revisions.get(i);
+ if (revision == null)
+ {
+ InternalCDORevision missingRevision = it.next();
+ revisions.set(i, missingRevision);
+ addRevision(missingRevision);
+ }
+ }
+ }
+
+ protected synchronized void removeRevision(CDOID id, int version)
+ {
+ RevisionHolder holder = revisions.get(id);
+ while (holder != null)
+ {
+ int holderVersion = holder.getVersion();
+ if (holderVersion > version)
+ {
+ holder = holder.getNext();
+ }
+ else
+ {
+ if (holderVersion == version)
+ {
+ removeHolder(holder);
+ }
+
+ holder = null;
+ }
+ }
+ }
+
+ protected InternalCDORevision verifyRevision(InternalCDORevision revision, int referenceChunk)
+ {
+ return revision;
+ }
+
+ @Override
+ protected void doActivate() throws Exception
+ {
+ super.doActivate();
+ currentLRU = new LRU(currentLRUCapacity);
+ revisedLRU = new LRU(revisedLRUCapacity);
+ }
+
+ @Override
+ protected void doDeactivate() throws Exception
+ {
+ currentLRU = null;
+ revisedLRU = null;
+ super.doDeactivate();
+ }
+
+ private void adjustHolder(InternalCDORevision revision, RevisionHolder holder, RevisionHolder prevHolder,
+ RevisionHolder nextHolder)
+ {
+ if (prevHolder != null)
+ {
+ if (nextHolder == null)
+ {
+ nextHolder = prevHolder.getNext();
+ }
+
+ holder.setPrev(prevHolder);
+ holder.setNext(nextHolder);
+ prevHolder.setNext(holder);
+ }
+ else
+ {
+ holder.setNext(nextHolder);
+ revisions.put(revision.getID(), holder);
+ }
+
+ reviseHolder(holder, nextHolder);
+ }
+
+ private void reviseHolder(RevisionHolder holder, RevisionHolder nextHolder)
+ {
+ if (nextHolder != null)
+ {
+ nextHolder.setPrev(holder);
+ if (holder.isCurrent() && nextHolder.isCurrent())
+ {
+ currentLRU.remove((DLRevisionHolder)nextHolder);
+ revisedLRU.add((DLRevisionHolder)nextHolder);
+
+ InternalCDORevision oldRevision = (InternalCDORevision)nextHolder.getRevision(false);
+ if (oldRevision != null)
+ {
+ oldRevision.setRevised(holder.getCreated() - 1);
+ }
+ }
+ }
+ }
+
+ private synchronized void removeHolder(RevisionHolder holder)
+ {
+ CDOID id = holder.getID();
+ RevisionHolder prev = holder.getPrev();
+ RevisionHolder next = holder.getNext();
+ if (next != null)
+ {
+ next.setPrev(prev);
+ }
+
+ if (prev != null)
+ {
+ prev.setNext(next);
+ }
+ else
+ {
+ if (next != null)
+ {
+ revisions.put(id, next);
+ }
+ else
+ {
+ revisions.remove(id);
+ }
+ }
+
+ holder.setPrev(null);
+ holder.setNext(null);
+ }
+
+ private RevisionHolder createHolder(InternalCDORevision revision)
+ {
+ LRURevisionList list = revision.isCurrent() ? currentLRU : revisedLRU;
+ return new LRURevisionHolder(list, revision);
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private final class LRU extends LRURevisionList
+ {
+ public LRU(int capacity)
+ {
+ super(capacity);
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("LRU[size={0}, capacity={1}]", size(), capacity());
+ }
+
+ @Override
+ protected void evict(LRURevisionHolder holder)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.format("Evicting revision {0}v{1}", holder.getID(), holder.getVersion());
+ }
+
+ super.evict(holder);
+ removeHolder(holder);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/DLRevisionHolder.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/DLRevisionHolder.java
new file mode 100644
index 0000000000..86f94cb422
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/DLRevisionHolder.java
@@ -0,0 +1,56 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.revision;
+
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+
+/**
+ * @author Eike Stepper
+ */
+public class DLRevisionHolder extends RevisionHolder
+{
+ private DLRevisionList dlList;
+
+ private DLRevisionHolder dlPrev;
+
+ private DLRevisionHolder dlNext;
+
+ public DLRevisionHolder(DLRevisionList list, CDORevision revision)
+ {
+ super(revision);
+ dlList = list;
+ }
+
+ public DLRevisionList getDLList()
+ {
+ return dlList;
+ }
+
+ public DLRevisionHolder getDLPrev()
+ {
+ return dlPrev;
+ }
+
+ public void setDLPrev(DLRevisionHolder prev)
+ {
+ dlPrev = prev;
+ }
+
+ public DLRevisionHolder getDLNext()
+ {
+ return dlNext;
+ }
+
+ public void setDLNext(DLRevisionHolder next)
+ {
+ dlNext = next;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/DLRevisionList.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/DLRevisionList.java
new file mode 100644
index 0000000000..f8ba7b7432
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/DLRevisionList.java
@@ -0,0 +1,222 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.revision;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.spi.common.InternalCDORevision;
+
+import java.text.MessageFormat;
+
+/**
+ * @author Eike Stepper
+ */
+public class DLRevisionList extends DLRevisionHolder
+{
+ private int size;
+
+ public DLRevisionList()
+ {
+ super(null, null);
+ setDLHead(this);
+ setDLTail(this);
+ }
+
+ public int size()
+ {
+ return size;
+ }
+
+ public DLRevisionHolder getDLHead()
+ {
+ return getDLNext();
+ }
+
+ public void setDLHead(DLRevisionHolder head)
+ {
+ setDLNext(head);
+ }
+
+ public DLRevisionHolder getDLTail()
+ {
+ return getDLPrev();
+ }
+
+ public void setDLTail(DLRevisionHolder tail)
+ {
+ setDLPrev(tail);
+ }
+
+ public DLRevisionHolder get(int index)
+ {
+ if (index < 0 || index >= size)
+ {
+ throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
+ }
+
+ DLRevisionHolder holder = this;
+ if (index < size >> 1)
+ {
+ for (int i = 0; i <= index; i++)
+ {
+ holder = holder.getDLNext();
+ }
+ }
+ else
+ {
+ for (int i = size; i > index; i--)
+ {
+ holder = holder.getDLPrev();
+ }
+ }
+
+ return holder;
+ }
+
+ public void add(DLRevisionHolder holder)
+ {
+ addTail(holder);
+ }
+
+ public synchronized void addHead(DLRevisionHolder holder)
+ {
+ ++size;
+ DLRevisionHolder head = getDLHead();
+ head.setDLPrev(holder);
+ holder.setDLNext(head);
+ holder.setDLPrev(this);
+ setDLHead(holder);
+ }
+
+ public synchronized void addTail(DLRevisionHolder holder)
+ {
+ ++size;
+ DLRevisionHolder tail = getDLTail();
+ tail.setDLNext(holder);
+ holder.setDLPrev(tail);
+ holder.setDLNext(this);
+ setDLTail(holder);
+ }
+
+ public synchronized void remove(DLRevisionHolder holder)
+ {
+ --size;
+ DLRevisionHolder prev = holder.getDLPrev();
+ DLRevisionHolder next = holder.getDLNext();
+
+ prev.setDLNext(next);
+ holder.setDLPrev(null);
+ holder.setDLNext(null);
+ next.setDLPrev(prev);
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("DLRevisionList[size={0}]", size);
+ }
+
+ @Override
+ public int compareTo(long timeStamp)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public long getCreated()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public DLRevisionList getDLList()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CDOID getID()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public RevisionHolder getNext()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public RevisionHolder getPrev()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public long getRevised()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public CDORevision getRevision(boolean loadOnDemand)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getVersion()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isCurrent()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isLoaded()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isValid(long timeStamp)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected InternalCDORevision loadRevision()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setNext(RevisionHolder next)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setPrev(RevisionHolder prev)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setRevision(CDORevision revision)
+ {
+ // Ignore
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/LRURevisionHolder.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/LRURevisionHolder.java
new file mode 100644
index 0000000000..4eb20d9a25
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/LRURevisionHolder.java
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.revision;
+
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+
+/**
+ * @author Eike Stepper
+ */
+public class LRURevisionHolder extends DLRevisionHolder
+{
+ private long usedStamp;
+
+ public LRURevisionHolder(LRURevisionList list, CDORevision revision)
+ {
+ super(list, revision);
+ usedStamp = System.currentTimeMillis();
+ }
+
+ @Override
+ public LRURevisionList getDLList()
+ {
+ return (LRURevisionList)super.getDLList();
+ }
+
+ public long getUsedStamp()
+ {
+ return usedStamp;
+ }
+
+ @Override
+ public CDORevision getRevision(boolean loadOnDemand)
+ {
+ if (loadOnDemand)
+ {
+ stamp();
+ }
+
+ return super.getRevision(loadOnDemand);
+ }
+
+ protected void stamp()
+ {
+ usedStamp = System.currentTimeMillis();
+ LRURevisionList list = getDLList();
+ if (list != null)
+ {
+ synchronized (list)
+ {
+ list.remove(this);
+ list.addHead(this);
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/LRURevisionList.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/LRURevisionList.java
new file mode 100644
index 0000000000..26525a7ac9
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/LRURevisionList.java
@@ -0,0 +1,66 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.revision;
+
+import java.text.MessageFormat;
+
+/**
+ * @author Eike Stepper
+ */
+public class LRURevisionList extends DLRevisionList
+{
+ private int capacity;
+
+ public LRURevisionList(int capacity)
+ {
+ this.capacity = capacity;
+ }
+
+ public int capacity()
+ {
+ return capacity;
+ }
+
+ public synchronized void capacity(int capacity)
+ {
+ this.capacity = capacity;
+ eviction();
+ }
+
+ @Override
+ public synchronized void add(DLRevisionHolder holder)
+ {
+ addHead(holder);
+ eviction();
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("LRURevisionList[size={0}, capacity={1}]", size(), capacity);
+ }
+
+ protected void eviction()
+ {
+ if (capacity != 0)
+ {
+ while (size() > capacity)
+ {
+ evict((LRURevisionHolder)getDLTail());
+ }
+ }
+ }
+
+ protected void evict(LRURevisionHolder holder)
+ {
+ remove(holder);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/RevisionHolder.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/RevisionHolder.java
new file mode 100644
index 0000000000..c58a1a3009
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/RevisionHolder.java
@@ -0,0 +1,142 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.revision;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.spi.common.InternalCDORevision;
+
+import java.text.MessageFormat;
+
+/**
+ * @author Eike Stepper
+ */
+public class RevisionHolder
+{
+ // private CDOID id;
+ //
+ // private int version;
+ //
+ // private long created;
+ //
+ // private long revised;
+
+ private RevisionHolder prev;
+
+ private RevisionHolder next;
+
+ private CDORevision revision;
+
+ public RevisionHolder(CDORevision revision)
+ {
+ setRevision(revision);
+ }
+
+ public CDOID getID()
+ {
+ return revision.getID();
+ }
+
+ public int getVersion()
+ {
+ return revision.getVersion();
+ }
+
+ public long getCreated()
+ {
+ return revision.getCreated();
+ }
+
+ public long getRevised()
+ {
+ return revision.getRevised();
+ }
+
+ public boolean isCurrent()
+ {
+ return getRevised() == CDORevision.UNSPECIFIED_DATE;
+ }
+
+ public boolean isValid(long timeStamp)
+ {
+ return (getRevised() == CDORevision.UNSPECIFIED_DATE || getRevised() >= timeStamp) && timeStamp >= getCreated();
+ }
+
+ public int compareTo(long timeStamp)
+ {
+ if (timeStamp < getCreated())
+ {
+ return -1;
+ }
+
+ if (getRevised() != CDORevision.UNSPECIFIED_DATE && timeStamp > getRevised())
+ {
+ return 1;
+ }
+
+ return 0;
+ }
+
+ public RevisionHolder getPrev()
+ {
+ return prev;
+ }
+
+ public void setPrev(RevisionHolder prev)
+ {
+ this.prev = prev;
+ }
+
+ public RevisionHolder getNext()
+ {
+ return next;
+ }
+
+ public void setNext(RevisionHolder next)
+ {
+ this.next = next;
+ }
+
+ public boolean isLoaded()
+ {
+ return revision != null;
+ }
+
+ public CDORevision getRevision(boolean loadOnDemand)
+ {
+ if (revision == null && loadOnDemand)
+ {
+ revision = loadRevision();
+ }
+
+ return revision;
+ }
+
+ public void setRevision(CDORevision revision)
+ {
+ this.revision = revision;
+ // id = revision.getID();
+ // version = revision.getVersion();
+ // created = revision.getCreated();
+ // revised = revision.getRevised();
+ }
+
+ @Override
+ public String toString()
+ {
+ return MessageFormat.format("RevisionHolder[{0}]", revision);
+ }
+
+ protected InternalCDORevision loadRevision()
+ {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOAddFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOAddFeatureDeltaImpl.java
new file mode 100644
index 0000000000..c7de939da6
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOAddFeatureDeltaImpl.java
@@ -0,0 +1,72 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.common.revision.delta;
+
+import org.eclipse.emf.cdo.common.model.CDOClass;
+import org.eclipse.emf.cdo.common.model.CDOFeature;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.delta.CDOAddFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
+import org.eclipse.emf.cdo.spi.common.InternalCDORevision;
+
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+
+import java.io.IOException;
+
+/**
+ * @author Simon McDuff
+ */
+public class CDOAddFeatureDeltaImpl extends CDOSingleValueFeatureDeltaImpl implements CDOAddFeatureDelta,
+ IListIndexAffecting, IListTargetAdding
+{
+ public CDOAddFeatureDeltaImpl(CDOFeature feature, int index, Object value)
+ {
+ super(feature, index, value);
+ }
+
+ public CDOAddFeatureDeltaImpl(ExtendedDataInput in, CDOClass cdoClass) throws IOException
+ {
+ super(in, cdoClass);
+ }
+
+ public Type getType()
+ {
+ return Type.ADD;
+ }
+
+ public void apply(CDORevision revision)
+ {
+ ((InternalCDORevision)revision).getList(getFeature()).add(getIndex(), getValue());
+ }
+
+ public void accept(CDOFeatureDeltaVisitor visitor)
+ {
+ visitor.visit(this);
+ }
+
+ public void affectIndices(int[] indices)
+ {
+ int index = getIndex();
+ if (index == NO_INDEX)
+ {
+ return;
+ }
+
+ for (int i = 1; i <= indices[0]; i++)
+ {
+ if (indices[i] >= index)
+ {
+ ++indices[i];
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOClearFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOClearFeatureDeltaImpl.java
new file mode 100644
index 0000000000..ba98c6e565
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOClearFeatureDeltaImpl.java
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.common.revision.delta;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.common.model.CDOClass;
+import org.eclipse.emf.cdo.common.model.CDOFeature;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.delta.CDOClearFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
+import org.eclipse.emf.cdo.spi.common.InternalCDORevision;
+
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * @author Simon McDuff
+ */
+public class CDOClearFeatureDeltaImpl extends CDOFeatureDeltaImpl implements CDOClearFeatureDelta
+{
+ public CDOClearFeatureDeltaImpl(CDOFeature feature)
+ {
+ super(feature);
+ }
+
+ public CDOClearFeatureDeltaImpl(ExtendedDataInput in, CDOClass cdoClass) throws IOException
+ {
+ super(in, cdoClass);
+ }
+
+ public Type getType()
+ {
+ return Type.CLEAR;
+ }
+
+ public void apply(CDORevision revision)
+ {
+ ((InternalCDORevision)revision).clear(getFeature());
+ }
+
+ public void accept(CDOFeatureDeltaVisitor visitor)
+ {
+ visitor.visit(this);
+ }
+
+ @Override
+ public void adjustReferences(Map<CDOIDTemp, CDOID> idMappings)
+ {
+ // Do nothing
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOContainerFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOContainerFeatureDeltaImpl.java
new file mode 100644
index 0000000000..6763434c40
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOContainerFeatureDeltaImpl.java
@@ -0,0 +1,197 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.common.revision.delta;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDProvider;
+import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.model.CDOClass;
+import org.eclipse.emf.cdo.common.model.CDOClassProxy;
+import org.eclipse.emf.cdo.common.model.CDOFeature;
+import org.eclipse.emf.cdo.common.model.CDOPackage;
+import org.eclipse.emf.cdo.common.model.CDOPackageManager;
+import org.eclipse.emf.cdo.common.model.CDOType;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
+import org.eclipse.emf.cdo.common.revision.delta.CDOContainerFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
+import org.eclipse.emf.cdo.spi.common.InternalCDORevision;
+
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+import org.eclipse.net4j.util.io.ExtendedDataOutput;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * @author Simon McDuff
+ */
+public class CDOContainerFeatureDeltaImpl extends CDOFeatureDeltaImpl implements CDOContainerFeatureDelta
+{
+ /**
+ * TODO Move to CDOObjectContainerFeature
+ */
+ private static CDOFeature CONTAINER_FEATURE = new ContainerFeature();
+
+ private CDOID newContainerID;
+
+ private int newContainerFeatureID;
+
+ public CDOContainerFeatureDeltaImpl(CDOID newContainerID, int newContainerFeatureID)
+ {
+ super(CONTAINER_FEATURE);
+ this.newContainerID = newContainerID;
+ this.newContainerFeatureID = newContainerFeatureID;
+ }
+
+ public CDOContainerFeatureDeltaImpl(ExtendedDataInput in, CDOClass cdoClass) throws IOException
+ {
+ super(CONTAINER_FEATURE);
+ newContainerFeatureID = in.readInt();
+ newContainerID = CDOIDUtil.read(in, cdoClass.getPackageManager().getCDOIDObjectFactory());
+ }
+
+ public int getContainerFeatureID()
+ {
+ return newContainerFeatureID;
+ }
+
+ public CDOID getContainerID()
+ {
+ return newContainerID;
+ }
+
+ public Type getType()
+ {
+ return Type.CONTAINER;
+ }
+
+ public void apply(CDORevision revision)
+ {
+ ((InternalCDORevision)revision).setContainerID(newContainerID);
+ ((InternalCDORevision)revision).setContainingFeatureID(newContainerFeatureID);
+ }
+
+ @Override
+ public void adjustReferences(Map<CDOIDTemp, CDOID> idMappings)
+ {
+ newContainerID = (CDOID)CDORevisionUtil.remapID(newContainerID, idMappings);
+ }
+
+ @Override
+ public void write(ExtendedDataOutput out, CDOClass cdoClass, CDOIDProvider idProvider) throws IOException
+ {
+ out.writeInt(getType().ordinal());
+ out.writeInt(newContainerFeatureID);
+ CDOIDUtil.write(out, newContainerID);
+ }
+
+ public void accept(CDOFeatureDeltaVisitor visitor)
+ {
+ visitor.visit(this);
+ }
+
+ /**
+ * @author Simon McDuff
+ */
+ private static final class ContainerFeature implements CDOFeature
+ {
+ public CDOClass getContainingClass()
+ {
+ return null;
+ }
+
+ public void setContainingClass(CDOClass cdoClass)
+ {
+ }
+
+ public CDOPackage getContainingPackage()
+ {
+ return null;
+ }
+
+ public int getFeatureID()
+ {
+ return 0;
+ }
+
+ public int getFeatureIndex()
+ {
+ return 0;
+ }
+
+ public CDOClass getReferenceType()
+ {
+ return null;
+ }
+
+ public CDOClassProxy getReferenceTypeProxy()
+ {
+ return null;
+ }
+
+ public CDOType getType()
+ {
+ return null;
+ }
+
+ public boolean isContainment()
+ {
+ return false;
+ }
+
+ public boolean isMany()
+ {
+ return false;
+ }
+
+ public boolean isReference()
+ {
+ return false;
+ }
+
+ public Object getClientInfo()
+ {
+ return null;
+ }
+
+ public String getName()
+ {
+ return null;
+ }
+
+ public CDOPackageManager getPackageManager()
+ {
+ return null;
+ }
+
+ public Object getServerInfo()
+ {
+ return null;
+ }
+
+ public void setClientInfo(Object clientInfo)
+ {
+ }
+
+ public void setServerInfo(Object serverInfo)
+ {
+ }
+
+ @Override
+ public String toString()
+ {
+ return "CONTAINER_FEATURE";
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOFeatureDeltaImpl.java
new file mode 100644
index 0000000000..cf02d045b9
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOFeatureDeltaImpl.java
@@ -0,0 +1,87 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.common.revision.delta;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDProvider;
+import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.common.model.CDOClass;
+import org.eclipse.emf.cdo.common.model.CDOFeature;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
+
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+import org.eclipse.net4j.util.io.ExtendedDataOutput;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * @author Simon McDuff
+ */
+public abstract class CDOFeatureDeltaImpl implements CDOFeatureDelta
+{
+ public static final int NO_INDEX = -1;
+
+ private CDOFeature feature;
+
+ protected CDOFeatureDeltaImpl(CDOFeature feature)
+ {
+ this.feature = feature;
+ }
+
+ public CDOFeatureDeltaImpl(ExtendedDataInput in, CDOClass cdoClass) throws IOException
+ {
+ int featureID = in.readInt();
+ feature = cdoClass.getAllFeatures()[featureID];
+ }
+
+ public CDOFeature getFeature()
+ {
+ return feature;
+ }
+
+ public abstract void adjustReferences(Map<CDOIDTemp, CDOID> idMappings);
+
+ public void write(ExtendedDataOutput out, CDOClass cdoClass, CDOIDProvider idProvider) throws IOException
+ {
+ out.writeInt(getType().ordinal());
+ out.writeInt(cdoClass.getFeatureID(feature));
+ }
+
+ public static CDOFeatureDeltaImpl read(ExtendedDataInput in, CDOClass cdoClass) throws IOException
+ {
+ int typeOrdinal = in.readInt();
+ Type type = Type.values()[typeOrdinal];
+ switch (type)
+ {
+ case ADD:
+ return new CDOAddFeatureDeltaImpl(in, cdoClass);
+ case SET:
+ return new CDOSetFeatureDeltaImpl(in, cdoClass);
+ case LIST:
+ return new CDOListFeatureDeltaImpl(in, cdoClass);
+ case MOVE:
+ return new CDOMoveFeatureDeltaImpl(in, cdoClass);
+ case CLEAR:
+ return new CDOClearFeatureDeltaImpl(in, cdoClass);
+ case REMOVE:
+ return new CDORemoveFeatureDeltaImpl(in, cdoClass);
+ case CONTAINER:
+ return new CDOContainerFeatureDeltaImpl(in, cdoClass);
+ case UNSET:
+ return new CDOUnsetFeatureDeltaImpl(in, cdoClass);
+ default:
+ // TODO Find better exception for signalling errors
+ throw new UnsupportedOperationException("Invalid type " + typeOrdinal);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOFeatureDeltaVisitorImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOFeatureDeltaVisitorImpl.java
new file mode 100644
index 0000000000..3317bad23b
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOFeatureDeltaVisitorImpl.java
@@ -0,0 +1,69 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.common.revision.delta;
+
+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.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.CDOSetFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta;
+
+/**
+ * @author Simon McDuff
+ */
+public class CDOFeatureDeltaVisitorImpl implements CDOFeatureDeltaVisitor
+{
+ public CDOFeatureDeltaVisitorImpl()
+ {
+ }
+
+ public void visit(CDOAddFeatureDelta delta)
+ {
+ }
+
+ public void visit(CDOClearFeatureDelta delta)
+ {
+ }
+
+ public void visit(CDOContainerFeatureDelta delta)
+ {
+ }
+
+ public void visit(CDOListFeatureDelta deltas)
+ {
+ for (CDOFeatureDelta delta : deltas.getListChanges())
+ {
+ delta.accept(this);
+ }
+ }
+
+ public void visit(CDOMoveFeatureDelta delta)
+ {
+ }
+
+ public void visit(CDORemoveFeatureDelta delta)
+ {
+ }
+
+ public void visit(CDOSetFeatureDelta delta)
+ {
+ }
+
+ public void visit(CDOUnsetFeatureDelta delta)
+ {
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOListFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOListFeatureDeltaImpl.java
new file mode 100644
index 0000000000..35cedd3690
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOListFeatureDeltaImpl.java
@@ -0,0 +1,126 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.common.revision.delta;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDProvider;
+import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.common.model.CDOClass;
+import org.eclipse.emf.cdo.common.model.CDOFeature;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+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.net4j.util.io.ExtendedDataInput;
+import org.eclipse.net4j.util.io.ExtendedDataOutput;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Simon McDuff
+ */
+public class CDOListFeatureDeltaImpl extends CDOFeatureDeltaImpl implements CDOListFeatureDelta
+{
+ private List<CDOFeatureDelta> featureDeltas = new ArrayList<CDOFeatureDelta>();
+
+ public CDOListFeatureDeltaImpl(CDOFeature feature)
+ {
+ super(feature);
+ }
+
+ public CDOListFeatureDeltaImpl(ExtendedDataInput in, CDOClass cdoClass) throws IOException
+ {
+ super(in, cdoClass);
+ int size = in.readInt();
+ for (int i = 0; i < size; i++)
+ {
+ featureDeltas.add(CDOFeatureDeltaImpl.read(in, cdoClass));
+ }
+ }
+
+ public Type getType()
+ {
+ return Type.LIST;
+ }
+
+ public List<CDOFeatureDelta> getListChanges()
+ {
+ return featureDeltas;
+ }
+
+ @Override
+ public void write(final ExtendedDataOutput out, CDOClass cdoClass, final CDOIDProvider idProvider) throws IOException
+ {
+ super.write(out, cdoClass, idProvider);
+ out.writeInt(featureDeltas.size());
+ for (CDOFeatureDelta featureDelta : featureDeltas)
+ {
+ ((CDOFeatureDeltaImpl)featureDelta).write(out, cdoClass, idProvider);
+ }
+ }
+
+ /**
+ * Returns the number of indices as the first element of the array.
+ *
+ * @return never <code>null</code>.
+ */
+ public int[] reconstructAddedIndices()
+ {
+ int[] indices = new int[1 + featureDeltas.size()];
+ for (CDOFeatureDelta featureDelta : featureDeltas)
+ {
+ if (featureDelta instanceof IListIndexAffecting)
+ {
+ IListIndexAffecting affecting = (IListIndexAffecting)featureDelta;
+ affecting.affectIndices(indices);
+ }
+
+ if (featureDelta instanceof IListTargetAdding)
+ {
+ indices[++indices[0]] = ((IListTargetAdding)featureDelta).getIndex();
+ }
+ }
+
+ return indices;
+ }
+
+ public void add(CDOFeatureDelta featureDelta)
+ {
+ featureDeltas.add(featureDelta);
+ }
+
+ public void apply(CDORevision revision)
+ {
+ for (CDOFeatureDelta featureDelta : featureDeltas)
+ {
+ ((CDOFeatureDeltaImpl)featureDelta).apply(revision);
+ }
+ }
+
+ @Override
+ public void adjustReferences(Map<CDOIDTemp, CDOID> idMappings)
+ {
+ for (CDOFeatureDelta featureDelta : featureDeltas)
+ {
+ ((CDOFeatureDeltaImpl)featureDelta).adjustReferences(idMappings);
+ }
+ }
+
+ public void accept(CDOFeatureDeltaVisitor visitor)
+ {
+ visitor.visit(this);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOMoveFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOMoveFeatureDeltaImpl.java
new file mode 100644
index 0000000000..850249b32c
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOMoveFeatureDeltaImpl.java
@@ -0,0 +1,123 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.common.revision.delta;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDProvider;
+import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.common.model.CDOClass;
+import org.eclipse.emf.cdo.common.model.CDOFeature;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
+import org.eclipse.emf.cdo.common.revision.delta.CDOMoveFeatureDelta;
+import org.eclipse.emf.cdo.spi.common.InternalCDORevision;
+
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+import org.eclipse.net4j.util.io.ExtendedDataOutput;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * @author Simon McDuff
+ */
+public class CDOMoveFeatureDeltaImpl extends CDOFeatureDeltaImpl implements CDOMoveFeatureDelta, IListIndexAffecting
+{
+ private int oldPosition;
+
+ private int newPosition;
+
+ public CDOMoveFeatureDeltaImpl(CDOFeature feature, int newPosition, int oldPosition)
+ {
+ super(feature);
+ this.newPosition = newPosition;
+ this.oldPosition = oldPosition;
+ }
+
+ public CDOMoveFeatureDeltaImpl(ExtendedDataInput in, CDOClass cdoClass) throws IOException
+ {
+ super(in, cdoClass);
+ newPosition = in.readInt();
+ oldPosition = in.readInt();
+ }
+
+ public int getNewPosition()
+ {
+ return newPosition;
+ }
+
+ public int getOldPosition()
+ {
+ return oldPosition;
+ }
+
+ public Type getType()
+ {
+ return Type.MOVE;
+ }
+
+ public void apply(CDORevision revision)
+ {
+ ((InternalCDORevision)revision).getList(getFeature()).move(newPosition, oldPosition);
+ }
+
+ @Override
+ public void write(ExtendedDataOutput out, CDOClass cdoClass, CDOIDProvider idProvider) throws IOException
+ {
+ super.write(out, cdoClass, idProvider);
+ out.writeInt(newPosition);
+ out.writeInt(oldPosition);
+ }
+
+ public void affectIndices(int[] indices)
+ {
+ if (oldPosition < newPosition)
+ {
+ for (int i = 1; i <= indices[0]; i++)
+ {
+ if (oldPosition < indices[i] && indices[i] <= newPosition)
+ {
+ --indices[i];
+ }
+ else if (indices[i] == oldPosition)
+ {
+ indices[i] = newPosition;
+ }
+ }
+ }
+ else if (newPosition < oldPosition)
+ {
+ for (int i = 1; i <= indices[0]; i++)
+ {
+ if (newPosition <= indices[i] && indices[i] < oldPosition)
+ {
+ ++indices[i];
+ }
+ else if (indices[i] == oldPosition)
+ {
+ indices[i] = newPosition;
+ }
+ }
+ }
+ }
+
+ public void accept(CDOFeatureDeltaVisitor visitor)
+ {
+ visitor.visit(this);
+ }
+
+ @Override
+ public void adjustReferences(Map<CDOIDTemp, CDOID> idMappings)
+ {
+ // Do nothing
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORemoveFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORemoveFeatureDeltaImpl.java
new file mode 100644
index 0000000000..4e6babfe2c
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORemoveFeatureDeltaImpl.java
@@ -0,0 +1,103 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.common.revision.delta;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDProvider;
+import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.common.model.CDOClass;
+import org.eclipse.emf.cdo.common.model.CDOFeature;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
+import org.eclipse.emf.cdo.common.revision.delta.CDORemoveFeatureDelta;
+import org.eclipse.emf.cdo.spi.common.InternalCDORevision;
+
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+import org.eclipse.net4j.util.io.ExtendedDataOutput;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * @author Simon McDuff
+ */
+public class CDORemoveFeatureDeltaImpl extends CDOFeatureDeltaImpl implements CDORemoveFeatureDelta,
+ IListIndexAffecting
+{
+ private int index;
+
+ public CDORemoveFeatureDeltaImpl(CDOFeature feature, int index)
+ {
+ super(feature);
+ this.index = index;
+ }
+
+ public CDORemoveFeatureDeltaImpl(ExtendedDataInput in, CDOClass cdoClass) throws IOException
+ {
+ super(in, cdoClass);
+ index = in.readInt();
+ }
+
+ public int getIndex()
+ {
+ return index;
+ }
+
+ public Type getType()
+ {
+ return Type.REMOVE;
+ }
+
+ public void apply(CDORevision revision)
+ {
+ ((InternalCDORevision)revision).getList(getFeature()).remove(index);
+ }
+
+ public void accept(CDOFeatureDeltaVisitor visitor)
+ {
+ visitor.visit(this);
+ }
+
+ @Override
+ public void write(ExtendedDataOutput out, CDOClass cdoClass, CDOIDProvider idProvider) throws IOException
+ {
+ super.write(out, cdoClass, idProvider);
+ out.writeInt(index);
+ }
+
+ public void affectIndices(int[] indices)
+ {
+ int index = getIndex();
+ for (int i = 1; i <= indices[0]; i++)
+ {
+ if (indices[i] > index)
+ {
+ --indices[i];
+ }
+ else if (indices[i] == index)
+ {
+ int rest = indices[0]-- - i;
+ if (rest > 0)
+ {
+ System.arraycopy(indices, i + 1, indices, i, rest);
+ --i;
+ }
+ }
+ }
+ }
+
+ @Override
+ public void adjustReferences(Map<CDOIDTemp, CDOID> idMappings)
+ {
+ // do Nothing
+ }
+}
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
new file mode 100644
index 0000000000..6eb47605a4
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionDeltaImpl.java
@@ -0,0 +1,261 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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 - https://bugs.eclipse.org/bugs/show_bug.cgi?id=201266
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.common.revision.delta;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDProvider;
+import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.common.id.CDOIDUtil;
+import org.eclipse.emf.cdo.common.model.CDOClass;
+import org.eclipse.emf.cdo.common.model.CDOClassRef;
+import org.eclipse.emf.cdo.common.model.CDOFeature;
+import org.eclipse.emf.cdo.common.model.CDOModelUtil;
+import org.eclipse.emf.cdo.common.model.CDOPackageManager;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionData;
+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.spi.common.InternalCDORevision;
+import org.eclipse.emf.cdo.spi.common.InternalCDORevisionDelta;
+
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+import org.eclipse.net4j.util.io.ExtendedDataOutput;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Eike Stepper
+ */
+public class CDORevisionDeltaImpl implements InternalCDORevisionDelta
+{
+ private CDOID cdoID;
+
+ private CDOClass cdoClass;
+
+ private int dirtyVersion;
+
+ private int originVersion;
+
+ private Map<CDOFeature, CDOFeatureDelta> featureDeltas = new HashMap<CDOFeature, CDOFeatureDelta>();
+
+ public CDORevisionDeltaImpl(CDORevision revision)
+ {
+ cdoID = revision.getID();
+ cdoClass = revision.getCDOClass();
+ dirtyVersion = revision.getVersion();
+ originVersion = dirtyVersion - 1;
+ }
+
+ public CDORevisionDeltaImpl(CDORevision originRevision, CDORevision dirtyRevision)
+ {
+ if (originRevision.getCDOClass() != dirtyRevision.getCDOClass())
+ {
+ throw new IllegalArgumentException();
+ }
+
+ cdoID = originRevision.getID();
+ cdoClass = originRevision.getCDOClass();
+ dirtyVersion = dirtyRevision.getVersion();
+ originVersion = originRevision.getVersion();
+
+ compare(originRevision, dirtyRevision);
+
+ CDORevisionData originData = originRevision.getData();
+ CDORevisionData dirtyData = dirtyRevision.getData();
+ if (!compare(originData.getContainerID(), dirtyData.getContainerID())
+ || !compare(originData.getContainingFeatureID(), dirtyData.getContainingFeatureID()))
+ {
+ addFeatureDelta(new CDOContainerFeatureDeltaImpl(dirtyData.getContainerID(), dirtyData.getContainingFeatureID()));
+ }
+
+ }
+
+ public CDORevisionDeltaImpl(ExtendedDataInput in, CDOPackageManager packageManager) throws IOException
+ {
+ CDOClassRef classRef = CDOModelUtil.readClassRef(in);
+ cdoClass = classRef.resolve(packageManager);
+ cdoID = CDOIDUtil.read(in, packageManager.getCDOIDObjectFactory());
+ originVersion = in.readInt();
+ dirtyVersion = in.readInt();
+ int size = in.readInt();
+ for (int i = 0; i < size; i++)
+ {
+ CDOFeatureDelta featureDelta = CDOFeatureDeltaImpl.read(in, cdoClass);
+ featureDeltas.put(featureDelta.getFeature(), featureDelta);
+ }
+ }
+
+ public void write(ExtendedDataOutput out, CDOIDProvider idProvider) throws IOException
+ {
+ CDOClassRef classRef = cdoClass.createClassRef();
+ CDOModelUtil.writeClassRef(out, classRef);
+ CDOIDUtil.write(out, cdoID);
+ out.writeInt(originVersion);
+ out.writeInt(dirtyVersion);
+ out.writeInt(featureDeltas.size());
+ for (CDOFeatureDelta featureDelta : featureDeltas.values())
+ {
+ ((CDOFeatureDeltaImpl)featureDelta).write(out, cdoClass, idProvider);
+ }
+ }
+
+ public CDOID getID()
+ {
+ return cdoID;
+ }
+
+ public int getOriginVersion()
+ {
+ return originVersion;
+ }
+
+ public int getDirtyVersion()
+ {
+ return dirtyVersion;
+ }
+
+ public List<CDOFeatureDelta> getFeatureDeltas()
+ {
+ return new ArrayList<CDOFeatureDelta>(featureDeltas.values());
+ }
+
+ public void apply(CDORevision revision)
+ {
+ ((InternalCDORevision)revision).setVersion(dirtyVersion);
+ for (CDOFeatureDelta featureDelta : featureDeltas.values())
+ {
+ ((CDOFeatureDeltaImpl)featureDelta).apply(revision);
+ }
+ }
+
+ public void addFeatureDelta(CDOFeatureDelta delta)
+ {
+ CDOFeature feature = delta.getFeature();
+ if (feature.isMany())
+ {
+ CDOListFeatureDeltaImpl lookupDelta = (CDOListFeatureDeltaImpl)featureDeltas.get(feature);
+ if (lookupDelta == null)
+ {
+ lookupDelta = new CDOListFeatureDeltaImpl(feature);
+ featureDeltas.put(lookupDelta.getFeature(), lookupDelta);
+ }
+
+ // Remove all previous changes
+ if (delta instanceof CDOClearFeatureDelta)
+ {
+ lookupDelta.getListChanges().clear();
+ }
+ lookupDelta.add(delta);
+ }
+ else
+ {
+ featureDeltas.put(feature, delta);
+ }
+ }
+
+ public void adjustReferences(Map<CDOIDTemp, CDOID> idMappings)
+ {
+ for (CDOFeatureDelta featureDelta : featureDeltas.values())
+ {
+ ((CDOFeatureDeltaImpl)featureDelta).adjustReferences(idMappings);
+ }
+ }
+
+ public void accept(CDOFeatureDeltaVisitor visitor)
+ {
+ for (CDOFeatureDelta featureDelta : featureDeltas.values())
+ {
+ ((CDOFeatureDeltaImpl)featureDelta).accept(visitor);
+ }
+ }
+
+ private void compare(CDORevision originRevision, CDORevision dirtyRevision)
+ {
+ CDOFeature features[] = cdoClass.getAllFeatures();
+ int count = cdoClass.getFeatureCount();
+ for (int i = 0; i < count; i++)
+ {
+ CDOFeature feature = features[i];
+ if (feature.isMany())
+ {
+ int originSize = originRevision.getData().size(feature);
+ int dirtySize = dirtyRevision.getData().size(feature);
+ if (dirtySize == 0 && originSize > 0)
+ {
+ addFeatureDelta(new CDOClearFeatureDeltaImpl(feature));
+ }
+ else
+ {
+ int originIndex = 0;
+ int dirtyIndex = 0;
+ if (originSize == dirtySize)
+ {
+ for (; originIndex < originSize && dirtyIndex < dirtySize; dirtyIndex++, originIndex++)
+ {
+ Object originValue = originRevision.getData().get(feature, originIndex);
+ Object dirtyValue = dirtyRevision.getData().get(feature, dirtyIndex);
+
+ if (!compare(originValue, dirtyValue))
+ {
+ dirtyIndex = 0;
+ break;
+ }
+ }
+ }
+
+ if (originIndex != originSize || dirtyIndex != dirtySize)
+ {
+ // Not identical
+ // Be very stupid and do the simplest thing.
+ // Clear and add all value;
+ if (originSize > 0)
+ {
+ addFeatureDelta(new CDOClearFeatureDeltaImpl(feature));
+ }
+
+ for (int k = 0; k < dirtySize; k++)
+ {
+ Object dirtyValue = dirtyRevision.getData().get(feature, k);
+ addFeatureDelta(new CDOAddFeatureDeltaImpl(feature, k, dirtyValue));
+ }
+ }
+ }
+ }
+ else
+ {
+ Object originValue = originRevision.getData().get(feature, 0);
+ Object dirtyValue = dirtyRevision.getData().get(feature, 0);
+ if (!compare(originValue, dirtyValue))
+ {
+ if (dirtyValue == null)
+ {
+ addFeatureDelta(new CDOUnsetFeatureDeltaImpl(feature));
+ }
+ else
+ {
+ addFeatureDelta(new CDOSetFeatureDeltaImpl(feature, 0, dirtyValue));
+ }
+ }
+ }
+ }
+ }
+
+ private boolean compare(Object originValue, Object dirtyValue)
+ {
+ return originValue == dirtyValue || originValue != null && dirtyValue != null && originValue.equals(dirtyValue);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionMerger.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionMerger.java
new file mode 100644
index 0000000000..d1300ae653
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDORevisionMerger.java
@@ -0,0 +1,84 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.common.revision.delta;
+
+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.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.revision.delta.CDOUnsetFeatureDelta;
+import org.eclipse.emf.cdo.spi.common.InternalCDORevision;
+
+/**
+ * @author Simon McDuff
+ */
+public class CDORevisionMerger extends CDOFeatureDeltaVisitorImpl
+{
+ private InternalCDORevision revision;
+
+ public CDORevisionMerger()
+ {
+ }
+
+ public void merge(InternalCDORevision revision, CDORevisionDelta delta)
+ {
+ this.revision = revision;
+ delta.accept(this);
+ revision = null;
+ }
+
+ @Override
+ public void visit(CDOMoveFeatureDelta delta)
+ {
+ revision.move(delta.getFeature(), delta.getOldPosition(), delta.getNewPosition());
+ }
+
+ @Override
+ public void visit(CDOAddFeatureDelta delta)
+ {
+ revision.add(delta.getFeature(), delta.getIndex(), delta.getValue());
+ }
+
+ @Override
+ public void visit(CDORemoveFeatureDelta delta)
+ {
+ revision.remove(delta.getFeature(), delta.getIndex());
+ }
+
+ @Override
+ public void visit(CDOSetFeatureDelta delta)
+ {
+ revision.set(delta.getFeature(), delta.getIndex(), delta.getValue());
+ }
+
+ @Override
+ public void visit(CDOUnsetFeatureDelta delta)
+ {
+ revision.unset(delta.getFeature());
+ }
+
+ @Override
+ public void visit(CDOClearFeatureDelta delta)
+ {
+ revision.clear(delta.getFeature());
+ }
+
+ @Override
+ public void visit(CDOContainerFeatureDelta delta)
+ {
+ revision.setContainerID(delta.getContainerID());
+ revision.setContainingFeatureID(delta.getContainerFeatureID());
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOSetFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOSetFeatureDeltaImpl.java
new file mode 100644
index 0000000000..44fdfe6b9c
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOSetFeatureDeltaImpl.java
@@ -0,0 +1,55 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.common.revision.delta;
+
+import org.eclipse.emf.cdo.common.model.CDOClass;
+import org.eclipse.emf.cdo.common.model.CDOFeature;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
+import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta;
+import org.eclipse.emf.cdo.spi.common.InternalCDORevision;
+
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+
+import java.io.IOException;
+
+/**
+ * @author Simon McDuff
+ */
+public class CDOSetFeatureDeltaImpl extends CDOSingleValueFeatureDeltaImpl implements CDOSetFeatureDelta,
+ IListTargetAdding
+{
+ public CDOSetFeatureDeltaImpl(CDOFeature feature, int index, Object value)
+ {
+ super(feature, index, value);
+ }
+
+ public CDOSetFeatureDeltaImpl(ExtendedDataInput in, CDOClass cdoClass) throws IOException
+ {
+ super(in, cdoClass);
+ }
+
+ public Type getType()
+ {
+ return Type.SET;
+ }
+
+ public void apply(CDORevision revision)
+ {
+ ((InternalCDORevision)revision).set(getFeature(), getIndex(), getValue());
+ }
+
+ public void accept(CDOFeatureDeltaVisitor visitor)
+ {
+ visitor.visit(this);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOSingleValueFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOSingleValueFeatureDeltaImpl.java
new file mode 100644
index 0000000000..741d76b8e6
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOSingleValueFeatureDeltaImpl.java
@@ -0,0 +1,82 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.common.revision.delta;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDProvider;
+import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.common.model.CDOClass;
+import org.eclipse.emf.cdo.common.model.CDOFeature;
+import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
+
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+import org.eclipse.net4j.util.io.ExtendedDataOutput;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * @author Simon McDuff
+ */
+public abstract class CDOSingleValueFeatureDeltaImpl extends CDOFeatureDeltaImpl implements CDOFeatureDelta
+{
+ private int index;
+
+ private Object newValue;
+
+ public CDOSingleValueFeatureDeltaImpl(CDOFeature feature, int index, Object value)
+ {
+ super(feature);
+ this.index = index;
+ newValue = value;
+ }
+
+ public CDOSingleValueFeatureDeltaImpl(ExtendedDataInput in, CDOClass cdoClass) throws IOException
+ {
+ super(in, cdoClass);
+ index = in.readInt();
+ newValue = getFeature().getType().readValue(in, cdoClass.getPackageManager().getCDOIDObjectFactory());
+ }
+
+ public int getIndex()
+ {
+ return index;
+ }
+
+ public Object getValue()
+ {
+ return newValue;
+ }
+
+ @Override
+ public void write(ExtendedDataOutput out, CDOClass cdoClass, CDOIDProvider idProvider) throws IOException
+ {
+ super.write(out, cdoClass, idProvider);
+ out.writeInt(index);
+ if (newValue != null && getFeature().isReference())
+ {
+ newValue = idProvider.provideCDOID(newValue);
+ }
+
+ getFeature().getType().writeValue(out, newValue);
+ }
+
+ @Override
+ public void adjustReferences(Map<CDOIDTemp, CDOID> idMappings)
+ {
+ if (newValue instanceof CDOID)
+ {
+ newValue = CDORevisionUtil.remapID(newValue, idMappings);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOUnsetFeatureDeltaImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOUnsetFeatureDeltaImpl.java
new file mode 100644
index 0000000000..235c999c96
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/CDOUnsetFeatureDeltaImpl.java
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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:
+ * Simon McDuff - initial API and implementation
+ * Eike Stepper - maintenance
+ **************************************************************************/
+package org.eclipse.emf.cdo.internal.common.revision.delta;
+
+import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.id.CDOIDTemp;
+import org.eclipse.emf.cdo.common.model.CDOClass;
+import org.eclipse.emf.cdo.common.model.CDOFeature;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDeltaVisitor;
+import org.eclipse.emf.cdo.common.revision.delta.CDOUnsetFeatureDelta;
+import org.eclipse.emf.cdo.spi.common.InternalCDORevision;
+
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * @author Simon McDuff
+ */
+public class CDOUnsetFeatureDeltaImpl extends CDOFeatureDeltaImpl implements CDOUnsetFeatureDelta
+{
+ public CDOUnsetFeatureDeltaImpl(CDOFeature feature)
+ {
+ super(feature);
+ }
+
+ public CDOUnsetFeatureDeltaImpl(ExtendedDataInput in, CDOClass cdoClass) throws IOException
+ {
+ super(in, cdoClass);
+ }
+
+ public Type getType()
+ {
+ return Type.UNSET;
+ }
+
+ public void apply(CDORevision revision)
+ {
+ ((InternalCDORevision)revision).unset(getFeature());
+ }
+
+ public void accept(CDOFeatureDeltaVisitor visitor)
+ {
+ visitor.visit(this);
+ }
+
+ @Override
+ public void adjustReferences(Map<CDOIDTemp, CDOID> idMappings)
+ {
+ // Do nothing
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/IListIndexAffecting.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/IListIndexAffecting.java
new file mode 100644
index 0000000000..9ccaeeeb41
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/IListIndexAffecting.java
@@ -0,0 +1,22 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.revision.delta;
+
+/**
+ * @author Eike Stepper
+ */
+public interface IListIndexAffecting
+{
+ /**
+ * Expects the number of indices in the first element of the indices array.
+ */
+ public void affectIndices(int[] indices);
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/IListTargetAdding.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/IListTargetAdding.java
new file mode 100644
index 0000000000..7fa52d0cd5
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/revision/delta/IListTargetAdding.java
@@ -0,0 +1,19 @@
+/***************************************************************************
+ * Copyright (c) 2004 - 2008 Eike Stepper, Germany.
+ * 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.common.revision.delta;
+
+/**
+ * @author Eike Stepper
+ */
+public interface IListTargetAdding
+{
+ public int getIndex();
+}

Back to the top