1 | package gov.hhs.fha.nhinc.adapter.reidentification;
|
---|
2 |
|
---|
3 | import gov.hhs.fha.nhinc.adapter.reidentification.data.PseudonymMap;
|
---|
4 | import gov.hhs.fha.nhinc.adapter.reidentification.data.PseudonymMaps;
|
---|
5 | import gov.hhs.fha.nhinc.adapter.reidentification.data.PseudonymMapsXML;
|
---|
6 | import java.io.BufferedReader;
|
---|
7 | import java.io.BufferedWriter;
|
---|
8 | import java.io.File;
|
---|
9 | import java.io.FileReader;
|
---|
10 | import java.io.FileWriter;
|
---|
11 | import java.io.IOException;
|
---|
12 | import java.io.Writer;
|
---|
13 | import org.apache.commons.logging.Log;
|
---|
14 | import org.apache.commons.logging.LogFactory;
|
---|
15 |
|
---|
16 | /**
|
---|
17 | * This class is used to manage the Pseudonym map. It provides operations that
|
---|
18 | * can be used to retrieve, save, and locate items within the map.
|
---|
19 | */
|
---|
20 | public class PseudonymMapManager {
|
---|
21 |
|
---|
22 | private static Log log = LogFactory.getLog(PseudonymMapManager.class);
|
---|
23 | private static final String RE_ID_FILENAME = "reidentification.xml";
|
---|
24 | private static final String NHINC_PROPERTIES_DIR = "NHINC_PROPERTIES_DIR";
|
---|
25 | private static PseudonymMaps pseudonymMaps = new PseudonymMaps();
|
---|
26 | private static File reIdFile;
|
---|
27 |
|
---|
28 | /**
|
---|
29 | * Lazy initializer for the location of the reidentification properties file
|
---|
30 | */
|
---|
31 | private static File getReidentificationFile() {
|
---|
32 | if (reIdFile == null) {
|
---|
33 | String propertyDir = System.getenv(NHINC_PROPERTIES_DIR);
|
---|
34 | if ((propertyDir != null) && (propertyDir.length() > 0)) {
|
---|
35 | reIdFile = new File(propertyDir, RE_ID_FILENAME);
|
---|
36 | } else {
|
---|
37 | reIdFile = new File(RE_ID_FILENAME);
|
---|
38 | }
|
---|
39 | }
|
---|
40 | return reIdFile;
|
---|
41 | }
|
---|
42 |
|
---|
43 | /**
|
---|
44 | * This method reads the map in from the XML text file, de-serializes it,
|
---|
45 | * and holds it in a private member variable.
|
---|
46 | */
|
---|
47 | public static void readMap() {
|
---|
48 | log.debug("Entering PseudonymMapManager.readMap");
|
---|
49 |
|
---|
50 | StringBuilder contents = new StringBuilder();
|
---|
51 | File file = getReidentificationFile();
|
---|
52 | try {
|
---|
53 | if (file.exists() && file.canRead()) {
|
---|
54 | BufferedReader input = new BufferedReader(new FileReader(file));
|
---|
55 | try {
|
---|
56 | String line = null;
|
---|
57 | while ((line = input.readLine()) != null) {
|
---|
58 | contents.append(line);
|
---|
59 | //readLine chops off the newline character, so add it back
|
---|
60 | contents.append(System.getProperty("line.separator"));
|
---|
61 | }
|
---|
62 | log.debug("Reading Pseudonym Maps from: " + file.getPath() + "\n" + contents.toString());
|
---|
63 | //de-serialize the contents of the file to get a list of items
|
---|
64 | PseudonymMaps fileItems = PseudonymMapsXML.deserialize(contents.toString());
|
---|
65 | if(fileItems != null && fileItems.getPseudonymMap() != null){
|
---|
66 | pseudonymMaps = fileItems;
|
---|
67 | } else {
|
---|
68 | pseudonymMaps.getPseudonymMap().clear();
|
---|
69 | }
|
---|
70 | } finally {
|
---|
71 | input.close();
|
---|
72 | }
|
---|
73 | } else {
|
---|
74 | log.error(file.getCanonicalPath() + " does not exist or can not be read.");
|
---|
75 | }
|
---|
76 | } catch (IOException ex) {
|
---|
77 | log.error("Exception on accessing " + file.getPath() + ": " + ex.getMessage());
|
---|
78 | }
|
---|
79 | log.debug("Exiting PseudonymMapManager.readMap");
|
---|
80 | }
|
---|
81 |
|
---|
82 | /**
|
---|
83 | * This operation takes the map that is located in the private internal
|
---|
84 | * memory location and writes it out to disk, replacing the old copy of the
|
---|
85 | * same file.
|
---|
86 | */
|
---|
87 | public static void writeMap() {
|
---|
88 | log.debug("Entering PseudonymMapManager.writeMap");
|
---|
89 |
|
---|
90 | File file = getReidentificationFile();
|
---|
91 | try {
|
---|
92 | // if file does not exist, create it
|
---|
93 | file.createNewFile();
|
---|
94 | Writer output = null;
|
---|
95 | try {
|
---|
96 | output = new BufferedWriter(new FileWriter(file));
|
---|
97 | // serialize the contents of the object and write it out
|
---|
98 | log.debug("Writing serialied Pseudonym Maps to: " + file.getPath());
|
---|
99 | output.write(PseudonymMapsXML.serialize(pseudonymMaps));
|
---|
100 | } finally {
|
---|
101 | output.close();
|
---|
102 | }
|
---|
103 | } catch (IOException ex) {
|
---|
104 | log.error("Exception on accessing " + file.getPath() + ": " + ex.getMessage());
|
---|
105 | }
|
---|
106 |
|
---|
107 | log.debug("Exiting PseudonymMapManager.writeMap");
|
---|
108 | }
|
---|
109 |
|
---|
110 | /**
|
---|
111 | * This method takes the pseudonym patient ID assigning authority with it's
|
---|
112 | * corresponding pseudonym patient ID and returns the mapping that is
|
---|
113 | * found in the map. If no mapping is found, then null is returned.
|
---|
114 | */
|
---|
115 | public static PseudonymMap findPseudonymMap(String pseudonymPatientIdAssigningAuthority, String pseudonymPatientId) {
|
---|
116 | log.debug("Entering PseudonymMapManager.findPseudonymMap with authority: " + pseudonymPatientIdAssigningAuthority + " and patient:" + pseudonymPatientId);
|
---|
117 |
|
---|
118 | PseudonymMap foundMap = null;
|
---|
119 | if (pseudonymPatientIdAssigningAuthority != null && pseudonymPatientId != null) {
|
---|
120 | for (PseudonymMap testMap : pseudonymMaps.getPseudonymMap()) {
|
---|
121 | if (pseudonymPatientIdAssigningAuthority.equals(testMap.getPseudonymPatientIdAssigningAuthority()) && pseudonymPatientId.equals(testMap.getPseudonymPatientId())) {
|
---|
122 | foundMap = testMap;
|
---|
123 | log.debug("Found match: " + foundMap.toString());
|
---|
124 | break;
|
---|
125 | }
|
---|
126 | }
|
---|
127 | }
|
---|
128 |
|
---|
129 | log.debug("Exiting PseudonymMapManager.findPseudonymMap: " + foundMap);
|
---|
130 | return foundMap;
|
---|
131 | }
|
---|
132 |
|
---|
133 | /**
|
---|
134 | * This adds the pseudonym map to the mappings. If there was already a map
|
---|
135 | * for this pseudonym, then it replaces it, and passes back the old one.
|
---|
136 | * If this is new, then null is returned. Note that by design, a pseudonym
|
---|
137 | * can only map to one real ID. There cannot be a mapping of one pseudonym
|
---|
138 | * and pseudonym assigning authority to multiple real IDs.
|
---|
139 | */
|
---|
140 | public static PseudonymMap addPseudonymMap(PseudonymMap pseudonymMap) {
|
---|
141 | log.debug("Entering PseudonymMapManager.addPseudonymMap");
|
---|
142 | PseudonymMap retMap = null;
|
---|
143 | if (pseudonymMap != null) {
|
---|
144 | String mapKey = pseudonymMap.getRealPatientId();
|
---|
145 | if (mapKey != null) {
|
---|
146 | boolean isIdFound = false;
|
---|
147 | for (PseudonymMap testMap : pseudonymMaps.getPseudonymMap()) {
|
---|
148 | if (mapKey.equals(testMap.getRealPatientId())) {
|
---|
149 | // if successfully removed then return the previous map
|
---|
150 | // and add the new one
|
---|
151 | if (removePseudonymMap(testMap)) {
|
---|
152 | retMap = testMap;
|
---|
153 | pseudonymMaps.getPseudonymMap().add(pseudonymMap);
|
---|
154 | log.debug("New map for ID: " + mapKey + " has been stored.");
|
---|
155 | }
|
---|
156 | isIdFound = true;
|
---|
157 | break;
|
---|
158 | }
|
---|
159 | }
|
---|
160 | // if it was not already in the list add it
|
---|
161 | if (!isIdFound) {
|
---|
162 | pseudonymMaps.getPseudonymMap().add(pseudonymMap);
|
---|
163 | log.debug("Map for ID: " + mapKey + " has been stored.");
|
---|
164 | }
|
---|
165 | } else {
|
---|
166 | log.error("Attempt to add an pseudonym map with a null real patient ID has been rejected.");
|
---|
167 | }
|
---|
168 | } else {
|
---|
169 | log.error("Attempt to add a null pseudonym map has been rejected.");
|
---|
170 | }
|
---|
171 | log.debug("Exiting PseudonymMapManager.addPseudonymMap");
|
---|
172 | return retMap;
|
---|
173 | }
|
---|
174 |
|
---|
175 | /**
|
---|
176 | * This looks for and removes the specified pseudonym mapping from the set
|
---|
177 | * of maps. If it existed and is actually removed, then true is returned.
|
---|
178 | * If it was never in the map to begin with then false is returned.
|
---|
179 | */
|
---|
180 | public static boolean removePseudonymMap(PseudonymMap pseudonymMap) {
|
---|
181 | log.debug("Entering PseudonymMapManager.removePseudonymMap");
|
---|
182 | boolean isRemoved = false;
|
---|
183 | if (pseudonymMap != null) {
|
---|
184 | String mapKey = pseudonymMap.getRealPatientId();
|
---|
185 | if (mapKey != null) {
|
---|
186 | for (PseudonymMap testMap : pseudonymMaps.getPseudonymMap()) {
|
---|
187 | if (mapKey.equals(testMap.getRealPatientId())) {
|
---|
188 | isRemoved = pseudonymMaps.getPseudonymMap().remove(testMap);
|
---|
189 | if (isRemoved) {
|
---|
190 | log.debug("Previous map for ID: " + mapKey + " has been removed.");
|
---|
191 | } else {
|
---|
192 | log.error("Attempt to remove map for ID: " + mapKey + " has failed.");
|
---|
193 | }
|
---|
194 | break;
|
---|
195 | }
|
---|
196 | }
|
---|
197 | }else {
|
---|
198 | log.error("Attempt to remove an pseudonym map with a null real patient ID has been rejected.");
|
---|
199 | }
|
---|
200 | } else {
|
---|
201 | log.error("Attempt to remove a null pseudonym map has been rejected.");
|
---|
202 | }
|
---|
203 | log.debug("Exiting PseudonymMapManager.removePseudonymMap removal: " + isRemoved);
|
---|
204 | return isRemoved;
|
---|
205 | }
|
---|
206 | }
|
---|