View Javadoc
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  	 * Constructor
48  	 */
49  	public ExportedProfileGroupFile() {
50  		// nothing
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; // don't add the same profile twice
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  	 * @return the profileGroup
81  	 */
82  	public ProfileGroup getProfileGroup() {
83  		return myProfileGroup;
84  	}
85  
86  	/**
87  	 * @return the profiles
88  	 */
89  	public List<ProfileWithContents> getProfiles() {
90  		if (myProfiles == null) {
91  			myProfiles = new ArrayList<ExportedProfileGroupFile.ProfileWithContents>();
92  		}
93  		return myProfiles;
94  	}
95  
96  	/**
97  	 * @return the tableFiles
98  	 */
99  	public List<TableFile> getTableFiles() {
100 		if (myTableFiles == null) {
101 			myTableFiles = new ArrayList<TableFile>();
102 		}
103 		return myTableFiles;
104 	}
105 
106 	/**
107 	 * @param theProfileGroup
108 	 *            the profileGroup to set
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 		 * @return the contents
138 		 */
139 		public String getContents() {
140 			return myContents;
141 		}
142 
143 		/**
144 		 * @return the id
145 		 */
146 		public String getId() {
147 			return myId;
148 		}
149 
150 		/**
151 		 * @param theContents
152 		 *            the contents to set
153 		 */
154 		public void setContents(String theContents) {
155 			myContents = theContents;
156 		}
157 
158 		/**
159 		 * @param theId
160 		 *            the id to set
161 		 */
162 		public void setId(String theId) {
163 			myId = theId;
164 		}
165 	}
166 
167 	/**
168 	 * Replaces all IDs within this file with new ones (maintaining existing
169 	 * links but with new IDs)
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 	 * Associate the profile contents with the profile group
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 }