]> git.argeo.org Git - gpl/argeo-slc.git/blob - org.argeo.slc.detached/src/main/java/org/argeo/slc/detached/drivers/FileDriver.java
Start introducing OSGi commands
[gpl/argeo-slc.git] / org.argeo.slc.detached / src / main / java / org / argeo / slc / detached / drivers / FileDriver.java
1 package org.argeo.slc.detached.drivers;
2
3 import java.io.File;
4 import java.io.FileFilter;
5 import java.io.FileInputStream;
6 import java.io.FileOutputStream;
7 import java.io.IOException;
8 import java.io.ObjectInputStream;
9 import java.io.ObjectOutputStream;
10
11 import javax.xml.transform.stream.StreamResult;
12 import javax.xml.transform.stream.StreamSource;
13
14 import org.apache.commons.io.FileUtils;
15 import org.apache.commons.io.FilenameUtils;
16 import org.apache.commons.io.IOUtils;
17 import org.apache.commons.io.filefilter.NotFileFilter;
18 import org.apache.commons.io.filefilter.SuffixFileFilter;
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.argeo.slc.detached.DetachedAnswer;
22 import org.argeo.slc.detached.DetachedClient;
23 import org.argeo.slc.detached.DetachedCommunication;
24 import org.argeo.slc.detached.DetachedException;
25 import org.argeo.slc.detached.DetachedRequest;
26 import org.springframework.beans.factory.InitializingBean;
27
28 public class FileDriver extends AbstractDriver implements DetachedClient,
29 InitializingBean {
30 private final static Log log = LogFactory.getLog(FileDriver.class);
31
32 private File baseDir;
33 private File requestsDir;
34 private File answersDir;
35 private File processedRequestsDir;
36 private File processedAnswersDir;
37
38 private String lockFileExt = "lck";
39 private FileFilter notLockFileFilter = new NotFileFilter(
40 new SuffixFileFilter("." + lockFileExt));
41
42 public synchronized DetachedRequest receiveRequest() throws Exception {
43 DetachedRequest request = (DetachedRequest) receiveFile(requestsDir,
44 processedRequestsDir, 0);
45 if (request != null)
46 if (log.isTraceEnabled())
47 log.trace("Received detached request #" + request.getUuid()
48 + " for ref '" + request.getRef() + "', path="
49 + request.getPath());
50 return request;
51 }
52
53 public void sendAnswer(DetachedAnswer answer) throws Exception {
54 sendFile(answersDir, answer);
55 if (log.isTraceEnabled())
56 log.trace("Sent detached answer #" + answer.getUuid());
57 }
58
59 public DetachedAnswer receiveAnswer() throws Exception {
60 DetachedAnswer answer = (DetachedAnswer) receiveFile(answersDir,
61 processedAnswersDir, getReceiveAnswerTimeout());
62 if (answer != null)
63 if (log.isTraceEnabled())
64 log.trace("Received detached answer #" + answer.getUuid());
65 return answer;
66 }
67
68 public void sendRequest(DetachedRequest request) throws Exception {
69 sendFile(requestsDir, request);
70 if (log.isTraceEnabled())
71 log.trace("Sent detached request #" + request.getUuid()
72 + " for ref '" + request.getRef() + "', path="
73 + request.getPath());
74 }
75
76 protected void sendFile(File dir, DetachedCommunication detCom)
77 throws Exception {
78 final File file;
79 if (getXmlConverter() != null)
80 file = new File(dir.getPath() + File.separator + detCom.getUuid()
81 + ".xml");
82 else
83 file = new File(dir.getPath() + File.separator + detCom.getUuid());
84
85 File lockFile = createLockFile(file);
86 if (getXmlConverter() != null) {
87 FileOutputStream outFile = new FileOutputStream(file);
88 try {
89 StreamResult result = new StreamResult(outFile);
90 getXmlConverter().marshallCommunication(detCom, result);
91 } finally {
92 IOUtils.closeQuietly(outFile);
93 }
94 } else {
95 ObjectOutputStream out = new ObjectOutputStream(
96 new FileOutputStream(file));
97 try {
98 out.writeObject(detCom);
99 } finally {
100 IOUtils.closeQuietly(out);
101 }
102 }
103 lockFile.delete();
104 }
105
106 /**
107 * @param timeout
108 * in ms, 0 is no timeout
109 */
110 protected synchronized DetachedCommunication receiveFile(File dir,
111 File processedDir, long timeout) throws Exception {
112 long begin = System.currentTimeMillis();
113 File file = null;
114 while (file == null && isActive()) {
115 if (!dir.exists())
116 throw new DetachedException("Dir " + dir + " does not exist.");
117
118 File[] files = dir.listFiles(notLockFileFilter);
119 if (files.length > 0)
120 file = files[0];
121 else {
122 try {
123 wait(100);
124 } catch (InterruptedException e) {
125 // silent
126 }
127 }
128
129 long duration = System.currentTimeMillis() - begin;
130 if (timeout != 0 && duration > timeout) {
131 throw new DetachedException("Receive file timed out after "
132 + duration + "ms.");
133 }
134 }
135
136 if (!isActive())
137 return null;
138
139 File lockFile = nameLockFile(file);
140 while (lockFile.exists())
141 // FIXME: implements time out
142 Thread.sleep(100);
143
144 // Read the file
145 final DetachedCommunication detCom;
146 if (FilenameUtils.getExtension(file.getName()).equals("xml")) {
147 if (getXmlConverter() == null)
148 throw new DetachedException("No XML converter defined.");
149 FileInputStream in = new FileInputStream(file);
150 try {
151 StreamSource source = new StreamSource(in);
152 detCom = getXmlConverter().unmarshallCommunication(source);
153 } finally {
154 IOUtils.closeQuietly(in);
155 }
156 } else {
157 ObjectInputStream in = new ObjectInputStream(new FileInputStream(
158 file));
159 try {
160 detCom = (DetachedCommunication) in.readObject();
161 } finally {
162 IOUtils.closeQuietly(in);
163 }
164 }
165 // Move to processed dir
166 FileUtils.moveFileToDirectory(file, processedDir, false);
167 return detCom;
168 }
169
170 protected File createLockFile(File file) {
171 File lockFile = nameLockFile(file);
172 try {
173 lockFile.createNewFile();
174 } catch (IOException e) {
175 throw new DetachedException("Cannot create lock file " + lockFile);
176 }
177 return lockFile;
178 }
179
180 protected File nameLockFile(File file) {
181 return new File(file.getAbsolutePath() + "." + lockFileExt);
182 }
183
184 public void setBaseDir(File baseDir) {
185 this.baseDir = baseDir;
186 }
187
188 private void createIfNotExist(File dir) {
189 if (!dir.exists()) {
190 log.warn("Dir " + dir.getAbsolutePath()
191 + " does not exist. Creating it...");
192 dir.mkdirs();
193 }
194 }
195
196 public void afterPropertiesSet() throws Exception {
197 this.requestsDir = new File(baseDir.getAbsolutePath() + File.separator
198 + "requests");
199 this.answersDir = new File(baseDir.getAbsolutePath() + File.separator
200 + "answers");
201 this.processedRequestsDir = new File(baseDir.getAbsolutePath()
202 + File.separator + "processed" + File.separator + "requests");
203 this.processedAnswersDir = new File(baseDir.getAbsolutePath()
204 + File.separator + "processed" + File.separator + "answers");
205
206 createIfNotExist(requestsDir);
207 createIfNotExist(answersDir);
208 createIfNotExist(processedRequestsDir);
209 createIfNotExist(processedAnswersDir);
210 }
211
212 }