f9efca3dca27dcaf4ad064572a6bfe69abcde86c
[hc2vpp.git] /
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package io.fd.honeycomb.v3po.translate.util.read;
18
19 import static com.google.common.base.Preconditions.checkArgument;
20
21 import com.google.common.base.Optional;
22 import com.google.common.collect.Lists;
23 import io.fd.honeycomb.v3po.translate.util.ReflectionUtils;
24 import java.lang.reflect.InvocationTargetException;
25 import java.lang.reflect.Method;
26 import java.util.Collections;
27 import javax.annotation.Nonnull;
28 import org.opendaylight.yangtools.concepts.Builder;
29 import org.opendaylight.yangtools.yang.binding.Augmentation;
30 import org.opendaylight.yangtools.yang.binding.DataObject;
31 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
32
33 /**
34  * Might be slow !
35  */
36 final class ReflexiveReaderCustomizer<C extends DataObject, B extends Builder<C>> extends NoopReaderCustomizer<C, B> {
37
38     private final Class<C> typeClass;
39     private final Class<B> builderClass;
40
41     public ReflexiveReaderCustomizer(final Class<C> typeClass, final Class<B> builderClass) {
42         this.typeClass = typeClass;
43         this.builderClass = builderClass;
44     }
45
46     protected Class<C> getTypeClass() {
47         return typeClass;
48     }
49
50     protected Class<B> getBuilderClass() {
51         return builderClass;
52     }
53
54     @Nonnull
55     @Override
56     public B getBuilder(@Nonnull InstanceIdentifier<C> id) {
57         try {
58             return builderClass.newInstance();
59         } catch (InstantiationException | IllegalAccessException e) {
60             throw new IllegalStateException("Unable to instantiate " + builderClass, e);
61         }
62     }
63
64     @Override
65     public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final C readValue) {
66         if (Augmentation.class.isAssignableFrom(typeClass)) {
67             mergeAugmentation(parentBuilder, (Class<? extends Augmentation<?>>) typeClass, readValue);
68         } else {
69             mergeRegular(parentBuilder, readValue);
70         }
71     }
72
73     private static void mergeRegular(@Nonnull final Builder<? extends DataObject> parentBuilder,
74                                      @Nonnull final DataObject readValue) {
75         final Optional<Method> method =
76                 ReflectionUtils.findMethodReflex(parentBuilder.getClass(), "set",
77                         Collections.singletonList(readValue.getClass()), parentBuilder.getClass());
78
79         checkArgument(method.isPresent(), "Unable to set %s to %s", readValue, parentBuilder);
80
81         try {
82             method.get().invoke(parentBuilder, readValue);
83         } catch (IllegalAccessException | InvocationTargetException e) {
84             throw new IllegalArgumentException("Unable to set " + readValue + " to " + parentBuilder, e);
85         }
86     }
87
88     private static void mergeAugmentation(@Nonnull final Builder<? extends DataObject> parentBuilder,
89                                           @Nonnull final Class<? extends Augmentation<?>> typeClass,
90                                           @Nonnull final DataObject readValue) {
91         final Optional<Method> method =
92                 ReflectionUtils.findMethodReflex(parentBuilder.getClass(), "addAugmentation",
93                         Lists.newArrayList(Class.class, Augmentation.class), parentBuilder.getClass());
94
95         checkArgument(method.isPresent(), "Not possible to add augmentations to builder: %s", parentBuilder);
96         try {
97             method.get().invoke(parentBuilder, typeClass, readValue);
98         } catch (IllegalAccessException | InvocationTargetException e) {
99             throw new IllegalArgumentException("Unable to set " + readValue + " to " + parentBuilder, e);
100         }
101     }
102
103 }