← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 22118: change schema validator/attribute service to use new ErrorReport classes

 

------------------------------------------------------------
revno: 22118
committer: Morten Olav Hansen <morten@xxxxxxxxx>
branch nick: dhis2
timestamp: Thu 2016-03-03 08:20:51 +0700
message:
  change schema validator/attribute service to use new ErrorReport classes
removed:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/schema/validation/ValidationViolation.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/webmessage/responses/ValidationViolationsWebMessageResponse.java
added:
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/webmessage/responses/ErrorReportsWebMessageResponse.java
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/attribute/AttributeService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/feedback/ErrorCode.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/feedback/ErrorReport.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/schema/validation/SchemaValidator.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/attribute/DefaultAttributeService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/validation/DefaultSchemaValidator.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultIdentifiableObjectImporter.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/DefaultObjectBundleService.java
  dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/ObjectBundleValidation.java
  dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/metadata2/objectbundle/ObjectBundleServiceTest.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/MaintenanceController.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/SchemaController.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/utils/WebMessageUtils.java


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/attribute/AttributeService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/attribute/AttributeService.java	2016-02-15 04:57:22 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/attribute/AttributeService.java	2016-03-03 01:20:51 +0000
@@ -30,7 +30,7 @@
 
 import org.hisp.dhis.attribute.exception.NonUniqueAttributeValueException;
 import org.hisp.dhis.common.IdentifiableObject;
-import org.hisp.dhis.schema.validation.ValidationViolation;
+import org.hisp.dhis.feedback.ErrorReport;
 
 import java.util.List;
 import java.util.Set;
@@ -183,7 +183,7 @@
      */
     int getAttributeValueCount();
 
-    <T extends IdentifiableObject> List<ValidationViolation> validateAttributeValues( T object, Set<AttributeValue> attributeValues );
+    <T extends IdentifiableObject> List<ErrorReport> validateAttributeValues( T object, Set<AttributeValue> attributeValues );
 
     <T extends IdentifiableObject> void updateAttributeValues( T object, List<String> jsonAttributeValues ) throws Exception;
 

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/feedback/ErrorCode.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/feedback/ErrorCode.java	2016-03-01 07:51:42 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/feedback/ErrorCode.java	2016-03-03 01:20:51 +0000
@@ -29,13 +29,29 @@
  */
 
 /**
+ * E4000 - E4999: Metadata Validation Errors
  * E5000 - E5999: Preheat Errors
- * E6000 - E6999: DXF2 Import Errors
+ * E6000 - E6999: Metadata Import Errors
  *
  * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
  */
 public enum ErrorCode
 {
+    /* Metadata Validation Errors */
+    E4000( "Missing required property \"{0}\"." ),
+    E4001( "Maximum length of property \"{0}\"is {1}, but given length was {2}." ),
+    E4002( "Allowed length range for property \"{0}\" is [{1},{2}], but given length was {3}." ),
+    E4003( "Property \"{0}\" requires a valid email address, was given \"{1}\"." ),
+    E4004( "Property \"{0}\" requires a valid URL, was given \"{1}\"." ),
+    E4005( "Property \"{0}\" requires a valid password, was given \"{1}\"." ),
+    E4006( "Property \"{0}\" requires a valid HEX color, was given \"{1}\"." ),
+    E4007( "Allowed size range for collection property \"{0}\" is [{1},{2}], but size given was {3}." ),
+    E4008( "Allowed range for numeric property \"{0}\" is [{1},{2}], but number given was {3}." ),
+    E4009( "Attribute \"{0}\" is unique, and value \"{1}\" already exist." ),
+    E4010( "Attribute \"{0}\" is not supported for type \"{1}\"." ),
+    E4011( "Attribute \"{0}\" is required, but not value was found." ),
+
+    /* Preheat Errors */
     E5000( "No matching object for given reference. Identifier was {0}, and object was {1}." ),
     E5001( "Invalid reference {0} on object {1} for association \"{2}\"." );
 

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/feedback/ErrorReport.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/feedback/ErrorReport.java	2016-03-01 07:51:42 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/feedback/ErrorReport.java	2016-03-03 01:20:51 +0000
@@ -28,11 +28,16 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
 import com.google.common.base.MoreObjects;
+import org.hisp.dhis.common.DxfNamespaces;
 
 /**
  * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
  */
+@JacksonXmlRootElement( localName = "errorReport", namespace = DxfNamespaces.DXF_2_0 )
 public class ErrorReport
 {
     protected final ErrorMessage message;
@@ -55,21 +60,29 @@
         this.message = message;
     }
 
+    @JsonProperty
+    @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 )
     public ErrorCode getErrorCode()
     {
         return message.getErrorCode();
     }
 
+    @JsonProperty
+    @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 )
     public String getMessage()
     {
         return message.getMessage();
     }
 
+    @JsonProperty
+    @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 )
     public Class<?> getMainKlass()
     {
         return mainKlass;
     }
 
+    @JsonProperty
+    @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 )
     public Class<?> getErrorKlass()
     {
         return errorKlass;
@@ -81,6 +94,8 @@
         return this;
     }
 
+    @JsonProperty
+    @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 )
     public Object getValue()
     {
         return value;

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/schema/validation/SchemaValidator.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/schema/validation/SchemaValidator.java	2016-02-15 04:57:22 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/schema/validation/SchemaValidator.java	2016-03-03 01:20:51 +0000
@@ -28,6 +28,8 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import org.hisp.dhis.feedback.ErrorReport;
+
 import java.util.List;
 
 /**
@@ -42,7 +44,7 @@
      * @param persisted Only include persisted properties
      * @return WebMessage containing validation response
      */
-    List<ValidationViolation> validate( Object object, boolean persisted );
+    List<ErrorReport> validate( Object object, boolean persisted );
 
     /**
      * Validate object against its schema, the object is required to be non-null and have a schema associated with it.
@@ -52,5 +54,5 @@
      * @param object Object to validate
      * @return WebMessage containing validation response
      */
-    List<ValidationViolation> validate( Object object );
+    List<ErrorReport> validate( Object object );
 }

=== removed file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/schema/validation/ValidationViolation.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/schema/validation/ValidationViolation.java	2016-02-15 04:57:22 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/schema/validation/ValidationViolation.java	1970-01-01 00:00:00 +0000
@@ -1,111 +0,0 @@
-package org.hisp.dhis.schema.validation;
-
-/*
- * Copyright (c) 2004-2016, University of Oslo
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * Neither the name of the HISP project nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonPropertyOrder;
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
-import com.google.common.base.MoreObjects;
-import org.hisp.dhis.common.DxfNamespaces;
-
-/**
- * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
- */
-@JsonPropertyOrder( {
-    "message"
-} )
-@JacksonXmlRootElement( localName = "validationViolation", namespace = DxfNamespaces.DXF_2_0 )
-public class ValidationViolation
-{
-    private String property;
-
-    private String message;
-
-    private Object value;
-
-    public ValidationViolation( String property, String message )
-    {
-        this.property = property;
-        this.message = message;
-    }
-
-    public ValidationViolation( String property, String message, Object value )
-    {
-        this.property = property;
-        this.message = message;
-        this.value = value;
-    }
-
-    @JsonProperty
-    @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 )
-    public String getProperty()
-    {
-        return property;
-    }
-
-    public void setProperty( String property )
-    {
-        this.property = property;
-    }
-
-    @JsonProperty
-    @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 )
-    public String getMessage()
-    {
-        return message;
-    }
-
-    public void setMessage( String message )
-    {
-        this.message = message;
-    }
-
-    @JsonProperty
-    @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 )
-    public Object getValue()
-    {
-        return value;
-    }
-
-    public void setValue( Object value )
-    {
-        this.value = value;
-    }
-
-    @Override
-    public String toString()
-    {
-        return MoreObjects.toStringHelper( this )
-            .add( "property", property )
-            .add( "message", message )
-            .add( "value", value )
-            .toString();
-    }
-}

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/attribute/DefaultAttributeService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/attribute/DefaultAttributeService.java	2016-02-29 07:35:27 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/attribute/DefaultAttributeService.java	2016-03-03 01:20:51 +0000
@@ -33,8 +33,9 @@
 import org.hisp.dhis.attribute.exception.NonUniqueAttributeValueException;
 import org.hisp.dhis.common.IdentifiableObject;
 import org.hisp.dhis.common.IdentifiableObjectManager;
+import org.hisp.dhis.feedback.ErrorCode;
+import org.hisp.dhis.feedback.ErrorReport;
 import org.hisp.dhis.i18n.I18nService;
-import org.hisp.dhis.schema.validation.ValidationViolation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.StringUtils;
@@ -273,13 +274,13 @@
     }
 
     @Override
-    public <T extends IdentifiableObject> List<ValidationViolation> validateAttributeValues( T object, Set<AttributeValue> attributeValues )
+    public <T extends IdentifiableObject> List<ErrorReport> validateAttributeValues( T object, Set<AttributeValue> attributeValues )
     {
-        List<ValidationViolation> validationViolations = new ArrayList<>();
+        List<ErrorReport> errorReports = new ArrayList<>();
 
         if ( attributeValues.isEmpty() )
         {
-            return validationViolations;
+            return errorReports;
         }
 
         Map<String, AttributeValue> attributeValueMap = attributeValues.stream()
@@ -300,9 +301,7 @@
                 {
                     if ( !manager.isAttributeValueUnique( object.getClass(), object, attributeValue.getAttribute(), av.getValue() ) )
                     {
-                        validationViolations.add( new ValidationViolation( attributeValue.getAttribute().getUid(),
-                            "Value '" + av.getValue() + "' already exists for attribute '"
-                                + attributeValue.getAttribute().getDisplayName() + "' (" + attributeValue.getAttribute().getUid() + ")" ) );
+                        errorReports.add( new ErrorReport( Attribute.class, ErrorCode.E4009, attributeValue.getAttribute().getUid(), av.getValue() ) );
                     }
                 }
 
@@ -317,9 +316,7 @@
 
             if ( !attributeValue.getAttribute().getSupportedClasses().contains( object.getClass() ) )
             {
-                validationViolations.add( new ValidationViolation( attributeValue.getAttribute().getUid(),
-                    "Attribute '" + attributeValue.getAttribute().getDisplayName() + "' (" + attributeValue.getAttribute().getUid() + ") is not supported for type "
-                        + object.getClass().getSimpleName() ) );
+                errorReports.add( new ErrorReport( Attribute.class, ErrorCode.E4010, attributeValue.getAttribute().getUid(), object.getClass().getSimpleName() ) );
             }
             else
             {
@@ -327,11 +324,9 @@
             }
         }
 
-        mandatoryAttributes.stream()
-            .forEach( att -> validationViolations.add(
-                new ValidationViolation( att.getUid(), "Missing mandatory attribute '" + att.getDisplayName() + "' (" + att.getUid() + ")" ) ) );
+        mandatoryAttributes.stream().forEach( att -> errorReports.add( new ErrorReport( Attribute.class, ErrorCode.E4011, att.getUid() ) ) );
 
-        return validationViolations;
+        return errorReports;
     }
 
     @Override

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/validation/DefaultSchemaValidator.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/validation/DefaultSchemaValidator.java	2016-02-15 04:57:22 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/validation/DefaultSchemaValidator.java	2016-03-03 01:20:51 +0000
@@ -29,6 +29,8 @@
  */
 
 import org.apache.commons.validator.GenericValidator;
+import org.hisp.dhis.feedback.ErrorCode;
+import org.hisp.dhis.feedback.ErrorReport;
 import org.hisp.dhis.schema.Property;
 import org.hisp.dhis.schema.PropertyType;
 import org.hisp.dhis.schema.Schema;
@@ -51,13 +53,13 @@
     private SchemaService schemaService;
 
     @Override
-    public List<ValidationViolation> validate( Object object )
+    public List<ErrorReport> validate( Object object )
     {
         return validate( object, true );
     }
 
     @Override
-    public List<ValidationViolation> validate( Object object, boolean persisted )
+    public List<ErrorReport> validate( Object object, boolean persisted )
     {
         if ( object == null || schemaService.getSchema( object.getClass() ) == null )
         {
@@ -66,7 +68,7 @@
 
         Schema schema = schemaService.getSchema( object.getClass() );
 
-        List<ValidationViolation> validationViolations = new ArrayList<>();
+        List<ErrorReport> errorReports = new ArrayList<>();
 
         for ( Property property : schema.getProperties() )
         {
@@ -81,30 +83,30 @@
             {
                 if ( property.isRequired() )
                 {
-                    validationViolations.add( new ValidationViolation( property.getName(), "Required property missing." ) );
+                    errorReports.add( new ErrorReport( object.getClass(), ErrorCode.E4000, property.getName() ).setErrorKlass( property.getKlass() ) );
                 }
 
                 continue;
             }
 
-            validationViolations.addAll( validateString( value, property ) );
-            validationViolations.addAll( validateCollection( value, property ) );
-            validationViolations.addAll( validateInteger( value, property ) );
-            validationViolations.addAll( validateFloat( value, property ) );
-            validationViolations.addAll( validateDouble( value, property ) );
+            errorReports.addAll( validateString( value, property ) );
+            errorReports.addAll( validateCollection( value, property ) );
+            errorReports.addAll( validateInteger( value, property ) );
+            errorReports.addAll( validateFloat( value, property ) );
+            errorReports.addAll( validateDouble( value, property ) );
         }
 
-        return validationViolations;
+        return errorReports;
     }
 
-    private Collection<? extends ValidationViolation> validateString( Object object, Property property )
+    private List<? extends ErrorReport> validateString( Object object, Property property )
     {
-        List<ValidationViolation> validationViolations = new ArrayList<>();
+        List<ErrorReport> errorReports = new ArrayList<>();
 
         // TODO How should empty strings be handled? they are not valid color, password, url, etc of course.
         if ( !String.class.isInstance( object ) || StringUtils.isEmpty( object ) )
         {
-            return validationViolations;
+            return errorReports;
         }
 
         String value = (String) object;
@@ -112,33 +114,36 @@
         // check column max length
         if ( value.length() > property.getLength() )
         {
-            validationViolations.add( new ValidationViolation( property.getName(), "Maximum length for property is "
-                + property.getLength() + ", length is " + value.length(), value ) );
-
-            return validationViolations;
+            errorReports.add( new ErrorReport( object.getClass(), ErrorCode.E4001, property.getName(), property.getLength(), value.length() )
+                .setErrorKlass( property.getKlass() ) );
+            return errorReports;
         }
 
         if ( value.length() < property.getMin() || value.length() > property.getMax() )
         {
-            validationViolations.add( new ValidationViolation( property.getName(), "Allowed range for length ["
-                + property.getMin() + ", " + property.getMax() + "], length is " + value.length(), value ) );
+            errorReports.add( new ErrorReport( object.getClass(), ErrorCode.E4002, property.getName(), property.getMin(), property.getMax(), value.length() )
+                .setErrorKlass( property.getKlass() ) );
         }
 
         if ( PropertyType.EMAIL == property.getPropertyType() && !GenericValidator.isEmail( value ) )
         {
-            validationViolations.add( new ValidationViolation( property.getName(), "Not a valid email.", value ) );
+            errorReports.add( new ErrorReport( object.getClass(), ErrorCode.E4003, property.getName(), value )
+                .setErrorKlass( property.getKlass() ) );
         }
         else if ( PropertyType.URL == property.getPropertyType() && !isUrl( value ) )
         {
-            validationViolations.add( new ValidationViolation( property.getName(), "Not a valid URL.", value ) );
+            errorReports.add( new ErrorReport( object.getClass(), ErrorCode.E4004, property.getName(), value )
+                .setErrorKlass( property.getKlass() ) );
         }
         else if ( PropertyType.PASSWORD == property.getPropertyType() && !ValidationUtils.passwordIsValid( value ) )
         {
-            validationViolations.add( new ValidationViolation( property.getName(), "Not a valid password.", value ) );
+            errorReports.add( new ErrorReport( object.getClass(), ErrorCode.E4005, property.getName(), value )
+                .setErrorKlass( property.getKlass() ) );
         }
         else if ( PropertyType.COLOR == property.getPropertyType() && !ValidationUtils.isValidHexColor( value ) )
         {
-            validationViolations.add( new ValidationViolation( property.getName(), "Not a valid hex color.", value ) );
+            errorReports.add( new ErrorReport( object.getClass(), ErrorCode.E4006, property.getName(), value )
+                .setErrorKlass( property.getKlass() ) );
         }
 
         /* TODO add proper validation for both Points and Polygons, ValidationUtils only supports points at this time
@@ -148,7 +153,7 @@
         }
         */
 
-        return validationViolations;
+        return errorReports;
     }
 
     // Commons validator have some issues in latest version, replacing with a very simple test for now
@@ -157,83 +162,83 @@
         return !StringUtils.isEmpty( url ) && (url.startsWith( "http://"; ) || url.startsWith( "https://"; ));
     }
 
-    private Collection<? extends ValidationViolation> validateCollection( Object object, Property property )
+    private List<? extends ErrorReport> validateCollection( Object object, Property property )
     {
-        List<ValidationViolation> validationViolations = new ArrayList<>();
+        List<ErrorReport> errorReports = new ArrayList<>();
 
         if ( !Collection.class.isInstance( object ) )
         {
-            return validationViolations;
+            return errorReports;
         }
 
         Collection<?> value = (Collection<?>) object;
 
         if ( value.size() < property.getMin() || value.size() > property.getMax() )
         {
-            validationViolations.add( new ValidationViolation( property.getName(), "Invalid range for size ["
-                + property.getMin() + ", " + property.getMax() + "], size is " + value.size(), value ) );
+            errorReports.add( new ErrorReport( object.getClass(), ErrorCode.E4007, property.getName(), property.getMin(), property.getMax(), value.size() )
+                .setErrorKlass( property.getKlass() ) );
         }
 
-        return validationViolations;
+        return errorReports;
     }
 
-    private Collection<? extends ValidationViolation> validateInteger( Object object, Property property )
+    private List<? extends ErrorReport> validateInteger( Object object, Property property )
     {
-        List<ValidationViolation> validationViolations = new ArrayList<>();
+        List<ErrorReport> errorReports = new ArrayList<>();
 
         if ( !Integer.class.isInstance( object ) )
         {
-            return validationViolations;
+            return errorReports;
         }
 
         Integer value = (Integer) object;
 
         if ( !GenericValidator.isInRange( value, property.getMin(), property.getMax() ) )
         {
-            validationViolations.add( new ValidationViolation( property.getName(), "Invalid range for value ["
-                + property.getMin() + ", " + property.getMax() + "], value is " + value, value ) );
+            errorReports.add( new ErrorReport( object.getClass(), ErrorCode.E4008, property.getName(), property.getMin(), property.getMax(), value )
+                .setErrorKlass( property.getKlass() ) );
         }
 
-        return validationViolations;
+        return errorReports;
     }
 
-    private Collection<? extends ValidationViolation> validateFloat( Object object, Property property )
+    private List<? extends ErrorReport> validateFloat( Object object, Property property )
     {
-        List<ValidationViolation> validationViolations = new ArrayList<>();
+        List<ErrorReport> errorReports = new ArrayList<>();
 
         if ( !Float.class.isInstance( object ) )
         {
-            return validationViolations;
+            return errorReports;
         }
 
         Float value = (Float) object;
 
         if ( !GenericValidator.isInRange( value, property.getMin(), property.getMax() ) )
         {
-            validationViolations.add( new ValidationViolation( property.getName(), "Invalid range for value ["
-                + property.getMin() + ", " + property.getMax() + "], value is " + value, value ) );
+            errorReports.add( new ErrorReport( object.getClass(), ErrorCode.E4008, property.getName(), property.getMin(), property.getMax(), value )
+                .setErrorKlass( property.getKlass() ) );
         }
 
-        return validationViolations;
+        return errorReports;
     }
 
-    private Collection<? extends ValidationViolation> validateDouble( Object object, Property property )
+    private List<? extends ErrorReport> validateDouble( Object object, Property property )
     {
-        List<ValidationViolation> validationViolations = new ArrayList<>();
+        List<ErrorReport> errorReports = new ArrayList<>();
 
         if ( !Double.class.isInstance( object ) )
         {
-            return validationViolations;
+            return errorReports;
         }
 
         Double value = (Double) object;
 
         if ( !GenericValidator.isInRange( value, property.getMin(), property.getMax() ) )
         {
-            validationViolations.add( new ValidationViolation( property.getName(), "Invalid range for value ["
-                + property.getMin() + ", " + property.getMax() + "], value is " + value, value ) );
+            errorReports.add( new ErrorReport( object.getClass(), ErrorCode.E4008, property.getName(), property.getMin(), property.getMax(), value )
+                .setErrorKlass( property.getKlass() ) );
         }
 
-        return validationViolations;
+        return errorReports;
     }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultIdentifiableObjectImporter.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultIdentifiableObjectImporter.java	2016-03-01 10:39:19 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata/importers/DefaultIdentifiableObjectImporter.java	2016-03-03 01:20:51 +0000
@@ -61,6 +61,8 @@
 import org.hisp.dhis.eventreport.EventReport;
 import org.hisp.dhis.expression.Expression;
 import org.hisp.dhis.expression.ExpressionService;
+import org.hisp.dhis.feedback.ErrorCode;
+import org.hisp.dhis.feedback.ErrorReport;
 import org.hisp.dhis.period.Period;
 import org.hisp.dhis.period.PeriodService;
 import org.hisp.dhis.period.PeriodType;
@@ -70,7 +72,6 @@
 import org.hisp.dhis.schema.Schema;
 import org.hisp.dhis.schema.SchemaService;
 import org.hisp.dhis.schema.validation.SchemaValidator;
-import org.hisp.dhis.schema.validation.ValidationViolation;
 import org.hisp.dhis.security.acl.AclService;
 import org.hisp.dhis.system.util.ReflectionUtils;
 import org.hisp.dhis.trackedentity.TrackedEntity;
@@ -283,12 +284,12 @@
             return false;
         }
 
-        List<ValidationViolation> validationViolations = schemaValidator.validate( object );
+        List<ErrorReport> errorReports = schemaValidator.validate( object );
 
-        if ( !validationViolations.isEmpty() )
+        if ( !errorReports.isEmpty() )
         {
             summaryType.getImportConflicts().add(
-                new ImportConflict( IdentifiableObjectUtils.getDisplayName( object ), "Validation Violations: " + validationViolations ) );
+                new ImportConflict( IdentifiableObjectUtils.getDisplayName( object ), "Validation Violations: " + errorReports ) );
 
             return false;
         }
@@ -302,12 +303,12 @@
         }
 
         NonIdentifiableObjects nonIdentifiableObjects = new NonIdentifiableObjects( user );
-        validationViolations = nonIdentifiableObjects.validate( object, object );
+        errorReports = nonIdentifiableObjects.validate( object, object );
 
-        if ( !validationViolations.isEmpty() )
+        if ( !errorReports.isEmpty() )
         {
             summaryType.getImportConflicts().add(
-                new ImportConflict( IdentifiableObjectUtils.getDisplayName( object ), "Validation Violations: " + validationViolations ) );
+                new ImportConflict( IdentifiableObjectUtils.getDisplayName( object ), "Validation Violations: " + errorReports ) );
 
             return false;
         }
@@ -408,23 +409,23 @@
             return true;
         }
 
-        List<ValidationViolation> validationViolations = schemaValidator.validate( object );
+        List<ErrorReport> errorReports = schemaValidator.validate( object );
 
-        if ( !validationViolations.isEmpty() )
+        if ( !errorReports.isEmpty() )
         {
             summaryType.getImportConflicts().add(
-                new ImportConflict( IdentifiableObjectUtils.getDisplayName( object ), "Validation Violations: " + validationViolations ) );
+                new ImportConflict( IdentifiableObjectUtils.getDisplayName( object ), "Validation Violations: " + errorReports ) );
 
             return false;
         }
 
         NonIdentifiableObjects nonIdentifiableObjects = new NonIdentifiableObjects( user );
-        validationViolations = nonIdentifiableObjects.validate( persistedObject, object );
+        errorReports = nonIdentifiableObjects.validate( persistedObject, object );
 
-        if ( !validationViolations.isEmpty() )
+        if ( !errorReports.isEmpty() )
         {
             summaryType.getImportConflicts().add(
-                new ImportConflict( IdentifiableObjectUtils.getDisplayName( object ), "Validation Violations: " + validationViolations ) );
+                new ImportConflict( IdentifiableObjectUtils.getDisplayName( object ), "Validation Violations: " + errorReports ) );
 
             return false;
         }
@@ -966,10 +967,10 @@
             this.user = user;
         }
 
-        public List<ValidationViolation> validate( T persistedObject, T object )
+        public List<ErrorReport> validate( T persistedObject, T object )
         {
             schema = schemaService.getDynamicSchema( object.getClass() );
-            List<ValidationViolation> validationViolations = new ArrayList<>();
+            List<ErrorReport> errorReports = new ArrayList<>();
 
             if ( schema.havePersistedProperty( "attributeValues" ) )
             {
@@ -979,17 +980,17 @@
 
                     if ( attribute == null )
                     {
-                        validationViolations.add( new ValidationViolation( attributeValue.getAttribute().getUid(),
-                            "Unknown reference to " + attributeValue.getAttribute() + " on object " + attributeValue ) );
+                        errorReports.add( new ErrorReport( Attribute.class, ErrorCode.E5001, attributeValue.getAttribute().getUid(),
+                            object.getUid(), "attributeValues" ) );
                     }
 
                     attributeValue.setAttribute( attribute );
                 }
 
-                validationViolations.addAll( attributeService.validateAttributeValues( persistedObject, object.getAttributeValues() ) );
+                errorReports.addAll( attributeService.validateAttributeValues( persistedObject, object.getAttributeValues() ) );
             }
 
-            return validationViolations;
+            return errorReports;
         }
 
         public void extract( T object )

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/DefaultObjectBundleService.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/DefaultObjectBundleService.java	2016-03-02 07:56:41 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/DefaultObjectBundleService.java	2016-03-03 01:20:51 +0000
@@ -38,6 +38,7 @@
 import org.hisp.dhis.common.IdentifiableObjectUtils;
 import org.hisp.dhis.dxf2.metadata2.objectbundle.hooks.ObjectBundleHook;
 import org.hisp.dhis.feedback.ErrorCode;
+import org.hisp.dhis.feedback.ErrorReport;
 import org.hisp.dhis.preheat.Preheat;
 import org.hisp.dhis.preheat.PreheatErrorReport;
 import org.hisp.dhis.preheat.PreheatIdentifier;
@@ -46,7 +47,6 @@
 import org.hisp.dhis.preheat.PreheatService;
 import org.hisp.dhis.schema.SchemaService;
 import org.hisp.dhis.schema.validation.SchemaValidator;
-import org.hisp.dhis.schema.validation.ValidationViolation;
 import org.hisp.dhis.user.CurrentUserService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
@@ -193,19 +193,19 @@
             List<List<PreheatErrorReport>> referenceErrors = preheatService.checkReferences( bundle.getObjects().get( klass ), bundle.getPreheat(), bundle.getPreheatIdentifier() );
             referenceErrors.forEach( objectBundleValidation::addErrorReports ); // collapsing for now, we might want to give pr object ref list
 
-            List<List<ValidationViolation>> validationViolations = new ArrayList<>();
+            List<List<ErrorReport>> validationErrorReports = new ArrayList<>();
 
             for ( IdentifiableObject object : bundle.getObjects().get( klass ) )
             {
-                List<ValidationViolation> validate = schemaValidator.validate( object );
+                List<ErrorReport> validate = schemaValidator.validate( object );
 
                 if ( !validate.isEmpty() )
                 {
-                    validationViolations.add( validate );
+                    validationErrorReports.add( validate );
                 }
             }
 
-            objectBundleValidation.addValidationViolation( klass, validationViolations );
+            validationErrorReports.forEach( objectBundleValidation::addErrorReports );
         }
 
         bundle.setObjectBundleStatus( ObjectBundleStatus.VALIDATED );

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/ObjectBundleValidation.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/ObjectBundleValidation.java	2016-03-02 07:56:41 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/ObjectBundleValidation.java	2016-03-03 01:20:51 +0000
@@ -28,10 +28,8 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-import org.hisp.dhis.common.IdentifiableObject;
 import org.hisp.dhis.feedback.ErrorCode;
 import org.hisp.dhis.feedback.ErrorReport;
-import org.hisp.dhis.schema.validation.ValidationViolation;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -45,8 +43,6 @@
 {
     private Map<Class<?>, Map<ErrorCode, List<ErrorReport>>> errorReports = new HashMap<>();
 
-    private Map<Class<? extends IdentifiableObject>, List<List<ValidationViolation>>> validationViolations = new HashMap<>();
-
     public ObjectBundleValidation()
     {
     }
@@ -105,14 +101,4 @@
 
         return map.get( errorCode );
     }
-
-    public void addValidationViolation( Class<? extends IdentifiableObject> klass, List<List<ValidationViolation>> validationViolations )
-    {
-        this.validationViolations.put( klass, validationViolations );
-    }
-
-    public Map<Class<? extends IdentifiableObject>, List<List<ValidationViolation>>> getValidationViolations()
-    {
-        return validationViolations;
-    }
 }

=== added file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/webmessage/responses/ErrorReportsWebMessageResponse.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/webmessage/responses/ErrorReportsWebMessageResponse.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/webmessage/responses/ErrorReportsWebMessageResponse.java	2016-03-03 01:20:51 +0000
@@ -0,0 +1,66 @@
+package org.hisp.dhis.dxf2.webmessage.responses;
+
+/*
+ * Copyright (c) 2004-2016, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import org.hisp.dhis.common.DxfNamespaces;
+import org.hisp.dhis.dxf2.webmessage.AbstractWebMessageResponse;
+import org.hisp.dhis.feedback.ErrorReport;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
+ */
+public class ErrorReportsWebMessageResponse
+    extends AbstractWebMessageResponse
+{
+    private List<ErrorReport> errorReports = new ArrayList<>();
+
+    public ErrorReportsWebMessageResponse( List<ErrorReport> errorReports )
+    {
+        this.errorReports = errorReports;
+    }
+
+    @JsonProperty
+    @JacksonXmlElementWrapper( localName = "errorReports", namespace = DxfNamespaces.DXF_2_0, useWrapping = false )
+    @JacksonXmlProperty( localName = "errorReport", namespace = DxfNamespaces.DXF_2_0 )
+    public List<ErrorReport> getErrorReports()
+    {
+        return errorReports;
+    }
+
+    public void setErrorReports( List<ErrorReport> errorReports )
+    {
+        this.errorReports = errorReports;
+    }
+}

=== removed file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/webmessage/responses/ValidationViolationsWebMessageResponse.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/webmessage/responses/ValidationViolationsWebMessageResponse.java	2016-02-15 04:57:22 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/webmessage/responses/ValidationViolationsWebMessageResponse.java	1970-01-01 00:00:00 +0000
@@ -1,66 +0,0 @@
-package org.hisp.dhis.dxf2.webmessage.responses;
-
-/*
- * Copyright (c) 2004-2016, University of Oslo
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * Neither the name of the HISP project nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
-import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
-import org.hisp.dhis.common.DxfNamespaces;
-import org.hisp.dhis.schema.validation.ValidationViolation;
-import org.hisp.dhis.dxf2.webmessage.AbstractWebMessageResponse;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author Morten Olav Hansen <mortenoh@xxxxxxxxx>
- */
-public class ValidationViolationsWebMessageResponse
-    extends AbstractWebMessageResponse
-{
-    private List<ValidationViolation> validationViolations = new ArrayList<>();
-
-    public ValidationViolationsWebMessageResponse( List<ValidationViolation> validationViolations )
-    {
-        this.validationViolations = validationViolations;
-    }
-
-    @JsonProperty
-    @JacksonXmlElementWrapper( localName = "validationViolations", namespace = DxfNamespaces.DXF_2_0, useWrapping = false )
-    @JacksonXmlProperty( localName = "validationViolation", namespace = DxfNamespaces.DXF_2_0 )
-    public List<ValidationViolation> getValidationViolations()
-    {
-        return validationViolations;
-    }
-
-    public void setValidationViolations( List<ValidationViolation> validationViolations )
-    {
-        this.validationViolations = validationViolations;
-    }
-}

=== modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/metadata2/objectbundle/ObjectBundleServiceTest.java'
--- dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/metadata2/objectbundle/ObjectBundleServiceTest.java	2016-03-01 07:51:42 +0000
+++ dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/metadata2/objectbundle/ObjectBundleServiceTest.java	2016-03-03 01:20:51 +0000
@@ -238,8 +238,8 @@
         ObjectBundle bundle = objectBundleService.create( params );
         ObjectBundleValidation validate = objectBundleService.validate( bundle );
 
-        assertFalse( validate.getValidationViolations().isEmpty() );
-        assertEquals( 2, validate.getValidationViolations().get( DataElement.class ).size() );
+        assertFalse( validate.getErrorReports().isEmpty() );
+        assertEquals( 2, validate.getErrorReports().get( DataElement.class ).size() );
     }
 
     @Test

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/MaintenanceController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/MaintenanceController.java	2016-03-02 06:42:30 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/MaintenanceController.java	2016-03-03 01:20:51 +0000
@@ -1,35 +1,6 @@
 package org.hisp.dhis.webapi.controller;
 
 import org.hisp.dhis.analytics.AnalyticsTableService;
-
-/*
- * Copyright (c) 2004-2016, University of Oslo
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * Neither the name of the HISP project nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
 import org.hisp.dhis.analytics.partition.PartitionManager;
 import org.hisp.dhis.cache.HibernateCacheManager;
 import org.hisp.dhis.common.IdentifiableObject;
@@ -37,19 +8,19 @@
 import org.hisp.dhis.dxf2.common.Options;
 import org.hisp.dhis.dxf2.metadata.ExportService;
 import org.hisp.dhis.dxf2.metadata.Metadata;
-import org.hisp.dhis.render.RenderService;
-import org.hisp.dhis.schema.validation.SchemaValidator;
 import org.hisp.dhis.dxf2.webmessage.WebMessage;
-import org.hisp.dhis.schema.validation.ValidationViolation;
-import org.hisp.dhis.webapi.service.WebMessageService;
-import org.hisp.dhis.webapi.utils.WebMessageUtils;
+import org.hisp.dhis.feedback.ErrorReport;
 import org.hisp.dhis.maintenance.MaintenanceService;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
+import org.hisp.dhis.render.RenderService;
 import org.hisp.dhis.resourcetable.ResourceTableService;
 import org.hisp.dhis.schema.Property;
 import org.hisp.dhis.schema.Schema;
 import org.hisp.dhis.schema.SchemaService;
+import org.hisp.dhis.schema.validation.SchemaValidator;
+import org.hisp.dhis.webapi.service.WebMessageService;
+import org.hisp.dhis.webapi.utils.WebMessageUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.MediaType;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -66,6 +37,34 @@
 import java.util.List;
 import java.util.Map;
 
+/*
+ * Copyright (c) 2004-2016, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
 /**
  * @author Lars Helge Overland
  */
@@ -77,7 +76,7 @@
 
     @Autowired
     private WebMessageService webMessageService;
-    
+
     @Autowired
     private MaintenanceService maintenanceService;
 
@@ -127,7 +126,7 @@
     {
         maintenanceService.removeExpiredInvitations();
     }
-    
+
     @RequestMapping( value = "/ouPathsUpdate", method = { RequestMethod.PUT, RequestMethod.POST } )
     @PreAuthorize( "hasRole('ALL') or hasRole('F_PERFORM_MAINTENANCE')" )
     public void forceUpdatePaths()
@@ -141,26 +140,26 @@
     {
         maintenanceService.prunePeriods();
     }
-    
+
     @RequestMapping( value = "/dataPruning/organisationUnits/{uid}", method = { RequestMethod.PUT, RequestMethod.POST } )
     @PreAuthorize( "hasRole('ALL')" )
     public void pruneDataByOrganisationUnit( @PathVariable String uid, HttpServletResponse response )
         throws Exception
     {
         OrganisationUnit organisationUnit = organisationUnitService.getOrganisationUnit( uid );
-        
+
         if ( organisationUnit == null )
         {
             webMessageService.sendJson( WebMessageUtils.conflict( "Organisation unit does not exist: " + uid ), response );
             return;
         }
-        
+
         boolean result = maintenanceService.pruneData( organisationUnit );
-        
+
         WebMessage message = result ? WebMessageUtils.ok( "Data was pruned successfully" ) : WebMessageUtils.conflict( "Data could not be pruned" );
-        
+
         webMessageService.sendJson( message, response );
-    }    
+    }
 
     @RequestMapping( value = "/zeroDataValueRemoval", method = { RequestMethod.PUT, RequestMethod.POST } )
     @PreAuthorize( "hasRole('ALL') or hasRole('F_PERFORM_MAINTENANCE')" )
@@ -208,7 +207,7 @@
         Metadata metadata = exportService.getMetaData( options );
         Schema schema = schemaService.getDynamicSchema( Metadata.class );
 
-        Map<String, Map<String, List<ValidationViolation>>> output = new HashMap<>();
+        Map<String, Map<String, List<ErrorReport>>> output = new HashMap<>();
 
         for ( Property property : schema.getProperties() )
         {
@@ -223,7 +222,7 @@
 
             for ( Object object : collection )
             {
-                List<ValidationViolation> validationViolations = schemaValidator.validate( object );
+                List<ErrorReport> validationViolations = schemaValidator.validate( object );
 
                 if ( !validationViolations.isEmpty() )
                 {

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/SchemaController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/SchemaController.java	2016-02-27 11:03:16 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/SchemaController.java	2016-03-03 01:20:51 +0000
@@ -30,6 +30,7 @@
 
 import com.google.common.collect.Lists;
 import org.hisp.dhis.dxf2.webmessage.WebMessage;
+import org.hisp.dhis.feedback.ErrorReport;
 import org.hisp.dhis.fieldfilter.FieldFilterService;
 import org.hisp.dhis.node.NodeUtils;
 import org.hisp.dhis.node.types.CollectionNode;
@@ -40,7 +41,6 @@
 import org.hisp.dhis.schema.SchemaService;
 import org.hisp.dhis.schema.Schemas;
 import org.hisp.dhis.schema.validation.SchemaValidator;
-import org.hisp.dhis.schema.validation.ValidationViolation;
 import org.hisp.dhis.webapi.service.ContextService;
 import org.hisp.dhis.webapi.service.LinkService;
 import org.hisp.dhis.webapi.service.WebMessageService;
@@ -144,9 +144,9 @@
         }
 
         Object object = renderService.fromJson( request.getInputStream(), schema.getKlass() );
-        List<ValidationViolation> validationViolations = schemaValidator.validate( object );
+        List<ErrorReport> validationViolations = schemaValidator.validate( object );
 
-        WebMessage webMessage = WebMessageUtils.validationViolations( validationViolations );
+        WebMessage webMessage = WebMessageUtils.errorReports( validationViolations );
         webMessageService.send( webMessage, response, request );
     }
 

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/utils/WebMessageUtils.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/utils/WebMessageUtils.java	2016-02-15 04:57:22 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/utils/WebMessageUtils.java	2016-03-03 01:20:51 +0000
@@ -28,14 +28,14 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import org.hisp.dhis.dxf2.common.Status;
 import org.hisp.dhis.dxf2.importsummary.ImportStatus;
 import org.hisp.dhis.dxf2.importsummary.ImportSummaries;
 import org.hisp.dhis.dxf2.importsummary.ImportSummary;
 import org.hisp.dhis.dxf2.metadata.ImportTypeSummary;
-import org.hisp.dhis.schema.validation.ValidationViolation;
 import org.hisp.dhis.dxf2.webmessage.WebMessage;
-import org.hisp.dhis.dxf2.common.Status;
-import org.hisp.dhis.dxf2.webmessage.responses.ValidationViolationsWebMessageResponse;
+import org.hisp.dhis.dxf2.webmessage.responses.ErrorReportsWebMessageResponse;
+import org.hisp.dhis.feedback.ErrorReport;
 import org.springframework.http.HttpStatus;
 
 import java.util.List;
@@ -246,12 +246,12 @@
         return webMessage;
     }
 
-    public static WebMessage validationViolations( List<ValidationViolation> validationViolations )
+    public static WebMessage errorReports( List<ErrorReport> errorReports )
     {
         WebMessage webMessage = new WebMessage();
-        webMessage.setResponse( new ValidationViolationsWebMessageResponse( validationViolations ) );
+        webMessage.setResponse( new ErrorReportsWebMessageResponse( errorReports ) );
 
-        if ( !validationViolations.isEmpty() )
+        if ( !errorReports.isEmpty() )
         {
             webMessage.setStatus( Status.ERROR );
             webMessage.setHttpStatus( HttpStatus.BAD_REQUEST );