patterntesting.runtime.util.ArchivEntry Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of patterntesting-rt Show documentation
Show all versions of patterntesting-rt Show documentation
PatternTesting Runtime (patterntesting-rt) is the runtime component for
the PatternTesting framework. It provides the annotations and base classes
for the PatternTesting testing framework (e.g. patterntesting-check,
patterntesting-concurrent or patterntesting-exception) but can be also
used standalone for classpath monitoring or profiling.
It uses AOP and AspectJ to perform this feat.
/*
* $Id: ArchivEntry.java,v 1.7 2012/01/16 21:58:11 oboehm Exp $
*
* Copyright (c) 2008 by Oliver Boehm
*
* 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 orimplied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* (c)reated 11-May-2009 by oliver ([email protected])
*/
package patterntesting.runtime.util;
import java.io.*;
import java.net.*;
import java.util.Arrays;
import java.util.zip.*;
import org.apache.commons.io.*;
import org.slf4j.*;
/**
* Unfortunately we can't extends URI because this is a final class.
* So now it is more or less implemented as URI wrapper and is intended for
* the use with zip and jar files to describe an entry inside an archive.
*
* Historically some parts of this class were developed for a log browser
* for Log4J. The facility to read (compressed) tar files (using
* org.apache.commons.compress.tar.*) were removed because we use it here only
* for zip and jar files.
*
* @author oliver ([email protected])
* @since 20.09.2007
* @version $Revision: 1.7 $
*/
public class ArchivEntry {
private static final Logger log = LoggerFactory.getLogger(ArchivEntry.class);
private File archiv = null;
private String entry = null;
private URI uri;
private Long size = null;
/**
* Instantiates a new archiv entry.
*
* @param file the file
*/
protected ArchivEntry(final File file) {
this.archiv = file;
try {
archiv = archiv.getCanonicalFile();
} catch (IOException ioe) {
log.info(ioe + " ignored - using absolute file for " + archiv);
archiv = archiv.getAbsoluteFile();
}
uri = this.archiv.toURI();
}
/**
* Instantiates a new archiv entry.
*
* @param s the s
*/
public ArchivEntry(final String s) {
try {
this.uri = new URI(s);
if (uri.getScheme() == null) {
throw new IllegalArgumentException('"' + s + "\" is not a valid URI (scheme missing)");
}
initArchiv();
} catch (URISyntaxException e) {
throw new IllegalArgumentException('"' + s + "\" is not a valid URI", e);
}
}
/**
* Instantiates a new archiv entry.
*
* @param uri the uri
*/
public ArchivEntry(final URI uri) {
this.uri = uri;
initArchiv();
}
/**
* Instantiates a new archiv entry.
*
* @param url the url
*/
public ArchivEntry(final URL url) {
this.uri = Converter.toURI(url);
initArchiv();
}
/**
* Instantiates a new archiv entry.
*
* @param scheme the scheme
* @param archive the archive
* @param entry the entry
*
* @throws URISyntaxException the URI syntax exception
*/
public ArchivEntry(final String scheme, final File archive, final String entry) throws URISyntaxException {
this(archive);
uri = toURI(scheme, entry);
}
private void initArchiv() {
assert uri.getScheme() != null;
if (uri.getScheme().equalsIgnoreCase("file")) {
this.archiv = new File(uri);
this.entry = null;
} else {
String name = uri.toString().substring(4);
int n = name.lastIndexOf("!");
try {
URI fileURI = new URI(name.substring(0, n));
this.archiv = Converter.toFile(fileURI);
} catch (URISyntaxException e) {
this.archiv = new File(name.substring(5, n));
}
this.entry = name.substring(n+1);
if (this.entry.charAt(0) == '/') {
this.entry = this.entry.substring(1);
}
}
}
/**
* To uri.
*
* @return the uRI
*/
public URI toURI() {
return this.uri;
}
private URI toURI(final String scheme, final String name) throws URISyntaxException {
String schemeURI = scheme + ":" + archiv.toURI().toString() + "!" + name;
return new URI(schemeURI).normalize();
}
/**
* Checks if is file.
*
* @return true, if is file
*/
public boolean isFile() {
return this.entry == null;
}
/**
* Gets the file.
*
* @return the file
*/
public File getFile() {
return this.archiv;
}
/**
* Gets the zip file.
*
* @return the zip file
*
* @throws IOException Signals that an I/O exception has occurred.
*/
public ZipFile getZipFile() throws IOException {
try {
return new ZipFile(this.archiv);
} catch (IOException ioe) {
IOException betterException = new IOException("can't get zip file \"" + this.archiv + '"');
betterException.initCause(ioe);
throw betterException;
}
}
/**
* Gets the entry.
*
* @return the entry
*/
public String getEntry() {
return this.entry;
}
/**
* Gets the zip entry.
*
* @return the zip entry
*/
public ZipEntry getZipEntry() {
return new ZipEntry(this.entry);
}
/**
* Gets the size.
*
* @return the size
*
* @throws IOException Signals that an I/O exception has occurred.
*/
public long getSize() throws IOException {
if (size == null) {
if (isFile()) {
size = this.archiv.length();
} else {
ZipFile zipFile = getZipFile();
ZipEntry zipEntry = zipFile.getEntry(this.entry);
size = zipEntry.getSize();
}
}
return size;
}
/**
* Gets the bytes.
*
* @return the bytes
*
* @throws IOException Signals that an I/O exception has occurred.
*/
public byte[] getBytes() throws IOException {
if (isFile()) {
return FileUtils.readFileToByteArray(this.archiv);
} else {
ZipFile zipFile = getZipFile();
ZipEntry zipEntry = zipFile.getEntry(this.entry);
InputStream istream = zipFile.getInputStream(zipEntry);
byte[] bytes = IOUtils.toByteArray(istream);
istream.close();
return bytes;
}
}
/**
* Equals.
*
* @param other the other
* @return true, if successful
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object other) {
if (other == null) {
return false;
}
try {
return equals((ArchivEntry) other);
} catch (ClassCastException e) {
return false;
}
}
/**
* If two entries have a different size or not the same byte code they are
* considered as not equal.
*
* @param other the other
*
* @return true if they have the same size and the same byte code.
*/
public boolean equals(final ArchivEntry other) {
try {
if (this.getSize() != other.getSize()) {
return false;
}
return Arrays.equals(this.getBytes(), other.getBytes());
} catch (IOException ioe) {
log.debug("can't compare " + this + " with " + other, ioe);
return false;
}
}
/**
* Hash code.
*
* @return the hash code
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
if (this.size == null) {
return 0;
} else {
return this.size.hashCode();
}
}
/**
* To string.
*
* @return the string
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "ArchivEntry " + this.uri;
}
}