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