=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/attribute/Attribute.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/attribute/Attribute.java 2015-11-19 04:01:09 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/attribute/Attribute.java 2015-11-23 06:05:02 +0000 @@ -60,6 +60,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** * @author Morten Olav Hansen @@ -121,6 +122,53 @@ this.valueType = valueType; } + @Override + public int hashCode() + { + return 31 * super.hashCode() + Objects.hash( valueType, dataElementAttribute, dataElementGroupAttribute, indicatorAttribute, indicatorGroupAttribute, dataSetAttribute, organisationUnitAttribute, organisationUnitGroupAttribute, + organisationUnitGroupSetAttribute, userAttribute, userGroupAttribute, programAttribute, programStageAttribute, trackedEntityAttribute, trackedEntityAttributeAttribute, categoryOptionAttribute, categoryOptionGroupAttribute, mandatory, unique, + sortOrder, optionSet ); + } + + @Override + public boolean equals( Object obj ) + { + if ( this == obj ) + { + return true; + } + if ( obj == null || getClass() != obj.getClass() ) + { + return false; + } + if ( !super.equals( obj ) ) + { + return false; + } + final Attribute other = (Attribute) obj; + return Objects.equals( this.valueType, other.valueType ) + && Objects.equals( this.dataElementAttribute, other.dataElementAttribute ) + && Objects.equals( this.dataElementGroupAttribute, other.dataElementGroupAttribute ) + && Objects.equals( this.indicatorAttribute, other.indicatorAttribute ) + && Objects.equals( this.indicatorGroupAttribute, other.indicatorGroupAttribute ) + && Objects.equals( this.dataSetAttribute, other.dataSetAttribute ) + && Objects.equals( this.organisationUnitAttribute, other.organisationUnitAttribute ) + && Objects.equals( this.organisationUnitGroupAttribute, other.organisationUnitGroupAttribute ) + && Objects.equals( this.organisationUnitGroupSetAttribute, other.organisationUnitGroupSetAttribute ) + && Objects.equals( this.userAttribute, other.userAttribute ) + && Objects.equals( this.userGroupAttribute, other.userGroupAttribute ) + && Objects.equals( this.programAttribute, other.programAttribute ) + && Objects.equals( this.programStageAttribute, other.programStageAttribute ) + && Objects.equals( this.trackedEntityAttribute, other.trackedEntityAttribute ) + && Objects.equals( this.trackedEntityAttributeAttribute, other.trackedEntityAttributeAttribute ) + && Objects.equals( this.categoryOptionAttribute, other.categoryOptionAttribute ) + && Objects.equals( this.categoryOptionGroupAttribute, other.categoryOptionGroupAttribute ) + && Objects.equals( this.mandatory, other.mandatory ) + && Objects.equals( this.unique, other.unique ) + && Objects.equals( this.sortOrder, other.sortOrder ) + && Objects.equals( this.optionSet, other.optionSet ); + } + @JsonProperty @JsonView( { DetailedView.class, ExportView.class } ) @JacksonXmlProperty( namespace = DxfNamespaces.DXF_2_0 ) === 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 2015-11-20 05:42:56 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/attribute/AttributeService.java 2015-11-23 06:05:02 +0000 @@ -285,4 +285,6 @@ * @return the number of attribute values. */ int getAttributeValueCount(); + + void updateAttributeValues( T object, List jsonAttributeValues ) throws NonUniqueAttributeValueException; } === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/attribute/AttributeValue.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/attribute/AttributeValue.java 2015-11-18 05:35:33 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/attribute/AttributeValue.java 2015-11-23 06:05:02 +0000 @@ -194,4 +194,9 @@ { this.value = value; } + + public boolean isUnique() + { + return attribute != null && attribute.isUnique(); + } } === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/attribute/NonUniqueAttributeValueException.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/attribute/NonUniqueAttributeValueException.java 2015-11-20 05:42:56 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/attribute/NonUniqueAttributeValueException.java 2015-11-23 06:05:02 +0000 @@ -33,8 +33,15 @@ */ public class NonUniqueAttributeValueException extends Exception { - public NonUniqueAttributeValueException( String message ) - { - super( message ); + public NonUniqueAttributeValueException( AttributeValue attributeValue ) + { + super( "Value " + attributeValue.getValue() + " already exists for attribute " + + attributeValue.getAttribute().getName() + "(" + attributeValue.getAttribute().getUid() + ")" ); + } + + public NonUniqueAttributeValueException( AttributeValue attributeValue, String value ) + { + super( "Value " + value + " already exists for attribute " + + attributeValue.getAttribute().getName() + "(" + attributeValue.getAttribute().getUid() + ")" ); } } === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObjectManager.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObjectManager.java 2015-11-20 02:38:53 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObjectManager.java 2015-11-23 06:05:02 +0000 @@ -155,9 +155,9 @@ List getAttributeValueByAttributeAndValue( Class klass, Attribute attribute, String value ); - boolean isAttributeValueUnique( Class klass, T object, AttributeValue attributeValue ); + boolean isAttributeValueUnique( Class klass, T object, AttributeValue attributeValue ); - boolean isAttributeValueUnique( Class klass, T object, Attribute attribute, String value ); + boolean isAttributeValueUnique( Class klass, T object, Attribute attribute, String value ); // ------------------------------------------------------------------------- // NO ACL === 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 2015-11-20 05:42:56 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/attribute/DefaultAttributeService.java 2015-11-23 06:05:02 +0000 @@ -28,14 +28,19 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import net.sf.json.JSONObject; import org.hisp.dhis.common.IdentifiableObject; import org.hisp.dhis.common.IdentifiableObjectManager; import org.hisp.dhis.i18n.I18nService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; import static org.hisp.dhis.i18n.I18nUtils.i18n; @@ -265,7 +270,7 @@ if ( !values.isEmpty() ) { - throw new NonUniqueAttributeValueException( "Value " + attributeValue.getValue() + " already exists for attribute." ); + throw new NonUniqueAttributeValueException( attributeValue ); } } @@ -289,7 +294,7 @@ if ( values.size() > 1 || (values.size() == 1 && !object.getAttributeValues().contains( values.get( 0 ) )) ) { - throw new NonUniqueAttributeValueException( "Value " + attributeValue.getValue() + " already exists for attribute." ); + throw new NonUniqueAttributeValueException( attributeValue ); } } @@ -339,4 +344,76 @@ { return attributeValueStore.getCount(); } + + // TODO remove when actions are no longer in use + @Override + public void updateAttributeValues( T object, List jsonAttributeValues ) throws NonUniqueAttributeValueException + { + Map attributeValueMap = getJsonAttributeValueMap( jsonAttributeValues ); + Iterator iterator = object.getAttributeValues().iterator(); + + while ( iterator.hasNext() ) + { + AttributeValue attributeValue = iterator.next(); + + if ( attributeValueMap.containsKey( attributeValue.getAttribute().getUid() ) ) + { + AttributeValue av = attributeValueMap.get( attributeValue.getAttribute().getUid() ); + + if ( attributeValue.isUnique() ) + { + if ( manager.isAttributeValueUnique( object.getClass(), object, attributeValue.getAttribute(), av.getValue() ) ) + { + attributeValue.setValue( av.getValue() ); + } + else + { + throw new NonUniqueAttributeValueException( attributeValue, av.getValue() ); + } + } + else + { + attributeValue.setValue( av.getValue() ); + } + + attributeValueMap.remove( attributeValue.getAttribute().getUid() ); + } + else + { + iterator.remove(); + } + } + + for ( String uid : attributeValueMap.keySet() ) + { + AttributeValue attributeValue = attributeValueMap.get( uid ); + addAttributeValue( object, attributeValue ); + } + } + + private Map getJsonAttributeValueMap( List jsonAttributeValues ) + { + Map map = new HashMap<>(); + + for ( String jsonValue : jsonAttributeValues ) + { + JSONObject json = JSONObject.fromObject( jsonValue ); + Integer id = json.getInt( "id" ); + String value = json.getString( "value" ); + + Attribute attribute = getAttribute( id ); + + if ( attribute == null || StringUtils.isEmpty( value ) ) + { + continue; + } + + AttributeValue attributeValue = new AttributeValue( value, attribute ); + attributeValue.setId( id ); + + map.put( attribute.getUid(), attributeValue ); + } + + return map; + } } === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultIdentifiableObjectManager.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultIdentifiableObjectManager.java 2015-11-20 02:38:53 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultIdentifiableObjectManager.java 2015-11-23 06:05:02 +0000 @@ -1001,14 +1001,15 @@ @Override @SuppressWarnings( "unchecked" ) - public boolean isAttributeValueUnique( Class klass, T object, AttributeValue attributeValue ) + public boolean isAttributeValueUnique( Class klass, T object, AttributeValue attributeValue ) { GenericIdentifiableObjectStore store = getIdentifiableObjectStore( klass ); return store != null && store.isAttributeValueUnique( object, attributeValue ); } @Override - public boolean isAttributeValueUnique( Class klass, T object, Attribute attribute, String value ) + @SuppressWarnings( "unchecked" ) + public boolean isAttributeValueUnique( Class klass, T object, Attribute attribute, String value ) { GenericIdentifiableObjectStore store = getIdentifiableObjectStore( klass ); return store != null && store.isAttributeValueUnique( object, attribute, value ); === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/DataElement.hbm.xml' --- dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/DataElement.hbm.xml 2015-10-08 08:37:55 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/resources/org/hisp/dhis/dataelement/hibernate/DataElement.hbm.xml 2015-11-23 06:05:02 +0000 @@ -76,7 +76,7 @@ - + === modified file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/AttributeUtils.java' --- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/AttributeUtils.java 2015-11-23 02:31:01 +0000 +++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/AttributeUtils.java 2015-11-23 06:05:02 +0000 @@ -42,7 +42,7 @@ import java.util.Set; /** - * @author mortenoh + * @author Morten Olav Hansen */ public class AttributeUtils { === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/dataelement/AddDataElementAction.java' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/dataelement/AddDataElementAction.java 2015-11-18 06:20:27 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/dataelement/AddDataElementAction.java 2015-11-23 06:05:02 +0000 @@ -32,6 +32,7 @@ import org.apache.commons.lang3.StringUtils; import org.hisp.dhis.analytics.AggregationType; import org.hisp.dhis.attribute.AttributeService; +import org.hisp.dhis.attribute.NonUniqueAttributeValueException; import org.hisp.dhis.common.ValueType; import org.hisp.dhis.commons.collection.ListUtils; import org.hisp.dhis.dataelement.DataElement; @@ -44,7 +45,6 @@ import org.hisp.dhis.legend.LegendSet; import org.hisp.dhis.option.OptionService; import org.hisp.dhis.option.OptionSet; -import org.hisp.dhis.system.util.AttributeUtils; import org.springframework.beans.factory.annotation.Autowired; import java.util.ArrayList; @@ -205,7 +205,7 @@ // ------------------------------------------------------------------------- @Override - public String execute() + public String execute() throws NonUniqueAttributeValueException { DataElement dataElement = new DataElement(); @@ -235,7 +235,7 @@ if ( jsonAttributeValues != null ) { - AttributeUtils.updateAttributeValuesFromJson( dataElement, dataElement.getAttributeValues(), jsonAttributeValues, attributeService ); + attributeService.updateAttributeValues( dataElement, jsonAttributeValues ); } dataElementService.addDataElement( dataElement ); === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/dataelement/UpdateDataElementAction.java' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/dataelement/UpdateDataElementAction.java 2015-11-18 06:20:27 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-datadictionary/src/main/java/org/hisp/dhis/dd/action/dataelement/UpdateDataElementAction.java 2015-11-23 06:05:02 +0000 @@ -32,6 +32,8 @@ import org.apache.commons.lang3.StringUtils; import org.hisp.dhis.analytics.AggregationType; import org.hisp.dhis.attribute.AttributeService; +import org.hisp.dhis.attribute.NonUniqueAttributeValueException; +import org.hisp.dhis.common.IdentifiableObjectManager; import org.hisp.dhis.common.ValueType; import org.hisp.dhis.commons.collection.ListUtils; import org.hisp.dhis.dataelement.DataElement; @@ -47,7 +49,6 @@ import org.hisp.dhis.legend.LegendSet; import org.hisp.dhis.option.OptionService; import org.hisp.dhis.option.OptionSet; -import org.hisp.dhis.system.util.AttributeUtils; import org.springframework.beans.factory.annotation.Autowired; import java.util.ArrayList; @@ -83,6 +84,9 @@ @Autowired private LegendService legendService; + @Autowired + private IdentifiableObjectManager manager; + // ------------------------------------------------------------------------- // Input // ------------------------------------------------------------------------- @@ -225,7 +229,7 @@ // ------------------------------------------------------------------------- @Override - public String execute() + public String execute() throws NonUniqueAttributeValueException { DataElement dataElement = dataElementService.getDataElement( id ); @@ -237,7 +241,7 @@ LegendSet legendSet = legendService.getLegendSet( selectedLegendSetId ); valueType = optionSet != null && optionSet.getValueType() != null ? optionSet.getValueType() : valueType; - + dataElement.setName( StringUtils.trimToNull( name ) ); dataElement.setShortName( StringUtils.trimToNull( shortName ) ); dataElement.setCode( StringUtils.trimToNull( code ) ); @@ -285,7 +289,7 @@ if ( jsonAttributeValues != null ) { - AttributeUtils.updateAttributeValuesFromJson( dataElement, dataElement.getAttributeValues(), jsonAttributeValues, attributeService ); + attributeService.updateAttributeValues( dataElement, jsonAttributeValues ); } dataElementService.updateDataElement( dataElement );