+ private static final class AugmentationGetterLoader extends CacheLoader<Class<?>, AugmentationFieldGetter> {
+ private static final AugmentationFieldGetter DUMMY = new AugmentationFieldGetter() {
+ @Override
+ Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAugmentations(final Object input) {
+ return Collections.emptyMap();
+ }
+ };
+
+ @Override
+ public AugmentationFieldGetter load(final Class<?> key) throws Exception {
+ Field field;
+ try {
+ field = key.getDeclaredField("augmentation");
+ } catch (NoSuchFieldException | SecurityException e) {
+ LOG.debug("Failed to acquire augmentation field", e);
+ return DUMMY;
+ }
+ field.setAccessible(true);
+
+ return new ReflectionAugmentationFieldGetter(field);
+ }
+ }
+
+ private static abstract class AugmentationFieldGetter {
+ abstract Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAugmentations(final Object input);
+ }
+
+ private static final class ReflectionAugmentationFieldGetter extends AugmentationFieldGetter {
+ private final Field augmentationField;
+
+ ReflectionAugmentationFieldGetter(final Field augmentationField) {
+ this.augmentationField = Preconditions.checkNotNull(augmentationField);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAugmentations(final Object input) {
+ try {
+ return (Map<Class<? extends Augmentation<?>>, Augmentation<?>>) augmentationField.get(input);
+ } catch (IllegalArgumentException | IllegalAccessException e) {
+ throw new IllegalStateException("Failed to access augmentation field", e);
+ }
+ }
+ }
+
+ private static abstract class IntermediateCodec<T> implements DomCodec<T>, Delegator<BindingCodec<Map<QName, Object>, Object>> {