
org.apache.geronimo.kernel.util.JarUtils Maven / Gradle / Ivy
The newest version!
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.geronimo.kernel.util;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
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 java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @version $Rev: 1307840 $ $Date: 2012-04-01 00:13:05 +0800 (Sun, 01 Apr 2012) $
*/
public final class JarUtils {
private static final Logger logger = LoggerFactory.getLogger(JarUtils.class);
private JarUtils() {
}
public static final File DUMMY_JAR_FILE;
public static final String TEMP_FILE_NAME;
private static final boolean jarUrlRewrite;
static {
//Why not always set this with true ? Online deployer also lock the jar files
jarUrlRewrite = Boolean.valueOf(System.getProperty("org.apache.geronimo.kernel.util.JarUtils.jarUrlRewrite", "true"));
try {
DUMMY_JAR_FILE = FileUtils.createTempFile(false);
TEMP_FILE_NAME = DUMMY_JAR_FILE.getCanonicalPath();
new JarOutputStream(new FileOutputStream(JarUtils.DUMMY_JAR_FILE), new Manifest()).close();
} catch (IOException e) {
throw new ExceptionInInitializerError(e);
}
}
public static void assertTempFile() throws IOException {
if(DUMMY_JAR_FILE.exists()) {
return;
} else {
new JarOutputStream(new FileOutputStream(new File(JarUtils.TEMP_FILE_NAME)), new Manifest()).close();
}
}
public static File toTempFile(JarFile jarFile, String path) throws IOException {
return toTempFile(createJarURL(jarFile, path));
}
public static File toTempFile(URL url) throws IOException {
InputStream in = null;
OutputStream out = null;
JarFile jarFile = null;
try {
if (url.getProtocol().equalsIgnoreCase("jar")) {
// url.openStream() locks the jar file and does not release the lock even after the stream is closed.
// This problem is avoided by using JarFile APIs.
String baseFileURIString = url.getFile().substring(0, url.getFile().indexOf("!/"));
File file = new File(new URI(baseFileURIString));
String path = url.getFile().substring(url.getFile().indexOf("!/") + 2);
jarFile = new JarFile(file);
JarEntry jarEntry = jarFile.getJarEntry(path);
if (jarEntry != null) {
in = jarFile.getInputStream(jarEntry);
} else {
throw new FileNotFoundException("JarEntry " + path + " not found in " + file);
}
} else {
in = url.openStream();
}
int index = url.getPath().lastIndexOf(".");
String extension = null;
if (index > 0) {
extension = url.getPath().substring(index);
}
File tempFile = FileUtils.createTempFile(extension);
out = new FileOutputStream(tempFile);
IOUtils.copy(in, out);
return tempFile;
} catch (URISyntaxException e) {
throw new IOException("Could not interpret url " + url, e);
} finally {
IOUtils.close(out);
IOUtils.close(in);
close(jarFile);
}
}
public static String readAll(URL url) throws IOException {
Reader reader = null;
JarFile jarFile = null;
try {
if (url.getProtocol().equalsIgnoreCase("jar")) {
// url.openStream() locks the jar file and does not release the lock even after the stream is closed.
// This problem is avoided by using JarFile APIs.
File file = new File(url.getFile().substring(5, url.getFile().indexOf("!/")));
String path = url.getFile().substring(url.getFile().indexOf("!/") + 2);
jarFile = new JarFile(file);
JarEntry jarEntry = jarFile.getJarEntry(path);
if (jarEntry != null) {
reader = new InputStreamReader(jarFile.getInputStream(jarEntry));
} else {
throw new FileNotFoundException("JarEntry " + path + " not found in " + file);
}
} else {
reader = new InputStreamReader(url.openStream());
}
char[] buffer = new char[4000];
StringBuilder out = new StringBuilder();
for (int count = reader.read(buffer); count >= 0; count = reader.read(buffer)) {
out.append(buffer, 0, count);
}
return out.toString();
} finally {
IOUtils.close(reader);
close(jarFile);
}
}
public static File toFile(JarFile jarFile) throws IOException {
if (jarFile instanceof UnpackedJarFile) {
return ((UnpackedJarFile) jarFile).getBaseDir();
} else {
throw new IOException("jarFile is not a directory");
}
}
// be careful with this method as it can leave a temp lying around
public static File toFile(JarFile jarFile, String path) throws IOException {
if (jarFile instanceof UnpackedJarFile) {
File baseDir = ((UnpackedJarFile) jarFile).getBaseDir();
File file = new File(baseDir, path);
if (!file.isFile()) {
throw new IOException("No such file: " + file.getAbsolutePath());
}
return file;
} else {
String urlString = "jar:" + new File(jarFile.getName()).toURI().toURL() + "!/" + path;
return toTempFile(new URL(urlString));
}
}
public static URL createJarURL(JarFile jarFile, String path) throws MalformedURLException {
if (jarFile instanceof NestedJarFile) {
NestedJarFile nestedJar = (NestedJarFile) jarFile;
if (nestedJar.isUnpacked()) {
JarFile baseJar = nestedJar.getBaseJar();
String basePath = nestedJar.getBasePath();
if (baseJar instanceof UnpackedJarFile) {
File baseDir = ((UnpackedJarFile) baseJar).getBaseDir();
baseDir = new File(baseDir, basePath);
return new File(baseDir, path).toURI().toURL();
}
}
}
if (jarFile instanceof UnpackedJarFile) {
File baseDir = ((UnpackedJarFile) jarFile).getBaseDir();
return new File(baseDir, path).toURI().toURL();
} else {
String urlString = "jar:" + new File(jarFile.getName()).toURI().toURL() + "!/" + path;
if (jarUrlRewrite) {
// To prevent the lockout of archive, instead of returning a jar url, write the content to a
// temp file and return the url of that file.
File tempFile = null;
try {
tempFile = toTempFile(new URL(urlString));
} catch (IOException e) {
// The JarEntry does not exist!
// Return url of a file that does not exist.
try {
tempFile = FileUtils.createTempFile();
tempFile.delete();
} catch (IOException ignored) {
}
}
return tempFile.toURI().toURL();
} else {
return new URL(urlString);
}
}
}
public static JarFile createJarFile(File jarFile) throws IOException {
if (jarFile.isDirectory()) {
return new UnpackedJarFile(jarFile);
} else {
return new JarFile(jarFile);
}
}
public static void copyToPackedJar(JarFile inputJar, File outputFile) throws IOException {
if (inputJar.getClass() == JarFile.class) {
// this is a plain old jar... nothign special
FileUtils.copyFile(new File(inputJar.getName()), outputFile);
} else if (inputJar instanceof NestedJarFile && ((NestedJarFile) inputJar).isPacked()) {
NestedJarFile nestedJarFile = (NestedJarFile) inputJar;
JarFile baseJar = nestedJarFile.getBaseJar();
String basePath = nestedJarFile.getBasePath();
if (baseJar instanceof UnpackedJarFile) {
// our target jar is just a file in upacked jar (a plain old directory)... now
// we just need to find where it is and copy it to the outptu
FileUtils.copyFile(((UnpackedJarFile) baseJar).getFile(basePath), outputFile);
} else {
// out target is just a plain old jar file directly accessabel from the file system
FileUtils.copyFile(new File(baseJar.getName()), outputFile);
}
} else {
// copy out the module contents to a standalone jar file (entry by entry)
JarOutputStream out = null;
try {
out = new JarOutputStream(new FileOutputStream(outputFile));
byte[] buffer = new byte[4096];
Enumeration entries = inputJar.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) entries.nextElement();
InputStream in = inputJar.getInputStream(entry);
try {
out.putNextEntry(new ZipEntry(entry.getName()));
try {
int count;
while ((count = in.read(buffer)) > 0) {
out.write(buffer, 0, count);
}
} finally {
out.closeEntry();
}
} finally {
IOUtils.close(in);
}
}
} finally {
IOUtils.close(out);
}
}
}
public static void jarDirectory(File sourceDirectory, File destinationFile) throws IOException {
JarOutputStream out = null;
try {
out = new JarOutputStream(new FileOutputStream(destinationFile));
jarDirectory(sourceDirectory, "", destinationFile, out);
} finally {
IOUtils.close(out);
}
}
private static void jarDirectory(File baseDirectory,
String baseName,
File destinationFile,
JarOutputStream out) throws IOException {
File[] files = baseDirectory.listFiles();
if (null == files) {
return;
}
byte[] buffer = new byte[4096];
for (File file : files) {
// make sure not to include the file we're creating
if (file.equals(destinationFile)) {
continue;
}
String name = baseName + file.getName();
if (file.isDirectory()) {
out.putNextEntry(new ZipEntry(name + "/"));
out.closeEntry();
jarDirectory(file, name + "/", destinationFile, out);
} else if (file.isFile()) {
out.putNextEntry(new ZipEntry(name));
InputStream in = new FileInputStream(file);
try {
int count;
while ((count = in.read(buffer)) > 0) {
out.write(buffer, 0, count);
}
} finally {
IOUtils.close(in);
out.closeEntry();
}
}
}
}
private static void createDirectory(File dir) throws IOException {
if (dir != null && !dir.exists()) {
boolean success = dir.mkdirs();
if (!success) {
throw new IOException("Cannot create directory " + dir.getAbsolutePath());
}
}
}
public static void unzipToDirectory(ZipInputStream zipIn, File destDir, String prefix, boolean stripPrefix) throws IOException {
ZipEntry entry = null;
while ((entry = zipIn.getNextEntry()) != null) {
if (!entry.getName().startsWith(prefix)) {
continue;
}
String subBasePath = null;
if (stripPrefix) {
subBasePath = prefix.equals(entry.getName()) ? "" : entry.getName().substring(prefix.length());
} else {
subBasePath = entry.getName();
}
unzipToDirectory(zipIn, entry, destDir, subBasePath);
}
}
public static void unzipToDirectory(ZipInputStream zipIn, File destDir) throws IOException {
ZipEntry entry = null;
while ((entry = zipIn.getNextEntry()) != null) {
unzipToDirectory(zipIn, entry, destDir);
}
}
public static void unzipToDirectory(ZipFile zipFile, File destDir, String prefix, boolean stripPrefix) throws IOException {
Enumeration extends ZipEntry> entries = zipFile.entries();
try {
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (!entry.getName().startsWith(prefix)) {
continue;
}
String subBasePath = null;
if (stripPrefix) {
subBasePath = prefix.equals(entry.getName()) ? "" : entry.getName().substring(prefix.length());
} else {
subBasePath = entry.getName();
}
unzipToDirectory(zipFile, entry, destDir, subBasePath);
}
} finally {
zipFile.close();
}
}
public static void unzipToDirectory(ZipFile zipFile, File destDir, String prefix) throws IOException {
unzipToDirectory(zipFile, destDir, prefix, false);
}
public static void unzipToDirectory(ZipFile zipFile, File destDir) throws IOException {
Enumeration extends ZipEntry> entries = zipFile.entries();
try {
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
unzipToDirectory(zipFile, entry, destDir);
}
} finally {
zipFile.close();
}
}
private static void unzipToDirectory(ZipInputStream zipIn, ZipEntry entry, File destDir) throws IOException {
unzipToDirectory(zipIn, entry, destDir, entry.getName());
}
private static void unzipToDirectory(ZipInputStream zipIn, ZipEntry entry, File destDir, String subBasePath) throws IOException {
if (entry.isDirectory()) {
File dir = new File(destDir, subBasePath);
createDirectory(dir);
} else {
File file = new File(destDir, subBasePath);
createDirectory(file.getParentFile());
OutputStream out = null;
try {
out = new BufferedOutputStream(new FileOutputStream(file));
IOUtils.copy(zipIn, out);
} finally {
IOUtils.close(out);
}
}
}
private static void unzipToDirectory(ZipFile zipFile, ZipEntry entry, File destDir) throws IOException {
unzipToDirectory(zipFile, entry, destDir, entry.getName());
}
private static void unzipToDirectory(ZipFile zipFile, ZipEntry entry, File destDir, String subBasePath) throws IOException {
if (entry.isDirectory()) {
File dir = new File(destDir, subBasePath);
createDirectory(dir);
} else {
File file = new File(destDir, subBasePath);
createDirectory(file.getParentFile());
OutputStream out = null;
InputStream in = null;
try {
out = new BufferedOutputStream(new FileOutputStream(file));
in = zipFile.getInputStream(entry);
IOUtils.copy(in, out);
} finally {
IOUtils.close(in);
IOUtils.close(out);
}
}
}
public static void close(JarFile thing) {
if (thing != null) {
try {
thing.close();
} catch (Exception ignored) {
}
}
}
public static void close(ZipFile thing) {
if (thing != null) {
try {
thing.close();
} catch (Exception ignored) {
}
}
}
/**
* Determine whether a file is a JAR File.
*
* Note: Jar file is a zip file with an *optional* META-INF directory.
* Therefore, there is no reliable way to check if a file is a Jar file.
* So this functions returns the same as calling isZipFile(File).
*/
public static boolean isJarFile(File file) throws IOException {
return isZipFile(file);
}
/**
* Determine whether a file is a ZIP File.
*/
public static boolean isZipFile(File file) throws IOException {
if (file.isDirectory()) {
return false;
}
if (!file.canRead()) {
throw new IOException("Cannot read file " + file.getAbsolutePath());
}
if (file.length() < 4) {
return false;
}
DataInputStream in = null;
try {
in = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
return in.readInt() == 0x504b0304;
} finally {
IOUtils.close(in);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy