From 97b7c020a53c84b8e374bba8d1f7eb79ce874046 Mon Sep 17 00:00:00 2001 From: fabiorj Date: Fri, 26 Nov 2021 20:02:12 -0300 Subject: [PATCH] Commit Inicial --- .gitignore | 7 + pom.xml | 32 + .../annotations/AuditarAtributo.java | 28 + .../auditador/annotations/AuditarClasse.java | 35 + .../annotations/AuditarEntidade.java | 20 + .../auditador/annotations/AuditarID.java | 18 + .../annotations/AuditarIDComposta.java | 15 + .../auditador/annotations/AuditarLista.java | 26 + .../auditador/annotations/AuditarMetodo.java | 28 + .../auditador/annotations/NaoAuditar.java | 15 + .../auditador/auditadores/Auditador.java | 628 ++++++++++++++++++ .../auditadores/AuditadorAtributo.java | 42 ++ .../auditadores/AuditadorEntidade.java | 76 +++ .../auditador/auditadores/AuditadorList.java | 131 ++++ .../auditadores/ExtrairAnotacao.java | 79 +++ .../enums/AuditadorTipoAlteracao.java | 16 + .../auditador/enums/TipoExtracaoDados.java | 8 + .../exceptions/AuditadorException.java | 11 + .../auditador/interfaces/Auditavel.java | 33 + .../interfaces/AuditavelTelaAlternativa.java | 18 + .../auditador/model/AuditadorObjects.java | 97 +++ target/Auditador.jar | Bin 0 -> 27952 bytes target/classes/META-INF/MANIFEST.MF | 5 + .../Auditador/pom.properties | 7 + .../br.com.rjconsultores/Auditador/pom.xml | 32 + .../annotations/AuditarAtributo.class | Bin 0 -> 541 bytes .../auditador/annotations/AuditarClasse.class | Bin 0 -> 663 bytes .../annotations/AuditarEntidade.class | Bin 0 -> 404 bytes .../auditador/annotations/AuditarID.class | Bin 0 -> 419 bytes .../annotations/AuditarIDComposta.class | Bin 0 -> 338 bytes .../auditador/annotations/AuditarLista.class | Bin 0 -> 445 bytes .../auditador/annotations/AuditarMetodo.class | Bin 0 -> 538 bytes .../auditador/annotations/NaoAuditar.class | Bin 0 -> 324 bytes .../auditador/auditadores/Auditador.class | Bin 0 -> 22754 bytes .../auditadores/AuditadorAtributo.class | Bin 0 -> 2563 bytes .../auditadores/AuditadorEntidade.class | Bin 0 -> 3886 bytes .../auditador/auditadores/AuditadorList.class | Bin 0 -> 6497 bytes .../auditadores/ExtrairAnotacao.class | Bin 0 -> 3092 bytes .../enums/AuditadorTipoAlteracao.class | Bin 0 -> 1541 bytes .../auditador/enums/TipoExtracaoDados.class | Bin 0 -> 1181 bytes .../exceptions/AuditadorException.class | Bin 0 -> 569 bytes .../auditador/interfaces/Auditavel.class | Bin 0 -> 472 bytes .../interfaces/AuditavelTelaAlternativa.class | Bin 0 -> 223 bytes .../auditador/model/AuditadorObjects.class | Bin 0 -> 3139 bytes target/maven-archiver/pom.properties | 5 + .../compile/default-compile/createdFiles.lst | 19 + .../compile/default-compile/inputFiles.lst | 19 + .../default-testCompile/inputFiles.lst | 0 48 files changed, 1450 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/br/com/rjconsultores/auditador/annotations/AuditarAtributo.java create mode 100644 src/main/java/br/com/rjconsultores/auditador/annotations/AuditarClasse.java create mode 100644 src/main/java/br/com/rjconsultores/auditador/annotations/AuditarEntidade.java create mode 100644 src/main/java/br/com/rjconsultores/auditador/annotations/AuditarID.java create mode 100644 src/main/java/br/com/rjconsultores/auditador/annotations/AuditarIDComposta.java create mode 100644 src/main/java/br/com/rjconsultores/auditador/annotations/AuditarLista.java create mode 100644 src/main/java/br/com/rjconsultores/auditador/annotations/AuditarMetodo.java create mode 100644 src/main/java/br/com/rjconsultores/auditador/annotations/NaoAuditar.java create mode 100644 src/main/java/br/com/rjconsultores/auditador/auditadores/Auditador.java create mode 100644 src/main/java/br/com/rjconsultores/auditador/auditadores/AuditadorAtributo.java create mode 100644 src/main/java/br/com/rjconsultores/auditador/auditadores/AuditadorEntidade.java create mode 100644 src/main/java/br/com/rjconsultores/auditador/auditadores/AuditadorList.java create mode 100644 src/main/java/br/com/rjconsultores/auditador/auditadores/ExtrairAnotacao.java create mode 100644 src/main/java/br/com/rjconsultores/auditador/enums/AuditadorTipoAlteracao.java create mode 100644 src/main/java/br/com/rjconsultores/auditador/enums/TipoExtracaoDados.java create mode 100644 src/main/java/br/com/rjconsultores/auditador/exceptions/AuditadorException.java create mode 100644 src/main/java/br/com/rjconsultores/auditador/interfaces/Auditavel.java create mode 100644 src/main/java/br/com/rjconsultores/auditador/interfaces/AuditavelTelaAlternativa.java create mode 100644 src/main/java/br/com/rjconsultores/auditador/model/AuditadorObjects.java create mode 100644 target/Auditador.jar create mode 100644 target/classes/META-INF/MANIFEST.MF create mode 100644 target/classes/META-INF/maven/br.com.rjconsultores/Auditador/pom.properties create mode 100644 target/classes/META-INF/maven/br.com.rjconsultores/Auditador/pom.xml create mode 100644 target/classes/br/com/rjconsultores/auditador/annotations/AuditarAtributo.class create mode 100644 target/classes/br/com/rjconsultores/auditador/annotations/AuditarClasse.class create mode 100644 target/classes/br/com/rjconsultores/auditador/annotations/AuditarEntidade.class create mode 100644 target/classes/br/com/rjconsultores/auditador/annotations/AuditarID.class create mode 100644 target/classes/br/com/rjconsultores/auditador/annotations/AuditarIDComposta.class create mode 100644 target/classes/br/com/rjconsultores/auditador/annotations/AuditarLista.class create mode 100644 target/classes/br/com/rjconsultores/auditador/annotations/AuditarMetodo.class create mode 100644 target/classes/br/com/rjconsultores/auditador/annotations/NaoAuditar.class create mode 100644 target/classes/br/com/rjconsultores/auditador/auditadores/Auditador.class create mode 100644 target/classes/br/com/rjconsultores/auditador/auditadores/AuditadorAtributo.class create mode 100644 target/classes/br/com/rjconsultores/auditador/auditadores/AuditadorEntidade.class create mode 100644 target/classes/br/com/rjconsultores/auditador/auditadores/AuditadorList.class create mode 100644 target/classes/br/com/rjconsultores/auditador/auditadores/ExtrairAnotacao.class create mode 100644 target/classes/br/com/rjconsultores/auditador/enums/AuditadorTipoAlteracao.class create mode 100644 target/classes/br/com/rjconsultores/auditador/enums/TipoExtracaoDados.class create mode 100644 target/classes/br/com/rjconsultores/auditador/exceptions/AuditadorException.class create mode 100644 target/classes/br/com/rjconsultores/auditador/interfaces/Auditavel.class create mode 100644 target/classes/br/com/rjconsultores/auditador/interfaces/AuditavelTelaAlternativa.class create mode 100644 target/classes/br/com/rjconsultores/auditador/model/AuditadorObjects.class create mode 100644 target/maven-archiver/pom.properties create mode 100644 target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst create mode 100644 target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst create mode 100644 target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..8d0718774 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +/.classpath +/.project +/.settings/org.eclipse.jdt.core.prefs +/.settings/org.eclipse.m2e.core.prefs +/.settings/org.eclipse.wst.common.component +/.settings/org.eclipse.wst.common.project.facet.core.xml +/.settings/org.eclipse.wst.validation.prefs diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..0a5a2e2cd --- /dev/null +++ b/pom.xml @@ -0,0 +1,32 @@ + + 4.0.0 + br.com.rjconsultores + Auditador + 0.0.1-SNAPSHOT + + + src/main/java + src/test/java + + + maven-compiler-plugin + 3.3 + + 1.6 + 1.6 + + + + ${project.artifactId} + + + + + commons-lang + commons-lang + 2.2 + + + \ No newline at end of file diff --git a/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarAtributo.java b/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarAtributo.java new file mode 100644 index 000000000..5fc1da175 --- /dev/null +++ b/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarAtributo.java @@ -0,0 +1,28 @@ +package br.com.rjconsultores.auditador.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Anotação utilizada para atributos. + * + * @author wilian + * + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface AuditarAtributo { + + /** + * Caso seja necessário colocar um nome amigável para o atributo, senão for informado o padrão será o nome do atributo da classe. + */ + String nome() default ""; + + /** + * Em caso de um atributo do tipo "DATE", informar o formato da data, valor padrão: "dd/MM/yyyy HH:mm" + */ + String pattern() default "dd/MM/yyyy HH:mm"; + +} diff --git a/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarClasse.java b/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarClasse.java new file mode 100644 index 000000000..a345677b7 --- /dev/null +++ b/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarClasse.java @@ -0,0 +1,35 @@ +package br.com.rjconsultores.auditador.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import br.com.rjconsultores.auditador.enums.TipoExtracaoDados; + +/** + * Anotação responsável por indicar que a classe será auditada. + * + * @author wilian + * + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface AuditarClasse { + + /** + * Caso seja necessário colocar um nome amigável para a classe, senão for informado o padrão será o nome da classe. + */ + String nome(); + + /** + * Atributo para indicar qual tela que o objeto será auditado. + */ + String tela(); + + /** + * Define se as informações serão extraídas pelo atributo ou metodo. + * @return + */ + TipoExtracaoDados tipoExtracaoDados() default TipoExtracaoDados.ATRIBUTO; +} diff --git a/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarEntidade.java b/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarEntidade.java new file mode 100644 index 000000000..636f0cd52 --- /dev/null +++ b/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarEntidade.java @@ -0,0 +1,20 @@ +package br.com.rjconsultores.auditador.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Anotação responsável que indicará que o atributo é uma entidade e seus atributos deverão ser auditados individualmente. + * + * @author wilian + * + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface AuditarEntidade { + + /** + * Caso seja necessário colocar um nome amigável para o atributo, senão for informado o padrão será o nome do atributo da classe. + */ + String nome() default ""; + +} diff --git a/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarID.java b/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarID.java new file mode 100644 index 000000000..6ebaa1ce9 --- /dev/null +++ b/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarID.java @@ -0,0 +1,18 @@ +package br.com.rjconsultores.auditador.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Anotação responsável para indicar qual o atributo que representa a chave primária da classe. + * + * @author wilian + * + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface AuditarID { + + String nome() default ""; + String pattern() default ""; + +} diff --git a/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarIDComposta.java b/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarIDComposta.java new file mode 100644 index 000000000..4ef8b5a18 --- /dev/null +++ b/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarIDComposta.java @@ -0,0 +1,15 @@ +package br.com.rjconsultores.auditador.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Anotação responsável para indicar qual o atributo que representa a chave primária composta da classe. + * + * @author wilian + * + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface AuditarIDComposta { + +} diff --git a/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarLista.java b/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarLista.java new file mode 100644 index 000000000..21f01c41d --- /dev/null +++ b/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarLista.java @@ -0,0 +1,26 @@ +package br.com.rjconsultores.auditador.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Anotação responsável para auditar o campos que são listas. + * + * @author wilian + * + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface AuditarLista { + + /** + * Caso seja necessário colocar um nome amigável para o atributo, senão for informado o padrão será o nome do atributo da classe. + */ + String nome() default ""; + + /** + * Indica que os atributos da lista são entidades e precisam ser auditados individualmente. O padrão é comparar apenas se os itens da lista foram removidos ou adicionados. + * @return + */ + boolean auditarEntidades() default false; + +} diff --git a/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarMetodo.java b/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarMetodo.java new file mode 100644 index 000000000..1058a377e --- /dev/null +++ b/src/main/java/br/com/rjconsultores/auditador/annotations/AuditarMetodo.java @@ -0,0 +1,28 @@ +package br.com.rjconsultores.auditador.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Anotação utilizada para methodos. + * + * @author wilian + * + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface AuditarMetodo { + + /** + * Caso seja necessário colocar um nome amigável para o atributo, senão for informado o padrão será o nome do atributo da classe. + */ + String nome() default ""; + + /** + * Em caso de um atributo do tipo "DATE", informar o formato da data, valor padrão: "dd/MM/yyyy HH:mm" + */ + String pattern() default "dd/MM/yyyy HH:mm"; + +} diff --git a/src/main/java/br/com/rjconsultores/auditador/annotations/NaoAuditar.java b/src/main/java/br/com/rjconsultores/auditador/annotations/NaoAuditar.java new file mode 100644 index 000000000..39d3e830a --- /dev/null +++ b/src/main/java/br/com/rjconsultores/auditador/annotations/NaoAuditar.java @@ -0,0 +1,15 @@ +package br.com.rjconsultores.auditador.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Anotação responsável para indicar que o atributo não deverá ser auditado, por padrão todos os atributos da classe são auditados. + * + * @author wilian + * + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface NaoAuditar { + +} diff --git a/src/main/java/br/com/rjconsultores/auditador/auditadores/Auditador.java b/src/main/java/br/com/rjconsultores/auditador/auditadores/Auditador.java new file mode 100644 index 000000000..c1ad89672 --- /dev/null +++ b/src/main/java/br/com/rjconsultores/auditador/auditadores/Auditador.java @@ -0,0 +1,628 @@ +package br.com.rjconsultores.auditador.auditadores; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.text.NumberFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import org.apache.commons.lang.StringUtils; + +import br.com.rjconsultores.auditador.annotations.AuditarAtributo; +import br.com.rjconsultores.auditador.annotations.AuditarClasse; +import br.com.rjconsultores.auditador.annotations.AuditarEntidade; +import br.com.rjconsultores.auditador.annotations.AuditarID; +import br.com.rjconsultores.auditador.annotations.AuditarIDComposta; +import br.com.rjconsultores.auditador.annotations.AuditarLista; +import br.com.rjconsultores.auditador.annotations.AuditarMetodo; +import br.com.rjconsultores.auditador.annotations.NaoAuditar; +import br.com.rjconsultores.auditador.enums.AuditadorTipoAlteracao; +import br.com.rjconsultores.auditador.enums.TipoExtracaoDados; +import br.com.rjconsultores.auditador.exceptions.AuditadorException; +import br.com.rjconsultores.auditador.interfaces.Auditavel; +import br.com.rjconsultores.auditador.interfaces.AuditavelTelaAlternativa; +import br.com.rjconsultores.auditador.model.AuditadorObjects; + +/** + * Classe responsável para listar as alterações do objeto. + * + * @author wilian + * + */ +public class Auditador { + + AuditadorAtributo auditadorAtributo; + AuditadorEntidade auditadorEntidade; + AuditadorList auditadorList; + ExtrairAnotacao extrairAnotacao; + + private AuditadorObjects padrao; + private TipoExtracaoDados tipoExtracaoDados; + + private Auditador() { + super(); + } + + public static Auditador getInstance( ) { + Auditador auditar = new Auditador(); + auditar.auditadorAtributo = new AuditadorAtributo(auditar); + auditar.auditadorEntidade = new AuditadorEntidade(auditar); + auditar.auditadorList = new AuditadorList(auditar); + auditar.extrairAnotacao = new ExtrairAnotacao(); + return auditar; + } + + /** + * Responsável por auditar os registros. + * + * @param original + * @param novo + * @param empresaId + * @return + */ + public List auditar(Object original, Object novo) { + List lsRetorno = new ArrayList(); + try { + + if(isObjetosNulos(original, novo) || !iniciarObjetoPadrao(novo != null ? novo : original, original == null ? AuditadorTipoAlteracao.INCLUSAO : AuditadorTipoAlteracao.ALTERACAO)) { + return lsRetorno; + } + + AuditadorObjects objectNovo = auditarObjetoNovo(null, original, novo); + if(objectNovo != null) { + lsRetorno.add(objectNovo); + return lsRetorno; + } + + lsRetorno.addAll(auditarCampos(original, novo, padrao.getClasseAlterada())); + return lsRetorno; + } catch (Exception e) { + throw new AuditadorException(e.getMessage(), e); + } catch (Throwable e) { + throw new AuditadorException(e.getMessage(), e); + } + } + + /** + * Responsável por auditar os registros filhos do objeto de referencia. + * + * @param objetoReferencia + * @param original + * @param novo + * @return + */ + public List auditar(Object objetoReferencia, Object original, Object novo) { + List lsRetorno = new ArrayList(); + try { + + if(!iniciarObjetoPadrao(objetoReferencia, AuditadorTipoAlteracao.ALTERACAO)) { + return lsRetorno; + } + + AuditadorObjects objectNovo = auditarObjetoNovo(null, original, novo); + if(objectNovo != null) { + lsRetorno.add(objectNovo); + return lsRetorno; + } + + lsRetorno.addAll(auditarCampos(original, novo, original != null ? original.getClass().getSimpleName() : novo.getClass().getSimpleName())); + return lsRetorno; + } catch (Exception e) { + throw new AuditadorException(e.getMessage(), e); + } catch (Throwable e) { + throw new AuditadorException(e.getMessage(), e); + } + } + + /** + * Responsável por auditar a lista quando a alteração acontece exclusivamente nos atributos lista do objeto + * + * @param objeto + * @param nomeCampoListAuditar + * @param original + * @param novo + * @return + */ + public List auditarList(Object objeto, String nomeCampoListAuditar, List original, List novo) { + List lsRetorno = new ArrayList(); + try { + if(!iniciarObjetoPadrao(objeto, AuditadorTipoAlteracao.ALTERACAO) || isObjetosNulos(original, novo)) { + return lsRetorno; + } + + Class classe = objeto.getClass(); + + List camposAuditaveis = extrairCamposAuditaveis(classe); + for (AccessibleObject campo : camposAuditaveis) { + campo.setAccessible(true); + String nome = extrairDeclaredNomeCampo(campo); + + if(!nome.equals(nomeCampoListAuditar)) { + continue; + } + + NaoAuditar naoAuditar = extrairAnotacao.extrairNaoAuditar(campo); + if(naoAuditar != null) { + continue; + } + + List lsOriginal = new ArrayList(); + if(original != null) { + lsOriginal.addAll(original); + } + + List lsNovo = new ArrayList(); + if(novo != null) { + lsNovo.addAll(novo); + } + + AuditarLista auditarLista = extrairAnotacao.extrairAuditarLista(campo); + lsRetorno.addAll(auditadorList.auditarList(campo, auditarLista != null ? auditarLista.auditarEntidades() : false, lsOriginal, lsNovo)); + + break; + } + } catch (Exception e) { + throw new AuditadorException(e.getMessage(), e); + } catch (Throwable e) { + throw new AuditadorException(e.getMessage(), e); + } + return lsRetorno; + } + + /** + * Responsável por auditar quando o objeto é excluído. + * + * @param objeto + * @param empresaId + * @return + */ + public List auditarExclusao(Object objeto) { + try { + List lsRetorno = new ArrayList(); + + if(isObjetosNulos(null, objeto) || !iniciarObjetoPadrao(objeto != null ? objeto : null, AuditadorTipoAlteracao.EXCLUSAO)) { + return lsRetorno; + } + + AuditadorObjects objetoExcluido = auditarObjetoExcluido(objeto); + if(objetoExcluido != null) { + lsRetorno.add(objetoExcluido); + } + + return lsRetorno; + } catch (Exception e) { + throw new AuditadorException(e.getMessage(), e); + } catch (Throwable e) { + throw new AuditadorException(e.getMessage(), e); + } + } + + /** + * Responsável por auditar quando o objeto sofre uma alteração personalizada. + * + * @param objeto + * @param valorNovo + * @param empresaId + * @return + */ + public List auditarPersonalizado(Object objeto, String valorNovo) { + try { + List lsRetorno = new ArrayList(); + + if(isObjetosNulos(null, objeto) || !iniciarObjetoPadrao(objeto != null ? objeto : null, AuditadorTipoAlteracao.ALTERACAO)) { + return lsRetorno; + } + + AuditadorObjects objetoAuditado = auditarObjetoPersonalizado(objeto, AuditadorTipoAlteracao.ALTERACAO, valorNovo); + if(objetoAuditado != null) { + lsRetorno.add(objetoAuditado); + } + + return lsRetorno; + } catch (Exception e) { + throw new AuditadorException(e.getMessage(), e); + } catch (Throwable e) { + throw new AuditadorException(e.getMessage(), e); + } + } + + protected AuditadorObjects auditarObjetoNovo(AccessibleObject campo, Object original, Object novo) throws CloneNotSupportedException { + if(original == null && novo != null) { + AuditadorObjects auditado = padrao.clonar(); + auditado.setValorNovo(String.format("Registro Criado [%s]", extrairTextoInclusaoExclusao(novo))); + auditado.setCampoAlterado(extrairNomeCampo(campo)); + return auditado; + } + return null; + } + + protected AuditadorObjects auditarObjetoPersonalizado(Object objeto, AuditadorTipoAlteracao tipoAlteracao, String valorNovo) throws CloneNotSupportedException { + if(objeto != null) { + AuditadorObjects auditado = padrao.clonar(); + auditado.setTipoAlteracao(tipoAlteracao != null ? tipoAlteracao : AuditadorTipoAlteracao.ALTERACAO); + auditado.setValorNovo(String.format("%s [%s]", valorNovo, extrairTextoInclusaoExclusao(objeto))); + return auditado; + } + return null; + } + + protected AuditadorObjects auditarObjetoExcluido(Object objeto) throws CloneNotSupportedException { + return auditarObjetoPersonalizado(objeto, AuditadorTipoAlteracao.EXCLUSAO, "Registro excluido"); + } + + protected AuditadorObjects auditarCampo(AccessibleObject campo, Object valorOriginal, Object valorNovo, String nomeClasse) throws CloneNotSupportedException { + if(isDiferente(valorOriginal, valorNovo)) { + String nomeCampo = extrairNomeCampo(campo); + AuditadorObjects auditado = padrao.clonar(); + auditado.setTipoAlteracao(AuditadorTipoAlteracao.ALTERACAO); + auditado.setCampoAlterado(nomeCampo); + auditado.setValorAnterior(valorOriginal != null ? valorOriginal.toString() : null); + auditado.setValorNovo(valorNovo != null ? valorNovo.toString() : null); + auditado.setClasseAlterada(nomeClasse); + return auditado; + } + return null; + } + + protected String extrairNomeClasse(Object original, Object novo) { + if(original != null) { + return original.getClass().getSimpleName(); + } + if(novo != null) { + return novo.getClass().getSimpleName(); + } + return null; + } + + protected String extrairNomeCampo(AccessibleObject campo) { + String nomeCampo = null; + if(campo != null) { + AuditarID auditarID = extrairAnotacao.extrairAuditarID(campo); + if(auditarID != null && StringUtils.isNotBlank(auditarID.nome())) { + nomeCampo = auditarID.nome(); + } + AuditarAtributo auditarAtributo = extrairAnotacao.extrairAuditarAtributo(campo); + if(auditarAtributo != null && StringUtils.isNotBlank(auditarAtributo.nome())) { + nomeCampo = auditarAtributo.nome(); + } + AuditarEntidade auditarEntidade = extrairAnotacao.extrairAuditarEntidade(campo); + if(auditarEntidade != null && StringUtils.isNotBlank(auditarEntidade.nome())) { + nomeCampo = auditarEntidade.nome(); + } + AuditarLista auditarLista = extrairAnotacao.extrairAuditarLista(campo); + if(auditarLista != null && StringUtils.isNotBlank(auditarLista.nome())) { + nomeCampo = auditarLista.nome(); + } + AuditarMetodo auditarMetodo = extrairAnotacao.extrairAuditarMetodo(campo); + if(auditarMetodo != null && StringUtils.isNotBlank(auditarMetodo.nome())) { + nomeCampo = auditarMetodo.nome(); + } + + if(StringUtils.isBlank(nomeCampo)) { + nomeCampo = extrairDeclaredNomeCampo(campo); + } + } + return nomeCampo; + } + + protected String extrairDeclaredNomeCampo(AccessibleObject campo) { + if(isExtrairDadosAtributo()) { + return ((Field) campo).getName(); + } if(isExtrairDadosMetodo()) { + return ((Method) campo).getName(); + } + return null; + } + + protected boolean isDiferente(Object valorOriginal, Object valorNovo) { + if(valorOriginal == null && valorNovo == null) { + return false; + } + + if(valorOriginal != null && valorNovo == null) { + return true; + } + + if(valorOriginal == null && valorNovo != null) { + return true; + } + + return !valorOriginal.equals(valorNovo); + } + + protected List auditarCampos(Object original, Object novo, String nomeClasse) throws IllegalArgumentException, IllegalAccessException { + List lsRetorno = new ArrayList(); + if(!isObjetosNulos(original, novo)) { + Class classe = original != null ? original.getClass() : novo.getClass(); + List camposAuditaveis = extrairCamposAuditaveis(classe); + for (AccessibleObject campo : camposAuditaveis) { + AuditarEntidade auditarEntidade = extrairAnotacao.extrairAuditarEntidade(campo); + AuditarLista auditarLista = extrairAnotacao.extrairAuditarLista(campo); + + if(auditarEntidade != null) { + lsRetorno.addAll(auditadorEntidade.auditar(campo, original, novo, null)); + } else if(auditarLista != null) { + lsRetorno.addAll(auditadorList.auditar(campo, original, novo, auditarLista.auditarEntidades())); + } else { + lsRetorno.addAll(auditadorAtributo.auditar(campo, original, novo, nomeClasse)); + } + } + } + return lsRetorno; + + } + + protected List extrairCamposAuditaveis(Class classe) { + List campo = new ArrayList(); + if(isExtrairDadosAtributo()) { + campo = extrairFields(classe); + } else if(isExtrairDadosMetodo()) { + campo = extrairMethods(classe); + } + return campo; + } + + protected List extrairMethods(Class classe) { + List campos = new ArrayList(); + Method[] methods = classe.getDeclaredMethods(); + for (Method method : methods) { + method.setAccessible(true); + + NaoAuditar naoAuditar = extrairAnotacao.extrairNaoAuditar(method); + if(naoAuditar != null) { + continue; + } + + if(!method.getReturnType().equals(Void.TYPE) && method.getParameterTypes().length == 0 && + !isMethodIgnorado(method)) { + campos.add(method); + } + } + return campos; + } + + private boolean isMethodIgnorado(Method method) { + return method.getName().equalsIgnoreCase("clone") || + method.getName().equalsIgnoreCase("clonar") || + method.getName().equalsIgnoreCase("getCloneObject") || + method.getName().equalsIgnoreCase("hashCode") || + method.getName().equalsIgnoreCase("equals"); + } + + protected List extrairFields(Class classe) { + List campos = new ArrayList(); + Field[] fields = classe.getDeclaredFields(); + for (Field field : fields) { + field.setAccessible(true); + + NaoAuditar naoAuditar = extrairAnotacao.extrairNaoAuditar(field); + if(naoAuditar != null) { + continue; + } + + campos.add(field); + } + return campos; + } + + protected Object getValor(AccessibleObject campo, Object object) throws IllegalArgumentException, IllegalAccessException, ParseException, InvocationTargetException { + return getValor(campo, object, null); + } + + protected Object getValor(AccessibleObject campo, Object object, String pattern) throws IllegalArgumentException, IllegalAccessException, ParseException, InvocationTargetException { + if(campo == null || object == null) { + return null; + } + Object retorno = extrairValor(campo, object); + + Object atributo = null; + if (retorno instanceof Date) { + Date aux = (Date) retorno; + + atributo = getStringDate(aux, pattern); + } else if (retorno instanceof Integer || retorno instanceof Long ) { + atributo = retorno.toString(); + } else if (retorno instanceof Number) { + atributo = getValorFormatado(retorno.toString()); + } else if(retorno instanceof String) { + atributo = StringUtils.isNotBlank(retorno.toString()) ? retorno.toString() : "nulo"; + } else { + return retorno; + } + return atributo; + + } + + protected String getValorFormatado(String value) throws ParseException { + + if(value != null && StringUtils.isNotBlank(value)) { + NumberFormat nf = NumberFormat.getInstance(new Locale("pt", "br")); + BigDecimal valor = new BigDecimal(nf.parse(value.replace(".", ",")).toString()); + + return nf.format(valor.doubleValue()); + } + + return null; + } + + protected String getStringDate(java.util.Date d, String pattern) { + if(StringUtils.isBlank(pattern)) { + pattern = "dd/MM/yyyy HH:mm"; + } + + SimpleDateFormat sdf = new SimpleDateFormat(pattern); + if (d != null) { + return sdf.format(d); + } + return null; + } + + @SuppressWarnings("unchecked") + protected List getValorList(AccessibleObject campo, Object object) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { + if(campo == null || object == null) { + return new ArrayList(); + } + Object aux = extrairValor(campo, object); + + List retorno = new ArrayList(); + if(aux != null && aux instanceof Collection) { + retorno.addAll((Collection) aux); + } + + return retorno; + } + + protected boolean isObjetosNulos(Object original, Object novo) { + return novo == null && original == null; + } + + protected boolean isObjetoNovo(Object original, Object novo) { + return novo != null && original == null; + } + + protected boolean iniciarObjetoPadrao(Object objeto, AuditadorTipoAlteracao tipoAlteracao) throws IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchFieldException, ParseException, NoSuchMethodException, InvocationTargetException { + padrao = null; + Class classe = objeto.getClass(); + AuditarClasse auditarClasse = extrairAnotacao.extrair(classe); + if(auditarClasse != null) { + tipoExtracaoDados = auditarClasse.tipoExtracaoDados(); + padrao = new AuditadorObjects(); + padrao.setTipoAlteracao(tipoAlteracao); + padrao.setTela(getNomeTela(auditarClasse, objeto)); + padrao.setIdAuditado(getIdEntidade(objeto)); + padrao.setClassePrincipal(StringUtils.isNotBlank(auditarClasse.nome()) ? auditarClasse.nome() : classe.getSimpleName()); + + } + return padrao != null; + } + + protected String getNomeTela(AuditarClasse auditarClasse, Object objeto) { + if(objeto instanceof AuditavelTelaAlternativa) { + AuditavelTelaAlternativa aux = (AuditavelTelaAlternativa) objeto; + if(aux != null && StringUtils.isNotBlank(aux.getTelaAlternativa())) { + return aux.getTelaAlternativa(); + } + } + return auditarClasse.tela(); + } + + protected String getIdEntidade(Object objeto) throws IllegalArgumentException, IllegalAccessException, ParseException, InvocationTargetException { + Object valor = null; + Class classe = objeto.getClass(); + List camposAuditaveis = extrairCamposAuditaveis(classe); + for (AccessibleObject campo : camposAuditaveis) { + campo.setAccessible(true); + AuditarID auditarID = extrairAnotacao.extrairAuditarID(campo); + if(auditarID != null) { + valor = getValor(campo, objeto, auditarID.pattern()); + } + + if(valor == null) { + AuditarIDComposta auditarIDComposta = extrairAnotacao.extrairAuditarIDComposta(campo); + if(auditarIDComposta != null) { + valor = getIdEntidadeComposta(campo, objeto); + } + } + + } + return valor != null ? valor.toString() : null; + } + + protected Object getIdEntidadeComposta(AccessibleObject campo, Object objeto) throws IllegalArgumentException, IllegalAccessException, ParseException, InvocationTargetException { + StringBuilder sb = new StringBuilder(); + if(campo != null && objeto != null) { + Object valorID = extrairValor(campo, objeto); + if(valorID != null) { + Class classe = valorID.getClass(); + List camposAuditaveis = extrairCamposAuditaveis(classe); + for (AccessibleObject campoId : camposAuditaveis) { + campoId.setAccessible(true); + AuditarID auditarID = extrairAnotacao.extrairAuditarID(campoId); + if(auditarID != null) { + Object valor = getValor(campoId, valorID, auditarID.pattern()); + if(valor != null) { + if(sb.length() > 0) { + sb.append("-"); + } + sb.append(valor.toString()); + } + } + } + } + } + return sb.length() > 0 ? sb.toString() : null; + } + + protected AuditadorObjects getPadrao() { + try { + return padrao.clonar(); + } catch (Exception e) { + throw new AuditadorException("Não foi possível clonar o objeto padrão", e); + } + } + + protected String extrairTextoInclusaoExclusao(Object objeto) { + if(objeto instanceof Auditavel) { + Auditavel auditavelAux = (Auditavel) objeto; + return auditavelAux.getTextoInclusaoExclusao(); + } + return ""; + } + + protected Object extrairValor(AccessibleObject campo, Object object) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { + if(isExtrairDadosAtributo()) { + return ((Field) campo).get(object); + } else if(isExtrairDadosMetodo()) { + return ((Method) campo).invoke(object); + } + return null; + } + + protected boolean isExtrairDadosAtributo() { + return TipoExtracaoDados.ATRIBUTO.equals(tipoExtracaoDados); + } + + protected boolean isExtrairDadosMetodo() { + return TipoExtracaoDados.METODO.equals(tipoExtracaoDados); + } + + protected String extrairPattern(AccessibleObject campoEntidade) { + String pattern = null; + if(isExtrairDadosAtributo()) { + AuditarAtributo auditarAtributo = extrairAnotacao.extrairAuditarAtributo(campoEntidade); + if(auditarAtributo != null) { + pattern = auditarAtributo.pattern(); + } + } else if(isExtrairDadosMetodo()) { + AuditarMetodo auditarMetodo = extrairAnotacao.extrairAuditarMetodo(campoEntidade); + if(auditarMetodo != null) { + pattern = auditarMetodo.pattern(); + } + } + return pattern; + } + + protected AccessibleObject extrairAccessibleObject(Object objeto, String nome) throws SecurityException, NoSuchFieldException, NoSuchMethodException { + if(objeto != null && StringUtils.isNotBlank(nome)) { + Class classe = objeto.getClass(); + if(isExtrairDadosAtributo()) { + Field field = classe.getDeclaredField(nome); + return field; + } else if(isExtrairDadosMetodo()) { + Method method = classe.getDeclaredMethod(nome); + return method; + } + + } + return null; + } + +} diff --git a/src/main/java/br/com/rjconsultores/auditador/auditadores/AuditadorAtributo.java b/src/main/java/br/com/rjconsultores/auditador/auditadores/AuditadorAtributo.java new file mode 100644 index 000000000..153c16adb --- /dev/null +++ b/src/main/java/br/com/rjconsultores/auditador/auditadores/AuditadorAtributo.java @@ -0,0 +1,42 @@ +package br.com.rjconsultores.auditador.auditadores; + +import java.lang.reflect.AccessibleObject; +import java.util.ArrayList; +import java.util.List; + +import br.com.rjconsultores.auditador.exceptions.AuditadorException; +import br.com.rjconsultores.auditador.model.AuditadorObjects; + +class AuditadorAtributo { + + protected Auditador auditador; + + public AuditadorAtributo(Auditador auditar) { + super(); + this.auditador = auditar; + } + + public List auditar(AccessibleObject campo, Object original, Object novo, String nomeClasse) { + List lsRetorno = new ArrayList(); + try { + + if(!auditador.isObjetosNulos(original, novo)) { + String pattern = auditador.extrairPattern(campo); + + Object valorOriginal = auditador.getValor(campo, original, pattern); + Object valorNovo = auditador.getValor(campo, novo, pattern); + AuditadorObjects auditado = auditador.auditarCampo(campo, valorOriginal, valorNovo, nomeClasse); + if(auditado != null) { + lsRetorno.add(auditado); + } + } + + } catch (Exception e) { + throw new AuditadorException(e.getMessage(), e); + } catch (Throwable e) { + throw new AuditadorException(e.getMessage(), e); + } + return lsRetorno; + } + +} diff --git a/src/main/java/br/com/rjconsultores/auditador/auditadores/AuditadorEntidade.java b/src/main/java/br/com/rjconsultores/auditador/auditadores/AuditadorEntidade.java new file mode 100644 index 000000000..a2e5dc48b --- /dev/null +++ b/src/main/java/br/com/rjconsultores/auditador/auditadores/AuditadorEntidade.java @@ -0,0 +1,76 @@ +package br.com.rjconsultores.auditador.auditadores; + +import java.lang.reflect.AccessibleObject; +import java.util.ArrayList; +import java.util.List; + +import br.com.rjconsultores.auditador.exceptions.AuditadorException; +import br.com.rjconsultores.auditador.model.AuditadorObjects; + +class AuditadorEntidade { + + protected Auditador auditador; + + public AuditadorEntidade(Auditador auditar) { + super(); + this.auditador = auditar; + } + + public List auditar(AccessibleObject campo, Object original, Object novo, String nomeClasse) { + List lsRetorno = new ArrayList(); + try { + Object valorOriginal = campo != null && original != null ? auditador.extrairValor(campo, original) : original; + Object valorNovo = campo != null && novo != null ? auditador.extrairValor(campo, novo) : novo; + + String localNomeClasse = nomeClasse != null ? nomeClasse : auditador.extrairNomeClasse(valorOriginal, valorNovo); + + AuditadorObjects objectNovo = auditador.auditarObjetoNovo(campo, valorOriginal, valorNovo); + if(objectNovo != null) { + lsRetorno.add(objectNovo); + return lsRetorno; + } + + if(!auditador.isObjetosNulos(valorOriginal, valorNovo)) { + Class classe = valorOriginal != null ? valorOriginal.getClass() : valorNovo.getClass(); + List camposAuditaveis = auditador.extrairCamposAuditaveis(classe); + for (AccessibleObject campoEntidade : camposAuditaveis) { + String pattern = auditador.extrairPattern(campoEntidade); + + Object valorOriginalEntidade = auditador.getValor(campoEntidade, valorOriginal, pattern); + Object valorNovoEntidade = auditador.getValor(campoEntidade, valorNovo, pattern); + + AuditadorObjects auditado = auditador.auditarCampo(campoEntidade, valorOriginalEntidade, valorNovoEntidade, localNomeClasse); + if(auditado != null) { + lsRetorno.add(auditado); + } + } +// Field[] campos = classe.getDeclaredFields(); +// for (Field campoEntidade : campos) { +// campoEntidade.setAccessible(true); +// +// NaoAuditar naoAuditar = auditador.extrairAnotacao.extrairNaoAuditar(campoEntidade); +// if(naoAuditar != null) { +// continue; +// } +// +// AuditarAtributo auditarAtributo = auditador.extrairAnotacao.extrairAuditarAtributo(campoEntidade); +// String pattern = auditarAtributo != null && StringUtils.isNotBlank(auditarAtributo.pattern()) ? auditarAtributo.pattern() : null; +// +// Object valorOriginalEntidade = auditador.getValor(campoEntidade, valorOriginal, pattern); +// Object valorNovoEntidade = auditador.getValor(campoEntidade, valorNovo, pattern); +// +// AuditadorObjects auditado = auditador.auditarCampo(campoEntidade, valorOriginalEntidade, valorNovoEntidade, localNomeClasse); +// if(auditado != null) { +// lsRetorno.add(auditado); +// } +// } + } + } catch (Exception e) { + throw new AuditadorException(e.getMessage(), e); + } catch (Throwable e) { + throw new AuditadorException(e.getMessage(), e); + } + return lsRetorno; + } + +} diff --git a/src/main/java/br/com/rjconsultores/auditador/auditadores/AuditadorList.java b/src/main/java/br/com/rjconsultores/auditador/auditadores/AuditadorList.java new file mode 100644 index 000000000..86daf1ab0 --- /dev/null +++ b/src/main/java/br/com/rjconsultores/auditador/auditadores/AuditadorList.java @@ -0,0 +1,131 @@ +package br.com.rjconsultores.auditador.auditadores; + +import java.lang.reflect.AccessibleObject; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import br.com.rjconsultores.auditador.enums.AuditadorTipoAlteracao; +import br.com.rjconsultores.auditador.exceptions.AuditadorException; +import br.com.rjconsultores.auditador.model.AuditadorObjects; + +class AuditadorList { + + protected Auditador auditador; + + public AuditadorList(Auditador auditar) { + super(); + this.auditador = auditar; + } + + public List auditar(AccessibleObject campo, Object original, Object novo, boolean auditarEntidades) { + List lsRetorno = new ArrayList(); + try { + + List lsOriginal = auditador.getValorList(campo, original); + List lsNovo = auditador.getValorList(campo, novo); + + lsRetorno.addAll(auditarList(campo, auditarEntidades, lsOriginal, lsNovo)); + } catch (Exception e) { + throw new AuditadorException(e.getMessage(), e); + } catch (Throwable e) { + throw new AuditadorException(e.getMessage(), e); + } + return lsRetorno; + } + + public List auditarList(AccessibleObject campo, boolean auditarEntidades, + List lsOriginal, List lsNovo) throws CloneNotSupportedException { + List lsRetorno = new ArrayList(); + + List lsObjetosInseridos = new ArrayList(0); + List lsObjetosRemovidos = new ArrayList(0); + List lsObjetosMantidos = new ArrayList(0); + + if(lsNovo != null) { + lsObjetosInseridos.addAll(lsNovo); + if(lsOriginal != null) { + lsObjetosInseridos.removeAll(lsOriginal); + } + lsRetorno.addAll(auditarRegistros(campo, lsObjetosInseridos, true)); + + if(auditarEntidades) { + lsObjetosMantidos.addAll(lsNovo); + } + } + + if(lsOriginal != null) { + lsObjetosRemovidos.addAll(lsOriginal); + if(lsNovo != null) { + lsObjetosRemovidos.removeAll(lsNovo); + } + lsRetorno.addAll(auditarRegistros(campo, lsObjetosRemovidos, false)); + + if(auditarEntidades) { + lsObjetosMantidos.retainAll(lsOriginal); + } + } + + if(auditarEntidades) { + for (Object object : lsObjetosMantidos) { + Object originalEntidade = lsOriginal.get(lsOriginal.indexOf(object)); + Object novoEntidade = lsNovo.get(lsNovo.indexOf(object)); + String nomeClasse = auditador.extrairNomeClasse(originalEntidade, novoEntidade); + + lsRetorno.addAll(auditador.auditadorEntidade.auditar(null, originalEntidade, novoEntidade, nomeClasse)); + } + } + return lsRetorno; + } + + protected List auditarRegistros(AccessibleObject campo, List lsObjetosRemovidos, boolean inserido) + throws CloneNotSupportedException { + List lsRetorno = new ArrayList(); + String nomeCampo = auditador.extrairNomeCampo(campo); + for (Object removido : lsObjetosRemovidos) { + AuditadorObjects objectInserido = null; + + if(inserido) { + objectInserido = auditarObjetoInserido(nomeCampo, removido); + } else { + objectInserido = auditarObjetoRemovido(nomeCampo, removido); + } + + if(objectInserido != null) { + lsRetorno.add(objectInserido); + } + } + return lsRetorno; + } + + protected boolean isObjetosList(Object objeto) { + return objeto != null && objeto instanceof Collection; + } + + protected AuditadorObjects auditarObjetoInserido(String nomeCampo, Object objeto) throws CloneNotSupportedException { + if(objeto != null) { + AuditadorObjects auditado = criarObjetoInseridoRemovido(nomeCampo, objeto); + auditado.setValorNovo(String.format("Registro inserido [%s]", auditador.extrairTextoInclusaoExclusao(objeto))); + return auditado; + } + return null; + } + + private AuditadorObjects criarObjetoInseridoRemovido(String nomeCampo, Object objeto) throws CloneNotSupportedException { + AuditadorObjects auditado = auditador.getPadrao().clonar(); + auditado.setTipoAlteracao(AuditadorTipoAlteracao.ALTERACAO); + auditado.setCampoAlterado(nomeCampo); + auditado.setClasseAlterada(objeto.getClass().getSimpleName()); + return auditado; + } + + protected AuditadorObjects auditarObjetoRemovido(String nomeCampo, Object objeto) throws CloneNotSupportedException { + if(objeto != null) { + AuditadorObjects auditado = criarObjetoInseridoRemovido(nomeCampo, objeto); + auditado.setValorNovo(String.format("Registro removido [%s]", auditador.extrairTextoInclusaoExclusao(objeto))); + return auditado; + } + return null; + } + +} diff --git a/src/main/java/br/com/rjconsultores/auditador/auditadores/ExtrairAnotacao.java b/src/main/java/br/com/rjconsultores/auditador/auditadores/ExtrairAnotacao.java new file mode 100644 index 000000000..934516d20 --- /dev/null +++ b/src/main/java/br/com/rjconsultores/auditador/auditadores/ExtrairAnotacao.java @@ -0,0 +1,79 @@ +package br.com.rjconsultores.auditador.auditadores; + +import java.lang.reflect.AccessibleObject; + +import br.com.rjconsultores.auditador.annotations.AuditarAtributo; +import br.com.rjconsultores.auditador.annotations.AuditarClasse; +import br.com.rjconsultores.auditador.annotations.AuditarEntidade; +import br.com.rjconsultores.auditador.annotations.AuditarID; +import br.com.rjconsultores.auditador.annotations.AuditarIDComposta; +import br.com.rjconsultores.auditador.annotations.AuditarLista; +import br.com.rjconsultores.auditador.annotations.AuditarMetodo; +import br.com.rjconsultores.auditador.annotations.NaoAuditar; + +class ExtrairAnotacao { + + protected AuditarClasse extrair(Class classe) { + if(classe == null) { + return null; + } + return classe.getAnnotation(AuditarClasse.class); + } + + protected AuditarAtributo extrairAuditarAtributo(AccessibleObject campo) { + if(campo == null) { + return null; + } + campo.setAccessible(true); + return campo.getAnnotation(AuditarAtributo.class); + } + + protected AuditarEntidade extrairAuditarEntidade(AccessibleObject campo) { + if(campo == null) { + return null; + } + campo.setAccessible(true); + return campo.getAnnotation(AuditarEntidade.class); + } + + protected AuditarID extrairAuditarID(AccessibleObject campo) { + if(campo == null) { + return null; + } + campo.setAccessible(true); + return campo.getAnnotation(AuditarID.class); + } + + protected AuditarIDComposta extrairAuditarIDComposta(AccessibleObject campo) { + if(campo == null) { + return null; + } + campo.setAccessible(true); + return campo.getAnnotation(AuditarIDComposta.class); + } + + protected AuditarLista extrairAuditarLista(AccessibleObject campo) { + if(campo == null) { + return null; + } + campo.setAccessible(true); + return campo.getAnnotation(AuditarLista.class); + } + + protected NaoAuditar extrairNaoAuditar(AccessibleObject campo) { + if(campo == null) { + return null; + } + campo.setAccessible(true); + return campo.getAnnotation(NaoAuditar.class); + } + + protected AuditarMetodo extrairAuditarMetodo(AccessibleObject campo) { + if(campo == null) { + return null; + } + campo.setAccessible(true); + return campo.getAnnotation(AuditarMetodo.class); + } + +} diff --git a/src/main/java/br/com/rjconsultores/auditador/enums/AuditadorTipoAlteracao.java b/src/main/java/br/com/rjconsultores/auditador/enums/AuditadorTipoAlteracao.java new file mode 100644 index 000000000..136a162e8 --- /dev/null +++ b/src/main/java/br/com/rjconsultores/auditador/enums/AuditadorTipoAlteracao.java @@ -0,0 +1,16 @@ +package br.com.rjconsultores.auditador.enums; + +import java.util.Arrays; +import java.util.List; + +public enum AuditadorTipoAlteracao { + + INCLUSAO, + ALTERACAO, + EXCLUSAO; + + public static List getList() { + return Arrays.asList(values()); + } + +} diff --git a/src/main/java/br/com/rjconsultores/auditador/enums/TipoExtracaoDados.java b/src/main/java/br/com/rjconsultores/auditador/enums/TipoExtracaoDados.java new file mode 100644 index 000000000..c80d1d2e5 --- /dev/null +++ b/src/main/java/br/com/rjconsultores/auditador/enums/TipoExtracaoDados.java @@ -0,0 +1,8 @@ +package br.com.rjconsultores.auditador.enums; + +public enum TipoExtracaoDados { + + ATRIBUTO, + METODO; + +} diff --git a/src/main/java/br/com/rjconsultores/auditador/exceptions/AuditadorException.java b/src/main/java/br/com/rjconsultores/auditador/exceptions/AuditadorException.java new file mode 100644 index 000000000..4dc50b532 --- /dev/null +++ b/src/main/java/br/com/rjconsultores/auditador/exceptions/AuditadorException.java @@ -0,0 +1,11 @@ +package br.com.rjconsultores.auditador.exceptions; + +public class AuditadorException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public AuditadorException(String message, Throwable throwable) { + super(message, throwable); + } + +} diff --git a/src/main/java/br/com/rjconsultores/auditador/interfaces/Auditavel.java b/src/main/java/br/com/rjconsultores/auditador/interfaces/Auditavel.java new file mode 100644 index 000000000..4cd59606f --- /dev/null +++ b/src/main/java/br/com/rjconsultores/auditador/interfaces/Auditavel.java @@ -0,0 +1,33 @@ +package br.com.rjconsultores.auditador.interfaces; + +/** + * Interface que deverá ser implementada quando o objeto for auditado, interface estende a interface Cloneable. + * + * @author wilian + * + * @param + */ +public interface Auditavel extends Cloneable { + + /** + * Método deverá ser implementado com o recurso de clonagem da Interface Cloneable. Executa o processo de clonagem do objeto para ser comparado com o alterado, executar esse método logo após recuperar o objeto do banco de dados. + * + * @throws CloneNotSupportedException + */ + public void clonar() throws CloneNotSupportedException; + + /** + * Após executar o método "clonar" retorna o objeto clonado. + * + * @return + * @throws CloneNotSupportedException + */ + public T getCloneObject() throws CloneNotSupportedException; + + /** + * Método que descreve informações do objeto quando o registro é criado/incluído/excluído. + * @return + */ + public String getTextoInclusaoExclusao(); + +} diff --git a/src/main/java/br/com/rjconsultores/auditador/interfaces/AuditavelTelaAlternativa.java b/src/main/java/br/com/rjconsultores/auditador/interfaces/AuditavelTelaAlternativa.java new file mode 100644 index 000000000..110767331 --- /dev/null +++ b/src/main/java/br/com/rjconsultores/auditador/interfaces/AuditavelTelaAlternativa.java @@ -0,0 +1,18 @@ +package br.com.rjconsultores.auditador.interfaces; + +/** + * Interface que permite informar uma tela alternativa para auditoria do objeto quando o mesmo é alterado em telas diferentes. + * + * @author wilian + * + */ +public interface AuditavelTelaAlternativa { + + /** + * Quando o objeto auditado implementar a interface, o valor do retorno desse método será priorizado. + * + * @return + */ + public String getTelaAlternativa(); + +} diff --git a/src/main/java/br/com/rjconsultores/auditador/model/AuditadorObjects.java b/src/main/java/br/com/rjconsultores/auditador/model/AuditadorObjects.java new file mode 100644 index 000000000..ce4bacab3 --- /dev/null +++ b/src/main/java/br/com/rjconsultores/auditador/model/AuditadorObjects.java @@ -0,0 +1,97 @@ +package br.com.rjconsultores.auditador.model; + +import br.com.rjconsultores.auditador.enums.AuditadorTipoAlteracao; + +public class AuditadorObjects implements Cloneable { + + private String valorAnterior; + private String valorNovo; + private String campoAlterado; + private String classeAlterada; + private String classePrincipal; + private String tela; + private AuditadorTipoAlteracao tipoAlteracao; + private String idAuditado; + + public String getValorAnterior() { + return valorAnterior; + } + + public void setValorAnterior(String valorAnterior) { + this.valorAnterior = valorAnterior; + } + + public String getValorNovo() { + return valorNovo; + } + + public void setValorNovo(String valorNovo) { + this.valorNovo = valorNovo; + } + + public String getCampoAlterado() { + return campoAlterado; + } + + public void setCampoAlterado(String campoAlterado) { + this.campoAlterado = campoAlterado; + } + + public String getClasseAlterada() { + return classeAlterada; + } + + public void setClasseAlterada(String classeAlterada) { + this.classeAlterada = classeAlterada; + } + + public String getClassePrincipal() { + return classePrincipal; + } + + public void setClassePrincipal(String classePrincipal) { + this.classePrincipal = classePrincipal; + } + + public String getTela() { + return tela; + } + + public void setTela(String tela) { + this.tela = tela; + } + + public AuditadorTipoAlteracao getTipoAlteracao() { + return tipoAlteracao; + } + + public void setTipoAlteracao(AuditadorTipoAlteracao tipoAlteracao) { + this.tipoAlteracao = tipoAlteracao; + } + + public String getIdAuditado() { + return idAuditado; + } + + public void setIdAuditado(String idAuditado) { + this.idAuditado = idAuditado; + } + + @Override + protected Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + public AuditadorObjects clonar() throws CloneNotSupportedException { + return (AuditadorObjects) this.clone(); + } + + @Override + public String toString() { + return "AuditadorObjects [valorAnterior=" + valorAnterior + ", valorNovo=" + valorNovo + ", campoAlterado=" + + campoAlterado + ", classeAlterada=" + classeAlterada + ", classePrincipal=" + classePrincipal + + ", tela=" + tela + ", tipoAlteracao=" + tipoAlteracao + ", idAuditado=" + + idAuditado + "]"; + } + +} diff --git a/target/Auditador.jar b/target/Auditador.jar new file mode 100644 index 0000000000000000000000000000000000000000..50ba2d7cbb34bf6844d2162ad8d085baddcc449b GIT binary patch literal 27952 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 + 4.0.0 + br.com.rjconsultores + Auditador + 0.0.1-SNAPSHOT + + + src/main/java + src/test/java + + + maven-compiler-plugin + 3.3 + + 1.6 + 1.6 + + + + ${project.artifactId} + + + + + commons-lang + commons-lang + 2.2 + + + \ No newline at end of file diff --git a/target/classes/br/com/rjconsultores/auditador/annotations/AuditarAtributo.class b/target/classes/br/com/rjconsultores/auditador/annotations/AuditarAtributo.class new file mode 100644 index 0000000000000000000000000000000000000000..3e4eba5059e54a2c02fccdad7068e2bcd908b5ac GIT binary patch literal 541 zcmaix%}N6?6opUv<7oYBwJIWFaUr@f;Igg?ZE2xZX{#GonVDEpW|ET06#8l|d;lLx zyyL%Qr!>7{K7og>%wsY8!@pIOI!Ojb5)A#|)LRNo^pzD$0ESWWCLrFr1E3?NlsZ zRHFPy=3Nqo^OYbgp(nylrK3#cg@{tJzFg0BA{k5VCd;|Z;BLP&Xfrg{!z1a4rJ)jf z^$+r7A{8tN^hVDQlm4)C#b^{o+GYC30{wx9O{%u2Dki9qu)Qkmpn%6?j}mJ{ zY!yN95Gqyms(7!eUS6M`0c>F*LP=n|?PcOp>AQ)uS#E;!lu4D}>Y#3&m&#ffRM4E1 zjrXYEH!900LPcP*tL~LF%68;gyGu!kFd(p8M2m9S`0ON5u`VTn`ufIkfxQS`+s-a$ z0~sYy3%ci;55cQMxdUdC3G8siAB@T7X(r>JwcNK>P&lAF#bR0i|Jw~V;?~jLWqc+u zeBpAR(4jW0YU9(PQ35#0#GK4P!i#~$^E7hj(@1y+8?wkR-^x5>!0KOpDM=;V=sQS0(FK00Zx2?&(=Rr!F*y#5G- u=%2yRhaJWUXGb|(C5&MlB}}kW!X#>J7x_2Efax0uLLD=h?R$hd%)bGU#l;W+ literal 0 HcmV?d00001 diff --git a/target/classes/br/com/rjconsultores/auditador/annotations/AuditarEntidade.class b/target/classes/br/com/rjconsultores/auditador/annotations/AuditarEntidade.class new file mode 100644 index 0000000000000000000000000000000000000000..b6ef27c5b57aec30ab7680204d068c4e5cace06b GIT binary patch literal 404 zcmah_yH3ME5S+~eLm-eK8Y-wFXgG-ysz?M0iI*IpKif-m*7;64pCj>W6np?5h1gKw zh=yXdubJ7=etx}w0652ff)3##3o7@O3T5tH-Pq^@*Ge~qiMsGXY3F>@(a2Iwf2LvP zqA7I233`N4sh3(=?H1}GD>;t|HV8-Uv=va(UoAq<`HBe#C#Sb9b{>Oqi%Y_|gxE(?0vV$EAB@bn_E3wBIVf+oZ C$#gdW literal 0 HcmV?d00001 diff --git a/target/classes/br/com/rjconsultores/auditador/annotations/AuditarID.class b/target/classes/br/com/rjconsultores/auditador/annotations/AuditarID.class new file mode 100644 index 0000000000000000000000000000000000000000..929626e7abc1c6419ca603a23d2810008f99420c GIT binary patch literal 419 zcmah_yG{c!5S+~eLm(jm8Y-wFXt0FnQbh_#k$C9>^uCLUeDc}I=ZnOzQSbqL6k z3l+s`wX-v`qy75+_yll?LxBe2Dh)F8g$#M-U0K=agD$12<|eAS4^lbjql$)?a{P;i z=|rGK=;vywq*ZPqAJSZBQDBR3Qlqt0j@K@Pmh*)s9G#ut*4$YP#w|vKK~0_LSH*z{ zAc!{=qYjSHnfWSY`o>r`>8&GOth@-vN#&v`^ouD?YISW^5>7YnZDdPy)U5H2ueX=V zR_r_chx+KP$=+EYlIQ!U>D~2^IAoKn&A)B%cLcV1+Tp2LqQk)M9{>&Pt(fSd$Gywk KeXhR700%$47IL}( literal 0 HcmV?d00001 diff --git a/target/classes/br/com/rjconsultores/auditador/annotations/AuditarIDComposta.class b/target/classes/br/com/rjconsultores/auditador/annotations/AuditarIDComposta.class new file mode 100644 index 0000000000000000000000000000000000000000..91e85f8b9bfc48ff26e6720fdf6061a2f72eeecc GIT binary patch literal 338 zcmaiwy-Gtt5QWbq#?@%VO0d!@r3<#&1b-l4RIbr}?`Dy`?A?+53HWLjK7bDuTvOy0 z3KnMu&dm7+=46Cw!4|QX764)l3bZ&=`lMRh9eBvCmxwXy^j()MvegK5yD*I$x z^J1f|o#_CPaC-OWk;)`fGVCu1gQar0@W=nGKC-j=y#z${d_SMgZpH*czi3dN1@s`+ RbqBkpkBUDm+B4Y4=o_DTWjO!< literal 0 HcmV?d00001 diff --git a/target/classes/br/com/rjconsultores/auditador/annotations/AuditarLista.class b/target/classes/br/com/rjconsultores/auditador/annotations/AuditarLista.class new file mode 100644 index 0000000000000000000000000000000000000000..33d9d983bac0b88139920d85f4be0716298d33d9 GIT binary patch literal 445 zcmaiwy-ve06orqQmO!DbAZ>+g+H-rt(@96dW~4&o?U=PU4CNOZlvvN(x!; zpq#S?MguvPUeb)w1l3uKqN3>GKh_6RsPvTv!uaX#@#c0mWJDLx=@4g&J}tyHRXbD# e4qXyQ+>YbzYvY7d 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 PVO~Ql!)lLUMeY4RHkyfX literal 0 HcmV?d00001 diff --git a/target/classes/br/com/rjconsultores/auditador/auditadores/AuditadorAtributo.class b/target/classes/br/com/rjconsultores/auditador/auditadores/AuditadorAtributo.class new file mode 100644 index 0000000000000000000000000000000000000000..dc4ff5f819d339a57bb8f41d64df37c6555bf063 GIT binary patch literal 2563 zcmcgt-%}e^6#i}q*(7WVw)|*nE46?S2#sP(OM+;`R?!f!!4#@}Si+hvU3N3O8`?VK z4F5yle0O}+nF^zw(KjFbqtx$iel1m`6K9-BcF#F`?m72-=iKl9{>RV10GPu)1tEdO zZ6{N)_cG3I#kSnK>Di9%X0-Z_;b}Xz(~)S+x2$>3F}CZTtspEgu&eEB8B?>WnYHa* zz2XVP+Uo`83*BVM2}BkR%kY*27N)ujktz#>m+c)rjvn->P@oF*Or^>(2%J&Ti-97F0&W7vCOxB^RE?W6@4i&7fMI0EKWp#z+we`ylA zOukalUDsgV29&vg&&ya!Y>ZXSr5elXo?&JRhU+nLtYlOz&8s`C@Z0|}_2OxW?Xf{- zXS5nsy1AvCg7X6Be2n};@{XfDk=4X8g1$Ij#U%w71+H~7Un*Y1D5t=1WkSz(i*?gx zgC~Q~oQQbpo=pF`iYpjn5dE>|Xoj<{d7kcA0yl#}PHb(nN&dlU_Dx2eQ1J#P1)^2m zD{H3BQTgJf;{EHW93PCpVa>^$DHYS05m1}cxvcHgY=Ni$J@4NkZ13chww*8+eV9c? z!BxWE84WoVD&E9fJm1>Rj=)fG=gmE&NO*6bPI&s`ieB>!l3`~kZ?$Z3T*nOs^R2=3 zfoy+OaT5yyadvK%$5^ZKtPM{6W1r`clZ3P=Fdf`#6P!RRHy$|lBS}QLR5^|%nf={k z+1m~Ry_H7a#slk596wH&?HEO|BLqKqgLxEb_tsw&j?QPI# zA3o0aPiigBUwNUF?x{>5QS!9P!&R;3-zN$_6S&er@}wpyxO?n=Z6MB;l^kQuBlo{jH51wOW>j=qg@ANYy(zA!S@C_bH zdFBw8vk_lPCnJX#&nmt$+fbsul2nq>WcUzM*;q368|IR|$=FXwhj8~hOk^X^F}Ee% zuO%Z#$o|?fywflwd%x$7V%WszJh$>~@&tt;E1XAy&p}#8xbyQE#Ra5Eg$uZd6C8+gGXav&F=&89GFcc!)|nWHKrk2rk{Af$(wS+J4wLEF(+Qxs zptzo>@&;F}RC#g@B2~yK2dgaq0ngsNcooI(bv}Ko0g!UJphqI2E*3*W9DuL*x zc?ZPKNbBM%p1_l&Hgld~x#78t#p>JkFC;4qL^7$wQz~|1mq5*=;kZ6$E_L|b=>pv_ z?NPB8`vjWuVLGVK%vw3G+07fW?6>*_dxR@WOj?~((Tk@k)N~A6XDbzGEC_XTcrXu7 zhOr<03J$Q{lzdcpRq+fCvUg>vkidol2Y-4gI4rPb?FJ(Kc|^st7^FY*_MOljs*!yl z2UkrMztem<_?(I%9P=EUFQ2o1H?7KVWyE}tmek6<<}H#Y+MqCjK!F6Md51W_b=3qd10FJ`rjSOzhg-~pl1Zd^DS;>`~xh!{1o+@}&P{VJK zw*lTO_#5iH$^Tv7q4p~mC&F)?OBo?$l(_Z$0*xLvZ|is?9oCa8W6j?Ud}|=Af>`8T zxr-8sCAQy2)A&tjiR!K;tnXezr1M+Uc6BeJc>z`3iGT$66u>b3eMDqF49=M^H;lLFW8f3|@3MBp~Y#-%o=wZKih{9_5AdjRTBe+Mxmf^4)| z5paLyy_u~~-sNu3r(Ze*OBum>83IjPQ~1v)n2Jon5jHsdlk!E4xx8)(Bf zXvZCF!_Vlzujs_@=)xadjqagM1aL@%Ioq2tAX;!lbYakq`CZ1AQ7puqr!)*kT*A&_ zQf35CQ#>)#crr09Z4m9$Aj2GJ#c!D5Yk(U5LX9Swf5Z457V&DR?H8EEYqa7T=3yhp zoVr0uhqPhpJBT?-Q>k?y-=|SW-Q&1GE)iPLii+PbfcPQ%$v96%*p4{zY2NYD^Lj%9wDa_MR1@Hca&HO63+I&dC y2lp9*It4-jZ2go%sJopp7(pd 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 literal 0 HcmV?d00001 diff --git a/target/classes/br/com/rjconsultores/auditador/enums/AuditadorTipoAlteracao.class b/target/classes/br/com/rjconsultores/auditador/enums/AuditadorTipoAlteracao.class new file mode 100644 index 0000000000000000000000000000000000000000..9bf2794481366cecded9331707c746ced687646d GIT binary patch literal 1541 zcmbtUZBNrs6n^gB+Kuw!&?yYxLAHTZQ1E4g&@3}qEG$}BT=>+LI!n5hv>gfmO2-El zjl|FXDC4=M$RhY@Uv7JPpZlEWJolXb`u*(;zzWs{L>P)qS2mos>>e0S$Lrd@nV zclRw{-*;Tu>~!0ntX#x9)}f==zUk_Q?g)r6j2-Alx@_y6mRun$gIL`ztGk*~V^~** zU@tNx6?LcbK`C=CvGVbPcBHbsyER)^)ZL24u(3B}7O`a5R>$%;7^1m+ogr3s_DvD- z6c{EX+(4QkQ3@fMoO)TY=DSv>RjlUgNy6Tg5Jy6Uz=PWo1RjVyn3fhA zvox#K(fzJVT<@;{N<*2nQRH4ckuZ-Od2yuMU6T}T=JLatpF#nP0v5>Uz|^1~#dY;# zPr_3yQ7+v(uX!%FH(-3Nd0-lT@rn&8Jj05Bl)@;i#JpD`iWiQrxi*zKjSoyr^R_2MoCaY8 z65&TFY9mG~pnL~wq{pJC7(c;e5ZsCdK_&?9#Dice@q=*D9wxO$tcQ%&i1#q1ogn*_ zNFumPYdWA5i9U&GN;yyI?*+RYL9-mDUM9g@vQSu8&9^yI)f(N_?B7BHP zMDm#4BbW^;m=6$y>0_>s{Fh*h>o}(w{hK?v`ViJ?HJO-`_3(Jja@h35JcXubJLJ^AAnW4I(G>d@Im+ z)U!k0^L)*6qd}mx>?5!KIrO>7yw{L4;iWzv zag`ynS8p|UiDR<9f3UaQ-qsK52E(fl<5Om9renKyxXB=u%58?!j@PrYNGo8NRxyJc z)VDS&DVFr>$&Apq-F~%EZs(}>riwH&S;)dEs*sTp)@>D8C7CKT;Si|4qv`h_x=QZCupm4qC<B`j9ka%5@0>tagmRY!jR?(9_=(K1 zpY#wR-&UbA9YXWK{n70kt-?v`7c!XY=s}Ep**Y8&vfXGbZLDCe1RF&{#Z{raPJ)rt zgOo+6xsk^{1iRt-3(T6SiU}R}KTBv4tU$)Gn9RRfa!n|hg?j~11QHU0MI!dDYa&;{t{l7S*;sG@4uzPe zC_(MQ_RMF`Jk9g>&*v9_3!DUKFx7tUB&CfrYz<5Oc3rJc0zToAmg z;6fGwIt+(1zTip0b)LLVW>UBSJ%&L;?+c?PpA?dzCn)BYp*@P<7{Z68kaMR8hq{J%-^Zer`(Fbj;9CRj#@7mXy1rILnBgQf(%e&OB*R z_>vpyTb-L-QfHOUsUl2`w?aOu)c{dF`}ss#^b1pkE?y~cQgD2!wP-u literal 0 HcmV?d00001 diff --git a/target/classes/br/com/rjconsultores/auditador/interfaces/AuditavelTelaAlternativa.class b/target/classes/br/com/rjconsultores/auditador/interfaces/AuditavelTelaAlternativa.class new file mode 100644 index 0000000000000000000000000000000000000000..8387fa3a156e5d1b60f6510ded5a8f26844b4f57 GIT binary patch literal 223 zcmZ{fzY4-I7{u?Zf2vL*uI{=RaCNGKli*Na;AC?g`X&4x!#<<(L8u N@Cf7HA&r_~@&=RYLJI%@ literal 0 HcmV?d00001 diff --git a/target/classes/br/com/rjconsultores/auditador/model/AuditadorObjects.class b/target/classes/br/com/rjconsultores/auditador/model/AuditadorObjects.class new file mode 100644 index 0000000000000000000000000000000000000000..e8105a749575c10a4211fcf4067126a64ae99a96 GIT binary patch literal 3139 zcmbuBZByJ-6vzLUr(M?2!WO8tPm7kyQeXvziWFK(siKtDf@q~wLpIVd+09Ni%lM6a zt1}8SI^+1-59Rnj$?k@PyVDmPhTM~rd(Qpc^929?_vhaL=5Uljm%{vkU$VSP$v?8Z zYQ5nGo^RJnW~1x`X4&&g6|Zc&rPbE^(}N@13hEj3C=4E%$7abjtB0jXok5?%rC7V> zdR5yzaBYQwW7GBg)oNh-j^``nH{)&Ff$vlgmlXQLO7!4m!9zRPO@?%MqIf>2{ZP1WAcHJz>gQ}mCeEA4y^NN7Nrw1%-$1|kFj_vMED6Ti z*+j|S+Xiy2^AaBwhGc&tkzz1u;2kj-qVwce7E0TqooO+dF<^*EzHQR}tdOD24r@U+ z&KVexjTvqfT@<=Rjuq}RbZ=86a?o7^7jQ9(a?1UKiMR4D2^rv(HrjP4=iM_fC>I;x z#o{jty_R&HLb4p929;`F|Jkx@fx~9c;Gx2;xDUg2-SUF%My=-gfn9EIl?s1kU!FIzLzX%@dch*kPql724xyISb}saH^0PO4NSGqNO%b z(NurW!fdJAbxHk8*5On^#uQ&(g&q^bD!j&z0?#^4FgNpezQbc?i?uLSh=&!AU>T@= z3CN*=FL0IF-}V~5Wj}UgCXb|pIwL8-7_-yO-(FxE3Fs3$-J>>uBgFbpxlWK99Y7=j0&+_WGM)w*(}H}c2N_R;j1%N`2N0& z7A51Dc9NoB!f6Xs{=&wK{8y)VGRX;df~WayJ}8fg{7oc}i~MaQ7e#&%$