3.0.2: 2012-01-25

net.sf.basedb.util.extensions.manager
Class ExtensionsFile

java.lang.Object
  extended by net.sf.basedb.util.extensions.manager.ExtensionsFile
All Implemented Interfaces:
Comparable<ExtensionsFile>

public class ExtensionsFile
extends Object
implements Comparable<ExtensionsFile>

Represents a file with extensions in it. The file is either an XML file or a JAR file. A JAR file is always a real file on the file system and can be accessed with getFile(). An XML file can be both a real file or an abstract stream of bytes and can be accessed by getXmlStream(). The latter method can also be used in the case of a JAR file and will then open the META-INF/extensions.xml file.

Since:
3.0
Author:
Nicklas
Last modified
$Date: 2011-10-24 15:02:46 +0200 (Mon, 24 Oct 2011) $

Nested Class Summary
static class ExtensionsFile.WriteableExtensionsFile
          An extensions file with additional methods that allows adding or modifying information in the underlying extensions file.
 
Field Summary
private  About about
           
private  Map<ObjectKey,Object> allObjects
           
private  File file
           
private  boolean hasError
           
private  boolean isJar
           
private  boolean isNew
           
private  boolean isValid
           
private  JarClassLoader jarLoader
           
private  long lastLength
           
private  long lastModified
           
private static Logger log
           
private  ExtensionsManager manager
           
private  String name
           
private  Map<ObjectKey,Object> objectMetadata
           
private  ReentrantReadWriteLock rwLock
           
private  URI uri
           
private  Throwable validationError
           
private  boolean wasModified
           
 
Constructor Summary
(package private) ExtensionsFile(ExtensionsManager manager, File file)
          Create a new extensions file backed by a real file on the file system.
(package private) ExtensionsFile(ExtensionsManager manager, File file, boolean isJar)
          Create a new extensions file backed by a real file on the file system.
private ExtensionsFile(ExtensionsManager manager, File file, URI uri, String name, boolean isJar)
           
(package private) ExtensionsFile(ExtensionsManager manager, URI uri)
          Create a new extension file backed by an URI.
 
Method Summary
 boolean checkModified()
          Check if the underlying file has been modified since it was last processed.
 int compareTo(ExtensionsFile other)
           
 boolean equals(Object o)
           
 boolean exists()
          Check if the file exists.
 About getAbout()
          Get information about the extensions in this file.
 List<Object> getAllObjects()
          Get a list of all objects defined in this extensions file.
 ClassLoader getClassLoader()
          Get the class loader used to load classes for the extension.
 File getFile()
          Get the underlying file on the file system.
<M> M
getMetadata(ObjectKey<M> key)
          Get metadata registered for a given given key.
<T> List<T>
getMetadataKeysOfClass(Class<T> ofClass)
          Get a list of all metadata defined in this extensions file that are keyed with the specified class or interface.
 String getName()
          Get the name of the file.
<O> O
getObjectForKey(ObjectKey<O> key)
          Get the object that was registered for the given key.
<T> List<T>
getObjectsOfClass(Class<T> ofClass)
          Get a list of all objects defined in this extensions file that are of the specified class or interface.
 InputStream getStream(String path)
          Get an input stream for reading the resource specified by the given path
 URI getURI()
          Get an URI that points to the extensions file.
 Throwable getValidationError()
          Get more information about the error that caused the validation to fail.
(package private)  ExtensionsFile.WriteableExtensionsFile getWriteableFile()
          Get a writeable view for the current file.
 InputStream getXmlStream()
          Get an input stream for reading the XML file containing the extension definitions.
 boolean hasError()
          If there was an error when registering the extensions in this file.
 int hashCode()
           
 boolean isInstalled()
          Is this file installed into the system or not?
 boolean isJar()
          If the file name ends with '.jar' the file is considered a JAR file.
 boolean isNew()
          If the file is a new file not previously processed by the extension system.
 boolean isValid()
          Is the file a valid extensions file according to the last performed validation.
(package private)  boolean readLock()
          Try to aquire a read-lock.
 String toString()
           
(package private)  boolean validate()
          Validate the XML file with the extension definitions.
 boolean wasModified()
          Check if the file was modified when the last call to checkModified() was made.
(package private)  boolean writeLock()
          Try to aquire a write-lock.
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

log

private static final Logger log

manager

private final ExtensionsManager manager

file

private final File file

uri

private final URI uri

isJar

private final boolean isJar

name

private final String name

rwLock

private final ReentrantReadWriteLock rwLock

allObjects

private final Map<ObjectKey,Object> allObjects

objectMetadata

private final Map<ObjectKey,Object> objectMetadata

isNew

private boolean isNew

wasModified

private boolean wasModified

lastModified

private long lastModified

lastLength

private long lastLength

jarLoader

private JarClassLoader jarLoader

about

private About about

hasError

private boolean hasError

isValid

private volatile boolean isValid

validationError

private Throwable validationError
Constructor Detail

ExtensionsFile

ExtensionsFile(ExtensionsManager manager,
               File file)
Create a new extensions file backed by a real file on the file system. If the file name ends with '.jar' it is assumed to be a JAR file, otherwise it must be an XML file containing extension definitions.

Parameters:
file - The file

ExtensionsFile

ExtensionsFile(ExtensionsManager manager,
               File file,
               boolean isJar)
Create a new extensions file backed by a real file on the file system. The file may be a JAR file or an XML file.

Parameters:
file - The file
isJar - TRUE if it is a JAR file, FALSE if it is an XML file

ExtensionsFile

ExtensionsFile(ExtensionsManager manager,
               URI uri)
Create a new extension file backed by an URI. The URI must point to an XML file containing extension definitions.

Parameters:
uri - The URI

ExtensionsFile

private ExtensionsFile(ExtensionsManager manager,
                       File file,
                       URI uri,
                       String name,
                       boolean isJar)
Method Detail

compareTo

public int compareTo(ExtensionsFile other)
Specified by:
compareTo in interface Comparable<ExtensionsFile>

hashCode

public int hashCode()
Overrides:
hashCode in class Object

equals

public boolean equals(Object o)
Overrides:
equals in class Object

toString

public String toString()
Overrides:
toString in class Object

getName

public String getName()
Get the name of the file. The name may or may not correspond to a real file.


getFile

public File getFile()
Get the underlying file on the file system. Return null if the extension is defined by an URI.


getURI

public URI getURI()
Get an URI that points to the extensions file.


isJar

public boolean isJar()
If the file name ends with '.jar' the file is considered a JAR file. Otherwise it is considered an XML file. The file name check is case sensitive.

Returns:
TRUE if the file is a JAR file, false if it is an XML file

exists

public boolean exists()
Check if the file exists. For files that are only represented by an URI this method always return true. For other files the call is forwarded to File.exists() and File.isFile().

Returns:
See File.exists()

isNew

public boolean isNew()
If the file is a new file not previously processed by the extension system. Thew 'new' status is changed when ExtensionsFile.WriteableExtensionsFile.markAsProcessed() is called which usually happens when all extensions has been registered.

Returns:
TRUE if the file is a new file, FALSE otherwise

isInstalled

public boolean isInstalled()
Is this file installed into the system or not?


wasModified

public boolean wasModified()
Check if the file was modified when the last call to checkModified() was made. It is recommended that processor implementation use this method instead to avoid inconsistent behaviour if the file happens to be modified while a processor is running.

Returns:
TRUE if the file was modified, FALSE otherwise

checkModified

public boolean checkModified()
Check if the underlying file has been modified since it was last processed. Files that are new are always considered to be modified. Files that are only represented as an URI are considered to be unmodifiable. For other files, we check the File.lastModified() and File.length() of the underlying file and compare that to the last known timestamp and size. Files that are JAR files we also check with the class loader if any of the libraries it uses have changed.

The result of this call is remembered until this method is called again or until the file is marked as processed.

See Also:
ExtensionsFile.WriteableExtensionsFile.markAsProcessed(), wasModified()

isValid

public boolean isValid()
Is the file a valid extensions file according to the last performed validation. This means that the file must be either: The result of the validation is remembered as long as the file is not modified. If checkModified() returns true, the return value of this method may be out of sync. Re-validation of modified files are usually performed by the extensions manager by calling ExtensionsManager.scanForChanges()

NOTE! The validation will only verify that the XML file follows the rules defined by the schema definition. It will not check that actual classes, etc. exists and can be created. This usually happens later in the registration process, and can be checked by hasError().

Returns:
TRUE if the file is valid, FALSE otherwise
See Also:
getValidationError(), checkModified(), hasError()

getValidationError

public Throwable getValidationError()
Get more information about the error that caused the validation to fail.

Returns:
An exception or null if the validation succeeded
See Also:
isValid()

getAbout

public About getAbout()
Get information about the extensions in this file.

Returns:
An About object or null if the file is not a valid extensions file

getXmlStream

public InputStream getXmlStream()
                         throws IOException
Get an input stream for reading the XML file containing the extension definitions.

Returns:
An input stream
Throws:
IOException

getStream

public InputStream getStream(String path)
                      throws IOException
Get an input stream for reading the resource specified by the given path

Parameters:
path - The path of the resource
Returns:
An input stream (or null if this extensions file is not a JAR file or if the given path is not found)
Throws:
IOException

validate

boolean validate()
Validate the XML file with the extension definitions.


hasError

public boolean hasError()
If there was an error when registering the extensions in this file. This property is only set if the file has been determined to be a valid extensions file by the isValid() method. Extensions that has an error are automatically disabled.

Returns:
TRUE if there was some error, FALSE if everything is ok

getAllObjects

public List<Object> getAllObjects()
Get a list of all objects defined in this extensions file. This list can contain any type of objects that have been registered by a processer, but typically this list contains ExtensionPoint:s and Extension:s. Use getObjectsOfClass(Class) to get a list with only one type of objects.

Returns:
A list with the objects

getObjectsOfClass

public <T> List<T> getObjectsOfClass(Class<T> ofClass)
Get a list of all objects defined in this extensions file that are of the specified class or interface. Note! The returned list may be empty if another thread is currently processing this file.

Parameters:
ofClass - The class/interface the objects must be an instance of
Returns:
A list with the objects, if no objects are found the list is empty

getObjectForKey

public <O> O getObjectForKey(ObjectKey<O> key)
Get the object that was registered for the given key.

Parameters:
key - An object key
Returns:
The object or null if no object was found

getMetadata

public <M> M getMetadata(ObjectKey<M> key)
Get metadata registered for a given given key.

Parameters:
key - An object key
Returns:
A metadata object, or null if no metadata was found

getMetadataKeysOfClass

public <T> List<T> getMetadataKeysOfClass(Class<T> ofClass)
Get a list of all metadata defined in this extensions file that are keyed with the specified class or interface. Note! The returned list may be empty if another thread is currently processing this file.

Parameters:
ofClass - The class/interface the metadata keys must be an instance of
Returns:
A list with the objects, if no objects are found the list is empty

getClassLoader

public ClassLoader getClassLoader()
                           throws IOException
Get the class loader used to load classes for the extension. Only JAR files have class loaders so this method may return null.

Throws:
IOException

getWriteableFile

ExtensionsFile.WriteableExtensionsFile getWriteableFile()
Get a writeable view for the current file. Note that the view is returned in read-only mode and to really be able to write information the method ExtensionsFile.WriteableExtensionsFile.open() must be called.


readLock

boolean readLock()
Try to aquire a read-lock. A read-lock is needed when reading information that may be corrupted if another thread is currently writing information to this file.

Returns:
TRUE if the read-lock could be aquired immediately, FALSE if not

writeLock

boolean writeLock()
Try to aquire a write-lock. A write-lock is needed by any thread that wants to update information about this file. The write-lock can only be held by a single thread at a time.

Returns:
TRUE if the write-lock could be aquired within 1 second, FALSE if not

3.0.2: 2012-01-25