diff options
author | Benoit Lamarche <benoitlamarche@google.com> | 2015-01-26 18:09:38 +0100 |
---|---|---|
committer | Benoit Lamarche <benoitlamarche@google.com> | 2015-01-27 14:37:48 +0100 |
commit | a67dc42085d6f9fa9d4dfcccd908a6a7645af70a (patch) | |
tree | 529452cb954e4810172ea9e0ea14910c8b6b2792 | |
parent | 4d7a9d313dfa7251c9ca5cd3cf6d47cc0723fb53 (diff) | |
download | toolchain_jack-a67dc42085d6f9fa9d4dfcccd908a6a7645af70a.zip toolchain_jack-a67dc42085d6f9fa9d4dfcccd908a6a7645af70a.tar.gz toolchain_jack-a67dc42085d6f9fa9d4dfcccd908a6a7645af70a.tar.bz2 |
Add VFSToVFSWrapper and ReadWriteZipFS
Change-Id: I447734418fb04e2e0e3186dcbb1c37c5b769e2d4
-rw-r--r-- | sched/src/com/android/sched/vfs/ReadWriteZipFS.java | 101 | ||||
-rw-r--r-- | sched/src/com/android/sched/vfs/VFSToVFSWrapper.java | 162 | ||||
-rw-r--r-- | sched/tests/com/android/sched/vfs/VFSTest.java | 36 |
3 files changed, 299 insertions, 0 deletions
diff --git a/sched/src/com/android/sched/vfs/ReadWriteZipFS.java b/sched/src/com/android/sched/vfs/ReadWriteZipFS.java new file mode 100644 index 0000000..1aa0ca6 --- /dev/null +++ b/sched/src/com/android/sched/vfs/ReadWriteZipFS.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2015 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 com.google.common.io.Files; + +import com.android.sched.util.file.CannotCreateFileException; +import com.android.sched.util.file.CannotSetPermissionException; +import com.android.sched.util.file.Directory; +import com.android.sched.util.file.FileAlreadyExistsException; +import com.android.sched.util.file.FileOrDirectory.ChangePermission; +import com.android.sched.util.file.FileOrDirectory.Existence; +import com.android.sched.util.file.FileOrDirectory.Permission; +import com.android.sched.util.file.FileUtils; +import com.android.sched.util.file.NoSuchFileException; +import com.android.sched.util.file.NotDirectoryException; +import com.android.sched.util.file.OutputZipFile; +import com.android.sched.util.file.WrongPermissionException; +import com.android.sched.util.location.Location; + +import java.io.File; +import java.io.IOException; + +import javax.annotation.Nonnull; + +/** + * A {@link VFS} backed by a real filesystem directory, compressed into a zip archive when closed. + */ +public class ReadWriteZipFS implements VFS { + + @Nonnull + private final VFSToVFSWrapper vfs; + @Nonnull + private final File dir; + + public ReadWriteZipFS(@Nonnull OutputZipFile file) + throws NotDirectoryException, + WrongPermissionException, + CannotSetPermissionException, + NoSuchFileException, + FileAlreadyExistsException, + CannotCreateFileException { + int permissions = Permission.READ | Permission.WRITE; + dir = Files.createTempDir(); + DirectFS workVFS = new DirectFS(new Directory(dir.getPath(), null, Existence.MUST_EXIST, + permissions, ChangePermission.NOCHANGE), permissions); + WriteZipFS finalVFS = new WriteZipFS(file); + this.vfs = new VFSToVFSWrapper(workVFS, finalVFS); + } + + @Override + @Nonnull + public Location getLocation() { + return vfs.getLocation(); + } + + @Override + public void close() throws IOException { + vfs.close(); + if (dir.exists()) { + FileUtils.deleteDir(dir); + } + } + + @Override + @Nonnull + public String getDescription() { + return "zip archive writer that uses a temporary directory"; + } + + @Override + @Nonnull + public String getPath() { + return vfs.getPath(); + } + + @Override + @Nonnull + public VDir getRootDir() { + return vfs.getRootDir(); + } + + @Override + public boolean needsSequentialWriting() { + return vfs.needsSequentialWriting(); + } +} diff --git a/sched/src/com/android/sched/vfs/VFSToVFSWrapper.java b/sched/src/com/android/sched/vfs/VFSToVFSWrapper.java new file mode 100644 index 0000000..3e380a6 --- /dev/null +++ b/sched/src/com/android/sched/vfs/VFSToVFSWrapper.java @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2015 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 com.android.sched.util.file.CannotCreateFileException; +import com.android.sched.util.file.WrongPermissionException; +import com.android.sched.util.location.Location; +import com.android.sched.util.stream.ByteStreamSucker; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Collections; +import java.util.EnumSet; +import java.util.Set; + +import javax.annotation.Nonnull; + +/** + * A double {@link VFS} wrapper that uses a work {@link VFS} during its life, and dumps it contents + * into a final {@link VFS} when it is closed. + */ +public class VFSToVFSWrapper implements VFS { + + @Nonnull + private final BaseVFS<BaseVDir, BaseVFile> workVFS; + @Nonnull + private final BaseVFS<BaseVDir, BaseVFile> finalVFS; + @Nonnull + private final Set<Capabilities> capabilities; + + private boolean closed = false; + + @SuppressWarnings("unchecked") + public VFSToVFSWrapper(@Nonnull BaseVFS<? extends BaseVDir, ? extends BaseVFile> workVFS, + @Nonnull BaseVFS<? extends BaseVDir, ? extends BaseVFile> finalVFS) { + this.workVFS = (BaseVFS<BaseVDir, BaseVFile>) workVFS; + this.finalVFS = (BaseVFS<BaseVDir, BaseVFile>) finalVFS; + + Set<Capabilities> capabilities = EnumSet.noneOf(Capabilities.class); + for (Capabilities capability : workVFS.getCapabilities()) { + switch (capability) { + case CASE_SENSITIVE: + if (finalVFS.getCapabilities().contains(capability)) { + // both VFSes need to support case sensitivity for this wrapper to support it + capabilities.add(capability); + } + break; + case DIGEST: + capabilities.add(capability); + break; + case PARALLEL_READ: + capabilities.add(capability); + break; + case PARALLEL_WRITE: + capabilities.add(capability); + break; + case READ: + capabilities.add(capability); + break; + case UNIQUE_ELEMENT: + capabilities.add(capability); + break; + case WRITE: + capabilities.add(capability); + break; + default: + throw new AssertionError(); + } + } + this.capabilities = Collections.unmodifiableSet(capabilities); + } + + @Override + @Nonnull + public Location getLocation() { + return finalVFS.getLocation(); + } + + @Override + public void close() throws CannotCreateFileException, WrongPermissionException, IOException { + if (!closed) { + dumpToDir(getRootDir(), finalVFS.getRootDir()); + finalVFS.close(); + workVFS.close(); + closed = true; + } + } + + private void dumpToDir(VDir srcRootDir, VDir destRootDir) throws CannotCreateFileException, + WrongPermissionException, IOException { + for (VElement element : srcRootDir.list()) { + String elementName = element.getName(); + if (element.isVDir()) { + VDir dir = destRootDir.createVDir(elementName); + dumpToDir((VDir) element, dir); + } else { + VFile file = destRootDir.createVFile(elementName); + InputStream is = null; + OutputStream os = null; + try { + is = ((VFile) element).openRead(); + os = file.openWrite(); + ByteStreamSucker sucker = new ByteStreamSucker(is, os); + sucker.suck(); + } finally { + if (is != null) { + is.close(); + } + if (os != null) { + os.close(); + } + } + } + } + + } + + @Override + @Nonnull + public String getDescription() { + return "a VFS-to-VFS wrapper"; + } + + @Override + @Nonnull + public String getPath() { + return finalVFS.getPath(); + } + + @Override + @Nonnull + public VDir getRootDir() { + return workVFS.getRootDir(); + } + + @Override + public boolean needsSequentialWriting() { + return workVFS.needsSequentialWriting(); + } + + @Override + @Nonnull + public Set<Capabilities> getCapabilities() { + return this.capabilities; + } + +} diff --git a/sched/tests/com/android/sched/vfs/VFSTest.java b/sched/tests/com/android/sched/vfs/VFSTest.java index c9b1981..401e3d1 100644 --- a/sched/tests/com/android/sched/vfs/VFSTest.java +++ b/sched/tests/com/android/sched/vfs/VFSTest.java @@ -504,6 +504,42 @@ public class VFSTest { Assert.assertEquals("dirB/dirBB/fileBB1", readFromFile(fileBB1)); } + @Test + public void testReadWriteZipFS() + throws NotDirectoryException, + CannotCreateFileException, + WrongPermissionException, + CannotSetPermissionException, + NoSuchFileException, + FileAlreadyExistsException, + IOException { + File file = null; + InputOutputVFS zipVFS = null; + InputZipVFS inputZipVFS = null; + try { + file = File.createTempFile("vfs", ".zip"); + String path = file.getAbsolutePath(); + zipVFS = new GenericInputOutputVFS(new ReadWriteZipFS( + new OutputZipFile(path, null, Existence.MAY_EXIST, ChangePermission.NOCHANGE))); + testOutputVFS(zipVFS); + testInputVFS(zipVFS); + zipVFS.close(); + inputZipVFS = new InputZipVFS( + new InputZipFile(path, null, Existence.MUST_EXIST, ChangePermission.NOCHANGE)); + testInputVFS(inputZipVFS); + } finally { + if (zipVFS != null) { + zipVFS.close(); + } + if (inputZipVFS != null) { + inputZipVFS.close(); + } + if (file != null) { + Assert.assertTrue(file.delete()); + } + } + } + private boolean containsFile(@Nonnull Collection<? extends InputVElement> elements, @Nonnull String fileSimpleName, @Nonnull String fileContent) throws IOException { for (VElement element : elements) { |