2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Modifications Copyright (c) 2019 Samsung
8 * ================================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 * ============LICENSE_END=========================================================
23 package org.onap.so.openpojo.rules;
25 import static org.hamcrest.CoreMatchers.anyOf;
26 import static org.hamcrest.CoreMatchers.anything;
28 import java.lang.reflect.Method;
29 import java.util.ArrayList;
30 import java.util.HashSet;
31 import java.util.List;
34 import javax.persistence.GeneratedValue;
35 import javax.persistence.Id;
37 import org.hamcrest.Matcher;
39 import com.openpojo.business.annotation.BusinessKey;
40 import com.openpojo.random.RandomFactory;
41 import com.openpojo.reflection.PojoClass;
42 import com.openpojo.reflection.PojoField;
43 import com.openpojo.validation.affirm.Affirm;
44 import com.openpojo.validation.test.Tester;
45 import com.openpojo.validation.utils.ValidationHelper;
47 public class EqualsAndHashCodeTester implements Tester {
50 private final Matcher m;
51 private boolean onlyDeclaredMethods = false;
52 public EqualsAndHashCodeTester() {
56 public EqualsAndHashCodeTester(Matcher m) {
60 public EqualsAndHashCodeTester onlyDeclaredMethods() {
61 this.onlyDeclaredMethods = true;
65 // Marks sonar warnings about object being compared to itself as false positive
66 // https://sonar.onap.org/coding_rules#rule_key=squid%3AS1764
67 @SuppressWarnings("squid:S1764")
69 public void run(PojoClass pojoClass) {
70 Class<?> clazz = pojoClass.getClazz();
71 if (anyOf(m).matches(clazz)) {
72 final Object classInstanceOne = ValidationHelper.getBasicInstance(pojoClass);
73 final Object classInstanceTwo = ValidationHelper.getBasicInstance(pojoClass);
74 if (onlyDeclaredMethods) {
75 Method[] methods = classInstanceOne.getClass().getDeclaredMethods();
76 boolean hasEquals = false;
77 boolean hasHashcode = false;
78 for (Method method : methods) {
79 if (method.getName().equals("equals")) {
81 } else if (method.getName().equals("hashCode")) {
86 if (!(hasEquals && hasHashcode)) {
90 Set<PojoField> identityFields = hasIdOrBusinessKey(pojoClass);
91 List<PojoField> otherFields = new ArrayList<>(pojoClass.getPojoFields());
92 otherFields.removeAll(identityFields);
94 for (PojoField field : identityFields) {
95 final Object value = RandomFactory.getRandomValue(field);
97 field.invokeSetter(classInstanceOne, value);
98 field.invokeSetter(classInstanceTwo, value);
101 for (PojoField field : otherFields) {
102 if (field.hasSetter()) {
103 final Object valueOne = RandomFactory.getRandomValue(field);
104 final Object valueTwo = RandomFactory.getRandomValue(field);
106 field.invokeSetter(classInstanceOne, valueOne);
107 field.invokeSetter(classInstanceTwo, valueTwo);
111 Affirm.affirmTrue("Equals test failed for [" + classInstanceOne.getClass().getName() + "]", classInstanceOne.equals(classInstanceTwo));
113 Affirm.affirmTrue("Expected true for comparison of the same references [" + classInstanceOne.getClass().getName() + "]",
114 classInstanceOne.equals(classInstanceOne));
116 Affirm.affirmTrue("HashCode test failed for [" + classInstanceOne.getClass().getName() + "]", classInstanceOne.hashCode() == classInstanceTwo.hashCode());
118 Affirm.affirmFalse("Expected false for comparison of two unlike objects", classInstanceOne.equals("test"));
123 private Set<PojoField> hasIdOrBusinessKey(PojoClass pojoClass) {
124 final Set<PojoField> fields = new HashSet<>();
126 fields.addAll(pojoClass.getPojoFieldsAnnotatedWith(BusinessKey.class));
127 fields.addAll(pojoClass.getPojoFieldsAnnotatedWith(Id.class));
128 fields.removeAll(pojoClass.getPojoFieldsAnnotatedWith(GeneratedValue.class));