Skip to content

Commit

Permalink
Adds support for converting DHIS2 values to FHIR values and vice versa.
Browse files Browse the repository at this point in the history
  • Loading branch information
volsch committed Aug 4, 2019
1 parent 96a8cde commit 262442e
Show file tree
Hide file tree
Showing 14 changed files with 1,675 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.dhis2.fhir.adapter.dhis.model;

/*
* Copyright (c) 2004-2018, University of Oslo
* Copyright (c) 2004-2019, University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -33,8 +33,10 @@
import com.fasterxml.jackson.annotation.JsonProperty;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.Serializable;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
Expand Down Expand Up @@ -77,4 +79,12 @@ public List<Option> getOptions()
{
return (delegate.getOptions() == null) ? null : delegate.getOptions().stream().map( ImmutableOption::new ).collect( Collectors.toList() );
}

@JsonIgnore
@Nonnull
@Override
public Optional<Option> getOptionalOptionByCode( @Nullable String code )
{
return delegate.getOptionalOptionByCode( code );
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.dhis2.fhir.adapter.dhis.model;

/*
* Copyright (c) 2004-2018, University of Oslo
* Copyright (c) 2004-2019, University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -30,7 +30,10 @@

import org.dhis2.fhir.adapter.scriptable.Scriptable;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Optional;

/**
* Contains read-only access to a DHIS2 Option Set contains DHIS2 Options.
Expand All @@ -47,4 +50,13 @@ public interface OptionSet
String getName();

List<? extends Option> getOptions();

/**
* Returns the option for the specified code.
*
* @param code the code for which the option should be returned.
* @return the optional option.
*/
@Nonnull
Optional<Option> getOptionalOptionByCode( @Nullable String code );
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.dhis2.fhir.adapter.dhis.model;

/*
* Copyright (c) 2004-2018, University of Oslo
* Copyright (c) 2004-2019, University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand All @@ -28,8 +28,15 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import com.fasterxml.jackson.annotation.JsonIgnore;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
* Writable implementation of {@link OptionSet} that can also be used for
Expand All @@ -47,6 +54,9 @@ public class WritableOptionSet implements OptionSet, Serializable

private List<WritableOption> options;

@JsonIgnore
private transient volatile Map<String, WritableOption> optionsByCode;

@Override
public String getId()
{
Expand Down Expand Up @@ -79,4 +89,21 @@ public void setOptions( List<WritableOption> options )
{
this.options = options;
}

@Nonnull
@Override
public Optional<Option> getOptionalOptionByCode( @Nullable String code )
{
if ( code == null )
{
return Optional.empty();
}

if ( optionsByCode == null )
{
optionsByCode = options.stream().collect( Collectors.toMap( WritableOption::getCode, o -> o ) );
}

return Optional.ofNullable( optionsByCode.get( code ) );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package org.dhis2.fhir.adapter.fhir.transform.dhis.impl.util.dstu3;

/*
* Copyright (c) 2004-2019, 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 ca.uhn.fhir.parser.DataFormatException;
import org.dhis2.fhir.adapter.dhis.converter.ValueConverter;
import org.dhis2.fhir.adapter.dhis.model.Option;
import org.dhis2.fhir.adapter.dhis.model.OptionSet;
import org.dhis2.fhir.adapter.dhis.model.WritableOption;
import org.dhis2.fhir.adapter.fhir.model.FhirVersion;
import org.dhis2.fhir.adapter.fhir.script.ScriptExecutionContext;
import org.dhis2.fhir.adapter.fhir.transform.TransformerDataException;
import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.util.AbstractValueTypeDhisToFhirTransformerUtils;
import org.dhis2.fhir.adapter.model.ValueType;
import org.dhis2.fhir.adapter.scriptable.Scriptable;
import org.hl7.fhir.dstu3.model.BooleanType;
import org.hl7.fhir.dstu3.model.CodeableConcept;
import org.hl7.fhir.dstu3.model.Coding;
import org.hl7.fhir.dstu3.model.DateTimeType;
import org.hl7.fhir.dstu3.model.DecimalType;
import org.hl7.fhir.dstu3.model.IntegerType;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.dstu3.model.TimeType;
import org.hl7.fhir.instance.model.api.IBaseDatatype;
import org.springframework.stereotype.Component;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Set;

/**
* DSTU3 specific implementation of {@link AbstractValueTypeDhisToFhirTransformerUtils}.
*
* @author volsch
*/
@Scriptable
@Component
public class Dstu3ValueTypeDhisToFhirTransformerUtils extends AbstractValueTypeDhisToFhirTransformerUtils
{
public Dstu3ValueTypeDhisToFhirTransformerUtils( @Nonnull ScriptExecutionContext scriptExecutionContext, @Nonnull ValueConverter valueConverter )
{
super( scriptExecutionContext, valueConverter );
}

@Nonnull
@Override
public Set<FhirVersion> getFhirVersions()
{
return FhirVersion.DSTU3_ONLY;
}

@Nullable
@Override
protected IBaseDatatype convert( @Nullable String dhisValue, @Nonnull ValueType valueType, @Nullable OptionSet optionSet )
{
if ( dhisValue == null )
{
return null;
}

if ( optionSet != null )
{
final Option option = optionSet.getOptionalOptionByCode( dhisValue ).orElseGet( () -> new WritableOption( dhisValue, dhisValue ) );

return new CodeableConcept().addCoding( new Coding().setCode( option.getCode() ).setDisplay( option.getName() ) );
}

try
{
switch ( valueType )
{
case TEXT:
case LONG_TEXT:
case EMAIL:
case LETTER:
case ORGANISATION_UNIT:
case PHONE_NUMBER:
case TRACKER_ASSOCIATE:
case URL:
case USERNAME:
return new StringType( dhisValue );
case INTEGER:
case INTEGER_POSITIVE:
case INTEGER_NEGATIVE:
case INTEGER_ZERO_OR_POSITIVE:
return new IntegerType( dhisValue );
case NUMBER:
case PERCENTAGE:
case UNIT_INTERVAL:
return new DecimalType( dhisValue );
case DATETIME:
case DATE:
case AGE:
return new DateTimeType( dhisValue );
case TIME:
return new TimeType( dhisValue );
case BOOLEAN:
case TRUE_ONLY:
return new BooleanType( dhisValue );
default:
throw new TransformerDataException( "Unsupported DHIS2 value type: " + valueType );
}
}
catch ( DataFormatException | IllegalArgumentException e )
{
throw new TransformerDataException( "Value with value type " + valueType + " could not be parsed for setting corresponding FHIR value: " + dhisValue, e );
}
}
}
Loading

0 comments on commit 262442e

Please sign in to comment.