@Test public void transformInternal() { final WritableProgram program = new WritableProgram(); program.setName( "Test Program" ); program.setDescription( "Test Description" ); program.setWithoutRegistration( false ); program.setTrackedEntityTypeId( "a1234567890" ); program.setStages( new ArrayList<>() ); final WritableProgramStage programStage = new WritableProgramStage(); programStage.setId( "b1234567890" ); programStage.setName( "Test Stage 1" ); programStage.setDescription( "Test Description 1" ); programStage.setRepeatable( false ); programStage.setDataElements( new ArrayList<>() ); WritableProgramStageDataElement programStageDataElement = new WritableProgramStageDataElement(); WritableDataElement dataElement = new WritableDataElement(); dataElement.setId( "d0123456789" ); dataElement.setName( "Value 1" ); dataElement.setValueType( ValueType.TEXT ); programStageDataElement.setElement( dataElement ); programStage.getDataElements().add( programStageDataElement ); programStageDataElement = new WritableProgramStageDataElement(); dataElement = new WritableDataElement(); dataElement.setId( "d7123456789" ); dataElement.setName( "Value 2" ); dataElement.setValueType( ValueType.TEXT ); programStageDataElement.setElement( dataElement ); programStage.getDataElements().add( programStageDataElement ); final Patient patient = new Patient(); patient.setId( new IdDt( "Patient/lyau3syaixys" ) ); final ScriptedTrackedEntityInstance scriptedTrackedEntityInstance = new WritableScriptedTrackedEntityInstance( trackedEntityMetadataService, trackedEntityService, trackedEntityAttributes, trackedEntityType, "lyau3syaixys", scriptExecutionContext, valueConverter ); final ArrayList<WritableDataValue> dataValues = new ArrayList<>(); dataValues.add( new WritableDataValue( "d0123456789", "Test Value 1x" ) ); dataValues.add( new WritableDataValue( "d7123456789", "Test Value 2x" ) ); final Event event = new Event(); event.setProgramId( "x72638dsydu" ); event.setProgramStageId( "x12638bsyda" ); event.setOrgUnitId( "j82jdy28dusx" ); event.setEnrollmentId( "a73dhsjxhs8" ); event.setTrackedEntityInstanceId( "lyau3syaixys" ); event.setStatus( EventStatus.OVERDUE ); event.setEventDate( ZonedDateTime.parse( "2011-12-03T10:15:30+01:00" ) ); event.setDueDate( ZonedDateTime.parse( "2011-12-08T10:11:30+01:00" ) ); event.setDataValues( dataValues ); final QuestionnaireResponse fhirQuestionnaireResponse = new QuestionnaireResponse(); final Map<String, Object> scriptVariables = new HashMap<>(); scriptVariables.put( "assignmentUtils", assignmentUtils ); scriptVariables.put( "valueTypeUtils", new R4ValueTypeDhisToFhirTransformerUtils( scriptExecutionContext, valueConverter ) ); Mockito.doAnswer( invocation -> invocation.getArgument( 0 ) ).when( valueConverter ) .convert( Mockito.any(), Mockito.any(), Mockito.eq( String.class ) ); Mockito.doReturn( new Reference( "Location/j82jdy28dusx" ) ).when( assignmentUtils ).getMappedFhirId( Mockito.same( context ), Mockito.any(), Mockito.eq( DhisResourceType.ORGANIZATION_UNIT ), Mockito.eq( "j82jdy28dusx" ), Mockito.eq( FhirResourceType.LOCATION ) ); Mockito.doReturn( new Reference( "Questionnaire/x12638bsyda" ) ).when( assignmentUtils ).getMappedFhirId( Mockito.same( context ), Mockito.any(), Mockito.eq( DhisResourceType.PROGRAM_STAGE_METADATA ), Mockito.eq( "x12638bsyda" ), Mockito.eq( FhirResourceType.QUESTIONNAIRE ) ); Mockito.doReturn( new Reference( "CarePlan/a73dhsjxhs8" ) ).when( assignmentUtils ).getMappedFhirId( Mockito.same( context ), Mockito.any(), Mockito.eq( DhisResourceType.ENROLLMENT ), Mockito.eq( "a73dhsjxhs8" ), Mockito.eq( FhirResourceType.CARE_PLAN ) ); transformer.transformInternal( fhirClient, context, new RuleInfo<>( new ProgramStageRule(), Collections.emptyList() ), scriptVariables, new ImmutableScriptedEvent( new WritableScriptedEvent( program, programStage, event, scriptedTrackedEntityInstance, scriptExecutionContext, valueConverter ) ), fhirQuestionnaireResponse, patient ); Assert.assertEquals( "CarePlan/a73dhsjxhs8", fhirQuestionnaireResponse.getBasedOnFirstRep().getReference() ); Assert.assertEquals( "Questionnaire/x12638bsyda", fhirQuestionnaireResponse.getQuestionnaire() ); Assert.assertEquals( QuestionnaireResponse.QuestionnaireResponseStatus.INPROGRESS, fhirQuestionnaireResponse.getStatus() ); Assert.assertEquals( EventStatus.OVERDUE, EventStatusExtensionUtils.getValue( fhirQuestionnaireResponse ) ); Assert.assertEquals( "Patient/lyau3syaixys", fhirQuestionnaireResponse.getSubject().getReference() ); Assert.assertEquals( "Location/j82jdy28dusx", Objects.requireNonNull( LocationExtensionUtils.getValue( fhirQuestionnaireResponse ) ).getReferenceElement().getValue() ); Assert.assertEquals( Date.from( ZonedDateTime.parse( "2011-12-03T10:15:30+01:00" ).toInstant() ), fhirQuestionnaireResponse.getAuthored() ); Assert.assertEquals( Date.from( ZonedDateTime.parse( "2011-12-08T10:11:30+01:00" ).toInstant() ), DueDateExtensionUtils.getValue( fhirQuestionnaireResponse ) ); Assert.assertEquals( 2, fhirQuestionnaireResponse.getItem().size() ); Assert.assertEquals( "d0123456789", fhirQuestionnaireResponse.getItem().get( 0 ).getLinkId() ); Assert.assertEquals( "Test Value 1x", fhirQuestionnaireResponse.getItem().get( 0 ).getAnswerFirstRep().getValue().primitiveValue() ); Assert.assertEquals( "d7123456789", fhirQuestionnaireResponse.getItem().get( 1 ).getLinkId() ); Assert.assertEquals( "Test Value 2x", fhirQuestionnaireResponse.getItem().get( 1 ).getAnswerFirstRep().getValue().primitiveValue() ); }
@Override protected boolean transformInternal( @Nonnull FhirClient fhirClient, @Nonnull DhisToFhirTransformerContext context, @Nonnull RuleInfo<ProgramStageRule> ruleInfo, @Nonnull Map<String, Object> scriptVariables, @Nonnull ScriptedEvent input, @Nonnull IBaseResource output, @Nonnull IBaseResource trackedEntityResource ) { final Event event = (Event) input.getDhisResource(); final ProgramStage programStage = input.getProgramStage(); final QuestionnaireResponse fhirQuestionnaireResponse = (QuestionnaireResponse) output; final IBaseReference questionnaireReference = createAssignedFhirReference( context, ruleInfo, scriptVariables, DhisResourceType.PROGRAM_STAGE_METADATA, event.getProgramStageId(), FhirResourceType.QUESTIONNAIRE ); fhirQuestionnaireResponse.setQuestionnaireElement( questionnaireReference == null ? null : new CanonicalType( questionnaireReference.getReferenceElement().getValue() ) ); fhirQuestionnaireResponse.setItem( null ); fhirQuestionnaireResponse.setBasedOn( createAssignedFhirReferences( context, ruleInfo, scriptVariables, DhisResourceType.ENROLLMENT, event.getEnrollmentId(), FhirResourceType.CARE_PLAN ) ); EventStatusExtensionUtils.setValue( fhirQuestionnaireResponse, event.getStatus(), ResourceFactory::createType ); fhirQuestionnaireResponse.setAuthored( Date.from( event.getEventDate().toInstant() ) ); DueDateExtensionUtils.setValue( fhirQuestionnaireResponse, event.getDueDate() == null ? null : Date.from( event.getDueDate().toInstant() ), ResourceFactory::createType ); LocationExtensionUtils.setValue( fhirQuestionnaireResponse, createAssignedFhirReference( context, ruleInfo, scriptVariables, DhisResourceType.ORGANIZATION_UNIT, event.getOrgUnitId(), FhirResourceType.LOCATION ) ); fhirQuestionnaireResponse.setSubject( new Reference( trackedEntityResource.getIdElement() ) ); if ( event.getStatus() == EventStatus.COMPLETED ) { fhirQuestionnaireResponse.setStatus( QuestionnaireResponseStatus.COMPLETED ); } else { fhirQuestionnaireResponse.setStatus( QuestionnaireResponseStatus.INPROGRESS ); } final AbstractValueTypeDhisToFhirTransformerUtils valueTypeUtils = TransformerUtils.getScriptVariable( scriptVariables, ScriptVariable.VALUE_TYPE_UTILS, AbstractValueTypeDhisToFhirTransformerUtils.class ); for ( final DataValue dataValue : event.getDataValues() ) { programStage.getOptionalDataElement( createIdReference( dataValue.getDataElementId() ) ).filter( dataElement -> valueTypeUtils.isSupportedValueType( dataElement.getElement().getValueType() ) ).ifPresent( dataElement -> { final QuestionnaireResponseItemComponent item = fhirQuestionnaireResponse.addItem(); item.setLinkId( dataValue.getDataElementId() ); item.addAnswer().setValue( (Type) valueTypeUtils.convert( dataValue.getValue(), dataElement.getElement().getValueType(), dataElement.getElement().getOptionSet() ) ); } ); } return true; }
R4ProgramStageToFhirQuestionnaireResponseTransformer extends AbstractProgramStageToFhirQuestionnaireResponseTransformer { @Override protected boolean transformInternal( @Nonnull FhirClient fhirClient, @Nonnull DhisToFhirTransformerContext context, @Nonnull RuleInfo<ProgramStageRule> ruleInfo, @Nonnull Map<String, Object> scriptVariables, @Nonnull ScriptedEvent input, @Nonnull IBaseResource output, @Nonnull IBaseResource trackedEntityResource ) { final Event event = (Event) input.getDhisResource(); final ProgramStage programStage = input.getProgramStage(); final QuestionnaireResponse fhirQuestionnaireResponse = (QuestionnaireResponse) output; final IBaseReference questionnaireReference = createAssignedFhirReference( context, ruleInfo, scriptVariables, DhisResourceType.PROGRAM_STAGE_METADATA, event.getProgramStageId(), FhirResourceType.QUESTIONNAIRE ); fhirQuestionnaireResponse.setQuestionnaireElement( questionnaireReference == null ? null : new CanonicalType( questionnaireReference.getReferenceElement().getValue() ) ); fhirQuestionnaireResponse.setItem( null ); fhirQuestionnaireResponse.setBasedOn( createAssignedFhirReferences( context, ruleInfo, scriptVariables, DhisResourceType.ENROLLMENT, event.getEnrollmentId(), FhirResourceType.CARE_PLAN ) ); EventStatusExtensionUtils.setValue( fhirQuestionnaireResponse, event.getStatus(), ResourceFactory::createType ); fhirQuestionnaireResponse.setAuthored( Date.from( event.getEventDate().toInstant() ) ); DueDateExtensionUtils.setValue( fhirQuestionnaireResponse, event.getDueDate() == null ? null : Date.from( event.getDueDate().toInstant() ), ResourceFactory::createType ); LocationExtensionUtils.setValue( fhirQuestionnaireResponse, createAssignedFhirReference( context, ruleInfo, scriptVariables, DhisResourceType.ORGANIZATION_UNIT, event.getOrgUnitId(), FhirResourceType.LOCATION ) ); fhirQuestionnaireResponse.setSubject( new Reference( trackedEntityResource.getIdElement() ) ); if ( event.getStatus() == EventStatus.COMPLETED ) { fhirQuestionnaireResponse.setStatus( QuestionnaireResponseStatus.COMPLETED ); } else { fhirQuestionnaireResponse.setStatus( QuestionnaireResponseStatus.INPROGRESS ); } final AbstractValueTypeDhisToFhirTransformerUtils valueTypeUtils = TransformerUtils.getScriptVariable( scriptVariables, ScriptVariable.VALUE_TYPE_UTILS, AbstractValueTypeDhisToFhirTransformerUtils.class ); for ( final DataValue dataValue : event.getDataValues() ) { programStage.getOptionalDataElement( createIdReference( dataValue.getDataElementId() ) ).filter( dataElement -> valueTypeUtils.isSupportedValueType( dataElement.getElement().getValueType() ) ).ifPresent( dataElement -> { final QuestionnaireResponseItemComponent item = fhirQuestionnaireResponse.addItem(); item.setLinkId( dataValue.getDataElementId() ); item.addAnswer().setValue( (Type) valueTypeUtils.convert( dataValue.getValue(), dataElement.getElement().getValueType(), dataElement.getElement().getOptionSet() ) ); } ); } return true; } }
R4ProgramStageToFhirQuestionnaireResponseTransformer extends AbstractProgramStageToFhirQuestionnaireResponseTransformer { @Override protected boolean transformInternal( @Nonnull FhirClient fhirClient, @Nonnull DhisToFhirTransformerContext context, @Nonnull RuleInfo<ProgramStageRule> ruleInfo, @Nonnull Map<String, Object> scriptVariables, @Nonnull ScriptedEvent input, @Nonnull IBaseResource output, @Nonnull IBaseResource trackedEntityResource ) { final Event event = (Event) input.getDhisResource(); final ProgramStage programStage = input.getProgramStage(); final QuestionnaireResponse fhirQuestionnaireResponse = (QuestionnaireResponse) output; final IBaseReference questionnaireReference = createAssignedFhirReference( context, ruleInfo, scriptVariables, DhisResourceType.PROGRAM_STAGE_METADATA, event.getProgramStageId(), FhirResourceType.QUESTIONNAIRE ); fhirQuestionnaireResponse.setQuestionnaireElement( questionnaireReference == null ? null : new CanonicalType( questionnaireReference.getReferenceElement().getValue() ) ); fhirQuestionnaireResponse.setItem( null ); fhirQuestionnaireResponse.setBasedOn( createAssignedFhirReferences( context, ruleInfo, scriptVariables, DhisResourceType.ENROLLMENT, event.getEnrollmentId(), FhirResourceType.CARE_PLAN ) ); EventStatusExtensionUtils.setValue( fhirQuestionnaireResponse, event.getStatus(), ResourceFactory::createType ); fhirQuestionnaireResponse.setAuthored( Date.from( event.getEventDate().toInstant() ) ); DueDateExtensionUtils.setValue( fhirQuestionnaireResponse, event.getDueDate() == null ? null : Date.from( event.getDueDate().toInstant() ), ResourceFactory::createType ); LocationExtensionUtils.setValue( fhirQuestionnaireResponse, createAssignedFhirReference( context, ruleInfo, scriptVariables, DhisResourceType.ORGANIZATION_UNIT, event.getOrgUnitId(), FhirResourceType.LOCATION ) ); fhirQuestionnaireResponse.setSubject( new Reference( trackedEntityResource.getIdElement() ) ); if ( event.getStatus() == EventStatus.COMPLETED ) { fhirQuestionnaireResponse.setStatus( QuestionnaireResponseStatus.COMPLETED ); } else { fhirQuestionnaireResponse.setStatus( QuestionnaireResponseStatus.INPROGRESS ); } final AbstractValueTypeDhisToFhirTransformerUtils valueTypeUtils = TransformerUtils.getScriptVariable( scriptVariables, ScriptVariable.VALUE_TYPE_UTILS, AbstractValueTypeDhisToFhirTransformerUtils.class ); for ( final DataValue dataValue : event.getDataValues() ) { programStage.getOptionalDataElement( createIdReference( dataValue.getDataElementId() ) ).filter( dataElement -> valueTypeUtils.isSupportedValueType( dataElement.getElement().getValueType() ) ).ifPresent( dataElement -> { final QuestionnaireResponseItemComponent item = fhirQuestionnaireResponse.addItem(); item.setLinkId( dataValue.getDataElementId() ); item.addAnswer().setValue( (Type) valueTypeUtils.convert( dataValue.getValue(), dataElement.getElement().getValueType(), dataElement.getElement().getOptionSet() ) ); } ); } return true; } R4ProgramStageToFhirQuestionnaireResponseTransformer( @Nonnull ScriptExecutor scriptExecutor, @Nonnull LockManager lockManager, @Nonnull SystemRepository systemRepository, @Nonnull FhirResourceRepository fhirResourceRepository,
        @Nonnull FhirResourceMappingRepository resourceMappingRepository, @Nonnull FhirDhisAssignmentRepository fhirDhisAssignmentRepository, @Nonnull TrackedEntityMetadataService trackedEntityMetadataService,
        @Nonnull TrackedEntityRuleRepository trackedEntityRuleRepository, @Nonnull ProgramMetadataService programMetadataService ); }
R4ProgramStageToFhirQuestionnaireResponseTransformer extends AbstractProgramStageToFhirQuestionnaireResponseTransformer { @Override protected boolean transformInternal( @Nonnull FhirClient fhirClient, @Nonnull DhisToFhirTransformerContext context, @Nonnull RuleInfo<ProgramStageRule> ruleInfo, @Nonnull Map<String, Object> scriptVariables, @Nonnull ScriptedEvent input, @Nonnull IBaseResource output, @Nonnull IBaseResource trackedEntityResource ) { final Event event = (Event) input.getDhisResource(); final ProgramStage programStage = input.getProgramStage(); final QuestionnaireResponse fhirQuestionnaireResponse = (QuestionnaireResponse) output; final IBaseReference questionnaireReference = createAssignedFhirReference( context, ruleInfo, scriptVariables, DhisResourceType.PROGRAM_STAGE_METADATA, event.getProgramStageId(), FhirResourceType.QUESTIONNAIRE ); fhirQuestionnaireResponse.setQuestionnaireElement( questionnaireReference == null ? null : new CanonicalType( questionnaireReference.getReferenceElement().getValue() ) ); fhirQuestionnaireResponse.setItem( null ); fhirQuestionnaireResponse.setBasedOn( createAssignedFhirReferences( context, ruleInfo, scriptVariables, DhisResourceType.ENROLLMENT, event.getEnrollmentId(), FhirResourceType.CARE_PLAN ) ); EventStatusExtensionUtils.setValue( fhirQuestionnaireResponse, event.getStatus(), ResourceFactory::createType ); fhirQuestionnaireResponse.setAuthored( Date.from( event.getEventDate().toInstant() ) ); DueDateExtensionUtils.setValue( fhirQuestionnaireResponse, event.getDueDate() == null ? null : Date.from( event.getDueDate().toInstant() ), ResourceFactory::createType ); LocationExtensionUtils.setValue( fhirQuestionnaireResponse, createAssignedFhirReference( context, ruleInfo, scriptVariables, DhisResourceType.ORGANIZATION_UNIT, event.getOrgUnitId(), FhirResourceType.LOCATION ) ); fhirQuestionnaireResponse.setSubject( new Reference( trackedEntityResource.getIdElement() ) ); if ( event.getStatus() == EventStatus.COMPLETED ) { fhirQuestionnaireResponse.setStatus( QuestionnaireResponseStatus.COMPLETED ); } else { fhirQuestionnaireResponse.setStatus( QuestionnaireResponseStatus.INPROGRESS ); } final AbstractValueTypeDhisToFhirTransformerUtils valueTypeUtils = TransformerUtils.getScriptVariable( scriptVariables, ScriptVariable.VALUE_TYPE_UTILS, AbstractValueTypeDhisToFhirTransformerUtils.class ); for ( final DataValue dataValue : event.getDataValues() ) { programStage.getOptionalDataElement( createIdReference( dataValue.getDataElementId() ) ).filter( dataElement -> valueTypeUtils.isSupportedValueType( dataElement.getElement().getValueType() ) ).ifPresent( dataElement -> { final QuestionnaireResponseItemComponent item = fhirQuestionnaireResponse.addItem(); item.setLinkId( dataValue.getDataElementId() ); item.addAnswer().setValue( (Type) valueTypeUtils.convert( dataValue.getValue(), dataElement.getElement().getValueType(), dataElement.getElement().getOptionSet() ) ); } ); } return true; } R4ProgramStageToFhirQuestionnaireResponseTransformer( @Nonnull ScriptExecutor scriptExecutor, @Nonnull LockManager lockManager, @Nonnull SystemRepository systemRepository, @Nonnull FhirResourceRepository fhirResourceRepository,
        @Nonnull FhirResourceMappingRepository resourceMappingRepository, @Nonnull FhirDhisAssignmentRepository fhirDhisAssignmentRepository, @Nonnull TrackedEntityMetadataService trackedEntityMetadataService,
        @Nonnull TrackedEntityRuleRepository trackedEntityRuleRepository, @Nonnull ProgramMetadataService programMetadataService ); @Nonnull @Override Set<FhirVersion> getFhirVersions(); }
R4ProgramStageToFhirQuestionnaireResponseTransformer extends AbstractProgramStageToFhirQuestionnaireResponseTransformer { @Override protected boolean transformInternal( @Nonnull FhirClient fhirClient, @Nonnull DhisToFhirTransformerContext context, @Nonnull RuleInfo<ProgramStageRule> ruleInfo, @Nonnull Map<String, Object> scriptVariables, @Nonnull ScriptedEvent input, @Nonnull IBaseResource output, @Nonnull IBaseResource trackedEntityResource ) { final Event event = (Event) input.getDhisResource(); final ProgramStage programStage = input.getProgramStage(); final QuestionnaireResponse fhirQuestionnaireResponse = (QuestionnaireResponse) output; final IBaseReference questionnaireReference = createAssignedFhirReference( context, ruleInfo, scriptVariables, DhisResourceType.PROGRAM_STAGE_METADATA, event.getProgramStageId(), FhirResourceType.QUESTIONNAIRE ); fhirQuestionnaireResponse.setQuestionnaireElement( questionnaireReference == null ? null : new CanonicalType( questionnaireReference.getReferenceElement().getValue() ) ); fhirQuestionnaireResponse.setItem( null ); fhirQuestionnaireResponse.setBasedOn( createAssignedFhirReferences( context, ruleInfo, scriptVariables, DhisResourceType.ENROLLMENT, event.getEnrollmentId(), FhirResourceType.CARE_PLAN ) ); EventStatusExtensionUtils.setValue( fhirQuestionnaireResponse, event.getStatus(), ResourceFactory::createType ); fhirQuestionnaireResponse.setAuthored( Date.from( event.getEventDate().toInstant() ) ); DueDateExtensionUtils.setValue( fhirQuestionnaireResponse, event.getDueDate() == null ? null : Date.from( event.getDueDate().toInstant() ), ResourceFactory::createType ); LocationExtensionUtils.setValue( fhirQuestionnaireResponse, createAssignedFhirReference( context, ruleInfo, scriptVariables, DhisResourceType.ORGANIZATION_UNIT, event.getOrgUnitId(), FhirResourceType.LOCATION ) ); fhirQuestionnaireResponse.setSubject( new Reference( trackedEntityResource.getIdElement() ) ); if ( event.getStatus() == EventStatus.COMPLETED ) { fhirQuestionnaireResponse.setStatus( QuestionnaireResponseStatus.COMPLETED ); } else { fhirQuestionnaireResponse.setStatus( QuestionnaireResponseStatus.INPROGRESS ); } final AbstractValueTypeDhisToFhirTransformerUtils valueTypeUtils = TransformerUtils.getScriptVariable( scriptVariables, ScriptVariable.VALUE_TYPE_UTILS, AbstractValueTypeDhisToFhirTransformerUtils.class ); for ( final DataValue dataValue : event.getDataValues() ) { programStage.getOptionalDataElement( createIdReference( dataValue.getDataElementId() ) ).filter( dataElement -> valueTypeUtils.isSupportedValueType( dataElement.getElement().getValueType() ) ).ifPresent( dataElement -> { final QuestionnaireResponseItemComponent item = fhirQuestionnaireResponse.addItem(); item.setLinkId( dataValue.getDataElementId() ); item.addAnswer().setValue( (Type) valueTypeUtils.convert( dataValue.getValue(), dataElement.getElement().getValueType(), dataElement.getElement().getOptionSet() ) ); } ); } return true; } R4ProgramStageToFhirQuestionnaireResponseTransformer( @Nonnull ScriptExecutor scriptExecutor, @Nonnull LockManager lockManager, @Nonnull SystemRepository systemRepository, @Nonnull FhirResourceRepository fhirResourceRepository,
        @Nonnull FhirResourceMappingRepository resourceMappingRepository, @Nonnull FhirDhisAssignmentRepository fhirDhisAssignmentRepository, @Nonnull TrackedEntityMetadataService trackedEntityMetadataService,
        @Nonnull TrackedEntityRuleRepository trackedEntityRuleRepository, @Nonnull ProgramMetadataService programMetadataService ); @Nonnull @Override Set<FhirVersion> getFhirVersions();  }