Como Receber Parâmetros do JColtrane
Nas seções passadas você aprendeu como dizer ao JColtrane como executar métodos e em que condições. Agora aprenderemos como obter informação do processamento.
ContextVariables
Na seção anterior, quando você estava construindo sua própria condição, você provavelmente notou que o método verify, da interface Condition, recebia um objeto da classe ContextVariable como parâmetro. Essa classe possui toda iformação sobre o processamento. Dada sua importância, resumimos os métodos dessa classe, dando a descrição de cada um:
Classe ContextVariables |
Método |
Descrição |
getBody() |
Retorna uma String com o conteúdo do corpo do último elemento. Deve ser usado com EndElement, uma vez que todo o corpo só é conhecido nesse momento |
getCurrentBranch() |
Retorna uma String com todos elementos que iniciaram e ainda não terminaram. Os elementos são separados por "/". |
getEvent(int) |
Retorna o evento dado por sua profundidade. Eventos são empilhados em um pilha, isto é,profundidade igual a 0 significa o último elemento, o do topo da pilha; profundidade igual a 1 siginifica o evento anterior e assim por diante. Retorna null se não há evento correspondente a profundidade |
getLastEvent() |
Retorna o último evento |
getGeneralUseMap() |
Retorna um mapa para uso geral que o usuário pode usar para armazenar alguma informação. As chaves são String e os valores da Classe Object. |
putInGeneralUseMap(String key,Object obj) |
insere um elemnto no General Use Map. |
Os eventos retornados em alguns métodos são do tipo SAXEvent. Essa classe possui métodos para acessar uri, local name, tag e atributos de um elemento.
O General Use Map existe para permitir ao usuário armazenar informações que pode, ajudar no processamento. Por exemplo, você pode colocar um objeto quando um elemento iniciar e acessá-lo quando um elemento estiver finalizando.
O objeto da classe ContextVariable é manipulada pelo JColtraneXMLHandler e cada Handler possui uma instância dessa classe.
Para acessar esse objeto, você só precisa declarar um objeto dessa classe como parâmetro no método anotado com StartElement ou EndElement .
Veja o exemplo a seguir para entender melhor:
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;
}
}
Processando o seguinte código:
<?xml version="1.0" encoding="UTF-8"?>
<beanDescriptor>
<line>
<property mandatory="true" >
body of the property
</property >
</line>
</beanDescriptor>
O sistema imprime:
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
Assim, com ContextVariables você pode acessar toda informação do processamento que precisar. Mas, para aplicações simples, trabalhar com ContextVariables pode fazê-lo sentir como "matar uma formiga com um bomba atômica ". Assim, vejamos outras maneiras de se receber parâmetros.
Anotações de Parâmetros
JColtrane permite receber algumas informações de parâmetros somente os anotando-os. Veja a tabela a seguir com todos tipos de anotações para parâmetros:
Anotação |
Descrição |
Attribute(String qName) |
Retorna o valor do atributo dado pelo seu nome qualificador do elemento corrente. Faz parsing automático para todos tipos primitivos ou seu respectivos Wrappers.
Retorna null para objetos ou MIN_VALUE para tipos primitivos, se o elemento não contiver o atributo. |
AttributeMap |
Retorna um mapa contendo todos atributtos do elemento corrente |
CurrentBranch |
Retorna o galho corrente do processamento |
Uri |
Retorna a uri do elemento corrente |
Tag |
Retorna a tag do elemento corrente |
LocalName |
Retorna o nome local do elemento corrente |
GeneralUseMap |
Retorna o GeneralUseMap do objeto da classe ContextVariables |
Body |
Retorna o corpo do elemento corrente. Possui as opções newLine e tab, que podem assumir valores verdadeiro (true) ou falso (false), que retornam a String com ou sem marcadores de linha ou tabulação, de acordo com o valor das propriedades. |
Assim, com as anotações acima, você pode usar somente a anotação apropriada no parâmetros dos métodos para recebê-los.
Vejamos um exemplo:
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);
}
Processando o código XML:
<?xml version="1.0" encoding="UTF-8"?>
<beanDescriptor>
<line>
<property mandatory="true" page="5" >
body of the property
</property >
</line>
</beanDescriptor>
Temos:
/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
Como você pode ver, você pode usar qualquer número de parâmetros que desejar. Note que para o atributo page, JColtrane codifica a String para int, retornando o MIN_VALUE para elementos que não contenham um atributo nomeado page. Se você quisesse, poderia acessar ContextVariables além de todos os parâmetro que acessamos no exemplo.
Agora você está pronto para acessar toda informação que necessitar sobre o processamento. Vejamos como extender o processamento na seção Extendendo o Processamento XML.