1 package ca.uhn.hl7v2.testpanel.model.conf;
2
3 import static org.apache.commons.lang.StringUtils.*;
4
5 import java.io.IOException;
6 import java.io.StringWriter;
7 import java.net.URL;
8 import java.util.ArrayList;
9 import java.util.HashMap;
10 import java.util.HashSet;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.Set;
14 import java.util.UUID;
15
16 import jakarta.xml.bind.JAXB;
17 import jakarta.xml.bind.JAXBContext;
18 import jakarta.xml.bind.JAXBException;
19 import jakarta.xml.bind.annotation.XmlAccessType;
20 import jakarta.xml.bind.annotation.XmlAccessorType;
21 import jakarta.xml.bind.annotation.XmlAttribute;
22 import jakarta.xml.bind.annotation.XmlElement;
23 import jakarta.xml.bind.annotation.XmlRootElement;
24 import jakarta.xml.bind.annotation.XmlType;
25
26 import ca.uhn.hl7v2.conf.ProfileException;
27 import ca.uhn.hl7v2.conf.parser.ProfileParser;
28 import ca.uhn.hl7v2.conf.spec.RuntimeProfile;
29 import ca.uhn.hl7v2.testpanel.model.conf.ProfileGroup.Entry;
30
31 @XmlAccessorType(XmlAccessType.FIELD)
32 @XmlRootElement(name = "ExportedProfileGroupFile")
33 public class ExportedProfileGroupFile {
34
35 private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExportedProfileGroupFile.class);
36
37 @XmlElement(name = "profileGroup")
38 private ProfileGroup myProfileGroup;
39
40 @XmlElement(name = "profile")
41 private List<ProfileWithContents> myProfiles;
42
43 @XmlElement(name = "tableFile")
44 private List<TableFile> myTableFiles;
45
46
47
48
49 public ExportedProfileGroupFile() {
50
51 }
52
53 public ExportedProfileGroupFile(ProfileGroup theProfileGroup, TableFileList theTableFileList) throws IOException {
54
55 ExportedProfileGroupFile exported = new ExportedProfileGroupFile();
56 exported.setProfileGroup(theProfileGroup);
57
58 Set<String> profileIds = new HashSet<String>();
59 Set<String> tablesIds = new HashSet<String>();
60 for (Entry next : theProfileGroup.getEntries()) {
61 if (!profileIds.add(next.getProfileProxy().getId())) {
62 continue;
63 }
64
65 ProfileWithContents contents = new ProfileWithContents();
66 contents.setContents(next.getProfileProxy().getProfileAsString());
67 contents.setId(next.getProfileProxy().getId());
68 exported.getProfiles().add(contents);
69
70 String tablesId = next.getTablesId();
71 if (isNotBlank(tablesId) && tablesIds.add(tablesId)) {
72 TableFile tableFile = theTableFileList.getTableFile(tablesId);
73 exported.getTableFiles().add(tableFile);
74 }
75 }
76
77 }
78
79
80
81
82 public ProfileGroup getProfileGroup() {
83 return myProfileGroup;
84 }
85
86
87
88
89 public List<ProfileWithContents> getProfiles() {
90 if (myProfiles == null) {
91 myProfiles = new ArrayList<ExportedProfileGroupFile.ProfileWithContents>();
92 }
93 return myProfiles;
94 }
95
96
97
98
99 public List<TableFile> getTableFiles() {
100 if (myTableFiles == null) {
101 myTableFiles = new ArrayList<TableFile>();
102 }
103 return myTableFiles;
104 }
105
106
107
108
109
110 public void setProfileGroup(ProfileGroup theProfileGroup) {
111 myProfileGroup = theProfileGroup;
112 }
113
114 public static ExportedProfileGroupFile loadFromUrl(URL theImportUrl) {
115 try {
116 Object unmarshal = JAXBContext.newInstance(ExportedProfileGroupFile.class).createUnmarshaller().unmarshal(theImportUrl);
117 if ((unmarshal != null) && !(unmarshal instanceof ExportedProfileGroupFile)) {
118 ourLog.error("Found wrong type: " + unmarshal.getClass().getName());
119 }
120 return (ExportedProfileGroupFile) unmarshal;
121 } catch (JAXBException e) {
122 ourLog.error("Failed to read profile group file from URL: " + theImportUrl, e);
123 return null;
124 }
125 }
126
127 @XmlType()
128 public static class ProfileWithContents {
129
130 @XmlElement(name = "contents")
131 private String myContents;
132
133 @XmlAttribute(name = "id")
134 private String myId;
135
136
137
138
139 public String getContents() {
140 return myContents;
141 }
142
143
144
145
146 public String getId() {
147 return myId;
148 }
149
150
151
152
153
154 public void setContents(String theContents) {
155 myContents = theContents;
156 }
157
158
159
160
161
162 public void setId(String theId) {
163 myId = theId;
164 }
165 }
166
167
168
169
170
171 public void renumberEverything() {
172 Map<String, String> ids = new HashMap<String, String>();
173 getProfileGroup().setId(mapId(ids, getProfileGroup().getId()));
174 for (Entry next : getProfileGroup().getEntries()) {
175 next.setTablesId(mapId(ids, next.getTablesId()));
176 next.getProfileProxy().setId(mapId(ids, next.getProfileProxy().getId()));
177 }
178 for (ProfileWithContents next : getProfiles()) {
179 next.setId(mapId(ids, next.getId()));
180 }
181 for (TableFile next : getTableFiles()) {
182 next.setId(mapId(ids, next.getId()));
183 }
184 }
185
186 private static String mapId(Map<String, String> theIds, String theId) {
187 if (theId == null) {
188 return null;
189 }
190 String retVal = theIds.get(theId);
191 if (retVal == null) {
192 retVal = UUID.randomUUID().toString();
193 theIds.put(theId, retVal);
194 }
195 return retVal;
196 }
197
198
199
200
201 public void hydrate() throws IOException, ProfileException {
202 Map<String, RuntimeProfile> parsedProfiles = new HashMap<String, RuntimeProfile>();
203
204 ProfileParser p = new ProfileParser(false);
205 for (ProfileWithContents next : getProfiles()) {
206 ourLog.info("Restoring runtime profile (conformance profile) with id: {}", next.getId());
207 parsedProfiles.put(next.getId(), p.parse(next.getContents()));
208 }
209
210 for (Entry next : myProfileGroup.getEntries()) {
211 String id = next.getProfileProxy().getId();
212 RuntimeProfile profile = parsedProfiles.get(id);
213 if (profile == null) {
214 throw new IOException("Exported file is inconsistent: Missing profile entry with id: " + id);
215 }
216 }
217 }
218
219 public CharSequence exportConfigToXm() {
220 StringWriter w = new StringWriter();
221 JAXB.marshal(this, w);
222 return w.toString();
223 }
224
225 }