Mercurial > hg > digilib-old
comparison pdf/src/main/java/digilib/servlet/PDFCache.java @ 903:7779b37d1d05
refactored into maven modules per servlet type.
can build servlet-api 2.3 and 3.0 via profile now!
author | robcast |
---|---|
date | Tue, 26 Apr 2011 20:24:31 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
902:89ba3ffcf552 | 903:7779b37d1d05 |
---|---|
1 package digilib.servlet; | |
2 | |
3 import java.io.File; | |
4 import java.io.FileNotFoundException; | |
5 import java.io.IOException; | |
6 import java.util.concurrent.Future; | |
7 | |
8 import javax.servlet.RequestDispatcher; | |
9 import javax.servlet.ServletConfig; | |
10 import javax.servlet.ServletContext; | |
11 import javax.servlet.ServletException; | |
12 import javax.servlet.http.HttpServlet; | |
13 import javax.servlet.http.HttpServletRequest; | |
14 import javax.servlet.http.HttpServletResponse; | |
15 | |
16 import org.apache.log4j.Logger; | |
17 | |
18 import digilib.image.DocuImage; | |
19 import digilib.pdf.PDFFileWorker; | |
20 import digilib.util.DigilibJobCenter; | |
21 | |
22 /** | |
23 * A class for handling user requests for pdf documents made from digilib images. | |
24 * | |
25 * If a document does not already exist, it will be enqueued for generation; if it does exist, it is sent | |
26 * to the user. | |
27 * | |
28 * @author cmielack | |
29 * | |
30 */ | |
31 | |
32 @SuppressWarnings("serial") | |
33 public class PDFCache extends HttpServlet { | |
34 | |
35 public static String version = "0.3a"; | |
36 | |
37 /** logger for accounting requests */ | |
38 protected static Logger accountlog = Logger.getLogger("account.pdf.request"); | |
39 | |
40 /** gengeral logger for this class */ | |
41 protected static Logger logger = Logger.getLogger("digilib.pdfcache"); | |
42 | |
43 /** logger for authentication related */ | |
44 protected static Logger authlog = Logger.getLogger("digilib.pdf.auth"); | |
45 | |
46 private DigilibConfiguration dlConfig = null; | |
47 | |
48 public static String instanceKey = "digilib.servlet.PDFCache"; | |
49 | |
50 private DigilibJobCenter<File> pdfJobCenter = null; | |
51 | |
52 private DigilibJobCenter<DocuImage> pdfImageJobCenter = null; | |
53 | |
54 private File cache_directory = new File("cache"); | |
55 | |
56 private File temp_directory = new File("pdf_temp"); | |
57 | |
58 private static String JSP_WIP = "/pdf/wip.jsp"; | |
59 | |
60 private static String JSP_ERROR = "/pdf/error.jsp"; | |
61 | |
62 /** document status. | |
63 * DONE: document exists in cache | |
64 * WIP: document is "work in progress" | |
65 * NONEXISTENT: document does not exist in cache and is not in progress | |
66 * ERROR: an error occurred while processing the request | |
67 */ | |
68 public static enum PDFStatus {DONE, WIP, NONEXISTENT, ERROR}; | |
69 | |
70 | |
71 public void init(ServletConfig config) throws ServletException { | |
72 super.init(config); | |
73 | |
74 System.out.println("***** Digital Image Library Image PDF-Cache Servlet (version " | |
75 + version + ") *****"); | |
76 // say hello in the log file | |
77 logger.info("***** Digital Image Library Image PDF-Cache Servlet (version " | |
78 + version + ") *****"); | |
79 | |
80 ServletContext context = getServletContext(); | |
81 dlConfig = (DigilibConfiguration) context.getAttribute("digilib.servlet.configuration"); | |
82 if (dlConfig == null) { | |
83 // no Configuration | |
84 throw new ServletException("No Configuration!"); | |
85 } | |
86 | |
87 String temp_fn = dlConfig.getAsString("pdf-temp-dir"); | |
88 temp_directory = new File(temp_fn); | |
89 if (!temp_directory.exists()) { | |
90 // try to create | |
91 temp_directory.mkdirs(); | |
92 } else { | |
93 // rid the temporary directory of possible incomplete document files | |
94 emptyDirectory(temp_directory); | |
95 } | |
96 if (!temp_directory.isDirectory()) { | |
97 throw new ServletException("Configuration error: problem with pdf-temp-dir="+temp_fn); | |
98 } | |
99 | |
100 String cache_fn = dlConfig.getAsString("pdf-cache-dir"); | |
101 cache_directory = new File(cache_fn); | |
102 if (!cache_directory.exists()) { | |
103 // try to create | |
104 cache_directory.mkdirs(); | |
105 } | |
106 if (!cache_directory.isDirectory()) { | |
107 throw new ServletException("Configuration error: problem with pdf-cache-dir="+cache_fn); | |
108 } | |
109 | |
110 pdfJobCenter = (DigilibJobCenter<File>) dlConfig.getValue("servlet.worker.pdfexecutor"); | |
111 pdfImageJobCenter = (DigilibJobCenter<DocuImage>) dlConfig.getValue("servlet.worker.pdfimageexecutor"); | |
112 | |
113 // register this instance globally | |
114 context.setAttribute(instanceKey, this); | |
115 | |
116 } | |
117 | |
118 /* (non-Javadoc) | |
119 * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) | |
120 */ | |
121 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException { | |
122 accountlog.info("GET from " + request.getRemoteAddr()); | |
123 this.processRequest(request, response); | |
124 } | |
125 | |
126 | |
127 /* (non-Javadoc) | |
128 * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) | |
129 */ | |
130 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException { | |
131 accountlog.info("POST from " + request.getRemoteAddr()); | |
132 this.processRequest(request, response); | |
133 } | |
134 | |
135 /** | |
136 * clean up any broken and unfinished files from the temporary directory. | |
137 */ | |
138 public void emptyDirectory(File dir){ | |
139 File[] temp_files = dir.listFiles(); | |
140 for (File f: temp_files){ | |
141 f.delete(); | |
142 } | |
143 } | |
144 | |
145 | |
146 public void processRequest(HttpServletRequest request, | |
147 HttpServletResponse response) throws ServletException { | |
148 | |
149 if (dlConfig == null) { | |
150 logger.error("ERROR: No Configuration!"); | |
151 throw new ServletException("NO VALID digilib CONFIGURATION!"); | |
152 } | |
153 | |
154 String docid = ""; | |
155 try { | |
156 // evaluate request ( make a PDFJobDeclaration , get the DocumentId) | |
157 PDFRequest pdfji = new PDFRequest(request, dlConfig); | |
158 | |
159 docid = pdfji.getDocumentId(); | |
160 | |
161 // if some invalid data has been entered ... | |
162 if(!pdfji.checkValidity()) { | |
163 notifyUser(PDFStatus.ERROR, docid, request, response); | |
164 return; | |
165 } | |
166 | |
167 PDFStatus status = getStatus(docid); | |
168 | |
169 if (status == PDFStatus.NONEXISTENT) { | |
170 // not there -- start creation | |
171 try { | |
172 createNewPdfDocument(pdfji, docid); | |
173 notifyUser(status, docid, request, response); | |
174 return; | |
175 } catch (FileNotFoundException e) { | |
176 // error in pdf creation | |
177 logger.error(e.getMessage()); | |
178 notifyUser(PDFStatus.ERROR, docid, request, response); | |
179 return; | |
180 } | |
181 } else if (status == PDFStatus.DONE) { | |
182 // pdf created -- send it | |
183 try { | |
184 ServletOps.sendFile(getCacheFile(docid), "application/pdf", getDownloadFilename(pdfji), response, logger); | |
185 return; | |
186 } catch (Exception e) { | |
187 // sending didn't work | |
188 logger.error(e.getMessage()); | |
189 return; | |
190 } | |
191 } else { | |
192 // should be work in progress | |
193 notifyUser(status, docid, request, response); | |
194 return; | |
195 } | |
196 } catch (Exception e) { | |
197 // error in pdf creation | |
198 logger.error(e.getMessage()); | |
199 notifyUser(PDFStatus.ERROR, docid, request, response); | |
200 return; | |
201 } | |
202 } | |
203 | |
204 /** | |
205 * depending on the documents status, redirect the user to the appropriate | |
206 * waiting or download page. | |
207 * | |
208 * @param status | |
209 * @param documentid | |
210 * @param request | |
211 * @param response | |
212 */ | |
213 public void notifyUser(PDFStatus status, String documentid, | |
214 HttpServletRequest request, HttpServletResponse response) { | |
215 | |
216 String jsp = null; | |
217 | |
218 if (status == PDFStatus.NONEXISTENT) { | |
219 // tell the user that the document has to be created before he/she | |
220 // can download it | |
221 logger.debug("PDFCache: " + documentid + " has STATUS_NONEXISTENT."); | |
222 jsp = JSP_WIP; | |
223 } else if (status == PDFStatus.WIP) { | |
224 logger.debug("PDFCache: " + documentid + " has STATUS_WIP."); | |
225 jsp = JSP_WIP; | |
226 | |
227 // TODO: estimate remaining work time | |
228 // TODO: tell the user he/she has to wait | |
229 } else if (status == PDFStatus.DONE) { | |
230 logger.debug("PDFCache: " + documentid + " has STATUS_DONE."); | |
231 } else { | |
232 logger.debug("PDFCache: " + documentid + " has STATUS_ERROR."); | |
233 jsp = JSP_ERROR; | |
234 } | |
235 | |
236 try { | |
237 // forward to the relevant jsp | |
238 ServletContext context = getServletContext(); | |
239 RequestDispatcher dispatch = context.getRequestDispatcher(jsp); | |
240 dispatch.forward(request, response); | |
241 } catch (ServletException e) { | |
242 logger.debug(e.getMessage()); | |
243 e.printStackTrace(); | |
244 } catch (IOException e) { | |
245 logger.debug(e.getMessage()); | |
246 e.printStackTrace(); | |
247 } | |
248 | |
249 } | |
250 | |
251 | |
252 /** check the status of the document corresponding to the documentid */ | |
253 public PDFStatus getStatus(String documentid){ | |
254 // looks into the cache and temp directory in order to find out the status of the document | |
255 File cached = getCacheFile(documentid); | |
256 File wip = getTempFile(documentid); | |
257 if(cached.exists()){ | |
258 return PDFStatus.DONE; | |
259 } else if (wip.exists()){ | |
260 return PDFStatus.WIP; | |
261 } else { | |
262 return PDFStatus.NONEXISTENT; | |
263 } | |
264 } | |
265 | |
266 /** | |
267 * create new thread for pdf generation. | |
268 * | |
269 * @param pdfji | |
270 * @param filename | |
271 * @return | |
272 * @throws FileNotFoundException | |
273 */ | |
274 public Future<File> createNewPdfDocument(PDFRequest pdfji, String filename) throws FileNotFoundException{ | |
275 // start new worker | |
276 File tempf = this.getTempFile(filename); | |
277 File finalf = this.getCacheFile(filename); | |
278 PDFFileWorker job = new PDFFileWorker(dlConfig, tempf, finalf, pdfji, pdfImageJobCenter); | |
279 // start job | |
280 Future<File> jobTicket = pdfJobCenter.submit(job); | |
281 return jobTicket; | |
282 } | |
283 | |
284 | |
285 /** | |
286 * generate the filename the user is going to receive the pdf as | |
287 * | |
288 * @param pdfji | |
289 * @return | |
290 */ | |
291 public String getDownloadFilename(PDFRequest pdfji){ | |
292 // filename example: digilib_example_pgs1-3.pdf | |
293 String filename; | |
294 filename = "digilib_"; | |
295 filename += pdfji.getAsString("fn"); | |
296 filename += "_pgs" + pdfji.getAsString("pgs"); | |
297 filename += ".pdf"; | |
298 | |
299 return filename; | |
300 } | |
301 | |
302 public File getCacheDirectory(){ | |
303 return cache_directory; | |
304 } | |
305 | |
306 public File getTempDirectory(){ | |
307 return temp_directory; | |
308 } | |
309 | |
310 /** | |
311 * returns a File object based on filename in the temp directory. | |
312 * @param filename | |
313 * @return | |
314 */ | |
315 public File getTempFile(String filename) { | |
316 return new File(temp_directory, filename); | |
317 } | |
318 | |
319 /** | |
320 * returns a File object based on filename in the cache directory. | |
321 * @param filename | |
322 * @return | |
323 */ | |
324 public File getCacheFile(String filename) { | |
325 return new File(cache_directory, filename); | |
326 } | |
327 } |