You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bval.apache.org by rm...@apache.org on 2013/08/14 17:35:27 UTC
svn commit: r1513933 - in /bval/branches/bval-11:
bval-core/src/main/java/org/apache/bval/MetaBeanManager.java
bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java
Author: rmannibucau
Date: Wed Aug 14 15:35:27 2013
New Revision: 1513933
URL: http://svn.apache.org/r1513933
Log:
better locking when concurrently trying to create the same metadata in MetaBeanManager
Modified:
bval/branches/bval-11/bval-core/src/main/java/org/apache/bval/MetaBeanManager.java
bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java
Modified: bval/branches/bval-11/bval-core/src/main/java/org/apache/bval/MetaBeanManager.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-core/src/main/java/org/apache/bval/MetaBeanManager.java?rev=1513933&r1=1513932&r2=1513933&view=diff
==============================================================================
--- bval/branches/bval-11/bval-core/src/main/java/org/apache/bval/MetaBeanManager.java (original)
+++ bval/branches/bval-11/bval-core/src/main/java/org/apache/bval/MetaBeanManager.java Wed Aug 14 15:35:27 2013
@@ -19,7 +19,12 @@ package org.apache.bval;
import org.apache.bval.model.MetaBean;
import org.apache.bval.model.MetaProperty;
-import static org.apache.bval.model.Features.Property.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import static org.apache.bval.model.Features.Property.REF_BEAN_ID;
+import static org.apache.bval.model.Features.Property.REF_BEAN_TYPE;
+import static org.apache.bval.model.Features.Property.REF_CASCADE;
/**
* Description: Default implementation for the interface to find, register and
@@ -36,6 +41,8 @@ public class MetaBeanManager implements
/** Complete flag */
protected boolean complete = false;
+ protected final ConcurrentMap<Object, Object> cacheLocks = new ConcurrentHashMap<Object, Object>();
+
/**
* Create a new MetaBeanManager instance.
*/
@@ -73,40 +80,69 @@ public class MetaBeanManager implements
/**
* {@inheritDoc}
*/
- public MetaBean findForId(String beanInfoId) {
+ public MetaBean findForId(final String beanInfoId) {
MetaBean beanInfo = cache.findForId(beanInfoId);
- if (beanInfo != null)
+ if (beanInfo != null) {
return beanInfo;
- try {
- beanInfo = builder.buildForId(beanInfoId);
- cache.cache(beanInfo);
- computeRelationships(beanInfo);
- return beanInfo;
- } catch (RuntimeException e) {
- throw e; // do not wrap runtime exceptions
- } catch (Exception e) {
- throw new IllegalArgumentException("error creating beanInfo with id: " + beanInfoId, e);
+ }
+
+ synchronized (getLockFor(beanInfoId)) {
+ beanInfo = cache.findForId(beanInfoId);
+ if (beanInfo != null) {
+ return beanInfo;
+ }
+
+ try {
+ beanInfo = builder.buildForId(beanInfoId);
+ cache.cache(beanInfo);
+ computeRelationships(beanInfo);
+ return beanInfo;
+ } catch (final RuntimeException e) {
+ throw e; // do not wrap runtime exceptions
+ } catch (final Exception e) {
+ throw new IllegalArgumentException("error creating beanInfo with id: " + beanInfoId, e);
+ }
}
}
+ private Object getLockFor(final Object key) {
+ final Object newLock = new Object();
+ Object lock = cacheLocks.putIfAbsent(key, newLock);
+ if (lock == null) {
+ lock = newLock;
+ }
+ return lock;
+ }
+
/**
* {@inheritDoc}
*/
- public MetaBean findForClass(Class<?> clazz) {
- if (clazz == null)
+ public MetaBean findForClass(final Class<?> clazz) {
+ if (clazz == null) {
return null;
+ }
+
MetaBean beanInfo = cache.findForClass(clazz);
- if (beanInfo != null)
+ if (beanInfo != null) {
return beanInfo;
- try {
- beanInfo = builder.buildForClass(clazz);
- cache.cache(beanInfo);
- computeRelationships(beanInfo);
- return beanInfo;
- } catch (RuntimeException e) {
- throw e; // do not wrap runtime exceptions
- } catch (Exception e) {
- throw new IllegalArgumentException("error creating beanInfo for " + clazz, e);
+ }
+
+ synchronized (getLockFor(clazz)) {
+ beanInfo = cache.findForClass(clazz);
+ if (beanInfo != null) {
+ return beanInfo;
+ }
+
+ try {
+ beanInfo = builder.buildForClass(clazz);
+ cache.cache(beanInfo);
+ computeRelationships(beanInfo);
+ return beanInfo;
+ } catch (final RuntimeException e) {
+ throw e; // do not wrap runtime exceptions
+ } catch (final Exception e) {
+ throw new IllegalArgumentException("error creating beanInfo for " + clazz, e);
+ }
}
}
@@ -118,8 +154,8 @@ public class MetaBeanManager implements
* - the bean for which to compute relationships
*/
protected void computeRelationships(MetaBean beanInfo) {
- for (MetaProperty prop : beanInfo.getProperties()) {
- String beanRef = (String) prop.getFeature(REF_BEAN_ID);
+ for (final MetaProperty prop : beanInfo.getProperties()) {
+ final String beanRef = prop.getFeature(REF_BEAN_ID);
computeRelatedMetaBean(prop, beanRef);
}
}
Modified: bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java?rev=1513933&r1=1513932&r2=1513933&view=diff
==============================================================================
--- bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java (original)
+++ bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java Wed Aug 14 15:35:27 2013
@@ -100,6 +100,8 @@ public class ClassValidator implements C
*/
protected final GroupsComputer groupsComputer = new GroupsComputer();
+ private final MetaBeanFinder metaBeanFinder;
+
/**
* Create a new ClassValidator instance.
*
@@ -107,16 +109,7 @@ public class ClassValidator implements C
*/
public ClassValidator(ApacheFactoryContext factoryContext) {
this.factoryContext = factoryContext;
- }
-
- /**
- * Get the metabean finder associated with this validator.
- *
- * @return a MetaBeanFinder
- * @see org.apache.bval.MetaBeanManagerFactory#getFinder()
- */
- protected MetaBeanFinder getMetaBeanFinder() {
- return factoryContext.getMetaBeanFinder();
+ metaBeanFinder = factoryContext.getMetaBeanFinder();
}
// Validator implementation
@@ -144,7 +137,7 @@ public class ClassValidator implements C
try {
final Class<T> objectClass = (Class<T>) object.getClass();
- final MetaBean objectMetaBean = getMetaBeanFinder().findForClass(objectClass);
+ final MetaBean objectMetaBean = metaBeanFinder.findForClass(objectClass);
final GroupValidationContext<T> context = createContext(objectMetaBean, object, objectClass, groups);
return validateBeanWithGroups(context, context.getGroups());
} catch (final RuntimeException ex) {
@@ -266,7 +259,7 @@ public class ClassValidator implements C
throw new IllegalArgumentException("Class cannot be null");
}
try {
- MetaBean metaBean = getMetaBeanFinder().findForClass(clazz); // don't throw an exception because of a missing validator here
+ MetaBean metaBean = metaBeanFinder.findForClass(clazz); // don't throw an exception because of a missing validator here
BeanDescriptorImpl edesc = metaBean.getFeature(Jsr303Features.Bean.BEAN_DESCRIPTOR);
if (edesc == null) {
edesc = createBeanDescriptor(metaBean);
@@ -1248,7 +1241,7 @@ public class ClassValidator implements C
checkGroups(groups);
try {
- final MetaBean initialMetaBean = new DynamicMetaBean(getMetaBeanFinder());
+ final MetaBean initialMetaBean = new DynamicMetaBean(metaBeanFinder);
initialMetaBean.setBeanClass(beanType);
GroupValidationContext<T> context = createContext(initialMetaBean, object, beanType, groups);
ValidationContextTraversal contextTraversal = createValidationContextTraversal(context);
@@ -1259,7 +1252,7 @@ public class ClassValidator implements C
if (value != VALIDATE_PROPERTY) {
assert !context.getPropertyPath().isRootPath();
if (prop == null && value != null) {
- context.setMetaBean(getMetaBeanFinder().findForClass(value.getClass()));
+ context.setMetaBean(metaBeanFinder.findForClass(value.getClass()));
}
if (!cascade) {
//TCK doesn't care what type a property is if there are no constraints to validate: