com.izforge.izpack.util
Class Librarian

java.lang.Object
  extended by com.izforge.izpack.util.Librarian
All Implemented Interfaces:
CleanupClient

public class Librarian
extends java.lang.Object
implements CleanupClient

This class handles loading of native libraries. There must only be one instance of Librarian per Java runtime, therefore this class is implemented as a 'Singleton'.

Librarian is capable of loading native libraries from a variety of different source locations. However, you should place your library files in the 'native' directory. The primary reason for supporting different source locations is to facilitate testing in a development environment, without the need to actually packing the application into a *.jar file.

Version:
1.0 / 1/30/02
Author:
Elmar Grom

Field Summary
private static int BLOCK_SIZE
          The block size used for reading and writing data, 4k.
private static java.lang.String CLIENT_EXTENSION
          The extension appended to the client name when searching for it as a resource.
private  java.util.Vector clients
          A list of references to clients that use libraries that were extracted from a *.jar file.
private  java.lang.String extension
          The extension to use for native libraries.
private static java.lang.String FILE_PROTOCOL
          Used to identify file URL protocols
private static java.lang.String JAR_PROTOCOL
          Used to identify jar URL protocols
private  java.util.Vector libraryNames
          A list of library names as they appear in the temporary directory.
private static Librarian me
          The reference to the single instance of Librarian.
private static java.lang.String NATIVE
          The default directory for native library files.
private  java.lang.String nativeDirectory
          The directory that is used to hold all native libraries.
private static java.lang.String TEMP_LOCATION_KEY
          The key used to retrieve the location of temporary files form the system properties.
private  java.util.Vector temporaryFileNames
          A list of fully qualified library names.
private  java.util.Vector trackList
          A list that is used to track all libraries that have been loaded.
 
Constructor Summary
private Librarian()
          This class is implemented as a 'Singleton'.
 
Method Summary
 void cleanUp()
          This method attempts to remove all native libraries that have been temporarily created from the system.
private  void extractFromJar(java.lang.String name, java.lang.String destination, NativeLibraryClient client)
          Makes an attempt to extract the named library from the jar file and to store it on the local file system for temporary use.
private  java.lang.String getClientPath(java.lang.String name, java.net.URL clientURL)
          Returns the complete path (including file name) for the native library, assuming the native library is located in the same directory from which the client was loaded.
static Librarian getInstance()
          Returns an instance of Librarian to use.
private  java.lang.String getNativePath(java.lang.String name, NativeLibraryClient client)
          Returns the complete path (including file name) for the native library, assuming the native library is located in a directory where native libraries are ordinarily expected.
private  java.lang.String getTempFileName(java.lang.String name)
          Builds a temporary file name for the native library.
private  boolean loaded(java.lang.String name)
          Verifies if the library has already been loaded and keeps track of all libraries that are verified.
 void loadLibrary(java.lang.String name, NativeLibraryClient client)
          Loads the requested library.
private  java.io.InputStream openInputStream(java.lang.String name, NativeLibraryClient client)
          Opens an InputStream to the native library.
private  java.lang.String revisePath(java.lang.String in)
          Revises the given path to a file compatible path.
 void setNativeDirectory(java.lang.String directory)
          Sets the directory where Librarian will search for native files.
private  java.lang.String strip(java.lang.String name)
          Strips the extension of the library name, if it has one.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

JAR_PROTOCOL

private static final java.lang.String JAR_PROTOCOL
Used to identify jar URL protocols

See Also:
Constant Field Values

FILE_PROTOCOL

private static final java.lang.String FILE_PROTOCOL
Used to identify file URL protocols

See Also:
Constant Field Values

TEMP_LOCATION_KEY

private static final java.lang.String TEMP_LOCATION_KEY
The key used to retrieve the location of temporary files form the system properties.

See Also:
Constant Field Values

CLIENT_EXTENSION

private static final java.lang.String CLIENT_EXTENSION
The extension appended to the client name when searching for it as a resource. Since the client is an object, the extension should always be '.class'

See Also:
Constant Field Values

NATIVE

private static final java.lang.String NATIVE
The default directory for native library files.

See Also:
Constant Field Values

BLOCK_SIZE

private static final int BLOCK_SIZE
The block size used for reading and writing data, 4k.

See Also:
Constant Field Values

me

private static Librarian me
The reference to the single instance of Librarian. Used in static methods in place of this.


trackList

private java.util.Vector trackList
A list that is used to track all libraries that have been loaded. This list is used to ensure that each library is loaded only once.


clients

private java.util.Vector clients
A list of references to clients that use libraries that were extracted from a *.jar file. This is needed because the clients need to be called for freeing their libraries.


libraryNames

private java.util.Vector libraryNames
A list of library names as they appear in the temporary directory. This is needed to free each library through the client. The index of each name corresponds to the index of the respective client in the clients list.


temporaryFileNames

private java.util.Vector temporaryFileNames
A list of fully qualified library names. This is needed to delete the temporary library files after use. The index of each name corresponds to the index of the respective client in the clients list.


extension

private java.lang.String extension
The extension to use for native libraries.


nativeDirectory

private java.lang.String nativeDirectory
The directory that is used to hold all native libraries.

Constructor Detail

Librarian

private Librarian()
This class is implemented as a 'Singleton'. Therefore the constructor is private to prevent instantiation of this class. Use getInstance() to obtain an instance for use.

For more information about the 'Singleton' pattern I highly recommend the book Design Patterns by Gamma, Helm, Johnson and Vlissides ISBN 0-201-63361-2.

Method Detail

getInstance

public static Librarian getInstance()
Returns an instance of Librarian to use.

Returns:
an instance of Librarian.

loadLibrary

public void loadLibrary(java.lang.String name,
                        NativeLibraryClient client)
                 throws java.lang.Exception
Loads the requested library. If the library is already loaded, this method returns immediately, without an attempt to load the library again.

Invocation Example: This assumes that the call is made from the class that links with the library. If this is not the case, this must be replaced by the reference of the class that links with the library.

Librarian.getInstance ().loadLibrary ("MyLibrary", this);

Loading of a native library file works as follows:


Loading from the local file system and from the *.jar file is attempted for the following potential locations of the library in this order:
  1. The same directory where the client is located
  2. The native library directory

Parameters:
name - the name of the library. A file extension and path are not needed, in fact if supplied, both is stripped off. A specific extension is appended.
client - the object that made the load request
Throws:
java.lang.Exception - if all attempts to load the library fail.
See Also:
setNativeDirectory(java.lang.String)

loaded

private boolean loaded(java.lang.String name)
Verifies if the library has already been loaded and keeps track of all libraries that are verified.

Parameters:
name - name of the library to verify
Returns:
true if the library had already been loaded, otherwise false.

strip

private java.lang.String strip(java.lang.String name)
Strips the extension of the library name, if it has one.

Parameters:
name - the name of the library
Returns:
the name without an extension

extractFromJar

private void extractFromJar(java.lang.String name,
                            java.lang.String destination,
                            NativeLibraryClient client)
                     throws java.lang.Exception
Makes an attempt to extract the named library from the jar file and to store it on the local file system for temporary use. If the attempt is successful, the fully qualified file name of the library on the local file system is returned.

Parameters:
name - the simple name of the library
destination - the fully qualified name of the destination file.
client - the class that made the load request.
Throws:
java.lang.Exception - if the library can not be extracted from the *.jar file.
java.io.FileNotFoundException - if the *.jar file does not exist. The way things operate here, this should actually never happen.

getClientPath

private java.lang.String getClientPath(java.lang.String name,
                                       java.net.URL clientURL)
Returns the complete path (including file name) for the native library, assuming the native library is located in the same directory from which the client was loaded.

Parameters:
name - the simple name of the library
clientURL - a URL that points to the client class
Returns:
the path to the client

getNativePath

private java.lang.String getNativePath(java.lang.String name,
                                       NativeLibraryClient client)
Returns the complete path (including file name) for the native library, assuming the native library is located in a directory where native libraries are ordinarily expected.

Parameters:
name - the simple name of the library
client - the class that made the load request.
Returns:
the path to the location of the native libraries.

revisePath

private java.lang.String revisePath(java.lang.String in)
Revises the given path to a file compatible path. In fact this method replaces URI-like entries with it chars (e.g. %20 with a space).

Parameters:
in - path to be revised
Returns:
revised path

openInputStream

private java.io.InputStream openInputStream(java.lang.String name,
                                            NativeLibraryClient client)
                                     throws java.lang.Exception
Opens an InputStream to the native library.

Parameters:
name - the simple name of the library
client - the class that made the load request.
Returns:
an InputStream from which the library can be read.
Throws:
java.lang.Exception - if the library can not be located.

getTempFileName

private java.lang.String getTempFileName(java.lang.String name)
Builds a temporary file name for the native library.

Parameters:
name - the file name of the library
Returns:
a fully qualified file name that can be used to store the file on the local file system.

setNativeDirectory

public void setNativeDirectory(java.lang.String directory)
Sets the directory where Librarian will search for native files. Directories are denoted relative to the root, where the root is the same location where the top level Java package directory is located (usually called com). The default directory is native.

Parameters:
directory - the directory where native files are located.

cleanUp

public void cleanUp()
This method attempts to remove all native libraries that have been temporarily created from the system.

Specified by:
cleanUp in interface CleanupClient