commit d971d5c04cf3896084fce766fe25bace15d7e318 Author: fabio.simeoni Date: Thu Oct 24 09:37:20 2013 +0000 branched for 1.x releases git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/branches/common/common-validator/1.0@83926 82a268e6-3cf1-43bd-a215-b396298e98cf diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..efcf778 --- /dev/null +++ b/.classpath @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..5ca7b9c --- /dev/null +++ b/.project @@ -0,0 +1,23 @@ + + + common-validator + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..e32b66e --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,7 @@ +#Thu Oct 24 11:33:16 CEST 2013 +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding//src/test/java=UTF-8 +encoding//src/test/resources=UTF-8 +encoding/=UTF-8 diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..b6f0f4d --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,13 @@ +#Thu Oct 24 11:33:16 CEST 2013 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..c7c6a1e --- /dev/null +++ b/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,5 @@ +#Mon Sep 09 18:07:27 CEST 2013 +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/distro/INSTALL b/distro/INSTALL new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/distro/INSTALL @@ -0,0 +1 @@ + diff --git a/distro/LICENSE b/distro/LICENSE new file mode 100644 index 0000000..630ba97 --- /dev/null +++ b/distro/LICENSE @@ -0,0 +1,6 @@ +gCube System - License +------------------------------------------------------------ + +The gCube/gCore software is licensed as Free Open Source software conveying to the EUPL (http://ec.europa.eu/idabc/eupl). +The software and documentation is provided by its authors/distributors "as is" and no expressed or +implied warranty is given for its use, quality or fitness for a particular case. diff --git a/distro/MAINTAINERS b/distro/MAINTAINERS new file mode 100644 index 0000000..02d640e --- /dev/null +++ b/distro/MAINTAINERS @@ -0,0 +1,2 @@ +* Lucio Lelii (lucio.lelii@isti.cnr.it), CNR, Italy +* Fabio Simeoni (fabio.simeoni@fao.org), FAO of the UN, Italy \ No newline at end of file diff --git a/distro/README b/distro/README new file mode 100644 index 0000000..8ba3d75 --- /dev/null +++ b/distro/README @@ -0,0 +1,39 @@ +The gCube System - ${name} +---------------------- + +This work has been partially supported by the following European projects: DILIGENT (FP6-2003-IST-2), D4Science (FP7-INFRA-2007-1.2.2), +D4Science-II (FP7-INFRA-2008-1.2.2), iMarine (FP7-INFRASTRUCTURES-2011-2), and EUBrazilOpenBio (FP7-ICT-2011-EU-Brazil). + +Authors +------- + +* Lucio Lelii (lucio.lelii@isti.cnr.it), CNR, Italy +* Fabio Simeoni (fabio.simeoni@fao.org), FAO of the UN, Italy + +Version and Release Date +------------------------ +${version} + +Description +----------- +${description} + +Download information +-------------------- + +Source code is available from SVN: +${scm.url} + +Binaries can be downloaded from: + + +Documentation +------------- +Documentation is available on-line from the Projects Documentation Wiki: +https://gcube.wiki.gcube-system.org/gcube/index.php/.... + + +Licensing +--------- + +This software is licensed under the terms you may find in the file named "LICENSE" in this directory. diff --git a/distro/changelog.xml b/distro/changelog.xml new file mode 100644 index 0000000..a4d71f9 --- /dev/null +++ b/distro/changelog.xml @@ -0,0 +1,5 @@ + + + First Release + + \ No newline at end of file diff --git a/distro/descriptor.xml b/distro/descriptor.xml new file mode 100644 index 0000000..52cb8a5 --- /dev/null +++ b/distro/descriptor.xml @@ -0,0 +1,42 @@ + + servicearchive + + tar.gz + + / + + + ${distroDirectory} + / + true + + README + LICENSE + INSTALL + MAINTAINERS + changelog.xml + + 755 + true + + + + + ${distroDirectory}/profile.xml + /etc + true + + + target/${build.finalName}.jar + /${artifactId} + + + ${distroDirectory}/svnpath.txt + /${artifactId} + true + + + \ No newline at end of file diff --git a/distro/profile.xml b/distro/profile.xml new file mode 100644 index 0000000..91c49e4 --- /dev/null +++ b/distro/profile.xml @@ -0,0 +1,26 @@ + + + + Service + + ${description} + Common + ${artifactId} + 1.0.0 + + + ${artifactId} + ${version} + + ${groupId} + ${artifactId} + ${version} + + + ${build.finalName}.jar + + + + + + diff --git a/distro/svnpath.txt b/distro/svnpath.txt new file mode 100644 index 0000000..f416f9d --- /dev/null +++ b/distro/svnpath.txt @@ -0,0 +1 @@ +${scm.url} diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..e4e369f --- /dev/null +++ b/pom.xml @@ -0,0 +1,101 @@ + + 4.0.0 + + + maven-parent + org.gcube.tools + 1.0.0 + + + + org.gcube.core + common-validator + 1.0.0-SNAPSHOT + validator + + + distro + + + + scm:svn:http://svn.d4science.research-infrastructures.eu/gcube/trunk/Common/${project.artifactId} + scm:svn:https://svn.d4science.research-infrastructures.eu/gcube/trunk/Common/${project.artifactId} + http://svn.d4science.research-infrastructures.eu/gcube/trunk/Common/${project.artifactId} + + + + + + org.slf4j + slf4j-api + 1.7.5 + + + junit + junit + 4.8.2 + test + + + ch.qos.logback + logback-classic + 1.0.13 + test + + + + + + + + + + org.apache.maven.plugins + maven-resources-plugin + 2.5 + + + copy-profile + install + + copy-resources + + + target + + + ${distroDirectory} + true + + profile.xml + + + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + ${distroDirectory}/descriptor.xml + + + + + servicearchive + install + + single + + + + + + + + \ No newline at end of file diff --git a/src/main/java/org/gcube/common/validator/DefaultValidator.java b/src/main/java/org/gcube/common/validator/DefaultValidator.java new file mode 100644 index 0000000..8b7d81d --- /dev/null +++ b/src/main/java/org/gcube/common/validator/DefaultValidator.java @@ -0,0 +1,70 @@ +package org.gcube.common.validator; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.gcube.common.validator.annotations.FieldValidator; +import org.gcube.common.validator.annotations.IsValid; +import org.gcube.common.validator.annotations.ValidityChecker; +import org.gcube.common.validator.context.ValidatorContext; + + +public class DefaultValidator implements Validator{ + + public List validate(Object obj){ + try{ + return validateObject(obj, null); + }catch (Exception e) { + throw new RuntimeException(e); + } + } + + private List validateObject(Object obj, Object parent) throws Exception{ + List errors = new ArrayList(); + Class _clazz = obj.getClass(); + for (Field field:Util.getAllFields(_clazz)){ + ValidatorContext context = new ValidatorContext(parent, field, obj); + validateField(context); + errors.addAll(context.errors()); + } + return errors; + } + + private void validateField(ValidatorContext context) throws Exception{ + Field field = context.field(); + field.setAccessible(true); + Object object = context.value(); + for (Annotation annotation:field.getAnnotations()){ + if (annotation.annotationType().isAnnotationPresent(ValidityChecker.class)){ + Class> managedClass = ((ValidityChecker)annotation.annotationType().getAnnotation(ValidityChecker.class)).managed(); + FieldValidator validator = managedClass.newInstance(); + Object toCheck = field.get(object); + if (!validator.isValid(toCheck)) + context.addError(validator.getErrorSuffix()); + } + } + + if(field.isAnnotationPresent(IsValid.class) && field.get(object)!=null){ + if (field.getType().isArray() ){ + for (Object o : (Object[])field.get(object)) + context.addErrors(validateObject(o, object)); + + }else if ( field.get(object) instanceof Iterable){ + for (Object o: (Iterable)field.get(object)){ + context.addErrors(validateObject(o, object)); + } + } else if (field.get(object) instanceof Map){ + for (Entry entry: ((Map)field.get(object)).entrySet()) + context.addErrors(validateObject(entry.getValue(), object)); + } else if (!field.getType().isPrimitive()) + context.addErrors(validateObject(field.get(object), object)); + + } + + } + +} diff --git a/src/main/java/org/gcube/common/validator/Util.java b/src/main/java/org/gcube/common/validator/Util.java new file mode 100644 index 0000000..37532a6 --- /dev/null +++ b/src/main/java/org/gcube/common/validator/Util.java @@ -0,0 +1,17 @@ +package org.gcube.common.validator; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Util { + + public static List getAllFields(Class type) { + List fields = new ArrayList(); + for (Class c = type; c != null; c = c.getSuperclass()) + fields.addAll(Arrays.asList(c.getDeclaredFields())); + return fields; + } + +} diff --git a/src/main/java/org/gcube/common/validator/ValidationError.java b/src/main/java/org/gcube/common/validator/ValidationError.java new file mode 100644 index 0000000..f7bbdda --- /dev/null +++ b/src/main/java/org/gcube/common/validator/ValidationError.java @@ -0,0 +1,27 @@ +package org.gcube.common.validator; + +import java.lang.reflect.Field; + +import org.gcube.common.validator.context.ValidatorContext; + +public class ValidationError { + + + public Field field; + public Object parent; + public Object value; + public String msg; + + public ValidationError(ValidatorContext context, String msg) { + this.field=context.field(); + this.parent=context.parent(); + this.value=context.value(); + this.msg=msg; + } + + + @Override + public String toString() { + return field.getName().toUpperCase()+" in "+value.getClass().getSimpleName()+" "+msg; + } +} diff --git a/src/main/java/org/gcube/common/validator/Validator.java b/src/main/java/org/gcube/common/validator/Validator.java new file mode 100644 index 0000000..82e5908 --- /dev/null +++ b/src/main/java/org/gcube/common/validator/Validator.java @@ -0,0 +1,9 @@ +package org.gcube.common.validator; + +import java.util.List; + +public interface Validator { + + List validate(Object obj); + +} diff --git a/src/main/java/org/gcube/common/validator/ValidatorFactory.java b/src/main/java/org/gcube/common/validator/ValidatorFactory.java new file mode 100644 index 0000000..8da5b5f --- /dev/null +++ b/src/main/java/org/gcube/common/validator/ValidatorFactory.java @@ -0,0 +1,18 @@ +package org.gcube.common.validator; + +public class ValidatorFactory { + + private static Validator validator = new DefaultValidator(); + + + public static Validator validator() { + return validator; + } + + public static void validator(Validator newValidator) { + validator = newValidator; + } + + + +} diff --git a/src/main/java/org/gcube/common/validator/annotations/FieldValidator.java b/src/main/java/org/gcube/common/validator/annotations/FieldValidator.java new file mode 100644 index 0000000..7d606c1 --- /dev/null +++ b/src/main/java/org/gcube/common/validator/annotations/FieldValidator.java @@ -0,0 +1,12 @@ +package org.gcube.common.validator.annotations; + +import java.lang.annotation.Annotation; + +public interface FieldValidator { + + Class annotation(); + + boolean isValid(Object toValidate); + + String getErrorSuffix(); +} diff --git a/src/main/java/org/gcube/common/validator/annotations/IsValid.java b/src/main/java/org/gcube/common/validator/annotations/IsValid.java new file mode 100644 index 0000000..212d19d --- /dev/null +++ b/src/main/java/org/gcube/common/validator/annotations/IsValid.java @@ -0,0 +1,12 @@ +package org.gcube.common.validator.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface IsValid { + +} diff --git a/src/main/java/org/gcube/common/validator/annotations/NotEmpty.java b/src/main/java/org/gcube/common/validator/annotations/NotEmpty.java new file mode 100644 index 0000000..0625022 --- /dev/null +++ b/src/main/java/org/gcube/common/validator/annotations/NotEmpty.java @@ -0,0 +1,15 @@ +package org.gcube.common.validator.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.gcube.common.validator.annotations.validators.NotEmptyValidator; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@ValidityChecker(managed=NotEmptyValidator.class) +public @interface NotEmpty { + +} diff --git a/src/main/java/org/gcube/common/validator/annotations/NotNull.java b/src/main/java/org/gcube/common/validator/annotations/NotNull.java new file mode 100644 index 0000000..310a0dc --- /dev/null +++ b/src/main/java/org/gcube/common/validator/annotations/NotNull.java @@ -0,0 +1,15 @@ +package org.gcube.common.validator.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.gcube.common.validator.annotations.validators.NotNullValidator; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@ValidityChecker(managed=NotNullValidator.class) +public @interface NotNull { + +} diff --git a/src/main/java/org/gcube/common/validator/annotations/ValidityChecker.java b/src/main/java/org/gcube/common/validator/annotations/ValidityChecker.java new file mode 100644 index 0000000..011b963 --- /dev/null +++ b/src/main/java/org/gcube/common/validator/annotations/ValidityChecker.java @@ -0,0 +1,15 @@ +package org.gcube.common.validator.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.ANNOTATION_TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface ValidityChecker { + + Class> managed(); +} diff --git a/src/main/java/org/gcube/common/validator/annotations/validators/NotEmptyValidator.java b/src/main/java/org/gcube/common/validator/annotations/validators/NotEmptyValidator.java new file mode 100644 index 0000000..1d12117 --- /dev/null +++ b/src/main/java/org/gcube/common/validator/annotations/validators/NotEmptyValidator.java @@ -0,0 +1,30 @@ +package org.gcube.common.validator.annotations.validators; + +import java.util.Map; +import org.gcube.common.validator.annotations.FieldValidator; +import org.gcube.common.validator.annotations.NotEmpty; + +public class NotEmptyValidator implements FieldValidator{ + + public Class annotation() { + return NotEmpty.class; + } + + public boolean isValid(Object toValidate) { + if (toValidate == null) return false; + if (toValidate.getClass().isArray() ){ + return ((Object[])toValidate).length>0; + }else if ( toValidate instanceof Iterable){ + return ((Iterable) toValidate).iterator().hasNext(); + } else if (toValidate instanceof Map){ + return ((Map) toValidate).size()>0; + } else if (toValidate instanceof String ){ + return !((String)toValidate).isEmpty(); + } else return true; + } + + public String getErrorSuffix() { + return "is empty"; + } + +} diff --git a/src/main/java/org/gcube/common/validator/annotations/validators/NotNullValidator.java b/src/main/java/org/gcube/common/validator/annotations/validators/NotNullValidator.java new file mode 100644 index 0000000..45e8f2c --- /dev/null +++ b/src/main/java/org/gcube/common/validator/annotations/validators/NotNullValidator.java @@ -0,0 +1,20 @@ +package org.gcube.common.validator.annotations.validators; + +import org.gcube.common.validator.annotations.FieldValidator; +import org.gcube.common.validator.annotations.NotNull; + +public class NotNullValidator implements FieldValidator{ + + public String getErrorSuffix() { + return "is null"; + } + + public Class annotation() { + return NotNull.class; + } + + public boolean isValid(Object toValidate) { + return toValidate!=null; + } + +} diff --git a/src/main/java/org/gcube/common/validator/context/ValidatorContext.java b/src/main/java/org/gcube/common/validator/context/ValidatorContext.java new file mode 100644 index 0000000..fb3fa77 --- /dev/null +++ b/src/main/java/org/gcube/common/validator/context/ValidatorContext.java @@ -0,0 +1,52 @@ +package org.gcube.common.validator.context; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +import org.gcube.common.validator.ValidationError; + +public class ValidatorContext { + + private List errors = new ArrayList(); + + private Object parent; + private Field field; + private Object value; + + public ValidatorContext(Object parent, Field field, Object value) { + super(); + this.parent = parent; + this.field = field; + this.value = value; + } + + public void addError(String msg) { + errors.add(new ValidationError(this,msg)); + } + + public void addErrors(List errorsToAdd) { + errors.addAll(errorsToAdd); + } + + public List errors() { + return errors; + } + + public Object parent() { + return parent; + } + + public Field field() { + return field; + } + + public Object value() { + return value; + } + + + +} + + diff --git a/src/test/java/org/gcube/commons/common/validator/beans/AnnotationTest.java b/src/test/java/org/gcube/commons/common/validator/beans/AnnotationTest.java new file mode 100644 index 0000000..23c4f2d --- /dev/null +++ b/src/test/java/org/gcube/commons/common/validator/beans/AnnotationTest.java @@ -0,0 +1,39 @@ +package org.gcube.commons.common.validator.beans; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.gcube.common.validator.ValidationError; +import org.gcube.common.validator.ValidatorFactory; +import org.junit.Assert; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AnnotationTest { + + private static Logger logger = LoggerFactory.getLogger(AnnotationTest.class); + + @Test + public void NotNullfail() throws Exception{ + ExampleValidation exampleValidation = new ExampleValidation(); + exampleValidation.setOffice("I43"); + List persons = new ArrayList(); + persons.add(new Person("Lucio", null, new Person[]{new Person(null, "Lelii", null)})); + exampleValidation.setPeople(persons); + Map slavePerPerson = new HashMap(); + //slavePerPerson.put("lucio", new Person("fabio", null, null)); + exampleValidation.setSlavePerPerson(slavePerPerson); + Set bosses= new HashSet(); + bosses.add(new Person("", "pagano", null)); + exampleValidation.setBosses(bosses); + List errors = ValidatorFactory.validator().validate(exampleValidation); + Assert.assertTrue(errors.size()>0); + logger.trace(errors.toString()); + + } +} diff --git a/src/test/java/org/gcube/commons/common/validator/beans/ExampleValidation.java b/src/test/java/org/gcube/commons/common/validator/beans/ExampleValidation.java new file mode 100644 index 0000000..9f4a348 --- /dev/null +++ b/src/test/java/org/gcube/commons/common/validator/beans/ExampleValidation.java @@ -0,0 +1,51 @@ +package org.gcube.commons.common.validator.beans; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.gcube.common.validator.annotations.IsValid; +import org.gcube.common.validator.annotations.NotEmpty; +import org.gcube.common.validator.annotations.NotNull; + +public class ExampleValidation { + + @NotNull + private String office; + + @NotNull @IsValid + private List people; + + @IsValid + private Set bosses; + + @IsValid @NotEmpty + private Map slavePerPerson; + + public void setOffice(String office) { + this.office = office; + } + + public void setPeople(List people) { + this.people = people; + } + + public void setBosses(Set bosses) { + this.bosses = bosses; + } + + public void setSlavePerPerson(Map slavePerPerson) { + this.slavePerPerson = slavePerPerson; + } + + @Override + public String toString() { + return "ExampleValidation [office=" + office + ", people=" + people + + ", bosses=" + bosses + ", slavePerPerson=" + slavePerPerson + + "]"; + } + + +} + + diff --git a/src/test/java/org/gcube/commons/common/validator/beans/Extension.java b/src/test/java/org/gcube/commons/common/validator/beans/Extension.java new file mode 100644 index 0000000..7a866fb --- /dev/null +++ b/src/test/java/org/gcube/commons/common/validator/beans/Extension.java @@ -0,0 +1,11 @@ +package org.gcube.commons.common.validator.beans; + +import org.gcube.common.validator.annotations.IsValid; +import org.gcube.common.validator.annotations.NotEmpty; + +public class Extension { + + @IsValid @NotEmpty + Person[] brothers; + +} diff --git a/src/test/java/org/gcube/commons/common/validator/beans/Person.java b/src/test/java/org/gcube/commons/common/validator/beans/Person.java new file mode 100644 index 0000000..fe2d4df --- /dev/null +++ b/src/test/java/org/gcube/commons/common/validator/beans/Person.java @@ -0,0 +1,34 @@ +package org.gcube.commons.common.validator.beans; + +import java.util.Arrays; + +import org.gcube.common.validator.annotations.NotEmpty; +import org.gcube.common.validator.annotations.NotNull; + +public class Person extends Extension{ + + public Person(String firstName, String lastName, Person[] brothers) { + super(); + this.firstName = firstName; + this.lastName = lastName; + this.brothers = brothers; + } + + @NotNull @NotEmpty + String firstName; + + @NotNull @NotEmpty + String lastName; + + + + @Override + public String toString() { + return "Person [firstName=" + firstName + ", lastName=" + lastName + + ", brothers=" + Arrays.toString(brothers) + "]"; + } + + + + +} diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml new file mode 100644 index 0000000..4f36cc8 --- /dev/null +++ b/src/test/resources/logback-test.xml @@ -0,0 +1,16 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{0}: %msg%n + + + + + + + + + + + \ No newline at end of file