optimization: cache common type tokens
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/22acd5d6 Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/22acd5d6 Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/22acd5d6 Branch: refs/heads/master Commit: 22acd5d6301898e0d226588fae0f7dd8344cd465 Parents: 98dfee2 Author: Alex Heneveld <[email protected]> Authored: Mon Sep 11 23:14:59 2017 +0100 Committer: Alex Heneveld <[email protected]> Committed: Tue Sep 12 22:12:36 2017 +0100 ---------------------------------------------------------------------- .../apache/brooklyn/util/guava/TypeTokens.java | 23 +++++++++++++++++--- .../javalang/coerce/TypeCoercerExtensible.java | 15 ++++++++----- 2 files changed, 30 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/22acd5d6/utils/common/src/main/java/org/apache/brooklyn/util/guava/TypeTokens.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/guava/TypeTokens.java b/utils/common/src/main/java/org/apache/brooklyn/util/guava/TypeTokens.java index 188f328..657a790 100644 --- a/utils/common/src/main/java/org/apache/brooklyn/util/guava/TypeTokens.java +++ b/utils/common/src/main/java/org/apache/brooklyn/util/guava/TypeTokens.java @@ -24,6 +24,14 @@ import com.google.common.reflect.TypeToken; public class TypeTokens { + // creating TypeToken is surprisingly expensive so cache these common ones + public static TypeToken<String> STRING = TypeToken.of(String.class); + public static TypeToken<Object> OBJECT = TypeToken.of(Object.class); + public static TypeToken<Integer> INTEGER = TypeToken.of(Integer.class); + public static TypeToken<Boolean> BOOLEAN = TypeToken.of(Boolean.class); + public static TypeToken<Double> DOUBLE = TypeToken.of(Double.class); + public static TypeToken<Long> LONG = TypeToken.of(Long.class); + /** returns raw type, if it's raw, else null; * used e.g. to set only one of the raw type or the type token, * for instance to make serialized output nicer */ @@ -47,9 +55,10 @@ public class TypeTokens { } /** given either a token or a raw type, returns the raw type */ - public static <T> Class<? super T> getRawType(TypeToken<T> token, Class<? super T> raw) { + @SuppressWarnings("unchecked") + public static <T,U extends T> Class<T> getRawType(TypeToken<U> token, Class<T> raw) { if (raw!=null) return raw; - if (token!=null) return token.getRawType(); + if (token!=null) return (Class<T>) token.getRawType(); throw new IllegalStateException("Both indicators of type are null"); } @@ -58,7 +67,15 @@ public class TypeTokens { @SuppressWarnings("unchecked") public static <T> TypeToken<T> getTypeToken(TypeToken<T> token, Class<? super T> raw) { if (token!=null) return token; - if (raw!=null) return TypeToken.of((Class<T>)raw); + if (raw!=null) { + if (String.class.equals(raw)) return (TypeToken<T>) STRING; + if (Object.class.equals(raw)) return (TypeToken<T>) OBJECT; + if (Integer.class.equals(raw)) return (TypeToken<T>) INTEGER; + if (Boolean.class.equals(raw)) return (TypeToken<T>) BOOLEAN; + if (Double.class.equals(raw)) return (TypeToken<T>) DOUBLE; + if (Long.class.equals(raw)) return (TypeToken<T>) LONG; + return TypeToken.of((Class<T>)raw); + } throw new IllegalStateException("Both indicators of type are null"); } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/22acd5d6/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 fdf1940..3465c09 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 @@ -28,6 +28,7 @@ import java.util.Set; import org.apache.brooklyn.util.exceptions.Exceptions; import org.apache.brooklyn.util.guava.Maybe; +import org.apache.brooklyn.util.guava.TypeTokens; import org.apache.brooklyn.util.javalang.Boxing; import org.apache.brooklyn.util.javalang.Reflections; import org.apache.brooklyn.util.time.Duration; @@ -103,24 +104,27 @@ public class TypeCoercerExtensible implements TypeCoercer { @Override public <T> Maybe<T> tryCoerce(Object input, Class<T> type) { - return tryCoerce(input, TypeToken.of(type)); + return changeExceptionSupplier( tryCoerceInternal(input, null, type) ); } @Override public <T> Maybe<T> tryCoerce(Object value, TypeToken<T> targetTypeToken) { - Maybe<T> result = tryCoerceInternal(value, targetTypeToken); + return changeExceptionSupplier( tryCoerceInternal(value, targetTypeToken, null) ); + } + + protected <T> Maybe<T> changeExceptionSupplier(Maybe<T> result) { return Maybe.Absent.changeExceptionSupplier(result, ClassCoercionException.class); } @SuppressWarnings("unchecked") - protected <T> Maybe<T> tryCoerceInternal(Object value, TypeToken<T> targetTypeToken) { + protected <T> Maybe<T> tryCoerceInternal(Object value, TypeToken<T> targetTypeToken, Class<T> targetType) { if (value==null) return Maybe.of((T)null); - Class<? super T> targetType = targetTypeToken.getRawType(); Maybe<T> result = null; Maybe<T> firstError = null; //recursive coercion of parameterized collections and map entries - if (targetTypeToken.getType() instanceof ParameterizedType) { + targetType = TypeTokens.getRawType(targetTypeToken, targetType); + if (targetTypeToken!=null && targetTypeToken.getType() instanceof ParameterizedType) { if (value instanceof Iterable && Iterable.class.isAssignableFrom(targetType)) { result = tryCoerceIterable(value, targetTypeToken, targetType); @@ -154,6 +158,7 @@ public class TypeCoercerExtensible implements TypeCoercer { if (targetType.isInstance(value)) return Maybe.of( (T) value ); + targetTypeToken = TypeTokens.getTypeToken(targetTypeToken, targetType); for (TryCoercer coercer : genericCoercers) { result = coercer.tryCoerce(value, targetTypeToken); if (result!=null && result.isPresent()) return result;
