no longer coerce things if generic parametrized types don't match previously we would return e.g. a List not containing T if List<T> was requested. this was deprecated and we would warn, but now we are stricter.
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/8d081d01 Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/8d081d01 Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/8d081d01 Branch: refs/heads/master Commit: 8d081d01a3bb6e0e48ba64f13a6d4485d9d3cad8 Parents: 89c692e Author: Alex Heneveld <alex.henev...@cloudsoftcorp.com> Authored: Fri Aug 31 01:13:37 2018 +0100 Committer: Alex Heneveld <alex.henev...@cloudsoftcorp.com> Committed: Fri Aug 31 01:13:37 2018 +0100 ---------------------------------------------------------------------- .../org/apache/brooklyn/util/guava/Maybe.java | 2 +- .../javalang/coerce/TypeCoercerExtensible.java | 49 ++++++++------------ 2 files changed, 21 insertions(+), 30 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8d081d01/utils/common/src/main/java/org/apache/brooklyn/util/guava/Maybe.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/guava/Maybe.java b/utils/common/src/main/java/org/apache/brooklyn/util/guava/Maybe.java index 8b69cc0..5b34249 100644 --- a/utils/common/src/main/java/org/apache/brooklyn/util/guava/Maybe.java +++ b/utils/common/src/main/java/org/apache/brooklyn/util/guava/Maybe.java @@ -365,7 +365,7 @@ public abstract class Maybe<T> implements Serializable, Supplier<T> { }); } public static <T> Maybe<T> changeExceptionSupplier(Maybe<T> original, Function<AnyExceptionSupplier<?>,Supplier<? extends RuntimeException>> transform) { - if (original.isPresent()) return original; + if (original==null || original.isPresent()) return original; final Supplier<? extends RuntimeException> supplier = ((Maybe.Absent<?>)original).getExceptionSupplier(); if (!(supplier instanceof AnyExceptionSupplier)) return original; http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8d081d01/utils/common/src/main/java/org/apache/brooklyn/util/javalang/coerce/TypeCoercerExtensible.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/javalang/coerce/TypeCoercerExtensible.java b/utils/common/src/main/java/org/apache/brooklyn/util/javalang/coerce/TypeCoercerExtensible.java index 3465c09..a4b4846 100644 --- a/utils/common/src/main/java/org/apache/brooklyn/util/javalang/coerce/TypeCoercerExtensible.java +++ b/utils/common/src/main/java/org/apache/brooklyn/util/javalang/coerce/TypeCoercerExtensible.java @@ -27,6 +27,8 @@ import java.util.Map; import java.util.Set; import org.apache.brooklyn.util.exceptions.Exceptions; +import org.apache.brooklyn.util.exceptions.PropagatedRuntimeException; +import org.apache.brooklyn.util.guava.AnyExceptionSupplier; import org.apache.brooklyn.util.guava.Maybe; import org.apache.brooklyn.util.guava.TypeTokens; import org.apache.brooklyn.util.javalang.Boxing; @@ -127,34 +129,20 @@ public class TypeCoercerExtensible implements TypeCoercer { if (targetTypeToken!=null && targetTypeToken.getType() instanceof ParameterizedType) { if (value instanceof Iterable && Iterable.class.isAssignableFrom(targetType)) { result = tryCoerceIterable(value, targetTypeToken, targetType); - - if (result != null && result.isAbsent() && targetType.isInstance(value)) { - log.warn("Failed to coerce iterable from " + value.getClass().getName() + " to " + targetTypeToken - + "; returning uncoerced result to preserve (deprecated) backwards compatibility", - Maybe.getException(result)); - } - } else if (value.getClass().isArray() && Iterable.class.isAssignableFrom(targetType)) { result = tryCoerceArray(value, targetTypeToken, targetType); - - if (result != null && result.isAbsent() && targetType.isInstance(value)) { - log.warn("Failed to coerce array from " + value.getClass().getName() + " to " + targetTypeToken - + "; returning uncoerced result to preserve (deprecated) backwards compatibility", - Maybe.getException(result)); - } - } else if (value instanceof Map && Map.class.isAssignableFrom(targetType)) { result = tryCoerceMap(value, targetTypeToken); - - if (result != null && result.isAbsent() && targetType.isInstance(value)) { - log.warn("Failed to coerce map from " + value.getClass().getName() + " to " + targetTypeToken - + "; returning uncoerced result to preserve (deprecated) backwards compatibility", - Maybe.getException(result)); - } + } + if (result!=null) { + if (result.isPresent()) return result; + // Previous to v1.0.0 we'd overlook errors in generics with warnings; now we bail + TypeToken<T> targetTypeTokenF = targetTypeToken; + RuntimeException e = Maybe.getException(result); + return Maybe.absent(new AnyExceptionSupplier<>(ClassCoercionException.class, + () -> "Generic type mismatch coercing "+value.getClass().getName()+" to "+targetTypeTokenF+": "+Exceptions.collapseText(e), e)); } } - if (result!=null && result.isPresent()) return result; - if (result!=null && firstError==null) firstError = result; if (targetType.isInstance(value)) return Maybe.of( (T) value ); @@ -206,8 +194,11 @@ public class TypeCoercerExtensible implements TypeCoercer { + ": "+e, e); } if (firstError==null) { - if (e instanceof ClassCoercionException) firstError = Maybe.absent(e); - else firstError = Maybe.absent(new ClassCoercionException("Cannot coerce type "+value.getClass().getCanonicalName()+" to "+targetType.getCanonicalName()+" ("+value+")", e)); + if (e instanceof ClassCoercionException) { + firstError = Maybe.absent(e); + } else { + firstError = Maybe.absent(new ClassCoercionException("Cannot coerce type "+value.getClass().getCanonicalName()+" to "+targetTypeToken+" ("+value+"): registered coercer failed", e)); + } } continue; } @@ -217,7 +208,7 @@ public class TypeCoercerExtensible implements TypeCoercer { //not found if (firstError!=null) return firstError; - return Maybe.absent(new ClassCoercionException("Cannot coerce type "+value.getClass().getCanonicalName()+" to "+targetType.getCanonicalName()+" ("+value+"): no adapter known")); + return Maybe.absent(new ClassCoercionException("Cannot coerce type "+value.getClass().getCanonicalName()+" to "+targetTypeToken+" ("+value+"): no adapter known")); } @SuppressWarnings("unchecked") @@ -234,15 +225,15 @@ public class TypeCoercerExtensible implements TypeCoercer { for (Map.Entry<?,?> entry : ((Map<?,?>) value).entrySet()) { Maybe<?> k = tryCoerce(entry.getKey(), mapKeyType); if (k.isAbsent()) return Maybe.absent(new ClassCoercionException( - "Could not coerce key of entry "+i+" in "+value+" to "+targetTypeToken, + "Could not coerce key of entry "+i+" ("+entry.getKey()+") to "+targetTypeToken, ((Maybe.Absent<T>)k).getException())); Maybe<?> v = tryCoerce(entry.getValue(), mapValueType); if (v.isAbsent()) return Maybe.absent(new ClassCoercionException( - "Could not coerce value of entry "+i+" in "+value+" to "+targetTypeToken, + "Could not coerce value of entry "+i+" ("+entry.getValue()+") to "+targetTypeToken, ((Maybe.Absent<T>)v).getException())); - coerced.put(k.get(), v.get()); + coerced.put(k.get(), v.get()); i++; } @@ -273,7 +264,7 @@ public class TypeCoercerExtensible implements TypeCoercer { coerced.add(entryCoerced.get()); } else { return Maybe.absent(new ClassCoercionException( - "Could not coerce entry "+i+" in "+value+" to "+targetTypeToken, + "Could not coerce entry "+i+" ("+entry+") to "+listEntryType, ((Maybe.Absent<T>)entryCoerced).getException())); } i++;