diff options
author | Eike Stepper | 2008-12-13 15:44:05 +0000 |
---|---|---|
committer | Eike Stepper | 2008-12-13 15:44:05 +0000 |
commit | 8bf748abac9ae72fbcc1537c93767d06b12e5e3d (patch) | |
tree | 5082fd762dadfdbd2f910876ca84c4e22b664a04 /plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf | |
parent | 5cc28537fd5cdf015fd98af184ad90e0df334d85 (diff) | |
download | cdo-8bf748abac9ae72fbcc1537c93767d06b12e5e3d.tar.gz cdo-8bf748abac9ae72fbcc1537c93767d06b12e5e3d.tar.xz cdo-8bf748abac9ae72fbcc1537c93767d06b12e5e3d.zip |
[257703] Required a possibility to configure value holder in CDO
https://bugs.eclipse.org/bugs/show_bug.cgi?id=257703
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf')
8 files changed, 707 insertions, 588 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevision.java index 824c5cda9f..010eafaf2f 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevision.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevision.java @@ -66,4 +66,9 @@ public interface CDORevision public CDORevisionDelta compare(CDORevision origin); public void merge(CDORevisionDelta delta); + + /** + * @since 2.0 + */ + public CDORevision copy(); } diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionFactory.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionFactory.java new file mode 100644 index 0000000000..27b9bf2b05 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionFactory.java @@ -0,0 +1,28 @@ +/*************************************************************************** + * 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.common.revision; + +import org.eclipse.emf.cdo.common.CDODataInput; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.model.CDOClass; + +import java.io.IOException; + +/** + * @author Eike Stepper + * @since 2.0 + */ +public interface CDORevisionFactory +{ + public CDORevision createRevision(CDOClass cdoClass, CDOID id); + + public CDORevision createRevision(CDODataInput in) throws IOException; +} diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java index 320df8e5b1..8df653e4f6 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/revision/CDORevisionUtil.java @@ -10,6 +10,7 @@ **************************************************************************/ package org.eclipse.emf.cdo.common.revision; +import org.eclipse.emf.cdo.common.CDODataInput; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.id.CDOIDTemp; import org.eclipse.emf.cdo.common.model.CDOClass; @@ -17,6 +18,7 @@ import org.eclipse.emf.cdo.common.model.core.CDOFeatureMapEntryDataType; import org.eclipse.emf.cdo.internal.common.model.core.CDOFeatureMapEntryDataTypeImpl; import org.eclipse.emf.cdo.internal.common.revision.CDORevisionImpl; +import java.io.IOException; import java.util.Map; /** @@ -41,14 +43,17 @@ public final class CDORevisionUtil /** * @since 2.0 */ - public static CDOFeatureMapEntryDataType createFeatureMapEntry(String uri, Object value) + public static CDORevision read(CDODataInput in) throws IOException { - return new CDOFeatureMapEntryDataTypeImpl(uri, value); + return new CDORevisionImpl(in); } - public static CDORevision copy(CDORevision source) + /** + * @since 2.0 + */ + public static CDOFeatureMapEntryDataType createFeatureMapEntry(String uri, Object value) { - return new CDORevisionImpl((CDORevisionImpl)source); + return new CDOFeatureMapEntryDataTypeImpl(uri, value); } public static Object remapID(Object value, Map<CDOIDTemp, CDOID> idMappings) diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDODataInputImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDODataInputImpl.java index 7c638429d0..664a2f2800 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDODataInputImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDODataInputImpl.java @@ -30,6 +30,7 @@ import org.eclipse.emf.cdo.common.revision.CDOList; import org.eclipse.emf.cdo.common.revision.CDOListFactory; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.CDORevisionResolver; +import org.eclipse.emf.cdo.common.revision.CDORevisionUtil; import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta; import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta; import org.eclipse.emf.cdo.internal.common.bundle.OM; @@ -44,7 +45,6 @@ import org.eclipse.emf.cdo.internal.common.model.CDOClassImpl; import org.eclipse.emf.cdo.internal.common.model.CDOClassRefImpl; import org.eclipse.emf.cdo.internal.common.model.CDOFeatureImpl; import org.eclipse.emf.cdo.internal.common.model.CDOPackageImpl; -import org.eclipse.emf.cdo.internal.common.revision.CDORevisionImpl; import org.eclipse.emf.cdo.internal.common.revision.delta.CDOAddFeatureDeltaImpl; import org.eclipse.emf.cdo.internal.common.revision.delta.CDOClearFeatureDeltaImpl; import org.eclipse.emf.cdo.internal.common.revision.delta.CDOContainerFeatureDeltaImpl; @@ -306,7 +306,7 @@ public abstract class CDODataInputImpl implements CDODataInput boolean notNull = readBoolean(); if (notNull) { - return new CDORevisionImpl(this); + return readCDORevisionData(); } return null; @@ -413,6 +413,11 @@ public abstract class CDODataInputImpl implements CDODataInput return readBoolean() ? RWLockManager.LockType.WRITE : RWLockManager.LockType.READ; } + protected CDORevision readCDORevisionData() throws IOException + { + return CDORevisionUtil.read(this); + } + protected abstract CDOPackageManager getPackageManager(); protected abstract CDOPackageURICompressor getPackageURICompressor(); diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDODataOutputImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDODataOutputImpl.java index a183be4dd6..ad5d5a89ea 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDODataOutputImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/CDODataOutputImpl.java @@ -30,13 +30,13 @@ import org.eclipse.emf.cdo.internal.common.bundle.OM; import org.eclipse.emf.cdo.internal.common.id.CDOIDAndVersionImpl; import org.eclipse.emf.cdo.internal.common.model.CDOClassRefImpl; import org.eclipse.emf.cdo.internal.common.model.CDOTypeImpl; -import org.eclipse.emf.cdo.internal.common.revision.CDORevisionImpl; import org.eclipse.emf.cdo.internal.common.revision.delta.CDOFeatureDeltaImpl; import org.eclipse.emf.cdo.internal.common.revision.delta.CDORevisionDeltaImpl; import org.eclipse.emf.cdo.spi.common.AbstractCDOID; import org.eclipse.emf.cdo.spi.common.InternalCDOClass; import org.eclipse.emf.cdo.spi.common.InternalCDOFeature; import org.eclipse.emf.cdo.spi.common.InternalCDOPackage; +import org.eclipse.emf.cdo.spi.common.InternalCDORevision; import org.eclipse.net4j.util.concurrent.RWLockManager; import org.eclipse.net4j.util.io.ExtendedDataOutput; @@ -243,7 +243,7 @@ public abstract class CDODataOutputImpl implements CDODataOutput if (revision != null) { writeBoolean(true); - ((CDORevisionImpl)revision).write(this, referenceChunk); + ((InternalCDORevision)revision).write(this, referenceChunk); } else { 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 index 906af08de3..d8fab97c24 100644 --- 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 @@ -14,635 +14,77 @@ package org.eclipse.emf.cdo.internal.common.revision; import org.eclipse.emf.cdo.common.CDODataInput; -import org.eclipse.emf.cdo.common.CDODataOutput; import org.eclipse.emf.cdo.common.id.CDOID; -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.CDOType; -import org.eclipse.emf.cdo.common.revision.CDOList; -import org.eclipse.emf.cdo.common.revision.CDOListFactory; -import org.eclipse.emf.cdo.common.revision.CDOReferenceAdjuster; import org.eclipse.emf.cdo.common.revision.CDORevision; -import org.eclipse.emf.cdo.common.revision.CDORevisionData; -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.AbstractCDORevision; import org.eclipse.emf.cdo.spi.common.InternalCDOList; -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.MoveableList; -import org.eclipse.net4j.util.om.trace.ContextTracer; -import org.eclipse.net4j.util.om.trace.PerfTracer; import java.io.IOException; -import java.util.Map; /** * @author Eike Stepper */ -public class CDORevisionImpl implements InternalCDORevision +public class CDORevisionImpl extends AbstractCDORevision { - 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 CDOClass cdoClass; - - private CDOID id; - - private int version; - - private long created; - - private long revised; - - private CDOID resourceID; - - private Object containerID; - - private int containingFeatureID; - private Object[] values; public CDORevisionImpl(CDOClass cdoClass, CDOID id) { - if (cdoClass.isAbstract()) - { - throw new IllegalArgumentException("CDOClass is abstract: " + cdoClass); - } - - if (CDOIDUtil.isNull(id)) - { - throw new IllegalArgumentException("CDIID is null"); - } - - 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) - { - 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); + super(cdoClass, id); } public CDORevisionImpl(CDODataInput in) throws IOException { - READING.start(this); - cdoClass = in.readCDOClassRefAndResolve(); - - id = in.readCDOID(); - version = in.readInt(); - if (!id.isTemporary()) - { - created = in.readLong(); - revised = in.readLong(); - } - - resourceID = in.readCDOID(); - containerID = in.readCDOID(); - containingFeatureID = in.readInt(); - if (TRACER.isEnabled()) - { - TRACER - .format( - "Reading revision: ID={0}, className={1}, version={2}, created={3}, revised={4}, resource={5}, container={6}, feature={7}", - id, cdoClass.getName(), version, created, revised, resourceID, containerID, containingFeatureID); - } - - readValues(in); - READING.stop(this); - } - - public void write(CDODataOutput out, 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); - out.writeCDOClassRef(classRef); - out.writeCDOID(id); - out.writeInt(getVersion()); - if (!id.isTemporary()) - { - out.writeLong(created); - out.writeLong(revised); - } - - out.writeCDOID(resourceID); - Object newContainerID = out.getIDProvider().provideCDOID(containerID); - out.writeCDOID((CDOID)newContainerID); - out.writeInt(containingFeatureID); - writeValues(out, referenceChunk); - WRITING.stop(this); - } - - 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; + super(in); } - 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 (revised != UNSPECIFIED_DATE && revised < Math.max(0, created)) - { - throw new IllegalArgumentException("created=" + created + ", revised=" + 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 isResourceNode() - { - return cdoClass.isResourceNode(); - } - - public boolean isResourceFolder() - { - return cdoClass.isResourceFolder(); - } - - public boolean isResource() - { - return cdoClass.isResource(); - } - - public CDORevisionData data() - { - return this; - } - - public CDORevision revision() - { - 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 Object getContainerID() - { - return containerID; - } - - public void setContainerID(Object 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(CDOReferenceAdjuster revisionAdjuster) + public CDORevisionImpl(CDORevisionImpl source) { - if (TRACER.isEnabled()) - { - TRACER.format("Adjusting references for revision {0}", this); - } - - resourceID = (CDOID)revisionAdjuster.adjustReference(resourceID); - containerID = revisionAdjuster.adjustReference(containerID); - - CDOFeature[] features = cdoClass.getAllFeatures(); + super(source); + CDOFeature[] features = getCDOClass().getAllFeatures(); + initValues(features.length); for (int i = 0; i < features.length; i++) { CDOFeature feature = features[i]; + CDOType type = feature.getType(); if (feature.isMany()) { - InternalCDOList list = (InternalCDOList)getValueAsList(i); - if (list != null) + InternalCDOList sourceList = (InternalCDOList)source.values[i]; + if (sourceList != null) { - list.adjustReferences(revisionAdjuster, feature.getType()); + setValue(i, sourceList.clone(type)); } } else { - values[i] = feature.getType().adjustReferences(revisionAdjuster, values[i]); + setValue(i, type.copyValue(source.values[i])); } } } - private CDOList getValueAsList(int i) + public CDORevision copy() { - return (CDOList)values[i]; + return new CDORevisionImpl(this); } @Override - public String toString() + protected void initValues(int size) { - return cdoClass.getName() + "@" + id + "v" + version; + values = new Object[size]; } - public Object getValue(CDOFeature feature) + @Override + protected Object getValue(int i) { - int i = cdoClass.getFeatureID(feature); return values[i]; } - public Object setValue(CDOFeature feature, Object value) - { - int i = cdoClass.getFeatureID(feature); - - try - { - Object old = values[i]; - values[i] = value; - return old; - } - catch (ArrayIndexOutOfBoundsException ex) - { - throw new IllegalArgumentException("Could not find feature " + feature + " in class " + cdoClass, ex); - } - } - - public CDOList getList(CDOFeature feature) - { - return getList(feature, 0); - } - - public CDOList getList(CDOFeature feature, int size) - { - int i = cdoClass.getFeatureID(feature); - CDOList list = (CDOList)values[i]; - if (list == null && size != -1) - { - list = CDOListFactory.DEFAULT.createList(size, 0, 0); - values[i] = list; - } - return list; - } - - public void setList(CDOFeature feature, InternalCDOList list) - { - int i = cdoClass.getFeatureID(feature); - values[i] = 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); - } - } - - 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()) - { - InternalCDOList sourceList = (InternalCDOList)sourceValues[i]; - if (sourceList != null) - { - values[i] = sourceList.clone(type); - } - } - else - { - values[i] = type.copyValue(sourceValues[i]); - } - } - } - - private void readValues(CDODataInput 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()) - { - values[i] = in.readCDOList(this, feature); - } - else - { - values[i] = type.readValue(in); - if (TRACER.isEnabled()) - { - TRACER.format("Read feature {0}: {1}", feature, values[i]); - } - } - } - } - - private void writeValues(CDODataOutput out, int referenceChunk) throws IOException - { - CDOFeature[] features = cdoClass.getAllFeatures(); - for (int i = 0; i < features.length; i++) - { - CDOFeature feature = features[i]; - if (feature.isMany()) - { - out.writeCDOList(getValueAsList(i), feature, referenceChunk); - } - else - { - Object value = values[i]; - if (value != null && feature.isReference()) - { - value = out.getIDProvider().provideCDOID(value); - } - - if (TRACER.isEnabled()) - { - TRACER.format("Writing feature {0}: {1}", feature, value); - } - - feature.getType().writeValue(out, value); - } - } - } - - public static Object remapID(Object value, Map<CDOIDTemp, CDOID> idMappings) + @Override + protected void setValue(int i, Object value) { - 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; + values[i] = value; } } diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractCDORevision.java new file mode 100644 index 0000000000..b4ad8768e1 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/AbstractCDORevision.java @@ -0,0 +1,626 @@ +/*************************************************************************** + * 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 - http://bugs.eclipse.org/201266 + * Simon McDuff - http://bugs.eclipse.org/212958 + * Simon McDuff - http://bugs.eclipse.org/213402 + **************************************************************************/ +package org.eclipse.emf.cdo.spi.common; + +import org.eclipse.emf.cdo.common.CDODataInput; +import org.eclipse.emf.cdo.common.CDODataOutput; +import org.eclipse.emf.cdo.common.id.CDOID; +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.CDOType; +import org.eclipse.emf.cdo.common.revision.CDOList; +import org.eclipse.emf.cdo.common.revision.CDOListFactory; +import org.eclipse.emf.cdo.common.revision.CDOReferenceAdjuster; +import org.eclipse.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.common.revision.CDORevisionData; +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.net4j.util.ImplementationError; +import org.eclipse.net4j.util.collection.MoveableList; +import org.eclipse.net4j.util.om.trace.ContextTracer; +import org.eclipse.net4j.util.om.trace.PerfTracer; + +import java.io.IOException; +import java.util.Map; + +/** + * @author Eike Stepper + * @since 2.0 + */ +public abstract class AbstractCDORevision implements InternalCDORevision +{ + private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_REVISION, AbstractCDORevision.class); + + private static final PerfTracer READING = new PerfTracer(OM.PERF_REVISION_READING, AbstractCDORevision.class); + + private static final PerfTracer WRITING = new PerfTracer(OM.PERF_REVISION_WRITING, AbstractCDORevision.class); + + private CDOClass cdoClass; + + private CDOID id; + + private int version; + + private long created; + + private long revised; + + private CDOID resourceID; + + private Object containerID; + + private int containingFeatureID; + + public AbstractCDORevision(CDOClass cdoClass, CDOID id) + { + if (cdoClass.isAbstract()) + { + throw new IllegalArgumentException("CDOClass is abstract: " + cdoClass); + } + + if (CDOIDUtil.isNull(id)) + { + throw new IllegalArgumentException("CDIID is null"); + } + + this.cdoClass = cdoClass; + this.id = id; + version = 0; + created = UNSPECIFIED_DATE; + revised = UNSPECIFIED_DATE; + resourceID = CDOID.NULL; + containerID = CDOID.NULL; + containingFeatureID = 0; + initValues(cdoClass.getAllFeatures().length); + } + + public AbstractCDORevision(AbstractCDORevision source) + { + 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; + } + + public AbstractCDORevision(CDODataInput in) throws IOException + { + READING.start(this); + cdoClass = in.readCDOClassRefAndResolve(); + + id = in.readCDOID(); + version = in.readInt(); + if (!id.isTemporary()) + { + created = in.readLong(); + revised = in.readLong(); + } + + resourceID = in.readCDOID(); + containerID = in.readCDOID(); + containingFeatureID = in.readInt(); + if (TRACER.isEnabled()) + { + TRACER + .format( + "Reading revision: ID={0}, className={1}, version={2}, created={3}, revised={4}, resource={5}, container={6}, feature={7}", + id, cdoClass.getName(), version, created, revised, resourceID, containerID, containingFeatureID); + } + + readValues(in); + READING.stop(this); + } + + public void write(CDODataOutput out, 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); + out.writeCDOClassRef(classRef); + out.writeCDOID(id); + out.writeInt(getVersion()); + if (!id.isTemporary()) + { + out.writeLong(created); + out.writeLong(revised); + } + + out.writeCDOID(resourceID); + Object newContainerID = out.getIDProvider().provideCDOID(containerID); + out.writeCDOID((CDOID)newContainerID); + out.writeInt(containingFeatureID); + writeValues(out, referenceChunk); + WRITING.stop(this); + } + + 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 (revised != UNSPECIFIED_DATE && revised < Math.max(0, created)) + { + throw new IllegalArgumentException("created=" + created + ", revised=" + 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 isResourceNode() + { + return cdoClass.isResourceNode(); + } + + public boolean isResourceFolder() + { + return cdoClass.isResourceFolder(); + } + + public boolean isResource() + { + return cdoClass.isResource(); + } + + public CDORevisionData data() + { + return this; + } + + public CDORevision revision() + { + 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 Object getContainerID() + { + return containerID; + } + + public void setContainerID(Object 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(CDOReferenceAdjuster revisionAdjuster) + { + if (TRACER.isEnabled()) + { + TRACER.format("Adjusting references for revision {0}", this); + } + + resourceID = (CDOID)revisionAdjuster.adjustReference(resourceID); + containerID = revisionAdjuster.adjustReference(containerID); + + CDOFeature[] features = cdoClass.getAllFeatures(); + for (int i = 0; i < features.length; i++) + { + CDOFeature feature = features[i]; + if (feature.isMany()) + { + InternalCDOList list = (InternalCDOList)getValueAsList(i); + if (list != null) + { + list.adjustReferences(revisionAdjuster, feature.getType()); + } + } + else + { + setValue(i, feature.getType().adjustReferences(revisionAdjuster, getValue(i))); + } + } + } + + @Override + public String toString() + { + return cdoClass.getName() + "@" + id + "v" + version; + } + + public Object getValue(CDOFeature feature) + { + int i = cdoClass.getFeatureID(feature); + return getValue(i); + } + + public Object setValue(CDOFeature feature, Object value) + { + int i = cdoClass.getFeatureID(feature); + + try + { + Object old = getValue(i); + setValue(i, value); + return old; + } + catch (ArrayIndexOutOfBoundsException ex) + { + throw new IllegalArgumentException("Could not find feature " + feature + " in class " + cdoClass, ex); + } + } + + public CDOList getList(CDOFeature feature) + { + return getList(feature, 0); + } + + public CDOList getList(CDOFeature feature, int size) + { + int i = cdoClass.getFeatureID(feature); + CDOList list = (CDOList)getValue(i); + if (list == null && size != -1) + { + list = CDOListFactory.DEFAULT.createList(size, 0, 0); + setValue(i, list); + } + return list; + } + + public void setList(CDOFeature feature, InternalCDOList list) + { + int i = cdoClass.getFeatureID(feature); + setValue(i, 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); + } + } + + protected abstract void initValues(int size); + + protected abstract Object getValue(int i); + + protected abstract void setValue(int i, Object value); + + private CDOList getValueAsList(int i) + { + return (CDOList)getValue(i); + } + + private void readValues(CDODataInput in) throws IOException + { + CDOFeature[] features = cdoClass.getAllFeatures(); + initValues(features.length); + for (int i = 0; i < features.length; i++) + { + CDOFeature feature = features[i]; + CDOType type = feature.getType(); + if (feature.isMany()) + { + setValue(i, in.readCDOList(this, feature)); + } + else + { + setValue(i, type.readValue(in)); + if (TRACER.isEnabled()) + { + TRACER.format("Read feature {0}: {1}", feature, getValue(i)); + } + } + } + } + + private void writeValues(CDODataOutput out, int referenceChunk) throws IOException + { + CDOFeature[] features = cdoClass.getAllFeatures(); + for (int i = 0; i < features.length; i++) + { + CDOFeature feature = features[i]; + if (feature.isMany()) + { + out.writeCDOList(getValueAsList(i), feature, referenceChunk); + } + else + { + Object value = getValue(i); + if (value != null && feature.isReference()) + { + value = out.getIDProvider().provideCDOID(value); + } + + if (TRACER.isEnabled()) + { + TRACER.format("Writing feature {0}: {1}", feature, value); + } + + feature.getType().writeValue(out, value); + } + } + } + + 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/spi/common/InternalCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/InternalCDORevision.java index fc8a25438c..f58e6d4ad8 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/InternalCDORevision.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/InternalCDORevision.java @@ -11,6 +11,7 @@ **************************************************************************/ package org.eclipse.emf.cdo.spi.common; +import org.eclipse.emf.cdo.common.CDODataOutput; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.model.CDOFeature; import org.eclipse.emf.cdo.common.revision.CDOList; @@ -19,6 +20,8 @@ import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.CDORevisionData; import org.eclipse.emf.cdo.common.revision.CDORevisionUtil; +import java.io.IOException; + /** * @author Eike Stepper */ @@ -83,4 +86,9 @@ public interface InternalCDORevision extends CDORevision, CDORevisionData, CDORe @Deprecated public void setListSize(CDOFeature feature, int size); + + /** + * @since 2.0 + */ + public void write(CDODataOutput out, int referenceChunk) throws IOException; } |