ContactCenters
V. 0.9.9.

umontreal.iro.lecuyer.xmlconfig
Class ParamReader

java.lang.Object
  extended by umontreal.iro.lecuyer.xmlconfig.ParamReader

public class ParamReader
extends Object

Constructs a parameter object from an XML document parsed using a DOM parser. For this parameter reader to be used, values must be added to the map elements in order to map root elements to class names. The method read(java.lang.String) can be used to construct a new parameter object from a DOM document or an XML file.


Nested Class Summary
static class ParamReader.MethodComparator
          Comparator for sorting the methods returned by Introspection.getMethods(java.lang.Class).
 
Field Summary
 URI baseURI
          Contains the base URI used by the readURL(java.lang.String) method.
 Map<String,Class<? extends Param>> elements
          Provides mappings for root elements to Java classes.
 File[] searchPath
          Contains the search path for the searchFile(java.lang.String) method.
 
Constructor Summary
ParamReader()
          Constructs a new parameter reader.
 
Method Summary
<T extends Param>
T
createParameterObject(Class<T> c, Element el)
          Constructs a new parameter object of class c from the DOM element el.
 ClassFinder getClassFinder()
          Returns the class finder associated with this parameter reader.
static URI getDefaultBaseURI()
          Returns the default base URI, which corresponds to the location of the current directory.
 DocumentBuilder getDocumentBuilder()
          Returns the document builder instance associated with this instance of parameter reader.
 Element getElementById(String id)
          Returns the element, in the currently read document, having an id attribute with value id.
 boolean isUsingSetAccessible()
          Determines if the parameter reader can use the AccessibleObject.setAccessible(boolean) when accessing members using Relfection.
 void processElement(Element el, Param o)
          Configures the parameter object o by processing the DOM element el.
 Param read(Document doc)
          Reads a DOM document doc and constructs a parameter object based on its contents.
 Param read(File fileName)
          Reads a parameter object from the XML file filaName.
 Param read(InputStream stream)
          This is similar to read(String), but it reads the XML document from the stream stream instead of from a file.
 Param read(String fileName)
          Deprecated. Use readFile(java.lang.String) instead.
 Param read(URL url)
          Reads a parameter object from the XML file located at URL url.
 Param readFile(String fileName)
          Reads the parameter object given by the file fileName.
 Param readURL(String url)
          Reads the parameter object given by the URL url.
 File searchFile(String fileName)
          Returns a file object corresponding to an existing file with name fileName by looking on the current search path.
 void setUsingSetAccessible(boolean useSetAccessible)
          Sets the set-accessible usage flag to useSetAccessible.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

elements

public Map<String,Class<? extends Param>> elements
Provides mappings for root elements to Java classes. The keys of the elements map are strings representing XML element names whereas the values are Class objects corresponding to parameter objects. When an element belongs to a namespace, its corresponding key in the map is given by namespaceURI/tagname, where tagname is the tag name of the element, without the namespace prefix. If the element is not in a namespace, its key name is its tag name. For example, if the root element was given by


 <pr:parameters xmlns:pr="http://www.test.uri">

The key name would be http://www.test.uri/parameters. If no namespace is used, the name is parameters.


searchPath

public File[] searchPath
Contains the search path for the searchFile(java.lang.String) method. See the documentation of searchFile(java.lang.String) for more information. The default search path contains a single file referring to ., the current directory.


baseURI

public URI baseURI
Contains the base URI used by the readURL(java.lang.String) method. The default base URL corresponds to the current working directory.

Constructor Detail

ParamReader

public ParamReader()
Constructs a new parameter reader.

Method Detail

getDefaultBaseURI

public static URI getDefaultBaseURI()
Returns the default base URI, which corresponds to the location of the current directory.

Returns:
the default base URL.

isUsingSetAccessible

public boolean isUsingSetAccessible()
Determines if the parameter reader can use the AccessibleObject.setAccessible(boolean) when accessing members using Relfection. This reader allows setter, adder, and dispatcher methods in parameter objects to be protected or private. In this case, it uses the setAccessible method to bypass Java access control. However, this can cause problems when using applets or Java Web Start programs. As a result, one can prevent this parameter reader from calling the setAccessible method by calling setUsingSetAccessible(boolean) with false. However, disabling the set-accessible usage flag may result in ParamReadExceptions caused by illegal accesses. By default, this returns true.

Returns:
the status of the set-accessible usage flag, default being true.

setUsingSetAccessible

public void setUsingSetAccessible(boolean useSetAccessible)
Sets the set-accessible usage flag to useSetAccessible.

Parameters:
useSetAccessible - the new value of the flag.
See Also:
isUsingSetAccessible()

getClassFinder

public ClassFinder getClassFinder()
Returns the class finder associated with this parameter reader. The import declarations associated with this class finder are obtained from the XML parameter file through import processing instructions. For each parsed element, ClassFinder.saveImports() is used at the beginning of processing and ClassFinder.restoreImports() is used at the end. For each processing instruction <?import name?>, name is added to the list returned by ClassFinder.getImports().

Returns:
the class finder associated to this parameter reader.

getElementById

public Element getElementById(String id)
Returns the element, in the currently read document, having an id attribute with value id. If no such element exists, null is returned.

Parameters:
id - the identifier of the element.
Returns:
the corresponding element.

readFile

public Param readFile(String fileName)
               throws IOException,
                      ParserConfigurationException,
                      SAXException
Reads the parameter object given by the file fileName. Uses searchFile(java.lang.String) to find an existing file with the name fileName on the current search path, and passes this file to the read(File) method. With the default search path, this looks in the current directory only.

Parameters:
fileName - the file name to be parsed.
Returns:
the constructed parameter object.
Throws:
ParserConfigurationException - if the parser could not be configured properly.
IOException - if an I/O error occurs.
SAXException - if a parse error occurs.
ParamReadException - if an extraction error occurs.
ClassCastException - if elements contains a value which is not of class Class.

readURL

public Param readURL(String url)
              throws IOException,
                     ParserConfigurationException,
                     SAXException
Reads the parameter object given by the URL url. Uses URI.resolve(java.net.URI) to resolve url against baseURI, converts the resulting URI into a URL, and give the resulting URL to read(URL).

Parameters:
url - the relative URI.
Returns:
the parameter object.
Throws:
IOException - if an I/O exception occurs during parameter reading.
SAXException - if a parse error occurs.
ParamReadException - if an extraction error occurs.
ClassCastException - if elements contains a value which is not of class Class.
ParserConfigurationException

read

@Deprecated
public Param read(String fileName)
           throws IOException,
                  ParserConfigurationException,
                  SAXException
Deprecated. Use readFile(java.lang.String) instead.

Uses searchFile(java.lang.String) to find an existing file with the name fileName on the current search path, and passes this file to the read(File) method. With the default search path, this looks in the current directory only.

Parameters:
fileName - the file name
Returns:
the constructed parameter object.
Throws:
ParserConfigurationException - if the parser could not be configured properly.
IOException - if an I/O error occurs.
SAXException - if a parse error occurs.
ParamReadException - if an extraction error occurs.
ClassCastException - if elements contains a value which is not of class Class.

read

public Param read(File fileName)
           throws IOException,
                  ParserConfigurationException,
                  SAXException
Reads a parameter object from the XML file filaName. If the given file is found, the method adds its parent directory to the search path, and sets it as the base URI. It then creates an XML parser using JAXP, parses the XML file and passes the created DOM document to (Documnet). The DocumentBuilder instance used to parse the XML files is created only once for each instance of parameter reader, by the getDocumentBuilder() method. After this process, the method restores the original search path.

Parameters:
fileName - the file name to be parsed.
Returns:
the constructed parameter object.
Throws:
ParserConfigurationException - if the parser could not be configured properly.
IOException - if an I/O error occurs.
SAXException - if a parse error occurs.
ParamReadException - if an extraction error occurs.
ClassCastException - if elements contains a value which is not of class Class.

searchFile

public File searchFile(String fileName)
                throws FileNotFoundException
Returns a file object corresponding to an existing file with name fileName by looking on the current search path. If the given file name is an absolute path, or the search path stored in the searchPath field is null or has length 0, this method creates a file object from the given file name. If that file exists, i.e., if fileName is a valid relative or absolute path pointing to an existing file, this method returns the file object. Otherwise, for each non-null element p of the searchPath array, this method makes a file object with parent p and name fileName. It returns the first file object referring to an existing file. If no file with the given name can be found on the search path, this method throws a FileNotFoundException.

Parameters:
fileName - the name of the file to search for.
Returns:
the found file.
Throws:
FileNotFoundException - if the file cannot be found.

read

public Param read(URL url)
           throws IOException,
                  ParserConfigurationException,
                  SAXException
Reads a parameter object from the XML file located at URL url. The method sets the given URL as the base URI. If the given URL corresponds to a file, the method also adds its parent directory to the search path. It then creates an XML parser using JAXP, parses the XML file and passes the created DOM document to (Documnet). The DocumentBuilder instance used to parse the XML files is created only once for each instance of parameter reader, by the getDocumentBuilder() method. After this process, the method restores the original search path.

Parameters:
url - the URL pointing to the file to be parsed.
Returns:
the constructed parameter object.
Throws:
ParserConfigurationException - if the parser could not be configured properly.
IOException - if an I/O error occurs.
SAXException - if a parse error occurs.
ParamReadException - if an extraction error occurs.
ClassCastException - if elements contains a value which is not of class Class.

read

public Param read(InputStream stream)
           throws IOException,
                  ParserConfigurationException,
                  SAXException
This is similar to read(String), but it reads the XML document from the stream stream instead of from a file.

Parameters:
stream - the stream to read the XML document from.
Returns:
the constructed parameter object.
Throws:
ParserConfigurationException - if the parser could not be configured properly.
IOException - if an I/O error occurs.
SAXException - if a parse error occurs.
ParamReadException - if an extraction error occurs.
ClassCastException - if elements contains a value which is not of class Class.

getDocumentBuilder

public DocumentBuilder getDocumentBuilder()
                                   throws ParserConfigurationException
Returns the document builder instance associated with this instance of parameter reader. If no document builder is associated yet, one is created. This coalescent document builder is configured to expand entities, ignore white spaces and is not validating. See DocumentBuilderFactory for more information.

Returns:
the associated document builder.
Throws:
ParserConfigurationException - if the parser could not be configured properly.

read

public Param read(Document doc)
Reads a DOM document doc and constructs a parameter object based on its contents. If some problems occur during the extraction of parameters, a ParamReadException is thrown.

When given an XML document, the method maps the root element name to a Java Class object by using elements.

Before the parameter object is created, the given document is scanned for elements with non-empty id attributes. These elements are put into an internal map that is cleared before this method ends. Each time an element with a xref attribute is found, it is automatically replaced with an element having the corresponding id attribute. The parameter reader keeps a stack of currently-processed elements to avoid infinite loops during this reference resolution process.

The createParameterObject(Class,Element) method is then used to construct the parameter object from the XML element.

Parameters:
doc - the DOM document being read.
Returns:
the constructed parameter object.
Throws:
ParamReadException - if an extraction error occurs.
ClassCastException - if elements contains a value which is not of class Class.

createParameterObject

public <T extends Param> T createParameterObject(Class<T> c,
                                                 Element el)
Constructs a new parameter object of class c from the DOM element el. The method first tries to construct the parameter object by calling one of the four type of constructors, in that order: (ParamReader, Element), (ParamReader), (Element), and (). The constructors receiving the processed element allow a class to override the automatic parameter extraction. Otherwise, the method uses processElement(Element,Param) to perform the processing if the call to the constructor succeeds. If the construction of the object fails, a ParamReadException is thrown.

Parameters:
c - the target class of the parameter object.
el - the element the parameters are extracted from.
Returns:
the constructed parameter object.
Throws:
ParamReadException - if an error occurs during parameter extraction.

processElement

public void processElement(Element el,
                           Param o)
Configures the parameter object o by processing the DOM element el. To achieve this result with arbitrary objects, the method assumes the parameter objects respect some design patterns summarized in tables 2 and 3. These patterns specify methods one can implement to interact with the parameter reader.

These methods are not specified in the Param interface because their signatures are incomplete or they are optional. Some method names depend on the attribute or nested element name and the argument type directs the conversion from string.

Some of the possible methods can take an optional URI argument which corresponds to the namespace URI of the attribute or nested element being set, created or added, or null if no namespace is used. If a namespace URI is incorrect, a tester method can return false and other methods can throw a ParamReadException.


Table 2: Variables used in parameter object methods
Name  Role
uri Namespace URI of attribute or nested element
lname Local name of attribute or nested element
class Name of a class or primitive type
pclass Name of a class implementing Param
value The value converted from string
el The element being processed
cel The nested (or child) element
attr An attribute in el



Table 3: Summary of design patterns for parameter objects
Method  Design pattern Role
Tester boolean isAttributeSupported ([ParamReader r, ][String uri, ]String lname) Determines if an attribute is supported
Setter void setAttr ([ParamReader r, ][String uri, ]class value) Sets attr to value
Tester boolean isNestedElementSupported ([ParamReader r, ][String uri, ]String lname) Determines if a nested element is supported
Adder void addNested ([ParamReader r, ][String uri, ]class paramobj) Adds processed nested element nested
Creater pclass createNested ([ParamReader r, ][String uri|Element cel]) Creates the nested element nested
Text void nestedText ([ParamReader r, ]class value) Adds character data
Dispatcher void defaultSetAttribute ([ParamReader r, ]Attr attr) Fallback method for attributes with no setter method
Dispatcher void defaultNestedElement ([ParamReader r, ]Element cel) Fallback method for elements with no adder or creater methods
Ender void finishReading ([ParamReader r, ]Element el) Terminates the reading


If the class of the parameter object defines several setter, adder or creater methods having the same name, the reader selects a single method to call. The methods of the parameter object are sorted using the comparator ParamReader.MethodComparator and the sorted array of methods is searched linearly, the first appropriate method being selected. This comparator implements an heuristic to place the most specialized methods first. In particular, the method with the greatest number of arguments and supported by the reader is taken. If more than one methods have the same greatest number of arguments, some argument types have priority over other types. ParamReader, Param, and Node have high priority whereas arrays have low priority.

For each attribute with local name attr, a suport test is performed. If the parameter object class defines a isAttributeSupported method returning a boolean value, this method is called to test attr. If it returns false, an exception is thrown. If it returns true or the method does not exist, the attribute processing continues. After the support test, the method tries to call an appropriate setter method in the parameter object. The String) method is given the string value of the attribute, and the result is given to the setter method. If no setter method is provided for a given attribute, the parameter reader tries to call a dispatcher method named defaultSetAttribute. If no setter or dispatcher method can be called to set a given attribute, the reader terminates with a ParamReadException.

After the attributes are set, nested elements can be constructed and added to the parameter object. For nested text, a nestedText method is looked for. The argument of nestedText can be of any type provided that String) is capable of converting it from String.

A nested element with local name nested is processed using an adder or a creater method. As with attributes, a support test is performed using isNestedElementSupported, if it exists. Often, a nested element may contain nested text only. For such elements, if the paramobj argument does not correspond to a class implementing Param, the parameter reader uses String) to convert the nested text into an object for the adder method. Otherwise, the class of paramobj must implement Param. The createParameterObject(java.lang.Class, org.w3c.dom.Element) method is called recursively to obtain a parameter object which is passed to the adder method. The class of the nested parameter object depends on the argument of the adder method.

If the nested element cannot be constructed by a single-argument or a no-argument constructor, the adder method can be replaced by a creater method of the form createNested. The method must construct and return the parameter object, possibly after configuring it. When the traversed element is received, the automatic extraction process is bypassed. If both an adder and creater methods are present with the same argument type, the creater method is called first and the adder method is called with the processed parameter object which was constructed using the creater method.

If no adder or creater methods are available to process a nested element, the method tries to call a dispatcher method with name If no adder, creater or dispatcher method can process a given element, a ParamReadException is thrown.

When all contents is processed, the method looks for a finishReading method in the parameter object. If such a method is found, it is called with el as an argument. This method can be used to finalize the parameter reading and processing.

Parameters:
el - the element being processed.
o - the parameter object being defined.
Throws:
ParamReadException - if a problem occurs during the extraction of parameters.

ContactCenters
V. 0.9.9.

To submit a bug or ask questions, send an e-mail to Richard Simard.