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