2.17.2: 2011-06-17

net.sf.basedb.util.extensions.xml
Class XmlLoader

java.lang.Object
  extended by net.sf.basedb.util.extensions.xml.XmlLoader

public class XmlLoader
extends Object

Loads extension points and extensions from extension definition XML files. This class may load extensions from more than one file and register or unregister all loaded extensions and extension points with a registry.

For a description of the XML file format this class can load see the BASE manual.

Factory initialisation
This loader uses reflection to create and initialise factory instances. The XML file contains the class name of the factory to create. This class must declare a public no-argument constructor and must also implement one of the specific factory interfaces (for example ActionFactory or RendererFactory). If the tag <parameters> is present inside the factory declaration, the loader will use reflection to find a setter method for each sub-tag inside the <parameters> tag. Here is an example:

// XML contents
<parameters>
   <image>button.png</image>
   <title>Click button</title>
</parameters>

// Factory initialization
factory.setImage("button.png");
factory.setTitle("Click button");
The setter methods must be public and accept a single String parameter.

The loader also looks for the setParameter(String, String) method signature. If the method exists it will be called for each parameter found with the tagname as the first parameter and the value as the second parameter. Continuing the above example:

factory.setParameter("image", "button.png");
factory.setParameter("title", "Click button");

Tags that doesn't have a corresponding setter method are simply ignored. The XML file format allows any tags as parameters, but only the first level will be parsed.

The parameter values may be subject to conversion by one or more ValueConverter:s. Converters are added to the loader by addValueConverter(ValueConverter) and are usually implemented to react on method annotations. For example, the web client uses this for path and variable substitution.

Version:
2.7
Author:
nicklas
Last modified
$Date:2008-03-20 12:15:25 +0100 (Thu, 20 Mar 2008) $

Field Summary
private  Set<ValueConverter> converters
           
private  List<ExtensionPoint<Action>> extensionPoints
           
private  List<Extension<Action>> extensions
           
private  Map<Object,String> factoryParameters
           
private static String namespace
          The name of the extensions namespace.
private static String schemaFileURL
          The URL pointing to the extensions.xsd schema.
private  Document validatedDom
           
private  XMLOutputter xmlOut
           
 
Constructor Summary
XmlLoader()
          Create a new XML loader instance.
 
Method Summary
 void addValueConverter(ValueConverter converter)
          Add a value converter to this loader
 void clearValueConverters()
          Remove all value converters.
protected
<F> F
createFactory(Element factoryTag, ClassLoader classLoader, Class<F> factoryType)
          Create a new factory instance.
protected  String getConvertedValue(String original, Method method)
           
 List<ExtensionPoint<Action>> getExtensionPoints()
          Get a list with all loaded extension points.
 List<Extension<Action>> getExtensions()
          Get a list with all loaded extensions.
 String getFactoryParameters(Object factory)
          Get a XML-like string representation of the parameters that was used to initialise a factory.
protected  Method getSetParameterMethod(Class<?> beanClass)
          Check if the bean class has a setParameter(String, String) method and return it's reference if it has.
protected  Method getSetterMethod(Class<?> beanClass, String tagName)
          Get the setter method for a given tag name.
protected  String getSetterMethodNameFromTag(String tagName)
          Convert the tag name to a setter method name.
 boolean hasValidFile()
          Checks if an XML file has passed validation in the validateXmlFile(InputStream, String) method.
protected  void initBeanWithReflection(Object bean, Element root)
          Initialise a bean using reflection.
protected  AboutBean loadAbout(Element aboutTag)
          Load information in an <about> tag.
protected  Document loadDocument(InputStream xmlFile, String filename)
          Load and validate the XML file.
protected  int loadExtensionPoints(Document dom, ClassLoader classLoader, About globalAbout)
          Create extension points from an XML document.
protected  int loadExtensions(Document dom, ClassLoader classLoader, About globalAbout)
          Create extensions from an XML document.
protected  AboutBean loadGlobalAbout(Document dom)
          Load the global about tag from the document.
 About loadLastValidatedFile(ClassLoader classLoader, boolean clear)
          Continue loading extensions from the last validated XML file.
 About loadXmlFile(InputStream xmlFile, String filename, ClassLoader classLoader, boolean clear)
          Load an extensions definition XML file.
 int registerExtensionPoints(Registry registry, boolean update)
          Register all loaded extension points with a registry.
 int registerExtensions(Registry registry, boolean update)
          Register all loaded extensions with a registry.
 void removeValueConverter(ValueConverter converter)
          Remove a converter.
 int unregisterExtensionPoints(Registry registry)
          Unregister all loaded extension points from a registry.
 int unregisterExtensions(Registry registry)
          Unregister all loaded extensions from a registry.
 About validateXmlFile(InputStream xmlFile, String filename)
          Validate an XML file against the extensions definition schema.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

schemaFileURL

private static final String schemaFileURL
The URL pointing to the extensions.xsd schema.


namespace

private static final String namespace
The name of the extensions namespace.

See Also:
Constant Field Values

xmlOut

private XMLOutputter xmlOut

extensionPoints

private List<ExtensionPoint<Action>> extensionPoints

extensions

private List<Extension<Action>> extensions

converters

private Set<ValueConverter> converters

factoryParameters

private Map<Object,String> factoryParameters

validatedDom

private Document validatedDom
Constructor Detail

XmlLoader

public XmlLoader()
Create a new XML loader instance.

Method Detail

addValueConverter

public void addValueConverter(ValueConverter converter)
Add a value converter to this loader

Parameters:
converter - The converter to add
Throws:
NullPointerException - If the converter is null

removeValueConverter

public void removeValueConverter(ValueConverter converter)
Remove a converter.

Parameters:
converter - The converter to remove, null values are ignored

clearValueConverters

public void clearValueConverters()
Remove all value converters.


loadXmlFile

public About loadXmlFile(InputStream xmlFile,
                         String filename,
                         ClassLoader classLoader,
                         boolean clear)
                  throws JDOMException,
                         IOException,
                         ClassNotFoundException,
                         NoSuchMethodException,
                         IllegalAccessException,
                         InstantiationException
Load an extensions definition XML file. This method may be called multiple times with different XML files. The loading may also be done by a two-step process where the first step validates the file and the second step loads the extensions. See validateXmlFile(InputStream, String) and loadLastValidatedFile(ClassLoader, boolean).

Parameters:
xmlFile - An input stream to read the XML data from
filename - The original filename the stream is coming from, or null if not known. This value is only used when generating error messages
classLoader - The classloader to use when loading classes that are named in the XML file, or null to use the default classloader (=the same class loader that loaded the BASE core classes)
clear - TRUE to clear all already loaded extensions before loading the extensions in this file
Returns:
Information about the extension, or null if no such information is available
Throws:
JDOMException - If validation of the XML file fails
IOException - If there is an error reading the XML file
ClassNotFoundException - If a class named in the XML file can't be found
NoSuchMethodException - If a factory class doesn't implement a public, no-argument constructor
IllegalAccessException - If a factory class constructor isn't public
InstantiationException - If a factory class can't be instantiated, for example, because it is an abstract class or an interface
See Also:
validateXmlFile(InputStream, String), loadLastValidatedFile(ClassLoader, boolean)

validateXmlFile

public About validateXmlFile(InputStream xmlFile,
                             String filename)
                      throws IOException,
                             JDOMException
Validate an XML file against the extensions definition schema. If the file is valid you may continue to load the extensions. See loadLastValidatedFile(ClassLoader, boolean).

Parameters:
xmlFile - An input stream to read the XML data from
filename - The original filename the stream is coming from, or null if not known. This value is only used when generating error messages
Returns:
Information about the extension, or null if no such information is available
Throws:
JDOMException - If validation of the XML file fails
IOException - If there is an error reading the XML file

loadLastValidatedFile

public About loadLastValidatedFile(ClassLoader classLoader,
                                   boolean clear)
                            throws ClassNotFoundException,
                                   IllegalAccessException,
                                   InstantiationException,
                                   NoSuchMethodException
Continue loading extensions from the last validated XML file. This is the second step in a two-step process and requires that validateXmlFile(InputStream, String) has been successfully called first.

Parameters:
classLoader - The classloader to use when loading classes that are named in the XML file, or null to use the default classloader (=the same class loader that loaded the BASE core classes)
clear - TRUE to clear all already loaded extensions before loading the extensions in this file
Returns:
Information about the extension, or null if no such information is available
Throws:
ClassNotFoundException - If a class named in the XML file can't be found
NoSuchMethodException - If a factory class doesn't implement a public, no-argument constructor
IllegalAccessException - If a factory class constructor isn't public
InstantiationException - If a factory class can't be instantiated, for example, because it is an abstract class or an interface

hasValidFile

public boolean hasValidFile()
Checks if an XML file has passed validation in the validateXmlFile(InputStream, String) method. If so, the loadLastValidatedFile(ClassLoader, boolean) can be called to continue loading the extensions.

Note that once the file has been loaded this flag is reset to FALSE.

Returns:
TRUE if a file has been validated, FALSE otherwise

getExtensionPoints

public List<ExtensionPoint<Action>> getExtensionPoints()
Get a list with all loaded extension points.


getExtensions

public List<Extension<Action>> getExtensions()
Get a list with all loaded extensions.


getFactoryParameters

public String getFactoryParameters(Object factory)
Get a XML-like string representation of the parameters that was used to initialise a factory.

Parameters:
factory - The factory object
Returns:
The parameters as found in the XML file

registerExtensionPoints

public int registerExtensionPoints(Registry registry,
                                   boolean update)
Register all loaded extension points with a registry.

Parameters:
registry - The registry
update - TRUE to update already registered extension points, FALSE to ignore
Returns:
The number of extension points registered or updated
See Also:
Registry.registerExtensionPoint(ExtensionPoint)

unregisterExtensionPoints

public int unregisterExtensionPoints(Registry registry)
Unregister all loaded extension points from a registry. All extensions will also be unregistered.

Parameters:
registry - The registry
Returns:
The number of extension points that was unregistered
See Also:
Registry.unregisterExtensionPoint(String)

registerExtensions

public int registerExtensions(Registry registry,
                              boolean update)
Register all loaded extensions with a registry.

Parameters:
registry - The registry
update - TRUE to update already registered extensions FALSE to ignore
Returns:
The number of registered or updated extensions
See Also:
Registry.registerExtension(Extension)

unregisterExtensions

public int unregisterExtensions(Registry registry)
Unregister all loaded extensions from a registry.

Parameters:
registry - The registry
Returns:
The number of extensions that was unregistered
See Also:
Registry.unregisterExtension(String)

loadDocument

protected Document loadDocument(InputStream xmlFile,
                                String filename)
                         throws IOException,
                                JDOMException
Load and validate the XML file.

Returns:
A JDOM document object
Throws:
IOException
JDOMException

loadGlobalAbout

protected AboutBean loadGlobalAbout(Document dom)
Load the global about tag from the document.

Returns:
An about bean or null if the about tag is not found.

loadAbout

protected AboutBean loadAbout(Element aboutTag)
Load information in an <about> tag.

Parameters:
aboutTag - The about tag

loadExtensionPoints

protected int loadExtensionPoints(Document dom,
                                  ClassLoader classLoader,
                                  About globalAbout)
                           throws ClassNotFoundException,
                                  NoSuchMethodException,
                                  IllegalAccessException,
                                  InstantiationException
Create extension points from an XML document.

Throws:
ClassNotFoundException
NoSuchMethodException
IllegalAccessException
InstantiationException

loadExtensions

protected int loadExtensions(Document dom,
                             ClassLoader classLoader,
                             About globalAbout)
                      throws ClassNotFoundException,
                             NoSuchMethodException,
                             IllegalAccessException,
                             InstantiationException
Create extensions from an XML document.

Throws:
ClassNotFoundException
NoSuchMethodException
IllegalAccessException
InstantiationException

createFactory

protected <F> F createFactory(Element factoryTag,
                              ClassLoader classLoader,
                              Class<F> factoryType)
                   throws ClassNotFoundException,
                          NoSuchMethodException,
                          IllegalAccessException,
                          InstantiationException
Create a new factory instance. The factory must be a class with a public, no-argument constructor. The factory class name is read from the <factory-class> tag and initialisation parameters from the <parameters> tag.

Parameters:
factoryTag - The root tag of the factory definition
classLoader - The classloader to use, or null to use the BASE core classloader
factoryType - Class type of the factory. The named class must implement or be a subclass of this class
Returns:
An initialised factory
Throws:
ClassNotFoundException
NoSuchMethodException
IllegalAccessException
InstantiationException

initBeanWithReflection

protected void initBeanWithReflection(Object bean,
                                      Element root)
Initialise a bean using reflection. For each child tag of the 'root' element, this method will check if the bean implements a setter method that is compatible with the child tag name. The method name should start with 'set' and then the tag name with the first letter capitalized. The method must take a single String argument. For example, if there is a child tag <image>button.png</image> this will be converted to the method call: setImage("button.png").

Tags that has no matching public setter method are ignored.

Parameters:
bean - The bean to initialize
root - The root element, if null nothing is done

getSetterMethod

protected Method getSetterMethod(Class<?> beanClass,
                                 String tagName)
Get the setter method for a given tag name.

Parameters:
beanClass - The class to look for the setter method in
tagName - The tag name in the XML file
Returns:
A Method object, or null if no method is found

getSetParameterMethod

protected Method getSetParameterMethod(Class<?> beanClass)
Check if the bean class has a setParameter(String, String) method and return it's reference if it has.

Parameters:
beanClass - The class to look for the method in
Returns:
A Method object, or null if no method is found

getSetterMethodNameFromTag

protected String getSetterMethodNameFromTag(String tagName)
Convert the tag name to a setter method name.

Parameters:
tagName - The tag name
Returns:
The tag name prefixed with 'set' and the first letter captialized

getConvertedValue

protected String getConvertedValue(String original,
                                   Method method)

2.17.2: 2011-06-17