Merge "Reformat sdnr devicemanager-oran to ONAP code style"
[ccsdk/features.git] / sdnr / wt / data-provider / provider / src / main / java / org / onap / ccsdk / features / sdnr / wt / dataprovider / yangtools / YangToolsCloner.java
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP : ccsdk features
4  * ================================================================================
5  * Copyright (C) 2019 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;
23
24 import java.lang.reflect.Field;
25 import java.lang.reflect.InvocationTargetException;
26 import java.lang.reflect.Method;
27 import java.util.ArrayList;
28 import java.util.List;
29
30 import javax.annotation.Nullable;
31 import org.opendaylight.yangtools.concepts.Builder;
32 import org.opendaylight.yangtools.yang.binding.DataObject;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 public class YangToolsCloner {
37
38     private static YangToolsMapper yangtoolsMapper = new YangToolsMapper();
39     private static final Logger LOG = LoggerFactory.getLogger(YangToolsCloner.class);
40     public static final int ACCESSOR_FIELD = 0;
41     public static final int ACCESSOR_METHOD = 1;
42
43
44     private final int accessor;
45
46     private YangToolsCloner(int ac) {
47         this.accessor = ac;
48     }
49
50     public static YangToolsCloner instance() {
51         return instance(ACCESSOR_METHOD);
52     }
53
54     public static YangToolsCloner instance(int ac) {
55         return new YangToolsCloner(ac);
56     }
57
58     /**
59      *
60      * @param source source object
61      * @param clazz Class of return object
62      * @return list of cloned object
63      * @return
64      */
65     public <S extends DataObject, T extends DataObject> List<T> cloneList(List<S> source, Class<T> clazz) {
66         return cloneList(source, clazz, null);
67     }
68
69     /**
70      *
71      * @param source source object
72      * @param clazz Class of return object
73      * @attrList filter for attribute Names to clone
74      * @return list of cloned object
75      */
76     public <S extends DataObject, T extends DataObject> List<T> cloneList(List<S> source, Class<T> clazz,
77             @Nullable List<String> attrList) {
78         if (source == null) {
79             return null;
80         }
81         List<T> list = new ArrayList<>();
82         for (S s : source) {
83             list.add(clone(s, clazz, attrList));
84         }
85         return list;
86     }
87
88     /**
89      *
90      * @param source source object
91      * @param clazz Class of return object
92      * @return cloned object
93      */
94     public <S, T extends DataObject> T clone(S source, Class<T> clazz) {
95         return clone(source, clazz, null);
96     }
97
98     /**
99      *
100      * @param source source object
101      * @param clazz Class of return object
102      * @attrList if empty copy all else list of attribute Names to clone
103      * @return cloned object
104      */
105     public <S, T extends DataObject> T clone(S source, Class<T> clazz, @Nullable List<String> attrList) {
106         if (source == null) {
107             return (T) null;
108         }
109         Field[] attributeFields;
110         Field sourceField;
111         Method m;
112         Builder<T> builder = yangtoolsMapper.getBuilder(clazz);
113         T object = builder.build();
114         attributeFields = object.getClass().getDeclaredFields();
115         for (Field attributeField : attributeFields) {
116             // check if attr is in inclusion list
117             if (attrList != null && !attrList.contains(attributeField.getName())) {
118                 continue;
119             }
120             // ignore QNAME
121             if (attributeField.getName().equals("QNAME")) {
122                 continue;
123             }
124
125             attributeField.setAccessible(true);
126             try {
127                 if (accessor == ACCESSOR_FIELD) {
128                     sourceField = source.getClass().getDeclaredField(attributeField.getName());
129                     sourceField.setAccessible(true);
130                     if (attributeField.getType().equals(String.class) && !sourceField.getType().equals(String.class)) {
131                         attributeField.set(object, String.valueOf(sourceField.get(source)));
132                     } else {
133                         attributeField.set(object, sourceField.get(source));
134                     }
135                 } else if (accessor == ACCESSOR_METHOD) {
136                     String getter = getter(attributeField.getName());
137                     System.out.println("getter=" + getter);
138                     m = source.getClass().getDeclaredMethod(getter);
139                     m.setAccessible(true);
140                     if (attributeField.getType().equals(String.class) && !m.getReturnType().equals(String.class)) {
141                         attributeField.set(object, String.valueOf(m.invoke(source)));
142                     } else {
143                         attributeField.set(object, m.invoke(source));
144                     }
145                 }
146
147             } catch (NoSuchMethodException | NoSuchFieldException e) {
148                 // Convert to run-time exception
149                 String msg = "no such field " + attributeField.getName() + " in class " + source.getClass().getName();
150                 LOG.debug(msg);
151                 // throw new IllegalArgumentException(msg);
152             } catch (IllegalAccessException | SecurityException e) {
153                 LOG.debug("Access problem " + attributeField.getName(), e);
154             } catch (IllegalArgumentException e) {
155                 LOG.debug("argument problem " + attributeField.getName(), e);
156             } catch (InvocationTargetException e) {
157                 LOG.debug("invocation problem " + attributeField.getName(), e);
158             }
159         }
160
161         return object;
162     }
163
164     private static String getter(String name) {
165         return String.format("%s%s%s", "get", name.substring(1, 2).toUpperCase(), name.substring(2));
166     }
167
168     public <S extends DataObject, T extends DataObject, B extends Builder<T>> B cloneToBuilder(S source, B builder) {
169         return cloneToBuilder(source, builder, null);
170     }
171
172     public <S extends DataObject, T extends DataObject, B extends Builder<T>> B cloneToBuilder(S source, B builder,
173             @Nullable List<String> attrList) {
174         Field[] attributeFields;
175         Field sourceField;
176         Method m;
177         attributeFields = builder.getClass().getDeclaredFields();
178         for (Field attributeField : attributeFields) {
179             // check if attr is in inclusion list
180             if (attrList != null && !attrList.contains(attributeField.getName())) {
181                 continue;
182             }
183             // ignore QNAME
184             if (attributeField.getName().equals("QNAME")) {
185                 continue;
186             }
187
188             attributeField.setAccessible(true);
189             try {
190                 if (accessor == ACCESSOR_FIELD) {
191                     sourceField = source.getClass().getDeclaredField(attributeField.getName());
192                     sourceField.setAccessible(true);
193                     if (attributeField.getType().equals(String.class) && !sourceField.getType().equals(String.class)) {
194                         attributeField.set(builder, String.valueOf(sourceField.get(source)));
195                     } else {
196                         attributeField.set(builder, sourceField.get(source));
197                     }
198                 } else if (accessor == ACCESSOR_METHOD) {
199                     m = source.getClass().getDeclaredMethod(getter(attributeField.getName()));
200                     m.setAccessible(true);
201                     if (attributeField.getType().equals(String.class) && !m.getReturnType().equals(String.class)) {
202                         attributeField.set(builder, String.valueOf(m.invoke(source)));
203                     } else {
204                         attributeField.set(builder, m.invoke(source));
205                     }
206                 }
207
208             } catch (NoSuchMethodException | NoSuchFieldException e) {
209                 // Convert to run-time exception
210                 String msg = "no such field " + attributeField.getName() + " in class " + source.getClass().getName();
211                 LOG.debug(msg);
212                 // throw new IllegalArgumentException(msg);
213             } catch (IllegalAccessException | SecurityException e) {
214                 LOG.debug("Access problem " + attributeField.getName(), e);
215             } catch (IllegalArgumentException e) {
216                 LOG.debug("argument problem " + attributeField.getName(), e);
217             } catch (InvocationTargetException e) {
218                 LOG.debug("invocation problem " + attributeField.getName(), e);
219             }
220         }
221         return builder;
222     }
223 }