Replaced all tabs with spaces in java and pom.xml
[so.git] / bpmn / MSOCommonBPMN / src / test / java / org / onap / so / SerializableChecker.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 - 2018 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.so;
22
23 import java.io.Serializable;
24 import java.lang.reflect.Field;
25 import java.lang.reflect.Modifier;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.HashSet;
29 import java.util.List;
30 import java.util.Set;
31
32 public final class SerializableChecker {
33     public static class SerializationFailure {
34         private final String mContainingClass;
35         private final String mMemberName;
36
37         public SerializationFailure(String inNonSerializableClass, String inMemberName) {
38             mContainingClass = inNonSerializableClass;
39             mMemberName = inMemberName;
40         }
41
42         public String getContainingClass() {
43             return mContainingClass;
44         }
45
46         public String getMemberName() {
47             return mMemberName;
48         }
49
50         public String getBadMemberString() {
51             if (mMemberName == null)
52                 return mContainingClass;
53             return mContainingClass + "." + mMemberName;
54         }
55
56         @Override
57         public String toString() {
58             return "SerializationFailure [mNonSerializableClass=" + mContainingClass + ", mMemberName=" + mMemberName
59                     + "]";
60         }
61     }
62
63     private static class SerializationCheckerData {
64         private Set<Class<?>> mSerializableClasses;
65
66         SerializationCheckerData() {
67             mSerializableClasses = new HashSet<Class<?>>();
68         }
69
70         boolean isAlreadyChecked(Class<?> inClass) {
71             return mSerializableClasses.contains(inClass);
72         }
73
74         void addSerializableClass(Class<?> inClass) {
75             mSerializableClasses.add(inClass);
76         }
77     }
78
79     private SerializableChecker() {}
80
81     public static SerializationFailure isFullySerializable(Class<?> inClass) {
82         if (!isSerializable(inClass))
83             return new SerializationFailure(inClass.getName(), null);
84
85         return isFullySerializable(inClass, new SerializationCheckerData());
86     }
87
88     private static SerializationFailure isFullySerializable(Class<?> inClass,
89             SerializationCheckerData inSerializationCheckerData) {
90         for (Field field : declaredFields(inClass)) {
91             Class<?> fieldDeclaringClass = field.getType();
92
93             if (field.getType() == Object.class)
94                 continue;
95
96             if (Modifier.isStatic(field.getModifiers()))
97                 continue;
98
99             if (field.isSynthetic())
100                 continue;
101
102             if (fieldDeclaringClass.isInterface() || fieldDeclaringClass.isPrimitive())
103                 continue;
104
105             if (Modifier.isAbstract(field.getType().getModifiers()))
106                 continue;
107
108             if (inSerializationCheckerData.isAlreadyChecked(fieldDeclaringClass))
109                 continue;
110
111             if (isSerializable(fieldDeclaringClass)) {
112                 inSerializationCheckerData.addSerializableClass(inClass);
113
114                 SerializationFailure failure = isFullySerializable(field.getType(), inSerializationCheckerData);
115                 if (failure != null)
116                     return failure;
117                 else
118                     continue;
119             }
120
121             if (Modifier.isTransient(field.getModifiers()))
122                 continue;
123
124             return new SerializationFailure(field.getDeclaringClass().getName(), field.getName());
125         }
126         return null;
127     }
128
129     private static boolean isSerializable(Class<?> inClass) {
130         Set<Class<?>> interfaces = getInterfaces(inClass);
131         if (interfaces == null)
132             return false;
133         boolean isSerializable = interfaces.contains(Serializable.class);
134         if (isSerializable)
135             return true;
136
137         for (Class<?> classInterface : interfaces) {
138             if (isSerializable(classInterface))
139                 return true;
140         }
141
142         if (inClass.getSuperclass() != null && isSerializable(inClass.getSuperclass()))
143             return true;
144
145         return false;
146     }
147
148     private static Set<Class<?>> getInterfaces(Class<?> inFieldDeclaringClass) {
149         return new HashSet<Class<?>>(Arrays.asList(inFieldDeclaringClass.getInterfaces()));
150     }
151
152     private static List<Field> declaredFields(Class<?> inClass) {
153         List<Field> fields = new ArrayList<Field>(Arrays.asList(inClass.getDeclaredFields()));
154
155         Class<?> parentClasses = inClass.getSuperclass();
156
157         if (parentClasses == null)
158             return fields;
159         fields.addAll(declaredFields(parentClasses));
160
161         return fields;
162     }
163 }