ca.uhn.hl7v2.util.MessageIDGenerator Maven / Gradle / Ivy
package ca.uhn.hl7v2.util;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ca.uhn.hl7v2.util.idgenerator.FileBasedHiLoGenerator;
/**
*
* Creates unique message IDs. IDs are stored in a file called {@link Home#getHomeDirectory() hapi.home}/id_file for persistence
* across JVM sessions. Note that if one day you run the JVM with a new working directory,
* you must move or copy id_file into this directory so that new ID numbers will begin
* with the last one used, rather than starting over again.
*
*
* Note that as of HAPI 2.0, by default this class will not fail even if the id_file can
* not be read/written. In this case, HAPI will try to fail gracefully by simply generating
* a numeric sequence starting at zero. This behaviour can be overwritten using
* {@link #NEVER_FAIL_PROPERTY}
*
* Note: you should not use this class directory, but use the {@link IDGeneratorFactory} instead.
* Also consider using {@link FileBasedHiLoGenerator} which provides better performance
*
*
* @author Neal Acharya
* @deprecated use one of the IDGenerator implementations
*/
public class MessageIDGenerator {
private static final Logger ourLog = LoggerFactory.getLogger(MessageIDGenerator.class.getName());
private static MessageIDGenerator messageIdGenerator;
/**
* Contains the complete path to the default ID file, which is a plain text file containing
* the number corresponding to the last generated ID
*/
public final static String DEFAULT_ID_FILE = Home.getHomeDirectory().getAbsolutePath() + "/id_file";
/**
* System property key which indicates that this class should never fail. If this
* system property is set to false (default is true), as in the following code:
* System.setProperty(MessageIDGenerator.NEVER_FAIL_PROPERTY, Boolean.FALSE.toString());
* this class will fail if the underlying disk file can not be
* read or written. This means you are roughly guaranteed a unique
* ID number between JVM sessions (barring the file getting lost or corrupted).
*/
public static final String NEVER_FAIL_PROPERTY = MessageIDGenerator.class.getName() + "_NEVER_FAIL_PROPERTY";
private long id;
private FileWriter fileW;
/**
* Constructor
* Creates an instance of the class
* Its reads an id (longint#) from an external file, if one is not present then the external file
* is created and initialized to zero.
* This id is stored into the private field of id.
*/
private MessageIDGenerator() throws IOException {
initialize();
}//end constructor code
/**
* Force the generator to re-load the ID file and initialize itself.
*
* This method is mostly provided as a convenience to unit tests, and does
* not normally need to be called.
*/
void initialize() throws IOException {
id = 0;
/*check external file for the last value unique id value generated by
this class*/
try{
// We should check to see if the external file for storing the unique ids exists
File extFile = new File(DEFAULT_ID_FILE);
if (extFile.createNewFile()== true){
/*there was no existing file so a new one has been created with createNewFile method. The
file is stored at /id_file.txt */
// We can simply initialize the private id field to zero
id = 0;
}//end if
else{
/*The file does exist which is why we received false from the
createNewFile method. We should now try to read from this file*/
FileReader fileR = new FileReader(DEFAULT_ID_FILE);
char[] charArray = new char[100];
int e = fileR.read(charArray);
if (e <= 0){
/*We know the file exists but it has no value stored in it. So at this point we can simply initialize the
private id field to zero*/
id = 0;
}//end if
else{
/* Here we know that the file exists and has a stored value. we should read this value and set the
private id field to it*/
String idStr = String.valueOf(charArray);
String idStrTrim = idStr.trim();
try {
id = Long.parseLong(idStrTrim);
} catch (NumberFormatException nfe) {
ourLog.warn("Failed to parse message ID file value \"" + idStrTrim + "\". Defaulting to 0.");
}
}//end else
//Fix for bug 1100881: Close the file after writing.
fileR.close();
}//end else
} catch (FileNotFoundException e) {
ourLog.error("Failed to locate message ID file. Message was: {}", e.getMessage());
} catch (IOException e) {
if (Boolean.TRUE.equals(System.getProperty(NEVER_FAIL_PROPERTY, Boolean.TRUE.toString()))) {
ourLog.warn("Could not retrieve message ID file, going to default to ID of 0. Message was: {}", e.getMessage());
id = 0;
return;
} else {
throw e;
}
}
}
/**
* Synchronized method used to return the single (static) instance of the class
*/
public static synchronized MessageIDGenerator getInstance() throws IOException {
if (messageIdGenerator == null)
messageIdGenerator = new MessageIDGenerator();
return messageIdGenerator;
}//end method
/**
* Synchronized method used to return the incremented id value
*/
public synchronized String getNewID() throws IOException{
try {
//increment the private field
id = id + 1;
//write the id value to the file
String idStr = String.valueOf(id);
//create an instance of the Filewriter Object pointing to "C:\\extfiles\\Idfile.txt"
fileW = new FileWriter(DEFAULT_ID_FILE, false);
fileW.write(idStr);
fileW.flush();
fileW.close();
} catch (FileNotFoundException e) {
if (Boolean.TRUE.equals(System.getProperty(NEVER_FAIL_PROPERTY, Boolean.TRUE.toString()))) {
ourLog.info("Failed to create message ID file. Message was: {}", e.getMessage());
fileW = null;
}
} catch (IOException e) {
if (Boolean.TRUE.equals(System.getProperty(NEVER_FAIL_PROPERTY, Boolean.TRUE.toString()))) {
ourLog.debug("Failed to create message ID file. Message was: {}", e.getMessage());
fileW = null;
} else {
throw e;
}
}
return String.valueOf(id);
}//end method
}