• 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

80.85
/api/src/main/java/org/openmrs/obs/handler/BinaryDataHandler.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.IOException;
13
import java.io.InputStream;
14
import java.io.UncheckedIOException;
15

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

28
/**
29
 * Handler for storing files for complex obs to the file system. Files are stored in the location
30
 * specified by the global property: "obs.complex_obs_dir"
31
 * 
32
 * @since 1.5
33
 */
34
@Component
35
public class BinaryDataHandler extends AbstractHandler implements ComplexObsHandler {
36
        
37
        /** Views supported by this handler */
38
        private static final String[] supportedViews = { ComplexObsHandler.RAW_VIEW, };
1✔
39
        
40
        private static final Logger log = LoggerFactory.getLogger(BinaryDataHandler.class);
1✔
41
        
42
        /**
43
         * Constructor initializes formats for alternative file names to protect from unintentionally
44
         * overwriting existing files.
45
         */
46
        public BinaryDataHandler() {
47
                super();
1✔
48
        }
1✔
49
        
50
        /**
51
         * Currently supports the following views: org.openmrs.obs.ComplexObsHandler#RAW_VIEW
52
         * 
53
         * @see org.openmrs.obs.ComplexObsHandler#getObs(org.openmrs.Obs, java.lang.String)
54
         */
55
        @Override
56
        public Obs getObs(Obs obs, String view) {
57
                String key = parseDataKey(obs);
1✔
58
                
59
                log.debug("value complex: {}", obs.getValueComplex());
1✔
60
                log.debug("file path: {}", key);
1✔
61
                ComplexData complexData = null;
1✔
62
                
63
                // Raw view (i.e. the file as is)
64
                if (ComplexObsHandler.RAW_VIEW.equals(view)) {
1✔
65
                        // to handle problem with downloading/saving files with blank spaces or commas in their names
66
                        // also need to remove the "file" text appended to the end of the file name
67
                        String[] names = obs.getValueComplex().split("\\|");
1✔
68
                        String originalFilename = names[0];
1✔
69
                        originalFilename = originalFilename.replaceAll(",", "")
1✔
70
                                .replaceAll(" ", "").replaceAll("file$", "");
1✔
71
                        
72
                        try (InputStream in = storageService.getData(key)){
1✔
73
                                complexData = new ComplexData(originalFilename, IOUtils.toByteArray(in));
1✔
74
                        }
75
                        catch (IOException e) {
×
NEW
76
                                log.error("Trying to read file: {}", key, e);
×
77
                        }
1✔
78
                } else {
1✔
79
                        // No other view supported
80
                        // NOTE: if adding support for another view, don't forget to update supportedViews list above
81
                        return null;
×
82
                }
83
                
84
                Assert.notNull(complexData, "Complex data must not be null");
1✔
85
                
86
                injectMissingMetadata(key, complexData);
1✔
87
                obs.setComplexData(complexData);
1✔
88
                
89
                return obs;
1✔
90
        }
91
        
92
        /**
93
         * @see org.openmrs.obs.ComplexObsHandler#getSupportedViews()
94
         */
95
        @Override
96
        public String[] getSupportedViews() {
97
                return supportedViews;
1✔
98
        }
99
        
100
        /**
101
         * TODO should this support a StringReader too?
102
         * 
103
         * @see org.openmrs.obs.ComplexObsHandler#saveObs(org.openmrs.Obs)
104
         */
105
        @Override
106
        public Obs saveObs(Obs obs) throws APIException {
107
                // Get the buffered file  from the ComplexData.
108
                ComplexData complexData = obs.getComplexData();
1✔
109
                if (complexData == null) {
1✔
NEW
110
                        log.error("Cannot save complex data where obsId={} because its ComplexData is null.", obs.getObsId());
×
111
                        return obs;
×
112
                }
113
                try {
114
                        Object data = obs.getComplexData().getData();
1✔
115
                        ObjectMetadata metadata = new ObjectMetadata();
1✔
116
                        if (data instanceof byte[]) {
1✔
117
                                metadata.setLength((long) ((byte[]) data).length);        
1✔
118
                        }
119
                        metadata.setFilename(obs.getComplexData().getTitle());
1✔
120
                        
121
                        String key = storageService.saveData(outputStream -> {
1✔
122
                                if (data instanceof byte[]) {
1✔
123
                                        IOUtils.write((byte[]) data, outputStream);
1✔
NEW
124
                                } else if (InputStream.class.isAssignableFrom(data.getClass())) {
×
NEW
125
                                        IOUtils.copy((InputStream) data, outputStream);
×
126
                                }
127
                                outputStream.flush();
1✔
128
                        }, metadata, getObsDir());
1✔
129

130
                        // Set the Title and URI for the valueComplex
131
                        obs.setValueComplex(StringUtils.defaultIfBlank(obs.getComplexData().getTitle(), key) + " file |" + key);
1✔
132

133
                        // Remove the ComplexData from the Obs
134
                        obs.setComplexData(null);
1✔
NEW
135
                } catch (IOException e) {
×
NEW
136
                        throw new UncheckedIOException(e);
×
137
                }
1✔
138
                
139
                return obs;
1✔
140
        }
141
        
142
}
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