All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javaxt.io.Jar Maven / Gradle / Ivy

package javaxt.io;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
//Imports for dealing with ZIP files
import java.net.URI;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

//******************************************************************************
//**  Jar Class - By Peter Borissow
//******************************************************************************
/**
 * Used to find entries in a jar file associated with a given class or package.
 *
 * The original motivation behind this class was to support a requirement to
 * extract and update config files stored in Java packages. For console apps,
 * the config file is stored in the jar (zip) file. For web apps, chances are
 * that the package has been un-zipped and the config file is laying around on
 * disk. This class was designed to support both use cases.
 *
 ******************************************************************************/

public class Jar {

	private java.io.File file;
	private java.lang.Package Package;

	// **************************************************************************
	// ** Constructor
	// **************************************************************************
	/**
	 * Creates a new instance of this class using an instance of another class.
	 */
	public Jar(java.lang.Object object) {
		this(object.getClass());
	}

	// **************************************************************************
	// ** Constructor
	// **************************************************************************
	/**
	 * Creates a new instance of this class using a Class.
	 */
	public Jar(java.lang.Class Class) {
		this.Package = Class.getPackage();
		String path = Class.getName();
		if (path != null)
			path = path.replace(".", "/") + ".class";
		java.util.ArrayList urls = getResource(path, Class.getClassLoader());
		if (urls.size() == 1) {
			file = getFile(urls.get(0));
		}
		/*
		 * else if (urls.size()>1){ //Should never happen!
		 * 
		 * for (java.net.URL url : urls){
		 * 
		 * java.net.JarURLConnection urlcon = (java.net.JarURLConnection)
		 * (url.openConnection()); java.util.jar.JarFile jar =
		 * urlcon.getJarFile(); java.util.Enumeration
		 * entries = jar.entries(); while (entries.hasMoreElements()) { String
		 * entry = entries.nextElement().getName(); //System.out.println(entry);
		 * } } }
		 */
	}

	// **************************************************************************
	// ** Constructor
	// **************************************************************************
	/**
	 * Creates a new instance of this class using a Package. This method is
	 * somewhat unreliable if there are multiple jar files that contain the same
	 * package name. Suggest using the getJars() method instead.
	 */
	public Jar(java.lang.Package Package) {
		this.Package = Package;
		String path = Package.getName().replace(".", "/");
		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		for (java.net.URL url : getResource(path, classLoader)) {
			file = getFile(url);
			if (file != null)
				break;
		}
	}

	// **************************************************************************
	// ** Constructor
	// **************************************************************************
	/**
	 * Creates a new instance of this class using a path to a jar file or
	 * directory.
	 */
	public Jar(java.io.File file) {
		this.file = file;
	}

	// **************************************************************************
	// ** getJars
	// **************************************************************************
	/**
	 * Returns an array of files or directories associated with a given Package.
	 * This method should be used instead of new Jar(java.lang.Package).
	 */
	public static Jar[] getJars(java.lang.Package Package) {
		return getJars(Package.getName());
	}

	public static Jar[] getJars(String packageName) {
		java.util.ArrayList jars = new java.util.ArrayList();
		String path = packageName.replace(".", "/");
		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		for (java.net.URL url : getResource(path, classLoader)) {
			java.io.File file = getFile(url);
			if (file != null)
				jars.add(new Jar(file));
		}
		return jars.toArray(new Jar[jars.size()]);
	}

	// **************************************************************************
	// ** getFile
	// **************************************************************************
	/**
	 * Returns a java.io.File representation of the jar file or directory where
	 * the jar file has been extracted.
	 */
	public java.io.File getFile() {
		return file;
	}

	// **************************************************************************
	// ** getManifest
	// **************************************************************************
	/**
	 * Returns the Manifest file found in the "META-INF" directory. The Manifest
	 * file contains metadata for the jar file including version numbers, vendor
	 * name, etc. You can loop through properties in the Manifest like this:
	 * 
	 * 
	  java.io.File file = new java.io.File("/Drivers/h2/h2-1.3.162.jar");
	  java.util.jar.JarFile jar = new javaxt.io.Jar(file);
	  java.util.jar.Manifest manifest = jar.getManifest();
	
	  System.out.println("\r\nMain Attributes:\r\n--------------------------");
	  printAttributes(manifest.getMainAttributes());
	
	
	  System.out.println("\r\nOther Attributes:\r\n--------------------------");
	  java.util.Map<String, java.util.jar.Attributes> entries = manifest.getEntries();
	  java.util.Iterator<String> it = entries.keySet().iterator();
	  while (it.hasNext()){
	      String key = it.next();
	      printAttributes(entries.get(key));
	      System.out.println();
	  }
	
	  jar.close();
	
	  private static void printAttributes(java.util.jar.Attributes attributes){
	      java.util.Iterator it = attributes.keySet().iterator();
	      while (it.hasNext()){
	          java.util.jar.Attributes.Name key = (java.util.jar.Attributes.Name) it.next();
	          Object value = attributes.get(key);
	          System.out.println(key + ":  " + value);
	      }
	  }
	 * 
*/ public java.util.jar.Manifest getManifest() { try { Entry entry = this.getEntry("META-INF", "MANIFEST.MF"); if (entry != null) { ByteArrayInputStream is = new ByteArrayInputStream(entry.getBytes()); java.util.jar.Manifest manifest = new java.util.jar.Manifest(is); is.close(); return manifest; } } catch (Exception e) { } return null; } // ************************************************************************** // ** getVersion // ************************************************************************** /** * Returns the version number of the jar file, if available. Two different * strategies are used to find the version number. First strategy is to * parse the jar file manifest and return the value of the * "Implementation-Version" or "Bundle-Version", whichever is found first. * If no version information is found in the manifest, an attempt is made to * parse the file name. Returns a null is no version information is * available. */ public String getVersion() { java.util.jar.Attributes attributes = getManifest().getMainAttributes(); if (attributes != null) { java.util.Iterator it = attributes.keySet().iterator(); while (it.hasNext()) { java.util.jar.Attributes.Name key = (java.util.jar.Attributes.Name) it.next(); String keyword = key.toString(); if (keyword.equals("Implementation-Version") || keyword.equals("Bundle-Version")) { return (String) attributes.get(key); } } } String fileName = file.getName().substring(0, file.getName().lastIndexOf(".")); if (fileName.contains(".")) { String majorVersion = fileName.substring(0, fileName.indexOf(".")); int delimiter = majorVersion.lastIndexOf("-"); if (majorVersion.indexOf("_") > delimiter) delimiter = majorVersion.indexOf("_"); majorVersion = majorVersion.substring(delimiter + 1, fileName.indexOf(".")); String minorVersion = fileName.substring(fileName.indexOf(".")); return majorVersion + minorVersion; } return null; } // ************************************************************************** // ** getEntries // ************************************************************************** /** * Used to return a list of all the entries found in the jar file. */ public Entry[] getEntries() { java.util.ArrayList entries = new java.util.ArrayList(); try { if (file.isDirectory()) { Directory dir = new Directory(file); java.util.List items = dir.getChildren(true); for (int i = 0; i < items.size(); i++) { Object item = items.get(i); if (item instanceof File) { entries.add(new Entry(((File) item).toFile())); } } } else { ZipInputStream in = new ZipInputStream(new FileInputStream(file)); ZipEntry zipEntry = null; while ((zipEntry = in.getNextEntry()) != null) { entries.add(new Entry(zipEntry)); } in.close(); } } catch (Exception e) { } return entries.toArray(new Entry[entries.size()]); } // ************************************************************************** // ** getEntry // ************************************************************************** /** Used to retrieve a single entry from the jar file. */ public Entry getEntry(String Entry) { return getEntry(Package.getName(), Entry); } // ************************************************************************** // ** getEntry // ************************************************************************** /** * Used to retrieve a single entry from the jar file. * * @param Package * Name of the package or directory in the jar file (e.g. * "javaxt.io"). Null values and zero length strings default to * the the root directory. * @param Entry * Name of the class/file found in the given package (e.g. * "Jar.class"). */ public Entry getEntry(String Package, String Entry) { ZipInputStream in = null; try { if (file.isDirectory()) { return new Entry(new java.io.File(file, Entry)); } else { // Update package name and entry if (Package != null) { Package = Package.trim(); if (Package.length() == 0) Package = null; } if (Package != null) { if (Package.contains(".")) Package = Package.replace(".", "/"); Entry = Package + "/" + Entry; } // Find entry in the jar file in = new ZipInputStream(new FileInputStream(file)); ZipEntry zipEntry = null; while ((zipEntry = in.getNextEntry()) != null) { if (zipEntry.getName().equalsIgnoreCase(Entry)) { // System.out.println(zipEntry.getName() + " <--"); Entry entry = new Entry(zipEntry); in.close(); return entry; } } in.close(); } } catch (Exception e) { if (in != null) { try { in.close(); } catch (Exception ex) { } } // e.printStackTrace(); } return null; } // ************************************************************************** // ** getEntries // ************************************************************************** /** Used to retrieve a single entry from the jar file. */ public Entry getEntry(java.lang.Class Class) { String ClassName = Class.getName(); String PackageName = Class.getPackage().getName(); ClassName = ClassName.substring(PackageName.length() + 1); return getEntry(PackageName, ClassName + ".class"); } // ************************************************************************** // ** toString // ************************************************************************** /** Returns the path to the jar file. */ @Override public String toString() { return file.toString(); } // ************************************************************************** // ** getResource // ************************************************************************** /** * Returns the URL associated with a given path in the jar file. * * @param cl * ClassLoader used to find the given path/resource. If the * ClassLoader is null or fails to find the requested path, an * alternate ClassLoader is used (e.g. ClassLoader's Parent, * ContextClassLoader, SystemClassLoader). */ private static java.util.ArrayList getResource(String path, ClassLoader cl) { java.util.ArrayList arr = new java.util.ArrayList(); try { int x = 0; while (true) { if (cl == null) { cl = Thread.currentThread().getContextClassLoader(); if (cl == null) { cl = java.lang.ClassLoader.getSystemClassLoader(); if (cl == null) { break; // Throw Exception? } } } java.util.Enumeration en = cl.getResources(path); if (en.hasMoreElements()) { while (en.hasMoreElements()) { java.net.URL url = en.nextElement(); arr.add(url); } break; } else { if (cl.getParent() != null && cl.getParent().equals(cl)) { break; } cl = cl.getParent(); } x++; if (x == 50) break; } /* * String debug = ""; debug += "Path: " + path + "\r\n"; debug += * "ClassLoader: " + cl + "\r\n"; for (java.net.URL url : arr){ * debug += "Resource: " + url + "\r\n"; } * System.out.println(debug); */ } catch (Exception e) { // e.printStackTrace(); } return arr; } private static java.io.File getFile(java.net.URL url) { if (url != null) try { java.net.URI uri = new java.net.URI(url.toString().replace(" ", "%20")); if (uri.getPath() == null) { String path = uri.toString(); if (path.startsWith("jar:file:")) { // Update Path and Define Zipped File path = path.substring(path.indexOf("file:/")); path = path.substring(0, path.toLowerCase().indexOf(".jar") + 4); if (path.startsWith("file://")) { // UNC Path path = "C:/" + path.substring(path.indexOf("file:/") + 7); path = "/" + new URI(path).getPath(); } else { path = new URI(path).getPath(); } return new java.io.File(path); } else if (path.startsWith("jar:http")) { path = path.substring(path.indexOf("http")); path = path.substring(0, path.toLowerCase().indexOf(".jar") + 4); } } else { return new java.io.File(uri); } } catch (Exception e) { // e.printStackTrace(); } return null; } // ************************************************************************** // ** JAR Entry Class // ************************************************************************** /** * Used to represent an entry in a jar/war file. The jar file might be * zipped or unpacked by a web server. */ public class Entry { private ZipEntry zipEntry = null; private java.io.File fileEntry = null; /** Constructor for zipped jar files. */ private Entry(ZipEntry zipEntry) { this.zipEntry = zipEntry; } /** Constructor for unzipped jar files. */ private Entry(java.io.File fileEntry) { this.fileEntry = fileEntry; } public String getName() { if (fileEntry == null) return zipEntry.getName(); else return fileEntry.getName(); } public java.util.Date getDate() { if (fileEntry == null) return new java.util.Date(zipEntry.getTime()); else return new java.util.Date(fileEntry.lastModified()); } /** * Returns a long value representing a cyclic redundancy check (CRC-32 * checksum) of the uncompressed entry data, or -1 if not known. */ public long checksum() { if (fileEntry == null) return zipEntry.getCrc(); else return new javaxt.io.File(fileEntry).checksum(); } public java.io.File getFile() { return fileEntry; } public long getSize() { if (fileEntry == null) { return zipEntry.getSize(); } else { return fileEntry.length(); } } public byte[] getBytes() { ZipFile zip = null; try { if (fileEntry == null) { zip = new ZipFile(file); java.io.DataInputStream is = new java.io.DataInputStream(zip.getInputStream(zipEntry)); int bufferSize = 1024; ByteArrayOutputStream bas = new ByteArrayOutputStream(); byte[] b = new byte[bufferSize]; int x = 0; while ((x = is.read(b, 0, bufferSize)) > -1) { bas.write(b, 0, x); } bas.close(); zip.close(); return bas.toByteArray(); } else { return new javaxt.io.File(fileEntry).getBytes().toByteArray(); } } catch (Exception e) { if (zip != null) { try { zip.close(); } catch (Exception ex) { } } return null; } } /** Used to extract the zip entry to a file. */ public void extractFile(java.io.File destination) { try { if (fileEntry == null) { destination.getParentFile().mkdirs(); FileOutputStream out = new FileOutputStream(destination); ZipInputStream in = new ZipInputStream(new FileInputStream(file)); ZipEntry zipEntry = null; while ((zipEntry = in.getNextEntry()) != null) { if (zipEntry.getName().equals(this.zipEntry.getName())) { byte[] buf = new byte[1024]; int len; while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); } break; } } in.close(); out.close(); } else { // Simply copy the file to the destination if (destination.isFile()) { new File(fileEntry).copyTo(new File(destination), false); } else { new File(fileEntry).copyTo(new Directory(destination), false); } } } catch (Exception e) { e.printStackTrace(); } } public void setText(String text) { try { if (fileEntry == null) { ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(); ByteArrayInputStream byteInput = new ByteArrayInputStream(text.getBytes()); ZipOutputStream zipOutput = new ZipOutputStream(byteOutput); ZipInputStream zipInput = new ZipInputStream(new FileInputStream(file)); ZipEntry zipEntry = null; while ((zipEntry = zipInput.getNextEntry()) != null) { if (zipEntry.getName().equals(this.zipEntry.getName())) { // Write Updated Config File zipOutput.putNextEntry(new ZipEntry(this.zipEntry.getName())); byte[] buf = new byte[1024]; int len; while ((len = byteInput.read(buf)) > 0) { zipOutput.write(buf, 0, len); } byteInput.close(); } else { zipOutput.putNextEntry(zipEntry); byte[] buf = new byte[1024]; int len; while ((len = zipInput.read(buf)) > 0) { zipOutput.write(buf, 0, len); } } zipInput.closeEntry(); zipOutput.closeEntry(); } zipInput.close(); zipOutput.close(); FileOutputStream fos = new FileOutputStream(file); fos.write(byteOutput.toByteArray()); fos.close(); byteOutput.close(); } else { new File(fileEntry).write(text); } } catch (Exception e) { } } /** Used to extract the contents to a string. */ public String getText() { return getText("UTF-8"); } /** * Used to extract the contents to a string. Returns null if the * extraction failed. * * @param charsetName * Name of the character encoding used to read the file. * Examples include UTF-8 and ISO-8859-1 */ public String getText(String charsetName) { try { if (fileEntry == null) { ByteArrayOutputStream out = new ByteArrayOutputStream(); ZipInputStream in = new ZipInputStream(new FileInputStream(file)); ZipEntry zipEntry = null; while ((zipEntry = in.getNextEntry()) != null) { if (zipEntry.getName().equals(this.zipEntry.getName())) { byte[] buf = new byte[1024]; int len; while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); } break; } } in.close(); return out.toString(charsetName); } else { return new File(fileEntry).getText(charsetName); } } catch (Exception e) { return null; } } @Override public String toString() { return getName(); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy