You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by un...@apache.org on 2014/09/17 13:20:50 UTC
svn commit: r1625518 - in /jackrabbit/trunk:
jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/
jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/
jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/db/
jackrabbit-d...
Author: unico
Date: Wed Sep 17 11:20:49 2014
New Revision: 1625518
URL: http://svn.apache.org/r1625518
Log:
JCR-3811 Allow retrying of failed journal entry database inserts.
- Add a new ResettableTempFileInputStream that is capable of being reset to the beginning of the stream in order to allow re-reading
- Simplify TempFileInputStream to only be responsible for removing the temporary file when it is closed
- Fix bug in ConnectionHelper where resources were not cleaned up when a SQL call would fail in batch mode
- Fix bug in DbDataStore where temporary file was never removed in addRecord
Added:
jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/db/ResettableTempFileInputStream.java
jackrabbit/trunk/jackrabbit-data/src/test/java/org/apache/jackrabbit/core/data/db/
jackrabbit/trunk/jackrabbit-data/src/test/java/org/apache/jackrabbit/core/data/db/ResettableTempFileInputStreamTest.java
jackrabbit/trunk/jackrabbit-data/src/test/java/org/apache/jackrabbit/core/data/db/TempFileInputStreamTest.java
Removed:
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/journal/AppendRecord.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TestAll.java
jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java
jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/db/TempFileInputStream.java
jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionHelper.java
jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/util/db/StreamWrapper.java
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/AppendRecord.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/AppendRecord.java?rev=1625518&r1=1625517&r2=1625518&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/AppendRecord.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/AppendRecord.java Wed Sep 17 11:20:49 2014
@@ -16,19 +16,19 @@
*/
package org.apache.jackrabbit.core.journal;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
+import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.BufferedOutputStream;
+
+import org.apache.jackrabbit.core.data.db.ResettableTempFileInputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Default temporary record used for appending to some journal.
@@ -298,7 +298,7 @@ public class AppendRecord extends Abstra
private InputStream openInput() throws JournalException {
if (file != null) {
try {
- return new FileInputStream(file);
+ return new ResettableTempFileInputStream(file);
} catch (IOException e) {
String msg = "Unable to open file input on: " + file.getPath();
throw new JournalException(msg, e);
Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TestAll.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TestAll.java?rev=1625518&r1=1625517&r2=1625518&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TestAll.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TestAll.java Wed Sep 17 11:20:49 2014
@@ -48,7 +48,6 @@ public class TestAll extends TestCase {
suite.addTestSuite(NodeTypeTest.class);
suite.addTestSuite(OpenFilesTest.class);
suite.addTestSuite(PersistenceManagerIteratorTest.class);
- suite.addTestSuite(TempFileInputStreamTest.class);
suite.addTestSuite(TestTwoGetStreams.class);
suite.addTestSuite(WriteWhileReadingTest.class);
suite.addTestSuite(GCSubtreeMoveTest.class);
Modified: jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java?rev=1625518&r1=1625517&r2=1625518&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java (original)
+++ jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java Wed Sep 17 11:20:49 2014
@@ -16,6 +16,7 @@
*/
package org.apache.jackrabbit.core.data.db;
+import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.CountingInputStream;
import org.apache.jackrabbit.core.data.AbstractDataStore;
import org.apache.jackrabbit.core.data.DataIdentifier;
@@ -35,8 +36,10 @@ import org.slf4j.LoggerFactory;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.security.DigestInputStream;
import java.security.MessageDigest;
@@ -349,7 +352,7 @@ public class DbDataStore extends Abstrac
} else if (STORE_TEMP_FILE.equals(storeStream)) {
File temp = moveToTempFile(in);
long length = temp.length();
- wrapper = new StreamWrapper(new TempFileInputStream(temp, true), length);
+ wrapper = new StreamWrapper(new ResettableTempFileInputStream(temp), length);
} else {
throw new DataStoreException("Unsupported stream store algorithm: " + storeStream);
}
@@ -471,10 +474,20 @@ public class DbDataStore extends Abstrac
*/
private File moveToTempFile(InputStream in) throws IOException {
File temp = File.createTempFile("dbRecord", null);
- TempFileInputStream.writeToFileAndClose(in, temp);
+ writeToFileAndClose(in, temp);
return temp;
}
+ private void writeToFileAndClose(InputStream in, File file) throws IOException {
+ OutputStream out = new FileOutputStream(file);
+ try {
+ IOUtils.copy(in, out);
+ } finally {
+ IOUtils.closeQuietly(out);
+ IOUtils.closeQuietly(in);
+ }
+ }
+
public synchronized void deleteRecord(DataIdentifier identifier) throws DataStoreException {
try {
conHelper.exec(deleteSQL, identifier.toString());
@@ -586,7 +599,7 @@ public class DbDataStore extends Abstrac
} else if (copyWhenReading) {
// If we copy while reading, create a temp file and close the stream
File temp = moveToTempFile(stream);
- stream = new BufferedInputStream(new TempFileInputStream(temp, false));
+ stream = new BufferedInputStream(new TempFileInputStream(temp));
DbUtility.close(rs);
} else {
stream = new BufferedInputStream(stream);
Added: jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/db/ResettableTempFileInputStream.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/db/ResettableTempFileInputStream.java?rev=1625518&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/db/ResettableTempFileInputStream.java (added)
+++ jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/db/ResettableTempFileInputStream.java Wed Sep 17 11:20:49 2014
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.data.db;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+
+/**
+ * TempFileInputStream that can be reset in order to allow the
+ * ConnectionHelper to retry SQL execution in case of failure.
+ */
+public class ResettableTempFileInputStream extends TempFileInputStream {
+
+ private final FileChannel fileChannel;
+ private long mark = 0;
+
+ public ResettableTempFileInputStream(final File file) throws FileNotFoundException {
+ this(new FileInputStream(file), file);
+ }
+
+ private ResettableTempFileInputStream(final FileInputStream in, final File file) {
+ super(in, file);
+ this.fileChannel = in.getChannel();
+ }
+
+ @Override
+ public boolean markSupported() {
+ return true;
+ }
+
+ @Override
+ public synchronized void mark(int readlimit) {
+ try {
+ mark = fileChannel.position();
+ } catch (IOException ex) {
+ mark = -1;
+ }
+ }
+
+ @Override
+ public synchronized void reset() throws IOException {
+ if (mark == -1) {
+ throw new IOException("Mark failed");
+ }
+ fileChannel.position(mark);
+ }
+}
Modified: jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/db/TempFileInputStream.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/db/TempFileInputStream.java?rev=1625518&r1=1625517&r2=1625518&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/db/TempFileInputStream.java (original)
+++ jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/data/db/TempFileInputStream.java Wed Sep 17 11:20:49 2014
@@ -16,133 +16,42 @@
*/
package org.apache.jackrabbit.core.data.db;
-import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
+import java.io.FilterInputStream;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.io.input.AutoCloseInputStream;
+import org.apache.commons.io.input.ClosedInputStream;
/**
* 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.
+ * closed or garbage collected.
*/
-public class TempFileInputStream extends AutoCloseInputStream {
+public class TempFileInputStream extends FilterInputStream {
private final File file;
- private boolean closed;
- private boolean delayedResourceCleanup = true;
- /**
- * Copy the data to a file and close the input stream afterwards.
- *
- * @param in the input stream
- * @param file the target file
- * @return the size of the file
- */
- public static long writeToFileAndClose(InputStream in, File file) throws IOException {
- OutputStream out = new FileOutputStream(file);
- IOUtils.copy(in, out);
- out.close();
- in.close();
- return file.length();
+ public TempFileInputStream(File file) throws FileNotFoundException {
+ this(new FileInputStream(file), file);
}
- /**
- * Construct a new temporary file input stream.
- * The file is deleted if the input stream is closed or fully read and
- * delayedResourceCleanup was set to true. Otherwise you must call {@link #deleteFile()}.
- * Deleting is only attempted once.
- *
- * @param file the temporary file
- * @param delayedResourceCleanup
- */
- public TempFileInputStream(File file, boolean delayedResourceCleanup) throws FileNotFoundException {
- super(new BufferedInputStream(new FileInputStream(file)));
+ protected TempFileInputStream(FileInputStream in, File file) {
+ super(in);
this.file = file;
- this.delayedResourceCleanup = delayedResourceCleanup;
- }
-
- public File getFile() {
- return file;
- }
-
- public void deleteFile() {
- file.delete();
- }
-
- private int closeIfEOF(int read) throws IOException {
- if (read < 0) {
- close();
- }
- return read;
}
+ @Override
public void close() throws IOException {
- if (!closed) {
- in.close();
- if (!delayedResourceCleanup) {
- deleteFile();
- }
- closed = true;
- }
- }
-
- public int available() throws IOException {
- return in.available();
- }
-
- /**
- * This method does nothing.
- */
- public void mark(int readlimit) {
- // do nothing
- }
-
- /**
- * Check whether mark and reset are supported.
- *
- * @return false
- */
- public boolean markSupported() {
- return false;
- }
-
- public long skip(long n) throws IOException {
- return in.skip(n);
- }
-
- public void reset() throws IOException {
- in.reset();
- }
-
- public int read(byte[] b, int off, int len) throws IOException {
- if (closed) {
- return -1;
- }
- return closeIfEOF(in.read(b, off, len));
- }
-
- public int read(byte[] b) throws IOException {
- if (closed) {
- return -1;
- }
- return closeIfEOF(in.read(b));
+ in.close();
+ in = new ClosedInputStream();
+ file.delete();
}
- public int read() throws IOException {
- if (closed) {
- return -1;
- }
- return closeIfEOF(in.read());
+ @Override
+ protected void finalize() throws Throwable {
+ close();
+ super.finalize();
}
}
Modified: jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionHelper.java?rev=1625518&r1=1625517&r2=1625518&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionHelper.java (original)
+++ jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/util/db/ConnectionHelper.java Wed Sep 17 11:20:49 2014
@@ -531,38 +531,40 @@ public class ConnectionHelper {
}
public final T doTry() throws SQLException {
- if (inBatchMode()) {
- return call();
- } else {
- boolean sleepInterrupted = false;
- int failures = 0;
- SQLException lastException = null;
- while (!sleepInterrupted && (blockOnConnectionLoss || failures <= RETRIES)) {
- try {
- T object = call();
- cleanupParamResources();
- return object;
- } catch (SQLException e) {
- lastException = e;
- }
- log.error("Failed to execute SQL (stacktrace on DEBUG log level): " + lastException);
- log.debug("Failed to execute SQL", lastException);
- if (!resetParamResources()) {
- break; // don't try again if streams cannot be reset
- }
- failures++;
- if (blockOnConnectionLoss || failures <= RETRIES) { // if we're going to try again
+ try {
+ if (inBatchMode()) {
+ return call();
+ } else {
+ boolean sleepInterrupted = false;
+ int failures = 0;
+ SQLException lastException = null;
+ while (!sleepInterrupted && (blockOnConnectionLoss || failures <= RETRIES)) {
try {
- Thread.sleep(SLEEP_BETWEEN_RETRIES_MS);
- } catch (InterruptedException e1) {
- Thread.currentThread().interrupt();
- sleepInterrupted = true;
- log.error("Interrupted: canceling retry");
+ return call();
+ } catch (SQLException e) {
+ lastException = e;
+ }
+ log.error("Failed to execute SQL (stacktrace on DEBUG log level): " + lastException);
+ log.debug("Failed to execute SQL", lastException);
+ if (!resetParamResources()) {
+ log.warn("Could not reset parameters: not retrying SQL call");
+ break;
+ }
+ failures++;
+ if (blockOnConnectionLoss || failures <= RETRIES) { // if we're going to try again
+ try {
+ Thread.sleep(SLEEP_BETWEEN_RETRIES_MS);
+ } catch (InterruptedException e1) {
+ Thread.currentThread().interrupt();
+ sleepInterrupted = true;
+ log.error("Interrupted: canceling retry");
+ }
}
}
+ throw lastException;
}
+ } finally {
cleanupParamResources();
- throw lastException;
}
}
@@ -570,15 +572,13 @@ public class ConnectionHelper {
/**
* Cleans up the Parameter resources that are not automatically closed or deleted.
- *
- * @param params
*/
protected void cleanupParamResources() {
for (int i = 0; params != null && i < params.length; i++) {
Object p = params[i];
if (p instanceof StreamWrapper) {
StreamWrapper wrapper = (StreamWrapper) p;
- wrapper.cleanupResources();
+ wrapper.closeStream();
}
}
}
@@ -589,7 +589,6 @@ public class ConnectionHelper {
if (p instanceof StreamWrapper) {
StreamWrapper wrapper = (StreamWrapper) p;
if(!wrapper.resetStream()) {
- wrapper.cleanupResources();
return false;
}
}
Modified: jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/util/db/StreamWrapper.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/util/db/StreamWrapper.java?rev=1625518&r1=1625517&r2=1625518&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/util/db/StreamWrapper.java (original)
+++ jackrabbit/trunk/jackrabbit-data/src/main/java/org/apache/jackrabbit/core/util/db/StreamWrapper.java Wed Sep 17 11:20:49 2014
@@ -16,18 +16,17 @@
*/
package org.apache.jackrabbit.core.util.db;
-import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
-import org.apache.jackrabbit.core.data.db.TempFileInputStream;
+import org.apache.commons.io.input.CloseShieldInputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class StreamWrapper {
- static Logger log = LoggerFactory.getLogger(StreamWrapper.class);
+ private final Logger log = LoggerFactory.getLogger(StreamWrapper.class);
private InputStream stream;
private final long size;
@@ -37,8 +36,7 @@ public class StreamWrapper {
* safely be passed as a parameter to the {@link ConnectionHelper#exec(String, Object...)},
* {@link ConnectionHelper#exec(String, Object[], boolean, int)} and
* {@link ConnectionHelper#update(String, Object[])} methods.
- * If the wrapped Stream is a {@link TempFileInputStream} it will be wrapped again by a {@link BufferedInputStream}.
- *
+ *
* @param in the InputStream to wrap
* @param size the size of the input stream
*/
@@ -48,48 +46,30 @@ public class StreamWrapper {
}
public InputStream getStream() {
- if (stream instanceof TempFileInputStream) {
- return new BufferedInputStream(stream);
- }
- return stream;
+ return new CloseShieldInputStream(stream);
}
public long getSize() {
return size;
}
- /**
- * Cleans up the internal Resources
- */
- public void cleanupResources() {
- if (stream instanceof TempFileInputStream) {
- try {
- stream.close();
- ((TempFileInputStream) stream).deleteFile();
- } catch (IOException e) {
- log.warn("Unable to cleanup the TempFileInputStream");
- }
+ public void closeStream() {
+ try {
+ stream.close();
+ } catch (IOException e) {
+ log.error("Error while closing stream", e);
}
- }
+ }
/**
* Resets the internal InputStream that it could be re-read.<br>
* Is used from {@link RetryManager} if a {@link SQLException} has occurred.<br>
+ * It relies on the assumption that the InputStream was not marked anywhere
+ * during reading so that resetting it moves the cursor to the beginning of the stream.
*
* @return returns true if it was able to reset the Stream
*/
public boolean resetStream() {
- if (stream instanceof TempFileInputStream) {
- try {
- TempFileInputStream tempFileInputStream = (TempFileInputStream) stream;
- // Close it if it is not already closed ...
- tempFileInputStream.close();
- stream = new TempFileInputStream(tempFileInputStream.getFile(), true);
- return true;
- } catch (Exception e) {
- log.warn("Failed to create a new TempFileInputStream", e);
- }
- }
try {
stream.reset();
return true;
Added: jackrabbit/trunk/jackrabbit-data/src/test/java/org/apache/jackrabbit/core/data/db/ResettableTempFileInputStreamTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-data/src/test/java/org/apache/jackrabbit/core/data/db/ResettableTempFileInputStreamTest.java?rev=1625518&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-data/src/test/java/org/apache/jackrabbit/core/data/db/ResettableTempFileInputStreamTest.java (added)
+++ jackrabbit/trunk/jackrabbit-data/src/test/java/org/apache/jackrabbit/core/data/db/ResettableTempFileInputStreamTest.java Wed Sep 17 11:20:49 2014
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.data.db;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+
+import junit.framework.TestCase;
+import static org.junit.Assume.assumeTrue;
+
+public class ResettableTempFileInputStreamTest extends TestCase {
+
+ public void testResetStreamAllowsReadAgain() throws Exception {
+ final File tmp = createTemporaryFileWithContents(new byte[1]);
+ ResettableTempFileInputStream in = null;
+ try {
+ in = new ResettableTempFileInputStream(tmp);
+ assertEquals(0, in.read());
+ assertEquals(-1, in.read());
+ in.reset();
+ assertEquals(0, in.read());
+ assertEquals(-1, in.read());
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ }
+
+ public void testMarkStreamAllowsReadFromMark() throws Exception {
+ final File tmp = createTemporaryFileWithContents(createTestByteArray());
+ ResettableTempFileInputStream in = null;
+ try {
+ in = new ResettableTempFileInputStream(tmp);
+ assumeTrue(in.read(new byte[5]) == 5);
+ in.mark(Integer.MAX_VALUE);
+ assumeTrue(in.read(new byte[5]) == 5);
+ in.reset();
+ assertEquals(5, in.read());
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ }
+
+ private File createTemporaryFileWithContents(byte[] data) throws IOException {
+ final File tmp = File.createTempFile("test", ".bin");
+ FileUtils.writeByteArrayToFile(tmp, data);
+ return tmp;
+ }
+
+ private byte[] createTestByteArray() {
+ byte[] bytes = new byte[10];
+ for (int i = 0; i < 10; i++) {
+ bytes[i] = (byte) i;
+ }
+ return bytes;
+ }
+}
Added: jackrabbit/trunk/jackrabbit-data/src/test/java/org/apache/jackrabbit/core/data/db/TempFileInputStreamTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-data/src/test/java/org/apache/jackrabbit/core/data/db/TempFileInputStreamTest.java?rev=1625518&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-data/src/test/java/org/apache/jackrabbit/core/data/db/TempFileInputStreamTest.java (added)
+++ jackrabbit/trunk/jackrabbit-data/src/test/java/org/apache/jackrabbit/core/data/db/TempFileInputStreamTest.java Wed Sep 17 11:20:49 2014
@@ -0,0 +1,26 @@
+package org.apache.jackrabbit.core.data.db;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+public class TempFileInputStreamTest extends TestCase {
+
+ private File tmp;
+ private TempFileInputStream in;
+
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ tmp = File.createTempFile("test", ".bin");
+ in = new TempFileInputStream(tmp);
+ }
+
+ public void testFileIsDeletedWhenStreamIsClosed() throws Exception {
+ assertTrue(tmp.exists());
+ in.close();
+ assertFalse(tmp.exists());
+ }
+
+}