Fixed some major sonar issues in yang-validation-tool
[yangtools.git] / yang / yang-binding / src / main / java / org / opendaylight / yangtools / yang / binding / util / AugmentationFieldGetter.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.binding.util;
9
10 import org.opendaylight.yangtools.yang.binding.AugmentationHolder;
11
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;
18 import java.util.Map;
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;
23
24 abstract class AugmentationFieldGetter {
25
26     private static final Logger LOG = LoggerFactory.getLogger(AugmentationFieldGetter.class);
27
28     private static final AugmentationFieldGetter DUMMY = new AugmentationFieldGetter() {
29         @Override
30         protected Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAugmentations(final Object input) {
31             return Collections.emptyMap();
32         }
33     };
34
35     private static final AugmentationFieldGetter AUGMENTATION_HOLDER_GETTER = new AugmentationFieldGetter() {
36
37         @Override
38         @SuppressWarnings({"unchecked", "rawtypes"})
39         protected Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAugmentations(final Object input) {
40             return (Map) ((AugmentationHolder<?>) input).augmentations();
41         }
42     };
43
44     /**
45      *
46      * Retrieves augmentations from supplied object
47      *
48      * @param input Input Data object, from which augmentations should be extracted
49      * @return Map of Augmentation class to augmentation
50      */
51     protected abstract Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAugmentations(final Object input);
52
53     private static final LoadingCache<Class<?>, AugmentationFieldGetter> AUGMENTATION_GETTERS = CacheBuilder
54             .newBuilder().weakKeys().softValues().build(new AugmentationGetterLoader());
55
56     public static AugmentationFieldGetter getGetter(final Class<? extends Object> clz) {
57         if(AugmentationHolder.class.isAssignableFrom(clz)) {
58             return AUGMENTATION_HOLDER_GETTER;
59         }
60         return AUGMENTATION_GETTERS.getUnchecked(clz);
61     }
62
63     private static final class AugmentationGetterLoader extends CacheLoader<Class<?>, AugmentationFieldGetter> {
64
65         @Override
66         public AugmentationFieldGetter load(final Class<?> key) throws Exception {
67             Field field;
68             try {
69                 field = key.getDeclaredField(BindingMapping.AUGMENTATION_FIELD);
70             } catch (NoSuchFieldException | SecurityException e) {
71                 LOG.debug("Failed to acquire augmentation field", e);
72                 return DUMMY;
73             }
74             field.setAccessible(true);
75
76             return new ReflectionAugmentationFieldGetter(field);
77         }
78     }
79
80     private static final class ReflectionAugmentationFieldGetter extends AugmentationFieldGetter {
81         private final Field augmentationField;
82
83         ReflectionAugmentationFieldGetter(final Field augmentationField) {
84             this.augmentationField = Preconditions.checkNotNull(augmentationField);
85         }
86
87         @Override
88         @SuppressWarnings("unchecked")
89         protected Map<Class<? extends Augmentation<?>>, Augmentation<?>> getAugmentations(final Object input) {
90             try {
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);
94             }
95         }
96     }
97
98 }