tomee-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jlmonte...@apache.org
Subject svn commit: r1101415 - in /openejb/branches/openejb-3.2.x/container/openejb-core/src: main/java/org/apache/openejb/bval/ test/java/org/apache/openejb/ test/java/org/apache/openejb/bval/
Date Tue, 10 May 2011 11:42:50 GMT
Author: jlmonteiro
Date: Tue May 10 11:42:49 2011
New Revision: 1101415

URL: http://svn.apache.org/viewvc?rev=1101415&view=rev
Log:
OPENEJB:1525 bean validation appendix.
Thanks Romain.

Added:
    openejb/branches/openejb-3.2.x/container/openejb-core/src/main/java/org/apache/openejb/bval/
    openejb/branches/openejb-3.2.x/container/openejb-core/src/main/java/org/apache/openejb/bval/BeanValidationAppendixInterceptor.java
    openejb/branches/openejb-3.2.x/container/openejb-core/src/test/java/org/apache/openejb/BeanContextSystemInterceptorTest.java
    openejb/branches/openejb-3.2.x/container/openejb-core/src/test/java/org/apache/openejb/bval/BeanValidationAppendixInterceptorTest.java
Modified:
    openejb/branches/openejb-3.2.x/container/openejb-core/src/test/java/org/apache/openejb/bval/BeanValidationTest.java

Added: openejb/branches/openejb-3.2.x/container/openejb-core/src/main/java/org/apache/openejb/bval/BeanValidationAppendixInterceptor.java
URL: http://svn.apache.org/viewvc/openejb/branches/openejb-3.2.x/container/openejb-core/src/main/java/org/apache/openejb/bval/BeanValidationAppendixInterceptor.java?rev=1101415&view=auto
==============================================================================
--- openejb/branches/openejb-3.2.x/container/openejb-core/src/main/java/org/apache/openejb/bval/BeanValidationAppendixInterceptor.java
(added)
+++ openejb/branches/openejb-3.2.x/container/openejb-core/src/main/java/org/apache/openejb/bval/BeanValidationAppendixInterceptor.java
Tue May 10 11:42:49 2011
@@ -0,0 +1,173 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.bval;
+
+
+import org.apache.openejb.core.ivm.naming.NamingException;
+import org.apache.openejb.util.LogCategory;
+import org.apache.openejb.util.Logger;
+
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.InvocationContext;
+import javax.naming.InitialContext;
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import javax.validation.ValidationException;
+import javax.validation.Validator;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * A simple interceptor to validate parameters and returned value using
+ * bean validation spec. It doesn't use group for now.
+ * <p/>
+ * It is dependent of the Apache Bean Validation implementation.
+ *
+ * @author Romain Manni-Bucau
+ */
+public class BeanValidationAppendixInterceptor {
+    private static final Logger logger = Logger.getInstance(LogCategory.OPENEJB, BeanValidationAppendixInterceptor.class);
+    private static final Class<?> APACHE_BVAL_METHOD_CLASS = initApache();
+    private static final Class<?> HIBERNATE_METHOD_CLASS = initHibernate();
+
+    @AroundInvoke
+    public Object aroundInvoke(final InvocationContext ejbContext) throws Exception {
+        Object validatorObject = null;
+        Validator validator = null;
+        try {
+            validator = (Validator) new InitialContext().lookup("java:comp/Validator");
+        } catch (NamingException ne) {
+            // no-op
+        }
+
+        Set<?> violations = Collections.emptySet();
+        if (APACHE_BVAL_METHOD_CLASS != null && validator != null) {
+            validatorObject = validator.unwrap(APACHE_BVAL_METHOD_CLASS);
+            violations = call(Set.class, validatorObject, "validateParameters",
+                    new Object[]{
+                            ejbContext.getTarget().getClass(), ejbContext.getMethod(), ejbContext.getParameters(),
new Class[0]
+                    },
+                    new Class<?>[]{
+                            Class.class, Method.class, Object[].class, Class[].class
+                    });
+        } else if (HIBERNATE_METHOD_CLASS != null && validator != null) {
+            validatorObject = validator.unwrap(HIBERNATE_METHOD_CLASS);
+            violations = call(Set.class, validatorObject, "validateAllParameters",
+                    new Object[]{
+                            ejbContext.getTarget(), ejbContext.getMethod(), ejbContext.getParameters(),
new Class[0]
+                    },
+                    new Class<?>[]{
+                            Object.class, Method.class, Object[].class, Class[].class
+                    });
+        } else { // a warning message to inform Apache Bean Validation is not present
+            if (validator == null) {
+                logger.error("can't find validator");
+            } else {
+                logger.warning("Apache Bean Validation is not present, "
+                        + BeanValidationAppendixInterceptor.class.getName() + " will not
work. "
+                        + "Please put it if you want to validate your parameters and returned
values "
+                        + "with bean validation JSR.");
+            }
+        }
+
+        if (violations.size() > 0) {
+            throw buildValidationException((Set<ConstraintViolation<?>>) violations);
+        }
+
+        Object returnedValue = ejbContext.proceed();
+
+        violations = Collections.emptySet();
+        if (validatorObject != null && APACHE_BVAL_METHOD_CLASS != null) {
+            violations = call(Set.class, validatorObject, "validateReturnedValue",
+                    new Object[]{
+                            ejbContext.getTarget().getClass(), ejbContext.getMethod(), returnedValue,
new Class[0]
+                    },
+                    new Class<?>[]{
+                            Class.class, Method.class, Object.class, Class[].class
+                    });
+        } else if (validatorObject != null && HIBERNATE_METHOD_CLASS != null) {
+            violations = call(Set.class, validatorObject, "validateReturnValue",
+                    new Object[]{
+                            ejbContext.getTarget(), ejbContext.getMethod(), returnedValue,
new Class[0]
+                    },
+                    new Class<?>[]{
+                            Object.class, Method.class, Object.class, Class[].class
+                    });
+        }
+
+        if (violations.size() > 0) {
+            throw buildValidationException((Set<ConstraintViolation<?>>) violations);
+        }
+
+        return returnedValue;
+    }
+
+    // just a simple EJBException for now
+    private RuntimeException buildValidationException(Set<ConstraintViolation<?>>
violations) {
+        return new ConstraintViolationException(violations);
+    }
+
+    private static <T> T call(Class<T> returnedType, Object o, String methodName,
Object[] params, Class<?>[] types) {
+        Method method = null;
+        boolean accessible = true;
+        try {
+            method = o.getClass().getMethod(methodName, types);
+            accessible = method.isAccessible();
+            if (!accessible) {
+                accessible = false;
+                method.setAccessible(true);
+            }
+            return (T) method.invoke(o, params);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new ValidationException("can't call method " + methodName + " on " + o,
e);
+        } finally {
+            if (method != null) {
+                method.setAccessible(accessible);
+            }
+        }
+    }
+
+    private static ClassLoader getClassLaoder() {
+        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+        if (classLoader == null) {
+            classLoader = BeanValidationAppendixInterceptor.class.getClassLoader();
+        }
+        return classLoader;
+    }
+
+    private static Class<?> initApache() {
+        try {
+            return getClassLaoder().loadClass("org.apache.bval.jsr303.extensions.MethodValidator");
+        } catch (ClassNotFoundException e) {
+            return null;
+        }
+    }
+
+    private static Class<?> initHibernate() {
+        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+        if (classLoader == null) {
+            classLoader = BeanValidationAppendixInterceptor.class.getClassLoader();
+        }
+        try {
+            return getClassLaoder().loadClass("org.hibernate.validator.method.MethodValidator");
+        } catch (ClassNotFoundException e) {
+            return null;
+        }
+    }
+}
\ No newline at end of file

Added: openejb/branches/openejb-3.2.x/container/openejb-core/src/test/java/org/apache/openejb/BeanContextSystemInterceptorTest.java
URL: http://svn.apache.org/viewvc/openejb/branches/openejb-3.2.x/container/openejb-core/src/test/java/org/apache/openejb/BeanContextSystemInterceptorTest.java?rev=1101415&view=auto
==============================================================================
--- openejb/branches/openejb-3.2.x/container/openejb-core/src/test/java/org/apache/openejb/BeanContextSystemInterceptorTest.java
(added)
+++ openejb/branches/openejb-3.2.x/container/openejb-core/src/test/java/org/apache/openejb/BeanContextSystemInterceptorTest.java
Tue May 10 11:42:49 2011
@@ -0,0 +1,94 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb;
+
+import org.apache.openejb.bval.BeanValidationAppendixInterceptor;
+import org.apache.openejb.core.CoreDeploymentInfo;
+import org.apache.openejb.jee.EmptyType;
+import org.apache.openejb.jee.StatelessBean;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.junit.Configuration;
+import org.apache.openejb.junit.Module;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.ejb.EJB;
+import javax.ejb.LocalBean;
+import javax.ejb.Stateless;
+import javax.validation.ConstraintViolationException;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.util.Properties;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
+
+/**
+ * @author Romain Manni-Bucau
+ */
+@RunWith(ApplicationComposer.class)
+public class BeanContextSystemInterceptorTest {
+    @EJB private Manager manager;
+
+    @Configuration public Properties config() {
+        final Properties p = new Properties();
+        p.put(CoreDeploymentInfo.USER_DEFAULT_INTERCEPTOR_KEY, BeanValidationAppendixInterceptor.class.getName());
+        return p;
+    }
+
+    @Module public StatelessBean app() throws Exception {
+        final StatelessBean bean = new StatelessBean(Manager.class);
+        bean.setLocalBean(new EmptyType());
+        return bean;
+    }
+
+    @LocalBean
+    @Stateless
+    public static class Manager {
+        @Size(min = 1, max = 5) @NotNull public String shouldBeValidated(String returned,
@Max(5) int param) {
+            return returned;
+        }
+    }
+
+    @Test public void valid()  {
+        manager.shouldBeValidated("hi", 1);
+    }
+
+    @Test public void notValid()  {
+        try {
+            manager.shouldBeValidated(null, 1);
+            fail();
+        } catch (Exception ejbException) {
+            assertTrue(ejbException.getCause() instanceof ConstraintViolationException);
+            ConstraintViolationException constraintViolationException = (ConstraintViolationException)
ejbException.getCause();
+            assertEquals(1, constraintViolationException.getConstraintViolations().size());
+        }
+    }
+
+    @Test public void notValid2() throws Exception {
+        try {
+            manager.shouldBeValidated("hello", 6);
+            fail();
+        } catch (Exception ejbException) {
+            assertTrue(ejbException.getCause() instanceof ConstraintViolationException);
+            ConstraintViolationException constraintViolationException = (ConstraintViolationException)
ejbException.getCause();
+            assertEquals(1, constraintViolationException.getConstraintViolations().size());
+        }
+    }
+}

Added: openejb/branches/openejb-3.2.x/container/openejb-core/src/test/java/org/apache/openejb/bval/BeanValidationAppendixInterceptorTest.java
URL: http://svn.apache.org/viewvc/openejb/branches/openejb-3.2.x/container/openejb-core/src/test/java/org/apache/openejb/bval/BeanValidationAppendixInterceptorTest.java?rev=1101415&view=auto
==============================================================================
--- openejb/branches/openejb-3.2.x/container/openejb-core/src/test/java/org/apache/openejb/bval/BeanValidationAppendixInterceptorTest.java
(added)
+++ openejb/branches/openejb-3.2.x/container/openejb-core/src/test/java/org/apache/openejb/bval/BeanValidationAppendixInterceptorTest.java
Tue May 10 11:42:49 2011
@@ -0,0 +1,82 @@
+package org.apache.openejb.bval;
+
+import org.apache.openejb.jee.EmptyType;
+import org.apache.openejb.jee.StatelessBean;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.junit.Module;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.ejb.EJB;
+import javax.ejb.LocalBean;
+import javax.ejb.Stateless;
+import javax.interceptor.Interceptors;
+import javax.validation.ConstraintViolationException;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * @author Romain Manni-Bucau
+ */
+@RunWith(ApplicationComposer.class)
+public class BeanValidationAppendixInterceptorTest {
+    @EJB private ValidationManager validationManager;
+
+    @Module public StatelessBean bean() throws Exception {
+        final StatelessBean bean = new StatelessBean(ValidationManager.class);
+        bean.setLocalBean(new EmptyType());
+        return bean;
+    }
+
+    @LocalBean
+    @Stateless
+    @Interceptors(BeanValidationAppendixInterceptor.class)
+    public static class ValidationManager {
+        @Min(0) public int valid(@Size(max = 1) @NotNull String complicatedName, @Max(5)
int ret) {
+            return ret;
+        }
+    }
+
+    @Test public void valid() {
+        validationManager.valid("", 1);
+    }
+
+    @Test public void paramNotValid() {
+        try {
+            validationManager.valid(":(", 1);
+            fail();
+        } catch (Exception exception) {
+            assertTrue(exception.getCause() instanceof ConstraintViolationException);
+            ConstraintViolationException validationException = (ConstraintViolationException)
exception.getCause();
+            assertEquals(1, validationException.getConstraintViolations().size());
+        }
+    }
+
+    @Test public void returnedNotValid() {
+        try {
+            validationManager.valid("", -1);
+            fail();
+        } catch (Exception exception) {
+            assertTrue(exception.getCause() instanceof ConstraintViolationException);
+            ConstraintViolationException validationException = (ConstraintViolationException)
exception.getCause();
+            assertEquals(1, validationException.getConstraintViolations().size());
+        }
+    }
+
+    @Test public void paramNotValid2() {
+        try {
+            validationManager.valid(null, 6);
+            fail();
+        } catch (Exception exception) {
+            assertTrue(exception.getCause() instanceof ConstraintViolationException);
+            ConstraintViolationException validationException = (ConstraintViolationException)
exception.getCause();
+            assertEquals(2, validationException.getConstraintViolations().size());
+        }
+    }
+}

Modified: openejb/branches/openejb-3.2.x/container/openejb-core/src/test/java/org/apache/openejb/bval/BeanValidationTest.java
URL: http://svn.apache.org/viewvc/openejb/branches/openejb-3.2.x/container/openejb-core/src/test/java/org/apache/openejb/bval/BeanValidationTest.java?rev=1101415&r1=1101414&r2=1101415&view=diff
==============================================================================
--- openejb/branches/openejb-3.2.x/container/openejb-core/src/test/java/org/apache/openejb/bval/BeanValidationTest.java
(original)
+++ openejb/branches/openejb-3.2.x/container/openejb-core/src/test/java/org/apache/openejb/bval/BeanValidationTest.java
Tue May 10 11:42:49 2011
@@ -1,3 +1,19 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
 package org.apache.openejb.bval;
 
 import org.apache.openejb.jee.EmptyType;



Mime
View raw message