diff options
Diffstat (limited to 'common/src/main/java/org/onap/so/openpojo')
7 files changed, 543 insertions, 0 deletions
diff --git a/common/src/main/java/org/onap/so/openpojo/rules/CustomSetterMustExistRule.java b/common/src/main/java/org/onap/so/openpojo/rules/CustomSetterMustExistRule.java new file mode 100644 index 0000000000..2c6590afb3 --- /dev/null +++ b/common/src/main/java/org/onap/so/openpojo/rules/CustomSetterMustExistRule.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.openpojo.rules; + +import static org.hamcrest.CoreMatchers.anyOf; +import static org.hamcrest.CoreMatchers.anything; +import static org.hamcrest.CoreMatchers.not; + +import org.hamcrest.Matcher; + +import com.openpojo.reflection.PojoClass; +import com.openpojo.reflection.PojoField; +import com.openpojo.validation.affirm.Affirm; +import com.openpojo.validation.rule.Rule; + +public class CustomSetterMustExistRule implements Rule { + + private Matcher[] excludeMatchers = new Matcher[]{not(anything())}; + private Matcher<PojoField>[] includeMatchers = new Matcher[]{anything()}; + public CustomSetterMustExistRule() { + } + @Override + public void evaluate(final PojoClass pojoClass) { + for (PojoField fieldEntry : pojoClass.getPojoFields()) { + if (!anyOf(excludeMatchers).matches(fieldEntry) && anyOf(includeMatchers).matches(fieldEntry) && !fieldEntry.isFinal() && !fieldEntry.hasSetter()) { + Affirm.fail(String.format("[%s] is missing a setter", fieldEntry)); + } + } + } + public CustomSetterMustExistRule exclude(Matcher... excludeMatchers) { + this.excludeMatchers = excludeMatchers; + return this; + } + + public CustomSetterMustExistRule include(Matcher<PojoField>... includeMatchers) { + this.includeMatchers = includeMatchers; + return this; + } + +} diff --git a/common/src/main/java/org/onap/so/openpojo/rules/EqualsAndHashCodeTester.java b/common/src/main/java/org/onap/so/openpojo/rules/EqualsAndHashCodeTester.java new file mode 100644 index 0000000000..5433681b83 --- /dev/null +++ b/common/src/main/java/org/onap/so/openpojo/rules/EqualsAndHashCodeTester.java @@ -0,0 +1,128 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.openpojo.rules; + +import static org.hamcrest.CoreMatchers.anyOf; +import static org.hamcrest.CoreMatchers.anything; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +import org.hamcrest.Matcher; + +import com.openpojo.business.annotation.BusinessKey; +import com.openpojo.random.RandomFactory; +import com.openpojo.reflection.PojoClass; +import com.openpojo.reflection.PojoField; +import com.openpojo.validation.affirm.Affirm; +import com.openpojo.validation.test.Tester; +import com.openpojo.validation.utils.ValidationHelper; + +public class EqualsAndHashCodeTester implements Tester { + + + private final Matcher m; + private boolean onlyDeclaredMethods = false; + public EqualsAndHashCodeTester() { + m = anything(); + } + + public EqualsAndHashCodeTester(Matcher m) { + this.m = m; + } + + public EqualsAndHashCodeTester onlyDeclaredMethods() { + this.onlyDeclaredMethods = true; + return this; + } + @Override + public void run(PojoClass pojoClass) { + Class<?> clazz = pojoClass.getClazz(); + if (anyOf(m).matches(clazz)) { + final Object classInstanceOne = ValidationHelper.getBasicInstance(pojoClass); + final Object classInstanceTwo = ValidationHelper.getBasicInstance(pojoClass); + if (onlyDeclaredMethods) { + Method[] methods = classInstanceOne.getClass().getDeclaredMethods(); + boolean hasEquals = false; + boolean hasHashcode = false; + for (Method method : methods) { + if (method.getName().equals("equals")) { + hasEquals = true; + } else if (method.getName().equals("hashCode")) { + hasHashcode = true; + } + } + + if (!(hasEquals && hasHashcode)) { + return; + } + } + Set<PojoField> identityFields = hasIdOrBusinessKey(pojoClass); + List<PojoField> otherFields = new ArrayList<>(pojoClass.getPojoFields()); + otherFields.removeAll(identityFields); + + for (PojoField field : identityFields) { + final Object value = RandomFactory.getRandomValue(field); + + field.invokeSetter(classInstanceOne, value); + field.invokeSetter(classInstanceTwo, value); + } + + for (PojoField field : otherFields) { + if (field.hasSetter()) { + final Object valueOne = RandomFactory.getRandomValue(field); + final Object valueTwo = RandomFactory.getRandomValue(field); + + field.invokeSetter(classInstanceOne, valueOne); + field.invokeSetter(classInstanceTwo, valueTwo); + } + } + + Affirm.affirmTrue("Equals test failed for [" + classInstanceOne.getClass().getName() + "]", classInstanceOne.equals(classInstanceTwo)); + + Affirm.affirmTrue("Equals test failed for [" + classInstanceOne.getClass().getName() + "]", classInstanceOne.equals( + classInstanceOne)); + + Affirm.affirmTrue("HashCode test failed for [" + classInstanceOne.getClass().getName() + "]", classInstanceOne.hashCode() == classInstanceTwo.hashCode()); + + Affirm.affirmFalse("Expected false for comparison of two unlike objects", classInstanceOne.equals("test")); + } + } + + + private Set<PojoField> hasIdOrBusinessKey(PojoClass pojoClass) { + final Set<PojoField> fields = new HashSet<>(); + + fields.addAll(pojoClass.getPojoFieldsAnnotatedWith(BusinessKey.class)); + fields.addAll(pojoClass.getPojoFieldsAnnotatedWith(Id.class)); + fields.removeAll(pojoClass.getPojoFieldsAnnotatedWith(GeneratedValue.class)); + + return fields; + + } + +} diff --git a/common/src/main/java/org/onap/so/openpojo/rules/HasAnnotationMatcher.java b/common/src/main/java/org/onap/so/openpojo/rules/HasAnnotationMatcher.java new file mode 100644 index 0000000000..6a06834d87 --- /dev/null +++ b/common/src/main/java/org/onap/so/openpojo/rules/HasAnnotationMatcher.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.openpojo.rules; + +import static org.hamcrest.CoreMatchers.anything; + +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; + +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeDiagnosingMatcher; + +import com.openpojo.reflection.PojoField; + +public class HasAnnotationMatcher<T extends PojoField> extends TypeSafeDiagnosingMatcher<T> { + private final Class<? extends Annotation> annotationType; + private final Matcher<? super T> annotationMatcher; + + public HasAnnotationMatcher(final Class<? extends Annotation> annotationType, final Matcher<? super T> annotationMatcher) { + this.annotationType = annotationType; + this.annotationMatcher = annotationMatcher; + } + + @Override + protected boolean matchesSafely(final PojoField item, final Description mismatchDescription) { + final Annotation annotation = item.getAnnotation(this.annotationType); + if (annotation == null) { + mismatchDescription.appendText("does not have annotation ").appendText(this.annotationType.getName()); + return false; + } + + if (!this.annotationMatcher.matches(annotation)) { + this.annotationMatcher.describeMismatch(annotation, mismatchDescription); + return false; + } + + return true; + } + + @Override + public void describeTo(final Description description) { + // Intentionally left blank. + } + + public static <T extends PojoField> Matcher<T> hasAnnotation(final Class<? extends Annotation> annotationType) { + return hasAnnotation(annotationType, anything("")); + } + + public static <T extends PojoField> Matcher<T> hasAnnotation(final Class<? extends Annotation> annotationType, final Matcher<? super T> annotationMatcher) { + return new HasAnnotationMatcher<T>(annotationType, annotationMatcher); + } +} diff --git a/common/src/main/java/org/onap/so/openpojo/rules/HasAnnotationPropertyWithValueMatcher.java b/common/src/main/java/org/onap/so/openpojo/rules/HasAnnotationPropertyWithValueMatcher.java new file mode 100644 index 0000000000..551305c14a --- /dev/null +++ b/common/src/main/java/org/onap/so/openpojo/rules/HasAnnotationPropertyWithValueMatcher.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.openpojo.rules; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeDiagnosingMatcher; +import org.onap.so.logger.MsoLogger; + +import com.openpojo.reflection.PojoField; + +public class HasAnnotationPropertyWithValueMatcher<T extends PojoField> extends TypeSafeDiagnosingMatcher<T> { + private MsoLogger logger=MsoLogger.getMsoLogger(MsoLogger.Catalog.GENERAL, HasAnnotationPropertyWithValueMatcher.class); + private final String attribute; + private final Matcher<?> annotationMatcher; + private final Class<? extends Annotation> annotationClass; + public HasAnnotationPropertyWithValueMatcher(Class<? extends Annotation> clazz, String attribute, final Matcher<?> annotationMatcher) { + this.attribute = attribute; + this.annotationMatcher = annotationMatcher; + this.annotationClass = clazz; + } + + @Override + protected boolean matchesSafely(T obj, final Description mismatchDescription) { + final PojoField temp = (PojoField)obj; + final Method method; + try { + Annotation a = temp.getAnnotation(this.annotationClass); + if (a == null) { + mismatchDescription.appendText("does not have annotation ").appendText(this.annotationClass.getSimpleName()); + return false; + } + method = a.getClass().getMethod(attribute); + final Object result = method.invoke(a); + if (!this.annotationMatcher.matches(result)) { + this.annotationMatcher.describeMismatch(result, mismatchDescription); + return false; + } + } catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + mismatchDescription.appendText("does not have property ").appendText(attribute); + logger.debug("Error occured", e); + return false; + } + return true; + } + + @Override + public void describeTo(final Description description) { + // Intentionally left blank. + } + + public static <T extends PojoField> Matcher<T> hasAnnotationPropertyWithValue(Class<? extends Annotation> clazz, String attribute, final Matcher<?> annotationMatcher) { + return new HasAnnotationPropertyWithValueMatcher<T>(clazz, attribute, annotationMatcher); + } +} diff --git a/common/src/main/java/org/onap/so/openpojo/rules/HasEqualsAndHashCodeRule.java b/common/src/main/java/org/onap/so/openpojo/rules/HasEqualsAndHashCodeRule.java new file mode 100644 index 0000000000..0c7d6add73 --- /dev/null +++ b/common/src/main/java/org/onap/so/openpojo/rules/HasEqualsAndHashCodeRule.java @@ -0,0 +1,81 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.openpojo.rules; + +import static org.hamcrest.CoreMatchers.anyOf; +import static org.hamcrest.CoreMatchers.anything; + +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; + +import org.hamcrest.Matcher; + +import com.openpojo.reflection.PojoClass; +import com.openpojo.validation.affirm.Affirm; +import com.openpojo.validation.rule.Rule; + +/** + * This rule ensures that classes have overriden the default equals and hashCode methods from Object + */ +public class HasEqualsAndHashCodeRule implements Rule { + + private final Matcher m; + public HasEqualsAndHashCodeRule() { + m = anything(); + } + + public HasEqualsAndHashCodeRule(Matcher m) { + this.m = m; + } + @Override + public void evaluate(PojoClass pojoClass) { + Class<?> clazz = pojoClass.getClazz(); + if (anyOf(m).matches(clazz)) { + boolean hasEquals = false; + boolean hasHashCode = false; + final String name = clazz.getSimpleName(); + final Method[] methods; + if (clazz.getSuperclass().equals(Object.class)) { + methods = clazz.getDeclaredMethods(); + } else { + methods = clazz.getMethods(); + } + for (Method method : methods) { + Parameter[] parameters = method.getParameters(); + if ("equals".equals(method.getName()) && boolean.class.equals(method.getReturnType()) && parameters.length == 1 && Object.class.equals(parameters[0].getType())) { + hasEquals = true; + } else if ("hashCode".equals(method.getName()) && int.class.equals(method.getReturnType())) { + hasHashCode = true; + } + } + + if (!hasEquals) { + Affirm.fail(String.format( + "[%s] does not override equals", name)); + } + if (!hasHashCode) { + Affirm.fail(String.format( + "[%s] does not override hashCode", name)); + } + } + } + +} diff --git a/common/src/main/java/org/onap/so/openpojo/rules/HasToStringRule.java b/common/src/main/java/org/onap/so/openpojo/rules/HasToStringRule.java new file mode 100644 index 0000000000..8a4333e0e2 --- /dev/null +++ b/common/src/main/java/org/onap/so/openpojo/rules/HasToStringRule.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.openpojo.rules; + +import static org.hamcrest.CoreMatchers.anyOf; +import static org.hamcrest.CoreMatchers.anything; + +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; + +import org.hamcrest.Matcher; + +import com.openpojo.reflection.PojoClass; +import com.openpojo.validation.affirm.Affirm; +import com.openpojo.validation.rule.Rule; + +public class HasToStringRule implements Rule { + + private final Matcher m; + public HasToStringRule() { + m = anything(); + } + + public HasToStringRule(Matcher m) { + this.m = m; + } + @Override + public void evaluate(PojoClass pojoClass) { + Class<?> clazz = pojoClass.getClazz(); + if (anyOf(m).matches(clazz)) { + boolean hasToString = false; + final String name = clazz.getSimpleName(); + final Method[] methods; + if (clazz.getSuperclass().equals(Object.class)) { + methods = clazz.getDeclaredMethods(); + } else { + methods = clazz.getMethods(); + } + for (Method method : methods) { + Parameter[] parameters = method.getParameters(); + if ("toString".equals(method.getName()) && String.class.equals(method.getReturnType()) && parameters.length == 0) { + hasToString = true; + break; + } + } + + if (!hasToString) { + Affirm.fail(String.format( + "[%s] does not override toString", name)); + } + } + } + +} diff --git a/common/src/main/java/org/onap/so/openpojo/rules/ToStringTester.java b/common/src/main/java/org/onap/so/openpojo/rules/ToStringTester.java new file mode 100644 index 0000000000..ff1a139768 --- /dev/null +++ b/common/src/main/java/org/onap/so/openpojo/rules/ToStringTester.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.so.openpojo.rules; + +import static org.hamcrest.CoreMatchers.anyOf; +import static org.hamcrest.CoreMatchers.anything; + +import org.hamcrest.Matcher; + +import com.openpojo.reflection.PojoClass; +import com.openpojo.validation.affirm.Affirm; +import com.openpojo.validation.test.Tester; +import com.openpojo.validation.utils.ValidationHelper; + +public class ToStringTester implements Tester { + + private final Matcher m; + public ToStringTester() { + m = anything(); + } + + public ToStringTester(Matcher m) { + this.m = m; + } + + @Override + public void run(PojoClass pojoClass) { + Class<?> clazz = pojoClass.getClazz(); + if (anyOf(m).matches(clazz)) { + final Object classInstance = ValidationHelper.getBasicInstance(pojoClass); + + Affirm.affirmFalse("Found default toString output", classInstance.toString().matches(Object.class.getName() + "@" + "\\w+")); + } + + } + +} |