Commit 2545cbeada0ff90edf780976195c9c5708eb0e50

Authored by Cleverson Sacramento
1 parent 10e37220
Exists in master

Implementação do tratamento de erros de validação

archetype/html-rest/src/main/resources/archetype-resources/src/main/java/rest/BookmarkREST.java
... ... @@ -37,7 +37,7 @@ public class BookmarkREST {
37 37 @GET
38 38 @Path("{id}")
39 39 @Produces("application/json")
40   - public Bookmark load(@PathParam("id") Long id) throws Exception {
  40 + public Bookmark load(@PathParam("id") Long id) {
41 41 Bookmark result = bc.load(id);
42 42  
43 43 if (result == null) {
... ... @@ -52,9 +52,7 @@ public class BookmarkREST {
52 52 @Produces("text/plain")
53 53 @Consumes("application/json")
54 54 public Response insert(Bookmark entity, @Context UriInfo uriInfo) {
55   - if (entity.getId() != null) {
56   - throw new BadRequestException();
57   - }
  55 + checkId(entity);
58 56  
59 57 String id = bc.insert(entity).getId().toString();
60 58 URI location = uriInfo.getRequestUriBuilder().path(id).build();
... ... @@ -67,29 +65,24 @@ public class BookmarkREST {
67 65 @Transactional
68 66 @Consumes("application/json")
69 67 public void update(@PathParam("id") Long id, Bookmark entity) {
70   - if (entity.getId() != null) {
71   - throw new BadRequestException();
72   - }
73   -
74   - if (bc.load(id) == null) {
75   - throw new NotFoundException();
76   - }
  68 + checkId(entity);
  69 + load(id);
77 70  
78 71 entity.setId(id);
79 72 bc.update(entity);
80 73 }
81   -
82   - @DELETE
83   - @Transactional
84   - @Consumes("application/json")
85   - public void delete(List<Long> ids) {
86   - bc.delete(ids);
87   - }
88 74  
89 75 @DELETE
90 76 @Path("{id}")
91 77 @Transactional
92 78 public void delete(@PathParam("id") Long id) {
  79 + load(id);
93 80 bc.delete(id);
94 81 }
  82 +
  83 + private void checkId(Bookmark entity) throws BadRequestException {
  84 + if (entity.getId() != null) {
  85 + throw new BadRequestException();
  86 + }
  87 + }
95 88 }
... ...
impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/interceptor/RequiredPermissionInterceptor.java
... ... @@ -46,7 +46,7 @@ import org.slf4j.Logger;
46 46 import br.gov.frameworkdemoiselle.security.RequiredPermission;
47 47  
48 48 /**
49   - * Intercepts calls with {@code @RequiredPermission} annotations.
  49 + * Intercepts calls with {@code @Validate} annotations.
50 50 *
51 51 * @author SERPRO
52 52 */
... ...
impl/core/src/main/java/br/gov/frameworkdemoiselle/security/RequiredPermissionInterceptor.java
... ... @@ -51,7 +51,7 @@ import br.gov.frameworkdemoiselle.util.ResourceBundle;
51 51 import br.gov.frameworkdemoiselle.util.Strings;
52 52  
53 53 /**
54   - * Intercepts calls with {@code @RequiredPermission} annotations.
  54 + * Intercepts calls with {@code @Validate} annotations.
55 55 *
56 56 * @author SERPRO
57 57 */
... ... @@ -66,7 +66,7 @@ public class RequiredPermissionInterceptor implements Serializable {
66 66 private static transient Logger logger;
67 67  
68 68 /**
69   - * Gets the values for both resource and operation properties of {@code @RequiredPermission}. Delegates to
  69 + * Gets the values for both resource and operation properties of {@code @Validate}. Delegates to
70 70 * {@code SecurityContext} check permissions. If the user has the required permission it executes the mehtod,
71 71 * otherwise throws an exception. Returns what is returned from the intercepted method. If the method's return type
72 72 * is {@code void} returns {@code null}.
... ... @@ -99,12 +99,12 @@ public class RequiredPermissionInterceptor implements Serializable {
99 99 }
100 100  
101 101 /**
102   - * Returns the resource defined in {@code @RequiredPermission} annotation, the name defined in {@code @AmbiguousQualifier}
  102 + * Returns the resource defined in {@code @Validate} annotation, the name defined in {@code @AmbiguousQualifier}
103 103 * annotation or the class name itself
104 104 *
105 105 * @param ic
106 106 * the {@code InvocationContext} in which the method is being called
107   - * @return the resource defined in {@code @RequiredPermission} annotation, the name defined in {@code @AmbiguousQualifier}
  107 + * @return the resource defined in {@code @Validate} annotation, the name defined in {@code @AmbiguousQualifier}
108 108 * annotation or the class name itself
109 109 */
110 110 private String getResource(InvocationContext ic) {
... ... @@ -127,12 +127,12 @@ public class RequiredPermissionInterceptor implements Serializable {
127 127 }
128 128  
129 129 /**
130   - * Returns the operation defined in {@code @RequiredPermission} annotation, the name defined in {@code @AmbiguousQualifier}
  130 + * Returns the operation defined in {@code @Validate} annotation, the name defined in {@code @AmbiguousQualifier}
131 131 * annotation or the method's name itself
132 132 *
133 133 * @param ic
134 134 * the {@code InvocationContext} in which the method is being called
135   - * @return the operation defined in {@code @RequiredPermission} annotation, the name defined in {@code @AmbiguousQualifier}
  135 + * @return the operation defined in {@code @Validate} annotation, the name defined in {@code @AmbiguousQualifier}
136 136 * annotation or the method's name itself
137 137 */
138 138 private String getOperation(InvocationContext ic) {
... ...
impl/core/src/main/java/br/gov/frameworkdemoiselle/validation/Validate.java 0 → 100644
... ... @@ -0,0 +1,55 @@
  1 +/*
  2 + * Demoiselle Framework
  3 + * Copyright (C) 2010 SERPRO
  4 + * ----------------------------------------------------------------------------
  5 + * This file is part of Demoiselle Framework.
  6 + *
  7 + * Demoiselle Framework is free software; you can redistribute it and/or
  8 + * modify it under the terms of the GNU Lesser General Public License version 3
  9 + * as published by the Free Software Foundation.
  10 + *
  11 + * This program is distributed in the hope that it will be useful,
  12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + * GNU General Public License for more details.
  15 + *
  16 + * You should have received a copy of the GNU Lesser General Public License version 3
  17 + * along with this program; if not, see <http://www.gnu.org/licenses/>
  18 + * or write to the Free Software Foundation, Inc., 51 Franklin Street,
  19 + * Fifth Floor, Boston, MA 02110-1301, USA.
  20 + * ----------------------------------------------------------------------------
  21 + * Este arquivo é parte do Framework Demoiselle.
  22 + *
  23 + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou
  24 + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação
  25 + * do Software Livre (FSF).
  26 + *
  27 + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA
  28 + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou
  29 + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português
  30 + * para maiores detalhes.
  31 + *
  32 + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título
  33 + * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/>
  34 + * ou escreva para a Fundação do Software Livre (FSF) Inc.,
  35 + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA.
  36 + */
  37 +package br.gov.frameworkdemoiselle.validation;
  38 +
  39 +import static java.lang.annotation.ElementType.METHOD;
  40 +import static java.lang.annotation.ElementType.TYPE;
  41 +import static java.lang.annotation.RetentionPolicy.RUNTIME;
  42 +
  43 +import java.lang.annotation.Inherited;
  44 +import java.lang.annotation.Retention;
  45 +import java.lang.annotation.Target;
  46 +
  47 +import javax.interceptor.InterceptorBinding;
  48 +
  49 +@Inherited
  50 +@InterceptorBinding
  51 +@Target({ METHOD, TYPE })
  52 +@Retention(RUNTIME)
  53 +public @interface Validate {
  54 +
  55 +}
... ...
impl/core/src/main/java/br/gov/frameworkdemoiselle/validation/ValidateInterceptor.java 0 → 100644
... ... @@ -0,0 +1,80 @@
  1 +/*
  2 + * Demoiselle Framework
  3 + * Copyright (C) 2010 SERPRO
  4 + * ----------------------------------------------------------------------------
  5 + * This file is part of Demoiselle Framework.
  6 + *
  7 + * Demoiselle Framework is free software; you can redistribute it and/or
  8 + * modify it under the terms of the GNU Lesser General Public License version 3
  9 + * as published by the Free Software Foundation.
  10 + *
  11 + * This program is distributed in the hope that it will be useful,
  12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + * GNU General Public License for more details.
  15 + *
  16 + * You should have received a copy of the GNU Lesser General Public License version 3
  17 + * along with this program; if not, see <http://www.gnu.org/licenses/>
  18 + * or write to the Free Software Foundation, Inc., 51 Franklin Street,
  19 + * Fifth Floor, Boston, MA 02110-1301, USA.
  20 + * ----------------------------------------------------------------------------
  21 + * Este arquivo é parte do Framework Demoiselle.
  22 + *
  23 + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou
  24 + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação
  25 + * do Software Livre (FSF).
  26 + *
  27 + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA
  28 + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou
  29 + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português
  30 + * para maiores detalhes.
  31 + *
  32 + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título
  33 + * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/>
  34 + * ou escreva para a Fundação do Software Livre (FSF) Inc.,
  35 + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA.
  36 + */
  37 +package br.gov.frameworkdemoiselle.validation;
  38 +
  39 +import java.io.Serializable;
  40 +import java.util.HashSet;
  41 +import java.util.Set;
  42 +
  43 +import javax.interceptor.AroundInvoke;
  44 +import javax.interceptor.Interceptor;
  45 +import javax.interceptor.InvocationContext;
  46 +import javax.validation.ConstraintViolation;
  47 +import javax.validation.ConstraintViolationException;
  48 +import javax.validation.Validation;
  49 +import javax.validation.Validator;
  50 +import javax.validation.ValidatorFactory;
  51 +
  52 +/**
  53 + * Intercepts calls with {@code @Validate} annotations.
  54 + *
  55 + * @author SERPRO
  56 + */
  57 +@Validate
  58 +@Interceptor
  59 +public class ValidateInterceptor implements Serializable {
  60 +
  61 + private static final long serialVersionUID = 1L;
  62 +
  63 + @AroundInvoke
  64 + public Object manage(final InvocationContext ic) throws Exception {
  65 + Set<ConstraintViolation<?>> violations = new HashSet<ConstraintViolation<?>>();
  66 +
  67 + for (Object params : ic.getParameters()) {
  68 + ValidatorFactory dfv = Validation.buildDefaultValidatorFactory();
  69 + Validator validator = dfv.getValidator();
  70 +
  71 + violations.addAll(validator.validate(params));
  72 + }
  73 +
  74 + if (!violations.isEmpty()) {
  75 + throw new ConstraintViolationException(violations);
  76 + }
  77 +
  78 + return ic.proceed();
  79 + }
  80 +}
... ...
impl/extension/rest/src/main/java/br/gov/frameworkdemoiselle/PreconditionFailedException.java 0 → 100644
... ... @@ -0,0 +1,95 @@
  1 +package br.gov.frameworkdemoiselle;
  2 +
  3 +import static javax.servlet.http.HttpServletResponse.SC_PRECONDITION_FAILED;
  4 +
  5 +import java.util.HashSet;
  6 +import java.util.Set;
  7 +
  8 +import javax.xml.ws.http.HTTPException;
  9 +
  10 +public class PreconditionFailedException extends HTTPException {
  11 +
  12 + private static final long serialVersionUID = 1L;
  13 +
  14 + private Set<Violation> violations = new HashSet<Violation>();
  15 +
  16 + public PreconditionFailedException() {
  17 + super(SC_PRECONDITION_FAILED);
  18 + }
  19 +
  20 + public PreconditionFailedException addViolation(String property, String message) {
  21 + this.violations.add(new Violation(property, message));
  22 + return this;
  23 + }
  24 +
  25 + public Set<Violation> getViolations() {
  26 + return violations;
  27 + }
  28 +
  29 + public static class Violation {
  30 +
  31 + public String property;
  32 +
  33 + public String message;
  34 +
  35 + public Violation() {
  36 + }
  37 +
  38 + public Violation(String property, String message) {
  39 + this.property = property;
  40 + this.message = message;
  41 + }
  42 +
  43 + public String getProperty() {
  44 + return property;
  45 + }
  46 +
  47 + public void setProperty(String property) {
  48 + this.property = property;
  49 + }
  50 +
  51 + public String getMessage() {
  52 + return message;
  53 + }
  54 +
  55 + public void setMessage(String message) {
  56 + this.message = message;
  57 + }
  58 +
  59 + @Override
  60 + public int hashCode() {
  61 + final int prime = 31;
  62 + int result = 1;
  63 + result = prime * result + ((message == null) ? 0 : message.hashCode());
  64 + result = prime * result + ((property == null) ? 0 : property.hashCode());
  65 + return result;
  66 + }
  67 +
  68 + @Override
  69 + public boolean equals(Object obj) {
  70 + if (this == obj)
  71 + return true;
  72 + if (obj == null)
  73 + return false;
  74 + if (getClass() != obj.getClass())
  75 + return false;
  76 + Violation other = (Violation) obj;
  77 + if (message == null) {
  78 + if (other.message != null)
  79 + return false;
  80 + } else if (!message.equals(other.message))
  81 + return false;
  82 + if (property == null) {
  83 + if (other.property != null)
  84 + return false;
  85 + } else if (!property.equals(other.property))
  86 + return false;
  87 + return true;
  88 + }
  89 +
  90 + @Override
  91 + public String toString() {
  92 + return this.property + " " + this.message;
  93 + }
  94 + }
  95 +}
... ...
impl/extension/rest/src/main/java/br/gov/frameworkdemoiselle/internal/implementation/ConstraintViolationExceptionMapper.java
1   -//package br.gov.frameworkdemoiselle.internal.implementation;
2   -//
3   -//import java.util.Arrays;
4   -//
5   -//import javax.validation.ConstraintViolation;
6   -//import javax.validation.ConstraintViolationException;
7   -//import javax.ws.rs.core.Context;
8   -//import javax.ws.rs.core.Response;
9   -//import javax.ws.rs.ext.ExceptionMapper;
10   -//import javax.ws.rs.ext.Provider;
11   -//
12   -//@Provider
13   -//public class ConstraintViolationExceptionMapper implements ExceptionMapper<Exception> {
14   -//
15   -// @Context
16   -// private Response response;
17   -//
18   -// @Override
19   -// public Response toResponse(Exception exception) {
20   -//
21   -// Throwable rootCause = exception;
22   -// while (rootCause != null) {
23   -// if (rootCause instanceof ConstraintViolationException) {
24   -// break;
25   -// }
26   -//
27   -// rootCause = rootCause.getCause();
28   -// }
29   -//
30   -// if (rootCause != null) {
31   -// for (ConstraintViolation<?> violation : ((ConstraintViolationException) rootCause)
32   -// .getConstraintViolations()) {
33   -// String parts[] = violation.getPropertyPath().toString().split("\\.|\\[|\\]\\.");
34   -// String property = null;
35   -//
36   -// if (parts.length > 1) {
37   -// property = parts[1];
38   -//
39   -// for (String part : Arrays.copyOfRange(parts, 2, parts.length)) {
40   -// property += "." + part;
41   -// }
42   -// }
43   -//
44   -// System.out.println(property);
45   -// }
46   -// }
47   -//
48   -// return null;
49   -// }
50   -// }
  1 +package br.gov.frameworkdemoiselle.internal.implementation;
  2 +
  3 +import static javax.ws.rs.core.Response.Status.PRECONDITION_FAILED;
  4 +
  5 +import java.util.Iterator;
  6 +
  7 +import javax.validation.ConstraintViolation;
  8 +import javax.validation.ConstraintViolationException;
  9 +import javax.ws.rs.core.Response;
  10 +import javax.ws.rs.ext.ExceptionMapper;
  11 +import javax.ws.rs.ext.Provider;
  12 +
  13 +import br.gov.frameworkdemoiselle.PreconditionFailedException;
  14 +
  15 +@Provider
  16 +public class ConstraintViolationExceptionMapper implements ExceptionMapper<ConstraintViolationException> {
  17 +
  18 + @Override
  19 + public Response toResponse(ConstraintViolationException exception) {
  20 + PreconditionFailedException failed = new PreconditionFailedException();
  21 +
  22 + for (Iterator<ConstraintViolation<?>> iter = exception.getConstraintViolations().iterator(); iter.hasNext();) {
  23 + ConstraintViolation<?> violation = iter.next();
  24 + failed.addViolation(violation.getPropertyPath().toString(), violation.getMessage());
  25 + }
  26 +
  27 + return Response.status(PRECONDITION_FAILED).entity(failed.getViolations()).build();
  28 + }
  29 +}
... ...
impl/extension/rest/src/main/java/br/gov/frameworkdemoiselle/internal/implementation/PreconditionFailedExceptionMapper.java 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +package br.gov.frameworkdemoiselle.internal.implementation;
  2 +
  3 +import javax.ws.rs.core.Response;
  4 +import javax.ws.rs.ext.ExceptionMapper;
  5 +import javax.ws.rs.ext.Provider;
  6 +
  7 +import br.gov.frameworkdemoiselle.PreconditionFailedException;
  8 +
  9 +@Provider
  10 +public class PreconditionFailedExceptionMapper implements ExceptionMapper<PreconditionFailedException> {
  11 +
  12 + @Override
  13 + public Response toResponse(PreconditionFailedException exception) {
  14 + return Response.status(exception.getStatusCode()).entity(exception.getViolations()).build();
  15 + }
  16 +}
... ...