net.yagga.util
Class MetaJarResources

java.lang.Object
  |
  +--net.yagga.util.MetaJarResources

public class MetaJarResources
extends java.lang.Object

Class that implements reading data from a Jar file. The Jar file can be in the class path or included in the jar file we are executing!. This class reads bytes arrays for a given entry in a given jar file. If the case is the simple one:


 ./Test.class
 ./net/yagga/util/MetaJarResource.class
 ./sample.jar
   +- icon.gif
 
one can read data from the file "sample.jar" via this class, in the main method of the Test class. This case is more or less the same as seen in JavaWorld's tip 49 (JarResource). The class reads the specified Jar entry and returns the byte array. The trick is a bit more complicated if we are in such a case:

 ./all.jar
   +- Test.class
   +- net/yagga/util/MetaJarResource.class
   +- sample.jar
     +- icon.gif
 
If we execute the Jar file "all.jar" Test class cannot find a resource inside the sample.jar file using the usual trick in JArResource. We must extract in a JarResource way from the top level Jar (all.jar) the entry for sample.jar, then extracting from it the entry from icon.gif. I have not found a simple way to do this:
  1. I extract the bytes for the sample.jar entry of the top level jar
  2. I save those bytes in the /tmp dir of the System
  3. I read from this actual file the sizes of each entry in the sub-jar file (sample.jar)
  4. I delete the temp file, and then I read from the bytes of the sub jar the given entry, for the number of bytes I have obtained in step 3

Author:
Walter Gamba
See Also:
JavaWorld's tip 49

Field Summary
private  boolean executingFromJar
           
private  java.util.Hashtable htSizes
           
private  java.lang.String jarFile
           
private  java.lang.String jarJarFile
           
private  java.util.Hashtable metaJarContent
           
private  java.util.jar.Manifest metaManifest
           
 
Constructor Summary
MetaJarResources(java.lang.String jFile)
          Construct a MetaJarResources file, a jar file that can be in the class path (simple case) or enclosed in the same jar file that is executing now.
 
Method Summary
 java.lang.String getActualJarName()
          Return the actual jar name.
 byte[] getBytes(java.lang.String entryName)
          Method that actually reads raw bytes. this method reads in the appropriate way raw bytes for the given entry.
 java.util.jar.Manifest getManifest()
          Return the manifest for the jar file.
private  java.util.jar.JarInputStream getTopJIS()
          Get top level JAR input stream.
private  void initTopJarSizes()
          Read the sizes for top-level JAR file.
private  java.io.InputStream openResource(java.lang.String filename)
          open a stream from the environment.
private  byte[] readBytesFromTopJar(java.lang.String entryName)
          Reads bytes from Top level Jar file.
private  void readJarInJar()
          Reads in self contained jar file.
 
Methods inherited from class java.lang.Object
, clone, equals, finalize, getClass, hashCode, notify, notifyAll, registerNatives, toString, wait, wait, wait
 

Field Detail

htSizes

private java.util.Hashtable htSizes

jarFile

private java.lang.String jarFile

executingFromJar

private boolean executingFromJar

metaJarContent

private java.util.Hashtable metaJarContent

jarJarFile

private java.lang.String jarJarFile

metaManifest

private java.util.jar.Manifest metaManifest
Constructor Detail

MetaJarResources

public MetaJarResources(java.lang.String jFile)
Construct a MetaJarResources file, a jar file that can be in the class path (simple case) or enclosed in the same jar file that is executing now. This constructor decides if the environment in which this class is called is
  1. we are created from a class in the classpath
  2. we are created from a class included in a Jar in the classpath
and consequently if the jar file passed is in the classspath or enclosed in the jar file we are currently executing.
Note that the behaviour of the class in either case is transparent regards to the user.
Parameters:
jFile - the name of the Jar file we want to read resources from.
Method Detail

getBytes

public byte[] getBytes(java.lang.String entryName)
Method that actually reads raw bytes. this method reads in the appropriate way raw bytes for the given entry.
Parameters:
entryName - a String containing the full qualified name of the entryi in the jar file the name must be given in the usual directory/filename format, for example
"img/icon.gif"
"net/yagga/test/Test.class"
Returns:
the array of bytes read foir the given entry, or null if sonething went wrong

getManifest

public java.util.jar.Manifest getManifest()
Return the manifest for the jar file. This can be the manifest of the plain Jar or the manifest of the jar file enclosed in the executing jar file.
Returns:
the Manifest of the jar file, or null if there is an error.

getActualJarName

public java.lang.String getActualJarName()
Return the actual jar name. This can be the top level Jar (whose name we usually ignore) or the jar file name we have passed in the constructor.
Returns:
the file name of the top-level jar file (if searching a Jar from inside an executing jar) or the jar name as we have passed it to the Constructor.

readJarInJar

private void readJarInJar()
Reads in self contained jar file. This is the case if the jar file we want to read is jarred in the jar currently executing so:
 FOO.jar
 +- Installer.class
 +- net/yagga/util/MetaJarResources.class
 +- PACK1.jar
    +- ClassIWantToInvoke.class <===
 

initTopJarSizes

private void initTopJarSizes()
Read the sizes for top-level JAR file. This can be the sole JAR file, or it can be the top level jar file from which we are executing thic class, and in this case sizes can be used to read further into the JAR, for another JAR file

readBytesFromTopJar

private byte[] readBytesFromTopJar(java.lang.String entryName)
Reads bytes from Top level Jar file. Can be used standalone, or to read in another Jar file and then, using readJarInJar, filling the metaJarContent hashtable
Parameters:
entryName - a String containig the top-level entry we eant to read. Ther entry mustbe given in the usual directory/filename format
Returns:
an array poff bytes for the entry, or null if there was an erro

getTopJIS

private java.util.jar.JarInputStream getTopJIS()
Get top level JAR input stream.
Returns:
the JarInputStream associated with the top level jar file

openResource

private java.io.InputStream openResource(java.lang.String filename)
open a stream from the environment. It can be from the file system or from inside the top-level jar
Parameters:
filename - the filename of the resource we want to read
Returns:
the InputStram associated with the given resource