You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by da...@apache.org on 2016/10/10 15:55:43 UTC
svn commit: r1764135 - in /felix/trunk/converter/converter/src/main/java/org:
apache/felix/converter/impl/AdapterImpl.java
apache/felix/converter/impl/ConvertingImpl.java
osgi/converter/Converting.java
Author: davidb
Date: Mon Oct 10 15:55:42 2016
New Revision: 1764135
URL: http://svn.apache.org/viewvc?rev=1764135&view=rev
Log:
Felix Converter - initial implementation of supporting the as() method.
The as() method is used to disabiguate input objects when these potentially match multiple rules.
Modified:
felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/AdapterImpl.java
felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/ConvertingImpl.java
felix/trunk/converter/converter/src/main/java/org/osgi/converter/Converting.java
Modified: felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/AdapterImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/AdapterImpl.java?rev=1764135&r1=1764134&r2=1764135&view=diff
==============================================================================
--- felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/AdapterImpl.java (original)
+++ felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/AdapterImpl.java Mon Oct 10 15:55:42 2016
@@ -80,6 +80,7 @@ public class AdapterImpl implements Inte
private final InternalConverting del;
private final Object object;
private volatile Object defaultValue;
+ private volatile Class<?> treatAsClass;
private volatile boolean hasDefault;
ConvertingWrapper(Object obj, InternalConverting c) {
@@ -88,6 +89,13 @@ public class AdapterImpl implements Inte
}
@Override
+ public Converting as(Class<?> cls) {
+ treatAsClass = cls;
+ del.as(cls);
+ return this;
+ }
+
+ @Override
public Converting defaultValue(Object defVal) {
del.defaultValue(defVal);
defaultValue = defVal;
@@ -116,6 +124,7 @@ public class AdapterImpl implements Inte
@Override
public Object to(Type type) {
if (object != null) {
+ // TODO use treatAsClass
Set<Type> fromTypes = assignableTypes(object.getClass());
Set<Type> toTypes = assignableTypes(type);
Modified: felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/ConvertingImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/ConvertingImpl.java?rev=1764135&r1=1764134&r2=1764135&view=diff
==============================================================================
--- felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/ConvertingImpl.java (original)
+++ felix/trunk/converter/converter/src/main/java/org/apache/felix/converter/impl/ConvertingImpl.java Mon Oct 10 15:55:42 2016
@@ -60,6 +60,7 @@ public class ConvertingImpl implements C
private volatile Converter converter;
private volatile Object object;
+ private volatile Class<?> treatAsClass;
private volatile Object defaultValue;
private volatile boolean hasDefault;
@@ -69,6 +70,12 @@ public class ConvertingImpl implements C
}
@Override
+ public Converting as(Class<?> type) {
+ treatAsClass = type;
+ return this;
+ }
+
+ @Override
public Converting defaultValue(Object defVal) {
defaultValue = defVal;
hasDefault = true;
@@ -115,8 +122,9 @@ public class ConvertingImpl implements C
return handleNull(cls);
Class<?> targetCls = Util.primitiveToBoxed(cls);
+ Class<?> sourceCls = treatAsClass != null ? treatAsClass : object.getClass();
- if (!isCopyRequiredType(targetCls) && targetCls.isAssignableFrom(object.getClass())) {
+ if (!isCopyRequiredType(targetCls) && targetCls.isAssignableFrom(sourceCls)) {
return object;
}
@@ -129,13 +137,13 @@ public class ConvertingImpl implements C
} else if (Collection.class.isAssignableFrom(targetCls)) {
return convertToCollection(targetCls, typeArguments);
} else if (DTO.class.isAssignableFrom(targetCls)) {
- return convertToDTO(targetCls);
+ return convertToDTO(sourceCls, targetCls);
} else if (isMapType(targetCls)) {
- return convertToMapType(targetCls, typeArguments);
+ return convertToMapType(sourceCls, targetCls, typeArguments);
}
// At this point we know that the target is a 'singular' type: not a map, collection or array
- if (object instanceof Collection) {
+ if (Collection.class.isAssignableFrom(sourceCls)) {
return convertCollectionToSingleValue(cls);
} else if ((object = asBoxedArray(object)) instanceof Object[]) {
return convertArrayToSingleValue(cls);
@@ -217,8 +225,8 @@ public class ConvertingImpl implements C
}
@SuppressWarnings({ "rawtypes", "unchecked" })
- private <T> T convertToDTO(Class<T> targetCls) {
- Map m = mapView(object, converter);
+ private <T> T convertToDTO(Class<?> sourceCls, Class<T> targetCls) {
+ Map m = mapView(object, sourceCls, converter);
try {
T dto = targetCls.newInstance();
@@ -248,8 +256,8 @@ public class ConvertingImpl implements C
}
@SuppressWarnings({ "rawtypes", "unchecked" })
- private Map convertToMap(Class<?> targetCls, Type[] typeArguments) {
- Map m = mapView(object, converter);
+ private Map convertToMap(Class<?> sourceCls, Class<?> targetCls, Type[] typeArguments) {
+ Map m = mapView(object, sourceCls, converter);
if (m == null)
return null;
Type targetKeyType = null, targetValueType = null;
@@ -289,19 +297,19 @@ public class ConvertingImpl implements C
}
@SuppressWarnings({ "unchecked", "rawtypes" })
- private Object convertToMapType(Class<?> targetCls, Type[] typeArguments) {
+ private Object convertToMapType(Class<?> sourceCls, Class<?> targetCls, Type[] typeArguments) {
if (Map.class.isAssignableFrom(targetCls))
- return convertToMap(targetCls, typeArguments);
+ return convertToMap(sourceCls, targetCls, typeArguments);
else if (Dictionary.class.isAssignableFrom(targetCls))
- return new Hashtable(convertToMap(Map.class, typeArguments));
+ return new Hashtable(convertToMap(sourceCls, Map.class, typeArguments));
else if (targetCls.isInterface())
- return createProxy(targetCls);
- return createJavaBean(targetCls);
+ return createProxy(sourceCls, targetCls);
+ return createJavaBean(sourceCls, targetCls);
}
- private Object createJavaBean(Class<?> targetCls) {
+ private Object createJavaBean(Class<?> sourceCls, Class<?> targetCls) {
@SuppressWarnings("rawtypes")
- Map m = mapView(object, converter);
+ Map m = mapView(object, sourceCls, converter);
try {
Object res = targetCls.getConstructor().newInstance();
for (Method setter : getSetters(targetCls)) {
@@ -321,8 +329,8 @@ public class ConvertingImpl implements C
}
@SuppressWarnings("rawtypes")
- private Object createProxy(Class<?> targetCls) {
- Map m = mapView(object, converter);
+ private Object createProxy(Class<?> sourceCls, Class<?> targetCls) {
+ Map m = mapView(object, sourceCls, converter);
return Proxy.newProxyInstance(targetCls.getClassLoader(), new Class[] {targetCls},
new InvocationHandler() {
@Override
@@ -477,14 +485,14 @@ public class ConvertingImpl implements C
}
@SuppressWarnings("rawtypes")
- private static Map createMapFromBeanAccessors(Object obj) {
+ private static Map createMapFromBeanAccessors(Object obj, Class<?> sourceCls) {
Set<String> invokedMethods = new HashSet<>();
Map result = new HashMap();
- for (Method md : obj.getClass().getDeclaredMethods()) {
+ for (Method md : sourceCls.getDeclaredMethods()) {
handleBeanMethod(obj, md, invokedMethods, result);
}
- for (Method md : obj.getClass().getMethods()) {
+ for (Method md : sourceCls.getMethods()) {
handleBeanMethod(obj, md, invokedMethods, result);
}
@@ -670,17 +678,20 @@ public class ConvertingImpl implements C
}
}
- private static Map<?,?> mapView(Object obj, Converter converter) {
- if (obj instanceof Map)
+ private static Map<?,?> mapView(Object obj, Class<?> sourceCls, Converter converter) {
+ if (Map.class.isAssignableFrom(sourceCls))
return (Map<?,?>) obj;
- else if (obj instanceof Dictionary)
+ else if (Dictionary.class.isAssignableFrom(sourceCls))
return null; // TODO
else if (obj instanceof DTO)
+ // TODO inspect if its a DTO, rather than instanceof
return createMapFromDTO(obj, converter);
- else if (obj.getClass().getInterfaces().length > 0)
- return createMapFromInterface(obj);
- else
- return createMapFromBeanAccessors(obj);
+ else {
+ Map<?,?> m = createMapFromBeanAccessors(obj, sourceCls);
+ if (m.size() > 0)
+ return m;
+ }
+ return createMapFromInterface(obj);// TODO, sourceCls);
}
private static boolean isCopyRequiredType(Class<?> cls) {
Modified: felix/trunk/converter/converter/src/main/java/org/osgi/converter/Converting.java
URL: http://svn.apache.org/viewvc/felix/trunk/converter/converter/src/main/java/org/osgi/converter/Converting.java?rev=1764135&r1=1764134&r2=1764135&view=diff
==============================================================================
--- felix/trunk/converter/converter/src/main/java/org/osgi/converter/Converting.java (original)
+++ felix/trunk/converter/converter/src/main/java/org/osgi/converter/Converting.java Mon Oct 10 15:55:42 2016
@@ -29,6 +29,16 @@ import org.osgi.annotation.versioning.Pr
*/
@ProviderType
public interface Converting {
+ /**
+ * Convert the source object based on rules for the class being passed in.
+ * This method can be used to disambiguate objects that would match multiple
+ * conversion rules.
+ * @param type The type or class to be used as the source type for the conversion
+ * @return The current {@code Converting} object so that additional calls
+ * can be chained.
+ */
+ Converting as(Class<?> type);
+
/**
* The default value to use when the object cannot be converted or in case
* of conversion from a {@code null} value.