[507] | 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 | }
|
---|