Author: rmannibucau
Date: Mon Oct  6 07:24:30 2014
New Revision: 1629580

URL: http://svn.apache.org/r1629580
Log:
TOMEE-1381 passing good ValidatorFactory property to JPA

Added:
    
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ComparableValidationConfig.java
Modified:
    
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
    
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EntityManagerFactoryCallable.java
    
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/PersistenceBuilder.java
    
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ValidatorFactoryWrapper.java
    
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/bval/ValidatorUtil.java

Modified: 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java?rev=1629580&r1=1629579&r2=1629580&view=diff
==============================================================================
--- 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
 (original)
+++ 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
 Mon Oct  6 07:24:30 2014
@@ -711,6 +711,9 @@ public class Assembler extends Assembler
             final Map<String, LazyValidatorFactory> lazyValidatorFactories = 
new HashMap<String, LazyValidatorFactory>();
             final Map<String, LazyValidator> lazyValidators = new 
HashMap<String, LazyValidator>();
             final boolean isGeronimo = 
SystemInstance.get().hasProperty("openejb.geronimo");
+
+            // try to not create N times the same validator for a single app
+            final Map<ComparableValidationConfig, ValidatorFactory> 
validatorFactoriesByConfig = new HashMap<ComparableValidationConfig, 
ValidatorFactory>();
             if (!isGeronimo) {
                 // Bean Validation
                 // ValidatorFactory needs to be put in the map sent to the 
entity manager factory
@@ -719,15 +722,27 @@ public class Assembler extends Assembler
                 final Map<String, ValidatorFactory> validatorFactories = new 
HashMap<String, ValidatorFactory>();
 
                 for (final CommonInfoObject info : vfs) {
-                    ValidatorFactory factory = null;
-                    try { // lazy cause of CDI :(
-                        final LazyValidatorFactory handler = new 
LazyValidatorFactory(classLoader, info.validationInfo);
-                        factory = (ValidatorFactory) Proxy.newProxyInstance(
-                            appContext.getClassLoader(), 
VALIDATOR_FACTORY_INTERFACES, handler);
-                        lazyValidatorFactories.put(info.uniqueId, handler);
-                    } catch (final ValidationException ve) {
-                        logger.warning("can't build the validation factory for 
module " + info.uniqueId, ve);
-                        continue;
+                    final ComparableValidationConfig conf = new 
ComparableValidationConfig(
+                            info.validationInfo.providerClassName, 
info.validationInfo.messageInterpolatorClass,
+                            info.validationInfo.traversableResolverClass, 
info.validationInfo.constraintFactoryClass,
+                            info.validationInfo.parameterNameProviderClass, 
info.validationInfo.version,
+                            info.validationInfo.propertyTypes, 
info.validationInfo.constraintMappings,
+                            info.validationInfo.executableValidationEnabled, 
info.validationInfo.validatedTypes
+                    );
+                    ValidatorFactory factory = 
validatorFactoriesByConfig.get(conf);
+                    if (factory == null) {
+                        try { // lazy cause of CDI :(
+                            final LazyValidatorFactory handler = new 
LazyValidatorFactory(classLoader, info.validationInfo);
+                            factory = (ValidatorFactory) 
Proxy.newProxyInstance(
+                                    appContext.getClassLoader(), 
VALIDATOR_FACTORY_INTERFACES, handler);
+                            lazyValidatorFactories.put(info.uniqueId, handler);
+                        } catch (final ValidationException ve) {
+                            logger.warning("can't build the validation factory 
for module " + info.uniqueId, ve);
+                            continue;
+                        }
+                        validatorFactoriesByConfig.put(conf, factory);
+                    } else {
+                        lazyValidatorFactories.put(info.uniqueId, 
LazyValidatorFactory.class.cast(Proxy.getInvocationHandler(factory)));
                     }
                     validatorFactories.put(info.uniqueId, factory);
                 }
@@ -767,7 +782,7 @@ public class Assembler extends Assembler
             for (final PersistenceUnitInfo info : appInfo.persistenceUnits) {
                 final ReloadableEntityManagerFactory factory;
                 try {
-                    factory = 
persistenceBuilder.createEntityManagerFactory(info, classLoader);
+                    factory = 
persistenceBuilder.createEntityManagerFactory(info, classLoader, 
validatorFactoriesByConfig);
                     
containerSystem.getJNDIContext().bind(PERSISTENCE_UNIT_NAMING_CONTEXT + 
info.id, factory);
                     units.put(info.name, PERSISTENCE_UNIT_NAMING_CONTEXT + 
info.id);
                 } catch (final NameAlreadyBoundException e) {

Added: 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ComparableValidationConfig.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ComparableValidationConfig.java?rev=1629580&view=auto
==============================================================================
--- 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ComparableValidationConfig.java
 (added)
+++ 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ComparableValidationConfig.java
 Mon Oct  6 07:24:30 2014
@@ -0,0 +1,101 @@
+/*
+ * 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.assembler.classic;
+
+import java.util.List;
+import java.util.Properties;
+
+public class ComparableValidationConfig {
+    private final String providerClassName;
+    private final String messageInterpolatorClass;
+    private final String traversableResolverClass;
+    private final String constraintFactoryClass;
+    private final String parameterNameProviderClass;
+    private final String version;
+    private final Properties propertyTypes;
+    private final List<String> constraintMappings;
+    private final boolean executableValidationEnabled;
+    private final List<String> validatedTypes;
+
+    private final int hash;
+
+    public ComparableValidationConfig(final String providerClassName, final 
String messageInterpolatorClass,
+                                      final String traversableResolverClass, 
final String constraintFactoryClass,
+                                      final String parameterNameProviderClass, 
final String version,
+                                      final Properties propertyTypes, final 
List<String> constraintMappings,
+                                      final boolean 
executableValidationEnabled, final List<String> validatedTypes) {
+        this.providerClassName = providerClassName;
+        this.messageInterpolatorClass = messageInterpolatorClass;
+        this.traversableResolverClass = traversableResolverClass;
+        this.constraintFactoryClass = constraintFactoryClass;
+        this.parameterNameProviderClass = parameterNameProviderClass;
+        this.version = version;
+        this.propertyTypes = propertyTypes;
+        this.constraintMappings = constraintMappings;
+        this.executableValidationEnabled = executableValidationEnabled;
+        this.validatedTypes = validatedTypes;
+
+        int result = providerClassName != null ? providerClassName.hashCode() 
: 0;
+        result = 31 * result + (messageInterpolatorClass != null ? 
messageInterpolatorClass.hashCode() : 0);
+        result = 31 * result + (traversableResolverClass != null ? 
traversableResolverClass.hashCode() : 0);
+        result = 31 * result + (constraintFactoryClass != null ? 
constraintFactoryClass.hashCode() : 0);
+        result = 31 * result + (parameterNameProviderClass != null ? 
parameterNameProviderClass.hashCode() : 0);
+        result = 31 * result + (version != null ? version.hashCode() : 0);
+        result = 31 * result + (propertyTypes != null ? 
propertyTypes.hashCode() : 0);
+        result = 31 * result + (constraintMappings != null ? 
constraintMappings.hashCode() : 0);
+        result = 31 * result + (executableValidationEnabled ? 1 : 0);
+        result = 31 * result + (validatedTypes != null ? 
validatedTypes.hashCode() : 0);
+        hash = result;
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final ComparableValidationConfig that = (ComparableValidationConfig) o;
+
+        if (executableValidationEnabled != that.executableValidationEnabled) 
return false;
+        if (constraintFactoryClass != null ? 
!constraintFactoryClass.equals(that.constraintFactoryClass) : 
that.constraintFactoryClass != null)
+            return false;
+        if (constraintMappings != null ? 
!constraintMappings.equals(that.constraintMappings) : that.constraintMappings 
!= null)
+            return false;
+        if (messageInterpolatorClass != null ? 
!messageInterpolatorClass.equals(that.messageInterpolatorClass) : 
that.messageInterpolatorClass != null)
+            return false;
+        if (parameterNameProviderClass != null ? 
!parameterNameProviderClass.equals(that.parameterNameProviderClass) : 
that.parameterNameProviderClass != null)
+            return false;
+        if (propertyTypes != null ? !propertyTypes.equals(that.propertyTypes) 
: that.propertyTypes != null)
+            return false;
+        if (providerClassName != null ? 
!providerClassName.equals(that.providerClassName) : that.providerClassName != 
null)
+            return false;
+        if (traversableResolverClass != null ? 
!traversableResolverClass.equals(that.traversableResolverClass) : 
that.traversableResolverClass != null)
+            return false;
+        if (validatedTypes != null ? 
!validatedTypes.equals(that.validatedTypes) : that.validatedTypes != null)
+            return false;
+        if (version != null ? !version.equals(that.version) : that.version != 
null) return false;
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return hash;
+    }
+}

Modified: 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EntityManagerFactoryCallable.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EntityManagerFactoryCallable.java?rev=1629580&r1=1629579&r2=1629580&view=diff
==============================================================================
--- 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EntityManagerFactoryCallable.java
 (original)
+++ 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EntityManagerFactoryCallable.java
 Mon Oct  6 07:24:30 2014
@@ -23,6 +23,7 @@ import org.apache.openejb.persistence.Pe
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.ValidationMode;
 import javax.persistence.spi.PersistenceProvider;
+import javax.validation.ValidatorFactory;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.Callable;
@@ -33,12 +34,15 @@ public class EntityManagerFactoryCallabl
 
     private final String persistenceProviderClassName;
     private final PersistenceUnitInfoImpl unitInfo;
+    private final Map<ComparableValidationConfig, ValidatorFactory> 
potentialValidators;
     private ClassLoader appClassLoader;
 
-    public EntityManagerFactoryCallable(final String 
persistenceProviderClassName, final PersistenceUnitInfoImpl unitInfo, final 
ClassLoader cl) {
+    public EntityManagerFactoryCallable(final String 
persistenceProviderClassName, final PersistenceUnitInfoImpl unitInfo,
+                                        final ClassLoader cl, final 
Map<ComparableValidationConfig, ValidatorFactory> validators) {
         this.persistenceProviderClassName = persistenceProviderClassName;
         this.unitInfo = unitInfo;
         this.appClassLoader = cl;
+        this.potentialValidators = validators;
     }
 
     @Override
@@ -52,7 +56,7 @@ public class EntityManagerFactoryCallabl
             // Create entity manager factories with the validator factory
             final Map<String, Object> properties = new HashMap<String, 
Object>();
             if (!ValidationMode.NONE.equals(unitInfo.getValidationMode())) {
-                properties.put("javax.persistence.validator.ValidatorFactory", 
new ValidatorFactoryWrapper());
+                properties.put("javax.persistence.validation.factory", new 
ValidatorFactoryWrapper(potentialValidators));
             }
 
             customizeProperties(properties);

Modified: 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/PersistenceBuilder.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/PersistenceBuilder.java?rev=1629580&r1=1629579&r2=1629580&view=diff
==============================================================================
--- 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/PersistenceBuilder.java
 (original)
+++ 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/PersistenceBuilder.java
 Mon Oct  6 07:24:30 2014
@@ -32,6 +32,8 @@ import javax.persistence.SharedCacheMode
 import javax.persistence.ValidationMode;
 import javax.persistence.spi.PersistenceUnitTransactionType;
 import javax.sql.DataSource;
+import javax.validation.ValidatorFactory;
+import java.util.Map;
 
 public class PersistenceBuilder {
 
@@ -46,7 +48,8 @@ public class PersistenceBuilder {
         this.persistenceClassLoaderHandler = persistenceClassLoaderHandler;
     }
 
-    public ReloadableEntityManagerFactory createEntityManagerFactory(final 
PersistenceUnitInfo info, final ClassLoader classLoader) throws Exception {
+    public ReloadableEntityManagerFactory createEntityManagerFactory(final 
PersistenceUnitInfo info, final ClassLoader classLoader,
+                                                                     final 
Map<ComparableValidationConfig, ValidatorFactory> validators) throws Exception {
         final PersistenceUnitInfoImpl unitInfo = new 
PersistenceUnitInfoImpl(persistenceClassLoaderHandler);
 
         // Persistence Unit Id
@@ -147,7 +150,7 @@ public class PersistenceBuilder {
         final String persistenceProviderClassName = 
unitInfo.getPersistenceProviderClassName();
         unitInfo.setPersistenceProviderClassName(persistenceProviderClassName);
 
-        final EntityManagerFactoryCallable callable = new 
EntityManagerFactoryCallable(persistenceProviderClassName, unitInfo, 
classLoader);
+        final EntityManagerFactoryCallable callable = new 
EntityManagerFactoryCallable(persistenceProviderClassName, unitInfo, 
classLoader, validators);
         return new ReloadableEntityManagerFactory(classLoader, callable, 
unitInfo);
     }
 

Modified: 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ValidatorFactoryWrapper.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ValidatorFactoryWrapper.java?rev=1629580&r1=1629579&r2=1629580&view=diff
==============================================================================
--- 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ValidatorFactoryWrapper.java
 (original)
+++ 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ValidatorFactoryWrapper.java
 Mon Oct  6 07:24:30 2014
@@ -21,6 +21,7 @@ import org.apache.openejb.bval.Validator
 import org.apache.openejb.util.LogCategory;
 import org.apache.openejb.util.Logger;
 
+import javax.naming.NamingException;
 import javax.validation.ConstraintValidatorFactory;
 import javax.validation.MessageInterpolator;
 import javax.validation.ParameterNameProvider;
@@ -29,12 +30,26 @@ import javax.validation.Validator;
 import javax.validation.ValidatorContext;
 import javax.validation.ValidatorFactory;
 import java.io.Serializable;
+import java.util.Map;
 
 public class ValidatorFactoryWrapper implements ValidatorFactory, Serializable 
{
     public static final Logger logger = 
Logger.getInstance(LogCategory.OPENEJB, ValidatorFactoryWrapper.class);
 
-    private static ValidatorFactory factory() {
-        return ValidatorUtil.validatorFactory();
+    private final Map<ComparableValidationConfig, ValidatorFactory> 
fallbackValidators;
+
+    private ValidatorFactory factory() {
+        try {
+            return ValidatorUtil.lookupFactory();
+        } catch (final NamingException e) { // in absolute we should sort them 
to get the closest one of the persistence-unit?
+            if (!fallbackValidators.isEmpty()) {
+                return fallbackValidators.values().iterator().next();
+            }
+            return ValidatorUtil.tryJndiLaterFactory();
+        }
+    }
+
+    public ValidatorFactoryWrapper(final Map<ComparableValidationConfig, 
ValidatorFactory> validators) {
+        fallbackValidators = validators;
     }
 
     @Override

Modified: 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/bval/ValidatorUtil.java
URL: 
http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/bval/ValidatorUtil.java?rev=1629580&r1=1629579&r2=1629580&view=diff
==============================================================================
--- 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/bval/ValidatorUtil.java
 (original)
+++ 
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/bval/ValidatorUtil.java
 Mon Oct  6 07:24:30 2014
@@ -43,12 +43,20 @@ public final class ValidatorUtil {
 
     public static ValidatorFactory validatorFactory() {
         try {
-            return (ValidatorFactory) new 
InitialContext().lookup("java:comp/ValidatorFactory");
+            return lookupFactory();
         } catch (final NamingException e) {
-            return proxy(ValidatorFactory.class, "java:comp/ValidatorFactory");
+            return tryJndiLaterFactory();
         }
     }
 
+    public static ValidatorFactory lookupFactory() throws NamingException {
+        return (ValidatorFactory) new 
InitialContext().lookup("java:comp/ValidatorFactory");
+    }
+
+    public static ValidatorFactory tryJndiLaterFactory() {
+        return proxy(ValidatorFactory.class, "java:comp/ValidatorFactory");
+    }
+
     public static Validator validator() {
         try {
             return (Validator) new 
InitialContext().lookup("java:comp/Validator");
@@ -113,7 +121,9 @@ public final class ValidatorUtil {
                                     }
                                 }
                             }
-                            break;
+                            if (ClassLoader.getSystemClassLoader() != 
appContextClassLoader) {
+                                break;
+                            } // else we surely have a single AppContext so 
let's try WebContext
                         }
                         for (final WebContext web : 
appContext.getWebContexts()) {
                             final ClassLoader webClassLoader = 
web.getClassLoader();


Reply via email to