pax_global_header 0000666 0000000 0000000 00000000064 13371131203 0014504 g ustar 00root root 0000000 0000000 52 comment=13949a5ff6b9c250e845e69aeb8cc4bfb30ba7f4
jarchivelib-1.0.0/ 0000775 0000000 0000000 00000000000 13371131203 0013764 5 ustar 00root root 0000000 0000000 jarchivelib-1.0.0/.gitignore 0000664 0000000 0000000 00000000247 13371131203 0015757 0 ustar 00root root 0000000 0000000 # 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.0.0/.travis-settings.xml 0000664 0000000 0000000 00000002131 13371131203 0017727 0 ustar 00root root 0000000 0000000
sonatype-nexus-snapshots${env.SONATYPE_USERNAME}${env.SONATYPE_PASSWORD}
jarchivelib-1.0.0/.travis.yml 0000664 0000000 0000000 00000000673 13371131203 0016103 0 ustar 00root root 0000000 0000000 language: java
jdk:
- openjdk7
- oraclejdk8
- oraclejdk9
- openjdk10
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.0.0/LICENSE 0000664 0000000 0000000 00000026136 13371131203 0015001 0 ustar 00root root 0000000 0000000
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.0.0/README.md 0000664 0000000 0000000 00000006505 13371131203 0015251 0 ustar 00root root 0000000 0000000 jarchivelib
===========
[](https://maven-badges.herokuapp.com/maven-central/org.rauschig/jarchivelib/)
[](https://travis-ci.org/thrau/jarchivelib)
[](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.18
Compatibility
-------------
* Java 7, 8, 9, 10
* 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.0.0/pom.xml 0000664 0000000 0000000 00000011513 13371131203 0015302 0 ustar 00root root 0000000 0000000
4.0.0org.rauschigoss-parent1org.rauschigjarchivelib1.0.0bundleJava 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.
2013http://rauschig.org/jarchivelibhttps://github.com/thrau/jarchivelibscm:git:git://git@github.com:thrau/jarchivelib.gitscm:git:git@github.com:thrau/jarchivelib.gitv1.0.0thrauThomas Rauschthomas@rauschig.org1.181.84.11${project.groupId} :: ${project.artifactId} :: ${project.name}${project.groupId}.${project.artifactId}${project.groupId}.${project.artifactId}org.apache.felixmaven-bundle-plugintrue${bundle.symbolicName}${bundle.name}${project.version}${bundle.namespace}.*;version="${project.version}"maven-compiler-plugin1.71.7maven-assembly-pluginjar-with-dependenciescom.mycila.maven-license-pluginmaven-license-pluginsrc/test/resources/**Thomas Rausch2013org.eluder.coverallscoveralls-maven-plugin3.0.1org.codehaus.mojocobertura-maven-plugin2.6xml256morg.apache.commonscommons-compress${commons.compress.version}org.tukaanixz${xz.version}truejunitjunit${junit.version}test
jarchivelib-1.0.0/src/ 0000775 0000000 0000000 00000000000 13371131203 0014553 5 ustar 00root root 0000000 0000000 jarchivelib-1.0.0/src/main/ 0000775 0000000 0000000 00000000000 13371131203 0015477 5 ustar 00root root 0000000 0000000 jarchivelib-1.0.0/src/main/java/ 0000775 0000000 0000000 00000000000 13371131203 0016420 5 ustar 00root root 0000000 0000000 jarchivelib-1.0.0/src/main/java/org/ 0000775 0000000 0000000 00000000000 13371131203 0017207 5 ustar 00root root 0000000 0000000 jarchivelib-1.0.0/src/main/java/org/rauschig/ 0000775 0000000 0000000 00000000000 13371131203 0021014 5 ustar 00root root 0000000 0000000 jarchivelib-1.0.0/src/main/java/org/rauschig/jarchivelib/ 0000775 0000000 0000000 00000000000 13371131203 0023276 5 ustar 00root root 0000000 0000000 jarchivelib-1.0.0/src/main/java/org/rauschig/jarchivelib/ArchiveEntry.java 0000664 0000000 0000000 00000005107 13371131203 0026547 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/main/java/org/rauschig/jarchivelib/ArchiveFormat.java 0000664 0000000 0000000 00000007204 13371131203 0026676 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/main/java/org/rauschig/jarchivelib/ArchiveStream.java 0000664 0000000 0000000 00000004342 13371131203 0026701 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/main/java/org/rauschig/jarchivelib/Archiver.java 0000664 0000000 0000000 00000010650 13371131203 0025706 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/main/java/org/rauschig/jarchivelib/ArchiverCompressorDecorator.java 0000664 0000000 0000000 00000012367 13371131203 0031635 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/main/java/org/rauschig/jarchivelib/ArchiverFactory.java 0000664 0000000 0000000 00000012325 13371131203 0027237 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/main/java/org/rauschig/jarchivelib/AttributeAccessor.java 0000664 0000000 0000000 00000010600 13371131203 0027564 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/main/java/org/rauschig/jarchivelib/CommonsArchiveEntry.java 0000664 0000000 0000000 00000004777 13371131203 0030117 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/main/java/org/rauschig/jarchivelib/CommonsArchiveStream.java 0000664 0000000 0000000 00000003317 13371131203 0030236 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/main/java/org/rauschig/jarchivelib/CommonsArchiver.java 0000664 0000000 0000000 00000024073 13371131203 0027246 0 ustar 00root root 0000000 0000000 /**
* 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;
/**
* 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 {
return CommonsStreamFactory.createArchiveOutputStream(this, archiveFile);
} 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.0.0/src/main/java/org/rauschig/jarchivelib/CommonsCompressor.java 0000664 0000000 0000000 00000012775 13371131203 0027645 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/main/java/org/rauschig/jarchivelib/CommonsStreamFactory.java 0000664 0000000 0000000 00000020423 13371131203 0030261 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/main/java/org/rauschig/jarchivelib/CompressionType.java 0000664 0000000 0000000 00000006555 13371131203 0027317 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/main/java/org/rauschig/jarchivelib/Compressor.java 0000664 0000000 0000000 00000005546 13371131203 0026307 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/main/java/org/rauschig/jarchivelib/CompressorFactory.java 0000664 0000000 0000000 00000006500 13371131203 0027626 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/main/java/org/rauschig/jarchivelib/FileModeMapper.java 0000664 0000000 0000000 00000012674 13371131203 0027004 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/main/java/org/rauschig/jarchivelib/FileType.java 0000664 0000000 0000000 00000013423 13371131203 0025665 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/main/java/org/rauschig/jarchivelib/IOUtils.java 0000664 0000000 0000000 00000012710 13371131203 0025472 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/main/java/org/rauschig/jarchivelib/SevenZArchiver.java 0000664 0000000 0000000 00000007674 13371131203 0027055 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/main/java/org/rauschig/jarchivelib/ZipFileArchiver.java 0000664 0000000 0000000 00000007307 13371131203 0027176 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/test/ 0000775 0000000 0000000 00000000000 13371131203 0015532 5 ustar 00root root 0000000 0000000 jarchivelib-1.0.0/src/test/java/ 0000775 0000000 0000000 00000000000 13371131203 0016453 5 ustar 00root root 0000000 0000000 jarchivelib-1.0.0/src/test/java/org/ 0000775 0000000 0000000 00000000000 13371131203 0017242 5 ustar 00root root 0000000 0000000 jarchivelib-1.0.0/src/test/java/org/rauschig/ 0000775 0000000 0000000 00000000000 13371131203 0021047 5 ustar 00root root 0000000 0000000 jarchivelib-1.0.0/src/test/java/org/rauschig/jarchivelib/ 0000775 0000000 0000000 00000000000 13371131203 0023331 5 ustar 00root root 0000000 0000000 jarchivelib-1.0.0/src/test/java/org/rauschig/jarchivelib/AbstractArchiverTest.java 0000664 0000000 0000000 00000024707 13371131203 0030275 0 ustar 00root root 0000000 0000000 /**
* 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(11, entries.size());
assertTrue(entries.contains("file.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.0.0/src/test/java/org/rauschig/jarchivelib/AbstractCompressorTest.java 0000664 0000000 0000000 00000013065 13371131203 0030661 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/test/java/org/rauschig/jarchivelib/AbstractResourceTest.java 0000664 0000000 0000000 00000015617 13371131203 0030321 0 ustar 00root root 0000000 0000000 /**
* 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:
*
*
* 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.0.0/src/test/java/org/rauschig/jarchivelib/ArchiveTarBzip2Test.java 0000664 0000000 0000000 00000001767 13371131203 0030006 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/test/java/org/rauschig/jarchivelib/Archiver7zTest.java 0000664 0000000 0000000 00000003073 13371131203 0027063 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/test/java/org/rauschig/jarchivelib/ArchiverCpioTest.java 0000664 0000000 0000000 00000001733 13371131203 0027416 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/test/java/org/rauschig/jarchivelib/ArchiverJarTest.java 0000664 0000000 0000000 00000001730 13371131203 0027235 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/test/java/org/rauschig/jarchivelib/ArchiverTarGzTest.java 0000664 0000000 0000000 00000002361 13371131203 0027551 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/test/java/org/rauschig/jarchivelib/ArchiverTarTest.java 0000664 0000000 0000000 00000002321 13371131203 0027244 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/test/java/org/rauschig/jarchivelib/ArchiverZipTest.java 0000664 0000000 0000000 00000001730 13371131203 0027263 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/test/java/org/rauschig/jarchivelib/CompressorBzip2Test.java 0000664 0000000 0000000 00000001750 13371131203 0030102 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/test/java/org/rauschig/jarchivelib/CompressorGzipTest.java 0000664 0000000 0000000 00000001745 13371131203 0030031 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/test/java/org/rauschig/jarchivelib/CompressorXzTest.java 0000664 0000000 0000000 00000001775 13371131203 0027524 0 ustar 00root root 0000000 0000000 /**
* 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.0.0/src/test/java/org/rauschig/jarchivelib/ExtractPermissionsTest.java 0000664 0000000 0000000 00000011321 13371131203 0030700 0 ustar 00root root 0000000 0000000 /**
* 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