remove more complex examples package, move remaining example code
Project: http://git-wip-us.apache.org/repos/asf/commons-compress/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-compress/commit/7a10230e Tree: http://git-wip-us.apache.org/repos/asf/commons-compress/tree/7a10230e Diff: http://git-wip-us.apache.org/repos/asf/commons-compress/diff/7a10230e Branch: refs/heads/master Commit: 7a10230e1ecbb0f642eb2352a7f85f00961a6d54 Parents: 848be9d Author: Stefan Bodewig <bode...@apache.org> Authored: Tue May 8 05:53:08 2018 +0200 Committer: Stefan Bodewig <bode...@apache.org> Committed: Tue May 8 05:53:08 2018 +0200 ---------------------------------------------------------------------- pom.xml | 2 +- .../commons/compress/archivers/Archiver.java | 214 --------------- .../commons/compress/archivers/Expander.java | 258 ------------------ .../compress/archivers/examples/Archive.java | 148 ----------- .../compress/archivers/examples/ArchiveCli.java | 44 ---- .../archivers/examples/ArchiveEntrySource.java | 36 --- .../archivers/examples/ArchiveSinks.java | 100 ------- .../archivers/examples/ArchiveSources.java | 139 ---------- .../compress/archivers/examples/Archiver.java | 216 +++++++++++++++ .../compress/archivers/examples/Chain.java | 54 ---- .../archivers/examples/ChainDefinition.java | 70 ----- .../archivers/examples/ChainPayload.java | 74 ------ .../archivers/examples/ChainRunner.java | 46 ---- .../compress/archivers/examples/ChainStep.java | 42 --- .../examples/DirectoryBasedSource.java | 104 -------- .../archivers/examples/DirectorySink.java | 73 ------ .../compress/archivers/examples/Expand.java | 123 --------- .../compress/archivers/examples/ExpandCli.java | 48 ---- .../compress/archivers/examples/Expander.java | 260 +++++++++++++++++++ .../archivers/examples/FileFilterAdapter.java | 37 --- .../archivers/examples/FileToArchiveSink.java | 68 ----- .../compress/archivers/examples/Filter.java | 44 ---- .../compress/archivers/examples/ListerCli.java | 68 ----- .../examples/SevenZArchiveEntrySource.java | 124 --------- .../examples/SevenZOutputFileSink.java | 78 ------ .../compress/archivers/examples/Sink.java | 54 ---- .../compress/archivers/examples/Source.java | 28 -- .../examples/StreamBasedArchiveEntrySource.java | 97 ------- .../compress/archivers/examples/Supplier.java | 37 --- .../archivers/examples/ThrowingIterator.java | 30 --- .../archivers/examples/Transformer.java | 41 --- .../examples/ZipArchiveEntrySource.java | 96 ------- .../compress/archivers/examples/package.html | 69 +---- .../compress/utils/NoCloseInputStream.java | 43 --- 34 files changed, 478 insertions(+), 2487 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-compress/blob/7a10230e/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 85ee514..c3eff8e 100644 --- a/pom.xml +++ b/pom.xml @@ -329,7 +329,7 @@ Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj. <configuration> <archive> <manifestEntries> - <Main-Class>org.apache.commons.compress.archivers.examples.ListerCli</Main-Class> + <Main-Class>org.apache.commons.compress.archivers.Lister</Main-Class> <Extension-Name>org.apache.commons.compress</Extension-Name> <Automatic-Module-Name>${commons.module.name}</Automatic-Module-Name> </manifestEntries> http://git-wip-us.apache.org/repos/asf/commons-compress/blob/7a10230e/src/main/java/org/apache/commons/compress/archivers/Archiver.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/Archiver.java b/src/main/java/org/apache/commons/compress/archivers/Archiver.java deleted file mode 100644 index 291d301..0000000 --- a/src/main/java/org/apache/commons/compress/archivers/Archiver.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * 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.commons.compress.archivers; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.channels.Channels; -import java.nio.channels.FileChannel; -import java.nio.channels.SeekableByteChannel; -import java.nio.file.Files; -import java.nio.file.StandardOpenOption; - -import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile; -import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; -import org.apache.commons.compress.utils.IOUtils; - -/** - * Provides a high level API for creating archives. - * @since 1.17 - */ -public class Archiver { - - private interface ArchiveEntryCreator { - ArchiveEntry create(File f, String entryName) throws IOException; - } - - private interface ArchiveEntryConsumer { - void accept(File source, ArchiveEntry entry) throws IOException; - } - - private interface Finisher { - void finish() throws IOException; - } - - /** - * Creates an archive {@code target} using the format {@code - * format} by recursively including all files and directories in - * {@code directory}. - * - * @param format the archive format. This uses the same format as - * accepted by {@link ArchiveStreamFactory}. - * @param target the file to write the new archive to. - * @param directory the directory that contains the files to archive. - * @throws IOException if an I/O error occurs - * @throws ArchiveException if the archive cannot be created for other reasons - */ - public void create(String format, File target, File directory) throws IOException, ArchiveException { - if (prefersSeekableByteChannel(format)) { - try (SeekableByteChannel c = FileChannel.open(target.toPath(), StandardOpenOption.WRITE, - StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) { - create(format, c, directory); - } - return; - } - try (OutputStream o = Files.newOutputStream(target.toPath())) { - create(format, o, directory); - } - } - - /** - * Creates an archive {@code target} using the format {@code - * format} by recursively including all files and directories in - * {@code directory}. - * - * @param format the archive format. This uses the same format as - * accepted by {@link ArchiveStreamFactory}. - * @param target the stream to write the new archive to. - * @param directory the directory that contains the files to archive. - * @throws IOException if an I/O error occurs - * @throws ArchiveException if the archive cannot be created for other reasons - */ - public void create(String format, OutputStream target, File directory) throws IOException, ArchiveException { - create(new ArchiveStreamFactory().createArchiveOutputStream(format, target), directory); - } - - /** - * Creates an archive {@code target} using the format {@code - * format} by recursively including all files and directories in - * {@code directory}. - * - * @param format the archive format. This uses the same format as - * accepted by {@link ArchiveStreamFactory}. - * @param target the channel to write the new archive to. - * @param directory the directory that contains the files to archive. - * @throws IOException if an I/O error occurs - * @throws ArchiveException if the archive cannot be created for other reasons - */ - public void create(String format, SeekableByteChannel target, File directory) - throws IOException, ArchiveException { - if (!prefersSeekableByteChannel(format)) { - create(format, Channels.newOutputStream(target), directory); - } else if (ArchiveStreamFactory.ZIP.equalsIgnoreCase(format)) { - create(new ZipArchiveOutputStream(target), directory); - } else if (ArchiveStreamFactory.SEVEN_Z.equalsIgnoreCase(format)) { - create(new SevenZOutputFile(target), directory); - } else { - throw new ArchiveException("don't know how to handle format " + format); - } - } - - /** - * Creates an archive {@code target} by recursively including all - * files and directories in {@code directory}. - * - * @param target the stream to write the new archive to. - * @param directory the directory that contains the files to archive. - * @throws IOException if an I/O error occurs - * @throws ArchiveException if the archive cannot be created for other reasons - */ - public void create(final ArchiveOutputStream target, File directory) - throws IOException, ArchiveException { - create(directory, new ArchiveEntryCreator() { - public ArchiveEntry create(File f, String entryName) throws IOException { - return target.createArchiveEntry(f, entryName); - } - }, new ArchiveEntryConsumer() { - public void accept(File source, ArchiveEntry e) throws IOException { - target.putArchiveEntry(e); - if (!e.isDirectory()) { - try (InputStream in = new BufferedInputStream(Files.newInputStream(source.toPath()))) { - IOUtils.copy(in, target); - } - } - target.closeArchiveEntry(); - } - }, new Finisher() { - public void finish() throws IOException { - target.finish(); - } - }); - } - - /** - * Creates an archive {@code target} by recursively including all - * files and directories in {@code directory}. - * - * @param target the file to write the new archive to. - * @param directory the directory that contains the files to archive. - * @throws IOException if an I/O error occurs - */ - public void create(final SevenZOutputFile target, File directory) throws IOException { - create(directory, new ArchiveEntryCreator() { - public ArchiveEntry create(File f, String entryName) throws IOException { - return target.createArchiveEntry(f, entryName); - } - }, new ArchiveEntryConsumer() { - public void accept(File source, ArchiveEntry e) throws IOException { - target.putArchiveEntry(e); - if (!e.isDirectory()) { - final byte[] buffer = new byte[8024]; - int n = 0; - long count = 0; - try (InputStream in = new BufferedInputStream(Files.newInputStream(source.toPath()))) { - while (-1 != (n = in.read(buffer))) { - target.write(buffer, 0, n); - count += n; - } - } - } - target.closeArchiveEntry(); - } - }, new Finisher() { - public void finish() throws IOException { - target.finish(); - } - }); - } - - private boolean prefersSeekableByteChannel(String format) { - return ArchiveStreamFactory.ZIP.equalsIgnoreCase(format) || ArchiveStreamFactory.SEVEN_Z.equalsIgnoreCase(format); - } - - private void create(File directory, ArchiveEntryCreator creator, ArchiveEntryConsumer consumer, - Finisher finisher) throws IOException { - create("", directory, creator, consumer); - finisher.finish(); - } - - private void create(String prefix, File directory, ArchiveEntryCreator creator, ArchiveEntryConsumer consumer) - throws IOException { - File[] children = directory.listFiles(); - if (children == null) { - return; - } - for (File f : children) { - String entryName = prefix + f.getName() + (f.isDirectory() ? "/" : ""); - consumer.accept(f, creator.create(f, entryName)); - if (f.isDirectory()) { - create(entryName, f, creator, consumer); - } - } - } -} http://git-wip-us.apache.org/repos/asf/commons-compress/blob/7a10230e/src/main/java/org/apache/commons/compress/archivers/Expander.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/Expander.java b/src/main/java/org/apache/commons/compress/archivers/Expander.java deleted file mode 100644 index 1575e10..0000000 --- a/src/main/java/org/apache/commons/compress/archivers/Expander.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * 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.commons.compress.archivers; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.channels.Channels; -import java.nio.channels.FileChannel; -import java.nio.channels.SeekableByteChannel; -import java.nio.file.Files; -import java.nio.file.StandardOpenOption; -import java.util.Enumeration; - -import org.apache.commons.compress.archivers.sevenz.SevenZFile; -import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; -import org.apache.commons.compress.archivers.zip.ZipFile; -import org.apache.commons.compress.utils.IOUtils; - -/** - * Provides a high level API for expanding archives. - * @since 1.17 - */ -public class Expander { - - private interface ArchiveEntrySupplier { - ArchiveEntry getNextReadableEntry() throws IOException; - } - - private interface EntryWriter { - void writeEntryDataTo(ArchiveEntry entry, OutputStream out) throws IOException; - } - - /** - * Expands {@code archive} into {@code targetDirectory}. - * - * <p>Tries to auto-detect the archive's format.</p> - * - * @param archive the file to expand - * @param targetDirectory the directory to write to - * @throws IOException if an I/O error occurs - * @throws ArchiveException if the archive cannot be read for other reasons - */ - public void expand(File archive, File targetDirectory) throws IOException, ArchiveException { - String format = null; - try (InputStream i = new BufferedInputStream(Files.newInputStream(archive.toPath()))) { - format = new ArchiveStreamFactory().detect(i); - } - expand(format, archive, targetDirectory); - } - - /** - * Expands {@code archive} into {@code targetDirectory}. - * - * @param archive the file to expand - * @param targetDirectory the directory to write to - * @param format the archive format. This uses the same format as - * accepted by {@link ArchiveStreamFactory}. - * @throws IOException if an I/O error occurs - * @throws ArchiveException if the archive cannot be read for other reasons - */ - public void expand(String format, File archive, File targetDirectory) throws IOException, ArchiveException { - if (prefersSeekableByteChannel(format)) { - try (SeekableByteChannel c = FileChannel.open(archive.toPath(), StandardOpenOption.READ)) { - expand(format, c, targetDirectory); - } - return; - } - try (InputStream i = new BufferedInputStream(Files.newInputStream(archive.toPath()))) { - expand(format, i, targetDirectory); - } - } - - /** - * Expands {@code archive} into {@code targetDirectory}. - * - * <p>Tries to auto-detect the archive's format.</p> - * - * @param archive the file to expand - * @param targetDirectory the directory to write to - * @throws IOException if an I/O error occurs - * @throws ArchiveException if the archive cannot be read for other reasons - */ - public void expand(InputStream archive, File targetDirectory) throws IOException, ArchiveException { - expand(new ArchiveStreamFactory().createArchiveInputStream(archive), targetDirectory); - } - - /** - * Expands {@code archive} into {@code targetDirectory}. - * - * @param archive the file to expand - * @param targetDirectory the directory to write to - * @param format the archive format. This uses the same format as - * accepted by {@link ArchiveStreamFactory}. - * @throws IOException if an I/O error occurs - * @throws ArchiveException if the archive cannot be read for other reasons - */ - public void expand(String format, InputStream archive, File targetDirectory) - throws IOException, ArchiveException { - expand(new ArchiveStreamFactory().createArchiveInputStream(format, archive), targetDirectory); - } - - /** - * Expands {@code archive} into {@code targetDirectory}. - * - * @param archive the file to expand - * @param targetDirectory the directory to write to - * @param format the archive format. This uses the same format as - * accepted by {@link ArchiveStreamFactory}. - * @throws IOException if an I/O error occurs - * @throws ArchiveException if the archive cannot be read for other reasons - */ - public void expand(String format, SeekableByteChannel archive, File targetDirectory) - throws IOException, ArchiveException { - if (!prefersSeekableByteChannel(format)) { - expand(format, Channels.newInputStream(archive), targetDirectory); - } else if (ArchiveStreamFactory.ZIP.equalsIgnoreCase(format)) { - expand(new ZipFile(archive), targetDirectory); - } else if (ArchiveStreamFactory.SEVEN_Z.equalsIgnoreCase(format)) { - expand(new SevenZFile(archive), targetDirectory); - } else { - throw new ArchiveException("don't know how to handle format " + format); - } - } - - /** - * Expands {@code archive} into {@code targetDirectory}. - * - * @param archive the file to expand - * @param targetDirectory the directory to write to - * @throws IOException if an I/O error occurs - * @throws ArchiveException if the archive cannot be read for other reasons - */ - public void expand(final ArchiveInputStream archive, File targetDirectory) - throws IOException, ArchiveException { - expand(new ArchiveEntrySupplier() { - @Override - public ArchiveEntry getNextReadableEntry() throws IOException { - ArchiveEntry next = archive.getNextEntry(); - while (next != null && !archive.canReadEntryData(next)) { - next = archive.getNextEntry(); - } - return next; - } - }, new EntryWriter() { - @Override - public void writeEntryDataTo(ArchiveEntry entry, OutputStream out) throws IOException { - IOUtils.copy(archive, out); - } - }, targetDirectory); - } - - /** - * Expands {@code archive} into {@code targetDirectory}. - * - * @param archive the file to expand - * @param targetDirectory the directory to write to - * @throws IOException if an I/O error occurs - * @throws ArchiveException if the archive cannot be read for other reasons - */ - public void expand(final ZipFile archive, File targetDirectory) - throws IOException, ArchiveException { - final Enumeration<ZipArchiveEntry> entries = archive.getEntries(); - expand(new ArchiveEntrySupplier() { - @Override - public ArchiveEntry getNextReadableEntry() throws IOException { - ZipArchiveEntry next = entries.hasMoreElements() ? entries.nextElement() : null; - while (next != null && !archive.canReadEntryData(next)) { - next = entries.hasMoreElements() ? entries.nextElement() : null; - } - return next; - } - }, new EntryWriter() { - @Override - public void writeEntryDataTo(ArchiveEntry entry, OutputStream out) throws IOException { - try (InputStream in = archive.getInputStream((ZipArchiveEntry) entry)) { - IOUtils.copy(in, out); - } - } - }, targetDirectory); - } - - /** - * Expands {@code archive} into {@code targetDirectory}. - * - * @param archive the file to expand - * @param targetDirectory the directory to write to - * @throws IOException if an I/O error occurs - * @throws ArchiveException if the archive cannot be read for other reasons - */ - public void expand(final SevenZFile archive, File targetDirectory) - throws IOException, ArchiveException { - expand(new ArchiveEntrySupplier() { - @Override - public ArchiveEntry getNextReadableEntry() throws IOException { - return archive.getNextEntry(); - } - }, new EntryWriter() { - @Override - public void writeEntryDataTo(ArchiveEntry entry, OutputStream out) throws IOException { - final byte[] buffer = new byte[8024]; - int n = 0; - long count = 0; - while (-1 != (n = archive.read(buffer))) { - out.write(buffer, 0, n); - count += n; - } - } - }, targetDirectory); - } - - private boolean prefersSeekableByteChannel(String format) { - return ArchiveStreamFactory.ZIP.equalsIgnoreCase(format) || ArchiveStreamFactory.SEVEN_Z.equalsIgnoreCase(format); - } - - private void expand(ArchiveEntrySupplier supplier, EntryWriter writer, File targetDirectory) - throws IOException { - String targetDirPath = targetDirectory.getCanonicalPath(); - ArchiveEntry nextEntry = supplier.getNextReadableEntry(); - while (nextEntry != null) { - File f = new File(targetDirectory, nextEntry.getName()); - if (!f.getCanonicalPath().startsWith(targetDirPath)) { - throw new IOException("expanding " + nextEntry.getName() - + " would craete file outside of " + targetDirectory); - } - if (nextEntry.isDirectory()) { - f.mkdirs(); - } else { - f.getParentFile().mkdirs(); - try (OutputStream o = Files.newOutputStream(f.toPath())) { - writer.writeEntryDataTo(nextEntry, o); - } - } - nextEntry = supplier.getNextReadableEntry(); - } - } - -} http://git-wip-us.apache.org/repos/asf/commons-compress/blob/7a10230e/src/main/java/org/apache/commons/compress/archivers/examples/Archive.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/examples/Archive.java b/src/main/java/org/apache/commons/compress/archivers/examples/Archive.java deleted file mode 100644 index 1895a7d..0000000 --- a/src/main/java/org/apache/commons/compress/archivers/examples/Archive.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 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.commons.compress.archivers.examples; - -import java.io.File; -import java.io.FileFilter; -import java.io.IOException; -import org.apache.commons.compress.archivers.ArchiveException; - -/** - * Consumes files and passes them to a sink, usually used to create an archive of them. - * @since 1.17 - */ -public class Archive { - /** - * Sets up a chain of operations and consumes the files from a source of files. - * @since 1.17 - */ - public interface ChainBuilder { - /** - * Adds a filter to the chain. - * @param filter the filter to apply - * @return an updated builder - */ - ChainBuilder filter(Filter<File> filter); - /** - * Adds a filter to the chain. - * @param filter the filter to apply - * @return an updated builder - */ - ChainBuilder filter(FileFilter filter); - /** - * Adds a filter to the chain that filters out entries that cannot be read. - * @return an updated builder - */ - ChainBuilder skipUnreadable(); - /** - * Adds a filter to the chain that filters out everything that is not a file. - * @return an updated builder - */ - ChainBuilder skipNonFiles(); - /** - * Adds a transformer to the chain. - * @param transformer transformer to apply - * @return an updated builder - */ - ChainBuilder map(Transformer<File> transformer); - /** - * Adds a generic step to the chain. - * @param step step to perform - * @return an updated builder - */ - ChainBuilder withStep(ChainStep<File> step); - /** - * Actually consumes all the files supplied. - * @param sink sink that the entries will be sent to - * @throws IOException if an I/O error occurs - * @throws ArchiveException if the archive cannot be written for other reasons - */ - void to(Sink<File> sink) throws IOException, ArchiveException; - } - - /** - * Sets the source of files to be a directory. - * @param f the source directory - * @return a builder for the chain to be created and run - */ - public static ChainBuilder directory(File f) { - return source(new DirectoryBasedSource(f)); - } - - /** - * Sets the source of files to process. - * @param source the source directory - * @return a builder for the chain to be created and run - */ - public static ChainBuilder source(Source<File> source) { - return new Builder(source); - } - - private static class Builder implements ChainBuilder { - private final Source<File> source; - private ChainDefinition<File> chainDef = new ChainDefinition<>(); - - Builder(Source<File> source) { - this.source = source; - } - - @Override - public ChainBuilder filter(Filter<File> filter) { - return withStep(filter); - } - @Override - public ChainBuilder filter(FileFilter filter) { - return filter(new FileFilterAdapter(filter)); - } - @Override - public ChainBuilder skipUnreadable() { - return filter(new FileFilter() { - @Override - public boolean accept(File f) { - return f.canRead(); - } - }); - } - @Override - public ChainBuilder skipNonFiles() { - return filter(new FileFilter() { - @Override - public boolean accept(File f) { - return f.isFile(); - } - }); - } - @Override - public ChainBuilder map(Transformer<File> transformer) { - return withStep(transformer); - } - @Override - public ChainBuilder withStep(ChainStep<File> step) { - chainDef.add(step); - return this; - } - @Override - public void to(Sink<File> sink) throws IOException, ArchiveException { - chainDef.add(sink); - chainDef.freeze(); - new ChainRunner<File>(source, chainDef, sink).run(); - } - } - -} http://git-wip-us.apache.org/repos/asf/commons-compress/blob/7a10230e/src/main/java/org/apache/commons/compress/archivers/examples/ArchiveCli.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/examples/ArchiveCli.java b/src/main/java/org/apache/commons/compress/archivers/examples/ArchiveCli.java deleted file mode 100644 index cb20460..0000000 --- a/src/main/java/org/apache/commons/compress/archivers/examples/ArchiveCli.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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.commons.compress.archivers.examples; - -import java.io.File; -import java.io.IOException; -import org.apache.commons.compress.archivers.ArchiveException; - -/** - * Simple command line tool that creates an archive from the contents of a directory. - * - * <p>Usage: <code>ArchiveCli dir format archive</code></p> - * @since 1.17 - */ -public class ArchiveCli { - - public static void main(String[] args) throws IOException, ArchiveException { - if (args.length != 3) { - System.err.println("Usage: ArchiveCli dir format target"); - System.exit(1); - } - try (Sink<File> sink = ArchiveSinks.forFile(args[1], new File(args[2]))) { - Archive.directory(new File(args[0])) - .to(sink); - } - } - -} http://git-wip-us.apache.org/repos/asf/commons-compress/blob/7a10230e/src/main/java/org/apache/commons/compress/archivers/examples/ArchiveEntrySource.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/examples/ArchiveEntrySource.java b/src/main/java/org/apache/commons/compress/archivers/examples/ArchiveEntrySource.java deleted file mode 100644 index 402134f..0000000 --- a/src/main/java/org/apache/commons/compress/archivers/examples/ArchiveEntrySource.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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.commons.compress.archivers.examples; - -import org.apache.commons.compress.archivers.ArchiveEntry; - -/** - * Combines Source and a factory for filter that skips unreadable entries. - * @since 1.17 - */ -public interface ArchiveEntrySource extends Source<ArchiveEntry> { - - /** - * Provides a filter that can be used to skip entries the - * underlying source is unable to read the content of. - * @return filter that can be used to skip entries the underlying - * source is unable to read the content of - */ - Filter<ArchiveEntry> skipUnreadable(); -} http://git-wip-us.apache.org/repos/asf/commons-compress/blob/7a10230e/src/main/java/org/apache/commons/compress/archivers/examples/ArchiveSinks.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/examples/ArchiveSinks.java b/src/main/java/org/apache/commons/compress/archivers/examples/ArchiveSinks.java deleted file mode 100644 index f00fc4f..0000000 --- a/src/main/java/org/apache/commons/compress/archivers/examples/ArchiveSinks.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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.commons.compress.archivers.examples; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.io.FileOutputStream; -import java.nio.channels.Channels; -import java.nio.channels.FileChannel; -import java.nio.channels.SeekableByteChannel; -import java.nio.file.StandardOpenOption; -import org.apache.commons.compress.archivers.ArchiveException; -import org.apache.commons.compress.archivers.ArchiveStreamFactory; -import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; - -/** - * Supplies factory methods for file sinks that write to archives, - * @since 1.17 - */ -public class ArchiveSinks { - /** - * Uses {@link ArchiveStreamFactory#createArchiveOutputStream}. - * - * <p>Will not support 7z.</p> - * - * @param format the archive format. This uses the same format as - * accepted by {@link ArchiveStreamFactory}. - * @param os the stream to write to. - * @return a sink that consumes the files - * @throws IOException if an I/O error occurs - * @throws ArchiveException if the archive cannot be created for other reasons - */ - public static Sink<File> forStream(String format, OutputStream os) throws IOException, ArchiveException { - return new FileToArchiveSink(new ArchiveStreamFactory().createArchiveOutputStream(format, os)); - } - - /** - * Uses {@link ArchiveStreamFactory#createArchiveOutputStream} unless - * special handling for ZIP or 7z is required. - * - * @param format the archive format. This uses the same format as - * accepted by {@link ArchiveStreamFactory}. - * @param target the file to write to. - * @return a sink that consumes the files - * @throws IOException if an I/O error occurs - * @throws ArchiveException if the archive cannot be created for other reasons - */ - public static Sink<File> forFile(String format, File target) throws IOException, ArchiveException { - if (prefersSeekableByteChannel(format)) { - return forChannel(format, FileChannel.open(target.toPath(), StandardOpenOption.WRITE, - StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)); - } - return new FileToArchiveSink(new ArchiveStreamFactory() - .createArchiveOutputStream(format, new FileOutputStream(target))); - } - - /** - * Uses {@link ArchiveStreamFactory#createArchiveOutputStream} unless - * special handling for ZIP or 7z is required. - * - * @param format the archive format. This uses the same format as - * accepted by {@link ArchiveStreamFactory}. - * @param c the channel to write to. - * @return a sink that consumes the files - * @throws IOException if an I/O error occurs - * @throws ArchiveException if the archive cannot be created for other reasons - */ - public static Sink<File> forChannel(String format, SeekableByteChannel c) throws IOException, ArchiveException { - if (!prefersSeekableByteChannel(format)) { - return forStream(format, Channels.newOutputStream(c)); - } else if (ArchiveStreamFactory.ZIP.equalsIgnoreCase(format)) { - return new FileToArchiveSink(new ZipArchiveOutputStream(c)); - } else if (ArchiveStreamFactory.SEVEN_Z.equalsIgnoreCase(format)) { - return new SevenZOutputFileSink(c); - } else { - throw new ArchiveException("don't know how to handle format " + format); - } - } - - private static boolean prefersSeekableByteChannel(String format) { - return ArchiveStreamFactory.ZIP.equalsIgnoreCase(format) || ArchiveStreamFactory.SEVEN_Z.equalsIgnoreCase(format); - } -} http://git-wip-us.apache.org/repos/asf/commons-compress/blob/7a10230e/src/main/java/org/apache/commons/compress/archivers/examples/ArchiveSources.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/examples/ArchiveSources.java b/src/main/java/org/apache/commons/compress/archivers/examples/ArchiveSources.java deleted file mode 100644 index 670eb2f..0000000 --- a/src/main/java/org/apache/commons/compress/archivers/examples/ArchiveSources.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * 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.commons.compress.archivers.examples; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.FileInputStream; -import java.nio.channels.Channels; -import java.nio.channels.FileChannel; -import java.nio.channels.SeekableByteChannel; -import java.nio.file.StandardOpenOption; -import org.apache.commons.compress.archivers.ArchiveException; -import org.apache.commons.compress.archivers.ArchiveInputStream; -import org.apache.commons.compress.archivers.ArchiveStreamFactory; -import org.apache.commons.compress.archivers.sevenz.SevenZFile; -import org.apache.commons.compress.archivers.zip.ZipFile; - -/** - * Supplies factory methods for ArchiveEntry sources that read from archives, - * @since 1.17 - */ -public class ArchiveSources { - /** - * Builder for {@link ArchiveEntrySource} that needs to know its format. - * @since 1.17 - */ - public interface PendingFormat { - /** - * Signals the format shall be detcted automatically. - * @return the configured source - * @throws IOException if an I/O error occurs - * @throws ArchiveException if the archive cannot be read for other reasons - */ - ArchiveEntrySource detectFormat() throws IOException, ArchiveException; - /** - * Explicitly provides the expected format of the archive. - * @param format the archive format. This uses the same format as - * accepted by {@link ArchiveStreamFactory}. - * @return the configured source - * @throws IOException if an I/O error occurs - * @throws ArchiveException if the archive cannot be read for other reasons - */ - ArchiveEntrySource withFormat(String format) throws IOException, ArchiveException; - } - - /** - * Uses {@link ArchiveStreamFactory#createArchiveInputStream} unless special handling for ZIP or /z is required. - * - * @param f the file to read from - * @return a builder that needs to know the format - */ - public static PendingFormat forFile(final File f) { - return new PendingFormat() { - @Override - public ArchiveEntrySource detectFormat() throws IOException, ArchiveException { - String format = null; - try (InputStream i = new BufferedInputStream(new FileInputStream(f))) { - format = new ArchiveStreamFactory().detect(i); - } - return withFormat(format); - } - @Override - public ArchiveEntrySource withFormat(String format) throws IOException, ArchiveException { - if (prefersSeekableByteChannel(format)) { - return forChannel(format, FileChannel.open(f.toPath(), StandardOpenOption.READ)); - } - return new StreamBasedArchiveEntrySource(new ArchiveStreamFactory() - .createArchiveInputStream(format, new BufferedInputStream(new FileInputStream(f)))); - } - }; - } - - /** - * Uses {@link ArchiveStreamFactory#createArchiveInputStream} unless special handling for ZIP or /z is required. - * - * @param format the archive format. This uses the same format as - * accepted by {@link ArchiveStreamFactory}. - * @param c the channel to read from - * @return the configured source - * @throws IOException if an I/O error occurs - * @throws ArchiveException if the archive cannot be read for other reasons - */ - public static ArchiveEntrySource forChannel(String format, SeekableByteChannel c) - throws IOException, ArchiveException { - if (!prefersSeekableByteChannel(format)) { - return new StreamBasedArchiveEntrySource(new ArchiveStreamFactory() - .createArchiveInputStream(format, Channels.newInputStream(c))); - } else if (ArchiveStreamFactory.ZIP.equalsIgnoreCase(format)) { - return new ZipArchiveEntrySource(c); - } else if (ArchiveStreamFactory.SEVEN_Z.equalsIgnoreCase(format)) { - return new SevenZArchiveEntrySource(c); - } - throw new ArchiveException("don't know how to handle format " + format); - } - - /** - * Uses {@link ArchiveStreamFactory#createArchiveInputStream}. - * - * <p>Will not support 7z.</p> - * - * @param in the stream to read from - * @return a builder that needs to know the format - */ - public static PendingFormat forStream(final InputStream in) { - return new PendingFormat() { - @Override - public ArchiveEntrySource detectFormat() throws IOException, ArchiveException { - return new StreamBasedArchiveEntrySource(new ArchiveStreamFactory().createArchiveInputStream(in)); - } - @Override - public ArchiveEntrySource withFormat(String format) throws IOException, ArchiveException { - return new StreamBasedArchiveEntrySource(new ArchiveStreamFactory() - .createArchiveInputStream(format, in)); - } - }; - } - - private static boolean prefersSeekableByteChannel(String format) { - return ArchiveStreamFactory.ZIP.equalsIgnoreCase(format) || ArchiveStreamFactory.SEVEN_Z.equalsIgnoreCase(format); - } -} http://git-wip-us.apache.org/repos/asf/commons-compress/blob/7a10230e/src/main/java/org/apache/commons/compress/archivers/examples/Archiver.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/examples/Archiver.java b/src/main/java/org/apache/commons/compress/archivers/examples/Archiver.java new file mode 100644 index 0000000..4c43bb9 --- /dev/null +++ b/src/main/java/org/apache/commons/compress/archivers/examples/Archiver.java @@ -0,0 +1,216 @@ +/* + * 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.commons.compress.archivers.examples; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.channels.Channels; +import java.nio.channels.FileChannel; +import java.nio.channels.SeekableByteChannel; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; + +import org.apache.commons.compress.archivers.ArchiveEntry; +import org.apache.commons.compress.archivers.ArchiveException; +import org.apache.commons.compress.archivers.ArchiveOutputStream; +import org.apache.commons.compress.archivers.ArchiveStreamFactory; +import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile; +import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; +import org.apache.commons.compress.utils.IOUtils; + +/** + * Provides a high level API for creating archives. + * @since 1.17 + */ +public class Archiver { + + private interface ArchiveEntryCreator { + ArchiveEntry create(File f, String entryName) throws IOException; + } + + private interface ArchiveEntryConsumer { + void accept(File source, ArchiveEntry entry) throws IOException; + } + + private interface Finisher { + void finish() throws IOException; + } + + /** + * Creates an archive {@code target} using the format {@code + * format} by recursively including all files and directories in + * {@code directory}. + * + * @param format the archive format. This uses the same format as + * accepted by {@link ArchiveStreamFactory}. + * @param target the file to write the new archive to. + * @param directory the directory that contains the files to archive. + * @throws IOException if an I/O error occurs + * @throws ArchiveException if the archive cannot be created for other reasons + */ + public void create(String format, File target, File directory) throws IOException, ArchiveException { + if (prefersSeekableByteChannel(format)) { + try (SeekableByteChannel c = FileChannel.open(target.toPath(), StandardOpenOption.WRITE, + StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) { + create(format, c, directory); + } + return; + } + try (OutputStream o = Files.newOutputStream(target.toPath())) { + create(format, o, directory); + } + } + + /** + * Creates an archive {@code target} using the format {@code + * format} by recursively including all files and directories in + * {@code directory}. + * + * @param format the archive format. This uses the same format as + * accepted by {@link ArchiveStreamFactory}. + * @param target the stream to write the new archive to. + * @param directory the directory that contains the files to archive. + * @throws IOException if an I/O error occurs + * @throws ArchiveException if the archive cannot be created for other reasons + */ + public void create(String format, OutputStream target, File directory) throws IOException, ArchiveException { + create(new ArchiveStreamFactory().createArchiveOutputStream(format, target), directory); + } + + /** + * Creates an archive {@code target} using the format {@code + * format} by recursively including all files and directories in + * {@code directory}. + * + * @param format the archive format. This uses the same format as + * accepted by {@link ArchiveStreamFactory}. + * @param target the channel to write the new archive to. + * @param directory the directory that contains the files to archive. + * @throws IOException if an I/O error occurs + * @throws ArchiveException if the archive cannot be created for other reasons + */ + public void create(String format, SeekableByteChannel target, File directory) + throws IOException, ArchiveException { + if (!prefersSeekableByteChannel(format)) { + create(format, Channels.newOutputStream(target), directory); + } else if (ArchiveStreamFactory.ZIP.equalsIgnoreCase(format)) { + create(new ZipArchiveOutputStream(target), directory); + } else if (ArchiveStreamFactory.SEVEN_Z.equalsIgnoreCase(format)) { + create(new SevenZOutputFile(target), directory); + } else { + throw new ArchiveException("don't know how to handle format " + format); + } + } + + /** + * Creates an archive {@code target} by recursively including all + * files and directories in {@code directory}. + * + * @param target the stream to write the new archive to. + * @param directory the directory that contains the files to archive. + * @throws IOException if an I/O error occurs + * @throws ArchiveException if the archive cannot be created for other reasons + */ + public void create(final ArchiveOutputStream target, File directory) + throws IOException, ArchiveException { + create(directory, new ArchiveEntryCreator() { + public ArchiveEntry create(File f, String entryName) throws IOException { + return target.createArchiveEntry(f, entryName); + } + }, new ArchiveEntryConsumer() { + public void accept(File source, ArchiveEntry e) throws IOException { + target.putArchiveEntry(e); + if (!e.isDirectory()) { + try (InputStream in = new BufferedInputStream(Files.newInputStream(source.toPath()))) { + IOUtils.copy(in, target); + } + } + target.closeArchiveEntry(); + } + }, new Finisher() { + public void finish() throws IOException { + target.finish(); + } + }); + } + + /** + * Creates an archive {@code target} by recursively including all + * files and directories in {@code directory}. + * + * @param target the file to write the new archive to. + * @param directory the directory that contains the files to archive. + * @throws IOException if an I/O error occurs + */ + public void create(final SevenZOutputFile target, File directory) throws IOException { + create(directory, new ArchiveEntryCreator() { + public ArchiveEntry create(File f, String entryName) throws IOException { + return target.createArchiveEntry(f, entryName); + } + }, new ArchiveEntryConsumer() { + public void accept(File source, ArchiveEntry e) throws IOException { + target.putArchiveEntry(e); + if (!e.isDirectory()) { + final byte[] buffer = new byte[8024]; + int n = 0; + long count = 0; + try (InputStream in = new BufferedInputStream(Files.newInputStream(source.toPath()))) { + while (-1 != (n = in.read(buffer))) { + target.write(buffer, 0, n); + count += n; + } + } + } + target.closeArchiveEntry(); + } + }, new Finisher() { + public void finish() throws IOException { + target.finish(); + } + }); + } + + private boolean prefersSeekableByteChannel(String format) { + return ArchiveStreamFactory.ZIP.equalsIgnoreCase(format) || ArchiveStreamFactory.SEVEN_Z.equalsIgnoreCase(format); + } + + private void create(File directory, ArchiveEntryCreator creator, ArchiveEntryConsumer consumer, + Finisher finisher) throws IOException { + create("", directory, creator, consumer); + finisher.finish(); + } + + private void create(String prefix, File directory, ArchiveEntryCreator creator, ArchiveEntryConsumer consumer) + throws IOException { + File[] children = directory.listFiles(); + if (children == null) { + return; + } + for (File f : children) { + String entryName = prefix + f.getName() + (f.isDirectory() ? "/" : ""); + consumer.accept(f, creator.create(f, entryName)); + if (f.isDirectory()) { + create(entryName, f, creator, consumer); + } + } + } +} http://git-wip-us.apache.org/repos/asf/commons-compress/blob/7a10230e/src/main/java/org/apache/commons/compress/archivers/examples/Chain.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/examples/Chain.java b/src/main/java/org/apache/commons/compress/archivers/examples/Chain.java deleted file mode 100644 index 86d2e1c..0000000 --- a/src/main/java/org/apache/commons/compress/archivers/examples/Chain.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.commons.compress.archivers.examples; - -import java.io.IOException; -import java.util.Iterator; -import org.apache.commons.compress.archivers.ArchiveException; - -/** - * Encapsulates the execution flow of a chain of operations. - * @since 1.17 - */ -public class Chain<T> { - - private final Iterator<ChainStep<T>> chain; - - /** - * Instantiates a new chain. - * - * @param chain the steps to take in order. - */ - public Chain(Iterator<ChainStep<T>> chain) { - this.chain = chain; - } - - /** - * Invokes the next step of the chain. - * - * @param payload the payload to pass to the next step - * @throws IOException if an I/O error occurs - * @throws ArchiveException if an archive format related error occurs - */ - public void next(ChainPayload<T> payload) throws IOException, ArchiveException { - if (chain.hasNext()) { - chain.next().process(payload, this); - } - } -} http://git-wip-us.apache.org/repos/asf/commons-compress/blob/7a10230e/src/main/java/org/apache/commons/compress/archivers/examples/ChainDefinition.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/examples/ChainDefinition.java b/src/main/java/org/apache/commons/compress/archivers/examples/ChainDefinition.java deleted file mode 100644 index d8a387f..0000000 --- a/src/main/java/org/apache/commons/compress/archivers/examples/ChainDefinition.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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.commons.compress.archivers.examples; - -import java.util.Deque; -import java.util.LinkedList; - -/** - * The recipe for building a {@link Chain}. - * @since 1.17 - */ -class ChainDefinition<T> { - private final Deque<ChainStep<T>> steps = new LinkedList<>(); - private volatile boolean frozen = false; - - /** - * Adds a step. - * @throws IllegalStateException if the definition is already frozen. - */ - void add(ChainStep<T> step) { - if (frozen) { - throw new IllegalStateException("the definition is already frozen"); - } - steps.addLast(step); - } - - /** - * Freezes the definition. - * - * <p>Once this method has been invoked {@link #add} can no longer be invoked.</p> - * - * @throws IllegalStateException if the last step of the definition is not a sink. - */ - void freeze() { - if (!frozen) { - frozen = true; - if (!(steps.getLast() instanceof Sink)) { - throw new IllegalStateException("this definition doesn't end in a sink"); - } - } - } - - /** - * Returns a chain for this definition. - * - * @throws IllegalStateException if the definition is not frozen. - */ - Chain<T> chain() { - if (!frozen) { - throw new IllegalStateException("the definition hasn't been frozen, yet"); - } - return new Chain(steps.iterator()); - } -} http://git-wip-us.apache.org/repos/asf/commons-compress/blob/7a10230e/src/main/java/org/apache/commons/compress/archivers/examples/ChainPayload.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/examples/ChainPayload.java b/src/main/java/org/apache/commons/compress/archivers/examples/ChainPayload.java deleted file mode 100644 index 11d8618..0000000 --- a/src/main/java/org/apache/commons/compress/archivers/examples/ChainPayload.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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.commons.compress.archivers.examples; - -import java.io.InputStream; - -/** - * The data that is pushed through a chain. - * @since 1.17 - */ -public class ChainPayload<T> { - private final T entry; - private final String entryName; - private final Supplier<InputStream> input; - /** - * Constructs the payload. - * @param entry entry the actual payload - * @param entryName the local name of the entry. This may - for - * example - be the file name relative to a directory. - * @param input supplies an input stream to the entry's - * content. Is not expected to be called more than once. - */ - public ChainPayload(T entry, String entryName, Supplier<InputStream> input) { - this.entry = entry; - this.entryName = entryName; - this.input = input; - } - /** - * Provides the real payload. - * @return the real playoad - * - */ - public T getEntry() { - return entry; - } - /** - * Provides the local name of the entry. - * - * <p>This may - for example - be the file name relative to a - * directory.</p> - * - * @return local name of the entry - */ - public String getEntryName() { - return entryName; - } - /** - * Returns a {@link Supplier} that can be used to read the entry's content. - * - * <p>The supplier is not required to be callable more than - * once.</p> - * - * @return supplier of input - */ - public Supplier<InputStream> getInput() { - return input; - } -} http://git-wip-us.apache.org/repos/asf/commons-compress/blob/7a10230e/src/main/java/org/apache/commons/compress/archivers/examples/ChainRunner.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/examples/ChainRunner.java b/src/main/java/org/apache/commons/compress/archivers/examples/ChainRunner.java deleted file mode 100644 index 5f43589..0000000 --- a/src/main/java/org/apache/commons/compress/archivers/examples/ChainRunner.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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.commons.compress.archivers.examples; - -import java.io.IOException; -import org.apache.commons.compress.archivers.ArchiveException; - -/** - * Contains the execution logic of a full chain including a source. - * @since 1.17 - */ -class ChainRunner<T> { - private final Source<T> source; - private final ChainDefinition<T> chainDef; - private final Sink<T> sink; - - ChainRunner(Source<T> source, ChainDefinition<T> chainDef, Sink<T> sink) { - this.source = source; - this.chainDef = chainDef; - this.sink = sink; - } - - void run() throws IOException, ArchiveException { - ThrowingIterator<ChainPayload<T>> iter = source.get(); - while (iter.hasNext()) { - chainDef.chain().next(iter.next()); - } - sink.finish(); - } -} http://git-wip-us.apache.org/repos/asf/commons-compress/blob/7a10230e/src/main/java/org/apache/commons/compress/archivers/examples/ChainStep.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/examples/ChainStep.java b/src/main/java/org/apache/commons/compress/archivers/examples/ChainStep.java deleted file mode 100644 index ee0e4b3..0000000 --- a/src/main/java/org/apache/commons/compress/archivers/examples/ChainStep.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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.commons.compress.archivers.examples; - -import java.io.IOException; -import org.apache.commons.compress.archivers.ArchiveException; - -/** - * A step inside of a {@link Chain}. - * @since 1.17 - */ -public interface ChainStep<T> { - /** - * Process the chain's payload. - * - * <p>Any non-terminal step that invokes the {@link Supplier} of - * the payload is responsible for providing a fresh supplier if - * the chain is to be continued.</p> - * - * @param payload the payload. - * @param chain chain to return control to once processing is done. - * @throws IOException if an I/O error occurs - * @throws ArchiveException if an archive format related error occurs - */ - void process(ChainPayload<T> payload, Chain<T> chain) throws IOException, ArchiveException; -} http://git-wip-us.apache.org/repos/asf/commons-compress/blob/7a10230e/src/main/java/org/apache/commons/compress/archivers/examples/DirectoryBasedSource.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/examples/DirectoryBasedSource.java b/src/main/java/org/apache/commons/compress/archivers/examples/DirectoryBasedSource.java deleted file mode 100644 index c6ca484..0000000 --- a/src/main/java/org/apache/commons/compress/archivers/examples/DirectoryBasedSource.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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.commons.compress.archivers.examples; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * Recursively returns all files and directories contained inside of a base directory. - * @since 1.17 - */ -public class DirectoryBasedSource implements Source<File> { - - private final File dir; - - /** - * Sets up a directory as source. - * - * @param dir the directory to provide entries from. - * @throws IllegalArgumentException if dir doesn't exist or is not a directory - */ - public DirectoryBasedSource(File dir) { - if (!dir.isDirectory()) { - throw new IllegalArgumentException("dir is not a readable directory"); - } - this.dir = dir; - } - - @Override - public ThrowingIterator<ChainPayload<File>> get() throws IOException { - return new DirectoryIterator("", dir); - } - - @Override - public void close() { - } - - private static class DirectoryIterator implements ThrowingIterator<ChainPayload<File>> { - private final Iterator<File> files; - private final String namePrefix; - private DirectoryIterator nestedIterator; - DirectoryIterator(String namePrefix, File dir) throws IOException { - this.namePrefix = namePrefix; - File[] fs = dir.listFiles(); - files = fs == null ? Collections.<File>emptyIterator() : Arrays.asList(fs).iterator(); - } - - @Override - public boolean hasNext() throws IOException { - if (nestedIterator != null && nestedIterator.hasNext()) { - return true; - } - if (nestedIterator != null) { - nestedIterator = null; - } - return files.hasNext(); - } - - @Override - public ChainPayload<File> next() throws IOException { - if (!hasNext()) { - throw new NoSuchElementException(); - } - if (nestedIterator != null) { - return nestedIterator.next(); - } - final File f = files.next(); - String entryName = namePrefix + f.getName(); - if (f.isDirectory()) { - entryName += "/"; - nestedIterator = new DirectoryIterator(entryName, f); - } - return new ChainPayload(f, entryName, new Supplier<InputStream>() { - @Override - public InputStream get() throws IOException { - return new FileInputStream(f); - } - }); - } - - } -} http://git-wip-us.apache.org/repos/asf/commons-compress/blob/7a10230e/src/main/java/org/apache/commons/compress/archivers/examples/DirectorySink.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/examples/DirectorySink.java b/src/main/java/org/apache/commons/compress/archivers/examples/DirectorySink.java deleted file mode 100644 index 7a34858..0000000 --- a/src/main/java/org/apache/commons/compress/archivers/examples/DirectorySink.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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.commons.compress.archivers.examples; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import org.apache.commons.compress.archivers.ArchiveEntry; -import org.apache.commons.compress.archivers.ArchiveException; -import org.apache.commons.compress.utils.IOUtils; - -/** - * A sink that expands archive entries into a directory. - * @since 1.17 - */ -public class DirectorySink extends Sink<ArchiveEntry> { - private final File dir; - private final String dirPath; - - /** - * Sets up a directory as sink. - * - * @param dir the directory to provide entries from. - * @throws IOException if the canonical path of the directory cannot be determined - * @throws IllegalArgumentException if dir doesn't exist or is not a directory - */ - public DirectorySink(File dir) throws IOException { - if (!dir.isDirectory()) { - throw new IllegalArgumentException("dir is not a readable directory"); - } - this.dir = dir; - dirPath = dir.getCanonicalPath(); - } - - @Override - public void consume(ChainPayload<ArchiveEntry> payload) throws IOException, ArchiveException { - File f = new File(dir, payload.getEntryName()); - if (!f.getCanonicalPath().startsWith(dirPath)) { - throw new IOException("expanding " + payload.getEntryName() + " would create file outside of " + dir); - } - if (payload.getEntry().isDirectory()) { - f.mkdirs(); - } else { - f.getParentFile().mkdirs(); - try (OutputStream o = new FileOutputStream(f); - InputStream i = payload.getInput().get()) { - IOUtils.copy(i, o); - } - } - } - - @Override - public void close() { - } -} http://git-wip-us.apache.org/repos/asf/commons-compress/blob/7a10230e/src/main/java/org/apache/commons/compress/archivers/examples/Expand.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/examples/Expand.java b/src/main/java/org/apache/commons/compress/archivers/examples/Expand.java deleted file mode 100644 index d6ece27..0000000 --- a/src/main/java/org/apache/commons/compress/archivers/examples/Expand.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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.commons.compress.archivers.examples; - -import java.io.IOException; -import org.apache.commons.compress.archivers.ArchiveEntry; -import org.apache.commons.compress.archivers.ArchiveException; - -/** - * Consumes archive entries and passes them to a sink, usually used to - * expand an archive. - * @since 1.17 - */ -public class Expand { - /** - * Sets up a chain of operations and consumes the entries from a source of archive entries. - * @since 1.17 - */ - public interface ChainBuilder { - /** - * Adds a filter to the chain. - * @param filter the filter to apply - * @return an updated builder - */ - ChainBuilder filter(Filter<ArchiveEntry> filter); - /** - * Adds a filter to the chain that filters out entries that cannot be read. - * @return an updated builder - */ - ChainBuilder skipUnreadable(); - /** - * Adds a filter to the chain that suppresses all directory entries. - * @return an updated builder - */ - ChainBuilder skipDirectories(); - /** - * Adds a transformer to the chain. - * @param transformer transformer to apply - * @return an updated builder - */ - ChainBuilder map(Transformer<ArchiveEntry> transformer); - /** - * Adds a generic step to the chain. - * @return an updated builder - * @param step step to perform - */ - ChainBuilder withStep(ChainStep<ArchiveEntry> step); - /** - * Actually consumes all the entries supplied. - * @param sink sink that the entries will be sent to - * @throws IOException if an I/O error occurs - * @throws ArchiveException if the source archive cannot be read for other reasons - */ - void to(Sink<ArchiveEntry> sink) throws IOException, ArchiveException; - } - - /** - * Sets the source of entries to process. - * @param source the source - * @return a builder for the chain to be created and run - */ - public static ChainBuilder source(ArchiveEntrySource source) { - return new Builder(source); - } - - private static class Builder implements ChainBuilder { - private final ArchiveEntrySource source; - private ChainDefinition<ArchiveEntry> chainDef = new ChainDefinition<>(); - - Builder(ArchiveEntrySource source) { - this.source = source; - } - - @Override - public ChainBuilder filter(Filter<ArchiveEntry> filter) { - return withStep(filter); - } - @Override - public ChainBuilder skipUnreadable() { - return filter(source.skipUnreadable()); - } - @Override - public ChainBuilder skipDirectories() { - return filter(new Filter<ArchiveEntry>() { - @Override - public boolean accept(String entryName, ArchiveEntry e) { - return !e.isDirectory(); - } - }); - } - @Override - public ChainBuilder map(Transformer<ArchiveEntry> transformer) { - return withStep(transformer); - } - @Override - public ChainBuilder withStep(ChainStep<ArchiveEntry> step) { - chainDef.add(step); - return this; - } - @Override - public void to(Sink<ArchiveEntry> sink) throws IOException, ArchiveException { - chainDef.add(sink); - chainDef.freeze(); - new ChainRunner<ArchiveEntry>(source, chainDef, sink).run(); - } - } -} http://git-wip-us.apache.org/repos/asf/commons-compress/blob/7a10230e/src/main/java/org/apache/commons/compress/archivers/examples/ExpandCli.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/examples/ExpandCli.java b/src/main/java/org/apache/commons/compress/archivers/examples/ExpandCli.java deleted file mode 100644 index fd264ce..0000000 --- a/src/main/java/org/apache/commons/compress/archivers/examples/ExpandCli.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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.commons.compress.archivers.examples; - -import java.io.File; -import java.io.IOException; -import org.apache.commons.compress.archivers.ArchiveException; - -/** - * Simple command line tool that extracts an archive into a directory. - * - * <p>Usage: <code>ExpandCli archive dir [format]</code></p> - * @since 1.17 - */ -public class ExpandCli { - - public static void main(String[] args) throws IOException, ArchiveException { - if (args.length < 2 || args.length > 3) { - System.err.println("Usage: ExpandCli dir archive [format]"); - System.exit(1); - } else if (args.length == 2) { - try (ArchiveEntrySource source = ArchiveSources.forFile(new File(args[0])).detectFormat()) { - Expand.source(source).to(new DirectorySink(new File(args[1]))); - } - } else { - try (ArchiveEntrySource source = ArchiveSources.forFile(new File(args[0])).withFormat(args[2])) { - Expand.source(source).to(new DirectorySink(new File(args[1]))); - } - } - } - -}