=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramIndicator.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramIndicator.java 2015-03-24 10:12:48 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramIndicator.java 2015-03-24 10:52:18 +0000 @@ -67,7 +67,9 @@ public static final String EXPRESSION_REGEXP = "(" + KEY_DATAELEMENT + "|" + KEY_ATTRIBUTE + "|" + KEY_PROGRAM_VARIABLE + "|" + KEY_CONSTANT + ")\\{(\\w+|" + INCIDENT_DATE + "|" + ENROLLMENT_DATE + "|" + CURRENT_DATE + ")" + SEPARATOR_ID + "?(\\w*)\\}"; - public static final Pattern EXPRESSION_PATTERN = Pattern.compile( EXPRESSION_REGEXP ); + public static final Pattern EXPRESSION_PATTERN = Pattern.compile( EXPRESSION_REGEXP ); + public static final Pattern DATAELEMENT_PATTERN = Pattern.compile( KEY_DATAELEMENT + "\\{(\\w{11})" + SEPARATOR_ID + "(\\w{11})\\}" ); + public static final Pattern ATTRIBUTE_PATTERN = Pattern.compile( KEY_ATTRIBUTE + "\\{(\\w{11})\\}" ); public static final String VALID = "valid"; === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramIndicatorService.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramIndicatorService.java 2015-03-10 11:25:25 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramIndicatorService.java 2015-03-24 10:52:18 +0000 @@ -30,6 +30,9 @@ import java.util.Collection; import java.util.Map; +import java.util.Set; + +import org.hisp.dhis.trackedentity.TrackedEntityAttribute; /** * @author Chau Thu Tran @@ -140,4 +143,22 @@ * @return The expression is valid or not */ String expressionIsValid( String expression ); + + /** + * Get all {@link ProgramStageDataElement} part of the expression of the + * given indicator. + * + * @param indicator the ProgramIndicator. + * @return a set of ProgramStageDataElements. + */ + Set getProgramStageDataElementsInExpression( ProgramIndicator indicator ); + + /** + * Get all {@link TrackedEntityAttribute} part of the expression of the + * given indicator. + * + * @param indicator the ProgramIndicator. + * @return a set of TrackedEntityAttributes. + */ + Set getAttributesInExpression( ProgramIndicator indicator ); } === modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageDataElement.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageDataElement.java 2015-01-17 07:41:26 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageDataElement.java 2015-03-24 10:52:18 +0000 @@ -85,6 +85,12 @@ { } + public ProgramStageDataElement( ProgramStage programStage, DataElement dataElement ) + { + this.programStage = programStage; + this.dataElement = dataElement; + } + public ProgramStageDataElement( ProgramStage programStage, DataElement dataElement, boolean compulsory ) { this.programStage = programStage; === modified file 'dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/program/DefaultProgramIndicatorService.java' --- dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/program/DefaultProgramIndicatorService.java 2015-03-24 10:12:48 +0000 +++ dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/program/DefaultProgramIndicatorService.java 2015-03-24 10:52:18 +0000 @@ -33,7 +33,9 @@ import java.util.Collection; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.regex.Matcher; import org.hisp.dhis.constant.Constant; @@ -305,6 +307,7 @@ } + @Override public String expressionIsValid( String expression ) { StringBuffer description = new StringBuffer(); @@ -379,6 +382,52 @@ return ProgramIndicator.VALID; } + @Override + public Set getProgramStageDataElementsInExpression( ProgramIndicator indicator ) + { + Set elements = new HashSet<>(); + + Matcher matcher = ProgramIndicator.DATAELEMENT_PATTERN.matcher( indicator.getExpression() ); + + while ( matcher.find() ) + { + String ps = matcher.group( 1 ); + String de = matcher.group( 2 ); + + ProgramStage programStage = programStageService.getProgramStage( ps ); + DataElement dataElement = dataElementService.getDataElement( de ); + + if ( programStage != null && dataElement != null ) + { + elements.add( new ProgramStageDataElement( programStage, dataElement ) ); + } + } + + return elements; + } + + @Override + public Set getAttributesInExpression( ProgramIndicator indicator ) + { + Set attributes = new HashSet<>(); + + Matcher matcher = ProgramIndicator.ATTRIBUTE_PATTERN.matcher( indicator.getExpression() ); + + while ( matcher.find() ) + { + String at = matcher.group( 1 ); + + TrackedEntityAttribute attribute = attributeService.getTrackedEntityAttribute( at ); + + if ( attribute != null ) + { + attributes.add( attribute ); + } + } + + return attributes; + } + // ------------------------------------------------------------------------- // Supportive methods // ------------------------------------------------------------------------- === modified file 'dhis-2/dhis-services/dhis-service-tracker/src/test/java/org/hisp/dhis/program/ProgramIndicatorServiceTest.java' --- dhis-2/dhis-services/dhis-service-tracker/src/test/java/org/hisp/dhis/program/ProgramIndicatorServiceTest.java 2015-03-24 10:12:48 +0000 +++ dhis-2/dhis-services/dhis-service-tracker/src/test/java/org/hisp/dhis/program/ProgramIndicatorServiceTest.java 2015-03-24 10:52:18 +0000 @@ -32,6 +32,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.hisp.dhis.program.ProgramIndicator.*; import java.util.Collection; import java.util.Date; @@ -40,9 +41,14 @@ import java.util.Set; import org.hisp.dhis.DhisSpringTest; +import org.hisp.dhis.dataelement.DataElement; +import org.hisp.dhis.dataelement.DataElementDomain; +import org.hisp.dhis.dataelement.DataElementService; import org.hisp.dhis.organisationunit.OrganisationUnit; import org.hisp.dhis.organisationunit.OrganisationUnitService; import org.hisp.dhis.system.util.DateUtils; +import org.hisp.dhis.trackedentity.TrackedEntityAttribute; +import org.hisp.dhis.trackedentity.TrackedEntityAttributeService; import org.hisp.dhis.trackedentity.TrackedEntityInstance; import org.hisp.dhis.trackedentity.TrackedEntityInstanceService; import org.hisp.dhis.trackedentitydatavalue.TrackedEntityDataValueService; @@ -60,6 +66,9 @@ private ProgramIndicatorService programIndicatorService; @Autowired + private TrackedEntityAttributeService attributeService; + + @Autowired private TrackedEntityInstanceService entityInstanceService; @Autowired @@ -76,24 +85,33 @@ @Autowired private TrackedEntityDataValueService dataValueService; + + @Autowired + private DataElementService dataElementService; private Date incidenDate; private Date enrollmentDate; + + private ProgramStage psA; + private ProgramStage psB; private Program programA; - private Program programB; private ProgramInstance programInstance; + + private DataElement deA; + private DataElement deB; + + private TrackedEntityAttribute atA; + private TrackedEntityAttribute atB; private ProgramIndicator indicatorDate; - private ProgramIndicator indicatorInt; - private ProgramIndicator indicatorC; - private ProgramIndicator indicatorD; + private ProgramIndicator indicatorE; @Override public void setUpTest() @@ -104,17 +122,17 @@ programA = createProgram( 'A', new HashSet(), organisationUnit ); programService.addProgram( programA ); - ProgramStage stageA = new ProgramStage( "StageA", programA ); - stageA.setSortOrder( 1 ); - programStageService.saveProgramStage( stageA ); + psA = new ProgramStage( "StageA", programA ); + psA.setSortOrder( 1 ); + programStageService.saveProgramStage( psA ); - ProgramStage stageB = new ProgramStage( "StageB", programA ); - stageB.setSortOrder( 2 ); - programStageService.saveProgramStage( stageB ); + psB = new ProgramStage( "StageB", programA ); + psB.setSortOrder( 2 ); + programStageService.saveProgramStage( psB ); Set programStages = new HashSet<>(); - programStages.add( stageA ); - programStages.add( stageB ); + programStages.add( psA ); + programStages.add( psB ); programA.setProgramStages( programStages ); programService.updateProgram( programA ); @@ -136,6 +154,20 @@ programInstance = programInstanceService.enrollTrackedEntityInstance( entityInstance, programA, enrollmentDate, incidenDate, organisationUnit ); + deA = createDataElement( 'A' ); + deA.setDomainType( DataElementDomain.TRACKER ); + deB = createDataElement( 'B' ); + deB.setDomainType( DataElementDomain.TRACKER ); + + dataElementService.addDataElement( deA ); + dataElementService.addDataElement( deB ); + + atA = createTrackedEntityAttribute( 'A' ); + atB = createTrackedEntityAttribute( 'B' ); + + attributeService.addTrackedEntityAttribute( atA ); + attributeService.addTrackedEntityAttribute( atB ); + indicatorDate = new ProgramIndicator( "IndicatorA", "IndicatorDesA", ProgramIndicator.VALUE_TYPE_INT, "( " + ProgramIndicator.KEY_PROGRAM_VARIABLE + "{" + ProgramIndicator.INCIDENT_DATE + "} - " + ProgramIndicator.KEY_PROGRAM_VARIABLE + "{" + ProgramIndicator.ENROLLMENT_DATE + "} ) / 7" ); indicatorDate.setUid( "UID-DATE" ); @@ -158,10 +190,15 @@ indicatorD.setUid( "UID-D" ); indicatorD.setShortName( "D" ); indicatorD.setProgram( programB ); + + indicatorE = new ProgramIndicator( "IndicatorE", "IndicatorDesE", VALUE_TYPE_INT, + KEY_DATAELEMENT + "{" + psA.getUid() + "." + deA.getUid() + "} + " + + KEY_DATAELEMENT + "{" + psB.getUid() + "." + deB.getUid() + "} - " + + KEY_ATTRIBUTE + "{" + atA.getUid() + "} + " + KEY_ATTRIBUTE + "{" + atB.getUid() + "}" ); } // ------------------------------------------------------------------------- - // Tests + // CRUD tests // ------------------------------------------------------------------------- @Test @@ -274,6 +311,30 @@ } + // ------------------------------------------------------------------------- + // Logic tests + // ------------------------------------------------------------------------- + + @Test + public void testGetProgramStageDataElementsInExpression() + { + Set elements = programIndicatorService.getProgramStageDataElementsInExpression( indicatorE ); + + assertEquals( 2, elements.size() ); + assertTrue( elements.contains( new ProgramStageDataElement( psA, deA ) ) ); + assertTrue( elements.contains( new ProgramStageDataElement( psB, deB ) ) ); + } + + @Test + public void testGetAttributesInExpression() + { + Set attributes = programIndicatorService.getAttributesInExpression( indicatorE ); + + assertEquals( 2, attributes.size() ); + assertTrue( attributes.contains( atA ) ); + assertTrue( attributes.contains( atB ) ); + } + @Test public void testGetProgramIndicatorValue() {