Author: tolusha
Date: 2009-12-11 09:21:29 -0500 (Fri, 11 Dec 2009)
New Revision: 1006
Modified:
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/value/BinaryValue.java
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/EditableValueData.java
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/PersistedValueData.java
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ByteArrayPersistedValueData.java
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/FileStreamPersistedValueData.java
Log:
EXOJCR-300: bugfix
Modified:
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/value/BinaryValue.java
===================================================================
---
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/value/BinaryValue.java 2009-12-11
13:04:44 UTC (rev 1005)
+++
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/value/BinaryValue.java 2009-12-11
14:21:29 UTC (rev 1006)
@@ -21,12 +21,14 @@
import org.exoplatform.services.jcr.core.value.EditableBinaryValue;
import org.exoplatform.services.jcr.datamodel.ValueData;
import org.exoplatform.services.jcr.impl.dataflow.EditableValueData;
+import org.exoplatform.services.jcr.impl.dataflow.PersistedValueData;
import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@@ -85,11 +87,10 @@
}
/** used in ValueFactory.loadValue */
- BinaryValue(ValueData data, FileCleaner fileCleaner, File tempDirectory, int
maxFufferSize)
- throws IOException
+ BinaryValue(ValueData data, FileCleaner fileCleaner, File tempDirectory, int
maxFufferSize) throws IOException
{
super(TYPE, data);
-
+
// TODO
//internalData.setFileCleaner(fileCleaner);
//internalData.setTempDirectory(tempDirectory);
@@ -137,15 +138,22 @@
* */
public void update(InputStream stream, long length, long position) throws IOException,
RepositoryException
{
- // TODO impl it
-// if (changedData == null)
-// {
-// changedData = this.getInternalData().createEditableCopy();
-// }
-//
-// this.changedData.update(stream, length, position);
-//
-// this.changed = true;
+ // if (changedData == null)
+ // {
+ // ValueData internalData = this.getInternalData();
+ //
+ // if (internalData instanceof TransientValueData)
+ // {
+ // changedData =
((TransientValueData)internalData).createEditableCopy();
+ // }
+ // else
+ // {
+ // changedData =
((PersistedValueData)internalData).createTransientCopy();
+ // }
+ // }
+ //
+ // this.changedData.update(stream, length, position);
+ // this.changed = true;
}
/**
@@ -156,16 +164,61 @@
*/
public void setLength(long size) throws IOException, RepositoryException
{
-
- // TODO impl it
-// if (changedData == null)
-// {
-// changedData = this.getInternalData().createEditableCopy();
-// }
-//
-// this.changedData.setLength(size);
-//
-// this.changed = true;
+ // if (changedData == null)
+ // {
+ // changedData =
((TransientValueData)this.getInternalData()).createEditableCopy();
+ // }
+ //
+ // this.changedData.setLength(size);
+ // this.changed = true;
}
+ /**
+ * Create editable ValueData copy.
+ *
+ * @return EditableValueData
+ * @throws RepositoryException
+ * if error occurs
+ * @throws IOException
+ * @throws IllegalStateException
+ */
+ private EditableValueData createEditableCopy(ValueData oldValue) throws
RepositoryException, IllegalStateException,
+ IOException
+ {
+ if (oldValue.isByteArray())
+ {
+ // bytes, make a copy of real data
+ byte[] oldBytes = oldValue.getAsByteArray();
+ byte[] newBytes = new byte[oldBytes.length];
+ System.arraycopy(oldBytes, 0, newBytes, 0, newBytes.length);
+
+ try
+ {
+ return new EditableValueData(newBytes, oldValue.getOrderNumber(), null, -1,
null);
+ }
+ catch (IOException e)
+ {
+ throw new RepositoryException(e);
+ }
+ }
+ else
+ {
+ // edited BLOB file, make a copy
+ try
+ {
+ EditableValueData copy =
+ new EditableValueData(oldValue.getAsStream(), oldValue.getOrderNumber(),
null, -1, null);
+ return copy;
+ }
+ catch (FileNotFoundException e)
+ {
+ throw new RepositoryException("Create transient copy error. " + e,
e);
+ }
+ catch (IOException e)
+ {
+ throw new RepositoryException("Create transient copy error. " + e,
e);
+ }
+ }
+ }
+
}
Modified:
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/EditableValueData.java
===================================================================
---
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/EditableValueData.java 2009-12-11
13:04:44 UTC (rev 1005)
+++
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/EditableValueData.java 2009-12-11
14:21:29 UTC (rev 1006)
@@ -40,7 +40,7 @@
{
protected final static Log LOG =
ExoLogger.getLogger("jcr.EditableValueData");
-
+
protected final int maxIOBuffSize;
public EditableValueData(byte[] bytes, int orderNumber, FileCleaner fileCleaner, int
maxBufferSize,
@@ -111,6 +111,61 @@
this.spooled = true;
}
+ public EditableValueData(InputStream stream, int orderNumber, FileCleaner fileCleaner,
int maxBufferSize,
+ File tempDirectory) throws IOException
+ {
+
+ // don't send any data there (no stream, no bytes)
+ super(orderNumber, null, null, null, fileCleaner, maxBufferSize, tempDirectory,
true);
+
+ this.maxIOBuffSize = calcMaxIOSize();
+
+ File sf = null;
+ FileChannel sch = null;
+ try
+ {
+ sf = File.createTempFile("jcrvdedit", null, tempDirectory);
+
+ sch = new RandomAccessFile(sf, "rw").getChannel();
+
+ FileChannel sourceCh = new FileInputStream(spoolFile).getChannel();
+ try
+ {
+ sch.transferFrom(sourceCh, 0, sourceCh.size());
+ }
+ finally
+ {
+ sourceCh.close();
+ }
+ }
+ catch (final IOException e)
+ {
+ try
+ {
+ sch.close();
+ sf.delete();
+ }
+ catch (Exception e1)
+ {
+ }
+ throw new IOException("init error " + e.getMessage())
+ {
+ @Override
+ public Throwable getCause()
+ {
+ return e;
+ }
+ };
+ }
+
+ this.data = null;
+
+ this.spoolFile = sf;
+ this.spoolChannel = sch;
+
+ this.spooled = true;
+ }
+
protected int calcMaxIOSize()
{
return maxBufferSize < 1024 ? 1024 : maxBufferSize < (250 * 1024) ?
maxBufferSize : 250 * 1024;
Modified:
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/PersistedValueData.java
===================================================================
---
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/PersistedValueData.java 2009-12-11
13:04:44 UTC (rev 1005)
+++
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/PersistedValueData.java 2009-12-11
14:21:29 UTC (rev 1006)
@@ -32,7 +32,7 @@
{
protected final static Log LOG =
ExoLogger.getLogger("jcr.PersistedValueData");
-
+
protected int orderNumber;
protected PersistedValueData(int orderNumber)
Modified:
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ByteArrayPersistedValueData.java
===================================================================
---
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ByteArrayPersistedValueData.java 2009-12-11
13:04:44 UTC (rev 1005)
+++
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/ByteArrayPersistedValueData.java 2009-12-11
14:21:29 UTC (rev 1006)
@@ -19,6 +19,7 @@
package org.exoplatform.services.jcr.impl.dataflow.persistent;
import org.exoplatform.services.jcr.datamodel.ValueData;
+import org.exoplatform.services.jcr.impl.dataflow.EditableValueData;
import org.exoplatform.services.jcr.impl.dataflow.PersistedValueData;
import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
import org.exoplatform.services.log.ExoLogger;
@@ -162,4 +163,5 @@
throw new RepositoryException(e);
}
}
+
}
Modified:
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/FileStreamPersistedValueData.java
===================================================================
---
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/FileStreamPersistedValueData.java 2009-12-11
13:04:44 UTC (rev 1005)
+++
jcr/branches/1.12.0-OPT/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/FileStreamPersistedValueData.java 2009-12-11
14:21:29 UTC (rev 1006)
@@ -22,12 +22,14 @@
import org.exoplatform.services.jcr.impl.dataflow.PersistedValueData;
import org.exoplatform.services.jcr.impl.dataflow.TransientValueData;
+import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
@@ -77,11 +79,11 @@
/**
* {@inheritDoc}
+ * @throws IOException
*/
- public byte[] getAsByteArray() throws IllegalStateException
+ public byte[] getAsByteArray() throws IllegalStateException, IOException
{
- throw new IllegalStateException(
- "It is illegal to call on FileStreamPersistedValueData due to potential
lack of memory");
+ return fileToByteArray();
}
/**
@@ -193,4 +195,36 @@
throw new RepositoryException(e);
}
}
+
+ /**
+ * Convert File to byte array. <br/>
+ * WARNING: Potential lack of memory due to call getAsByteArray() on stream data.
+ *
+ * @return byte[] bytes array
+ */
+ private byte[] fileToByteArray() throws IOException
+ {
+ FileChannel fch = new FileInputStream(file).getChannel();
+
+ try
+ {
+ ByteBuffer bb = ByteBuffer.allocate((int)fch.size());
+ fch.read(bb);
+ if (bb.hasArray())
+ {
+ return bb.array();
+ }
+ else
+ {
+ // impossible code in most cases, as we use heap backed buffer
+ byte[] tmpb = new byte[bb.capacity()];
+ bb.get(tmpb);
+ return tmpb;
+ }
+ }
+ finally
+ {
+ fch.close();
+ }
+ }
}