org.apache.jackrabbit.classloader
Class DynamicRepositoryClassLoader

java.lang.Object
  extended by java.lang.ClassLoader
      extended by java.security.SecureClassLoader
          extended by java.net.URLClassLoader
              extended by org.apache.jackrabbit.classloader.RepositoryClassLoader
                  extended by org.apache.jackrabbit.classloader.DynamicRepositoryClassLoader
All Implemented Interfaces:
EventListener

public class DynamicRepositoryClassLoader
extends RepositoryClassLoader
implements EventListener

The DynamicRepositoryClassLoader class extends the RepositoryClassLoader and provides the functionality to load classes and resources from the JCR Repository. Additionally, this class supports the notion of getting 'dirty', which means, that if a resource loaded through this class loader has been modified in the Repository, this class loader marks itself dirty, which flag can get retrieved. This helps the user of this class loader to decide on whether to reinstantiate it or continue using this class loader.

When a user of the class loader recognizes an instance to be dirty, it can easily be reinstantiated with the reinstantiate(javax.jcr.Session, java.lang.ClassLoader) method. This reinstantiation will also rebuild the internal real class path from the same list of path patterns as was used to create the internal class path for the original class loader. The resulting internal class path need not be the same, though.

As an additional feature the class loaders provides the functionality for complete reconfiguration of the list of path patterns defined at class loader construction time through the reconfigure(String[]) method. This reconfiguration replaces the internal class path with a new one built from the new path list and also replaces that path list. Reinstantiating a reconfigured class loader gets a class loader containing the same path list as the original class loader had after reconfiguration. That is the original configuration is lost. While reconfiguration is not able to throw away classes already loaded, it will nevertheless mark the class loader dirty, if any classes have already been loaded through it.

This class is not intended to be extended by clients.

Author:
Felix Meschberger

Constructor Summary
DynamicRepositoryClassLoader(Session session, String[] classPath, ClassLoader parent)
          Creates a DynamicRepositoryClassLoader from a list of item path strings containing globbing pattens for the paths defining the class path.
 
Method Summary
protected  void addClassPathEntry(org.apache.jackrabbit.classloader.ClassPathEntry cpe)
          Adds the class path entry to the current class path list.
protected  void buildRepository()
          Builds the repository list from the list of path patterns and appends the path entries from any added handles.
 void destroy()
          Destroys this class loader.
protected  org.apache.jackrabbit.classloader.ClassPathEntry[] getAddedRepositories()
          Returns the list of added class path entries to readd them to the class path after reconfiguring the class loader.
 boolean isDirty()
          Returns whether the class loader is dirty.
 void onEvent(EventIterator events)
          Handles a repository item modifcation events checking whether a class needs to be expired.
 void pathChanged()
          Handles modified matched path set by setting the class loader dirty.
 void reconfigure(String[] classPath)
          Reconfigures this class loader with the pattern list.
 DynamicRepositoryClassLoader reinstantiate(Session session, ClassLoader parent)
          Reinstantiates this class loader.
protected  void setAddedRepositories(org.apache.jackrabbit.classloader.ClassPathEntry[] addedRepositories)
          Sets the list of class path entries to add to the class path after reconfiguration or reinstantiation.
 boolean shouldReload()
          Returns true if any of the loaded classes need reload.
 boolean shouldReload(String name)
          Checks whether this class loader already loaded the named resource and would load another version if it were instructed to do so.
 boolean shouldReload(String name, boolean force)
          Checks whether this class loader already loaded the named resource and whether the class loader should be set dirty depending on the force argument.
 String toString()
          Returns a string representation of this class loader.
 
Methods inherited from class org.apache.jackrabbit.classloader.RepositoryClassLoader
addClassPathEntry, addHandle, addURL, cleanCache, findClass, findResource, findResources, getRepository, getSession, getURLs, hasLoadedResources, isDestroyed, setRepository
 
Methods inherited from class java.net.URLClassLoader
definePackage, getPermissions, newInstance, newInstance
 
Methods inherited from class java.security.SecureClassLoader
defineClass, defineClass
 
Methods inherited from class java.lang.ClassLoader
clearAssertionStatus, defineClass, defineClass, defineClass, defineClass, definePackage, findLibrary, findLoadedClass, findSystemClass, getPackage, getPackages, getParent, getResource, getResourceAsStream, getResources, getSystemClassLoader, getSystemResource, getSystemResourceAsStream, getSystemResources, loadClass, loadClass, resolveClass, setClassAssertionStatus, setDefaultAssertionStatus, setPackageAssertionStatus, setSigners
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

DynamicRepositoryClassLoader

public DynamicRepositoryClassLoader(Session session,
                                    String[] classPath,
                                    ClassLoader parent)
Creates a DynamicRepositoryClassLoader from a list of item path strings containing globbing pattens for the paths defining the class path.

Parameters:
session - The Session to use to access the class items.
classPath - The list of path strings making up the (initial) class path of this class loader. The strings may contain globbing characters which will be resolved to build the actual class path.
parent - The parent ClassLoader, which may be null.
Throws:
NullPointerException - if either the session or the handles list is null.
Method Detail

destroy

public void destroy()
Destroys this class loader. This process encompasses all steps needed to remove as much references to this class loader as possible.

NOTE: This method just clears all internal fields and especially the class path to render this class loader unusable.

This implementation does not throw any exceptions.

Overrides:
destroy in class RepositoryClassLoader

shouldReload

public boolean shouldReload(String name)
Checks whether this class loader already loaded the named resource and would load another version if it were instructed to do so. As a side effect the class loader sets itself dirty in this case.

Calling this method yields the same result as calling shouldReload(String, boolean) with the force argument set to false.

Parameters:
name - The name of the resource to check.
Returns:
true if the resource is loaded and reloading would take another version than currently loaded.
See Also:
isDirty()

shouldReload

public boolean shouldReload(String name,
                            boolean force)
Checks whether this class loader already loaded the named resource and whether the class loader should be set dirty depending on the force argument. If the argument is true, the class loader is marked dirty and true is returned if the resource has been loaded, else the loaded resource is checked for expiry and the class loader is only set dirty if the loaded resource has expired.

Parameters:
name - The name of the resource to check.
force - true if the class loader should be marked dirty if the resource is loaded, else the class loader is only marked dirty if the resource is loaded and has expired.
Returns:
true if the resource is loaded and force is true or if the resource has expired. true is also returned if this class loader has already been destroyed.
See Also:
isDirty()

shouldReload

public boolean shouldReload()
Returns true if any of the loaded classes need reload. Also sets this class loader dirty. If the class loader is already set dirty or if this class loader has been destroyed before calling this method, it returns immediately.

Returns:
true if any class loader needs to be reinstantiated.
See Also:
isDirty()

isDirty

public boolean isDirty()
Returns whether the class loader is dirty. This can be the case if any of the shouldReload(String) or shouldReload() methods returned true or if a loaded class has been expired through the observation.

This method may also return true if the Session associated with this class loader is not valid anymore.

Finally the method always returns true if the class loader has already been destroyed. Note, however, that a destroyed class loader cannot be reinstantiated. See reinstantiate(Session, ClassLoader).

If the class loader is dirty, it should be reinstantiated through the reinstantiate(javax.jcr.Session, java.lang.ClassLoader) method.

Returns:
true if the class loader is dirty and needs reinstantiation.

reinstantiate

public DynamicRepositoryClassLoader reinstantiate(Session session,
                                                  ClassLoader parent)
Reinstantiates this class loader. That is, a new ClassLoader with no loaded class is created with the same configuration as this class loader.

When the new class loader is returned, this class loader has been destroyed and may not be used any more.

Parameters:
parent - The parent ClassLoader for the reinstantiated DynamicRepositoryClassLoader, which may be null.
Returns:
a new instance with the same configuration as this class loader.
Throws:
IllegalStateException - if this DynamicRepositoryClassLoader has already been destroyed through the destroy() method.

reconfigure

public void reconfigure(String[] classPath)
Reconfigures this class loader with the pattern list. That is the new pattern list completely replaces the current pattern list. This new pattern list will also be used later to configure the reinstantiated class loader.

If this class loader already has loaded classes using the old, replaced path list, it is set dirty.

If this class loader has already been destroyed, this method has no effect.

Parameters:
classPath - The list of path strings making up the (initial) class path of this class loader. The strings may contain globbing characters which will be resolved to build the actual class path.

buildRepository

protected void buildRepository()
Builds the repository list from the list of path patterns and appends the path entries from any added handles. This method may be used multiple times, each time replacing the currently defined repository list.

Overrides:
buildRepository in class RepositoryClassLoader
Throws:
NullPointerException - If this class loader has already been destroyed.

onEvent

public void onEvent(EventIterator events)
Handles a repository item modifcation events checking whether a class needs to be expired. As a side effect, this method sets the class loader dirty if a loaded class has been modified in the repository.

Specified by:
onEvent in interface EventListener
Parameters:
events - The iterator of repository events to be handled.

pathChanged

public void pathChanged()
Handles modified matched path set by setting the class loader dirty. The internal class path is only rebuilt when the class loader is reinstantiated.


toString

public String toString()
Returns a string representation of this class loader.

Overrides:
toString in class RepositoryClassLoader

setAddedRepositories

protected void setAddedRepositories(org.apache.jackrabbit.classloader.ClassPathEntry[] addedRepositories)
Sets the list of class path entries to add to the class path after reconfiguration or reinstantiation.

Parameters:
addedRepositories - The list of class path entries to keep for readdition.

getAddedRepositories

protected org.apache.jackrabbit.classloader.ClassPathEntry[] getAddedRepositories()
Returns the list of added class path entries to readd them to the class path after reconfiguring the class loader.


addClassPathEntry

protected void addClassPathEntry(org.apache.jackrabbit.classloader.ClassPathEntry cpe)
Adds the class path entry to the current class path list. If the class loader has already been destroyed, this method creates a single entry class path list with the new class path entry.

Besides adding the entry to the current class path, it is also added to the list to be readded after reconfiguration and/or reinstantiation.

Overrides:
addClassPathEntry in class RepositoryClassLoader
See Also:
getAddedRepositories(), setAddedRepositories(ClassPathEntry[])


Copyright © 2004-2007 The Apache Software Foundation. All Rights Reserved.