| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
| MessageIDGenerator |
|
| 4.5;4.5 |
| 1 | package ca.uhn.hl7v2.util; | |
| 2 | ||
| 3 | import java.io.File; | |
| 4 | import java.io.FileNotFoundException; | |
| 5 | import java.io.FileReader; | |
| 6 | import java.io.FileWriter; | |
| 7 | import java.io.IOException; | |
| 8 | ||
| 9 | import org.slf4j.Logger; | |
| 10 | import org.slf4j.LoggerFactory; | |
| 11 | ||
| 12 | import ca.uhn.hl7v2.util.idgenerator.FileBasedHiLoGenerator; | |
| 13 | ||
| 14 | /** | |
| 15 | * <p> | |
| 16 | * Creates unique message IDs. IDs are stored in a file called {@link Home#getHomeDirectory() hapi.home}/id_file for persistence | |
| 17 | * across JVM sessions. Note that if one day you run the JVM with a new working directory, | |
| 18 | * you must move or copy id_file into this directory so that new ID numbers will begin | |
| 19 | * with the last one used, rather than starting over again. | |
| 20 | * </p> | |
| 21 | * <p> | |
| 22 | * Note that as of HAPI 2.0, by default this class will not fail even if the id_file can | |
| 23 | * not be read/written. In this case, HAPI will try to fail gracefully by simply generating | |
| 24 | * a numeric sequence starting at zero. This behaviour can be overwritten using | |
| 25 | * {@link #NEVER_FAIL_PROPERTY} | |
| 26 | * </p> | |
| 27 | * Note: you should not use this class directory, but use the {@link IDGeneratorFactory} instead. | |
| 28 | * Also consider using {@link FileBasedHiLoGenerator} which provides better performance | |
| 29 | * | |
| 30 | * | |
| 31 | * @author Neal Acharya | |
| 32 | * @deprecated use one of the IDGenerator implementations | |
| 33 | */ | |
| 34 | public class MessageIDGenerator { | |
| 35 | ||
| 36 | 5 | private static final Logger ourLog = LoggerFactory.getLogger(MessageIDGenerator.class.getName()); |
| 37 | private static MessageIDGenerator messageIdGenerator; | |
| 38 | ||
| 39 | /** | |
| 40 | * Contains the complete path to the default ID file, which is a plain text file containing | |
| 41 | * the number corresponding to the last generated ID | |
| 42 | */ | |
| 43 | 5 | public final static String DEFAULT_ID_FILE = Home.getHomeDirectory().getAbsolutePath() + "/id_file"; |
| 44 | ||
| 45 | /** | |
| 46 | * System property key which indicates that this class should never fail. If this | |
| 47 | * system property is set to false (default is true), as in the following code:<br> | |
| 48 | * <code>System.setProperty(MessageIDGenerator.NEVER_FAIL_PROPERTY, Boolean.FALSE.toString());</code><br> | |
| 49 | * this class will fail if the underlying disk file can not be | |
| 50 | * read or written. This means you are roughly guaranteed a unique | |
| 51 | * ID number between JVM sessions (barring the file getting lost or corrupted). | |
| 52 | */ | |
| 53 | 5 | public static final String NEVER_FAIL_PROPERTY = MessageIDGenerator.class.getName() + "_NEVER_FAIL_PROPERTY"; |
| 54 | ||
| 55 | private long id; | |
| 56 | private FileWriter fileW; | |
| 57 | ||
| 58 | /** | |
| 59 | * Constructor | |
| 60 | * Creates an instance of the class | |
| 61 | * Its reads an id (longint#) from an external file, if one is not present then the external file | |
| 62 | * is created and initialized to zero. | |
| 63 | * This id is stored into the private field of id. | |
| 64 | */ | |
| 65 | 5 | private MessageIDGenerator() throws IOException { |
| 66 | 5 | initialize(); |
| 67 | 5 | }//end constructor code |
| 68 | ||
| 69 | ||
| 70 | /** | |
| 71 | * Force the generator to re-load the ID file and initialize itself. | |
| 72 | * | |
| 73 | * This method is mostly provided as a convenience to unit tests, and does | |
| 74 | * not normally need to be called. | |
| 75 | */ | |
| 76 | void initialize() throws IOException { | |
| 77 | 10 | id = 0; |
| 78 | ||
| 79 | /*check external file for the last value unique id value generated by | |
| 80 | this class*/ | |
| 81 | try{ | |
| 82 | // We should check to see if the external file for storing the unique ids exists | |
| 83 | 10 | File extFile = new File(DEFAULT_ID_FILE); |
| 84 | 10 | if (extFile.createNewFile()== true){ |
| 85 | /*there was no existing file so a new one has been created with createNewFile method. The | |
| 86 | file is stored at <hapi.home>/id_file.txt */ | |
| 87 | // We can simply initialize the private id field to zero | |
| 88 | 0 | id = 0; |
| 89 | ||
| 90 | }//end if | |
| 91 | else{ | |
| 92 | /*The file does exist which is why we received false from the | |
| 93 | createNewFile method. We should now try to read from this file*/ | |
| 94 | 10 | FileReader fileR = new FileReader(DEFAULT_ID_FILE); |
| 95 | 5 | char[] charArray = new char[100]; |
| 96 | 5 | int e = fileR.read(charArray); |
| 97 | 5 | if (e <= 0){ |
| 98 | /*We know the file exists but it has no value stored in it. So at this point we can simply initialize the | |
| 99 | private id field to zero*/ | |
| 100 | 0 | id = 0; |
| 101 | }//end if | |
| 102 | else{ | |
| 103 | /* Here we know that the file exists and has a stored value. we should read this value and set the | |
| 104 | private id field to it*/ | |
| 105 | 5 | String idStr = String.valueOf(charArray); |
| 106 | 5 | String idStrTrim = idStr.trim(); |
| 107 | ||
| 108 | try { | |
| 109 | 5 | id = Long.parseLong(idStrTrim); |
| 110 | 0 | } catch (NumberFormatException nfe) { |
| 111 | 0 | ourLog.warn("Failed to parse message ID file value \"" + idStrTrim + "\". Defaulting to 0."); |
| 112 | 5 | } |
| 113 | ||
| 114 | }//end else | |
| 115 | //Fix for bug 1100881: Close the file after writing. | |
| 116 | 5 | fileR.close(); |
| 117 | }//end else | |
| 118 | 5 | } catch (FileNotFoundException e) { |
| 119 | 5 | ourLog.error("Failed to locate message ID file. Message was: {}", e.getMessage()); |
| 120 | 0 | } catch (IOException e) { |
| 121 | 0 | if (Boolean.TRUE.equals(System.getProperty(NEVER_FAIL_PROPERTY, Boolean.TRUE.toString()))) { |
| 122 | 0 | ourLog.warn("Could not retrieve message ID file, going to default to ID of 0. Message was: {}", e.getMessage()); |
| 123 | 0 | id = 0; |
| 124 | 0 | return; |
| 125 | } else { | |
| 126 | 0 | throw e; |
| 127 | } | |
| 128 | 10 | } |
| 129 | 10 | } |
| 130 | ||
| 131 | /** | |
| 132 | * Synchronized method used to return the single (static) instance of the class | |
| 133 | */ | |
| 134 | public static synchronized MessageIDGenerator getInstance() throws IOException { | |
| 135 | 6015 | if (messageIdGenerator == null) |
| 136 | 5 | messageIdGenerator = new MessageIDGenerator(); |
| 137 | 6015 | return messageIdGenerator; |
| 138 | }//end method | |
| 139 | ||
| 140 | /** | |
| 141 | * Synchronized method used to return the incremented id value | |
| 142 | */ | |
| 143 | public synchronized String getNewID() throws IOException{ | |
| 144 | try { | |
| 145 | //increment the private field | |
| 146 | 6015 | id = id + 1; |
| 147 | //write the id value to the file | |
| 148 | 6015 | String idStr = String.valueOf(id); |
| 149 | ||
| 150 | //create an instance of the Filewriter Object pointing to "C:\\extfiles\\Idfile.txt" | |
| 151 | 6015 | fileW = new FileWriter(DEFAULT_ID_FILE, false); |
| 152 | 6010 | fileW.write(idStr); |
| 153 | 6010 | fileW.flush(); |
| 154 | 6010 | fileW.close(); |
| 155 | 5 | } catch (FileNotFoundException e) { |
| 156 | 5 | if (Boolean.TRUE.equals(System.getProperty(NEVER_FAIL_PROPERTY, Boolean.TRUE.toString()))) { |
| 157 | 0 | ourLog.info("Failed to create message ID file. Message was: {}", e.getMessage()); |
| 158 | 0 | fileW = null; |
| 159 | } | |
| 160 | 0 | } catch (IOException e) { |
| 161 | 0 | if (Boolean.TRUE.equals(System.getProperty(NEVER_FAIL_PROPERTY, Boolean.TRUE.toString()))) { |
| 162 | 0 | ourLog.debug("Failed to create message ID file. Message was: {}", e.getMessage()); |
| 163 | 0 | fileW = null; |
| 164 | } else { | |
| 165 | 0 | throw e; |
| 166 | } | |
| 167 | 6015 | } |
| 168 | 6015 | return String.valueOf(id); |
| 169 | }//end method | |
| 170 | ||
| 171 | } |