0a119e0a7274614e3e911963b10605deeeb768ae
[ccsdk/features.git] / sdnr / wt / data-provider / provider / src / main / java / org / onap / ccsdk / features / sdnr / wt / dataprovider / yangtools / mapperextensions / YangToolsBuilderAnnotationIntrospector.java
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP : ccsdk features
4  * ================================================================================
5  * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
6  * All rights reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  *
21  */
22 package org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.mapperextensions;
23
24 import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
25 import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder.Value;
26 import com.fasterxml.jackson.databind.cfg.MapperConfig;
27 import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
28 import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
29 import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
30 import java.math.BigInteger;
31 import java.util.HashMap;
32 import java.util.List;
33 import java.util.Map;
34 import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.YangToolsMapperHelper;
35 import org.onap.ccsdk.features.sdnr.wt.dataprovider.yangtools.builder.DateAndTimeBuilder;
36 //import org.onap.ccsdk.features.sdnr.wt.dataprovider.data.builders.rev201110.read.network.element.connection.list.output.DataBuilder;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.Credentials;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPasswordBuilder;
40 import org.opendaylight.yangtools.yang.common.Uint16;
41 import org.opendaylight.yangtools.yang.common.Uint32;
42 import org.opendaylight.yangtools.yang.common.Uint64;
43 import org.opendaylight.yangtools.yang.common.Uint8;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 public class YangToolsBuilderAnnotationIntrospector extends JacksonAnnotationIntrospector {
48
49     private static final Logger LOG = LoggerFactory.getLogger(YangToolsBuilderAnnotationIntrospector.class);
50     private static final long serialVersionUID = 1L;
51
52     private final Map<Class<?>, String> customDeserializer;
53
54     public YangToolsBuilderAnnotationIntrospector() {
55         this(null, null);
56     }
57
58     public YangToolsBuilderAnnotationIntrospector(Class<?> cls, Class<?> builderClass) {
59         this.customDeserializer = new HashMap<>();
60         if (cls != null && builderClass != null) {
61             this.customDeserializer.put(cls, builderClass.getName());
62         }
63         this.customDeserializer.put(DateAndTime.class, DateAndTimeBuilder.class.getName());
64         this.customDeserializer.put(Credentials.class, LoginPasswordBuilder.class.getName());
65     }
66
67     @Override
68     public Class<?> findPOJOBuilder(AnnotatedClass ac) {
69         try {
70             String builder = null;
71             if (this.customDeserializer.containsKey(ac.getRawType())) {
72                 builder = this.customDeserializer.get(ac.getRawType());
73             } else {
74                 if (ac.getRawType().isInterface()) {
75                     builder = ac.getName() + "Builder";
76                 }
77             }
78             if (builder != null) {
79                 LOG.trace("map {} with builder {}", ac.getName(), builder);
80                 Class<?> innerBuilder = YangToolsMapperHelper.findClass(builder);
81                 return innerBuilder;
82             }
83         } catch (ClassNotFoundException e) {
84             LOG.trace("builder class not found for {}", ac.getName());
85         }
86         return super.findPOJOBuilder(ac);
87     }
88
89     @Override
90     public Value findPOJOBuilderConfig(AnnotatedClass ac) {
91         if (ac.hasAnnotation(JsonPOJOBuilder.class)) {
92             return super.findPOJOBuilderConfig(ac);
93         }
94         return new JsonPOJOBuilder.Value("build", "set");
95     }
96
97     @Override
98     public AnnotatedMethod resolveSetterConflict(MapperConfig<?> config, AnnotatedMethod setter1,
99             AnnotatedMethod setter2) {
100         Class<?> p1 = setter1.getRawParameterType(0);
101         Class<?> p2 = setter2.getRawParameterType(0);
102         AnnotatedMethod res = null;
103
104         if (this.isAssignable(p1, p2, Map.class, List.class)) {
105                         res = p1.isAssignableFrom(List.class) ? setter1 : setter2; //prefer List setter
106         } else if (this.isAssignable(p1, p2, Uint64.class, BigInteger.class)) {
107             res = setter1;
108         } else if (this.isAssignable(p1, p2, Uint32.class, Long.class)) {
109             res = setter1;
110         } else if (this.isAssignable(p1, p2, Uint16.class, Integer.class)) {
111             res = setter1;
112         } else if (this.isAssignable(p1, p2, Uint8.class, Short.class)) {
113             res = setter1;
114         }
115         if (res == null) {
116             res = super.resolveSetterConflict(config, setter1, setter2);
117         }
118         LOG.debug("{} (m1={} <=> m2={} => result:{})", setter1.getName(), p1.getSimpleName(), p2.getSimpleName(),
119                 res.getRawParameterType(0).getSimpleName());
120
121         return res;
122     }
123
124     private boolean isAssignable(Class<?> p1, Class<?> p2, Class<?> c1, Class<?> c2) {
125         return ((p1.isAssignableFrom(c1) && p2.isAssignableFrom(c2))
126                 || (p2.isAssignableFrom(c1) && p1.isAssignableFrom(c2)));
127
128     }
129
130 }