Author: rhauch
Date: 2009-01-08 13:17:07 -0500 (Thu, 08 Jan 2009)
New Revision: 698
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/BinaryFactory.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/AbstractBinary.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/AbstractBinaryValueFactory.java
Modified:
trunk/dna-common/src/main/java/org/jboss/dna/common/util/FileUtil.java
trunk/dna-common/src/main/java/org/jboss/dna/common/util/IoUtil.java
trunk/dna-common/src/main/java/org/jboss/dna/common/util/SecureHash.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/Binary.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/ValueFactories.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/DelegatingValueFactories.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/InMemoryBinary.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/InMemoryBinaryValueFactory.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/StandardValueFactories.java
trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemRequestProcessor.java
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/models/basic/BasicRequestProcessor.java
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/util/Serializer.java
Log:
DNA-260 Add factory method to create a Binary instance from a (local) File
Created the BinaryFactory interface, which extends ValueFactory<Binary> and adds
several methods for creating Binary objects from File objects, and from InputStream (or
Reader) when then binary's hash is already known. These latter methods will allow an
implementation to maintain a pool of Binary objects keyed by their hash, so that only one
Binary object per unique value is needed. Also added a method to find a Binary value
given the hash (so that connectors and clients that know the hash may attempt to reuse an
existing Binary value with the same hash, without having to create the InputStream (or
Reader), since that may be expensive even if the stream/reader is not used.
None of the factories in 'org.jboss.dna.graph' reuse Binary values, however; they
always create a new object.
Also added some better error handling logic in IoUtil - getting an exception when closing
a stream (in the finally block) will not stomp on an exception thrown from the try block.
Modified: trunk/dna-common/src/main/java/org/jboss/dna/common/util/FileUtil.java
===================================================================
--- trunk/dna-common/src/main/java/org/jboss/dna/common/util/FileUtil.java 2009-01-08
12:56:19 UTC (rev 697)
+++ trunk/dna-common/src/main/java/org/jboss/dna/common/util/FileUtil.java 2009-01-08
18:17:07 UTC (rev 698)
@@ -22,10 +22,14 @@
package org.jboss.dna.common.util;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
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.net.MalformedURLException;
import java.net.URL;
@@ -89,9 +93,11 @@
numberOfFilesCopied += copy(new File(src1), new File(dest1));
}
} else {
- FileInputStream fin = new FileInputStream(sourceFileOrDirectory);
+ InputStream fin = new FileInputStream(sourceFileOrDirectory);
+ fin = new BufferedInputStream(fin);
try {
- FileOutputStream fout = new
FileOutputStream(destinationFileOrDirectory);
+ OutputStream fout = new FileOutputStream(destinationFileOrDirectory);
+ fout = new BufferedOutputStream(fout);
try {
int c;
while ((c = fin.read()) >= 0) {
Modified: trunk/dna-common/src/main/java/org/jboss/dna/common/util/IoUtil.java
===================================================================
--- trunk/dna-common/src/main/java/org/jboss/dna/common/util/IoUtil.java 2009-01-08
12:56:19 UTC (rev 697)
+++ trunk/dna-common/src/main/java/org/jboss/dna/common/util/IoUtil.java 2009-01-08
18:17:07 UTC (rev 698)
@@ -21,7 +21,10 @@
*/
package org.jboss.dna.common.util;
+import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -37,6 +40,7 @@
/**
* Read and return the entire contents of the supplied {@link InputStream stream}.
This method always closes the stream when
* finished reading.
+ *
* @param stream the stream to the contents; may be null
* @return the contents, or an empty byte array if the supplied reader is null
* @throws IOException if there is an error reading the content
@@ -45,21 +49,61 @@
if (stream == null) return new byte[] {};
byte[] buffer = new byte[1024];
ByteArrayOutputStream output = new ByteArrayOutputStream();
+ boolean error = false;
try {
int numRead = 0;
while ((numRead = stream.read(buffer)) > -1) {
output.write(buffer, 0, numRead);
}
+ } catch (IOException e) {
+ error = true; // this error should be thrown, even if there is an error
closing stream
+ throw e;
+ } catch (RuntimeException e) {
+ error = true; // this error should be thrown, even if there is an error
closing stream
+ throw e;
} finally {
- stream.close();
+ try {
+ stream.close();
+ } catch (IOException e) {
+ if (!error) throw e;
+ }
}
output.flush();
return output.toByteArray();
}
/**
+ * Read and return the entire contents of the supplied {@link File file}.
+ *
+ * @param file the file containing the contents; may be null
+ * @return the contents, or an empty byte array if the supplied file is null
+ * @throws IOException if there is an error reading the content
+ */
+ public static byte[] readBytes( File file ) throws IOException {
+ if (file == null) return new byte[] {};
+ InputStream stream = new BufferedInputStream(new FileInputStream(file));
+ boolean error = false;
+ try {
+ return readBytes(stream);
+ } catch (IOException e) {
+ error = true; // this error should be thrown, even if there is an error
closing stream
+ throw e;
+ } catch (RuntimeException e) {
+ error = true; // this error should be thrown, even if there is an error
closing stream
+ throw e;
+ } finally {
+ try {
+ stream.close();
+ } catch (IOException e) {
+ if (!error) throw e;
+ }
+ }
+ }
+
+ /**
* Read and return the entire contents of the supplied {@link Reader}. This method
always closes the reader when finished
* reading.
+ *
* @param reader the reader of the contents; may be null
* @return the contents, or an empty string if the supplied reader is null
* @throws IOException if there is an error reading the content
@@ -67,21 +111,33 @@
public static String read( Reader reader ) throws IOException {
if (reader == null) return "";
char[] buffer = new char[1024];
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
+ boolean error = false;
try {
int numRead = 0;
while ((numRead = reader.read(buffer)) > -1) {
sb.append(buffer, 0, numRead);
}
+ } catch (IOException e) {
+ error = true; // this error should be thrown, even if there is an error
closing reader
+ throw e;
+ } catch (RuntimeException e) {
+ error = true; // this error should be thrown, even if there is an error
closing reader
+ throw e;
} finally {
- reader.close();
+ try {
+ reader.close();
+ } catch (IOException e) {
+ if (!error) throw e;
+ }
}
return sb.toString();
}
/**
- * Read and return the entire contents of the supplied {@link InputStream}. This
method always closes the stream when
- * finished reading.
+ * Read and return the entire contents of the supplied {@link InputStream}. This
method always closes the stream when finished
+ * reading.
+ *
* @param stream the streamed contents; may be null
* @return the contents, or an empty string if the supplied stream is null
* @throws IOException if there is an error reading the content
@@ -93,23 +149,38 @@
/**
* Write the entire contents of the supplied string to the given stream. This method
always flushes and closes the stream when
* finished.
+ *
* @param content the content to write to the stream; may be null
* @param stream the stream to which the content is to be written
* @throws IOException
* @throws IllegalArgumentException if the stream is null
*/
- public static void write( String content, OutputStream stream ) throws IOException {
+ public static void write( String content,
+ OutputStream stream ) throws IOException {
CheckArg.isNotNull(stream, "destination stream");
+ boolean error = false;
try {
if (content != null) {
byte[] bytes = content.getBytes();
stream.write(bytes, 0, bytes.length);
}
+ } catch (IOException e) {
+ error = true; // this error should be thrown, even if there is an error
flushing/closing stream
+ throw e;
+ } catch (RuntimeException e) {
+ error = true; // this error should be thrown, even if there is an error
flushing/closing stream
+ throw e;
} finally {
try {
stream.flush();
+ } catch (IOException e) {
+ if (!error) throw e;
} finally {
- stream.close();
+ try {
+ stream.close();
+ } catch (IOException e) {
+ if (!error) throw e;
+ }
}
}
}
@@ -117,22 +188,37 @@
/**
* Write the entire contents of the supplied string to the given writer. This method
always flushes and closes the writer when
* finished.
+ *
* @param content the content to write to the writer; may be null
* @param writer the writer to which the content is to be written
* @throws IOException
* @throws IllegalArgumentException if the writer is null
*/
- public static void write( String content, Writer writer ) throws IOException {
+ public static void write( String content,
+ Writer writer ) throws IOException {
CheckArg.isNotNull(writer, "destination writer");
+ boolean error = false;
try {
if (content != null) {
writer.write(content);
}
+ } catch (IOException e) {
+ error = true; // this error should be thrown, even if there is an error
flushing/closing writer
+ throw e;
+ } catch (RuntimeException e) {
+ error = true; // this error should be thrown, even if there is an error
flushing/closing writer
+ throw e;
} finally {
try {
writer.flush();
+ } catch (IOException e) {
+ if (!error) throw e;
} finally {
- writer.close();
+ try {
+ writer.close();
+ } catch (IOException e) {
+ if (!error) throw e;
+ }
}
}
}
@@ -140,13 +226,16 @@
/**
* Write the entire contents of the supplied string to the given stream. This method
always flushes and closes the stream when
* finished.
+ *
* @param input the content to write to the stream; may be null
* @param stream the stream to which the content is to be written
* @throws IOException
* @throws IllegalArgumentException if the stream is null
*/
- public static void write( InputStream input, OutputStream stream ) throws IOException
{
+ public static void write( InputStream input,
+ OutputStream stream ) throws IOException {
CheckArg.isNotNull(stream, "destination stream");
+ boolean error = false;
try {
if (input != null) {
byte[] buffer = new byte[1024];
@@ -159,11 +248,23 @@
input.close();
}
}
+ } catch (IOException e) {
+ error = true; // this error should be thrown, even if there is an error
flushing/closing stream
+ throw e;
+ } catch (RuntimeException e) {
+ error = true; // this error should be thrown, even if there is an error
flushing/closing stream
+ throw e;
} finally {
try {
stream.flush();
+ } catch (IOException e) {
+ if (!error) throw e;
} finally {
- stream.close();
+ try {
+ stream.close();
+ } catch (IOException e) {
+ if (!error) throw e;
+ }
}
}
}
@@ -171,13 +272,16 @@
/**
* Write the entire contents of the supplied string to the given writer. This method
always flushes and closes the writer when
* finished.
+ *
* @param input the content to write to the writer; may be null
* @param writer the writer to which the content is to be written
* @throws IOException
* @throws IllegalArgumentException if the writer is null
*/
- public static void write( Reader input, Writer writer ) throws IOException {
+ public static void write( Reader input,
+ Writer writer ) throws IOException {
CheckArg.isNotNull(writer, "destination writer");
+ boolean error = false;
try {
if (input != null) {
char[] buffer = new char[1024];
@@ -190,11 +294,23 @@
input.close();
}
}
+ } catch (IOException e) {
+ error = true; // this error should be thrown, even if there is an error
flushing/closing writer
+ throw e;
+ } catch (RuntimeException e) {
+ error = true; // this error should be thrown, even if there is an error
flushing/closing writer
+ throw e;
} finally {
try {
writer.flush();
+ } catch (IOException e) {
+ if (!error) throw e;
} finally {
- writer.close();
+ try {
+ writer.close();
+ } catch (IOException e) {
+ if (!error) throw e;
+ }
}
}
}
Modified: trunk/dna-common/src/main/java/org/jboss/dna/common/util/SecureHash.java
===================================================================
--- trunk/dna-common/src/main/java/org/jboss/dna/common/util/SecureHash.java 2009-01-08
12:56:19 UTC (rev 697)
+++ trunk/dna-common/src/main/java/org/jboss/dna/common/util/SecureHash.java 2009-01-08
18:17:07 UTC (rev 698)
@@ -21,6 +21,11 @@
*/
package org.jboss.dna.common.util;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -88,6 +93,38 @@
}
/**
+ * Get the hash of the supplied content, using the supplied digest algorithm.
+ *
+ * @param algorithm the hashing function algorithm that should be used
+ * @param file the file containing the content to be hashed; may not be null
+ * @return the hash of the contents as a byte array
+ * @throws NoSuchAlgorithmException if the supplied algorithm could not be found
+ * @throws IllegalArgumentException if the algorithm is null
+ * @throws IOException if there is an error reading the file
+ */
+ public static byte[] getHash( Algorithm algorithm,
+ File file ) throws NoSuchAlgorithmException,
IOException {
+ CheckArg.isNotNull(algorithm, "algorithm");
+ return getHash(algorithm.digestName(), file);
+ }
+
+ /**
+ * Get the hash of the supplied content, using the supplied digest algorithm.
+ *
+ * @param algorithm the hashing function algorithm that should be used
+ * @param stream the stream containing the content to be hashed; may not be null
+ * @return the hash of the contents as a byte array
+ * @throws NoSuchAlgorithmException if the supplied algorithm could not be found
+ * @throws IllegalArgumentException if the algorithm is null
+ * @throws IOException if there is an error reading the stream
+ */
+ public static byte[] getHash( Algorithm algorithm,
+ InputStream stream ) throws NoSuchAlgorithmException,
IOException {
+ CheckArg.isNotNull(algorithm, "algorithm");
+ return getHash(algorithm.digestName(), stream);
+ }
+
+ /**
* Get the hash of the supplied content, using the digest identified by the supplied
name.
*
* @param digestName the name of the hashing function (or {@link MessageDigest
message digest}) that should be used
@@ -101,4 +138,70 @@
assert digest != null;
return digest.digest(content);
}
+
+ /**
+ * Get the hash of the supplied content, using the digest identified by the supplied
name.
+ *
+ * @param digestName the name of the hashing function (or {@link MessageDigest
message digest}) that should be used
+ * @param file the file whose content is to be hashed; may not be null
+ * @return the hash of the contents as a byte array
+ * @throws NoSuchAlgorithmException if the supplied algorithm could not be found
+ * @throws IOException if there is an error reading the file
+ */
+ public static byte[] getHash( String digestName,
+ File file ) throws NoSuchAlgorithmException,
IOException {
+ CheckArg.isNotNull(file, "file");
+ MessageDigest digest = MessageDigest.getInstance(digestName);
+ assert digest != null;
+ InputStream in = new BufferedInputStream(new FileInputStream(file));
+ boolean error = false;
+ try {
+ int bufSize = 1024;
+ byte[] buffer = new byte[bufSize];
+ int n = in.read(buffer, 0, bufSize);
+ int count = 0;
+ while (n != -1) {
+ count += n;
+ digest.update(buffer, 0, n);
+ n = in.read(buffer, 0, bufSize);
+ }
+ } catch (IOException e) {
+ error = true;
+ throw e;
+ } finally {
+ try {
+ in.close();
+ } catch (IOException e) {
+ if (!error) throw e;
+ }
+ }
+ return digest.digest();
+ }
+
+ /**
+ * Get the hash of the supplied content, using the digest identified by the supplied
name. Note that this method never closes
+ * the supplied stream.
+ *
+ * @param digestName the name of the hashing function (or {@link MessageDigest
message digest}) that should be used
+ * @param stream the stream containing the content to be hashed; may not be null
+ * @return the hash of the contents as a byte array
+ * @throws NoSuchAlgorithmException if the supplied algorithm could not be found
+ * @throws IOException if there is an error reading the stream
+ */
+ public static byte[] getHash( String digestName,
+ InputStream stream ) throws NoSuchAlgorithmException,
IOException {
+ CheckArg.isNotNull(stream, "stream");
+ MessageDigest digest = MessageDigest.getInstance(digestName);
+ assert digest != null;
+ int bufSize = 1024;
+ byte[] buffer = new byte[bufSize];
+ int n = stream.read(buffer, 0, bufSize);
+ int count = 0;
+ while (n != -1) {
+ count += n;
+ digest.update(buffer, 0, n);
+ n = stream.read(buffer, 0, bufSize);
+ }
+ return digest.digest();
+ }
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/Binary.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/Binary.java 2009-01-08
12:56:19 UTC (rev 697)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/Binary.java 2009-01-08
18:17:07 UTC (rev 698)
@@ -61,6 +61,7 @@
*
* @return the stream to this data's contents
* @see #acquire()
+ * @throws IoException if there is a problem returning the stream
*/
public InputStream getStream();
@@ -69,6 +70,7 @@
*
* @return the data as an array
* @see #acquire()
+ * @throws IoException if there is a problem returning the bytes
*/
public byte[] getBytes();
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/BinaryFactory.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/BinaryFactory.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/BinaryFactory.java 2009-01-08
18:17:07 UTC (rev 698)
@@ -0,0 +1,94 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.graph.properties;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+/**
+ * A factory for creating {@link Binary} instances. This interface extends the {@link
ValueFactory} generic interface and adds
+ * specific methods for creating binary objects.
+ *
+ * @author Randall Hauch
+ */
+public interface BinaryFactory extends ValueFactory<Binary> {
+
+ /**
+ * Create a value from the binary content given by the supplied stream, the
approximate length, and the SHA-1 secure hash of
+ * the content. If the secure hash is null, then a secure hash is computed from the
content. If the secure hash is not null,
+ * it is assumed to be the hash for the content and may not be checked.
+ *
+ * @param stream the stream containing the content to be used to create the value
+ * @param approximateLength the approximate length of the content (in bytes)
+ * @param secureHash the secure hash of the content in the
<code>stream</code>; if null, the secure hash is computed from the
+ * content, and if not null it is assumed to be the correct secure hash (and
is not checked)
+ * @return the value, or null if the supplied stream is null
+ * @throws ValueFormatException if the conversion from an input stream could not be
performed
+ * @throws IoException If an unexpected problem occurs while accessing the supplied
stream (such as an {@link IOException}).
+ * @throws IllegalArgumentException if the secure hash was discovered to be
incorrect
+ */
+ Binary create( InputStream stream,
+ long approximateLength,
+ byte[] secureHash ) throws ValueFormatException, IoException;
+
+ /**
+ * Create a value from the binary content given by the supplied reader, the
approximate length, and the SHA-1 secure hash of
+ * the content. If the secure hash is null, then a secure hash is computed from the
content. If the secure hash is not null,
+ * it is assumed to be the hash for the content and may not be checked.
+ *
+ * @param reader the reader containing the content to be used to create the value
+ * @param approximateLength the approximate length of the content (in bytes)
+ * @param secureHash the secure hash of the content in the
<code>stream</code>; if null, the secure hash is computed from the
+ * content, and if not null it is assumed to be the correct secure hash (and
is not checked)
+ * @return the value, or null if the supplied string is null
+ * @throws ValueFormatException if the conversion from a reader could not be
performed
+ * @throws IoException If an unexpected problem occurs while accessing the supplied
reader (such as an {@link IOException}).
+ * @throws IllegalArgumentException if the secure hash was discovered to be
incorrect
+ */
+ Binary create( Reader reader,
+ long approximateLength,
+ byte[] secureHash ) throws ValueFormatException, IoException;
+
+ /**
+ * Create a binary value from the given file.
+ *
+ * @param file the file containing the content to be used
+ * @return the binary value, or null if the file parameter was null
+ * @throws ValueFormatException if the conversion from the file could not be
performed
+ * @throws IoException If an unexpected problem occurs while accessing the supplied
file (such as an {@link IOException}).
+ */
+ Binary create( File file ) throws ValueFormatException, IoException;
+
+ /**
+ * Find an existing binary value given the supplied secure hash. If no such binary
value exists, null is returned. This method
+ * can be used when the caller knows the secure hash (e.g., from a previously-held
Binary object), and would like to reuse an
+ * existing binary value (if possible) rather than recreate the binary value by
processing the stream contents. This is
+ * especially true when the size of the binary is quite large.
+ *
+ * @param secureHash the secure hash of the binary content, which was probably {@link
Binary#getHash() obtained} from a
+ * previously-held {@link Binary} object; a null or empty value is allowed,
but will always result in returning null
+ * @return the existing Binary value that has the same secure hash, or null if there
is no such value available at this time
+ */
+ Binary find( byte[] secureHash );
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/BinaryFactory.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/ValueFactories.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/ValueFactories.java 2009-01-08
12:56:19 UTC (rev 697)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/ValueFactories.java 2009-01-08
18:17:07 UTC (rev 698)
@@ -61,7 +61,7 @@
*
* @return the factory; never null
*/
- ValueFactory<Binary> getBinaryFactory();
+ BinaryFactory getBinaryFactory();
/**
* Get the value factory for {@link PropertyType#LONG long} properties.
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/AbstractBinary.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/AbstractBinary.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/AbstractBinary.java 2009-01-08
18:17:07 UTC (rev 698)
@@ -0,0 +1,140 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008-2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.graph.properties.basic;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.NoSuchAlgorithmException;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+import net.jcip.annotations.Immutable;
+import org.jboss.dna.common.util.Base64;
+import org.jboss.dna.common.util.Logger;
+import org.jboss.dna.common.util.SecureHash;
+import org.jboss.dna.graph.GraphI18n;
+import org.jboss.dna.graph.properties.Binary;
+import org.jboss.dna.graph.properties.ValueComparators;
+
+/**
+ * An abstract implementation of {@link Binary} that provides some common capabilities
for other implementations.
+ *
+ * @author Randall Hauch
+ */
+@Immutable
+public abstract class AbstractBinary implements Binary {
+
+ protected static final Set<String> ALGORITHMS_NOT_FOUND_AND_LOGGED = new
CopyOnWriteArraySet<String>();
+ private static final SecureHash.Algorithm ALGORITHM = SecureHash.Algorithm.SHA_1;
+ private static final byte[] NO_HASH = new byte[] {};
+
+ protected static final byte[] EMPTY_CONTENT = new byte[0];
+
+ /**
+ * Version {@value} .
+ */
+ private static final long serialVersionUID = 1L;
+
+ protected AbstractBinary() {
+ }
+
+ protected byte[] computeHash( byte[] content ) {
+ try {
+ return SecureHash.getHash(ALGORITHM, content);
+ } catch (NoSuchAlgorithmException e) {
+ if (ALGORITHMS_NOT_FOUND_AND_LOGGED.add(ALGORITHM.digestName())) {
+ Logger.getLogger(getClass()).error(e, GraphI18n.messageDigestNotFound,
ALGORITHM.digestName());
+ }
+ return NO_HASH;
+ }
+ }
+
+ protected byte[] computeHash( File file ) {
+ try {
+ return SecureHash.getHash(ALGORITHM, file);
+ } catch (NoSuchAlgorithmException e) {
+ if (ALGORITHMS_NOT_FOUND_AND_LOGGED.add(ALGORITHM.digestName())) {
+ Logger.getLogger(getClass()).error(e, GraphI18n.messageDigestNotFound,
ALGORITHM.digestName());
+ }
+ return NO_HASH;
+ } catch (IOException e) {
+ if (ALGORITHMS_NOT_FOUND_AND_LOGGED.add(ALGORITHM.digestName())) {
+ Logger.getLogger(getClass()).error(e, GraphI18n.messageDigestNotFound,
ALGORITHM.digestName());
+ }
+ return NO_HASH;
+ }
+ }
+
+ protected byte[] computeHash( InputStream stream ) {
+ try {
+ return SecureHash.getHash(ALGORITHM, stream);
+ } catch (NoSuchAlgorithmException e) {
+ if (ALGORITHMS_NOT_FOUND_AND_LOGGED.add(ALGORITHM.digestName())) {
+ Logger.getLogger(getClass()).error(e, GraphI18n.messageDigestNotFound,
ALGORITHM.digestName());
+ }
+ return NO_HASH;
+ } catch (IOException e) {
+ if (ALGORITHMS_NOT_FOUND_AND_LOGGED.add(ALGORITHM.digestName())) {
+ Logger.getLogger(getClass()).error(e, GraphI18n.messageDigestNotFound,
ALGORITHM.digestName());
+ }
+ return NO_HASH;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int compareTo( Binary o ) {
+ return ValueComparators.BINARY_COMPARATOR.compare(this, o);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof Binary) {
+ Binary that = (Binary)obj;
+ if (this.getSize() != that.getSize()) return false;
+ return ValueComparators.BINARY_COMPARATOR.compare(this, that) == 0;
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ try {
+ acquire();
+ StringBuilder sb = new StringBuilder(super.toString());
+ sb.append(" len=").append(getSize()).append("; [");
+ sb.append(Base64.encodeBytes(getBytes()));
+ return sb.toString();
+ } finally {
+ release();
+ }
+ }
+
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/AbstractBinary.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/AbstractBinaryValueFactory.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/AbstractBinaryValueFactory.java
(rev 0)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/AbstractBinaryValueFactory.java 2009-01-08
18:17:07 UTC (rev 698)
@@ -0,0 +1,312 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008-2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.graph.properties.basic;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
+import java.net.URI;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.UUID;
+import net.jcip.annotations.Immutable;
+import org.jboss.dna.common.text.TextDecoder;
+import org.jboss.dna.common.util.IoUtil;
+import org.jboss.dna.graph.GraphI18n;
+import org.jboss.dna.graph.properties.Binary;
+import org.jboss.dna.graph.properties.BinaryFactory;
+import org.jboss.dna.graph.properties.DateTime;
+import org.jboss.dna.graph.properties.IoException;
+import org.jboss.dna.graph.properties.Name;
+import org.jboss.dna.graph.properties.Path;
+import org.jboss.dna.graph.properties.PropertyType;
+import org.jboss.dna.graph.properties.Reference;
+import org.jboss.dna.graph.properties.ValueFactory;
+import org.jboss.dna.graph.properties.ValueFormatException;
+
+/**
+ * An abstract {@link BinaryFactory} implementation that contains many general methods
that are likely to be appropriate for many
+ * concrete implementations.
+ *
+ * @author Randall Hauch
+ * @author John Verhaeg
+ */
+@Immutable
+public abstract class AbstractBinaryValueFactory extends
AbstractValueFactory<Binary> implements BinaryFactory {
+
+ private static final String CHAR_SET_NAME = "UTF-8";
+
+ protected AbstractBinaryValueFactory( TextDecoder decoder,
+ ValueFactory<String> stringValueFactory )
{
+ super(PropertyType.BINARY, decoder, stringValueFactory);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Binary create( String value ) {
+ if (value == null) return null;
+ try {
+ return create(value.getBytes(CHAR_SET_NAME));
+ } catch (UnsupportedEncodingException err) {
+ throw new ValueFormatException(value, getPropertyType(),
+
GraphI18n.errorConvertingType.text(String.class.getSimpleName(),
+
Binary.class.getSimpleName(),
+ value),
err);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Binary create( String value,
+ TextDecoder decoder ) {
+ if (value == null) return null;
+ return create(getDecoder(decoder).decode(value));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Binary create( int value ) {
+ // Convert the value to a string, then to a binary ...
+ return create(this.getStringValueFactory().create(value));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Binary create( long value ) {
+ // Convert the value to a string, then to a binary ...
+ return create(this.getStringValueFactory().create(value));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Binary create( boolean value ) {
+ // Convert the value to a string, then to a binary ...
+ return create(this.getStringValueFactory().create(value));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Binary create( float value ) {
+ // Convert the value to a string, then to a binary ...
+ return create(this.getStringValueFactory().create(value));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Binary create( double value ) {
+ // Convert the value to a string, then to a binary ...
+ return create(this.getStringValueFactory().create(value));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Binary create( BigDecimal value ) {
+ // Convert the value to a string, then to a binary ...
+ return create(this.getStringValueFactory().create(value));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Binary create( Calendar value ) {
+ // Convert the value to a string, then to a binary ...
+ return create(this.getStringValueFactory().create(value));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Binary create( Date value ) {
+ // Convert the value to a string, then to a binary ...
+ return create(this.getStringValueFactory().create(value));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.properties.ValueFactory#create(org.jboss.dna.graph.properties.DateTime)
+ */
+ public Binary create( DateTime value ) throws ValueFormatException {
+ // Convert the value to a string, then to a binary ...
+ return create(this.getStringValueFactory().create(value));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Binary create( Name value ) {
+ // Convert the value to a string, then to a binary ...
+ return create(this.getStringValueFactory().create(value));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Binary create( Path value ) {
+ // Convert the value to a string, then to a binary ...
+ return create(this.getStringValueFactory().create(value));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Binary create( Reference value ) {
+ // Convert the value to a string, then to a binary ...
+ return create(this.getStringValueFactory().create(value));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Binary create( URI value ) {
+ // Convert the value to a string, then to a binary ...
+ return create(this.getStringValueFactory().create(value));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.properties.ValueFactory#create(java.util.UUID)
+ */
+ public Binary create( UUID value ) {
+ // Convert the value to a string, then to a binary ...
+ return create(this.getStringValueFactory().create(value));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.graph.properties.ValueFactory#create(org.jboss.dna.graph.properties.Binary)
+ */
+ public Binary create( Binary value ) throws ValueFormatException, IoException {
+ return value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Binary create( InputStream stream,
+ long approximateLength ) throws IoException {
+ if (stream == null) return null;
+ try {
+ byte[] value = IoUtil.readBytes(stream);
+ return create(value);
+ } catch (IOException err) {
+ throw new
IoException(GraphI18n.errorConvertingIo.text(InputStream.class.getSimpleName(),
+
Binary.class.getSimpleName()), err);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Binary create( Reader reader,
+ long approximateLength ) throws IoException {
+ if (reader == null) return null;
+ // Convert the value to a string, then to a binary ...
+ try {
+ String value = IoUtil.read(reader);
+ return create(this.getStringValueFactory().create(value));
+ } catch (IOException err) {
+ throw new
IoException(GraphI18n.errorConvertingIo.text(Reader.class.getSimpleName(),
Binary.class.getSimpleName()),
+ err);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.properties.BinaryFactory#create(java.io.File)
+ */
+ public Binary create( File file ) throws ValueFormatException, IoException {
+ if (file == null) return null;
+ if (!file.canRead()) return null;
+ if (!file.isFile()) return null;
+ try {
+ byte[] value = IoUtil.readBytes(file);
+ return create(value);
+ } catch (IOException err) {
+ throw new IoException(GraphI18n.errorConvertingIo.text(file,
Binary.class.getSimpleName()), err);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This implementation does not manage or share the in-memory binary values, so this
implementation is identical to calling
+ * {@link #create(Reader, long)}.
+ * </p>
+ *
+ * @see org.jboss.dna.graph.properties.BinaryFactory#create(java.io.Reader, long,
byte[])
+ */
+ public Binary create( Reader reader,
+ long approximateLength,
+ byte[] secureHash ) throws ValueFormatException, IoException {
+ return create(reader, approximateLength);
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This implementation does not manage or share the in-memory binary values, so this
implementation is identical to calling
+ * {@link #create(InputStream, long)}.
+ * </p>
+ *
+ * @see org.jboss.dna.graph.properties.BinaryFactory#create(java.io.InputStream,
long, byte[])
+ */
+ public Binary create( InputStream stream,
+ long approximateLength,
+ byte[] secureHash ) throws ValueFormatException, IoException {
+ return create(stream, approximateLength);
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This method always returns null, since the in-memory binary values are not managed
or shared.
+ * </p>
+ *
+ * @see org.jboss.dna.graph.properties.BinaryFactory#find(byte[])
+ */
+ public Binary find( byte[] secureHash ) {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Binary[] createEmptyArray( int length ) {
+ return new Binary[length];
+ }
+}
Property changes on:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/AbstractBinaryValueFactory.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/DelegatingValueFactories.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/DelegatingValueFactories.java 2009-01-08
12:56:19 UTC (rev 697)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/DelegatingValueFactories.java 2009-01-08
18:17:07 UTC (rev 698)
@@ -23,7 +23,7 @@
import java.math.BigDecimal;
import java.net.URI;
-import org.jboss.dna.graph.properties.Binary;
+import org.jboss.dna.graph.properties.BinaryFactory;
import org.jboss.dna.graph.properties.DateTimeFactory;
import org.jboss.dna.graph.properties.NameFactory;
import org.jboss.dna.graph.properties.PathFactory;
@@ -44,7 +44,7 @@
this.delegate = delegate;
}
- public ValueFactory<Binary> getBinaryFactory() {
+ public BinaryFactory getBinaryFactory() {
return delegate.getBinaryFactory();
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/InMemoryBinary.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/InMemoryBinary.java 2009-01-08
12:56:19 UTC (rev 697)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/InMemoryBinary.java 2009-01-08
18:17:07 UTC (rev 698)
@@ -23,17 +23,9 @@
import java.io.ByteArrayInputStream;
import java.io.InputStream;
-import java.security.NoSuchAlgorithmException;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArraySet;
import net.jcip.annotations.Immutable;
-import org.jboss.dna.common.util.Base64;
import org.jboss.dna.common.util.CheckArg;
-import org.jboss.dna.common.util.Logger;
-import org.jboss.dna.common.util.SecureHash;
-import org.jboss.dna.graph.GraphI18n;
import org.jboss.dna.graph.properties.Binary;
-import org.jboss.dna.graph.properties.ValueComparators;
/**
* An implementation of {@link Binary} that keeps the binary data in-memory.
@@ -41,18 +33,13 @@
* @author Randall Hauch
*/
@Immutable
-public class InMemoryBinary implements Binary {
+public class InMemoryBinary extends AbstractBinary {
- protected static final Set<String> ALGORITHMS_NOT_FOUND_AND_LOGGED = new
CopyOnWriteArraySet<String>();
- private static final SecureHash.Algorithm ALGORITHM = SecureHash.Algorithm.SHA_1;
- private static final byte[] NO_HASH = new byte[] {};
-
/**
+ * Version {@value} .
*/
- private static final long serialVersionUID = 8792863149767123559L;
+ private static final long serialVersionUID = 2L;
- protected static final byte[] EMPTY_CONTENT = new byte[0];
-
private final byte[] bytes;
private byte[] sha1hash;
@@ -76,14 +63,7 @@
public byte[] getHash() {
if (sha1hash == null) {
// Idempotent, so doesn't matter if we recompute in concurrent threads
...
- try {
- sha1hash = SecureHash.getHash(ALGORITHM, bytes);
- } catch (NoSuchAlgorithmException e) {
- if (ALGORITHMS_NOT_FOUND_AND_LOGGED.add(ALGORITHM.digestName())) {
- Logger.getLogger(getClass()).error(e,
GraphI18n.messageDigestNotFound, ALGORITHM.digestName());
- }
- sha1hash = NO_HASH;
- }
+ sha1hash = computeHash(bytes);
}
return sha1hash;
}
@@ -115,37 +95,4 @@
public void release() {
// do nothing
}
-
- /**
- * {@inheritDoc}
- */
- public int compareTo( Binary o ) {
- return ValueComparators.BINARY_COMPARATOR.compare(this, o);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean equals( Object obj ) {
- if (obj == this) return true;
- if (obj instanceof Binary) {
- Binary that = (Binary)obj;
- if (this.getSize() != that.getSize()) return false;
- return ValueComparators.BINARY_COMPARATOR.compare(this, that) == 0;
- }
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder(super.toString());
- sb.append(" len=").append(getSize()).append("; [");
- sb.append(Base64.encodeBytes(this.bytes));
- return sb.toString();
- }
-
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/InMemoryBinaryValueFactory.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/InMemoryBinaryValueFactory.java 2009-01-08
12:56:19 UTC (rev 697)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/InMemoryBinaryValueFactory.java 2009-01-08
18:17:07 UTC (rev 698)
@@ -21,237 +21,33 @@
*/
package org.jboss.dna.graph.properties.basic;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.io.UnsupportedEncodingException;
-import java.math.BigDecimal;
-import java.net.URI;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.UUID;
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.text.TextDecoder;
-import org.jboss.dna.common.util.IoUtil;
-import org.jboss.dna.graph.GraphI18n;
import org.jboss.dna.graph.properties.Binary;
-import org.jboss.dna.graph.properties.DateTime;
-import org.jboss.dna.graph.properties.IoException;
-import org.jboss.dna.graph.properties.Name;
-import org.jboss.dna.graph.properties.Path;
import org.jboss.dna.graph.properties.PropertyType;
-import org.jboss.dna.graph.properties.Reference;
import org.jboss.dna.graph.properties.ValueFactory;
-import org.jboss.dna.graph.properties.ValueFormatException;
/**
- * Teh standard {@link ValueFactory} for {@link PropertyType#BINARY} values.
+ * The {@link ValueFactory} for in-memory {@link PropertyType#BINARY} values.
+ * <p>
+ * This factory does not {@link #find(byte[]) reuse} any instances.
+ * </p>
*
* @author Randall Hauch
- * @author John Verhaeg
*/
@Immutable
-public class InMemoryBinaryValueFactory extends AbstractValueFactory<Binary> {
+public class InMemoryBinaryValueFactory extends AbstractBinaryValueFactory {
- private static final String CHAR_SET_NAME = "UTF-8";
-
public InMemoryBinaryValueFactory( TextDecoder decoder,
ValueFactory<String> stringValueFactory ) {
- super(PropertyType.BINARY, decoder, stringValueFactory);
+ super(decoder, stringValueFactory);
}
/**
* {@inheritDoc}
*/
- public Binary create( String value ) {
- if (value == null) return null;
- try {
- return create(value.getBytes(CHAR_SET_NAME));
- } catch (UnsupportedEncodingException err) {
- throw new ValueFormatException(value, getPropertyType(),
-
GraphI18n.errorConvertingType.text(String.class.getSimpleName(),
-
Binary.class.getSimpleName(),
- value),
err);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public Binary create( String value,
- TextDecoder decoder ) {
- if (value == null) return null;
- return create(getDecoder(decoder).decode(value));
- }
-
- /**
- * {@inheritDoc}
- */
- public Binary create( int value ) {
- // Convert the value to a string, then to a binary ...
- return create(this.getStringValueFactory().create(value));
- }
-
- /**
- * {@inheritDoc}
- */
- public Binary create( long value ) {
- // Convert the value to a string, then to a binary ...
- return create(this.getStringValueFactory().create(value));
- }
-
- /**
- * {@inheritDoc}
- */
- public Binary create( boolean value ) {
- // Convert the value to a string, then to a binary ...
- return create(this.getStringValueFactory().create(value));
- }
-
- /**
- * {@inheritDoc}
- */
- public Binary create( float value ) {
- // Convert the value to a string, then to a binary ...
- return create(this.getStringValueFactory().create(value));
- }
-
- /**
- * {@inheritDoc}
- */
- public Binary create( double value ) {
- // Convert the value to a string, then to a binary ...
- return create(this.getStringValueFactory().create(value));
- }
-
- /**
- * {@inheritDoc}
- */
- public Binary create( BigDecimal value ) {
- // Convert the value to a string, then to a binary ...
- return create(this.getStringValueFactory().create(value));
- }
-
- /**
- * {@inheritDoc}
- */
- public Binary create( Calendar value ) {
- // Convert the value to a string, then to a binary ...
- return create(this.getStringValueFactory().create(value));
- }
-
- /**
- * {@inheritDoc}
- */
- public Binary create( Date value ) {
- // Convert the value to a string, then to a binary ...
- return create(this.getStringValueFactory().create(value));
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.graph.properties.ValueFactory#create(org.jboss.dna.graph.properties.DateTime)
- */
- public Binary create( DateTime value ) throws ValueFormatException {
- // Convert the value to a string, then to a binary ...
- return create(this.getStringValueFactory().create(value));
- }
-
- /**
- * {@inheritDoc}
- */
- public Binary create( Name value ) {
- // Convert the value to a string, then to a binary ...
- return create(this.getStringValueFactory().create(value));
- }
-
- /**
- * {@inheritDoc}
- */
- public Binary create( Path value ) {
- // Convert the value to a string, then to a binary ...
- return create(this.getStringValueFactory().create(value));
- }
-
- /**
- * {@inheritDoc}
- */
- public Binary create( Reference value ) {
- // Convert the value to a string, then to a binary ...
- return create(this.getStringValueFactory().create(value));
- }
-
- /**
- * {@inheritDoc}
- */
- public Binary create( URI value ) {
- // Convert the value to a string, then to a binary ...
- return create(this.getStringValueFactory().create(value));
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.properties.ValueFactory#create(java.util.UUID)
- */
- public Binary create( UUID value ) {
- // Convert the value to a string, then to a binary ...
- return create(this.getStringValueFactory().create(value));
- }
-
- /**
- * {@inheritDoc}
- */
public Binary create( byte[] value ) {
return new InMemoryBinary(value);
}
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.graph.properties.ValueFactory#create(org.jboss.dna.graph.properties.Binary)
- */
- public Binary create( Binary value ) throws ValueFormatException, IoException {
- return value;
- }
-
- /**
- * {@inheritDoc}
- */
- public Binary create( InputStream stream,
- long approximateLength ) throws IoException {
- if (stream == null) return null;
- try {
- byte[] value = IoUtil.readBytes(stream);
- return create(value);
- } catch (IOException err) {
- throw new IoException(
-
GraphI18n.errorConvertingIo.text(InputStream.class.getSimpleName(),
Binary.class.getSimpleName()),
- err);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public Binary create( Reader reader,
- long approximateLength ) throws IoException {
- if (reader == null) return null;
- // Convert the value to a string, then to a binary ...
- try {
- String value = IoUtil.read(reader);
- return create(this.getStringValueFactory().create(value));
- } catch (IOException err) {
- throw new
IoException(GraphI18n.errorConvertingIo.text(Reader.class.getSimpleName(),
Binary.class.getSimpleName()), err);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected Binary[] createEmptyArray( int length ) {
- return new Binary[length];
- }
}
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/StandardValueFactories.java
===================================================================
---
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/StandardValueFactories.java 2009-01-08
12:56:19 UTC (rev 697)
+++
trunk/dna-graph/src/main/java/org/jboss/dna/graph/properties/basic/StandardValueFactories.java 2009-01-08
18:17:07 UTC (rev 698)
@@ -29,7 +29,7 @@
import org.jboss.dna.common.text.TextDecoder;
import org.jboss.dna.common.text.TextEncoder;
import org.jboss.dna.common.util.CheckArg;
-import org.jboss.dna.graph.properties.Binary;
+import org.jboss.dna.graph.properties.BinaryFactory;
import org.jboss.dna.graph.properties.DateTimeFactory;
import org.jboss.dna.graph.properties.NameFactory;
import org.jboss.dna.graph.properties.NamespaceRegistry;
@@ -49,7 +49,7 @@
// This class is implemented with separate members for each factory so that the
typical usage is optimized.
private final ValueFactory<String> stringFactory;
- private final ValueFactory<Binary> binaryFactory;
+ private final BinaryFactory binaryFactory;
private final ValueFactory<Boolean> booleanFactory;
private final DateTimeFactory dateFactory;
private final ValueFactory<BigDecimal> decimalFactory;
@@ -104,7 +104,8 @@
// Now assign the members, using the factories in the map or (if null) the
supplied default ...
this.stringFactory = getFactory(factories, new StringValueFactory(this.decoder,
this.encoder));
- this.binaryFactory = getFactory(factories, new
InMemoryBinaryValueFactory(this.decoder, this.stringFactory));
+ this.binaryFactory = (BinaryFactory)getFactory(factories,
+ new
InMemoryBinaryValueFactory(this.decoder, this.stringFactory));
this.booleanFactory = getFactory(factories, new BooleanValueFactory(this.decoder,
this.stringFactory));
this.dateFactory = (DateTimeFactory)getFactory(factories, new
JodaDateTimeValueFactory(this.decoder, this.stringFactory));
this.decimalFactory = getFactory(factories, new DecimalValueFactory(this.decoder,
this.stringFactory));
@@ -149,7 +150,7 @@
/**
* {@inheritDoc}
*/
- public ValueFactory<Binary> getBinaryFactory() {
+ public BinaryFactory getBinaryFactory() {
return this.binaryFactory;
}
Modified:
trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemRequestProcessor.java
===================================================================
---
trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemRequestProcessor.java 2009-01-08
12:56:19 UTC (rev 697)
+++
trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemRequestProcessor.java 2009-01-08
18:17:07 UTC (rev 698)
@@ -30,6 +30,7 @@
import org.jboss.dna.graph.JcrNtLexicon;
import org.jboss.dna.graph.Location;
import org.jboss.dna.graph.connectors.RepositorySourceException;
+import org.jboss.dna.graph.properties.BinaryFactory;
import org.jboss.dna.graph.properties.DateTimeFactory;
import org.jboss.dna.graph.properties.Name;
import org.jboss.dna.graph.properties.NameFactory;
@@ -165,8 +166,8 @@
// request.addProperty(factory.create(JcrLexicon.MIMETYPE, mimeType));
// Now put the file's content into the "jcr:data" property
...
- // BinaryFactory binaryFactory =
getExecutionContext().getValueFactories().getBinaryFactory();
- // request.addProperty(factory.create(JcrLexicon.DATA,
binaryFactory.create(file)));
+ BinaryFactory binaryFactory =
getExecutionContext().getValueFactories().getBinaryFactory();
+ request.addProperty(factory.create(JcrLexicon.DATA,
binaryFactory.create(file)));
} else {
// The request is to get properties for the node representing the file
Modified:
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/models/basic/BasicRequestProcessor.java
===================================================================
---
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/models/basic/BasicRequestProcessor.java 2009-01-08
12:56:19 UTC (rev 697)
+++
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/models/basic/BasicRequestProcessor.java 2009-01-08
18:17:07 UTC (rev 698)
@@ -1627,6 +1627,8 @@
}
}
break;
+ case URI:
+ // This will be treated as a string ...
default:
String str = factories.getStringFactory().create(value);
if (compressData) {
Modified:
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/util/Serializer.java
===================================================================
---
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/util/Serializer.java 2009-01-08
12:56:19 UTC (rev 697)
+++
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/util/Serializer.java 2009-01-08
18:17:07 UTC (rev 698)
@@ -40,6 +40,7 @@
import org.jboss.dna.graph.DnaLexicon;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.properties.Binary;
+import org.jboss.dna.graph.properties.BinaryFactory;
import org.jboss.dna.graph.properties.DateTime;
import org.jboss.dna.graph.properties.Name;
import org.jboss.dna.graph.properties.Path;
@@ -257,8 +258,21 @@
stream.writeLong(uuid.getMostSignificantBits());
stream.writeLong(uuid.getLeastSignificantBits());
} else if (value instanceof URI) {
- stream.writeChar('I');
- stream.writeObject(((URI)value).toString());
+ URI uri = (URI)value;
+ String stringValue = uri.toString();
+ if (largeValues != null && stringValue.length() >
largeValues.getMinimumSize()) {
+ // Store the URI in the large values area, but record the hash and
length here.
+ byte[] hash = computeHash(stringValue);
+ stream.writeChar('L');
+ stream.writeInt(hash.length);
+ stream.write(hash);
+ stream.writeLong(stringValue.length());
+ // Now write to the large objects ...
+ largeValues.write(computeHash(stringValue), stringValue.length(),
PropertyType.URI, stringValue);
+ } else {
+ stream.writeChar('I');
+ stream.writeObject(stringValue);
+ }
} else if (value instanceof Name) {
stream.writeChar('N');
stream.writeObject(((Name)value).getString());
@@ -780,7 +794,13 @@
if (skip) {
skippedLargeValues.read(valueFactories, hash, length);
} else {
- value = largeValues.read(valueFactories, hash, length);
+ BinaryFactory factory = valueFactories.getBinaryFactory();
+ // Look for an already-loaded Binary value with the same hash
...
+ value = factory.find(hash);
+ if (value == null) {
+ // Didn't find an existing large value, so we have to
read the large value ...
+ value = largeValues.read(valueFactories, hash, length);
+ }
}
break;
default: