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

openmrs / openmrs-core / 13853363634

14 Mar 2025 09:10AM UTC coverage: 65.081% (+0.1%) from 64.959%
13853363634

push

github

web-flow
TRUNK-6304 Refactor code to use Storage Service (#4944)

* TRUNK-6300 Add Storage Service

* TRUNK-6304 Refactor code to use Storage Service

319 of 401 new or added lines in 13 files covered. (79.55%)

17 existing lines in 4 files now uncovered.

23407 of 35966 relevant lines covered (65.08%)

0.65 hits per line

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

82.86
/api/src/main/java/org/openmrs/obs/handler/BinaryStreamHandler.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.obs.handler;
11

12
import java.io.InputStream;
13

14
import org.apache.commons.io.IOUtils;
15
import org.apache.commons.lang3.StringUtils;
16
import org.openmrs.Obs;
17
import org.openmrs.api.APIException;
18
import org.openmrs.api.storage.ObjectMetadata;
19
import org.openmrs.obs.ComplexData;
20
import org.openmrs.obs.ComplexObsHandler;
21
import org.openmrs.util.OpenmrsConstants;
22
import org.slf4j.Logger;
23
import org.slf4j.LoggerFactory;
24
import org.springframework.stereotype.Component;
25
import org.springframework.util.Assert;
26

27
/**
28
 * Handler for storing generic binary data for complex obs to the file system.
29
 * 
30
 * @see OpenmrsConstants#GLOBAL_PROPERTY_COMPLEX_OBS_DIR
31
 * @since 1.8
32
 */
33
@Component
34
public class BinaryStreamHandler extends AbstractHandler implements ComplexObsHandler {
35
        
36
        /** Views supported by this handler */
37
        private static final String[] supportedViews = { ComplexObsHandler.RAW_VIEW, };
1✔
38
        
39
        private static final Logger log = LoggerFactory.getLogger(BinaryStreamHandler.class);
1✔
40
        
41
        /**
42
         * Constructor initializes formats for alternative file names to protect from unintentionally
43
         * overwriting existing files.
44
         */
45
        public BinaryStreamHandler() {
46
                super();
1✔
47
        }
1✔
48
        
49
        /**
50
         * Returns the same ComplexData for all views. The title is the original filename, and the data
51
         * is the raw byte[] of data (If the view is set to "download", all commas and whitespace are
52
         * stripped out of the filename to fix an issue where the browser wasn't handling a filename
53
         * with whitespace properly) Note that if the method cannot find the file associated with the
54
         * obs, it returns the obs with the ComplexData = null
55
         * 
56
         * @see ComplexObsHandler#getObs(Obs, String)
57
         */
58
        @Override
59
        public Obs getObs(Obs obs, String view) {
60
                String key = parseDataKey(obs);
1✔
61
                        
62
                ComplexData complexData = null;
1✔
63
                // Raw stream
64
                if (ComplexObsHandler.RAW_VIEW.equals(view)) {
1✔
65
                        try {
66
                                String[] names = obs.getValueComplex().split("\\|");
1✔
67
                                String originalFilename = names[0];
1✔
68
                                originalFilename = originalFilename.replace(",", "").replace(" ", "");
1✔
69
                                        
70
                                if (storageService.exists(key)) {
1✔
71
                                        InputStream in = storageService.getData(key);
1✔
72
                                        complexData = new ComplexData(originalFilename, in);
1✔
73
                                } else {
1✔
NEW
74
                                        log.error("Unable to find file associated with complex obs {}", obs.getId());
×
75
                                }
76
                        }
77
                        catch (Exception e) {
×
78
                                throw new APIException("Obs.error.while.trying.get.binary.complex", null, e);
×
79
                        }
1✔
80
                } else {
81
                        // No other view supported
82
                        // NOTE: if adding support for another view, don't forget to update supportedViews list above
83
                        return null;
×
84
                }
85
                
86
                Assert.notNull(complexData, "Complex data must not be null");
1✔
87

88
                injectMissingMetadata(key, complexData);
1✔
89
                obs.setComplexData(complexData);
1✔
90
                
91
                return obs;
1✔
92
        }
93

94
        /**
95
         * @see org.openmrs.obs.ComplexObsHandler#getSupportedViews()
96
         */
97
        @Override
98
        public String[] getSupportedViews() {
99
                return supportedViews;
1✔
100
        }
101
        
102
        /**
103
         * @see ComplexObsHandler#saveObs(Obs)
104
         */
105
        @Override
106
        public Obs saveObs(Obs obs) throws APIException {
107
                try {
108
                        String key = storageService.saveData(outputStream -> {
1✔
109
                                InputStream in = (InputStream) obs.getComplexData().getData();
1✔
110
                                IOUtils.copy(in, outputStream);
1✔
111
                                outputStream.flush();
1✔
112
                        }, ObjectMetadata.builder().setFilename(obs.getComplexData().getTitle()).build(), getObsDir());
1✔
113
                        // Store the filename in the Obs
114
                        obs.setValueComplex(StringUtils.defaultIfBlank(obs.getComplexData().getTitle(), key) + "|" + key);
1✔
115
                        obs.setComplexData(null);
1✔
116
                }
UNCOV
117
                catch (Exception e) {
×
118
                        throw new APIException("Obs.error.writing.binary.data.complex", null, e);
×
119
                }
1✔
120
                
121
                return obs;
1✔
122
        }
123
        
124
}
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