~mortenoh/+junk/dhis2-detailed-import-export

« back to all changes in this revision

Viewing changes to dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/history/DefaultHistoryRetriever.java

  • Committer: larshelge at gmail
  • Date: 2009-03-03 16:46:36 UTC
  • Revision ID: larshelge@gmail.com-20090303164636-2sjlrquo7ib1gf7r
Initial check-in

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package org.hisp.dhis.de.history;
 
2
 
 
3
/*
 
4
 * Copyright (c) 2004-2007, University of Oslo
 
5
 * All rights reserved.
 
6
 *
 
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.
 
17
 *
 
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.
 
28
 */
 
29
 
 
30
import java.util.ArrayList;
 
31
import java.util.Collections;
 
32
import java.util.List;
 
33
 
 
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;
 
43
 
 
44
/**
 
45
 * @author Torgeir Lorange Ostby
 
46
 * @version $Id: DefaultHistoryRetriever.java 5131 2008-05-11 21:06:23Z larshelg $
 
47
 */
 
48
public class DefaultHistoryRetriever
 
49
    implements HistoryRetriever
 
50
{
 
51
    // -------------------------------------------------------------------------
 
52
    // Dependencies
 
53
    // -------------------------------------------------------------------------
 
54
 
 
55
    private MinMaxDataElementStore minMaxDataElementStore;
 
56
 
 
57
    public void setMinMaxDataElementStore( MinMaxDataElementStore minMaxDataElementStore )
 
58
    {
 
59
        this.minMaxDataElementStore = minMaxDataElementStore;
 
60
    }
 
61
 
 
62
    private DataValueService dataValueService;
 
63
 
 
64
    public void setDataValueService( DataValueService dataValueService )
 
65
    {
 
66
        this.dataValueService = dataValueService;
 
67
    }
 
68
 
 
69
    // -------------------------------------------------------------------------
 
70
    // HistoryRetriever implementation
 
71
    // -------------------------------------------------------------------------
 
72
 
 
73
    public DataElementHistory getHistory( DataElement dataElement, DataElementCategoryOptionCombo optionCombo, OrganisationUnit organisationUnit,
 
74
        Period lastPeriod, int historyLength )
 
75
        throws HistoryRetrieverException
 
76
    {
 
77
        if ( !dataElement.getType().equals( DataElement.TYPE_INT ) )
 
78
        {       
 
79
            return null;
 
80
                
 
81
            /*throw new HistoryRetrieverException( "DataElement is not of type " + DataElement.TYPE_INT + ": "
 
82
                + dataElement.getShortName() ) ; */
 
83
        }
 
84
 
 
85
        // ---------------------------------------------------------------------
 
86
        // Initialise history
 
87
        // ---------------------------------------------------------------------
 
88
 
 
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 );
 
95
 
 
96
        // ---------------------------------------------------------------------
 
97
        // Create history points
 
98
        // ---------------------------------------------------------------------
 
99
 
 
100
        List<Period> periods = getPeriods( lastPeriod, historyLength );
 
101
 
 
102
        double max = 1;
 
103
        double average = 0;
 
104
        double total = 0;
 
105
        int count = 0;
 
106
 
 
107
        if ( history.getMaxLimit() != null )
 
108
        {
 
109
            max = Math.max( max, history.getMaxLimit() );
 
110
        }
 
111
 
 
112
        for ( Period period : periods )
 
113
        {
 
114
            DataElementHistoryPoint historyPoint = new DataElementHistoryPoint();
 
115
            historyPoint.setPeriod( period );
 
116
 
 
117
            Double value = getValue( dataElement, optionCombo, organisationUnit, period );
 
118
 
 
119
            if ( value != null )
 
120
            {
 
121
                historyPoint.setValue( value );
 
122
            }
 
123
 
 
124
            if ( historyPoint.getValue() != null )
 
125
            {
 
126
                max = Math.max( max, historyPoint.getValue() );
 
127
                total += historyPoint.getValue();
 
128
                average = total / ++count;
 
129
            }
 
130
 
 
131
            historyPoint.setAverage( average );
 
132
 
 
133
            history.getHistoryPoints().add( historyPoint );
 
134
        }
 
135
 
 
136
        history.setMaxHistoryValue( max );
 
137
 
 
138
        // get the maxValue
 
139
        double maxValue = getMaxValue( history );
 
140
 
 
141
        // if there was any entred values, set minValue and maxValue
 
142
        if ( maxValue != Double.NEGATIVE_INFINITY )
 
143
        {
 
144
            history.setMaxValue( maxValue );
 
145
 
 
146
            double minValue = getMinValue( history );
 
147
            history.setMinValue( minValue );
 
148
        }
 
149
 
 
150
        return history;
 
151
    }
 
152
    
 
153
    public DataElementHistory getHistory( DataElement dataElement, OrganisationUnit organisationUnit,
 
154
            Period lastPeriod, int historyLength )
 
155
        throws HistoryRetrieverException
 
156
        {
 
157
            if ( !dataElement.getType().equals( DataElement.TYPE_INT ) )
 
158
            {
 
159
                throw new HistoryRetrieverException( "DataElement is not of type " + DataElement.TYPE_INT + ": "
 
160
                    + dataElement.getShortName() );
 
161
            }
 
162
 
 
163
            // ---------------------------------------------------------------------
 
164
            // Initialise history
 
165
            // ---------------------------------------------------------------------
 
166
 
 
167
            DataElementHistory history = new DataElementHistory();
 
168
            history.setDataElement( dataElement );            
 
169
            history.setOrganisationUnit( organisationUnit );
 
170
            history.setHistoryLength( historyLength );
 
171
            addMinMaxLimits( organisationUnit, dataElement, history );
 
172
 
 
173
            // ---------------------------------------------------------------------
 
174
            // Create history points
 
175
            // ---------------------------------------------------------------------
 
176
 
 
177
            List<Period> periods = getPeriods( lastPeriod, historyLength );
 
178
 
 
179
            double max = 1;
 
180
            double average = 0;
 
181
            double total = 0;
 
182
            int count = 0;
 
183
 
 
184
            if ( history.getMaxLimit() != null )
 
185
            {
 
186
                max = Math.max( max, history.getMaxLimit() );
 
187
            }
 
188
 
 
189
            for ( Period period : periods )
 
190
            {
 
191
                DataElementHistoryPoint historyPoint = new DataElementHistoryPoint();
 
192
                historyPoint.setPeriod( period );
 
193
 
 
194
                Double value = getValue( dataElement, organisationUnit, period );
 
195
 
 
196
                if ( value != null )
 
197
                {
 
198
                    historyPoint.setValue( value );
 
199
                }
 
200
 
 
201
                if ( historyPoint.getValue() != null )
 
202
                {
 
203
                    max = Math.max( max, historyPoint.getValue() );
 
204
                    total += historyPoint.getValue();
 
205
                    average = total / ++count;
 
206
                }
 
207
 
 
208
                historyPoint.setAverage( average );
 
209
 
 
210
                history.getHistoryPoints().add( historyPoint );
 
211
            }
 
212
 
 
213
            history.setMaxHistoryValue( max );
 
214
 
 
215
            // get the maxValue
 
216
            double maxValue = getMaxValue( history );
 
217
 
 
218
            // if there was any entred values, set minValue and maxValue
 
219
            if ( maxValue != Double.NEGATIVE_INFINITY )
 
220
            {
 
221
                history.setMaxValue( maxValue );
 
222
 
 
223
                double minValue = getMinValue( history );
 
224
                history.setMinValue( minValue );
 
225
           }
 
226
 
 
227
            return history;
 
228
        }
 
229
 
 
230
 
 
231
    private void addMinMaxLimits( OrganisationUnit organisationUnit, DataElement dataElement, DataElementHistory history )
 
232
    {
 
233
        MinMaxDataElement minMaxDataElement = minMaxDataElementStore.getMinMaxDataElement( organisationUnit,
 
234
            dataElement );
 
235
 
 
236
        if ( minMaxDataElement != null )
 
237
        {
 
238
            history.setMaxLimit( minMaxDataElement.getMax() );
 
239
            history.setMinLimit( minMaxDataElement.getMin() );
 
240
        }
 
241
    }
 
242
 
 
243
    /**
 
244
     * Finds the lowest value entered in the periode given by
 
245
     * history.historyLenght.
 
246
     * 
 
247
     * @param history DataElementHistory
 
248
     * @return the lowest Double value entred. If no values are entred,
 
249
     *         Double.MAX_VALUE is returned
 
250
     */
 
251
    private Double getMinValue( DataElementHistory history )
 
252
    {
 
253
        double value = Double.MAX_VALUE;
 
254
        List<DataElementHistoryPoint> historyPoints = history.getHistoryPoints();
 
255
 
 
256
        for ( DataElementHistoryPoint DEPoint : historyPoints )
 
257
        {
 
258
            if ( DEPoint.getValue() != null )
 
259
            {
 
260
                if ( DEPoint.getValue() < value )
 
261
                {
 
262
                    value = DEPoint.getValue();
 
263
                }
 
264
            }
 
265
        }
 
266
 
 
267
        return value;
 
268
    }
 
269
 
 
270
    /**
 
271
     * Finds the highest value entered in the periode given by
 
272
     * history.historyLenght.
 
273
     * 
 
274
     * @param history DataElementHistory
 
275
     * @return the highest entred value. If no value is entred
 
276
     *         Double.NEGATIVE_INFINITY is returned
 
277
     */
 
278
    private Double getMaxValue( DataElementHistory history )
 
279
    {
 
280
        double value = Double.NEGATIVE_INFINITY;
 
281
        List<DataElementHistoryPoint> historyPoints = history.getHistoryPoints();
 
282
 
 
283
        for ( DataElementHistoryPoint DEPoint : historyPoints )
 
284
        {
 
285
            if ( DEPoint.getValue() != null )
 
286
            {
 
287
                if ( DEPoint.getValue() > value )
 
288
                {
 
289
                    value = DEPoint.getValue();
 
290
                }
 
291
            }
 
292
        }
 
293
 
 
294
        return value;
 
295
    }
 
296
 
 
297
    private List<Period> getPeriods( Period lastPeriod, int historyLength )
 
298
    {
 
299
        List<Period> periods = new ArrayList<Period>( historyLength );
 
300
 
 
301
        CalendarPeriodType periodType = (CalendarPeriodType) lastPeriod.getPeriodType();
 
302
 
 
303
        Period period = lastPeriod;
 
304
 
 
305
        for ( int i = 0; i < historyLength; ++i )
 
306
        {
 
307
            periods.add( period );
 
308
            period = periodType.getPreviousPeriod( period );
 
309
        }
 
310
 
 
311
        Collections.reverse( periods );
 
312
 
 
313
        return periods;
 
314
    }
 
315
 
 
316
    private Double getValue( DataElement dataElement, DataElementCategoryOptionCombo optionCombo, OrganisationUnit organisationUnit, Period period )
 
317
        throws HistoryRetrieverException
 
318
    {
 
319
        DataValue dataValue = dataValueService.getDataValue( organisationUnit, dataElement, period, optionCombo );
 
320
 
 
321
        if ( dataValue != null )
 
322
        {
 
323
            if ( dataValue.getValue() != null )
 
324
            {
 
325
                return parseValue( dataValue.getValue() );
 
326
 
 
327
            }
 
328
        }
 
329
 
 
330
        return null;
 
331
    }
 
332
    
 
333
    private Double getValue( DataElement dataElement, OrganisationUnit organisationUnit, Period period )
 
334
    throws HistoryRetrieverException
 
335
    {
 
336
        DataValue dataValue = dataValueService.getDataValue( organisationUnit, dataElement, period );
 
337
 
 
338
        if ( dataValue != null )
 
339
        {
 
340
                if ( dataValue.getValue() != null )
 
341
                {
 
342
                        return parseValue( dataValue.getValue() );
 
343
 
 
344
                }
 
345
        }
 
346
 
 
347
        return null;
 
348
    }
 
349
 
 
350
 
 
351
    private Double parseValue( String value )
 
352
        throws HistoryRetrieverException
 
353
    {
 
354
        try
 
355
        {
 
356
            return Double.parseDouble( value );
 
357
        }
 
358
        catch ( NumberFormatException e )
 
359
        {
 
360
            throw new HistoryRetrieverException( "Failed to parse double: " + value, e );
 
361
        }
 
362
    }
 
363
}