diff --git a/impl/core/pom.xml b/impl/core/pom.xml index 3366900..da14eb3 100755 --- a/impl/core/pom.xml +++ b/impl/core/pom.xml @@ -77,15 +77,6 @@ import pom - @@ -248,6 +239,13 @@ slf4j-log4j12 test + + + br.gov.frameworkdemoiselle.component + demoiselle-validation + test + ${demoiselle.validation.version} + @@ -279,5 +277,6 @@ + 2.4.0-BETA2-SNAPSHOT diff --git a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/management/Management.java b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/management/Management.java index 2f3133b..967ffec 100644 --- a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/management/Management.java +++ b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/management/Management.java @@ -40,11 +40,16 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Set; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.management.ReflectionException; +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.ValidationException; +import javax.validation.Validator; import org.slf4j.Logger; @@ -78,6 +83,8 @@ public class Management { private ResourceBundle bundle; private final List managedTypes = new ArrayList(); + + private Validator validator; public void addManagedType(ManagedType managedType) { managedTypes.add(managedType); @@ -215,12 +222,31 @@ public class Management { "management-debug-setting-property", method.getName(), managedType.getType().getCanonicalName())); - // Obtém uma instância da classe gerenciada, lembrando que - // classes - // anotadas com @ManagementController são sempre singletons. activateContexts(managedType.getType()); try { + // Obtém uma instância da classe gerenciada, lembrando que + // classes + // anotadas com @ManagementController são sempre singletons. Object delegate = Beans.getReference(managedType.getType()); + + //Se houver um validador anexado à propriedade alterada, executa o validador sobre + //o novo valor. + Validator validator = getDefaultValidator(); + if (validator!=null){ + Set violations = validator.validateValue(managedType.getType(), propertyName, newValue); + if (violations.size()>0){ + StringBuffer errorBuffer = new StringBuffer(); + for (Object objectViolation : violations){ + ConstraintViolation violation = (ConstraintViolation) objectViolation; + errorBuffer.append(violation.getMessage()).append('\r').append('\n'); + } + + throw new DemoiselleException(bundle.getString("validation-constraint-violation",managedType.getType().getCanonicalName(),errorBuffer.toString())); + } + } + else{ + logger.warn(bundle.getString("validation-validator-not-found")); + } Method getterMethod = managedType.getFields().get(propertyName).getGetterMethod(); Object oldValue; @@ -244,6 +270,8 @@ public class Management { , newValue); notificationManager.sendNotification(notification); + } catch (DemoiselleException de){ + throw de; } catch (Exception e) { throw new DemoiselleException(bundle.getString( "management-invoke-error", method.getName()), e); @@ -306,5 +334,18 @@ public class Management { } } + + private Validator getDefaultValidator(){ + if (validator == null){ + try{ + this.validator = Validation.buildDefaultValidatorFactory().getValidator(); + } + catch(ValidationException e){ + this.validator = null; + } + } + + return this.validator; + } } diff --git a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/validation/AllowedValuesValidator.java b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/validation/AllowedValuesValidator.java deleted file mode 100644 index 23d5e2b..0000000 --- a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/validation/AllowedValuesValidator.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Demoiselle Framework - * Copyright (C) 2010 SERPRO - * ---------------------------------------------------------------------------- - * This file is part of Demoiselle Framework. - * - * Demoiselle Framework is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License version 3 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License version 3 - * along with this program; if not, see - * or write to the Free Software Foundation, Inc., 51 Franklin Street, - * Fifth Floor, Boston, MA 02110-1301, USA. - * ---------------------------------------------------------------------------- - * Este arquivo é parte do Framework Demoiselle. - * - * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou - * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação - * do Software Livre (FSF). - * - * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA - * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou - * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português - * para maiores detalhes. - * - * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título - * "LICENCA.txt", junto com esse programa. Se não, acesse - * ou escreva para a Fundação do Software Livre (FSF) Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. - */ -package br.gov.frameworkdemoiselle.internal.validation; - -import java.math.BigDecimal; - -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; - -import br.gov.frameworkdemoiselle.validation.AllowedValues; - - -public class AllowedValuesValidator implements ConstraintValidator { - - private br.gov.frameworkdemoiselle.validation.AllowedValues.ValueType valueType; - private String[] allowedValues; - - @Override - public void initialize(AllowedValues constraintAnnotation) { - valueType = constraintAnnotation.valueType(); - allowedValues = constraintAnnotation.allows(); - } - - @Override - public boolean isValid(Object value, ConstraintValidatorContext context) { - - if (value==null){ - return false; - } - - switch(valueType){ - case STRING: - for (String str : allowedValues){ - if (str.equals(value)) return true; - } - return false; - - case INTEGER: - try{ - Integer number = Integer.valueOf(value.toString()); - String strNumber = number.toString(); - for (String str : allowedValues){ - if (str.equals(strNumber)) return true; - } - - return false; - } - catch(NumberFormatException ne){ - return false; - } - - case DECIMAL: - try{ - BigDecimal number = new BigDecimal(value.toString()); - String strNumber = number.toString(); - for (String str : allowedValues){ - if (str.equals(strNumber)) return true; - } - } - catch(NumberFormatException ne){ - return false; - } - - return false; - } - - return false; - } - -} diff --git a/impl/core/src/main/java/br/gov/frameworkdemoiselle/validation/AllowedValues.java b/impl/core/src/main/java/br/gov/frameworkdemoiselle/validation/AllowedValues.java deleted file mode 100644 index 3a8983f..0000000 --- a/impl/core/src/main/java/br/gov/frameworkdemoiselle/validation/AllowedValues.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Demoiselle Framework - * Copyright (C) 2010 SERPRO - * ---------------------------------------------------------------------------- - * This file is part of Demoiselle Framework. - * - * Demoiselle Framework is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License version 3 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License version 3 - * along with this program; if not, see - * or write to the Free Software Foundation, Inc., 51 Franklin Street, - * Fifth Floor, Boston, MA 02110-1301, USA. - * ---------------------------------------------------------------------------- - * Este arquivo é parte do Framework Demoiselle. - * - * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou - * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação - * do Software Livre (FSF). - * - * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA - * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou - * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português - * para maiores detalhes. - * - * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título - * "LICENCA.txt", junto com esse programa. Se não, acesse - * ou escreva para a Fundação do Software Livre (FSF) Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. - */ -package br.gov.frameworkdemoiselle.validation; - -import static java.lang.annotation.ElementType.FIELD; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -import javax.validation.Constraint; - -import br.gov.frameworkdemoiselle.internal.validation.AllowedValuesValidator; - -@Documented -@Target({ FIELD}) -@Retention(RUNTIME) -@Constraint(validatedBy = AllowedValuesValidator.class) -/** - * Validate a value against a list of allowed values. - * - * @author serpro - * - */ -public @interface AllowedValues { - - /** - * List of accepted values - */ - String[] allows(); - - /** - * Type of allowed values. Defaults to {@link ValueType#STRING}. - */ - ValueType valueType() default ValueType.STRING; - - enum ValueType { - STRING,INTEGER,DECIMAL; - } - -} diff --git a/impl/core/src/main/resources/demoiselle-core-bundle.properties b/impl/core/src/main/resources/demoiselle-core-bundle.properties index 1923cc0..039f0f2 100644 --- a/impl/core/src/main/resources/demoiselle-core-bundle.properties +++ b/impl/core/src/main/resources/demoiselle-core-bundle.properties @@ -113,4 +113,6 @@ management-debug-starting-custom-context=Levantando contexto {0} para executar c management-debug-stoping-custom-context=Desligando contexto {0} para classe gerenciada {1} management-debug-registering-managed-type=Registrando classe gerenciada [{0}] management-debug-processing-management-extension=Processando extens\u00E3o de gerenciamento [{0}] -management-debug-removing-management-extension=Desativando extens\u00E3o de gerenciamento [{0}] \ No newline at end of file +management-debug-removing-management-extension=Desativando extens\u00E3o de gerenciamento [{0}] + +validation-validator-not-found=Nenhum provedor de valida\u00E7\u00E3o de beans encontrado, as anota\u00E7\u00F5es de valida\u00E7\u00E3o n\u00E3o ser\u00E3o processadas diff --git a/impl/core/src/test/java/management/ValidationTestCase.java b/impl/core/src/test/java/management/ValidationTestCase.java new file mode 100644 index 0000000..f4e4c28 --- /dev/null +++ b/impl/core/src/test/java/management/ValidationTestCase.java @@ -0,0 +1,62 @@ +package management; + +import java.io.File; + +import management.testclasses.DummyManagedClass; +import management.testclasses.DummyManagementExtension; +import management.testclasses.ManagedClassStore; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.FileAsset; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +import test.LocaleProducer; +import br.gov.frameworkdemoiselle.DemoiselleException; +import br.gov.frameworkdemoiselle.util.Beans; + +@RunWith(Arquillian.class) +public class ValidationTestCase { + + @Deployment + public static JavaArchive createDeployment() { + return ShrinkWrap + .create(JavaArchive.class) + .addClass(LocaleProducer.class) + .addPackages(true, "br") + .addAsResource(new FileAsset(new File("src/test/resources/test/beans.xml")), "beans.xml") + .addAsManifestResource( + new File("src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension"), + "services/javax.enterprise.inject.spi.Extension") + .addPackages(false, NotificationTestCase.class.getPackage()) + .addClasses(DummyManagementExtension.class,ManagedClassStore.class,DummyManagedClass.class); + } + + /** + * Test if changing properties of a management controller passes through + * validation phase. + */ + @Test + public void testManagedClassValidation(){ + + //Testa se é possível definir um valor válido para uma propriedade. + ManagedClassStore store = Beans.getReference(ManagedClassStore.class); + store.setProperty(DummyManagedClass.class, "id", new Integer(1)); + Assert.assertEquals(new Integer(1), store.getProperty(DummyManagedClass.class, "id")); + + //Testa se definir um valor inválido dispara o erro adequado + try{ + store.setProperty(DummyManagedClass.class, "id", new Integer(5)); + Assert.fail(); + } + catch(DemoiselleException e){ + //SUCCESS + } + + } + +} diff --git a/impl/core/src/test/java/management/testclasses/DummyManagedClass.java b/impl/core/src/test/java/management/testclasses/DummyManagedClass.java index 1577842..1311c7a 100644 --- a/impl/core/src/test/java/management/testclasses/DummyManagedClass.java +++ b/impl/core/src/test/java/management/testclasses/DummyManagedClass.java @@ -41,8 +41,8 @@ import java.util.UUID; import br.gov.frameworkdemoiselle.annotation.ManagedOperation; import br.gov.frameworkdemoiselle.annotation.ManagedProperty; import br.gov.frameworkdemoiselle.stereotype.ManagementController; -import br.gov.frameworkdemoiselle.validation.AllowedValues; -import br.gov.frameworkdemoiselle.validation.AllowedValues.ValueType; +import br.gov.frameworkdemoiselle.validation.annotation.AllowedValues; +import br.gov.frameworkdemoiselle.validation.annotation.AllowedValues.ValueType; @ManagementController public class DummyManagedClass { @@ -51,7 +51,7 @@ public class DummyManagedClass { private String name; @ManagedProperty - @AllowedValues(allows={"f","m","F","M"},valueType=ValueType.INTEGER) + @AllowedValues(allows={"1","2","3","4"},valueType=ValueType.INTEGER) private Integer id; @ManagedProperty -- libgit2 0.21.2