• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

openmrs / openmrs-core / 15005692593

13 May 2025 08:05PM UTC coverage: 64.869% (-0.09%) from 64.958%
15005692593

push

github

dkayiwa
TRUNK-6245 initialize the velocity engine

(cherry picked from commit 1e56a70e1)

6 of 8 new or added lines in 1 file covered. (75.0%)

39 existing lines in 5 files now uncovered.

23317 of 35945 relevant lines covered (64.87%)

0.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.05
/api/src/main/java/org/openmrs/util/ConceptReferenceRangeUtility.java
1
/**
2
 * This Source Code Form is subject to the terms of the Mozilla Public License,
3
 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
4
 * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
5
 * the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
6
 *
7
 * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
8
 * graphic logo is a trademark of OpenMRS Inc.
9
 */
10
package org.openmrs.util;
11

12
import org.apache.commons.lang.StringUtils;
13
import org.apache.velocity.VelocityContext;
14
import org.apache.velocity.app.VelocityEngine;
15
import org.apache.velocity.exception.ParseErrorException;
16
import org.apache.velocity.runtime.log.Log4JLogChute;
17
import org.joda.time.LocalTime;
18
import org.openmrs.Concept;
19
import org.openmrs.Obs;
20
import org.openmrs.Person;
21
import org.openmrs.api.APIException;
22
import org.openmrs.api.context.Context;
23

24
import java.util.Properties;
25
import java.io.StringWriter;
26
import java.util.Collections;
27
import java.util.List;
28
import java.util.Locale;
29

30
/**
31
 * A utility class that evaluates the concept ranges 
32
 * 
33
 * @since 2.7.0
34
 */
35
public class ConceptReferenceRangeUtility {
36
        
37
        public ConceptReferenceRangeUtility() {
1✔
38
        }
1✔
39
        
40
        /**
41
         * This method evaluates the given criteria against the provided {@link Obs}.
42
         *
43
         * @param criteria the criteria string to evaluate e.g. "$patient.getAge() > 1"
44
         * @param obs The observation (Obs) object containing the values to be used in the criteria evaluation.
45
         *                  
46
         * @return true if the criteria evaluates to true, false otherwise
47
         */
48
        public boolean evaluateCriteria(String criteria, Obs obs) {
49
                if (obs == null) {
1✔
50
                        throw new IllegalArgumentException("Failed to evaluate criteria with reason: Obs is null");
1✔
51
                }
52
                
53
                if (obs.getPerson() == null) {
1✔
54
                        throw new IllegalArgumentException("Failed to evaluate criteria with reason: patient is null");
×
55
                }
56
                
57
                if (StringUtils.isBlank(criteria)) {
1✔
58
                        throw new IllegalArgumentException("Failed to evaluate criteria with reason: criteria is empty");
1✔
59
                }
60
                
61
                VelocityContext velocityContext = new VelocityContext();
1✔
62
                velocityContext.put("fn", this);
1✔
63
                velocityContext.put("obs", obs);
1✔
64
                
65
                velocityContext.put("patient", obs.getPerson());
1✔
66
                
67
                VelocityEngine velocityEngine = new VelocityEngine();
1✔
68
                try {
69
                        Properties props = new Properties();
1✔
70
                        props.put("runtime.log.logsystem.class", Log4JLogChute.class.getName());
1✔
71
                        props.put("runtime.log.logsystem.log4j.category", "velocity");
1✔
72
                        props.put("runtime.log.logsystem.log4j.logger", "velocity");
1✔
73
                        velocityEngine.init(props);
1✔
74
                }
NEW
75
                catch (Exception e) {
×
NEW
76
                        throw new APIException("Failed to create the velocity engine: " + e.getMessage(), e);
×
77
                }
1✔
78
                
79
                StringWriter writer = new StringWriter();
1✔
80
                String wrappedCriteria = "#set( $criteria = " + criteria + " )$criteria";
1✔
81
                
82
                try {
83
                        velocityEngine.evaluate(velocityContext, writer, ConceptReferenceRangeUtility.class.getName(), wrappedCriteria);
1✔
84
                        return Boolean.parseBoolean(writer.toString());
1✔
85
                }
86
                catch (ParseErrorException e) {
1✔
87
                        throw new APIException("An error occurred while evaluating criteria. Invalid criteria: " + criteria, e);
1✔
88
                }
89
                catch (Exception e) {
×
90
                        throw new APIException("An error occurred while evaluating criteria: ", e);
×
91
                }
92
        }
93
        
94
        /**
95
         * Gets the latest Obs by concept.
96
         *
97
         * @param conceptRef can be either concept uuid or conceptMap's code and sourceName 
98
         *                   e.g "bac25fd5-c143-4e43-bffe-4eb1e7efb6ce" or "CIEL:1434"
99
         * @param person person to get obs for
100
         *                   
101
         * @return Obs latest Obs
102
         */
103
        public Obs getLatestObs(String conceptRef, Person person) {
104
                Concept concept = Context.getConceptService().getConceptByReference(conceptRef);
1✔
105

106
                if (concept != null) {
1✔
107
                        List<Obs> observations = Context.getObsService().getObservations(
1✔
108
                                Collections.singletonList(person), 
1✔
109
                                null, 
110
                                Collections.singletonList(concept), 
1✔
111
                                null, 
112
                                null, 
113
                                null,
114
                                Collections.singletonList("dateCreated"), 
1✔
115
                                1, 
1✔
116
                                null,
117
                                null, 
118
                                null, 
119
                                false
120
                        );
121

122
                        return observations.isEmpty() ? null : observations.get(0);
1✔
123
                }
124

125
                return null;
1✔
126
        }
127
        
128
        /**
129
         * Gets the time of the day in hours.
130
         *
131
         * @return the hour of the day in 24hr format (e.g. 14 to mean 2pm)
132
         */
133
        public int getCurrentHour() {
134
                return LocalTime.now().getHourOfDay();
1✔
135
        }
136
        
137
        /**
138
         * Retrieves the most relevant Obs for the given current Obs and conceptRef. If the current Obs contains a valid value 
139
         * (coded, numeric, date, text e.t.c) and the concept in Obs is the same as the supplied concept,
140
         * the method returns the current Obs. Otherwise, it fetches the latest Obs for the supplied concept and patient.
141
         *
142
         * @param currentObs the current Obs being evaluated
143
         * @return the most relevant Obs based on the current Obs, or the latest Obs if the current one has no valid value
144
         */
145
        public Obs getCurrentObs(String conceptRef, Obs currentObs) {
146
                Concept concept = Context.getConceptService().getConceptByReference(conceptRef);
1✔
147
                
148
                if (currentObs.getValueAsString(Locale.ENGLISH).isEmpty() && (concept != null && concept == currentObs.getConcept())) {
1✔
149
                        return currentObs;
×
150
                } else {
151
                        return getLatestObs(conceptRef, currentObs.getPerson());
1✔
152
                }
153
        }
154
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc