diff options
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal')
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(); +} |