diff options
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common')
9 files changed, 816 insertions, 294 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDExternalImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDExternalImpl.java index f3491c1e5c..8717d8ed7e 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDExternalImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDExternalImpl.java @@ -6,53 +6,70 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Simon McDuff - initial API and implementation - * Eike Stepper - maintenance + * 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.CDOIDExternal; +import org.eclipse.emf.cdo.common.id.CDOIDString; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; import org.eclipse.emf.cdo.spi.common.id.AbstractCDOID; -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.CheckUtil; +import org.eclipse.net4j.util.ref.Interner; import java.io.IOException; +import java.io.ObjectStreamException; /** - * @author Simon McDuff + * @author Eike Stepper + * @since 2.0 */ -public class CDOIDExternalImpl extends AbstractCDOID implements CDOIDExternal +public final class CDOIDExternalImpl extends AbstractCDOID implements CDOIDExternal, CDOIDString { private static final long serialVersionUID = 1L; - private String uri; + private static final StringInterner INTERNER = new StringInterner(); - public CDOIDExternalImpl(String uri) + private final String uri; + + private CDOIDExternalImpl(String uri) { + CheckUtil.checkArg(uri, "Null not allowed"); this.uri = uri; } - public Type getType() + @Override + public void write(CDODataOutput out) throws IOException { - return Type.EXTERNAL_OBJECT; + out.writeString(uri); } - public boolean isDangling() + public String toURIFragment() { - return false; + return uri; } - public boolean isExternal() + public String getURI() { - return true; + return uri; } - public boolean isNull() + public String getStringValue() { - return false; + return uri; + } + + public Type getType() + { + return Type.EXTERNAL_OBJECT; + } + + public boolean isExternal() + { + return true; } public boolean isObject() @@ -65,67 +82,71 @@ public class CDOIDExternalImpl extends AbstractCDOID implements CDOIDExternal return false; } - public String getURI() + @Override + public int hashCode() { - return uri; + return uri.hashCode(); } @Override public String toString() { - return "oid:" + toURIFragment(); //$NON-NLS-1$ + return "oid:" + uri; //$NON-NLS-1$ } @Override - public void read(String fragmentPart) + protected int doCompareTo(CDOID o) throws ClassCastException { - uri = fragmentPart; + return uri.compareTo(((CDOIDExternalImpl)o).uri); } - @Override - public void read(ExtendedDataInput in) throws IOException + private Object readResolve() throws ObjectStreamException { - uri = in.readString(); + return create(uri); } - @Override - public void write(ExtendedDataOutput out) throws IOException + private static int getHashCode(String uri) { - out.writeString(uri); + return uri.hashCode(); } - public String toURIFragment() + public static CDOIDExternalImpl create(String uri) { - return uri; + return INTERNER.intern(uri); } - @Override - public boolean equals(Object obj) + public static CDOIDExternalImpl create(CDODataInput in) throws IOException + { + String uri = in.readString(); + return create(uri); + } + + /** + * @author Eike Stepper + */ + private static final class StringInterner extends Interner<CDOIDExternalImpl> { - if (obj == this) + public synchronized CDOIDExternalImpl intern(String uri) { - return true; + int hashCode = getHashCode(uri); + for (Entry<CDOIDExternalImpl> entry = getEntry(hashCode); entry != null; entry = entry.getNextEntry()) + { + CDOIDExternalImpl id = entry.get(); + if (id != null && id.uri.equals(uri)) + { + return id; + } + } + + CDOIDExternalImpl id = new CDOIDExternalImpl(uri); + addEntry(createEntry(id, hashCode)); + return id; } - // Could CDOIDTempObjectExternalImpl and CDOIDExternalImpl have the same uri. We don't want to mixed them. - if (obj != null && obj.getClass() == getClass()) + @Override + protected int hashCode(CDOIDExternalImpl id) { - CDOIDExternal that = (CDOIDExternal)obj; - return ObjectUtil.equals(getURI(), that.getURI()); + return getHashCode(id.uri); } - - return false; - } - - @Override - public int hashCode() - { - return getClass().hashCode() ^ uri.hashCode(); - } - - @Override - protected int doCompareTo(CDOID o) throws ClassCastException - { - return getURI().compareTo(((CDOIDExternalImpl)o).getURI()); } } 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 index 836db08673..eeb2c3c89e 100644 --- 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 @@ -15,93 +15,70 @@ package org.eclipse.emf.cdo.internal.common.id; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.id.CDOIDObject; import org.eclipse.emf.cdo.common.id.CDOIDTemp; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; import org.eclipse.emf.cdo.spi.common.id.AbstractCDOID; -import org.eclipse.net4j.util.io.ExtendedDataInput; -import org.eclipse.net4j.util.io.ExtendedDataOutput; - import java.io.IOException; +import java.io.ObjectStreamException; /** * @author Eike Stepper */ public final class CDOIDNullImpl extends AbstractCDOID implements CDOIDTemp, CDOIDObject { - public static final CDOIDNullImpl INSTANCE = new CDOIDNullImpl(); - private static final long serialVersionUID = 1L; + public static final CDOIDNullImpl INSTANCE = new CDOIDNullImpl(); + private CDOIDNullImpl() { } - public Type getType() + public int getIntValue() { - return Type.NULL; + return 0; } - public boolean isDangling() + public long getLongValue() { - return false; + return 0L; } - public boolean isExternal() + @Override + public void write(CDODataOutput out) throws IOException { - return false; + // Do nothing } - public boolean isNull() + public String toURIFragment() { - return true; + return "NULL"; //$NON-NLS-1$ } - public boolean isObject() + public Type getType() { - return false; + return Type.NULL; } - public boolean isTemporary() + public boolean isExternal() { return false; } - public int getIntValue() - { - return 0; - } - - public long getLongValue() - { - return 0L; - } - - public String toURIFragment() - { - return "NULL"; //$NON-NLS-1$ - } - @Override - public void read(String fragmentPart) - { - // Do nothing - } - - @Override - public void read(ExtendedDataInput in) throws IOException + public boolean isNull() { - // Do nothing + return true; } - @Override - public void write(ExtendedDataOutput out) throws IOException + public boolean isObject() { - // Do nothing + return false; } - @Override - public boolean equals(Object obj) + public boolean isTemporary() { - return obj == INSTANCE; + return false; } @Override @@ -119,7 +96,11 @@ public final class CDOIDNullImpl extends AbstractCDOID implements CDOIDTemp, CDO @Override protected int doCompareTo(CDOID o) throws ClassCastException { - ((CDOIDNullImpl)o).getIntValue(); // Possibly throw ClassCastException return 0; // NULL == NULL } + + private Object readResolve() throws ObjectStreamException + { + return INSTANCE; + } } diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDObjectLongImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDObjectLongImpl.java index a4d17b3855..48f267696c 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDObjectLongImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDObjectLongImpl.java @@ -11,42 +11,58 @@ package org.eclipse.emf.cdo.internal.common.id; import org.eclipse.emf.cdo.common.id.CDOID; -import org.eclipse.emf.cdo.spi.common.id.AbstractCDOIDLong; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.spi.common.id.AbstractCDOID; import org.eclipse.emf.cdo.spi.common.id.InternalCDOIDObject; +import org.eclipse.net4j.util.CheckUtil; +import org.eclipse.net4j.util.ObjectUtil; +import org.eclipse.net4j.util.ref.Interner; + +import java.io.IOException; +import java.io.ObjectStreamException; + /** * @author Eike Stepper * @since 2.0 */ -public class CDOIDObjectLongImpl extends AbstractCDOIDLong implements InternalCDOIDObject +public final class CDOIDObjectLongImpl extends AbstractCDOID implements InternalCDOIDObject { private static final long serialVersionUID = 1L; - public CDOIDObjectLongImpl() + private static final LongInterner INTERNER = new LongInterner(); + + private final long value; + + private CDOIDObjectLongImpl(long value) { + CheckUtil.checkArg(value != 0L, "Zero not allowed"); + this.value = value; } - public CDOIDObjectLongImpl(long value) + public long getLongValue() { - super(value); + return value; } - public Type getType() + @Override + public void write(CDODataOutput out) throws IOException { - return Type.OBJECT; + out.writeLong(value); } - public boolean isDangling() + public String toURIFragment() { - return false; + return String.valueOf(value); } - public boolean isExternal() + public Type getType() { - return false; + return Type.OBJECT; } - public boolean isNull() + public boolean isExternal() { return false; } @@ -70,14 +86,76 @@ public class CDOIDObjectLongImpl extends AbstractCDOIDLong implements InternalCD } @Override + public int hashCode() + { + return ObjectUtil.hashCode(value); + } + + @Override public String toString() { - return "OID" + getLongValue(); //$NON-NLS-1$ + return "OID" + value; //$NON-NLS-1$ } @Override protected int doCompareTo(CDOID o) throws ClassCastException { - return new Long(getLongValue()).compareTo(((CDOIDObjectLongImpl)o).getLongValue()); + return new Long(value).compareTo(((CDOIDObjectLongImpl)o).value); + } + + private Object readResolve() throws ObjectStreamException + { + return create(value); + } + + private static int getHashCode(long value) + { + return ObjectUtil.hashCode(value); + } + + public static CDOIDObjectLongImpl create(long value) + { + return INTERNER.intern(value); + } + + public static CDOIDObjectLongImpl create(CDODataInput in) throws IOException + { + long value = in.readLong(); + return create(value); + } + + public static CDOIDObjectLongImpl create(String fragmentPart) + { + long value = Long.parseLong(fragmentPart); + return create(value); + } + + /** + * @author Eike Stepper + */ + private static final class LongInterner extends Interner<CDOIDObjectLongImpl> + { + public synchronized CDOIDObjectLongImpl intern(long value) + { + int hashCode = getHashCode(value); + for (Entry<CDOIDObjectLongImpl> entry = getEntry(hashCode); entry != null; entry = entry.getNextEntry()) + { + CDOIDObjectLongImpl id = entry.get(); + if (id != null && id.value == value) + { + return id; + } + } + + CDOIDObjectLongImpl id = new CDOIDObjectLongImpl(value); + addEntry(createEntry(id, hashCode)); + return id; + } + + @Override + protected int hashCode(CDOIDObjectLongImpl id) + { + return getHashCode(id.value); + } } } diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDObjectLongWithClassifierImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDObjectLongWithClassifierImpl.java index eb781efea5..c8f9d9893f 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDObjectLongWithClassifierImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDObjectLongWithClassifierImpl.java @@ -15,31 +15,41 @@ import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.model.CDOClassifierRef; import org.eclipse.emf.cdo.common.protocol.CDODataInput; import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.spi.common.id.AbstractCDOID; +import org.eclipse.emf.cdo.spi.common.id.InternalCDOIDObject; +import org.eclipse.net4j.util.CheckUtil; 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.ref.Interner; import java.io.IOException; +import java.io.ObjectStreamException; /** * @author Martin Taal * @since 3.0 */ -public class CDOIDObjectLongWithClassifierImpl extends CDOIDObjectLongImpl implements CDOClassifierRef.Provider +public final class CDOIDObjectLongWithClassifierImpl extends AbstractCDOID implements InternalCDOIDObject, + CDOClassifierRef.Provider { private static final long serialVersionUID = 1L; - private CDOClassifierRef classifierRef; + private static final LongWithClassifierInterner INTERNER = new LongWithClassifierInterner(); - public CDOIDObjectLongWithClassifierImpl() + private final long value; + + private final CDOClassifierRef classifierRef; + + private CDOIDObjectLongWithClassifierImpl(long value, CDOClassifierRef classifierRef) { + CheckUtil.checkArg(value != 0L, "Zero not allowed"); + this.value = value; + this.classifierRef = classifierRef; } - public CDOIDObjectLongWithClassifierImpl(CDOClassifierRef classifierRef, long value) + public long getLongValue() { - super(value); - this.classifierRef = classifierRef; + return value; } public CDOClassifierRef getClassifierRef() @@ -48,98 +58,127 @@ public class CDOIDObjectLongWithClassifierImpl extends CDOIDObjectLongImpl imple } @Override + public void write(CDODataOutput out) throws IOException + { + out.writeLong(value); + out.writeCDOClassifierRef(classifierRef); + } + + public String toURIFragment() + { + return classifierRef.getPackageURI() + CDOClassifierRef.URI_SEPARATOR + classifierRef.getClassifierName() + + CDOClassifierRef.URI_SEPARATOR + value; + } + public Type getType() { return Type.OBJECT; } - @Override public CDOID.ObjectType getSubType() { return CDOID.ObjectType.LONG_WITH_CLASSIFIER; } - @Override - public String toURIFragment() + public boolean isExternal() { - return getClassifierRef().getPackageURI() + CDOClassifierRef.URI_SEPARATOR + getClassifierRef().getClassifierName() - + CDOClassifierRef.URI_SEPARATOR + super.toURIFragment(); + return false; } - @Override - public void read(String fragmentPart) + public boolean isObject() { - // get the CDOClassifierRef part - int index1 = fragmentPart.indexOf(CDOClassifierRef.URI_SEPARATOR); - int index2 = fragmentPart.indexOf(CDOClassifierRef.URI_SEPARATOR, index1 + 1); - if (index1 == -1 || index2 == -1) - { - throw new IllegalArgumentException("The fragment " + fragmentPart + " is not a valid fragment"); - } - - classifierRef = new CDOClassifierRef(fragmentPart.substring(0, index1), fragmentPart.substring(index1 + 1, index2)); + return true; + } - // let the super take care of the rest - super.read(fragmentPart.substring(index2 + 1)); + public boolean isTemporary() + { + return false; } @Override - public void read(ExtendedDataInput in) throws IOException + public int hashCode() { - // TODO: change the parameter to prevent casting to CDODataInput - CDODataInput cdoDataInput = (CDODataInput)in; - classifierRef = cdoDataInput.readCDOClassifierRef(); - - // and let the super take care of the rest - super.read(in); + return getHashCode(value, classifierRef); } @Override - public void write(ExtendedDataOutput out) throws IOException + public String toString() { - // TODO: change the parameter to prevent casting to CDODataInput - CDODataOutput cdoDataOutput = (CDODataOutput)out; - cdoDataOutput.writeCDOClassifierRef(classifierRef); - - // and let the super write the rest - super.write(out); + return "OID:" + toURIFragment(); //$NON-NLS-1$ } @Override - public boolean equals(Object obj) + protected int doCompareTo(CDOID o) throws ClassCastException { - if (obj == this) - { - return true; - } + return toURIFragment().compareTo(o.toURIFragment()); + } - if (obj != null && obj.getClass() == getClass()) - { - CDOIDObjectLongWithClassifierImpl that = (CDOIDObjectLongWithClassifierImpl)obj; - return ObjectUtil.equals(classifierRef, that.classifierRef) && getLongValue() == that.getLongValue(); - } + private Object readResolve() throws ObjectStreamException + { + return create(value, classifierRef); + } - return false; + private static int getHashCode(long value, CDOClassifierRef classifierRef) + { + return ObjectUtil.hashCode(value) ^ classifierRef.hashCode(); } - @Override - public int hashCode() + public static CDOIDObjectLongWithClassifierImpl create(long value, CDOClassifierRef classifierRef) { - int hashCode = classifierRef.hashCode() ^ ObjectUtil.hashCode(getLongValue()); - return getClass().hashCode() ^ hashCode; + return INTERNER.intern(value, classifierRef); } - @Override - public String toString() + public static CDOIDObjectLongWithClassifierImpl create(CDODataInput in) throws IOException { - return "OID:" + toURIFragment(); //$NON-NLS-1$ + long value = in.readLong(); + CDOClassifierRef classifierRef = in.readCDOClassifierRef(); + return create(value, classifierRef); } - @Override - protected int doCompareTo(CDOID o) throws ClassCastException + public static CDOIDObjectLongWithClassifierImpl create(String fragmentPart) { - // conversion to uri fragment is pretty heavy but afaics the compareTo - // is not used in a critical place. - return toURIFragment().compareTo(o.toURIFragment()); + int index1 = fragmentPart.indexOf(CDOClassifierRef.URI_SEPARATOR); + int index2 = fragmentPart.indexOf(CDOClassifierRef.URI_SEPARATOR, index1 + 1); + if (index1 == -1 || index2 == -1) + { + throw new IllegalArgumentException("The fragment " + fragmentPart + " is not a valid fragment"); + } + + String packageURI = fragmentPart.substring(0, index1); + String classifierName = fragmentPart.substring(index1 + 1, index2); + CDOClassifierRef classifierRef = new CDOClassifierRef(packageURI, classifierName); + + long value = Long.parseLong(fragmentPart.substring(index2 + 1)); + return create(value, classifierRef); + } + + /** + * @author Eike Stepper + */ + private static final class LongWithClassifierInterner extends Interner<CDOIDObjectLongWithClassifierImpl> + { + public synchronized CDOIDObjectLongWithClassifierImpl intern(long value, CDOClassifierRef classifierRef) + { + int hashCode = getHashCode(value, classifierRef); + for (Entry<CDOIDObjectLongWithClassifierImpl> entry = getEntry(hashCode); entry != null; entry = entry + .getNextEntry()) + { + CDOIDObjectLongWithClassifierImpl id = entry.get(); + if (id != null && id.value == value && id.classifierRef.equals(classifierRef)) + { + return id; + } + } + + CDOIDObjectLongWithClassifierImpl id = new CDOIDObjectLongWithClassifierImpl(value, classifierRef); + addEntry(createEntry(id, hashCode)); + return id; + } + + @Override + protected int hashCode(CDOIDObjectLongWithClassifierImpl id) + { + return getHashCode(id.value, id.classifierRef); + } } } diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDObjectStringImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDObjectStringImpl.java index 376a113b81..12cce04f7d 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDObjectStringImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDObjectStringImpl.java @@ -6,48 +6,68 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Martin Taal - initial API and implementation - * Eike Stepper - maintenance + * 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.spi.common.id.AbstractCDOIDString; +import org.eclipse.emf.cdo.common.id.CDOIDString; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.spi.common.id.AbstractCDOID; import org.eclipse.emf.cdo.spi.common.id.InternalCDOIDObject; +import org.eclipse.net4j.util.CheckUtil; +import org.eclipse.net4j.util.ref.Interner; + +import java.io.IOException; +import java.io.ObjectStreamException; + /** - * @author Martin Taal - * @since 3.0 + * @author Eike Stepper + * @since 2.0 */ -public class CDOIDObjectStringImpl extends AbstractCDOIDString implements InternalCDOIDObject +public final class CDOIDObjectStringImpl extends AbstractCDOID implements InternalCDOIDObject, CDOIDString { private static final long serialVersionUID = 1L; - public CDOIDObjectStringImpl() + private static final StringInterner INTERNER = new StringInterner(); + + private final String value; + + private CDOIDObjectStringImpl(String value) { + CheckUtil.checkArg(value, "Null not allowed"); + this.value = value; } - public CDOIDObjectStringImpl(String value) + @Override + public void write(CDODataOutput out) throws IOException { - super(value); + out.writeString(value); } - public Type getType() + public String toURIFragment() { - return Type.OBJECT; + return value; } - public boolean isDangling() + public String getStringValue() { - return false; + return value; } - public boolean isExternal() + public Type getType() { - return false; + return Type.OBJECT; } - public boolean isNull() + public CDOID.ObjectType getSubType() + { + return CDOID.ObjectType.STRING; + } + + public boolean isExternal() { return false; } @@ -62,20 +82,71 @@ public class CDOIDObjectStringImpl extends AbstractCDOIDString implements Intern return false; } - public CDOID.ObjectType getSubType() + @Override + public int hashCode() { - return CDOID.ObjectType.STRING; + return value.hashCode(); } @Override public String toString() { - return "OID" + getStringValue(); //$NON-NLS-1$ + return "OID" + value; //$NON-NLS-1$ } @Override protected int doCompareTo(CDOID o) throws ClassCastException { - return getStringValue().compareTo(((CDOIDObjectStringImpl)o).getStringValue()); + return value.compareTo(((CDOIDObjectStringImpl)o).value); + } + + private Object readResolve() throws ObjectStreamException + { + return create(value); + } + + private static int getHashCode(String value) + { + return value.hashCode(); + } + + public static CDOIDObjectStringImpl create(String value) + { + return INTERNER.intern(value); + } + + public static CDOIDObjectStringImpl create(CDODataInput in) throws IOException + { + String value = in.readString(); + return create(value); + } + + /** + * @author Eike Stepper + */ + private static final class StringInterner extends Interner<CDOIDObjectStringImpl> + { + public synchronized CDOIDObjectStringImpl intern(String value) + { + int hashCode = getHashCode(value); + for (Entry<CDOIDObjectStringImpl> entry = getEntry(hashCode); entry != null; entry = entry.getNextEntry()) + { + CDOIDObjectStringImpl id = entry.get(); + if (id != null && id.value.equals(value)) + { + return id; + } + } + + CDOIDObjectStringImpl id = new CDOIDObjectStringImpl(value); + addEntry(createEntry(id, hashCode)); + return id; + } + + @Override + protected int hashCode(CDOIDObjectStringImpl id) + { + return getHashCode(id.value); + } } } diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDObjectStringWithClassifierImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDObjectStringWithClassifierImpl.java index 6b6ed62ff2..f032d53dcb 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDObjectStringWithClassifierImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDObjectStringWithClassifierImpl.java @@ -12,34 +12,44 @@ package org.eclipse.emf.cdo.internal.common.id; import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.id.CDOIDString; import org.eclipse.emf.cdo.common.model.CDOClassifierRef; import org.eclipse.emf.cdo.common.protocol.CDODataInput; import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.spi.common.id.AbstractCDOID; +import org.eclipse.emf.cdo.spi.common.id.InternalCDOIDObject; -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.CheckUtil; +import org.eclipse.net4j.util.ref.Interner; import java.io.IOException; +import java.io.ObjectStreamException; /** * @author Martin Taal * @since 3.0 */ -public class CDOIDObjectStringWithClassifierImpl extends CDOIDObjectStringImpl implements CDOClassifierRef.Provider +public final class CDOIDObjectStringWithClassifierImpl extends AbstractCDOID implements InternalCDOIDObject, + CDOIDString, CDOClassifierRef.Provider { private static final long serialVersionUID = 1L; - private CDOClassifierRef classifierRef; + private static final StringWithClassifierInterner INTERNER = new StringWithClassifierInterner(); - public CDOIDObjectStringWithClassifierImpl() + private final String value; + + private final CDOClassifierRef classifierRef; + + private CDOIDObjectStringWithClassifierImpl(String value, CDOClassifierRef classifierRef) { + CheckUtil.checkArg(value, "Null not allowed"); + this.value = value; + this.classifierRef = classifierRef; } - public CDOIDObjectStringWithClassifierImpl(CDOClassifierRef classifierRef, String value) + public String getStringValue() { - super(value); - this.classifierRef = classifierRef; + return value; } public CDOClassifierRef getClassifierRef() @@ -48,78 +58,47 @@ public class CDOIDObjectStringWithClassifierImpl extends CDOIDObjectStringImpl i } @Override - public CDOID.ObjectType getSubType() + public void write(CDODataOutput out) throws IOException { - return CDOID.ObjectType.STRING_WITH_CLASSIFIER; + out.writeString(value); + out.writeCDOClassifierRef(classifierRef); } - @Override public String toURIFragment() { - return getClassifierRef().getPackageURI() + CDOClassifierRef.URI_SEPARATOR + getClassifierRef().getClassifierName() - + CDOClassifierRef.URI_SEPARATOR + super.toURIFragment(); + return classifierRef.getPackageURI() + CDOClassifierRef.URI_SEPARATOR + classifierRef.getClassifierName() + + CDOClassifierRef.URI_SEPARATOR + value; } - @Override - public void read(String fragmentPart) + public Type getType() { - // get the EClass part - int index1 = fragmentPart.indexOf(CDOClassifierRef.URI_SEPARATOR); - int index2 = fragmentPart.indexOf(CDOClassifierRef.URI_SEPARATOR, index1 + 1); - if (index1 == -1 || index2 == -1) - { - throw new IllegalArgumentException("The fragment " + fragmentPart + " is invalid"); - } - - classifierRef = new CDOClassifierRef(fragmentPart.substring(0, index1), fragmentPart.substring(index1 + 1, index2)); - - // let the super take care of the rest - super.read(fragmentPart.substring(index2 + 1)); + return Type.OBJECT; } - @Override - public void read(ExtendedDataInput in) throws IOException + public CDOID.ObjectType getSubType() { - CDODataInput cdoDataInput = (CDODataInput)in; - classifierRef = cdoDataInput.readCDOClassifierRef(); - - // and let the super take care of the rest - super.read(in); + return CDOID.ObjectType.STRING_WITH_CLASSIFIER; } - @Override - public void write(ExtendedDataOutput out) throws IOException + public boolean isExternal() { - // TODO: change the parameter to prevent casting to CDODataInput - CDODataOutput cdoDataOutput = (CDODataOutput)out; - cdoDataOutput.writeCDOClassifierRef(classifierRef); - - // and let the super write the rest - super.write(out); + return false; } - @Override - public boolean equals(Object obj) + public boolean isObject() { - if (obj == this) - { - return true; - } - - if (obj != null && obj.getClass() == getClass()) - { - CDOIDObjectStringWithClassifierImpl that = (CDOIDObjectStringWithClassifierImpl)obj; - return ObjectUtil.equals(classifierRef, that.classifierRef) && getStringValue().equals(that.getStringValue()); - } + return true; + } + public boolean isTemporary() + { return false; } @Override public int hashCode() { - int hashCode = classifierRef.hashCode() ^ ObjectUtil.hashCode(getStringValue()); - return getClass().hashCode() ^ hashCode; + return getHashCode(value, classifierRef); } @Override @@ -131,8 +110,75 @@ public class CDOIDObjectStringWithClassifierImpl extends CDOIDObjectStringImpl i @Override protected int doCompareTo(CDOID o) throws ClassCastException { - // conversion to uri fragment is pretty heavy but afaics the compareTo - // is not used in a critical place. return toURIFragment().compareTo(o.toURIFragment()); } + + private Object readResolve() throws ObjectStreamException + { + return create(value, classifierRef); + } + + private static int getHashCode(String value, CDOClassifierRef classifierRef) + { + return value.hashCode() ^ classifierRef.hashCode(); + } + + public static CDOIDObjectStringWithClassifierImpl create(String value, CDOClassifierRef classifierRef) + { + return INTERNER.intern(value, classifierRef); + } + + public static CDOIDObjectStringWithClassifierImpl create(CDODataInput in) throws IOException + { + String value = in.readString(); + CDOClassifierRef classifierRef = in.readCDOClassifierRef(); + return create(value, classifierRef); + } + + public static CDOIDObjectStringWithClassifierImpl create(String fragmentPart) + { + int index1 = fragmentPart.indexOf(CDOClassifierRef.URI_SEPARATOR); + int index2 = fragmentPart.indexOf(CDOClassifierRef.URI_SEPARATOR, index1 + 1); + if (index1 == -1 || index2 == -1) + { + throw new IllegalArgumentException("The fragment " + fragmentPart + " is invalid"); + } + + String packageURI = fragmentPart.substring(0, index1); + String classifierName = fragmentPart.substring(index1 + 1, index2); + CDOClassifierRef classifierRef = new CDOClassifierRef(packageURI, classifierName); + + String value = fragmentPart.substring(index2 + 1); + return create(value, classifierRef); + } + + /** + * @author Eike Stepper + */ + private static final class StringWithClassifierInterner extends Interner<CDOIDObjectStringWithClassifierImpl> + { + public synchronized CDOIDObjectStringWithClassifierImpl intern(String value, CDOClassifierRef classifierRef) + { + int hashCode = getHashCode(value, classifierRef); + for (Entry<CDOIDObjectStringWithClassifierImpl> entry = getEntry(hashCode); entry != null; entry = entry + .getNextEntry()) + { + CDOIDObjectStringWithClassifierImpl id = entry.get(); + if (id != null && id.value.equals(value) && id.classifierRef.equals(classifierRef)) + { + return id; + } + } + + CDOIDObjectStringWithClassifierImpl id = new CDOIDObjectStringWithClassifierImpl(value, classifierRef); + addEntry(createEntry(id, hashCode)); + return id; + } + + @Override + protected int hashCode(CDOIDObjectStringWithClassifierImpl id) + { + return getHashCode(id.value, id.classifierRef); + } + } } diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDObjectUUIDImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDObjectUUIDImpl.java index fd76f4f4b4..70ca6411b5 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDObjectUUIDImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDObjectUUIDImpl.java @@ -12,42 +12,64 @@ package org.eclipse.emf.cdo.internal.common.id; import org.eclipse.emf.cdo.common.id.CDOID; -import org.eclipse.emf.cdo.spi.common.id.AbstractCDOIDByteArray; +import org.eclipse.emf.cdo.common.id.CDOIDUtil; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.spi.common.id.AbstractCDOID; import org.eclipse.emf.cdo.spi.common.id.InternalCDOIDObject; +import org.eclipse.net4j.util.CheckUtil; +import org.eclipse.net4j.util.ref.Interner; + +import java.io.IOException; +import java.io.ObjectStreamException; +import java.util.Arrays; + /** * @author Martin Taal * @since 3.0 */ -public class CDOIDObjectUUIDImpl extends AbstractCDOIDByteArray implements InternalCDOIDObject +public final class CDOIDObjectUUIDImpl extends AbstractCDOID implements InternalCDOIDObject { private static final long serialVersionUID = 1L; - public CDOIDObjectUUIDImpl() + private static final UUIDInterner INTERNER = new UUIDInterner(); + + private final byte[] value; + + private CDOIDObjectUUIDImpl(byte[] value) { + CheckUtil.checkArg(value, "Null not allowed"); + this.value = value; } - public CDOIDObjectUUIDImpl(byte[] value) + public byte[] getByteArrayValue() { - super(value); + return value; } - public Type getType() + @Override + public void write(CDODataOutput out) throws IOException { - return Type.OBJECT; + out.writeByteArray(value); } - public boolean isDangling() + public String toURIFragment() { - return false; + return CDOIDUtil.encodeUUID(value); } - public boolean isExternal() + public Type getType() { - return false; + return Type.OBJECT; } - public boolean isNull() + public CDOID.ObjectType getSubType() + { + return CDOID.ObjectType.UUID; + } + + public boolean isExternal() { return false; } @@ -62,21 +84,21 @@ public class CDOIDObjectUUIDImpl extends AbstractCDOIDByteArray implements Inter return false; } - public CDOID.ObjectType getSubType() + @Override + public int hashCode() { - return CDOID.ObjectType.UUID; + return getHashCode(value); } @Override protected int doCompareTo(CDOID o) throws ClassCastException { - byte[] thisValue = getByteArrayValue(); - byte[] thatValue = ((CDOIDObjectUUIDImpl)o).getByteArrayValue(); - int minLength = Math.min(thisValue.length, thatValue.length); + byte[] thatValue = ((CDOIDObjectUUIDImpl)o).value; + int minLength = Math.min(value.length, thatValue.length); for (int i = 0; i < minLength; i++) { - byte thisByte = thisValue[i]; + byte thisByte = value[i]; byte thatByte = thatValue[i]; if (thisByte < thatByte) { @@ -89,16 +111,72 @@ public class CDOIDObjectUUIDImpl extends AbstractCDOIDByteArray implements Inter } } - if (thisValue.length < thatValue.length) + if (value.length < thatValue.length) { return -1; } - if (thisValue.length > thatValue.length) + if (value.length > thatValue.length) { return 1; } return 0; } + + private Object readResolve() throws ObjectStreamException + { + return create(value); + } + + private static int getHashCode(byte[] value) + { + return Arrays.hashCode(value); + } + + public static CDOIDObjectUUIDImpl create(byte[] value) + { + return INTERNER.intern(value); + } + + public static CDOIDObjectUUIDImpl create(CDODataInput in) throws IOException + { + byte[] value = in.readByteArray(); + return create(value); + } + + public static CDOIDObjectUUIDImpl create(String fragmentPart) + { + byte[] value = CDOIDUtil.decodeUUID(fragmentPart); + return create(value); + } + + /** + * @author Eike Stepper + */ + private static final class UUIDInterner extends Interner<CDOIDObjectUUIDImpl> + { + public synchronized CDOIDObjectUUIDImpl intern(byte[] value) + { + int hashCode = getHashCode(value); + for (Entry<CDOIDObjectUUIDImpl> entry = getEntry(hashCode); entry != null; entry = entry.getNextEntry()) + { + CDOIDObjectUUIDImpl id = entry.get(); + if (id != null && Arrays.equals(id.value, value)) + { + return id; + } + } + + CDOIDObjectUUIDImpl id = new CDOIDObjectUUIDImpl(value); + addEntry(createEntry(id, hashCode)); + return id; + } + + @Override + protected int hashCode(CDOIDObjectUUIDImpl id) + { + return getHashCode(id.value); + } + } } diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempObjectExternalImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempObjectExternalImpl.java index b72babdd7e..ac1cb3a843 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempObjectExternalImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/id/CDOIDTempObjectExternalImpl.java @@ -4,30 +4,150 @@ * 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 + * 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.CDOIDExternal; +import org.eclipse.emf.cdo.common.id.CDOIDString; import org.eclipse.emf.cdo.common.id.CDOIDTemp; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.spi.common.id.AbstractCDOID; + +import org.eclipse.net4j.util.CheckUtil; +import org.eclipse.net4j.util.ref.Interner; + +import java.io.IOException; +import java.io.ObjectStreamException; /** - * @author Simon McDuff + * @author Eike Stepper + * @since 2.0 */ -public class CDOIDTempObjectExternalImpl extends CDOIDExternalImpl implements CDOIDTemp +public final class CDOIDTempObjectExternalImpl extends AbstractCDOID implements CDOIDExternal, CDOIDTemp, CDOIDString { private static final long serialVersionUID = 1L; - public CDOIDTempObjectExternalImpl(String uri) + private static final StringInterner INTERNER = new StringInterner(); + + private final String uri; + + private CDOIDTempObjectExternalImpl(String uri) { - super(uri); + CheckUtil.checkArg(uri, "Null not allowed"); + this.uri = uri; } @Override + public void write(CDODataOutput out) throws IOException + { + out.writeString(uri); + } + + public String toURIFragment() + { + return uri; + } + + public String getURI() + { + return uri; + } + + public String getStringValue() + { + return uri; + } + public Type getType() { return Type.EXTERNAL_TEMP_OBJECT; } + + public boolean isExternal() + { + return true; + } + + public boolean isObject() + { + return true; + } + + public boolean isTemporary() + { + return true; + } + + @Override + public int hashCode() + { + return uri.hashCode(); + } + + @Override + public String toString() + { + return "oid:" + uri; //$NON-NLS-1$ + } + + @Override + protected int doCompareTo(CDOID o) throws ClassCastException + { + return uri.compareTo(((CDOIDTempObjectExternalImpl)o).uri); + } + + private Object readResolve() throws ObjectStreamException + { + return create(uri); + } + + private static int getHashCode(String uri) + { + return uri.hashCode(); + } + + public static CDOIDTempObjectExternalImpl create(String uri) + { + return INTERNER.intern(uri); + } + + public static CDOIDTempObjectExternalImpl create(CDODataInput in) throws IOException + { + String uri = in.readString(); + return create(uri); + } + + /** + * @author Eike Stepper + */ + private static final class StringInterner extends Interner<CDOIDTempObjectExternalImpl> + { + public synchronized CDOIDTempObjectExternalImpl intern(String uri) + { + int hashCode = getHashCode(uri); + for (Entry<CDOIDTempObjectExternalImpl> entry = getEntry(hashCode); entry != null; entry = entry.getNextEntry()) + { + CDOIDTempObjectExternalImpl id = entry.get(); + if (id != null && id.uri.equals(uri)) + { + return id; + } + } + + CDOIDTempObjectExternalImpl id = new CDOIDTempObjectExternalImpl(uri); + addEntry(createEntry(id, hashCode)); + return id; + } + + @Override + protected int hashCode(CDOIDTempObjectExternalImpl id) + { + return getHashCode(id.uri); + } + } } 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 index 2cc4034065..54232a02da 100644 --- 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 @@ -12,36 +12,56 @@ package org.eclipse.emf.cdo.internal.common.id; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.id.CDOIDTemp; -import org.eclipse.emf.cdo.spi.common.id.AbstractCDOIDInteger; +import org.eclipse.emf.cdo.common.protocol.CDODataInput; +import org.eclipse.emf.cdo.common.protocol.CDODataOutput; +import org.eclipse.emf.cdo.spi.common.id.AbstractCDOID; + +import org.eclipse.net4j.util.CheckUtil; +import org.eclipse.net4j.util.ObjectUtil; +import org.eclipse.net4j.util.ref.Interner; + +import java.io.IOException; /** * @author Eike Stepper + * @since 2.0 */ -public class CDOIDTempObjectImpl extends AbstractCDOIDInteger implements CDOIDTemp +public final class CDOIDTempObjectImpl extends AbstractCDOID implements CDOIDTemp { private static final long serialVersionUID = 1L; - public CDOIDTempObjectImpl(int value) + private static final IntInterner INTERNER = new IntInterner(); + + private final int value; + + private CDOIDTempObjectImpl(int value) { - super(value); + CheckUtil.checkArg(value != 0, "Zero not allowed"); + this.value = value; } - public Type getType() + public int getIntValue() { - return Type.TEMP_OBJECT; + return value; } - public boolean isDangling() + @Override + public void write(CDODataOutput out) throws IOException { - return false; + out.writeInt(value); } - public boolean isExternal() + public String toURIFragment() { - return false; + return String.valueOf(value); } - public boolean isNull() + public Type getType() + { + return Type.TEMP_OBJECT; + } + + public boolean isExternal() { return false; } @@ -57,14 +77,82 @@ public class CDOIDTempObjectImpl extends AbstractCDOIDInteger implements CDOIDTe } @Override + public int hashCode() + { + return ObjectUtil.hashCode(value); + } + + @Override public String toString() { - return "oid" + getIntValue(); //$NON-NLS-1$ + return "oid" + value; //$NON-NLS-1$ } @Override protected int doCompareTo(CDOID o) throws ClassCastException { - return new Integer(getIntValue()).compareTo(((CDOIDTempObjectImpl)o).getIntValue()); + CDOIDTempObjectImpl that = (CDOIDTempObjectImpl)o; + if (value < that.value) + { + return -1; + } + + if (value > that.value) + { + return 1; + } + + return 0; + } + + private static int getHashCode(int value) + { + return value; + } + + public static CDOIDTempObjectImpl create(int value) + { + return INTERNER.intern(value); + } + + public static CDOIDTempObjectImpl create(CDODataInput in) throws IOException + { + int value = in.readInt(); + return create(value); + } + + public static CDOIDTempObjectImpl create(String fragmentPart) + { + int value = Integer.parseInt(fragmentPart); + return create(value); + } + + /** + * @author Eike Stepper + */ + private static final class IntInterner extends Interner<CDOIDTempObjectImpl> + { + public synchronized CDOIDTempObjectImpl intern(int value) + { + int hashCode = getHashCode(value); + for (Entry<CDOIDTempObjectImpl> entry = getEntry(hashCode); entry != null; entry = entry.getNextEntry()) + { + CDOIDTempObjectImpl id = entry.get(); + if (id != null && id.value == value) + { + return id; + } + } + + CDOIDTempObjectImpl id = new CDOIDTempObjectImpl(value); + addEntry(createEntry(id, hashCode)); + return id; + } + + @Override + protected int hashCode(CDOIDTempObjectImpl id) + { + return getHashCode(id.value); + } } } |