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

openmrs / openmrs-core / 24035792291

06 Apr 2026 02:28PM UTC coverage: 63.244% (+0.07%) from 63.176%
24035792291

push

github

ibacher
LUI-199: Editing the Address Template does not save the address template correctly (#5839)

13 of 23 new or added lines in 2 files covered. (56.52%)

44 existing lines in 4 files now uncovered.

23203 of 36688 relevant lines covered (63.24%)

0.63 hits per line

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

79.75
/api/src/main/java/org/openmrs/layout/address/AddressSupport.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.layout.address;
11

12
import java.util.ArrayList;
13
import java.util.List;
14

15
import org.apache.commons.lang.StringEscapeUtils;
16
import org.apache.commons.lang3.StringUtils;
17
import org.openmrs.GlobalProperty;
18
import org.openmrs.api.GlobalPropertyListener;
19
import org.openmrs.api.context.Context;
20
import org.openmrs.layout.LayoutSupport;
21
import org.openmrs.serialization.SerializationException;
22
import org.openmrs.util.OpenmrsConstants;
23
import org.slf4j.Logger;
24
import org.slf4j.LoggerFactory;
25

26
/**
27
 * @since 1.12
28
 */
29
public class AddressSupport extends LayoutSupport<AddressTemplate> implements GlobalPropertyListener {
30

31
        private static AddressSupport singleton;
32

33
        private boolean initialized = false;
1✔
34

35
        private static final Logger log = LoggerFactory.getLogger(AddressSupport.class);
1✔
36

37
        private AddressSupport() {
1✔
38
                if (singleton == null) {
1✔
39
                        singleton = this;
1✔
40
                }
41
                log.debug("Setting singleton: " + singleton);
1✔
42
        }
1✔
43

44
        public static AddressSupport getInstance() {
45
                synchronized (AddressSupport.class) {
1✔
46
                        if (singleton == null) {
1✔
47
                                singleton = new AddressSupport();
1✔
48
                        }
49
                }
1✔
50
                singleton.init();
1✔
51
                return singleton;
1✔
52

53
        }
54

55
        private void init() {
56
                if (!initialized) {
1✔
57
                        Context.getAdministrationService().addGlobalPropertyListener(singleton);
1✔
58

59
                        String layoutTemplateXml = Context.getAdministrationService().getGlobalProperty(
1✔
60
                            OpenmrsConstants.GLOBAL_PROPERTY_ADDRESS_TEMPLATE);
61
                        setAddressTemplate(layoutTemplateXml);
1✔
62

63
                        List<String> specialTokens = new ArrayList<>();
1✔
64
                        specialTokens.add("address1");
1✔
65
                        specialTokens.add("address2");
1✔
66
                        specialTokens.add("address3");
1✔
67
                        specialTokens.add("address4");
1✔
68
                        specialTokens.add("address5");
1✔
69
                        specialTokens.add("address6");
1✔
70
                        specialTokens.add("cityVillage");
1✔
71
                        specialTokens.add("countyDistrict");
1✔
72
                        specialTokens.add("stateProvince");
1✔
73
                        specialTokens.add("country");
1✔
74
                        specialTokens.add("latitude");
1✔
75
                        specialTokens.add("longitude");
1✔
76
                        specialTokens.add("postalCode");
1✔
77
                        specialTokens.add("startDate");
1✔
78
                        specialTokens.add("endDate");
1✔
79

80
                        setSpecialTokens(specialTokens);
1✔
81
                        initialized = true;
1✔
82
                }
83
        }
1✔
84

85
        /**
86
         * @return Returns the defaultLayoutFormat
87
         */
88
        @Override
89
        public String getDefaultLayoutFormat() {
90
                return defaultLayoutFormat;
×
91
        }
92

93
        /**
94
         * @param addressTemplates The addressTemplates to set.
95
         */
96
        public void setAddressTemplate(List<AddressTemplate> addressTemplates) {
97
                this.layoutTemplates = addressTemplates;
1✔
98
                setDefaultLayoutFormat(layoutTemplates.get(0).getCodeName());
1✔
99

100
        }
1✔
101

102
        /**
103
         * @return Returns the addressTemplates.
104
         */
105

106
        public List<AddressTemplate> getAddressTemplate() {
107
                if (layoutTemplates == null) {
1✔
108
                        try {
109
                                String xml = Context.getAdministrationService().getGlobalProperty(
×
110
                                    OpenmrsConstants.GLOBAL_PROPERTY_ADDRESS_TEMPLATE);
111
                                setAddressTemplate(xml);
×
112
                        }
113
                        catch (Exception ex) {
×
114
                                //The old AddressTemplate prevails
115
                        }
×
116
                }
117
                return layoutTemplates;
1✔
118
        }
119

120
        /**
121
         * @see org.openmrs.api.GlobalPropertyListener#supportsPropertyName(String)
122
         */
123
        @Override
124
        public boolean supportsPropertyName(String propertyName) {
125
                return OpenmrsConstants.GLOBAL_PROPERTY_ADDRESS_TEMPLATE.equals(propertyName);
1✔
126
        }
127

128
        /**
129
         * @see org.openmrs.api.GlobalPropertyListener#globalPropertyChanged(org.openmrs.GlobalProperty)
130
         */
131
        @Override
132
        public void globalPropertyChanged(GlobalProperty newValue) {
133
                if (!OpenmrsConstants.GLOBAL_PROPERTY_ADDRESS_TEMPLATE.equals(newValue.getProperty())) {
1✔
134
                        return;
×
135
                }
136
                try {
137
                        setAddressTemplate(newValue.getPropertyValue());
1✔
138
                }
139
                catch (Exception ex) {
×
140
                        log.error("Error in new xml global property value", ex);
×
141
                        setAddressTemplate(new ArrayList<>());
×
142
                }
1✔
143
        }
1✔
144

145
        private void setAddressTemplate(String xml) {
146
                AddressTemplate addressTemplate;
147
                try {
148
                        addressTemplate = deserializeAddressTemplate(xml);
1✔
149
                }
150
                catch (SerializationException e) {
1✔
151
                        log.error("Error in deserializing address template", e);
1✔
152
                        addressTemplate = new AddressTemplate("Error while deserializing address layout template.");
1✔
153
                }
1✔
154

155
                List<AddressTemplate> list = new ArrayList<>();
1✔
156
                list.add(addressTemplate);
1✔
157
                setAddressTemplate(list);
1✔
158
        }
1✔
159

160
        /**
161
         * Supports both raw XML and XML-escaped text as persisted by different GP edit flows.
162
         */
163
        private AddressTemplate deserializeAddressTemplate(String xml) throws SerializationException {
164
                if (StringUtils.isBlank(xml)) {
1✔
165
                        throw new SerializationException("Address template xml is blank");
1✔
166
                }
167

168
                try {
169
                        return Context.getSerializationService().getDefaultSerializer().deserialize(xml, AddressTemplate.class);
1✔
170
                }
171
                catch (SerializationException firstException) {
1✔
172
                        String unescaped = StringEscapeUtils.unescapeXml(xml);
1✔
173
                        if (xml.equals(unescaped)) {
1✔
174
                                throw firstException;
1✔
175
                        }
176

177
                        try {
178
                                return Context.getSerializationService().getDefaultSerializer().deserialize(unescaped,
1✔
179
                                    AddressTemplate.class);
180
                        }
NEW
181
                        catch (SerializationException secondException) {
×
NEW
182
                                secondException.addSuppressed(firstException);
×
NEW
183
                                throw secondException;
×
184
                        }
185
                }
186
        }
187

188
        /**
189
         * @see org.openmrs.api.GlobalPropertyListener#globalPropertyDeleted(String)
190
         */
191
        @Override
192
        public void globalPropertyDeleted(String propertyName) {
193
                if (!OpenmrsConstants.GLOBAL_PROPERTY_ADDRESS_TEMPLATE.equals(propertyName)) {
×
194
                        return;
×
195
                }
196
                setAddressTemplate(new ArrayList<>());
×
197
        }
×
198

199
}
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