You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by st...@apache.org on 2005/11/16 16:27:28 UTC
svn commit: r345037 - in
/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit:
core/xml/DocViewImportHandler.java core/xml/SessionImporter.java
core/xml/WorkspaceImporter.java value/ValueHelper.java
Author: stefan
Date: Wed Nov 16 07:27:23 2005
New Revision: 345037
URL: http://svn.apache.org/viewcvs?rev=345037&view=rev
Log:
improved handling of (potentially large) binary data on import
Modified:
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewImportHandler.java
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/SessionImporter.java
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java
incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/value/ValueHelper.java
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewImportHandler.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewImportHandler.java?rev=345037&r1=345036&r2=345037&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewImportHandler.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/DocViewImportHandler.java Wed Nov 16 07:27:23 2005
@@ -27,6 +27,7 @@
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import java.io.IOException;
+import java.io.Reader;
import java.util.ArrayList;
import java.util.Stack;
@@ -99,14 +100,25 @@
// there is character data that needs to be added to
// the current node
- String text = textHandler.retrieve();
- if (text.trim().length() == 0) {
- // ignore whitespace-only character data
- log.debug("ignoring whitespace character data: " + text);
- // reset handler
- textHandler.dispose();
- textHandler = null;
- return;
+ // check for pure whitespace character data
+ Reader reader = textHandler.reader();
+ try {
+ int ch;
+ while ((ch = reader.read()) != -1) {
+ if (ch > 0x20) {
+ break;
+ }
+ }
+ if (ch == -1) {
+ // the character data consists of pure whitespace, ignore
+ log.debug("ignoring pure whitespace character data...");
+ // reset handler
+ textHandler.dispose();
+ textHandler = null;
+ return;
+ }
+ } finally {
+ reader.close();
}
Importer.NodeInfo node =
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/SessionImporter.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/SessionImporter.java?rev=345037&r1=345036&r2=345037&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/SessionImporter.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/SessionImporter.java Wed Nov 16 07:27:23 2005
@@ -322,10 +322,19 @@
// session's namespace mappings
va[i] = ival.toJCRValue(session.getNamespaceResolver());
} else if (targetType == PropertyType.BINARY) {
- // deserialize BINARY type using Reader
try {
- Reader reader = tv.reader();
- va[i] = ValueHelper.deserialize(reader, targetType, false);
+ if (tv.length() < 0x10000) {
+ // < 65kb: deserialize BINARY type using String
+ va[i] = ValueHelper.deserialize(tv.retrieve(), targetType, false);
+ } else {
+ // >= 65kb: deserialize BINARY type using Reader
+ Reader reader = tv.reader();
+ try {
+ va[i] = ValueHelper.deserialize(reader, targetType, false);
+ } finally {
+ reader.close();
+ }
+ }
} catch (IOException ioe) {
String msg = "failed to deserialize binary value";
log.debug(msg, ioe);
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java?rev=345037&r1=345036&r2=345037&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/xml/WorkspaceImporter.java Wed Nov 16 07:27:23 2005
@@ -22,7 +22,6 @@
import org.apache.jackrabbit.core.PropertyId;
import org.apache.jackrabbit.core.SessionImpl;
import org.apache.jackrabbit.core.WorkspaceImpl;
-import org.apache.jackrabbit.core.version.VersionManager;
import org.apache.jackrabbit.core.nodetype.EffectiveNodeType;
import org.apache.jackrabbit.core.nodetype.NodeDef;
import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
@@ -32,11 +31,13 @@
import org.apache.jackrabbit.core.state.PropertyState;
import org.apache.jackrabbit.core.util.ReferenceChangeTracker;
import org.apache.jackrabbit.core.value.InternalValue;
+import org.apache.jackrabbit.core.version.VersionManager;
import org.apache.jackrabbit.name.MalformedPathException;
import org.apache.jackrabbit.name.NamespaceResolver;
import org.apache.jackrabbit.name.Path;
import org.apache.jackrabbit.name.QName;
import org.apache.jackrabbit.util.Base64;
+import org.apache.jackrabbit.util.TransientFileFactory;
import org.apache.jackrabbit.uuid.UUID;
import org.apache.log4j.Logger;
@@ -50,9 +51,11 @@
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.version.VersionException;
import javax.jcr.version.VersionHistory;
-import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.Reader;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
@@ -573,34 +576,29 @@
if (targetType == PropertyType.BINARY) {
// base64 encoded BINARY type;
// decode using Reader
-/*
- // @todo decode to temp file and pass FileInputStream to InternalValue factory method
- File tmpFile = null;
try {
- tmpFile = File.createTempFile("bin", null);
- FileOutputStream out = new FileOutputStream(tmpFile);
- Base64.decode(tv.reader(), out);
- out.close();
- iva[i] = InternalValue.create(new FileInputStream(tmpFile));
- } catch (IOException ioe) {
- String msg = "failed to decode binary value";
- log.debug(msg, ioe);
- throw new RepositoryException(msg, ioe);
- } finally {
- // the temp file can be deleted because
- // the InternalValue instance has spooled
- // its contents
- if (tmpFile != null) {
- tmpFile.delete();
+ if (tv.length() < 0x10000) {
+ // < 65kb: deserialize BINARY type in memory
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ Base64.decode(tv.retrieve(), baos);
+ // no need to close ByteArrayOutputStream
+ //baos.close();
+ iva[i] = InternalValue.create(baos.toByteArray());
+ } else {
+ // >= 65kb: deserialize BINARY type
+ // using Reader and temporay file
+ TransientFileFactory fileFactory = TransientFileFactory.getInstance();
+ File tmpFile = fileFactory.createTransientFile("bin", null, null);
+ FileOutputStream out = new FileOutputStream(tmpFile);
+ Reader reader = tv.reader();
+ try {
+ Base64.decode(reader, out);
+ } finally {
+ reader.close();
+ out.close();
+ }
+ iva[i] = InternalValue.create(tmpFile);
}
- }
-*/
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- try {
- Base64.decode(tv.reader(), baos);
- // no need to close ByteArrayOutputStream
- //baos.close();
- iva[i] = InternalValue.create(new ByteArrayInputStream(baos.toByteArray()));
} catch (IOException ioe) {
String msg = "failed to decode binary value";
log.debug(msg, ioe);
Modified: incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/value/ValueHelper.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/value/ValueHelper.java?rev=345037&r1=345036&r2=345037&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/value/ValueHelper.java (original)
+++ incubator/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/value/ValueHelper.java Wed Nov 16 07:27:23 2005
@@ -22,6 +22,7 @@
import org.apache.jackrabbit.name.QName;
import org.apache.jackrabbit.util.Base64;
import org.apache.jackrabbit.util.Text;
+import org.apache.jackrabbit.util.TransientFileFactory;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
@@ -33,6 +34,9 @@
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileInputStream;
/**
* The <code>ValueHelper</code> class provides several <code>Value</code>
@@ -50,7 +54,7 @@
* @param srcValue
* @param targetType
* @return
- * @throws javax.jcr.ValueFormatException
+ * @throws ValueFormatException
* @throws IllegalArgumentException
*/
public static Value convert(String srcValue, int targetType)
@@ -66,7 +70,7 @@
* @param srcValues
* @param targetType
* @return
- * @throws javax.jcr.ValueFormatException
+ * @throws ValueFormatException
* @throws IllegalArgumentException
*/
public static Value[] convert(String[] srcValues, int targetType)
@@ -85,7 +89,7 @@
* @param srcValues
* @param targetType
* @return
- * @throws javax.jcr.ValueFormatException
+ * @throws ValueFormatException
* @throws IllegalArgumentException
*/
public static Value[] convert(Value[] srcValues, int targetType)
@@ -119,7 +123,7 @@
* @param srcValue
* @param targetType
* @return
- * @throws javax.jcr.ValueFormatException
+ * @throws ValueFormatException
* @throws IllegalStateException
* @throws IllegalArgumentException
*/
@@ -417,14 +421,14 @@
* Serializes the given value to a <code>String</code>. The serialization
* format is the same as used by Document & System View XML, i.e.
* binary values will be Base64-encoded whereas for all others
- * <code>{@link javax.jcr.Value#getString()}</code> will be used.
+ * <code>{@link Value#getString()}</code> will be used.
*
* @param value the value to be serialized
* @param encodeBlanks if <code>true</code> space characters will be encoded
* as <code>"_x0020_"</code> within he output string.
* @return a string representation of the given value.
* @throws IllegalStateException if the given value is in an illegal state
- * @throws javax.jcr.RepositoryException if an error occured during the serialization.
+ * @throws RepositoryException if an error occured during the serialization.
*/
public static String serialize(Value value, boolean encodeBlanks)
throws IllegalStateException, RepositoryException {
@@ -442,17 +446,16 @@
* Outputs the serialized value to a <code>Writer</code>. The serialization
* format is the same as used by Document & System View XML, i.e.
* binary values will be Base64-encoded whereas for all others
- * <code>{@link javax.jcr.Value#getString()}</code> will be used for
- * serialization.
+ * <code>{@link Value#getString()}</code> will be used for serialization.
*
* @param value the value to be serialized
* @param encodeBlanks if <code>true</code> space characters will be encoded
* as <code>"_x0020_"</code> within he output string.
* @param writer writer to output the encoded data
* @throws IllegalStateException if the given value is in an illegal state
- * @throws java.io.IOException if an i/o error occured during the
+ * @throws IOException if an i/o error occured during the
* serialization
- * @throws javax.jcr.RepositoryException if an error occured during the serialization.
+ * @throws RepositoryException if an error occured during the serialization.
*/
public static void serialize(Value value, boolean encodeBlanks,
Writer writer)
@@ -492,9 +495,9 @@
* character sequences will be decoded to single space
* characters each.
* @return the deserialized <code>Value</code>
- * @throws javax.jcr.ValueFormatException if the string data is not of the required
+ * @throws ValueFormatException if the string data is not of the required
* format
- * @throws javax.jcr.RepositoryException if an error occured during the
+ * @throws RepositoryException if an error occured during the
* deserialization.
*/
public static Value deserialize(String value, int type,
@@ -533,11 +536,11 @@
* character sequences will be decoded to single space
* characters each.
* @return the deserialized <code>Value</code>
- * @throws java.io.IOException if an i/o error occured during the
+ * @throws IOException if an i/o error occured during the
* serialization
- * @throws javax.jcr.ValueFormatException if the string data is not of the required
+ * @throws ValueFormatException if the string data is not of the required
* format
- * @throws javax.jcr.RepositoryException if an error occured during the
+ * @throws RepositoryException if an error occured during the
* deserialization.
*/
public static Value deserialize(Reader reader, int type,
@@ -547,20 +550,63 @@
// base64 encoded binary value;
// the encodeBlanks flag can be ignored since base64-encoded
// data cannot contain encoded space characters
-/*
- // @todo decode to temp file and pass FileInputStream to BinaryValue constructor
- File tmpFile = File.createTempFile("bin", null);
+
+ // decode to temp file
+ TransientFileFactory fileFactory = TransientFileFactory.getInstance();
+ final File tmpFile = fileFactory.createTransientFile("bin", null, null);
FileOutputStream out = new FileOutputStream(tmpFile);
- tmpFile.deleteOnExit();
- Base64.decode(reader, out);
- out.close();
- return new BinaryValue(new FileInputStream(tmpFile));
-*/
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- Base64.decode(reader, baos);
- // no need to close ByteArrayOutputStream
- //baos.close();
- return new BinaryValue(baos.toByteArray());
+ try {
+ Base64.decode(reader, out);
+ } finally {
+ out.close();
+ }
+
+ // create an InputStream that keeps a hard reference to the temp file
+ // in order to prevent its automatic deletion once the associated
+ // File object is reclaimed by the garbage collector;
+ // pass InputStream to BinaryValue constructor
+ return new BinaryValue(new InputStream() {
+ File f = tmpFile;
+ InputStream in = new FileInputStream(f);
+
+ public int available() throws IOException {
+ return in.available();
+ }
+
+ public void close() throws IOException {
+ in.close();
+ // now it's safe to prepare temp file to be gc'ed
+ f = null;
+ }
+
+ public synchronized void mark(int readlimit) {
+ in.mark(readlimit);
+ }
+
+ public boolean markSupported() {
+ return in.markSupported();
+ }
+
+ public int read(byte b[]) throws IOException {
+ return in.read(b);
+ }
+
+ public int read(byte b[], int off, int len) throws IOException {
+ return in.read(b, off, len);
+ }
+
+ public synchronized void reset() throws IOException {
+ in.reset();
+ }
+
+ public long skip(long n) throws IOException {
+ return in.skip(n);
+ }
+
+ public int read() throws IOException {
+ return in.read();
+ }
+ });
} else {
char[] chunk = new char[8192];
int read;