You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bval.apache.org by mb...@apache.org on 2010/10/05 21:35:30 UTC
svn commit: r1004783 - in
/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic:
DynamicMetaGraphManagerImpl.java DynamicModel.java
Author: mbenson
Date: Tue Oct 5 19:35:30 2010
New Revision: 1004783
URL: http://svn.apache.org/viewvc?rev=1004783&view=rev
Log:
merge, rather than simply copy, features whenever possible
Modified:
incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManagerImpl.java
incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicModel.java
Modified: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManagerImpl.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManagerImpl.java?rev=1004783&r1=1004782&r2=1004783&view=diff
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManagerImpl.java (original)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManagerImpl.java Tue Oct 5 19:35:30 2010
@@ -16,8 +16,7 @@
*/
package org.apache.bval.jsr303.dynamic;
-import static org.apache.bval.jsr303.dynamic.DynamicModel.copyConstraints;
-import static org.apache.bval.jsr303.dynamic.DynamicModel.copyFeatures;
+import static org.apache.bval.jsr303.dynamic.DynamicModel.mergeFeatures;
import static org.apache.bval.jsr303.dynamic.DynamicModel.getRequiredContainer;
import static org.apache.bval.jsr303.dynamic.DynamicModel.getRequiredProperty;
import static org.apache.bval.jsr303.dynamic.DynamicModel.Features.DYNAMIC_CONSTRAINT_COLLECTION;
@@ -265,13 +264,11 @@ final class DynamicMetaGraphManagerImpl
}
// copy bean + property features and constraints:
- copyFeatures(result, leaf);
- copyConstraints(result, leaf);
+ mergeFeatures(result, leaf);
for (MetaProperty sourceProperty : leaf.getProperties()) {
MetaProperty targetProperty = getRequiredProperty(result, sourceProperty.getName());
- copyFeatures(targetProperty, sourceProperty);
- copyConstraints(targetProperty, sourceProperty);
+ mergeFeatures(targetProperty, sourceProperty);
}
}
Modified: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicModel.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicModel.java?rev=1004783&r1=1004782&r2=1004783&view=diff
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicModel.java (original)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicModel.java Tue Oct 5 19:35:30 2010
@@ -19,13 +19,20 @@ package org.apache.bval.jsr303.dynamic;
import static org.apache.bval.jsr303.dynamic.DynamicModel.Features.*;
import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
+import java.lang.reflect.Array;
import java.lang.reflect.Type;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
import java.util.SortedSet;
+import java.util.TreeMap;
import java.util.TreeSet;
import org.apache.bval.jsr303.ConstraintValidation;
@@ -57,19 +64,6 @@ public class DynamicModel {
}
- private static final SortedSet<String> FEATURE_KEYS;
- static {
- TreeSet<String> featureKeys = new TreeSet<String>();
- for (Field f : Features.class.getDeclaredFields()) {
- try {
- featureKeys.add((String) f.get(null));
- } catch (Exception e) {
- // dunno, shouldn't happen
- }
- }
- FEATURE_KEYS = Collections.unmodifiableSortedSet(featureKeys);
- }
-
private DynamicModel() {
}
@@ -88,8 +82,7 @@ public class DynamicModel {
for (MetaProperty property : source.getProperties()) {
copy(getRequiredProperty(target, property.getName()), property);
}
- copyFeatures(target, source);
- copyConstraints(target, source);
+ mergeFeatures(target, source);
}
/**
@@ -144,8 +137,7 @@ public class DynamicModel {
* @param source
*/
public static void copy(MetaProperty target, MetaProperty source) {
- copyFeatures(target, source);
- copyConstraints(target, source);
+ mergeFeatures(target, source);
if (KeyedAccess.getJavaElementType(source.getType()) != null
|| IndexedAccess.getJavaElementType(source.getType()) != null) {
@@ -193,12 +185,64 @@ public class DynamicModel {
}
/**
- * Copy constraints from source to target meta.
+ * Get or create the dynamic constraints collection from <code>meta</code>.
+ *
+ * @param meta
+ * @return Collection<Annotation>
+ */
+ public static Collection<Annotation> getRequiredDynamicConstraints(FeaturesCapable meta) {
+ Collection<Annotation> result = meta.getFeature(DYNAMIC_CONSTRAINT_COLLECTION);
+ if (result == null) {
+ result = Collections.synchronizedList(new ArrayList<Annotation>());
+ meta.optimizeRead(false);
+ meta.putFeature(DYNAMIC_CONSTRAINT_COLLECTION, result);
+ meta.optimizeRead(true);
+ }
+ return result;
+ }
+
+ /**
+ * Copy features that are not members of {@link DynamicModel.Features}
*
* @param target
* @param source
*/
- public static boolean copyConstraints(FeaturesCapable target, FeaturesCapable source) {
+ public static void mergeFeatures(FeaturesCapable target, FeaturesCapable source) {
+ for (Map.Entry<String, Object> e : source.getFeatures().entrySet()) {
+ if (DYNAMIC_CONSTRAINT_COLLECTION.equals(e.getKey())) {
+ mergeConstraints(target, source);
+ } else if (META_CONTAINER.contains(e.getKey())) {
+ continue;
+ } else {
+ Object targetValue = target.getFeature(e.getKey());
+ target.putFeature(e.getKey(), mergeFeatureValues(targetValue, e.getValue()));
+ }
+ }
+ }
+
+ private static <T> T mergeFeatureValues(T target, T source) {
+ if (target == null || source == null) {
+ return source;
+ }
+ if (source.getClass().isArray() && !source.getClass().getComponentType().isPrimitive()) {
+ @SuppressWarnings("unchecked")
+ T result = (T) mergeArrays((Object[]) target, (Object[]) source);
+ return result;
+ }
+ if (source instanceof Collection<?> && target instanceof Collection<?>) {
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ T result = (T) mergeCollections((Collection) target, (Collection) source);
+ return result;
+ }
+ if (source instanceof Map<?, ?> && target instanceof Map<?, ?>) {
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ T result = (T) mergeMaps((Map) target, (Map) source);
+ return result;
+ }
+ return source;
+ }
+
+ private static boolean mergeConstraints(FeaturesCapable target, FeaturesCapable source) {
Collection<Annotation> targetConstraints = target.getFeature(DYNAMIC_CONSTRAINT_COLLECTION);
Collection<Annotation> sourceConstraints = source.getFeature(DYNAMIC_CONSTRAINT_COLLECTION);
if (sourceConstraints == null || sourceConstraints.isEmpty()) {
@@ -228,35 +272,45 @@ public class DynamicModel {
return result;
}
- /**
- * Get or create the dynamic constraints collection from <code>meta</code>.
- *
- * @param meta
- * @return Collection<Annotation>
- */
- public static Collection<Annotation> getRequiredDynamicConstraints(FeaturesCapable meta) {
- Collection<Annotation> result = meta.getFeature(DYNAMIC_CONSTRAINT_COLLECTION);
- if (result == null) {
- result = Collections.synchronizedList(new ArrayList<Annotation>());
- meta.optimizeRead(false);
- meta.putFeature(DYNAMIC_CONSTRAINT_COLLECTION, result);
- meta.optimizeRead(true);
+ private static <T> T[] mergeArrays(T[] target, T[] source) {
+ LinkedHashSet<T> targetSet = new LinkedHashSet<T>();
+ Collections.addAll(targetSet, target);
+ Collection<T> coll = mergeCollections(targetSet, Arrays.asList(source));
+ @SuppressWarnings("unchecked")
+ T[] result = (T[]) Array.newInstance(source.getClass().getComponentType(), coll.size());
+ return coll.toArray(result);
+ }
+
+ private static <E> Collection<E> mergeCollections(Collection<? extends E> target, Collection<? extends E> source) {
+ Collection<E> result;
+ if (target instanceof SortedSet<?>) {
+ @SuppressWarnings("unchecked")
+ Comparator<? super E> cmp = ((SortedSet<E>) target).comparator();
+ result = cmp == null ? new TreeSet<E>() : new TreeSet<E>(cmp);
+ } else if (target instanceof Set<?>) {
+ result = new LinkedHashSet<E>();
+ } else {
+ result = new ArrayList<E>();
}
+ result.addAll(target);
+ result.addAll(source);
return result;
}
- /**
- * Copy features that are not members of {@link DynamicModel.Features}
- *
- * @param target
- * @param source
- */
- public static void copyFeatures(FeaturesCapable target, FeaturesCapable source) {
- for (Map.Entry<String, Object> e : source.getFeatures().entrySet()) {
- if (FEATURE_KEYS.contains(e.getKey())) {
- continue;
- }
- target.putFeature(e.getKey(), e.getValue());
+ private static <K, V> Map<K, V> mergeMaps(Map<? extends K, ? extends V> target, Map<? extends K, ? extends V> source) {
+ Map<K, V> result;
+ if (target instanceof SortedMap<?, ?>) {
+ @SuppressWarnings("unchecked")
+ Comparator<? super K> cmp = ((SortedMap<K, V>) target).comparator();
+ result = cmp == null ? new TreeMap<K, V>() : new TreeMap<K, V>(cmp);
+ } else {
+ result = new HashMap<K, V>();
+ }
+ result.putAll(target);
+ for (Map.Entry<? extends K, ? extends V> e : source.entrySet()) {
+ V targetValue = result.get(e.getKey());
+ result.put(e.getKey(), mergeFeatureValues(targetValue, e.getValue()));
}
+ return result;
}
}