Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2010-10-03 17:43:24 +0000
committerEike Stepper2010-10-03 17:43:24 +0000
commit28970a96cbd16c2ade77c0a1d7a339cf8e7400a7 (patch)
tree5824dcbd4db52b1478c0b8e47acfaa45872a3c47 /plugins/org.eclipse.emf.cdo.common/src
parenta91d414d00d86b12cea002dc06cbb75ea8f0327a (diff)
downloadcdo-28970a96cbd16c2ade77c0a1d7a339cf8e7400a7.tar.gz
cdo-28970a96cbd16c2ade77c0a1d7a339cf8e7400a7.tar.xz
cdo-28970a96cbd16c2ade77c0a1d7a339cf8e7400a7.zip
[284307] Add support for streaming of large byte arrays / BLOB
https://bugs.eclipse.org/bugs/show_bug.cgi?id=284307
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.common/src')
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOModelUtil.java63
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOType.java10
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOBlob.java57
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOClob.java57
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOLob.java65
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOLobInfo.java42
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOLobStore.java73
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOLobUtil.java57
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java11
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOTypeImpl.java55
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataInputImpl.java14
-rw-r--r--plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/model/CDOLobStoreImpl.java196
12 files changed, 692 insertions, 8 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOModelUtil.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOModelUtil.java
index 7022e2ac84..2be7589304 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOModelUtil.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOModelUtil.java
@@ -58,6 +58,11 @@ public final class CDOModelUtil
/**
* @since 2.0
*/
+ public static final String ROOT_CLASS_NAME = "EObject"; //$NON-NLS-1$
+
+ /**
+ * @since 2.0
+ */
public static final String RESOURCE_PACKAGE_URI = "http://www.eclipse.org/emf/CDO/Eresource/2.0.0"; //$NON-NLS-1$
/**
@@ -76,9 +81,19 @@ public final class CDOModelUtil
public static final String RESOURCE_CLASS_NAME = "CDOResource"; //$NON-NLS-1$
/**
- * @since 2.0
+ * @since 4.0
*/
- public static final String ROOT_CLASS_NAME = "EObject"; //$NON-NLS-1$
+ public static final String TYPES_PACKAGE_URI = "http://www.eclipse.org/emf/CDO/Etypes/4.0.0"; //$NON-NLS-1$
+
+ /**
+ * @since 4.0
+ */
+ public static final String BLOB_CLASS_NAME = "Blob"; //$NON-NLS-1$
+
+ /**
+ * @since 4.0
+ */
+ public static final String CLOB_CLASS_NAME = "Clob"; //$NON-NLS-1$
private static CDOType[] coreTypes;
@@ -137,6 +152,14 @@ public final class CDOModelUtil
/**
* @since 2.0
*/
+ public static boolean isRoot(EClass eClass)
+ {
+ return isCorePackage(eClass.getEPackage()) && ROOT_CLASS_NAME.equals(eClass.getName());
+ }
+
+ /**
+ * @since 2.0
+ */
public static boolean isResourcePackage(EPackage ePackage)
{
return RESOURCE_PACKAGE_URI.equals(ePackage.getNsURI());
@@ -177,11 +200,20 @@ public final class CDOModelUtil
}
/**
- * @since 2.0
+ * @since 4.0
*/
- public static boolean isRoot(EClass eClass)
+ public static boolean isTypesPackage(EPackage ePackage)
{
- return isCorePackage(eClass.getEPackage()) && ROOT_CLASS_NAME.equals(eClass.getName());
+ return TYPES_PACKAGE_URI.equals(ePackage.getNsURI());
+ }
+
+ /**
+ * @since 4.0
+ */
+ public static boolean isLob(EClassifier eClassifier)
+ {
+ return isTypesPackage(eClassifier.getEPackage())
+ && (BLOB_CLASS_NAME.equals(eClassifier.getName()) || CLOB_CLASS_NAME.equals(eClassifier.getName()));
}
/**
@@ -217,15 +249,32 @@ public final class CDOModelUtil
return CDOType.ENUM_ORDINAL;
}
- if (isCorePackage(classifier.getEPackage()))
+ EDataType eDataType = (EDataType)classifier;
+ EPackage ePackage = eDataType.getEPackage();
+
+ if (isCorePackage(ePackage))
{
- EDataType eDataType = (EDataType)classifier;
CDOType type = getCoreType(eDataType);
if (type != null)
{
return type;
}
}
+ else if (isTypesPackage(ePackage))
+ {
+ String name = eDataType.getName();
+ if (BLOB_CLASS_NAME.equals(name))
+ {
+ return CDOType.BLOB;
+ }
+
+ if (CLOB_CLASS_NAME.equals(name))
+ {
+ return CDOType.CLOB;
+ }
+
+ throw new IllegalArgumentException("Illegal data type: " + eDataType);
+ }
return CDOType.CUSTOM;
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOType.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOType.java
index 286067bc54..10df08d71d 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOType.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOType.java
@@ -90,6 +90,16 @@ public interface CDOType
*/
public static final CDOType ENUM_LITERAL = org.eclipse.emf.cdo.internal.common.model.CDOTypeImpl.ENUM_LITERAL;
+ /**
+ * @since 4.0
+ */
+ public static final CDOType BLOB = org.eclipse.emf.cdo.internal.common.model.CDOTypeImpl.BLOB;
+
+ /**
+ * @since 4.0
+ */
+ public static final CDOType CLOB = org.eclipse.emf.cdo.internal.common.model.CDOTypeImpl.CLOB;
+
public static final CDOType CUSTOM = org.eclipse.emf.cdo.internal.common.model.CDOTypeImpl.CUSTOM;
/**
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOBlob.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOBlob.java
new file mode 100644
index 0000000000..ca424d730a
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOBlob.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2004 - 2010 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.common.model.lob;
+
+import org.eclipse.emf.cdo.spi.common.model.CDOLobStoreImpl;
+
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * @author Eike Stepper
+ * @since 4.0
+ */
+public final class CDOBlob extends CDOLob<byte[], InputStream>
+{
+ public CDOBlob(InputStream contents) throws IOException
+ {
+ super(contents, CDOLobStoreImpl.INSTANCE);
+ }
+
+ public CDOBlob(InputStream contents, CDOLobStore store) throws IOException
+ {
+ super(contents, store);
+ }
+
+ CDOBlob(byte[] id, long size)
+ {
+ super(id, size);
+ }
+
+ CDOBlob(ExtendedDataInput in) throws IOException
+ {
+ super(in);
+ }
+
+ @Override
+ public InputStream getContents() throws IOException
+ {
+ return getStore().getBinary(this);
+ }
+
+ @Override
+ protected CDOLobInfo put(InputStream contents) throws IOException
+ {
+ return getStore().putBinary(contents);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOClob.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOClob.java
new file mode 100644
index 0000000000..18ebb65c68
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOClob.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2004 - 2010 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.common.model.lob;
+
+import org.eclipse.emf.cdo.spi.common.model.CDOLobStoreImpl;
+
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * @author Eike Stepper
+ * @since 4.0
+ */
+public final class CDOClob extends CDOLob<char[], Reader>
+{
+ public CDOClob(Reader contents) throws IOException
+ {
+ super(contents, CDOLobStoreImpl.INSTANCE);
+ }
+
+ public CDOClob(Reader contents, CDOLobStore store) throws IOException
+ {
+ super(contents, store);
+ }
+
+ CDOClob(byte[] id, long size)
+ {
+ super(id, size);
+ }
+
+ CDOClob(ExtendedDataInput in) throws IOException
+ {
+ super(in);
+ }
+
+ @Override
+ public Reader getContents() throws IOException
+ {
+ return getStore().getCharacter(this);
+ }
+
+ @Override
+ protected CDOLobInfo put(Reader contents) throws IOException
+ {
+ return getStore().putCharacter(contents);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOLob.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOLob.java
new file mode 100644
index 0000000000..538fa6ef9c
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOLob.java
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2004 - 2010 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.common.model.lob;
+
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+import org.eclipse.net4j.util.io.ExtendedDataOutput;
+
+import java.io.IOException;
+
+/**
+ * @author Eike Stepper
+ * @since 4.0
+ */
+public abstract class CDOLob<ARRAY, IO> extends CDOLobInfo
+{
+ private CDOLobStore store;
+
+ CDOLob(byte[] id, long size)
+ {
+ this.id = id;
+ this.size = size;
+ }
+
+ CDOLob(IO contents, CDOLobStore store) throws IOException
+ {
+ this.store = store;
+ CDOLobInfo info = put(contents);
+ id = info.getID();
+ size = info.getSize();
+ }
+
+ CDOLob(ExtendedDataInput in) throws IOException
+ {
+ id = in.readByteArray();
+ size = in.readLong();
+ }
+
+ final void write(ExtendedDataOutput out) throws IOException
+ {
+ out.writeByteArray(id);
+ out.writeLong(size);
+ }
+
+ final void setStore(CDOLobStore store)
+ {
+ this.store = store;
+ }
+
+ public final CDOLobStore getStore()
+ {
+ return store;
+ }
+
+ public abstract IO getContents() throws IOException;
+
+ protected abstract CDOLobInfo put(IO contents) throws IOException;
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOLobInfo.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOLobInfo.java
new file mode 100644
index 0000000000..e892626a47
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOLobInfo.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2004 - 2010 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.common.model.lob;
+
+/**
+ * @author Eike Stepper
+ * @since 4.0
+ */
+public class CDOLobInfo
+{
+ byte[] id;
+
+ long size;
+
+ CDOLobInfo()
+ {
+ }
+
+ public CDOLobInfo(byte[] id, long size)
+ {
+ this.id = id;
+ this.size = size;
+ }
+
+ public final byte[] getID()
+ {
+ return id;
+ }
+
+ public final long getSize()
+ {
+ return size;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOLobStore.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOLobStore.java
new file mode 100644
index 0000000000..a8c7a6b613
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOLobStore.java
@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2004 - 2010 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.common.model.lob;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+/**
+ * @author Eike Stepper
+ * @since 4.0
+ */
+public interface CDOLobStore
+{
+ public File getBinaryFile(byte[] id);
+
+ public InputStream getBinary(CDOLobInfo info) throws IOException;
+
+ public CDOLobInfo putBinary(InputStream contents) throws IOException;
+
+ public File getCharacterFile(byte[] id);
+
+ public Reader getCharacter(CDOLobInfo info) throws IOException;
+
+ public CDOLobInfo putCharacter(Reader contents) throws IOException;
+
+ /**
+ * @author Eike Stepper
+ */
+ public static abstract class Delegating implements CDOLobStore
+ {
+ public File getBinaryFile(byte[] id)
+ {
+ return getDelegate().getBinaryFile(id);
+ }
+
+ public InputStream getBinary(CDOLobInfo info) throws IOException
+ {
+ return getDelegate().getBinary(info);
+ }
+
+ public CDOLobInfo putBinary(InputStream contents) throws IOException
+ {
+ return getDelegate().putBinary(contents);
+ }
+
+ public File getCharacterFile(byte[] id)
+ {
+ return getDelegate().getCharacterFile(id);
+ }
+
+ public Reader getCharacter(CDOLobInfo info) throws IOException
+ {
+ return getDelegate().getCharacter(info);
+ }
+
+ public CDOLobInfo putCharacter(Reader contents) throws IOException
+ {
+ return getDelegate().putCharacter(contents);
+ }
+
+ protected abstract CDOLobStore getDelegate();
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOLobUtil.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOLobUtil.java
new file mode 100644
index 0000000000..774534e471
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/lob/CDOLobUtil.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2004 - 2010 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.common.model.lob;
+
+import org.eclipse.net4j.util.io.ExtendedDataInput;
+import org.eclipse.net4j.util.io.ExtendedDataOutput;
+
+import java.io.IOException;
+
+/**
+ * @author Eike Stepper
+ * @since 4.0
+ */
+public final class CDOLobUtil
+{
+ private CDOLobUtil()
+ {
+ }
+
+ public static CDOBlob readBlob(ExtendedDataInput in) throws IOException
+ {
+ return new CDOBlob(in);
+ }
+
+ public static CDOClob readClob(ExtendedDataInput in) throws IOException
+ {
+ return new CDOClob(in);
+ }
+
+ public static void write(ExtendedDataOutput out, CDOLob<?, ?> lob) throws IOException
+ {
+ lob.write(out);
+ }
+
+ public static CDOBlob createBlob(byte[] id, long size)
+ {
+ return new CDOBlob(id, size);
+ }
+
+ public static CDOClob createClob(byte[] id, long size)
+ {
+ return new CDOClob(id, size);
+ }
+
+ public static void setStore(CDOLobStore store, CDOLob<?, ?> lob) throws IOException
+ {
+ lob.setStore(store);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java
index bf2ce437b9..89abb5bd13 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/protocol/CDOProtocolConstants.java
@@ -194,8 +194,19 @@ public interface CDOProtocolConstants
*/
public static final short SIGNAL_LOAD_MERGE_DATA = 44;
+ /**
+ * @since 4.0
+ */
+ public static final short SIGNAL_QUERY_LOBS = 45;
+
+ /**
+ * @since 4.0
+ */
+ public static final short SIGNAL_LOAD_LOB = 46;
+
// //////////////////////////////////////////////////////////////////////
// Session Refresh
+
/**
* @since 3.0
*/
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
index 80fe047874..4b252a743a 100644
--- 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
@@ -14,6 +14,9 @@ package org.eclipse.emf.cdo.internal.common.model;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.model.CDOModelUtil;
import org.eclipse.emf.cdo.common.model.CDOType;
+import org.eclipse.emf.cdo.common.model.lob.CDOBlob;
+import org.eclipse.emf.cdo.common.model.lob.CDOClob;
+import org.eclipse.emf.cdo.common.model.lob.CDOLobUtil;
import org.eclipse.emf.cdo.common.protocol.CDODataInput;
import org.eclipse.emf.cdo.common.protocol.CDODataOutput;
import org.eclipse.emf.cdo.common.revision.CDOReferenceAdjuster;
@@ -568,6 +571,58 @@ public abstract class CDOTypeImpl implements CDOType
}
};
+ public static final CDOType BLOB = new CDOTypeImpl("BLOB", 2004, true) //$NON-NLS-1$
+ {
+ public CDOBlob readValue(CDODataInput in) throws IOException
+ {
+ if (in.readBoolean())
+ {
+ return CDOLobUtil.readBlob(in);
+ }
+
+ return null;
+ }
+
+ public void writeValue(CDODataOutput out, Object value) throws IOException
+ {
+ if (value != null)
+ {
+ out.writeBoolean(true);
+ CDOLobUtil.write(out, (CDOBlob)value);
+ }
+ else
+ {
+ out.writeBoolean(false);
+ }
+ }
+ };
+
+ public static final CDOType CLOB = new CDOTypeImpl("CLOB", 2005, true) //$NON-NLS-1$
+ {
+ public CDOClob readValue(CDODataInput in) throws IOException
+ {
+ if (in.readBoolean())
+ {
+ return CDOLobUtil.readClob(in);
+ }
+
+ return null;
+ }
+
+ public void writeValue(CDODataOutput out, Object value) throws IOException
+ {
+ if (value != null)
+ {
+ out.writeBoolean(true);
+ CDOLobUtil.write(out, (CDOClob)value);
+ }
+ else
+ {
+ out.writeBoolean(false);
+ }
+ }
+ };
+
public static final CDOType CUSTOM = new CDOTypeImpl("CUSTOM", 999, true) //$NON-NLS-1$
{
@Override
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataInputImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataInputImpl.java
index ee2764cc15..08b0bdd830 100644
--- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataInputImpl.java
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/protocol/CDODataInputImpl.java
@@ -31,6 +31,9 @@ import org.eclipse.emf.cdo.common.model.CDOPackageInfo;
import org.eclipse.emf.cdo.common.model.CDOPackageRegistry;
import org.eclipse.emf.cdo.common.model.CDOPackageUnit;
import org.eclipse.emf.cdo.common.model.CDOType;
+import org.eclipse.emf.cdo.common.model.lob.CDOLob;
+import org.eclipse.emf.cdo.common.model.lob.CDOLobStore;
+import org.eclipse.emf.cdo.common.model.lob.CDOLobUtil;
import org.eclipse.emf.cdo.common.protocol.CDODataInput;
import org.eclipse.emf.cdo.common.revision.CDOList;
import org.eclipse.emf.cdo.common.revision.CDOListFactory;
@@ -439,7 +442,14 @@ public abstract class CDODataInputImpl extends ExtendedDataInput.Delegating impl
public Object readCDOFeatureValue(EStructuralFeature feature) throws IOException
{
CDOType type = CDOModelUtil.getType(feature);
- return type.readValue(this);
+ Object value = type.readValue(this);
+ if (value instanceof CDOLob<?, ?>)
+ {
+ CDOLob<?, ?> lob = (CDOLob<?, ?>)value;
+ CDOLobUtil.setStore(getLobStore(), lob);
+ }
+
+ return value;
}
public CDORevisionDelta readCDORevisionDelta() throws IOException
@@ -518,4 +528,6 @@ public abstract class CDODataInputImpl extends ExtendedDataInput.Delegating impl
protected abstract CDORevisionFactory getRevisionFactory();
protected abstract CDOListFactory getListFactory();
+
+ protected abstract CDOLobStore getLobStore();
}
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/model/CDOLobStoreImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/model/CDOLobStoreImpl.java
new file mode 100644
index 0000000000..9b24e3f670
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/model/CDOLobStoreImpl.java
@@ -0,0 +1,196 @@
+/**
+ * Copyright (c) 2004 - 2010 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.spi.common.model;
+
+import org.eclipse.emf.cdo.common.model.lob.CDOLobInfo;
+import org.eclipse.emf.cdo.common.model.lob.CDOLobStore;
+
+import org.eclipse.net4j.util.HexUtil;
+import org.eclipse.net4j.util.WrappedException;
+import org.eclipse.net4j.util.io.DigestWriter;
+import org.eclipse.net4j.util.io.ExpectedFileInputStream;
+import org.eclipse.net4j.util.io.IORuntimeException;
+import org.eclipse.net4j.util.io.IOUtil;
+import org.eclipse.net4j.util.om.OMPlatform;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.security.DigestOutputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * @author Eike Stepper
+ * @since 4.0
+ */
+public class CDOLobStoreImpl implements CDOLobStore
+{
+ public static final CDOLobStoreImpl INSTANCE = new CDOLobStoreImpl();
+
+ private File folder;
+
+ private int tempID;
+
+ public CDOLobStoreImpl(File folder)
+ {
+ this.folder = folder;
+ if (!folder.exists())
+ {
+ folder.mkdirs();
+ if (!folder.exists())
+ {
+ throw new IORuntimeException("Folder could not be created: " + folder);
+ }
+
+ if (!folder.isDirectory())
+ {
+ throw new IORuntimeException("Not a folder: " + folder);
+ }
+ }
+ }
+
+ public CDOLobStoreImpl()
+ {
+ this(getDefaultFolder());
+ }
+
+ public File getFolder()
+ {
+ return folder;
+ }
+
+ public File getBinaryFile(byte[] id)
+ {
+ return new File(folder, HexUtil.bytesToHex(id) + ".blob");
+ }
+
+ public InputStream getBinary(CDOLobInfo info) throws IOException
+ {
+ File file = getBinaryFile(info.getID());
+ long expectedSize = info.getSize();
+
+ // if (file.length() >= expectedSize)
+ // {
+ // return new FileInputStream(file);
+ // }
+
+ return new ExpectedFileInputStream(file, expectedSize);
+ }
+
+ public CDOLobInfo putBinary(InputStream contents) throws IOException
+ {
+ File tempFile = getTempFile();
+ MessageDigest digest = createDigest();
+ digest.update("BINARY".getBytes());
+
+ FileOutputStream fos = null;
+ long size;
+
+ try
+ {
+ fos = new FileOutputStream(tempFile);
+ DigestOutputStream dos = new DigestOutputStream(fos, digest);
+ size = IOUtil.copyBinary(contents, dos);
+ }
+ finally
+ {
+ IOUtil.close(fos);
+ }
+
+ byte[] id = digest.digest();
+ makePermanent(tempFile, getBinaryFile(id));
+ return new CDOLobInfo(id, size);
+ }
+
+ public File getCharacterFile(byte[] id)
+ {
+ return new File(folder, HexUtil.bytesToHex(id) + ".clob");
+ }
+
+ public Reader getCharacter(CDOLobInfo info) throws IOException
+ {
+ File file = getCharacterFile(info.getID());
+ return new FileReader(file);
+ }
+
+ public CDOLobInfo putCharacter(Reader contents) throws IOException
+ {
+ File tempFile = getTempFile();
+ MessageDigest digest = createDigest();
+ digest.update("CHARACTER".getBytes());
+
+ FileWriter fw = null;
+ long size;
+
+ try
+ {
+ fw = new FileWriter(tempFile);
+ DigestWriter dw = new DigestWriter(fw, digest);
+ size = IOUtil.copyCharacter(contents, dw);
+ }
+ finally
+ {
+ IOUtil.close(fw);
+ }
+
+ byte[] id = digest.digest();
+ makePermanent(tempFile, getCharacterFile(id));
+ return new CDOLobInfo(id, size);
+ }
+
+ protected MessageDigest createDigest()
+ {
+ try
+ {
+ return MessageDigest.getInstance("SHA-1");
+ }
+ catch (NoSuchAlgorithmException ex)
+ {
+ throw WrappedException.wrap(ex);
+ }
+ }
+
+ protected synchronized File getTempFile()
+ {
+ for (;;)
+ {
+ ++tempID;
+ File file = new File(folder, "contents" + tempID + ".tmp");
+ if (!file.exists())
+ {
+ return file;
+ }
+ }
+ }
+
+ private void makePermanent(File tempFile, File file)
+ {
+ if (file.exists())
+ {
+ tempFile.delete();
+ }
+ else
+ {
+ tempFile.renameTo(file);
+ }
+ }
+
+ private static File getDefaultFolder()
+ {
+ String path = OMPlatform.INSTANCE.getProperty("java.io.tmpdir");
+ return new File(new File(path), "cdolobs");
+ }
+}

Back to the top