Receiving Parameters from JColtrane
In past sections you learned how to tell JColtrane to execute methods and in what conditions. Now you are gonna to learn how to obtain information from the pasing.
ContextVariables
In last section, when you were building your own condition, you probably noted that the method verify, from interface Condition, receive a object from ContextVariable as parameter. This class has all iformation about parsing process. Given its importance, we summarize the methods from this class, giving a description to each one:
Class ContextVariables |
Method |
Description |
getBody() |
Returns a String with the body content from the last element. Should be used with EndElement, once the full body is known only at this time |
getCurrentBranch() |
Returns a String with all the elements that have started but are no finished yet. The element are separeted by "/". |
getEvent(int) |
Returns the event given by its deep. Events are pushed in a stack. deep equals 0 means the last event, e.g. the element in stack top, deep equals to 1 means the event before the last and so on. Returns null if there is no event corresponding to the deep |
getLastEvent() |
Returns the last Element |
getGeneralUseMap() |
Returns a map for general purpose that user can use to store some information. Keys are from String type and value is from Object class. |
putInGeneralUseMap(String key,Object obj) |
put an element in General Use Map. |
The event returned in some methods is from SAXEvent. It contains methods to acces uri, local name, tag and attributes from a element.
The General Use Map exist to allow user store information that can help parsing process. For example, you can put in it a object in a start element and acces it on end element.
The ContextVariable is manipulated by JColtraneXMLHandler, and each handler has an instance of ContextVariables.
To acces it, you need just declare an object of this class as parameter in a method that is annotated with StartElement or EndElement .
See next example to better undestanding:
public class ContextVariableReceiver {
int key=0;
@StartElement
public void executeUserStartTest(ContextVariables contextVariables){
System.out.println("\n\nExecuting in start element");
System.out.println(contextVariables.getCurrentBranch());
SAXEvent event=contextVariables.getLastEvent();
System.out.println("Current tag: "+event.getTag());
if(event!=null){
for(String qName: event.getAtributesHolder().getQNames()){
System.out.println("Attribute name: "+qName+"\nvalue: "+event.getAtributesHolder().getValue(qName));
}
}
SAXEvent beforeEvent=contextVariables.getEvent(1);
if(beforeEvent!=null)
System.out.println("\nBefore tag: "+beforeEvent.getTag());
++key;
contextVariables.putInGeneralUseMap(Integer.toString(key), new Date());
}
@EndElement
public void executeUserEndTest(ContextVariables contextVariables){
System.out.println("\n\nExecuting in end element");
System.out.println(contextVariables.getCurrentBranch());
SAXEvent event=contextVariables.getLastEvent();
System.out.println("Current tag: "+event.getTag());
if(event!=null){
for(String qName: event.getAtributesHolder().getQNames()){
System.out.println("Attribute name: "+qName+"\nvalue: "+event.getAtributesHolder().getValue(qName));
}
}
SAXEvent beforeEvent=contextVariables.getEvent(1);
if(beforeEvent!=null)
System.out.println("\nBefore tag: "+beforeEvent.getTag());
Date date=(Date) contextVariables.getGeneralUseMap().get(Integer.toString(key));
System.out.println(date.getTime());
--key;
}
}
Parsing the following code:
<?xml version="1.0" encoding="UTF-8"?>
<beanDescriptor>
<line>
<property mandatory="true" >
body of the property
</property >
</line>
</beanDescriptor>
System prints:
Executing in start element
/beanDescriptor/
Current tag: beanDescriptor
Executing in start element
/beanDescriptor/line/
Current tag: line
Before tag: beanDescriptor
Executing in start element
/beanDescriptor/line/property/
Current tag: property
Attribute name: mandatory
value: true
Before tag: line
Executing in end element
/beanDescriptor/line/property/
Current tag: property
Attribute name: mandatory
value: true
Before tag: line
1221067433116
Executing in end element
/beanDescriptor/line/
Current tag: line
Before tag: beanDescriptor
1221067433115
Executing in end element
/beanDescriptor/
Current tag: beanDescriptor
1221067433114
So, with ContextVariables you can acces all information about the parsing. But, for simple applications, work with ContextVariables can make you feel like "killing an ant with an atomic bomb". So let's see another ways to receive parameters.
Parameter's Annotions
JColtrane allows you receive some kind of parameters just annotating them. See next table with all types of annotations for parameters:
Annotation |
Description |
Attribute(String qName) |
Returns the value of the attribute given by its qualifier name from the current element. Make automatic parse for all primtive types or their correspondig Wrappers and String class.
Returns null for objects or MIN_VALUE for primitive types, if element doesn't contain the attribute |
AttributeMap |
Returns a map containing all the attributtes from the current element |
CurrentBranch |
Returns the current branch from the parsing |
Uri |
Returns the uri from current element |
Tag |
Returns the tag from current element |
LocalName |
Returns the local name from current element |
GeneralUseMap |
Returns the GeneralUseMap from ContextVariables |
Body |
Returns the body of current element. Has options newLine and tab, that can be true or false, that returns the string with or without new lines or tabs according with these option values. |
So, with the anntotions above, you can just put the right annotation in method's parameters to receive them.
Let's see an example:
public class ParametersReceiver {
@StartElement
public void executeUserStartTest(@CurrentBranch String currentBranch,
@Attribute("page") int pageNumber,
@AttributeMap Map attributeMap,
@Tag String tag,
@Body(newLine=false) String body){
System.out.println();
System.out.println(currentBranch);
System.out.println("current tag: "+tag);
System.out.println("page number: "+pageNumber);
System.out.println("Att Map: "+attributeMap);
System.out.println("Body"+body);
}
Parsing the XML code:
<?xml version="1.0" encoding="UTF-8"?>
<beanDescriptor>
<line>
<property mandatory="true" page="5" >
body of the property
</property >
</line>
</beanDescriptor>
Running the example we have:
/beanDescriptor/
current tag: beanDescriptor
page number: -2147483648
Att Map: {}
Body
/beanDescriptor/line/
current tag: line
page number: -2147483648
Att Map: {}
Body
/beanDescriptor/line/property/
current tag: property
page number: 5
Att Map: {page=5, mandatory=true}
Body
As you can see, you can use any number of parameters you want. Note that for attribute page, JColtrane parse the String to int, returning the MIN_VALUE for elements that don't contain an attribute named as page. If you want, you could access ContextVariables besides all the parameters we have accessed on example.
Now you are able to acces all information you need about parsing. Let's see how to extend the parsing process in section Extending Parsing Process.