=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/ExpressionService.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/ExpressionService.java 2011-04-24 15:50:02 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/expression/ExpressionService.java 2011-05-20 12:27:47 +0000 @@ -57,7 +57,8 @@ final String NULL_REPLACEMENT = "0"; final String SPACE = " "; - final String FORMULA_EXPRESSION = "\\[.+?\\]"; + final String FORMULA_EXPRESSION = "\\[\\d+?.*?\\]"; // [ - one or more digits - any characters - ] + final String DAYS_EXPRESSION = "\\[days\\]"; // [days] /** * Adds a new Expression to the database. @@ -195,4 +196,14 @@ */ String generateExpression( String expression, Period period, OrganisationUnit source, boolean nullIfNoValues, boolean aggregated ); + /** + * Generates an expression where the Operand identifiers, consisting of + * data element id and category option combo id, are replaced + * by the aggregated value for the relevant combination of data element, + * period, and source. + * + * @param formula The formula to parse. + * @param valueMap The map containing data element identifiers and aggregated value. + */ + String generateExpression( String expression, Map valueMap ); } === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/expression/DefaultExpressionService.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/expression/DefaultExpressionService.java 2011-04-24 15:50:02 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/expression/DefaultExpressionService.java 2011-05-20 12:27:47 +0000 @@ -378,10 +378,10 @@ if ( expression != null ) { + buffer = new StringBuffer(); + final Matcher matcher = FORMULA_PATTERN.matcher( expression ); - buffer = new StringBuffer(); - while ( matcher.find() ) { String match = matcher.group(); @@ -416,4 +416,33 @@ return buffer != null ? buffer.toString() : null; } + + public String generateExpression( String expression, Map valueMap ) + { + StringBuffer buffer = null; + + if ( expression != null ) + { + final Matcher matcher = FORMULA_PATTERN.matcher( expression ); + + buffer = new StringBuffer(); + + while ( matcher.find() ) + { + String match = matcher.group(); + + final DataElementOperand operand = DataElementOperand.getOperand( match ); + + Double aggregatedValue = valueMap.get( operand ); + + match = ( aggregatedValue == null ) ? NULL_REPLACEMENT : String.valueOf( aggregatedValue ); + + matcher.appendReplacement( buffer, match ); + } + + matcher.appendTail( buffer ); + } + + return buffer != null ? buffer.toString() : null; + } } === modified file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/expression/ExpressionServiceTest.java' --- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/expression/ExpressionServiceTest.java 2011-05-10 08:58:10 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/expression/ExpressionServiceTest.java 2011-05-20 12:27:47 +0000 @@ -282,10 +282,6 @@ assertEquals( ExpressionService.VALID, expressionService.expressionIsValid( expressionA ) ); assertEquals( ExpressionService.VALID, expressionService.expressionIsValid( expressionB ) ); - expressionA = "[" + "foo" + SEPARATOR + categoryOptionComboId + "] + 12"; - - assertEquals( ExpressionService.ID_NOT_NUMERIC, expressionService.expressionIsValid( expressionA ) ); - expressionA = "[" + dataElementIdA + SEPARATOR + "foo" + "] + 12"; assertEquals( ExpressionService.ID_NOT_NUMERIC, expressionService.expressionIsValid( expressionA ) ); @@ -327,6 +323,16 @@ assertEquals( "0-0", expression ); } + @Test + public void testGenerateExpressionMap() + { + Map valueMap = new HashMap(); + valueMap.put( new DataElementOperand( dataElementIdA, categoryOptionComboId ), new Double( 12 ) ); + valueMap.put( new DataElementOperand( dataElementIdB, categoryOptionComboId ), new Double( 34 ) ); + + assertEquals( "12.0+34.0", expressionService.generateExpression( expressionA, valueMap ) ); + } + // ------------------------------------------------------------------------- // CRUD tests // ------------------------------------------------------------------------- === modified file 'dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/indicator/DefaultIndicatorDataMart.java' --- dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/indicator/DefaultIndicatorDataMart.java 2011-04-15 15:02:55 +0000 +++ dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/indicator/DefaultIndicatorDataMart.java 2011-05-20 12:27:47 +0000 @@ -27,7 +27,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import static org.hisp.dhis.datamart.util.ParserUtil.generateExpression; import static org.hisp.dhis.options.SystemSettingManager.KEY_OMIT_INDICATORS_ZERO_NUMERATOR_DATAMART; import static org.hisp.dhis.system.util.DateUtils.DAYS_IN_YEAR; import static org.hisp.dhis.system.util.MathUtils.calculateExpression; @@ -43,6 +42,7 @@ import org.hisp.dhis.dataelement.DataElementOperand; import org.hisp.dhis.datamart.aggregation.cache.AggregationCache; import org.hisp.dhis.datamart.aggregation.dataelement.DataElementAggregator; +import org.hisp.dhis.expression.ExpressionService; import org.hisp.dhis.indicator.Indicator; import org.hisp.dhis.jdbc.batchhandler.AggregatedIndicatorValueBatchHandler; import org.hisp.dhis.options.SystemSettingManager; @@ -74,6 +74,13 @@ { this.organisationUnitService = organisationUnitService; } + + private ExpressionService expressionService; + + public void setExpressionService( ExpressionService expressionService ) + { + this.expressionService = expressionService; + } private DataElementAggregator sumIntAggregator; @@ -161,8 +168,8 @@ for ( final Indicator indicator : indicators ) { - final double numeratorValue = calculateExpression( generateExpression( indicator.getExplodedNumerator(), valueMap ) ); - final double denominatorValue = calculateExpression( generateExpression( indicator.getExplodedDenominator(), valueMap ) ); + final double numeratorValue = calculateExpression( expressionService.generateExpression( indicator.getExplodedNumerator(), valueMap ) ); + final double denominatorValue = calculateExpression( expressionService.generateExpression( indicator.getExplodedDenominator(), valueMap ) ); // --------------------------------------------------------- // AggregatedIndicatorValue === removed directory 'dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/util' === removed file 'dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/util/ParserUtil.java' --- dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/util/ParserUtil.java 2011-01-09 21:24:40 +0000 +++ dhis-2/dhis-services/dhis-service-datamart-default/src/main/java/org/hisp/dhis/datamart/util/ParserUtil.java 1970-01-01 00:00:00 +0000 @@ -1,119 +0,0 @@ -package org.hisp.dhis.datamart.util; - -/* - * Copyright (c) 2004-2010, 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 static org.hisp.dhis.expression.Expression.SEPARATOR; - -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.hisp.dhis.dataelement.DataElementOperand; - -/** - * @author Lars Helge Overland - * @version $Id: ParserUtil.java 5510 2008-07-30 16:30:27Z larshelg $ - */ -public class ParserUtil -{ - private static final String NULL_REPLACEMENT = "0"; - - private static final Pattern OPERAND_PATTERN = Pattern.compile( "(\\[\\d+\\" + SEPARATOR + "\\d+\\])" ); - - /** - * Returns the data element identifiers in the given expression. Returns null - * if the formula is null, returns an empty set if no data elements exist in - * the formula, otherwise a set of the data elements in the formula. - * - * @param formula The formula to be parsed. - */ - public static Set getDataElementIdsInExpression( String expression ) - { - Set dataElementIdsInExpression = null; - - if ( expression != null ) - { - dataElementIdsInExpression = new HashSet(); - - final Matcher matcher = OPERAND_PATTERN.matcher( expression ); - - while ( matcher.find() ) - { - String replaceString = matcher.group().replaceAll( "[\\[\\]]", "" ); - - replaceString = replaceString.substring( 0, replaceString.indexOf( SEPARATOR ) ); - - dataElementIdsInExpression.add( Integer.parseInt( replaceString ) ); - } - } - - return dataElementIdsInExpression; - } - - /** - * Generates an expression where the Operand identifiers, consisting of - * data element id and category option combo id, are replaced - * by the aggregated value for the relevant combination of data element, - * period, and source. - * - * @param formula The formula to parse. - * @param valueMap The map containing data element identifiers and aggregated value. - */ - public static String generateExpression( final String formula, final Map valueMap ) - { - try - { - final Matcher matcher = OPERAND_PATTERN.matcher( formula ); - - final StringBuffer buffer = new StringBuffer(); - - while ( matcher.find() ) - { - String match = matcher.group(); - - final DataElementOperand operand = DataElementOperand.getOperand( match ); - - Double aggregatedValue = valueMap.get( operand ); - - match = ( aggregatedValue == null ) ? NULL_REPLACEMENT : String.valueOf( aggregatedValue ); - - matcher.appendReplacement( buffer, match ); - } - - matcher.appendTail( buffer ); - - return buffer.toString(); - } - catch ( NumberFormatException ex ) - { - throw new RuntimeException( "Illegal data element or category combo id", ex ); - } - } -} === modified file 'dhis-2/dhis-services/dhis-service-datamart-default/src/main/resources/META-INF/dhis/beans.xml' --- dhis-2/dhis-services/dhis-service-datamart-default/src/main/resources/META-INF/dhis/beans.xml 2011-04-24 15:50:02 +0000 +++ dhis-2/dhis-services/dhis-service-datamart-default/src/main/resources/META-INF/dhis/beans.xml 2011-05-20 12:27:47 +0000 @@ -160,6 +160,8 @@ class="org.hisp.dhis.datamart.indicator.DefaultIndicatorDataMart"> +