1
2
3
4
5
6
7
8
9
10
11 package org.mule.util.queue;
12
13 import org.mule.RegistryContext;
14 import org.mule.api.MuleContext;
15 import org.mule.api.context.MuleContextAware;
16 import org.mule.util.FileUtils;
17 import org.mule.util.file.DeleteException;
18
19 import java.io.File;
20 import java.io.FileInputStream;
21 import java.io.FileNotFoundException;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.io.ObjectInputStream;
25 import java.io.ObjectOutputStream;
26 import java.util.ArrayList;
27 import java.util.List;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.safehaus.uuid.UUIDGenerator;
32
33 public class FilePersistenceStrategy implements QueuePersistenceStrategy, MuleContextAware
34 {
35 private static final Log logger = LogFactory.getLog(FilePersistenceStrategy.class);
36
37
38 public static final String DEFAULT_QUEUE_STORE = "queuestore";
39
40 public static final String EXTENSION = ".msg";
41
42 private File store;
43
44 private UUIDGenerator gen = UUIDGenerator.getInstance();
45
46 protected MuleContext muleContext;
47
48 public FilePersistenceStrategy()
49 {
50 super();
51 }
52
53
54 public void setMuleContext(MuleContext context)
55 {
56 this.muleContext = context;
57 }
58
59 protected String getId(Object obj)
60 {
61 String id = gen.generateRandomBasedUUID().toString();
62 return id;
63 }
64
65
66
67
68
69
70 public Object store(String queue, Object obj) throws IOException
71 {
72 String id = getId(obj);
73 File file = FileUtils.newFile(store, queue + File.separator + id + EXTENSION);
74 file.getParentFile().mkdirs();
75 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
76 oos.writeObject(obj);
77 oos.close();
78 return id;
79 }
80
81
82
83
84
85
86 public void remove(String queue, Object id) throws IOException
87 {
88 File file = FileUtils.newFile(store, queue + File.separator + id + EXTENSION);
89 if (file.exists())
90 {
91 if (!file.delete())
92 {
93 throw new DeleteException(file);
94 }
95 }
96 else
97 {
98 throw new FileNotFoundException(file.toString());
99 }
100 }
101
102
103
104
105
106
107 public Object load(String queue, Object id) throws IOException
108 {
109 File file = FileUtils.newFile(store, queue + File.separator + id + EXTENSION);
110 ObjectInputStream ois = null;
111 try
112 {
113 ois = new ObjectInputStream(new FileInputStream(file));
114 Object obj = ois.readObject();
115 return obj;
116 }
117 catch (ClassNotFoundException e)
118 {
119 throw (IOException) new IOException("Error loading persistent object").initCause(e);
120 }
121 finally
122 {
123 if (ois != null)
124 {
125 ois.close();
126 }
127 }
128 }
129
130
131
132
133
134
135 public List restore() throws IOException
136 {
137 List msgs = new ArrayList();
138 if (store == null)
139 {
140 logger.warn("No store has be set on the File Persistence Strategy. Not restoring at this time");
141 return msgs;
142 }
143 try
144 {
145 restoreFiles(store, msgs);
146 logger.debug("Restore retrieved " + msgs.size() + " objects");
147 return msgs;
148 }
149 catch (ClassNotFoundException e)
150 {
151 throw (IOException) new IOException("Could not restore").initCause(e);
152 }
153 }
154
155 protected void restoreFiles(File dir, List msgs) throws IOException, ClassNotFoundException
156 {
157 File[] files = dir.listFiles();
158 if (files == null)
159 {
160 return;
161 }
162
163 for (int i = 0; i < files.length; i++)
164 {
165 if (files[i].isDirectory())
166 {
167 restoreFiles(files[i], msgs);
168 }
169 else if (files[i].getName().endsWith(EXTENSION))
170 {
171 String id = files[i].getCanonicalPath();
172 id = id.substring(store.getCanonicalPath().length() + 1, id.length() - EXTENSION.length());
173 String queue = id.substring(0, id.indexOf(File.separator));
174 id = id.substring(queue.length() + 1);
175 msgs.add(new HolderImpl(queue, id));
176 }
177 }
178 }
179
180
181
182
183
184
185 public void open() throws IOException
186 {
187 String path = RegistryContext.getConfiguration().getWorkingDirectory() + File.separator + DEFAULT_QUEUE_STORE;
188 store = FileUtils.newFile(path).getCanonicalFile();
189 store.mkdirs();
190 }
191
192
193
194
195
196
197 public void close() throws IOException
198 {
199
200 }
201
202 protected static class HolderImpl implements Holder
203 {
204 private String queue;
205 private Object id;
206
207 public HolderImpl(String queue, Object id)
208 {
209 this.queue = queue;
210 this.id = id;
211 }
212
213 public Object getId()
214 {
215 return id;
216 }
217
218 public String getQueue()
219 {
220 return queue;
221 }
222 }
223
224 public boolean isTransient()
225 {
226 return false;
227 }
228 }