1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package ca.uhn.hl7v2.util.idgenerator;
27
28 import java.io.BufferedReader;
29 import java.io.File;
30 import java.io.FileInputStream;
31 import java.io.FileOutputStream;
32 import java.io.IOException;
33 import java.io.InputStreamReader;
34 import java.io.PrintWriter;
35 import java.util.concurrent.locks.ReentrantLock;
36
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 import ca.uhn.hl7v2.util.Home;
41
42
43
44
45
46
47
48
49
50
51 public class FileBasedGenerator extends InMemoryIDGenerator {
52
53 private static final Logger LOG = LoggerFactory.getLogger(FileBasedGenerator.class.getName());
54
55 private String directory = Home.getHomeDirectory().getAbsolutePath();
56 private String fileName = "id_file";
57 private boolean neverFail = true;
58 private boolean used = false;
59 private boolean minimizeReads = false;
60 private ReentrantLock lock = new ReentrantLock();
61
62 public FileBasedGenerator() {
63 this(1L);
64 }
65
66 FileBasedGenerator(long increment) {
67 super(increment);
68 }
69
70 public String getID() throws IOException {
71 try {
72 lock.lock();
73
74
75 if (!minimizeReads || !used) {
76 long readInitialValue = readInitialValue(getFilePath());
77 if (readInitialValue >= 0) {
78 set(readInitialValue);
79 }
80 used = true;
81 }
82
83 String id = super.getID();
84
85
86 writeNextValue(Long.parseLong(id) + getIncrement());
87 return id;
88 } finally {
89 lock.unlock();
90 }
91 }
92
93
94 private void writeNextValue(long id) throws IOException {
95 PrintWriter pw = null;
96 try {
97 pw = new PrintWriter(new FileOutputStream(getFilePath(), false));
98 pw.println(Long.toString(id));
99 } catch (IOException e) {
100 if (neverFail) {
101 LOG.warn("Could not write ID to file {}, going to use internal ID generator. {}",
102 getFilePath(), e.getMessage());
103 return;
104 }
105 throw e;
106 } finally {
107 if (pw != null)
108 pw.close();
109 }
110 }
111
112 private long readInitialValue(String path) throws IOException {
113 BufferedReader br = null;
114 String id = null;
115 try {
116 br = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
117 id = br.readLine();
118 return Long.parseLong(id);
119 } catch (IOException e) {
120 LOG.info("Could not read ID file {} ", path);
121 if (!neverFail) {
122 throw e;
123 }
124 return -1;
125 } catch (NumberFormatException e) {
126 LOG.info("ID {} read from file is not a number", id);
127 return -1;
128 } finally {
129 if (br != null)
130 try {
131 br.close();
132 } catch (IOException e) {
133 }
134 }
135 }
136
137 private String getFilePath() {
138 return new File(directory, fileName).getAbsolutePath();
139 }
140
141 public void setDirectory(String directory) {
142 try {
143 lock.lock();
144 this.directory = directory;
145 } finally {
146 lock.unlock();
147 }
148 }
149
150 public void setFileName(String fileName) {
151 try {
152 lock.lock();
153 this.fileName = fileName;
154 } finally {
155 lock.unlock();
156 }
157 }
158
159
160
161
162
163
164
165 public void setMinimizeReads(boolean theMinimizeReads) {
166 minimizeReads = theMinimizeReads;
167 }
168
169
170
171
172
173
174
175
176 public void setNeverFail(boolean neverFail) {
177 this.neverFail = neverFail;
178 }
179
180 public void reset() {
181 try {
182 lock.lock();
183 super.reset();
184 writeNextValue(0l);
185 } catch (IOException e) {
186 throw new IllegalStateException("Cannot initialize persistent ID generator", e);
187 } finally {
188 lock.unlock();
189 }
190 }
191
192 }