geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gno...@apache.org
Subject svn commit: r785996 - in /geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint: container/ di/ utils/
Date Thu, 18 Jun 2009 10:06:07 GMT
Author: gnodet
Date: Thu Jun 18 10:06:00 2009
New Revision: 785996

URL: http://svn.apache.org/viewvc?rev=785996&view=rev
Log:
Refactor the map / collection / array conversion inside the AggregateConverter now that the
interface allows it

Removed:
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/ConversionUtils.java
Modified:
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/AggregateConverter.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintRepository.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/RefListRecipe.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/ReferenceRecipe.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/di/CollectionRecipe.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/di/MapRecipe.java
    geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/TypeUtils.java

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/AggregateConverter.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/AggregateConverter.java?rev=785996&r1=785995&r2=785996&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/AggregateConverter.java
(original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/AggregateConverter.java
Thu Jun 18 10:06:00 2009
@@ -20,15 +20,22 @@
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Type;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Array;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Properties;
+import java.util.Collection;
+import java.util.Map;
 import java.util.regex.Pattern;
 
 import org.apache.geronimo.blueprint.ExtendedBlueprintContainer;
+import org.apache.geronimo.blueprint.di.MapRecipe;
+import org.apache.geronimo.blueprint.di.CollectionRecipe;
 import static org.apache.geronimo.blueprint.utils.ReflectionUtils.getRealCause;
 import org.apache.geronimo.blueprint.utils.TypeUtils;
+import static org.apache.geronimo.blueprint.utils.TypeUtils.toClass;
 import org.osgi.service.blueprint.container.Converter;
 
 /**
@@ -81,17 +88,33 @@
     }
 
     public Object convert(Object fromValue, Object toType) throws Exception {
+        // Discard null values
         if (fromValue == null) {
             return null;
         }
         Type type = (Type) toType;
-        if (TypeUtils.isInstance(type, fromValue)) {
+        // First convert service proxies
+        if (fromValue instanceof Convertible) {
+            return ((Convertible) fromValue).convert(type);
+        }
+        // If the object is an instance of the type, just return it
+        // We need to pass through for arrays / maps / collections because of genenrics
+        if (TypeUtils.isInstance(type, fromValue)
+                && !toClass(type).isArray()
+                && !Map.class.isAssignableFrom(toClass(type))
+                && !Collection.class.isAssignableFrom(toClass(type))) {
             return fromValue;
         }
-        Object value = doConvert(fromValue, type);        
+        Object value = convertWithConverters(fromValue, type);
         if (value == null) {
             if (fromValue instanceof String && toType instanceof Class) {
-                return convertString((String) fromValue, (Class) type);
+                return convertFromString((String) fromValue, (Class) type, blueprintContainer);
+            } else if (toClass(type).isArray()) {
+                return convertArray(fromValue, type);
+            } else if (Map.class.isAssignableFrom(toClass(type))) {
+                return convertMap(fromValue, type);
+            } else if (Collection.class.isAssignableFrom(toClass(type))) {
+                return convertCollection(fromValue, type);
             } else {
                 throw new Exception("Unable to convert value " + fromValue + " to type "
+ type);
             }
@@ -100,7 +123,7 @@
         }
     }
 
-    private Object doConvert(Object source, Type type) throws Exception {
+    private Object convertWithConverters(Object source, Type type) throws Exception {
         Object value = null;
         for (Converter converter : converters) {
             if (converter.canConvert(source, type)) {
@@ -113,20 +136,14 @@
         return value;
     }
 
-    private Object convertString(String value, Class toType) throws Exception {
-        if (Class.class == toType) {
+    public static Object convertFromString(String value, Class toType, Object loader) throws
Exception {
+        if (Class.class == toType || Type.class == toType) {
             try {
-                return blueprintContainer.loadClass(value);
+                return TypeUtils.parseJavaType(value, loader);
             } catch (ClassNotFoundException e) {
                 throw new Exception("Unable to convert", e);
             }
-        } else {
-            return defaultConversion(value, toType);
-        }
-    }
-
-    public static Object defaultConversion(String value, Class toType) throws Exception {
-        if (Locale.class == toType) {
+        } else if (Locale.class == toType) {
             String[] tokens = value.split("_");
             if (tokens.length == 1) {
                 return new Locale(tokens[0]);
@@ -167,7 +184,7 @@
                 int code = Integer.parseInt(value.substring(2), 16);
                 return (char)code;
             } else if (value.length() == 1) {
-                return Character.valueOf(value.charAt(0));
+                return value.charAt(0);
             } else {
                 throw new Exception("Invalid value for character type: " + value);
             }
@@ -197,4 +214,79 @@
         }
     }
 
+    private Object convertCollection(Object obj, Type type) throws Exception {
+        Type valueType = Object.class;
+        Type[] typeParameters = TypeUtils.getTypeParameters(Collection.class, type);
+        if (typeParameters != null && typeParameters.length == 1) {
+            valueType = typeParameters[0];
+        }
+        Collection newCol = (Collection) CollectionRecipe.getCollection(toClass(type)).newInstance();
+        if (obj.getClass().isArray()) {
+            for (int i = 0; i < Array.getLength(obj); i++) {
+                try {
+                    newCol.add(convert(Array.get(obj, i), valueType));
+                } catch (Exception t) {
+                    throw new Exception("Unable to convert from " + obj + " to " + type +
"(error converting array element)", t);
+                }
+            }
+        } else {
+            for (Object item : (Collection) obj) {
+                try {
+                    newCol.add(convert(item, valueType));
+                } catch (Exception t) {
+                    throw new Exception("Unable to convert from " + obj + " to " + type +
"(error converting collection entry)", t);
+                }
+            }
+        }
+        return newCol;
+    }
+
+    private Object convertMap(Object obj, Type type) throws Exception {
+        Type keyType = Object.class;
+        Type valueType = Object.class;
+        Type[] typeParameters = TypeUtils.getTypeParameters(Map.class, type);
+        if (typeParameters != null && typeParameters.length == 2) {
+            keyType = typeParameters[0];
+            valueType = typeParameters[1];
+        }
+        Map newMap = (Map) MapRecipe.getMap(toClass(type)).newInstance();
+        for (Map.Entry e : ((Map<Object,Object>) obj).entrySet()) {
+            try {
+                newMap.put(convert(e.getKey(), keyType), convert(e.getValue(), valueType));
+            } catch (Exception t) {
+                throw new Exception("Unable to convert from " + obj + " to " + type + "(error
converting map entry)", t);
+            }
+        }
+        return newMap;
+    }
+
+    private Object convertArray(Object obj, Type type) throws Exception {
+        if (obj instanceof Collection) {
+            obj = ((Collection) obj).toArray();
+        }
+        if (!obj.getClass().isArray()) {
+            throw new Exception("Unable to convert from " + obj + " to " + type);
+        }
+        Type componentType = type instanceof GenericArrayType
+                                    ? ((GenericArrayType) type).getGenericComponentType()
+                                    : toClass(type).getComponentType();
+        Object array = Array.newInstance(TypeUtils.toClass(componentType), Array.getLength(obj));
+        for (int i = 0; i < Array.getLength(obj); i++) {
+            try {
+                Array.set(array, i, convert(Array.get(obj, i), componentType));
+            } catch (Exception t) {
+                throw new Exception("Unable to convert from " + obj + " to " + type + "(error
converting array element)", t);
+            }
+        }
+        return array;
+    }
+
+    /**
+     * Objects implementing this interface will bypass the default conversion rules
+     * and be called directly to transform into the expected type.
+     */
+    public static interface Convertible {
+
+        Object convert(Type type) throws Exception;
+    }
 }
\ No newline at end of file

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintRepository.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintRepository.java?rev=785996&r1=785995&r2=785996&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintRepository.java
(original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintRepository.java
Thu Jun 18 10:06:00 2009
@@ -23,7 +23,6 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.LinkedHashMap;
-import java.util.HashMap;
 import java.util.Collections;
 import java.util.Collection;
 import java.util.Arrays;
@@ -42,7 +41,6 @@
 import org.apache.geronimo.blueprint.di.RefRecipe;
 import org.apache.geronimo.blueprint.di.IdRefRecipe;
 import org.apache.geronimo.blueprint.di.CircularDependencyException;
-import org.apache.geronimo.blueprint.utils.ConversionUtils;
 import org.apache.geronimo.blueprint.ExtendedBlueprintContainer;
 
 /**
@@ -144,7 +142,7 @@
                 Object obj = createInstance(name);
                 try {
                     // Make sure to go through the conversion step in case we have a Convertible
object
-                    obj = ConversionUtils.convert(obj, Object.class, blueprintContainer.getConverter());
+                    obj = convert(obj, Object.class);
                 } catch (Exception e) {
                     throw new ComponentDefinitionException("Unable to convert instance "
+ name, e);
                 }
@@ -315,7 +313,7 @@
     }
 
     public Object convert(Object value, Type type) throws Exception {
-        return ConversionUtils.convert(value, type, blueprintContainer.getConverter());
+        return blueprintContainer.getConverter().convert(value, type);
     }
 
     public Class loadClass(String typeName) throws ClassNotFoundException {

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/RefListRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/RefListRecipe.java?rev=785996&r1=785995&r2=785996&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/RefListRecipe.java
(original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/RefListRecipe.java
Thu Jun 18 10:06:00 2009
@@ -34,7 +34,6 @@
 import org.apache.geronimo.blueprint.ExtendedBlueprintContainer;
 import org.apache.geronimo.blueprint.ExtendedRefListMetadata;
 import org.apache.geronimo.blueprint.di.Recipe;
-import org.apache.geronimo.blueprint.utils.ConversionUtils;
 import org.apache.geronimo.blueprint.utils.DynamicCollection;
 import org.apache.geronimo.blueprint.utils.TypeUtils;
 import org.osgi.framework.Constants;
@@ -229,7 +228,7 @@
 
     }
 
-    public class ProvidedObject implements ConversionUtils.Convertible {
+    public class ProvidedObject implements AggregateConverter.Convertible {
 
         public Object convert(Type type) {
             LOGGER.debug("Converting ManagedCollection to {}", type);

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/ReferenceRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/ReferenceRecipe.java?rev=785996&r1=785995&r2=785996&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/ReferenceRecipe.java
(original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/ReferenceRecipe.java
Thu Jun 18 10:06:00 2009
@@ -25,7 +25,6 @@
 
 import org.apache.geronimo.blueprint.ExtendedBlueprintContainer;
 import org.apache.geronimo.blueprint.di.Recipe;
-import org.apache.geronimo.blueprint.utils.ConversionUtils;
 import org.apache.geronimo.blueprint.utils.TypeUtils;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.blueprint.container.BlueprintEvent;
@@ -206,7 +205,7 @@
 
     }
 
-    public class ServiceProxyWrapper implements ConversionUtils.Convertible {
+    public class ServiceProxyWrapper implements AggregateConverter.Convertible {
 
         public Object convert(Type type) throws Exception {
             if (type == ServiceReference.class) {

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/di/CollectionRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/di/CollectionRecipe.java?rev=785996&r1=785995&r2=785996&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/di/CollectionRecipe.java
(original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/di/CollectionRecipe.java
Thu Jun 18 10:06:00 2009
@@ -19,8 +19,13 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.Set;
+import java.util.LinkedHashSet;
+import java.util.Queue;
+import java.util.LinkedList;
 
-import org.apache.geronimo.blueprint.utils.ConversionUtils;
 import org.apache.geronimo.blueprint.utils.TypeUtils;
 import org.osgi.service.blueprint.container.ComponentDefinitionException;
 
@@ -50,7 +55,7 @@
     }
 
     protected Object internalCreate() throws ComponentDefinitionException {
-        Class type = ConversionUtils.getCollection(typeClass);
+        Class type = getCollection(typeClass);
 
         if (!TypeUtils.hasDefaultConstructor(type)) {
             throw new ComponentDefinitionException("Type does not have a default constructor
" + type.getName());
@@ -88,4 +93,19 @@
         list.add(value);
     }
 
+    public static Class getCollection(Class type) {
+        if (TypeUtils.hasDefaultConstructor(type)) {
+            return type;
+        } else if (SortedSet.class.isAssignableFrom(type)) {
+            return TreeSet.class;
+        } else if (Set.class.isAssignableFrom(type)) {
+            return LinkedHashSet.class;
+        } else if (List.class.isAssignableFrom(type)) {
+            return ArrayList.class;
+        } else if (Queue.class.isAssignableFrom(type)) {
+            return LinkedList.class;
+        } else {
+            return ArrayList.class;
+        }
+    }
 }

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/di/MapRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/di/MapRecipe.java?rev=785996&r1=785995&r2=785996&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/di/MapRecipe.java
(original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/di/MapRecipe.java
Thu Jun 18 10:06:00 2009
@@ -22,8 +22,12 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.LinkedHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
 
-import org.apache.geronimo.blueprint.utils.ConversionUtils;
 import org.apache.geronimo.blueprint.utils.TypeUtils;
 import org.osgi.service.blueprint.container.ComponentDefinitionException;
 
@@ -54,7 +58,7 @@
     }
 
     protected Object internalCreate() throws ComponentDefinitionException {
-        Class mapType = ConversionUtils.getMap(typeClass);
+        Class mapType = getMap(typeClass);
 
         if (!TypeUtils.hasDefaultConstructor(mapType)) {
             throw new ComponentDefinitionException("Type does not have a default constructor
" + mapType.getName());
@@ -99,6 +103,18 @@
         }
     }
 
+    public static Class getMap(Class type) {
+        if (TypeUtils.hasDefaultConstructor(type)) {
+            return type;
+        } else if (SortedMap.class.isAssignableFrom(type)) {
+            return TreeMap.class;
+        } else if (ConcurrentMap.class.isAssignableFrom(type)) {
+            return ConcurrentHashMap.class;
+        } else {
+            return LinkedHashMap.class;
+        }
+    }
+
     public static class DummyDictionaryAsMap extends AbstractMap {
 
         private final Dictionary dictionary;

Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/TypeUtils.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/TypeUtils.java?rev=785996&r1=785995&r2=785996&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/TypeUtils.java
(original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/utils/TypeUtils.java
Thu Jun 18 10:06:00 2009
@@ -90,6 +90,7 @@
     }
 
     public static boolean isAssignable(Type expectedType, Type actualType) {
+        // TODO: check parameterized Collection / Maps / Arrays ?
         Class expectedClass = toClass(expectedType);
         Class actualClass = toClass(actualType);
         return expectedClass.isAssignableFrom(actualClass);
@@ -171,6 +172,7 @@
     }
 
     public static Type parseJavaType(String type, Object loader) throws ClassNotFoundException
{
+        // TODO: support wilcards for generics
         type = type.trim();
         // Check if this is an array
         if (type.endsWith("[]")) {



Mime
View raw message