package br.gov.verificador; import java.io.*; import java.util.*; import org.xml.sax.*; import br.gov.verificador.excecao.*; import br.gov.verificador.objeto.*; import br.gov.verificador.reflexao.*; import br.gov.verificador.xml.*; import br.gov.verificador.xml.excecao.*; import br.gov.verificador.xml.tagclasses.*; public class Verificador {
public static final int METODO_GET = 0; public static final int METODO_SET = 1; public Verificador() {
} /**
* Verifica se o estado do VO está atualizado. Se não estiver, retorna * uma exceção VersaoDesatualizadaException. Se estiver atualizada, * incrementa o número de versão.
* @param vo
* @throws VersaoDesatualizadaException * @throws TabelaNaoEncontradaException */
public static synchronized void checaEstadoVO(ValueObject vo) throws VersaoDesatualizadaException, VerificadorException,
TabelaNaoEncontradaException { long versao = buscaNumeroVersao(vo); if (versao == vo.getNumeroVersao()){ incrementaNumeroVersao(vo); }else
throw new VersaoDesatualizadaException("o objeto com descritor '"+vo.getDescritor()+"' está desatualizado.");
} /**
* Verifica se algum ValueObject contido no Composite está desatualizado. * Só serão verificados as entidades que forem setadas no arquivo de * configuração. * @param composite * @throws TabelaNaoEncontradaException * @throws VerificadorException * @throws VersaoDesatualizadaException */
public static synchronized void checaEstadoComposite(CompositeEntity composite) throws TabelaNaoEncontradaException, VerificadorException,
VersaoDesatualizadaException { try {
Tabela configComposite = ParserXML.getTabela(composite.getDescritor()); verificaComposite(composite, configComposite);
}
catch (SAXException ex) {
throw new VerificadorException("o arquivo de configuração pode estar em um formato inválido.", ex);
}
catch (IOException ex) {
throw new VerificadorException("não foi possível ler o arquivo de configuração.", ex); }
} /**
* Varre o composite procurando seus atributos que foram anotados no arquivo * de configuração para verificar seu estado. Se não houver o objeto, a
* verificação apenas não é feita. Um composite pode conter um ValueObject ou * um array deles, ou um outro CompositeEntity ou um array deles. Se algum * dos ValueObject verificados estiver desatualizado, uma exceção é lançada. * @param composite * @param tabela * @throws TabelaNaoEncontradaException * @throws VersaoDesatualizadaException * @throws VerificadorException */
protected static void verificaComposite(CompositeEntity composite, Tabela tabela) throws TabelaNaoEncontradaException, VersaoDesatualizadaException,
VerificadorException {
//Pega o principal atributo do CompositeEntity, ou seja, aquele que //associa os demais atributos.
ValueObject voPrincipal = getValueObject(composite, tabela.getNomeAtributo()+"VO");// composite.getDescritor());
//Verifica se o estado do atributo está atualizado. checaEstadoVO(voPrincipal);
Vector campos = tabela.getCampos(); for (int i = 0; i < campos.size(); i++){ Campo campo = (Campo) campos.get(i);
String nomeAtributo = campo.getTabela().getNomeAtributo()+"CE";// getNomeAtributoCE(campo.getTabela().getNome());
String metodoGet = getMetodo(nomeAtributo, METODO_GET); //Como um Composite pode conter outro Composite, aqui é verificado
//se existe algum método get para Composite. Só chamremos o método se ele existir. if (BeanUtilReflexao.existeMetodo(composite, metodoGet)){
//O método é invocado e o retorno é armazenado na variável resultado
Object resultado = BeanUtilReflexao.executaMetodoGet(composite, metodoGet); if (resultado != null)
//É preciso saber é entidade simples ou múltipla para tratar a //verificação.
if (campo.getMultiplo() != null && "S".equalsIgnoreCase(campo.getMultiplo())){ CompositeEntity[] vetorComposite = (CompositeEntity[]) resultado;
for (int c = 0; c < vetorComposite.length; c++){
verificaComposite(vetorComposite[c], campo.getTabela()); }//end for composite
}else
}else{
//Se entrar aqui, é porque o campo não é um Composite. Neste caso //será um ValueObject ou um array de ValueObject, ou também pode não //conter este atributo. Se não o conter, apenas não é chamado.
nomeAtributo =
campo.getTabela().getNomeAtributo()+"VO";//getNomeAtributoVO(campo.getTabela().getNome ());
metodoGet = getMetodo(nomeAtributo, METODO_GET);
//Só chamremos o método para buscar o ValueObject se ele existir. if (BeanUtilReflexao.existeMetodo(composite, metodoGet)) {
Object resultado = BeanUtilReflexao.executaMetodoGet(composite, metodoGet);
if (resultado != null)
//Precisamos saber se retornará um objeto simples ou um array. if (campo.getMultiplo() != null &&
"S".equalsIgnoreCase(campo.getMultiplo())) { ValueObject[] vetorVOs = (ValueObject[]) resultado; for (int j = 0; j < vetorVOs.length; j++) {
checaEstadoVO(vetorVOs[j]); } //end for
} else
checaEstadoVO( (ValueObject) resultado); }
} }//end for }
protected static long buscaNumeroVersao(ValueObject vo) throws TabelaNaoEncontradaException, VerificadorException {
//ESSA PARTE FICA A CRITÉRIO DO ANALISTA. ELE DECIDE ONDE GUARDAR O //NÚMERO DA VERSÃO DOS OBJETOS.
try {
Tabela tabela = ParserXML.getTabela(vo.getDescritor());
String metodoGetChavePrimaria = getMetodo(tabela.getChavePrimaria(), METODO_GET); if (BeanUtilReflexao.existeMetodo(vo, metodoGetChavePrimaria)){
Object resultado = BeanUtilReflexao.executaMetodoGet(vo, metodoGetChavePrimaria);
if (resultado != null)
System.out.println("chave primaria: "+resultado.toString()); }else
throw new VerificadorException("a chave primária para '"+tabela.getNome()+"' não foi definida corretamente no arquivo de configuração.");
}
catch (SAXException ex) { throw new VerificadorException(
"o arquivo de configuração pode estar em um formato inválido.", ex); }
catch (IOException ex) {
throw new VerificadorException(
"não foi possível ler o arquivo de configuração.", ex); }
return 0; }
public static ValueObject incrementaNumeroVersao(ValueObject vo){
//ESSA PARTE FICA A CRITÉRIO DO ANALISTA. ELE DECIDE ONDE GUARDAR O //NÚMERO DA VERSÃO DOS OBJETOS.
long versao = vo.getNumeroVersao(); versao++;
vo.setNumeroVersao(versao); return vo;
} /**
* Executa um método get no CompositeEntity para pegar um atributo * ValueObject. Se o método não existir, retorna uma exceção. * @param composite
* @param descritor nome da tabela no arquivo de configuração
* @return retorna um ValueObject chamado pelo metodo invocado no composite * @throws VerificadorException
*/
protected static ValueObject getValueObject(CompositeEntity composite, String atributo) throws
VerificadorException {
//String atributo = getNomeAtributoVO(atributo);
String metodoGet = getMetodo(atributo, METODO_GET); Object resultado = null;
if (!BeanUtilReflexao.existeMetodo(composite, metodoGet))
throw new VerificadorException("não existe o método \""+metodoGet+"\" na classe \""+composite.getClass().getName()+"\"");
else{
resultado = BeanUtilReflexao.executaMetodoGet(composite, metodoGet);
}
return (resultado == null ? null : (ValueObject) resultado); }
/**
* Retorna o nome de um atributo padronizado para atributos do tipo * ValueObject, ou seja, deve possuir o sufixo VO.
* @param atributo * @return
*/
public static String getNomeAtributoVO(String atributo) { return getNomeAtributo(atributo)+"VO";
} /**
* Retorna o nome de um atributo padronizado para atributos do tipo * CompositeEntity, ou seja, deve possuir o sufixo CE.
* @param atributo * @return
*/
public static String getNomeAtributoCE(String atributo) { return getNomeAtributo(atributo) + "CE";
/**
* Monta o nome do atributo segundo o padrão estabelecido. * UM_ATRIBUTO -> umAtributo
* UM_OUTRO_ATRIBUTO -> umOutroAtributo * UMATRIBUTO -> umatributo
* O separador "_" é eliminado, e a letra seguinte é passada para * maiúscula.
* @param atributo * @return
*/
public static String getNomeAtributo(String atributo) { atributo = atributo.toLowerCase();
while (atributo.startsWith("_"))
atributo = atributo.substring(1, atributo.length()); while (atributo.endsWith("_"))
atributo = atributo.substring(0, atributo.length() - 1); String aux = new String(atributo);
int indice = atributo.indexOf("_"); while (indice > 0) {
aux = atributo.substring(0, indice);
aux += atributo.substring(indice + 1, indice + 2).toUpperCase(); aux += atributo.substring(indice + 2, atributo.length());
atributo = aux; indice = atributo.indexOf("_"); } //end while return atributo; } /**
* Monta o nome do método segundo o padrão para um bean. Para um atributo * umAtributo, seu método get seria getUmAtributo e o método set seria * setUmAtributo.
* @param nomeAtributo * @param tipoMetodo * @return
*/
public static String getMetodo(String nomeAtributo, int tipoMetodo) { String metodo = new String();
if (tipoMetodo == METODO_GET) { metodo += "get";
}
else if (tipoMetodo == METODO_SET) { metodo += "set";
}
metodo += nomeAtributo.substring(0, 1).toUpperCase(); metodo += nomeAtributo.substring(1, nomeAtributo.length()); return metodo;
} }
import java.io.*;
public class ValueObject implements Serializable {
private long numeroVersao;//guarda o número da versão da entidade private String descritor;//indica à qual tabela a entidade representa, public ValueObject() {
}
public ValueObject(String descritor) { this.descritor = descritor;
}
public long getNumeroVersao() { return numeroVersao;
}
public void setNumeroVersao(long numeroVersao) { this.numeroVersao = numeroVersao;
}
public String getDescritor() { return descritor;
}
public void setDescritor(String descritor) { this.descritor = descritor;
} }
package br.gov.verificador.objeto; import java.io.*;
public class CompositeEntity implements Serializable { /*Esse é o descritor do principal atributo do Composite. Esse descritor se refere à propriedade descritor da tag <tabela> no arquivo de configuração. A partir desta tag é possível saber quais os nomes dos atributos do composite.
*/
protected String descritor; public CompositeEntity() { }
public CompositeEntity(String descritor) { this.descritor = descritor;
}
public String getDescritor() { return descritor;
}
public void setDescritor(String descritor) { this.descritor = descritor;
} }
package br.gov.verificador.reflexao; import java.beans.*; import java.lang.reflect.*; import br.gov.verificador.excecao.*; /**
* <p>Title: Verificador de versão de entidades</p> * <p>Description: </p>
* <p>Copyright: Copyright (c) 2004</p> * <p>Company: </p>
* @author Adriano Ferlin * @version 1.0
*/
public class BeanUtilReflexao { public BeanUtilReflexao() { }
/**
* Invoca um método get do bean obj passado por parametro. * O método retorna o retorno do método invocado no objeto. * @param obj objeto
* @param nomeMetodo nome do método get a ser invocado * @return retorno da invocação do método
*/
public static Object executaMetodoGet(Object obj, String nomeMetodo) { try {
Method metodoGet = obj.getClass().getMethod(nomeMetodo, null); return metodoGet.invoke(obj, new Object[] {});
}
catch (Exception ex) { return null;
} } /**
* Invoca um método get do bean obj passado por parametro. O nome do * método e seus parametros devem ser passados como parâmetro. * @param obj objeto que contém o método
* @param nomeMetodo nome do método a ser invocado * @param parametro array de parametros do metodo. * @param uppercase parametro booleano que indica se */
public static void executaMetodoSet(Object obj, String nomeMetodo, Object parametro, boolean uppercase) { try {
String nomeClasse = parametro.getClass().getName(); if (uppercase && nomeClasse.indexOf("String") > -1) { parametro = ( (String) parametro).toUpperCase(); }
Method metodoSet = obj.getClass().getMethod(nomeMetodo, new Class[] {
Class.forName(nomeClasse)}); metodoSet.invoke(obj, new Object[] {parametro});
}
catch (Exception ex) {
System.out.println("executaMetodoSet: \n" + ex.getClass() + "\n" + ex.getMessage());
} } /**
* Verifica se um determinado método existe no objeto. * @param objeto
* @param nomeMetodo * @return
* @throws VerificadorException */
public static boolean existeMetodo(Object objeto, String nomeMetodo) throws VerificadorException {
try {
BeanInfo info = Introspector.getBeanInfo(objeto.getClass());
MethodDescriptor[] metodosDaClasse = info.getMethodDescriptors(); for (int i = 0; i < metodosDaClasse.length; i++){
if (nomeMetodo.equals(metodosDaClasse[i].getMethod().getName())) return true;
}//end for return false; }
catch (IntrospectionException ex) {
throw new VerificadorException("não foi possível encontrar o método da classe.", ex); } } } package br.gov.verificador.xml; import java.io.*; import java.util.*; import org.apache.commons.digester.*; import org.xml.sax.*; import br.gov.verificador.xml.excecao.*; import br.gov.verificador.xml.tagclasses.*; /** * <p>Title: </p> * <p>Description: </p> * <p>Copyright: Copyright (c) 2004</p> * <p>Company: </p>
* @author Adriano Ferlin * @version 1.0
*/
public class ParserXML { public static final int NIVEL = 6;
public ParserXML() { }
public static void main(String[] args) { ParserXML parser = new ParserXML(); Tabela tabela = null;
try {
tabela = getTabela("TABELA1"); }
catch (TabelaNaoEncontradaException ex) { ex.printStackTrace();
System.out.println(ex.getMessage()); }
catch (SAXException ex) { ex.printStackTrace(); }
catch (IOException ex) { ex.printStackTrace(); } System.out.println("tabela: "+tabela); //parser.testeDigester1(); } /**
* Faz o parser do arquivo de configuração, e retorna em um objeto Tabelas, * com todos os ítens da árvore.
* @param fileName * @return
* @throws SAXException * @throws IOException */
public static Tabelas parse(String fileName) throws SAXException, IOException { File input = new File(fileName);
return (Tabelas) ParserXML.getVerificaroDigester().parse(input); }
/**
* Monta o parser para ler o arquivo XML com as configurações do banco de * dados, para verificar as dependências. A profundidade das verificações * varia de acordo com o NIVEL definido pelo programador.
* @return */
public static Digester getVerificaroDigester(){ Digester digester = new Digester(); digester.setValidating(false);
digester.addObjectCreate("tabelas", Tabelas.class); digester.addObjectCreate("tabelas/tabela", Tabela.class); digester.addSetProperties("tabelas/tabela", "nome", "nome");
digester.addSetProperties("tabelas/tabela", "nome-atributo", "nomeAtributo"); digester.addSetProperties("tabelas/tabela", "chave-primaria", "chavePrimaria"); digester.addSetNext("tabelas/tabela", "addTabela");
String path = "tabelas/tabela"; for (int i=0; i < NIVEL; i++){ path += "/campo";
digester.addObjectCreate(path, Campo.class); digester.addSetProperties(path, "multiplo", "multiplo"); digester.addSetNext(path, "addCampo");
path += "/tabela";
digester.addObjectCreate(path, Tabela.class); digester.addSetProperties(path, "nome", "nome");
digester.addSetProperties(path, "nome-atributo", "nomeAtributo"); digester.addSetProperties(path, "chave-primaria", "chavePrimaria"); digester.addSetNext(path, "setTabela");
}//end for return digester; }
/**
* Retorna um objeto do tipo Tabela com seus atributos contidos no * arquivo de configuração.
* @param nomeTabela nome da tabela a ser buscada no esquema * @return
* @throws IOException * @throws SAXException
* @throws TabelaNaoEncontradaException */
public static Tabela getTabela(String nomeTabela) throws IOException, SAXException, TabelaNaoEncontradaException {
Tabelas tabelas = parse(arquivo); Vector lstTabela = tabelas.getTabelas(); for (int i=0; i < lstTabela.size(); i++){ Tabela tabela = (Tabela) lstTabela.get(i);
if (nomeTabela.equalsIgnoreCase(tabela.getNome())) return tabela;
}//end for
throw new TabelaNaoEncontradaException("a tabela \""+nomeTabela+"\" não foi encontrada no arquivo de configuração."); } } package br.gov.verificador.xml.tagclasses; import java.util.Vector; /** * <p>Title: </p> * <p>Description: </p> * <p>Copyright: Copyright (c) 2004</p> * <p>Company: </p>
* @author not attributable * @version 1.0
*/
private Vector tabelas; public Tabelas() { tabelas = new Vector(); }
public void addTabela( Tabela tb ) { tabelas.addElement( tb ); }
public void setTabelas(Vector tabelas) { this.tabelas = tabelas;
}
public Vector getTabelas() { return tabelas; } } package br.gov.verificador.xml.tagclasses; import java.util.Vector; /** * <p>Title: </p> * <p>Description: </p> * <p>Copyright: Copyright (c) 2004</p> * <p>Company: </p>
* @author not attributable * @version 1.0
*/
public class Tabela { protected Vector campos; protected String nome;
protected String chavePrimaria; private String nomeAtributo; public Tabela() {
campos = new Vector(); }
public void addCampo(Campo campo){ campos.addElement(campo);
}
public void setChavePrimaria(String chavePrimaria) { this.chavePrimaria = chavePrimaria;
}
public void setNome(String nome) { this.nome = nome;
}
public void setCampos(Vector campos) { this.campos = campos;
}
public Vector getCampos() { return campos;
}
public String getChavePrimaria() { return chavePrimaria;
}
public String getNome() { return nome;
}
public String getNomeAtributo() { return nomeAtributo;
}
public void setNomeAtributo(String nomeAtributo) { this.nomeAtributo = nomeAtributo; } } package br.gov.verificador.xml.tagclasses; /** * <p>Title: </p> * <p>Description: </p> * <p>Copyright: Copyright (c) 2004</p> * <p>Company: </p>
* @author not attributable * @version 1.0
*/
public class Campo { protected String multiplo; protected Tabela tabela; public Campo() {
tabela = new Tabela(); }
public void setTabela(Tabela tabela) { this.tabela = tabela;
}
public void setMultiplo(String multiplo) { this.multiplo = multiplo;
}
public String getMultiplo() { return multiplo;
}
public Tabela getTabela() { return tabela;
} }
package br.gov.verificador.xml.excecao; /**
* <p>Title: Verificador de versão de entidades</p> * <p>Description: </p>
* <p>Company: </p> * @author Adriano Ferlin * @version 1.0
*/
public class TabelaNaoEncontradaException extends Exception { public TabelaNaoEncontradaException(String mensagem) { super(mensagem); } public TabelaNaoEncontradaException() { } } package br.gov.verificador.excecao;
public class VerificadorException extends Exception { public VerificadorException() {
}
public VerificadorException(String mensagem) { super(mensagem);
}
public VerificadorException(String mensagem, Exception ex) { super(mensagem, ex);
} }
package br.gov.verificador.excecao;
public class VersaoDesatualizadaException extends Exception { public VersaoDesatualizadaException() {
}
public VersaoDesatualizadaException(String mensagem) { super(mensagem);
} }
This document was created with Win2PDF available at http://www.daneprairie.com.