summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenoit Lamarche <benoitlamarche@google.com>2014-07-25 12:09:39 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-07-23 19:33:25 +0000
commit5c8ec05f6180f26c73745fead5d14045fc84e6d4 (patch)
tree3e2cd23997c799b803e28cb800380c0893e022f0
parent4a3eaf7d351160a937021fc07fbeb8d2173a066b (diff)
parent4a87cec7f6314b573b7b4ef0fee3af1129f900e1 (diff)
downloadtoolchain_jack-5c8ec05f6180f26c73745fead5d14045fc84e6d4.tar.gz
toolchain_jack-5c8ec05f6180f26c73745fead5d14045fc84e6d4.tar.bz2
toolchain_jack-5c8ec05f6180f26c73745fead5d14045fc84e6d4.zip
Merge "Return errors when writing VFiles w/o closing" into ub-jack
-rw-r--r--sched/src/com/android/sched/vfs/SequentialOutputVDir.java42
-rw-r--r--sched/src/com/android/sched/vfs/direct/DirectDir.java26
-rw-r--r--sched/src/com/android/sched/vfs/direct/DirectFile.java37
-rw-r--r--sched/src/com/android/sched/vfs/zip/OutputZipRootVDir.java7
-rw-r--r--sched/src/com/android/sched/vfs/zip/OutputZipVFile.java36
5 files changed, 134 insertions, 14 deletions
diff --git a/sched/src/com/android/sched/vfs/SequentialOutputVDir.java b/sched/src/com/android/sched/vfs/SequentialOutputVDir.java
new file mode 100644
index 00000000..73320182
--- /dev/null
+++ b/sched/src/com/android/sched/vfs/SequentialOutputVDir.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed 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 com.android.sched.vfs;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.annotation.Nonnull;
+
+
+/**
+ * {@link OutputVDir} that contains {@link OutputVFile}s that must be written to and closed
+ * sequentially.
+ */
+public abstract class SequentialOutputVDir extends AbstractVElement implements OutputVDir {
+
+ @Nonnull
+ private final AtomicBoolean lastVFileOpen = new AtomicBoolean(false);
+
+ public void notifyVFileClosed() {
+ boolean previousState = lastVFileOpen.getAndSet(false);
+ assert previousState;
+ }
+
+ public boolean notifyVFileOpenAndReturnPreviousState() {
+ return lastVFileOpen.getAndSet(true);
+ }
+
+}
diff --git a/sched/src/com/android/sched/vfs/direct/DirectDir.java b/sched/src/com/android/sched/vfs/direct/DirectDir.java
index c097cd57..789b37de 100644
--- a/sched/src/com/android/sched/vfs/direct/DirectDir.java
+++ b/sched/src/com/android/sched/vfs/direct/DirectDir.java
@@ -23,12 +23,12 @@ import com.android.sched.util.file.NotFileOrDirectoryException;
import com.android.sched.util.location.DirectoryLocation;
import com.android.sched.util.location.FileLocation;
import com.android.sched.util.location.Location;
-import com.android.sched.vfs.AbstractVElement;
import com.android.sched.vfs.InputOutputVDir;
import com.android.sched.vfs.InputRootVDir;
import com.android.sched.vfs.InputVElement;
import com.android.sched.vfs.InputVFile;
import com.android.sched.vfs.OutputVFile;
+import com.android.sched.vfs.SequentialOutputVDir;
import com.android.sched.vfs.VPath;
import java.io.File;
@@ -42,7 +42,7 @@ import javax.annotation.Nonnull;
/**
* Directory in the file system.
*/
-public class DirectDir extends AbstractVElement implements InputRootVDir, InputOutputVDir {
+public class DirectDir extends SequentialOutputVDir implements InputRootVDir, InputOutputVDir {
@Nonnull
private final File dir;
@@ -50,10 +50,13 @@ public class DirectDir extends AbstractVElement implements InputRootVDir, InputO
private ArrayList<InputVElement> list;
@Nonnull
private final Location location;
+ @Nonnull
+ private final InputOutputVDir vfsRoot;
public DirectDir(@Nonnull Directory directory) {
dir = directory.getFile();
location = directory.getLocation();
+ vfsRoot = this;
}
public DirectDir(@Nonnull File dir) throws NotFileOrDirectoryException {
@@ -62,6 +65,17 @@ public class DirectDir extends AbstractVElement implements InputRootVDir, InputO
}
this.dir = dir;
location = new FileLocation(dir);
+ vfsRoot = this;
+ }
+
+ DirectDir(@Nonnull File dir, @Nonnull InputOutputVDir vfsRoot)
+ throws NotFileOrDirectoryException {
+ if (!dir.isDirectory()) {
+ throw new NotFileOrDirectoryException(new DirectoryLocation(dir));
+ }
+ this.dir = dir;
+ location = new FileLocation(dir);
+ this.vfsRoot = vfsRoot;
}
@Nonnull
@@ -86,9 +100,9 @@ public class DirectDir extends AbstractVElement implements InputRootVDir, InputO
for (File sub : subs) {
try {
if (sub.isFile()) {
- list.add(new DirectFile(sub));
+ list.add(new DirectFile(sub, vfsRoot));
} else {
- list.add(new DirectDir(sub));
+ list.add(new DirectDir(sub, vfsRoot));
}
} catch (NotFileOrDirectoryException e) {
throw new ConcurrentIOException(e);
@@ -113,7 +127,7 @@ public class DirectDir extends AbstractVElement implements InputRootVDir, InputO
if (!file.isFile()) {
throw new NotFileOrDirectoryException(new FileLocation(file));
}
- return new DirectFile(file);
+ return new DirectFile(file, vfsRoot);
}
@Override
@@ -123,7 +137,7 @@ public class DirectDir extends AbstractVElement implements InputRootVDir, InputO
if (!file.getParentFile().mkdirs() && !file.getParentFile().isDirectory()) {
throw new CannotCreateFileException(new DirectoryLocation(file.getParentFile()));
}
- return new DirectFile(file);
+ return new DirectFile(file, vfsRoot);
}
@Override
diff --git a/sched/src/com/android/sched/vfs/direct/DirectFile.java b/sched/src/com/android/sched/vfs/direct/DirectFile.java
index 63abca02..3bb7fa5b 100644
--- a/sched/src/com/android/sched/vfs/direct/DirectFile.java
+++ b/sched/src/com/android/sched/vfs/direct/DirectFile.java
@@ -19,12 +19,17 @@ package com.android.sched.vfs.direct;
import com.android.sched.util.location.FileLocation;
import com.android.sched.util.location.Location;
import com.android.sched.vfs.AbstractVElement;
+import com.android.sched.vfs.InputOutputVDir;
import com.android.sched.vfs.InputOutputVFile;
+import com.android.sched.vfs.OutputVDir;
+import com.android.sched.vfs.SequentialOutputVDir;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -37,9 +42,12 @@ public class DirectFile extends AbstractVElement implements InputOutputVFile {
@Nonnull
private final File file;
+ @Nonnull
+ private final InputOutputVDir vfsRoot;
- public DirectFile(@Nonnull File file) {
+ public DirectFile(@Nonnull File file, @Nonnull InputOutputVDir vfsRoot) {
this.file = file;
+ this.vfsRoot = vfsRoot;
}
@Nonnull
@@ -51,7 +59,13 @@ public class DirectFile extends AbstractVElement implements InputOutputVFile {
@Nonnull
@Override
public OutputStream openWrite() throws FileNotFoundException {
- return new FileOutputStream(file);
+ if (vfsRoot instanceof SequentialOutputVDir) {
+ if (((SequentialOutputVDir) vfsRoot).notifyVFileOpenAndReturnPreviousState()) {
+ throw new AssertionError(getLocation().getDescription()
+ + " cannot be written to because a previous stream has not been closed.");
+ }
+ }
+ return new VFileOutputStream(new FileOutputStream(file), vfsRoot);
}
@Nonnull
@@ -70,4 +84,23 @@ public class DirectFile extends AbstractVElement implements InputOutputVFile {
public boolean isVDir() {
return false;
}
+
+ private static class VFileOutputStream extends FilterOutputStream {
+
+ private final OutputVDir vfsRoot;
+
+ public VFileOutputStream(@Nonnull OutputStream out, @Nonnull OutputVDir vfsRoot) {
+ super(out);
+ this.vfsRoot = vfsRoot;
+ }
+
+ @Override
+ public void close() throws IOException {
+ super.close();
+ if (vfsRoot instanceof SequentialOutputVDir) {
+ ((SequentialOutputVDir) vfsRoot).notifyVFileClosed();
+ }
+ }
+
+ }
}
diff --git a/sched/src/com/android/sched/vfs/zip/OutputZipRootVDir.java b/sched/src/com/android/sched/vfs/zip/OutputZipRootVDir.java
index 48c08b78..a1962d18 100644
--- a/sched/src/com/android/sched/vfs/zip/OutputZipRootVDir.java
+++ b/sched/src/com/android/sched/vfs/zip/OutputZipRootVDir.java
@@ -19,9 +19,9 @@ package com.android.sched.vfs.zip;
import com.android.sched.util.file.OutputZipFile;
import com.android.sched.util.location.Location;
import com.android.sched.util.location.ZipLocation;
-import com.android.sched.vfs.AbstractVElement;
import com.android.sched.vfs.OutputVDir;
import com.android.sched.vfs.OutputVFile;
+import com.android.sched.vfs.SequentialOutputVDir;
import com.android.sched.vfs.VElement;
import com.android.sched.vfs.VPath;
@@ -36,7 +36,7 @@ import javax.annotation.Nonnull;
/**
* A root {@link OutputVDir} backed by a zip archive.
*/
-public class OutputZipRootVDir extends AbstractVElement implements OutputVDir, Closeable {
+public class OutputZipRootVDir extends SequentialOutputVDir implements OutputVDir, Closeable {
@Nonnull
protected final HashMap<String, VElement> subs = new HashMap<String, VElement>();
@@ -65,7 +65,8 @@ public class OutputZipRootVDir extends AbstractVElement implements OutputVDir, C
@Override
@Nonnull
public OutputVFile createOutputVFile(@Nonnull VPath path) {
- return new OutputZipVFile(zos, new ZipEntry(path.getPathAsString(getSeparator())), zipFile);
+ return new OutputZipVFile(zos, new ZipEntry(path.getPathAsString(getSeparator())), zipFile,
+ this);
}
@Override
diff --git a/sched/src/com/android/sched/vfs/zip/OutputZipVFile.java b/sched/src/com/android/sched/vfs/zip/OutputZipVFile.java
index 5daecc89..159c5df8 100644
--- a/sched/src/com/android/sched/vfs/zip/OutputZipVFile.java
+++ b/sched/src/com/android/sched/vfs/zip/OutputZipVFile.java
@@ -19,10 +19,12 @@ package com.android.sched.vfs.zip;
import com.android.sched.util.file.OutputZipFile;
import com.android.sched.util.location.Location;
import com.android.sched.util.location.ZipLocation;
-import com.android.sched.util.stream.UncloseableOutputStream;
import com.android.sched.vfs.AbstractVElement;
+import com.android.sched.vfs.OutputVDir;
import com.android.sched.vfs.OutputVFile;
+import com.android.sched.vfs.SequentialOutputVDir;
+import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
@@ -38,19 +40,28 @@ class OutputZipVFile extends AbstractVElement implements OutputVFile {
private final ZipEntry entry;
@Nonnull
private final Location location;
+ @Nonnull
+ private final OutputVDir vfsRoot;
OutputZipVFile(@Nonnull ZipOutputStream zos, @Nonnull ZipEntry entry,
- @Nonnull OutputZipFile zipFile) {
+ @Nonnull OutputZipFile zipFile, @Nonnull OutputVDir vfsRoot) {
this.zos = zos;
this.entry = entry;
location = new ZipLocation(zipFile.getLocation(), entry);
+ this.vfsRoot = vfsRoot;
}
@Nonnull
@Override
public OutputStream openWrite() throws IOException {
zos.putNextEntry(entry);
- return new UncloseableOutputStream(zos);
+ if (vfsRoot instanceof SequentialOutputVDir) {
+ if (((SequentialOutputVDir) vfsRoot).notifyVFileOpenAndReturnPreviousState()) {
+ throw new AssertionError(getLocation().getDescription()
+ + " cannot be written to because a previous stream has not been closed.");
+ }
+ }
+ return new UnclosableVFileOutputStream(zos, vfsRoot);
}
@Override
@@ -63,4 +74,23 @@ class OutputZipVFile extends AbstractVElement implements OutputVFile {
public boolean isVDir() {
return false;
}
+
+ private static class UnclosableVFileOutputStream extends FilterOutputStream {
+
+ private final OutputVDir vfsRoot;
+
+ public UnclosableVFileOutputStream(@Nonnull OutputStream out, @Nonnull OutputVDir vfsRoot) {
+ super(out);
+ this.vfsRoot = vfsRoot;
+ }
+
+ @Override
+ public void close() {
+ // we do not actually close the stream
+ if (vfsRoot instanceof SequentialOutputVDir) {
+ ((SequentialOutputVDir) vfsRoot).notifyVFileClosed();
+ }
+ }
+
+ }
}