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;
     }
 }