2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the terms of the Eclipse
5 * Public License v1.0 which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.binding.util;
10 import org.opendaylight.yangtools.yang.binding.AugmentationHolder;
12 import com.google.common.base.Preconditions;
13 import com.google.common.cache.CacheBuilder;
14 import com.google.common.cache.CacheLoader;
15 import com.google.common.cache.LoadingCache;
16 import java.lang.reflect.Field;
17 import java.util.Collections;
19 import org.opendaylight.yangtools.yang.binding.Augmentation;
20 import org.opendaylight.yangtools.yang.binding.BindingMapping;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
24 abstract class AugmentationFieldGetter {
26 private static final Logger LOG = LoggerFactory.getLogger(AugmentationFieldGetter.class);
28 private static final AugmentationFieldGetter DUMMY = new AugmentationFieldGetter() {
30 protected Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAugmentations(final Object input) {
31 return Collections.emptyMap();
35 private static final AugmentationFieldGetter AUGMENTATION_HOLDER_GETTER = new AugmentationFieldGetter() {
38 @SuppressWarnings({"unchecked", "rawtypes"})
39 protected Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAugmentations(final Object input) {
40 return (Map) ((AugmentationHolder<?>) input).augmentations();
46 * Retrieves augmentations from supplied object
48 * @param input Input Data object, from which augmentations should be extracted
49 * @return Map of Augmentation class to augmentation
51 protected abstract Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAugmentations(final Object input);
53 private static final LoadingCache<Class<?>, AugmentationFieldGetter> AUGMENTATION_GETTERS = CacheBuilder
54 .newBuilder().weakKeys().softValues().build(new AugmentationGetterLoader());
56 public static AugmentationFieldGetter getGetter(final Class<? extends Object> clz) {
57 if(AugmentationHolder.class.isAssignableFrom(clz)) {
58 return AUGMENTATION_HOLDER_GETTER;
60 return AUGMENTATION_GETTERS.getUnchecked(clz);
63 private static final class AugmentationGetterLoader extends CacheLoader<Class<?>, AugmentationFieldGetter> {
66 public AugmentationFieldGetter load(final Class<?> key) throws Exception {
69 field = key.getDeclaredField(BindingMapping.AUGMENTATION_FIELD);
70 } catch (NoSuchFieldException | SecurityException e) {
71 LOG.debug("Failed to acquire augmentation field", e);
74 field.setAccessible(true);
76 return new ReflectionAugmentationFieldGetter(field);
80 private static final class ReflectionAugmentationFieldGetter extends AugmentationFieldGetter {
81 private final Field augmentationField;
83 ReflectionAugmentationFieldGetter(final Field augmentationField) {
84 this.augmentationField = Preconditions.checkNotNull(augmentationField);
88 @SuppressWarnings("unchecked")
89 protected Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAugmentations(final Object input) {
91 return (Map<Class<? extends Augmentation<?>>, Augmentation<?>>) augmentationField.get(input);
92 } catch (IllegalArgumentException | IllegalAccessException e) {
93 throw new IllegalStateException("Failed to access augmentation field", e);