diff options
author | Benjamin, Max (mb388a) <mb388a@us.att.com> | 2018-03-21 14:16:56 -0400 |
---|---|---|
committer | Benjamin, Max (mb388a) <mb388a@us.att.com> | 2018-03-21 14:18:16 -0400 |
commit | db675a54e8e7bb3553e059d237774b4b737488f1 (patch) | |
tree | c2eaec34581f45ee16cb15ea3a208a61348b6fc0 /common/src/main | |
parent | 558a73181640d0d19f7f05cab6e0b8568574b504 (diff) |
added custom validators for use with openpojo
Change-Id: I7c9fdeb6bccddb1b7ec6bf845351731c3043aafa
Issue-ID: SO-510
Signed-off-by: Benjamin, Max (mb388a) <mb388a@us.att.com>
Diffstat (limited to 'common/src/main')
7 files changed, 513 insertions, 0 deletions
diff --git a/common/src/main/java/org/openecomp/mso/openpojo/rules/CustomSetterMustExistRule.java b/common/src/main/java/org/openecomp/mso/openpojo/rules/CustomSetterMustExistRule.java new file mode 100644 index 0000000000..fa24662d69 --- /dev/null +++ b/common/src/main/java/org/openecomp/mso/openpojo/rules/CustomSetterMustExistRule.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2018 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.openecomp.mso.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<PojoField>[] 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<PojoField>... 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/openecomp/mso/openpojo/rules/EqualsAndHashCodeTester.java b/common/src/main/java/org/openecomp/mso/openpojo/rules/EqualsAndHashCodeTester.java new file mode 100644 index 0000000000..f4192e6cc8 --- /dev/null +++ b/common/src/main/java/org/openecomp/mso/openpojo/rules/EqualsAndHashCodeTester.java @@ -0,0 +1,103 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2018 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.openecomp.mso.openpojo.rules; + +import static org.hamcrest.CoreMatchers.anyOf; +import static org.hamcrest.CoreMatchers.anything; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +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; + public EqualsAndHashCodeTester() { + m = anything(); + } + + public EqualsAndHashCodeTester(Matcher m) { + this.m = m; + } + @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); + 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)); + + return fields; + + } + +} diff --git a/common/src/main/java/org/openecomp/mso/openpojo/rules/HasAnnotationMatcher.java b/common/src/main/java/org/openecomp/mso/openpojo/rules/HasAnnotationMatcher.java new file mode 100644 index 0000000000..fdfb9695e7 --- /dev/null +++ b/common/src/main/java/org/openecomp/mso/openpojo/rules/HasAnnotationMatcher.java @@ -0,0 +1,69 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2018 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.openecomp.mso.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; + +public class HasAnnotationMatcher<T extends Annotation> extends TypeSafeDiagnosingMatcher<AnnotatedElement> { + private final Class<T> annotationType; + private final Matcher<? super T> annotationMatcher; + + public HasAnnotationMatcher(final Class<T> annotationType, final Matcher<? super T> annotationMatcher) { + this.annotationType = annotationType; + this.annotationMatcher = annotationMatcher; + } + + @Override + protected boolean matchesSafely(final AnnotatedElement item, final Description mismatchDescription) { + final T 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 Matcher<AnnotatedElement> hasAnnotation(final Class<? extends Annotation> annotationType) { + return hasAnnotation(annotationType, anything("")); + } + + public static <T extends Annotation> Matcher<AnnotatedElement> hasAnnotation(final Class<T> annotationType, final Matcher<? super T> annotationMatcher) { + return new HasAnnotationMatcher<T>(annotationType, annotationMatcher); + } +} diff --git a/common/src/main/java/org/openecomp/mso/openpojo/rules/HasAnnotationPropertyWithValueMatcher.java b/common/src/main/java/org/openecomp/mso/openpojo/rules/HasAnnotationPropertyWithValueMatcher.java new file mode 100644 index 0000000000..f0c1b18df2 --- /dev/null +++ b/common/src/main/java/org/openecomp/mso/openpojo/rules/HasAnnotationPropertyWithValueMatcher.java @@ -0,0 +1,75 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2018 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.openecomp.mso.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 com.openpojo.reflection.PojoField; + +public class HasAnnotationPropertyWithValueMatcher<T extends PojoField> extends TypeSafeDiagnosingMatcher<T> { + 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); + 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/openecomp/mso/openpojo/rules/HasEqualsAndHashCodeRule.java b/common/src/main/java/org/openecomp/mso/openpojo/rules/HasEqualsAndHashCodeRule.java new file mode 100644 index 0000000000..4ef560721f --- /dev/null +++ b/common/src/main/java/org/openecomp/mso/openpojo/rules/HasEqualsAndHashCodeRule.java @@ -0,0 +1,81 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2018 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.openecomp.mso.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/openecomp/mso/openpojo/rules/HasToStringRule.java b/common/src/main/java/org/openecomp/mso/openpojo/rules/HasToStringRule.java new file mode 100644 index 0000000000..f866650d66 --- /dev/null +++ b/common/src/main/java/org/openecomp/mso/openpojo/rules/HasToStringRule.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2018 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.openecomp.mso.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/openecomp/mso/openpojo/rules/ToStringTester.java b/common/src/main/java/org/openecomp/mso/openpojo/rules/ToStringTester.java new file mode 100644 index 0000000000..bd582d45dc --- /dev/null +++ b/common/src/main/java/org/openecomp/mso/openpojo/rules/ToStringTester.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Copyright (C) 2018 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.openecomp.mso.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+")); + } + + } + +} |