Containerization feature of SO
[so.git] / common / src / main / java / org / onap / so / openpojo / rules / EqualsAndHashCodeTester.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 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.openpojo.rules;
22
23 import static org.hamcrest.CoreMatchers.anyOf;
24 import static org.hamcrest.CoreMatchers.anything;
25
26 import java.lang.reflect.Method;
27 import java.util.ArrayList;
28 import java.util.HashSet;
29 import java.util.List;
30 import java.util.Set;
31
32 import javax.persistence.GeneratedValue;
33 import javax.persistence.Id;
34
35 import org.hamcrest.Matcher;
36
37 import com.openpojo.business.annotation.BusinessKey;
38 import com.openpojo.random.RandomFactory;
39 import com.openpojo.reflection.PojoClass;
40 import com.openpojo.reflection.PojoField;
41 import com.openpojo.validation.affirm.Affirm;
42 import com.openpojo.validation.test.Tester;
43 import com.openpojo.validation.utils.ValidationHelper;
44
45 public class EqualsAndHashCodeTester implements Tester {
46
47         
48         private final Matcher m;
49         private boolean onlyDeclaredMethods = false;
50         public EqualsAndHashCodeTester() {
51                 m = anything();
52         }
53         
54         public EqualsAndHashCodeTester(Matcher m) {
55                 this.m = m;
56         }
57         
58         public EqualsAndHashCodeTester onlyDeclaredMethods() {
59                 this.onlyDeclaredMethods = true;
60                 return this;
61         }
62         @Override
63         public void run(PojoClass pojoClass) {
64                 Class<?> clazz = pojoClass.getClazz();
65                 if (anyOf(m).matches(clazz)) {
66                         final Object classInstanceOne = ValidationHelper.getBasicInstance(pojoClass);
67                         final Object classInstanceTwo = ValidationHelper.getBasicInstance(pojoClass);
68                         if (onlyDeclaredMethods) {
69                                 Method[] methods = classInstanceOne.getClass().getDeclaredMethods();
70                                 boolean hasEquals = false;
71                                 boolean hasHashcode = false;
72                                 for (Method method : methods) {
73                                         if (method.getName().equals("equals")) {
74                                                 hasEquals = true;
75                                         } else if (method.getName().equals("hashCode")) {
76                                                 hasHashcode = true;
77                                         }
78                                 }
79                                 
80                                 if (!(hasEquals && hasHashcode)) {
81                                         return;
82                                 }
83                         }
84                         Set<PojoField> identityFields = hasIdOrBusinessKey(pojoClass);
85                         List<PojoField> otherFields = new ArrayList<>(pojoClass.getPojoFields());
86                         otherFields.removeAll(identityFields);
87                         
88                         for (PojoField field : identityFields) {
89                                 final Object value  = RandomFactory.getRandomValue(field);
90         
91                                 field.invokeSetter(classInstanceOne, value);
92                                 field.invokeSetter(classInstanceTwo, value);
93                         }
94                         
95                         for (PojoField field : otherFields) {
96                                 if (field.hasSetter()) {
97                                         final Object valueOne  = RandomFactory.getRandomValue(field);
98                                         final Object valueTwo  = RandomFactory.getRandomValue(field);
99                                         
100                                         field.invokeSetter(classInstanceOne, valueOne);
101                                         field.invokeSetter(classInstanceTwo, valueTwo);
102                                 }
103                         }
104                         
105                         Affirm.affirmTrue("Equals test failed for [" + classInstanceOne.getClass().getName() + "]", classInstanceOne.equals(classInstanceTwo));
106                         
107                         Affirm.affirmTrue("Equals test failed for [" + classInstanceOne.getClass().getName() + "]", classInstanceOne.equals(
108                                         classInstanceOne));
109                         
110                         Affirm.affirmTrue("HashCode test failed for [" + classInstanceOne.getClass().getName() + "]", classInstanceOne.hashCode() == classInstanceTwo.hashCode());
111                         
112                         Affirm.affirmFalse("Expected false for comparison of two unlike objects", classInstanceOne.equals("test"));
113                 }
114         }
115         
116         
117         private Set<PojoField> hasIdOrBusinessKey(PojoClass pojoClass) {
118                 final Set<PojoField> fields = new HashSet<>();
119                 
120                 fields.addAll(pojoClass.getPojoFieldsAnnotatedWith(BusinessKey.class));
121                 fields.addAll(pojoClass.getPojoFieldsAnnotatedWith(Id.class));
122                 fields.removeAll(pojoClass.getPojoFieldsAnnotatedWith(GeneratedValue.class));
123                 
124                 return fields;
125                 
126         }
127
128 }