jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From thom...@apache.org
Subject svn commit: r924769 - in /jackrabbit/trunk/jackrabbit-core/src: main/java/org/apache/jackrabbit/core/data/db/ test/java/org/apache/jackrabbit/core/data/
Date Thu, 18 Mar 2010 13:37:30 GMT
Author: thomasm
Date: Thu Mar 18 13:37:30 2010
New Revision: 924769

URL: http://svn.apache.org/viewvc?rev=924769&view=rev
Log:
JCR-2576 DbInputStream does not support mark()/reset() when exhausted.

Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataRecord.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbInputStream.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/TempFileInputStream.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/DBDataStoreTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TempFileInputStreamTest.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataRecord.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataRecord.java?rev=924769&r1=924768&r2=924769&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataRecord.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataRecord.java
Thu Mar 18 13:37:30 2010
@@ -20,6 +20,7 @@ import org.apache.jackrabbit.core.data.A
 import org.apache.jackrabbit.core.data.DataIdentifier;
 import org.apache.jackrabbit.core.data.DataStoreException;
 
+import java.io.BufferedInputStream;
 import java.io.InputStream;
 
 /**
@@ -33,7 +34,7 @@ public class DbDataRecord extends Abstra
 
     /**
      * Creates a data record based on the given identifier and length.
-     * 
+     *
      * @param identifier data identifier
      * @param length the length
      * @param lastModified
@@ -58,7 +59,7 @@ public class DbDataRecord extends Abstra
      */
     public InputStream getStream() throws DataStoreException {
         lastModified = store.touch(getIdentifier(), lastModified);
-        return new DbInputStream(store, getIdentifier());
+        return new BufferedInputStream(new DbInputStream(store, getIdentifier()));
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java?rev=924769&r1=924768&r2=924769&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java
Thu Mar 18 13:37:30 2010
@@ -118,12 +118,12 @@ public class DbDataStore implements Data
      * Call PreparedStatement.setBinaryStream(..., Integer.MAX_VALUE)
      */
     public static final String STORE_SIZE_MAX = "max";
-    
+
     /**
      * The digest algorithm used to uniquely identify records.
      */
     protected static final String DIGEST = "SHA-1";
-    
+
     /**
      * The prefix used for temporary objects.
      */
@@ -195,7 +195,7 @@ public class DbDataStore implements Data
      * in the [databaseType].properties file, initialized with the default value.
      */
     protected String tableSQL = "DATASTORE";
-    
+
     /**
      * This is the property 'createTable'
      * in the [databaseType].properties file, initialized with the default value.
@@ -281,9 +281,9 @@ public class DbDataStore implements Data
     /**
      * All data identifiers that are currently in use are in this set until they are garbage
collected.
      */
-    protected Map<DataIdentifier, WeakReference<DataIdentifier>> inUse = 
+    protected Map<DataIdentifier, WeakReference<DataIdentifier>> inUse =
         Collections.synchronizedMap(new WeakHashMap<DataIdentifier, WeakReference<DataIdentifier>>());
-    
+
     /**
      * The temporary identifiers that are currently in use.
      */
@@ -311,11 +311,11 @@ public class DbDataStore implements Data
      */
     public DataRecord addRecord(InputStream stream) throws DataStoreException {
         ResultSet rs = null;
-        TempFileInputStream fileInput = null;
+        InputStream fileInput = null;
         String id = null, tempId = null;
         try {
             long now;
-            while(true) {
+            while (true) {
                 try {
                     now = System.currentTimeMillis();
                     id = UUID.randomUUID().toString();
@@ -351,7 +351,7 @@ public class DbDataStore implements Data
                 wrapper = new StreamWrapper(in, Integer.MAX_VALUE);
             } else if (STORE_TEMP_FILE.equals(storeStream)) {
                 File temp = moveToTempFile(in);
-                fileInput = new TempFileInputStream(temp);
+                fileInput = new BufferedInputStream(new TempFileInputStream(temp));
                 long length = temp.length();
                 wrapper = new StreamWrapper(fileInput, length);
             } else {
@@ -512,7 +512,7 @@ public class DbDataStore implements Data
             DbUtility.close(rs);
         }
     }
-    
+
     /**
      * {@inheritDoc}
      */
@@ -523,16 +523,16 @@ public class DbDataStore implements Data
         }
         return record;
     }
-    
+
     /**
      * Open the input stream. This method sets those fields of the caller
      * that need to be closed once the input stream is read.
-     * 
+     *
      * @param inputStream the database input stream object
      * @param identifier data identifier
-     * @throws DataStoreException if the data store could not be accessed, 
+     * @throws DataStoreException if the data store could not be accessed,
      *          or if the given identifier is invalid
-     */    
+     */
     InputStream openStream(DbInputStream inputStream, DataIdentifier identifier) throws DataStoreException
{
         ResultSet rs = null;
         try {
@@ -548,7 +548,7 @@ public class DbDataStore implements Data
             } else if (copyWhenReading) {
                 // If we copy while reading, create a temp file and close the stream
                 File temp = moveToTempFile(stream);
-                stream = new TempFileInputStream(temp);
+                stream = new BufferedInputStream(new TempFileInputStream(temp));
                 DbUtility.close(rs);
             } else {
                 stream = new BufferedInputStream(stream);
@@ -560,7 +560,7 @@ public class DbDataStore implements Data
             throw convert("Retrieving database resource ", e);
         }
     }
-    
+
     /**
      * {@inheritDoc}
      */
@@ -574,7 +574,7 @@ public class DbDataStore implements Data
                 createCheckSchemaOperation().run();
             }
         } catch (Exception e) {
-            throw convert("Can not init data store, driver=" + driver + " url=" + url + "
user=" + user + 
+            throw convert("Can not init data store, driver=" + driver + " url=" + url + "
user=" + user +
                     " schemaObjectPrefix=" + schemaObjectPrefix + " tableSQL=" + tableSQL
+ " createTableSQL=" + createTableSQL, e);
         }
     }
@@ -591,7 +591,7 @@ public class DbDataStore implements Data
      * This method is called from the {@link #init(String)} method of this class and returns
a
      * {@link ConnectionHelper} instance which is assigned to the {@code conHelper} field.
Subclasses may
      * override it to return a specialized connection helper.
-     * 
+     *
      * @param dataSrc the {@link DataSource} of this persistence manager
      * @return a {@link ConnectionHelper}
      * @throws Exception on error
@@ -603,7 +603,7 @@ public class DbDataStore implements Data
     /**
      * This method is called from {@link #init(String)} after the
      * {@link #createConnectionHelper(DataSource)} method, and returns a default {@link CheckSchemaOperation}.
-     * 
+     *
      * @return a new {@link CheckSchemaOperation} instance
      */
     protected final CheckSchemaOperation createCheckSchemaOperation() {
@@ -688,7 +688,7 @@ public class DbDataStore implements Data
     /**
      * Get the expanded property value. The following placeholders are supported:
      * ${table}: the table name (the default is DATASTORE) and
-     * ${tablePrefix}: tablePrefix plus schemaObjectPrefix as set in the configuration 
+     * ${tablePrefix}: tablePrefix plus schemaObjectPrefix as set in the configuration
      *
      * @param prop the properties object
      * @param key the key
@@ -927,7 +927,7 @@ public class DbDataStore implements Data
     }
 
     /**
-     * Get the table prefix. 
+     * Get the table prefix.
      *
      * @return the table prefix.
      */
@@ -945,10 +945,10 @@ public class DbDataStore implements Data
     public void setTablePrefix(String tablePrefix) {
         this.tablePrefix = tablePrefix;
     }
-    
+
     /**
      * Get the schema prefix.
-     * 
+     *
      * @return the schema object prefix
      */
     public String getSchemaObjectPrefix() {
@@ -959,12 +959,12 @@ public class DbDataStore implements Data
      * Set the schema object prefix. The default is empty.
      * The table name is constructed like this:
      * ${tablePrefix}${schemaObjectPrefix}${tableName}
-     * 
+     *
      * @param schemaObjectPrefix the new prefix
      */
     public void setSchemaObjectPrefix(String schemaObjectPrefix) {
         this.schemaObjectPrefix = schemaObjectPrefix;
-    }    
+    }
 
     public String getDataSourceName() {
         return dataSourceName;

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbInputStream.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbInputStream.java?rev=924769&r1=924768&r2=924769&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbInputStream.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbInputStream.java
Thu Mar 18 13:37:30 2010
@@ -24,29 +24,27 @@ import org.apache.commons.io.input.AutoC
 import org.apache.jackrabbit.core.data.DataIdentifier;
 import org.apache.jackrabbit.core.data.DataStoreException;
 import org.apache.jackrabbit.core.util.db.DbUtility;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * This class represents an input stream backed by a database. The database
  * objects are only acquired when reading from the stream, and stay open until
  * the stream is closed, fully read, or garbage collected.
+ * <p>
+ * This class does not support mark/reset. It is always to be wrapped
+ * using a BufferedInputStream.
  */
 public class DbInputStream extends AutoCloseInputStream {
 
-    private static Logger log = LoggerFactory.getLogger(DbInputStream.class);
-
     protected DbDataStore store;
     protected DataIdentifier identifier;
     protected boolean endOfStream;
 
     protected ResultSet rs;
-    
 
     /**
      * Create a database input stream for the given identifier.
      * Database access is delayed until the first byte is read from the stream.
-     * 
+     *
      * @param store the database data store
      * @param identifier the data identifier
      */
@@ -58,7 +56,7 @@ public class DbInputStream extends AutoC
 
     /**
      * Open the stream if required.
-     * 
+     *
      * @throws IOException
      */
     protected void openStream() throws IOException {
@@ -126,7 +124,7 @@ public class DbInputStream extends AutoC
         if (in != null) {
             in.close();
             in = null;
-            // some additional database objects 
+            // some additional database objects
             // may need to be closed
             if (rs != null) {
                 DbUtility.close(rs);
@@ -141,7 +139,7 @@ public class DbInputStream extends AutoC
     public long skip(long n) throws IOException {
         if (endOfStream) {
             return -1;
-        }        
+        }
         openStream();
         return in.skip(n);
     }
@@ -152,57 +150,38 @@ public class DbInputStream extends AutoC
     public int available() throws IOException {
         if (endOfStream) {
             return 0;
-        }        
+        }
         openStream();
         return in.available();
     }
 
     /**
-     * {@inheritDoc}
+     * This method does nothing.
      */
     public void mark(int readlimit) {
-        if (endOfStream) {
-            return;
-        } 
-        try {
-            openStream();
-        } catch (IOException e) {
-            log.info("Error getting underlying stream: ", e);
-        }
-        in.mark(readlimit);
+        // do nothing
     }
 
     /**
-     * {@inheritDoc}
+     * This method does nothing.
      */
     public void reset() throws IOException {
-        if (endOfStream) {
-            throw new EOFException();
-        }         
-        openStream();
-        in.reset();
+        // do nothing
     }
 
     /**
-     * {@inheritDoc}
+     * Check whether mark and reset are supported.
+     *
+     * @return false
      */
     public boolean markSupported() {
-        if (endOfStream) {
-            return false;
-        }      
-        try {
-            openStream();
-        } catch (IOException e) {
-            log.info("Error getting underlying stream: ", e);
-            return false;
-        }
-        return in.markSupported();
+        return false;
     }
 
     /**
      * Set the result set of this input stream. This object must be closed once
      * the stream is closed.
-     * 
+     *
      * @param rs the result set
      */
     void setResultSet(ResultSet rs) {

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/TempFileInputStream.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/TempFileInputStream.java?rev=924769&r1=924768&r2=924769&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/TempFileInputStream.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/TempFileInputStream.java
Thu Mar 18 13:37:30 2010
@@ -31,6 +31,9 @@ import org.apache.commons.io.input.AutoC
 /**
  * An input stream from a temporary file. The file is deleted when the stream is
  * closed, fully read, or garbage collected.
+ * <p>
+ * This class does not support mark/reset. It is always to be wrapped
+ * using a BufferedInputStream.
  */
 public class TempFileInputStream extends AutoCloseInputStream {
 
@@ -83,12 +86,20 @@ public class TempFileInputStream extends
         return in.available();
     }
 
+    /**
+     * This method does nothing.
+     */
     public void mark(int readlimit) {
-        in.mark(readlimit);
+        // do nothing
     }
 
+    /**
+     * Check whether mark and reset are supported.
+     *
+     * @return false
+     */
     public boolean markSupported() {
-        return in.markSupported();
+        return false;
     }
 
     public long skip(long n) throws IOException {

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/DBDataStoreTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/DBDataStoreTest.java?rev=924769&r1=924768&r2=924769&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/DBDataStoreTest.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/DBDataStoreTest.java
Thu Mar 18 13:37:30 2010
@@ -16,20 +16,22 @@
  */
 package org.apache.jackrabbit.core.data;
 
+import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.InputStream;
 import java.util.Random;
 
-import junit.framework.TestCase;
-
 import org.apache.commons.io.FileUtils;
 import org.apache.jackrabbit.core.data.db.DbDataStore;
+import org.apache.jackrabbit.core.data.db.DbInputStream;
+import org.apache.jackrabbit.core.util.db.ConnectionFactory;
+import org.apache.jackrabbit.test.JUnitTest;
 
 /**
  * Test the Database Data Store.
  */
-public class DBDataStoreTest extends TestCase {
+public class DBDataStoreTest extends JUnitTest {
 
     private DbDataStore store = new DbDataStore();
 
@@ -41,6 +43,7 @@ public class DBDataStoreTest extends Tes
         FileUtils.deleteQuietly(new File("target/test-db-datastore"));
 
         // Initialize the data store
+        store.setConnectionFactory(new ConnectionFactory());
         store.setUrl("jdbc:derby:target/test-db-datastore/db;create=true");
         store.setDriver("org.apache.derby.jdbc.EmbeddedDriver");
         store.init("target/test-db-datastore");
@@ -82,6 +85,89 @@ public class DBDataStoreTest extends Tes
         }
     }
 
+    public void testDbInputStreamReset() throws Exception {
+        DataRecord record = store.getRecord(identifier);
+        InputStream in = record.getStream();
+        try {
+            // test whether mark and reset works
+            assertTrue(in instanceof DbInputStream);
+            in = new BufferedInputStream(in);
+            assertTrue(in.markSupported());
+            in.mark(data.length);
+            while (-1 != in.read()) {
+                // loop
+            }
+            assertTrue(in.markSupported());
+            try {
+                in.reset();
+            } catch (Exception e) {
+                fail("Unexpected exception while resetting input stream: " + e.getMessage());
+            }
+
+            // test integrity of replayed bytes
+            byte[] replayedBytes = new byte[data.length];
+            int length = in.read(replayedBytes);
+            assertEquals(length, data.length);
+
+            for (int i = 0; i < data.length; i++) {
+                log.append(i + " data: " + data[i] + " replayed: " + replayedBytes[i] + "\n");
+                assertEquals(data[i], replayedBytes[i]);
+            }
+
+            assertEquals(-1, in.read());
+
+
+        } finally {
+            in.close();
+            log.flush();
+        }
+    }
+
+    /*
+    public void testDbInputStreamMarkTwice() throws Exception {
+        DataRecord record = store.getRecord(identifier);
+        InputStream in = record.getStream();
+        try {
+            // test whether mark and reset works
+            assertTrue(in instanceof DbInputStream);
+            assertTrue(in.markSupported());
+            in.mark(data.length);
+
+            // read first 100 bytes
+            for (int i = 0; i < 100; i++) {
+                in.read();
+            }
+
+            in.mark(data.length - 100);
+
+            // read next 150 bytes
+            for (int i = 0; i < 150; i++) {
+                in.read();
+            }
+
+            try {
+                log.append("attempting a reset()\n");
+                in.reset();
+            } catch (Exception e) {
+                fail("Unexpected exception while resetting input stream: " + e.getMessage());
+            }
+
+            // test integrity of replayed bytes
+            byte[] replayedBytes = new byte[data.length];
+            int length = in.read(replayedBytes);
+            assertEquals(length, data.length - 100 - 150);
+
+            for (int i = 0; i < length; i++) {
+                assertEquals(data[i + 100 + 150] & 0xff, replayedBytes[i] & 0xff);
+            }
+
+            assertTrue(-1 == in.read());
+        } finally {
+            in.close();
+        }
+    }
+    */
+
     public void testConcurrentRead() throws Exception {
         InputStream[] streams = new InputStream[10];
 
@@ -103,5 +189,4 @@ public class DBDataStoreTest extends Tes
             streams[i].close();
         }
     }
-
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TempFileInputStreamTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TempFileInputStreamTest.java?rev=924769&r1=924768&r2=924769&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TempFileInputStreamTest.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TempFileInputStreamTest.java
Thu Mar 18 13:37:30 2010
@@ -19,9 +19,11 @@ package org.apache.jackrabbit.core.data;
 import org.apache.jackrabbit.core.data.db.TempFileInputStream;
 import org.apache.jackrabbit.test.JUnitTest;
 
+import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
 
 /**
  * Tests the class TempFileInputStream
@@ -39,4 +41,21 @@ public class TempFileInputStreamTest ext
         in.close();
     }
 
+    public void testMarkReset() throws IOException {
+        File temp = File.createTempFile("test", null);
+        TempFileInputStream.writeToFileAndClose(new ByteArrayInputStream(new byte[10]), temp);
+        InputStream in = new BufferedInputStream(new TempFileInputStream(temp));
+        in.mark(100);
+        for (int i = 0; i < 10; i++) {
+            assertEquals(0, in.read());
+        }
+        assertEquals(-1, in.read());
+        in.reset();
+        for (int i = 0; i < 10; i++) {
+            assertEquals(0, in.read());
+        }
+        assertEquals(-1, in.read());
+        in.close();
+    }
+
 }



Mime
View raw message