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