Extendendo o Processamento XML
De tudo que você já viu até agora é possivel pensar em como extender o processamento XML de duas maneiras:
- Alterando métodos
- Introduzindo novos métodos em sua classe
Considere o código XML abaixo:
<?xml version="1.0" encoding="UTF-8"?>
<beanDescriptor>
<line>
<property mandatory="true" >
body of the property
</property >
</line>
</beanDescriptor>
Considere que você tenha criado uma nova propriedade, como a marcada:
<?xml version="1.0" encoding="UTF-8"?>
<beanDescriptor>
<line>
<property mandatory="true" page="5" >
body of the property
</property >
</line>
<afterLine/>
</beanDescriptor>
Usando JColtrane, você cria sua classe de processamento:
public class Parser1 {
@StartElement(tag="line")
public void parse(@CurrentBranch String branch){
System.out.println(branch);
System.out.println("execute some action");
}
}
Testando:
public class ParserTest {
public static void main(String[] args) {
SAXParser parser=null;
try {
parser= SAXParserFactory.newInstance().newSAXParser();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
File file=new File("examples\\example6\\Example6.xml");
if(parser!=null){
InputSource input=new InputSource(file.getAbsolutePath());
try {
parser.parse(input,new JColtraneXMLHandler(new Parser1()));
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Se você processar o documento depois de inserir a linha no XML, não haverá mudança no processamento. Para fazer a classe processar o novo elemento, poríamos modificar o método da seguinte forma:
public class Parser1 {
@StartElement(tag="line|afterLine")
public void parse(@CurrentBranch String branch, @Tag String tag){
System.out.println(branch);
if(tag.equals("line"))
System.out.println("execute some action");
else
System.out.println("execute another action");
}
}
Mas, fazer isso não é uma boa abordagem, uma vez que tornaria o código difícil de manter e você teria que fazer novos testes para o método.
Uma melhor abordagem seria incluir outro método na classe:
public class Parser1 {
@StartElement(tag="line")
public void parse(@CurrentBranch String branch){
System.out.println(branch);
System.out.println("execute some action");
}
@StartElement(tag="afterLine")
public void parse2(@CurrentBranch String branch){
System.out.println(branch);
System.out.println("execute another action");
}
}
Assim, com essa abordagem, você só precisa testar se o seu novo método está funcionando.
Você poderia ainda tratar o novo elemento em uma outra classe:
public class Parser2 {
@StartElement(tag="afterLine")
public void parse2(@CurrentBranch String branch){
System.out.println(branch);
System.out.println("execute another action");
}
}
Alterando a classe ParserTest:
public class ParserTest {
public static void main(String[] args) {
SAXParser parser=null;
try {
parser= SAXParserFactory.newInstance().newSAXParser();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
File file=new File("examples\\example6\\Example6.xml");
if(parser!=null){
InputSource input=new InputSource(file.getAbsolutePath());
try {
parser.parse(input,new JColtraneXMLHandler(new Parser1(),new Parser2()));
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Como você pode ver, JColtraneXMLHandler aceita mais de uma classe em seu construtor. Assim, você pode separar o processamento em quantas classe quiser.
A vantagem dessa abordagem é que você evita classes com inúmeros métodos. A desvantagem é que a opção priority funciona somente para métodos da mesma classe. Dessa maneira, se duas diferentes classes executam alguma ação no mesmo momento, por exemplo quando um determinado elemento é iniciado, você não poderá determinar a ordem de execução.
Assim, escolher qual técnica é melhor é sua responsabilidade em cada aplicação.