1
2
3
4
5
6
7
8
9
10
11 package org.mule.util.store;
12
13 import org.mule.api.MuleContext;
14 import org.mule.api.MuleRuntimeException;
15 import org.mule.api.context.MuleContextAware;
16 import org.mule.api.store.ListableObjectStore;
17 import org.mule.api.store.ObjectDoesNotExistException;
18 import org.mule.api.store.ObjectStore;
19 import org.mule.api.store.ObjectStoreException;
20 import org.mule.config.i18n.CoreMessages;
21 import org.mule.config.i18n.Message;
22 import org.mule.util.FileUtils;
23 import org.mule.util.SerializationUtils;
24 import org.mule.util.queue.QueueKey;
25
26 import java.io.File;
27 import java.io.FileInputStream;
28 import java.io.FileNotFoundException;
29 import java.io.FileOutputStream;
30 import java.io.IOException;
31 import java.io.Serializable;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.Collections;
35 import java.util.List;
36
37 import org.apache.commons.lang.SerializationException;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public class QueuePersistenceObjectStore<T extends Serializable> extends AbstractObjectStore<T>
56 implements ListableObjectStore<T>, MuleContextAware
57 {
58
59
60
61 public static final String DEFAULT_QUEUE_STORE = "queuestore";
62
63 private static final String FILE_EXTENSION = ".msg";
64
65 private MuleContext muleContext;
66
67
68
69
70 private File storeDirectory;
71
72
73
74
75 public QueuePersistenceObjectStore()
76 {
77 super();
78 }
79
80 public QueuePersistenceObjectStore(MuleContext context)
81 {
82 super();
83 muleContext = context;
84 }
85
86
87
88
89 public boolean isPersistent()
90 {
91 return true;
92 }
93
94 public void open() throws ObjectStoreException
95 {
96 initStoreDirectory();
97 if (!storeDirectory.exists())
98 {
99 createStoreDirectory(storeDirectory);
100 }
101 }
102
103 private void initStoreDirectory() throws ObjectStoreException
104 {
105 try
106 {
107 String workingDirectory = muleContext.getConfiguration().getWorkingDirectory();
108 String path = workingDirectory + File.separator + DEFAULT_QUEUE_STORE;
109 storeDirectory = FileUtils.newFile(path);
110 }
111 catch (MuleRuntimeException mre)
112 {
113
114
115
116 throw new ObjectStoreException(mre);
117 }
118 }
119
120 protected synchronized void createStoreDirectory(File directory) throws ObjectStoreException
121 {
122
123
124 if (!directory.exists() && !directory.mkdirs())
125 {
126 Message message = CoreMessages.failedToCreate("queue store store directory " + directory.getAbsolutePath());
127 throw new ObjectStoreException(message);
128 }
129 }
130
131 public void close() throws ObjectStoreException
132 {
133
134 }
135
136 public List<Serializable> allKeys() throws ObjectStoreException
137 {
138 if (storeDirectory == null)
139 {
140 return Collections.emptyList();
141 }
142
143 return collectAllKeys();
144 }
145
146 protected List<Serializable> collectAllKeys() throws ObjectStoreException
147 {
148 try
149 {
150 List<Serializable> keys = new ArrayList<Serializable>();
151 listStoredFiles(storeDirectory, keys);
152
153 if (logger.isDebugEnabled())
154 {
155 logger.debug("Restore retrieved " + keys.size() + " objects");
156 }
157
158 return keys;
159 }
160 catch (ClassNotFoundException e)
161 {
162 String message = String.format("Could not restore from %1s", storeDirectory.getAbsolutePath());
163 throw new ObjectStoreException(CoreMessages.createStaticMessage(message));
164 }
165 catch (IOException e)
166 {
167 String message = String.format("Could not restore from %1s", storeDirectory.getAbsolutePath());
168 throw new ObjectStoreException(CoreMessages.createStaticMessage(message));
169 }
170 }
171
172 protected void listStoredFiles(File directory, List<Serializable> keys) throws IOException, ClassNotFoundException
173 {
174 File[] files = directory.listFiles();
175 if (files == null)
176 {
177 return;
178 }
179
180
181 Arrays.sort(files);
182
183 for (int i = 0; i < files.length; i++)
184 {
185 if (files[i].isDirectory())
186 {
187 listStoredFiles(files[i], keys);
188 }
189 else if (files[i].getName().endsWith(FILE_EXTENSION))
190 {
191 String id = files[i].getCanonicalPath();
192
193 int beginIndex = storeDirectory.getCanonicalPath().length() + 1;
194 int length = id.length() - FILE_EXTENSION.length();
195 id = id.substring(beginIndex, length);
196
197 String queue = id.substring(0, id.indexOf(File.separator));
198 id = id.substring(queue.length() + 1);
199
200 keys.add(new QueueKey(queue, id));
201 }
202 }
203 }
204
205 @Override
206 protected boolean doContains(Serializable key) throws ObjectStoreException
207 {
208 File storeFile = createStoreFile(key);
209 return storeFile.exists();
210 }
211
212 @Override
213 protected void doStore(Serializable key, T value) throws ObjectStoreException
214 {
215 File outputFile = createStoreFile(key);
216 ensureStoreDirectoryExists(outputFile);
217 serialize(value, outputFile);
218 }
219
220 protected void ensureStoreDirectoryExists(File outputFile) throws ObjectStoreException
221 {
222 File directory = outputFile.getParentFile();
223 if (!directory.exists())
224 {
225 createStoreDirectory(directory);
226 }
227 }
228
229 protected void serialize(T value, File outputFile) throws ObjectStoreException
230 {
231 try
232 {
233 FileOutputStream out = new FileOutputStream(outputFile);
234 SerializationUtils.serialize(value, out);
235 }
236 catch (SerializationException se)
237 {
238 throw new ObjectStoreException(se);
239 }
240 catch (FileNotFoundException fnfe)
241 {
242 throw new ObjectStoreException(fnfe);
243 }
244 }
245
246 @Override
247 protected T doRetrieve(Serializable key) throws ObjectStoreException
248 {
249 File file = createStoreFile(key);
250 return deserialize(file);
251 }
252
253 protected File createStoreFile(Serializable key) throws ObjectStoreException
254 {
255 QueueKey queueKey = (QueueKey) key;
256
257 String filename = queueKey.id + FILE_EXTENSION;
258 String path = queueKey.queueName + File.separator + filename;
259
260 try
261 {
262 return FileUtils.newFile(storeDirectory, path);
263 }
264 catch (MuleRuntimeException mre)
265 {
266
267
268
269 throw new ObjectStoreException(mre);
270 }
271 }
272
273 @SuppressWarnings("unchecked")
274 protected T deserialize(File file) throws ObjectStoreException
275 {
276 try
277 {
278 FileInputStream in = new FileInputStream(file);
279 return (T)SerializationUtils.deserialize(in, muleContext);
280 }
281 catch (SerializationException se)
282 {
283 throw new ObjectStoreException(se);
284 }
285 catch (FileNotFoundException fnfe)
286 {
287 throw new ObjectStoreException(fnfe);
288 }
289 }
290
291 @Override
292 protected T doRemove(Serializable key) throws ObjectStoreException
293 {
294 File storeFile = createStoreFile(key);
295 deleteStoreFile(storeFile);
296
297
298
299 return null;
300 }
301
302 protected void deleteStoreFile(File file) throws ObjectStoreException
303 {
304 if (file.exists())
305 {
306 if (!file.delete())
307 {
308 Message message =
309 CoreMessages.createStaticMessage("Deleting " + file.getAbsolutePath() + " failed");
310 throw new ObjectStoreException(message);
311 }
312 }
313 else
314 {
315 throw new ObjectDoesNotExistException();
316 }
317 }
318
319 public void setMuleContext(MuleContext context)
320 {
321 muleContext = context;
322 }
323 }