pax_global_header00006660000000000000000000000064141044605650014517gustar00rootroot0000000000000052 comment=6ecbbbbb598df8715188001433d27687a2585369 jarchivelib-1.2.0/000077500000000000000000000000001410446056500140015ustar00rootroot00000000000000jarchivelib-1.2.0/.gitignore000066400000000000000000000002471410446056500157740ustar00rootroot00000000000000# Maven files target/ bin/ # Eclipse project files .project .classpath .settings # Mac OS .DS_Store # IntelliJ IDEA files *.iml *.ipr *.iws .idea #backup-files *~ jarchivelib-1.2.0/.travis-settings.xml000066400000000000000000000021311410446056500177440ustar00rootroot00000000000000 sonatype-nexus-snapshots ${env.SONATYPE_USERNAME} ${env.SONATYPE_PASSWORD} jarchivelib-1.2.0/.travis.yml000066400000000000000000000016001410446056500161070ustar00rootroot00000000000000language: java jobs: include: - stage: test # test jobs os: linux dist: trusty jdk: openjdk7 - os: linux dist: trusty jdk: openjdk8 - os: linux dist: trusty jdk: oraclejdk9 - os: linux dist: xenial jdk: openjdk10 - os: linux dist: xenial jdk: openjdk11 - os: linux dist: bionic jdk: openjdk14 # deploy job (re-run jdk7 build) - stage: deploy os: linux dist: trusty jdk: openjdk7 after_success: - mvn clean cobertura:cobertura coveralls:report - mvn clean deploy -DskipTests --settings .travis-settings.xml env: global: - SONATYPE_USERNAME=thrau - secure: RC4WPxCVQMI1Y+F0Qh1SVozaHB6035yn4VjMgvTrXuR2Vf3dsvKaxOtaIn7zwzX4suBDJQE55Lo4l7AjI8En6LtEMKrZmgGMgQGWLO2I51rCgWGyFsW9MOYxf3SoDApl2YmhwbGsVEhAYogYhoXyO0CWsHAJTfnnI3Tc+Onf0+M= jarchivelib-1.2.0/LICENSE000066400000000000000000000261361410446056500150160ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. jarchivelib-1.2.0/README.md000066400000000000000000000065111410446056500152630ustar00rootroot00000000000000jarchivelib =========== [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.rauschig/jarchivelib/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.rauschig/jarchivelib/) [![Build Status](https://travis-ci.org/thrau/jarchivelib.svg?branch=master)](https://travis-ci.org/thrau/jarchivelib) [![Coverage Status](https://coveralls.io/repos/thrau/jarchivelib/badge.svg)](https://coveralls.io/r/thrau/jarchivelib) A simple archiving and compression library for Java that provides a thin and easy-to-use API layer on top of the powerful and feature-rich [org.apache.commons.compress]. [org.apache.commons.compress]: http://commons.apache.org/proper/commons-compress/ Usage ----- ### Using the ArchiverFactory Create a new Archiver to handle zip archives ```java Archiver archiver = ArchiverFactory.createArchiver(ArchiveFormat.ZIP); ``` Create a new Archiver to handle tar archives with gzip compression ```java Archiver archiver = ArchiverFactory.createArchiver(ArchiveFormat.TAR, CompressionType.GZIP); ``` Alternatively you can use string representations of the archive and compression types. ```java Archiver archiver = ArchiverFactory.createArchiver("zip"); ``` The ArchiveFactory can also detect archive types based on file extensions and hand you the correct Archiver. This example returns an Archiver instance that handles tar.gz files. (It would also recognize the `.tgz` extension) ```java Archiver archiver = ArchiverFactory.createArchiver(new File("archive.tar.gz")); ``` ### Using Archivers #### Extract To extract the zip archive `/home/jack/archive.zip` to `/home/jack/archive`: ```java File archive = new File("/home/jack/archive.zip"); File destination = new File("/home/jack/archive"); Archiver archiver = ArchiverFactory.createArchiver(ArchiveFormat.ZIP); archiver.extract(archive, destination); ``` #### Create To create a new tar archive with gzip compression `archive.tar.gz` in `/home/jack/` containing the entire directory `/home/jack/archive` ```java String archiveName = "archive"; File destination = new File("/home/jack"); File source = new File("/home/jack/archive"); Archiver archiver = ArchiverFactory.createArchiver(ArchiveFormat.TAR, CompressionType.GZIP); File archive = archiver.create(archiveName, destination, source); ``` notice that you can omit the filename extension in the archive name, as it will be appended by the archiver automatically if it is missing. #### Stream To access the contents of an archive as a Stream, rather than extracting them directly onto the filesystem ```java ArchiveStream stream = archiver.stream(archive); ArchiveEntry entry; while((entry = stream.getNextEntry()) != null) { // access each archive entry individually using the stream // or extract it using entry.extract(destination) // or fetch meta-data using entry.getName(), entry.isDirectory(), ... } stream.close(); ``` Dependencies ------------ * commons-compress(tm) 1.20 Compatibility ------------- * Java 7, 8, 9, 10, 14 * Currently only tested for *nix file systems. ### OSGi jarchivelib compiles to a bundle and is OSGi compatible ### jarchivelib 0.8.x and below * Java 6 and 7 Known limitations ----------------- * Permissions are not stored when creating archives * There is no support for Windows permissions * JAR files are treated like streamed zip files and can not restore permissions jarchivelib-1.2.0/pom.xml000066400000000000000000000115151410446056500153210ustar00rootroot00000000000000 4.0.0 org.rauschig oss-parent 1 org.rauschig jarchivelib 1.2.0 bundle Java archiving library A simple library that facades org.apache.commons.compress, to provide an easy-to-use API for archiving and compressing into and out of File objects. 2013 http://rauschig.org/jarchivelib https://github.com/thrau/jarchivelib scm:git:git://git@github.com:thrau/jarchivelib.git scm:git:git@github.com:thrau/jarchivelib.git v1.2.0 thrau Thomas Rausch thomas@rauschig.org 1.21 1.8 4.13.1 ${project.groupId} :: ${project.artifactId} :: ${project.name} ${project.groupId}.${project.artifactId} ${project.groupId}.${project.artifactId} org.apache.felix maven-bundle-plugin true ${bundle.symbolicName} ${bundle.name} ${project.version} ${bundle.namespace}.*;version="${project.version}" maven-compiler-plugin 1.7 1.7 maven-assembly-plugin jar-with-dependencies com.mycila.maven-license-plugin maven-license-plugin src/test/resources/** Thomas Rausch 2013 org.eluder.coveralls coveralls-maven-plugin 3.0.1 org.codehaus.mojo cobertura-maven-plugin 2.6 xml 256m org.apache.commons commons-compress ${commons.compress.version} org.tukaani xz ${xz.version} true junit junit ${junit.version} test jarchivelib-1.2.0/src/000077500000000000000000000000001410446056500145705ustar00rootroot00000000000000jarchivelib-1.2.0/src/main/000077500000000000000000000000001410446056500155145ustar00rootroot00000000000000jarchivelib-1.2.0/src/main/java/000077500000000000000000000000001410446056500164355ustar00rootroot00000000000000jarchivelib-1.2.0/src/main/java/org/000077500000000000000000000000001410446056500172245ustar00rootroot00000000000000jarchivelib-1.2.0/src/main/java/org/rauschig/000077500000000000000000000000001410446056500210315ustar00rootroot00000000000000jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/000077500000000000000000000000001410446056500233135ustar00rootroot00000000000000jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/ArchiveEntry.java000066400000000000000000000051071410446056500265640ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.File; import java.io.IOException; import java.util.Date; /** * The entry of an archive. * * The life of an {@link ArchiveEntry} is dependent on the status of the {@link ArchiveStream} it came from. Once * retrieved via {@link ArchiveStream#getNextEntry()}, the entry can be used as long as the {@code ArchiveStream} * remains on this entry, i.e. {@code getNextEntry()} was not called, and the stream was not since closed. */ public interface ArchiveEntry { /** * Special value indicating that the size is unknown */ static final long UNKNOWN_SIZE = -1; /** * The name of the entry in the archive. May refer to a file or directory or other item. * * @return the name of the item */ String getName(); /** * The (uncompressed) size of the entry. May be -1 (UNKNOWN_SIZE) if the size is unknown * * @return the size of the entry once uncompressed, or -1 if unknown. */ long getSize(); /** * Returns the last modified date of the entry. * * @return the date the entry was last modified. */ Date getLastModifiedDate(); /** * Checks whether the given entry is a directory. * * @return true if the entry refers to a directory */ boolean isDirectory(); /** * Extracts the entry to the given destination directory. * * The destination is expected to be a writable directory. * * @param destination the directory to extract the value to * @return the extracted File * @throws IOException propagated I/O errors by {@code java.io} * @throws IllegalStateException if the entry is out of sync with the stream * @throws IllegalArgumentException if the destination is not a directory, or a directory can not be created at the * given location */ File extract(File destination) throws IOException, IllegalStateException, IllegalArgumentException; } jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/ArchiveFormat.java000066400000000000000000000072041410446056500267130ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import org.apache.commons.compress.archivers.ArchiveStreamFactory; /** * Denotes an archive format such as zip or tar. */ public enum ArchiveFormat { /** * Constant used to identify the AR archive format. */ AR(ArchiveStreamFactory.AR, ".ar"), /** * Constant used to identify the CPIO archive format. */ CPIO(ArchiveStreamFactory.CPIO, ".cpio"), /** * Constant used to identify the Unix DUMP archive format. */ DUMP(ArchiveStreamFactory.DUMP, ".dump"), /** * Constant used to identify the JAR archive format. */ JAR(ArchiveStreamFactory.JAR, ".jar"), /** * Constant used to identify the 7z archive format. */ SEVEN_Z(ArchiveStreamFactory.SEVEN_Z, ".7z"), /** * Constant used to identify the TAR archive format. */ TAR(ArchiveStreamFactory.TAR, ".tar"), /** * Constant used to identify the ZIP archive format. */ ZIP(ArchiveStreamFactory.ZIP, ".zip"); /** * The name by which the compression algorithm is identified. */ private final String name; /** * default file extension the archive format is mapped to */ private final String defaultFileExtension; private ArchiveFormat(String name, String defaultFileExtension) { this.name = name; this.defaultFileExtension = defaultFileExtension; } /** * Returns the name by which the archive format is identified. * * @return the archiver format name */ public String getName() { return name; } /** * Returns the default file extension for this compression type. E.g. ".gz" for gzip. * * @return the default file extension preceded by a dot */ public String getDefaultFileExtension() { return defaultFileExtension; } /** * Checks if the given archive format name is valid and known format. * * @param archiveFormat the archive format name * @return true if the given archive format is known to the factory, false otherwise */ public static boolean isValidArchiveFormat(String archiveFormat) { for (ArchiveFormat format : values()) { if (archiveFormat.trim().equalsIgnoreCase(format.getName())) { return true; } } return false; } /** * Attempts to return the {@link ArchiveFormat} instance from a possible given string representation. Ignores case. * * @param archiveFormat string representation of the archive format. E.g. "tar" or "ZIP". * @return the compression type enum * @throws IllegalArgumentException if the given archive format is unknown. */ public static ArchiveFormat fromString(String archiveFormat) { for (ArchiveFormat format : values()) { if (archiveFormat.trim().equalsIgnoreCase(format.getName())) { return format; } } throw new IllegalArgumentException("Unknown archive format " + archiveFormat); } } jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/ArchiveStream.java000066400000000000000000000043421410446056500267160ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.Closeable; import java.io.IOException; import java.io.InputStream; /** * An input stream of an archive. Can be used to retrieve each individual {@link ArchiveEntry}. *
* The {@link #getNextEntry()} method is used to reset the input stream ready for reading the data from the next entry. */ public abstract class ArchiveStream extends InputStream implements Closeable { private ArchiveEntry currentEntry; private boolean closed; /** * Returns the {@link ArchiveEntry} the stream currently points to. * * @return the current {@link ArchiveEntry} */ public ArchiveEntry getCurrentEntry() { return currentEntry; } /** * Moves the pointer of the stream to the next {@link ArchiveEntry} and returns it. * * @return the next archive entry. * @throws IOException propagated I/O exception */ public ArchiveEntry getNextEntry() throws IOException { currentEntry = createNextEntry(); return currentEntry; } /** * Abstract method to create the next {@link ArchiveEntry} for the {@link ArchiveStream} implementation. * * @return the next archive entry * @throws IOException propagated I/O exception */ protected abstract ArchiveEntry createNextEntry() throws IOException; @Override public void close() throws IOException { closed = true; } /** * Checks whether the current stream has been closed * * @return true if the stream has been closed */ public boolean isClosed() { return closed; } } jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/Archiver.java000066400000000000000000000106501410446056500257230ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.File; import java.io.IOException; import java.io.InputStream; /** * An Archiver facades a specific archiving library, allowing for simple archiving of files and directories, and * extraction of archives. *
* Some archivers might use an additional {@link Compressor} to compress and decompress their respective archive files. */ public interface Archiver { /** * Creates an archive from the given source file or directory, and saves it into the given destination. *
* If the source is a directory, the archive will contain all the files in that directory, but not the directory * itself. *
* If the archive parameter has no file extension (e.g. "archive" instead of "archive.zip"), the concrete archiver * implementation should append it according to its file format (.zip, .tar, .tar.gz, ...). * * @param archive the name of the archive to create * @param destination the destination directory where to place the created archive * @param source the input file or directory to archive * @return the newly created archive file * @throws IOException propagated I/O errors by {@code java.io} */ File create(String archive, File destination, File source) throws IOException; /** * Creates an archive from the given source files or directories, and saves it into the given destination. *
* If the source is a directory, the archive will contain all the files in that directory, but not the directory * itself. *
* If the archive parameter has no file extension (e.g. "archive" instead of "archive.zip"), the concrete archiver * implementation should append it according to its file format (.zip, .tar, .tar.gz, ...). * * @param archive the name of the archive to create * @param destination the destination directory where to place the created archive * @param sources the input files or directories to archive * @return the newly created archive file * @throws IOException propagated I/O errors by {@code java.io} */ File create(String archive, File destination, File... sources) throws IOException; /** * Extracts the given archive file into the given destination directory. *
* The destination is expected to be a writable directory. * * @param archive the archive file to extract * @param destination the directory to which to extract the files * @throws IOException propagated I/O errors by {@code java.io} */ void extract(File archive, File destination) throws IOException; /** * Extracts the given archive supplied as an input stream into the given destination directory. *
* The destination directory is expected to be a writable directory. * * @param archive the archive contents as a stream. * @param destination the destination directory. * @throws IOException */ void extract(InputStream archive, File destination) throws IOException; /** * Reads the given archive file as an {@link ArchiveStream} which is used to access individual {@link ArchiveEntry} * objects within the archive without extracting the archive onto the file system. * * @param archive the archive file to stream * @return a new archive stream for the given archive * @throws IOException propagated I/O errors by {@code java.io} */ ArchiveStream stream(File archive) throws IOException; /** * Returns the filename extension that indicates the file format this archiver handles. E.g .tar" or ".zip". In case * of compressed archives, it will return the composite filename extensions, e.g. ".tar.gz" * * @return a filename extension with a preceding dot */ String getFilenameExtension(); } jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/ArchiverCompressorDecorator.java000066400000000000000000000123671410446056500316520ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import static org.rauschig.jarchivelib.CommonsStreamFactory.createArchiveInputStream; import static org.rauschig.jarchivelib.CommonsStreamFactory.createCompressorInputStream; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import org.apache.commons.compress.archivers.ArchiveException; import org.apache.commons.compress.compressors.CompressorException; /** * Decorates an {@link Archiver} with a {@link Compressor}, s.t. it is able to compress the archives it generates and * decompress the archives it extracts. */ class ArchiverCompressorDecorator implements Archiver { private CommonsArchiver archiver; private CommonsCompressor compressor; /** * Decorates the given Archiver with the given Compressor. * * @param archiver the archiver to decorate * @param compressor the compressor used for compression */ ArchiverCompressorDecorator(CommonsArchiver archiver, CommonsCompressor compressor) { this.archiver = archiver; this.compressor = compressor; } @Override public File create(String archive, File destination, File source) throws IOException { return create(archive, destination, IOUtils.filesContainedIn(source)); } @Override public File create(String archive, File destination, File... sources) throws IOException { IOUtils.requireDirectory(destination); File temp = File.createTempFile(destination.getName(), archiver.getFilenameExtension(), destination); File destinationArchive = null; try { temp = archiver.create(temp.getName(), temp.getParentFile(), sources); destinationArchive = new File(destination, getArchiveFileName(archive)); compressor.compress(temp, destinationArchive); } finally { temp.delete(); } return destinationArchive; } @Override public void extract(File archive, File destination) throws IOException { IOUtils.requireDirectory(destination); /* * The decompressor has to map F-N-F to I-A-E in some cases to preserve compatibility, * and we don't want that here. */ if (!archive.exists()) { throw new FileNotFoundException(String.format("Archive %s does not exist.", archive.getAbsolutePath())); } InputStream archiveStream = null; try { archiveStream = new BufferedInputStream(new FileInputStream(archive)); archiver.extract(compressor.decompressingStream(archiveStream), destination); } catch (FileNotFoundException e) { // Java throws F-N-F for no access, and callers expect I-A-E for that. throw new IllegalArgumentException(String.format("Access control or other error opening %s", archive.getAbsolutePath()), e); } finally { IOUtils.closeQuietly(archiveStream); } } @Override public void extract(InputStream archive, File destination) throws IOException { IOUtils.requireDirectory(destination); archiver.extract(compressor.decompressingStream(archive), destination); } @Override public ArchiveStream stream(File archive) throws IOException { try { return new CommonsArchiveStream(createArchiveInputStream(archiver, createCompressorInputStream(archive))); } catch (ArchiveException e) { throw new IOException(e); } catch (CompressorException e) { throw new IOException(e); } } @Override public String getFilenameExtension() { return archiver.getFilenameExtension() + compressor.getFilenameExtension(); } /** * Returns a file name from the given archive name. The file extension suffix will be appended according to what is * already present. *
* E.g. if the compressor uses the file extension "gz", the archiver "tar", and passed argument is "archive.tar", * the returned value will be "archive.tar.gz". * * @param archive the existing archive file name * @return the normalized archive file name including the correct file name extension */ private String getArchiveFileName(String archive) { String fileExtension = getFilenameExtension(); if (archive.endsWith(fileExtension)) { return archive; } else if (archive.endsWith(archiver.getFilenameExtension())) { return archive + compressor.getFilenameExtension(); } else { return archive + fileExtension; } } } jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/ArchiverFactory.java000066400000000000000000000123251410446056500272540ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.File; /** * Factory for creating {@link Archiver} instances by a given archiver type name. Use the constants in this class to * pass to the factory method. */ public final class ArchiverFactory { private ArchiverFactory() { } /** * Probes the given {@link File} for its file type and creates an {@link Archiver} based on this file type. If the * File has a composite file extension such as ".tar.gz", the created {@link Archiver} will also handle ".gz" * compression. * * @param archive the archive file to check. * @return a new Archiver instance (that may also handle compression) * @throws IllegalArgumentException if the given file is not a known archive */ public static Archiver createArchiver(File archive) throws IllegalArgumentException { FileType fileType = FileType.get(archive); if (fileType == FileType.UNKNOWN) { throw new IllegalArgumentException("Unknown file extension " + archive.getName()); } return createArchiver(fileType); } /** * Creates an Archiver that handles the given {@link FileType}. The Archiver may handle compression inherently, if * the {@link FileType} uses a compression type, such as ".tgz" might. * * @param fileType the file type * @return a new Archiver instance (that may also handle compression) */ public static Archiver createArchiver(FileType fileType) { if (fileType == FileType.UNKNOWN) { throw new IllegalArgumentException("Unknown file type"); } if (fileType.isArchive() && fileType.isCompressed()) { return createArchiver(fileType.getArchiveFormat(), fileType.getCompressionType()); } else if (fileType.isArchive()) { return createArchiver(fileType.getArchiveFormat()); } else { throw new IllegalArgumentException("Unknown archive file extension " + fileType); } } /** * Creates an Archiver for the given archive format that uses compression. * * @param archiveFormat the archive format e.g. "tar" or "zip" * @param compression the compression algorithm name e.g. "gz" * @return a new Archiver instance that also handles compression * @throws IllegalArgumentException if the archive format or the compression type is unknown */ public static Archiver createArchiver(String archiveFormat, String compression) throws IllegalArgumentException { if (!ArchiveFormat.isValidArchiveFormat(archiveFormat)) { throw new IllegalArgumentException("Unknown archive format " + archiveFormat); } if (!CompressionType.isValidCompressionType(compression)) { throw new IllegalArgumentException("Unknown compression type " + compression); } return createArchiver(ArchiveFormat.fromString(archiveFormat), CompressionType.fromString(compression)); } /** * Creates an Archiver for the given archive format that uses compression. * * @param archiveFormat the archive format * @param compression the compression algorithm * @return a new Archiver instance that also handles compression */ public static Archiver createArchiver(ArchiveFormat archiveFormat, CompressionType compression) { CommonsArchiver archiver = new CommonsArchiver(archiveFormat); CommonsCompressor compressor = new CommonsCompressor(compression); return new ArchiverCompressorDecorator(archiver, compressor); } /** * Creates an Archiver for the given archive format. * * @param archiveFormat the archive format e.g. "tar" or "zip" * @return a new Archiver instance * @throws IllegalArgumentException if the archive format is unknown */ public static Archiver createArchiver(String archiveFormat) throws IllegalArgumentException { if (!ArchiveFormat.isValidArchiveFormat(archiveFormat)) { throw new IllegalArgumentException("Unknown archive format " + archiveFormat); } return createArchiver(ArchiveFormat.fromString(archiveFormat)); } /** * Creates an Archiver for the given archive format. * * @param archiveFormat the archive format * @return a new Archiver instance */ public static Archiver createArchiver(ArchiveFormat archiveFormat) { if (archiveFormat == ArchiveFormat.SEVEN_Z) { return new SevenZArchiver(); } else if (archiveFormat == ArchiveFormat.ZIP) { return new ZipFileArchiver(); } return new CommonsArchiver(archiveFormat); } } jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/AttributeAccessor.java000066400000000000000000000106001410446056500276010ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.IOException; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ar.ArArchiveEntry; import org.apache.commons.compress.archivers.arj.ArjArchiveEntry; import org.apache.commons.compress.archivers.cpio.CpioArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; /** * Adapter for accessing mode flags from the different types of ArchiveEntries. * * @param the type of ArchiveEntry */ abstract class AttributeAccessor { private E entry; public AttributeAccessor(E entry) { this.entry = entry; } /** * Returns the entry that is being accessed * * @return the entry */ public E getEntry() { return entry; } /** * Returns the unix file mode. * * @return unix file mode flags * @throws java.io.IOException */ public abstract int getMode() throws IOException; /** * Detects the type of the given ArchiveEntry and returns an appropriate AttributeAccessor for it. * * @param entry the adaptee * @return a new attribute accessor instance */ public static AttributeAccessor create(ArchiveEntry entry) { if (entry instanceof TarArchiveEntry) { return new TarAttributeAccessor((TarArchiveEntry) entry); } else if (entry instanceof ZipArchiveEntry) { return new ZipAttributeAccessor((ZipArchiveEntry) entry); } else if (entry instanceof CpioArchiveEntry) { return new CpioAttributeAccessor((CpioArchiveEntry) entry); } else if (entry instanceof ArjArchiveEntry) { return new ArjAttributeAccessor((ArjArchiveEntry) entry); } else if (entry instanceof ArArchiveEntry) { return new ArAttributeAccessor((ArArchiveEntry) entry); } return new FallbackAttributeAccessor(entry); } public static class FallbackAttributeAccessor extends AttributeAccessor { protected FallbackAttributeAccessor(ArchiveEntry entry) { super(entry); } @Override public int getMode() { return 0; } } public static class TarAttributeAccessor extends AttributeAccessor { public TarAttributeAccessor(TarArchiveEntry entry) { super(entry); } @Override public int getMode() { return getEntry().getMode(); } } public static class ZipAttributeAccessor extends AttributeAccessor { public ZipAttributeAccessor(ZipArchiveEntry entry) { super(entry); } @Override public int getMode() { return getEntry().getUnixMode(); } } public static class CpioAttributeAccessor extends AttributeAccessor { public CpioAttributeAccessor(CpioArchiveEntry entry) { super(entry); } @Override public int getMode() { return (int) getEntry().getMode(); } } public static class ArjAttributeAccessor extends AttributeAccessor { public ArjAttributeAccessor(ArjArchiveEntry entry) { super(entry); } @Override public int getMode() throws IOException { return getEntry().getMode(); } } public static class ArAttributeAccessor extends AttributeAccessor { public ArAttributeAccessor(ArArchiveEntry entry) { super(entry); } @Override public int getMode() throws IOException { return getEntry().getMode(); } } } jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/CommonsArchiveEntry.java000066400000000000000000000047771410446056500301340ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.File; import java.io.IOException; import java.util.Date; /** * Implementation of an {@link ArchiveEntry} that wraps the commons compress version of the same type. */ class CommonsArchiveEntry implements ArchiveEntry { /** * The wrapped {@code ArchiveEntry} entry. */ private org.apache.commons.compress.archivers.ArchiveEntry entry; /** * The {@link ArchiveStream} this entry belongs to. */ private ArchiveStream stream; CommonsArchiveEntry(ArchiveStream stream, org.apache.commons.compress.archivers.ArchiveEntry entry) { this.stream = stream; this.entry = entry; } @Override public String getName() { assertState(); return entry.getName(); } @Override public long getSize() { assertState(); return entry.getSize(); } @Override public Date getLastModifiedDate() { assertState(); return entry.getLastModifiedDate(); } @Override public boolean isDirectory() { assertState(); return entry.isDirectory(); } @Override public File extract(File destination) throws IOException, IllegalStateException, IllegalArgumentException { assertState(); IOUtils.requireDirectory(destination); File file = new File(destination, entry.getName()); if (entry.isDirectory()) { file.mkdirs(); } else { file.getParentFile().mkdirs(); IOUtils.copy(stream, file); } FileModeMapper.map(entry, file); return file; } private void assertState() { if (stream.isClosed()) { throw new IllegalStateException("Stream has already been closed"); } if (this != stream.getCurrentEntry()) { throw new IllegalStateException("Illegal stream pointer"); } } } jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/CommonsArchiveStream.java000066400000000000000000000033171410446056500302530ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.IOException; import org.apache.commons.compress.archivers.ArchiveInputStream; /** * {@link ArchiveStream} implementation that wraps a commons compress {@link ArchiveInputStream}. */ class CommonsArchiveStream extends ArchiveStream { private ArchiveInputStream stream; CommonsArchiveStream(ArchiveInputStream stream) { this.stream = stream; } @Override protected ArchiveEntry createNextEntry() throws IOException { org.apache.commons.compress.archivers.ArchiveEntry next = stream.getNextEntry(); return (next == null) ? null : new CommonsArchiveEntry(this, next); } @Override public int read() throws IOException { return stream.read(); } @Override public int read(byte[] b) throws IOException { return stream.read(b); } @Override public int read(byte[] b, int off, int len) throws IOException { return stream.read(b, off, len); } @Override public void close() throws IOException { super.close(); stream.close(); } } jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/CommonsArchiver.java000066400000000000000000000246371410446056500272710ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ArchiveException; import org.apache.commons.compress.archivers.ArchiveInputStream; import org.apache.commons.compress.archivers.ArchiveOutputStream; import org.apache.commons.compress.archivers.ArchiveStreamFactory; import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; /** * Implementation of an {@link Archiver} that uses {@link ArchiveStreamFactory} to generate archive streams by a given * archiver name passed when creating the {@code GenericArchiver}. Thus, it can be used for all archive formats the * {@code org.apache.commons.compress} library supports. */ class CommonsArchiver implements Archiver { private final ArchiveFormat archiveFormat; CommonsArchiver(ArchiveFormat archiveFormat) { this.archiveFormat = archiveFormat; } public ArchiveFormat getArchiveFormat() { return archiveFormat; } @Override public File create(String archive, File destination, File source) throws IOException { return create(archive, destination, IOUtils.filesContainedIn(source)); } @Override public File create(String archive, File destination, File... sources) throws IOException { IOUtils.requireDirectory(destination); File archiveFile = createNewArchiveFile(archive, getFilenameExtension(), destination); ArchiveOutputStream outputStream = null; try { outputStream = createArchiveOutputStream(archiveFile); writeToArchive(sources, outputStream); outputStream.flush(); } finally { IOUtils.closeQuietly(outputStream); } return archiveFile; } @Override public void extract(File archive, File destination) throws IOException { assertExtractSource(archive); IOUtils.requireDirectory(destination); ArchiveInputStream input = null; try { input = createArchiveInputStream(archive); extract(input, destination); } finally { IOUtils.closeQuietly(input); } } @Override public void extract(InputStream archive, File destination) throws IOException { ArchiveInputStream input = createArchiveInputStream(archive); extract(input, destination); } private void extract(ArchiveInputStream input, File destination) throws IOException { ArchiveEntry entry; while ((entry = input.getNextEntry()) != null) { File file = new File(destination, entry.getName()); if (entry.isDirectory()) { file.mkdirs(); } else { file.getParentFile().mkdirs(); IOUtils.copy(input, file); } FileModeMapper.map(entry, file); } } @Override public ArchiveStream stream(File archive) throws IOException { return new CommonsArchiveStream(createArchiveInputStream(archive)); } @Override public String getFilenameExtension() { return getArchiveFormat().getDefaultFileExtension(); } /** * Returns a new ArchiveInputStream for reading archives. Subclasses can override this to return their own custom * implementation. * * @param archive the archive file to stream from * @return a new ArchiveInputStream for the given archive file * @throws IOException propagated IO exceptions */ protected ArchiveInputStream createArchiveInputStream(File archive) throws IOException { try { return CommonsStreamFactory.createArchiveInputStream(archive); } catch (ArchiveException e) { throw new IOException(e); } } /** * Returns a new ArchiveInputStream for reading archives. Subclasses can override this to return their own custom * implementation. * * @param archive the archive contents to stream from * @return a new ArchiveInputStream for the given archive file * @throws IOException propagated IO exceptions */ protected ArchiveInputStream createArchiveInputStream(InputStream archive) throws IOException { try { return CommonsStreamFactory.createArchiveInputStream(archive); } catch (ArchiveException e) { throw new IOException(e); } } /** * Returns a new ArchiveOutputStream for creating archives. Subclasses can override this to return their own custom * implementation. * * @param archiveFile the archive file to stream to * @return a new ArchiveOutputStream for the given archive file. * @throws IOException propagated IO exceptions */ protected ArchiveOutputStream createArchiveOutputStream(File archiveFile) throws IOException { try { ArchiveOutputStream archiveOutputStream = CommonsStreamFactory.createArchiveOutputStream(this, archiveFile); if (archiveOutputStream instanceof TarArchiveOutputStream) { ((TarArchiveOutputStream) archiveOutputStream).setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX); } return archiveOutputStream; } catch (ArchiveException e) { throw new IOException(e); } } /** * Asserts that the given File object is a readable file that can be used to extract from. * * @param archive the file to check * @throws FileNotFoundException if the file does not exist * @throws IllegalArgumentException if the file is a directory or not readable */ protected void assertExtractSource(File archive) throws FileNotFoundException, IllegalArgumentException { if (archive.isDirectory()) { throw new IllegalArgumentException("Can not extract " + archive + ". Source is a directory."); } else if (!archive.exists()) { throw new FileNotFoundException(archive.getPath()); } else if (!archive.canRead()) { throw new IllegalArgumentException("Can not extract " + archive + ". Can not read from source."); } } /** * Creates a new File in the given destination. The resulting name will always be "archive"."fileExtension". If the * archive name parameter already ends with the given file name extension, it is not additionally appended. * * @param archive the name of the archive * @param extension the file extension (e.g. ".tar") * @param destination the parent path * @return the newly created file * @throws IOException if an I/O error occurred while creating the file */ protected File createNewArchiveFile(String archive, String extension, File destination) throws IOException { if (!archive.endsWith(extension)) { archive += extension; } File file = new File(destination, archive); file.createNewFile(); return file; } /** * Recursion entry point for {@link #writeToArchive(File, File[], ArchiveOutputStream)}. *
* Recursively writes all given source {@link File}s into the given {@link ArchiveOutputStream}. * * @param sources the files to write in to the archive * @param archive the archive to write into * @throws IOException when an I/O error occurs */ protected void writeToArchive(File[] sources, ArchiveOutputStream archive) throws IOException { for (File source : sources) { if (!source.exists()) { throw new FileNotFoundException(source.getPath()); } else if (!source.canRead()) { throw new FileNotFoundException(source.getPath() + " (Permission denied)"); } writeToArchive(source.getParentFile(), new File[]{ source }, archive); } } /** * Recursively writes all given source {@link File}s into the given {@link ArchiveOutputStream}. The paths of the * sources in the archive will be relative to the given parent {@code File}. * * @param parent the parent file node for computing a relative path (see {@link IOUtils#relativePath(File, File)}) * @param sources the files to write in to the archive * @param archive the archive to write into * @throws IOException when an I/O error occurs */ protected void writeToArchive(File parent, File[] sources, ArchiveOutputStream archive) throws IOException { for (File source : sources) { String relativePath = IOUtils.relativePath(parent, source); createArchiveEntry(source, relativePath, archive); if (source.isDirectory()) { writeToArchive(parent, source.listFiles(), archive); } } } /** * Creates a new {@link ArchiveEntry} in the given {@link ArchiveOutputStream}, and copies the given {@link File} * into the new entry. * * @param file the file to add to the archive * @param entryName the name of the archive entry * @param archive the archive to write to * @throws IOException when an I/O error occurs during FileInputStream creation or during copying */ protected void createArchiveEntry(File file, String entryName, ArchiveOutputStream archive) throws IOException { ArchiveEntry entry = archive.createArchiveEntry(file, entryName); // TODO #23: read permission from file, write it to the ArchiveEntry archive.putArchiveEntry(entry); if (!entry.isDirectory()) { FileInputStream input = null; try { input = new FileInputStream(file); IOUtils.copy(input, archive); } finally { IOUtils.closeQuietly(input); } } archive.closeArchiveEntry(); } } jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/CommonsCompressor.java000066400000000000000000000127751410446056500276620ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import static org.rauschig.jarchivelib.CommonsStreamFactory.createCompressorInputStream; import static org.rauschig.jarchivelib.CommonsStreamFactory.createCompressorOutputStream; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import org.apache.commons.compress.compressors.CompressorException; import org.apache.commons.compress.compressors.CompressorInputStream; import org.apache.commons.compress.compressors.CompressorOutputStream; import org.apache.commons.compress.compressors.CompressorStreamFactory; /** * Implementation of a compressor that uses {@link CompressorStreamFactory} to generate compressor streams by a given * compressor name passed when creating the GenericCompressor. Thus, it can be used for all compression algorithms the * {@code org.apache.commons.compress} library supports. */ class CommonsCompressor implements Compressor { private final CompressionType compressionType; CommonsCompressor(CompressionType type) { this.compressionType = type; } public CompressionType getCompressionType() { return compressionType; } @Override public void compress(File source, File destination) throws IllegalArgumentException, IOException { assertSource(source); assertDestination(destination); if (destination.isDirectory()) { destination = new File(destination, getCompressedFilename(source)); } CompressorOutputStream compressed = null; BufferedInputStream input = null; try { input = new BufferedInputStream(new FileInputStream(source)); compressed = createCompressorOutputStream(this, destination); IOUtils.copy(input, compressed); } catch (CompressorException e) { throw new IOException(e); } finally { IOUtils.closeQuietly(compressed); IOUtils.closeQuietly(input); } } @Override public void decompress(File source, File destination) throws IOException { assertSource(source); assertDestination(destination); if (destination.isDirectory()) { destination = new File(destination, getDecompressedFilename(source)); } CompressorInputStream compressed = null; FileOutputStream output = null; try { compressed = createCompressorInputStream(getCompressionType(), source); output = new FileOutputStream(destination); IOUtils.copy(compressed, output); } catch (CompressorException e) { throw new IOException(e); } finally { IOUtils.closeQuietly(compressed); IOUtils.closeQuietly(output); } } @Override public InputStream decompressingStream(InputStream compressedStream) throws IOException { try { return CommonsStreamFactory.createCompressorInputStream(getCompressionType(), compressedStream); } catch (CompressorException e) { throw new IOException(e); } } @Override public String getFilenameExtension() { return getCompressionType().getDefaultFileExtension(); } private String getCompressedFilename(File source) { return source.getName() + getFilenameExtension(); } private String getDecompressedFilename(File source) { FileType fileType = FileType.get(source); if (compressionType != fileType.getCompressionType()) { throw new IllegalArgumentException(source + " is not of type " + compressionType); } return source.getName().substring(0, source.getName().length() - fileType.getSuffix().length()); } private void assertSource(File source) throws IllegalArgumentException, FileNotFoundException { if (source == null) { throw new IllegalArgumentException("Source is null"); } else if (source.isDirectory()) { throw new IllegalArgumentException("Source " + source + " is a directory."); } else if (!source.exists()) { throw new FileNotFoundException(source.getName()); } else if (!source.canRead()) { throw new IllegalArgumentException("Can not read from source " + source); } } private void assertDestination(File destination) { if (destination == null) { throw new IllegalArgumentException("Destination is null"); } else if (destination.isDirectory()) { if (!destination.canWrite()) { throw new IllegalArgumentException("Can not write to destination " + destination); } } else if (destination.exists() && !destination.canWrite()) { throw new IllegalArgumentException("Can not write to destination " + destination); } } } jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/CommonsStreamFactory.java000066400000000000000000000204231410446056500302760ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; 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 org.apache.commons.compress.archivers.ArchiveException; import org.apache.commons.compress.archivers.ArchiveInputStream; import org.apache.commons.compress.archivers.ArchiveOutputStream; import org.apache.commons.compress.archivers.ArchiveStreamFactory; import org.apache.commons.compress.compressors.CompressorException; import org.apache.commons.compress.compressors.CompressorInputStream; import org.apache.commons.compress.compressors.CompressorOutputStream; import org.apache.commons.compress.compressors.CompressorStreamFactory; /** * Wraps the two commons-compress factory types {@link CompressorFactory} and {@link ArchiveStreamFactory} into a * singleton factory. */ final class CommonsStreamFactory { private CommonsStreamFactory() { } private static CompressorStreamFactory compressorStreamFactory; private static ArchiveStreamFactory archiveStreamFactory; static { archiveStreamFactory = new ArchiveStreamFactory(); compressorStreamFactory = new CompressorStreamFactory(); } /** * @see {@link ArchiveStreamFactory#createArchiveInputStream(String, InputStream)} */ static ArchiveInputStream createArchiveInputStream(String archiverName, InputStream in) throws ArchiveException { return archiveStreamFactory.createArchiveInputStream(archiverName, in); } /** * @see {@link ArchiveStreamFactory#createArchiveInputStream(String, InputStream)} */ static ArchiveInputStream createArchiveInputStream(ArchiveFormat archiveFormat, InputStream in) throws ArchiveException { return createArchiveInputStream(archiveFormat.getName(), in); } /** * @see {@link ArchiveStreamFactory#createArchiveInputStream(String, InputStream)} */ static ArchiveInputStream createArchiveInputStream(CommonsArchiver archiver, InputStream in) throws ArchiveException { return createArchiveInputStream(archiver.getArchiveFormat(), in); } /** * @see {@link ArchiveStreamFactory#createArchiveInputStream(InputStream)}; */ static ArchiveInputStream createArchiveInputStream(InputStream in) throws ArchiveException { return archiveStreamFactory.createArchiveInputStream(new BufferedInputStream(in)); } /** * Uses the {@link ArchiveStreamFactory} to create a new {@link ArchiveInputStream} for the given archive file. * * @param archive the archive file * @return a new {@link ArchiveInputStream} for the given archive file * @throws IOException propagated IOException when creating the FileInputStream. * @throws ArchiveException if the archiver name is not known */ static ArchiveInputStream createArchiveInputStream(File archive) throws IOException, ArchiveException { return createArchiveInputStream(new BufferedInputStream(new FileInputStream(archive))); } /** * @see {@link ArchiveStreamFactory#createArchiveOutputStream(String, OutputStream)}; */ static ArchiveOutputStream createArchiveOutputStream(String archiverName, OutputStream out) throws ArchiveException { return archiveStreamFactory.createArchiveOutputStream(archiverName, out); } static ArchiveOutputStream createArchiveOutputStream(ArchiveFormat format, File archive) throws IOException, ArchiveException { return createArchiveOutputStream(format.getName(), new FileOutputStream(archive)); } /** * Uses the {@link ArchiveStreamFactory} and the name of the given archiver to create a new * {@link ArchiveOutputStream} for the given archive {@link File}. * * @param archiver the invoking archiver * @param archive the archive file to create the {@link ArchiveOutputStream} for * @return a new {@link ArchiveOutputStream} * @throws IOException propagated IOExceptions when creating the FileOutputStream. * @throws ArchiveException if the archiver name is not known */ static ArchiveOutputStream createArchiveOutputStream(CommonsArchiver archiver, File archive) throws IOException, ArchiveException { return createArchiveOutputStream(archiver.getArchiveFormat(), archive); } /** * Uses the {@link CompressorStreamFactory} to create a new {@link CompressorInputStream} for the given source * {@link File}. * * @param source the file to create the {@link CompressorInputStream} for * @return a new {@link CompressorInputStream} * @throws IOException if an I/O error occurs * @throws CompressorException if the compressor name is not known */ static CompressorInputStream createCompressorInputStream(File source) throws IOException, CompressorException { return createCompressorInputStream(new BufferedInputStream(new FileInputStream(source))); } /** * Uses the {@link CompressorStreamFactory} to create a new {@link CompressorInputStream} for the compression type * and wraps the given source {@link File} with it. * * @param source the file to create the {@link CompressorInputStream} for * @return a new {@link CompressorInputStream} * @throws IOException if an I/O error occurs * @throws CompressorException if the compressor name is not known */ static CompressorInputStream createCompressorInputStream(CompressionType type, File source) throws IOException, CompressorException { return createCompressorInputStream(type, new BufferedInputStream(new FileInputStream(source))); } /** * @see {@link CompressorStreamFactory#createCompressorInputStream(String, java.io.InputStream)} */ static CompressorInputStream createCompressorInputStream(CompressionType compressionType, InputStream in) throws CompressorException { return compressorStreamFactory.createCompressorInputStream(compressionType.getName(), in); } /** * @see {@link CompressorStreamFactory#createCompressorInputStream(InputStream)}; */ static CompressorInputStream createCompressorInputStream(InputStream in) throws CompressorException { return compressorStreamFactory.createCompressorInputStream(in); } static CompressorOutputStream createCompressorOutputStream(CompressionType compressionType, File destination) throws IOException, CompressorException { return createCompressorOutputStream(compressionType.getName(), new FileOutputStream(destination)); } /** * Uses the {@link CompressorStreamFactory} and the name of the given compressor to create a new * {@link CompressorOutputStream} for the given destination {@link File}. * * @param compressor the invoking compressor * @param destination the file to create the {@link CompressorOutputStream} for * @return a new {@link CompressorOutputStream} * @throws IOException if an I/O error occurs * @throws CompressorException if the compressor name is not known */ static CompressorOutputStream createCompressorOutputStream(CommonsCompressor compressor, File destination) throws IOException, CompressorException { return createCompressorOutputStream(compressor.getCompressionType(), destination); } /** * @see {@link CompressorStreamFactory#createCompressorOutputStream(String, OutputStream)}; */ static CompressorOutputStream createCompressorOutputStream(String compressorName, OutputStream out) throws CompressorException { return compressorStreamFactory.createCompressorOutputStream(compressorName, out); } } jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/CompressionType.java000066400000000000000000000065551410446056500273340ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import org.apache.commons.compress.compressors.CompressorStreamFactory; /** * Denotes a compression algorithm such as gzip or bzip2 */ public enum CompressionType { /** * Constant used to identify the BZIP2 compression algorithm. */ BZIP2(CompressorStreamFactory.BZIP2, ".bz2"), /** * Constant used to identify the GZIP compression algorithm. */ GZIP(CompressorStreamFactory.GZIP, ".gz"), /** * Constant used to identify the XZ compression algorithm. */ XZ(CompressorStreamFactory.XZ, ".xz"), /** * Constant used to identify the PACK200 compression algorithm. */ PACK200(CompressorStreamFactory.PACK200, ".pack"); /** * The name by which the compression algorithm is identified */ private final String name; /** * The default file extension the compression type is mapped to */ private final String defaultFileExtension; private CompressionType(String name, String defaultFileExtension) { this.name = name; this.defaultFileExtension = defaultFileExtension; } /** * Returns the name by which the compression algorithm is identified. * * @return the compression algorithm name */ public String getName() { return name; } /** * Returns the default file extension for this compression type. E.g. ".gz" for gzip. * * @return the default file extension preceded by a dot */ public String getDefaultFileExtension() { return defaultFileExtension; } /** * Checks if the given compression type name is valid and known format. * * @param compression the compression algorithm name * @return true true if the given compression type is known to the factory, false otherwise */ public static boolean isValidCompressionType(String compression) { for (CompressionType type : values()) { if (compression.equalsIgnoreCase(type.getName())) { return true; } } return false; } /** * Attempts to return the {@link CompressionType} instance from a possible given string representation. Ignores * case. * * @param compression string representation of the compression type. E.g. "GZIP". * @return the compression type enum * @throws IllegalArgumentException if the given compression type is unknown. */ public static CompressionType fromString(String compression) { for (CompressionType type : values()) { if (compression.equalsIgnoreCase(type.getName())) { return type; } } throw new IllegalArgumentException("Unknown compression type " + compression); } } jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/Compressor.java000066400000000000000000000055461410446056500263240ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.File; import java.io.IOException; import java.io.InputStream; /** * A compressor facades a specific compression library, allowing for simple compression and decompression of files. */ public interface Compressor { /** * Compresses the given input file to the given destination directory or file. *
* Requires the source the be an existing and readable File, and the destination to be either a file or a directory. * If you pass a directory, the name of the source file is used, with the appended filename extension suffix of the * compression type. * * @param source the source file to compress * @param destination the destination file * @throws IllegalArgumentException if the source is not readable or the destination is not writable * @throws IOException when an I/O error occurs */ void compress(File source, File destination) throws IllegalArgumentException, IOException; /** * Decompresses the given source file to the given destination directory or file. *
* Requires the source the be an existing and readable File, and the destination to be either a file or a directory. * If you pass a directory, the name of the source file is used, with the removed filename extension suffix of the * compression type. * * @param source the compressed source file to decompress * @param destination the destination file * @throws IllegalArgumentException if the source is not readable or the destination is not writable * @throws IOException when an I/O error occurs */ void decompress(File source, File destination) throws IllegalArgumentException, IOException; /** * Accept a stream and wrap it in a decompressing stream suitable for the current compressor. * @param compressedStream the stream of compressed data. * @throws IOException an I/O error. */ InputStream decompressingStream(InputStream compressedStream) throws IOException; /** * Returns the filename extension that indicates the file format this compressor handles. E.g .gz". or ".bz2". * * @return a filename extension with a preceding dot */ String getFilenameExtension(); } jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/CompressorFactory.java000066400000000000000000000065001410446056500276430ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.File; /** * Factory for creating {@link Compressor} instances by a given compression algorithm. Use the constants in this class * to pass to the factory method. */ public final class CompressorFactory { private CompressorFactory() { } /** * Probes the given {@link File} for its file type and creates a {@link Compressor} based on this file type. * * @param file the file to check. * @return a new Compressor instance * @throws IllegalArgumentException if the given file is not a known compressed file type */ public static Compressor createCompressor(File file) throws IllegalArgumentException { FileType fileType = FileType.get(file); if (fileType == FileType.UNKNOWN) { throw new IllegalArgumentException("Unknown file extension " + file.getName()); } return createCompressor(fileType); } /** * Creates a new {@link Compressor} for the given {@link FileType}. * * @param fileType the file type to create the compressor for * @return a new Compressor instance * @throws IllegalArgumentException if the given file type is not a known compression type */ public static Compressor createCompressor(FileType fileType) throws IllegalArgumentException { if (fileType == FileType.UNKNOWN) { throw new IllegalArgumentException("Unknown file type"); } if (fileType.isCompressed()) { return createCompressor(fileType.getCompressionType()); } else { throw new IllegalArgumentException("Unknown compressed file type " + fileType); } } /** * Creates a compressor from the given compression type. * * @param compression the name of the compression algorithm e.g. "gz" or "bzip2". * @return a new {@link Compressor} instance for the given compression algorithm * @throws IllegalArgumentException if the compression type is unknown */ public static Compressor createCompressor(String compression) throws IllegalArgumentException { if (!CompressionType.isValidCompressionType(compression)) { throw new IllegalArgumentException("Unkonwn compression type " + compression); } return createCompressor(CompressionType.fromString(compression)); } /** * Creates a compressor from the given CompressionType. * * @param compression the type of the compression algorithm * @return a new {@link Compressor} instance that uses the specified compression algorithm. */ public static Compressor createCompressor(CompressionType compression) { return new CommonsCompressor(compression); } } jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/FileModeMapper.java000066400000000000000000000126741410446056500270210ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.File; import java.io.IOException; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.attribute.PosixFilePermission; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.logging.Logger; import org.apache.commons.compress.archivers.ArchiveEntry; /** * Reads *nix file mode flags of commons-compress' ArchiveEntry (where possible) and maps them onto Files on the file * system. */ abstract class FileModeMapper { private static final Logger LOG = Logger.getLogger(FileModeMapper.class.getCanonicalName()); private static boolean IS_POSIX = FileSystems.getDefault().supportedFileAttributeViews().contains("posix"); private ArchiveEntry archiveEntry; public FileModeMapper(ArchiveEntry archiveEntry) { this.archiveEntry = archiveEntry; } public abstract void map(File file) throws IOException; public ArchiveEntry getArchiveEntry() { return archiveEntry; } /** * Utility method to create a FileModeMapper for the given entry, and use it to map the file mode onto the given * file. * * @param entry the archive entry that holds the mode * @param file the file to apply the mode onto */ public static void map(ArchiveEntry entry, File file) throws IOException { create(entry).map(file); } /** * Factory method for creating a FileModeMapper for the given ArchiveEntry. Unknown types will yield a * FallbackFileModeMapper that discretely does nothing. * * @param entry the archive entry for which to create a FileModeMapper for * @return a new FileModeMapper instance */ public static FileModeMapper create(ArchiveEntry entry) { if (IS_POSIX) { return new PosixPermissionMapper(entry); } // TODO: implement basic windows permission mapping (e.g. with File.setX or attrib) return new FallbackFileModeMapper(entry); } /** * Does nothing! */ public static class FallbackFileModeMapper extends FileModeMapper { public FallbackFileModeMapper(ArchiveEntry archiveEntry) { super(archiveEntry); } @Override public void map(File file) throws IOException { // do nothing } } /** * Uses an AttributeAccessor to extract the posix file permissions from the ArchiveEntry and sets them * on the given file. */ public static class PosixPermissionMapper extends FileModeMapper { public static final int UNIX_PERMISSION_MASK = 0777; public PosixPermissionMapper(ArchiveEntry archiveEntry) { super(archiveEntry); } @Override public void map(File file) throws IOException { int mode = getMode() & UNIX_PERMISSION_MASK; if (mode > 0) { setPermissions(mode, file); } } public int getMode() throws IOException { return AttributeAccessor.create(getArchiveEntry()).getMode(); } private void setPermissions(int mode, File file) { try { Set posixFilePermissions = new PosixFilePermissionsMapper().map(mode); Files.setPosixFilePermissions(file.toPath(), posixFilePermissions); } catch (Exception e) { LOG.warning("Could not set file permissions of " + file + ". Exception was: " + e.getMessage()); } } } public static class PosixFilePermissionsMapper { public static Map intToPosixFilePermission = new HashMap<>(); static { intToPosixFilePermission.put(0400, PosixFilePermission.OWNER_READ); intToPosixFilePermission.put(0200, PosixFilePermission.OWNER_WRITE); intToPosixFilePermission.put(0100, PosixFilePermission.OWNER_EXECUTE); intToPosixFilePermission.put(0040, PosixFilePermission.GROUP_READ); intToPosixFilePermission.put(0020, PosixFilePermission.GROUP_WRITE); intToPosixFilePermission.put(0010, PosixFilePermission.GROUP_EXECUTE); intToPosixFilePermission.put(0004, PosixFilePermission.OTHERS_READ); intToPosixFilePermission.put(0002, PosixFilePermission.OTHERS_WRITE); intToPosixFilePermission.put(0001, PosixFilePermission.OTHERS_EXECUTE); } public Set map(int mode) { Set permissionSet = new HashSet<>(); for (Map.Entry entry : intToPosixFilePermission.entrySet()) { if ((mode & entry.getKey()) > 0) { permissionSet.add(entry.getValue()); } } return permissionSet; } } } jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/FileType.java000066400000000000000000000134231410446056500257020ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import static org.rauschig.jarchivelib.ArchiveFormat.AR; import static org.rauschig.jarchivelib.ArchiveFormat.CPIO; import static org.rauschig.jarchivelib.ArchiveFormat.DUMP; import static org.rauschig.jarchivelib.ArchiveFormat.JAR; import static org.rauschig.jarchivelib.ArchiveFormat.SEVEN_Z; import static org.rauschig.jarchivelib.ArchiveFormat.TAR; import static org.rauschig.jarchivelib.ArchiveFormat.ZIP; import static org.rauschig.jarchivelib.CompressionType.BZIP2; import static org.rauschig.jarchivelib.CompressionType.GZIP; import static org.rauschig.jarchivelib.CompressionType.PACK200; import static org.rauschig.jarchivelib.CompressionType.XZ; import java.io.File; import java.util.LinkedHashMap; import java.util.Map; /** * Holds the file extension as String and the corresponding {@link ArchiveFormat} and/or {@link CompressionType}. */ public final class FileType { private static final Map MAP = new LinkedHashMap(); /** * Special case object for an unknown archive/compression file type. */ public static final FileType UNKNOWN = new FileType("", null, null); static { // compressed archives add(".tar.gz", TAR, GZIP); add(".tgz", TAR, GZIP); add(".tar.bz2", TAR, BZIP2); add(".tbz2", TAR, BZIP2); // archive formats add(".7z", SEVEN_Z); add(".a", AR); add(".ar", AR); add(".cpio", CPIO); add(".dump", DUMP); add(".jar", JAR); add(".tar", TAR); add(".zip", ZIP); add(".zipx", ZIP); // compression formats add(".bz2", BZIP2); add(".xz", XZ); add(".gzip", GZIP); add(".gz", GZIP); add(".pack", PACK200); } private final String suffix; private final ArchiveFormat archiveFormat; private final CompressionType compression; private FileType(String suffix, ArchiveFormat archiveFormat) { this(suffix, archiveFormat, null); } private FileType(String suffix, CompressionType compression) { this(suffix, null, compression); } private FileType(String suffix, ArchiveFormat archiveFormat, CompressionType compression) { this.suffix = suffix; this.compression = compression; this.archiveFormat = archiveFormat; } /** * Returns true if the given file extension denotes an archive. * * @return true if file extension is an archive, false otherwise */ public boolean isArchive() { return archiveFormat != null; } /** * Returns true if the given file extension denotes a compressed file. * * @return true if file extension is a compressed type, false otherwise */ public boolean isCompressed() { return compression != null; } /** * Returns the file extension suffix (e.g. ".zip" or ".tar.gz"). * * @return the file extension suffix */ public String getSuffix() { return suffix; } /** * Returns the archive format corresponding to this file extension if any. * * @return the archive format or null if the file extension does not denote an archive */ public ArchiveFormat getArchiveFormat() { return archiveFormat; } /** * Returns the compression type corresponding to this file extension if any. * * @return the compression type or null if the file extension does not denote a compressed file */ public CompressionType getCompressionType() { return compression; } @Override public String toString() { return getSuffix(); } /** * Checks the suffix of the given string for an entry in the map. If it exists, the corresponding {@link FileType} * entry will be returned. * * @param filename the filename to check * @return a {@link FileType} entry for the file extension of the given name, or the UNKNOWN type if it does not * exist */ public static FileType get(String filename) { for (Map.Entry entry : MAP.entrySet()) { if (filename.toLowerCase().endsWith(entry.getKey())) { return entry.getValue(); } } return UNKNOWN; } /** * Checks the suffix of the given {@link File} for an entry in the map. If it exists, the corresponding * {@link FileType} entry will be returned. * * @param file the file to check * @return a {@link FileType} entry for the file extension of the given file, or the UNKNOWN type if it does not * exist */ public static FileType get(File file) { return get(file.getName()); } private static void add(String suffix, ArchiveFormat archiveFormat) { MAP.put(suffix, new FileType(suffix, archiveFormat)); } private static void add(String suffix, CompressionType compressionType) { MAP.put(suffix, new FileType(suffix, compressionType)); } private static void add(String suffix, ArchiveFormat archiveFormat, CompressionType compressionType) { MAP.put(suffix, new FileType(suffix, archiveFormat, compressionType)); } } jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/IOUtils.java000066400000000000000000000127101410446056500255070ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.Closeable; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * Utility class for I/O operations. */ public final class IOUtils { /** * Default buffer size used for {@code copy} operations. */ private static final int DEFAULT_BUFFER_SIZE = 8024; private IOUtils() { } /** * Copies the content of an InputStream into a destination File. * * @param source the InputStream to copy * @param destination the target File * @throws IOException if an error occurs */ public static void copy(InputStream source, File destination) throws IOException { OutputStream output = null; try { output = new FileOutputStream(destination); copy(source, output); } finally { closeQuietly(output); } } /** * Copies the content of a InputStream into an OutputStream. Uses a default buffer size of 8024 bytes. * * @param input the InputStream to copy * @param output the target Stream * @return the amount of bytes written * @throws IOException if an error occurs */ public static long copy(final InputStream input, final OutputStream output) throws IOException { return copy(input, output, DEFAULT_BUFFER_SIZE); } /** * Copies the entire content of the given InputStream into the given OutputStream. * * @param input the InputStream to copy * @param output the target Stream * @param buffersize the buffer size to use * @return the amount of bytes written * @throws IOException if an error occurs */ public static long copy(final InputStream input, final OutputStream output, int buffersize) throws IOException { final byte[] buffer = new byte[buffersize]; int n; long count = 0; while (-1 != (n = input.read(buffer))) { output.write(buffer, 0, n); count += n; } return count; } /** * Computes the path name of a file node relative to a given root node. *
* If the root is {@code /home/cdlflex/custom-ahy} and the given node is * {@code /home/cdlflex/custom-ahy/assembly/pom.xml}, the returned path name will be {@code assembly/pom.xml}. * * @param root the parent node * @param node the file node to compute the relative path for * @return the path of {@code node} relative to {@code root} * @throws IOException when an I/O error occurs during resolving the canonical path of the files */ public static String relativePath(File root, File node) throws IOException { String rootPath = root.getCanonicalPath(); String nodePath = node.getCanonicalPath(); return nodePath.substring(rootPath.length() + 1); } /** * Makes sure that the given {@link File} is either a writable directory, or that it does not exist and a directory * can be created at its path. *
* Will throw an exception if the given {@link File} is actually an existing file, or the directory is not writable * * @param destination the directory which to ensure its existence for * @throws IOException if an I/O error occurs e.g. when attempting to create the destination directory * @throws IllegalArgumentException if the destination is an existing file, or the directory is not writable */ public static void requireDirectory(File destination) throws IOException, IllegalArgumentException { if (destination.isFile()) { throw new IllegalArgumentException(destination + " exists and is a file, directory or path expected."); } else if (!destination.exists()) { destination.mkdirs(); } if (!destination.canWrite()) { throw new IllegalArgumentException("Can not write to destination " + destination); } } /** * Null-safe method that calls {@link java.io.Closeable#close()} and chokes the IOException. * * @param closeable the object to close */ public static void closeQuietly(Closeable closeable) { if (closeable != null) { try { closeable.close(); } catch (IOException e) { } } } /** * Given a source File, return its direct descendants if the File is a directory. Otherwise return the File itself. * * @param source File or folder to be examined * @return a File[] array containing the files inside this folder, or a size-1 array containing the file itself. */ public static File[] filesContainedIn(File source) { if (source.isDirectory()) { return source.listFiles(); } else { return new File[] { source }; } } } jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/SevenZArchiver.java000066400000000000000000000076741410446056500270720ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.File; import java.io.IOException; import org.apache.commons.compress.archivers.ArchiveInputStream; import org.apache.commons.compress.archivers.ArchiveOutputStream; import org.apache.commons.compress.archivers.sevenz.SevenZFile; import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile; /** * Archiver to handle 7z archives. commons-compress does not handle 7z over ArchiveStreams, so we need this custom * implementation. *
* Basically this could disperse by adapting the CommonsStreamFactory, but this seemed more convenient as we also have * both Input and Output stream wrappers capsuled here. */ class SevenZArchiver extends CommonsArchiver { public SevenZArchiver() { super(ArchiveFormat.SEVEN_Z); } @Override protected ArchiveOutputStream createArchiveOutputStream(File archive) throws IOException { return new SevenZOutputStream(new SevenZOutputFile(archive)); } @Override protected ArchiveInputStream createArchiveInputStream(File archive) throws IOException { return new SevenZInputStream(new SevenZFile(archive)); } /** * Wraps a SevenZFile to make it usable as an ArchiveInputStream. */ static class SevenZInputStream extends ArchiveInputStream { private SevenZFile file; public SevenZInputStream(SevenZFile file) { this.file = file; } @Override public int read(byte[] b, int off, int len) throws IOException { return file.read(b, off, len); } @Override public org.apache.commons.compress.archivers.ArchiveEntry getNextEntry() throws IOException { return file.getNextEntry(); } @Override public void close() throws IOException { file.close(); } } /** * Wraps a SevenZOutputFile to make it usable as an ArchiveOutputStream. */ static class SevenZOutputStream extends ArchiveOutputStream { private SevenZOutputFile file; public SevenZOutputStream(SevenZOutputFile file) { this.file = file; } @Override public void putArchiveEntry(org.apache.commons.compress.archivers.ArchiveEntry entry) throws IOException { file.putArchiveEntry(entry); } @Override public void closeArchiveEntry() throws IOException { file.closeArchiveEntry(); } @Override public void finish() throws IOException { file.finish(); } @Override public org.apache.commons.compress.archivers.ArchiveEntry createArchiveEntry(File inputFile, String entryName) throws IOException { return file.createArchiveEntry(inputFile, entryName); } @Override public void write(int b) throws IOException { file.write(b); } @Override public void write(byte[] b) throws IOException { file.write(b); } @Override public void write(byte[] b, int off, int len) throws IOException { file.write(b, off, len); } @Override public void close() throws IOException { file.close(); } public SevenZOutputFile getSevenZOutputFile() { return file; } } } jarchivelib-1.2.0/src/main/java/org/rauschig/jarchivelib/ZipFileArchiver.java000066400000000000000000000073071410446056500272130ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.ArchiveInputStream; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipFile; /** * Archiver that overwrites the extraction of Zip archives. It provides a wrapper for ZipFile as an ArchiveInputStream * to retrieve file attributes properly. */ class ZipFileArchiver extends CommonsArchiver { ZipFileArchiver() { super(ArchiveFormat.ZIP); } @Override protected ArchiveInputStream createArchiveInputStream(File archive) throws IOException { return new ZipFileArchiveInputStream(new ZipFile(archive)); } /** * Wraps a ZipFile to make it usable as an ArchiveInputStream. */ static class ZipFileArchiveInputStream extends ArchiveInputStream { private ZipFile file; private Enumeration entries; private ZipArchiveEntry currentEntry; private InputStream currentEntryStream; public ZipFileArchiveInputStream(ZipFile file) { this.file = file; } @Override public ZipArchiveEntry getNextEntry() throws IOException { Enumeration entries = getEntries(); closeCurrentEntryStream(); currentEntry = (entries.hasMoreElements()) ? entries.nextElement() : null; currentEntryStream = (currentEntry != null) ? file.getInputStream(currentEntry) : null; return currentEntry; } @Override public int read(byte[] b, int off, int len) throws IOException { int read = getCurrentEntryStream().read(b, off, len); if (read == -1) { IOUtils.closeQuietly(getCurrentEntryStream()); } count(read); return read; } @Override public boolean canReadEntryData(ArchiveEntry archiveEntry) { return archiveEntry == getCurrentEntry(); } public ZipArchiveEntry getCurrentEntry() { return currentEntry; } public InputStream getCurrentEntryStream() { return currentEntryStream; } private Enumeration getEntries() { if (entries == null) { entries = file.getEntriesInPhysicalOrder(); } return entries; } private void closeCurrentEntryStream() { InputStream stream = getCurrentEntryStream(); IOUtils.closeQuietly(stream); currentEntryStream = null; } private void closeFile() { try { file.close(); } catch (IOException e) { // close quietly } } @Override public void close() throws IOException { closeCurrentEntryStream(); closeFile(); super.close(); } } } jarchivelib-1.2.0/src/test/000077500000000000000000000000001410446056500155475ustar00rootroot00000000000000jarchivelib-1.2.0/src/test/java/000077500000000000000000000000001410446056500164705ustar00rootroot00000000000000jarchivelib-1.2.0/src/test/java/org/000077500000000000000000000000001410446056500172575ustar00rootroot00000000000000jarchivelib-1.2.0/src/test/java/org/rauschig/000077500000000000000000000000001410446056500210645ustar00rootroot00000000000000jarchivelib-1.2.0/src/test/java/org/rauschig/jarchivelib/000077500000000000000000000000001410446056500233465ustar00rootroot00000000000000jarchivelib-1.2.0/src/test/java/org/rauschig/jarchivelib/AbstractArchiverTest.java000066400000000000000000000253321410446056500303050ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.junit.After; import org.junit.Before; import org.junit.Test; public abstract class AbstractArchiverTest extends AbstractResourceTest { private Archiver archiver; private File archive; @Before public void setUp() { archiver = getArchiver(); archive = getArchive(); } @After public void tearDown() { archiver = null; archive = null; } protected abstract Archiver getArchiver(); protected abstract File getArchive(); @Test public void extract_properlyExtractsArchive() throws Exception { archiver.extract(archive, ARCHIVE_EXTRACT_DIR); assertExtractionWasSuccessful(); } @Test public void extract_properlyExtractsArchiveStream() throws Exception { InputStream archiveAsStream = null; try { archiveAsStream = new FileInputStream(archive); archiver.extract(archiveAsStream, ARCHIVE_EXTRACT_DIR); assertExtractionWasSuccessful(); } finally { IOUtils.closeQuietly(archiveAsStream); } } @Test public void create_recursiveDirectory_withFileExtension_properlyCreatesArchive() throws Exception { String archiveName = archive.getName(); File createdArchive = archiver.create(archiveName, ARCHIVE_CREATE_DIR, ARCHIVE_DIR); assertTrue(createdArchive.exists()); assertEquals(archiveName, createdArchive.getName()); archiver.extract(createdArchive, ARCHIVE_EXTRACT_DIR); assertExtractionWasSuccessful(); } @Test public void create_multipleSourceFiles_properlyCreatesArchive() throws Exception { String archiveName = archive.getName(); File createdArchive = archiver.create(archiveName, ARCHIVE_CREATE_DIR, ARCHIVE_DIR.listFiles()); assertTrue(createdArchive.exists()); assertEquals(archiveName, createdArchive.getName()); archiver.extract(createdArchive, ARCHIVE_EXTRACT_DIR); assertDirectoryStructureEquals(ARCHIVE_DIR, ARCHIVE_EXTRACT_DIR); } @Test public void create_recursiveDirectory_withoutFileExtension_properlyCreatesArchive() throws Exception { String archiveName = archive.getName(); File archive = archiver.create("archive", ARCHIVE_CREATE_DIR, ARCHIVE_DIR); assertTrue(archive.exists()); assertEquals(archiveName, archive.getName()); archiver.extract(archive, ARCHIVE_EXTRACT_DIR); assertExtractionWasSuccessful(); } @Test(expected = FileNotFoundException.class) public void create_withNonExistingSource_fails() throws Exception { archiver.create("archive", ARCHIVE_CREATE_DIR, NON_EXISTING_FILE); } @Test(expected = FileNotFoundException.class) public void create_withNonReadableSource_fails() throws Exception { archiver.create("archive", ARCHIVE_CREATE_DIR, NON_READABLE_FILE); } @Test(expected = IllegalArgumentException.class) public void create_withFileAsDestination_fails() throws Exception { archiver.create("archive", NON_READABLE_FILE, ARCHIVE_DIR); } @Test(expected = IllegalArgumentException.class) public void create_withNonWritableDestination_fails() throws Exception { archiver.create("archive", NON_WRITABLE_DIR, ARCHIVE_DIR); } @Test(expected = FileNotFoundException.class) public void extract_withNonExistingSource_fails() throws Exception { archiver.extract(NON_EXISTING_FILE, ARCHIVE_EXTRACT_DIR); } @Test(expected = IllegalArgumentException.class) public void extract_withNonReadableSource_fails() throws Exception { archiver.extract(NON_READABLE_FILE, ARCHIVE_EXTRACT_DIR); } @Test(expected = IllegalArgumentException.class) public void extract_withFileAsDestination_fails() throws Exception { archiver.extract(archive, NON_READABLE_FILE); } @Test(expected = IllegalArgumentException.class) public void extract_withNonWritableDestination_fails() throws Exception { archiver.extract(archive, NON_WRITABLE_DIR); } @Test public void stream_returnsCorrectEntries() throws IOException { ArchiveStream stream = null; try { stream = archiver.stream(archive); ArchiveEntry entry; List entries = new ArrayList(); while ((entry = stream.getNextEntry()) != null) { entries.add(entry.getName().replaceAll("/$", "")); // remove trailing slashes for test compatibility } assertEquals(12, entries.size()); assertTrue(entries.contains("file.txt")); assertTrue(entries.contains("looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_filename.txt")); assertTrue(entries.contains("folder")); assertTrue(entries.contains("folder/folder_file.txt")); assertTrue(entries.contains("folder/subfolder/subfolder_file.txt")); assertTrue(entries.contains("folder/subfolder")); assertTrue(entries.contains("permissions")); assertTrue(entries.contains("permissions/executable_file.txt")); assertTrue(entries.contains("permissions/private_executable_file.txt")); assertTrue(entries.contains("permissions/readonly_file.txt")); assertTrue(entries.contains("permissions/private_folder")); assertTrue(entries.contains("permissions/private_folder/private_file.txt")); } finally { IOUtils.closeQuietly(stream); } } @Test public void entry_isDirectory_behavesCorrectly() throws Exception { ArchiveStream stream = null; try { stream = archiver.stream(archive); ArchiveEntry entry; while ((entry = stream.getNextEntry()) != null) { String name = entry.getName().replaceAll("/$", ""); // remove trailing slashes for test compatibility if (name.endsWith("folder") || name.endsWith("subfolder") || name.endsWith("permissions") || name.endsWith("private_folder")) { assertTrue(entry.getName() + " is a directory", entry.isDirectory()); } else { assertFalse(entry.getName() + " is not a directory", entry.isDirectory()); } } } finally { IOUtils.closeQuietly(stream); } } @Test public void entry_geSize_behavesCorrectly() throws Exception { ArchiveStream stream = null; try { stream = archiver.stream(archive); ArchiveEntry entry; while ((entry = stream.getNextEntry()) != null) { String name = entry.getName().replaceAll("/$", ""); // remove trailing slashes for test compatibility if (name.endsWith("folder") || name.endsWith("subfolder") || name.endsWith("permissions") || name.endsWith("private_folder")) { assertEquals(0, entry.getSize()); } else { assertNotEquals(0, entry.getSize()); } } } finally { IOUtils.closeQuietly(stream); } } @Test public void entry_getLastModifiedDate_behavesCorrectly() throws Exception { ArchiveStream stream = null; try { stream = archiver.stream(archive); ArchiveEntry entry; while ((entry = stream.getNextEntry()) != null) { assertNotNull(entry.getLastModifiedDate()); assertTrue("modification date should be before now", new Date().after(entry.getLastModifiedDate())); } } finally { IOUtils.closeQuietly(stream); } } @Test public void stream_extractEveryEntryWorks() throws Exception { ArchiveStream stream = null; try { stream = archiver.stream(archive); ArchiveEntry entry; while ((entry = stream.getNextEntry()) != null) { entry.extract(ARCHIVE_EXTRACT_DIR); } } finally { IOUtils.closeQuietly(stream); } assertExtractionWasSuccessful(); } @Test(expected = IllegalStateException.class) public void stream_extractPassedEntry_throwsException() throws Exception { ArchiveStream stream = null; try { stream = archiver.stream(archive); ArchiveEntry entry = null; try { entry = stream.getNextEntry(); stream.getNextEntry(); } catch (IllegalStateException e) { fail("Illegal state exception caugth to early"); } entry.extract(ARCHIVE_EXTRACT_DIR); } finally { IOUtils.closeQuietly(stream); } } @Test(expected = IllegalStateException.class) public void stream_extractOnClosedStream_throwsException() throws Exception { ArchiveEntry entry = null; ArchiveStream stream = null; try { stream = archiver.stream(archive); entry = stream.getNextEntry(); } catch (IllegalStateException e) { fail("Illegal state exception caugth too early"); } finally { IOUtils.closeQuietly(stream); } entry.extract(ARCHIVE_EXTRACT_DIR); } protected static void assertExtractionWasSuccessful() throws Exception { assertDirectoryStructureEquals(ARCHIVE_DIR, ARCHIVE_EXTRACT_DIR); assertFilesEquals(ARCHIVE_DIR, ARCHIVE_EXTRACT_DIR); } } jarchivelib-1.2.0/src/test/java/org/rauschig/jarchivelib/AbstractCompressorTest.java000066400000000000000000000130651410446056500306760ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.File; import java.io.FileNotFoundException; import org.junit.After; import org.junit.Before; import org.junit.Test; public abstract class AbstractCompressorTest extends AbstractResourceTest { private File original = new File(RESOURCES_DIR, "compress.txt"); private File decompressDestinationDir = ARCHIVE_EXTRACT_DIR; private File decompressDestinationFile; private File compressDestinationDir = ARCHIVE_CREATE_DIR; private File compressDestinationFile; private Compressor compressor; private File compressedFile; @Before public void setUp() throws Exception { compressor = getCompressor(); compressedFile = getCompressedFile(); decompressDestinationFile = new File(decompressDestinationDir, "compress.txt"); compressDestinationFile = new File(compressDestinationDir, "compress.txt" + compressor.getFilenameExtension()); } @After public void tearDown() throws Exception { compressor = null; compressedFile = null; if (decompressDestinationFile.exists()) { decompressDestinationFile.delete(); } if (compressDestinationFile.exists()) { compressDestinationFile.delete(); } decompressDestinationFile = null; compressDestinationFile = null; } protected abstract File getCompressedFile(); protected abstract Compressor getCompressor(); @Test public void compress_withFileDestination_compressesFileCorrectly() throws Exception { compressor.compress(original, compressDestinationFile); assertCompressionWasSuccessful(); } @Test public void compress_withDirectoryDestination_compressesFileCorrectly() throws Exception { compressor.compress(original, compressDestinationDir); assertCompressionWasSuccessful(); } @Test(expected = IllegalArgumentException.class) public void compress_nonReadableFile_throwsException() throws Exception { try { compressor.compress(NON_READABLE_FILE, compressDestinationFile); } finally { assertFalse(compressDestinationFile.exists()); } } @Test(expected = FileNotFoundException.class) public void compress_nonExistingFile_throwsException() throws Exception { try { compressor.compress(NON_EXISTING_FILE, compressDestinationFile); } finally { assertFalse(compressDestinationFile.exists()); } } @Test(expected = FileNotFoundException.class) public void compress_withNonExistingDestination_throwsException() throws Exception { compressor.compress(original, NON_EXISTING_FILE); } @Test(expected = IllegalArgumentException.class) public void compress_withNonWritableDestinationFile_throwsException() throws Exception { compressor.compress(original, NON_WRITABLE_FILE); } @Test(expected = IllegalArgumentException.class) public void compress_withNonWritableDestinationDirectory_throwsException() throws Exception { compressor.compress(original, NON_WRITABLE_DIR); } @Test public void decompress_withFileDestination_decompressesFileCorrectly() throws Exception { compressor.decompress(compressedFile, decompressDestinationFile); assertDecompressionWasSuccessful(); } @Test public void decompress_withDirectoryDestination_decompressesFileCorrectly() throws Exception { compressor.decompress(compressedFile, decompressDestinationDir); assertDecompressionWasSuccessful(); } @Test(expected = FileNotFoundException.class) public void decompress_withNonExistingDestination_throwsException() throws Exception { compressor.decompress(compressedFile, NON_EXISTING_FILE); } @Test(expected = IllegalArgumentException.class) public void decompress_withNonWritableDestinationFile_throwsException() throws Exception { compressor.decompress(compressedFile, NON_WRITABLE_FILE); } @Test(expected = IllegalArgumentException.class) public void decompress_withNonWritableDestinationDirectory_throwsException() throws Exception { compressor.decompress(compressedFile, NON_WRITABLE_DIR); } @Test(expected = FileNotFoundException.class) public void decompress_nonExistingFile_throwsException() throws Exception { compressor.decompress(NON_EXISTING_FILE, decompressDestinationFile); } private void assertCompressionWasSuccessful() throws Exception { assertTrue(compressDestinationFile.exists()); compressor.decompress(compressDestinationFile, decompressDestinationFile); assertDecompressionWasSuccessful(); } private void assertDecompressionWasSuccessful() throws Exception { assertTrue(decompressDestinationFile.exists()); assertFileContentEquals(original, decompressDestinationFile); } } jarchivelib-1.2.0/src/test/java/org/rauschig/jarchivelib/AbstractResourceTest.java000066400000000000000000000156171410446056500303360ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Scanner; import org.junit.After; import org.junit.Assert; import org.junit.Before; public abstract class AbstractResourceTest { public static final File RESOURCES_DIR = new File("src/test/resources"); public static final File ARCHIVE_CREATE_DIR = new File(RESOURCES_DIR, "created"); public static final File ARCHIVE_EXTRACT_DIR = new File(RESOURCES_DIR, "extracted"); /** * Contains the following files: *
    *
  • src/test/resources/archives/archive/folder
  • *
  • src/test/resources/archives/archive/folder/folder_file.txt
  • *
  • src/test/resources/archives/archive/folder/subfolder
  • *
  • src/test/resources/archives/archive/folder/subfolder/subfolder_file.txt
  • *
  • src/test/resources/archives/archive/file.txt
  • *
*
* Used both as reference to compare whether extraction was successful, and used as source for compression tests. */ public static final File ARCHIVE_DIR = new File(RESOURCES_DIR, "archive"); public static final File NON_READABLE_FILE = new File(RESOURCES_DIR, "non_readable_file.txt"); public static final File NON_WRITABLE_FILE = new File(RESOURCES_DIR, "non_writable_file.txt"); public static final File NON_READABLE_DIR = new File(RESOURCES_DIR, "non_readable_dir"); public static final File NON_WRITABLE_DIR = new File(RESOURCES_DIR, "non_writable_dir"); public static final File NON_EXISTING_FILE = new File(RESOURCES_DIR, "some/file/that/does/not/exist"); @Before public synchronized void createResources() throws IOException { useDirectory(ARCHIVE_EXTRACT_DIR); useDirectory(ARCHIVE_CREATE_DIR); free(NON_EXISTING_FILE); useFile(NON_READABLE_FILE); NON_READABLE_FILE.setReadable(false); useFile(NON_WRITABLE_FILE); NON_WRITABLE_FILE.setWritable(false); useDirectory(NON_READABLE_DIR); NON_READABLE_DIR.setReadable(false); useDirectory(NON_WRITABLE_DIR); NON_WRITABLE_DIR.setWritable(false); } @After public synchronized void dropResources() throws IOException { free(ARCHIVE_EXTRACT_DIR); free(ARCHIVE_CREATE_DIR); free(NON_READABLE_FILE); free(NON_WRITABLE_FILE); free(NON_READABLE_DIR); free(NON_WRITABLE_DIR); } protected static void assertDirectoryStructureEquals(File expected, File actual) throws IOException { String[] expecteds = flatRelativeArray(expected); String[] actuals = flatRelativeArray(actual); Arrays.sort(expecteds); Arrays.sort(actuals); String msg = String.format("Directory structures of %s and %s do not match.", expected, actual); Assert.assertArrayEquals(msg, expecteds, actuals); } public static void assertFileContentEquals(File expected, File actual) throws IOException { String actualString = new Scanner(actual).useDelimiter("\\Z").next(); String expectedString = new Scanner(expected).useDelimiter("\\Z").next(); String msg = String.format("File contents of %s and %s differ.", expected, actual); Assert.assertEquals(msg, expectedString, actualString); } protected static void assertFilesEquals(File expectedDir, File actualDir) throws Exception { String[] expecteds = flatArray(expectedDir); String[] actuals = flatArray(actualDir); Arrays.sort(expecteds); Arrays.sort(actuals); // check whether hashes of files match for (int i = 0; i < expecteds.length; i++) { File expected = new File(expecteds[i]); File actual = new File(actuals[i]); Assert.assertEquals(expected.getName(), actual.getName()); if (expected.isFile()) { assertFileContentEquals(expected, actual); } } } public static String[] flatArray(File root) throws IOException { List flatList = flatList(root); return flatList.toArray(new String[flatList.size()]); } public static List flatList(File root) throws IOException { List list = new ArrayList(); File[] nodes = root.listFiles(); for (File node : nodes) { list.add(node.getPath()); if (node.isDirectory()) { list.addAll(flatList(node)); } } return list; } public static String[] flatRelativeArray(File root) throws IOException { List flatList = flatRelativeList(root); return flatList.toArray(new String[flatList.size()]); } public static List flatRelativeList(File root) throws IOException { return flatRelativeList(root, root); } public static List flatRelativeList(File root, File current) throws IOException { List list = new ArrayList(); String prefix = root.getCanonicalPath(); File[] nodes = current.getCanonicalFile().listFiles(); for (File node : nodes) { list.add(node.getPath().substring(prefix.length() + 1)); if (node.isDirectory()) { list.addAll(flatRelativeList(root, node)); } } return list; } public static void useDirectory(File dir) { if (!dir.exists()) { dir.mkdir(); } } public static void useFile(File file) throws IOException { if (!file.exists()) { file.createNewFile(); } } public static void free(File file) throws IOException { if (file.exists()) { file.setWritable(true); file.setReadable(true); remove(file); } } protected static void remove(File file) throws IOException { if (file.isDirectory()) { removeDirectory(file); } else { file.delete(); } } protected static void removeDirectory(File directory) throws IOException { File[] files = directory.listFiles(); if (files == null) { return; } for (File file : files) { remove(file); } directory.delete(); } } jarchivelib-1.2.0/src/test/java/org/rauschig/jarchivelib/ArchiveTarBzip2Test.java000066400000000000000000000017671410446056500300230ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.File; public class ArchiveTarBzip2Test extends AbstractArchiverTest { @Override protected Archiver getArchiver() { return ArchiverFactory.createArchiver(ArchiveFormat.TAR, CompressionType.BZIP2); } @Override protected File getArchive() { return new File(RESOURCES_DIR, "archive.tar.bz2"); } } jarchivelib-1.2.0/src/test/java/org/rauschig/jarchivelib/Archiver7zTest.java000066400000000000000000000030731410446056500271000ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.File; import org.apache.commons.compress.archivers.StreamingNotSupportedException; import org.hamcrest.CoreMatchers; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; /** * Archiver7zTest */ public class Archiver7zTest extends AbstractArchiverTest { @Rule public ExpectedException expectedException = ExpectedException.none(); @Override protected Archiver getArchiver() { return ArchiverFactory.createArchiver(ArchiveFormat.SEVEN_Z); } @Override protected File getArchive() { return new File(RESOURCES_DIR, "archive.7z"); } @Test public void extract_properlyExtractsArchiveStream() throws Exception { // 7z does not allow streaming expectedException.expectCause(CoreMatchers.instanceOf(StreamingNotSupportedException.class)); super.extract_properlyExtractsArchiveStream(); } } jarchivelib-1.2.0/src/test/java/org/rauschig/jarchivelib/ArchiverCpioTest.java000066400000000000000000000017331410446056500274330ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.File; public class ArchiverCpioTest extends AbstractArchiverTest { @Override protected Archiver getArchiver() { return ArchiverFactory.createArchiver(ArchiveFormat.CPIO); } @Override protected File getArchive() { return new File(RESOURCES_DIR, "archive.cpio"); } } jarchivelib-1.2.0/src/test/java/org/rauschig/jarchivelib/ArchiverJarTest.java000066400000000000000000000017301410446056500272520ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.File; public class ArchiverJarTest extends AbstractArchiverTest { @Override protected Archiver getArchiver() { return ArchiverFactory.createArchiver(ArchiveFormat.JAR); } @Override protected File getArchive() { return new File(RESOURCES_DIR, "archive.jar"); } } jarchivelib-1.2.0/src/test/java/org/rauschig/jarchivelib/ArchiverTarGzTest.java000066400000000000000000000023611410446056500275660ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import static org.junit.Assert.assertEquals; import java.io.File; import org.junit.Test; public class ArchiverTarGzTest extends AbstractArchiverTest { @Override protected Archiver getArchiver() { return ArchiverFactory.createArchiver(ArchiveFormat.TAR, CompressionType.GZIP); } @Override protected File getArchive() { return new File(RESOURCES_DIR, "archive.tar.gz"); } @Test public void getFilenameExtension_targz_returnsCorrectFilenameExtension() throws Exception { assertEquals(".tar.gz", getArchiver().getFilenameExtension()); } } jarchivelib-1.2.0/src/test/java/org/rauschig/jarchivelib/ArchiverTarTest.java000066400000000000000000000023211410446056500272610ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import static org.junit.Assert.assertEquals; import java.io.File; import org.junit.Test; public class ArchiverTarTest extends AbstractArchiverTest { @Override protected Archiver getArchiver() { return ArchiverFactory.createArchiver(ArchiveFormat.TAR); } @Override protected File getArchive() { return new File(RESOURCES_DIR, "archive.tar"); } @Test public void getFilenameExtension_tar_returnsCorrectFilenameExtension() throws Exception { assertEquals(".tar", getArchiver().getFilenameExtension()); } } jarchivelib-1.2.0/src/test/java/org/rauschig/jarchivelib/ArchiverZipTest.java000066400000000000000000000017301410446056500273000ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.File; public class ArchiverZipTest extends AbstractArchiverTest { @Override protected Archiver getArchiver() { return ArchiverFactory.createArchiver(ArchiveFormat.ZIP); } @Override protected File getArchive() { return new File(RESOURCES_DIR, "archive.zip"); } } jarchivelib-1.2.0/src/test/java/org/rauschig/jarchivelib/CompressorBzip2Test.java000066400000000000000000000017501410446056500301170ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.File; public class CompressorBzip2Test extends AbstractCompressorTest { @Override protected File getCompressedFile() { return new File(RESOURCES_DIR, "compress.txt.bz2"); } @Override protected Compressor getCompressor() { return new CommonsCompressor(CompressionType.BZIP2); } } jarchivelib-1.2.0/src/test/java/org/rauschig/jarchivelib/CompressorGzipTest.java000066400000000000000000000017451410446056500300460ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.File; public class CompressorGzipTest extends AbstractCompressorTest { @Override protected File getCompressedFile() { return new File(RESOURCES_DIR, "compress.txt.gz"); } @Override protected Compressor getCompressor() { return new CommonsCompressor(CompressionType.GZIP); } } jarchivelib-1.2.0/src/test/java/org/rauschig/jarchivelib/CompressorXzTest.java000066400000000000000000000017751410446056500275410ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import java.io.File; /** * CompressorXzTest */ public class CompressorXzTest extends AbstractCompressorTest { @Override protected File getCompressedFile() { return new File(RESOURCES_DIR, "compress.txt.xz"); } @Override protected Compressor getCompressor() { return new CommonsCompressor(CompressionType.XZ); } } jarchivelib-1.2.0/src/test/java/org/rauschig/jarchivelib/ExtractPermissionsTest.java000066400000000000000000000113211410446056500307150ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import static org.junit.Assert.assertEquals; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.attribute.PosixFilePermissions; import java.util.Arrays; import java.util.Collection; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; /** * Tests whether permissions are extracted from archives that support them correctly. Just playing around with JUnit's * Parameterized feature. */ @RunWith(Parameterized.class) public class ExtractPermissionsTest extends AbstractResourceTest { @Parameterized.Parameters(name = "{0}") public static Collection parameters() { return Arrays.asList(new Object[][] { { ArchiveFormat.TAR, "archive.tar" }, { ArchiveFormat.ZIP, "archive.zip" } }); } private ArchiveFormat archiveFormat; private String archiveFileName; private Archiver archiver; private File archive; public ExtractPermissionsTest(ArchiveFormat archiveFormat, String archiveFileName) { this.archiveFormat = archiveFormat; this.archiveFileName = archiveFileName; } @Before public void setUp() throws Exception { archiver = ArchiverFactory.createArchiver(archiveFormat); archive = new File(RESOURCES_DIR, archiveFileName); } @Test public void extract_restoresJavaFilePermissions() throws Exception { archiver.extract(archive, ARCHIVE_EXTRACT_DIR); assertJavaPermissions(); } @Test public void extract_restoresUnixPermissions() throws Exception { archiver.extract(archive, ARCHIVE_EXTRACT_DIR); assertPosixPermissions(); } @Test public void extract_stream_restoresUnixPermissions() throws Exception { extractWithStream(); assertPosixPermissions(); } @Test public void extract_stream_restoresJavaPermissions() throws Exception { extractWithStream(); assertJavaPermissions(); } private void extractWithStream() throws IOException { ArchiveStream stream = null; try { stream = archiver.stream(archive); ArchiveEntry entry; while ((entry = stream.getNextEntry()) != null) { entry.extract(ARCHIVE_EXTRACT_DIR); } } finally { IOUtils.closeQuietly(stream); } } private void assertJavaPermissions() { assertPermissions(true, true, true, getExtractedFile("permissions/executable_file.txt")); assertPermissions(true, true, true, getExtractedFile("permissions/private_executable_file.txt")); assertPermissions(true, false, false, getExtractedFile("permissions/readonly_file.txt")); assertPermissions(true, true, true, getExtractedFile("permissions/private_folder")); assertPermissions(true, true, false, getExtractedFile("permissions/private_folder/private_file.txt")); } private void assertPosixPermissions() throws IOException { assertEquals("rwxr-xr-x", getPosixPermissionsString(getExtractedFile("permissions/executable_file.txt"))); assertEquals("rwx------", getPosixPermissionsString(getExtractedFile("permissions/private_executable_file.txt"))); assertEquals("r--r--r--", getPosixPermissionsString(getExtractedFile("permissions/readonly_file.txt"))); assertEquals("rwx------", getPosixPermissionsString(getExtractedFile("permissions/private_folder"))); assertEquals("rw-------", getPosixPermissionsString(getExtractedFile("permissions/private_folder/private_file.txt"))); } private void assertPermissions(boolean r, boolean w, boolean x, File file) { assertEquals(r, file.canRead()); assertEquals(w, file.canWrite()); assertEquals(x, file.canExecute()); } private String getPosixPermissionsString(File file) throws IOException { return PosixFilePermissions.toString(Files.getPosixFilePermissions(file.toPath())); } private File getExtractedFile(String name) { return new File(ARCHIVE_EXTRACT_DIR, name); } } jarchivelib-1.2.0/src/test/java/org/rauschig/jarchivelib/FactoryTest.java000066400000000000000000000107661410446056500264720ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.io.File; import org.junit.Test; public class FactoryTest extends AbstractResourceTest { @Test(expected = IllegalArgumentException.class) public void createArchiver_withUnknownArchiveType_fails() throws Exception { ArchiverFactory.createArchiver("foo"); } @Test(expected = IllegalArgumentException.class) public void createArchiver_withUnknownArchiveAndCompressionType_fails() throws Exception { ArchiverFactory.createArchiver("foo", "bar"); } @Test(expected = IllegalArgumentException.class) public void createArchiver_withUnknownCompressionType_fails() throws Exception { ArchiverFactory.createArchiver("tar", "bar"); } @Test public void createArchiver_fromStringArchiveFormat_returnsCorrectArchiver() throws Exception { Archiver archiver = ArchiverFactory.createArchiver("tar"); assertNotNull(archiver); assertEquals(CommonsArchiver.class, archiver.getClass()); } @Test public void createArchiver_fromStringArchiveAndCompressionFormat_returnsCorrectArchiver() throws Exception { Archiver archiver = ArchiverFactory.createArchiver("tar", "gz"); assertNotNull(archiver); assertEquals(ArchiverCompressorDecorator.class, archiver.getClass()); } @Test public void createArchiver_fromCompressedArchiveFile_returnsCorrectArchiver() throws Exception { Archiver archiver = ArchiverFactory.createArchiver(new File(RESOURCES_DIR, "archive.tar.gz")); assertNotNull(archiver); assertEquals(ArchiverCompressorDecorator.class, archiver.getClass()); } @Test public void createArchiver_fromArchiveFile_returnsCorrectArchiver() throws Exception { Archiver archiver = ArchiverFactory.createArchiver(new File(RESOURCES_DIR, "archive.tar")); assertNotNull(archiver); assertEquals(CommonsArchiver.class, archiver.getClass()); } @Test(expected = IllegalArgumentException.class) public void createArchiver_fromUnknownFileExtension_fails() throws Exception { ArchiverFactory.createArchiver(NON_READABLE_FILE); } @Test(expected = IllegalArgumentException.class) public void createArchiver_fromUnknownArchiveType_fails() throws Exception { ArchiverFactory.createArchiver(new File(RESOURCES_DIR, "compress.txt.gz")); } @Test(expected = IllegalArgumentException.class) public void createCompressor_withUnknownCompressionType_fails() throws Exception { CompressorFactory.createCompressor("foo"); } @Test public void createCompressor_fromStringCompressionFormat_returnsCorrectCompressor() throws Exception { Compressor compressor = CompressorFactory.createCompressor("gz"); assertNotNull(compressor); assertEquals(CommonsCompressor.class, compressor.getClass()); } @Test public void createCompressor_fromFile_returnsCorrectCompressor() throws Exception { Compressor compressor = CompressorFactory.createCompressor(new File(RESOURCES_DIR, "compress.txt.gz")); assertNotNull(compressor); assertEquals(CommonsCompressor.class, compressor.getClass()); } @Test(expected = IllegalArgumentException.class) public void createCompressor_fromUnknownFileExtension_fails() throws Exception { CompressorFactory.createCompressor(NON_READABLE_FILE); } @Test(expected = IllegalArgumentException.class) public void createCompressor_fromUnknownCompressionType_fails() throws Exception { CompressorFactory.createCompressor(new File(RESOURCES_DIR, "archive.tar")); } @Test(expected = IllegalArgumentException.class) public void createCompressor_fromUnknownFileType_throwsException() throws Exception { CompressorFactory.createCompressor(FileType.UNKNOWN); } } jarchivelib-1.2.0/src/test/java/org/rauschig/jarchivelib/FileTypeTest.java000066400000000000000000000046141410446056500265770ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import org.junit.Test; public class FileTypeTest { @Test public void get_archive_returnsCorrectFileType() throws Exception { FileType extension; extension = FileType.get("/path/to/file/file.tar"); assertTrue(extension.isArchive()); assertFalse(extension.isCompressed()); assertNull(extension.getCompressionType()); assertEquals(ArchiveFormat.TAR, extension.getArchiveFormat()); assertEquals(".tar", extension.getSuffix()); } @Test public void get_compressed_returnsCorrectFileType() throws Exception { FileType extension; extension = FileType.get("/path/to/file/file.gz"); assertFalse(extension.isArchive()); assertTrue(extension.isCompressed()); assertEquals(CompressionType.GZIP, extension.getCompressionType()); assertNull(extension.getArchiveFormat()); assertEquals(".gz", extension.getSuffix()); } @Test public void get_compressedArchive_returnsCorrectFileType() throws Exception { FileType extension; extension = FileType.get("/path/to/file/file.tar.gz"); assertTrue(extension.isArchive()); assertTrue(extension.isCompressed()); assertEquals(CompressionType.GZIP, extension.getCompressionType()); assertEquals(ArchiveFormat.TAR, extension.getArchiveFormat()); assertEquals(".tar.gz", extension.getSuffix()); } @Test public void get_unknownExtension_returnsUnknown() throws Exception { assertEquals(FileType.UNKNOWN, FileType.get("/path/to/file/file.foobar")); } } jarchivelib-1.2.0/src/test/java/org/rauschig/jarchivelib/PosixFilePermissionsMapperTest.java000066400000000000000000000124751410446056500323650ustar00rootroot00000000000000/** * Copyright 2013 Thomas Rausch * * 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 org.rauschig.jarchivelib; import org.junit.Test; import org.rauschig.jarchivelib.FileModeMapper.PosixFilePermissionsMapper; import java.nio.file.attribute.PosixFilePermission; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import static java.nio.file.attribute.PosixFilePermission.GROUP_EXECUTE; import static java.nio.file.attribute.PosixFilePermission.GROUP_READ; import static java.nio.file.attribute.PosixFilePermission.GROUP_WRITE; import static java.nio.file.attribute.PosixFilePermission.OTHERS_EXECUTE; import static java.nio.file.attribute.PosixFilePermission.OTHERS_READ; import static java.nio.file.attribute.PosixFilePermission.OTHERS_WRITE; import static java.nio.file.attribute.PosixFilePermission.OWNER_EXECUTE; import static java.nio.file.attribute.PosixFilePermission.OWNER_READ; import static java.nio.file.attribute.PosixFilePermission.OWNER_WRITE; import static org.junit.Assert.assertEquals; public class PosixFilePermissionsMapperTest { private PosixFilePermissionsMapper posixFilePermissionsMapper = new PosixFilePermissionsMapper(); private Set setOf(PosixFilePermission... posixFilePermissions) { return new HashSet<>(Arrays.asList(posixFilePermissions)); } @Test public void noPermissions() { assertEquals(posixFilePermissionsMapper.map(0000), setOf()); } @Test public void allPermissions() { assertEquals(posixFilePermissionsMapper.map(0777), setOf(PosixFilePermission.values())); } @Test public void ownerPermissions() { assertEquals(posixFilePermissionsMapper.map(0400), setOf(OWNER_READ)); assertEquals(posixFilePermissionsMapper.map(0200), setOf(OWNER_WRITE)); assertEquals(posixFilePermissionsMapper.map(0100), setOf(OWNER_EXECUTE)); assertEquals(posixFilePermissionsMapper.map(0700), setOf(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE)); assertEquals(posixFilePermissionsMapper.map(0600), setOf(OWNER_WRITE, OWNER_READ)); assertEquals(posixFilePermissionsMapper.map(0500), setOf(OWNER_EXECUTE, OWNER_READ)); assertEquals(posixFilePermissionsMapper.map(0300), setOf(OWNER_EXECUTE, OWNER_WRITE)); } @Test public void groupPermissions() { assertEquals(posixFilePermissionsMapper.map(0040), setOf(GROUP_READ)); assertEquals(posixFilePermissionsMapper.map(0020), setOf(GROUP_WRITE)); assertEquals(posixFilePermissionsMapper.map(0010), setOf(GROUP_EXECUTE)); assertEquals(posixFilePermissionsMapper.map(0070), setOf(GROUP_READ, GROUP_WRITE, GROUP_EXECUTE)); assertEquals(posixFilePermissionsMapper.map(0060), setOf(GROUP_WRITE, GROUP_READ)); assertEquals(posixFilePermissionsMapper.map(0050), setOf(GROUP_EXECUTE, GROUP_READ)); assertEquals(posixFilePermissionsMapper.map(0030), setOf(GROUP_EXECUTE, GROUP_WRITE)); } @Test public void othersPermissions() { assertEquals(posixFilePermissionsMapper.map(0004), setOf(OTHERS_READ)); assertEquals(posixFilePermissionsMapper.map(0002), setOf(OTHERS_WRITE)); assertEquals(posixFilePermissionsMapper.map(0001), setOf(OTHERS_EXECUTE)); assertEquals(posixFilePermissionsMapper.map(0007), setOf(OTHERS_READ, OTHERS_WRITE, OTHERS_EXECUTE)); assertEquals(posixFilePermissionsMapper.map(0006), setOf(OTHERS_WRITE, OTHERS_READ)); assertEquals(posixFilePermissionsMapper.map(0005), setOf(OTHERS_EXECUTE, OTHERS_READ)); assertEquals(posixFilePermissionsMapper.map(0003), setOf(OTHERS_EXECUTE, OTHERS_WRITE)); } @Test public void permissionsSameForAll() { assertEquals(posixFilePermissionsMapper.map(0444), setOf(OTHERS_READ, GROUP_READ, OWNER_READ)); assertEquals(posixFilePermissionsMapper.map(0222), setOf(OTHERS_WRITE, GROUP_WRITE, OWNER_WRITE)); assertEquals(posixFilePermissionsMapper.map(0111), setOf(OTHERS_EXECUTE, GROUP_EXECUTE, OWNER_EXECUTE)); } @Test public void permissionCombinations() { assertEquals(posixFilePermissionsMapper.map(0750), setOf(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ, GROUP_EXECUTE)); assertEquals(posixFilePermissionsMapper.map(0753), setOf(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ, GROUP_EXECUTE, OTHERS_WRITE, OTHERS_EXECUTE)); assertEquals(posixFilePermissionsMapper.map(0574), setOf(OWNER_READ, OWNER_EXECUTE, GROUP_READ, GROUP_WRITE, GROUP_EXECUTE, OTHERS_READ)); assertEquals(posixFilePermissionsMapper.map(0544), setOf(OWNER_READ, OWNER_EXECUTE, GROUP_READ, OTHERS_READ)); assertEquals(posixFilePermissionsMapper.map(0055), setOf(GROUP_READ, GROUP_EXECUTE, OTHERS_READ, OTHERS_EXECUTE)); } }jarchivelib-1.2.0/src/test/resources/000077500000000000000000000000001410446056500175615ustar00rootroot00000000000000jarchivelib-1.2.0/src/test/resources/Makefile000077500000000000000000000023571410446056500212330ustar00rootroot00000000000000.PHONY = permissions archives compress clean CPF = compress.txt AR = archive all: permissions archives compress permissions: cd $(AR); \ chmod 755 permissions/executable_file.txt; \ chmod 700 permissions/private_executable_file.txt; \ chmod 444 permissions/readonly_file.txt; \ chmod 700 permissions/private_folder; \ chmod 600 permissions/private_folder/private_file.txt; ## archives ## TODO: separate archives: cd $(AR); \ tar czf ../$(AR).tar.gz *; \ tar cjf ../$(AR).tar.bz2 *; \ tar cf ../$(AR).tar *; \ zip -q -r ../$(AR) .; \ jar cMf ../$(AR).jar .; \ find . -depth ! -path . -print | cpio --quiet -o > ../$(AR).cpio; \ 7z a -t7z ../$(AR).7z . > /dev/null; ## compress compress: $(CPF).gz $(CPF).lzma $(CPF).bz2 $(CPF).xz $(CPF).gz: gzip -c $(CPF) > $@ $(CPF).bz2: bzip2 -c $(CPF) > $@ $(CPF).lzma: lzma -z -c $(CPF) > $@ $(CPF).xz: xz -z -c $(CPF) > $@ ## clean clean: clean-compress clean-archives clean-compress: rm -f $(CPF).* clean-archives: rm -f $(AR).* jarchivelib-1.2.0/src/test/resources/archive.7z000066400000000000000000000006631410446056500214710ustar00rootroot000000000000007z'5q"7T]0A=;EC A"Ljr"bӲy &"vݨ)EJ˭3\F@}iM9cz&gы67?[`y8MD6˂yca}~Tu-Kq甏]*0'I%|#b7| yM6'K7vz^<;sk@ԲQk\  #] ܜjarchivelib-1.2.0/src/test/resources/archive.cpio000066400000000000000000000030001410446056500220470ustar00rootroot00000000000000q62[Ѩ$,folder/subfolder/subfolder_file.txtarchive/folder/subfolder/subfolder_file.txt q6.A[Ѩfolder/subfolderq62[Ѩfolder/folder_file.txtarchive/folder/folder_file.txt q6.A[Ѩfolderq62[Ѩ,permissions/private_folder/private_file.txtprivate_file.txt q6.A[Ѩpermissions/private_folderq62[Ѩ permissions/executable_file.txtexecutable_file.txt q62[Ѩ(permissions/private_executable_file.txtprivate_executable_file.txt q62$[Ѩpermissions/readonly_file.txtreadonly_file.txt q6.A[Ѩ permissionsq62[Ѩ file.txtarchive/file.txt q6Pb`looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_filename.txtlooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_filenae.txt q TRAILER!!!jarchivelib-1.2.0/src/test/resources/archive.jar000066400000000000000000000043221410446056500217010ustar00rootroot00000000000000PK hMfolder/PK hMfolder/subfolder/PKhM#folder/subfolder/subfolder_file.txtK,J,KOII-/.MBgŧeTpPKw ,PKhMfolder/folder_file.txtK,J,KOII-Ri9z%%\PK/C) PK hM permissions/PK hMpermissions/private_folder/PKhM+permissions/private_folder/private_file.txt+(,K,IOI+(PKHlPKhMpermissions/executable_file.txtKHM.-ILIOI+(PKхPKhM'permissions/private_executable_file.txt+(,K,IOHM.-ILIOI+(PK;hPKhMpermissions/readonly_file.txt+JML˩OI+(PK"PKhMfile.txtK,J,KOI+(PKSPK}Rlooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_filename.txt /=>-3'5/1U PK*'PK hMfolder/PK hM)folder/subfolder/PKhMw ,#Xfolder/subfolder/subfolder_file.txtPKhM/C) folder/folder_file.txtPK hM (permissions/PK hMRpermissions/private_folder/PKhMHl+permissions/private_folder/private_file.txtPKhMхpermissions/executable_file.txtPKhM;h'Zpermissions/private_executable_file.txtPKhM"permissions/readonly_file.txtPKhMS,file.txtPK}R*'ulooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_filename.txtPK jarchivelib-1.2.0/src/test/resources/archive.tar000066400000000000000000000500001410446056500217050ustar00rootroot00000000000000file.txt0000664000175000017500000000002113371124321012076 0ustar thomasthomasarchive/file.txt folder/0000775000175000017500000000000013371124321011700 5ustar thomasthomasfolder/subfolder/0000775000175000017500000000000013371124321013665 5ustar thomasthomasfolder/subfolder/subfolder_file.txt0000664000175000017500000000005413371124321017411 0ustar thomasthomasarchive/folder/subfolder/subfolder_file.txt folder/folder_file.txt0000664000175000017500000000003713371124321014713 0ustar thomasthomasarchive/folder/folder_file.txt ././@LongLink0000644000000000000000000000034600000000000011606 Lustar rootrootlooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_filename.txtlooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000664000175000017500000000034514047477405036201 0ustar thomasthomaslooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_filenae.txt permissions/0000775000175000017500000000000013371124321013000 5ustar thomasthomaspermissions/private_folder/0000700000175000017500000000000013371124321015771 5ustar thomasthomaspermissions/private_folder/private_file.txt0000600000175000017500000000002113371124321021176 0ustar thomasthomasprivate_file.txt permissions/executable_file.txt0000755000175000017500000000002413371124321016656 0ustar thomasthomasexecutable_file.txt permissions/private_executable_file.txt0000700000175000017500000000003413371124321020377 0ustar thomasthomasprivate_executable_file.txt permissions/readonly_file.txt0000444000175000017500000000002213371124321016343 0ustar thomasthomasreadonly_file.txt jarchivelib-1.2.0/src/test/resources/archive.tar.bz2000066400000000000000000000007501410446056500224100ustar00rootroot00000000000000BZh91AY&SYnΐA@@j`` $@ @2A22izDFjL`&4@&L`&)$Ɖ 0o0|Qq( A gdE -|D7,R$n(ޤfOe+^` Z@y BB/ޟ/D!р4h^Qvh\lc08M1 $$LRCl6;TΤ2Y m!Eԑ5Cf7ȲE;54JP8<DI2xB/6(aB D:/J,Tx/|u?3c h-j%;M@:4zlG96R!\8' H[DAj)rclGi*X& Ѻ4 j6* 3]B@jarchivelib-1.2.0/src/test/resources/archive.tar.gz000066400000000000000000000007711410446056500223360ustar00rootroot00000000000000]n@` V 3k *()Bh eA $3w$1T-U?|P>g>>Qqɋ:eSn]P<] 6>^o}A`U%0q埪+WԿ/ ןI)Pn[DCM zZ߆K05xAM3+ʐ#3fuQ]z+eL|[=R ߊ;50!@i S &< Y| qλqH=(|~Pjarchivelib-1.2.0/src/test/resources/archive.zip000066400000000000000000000052601410446056500217310ustar00rootroot00000000000000PK hMfolder/UT Ѩ[O`ux PK hMfolder/subfolder/UT Ѩ[O`ux PKhMw ,#folder/subfolder/subfolder_file.txtUT Ѩ[hO`ux K,J,KOII-/.MBgŧeTpPKhM/C) folder/folder_file.txtUT Ѩ[hO`ux K,J,KOII-Ri9z%%\PK hM permissions/UT Ѩ[O`ux PK hMpermissions/private_folder/UT Ѩ[e`ux PK hMHl+permissions/private_folder/private_file.txtUT Ѩ[e`ux private_file.txt PK hMхpermissions/executable_file.txtUT Ѩ[e`ux executable_file.txt PK hM;h'permissions/private_executable_file.txtUT Ѩ[e`ux private_executable_file.txt PK hM"permissions/readonly_file.txtUT Ѩ[e`ux readonly_file.txt PK hMSfile.txtUT Ѩ[hO`ux archive/file.txt PK}R*'looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_filename.txtUT ``ux  /=>-3'5/1U PK hMAfolder/UTѨ[ux PK hMAAfolder/subfolder/UTѨ[ux PKhMw ,#folder/subfolder/subfolder_file.txtUTѨ[ux PKhM/C)  folder/folder_file.txtUTѨ[ux PK hM Atpermissions/UTѨ[ux PK hMApermissions/private_folder/UTѨ[ux PK hMHl+permissions/private_folder/private_file.txtUTѨ[ux PK hMх큅permissions/executable_file.txtUTѨ[ux PK hM;h'permissions/private_executable_file.txtUTѨ[ux PK hM"$opermissions/readonly_file.txtUTѨ[ux PK hMSfile.txtUTѨ[ux PK}R*'+looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_filename.txtUT`ux PK ;_jarchivelib-1.2.0/src/test/resources/archive/000077500000000000000000000000001410446056500212025ustar00rootroot00000000000000jarchivelib-1.2.0/src/test/resources/archive/file.txt000066400000000000000000000000211410446056500226530ustar00rootroot00000000000000archive/file.txt jarchivelib-1.2.0/src/test/resources/archive/folder/000077500000000000000000000000001410446056500224555ustar00rootroot00000000000000jarchivelib-1.2.0/src/test/resources/archive/folder/folder_file.txt000066400000000000000000000000371410446056500254700ustar00rootroot00000000000000archive/folder/folder_file.txt jarchivelib-1.2.0/src/test/resources/archive/folder/subfolder/000077500000000000000000000000001410446056500244425ustar00rootroot00000000000000jarchivelib-1.2.0/src/test/resources/archive/folder/subfolder/subfolder_file.txt000066400000000000000000000000541410446056500301660ustar00rootroot00000000000000archive/folder/subfolder/subfolder_file.txt 3b1f8bdfdddf47ebb95d1a7fae7ff4cf958b6947.paxheader00006660000000000000000000000434141044605650021277xustar00rootroot00000000000000284 path=jarchivelib-1.2.0/src/test/resources/archive/looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_filename.txt 3b1f8bdfdddf47ebb95d1a7fae7ff4cf958b6947.data000066400000000000000000000003451410446056500201360ustar00rootroot00000000000000looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_filenae.txt jarchivelib-1.2.0/src/test/resources/archive/permissions/000077500000000000000000000000001410446056500235555ustar00rootroot00000000000000jarchivelib-1.2.0/src/test/resources/archive/permissions/executable_file.txt000077500000000000000000000000241410446056500274350ustar00rootroot00000000000000executable_file.txt jarchivelib-1.2.0/src/test/resources/archive/permissions/private_executable_file.txt000077500000000000000000000000341410446056500311700ustar00rootroot00000000000000private_executable_file.txt jarchivelib-1.2.0/src/test/resources/archive/permissions/private_folder/000077500000000000000000000000001410446056500265625ustar00rootroot00000000000000jarchivelib-1.2.0/src/test/resources/archive/permissions/private_folder/private_file.txt000066400000000000000000000000211410446056500317650ustar00rootroot00000000000000private_file.txt jarchivelib-1.2.0/src/test/resources/archive/permissions/readonly_file.txt000066400000000000000000000000221410446056500271240ustar00rootroot00000000000000readonly_file.txt jarchivelib-1.2.0/src/test/resources/compress.txt000077500000000000000000000000431410446056500221550ustar00rootroot00000000000000this is the decompressed textfile jarchivelib-1.2.0/src/test/resources/compress.txt.bz2000066400000000000000000000001041410446056500226440ustar00rootroot00000000000000BZh91AY&SY8р@f@ !2hhSщNnzw^^8TQ|]B@jarchivelib-1.2.0/src/test/resources/compress.txt.gz000066400000000000000000000001021410446056500225650ustar00rootroot00000000000000Ѩ[compress.txt+,VT܂Ԋ̜T..j#jarchivelib-1.2.0/src/test/resources/compress.txt.lzma000066400000000000000000000000701410446056500231140ustar00rootroot00000000000000]: g~sѷDZ(*0R EJОD8jarchivelib-1.2.0/src/test/resources/compress.txt.xz000066400000000000000000000001341410446056500226130ustar00rootroot000000000000007zXZִF!t/"this is the decompressed textfile P퇵#t;#a+S}YZ