/** tries to coerce a list; * returns null if it just doesn't apply, a {@link Maybe.Present} if it succeeded, * or {@link Maybe.Absent} with a good exception if it should have applied but couldn't */ @SuppressWarnings("unchecked") protected <T> Maybe<T> tryCoerceIterable(Object value, TypeToken<T> targetTypeToken, Class<? super T> targetType) { if (!(value instanceof Iterable) || !(Iterable.class.isAssignableFrom(targetTypeToken.getRawType()))) return null; Type[] arguments = ((ParameterizedType) targetTypeToken.getType()).getActualTypeArguments(); if (arguments.length != 1) { return Maybe.absent(new IllegalStateException("Unexpected number of parameters in iterable type: " + arguments)); } Collection<Object> coerced = Lists.newLinkedList(); TypeToken<?> listEntryType = TypeToken.of(arguments[0]); int i = 0; for (Object entry : (Iterable<?>) value) { Maybe<?> entryCoerced = tryCoerce(entry, listEntryType); if (entryCoerced.isPresent()) { coerced.add(entryCoerced.get()); } else { return Maybe.absent(new ClassCoercionException( "Could not coerce entry "+i+" in "+value+" to "+targetTypeToken, ((Maybe.Absent<T>)entryCoerced).getException())); } i++; } if (Set.class.isAssignableFrom(targetType)) { return Maybe.of((T) Sets.newLinkedHashSet(coerced)); } else { return Maybe.of((T) Lists.newArrayList(coerced)); } }
@Override @SuppressWarnings("unchecked") public <T> Maybe<T> tryCoerce(Object input, TypeToken<T> targetType) { if (!targetType.isArray()) return null; TypeToken<?> targetComponentType = targetType.getComponentType(); Iterable<?> castInput; if (input.getClass().isArray()) { castInput = Reflections.arrayToList(input); } else if (Iterable.class.isAssignableFrom(input.getClass())) { castInput = (Iterable<?>) input; } else { return null; } Object result = Array.newInstance(targetComponentType.getRawType(), Iterables.size(castInput)); int index = 0; for (Object member : castInput) { Maybe<?> coercedMember = coercer.tryCoerce(member, targetComponentType); if (coercedMember == null || coercedMember.isAbsent()) { RuntimeException cause = Maybe.Absent.getException(coercedMember); return Maybe.absent("Array member at index "+index+" cannot be coerced to "+targetComponentType, cause); } Array.set(result, index++, coercedMember.get()); } return (Maybe<T>) Maybe.of(result); } }
@SuppressWarnings("unchecked") protected <T> Maybe<T> tryCoerceMap(Object value, TypeToken<T> targetTypeToken) { if (!(value instanceof Map) || !(Map.class.isAssignableFrom(targetTypeToken.getRawType()))) return null; Type[] arguments = ((ParameterizedType) targetTypeToken.getType()).getActualTypeArguments(); if (arguments.length != 2) { throw new IllegalStateException("Unexpected number of parameters in map type: " + arguments); } Map<Object,Object> coerced = Maps.newLinkedHashMap(); TypeToken<?> mapKeyType = TypeToken.of(arguments[0]); TypeToken<?> mapValueType = TypeToken.of(arguments[1]); int i=0; 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, ((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, ((Maybe.Absent<T>)v).getException())); coerced.put(k.get(), v.get()); i++; } return Maybe.of((T) Maps.newLinkedHashMap(coerced)); }
if (requireUrlIfNotAlreadyPresent) { throw new IllegalStateException("Bundle "+bundleMetadata+" not previously registered, but URL is empty.", Maybe.Absent.getException(installedBundle));
/** Finds the {@link Absent#getException()} if {@link #isAbsent()}, or null */ public static RuntimeException getException(Maybe<?> t) { return ((Maybe.Absent<?>)t).getException(); } }
@Override public T orThrowUnwrapped() { throw getException(); } public RuntimeException getException() {
@Override public T get() { throw getException(); } @Override