1
package org.hisp.dhis.de.history;
4
* Copyright (c) 2004-2007, University of Oslo
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions are met:
9
* * Redistributions of source code must retain the above copyright notice, this
10
* list of conditions and the following disclaimer.
11
* * Redistributions in binary form must reproduce the above copyright notice,
12
* this list of conditions and the following disclaimer in the documentation
13
* and/or other materials provided with the distribution.
14
* * Neither the name of the HISP project nor the names of its contributors may
15
* be used to endorse or promote products derived from this software without
16
* specific prior written permission.
18
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
22
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
import java.util.ArrayList;
31
import java.util.Collections;
32
import java.util.List;
34
import org.hisp.dhis.dataelement.DataElement;
35
import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
36
import org.hisp.dhis.datavalue.DataValue;
37
import org.hisp.dhis.datavalue.DataValueService;
38
import org.hisp.dhis.minmax.MinMaxDataElement;
39
import org.hisp.dhis.minmax.MinMaxDataElementStore;
40
import org.hisp.dhis.organisationunit.OrganisationUnit;
41
import org.hisp.dhis.period.CalendarPeriodType;
42
import org.hisp.dhis.period.Period;
45
* @author Torgeir Lorange Ostby
46
* @version $Id: DefaultHistoryRetriever.java 5131 2008-05-11 21:06:23Z larshelg $
48
public class DefaultHistoryRetriever
49
implements HistoryRetriever
51
// -------------------------------------------------------------------------
53
// -------------------------------------------------------------------------
55
private MinMaxDataElementStore minMaxDataElementStore;
57
public void setMinMaxDataElementStore( MinMaxDataElementStore minMaxDataElementStore )
59
this.minMaxDataElementStore = minMaxDataElementStore;
62
private DataValueService dataValueService;
64
public void setDataValueService( DataValueService dataValueService )
66
this.dataValueService = dataValueService;
69
// -------------------------------------------------------------------------
70
// HistoryRetriever implementation
71
// -------------------------------------------------------------------------
73
public DataElementHistory getHistory( DataElement dataElement, DataElementCategoryOptionCombo optionCombo, OrganisationUnit organisationUnit,
74
Period lastPeriod, int historyLength )
75
throws HistoryRetrieverException
77
if ( !dataElement.getType().equals( DataElement.TYPE_INT ) )
81
/*throw new HistoryRetrieverException( "DataElement is not of type " + DataElement.TYPE_INT + ": "
82
+ dataElement.getShortName() ) ; */
85
// ---------------------------------------------------------------------
87
// ---------------------------------------------------------------------
89
DataElementHistory history = new DataElementHistory();
90
history.setDataElement( dataElement );
91
history.setOptionCombo( optionCombo );
92
history.setOrganisationUnit( organisationUnit );
93
history.setHistoryLength( historyLength );
94
addMinMaxLimits( organisationUnit, dataElement, history );
96
// ---------------------------------------------------------------------
97
// Create history points
98
// ---------------------------------------------------------------------
100
List<Period> periods = getPeriods( lastPeriod, historyLength );
107
if ( history.getMaxLimit() != null )
109
max = Math.max( max, history.getMaxLimit() );
112
for ( Period period : periods )
114
DataElementHistoryPoint historyPoint = new DataElementHistoryPoint();
115
historyPoint.setPeriod( period );
117
Double value = getValue( dataElement, optionCombo, organisationUnit, period );
121
historyPoint.setValue( value );
124
if ( historyPoint.getValue() != null )
126
max = Math.max( max, historyPoint.getValue() );
127
total += historyPoint.getValue();
128
average = total / ++count;
131
historyPoint.setAverage( average );
133
history.getHistoryPoints().add( historyPoint );
136
history.setMaxHistoryValue( max );
139
double maxValue = getMaxValue( history );
141
// if there was any entred values, set minValue and maxValue
142
if ( maxValue != Double.NEGATIVE_INFINITY )
144
history.setMaxValue( maxValue );
146
double minValue = getMinValue( history );
147
history.setMinValue( minValue );
153
public DataElementHistory getHistory( DataElement dataElement, OrganisationUnit organisationUnit,
154
Period lastPeriod, int historyLength )
155
throws HistoryRetrieverException
157
if ( !dataElement.getType().equals( DataElement.TYPE_INT ) )
159
throw new HistoryRetrieverException( "DataElement is not of type " + DataElement.TYPE_INT + ": "
160
+ dataElement.getShortName() );
163
// ---------------------------------------------------------------------
164
// Initialise history
165
// ---------------------------------------------------------------------
167
DataElementHistory history = new DataElementHistory();
168
history.setDataElement( dataElement );
169
history.setOrganisationUnit( organisationUnit );
170
history.setHistoryLength( historyLength );
171
addMinMaxLimits( organisationUnit, dataElement, history );
173
// ---------------------------------------------------------------------
174
// Create history points
175
// ---------------------------------------------------------------------
177
List<Period> periods = getPeriods( lastPeriod, historyLength );
184
if ( history.getMaxLimit() != null )
186
max = Math.max( max, history.getMaxLimit() );
189
for ( Period period : periods )
191
DataElementHistoryPoint historyPoint = new DataElementHistoryPoint();
192
historyPoint.setPeriod( period );
194
Double value = getValue( dataElement, organisationUnit, period );
198
historyPoint.setValue( value );
201
if ( historyPoint.getValue() != null )
203
max = Math.max( max, historyPoint.getValue() );
204
total += historyPoint.getValue();
205
average = total / ++count;
208
historyPoint.setAverage( average );
210
history.getHistoryPoints().add( historyPoint );
213
history.setMaxHistoryValue( max );
216
double maxValue = getMaxValue( history );
218
// if there was any entred values, set minValue and maxValue
219
if ( maxValue != Double.NEGATIVE_INFINITY )
221
history.setMaxValue( maxValue );
223
double minValue = getMinValue( history );
224
history.setMinValue( minValue );
231
private void addMinMaxLimits( OrganisationUnit organisationUnit, DataElement dataElement, DataElementHistory history )
233
MinMaxDataElement minMaxDataElement = minMaxDataElementStore.getMinMaxDataElement( organisationUnit,
236
if ( minMaxDataElement != null )
238
history.setMaxLimit( minMaxDataElement.getMax() );
239
history.setMinLimit( minMaxDataElement.getMin() );
244
* Finds the lowest value entered in the periode given by
245
* history.historyLenght.
247
* @param history DataElementHistory
248
* @return the lowest Double value entred. If no values are entred,
249
* Double.MAX_VALUE is returned
251
private Double getMinValue( DataElementHistory history )
253
double value = Double.MAX_VALUE;
254
List<DataElementHistoryPoint> historyPoints = history.getHistoryPoints();
256
for ( DataElementHistoryPoint DEPoint : historyPoints )
258
if ( DEPoint.getValue() != null )
260
if ( DEPoint.getValue() < value )
262
value = DEPoint.getValue();
271
* Finds the highest value entered in the periode given by
272
* history.historyLenght.
274
* @param history DataElementHistory
275
* @return the highest entred value. If no value is entred
276
* Double.NEGATIVE_INFINITY is returned
278
private Double getMaxValue( DataElementHistory history )
280
double value = Double.NEGATIVE_INFINITY;
281
List<DataElementHistoryPoint> historyPoints = history.getHistoryPoints();
283
for ( DataElementHistoryPoint DEPoint : historyPoints )
285
if ( DEPoint.getValue() != null )
287
if ( DEPoint.getValue() > value )
289
value = DEPoint.getValue();
297
private List<Period> getPeriods( Period lastPeriod, int historyLength )
299
List<Period> periods = new ArrayList<Period>( historyLength );
301
CalendarPeriodType periodType = (CalendarPeriodType) lastPeriod.getPeriodType();
303
Period period = lastPeriod;
305
for ( int i = 0; i < historyLength; ++i )
307
periods.add( period );
308
period = periodType.getPreviousPeriod( period );
311
Collections.reverse( periods );
316
private Double getValue( DataElement dataElement, DataElementCategoryOptionCombo optionCombo, OrganisationUnit organisationUnit, Period period )
317
throws HistoryRetrieverException
319
DataValue dataValue = dataValueService.getDataValue( organisationUnit, dataElement, period, optionCombo );
321
if ( dataValue != null )
323
if ( dataValue.getValue() != null )
325
return parseValue( dataValue.getValue() );
333
private Double getValue( DataElement dataElement, OrganisationUnit organisationUnit, Period period )
334
throws HistoryRetrieverException
336
DataValue dataValue = dataValueService.getDataValue( organisationUnit, dataElement, period );
338
if ( dataValue != null )
340
if ( dataValue.getValue() != null )
342
return parseValue( dataValue.getValue() );
351
private Double parseValue( String value )
352
throws HistoryRetrieverException
356
return Double.parseDouble( value );
358
catch ( NumberFormatException e )
360
throw new HistoryRetrieverException( "Failed to parse double: " + value, e );