------------------------------------------------------------ revno: 19267 committer: Lars Helge Overland <larshe...@gmail.com> branch nick: dhis2 timestamp: Wed 2015-06-03 00:11:37 +0200 message: Impl method ProgramIndicatorService.filterIsValid modified: dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramIndicator.java dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramIndicatorService.java dhis-2/dhis-services/dhis-service-core/src/main/resources/i18n_global.properties dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/program/DefaultProgramIndicatorService.java dhis-2/dhis-services/dhis-service-tracker/src/test/java/org/hisp/dhis/program/ProgramIndicatorServiceTest.java dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/ProgramIndicatorController.java dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/addProgramIndicator.vm dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/javascript/programIndicator.js dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/programIndicatorForm.vm dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/updateProgramIndicator.vm
-- 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/program/ProgramIndicator.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramIndicator.java 2015-06-02 16:33:45 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramIndicator.java 2015-06-02 22:11:37 +0000 @@ -78,6 +78,7 @@ public static final String EXPRESSION_NOT_WELL_FORMED = "expression_not_well_formed"; public static final String INVALID_IDENTIFIERS_IN_EXPRESSION = "invalid_identifiers_in_expression"; + public static final String FILTER_NOT_EVALUATING_TO_TRUE_OR_FALSE = "filter_not_evaluating_to_true_or_false"; private Program program; === 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-06-02 15:19:55 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramIndicatorService.java 2015-06-02 22:11:37 +0000 @@ -147,6 +147,16 @@ * {@link ProgramIndicator.INVALID_VARIABLES_IN_EXPRESSION}. */ String expressionIsValid( String expression ); + + /** + * Indicates whether the given program indicator expression is valid. + * + * @param expression An expression string. + * @return the string {@link ProgramIndicator.VALID} if valid, if not any of + * {@link ProgramIndicator.FILTER_NOT_EVALUATING_TO_TRUE_OR_FALSE}, + * {@link ProgramIndicator.INVALID_VARIABLES_IN_EXPRESSION}. + */ + String filterIsValid( String filter ); /** * Get all {@link ProgramStageDataElement} part of the expression of the === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/i18n_global.properties' --- dhis-2/dhis-services/dhis-service-core/src/main/resources/i18n_global.properties 2015-06-02 15:19:55 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/resources/i18n_global.properties 2015-06-02 22:11:37 +0000 @@ -654,6 +654,7 @@ waiting=Please wait expression_not_well_formed=Expression is not well formed invalid_identifiers_in_expression=Invalid identifiers in expression +filter_not_evaluating_to_true_or_false=Filter is not evaluating to true or false locate_by_code=Locate by code select_at_level=Select at level === 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-06-02 16:33:45 +0000 +++ dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/program/DefaultProgramIndicatorService.java 2015-06-02 22:11:37 +0000 @@ -45,6 +45,7 @@ import org.hisp.dhis.i18n.I18nService; import org.hisp.dhis.system.util.DateUtils; import org.hisp.dhis.system.util.MathUtils; +import org.hisp.dhis.util.ExpressionUtils; import org.hisp.dhis.util.TextUtils; import org.hisp.dhis.trackedentity.TrackedEntityAttribute; import org.hisp.dhis.trackedentity.TrackedEntityAttributeService; @@ -318,76 +319,103 @@ @Override public String expressionIsValid( String expression ) { - StringBuffer description = new StringBuffer(); - - Matcher matcher = ProgramIndicator.EXPRESSION_PATTERN.matcher( expression ); + String expr = getSubstitutedExpression( expression ); - while ( matcher.find() ) + if ( ProgramIndicator.INVALID_IDENTIFIERS_IN_EXPRESSION.equals( expr ) ) { - String key = matcher.group( 1 ); - String uid = matcher.group( 2 ); - - if ( ProgramIndicator.KEY_DATAELEMENT.equals( key ) ) - { - String de = matcher.group( 3 ); - - ProgramStage programStage = programStageService.getProgramStage( uid ); - DataElement dataElement = dataElementService.getDataElement( de ); - - if ( programStage != null && dataElement != null ) - { - matcher.appendReplacement( description, String.valueOf( 1 ) ); - } - else - { - return ProgramIndicator.INVALID_IDENTIFIERS_IN_EXPRESSION; - } - } - else if ( ProgramIndicator.KEY_ATTRIBUTE.equals( key ) ) - { - TrackedEntityAttribute attribute = attributeService.getTrackedEntityAttribute( uid ); - - if ( attribute != null ) - { - matcher.appendReplacement( description, String.valueOf( 1 ) ); - } - else - { - return ProgramIndicator.INVALID_IDENTIFIERS_IN_EXPRESSION; - } - } - else if ( ProgramIndicator.KEY_CONSTANT.equals( key ) ) - { - Constant constant = constantService.getConstant( uid ); - - if ( constant != null ) - { - matcher.appendReplacement( description, String.valueOf( constant.getValue() ) ); - } - else - { - return ProgramIndicator.INVALID_IDENTIFIERS_IN_EXPRESSION; - } - } - else if ( ProgramIndicator.KEY_PROGRAM_VARIABLE.equals( key ) ) - { - matcher.appendReplacement( description, String.valueOf( 0 ) ); - } + return expr; } - matcher.appendTail( description ); - - // --------------------------------------------------------------------- - // Well-formed expression - // --------------------------------------------------------------------- - - if ( MathUtils.expressionHasErrors( description.toString() ) ) + if ( MathUtils.expressionHasErrors( expr ) ) { return ProgramIndicator.EXPRESSION_NOT_WELL_FORMED; } return ProgramIndicator.VALID; } + + @Override + public String filterIsValid( String filter ) + { + String expr = getSubstitutedExpression( filter ); + + if ( ProgramIndicator.INVALID_IDENTIFIERS_IN_EXPRESSION.equals( expr ) ) + { + return expr; + } + + return ExpressionUtils.isBoolean( expr, null ) ? ProgramIndicator.VALID : ProgramIndicator.FILTER_NOT_EVALUATING_TO_TRUE_OR_FALSE; + } + + /** + * Generates an expression where all items are substituted with a sample value + * in order to maintain a valid expression syntax. + * + * @param expression the expression. + */ + private String getSubstitutedExpression( String expression ) + { + StringBuffer expr = new StringBuffer(); + + Matcher matcher = ProgramIndicator.EXPRESSION_PATTERN.matcher( expression ); + + while ( matcher.find() ) + { + String key = matcher.group( 1 ); + String uid = matcher.group( 2 ); + + if ( ProgramIndicator.KEY_DATAELEMENT.equals( key ) ) + { + String de = matcher.group( 3 ); + + ProgramStage programStage = programStageService.getProgramStage( uid ); + DataElement dataElement = dataElementService.getDataElement( de ); + + if ( programStage != null && dataElement != null ) + { + matcher.appendReplacement( expr, String.valueOf( 1 ) ); + } + else + { + return ProgramIndicator.INVALID_IDENTIFIERS_IN_EXPRESSION; + } + } + else if ( ProgramIndicator.KEY_ATTRIBUTE.equals( key ) ) + { + TrackedEntityAttribute attribute = attributeService.getTrackedEntityAttribute( uid ); + + if ( attribute != null ) + { + matcher.appendReplacement( expr, String.valueOf( 1 ) ); + } + else + { + return ProgramIndicator.INVALID_IDENTIFIERS_IN_EXPRESSION; + } + } + else if ( ProgramIndicator.KEY_CONSTANT.equals( key ) ) + { + Constant constant = constantService.getConstant( uid ); + + if ( constant != null ) + { + matcher.appendReplacement( expr, String.valueOf( constant.getValue() ) ); + } + else + { + return ProgramIndicator.INVALID_IDENTIFIERS_IN_EXPRESSION; + } + } + else if ( ProgramIndicator.KEY_PROGRAM_VARIABLE.equals( key ) ) + { + matcher.appendReplacement( expr, String.valueOf( 0 ) ); + } + } + + matcher.appendTail( expr ); + + return expr.toString(); + } @Override public Set<ProgramStageDataElement> getProgramStageDataElementsInExpression( ProgramIndicator indicator ) === 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-06-02 16:33:45 +0000 +++ dhis-2/dhis-services/dhis-service-tracker/src/test/java/org/hisp/dhis/program/ProgramIndicatorServiceTest.java 2015-06-02 22:11:37 +0000 @@ -507,7 +507,20 @@ assertEquals( ProgramIndicator.VALID, programIndicatorService.expressionIsValid( indicatorB.getExpression() ) ); assertEquals( ProgramIndicator.VALID, programIndicatorService.expressionIsValid( indicatorA.getExpression() ) ); - assertEquals( ProgramIndicator.EXPRESSION_NOT_WELL_FORMED, - programIndicatorService.expressionIsValid( indicatorD.getExpression() ) ); + assertEquals( ProgramIndicator.EXPRESSION_NOT_WELL_FORMED, programIndicatorService.expressionIsValid( indicatorD.getExpression() ) ); + } + + @Test + public void testFilterIsValid() + { + String filterA = KEY_DATAELEMENT + "{" + psA.getUid() + "." + deA.getUid() + "} - " + KEY_ATTRIBUTE + "{" + atA.getUid() + "} > 10"; + String filterB = KEY_ATTRIBUTE + "{" + atA.getUid() + "} == " + KEY_DATAELEMENT + "{" + psA.getUid() + "." + deA.getUid() + "} - 5"; + String filterC = KEY_ATTRIBUTE + "{invaliduid} == 100"; + String filterD = KEY_ATTRIBUTE + "{" + atA.getUid() + "} + 200"; + + assertEquals( ProgramIndicator.VALID, programIndicatorService.filterIsValid( filterA ) ); + assertEquals( ProgramIndicator.VALID, programIndicatorService.filterIsValid( filterB ) ); + assertEquals( ProgramIndicator.INVALID_IDENTIFIERS_IN_EXPRESSION, programIndicatorService.filterIsValid( filterC ) ); + assertEquals( ProgramIndicator.FILTER_NOT_EVALUATING_TO_TRUE_OR_FALSE, programIndicatorService.filterIsValid( filterD ) ); } } === modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/ProgramIndicatorController.java' --- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/ProgramIndicatorController.java 2015-06-02 15:46:55 +0000 +++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/event/ProgramIndicatorController.java 2015-06-02 22:11:37 +0000 @@ -38,7 +38,6 @@ import org.hisp.dhis.program.ProgramIndicator; import org.hisp.dhis.program.ProgramIndicatorService; import org.hisp.dhis.schema.descriptors.ProgramIndicatorSchemaDescriptor; -import org.hisp.dhis.util.ExpressionUtils; import org.hisp.dhis.webapi.controller.AbstractCrudController; import org.hisp.dhis.webapi.webdomain.ValidationResult; import org.springframework.beans.factory.annotation.Autowired; @@ -86,18 +85,22 @@ } @RequestMapping( value = "/filter/description", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE ) - public void validateFilter( @RequestParam String filter, HttpServletResponse response ) + public void validateFilter( @RequestParam String expression, HttpServletResponse response ) throws IOException { - boolean result = ExpressionUtils.isBoolean( filter, null ); + I18n i18n = i18nManager.getI18n(); + + String result = programIndicatorService.filterIsValid( expression ); ValidationResult validation = new ValidationResult(); - validation.setValid( result ); - validation.setMessage( result ? ProgramIndicator.VALID : ProgramIndicator.EXPRESSION_NOT_WELL_FORMED ); + validation.setValid( ProgramIndicator.VALID.equals( result ) ); + validation.setMessage( i18n.getString( result ) ); if ( validation.isValid() ) { - validation.setDescription( "" ); + String description = programIndicatorService.getExpressionDescription( expression ); + + validation.setDescription( description ); } response.setContentType( MediaType.APPLICATION_JSON_VALUE ); === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/addProgramIndicator.vm' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/addProgramIndicator.vm 2015-06-02 18:23:24 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/addProgramIndicator.vm 2015-06-02 22:11:37 +0000 @@ -33,7 +33,7 @@ </thead> <tbody> <tr> - <td><label for="name">$i18n.getString( "name" ) <em title="$i18n.getString( "required" )" class="required">*</em></label></td> + <td style="width:80px"><label for="name">$i18n.getString( "name" ) <em title="$i18n.getString( "required" )" class="required">*</em></label></td> <td><input type="text" id="name" name="name" ></td> <td></td> </tr> @@ -78,10 +78,10 @@ #parse( "/dhis-web-maintenance-program/programIndicatorForm.vm" ) -<p> +<div style="margin-top:25px"> <input type="submit" value="$i18n.getString( 'add' )" style="width:10em"> <input type="button" value="$i18n.getString( 'cancel' )" style="width:10em" onclick="window.location.href='programIndicator.action?programId=$program.id'" > -</p> +</div> </form> === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/javascript/programIndicator.js' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/javascript/programIndicator.js 2015-06-02 18:23:24 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/javascript/programIndicator.js 2015-06-02 22:11:37 +0000 @@ -85,7 +85,7 @@ dataElementId = getFieldValue(deFieldId); insertTextCommon(areaId, "#{" + programStageId + "." + dataElementId + "}"); - getConditionDescription(); + getExpressionDescription( type ); } function insertAttribute( type ){ @@ -94,7 +94,7 @@ attributeId = getFieldValue(atFieldId); insertTextCommon(areaId, "A{" + attributeId + "}"); - getConditionDescription(); + getExpressionDescription( type ); } function insertVariable( type ){ @@ -103,7 +103,7 @@ variableId = getFieldValue(varFieldId); insertTextCommon(areaId, "V{" + variableId + "}"); - getConditionDescription(); + getExpressionDescription( type ); } function insertConstant( type ){ @@ -112,33 +112,33 @@ constantId = getFieldValue(coFieldId); insertTextCommon(areaId, "C{" + constantId + "}"); - getConditionDescription(); + getExpressionDescription( type ); } function insertOperator( type, value ) { insertTextCommon(type, ' ' + value + ' '); - getConditionDescription(); + getExpressionDescription( type ); } -function getConditionDescription() { - var expression = getFieldValue('expression'); +function getExpressionDescription( type ) { + var expression = getFieldValue( type ); if( expression == '' ) { - setInnerHTML('expression-description', ''); + setInnerHTML(type + '-description', ''); } else { - $.getJSON('../api/programIndicators/expression/description', { + $.getJSON('../api/programIndicators/' + type + '/description', { expression: expression }, function( json ) { if( json.valid ){ - setFieldValue('checkExpression', json.message); - setInnerHTML('expression-description', json.description); + setFieldValue(type + '-check', json.message); + setInnerHTML(type + '-description', json.description); } else { - setFieldValue('checkExpression',''); - setInnerHTML('expression-description', json.message); + setFieldValue(type + '-check',''); + setInnerHTML(type + '-description', json.message); } }); } === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/programIndicatorForm.vm' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/programIndicatorForm.vm 2015-06-02 20:35:23 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/programIndicatorForm.vm 2015-06-02 22:11:37 +0000 @@ -120,7 +120,7 @@ </tr> <tr> <td> - <textarea style="width:665px" id="expression" name="expression" onkeyup='getConditionDescription();' >$!encoder.htmlEncode($!programIndicator.expression)</textarea> + <textarea style="width:665px" id="expression" name="expression" onkeyup="getExpressionDescription('expression')">$!encoder.htmlEncode($!programIndicator.expression)</textarea> </td> </tr> <tr> @@ -139,7 +139,7 @@ <tr> <td> <div id='expression-description' style="padding: 5px 0 20px 0">$!encoder.htmlEncode($!description)</div> - <input type="hidden" id="checkExpression" name="checkExpression" title="$i18n.getString('expression_is_not_well_formed')" class="{validate:{required:true}}" /> + <input type="hidden" id="expression-check" name="expression-check" title="$i18n.getString('expression_is_not_well_formed')" class="{validate:{required:true}}" /> </td> </tr> </table> @@ -151,7 +151,8 @@ <th>$i18n.getString( "filter" )</th> </tr> <tr> - <td><div class="message message-info" style="margin-top:10px">The filter is applied to events and filters the data source used for the calculation</div></td> + <td><div class="message message-info" style="margin-top:10px">The filter is applied to events and filters the data source used for the calculation of the indicator. + The filter must evaluate to either true or false.</div></td> </tr> <tr> <td> @@ -242,7 +243,7 @@ </tr> <tr> <td> - <textarea style="width:665px" id="filter" name="filter" onkeyup='getConditionDescription();' >$!encoder.htmlEncode($!programIndicator.filter)</textarea> + <textarea style="width:665px" id="filter" name="filter" onkeyup="getExpressionDescription('filter')">$!encoder.htmlEncode($!programIndicator.filter)</textarea> </td> </tr> <tr> @@ -261,7 +262,7 @@ <tr> <td> <div id='filter-description' style="padding: 5px 0 20px 0">$!encoder.htmlEncode($!description)</div> - <input type="hidden" id="checkExpression" name="checkExpression" title="$i18n.getString('expression_is_not_well_formed')" class="{validate:{required:true}}" /> + <input type="hidden" id="filter-check" name="filter-check" title="$i18n.getString('expression_is_not_well_formed')" class="{validate:{required:true}}" /> </td> </tr> </table> === modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/updateProgramIndicator.vm' --- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/updateProgramIndicator.vm 2015-06-02 18:23:24 +0000 +++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/updateProgramIndicator.vm 2015-06-02 22:11:37 +0000 @@ -37,7 +37,7 @@ </tr> </thead> <tr> - <td><label for="name">$i18n.getString( "name" ) <em title="$i18n.getString( "required" )" class="required">*</em></label></td> + <td style="width:80px"><label for="name">$i18n.getString( "name" ) <em title="$i18n.getString( "required" )" class="required">*</em></label></td> <td><input type="text" id="name" name="name" value='$encoder.htmlEncode($programIndicator.name)'></td> <td></td> </tr> @@ -82,10 +82,10 @@ #parse( "/dhis-web-maintenance-program/programIndicatorForm.vm" ) -<p> +<div style="margin-top:25px"> <input type="submit" value="$i18n.getString( 'update' )" style="width:10em"> <input type="button" value="$i18n.getString( 'cancel' )" style="width:10em" onclick="window.location.href='programIndicator.action?programId=$programIndicator.program.id'" > -</p> +</div> </form>
_______________________________________________ Mailing list: https://launchpad.net/~dhis2-devs Post to : dhis2-devs@lists.launchpad.net Unsubscribe : https://launchpad.net/~dhis2-devs More help : https://help.launchpad.net/ListHelp