Merge "YANG Model update for A1 Adapter"
[ccsdk/features.git] / sdnr / wt / data-provider / database / src / main / java / org / onap / ccsdk / features / sdnr / wt / yangtools / YangToolsCloner.java
1 /*******************************************************************************
2  * ============LICENSE_START========================================================================
3  * ONAP : ccsdk feature sdnr wt
4  * =================================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
6  * =================================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License
13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14  * or implied. See the License for the specific language governing permissions and limitations under
15  * the License.
16  * ============LICENSE_END==========================================================================
17  ******************************************************************************/
18 package org.onap.ccsdk.features.sdnr.wt.yangtools;
19
20 import java.lang.reflect.Field;
21 import java.lang.reflect.InvocationTargetException;
22 import java.lang.reflect.Method;
23 import java.util.ArrayList;
24 import java.util.List;
25
26 import javax.annotation.Nullable;
27
28 import org.opendaylight.yangtools.concepts.Builder;
29 import org.opendaylight.yangtools.yang.binding.DataObject;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 public class YangToolsCloner {
34
35         private static YangToolsMapper yangtoolsMapper = new YangToolsMapper();
36         private static final Logger LOG = LoggerFactory.getLogger(YangToolsCloner.class);
37         public static final int ACCESSOR_FIELD = 0;
38         public static final int ACCESSOR_METHOD = 1;
39
40
41         private final int accessor;
42
43         private YangToolsCloner(int ac) {
44                 this.accessor = ac;
45         }
46         public static YangToolsCloner instance() {
47                 return instance(ACCESSOR_METHOD);
48         }
49         public static YangToolsCloner instance(int ac) {
50                 return new YangToolsCloner(ac);
51         }
52         /**
53          *
54      * @param source source object
55          * @param clazz Class of return object
56          * @return list of cloned object
57          * @return
58          */
59         public <S extends DataObject, T extends DataObject> List<T> cloneList(List<S> source, Class<T> clazz) {
60                 return cloneList(source, clazz, null);
61         }
62
63         /**
64          *
65          * @param source source object
66          * @param clazz Class of return object
67          * @attrList filter for attribute Names to clone
68          * @return list of cloned object
69          */
70         public <S extends DataObject, T extends DataObject> List<T> cloneList(List<S> source, Class<T> clazz,
71                         @Nullable List<String> attrList) {
72                 if (source == null) {
73                         return null;
74                 }
75                 List<T> list = new ArrayList<T>();
76                 for (S s : source) {
77                         list.add(clone(s, clazz, attrList));
78                 }
79                 return list;
80         }
81
82         /**
83          *
84          * @param source source object
85          * @param clazz Class of return object
86          * @return cloned object
87          */
88         public <S , T extends DataObject> T clone(S source, Class<T> clazz) {
89                 return clone(source, clazz, null);
90         }
91         /**
92          *
93          * @param source source object
94          * @param clazz Class of return object
95          * @attrList if empty copy all else list of attribute Names to clone
96          * @return cloned object
97          */
98         public <S, T extends DataObject> T clone(S source, Class<T> clazz,
99                         @Nullable List<String> attrList) {
100                 if (source == null) {
101                         return (T)null;
102                 }
103                 Field[] attributeFields;
104                 Field sourceField;
105                 Method m;
106                 Builder<T> builder = yangtoolsMapper.getBuilder(clazz);
107                 T object = builder.build();
108                 attributeFields = object.getClass().getDeclaredFields();
109                 for (Field attributeField : attributeFields) {
110                         // check if attr is in inclusion list
111                         if (attrList != null && !attrList.contains(attributeField.getName())) {
112                                 continue;
113                         }
114                         // ignore QNAME
115                         if (attributeField.getName().equals("QNAME")) {
116                                 continue;
117                         }
118
119                         attributeField.setAccessible(true);
120                         try {
121                                 if(accessor==ACCESSOR_FIELD) {
122                                         sourceField = source.getClass().getDeclaredField(attributeField.getName());
123                                         sourceField.setAccessible(true);
124                                         if (attributeField.getType().equals(String.class) && !sourceField.getType().equals(String.class)) {
125                                                 attributeField.set(object, String.valueOf(sourceField.get(source)));
126                                         } else {
127                                                 attributeField.set(object, sourceField.get(source));
128                                         }
129                                 }
130                                 else if(accessor==ACCESSOR_METHOD) {
131                                         String getter = getter(attributeField.getName());
132                                         System.out.println("getter="+getter);
133                                         m = source.getClass().getDeclaredMethod(getter);
134                                         m.setAccessible(true);
135                                         if (attributeField.getType().equals(String.class) && !m.getReturnType().equals(String.class)) {
136                                                 attributeField.set(object, String.valueOf(m.invoke(source)));
137                                         } else {
138                                                 attributeField.set(object, m.invoke(source));
139                                         }
140                                 }
141
142                         } catch (NoSuchMethodException | NoSuchFieldException e) {
143                                 // Convert to run-time exception
144                                 String msg = "no such field " + attributeField.getName() + " in class " + source.getClass().getName();
145                                 LOG.debug(msg);
146                                 // throw new IllegalArgumentException(msg);
147                         } catch (IllegalAccessException|SecurityException e) {
148                                 LOG.debug("Access problem " + attributeField.getName(), e);
149                         } catch (IllegalArgumentException e) {
150                                 LOG.debug("argument problem " + attributeField.getName(), e);
151                         } catch (InvocationTargetException e) {
152                                 LOG.debug("invocation problem " + attributeField.getName(), e);
153                         }
154                 }
155
156                 return object;
157         }
158
159         private static String getter(String name) {
160                 return String.format("%s%s%s","get",name.substring(1, 2).toUpperCase(),name.substring(2));
161         }
162         public <S extends DataObject, T extends DataObject,B extends Builder<T>> B cloneToBuilder(S source, B builder){
163                 return cloneToBuilder(source, builder,null);
164         }
165         public <S extends DataObject, T extends DataObject,B extends Builder<T>> B  cloneToBuilder(S source, B builder,
166                         @Nullable List<String> attrList) {
167                 Field[] attributeFields;
168                 Field sourceField;
169                 Method m;
170                 attributeFields = builder.getClass().getDeclaredFields();
171                 for (Field attributeField : attributeFields) {
172                         // check if attr is in inclusion list
173                         if (attrList != null && !attrList.contains(attributeField.getName())) {
174                                 continue;
175                         }
176                         // ignore QNAME
177                         if (attributeField.getName().equals("QNAME")) {
178                                 continue;
179                         }
180
181                         attributeField.setAccessible(true);
182                         try {
183                                 if(accessor==ACCESSOR_FIELD) {
184                                         sourceField = source.getClass().getDeclaredField(attributeField.getName());
185                                         sourceField.setAccessible(true);
186                                         if (attributeField.getType().equals(String.class) && !sourceField.getType().equals(String.class)) {
187                                                 attributeField.set(builder, String.valueOf(sourceField.get(source)));
188                                         } else {
189                                                 attributeField.set(builder, sourceField.get(source));
190                                         }
191                                 }
192                                 else if(accessor==ACCESSOR_METHOD) {
193                                         m = source.getClass().getDeclaredMethod(getter(attributeField.getName()));
194                                         m.setAccessible(true);
195                                         if (attributeField.getType().equals(String.class) && !m.getReturnType().equals(String.class)) {
196                                                 attributeField.set(builder, String.valueOf(m.invoke(source)));
197                                         } else {
198                                                 attributeField.set(builder, m.invoke(source));
199                                         }
200                                 }
201
202                         } catch (NoSuchMethodException | NoSuchFieldException e) {
203                                 // Convert to run-time exception
204                                 String msg = "no such field " + attributeField.getName() + " in class " + source.getClass().getName();
205                                 LOG.debug(msg);
206                                 // throw new IllegalArgumentException(msg);
207                         } catch (IllegalAccessException|SecurityException e) {
208                                 LOG.debug("Access problem " + attributeField.getName(), e);
209                         } catch (IllegalArgumentException e) {
210                                 LOG.debug("argument problem " + attributeField.getName(), e);
211                         } catch (InvocationTargetException e) {
212                                 LOG.debug("invocation problem " + attributeField.getName(), e);
213                         }
214                 }
215                 return builder;
216         }
217 }