You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by th...@apache.org on 2009/05/27 12:18:13 UTC
svn commit: r779081 - in /jackrabbit/trunk/jackrabbit-core/src:
main/java/org/apache/jackrabbit/core/data/
test/java/org/apache/jackrabbit/core/data/
Author: thomasm
Date: Wed May 27 10:18:12 2009
New Revision: 779081
URL: http://svn.apache.org/viewvc?rev=779081&view=rev
Log:
JCR-2067 FileDataStore: only open a stream when really necessary - close() can throw a NullPointerException
Added:
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/LazyFileInputStreamTest.java
Modified:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/LazyFileInputStream.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/TestAll.java
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/LazyFileInputStream.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/LazyFileInputStream.java?rev=779081&r1=779080&r2=779081&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/LazyFileInputStream.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/LazyFileInputStream.java Wed May 27 10:18:12 2009
@@ -17,13 +17,12 @@
package org.apache.jackrabbit.core.data;
import java.io.File;
+import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.apache.commons.io.input.AutoCloseInputStream;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* This input stream delays opening the file until the first byte is read, and
@@ -32,7 +31,10 @@
*/
public class LazyFileInputStream extends AutoCloseInputStream {
- private static Logger log = LoggerFactory.getLogger(LazyFileInputStream.class);
+ /**
+ * The file descriptor to use.
+ */
+ protected final FileDescriptor fd;
/**
* The file to read from.
@@ -47,83 +49,119 @@
protected boolean opened;
/**
- * Create a lazy input stream for the given file.
+ * Creates a new <code>LazyFileInputStream</code> for the given file. If the
+ * file is unreadable, a FileNotFoundException is thrown.
* The file is not opened until the first byte is read from the stream.
- *
+ *
* @param file the file
+ * @throws java.io.FileNotFoundException
*/
- public LazyFileInputStream(File file) throws FileNotFoundException {
+ public LazyFileInputStream(File file)
+ throws FileNotFoundException {
super(null);
if (!file.canRead()) {
throw new FileNotFoundException(file.getPath());
- }
+ }
this.file = file;
+ this.fd = null;
+ }
+
+ /**
+ * Creates a new <code>LazyFileInputStream</code> for the given file
+ * descriptor.
+ * The file is not opened until the first byte is read from the stream.
+ *
+ * @param fdObj
+ */
+ public LazyFileInputStream(FileDescriptor fd) {
+ super(null);
+ this.file = null;
+ this.fd = fd;
+ }
+
+ /**
+ * Creates a new <code>LazyFileInputStream</code> for the given file. If the
+ * file is unreadable, a FileNotFoundException is thrown.
+ *
+ * @param name
+ * @throws java.io.FileNotFoundException
+ */
+ public LazyFileInputStream(String name) throws FileNotFoundException {
+ this(new File(name));
}
/**
* Open the stream if required.
- *
- * @throws IOException
+ *
+ * @throws java.io.IOException
*/
- protected void openStream() throws IOException {
+ protected void open() throws IOException {
if (!opened) {
opened = true;
- in = new FileInputStream(file);
+ if (fd != null) {
+ in = new FileInputStream(fd);
+ } else {
+ in = new FileInputStream(file);
+ }
}
}
-
+
public int read() throws IOException {
- openStream();
+ open();
return super.read();
}
- public int read(byte[] b) throws IOException {
- return read(b, 0, b.length);
- }
-
- public int read(byte[] b, int off, int len) throws IOException {
- openStream();
- return super.read(b, off, len);
+ public int available() throws IOException {
+ open();
+ return super.available();
}
public void close() throws IOException {
// make sure the file is not opened afterwards
opened = true;
- super.close();
+
+ // only close the file if it was in fact opened
+ if (in != null) {
+ super.close();
+ }
}
- public long skip(long n) throws IOException {
- openStream();
- return super.skip(n);
+ public synchronized void reset() throws IOException {
+ open();
+ super.reset();
}
- public int available() throws IOException {
- openStream();
- return super.available();
+ public boolean markSupported() {
+ try {
+ open();
+ } catch (IOException e) {
+ throw new IllegalStateException(e.toString());
+ }
+ return super.markSupported();
}
- public void mark(int readlimit) {
+ public synchronized void mark(int readlimit) {
try {
- openStream();
+ open();
} catch (IOException e) {
- log.info("Error getting underlying stream: ", e);
+ throw new IllegalStateException(e.toString());
}
super.mark(readlimit);
}
- public void reset() throws IOException {
- openStream();
- super.reset();
+ public long skip(long n) throws IOException {
+ open();
+ return super.skip(n);
}
- public boolean markSupported() {
- try {
- openStream();
- } catch (IOException e) {
- log.info("Error getting underlying stream: ", e);
- return false;
- }
- return super.markSupported();
+ public int read(byte[] b) throws IOException {
+ open();
+ return super.read(b, 0, b.length);
+ }
+
+ public int read(byte[] b, int off, int len) throws IOException {
+ open();
+ return super.read(b, off, len);
}
}
Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/LazyFileInputStreamTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/LazyFileInputStreamTest.java?rev=779081&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/LazyFileInputStreamTest.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/LazyFileInputStreamTest.java Wed May 27 10:18:12 2009
@@ -0,0 +1,143 @@
+/*
+ * 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;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+import org.apache.jackrabbit.test.JUnitTest;
+
+/**
+ * Tests the LazyFileInputStream class.
+ */
+public class LazyFileInputStreamTest extends JUnitTest {
+
+ private static final String TEST_FILE = "target/test.txt";
+
+ private File file = new File(TEST_FILE);
+
+ public void setUp() {
+ // Create the test directory
+ new File(TEST_FILE).getParentFile().mkdirs();
+ }
+
+ public void tearDown() {
+ new File(TEST_FILE).delete();
+ }
+
+ private void createFile() throws IOException {
+ FileOutputStream out = new FileOutputStream(file);
+ out.write(new byte[1]);
+ out.close();
+ }
+
+ public void test() throws IOException {
+
+ createFile();
+
+ // test exception if file doesn't exist
+ try {
+ LazyFileInputStream in = new LazyFileInputStream(file.getAbsolutePath() + "XX");
+ in.close();
+ fail();
+ } catch (IOException e) {
+ // expected
+ }
+
+ // test open / close (without reading)
+ LazyFileInputStream in = new LazyFileInputStream(file);
+ in.close();
+
+ // test reading too much and closing too much
+ in = new LazyFileInputStream(file);
+ assertEquals(0, in.read());
+ assertEquals(-1, in.read());
+ assertEquals(-1, in.read());
+ assertEquals(-1, in.read());
+ in.close();
+ in.close();
+ in.close();
+ assertEquals(-1, in.read());
+
+ // test with file name
+ in = new LazyFileInputStream(file.getAbsolutePath());
+ assertEquals(1, in.available());
+ assertEquals(0, in.read());
+ assertEquals(0, in.available());
+ assertEquals(-1, in.read());
+ assertEquals(0, in.available());
+ in.close();
+
+ // test markSupported, mark, and reset
+ in = new LazyFileInputStream(file);
+ assertFalse(in.markSupported());
+ in.mark(1);
+ assertEquals(0, in.read());
+ try {
+ in.reset();
+ fail();
+ } catch (IOException e) {
+ // expected
+ }
+ assertEquals(-1, in.read());
+ in.close();
+
+ // test read(byte[])
+ in = new LazyFileInputStream(file);
+ byte[] test = new byte[2];
+ assertEquals(1, in.read(test));
+ in.close();
+
+ // test read(byte[],int,int)
+ in = new LazyFileInputStream(file);
+ assertEquals(1, in.read(test, 0, 2));
+ in.close();
+
+ // test skip
+ in = new LazyFileInputStream(file);
+ assertEquals(2, in.skip(2));
+ assertEquals(-1, in.read(test));
+ assertEquals(0, in.skip(2));
+ in.close();
+
+ // test with the file descriptor
+ RandomAccessFile ra = new RandomAccessFile(file, "r");
+ in = new LazyFileInputStream(ra.getFD());
+ assertEquals(0, in.read());
+ assertEquals(-1, in.read());
+ in.close();
+ ra.close();
+
+ // test that the file is not opened before reading
+ in = new LazyFileInputStream(file);
+ // this should fail in Windows if the file was opened
+ file.delete();
+
+ createFile();
+
+ // test that the file is closed after reading the last byte
+ in = new LazyFileInputStream(file);
+ assertEquals(0, in.read());
+ assertEquals(-1, in.read());
+ // this should fail in Windows if the file was opened
+ file.delete();
+
+ }
+
+}
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=779081&r1=779080&r2=779081&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 May 27 10:18:12 2009
@@ -32,6 +32,7 @@
*/
public static Test suite() {
TestSuite suite = new TestSuite("Data tests");
+ suite.addTestSuite(LazyFileInputStreamTest.class);
suite.addTestSuite(OpenFilesTest.class);
suite.addTestSuite(DataStoreTest.class);
suite.addTestSuite(NodeTypeTest.class);