Mercurial > hg > digilib-old
comparison servlet/src/digilib/servlet/Scaler.java @ 544:5ff500d6812a digilibPDF
more steps towards more standard java.util.concurrent design
author | robcast |
---|---|
date | Thu, 14 Oct 2010 20:47:31 +0200 |
parents | 919e008ab1fb |
children | e1094c5ec032 |
comparison
equal
deleted
inserted
replaced
543:919e008ab1fb | 544:5ff500d6812a |
---|---|
1 package digilib.servlet; | 1 package digilib.servlet; |
2 | 2 |
3 import java.io.File; | 3 import java.io.File; |
4 import java.io.IOException; | 4 import java.io.IOException; |
5 import java.io.OutputStream; | |
6 import java.util.List; | 5 import java.util.List; |
7 import java.util.concurrent.ExecutionException; | 6 import java.util.concurrent.ExecutionException; |
8 import java.util.concurrent.ExecutorService; | |
9 import java.util.concurrent.Future; | 7 import java.util.concurrent.Future; |
10 | 8 |
11 import javax.servlet.ServletConfig; | 9 import javax.servlet.ServletConfig; |
12 import javax.servlet.ServletContext; | 10 import javax.servlet.ServletContext; |
13 import javax.servlet.ServletException; | 11 import javax.servlet.ServletException; |
19 import digilib.image.DocuImage; | 17 import digilib.image.DocuImage; |
20 import digilib.image.ImageOpException; | 18 import digilib.image.ImageOpException; |
21 import digilib.io.DocuDirCache; | 19 import digilib.io.DocuDirCache; |
22 import digilib.io.DocuDirectory; | 20 import digilib.io.DocuDirectory; |
23 import digilib.io.DocuDirent; | 21 import digilib.io.DocuDirent; |
24 import digilib.io.FileOpException; | |
25 import digilib.io.FileOps; | 22 import digilib.io.FileOps; |
26 import digilib.io.ImageFile; | 23 import digilib.io.ImageFile; |
27 | 24 |
28 | |
29 // TODO digilibError is not used anymore and may need to get reintegrated | 25 // TODO digilibError is not used anymore and may need to get reintegrated |
30 | 26 |
31 public class Scaler extends RequestHandler { | 27 public class Scaler extends RequestHandler { |
32 | 28 |
33 /** digilib servlet version (for all components) */ | 29 /** digilib servlet version (for all components) */ |
34 public static final String dlVersion = "1.8.1a"; | 30 public static final String dlVersion = "1.8.1a"; |
35 | 31 |
36 /** general error code */ | 32 /** general error code */ |
37 public static final int ERROR_UNKNOWN = 0; | 33 public static final int ERROR_UNKNOWN = 0; |
38 | 34 |
39 /** error code for authentication error */ | 35 /** error code for authentication error */ |
40 public static final int ERROR_AUTH = 1; | 36 public static final int ERROR_AUTH = 1; |
41 | 37 |
42 /** error code for file operation error */ | 38 /** error code for file operation error */ |
43 public static final int ERROR_FILE = 2; | 39 public static final int ERROR_FILE = 2; |
44 | 40 |
45 /** error code for image operation error */ | 41 /** error code for image operation error */ |
46 public static final int ERROR_IMAGE = 3; | 42 public static final int ERROR_IMAGE = 3; |
47 | 43 |
48 /** DocuDirCache instance */ | 44 /** DocuDirCache instance */ |
49 DocuDirCache dirCache; | 45 DocuDirCache dirCache; |
50 | 46 |
51 /** Image executor */ | 47 /** Image executor */ |
52 ExecutorService imageJobCenter; | 48 DigilibJobCenter imageJobCenter; |
53 | 49 |
54 /** authentication error image file */ | 50 /** authentication error image file */ |
55 File denyImgFile; | 51 File denyImgFile; |
56 | 52 |
57 /** image error image file */ | 53 /** image error image file */ |
58 File errorImgFile; | 54 File errorImgFile; |
59 | 55 |
60 /** not found error image file */ | 56 /** not found error image file */ |
61 File notfoundImgFile; | 57 File notfoundImgFile; |
62 | 58 |
63 /** subsampling before scaling */ | 59 /** send files as is? */ |
64 float minSubsample = 2f; | 60 boolean sendFileAllowed = true; |
65 | 61 |
66 /** send files as is? */ | 62 /** DigilibConfiguration instance */ |
67 boolean sendFileAllowed = true; | 63 DigilibConfiguration dlConfig; |
68 | 64 |
69 /** default scaling quality */ | 65 /** use authorization database */ |
70 int defaultQuality = 1; | 66 boolean useAuthorization = true; |
71 | 67 |
72 /** DigilibConfiguration instance */ | 68 /** AuthOps instance */ |
73 DigilibConfiguration dlConfig; | 69 AuthOps authOp; |
74 | 70 |
75 /** use authorization database */ | 71 // EXPRIMENTAL |
76 boolean useAuthorization = true; | 72 /** try to enlarge cropping area for "oblique" angles */ |
77 | 73 boolean wholeRotArea = false; |
78 /** AuthOps instance */ | 74 |
79 AuthOps authOp; | 75 protected long getLastModified(HttpServletRequest request) { |
80 | 76 accountlog.debug("GetLastModified from " + request.getRemoteAddr() |
81 // EXPRIMENTAL | 77 + " for " + request.getQueryString()); |
82 /** try to enlarge cropping area for "oblique" angles */ | 78 long mtime = -1; |
83 boolean wholeRotArea = false; | 79 // create new request with defaults |
84 | 80 DigilibRequest dlReq = new DigilibRequest(); |
85 | 81 // set with request parameters |
86 protected long getLastModified(HttpServletRequest request) { | 82 dlReq.setWithRequest(request); |
87 accountlog.debug("GetLastModified from " + request.getRemoteAddr() | 83 // find the requested file |
88 + " for " + request.getQueryString()); | 84 DocuDirent f = findFile(dlReq); |
89 long mtime = -1; | 85 if (f != null) { |
90 // create new request with defaults | 86 DocuDirectory dd = (DocuDirectory) f.getParent(); |
91 DigilibRequest dlReq = new DigilibRequest(); | 87 mtime = dd.getDirMTime() / 1000 * 1000; |
92 // set with request parameters | 88 } |
93 dlReq.setWithRequest(request); | 89 return mtime; |
94 // find the requested file | 90 } |
95 DocuDirent f = findFile(dlReq); | 91 |
96 if (f != null) { | 92 /** |
97 DocuDirectory dd = (DocuDirectory) f.getParent(); | 93 * Returns the DocuDirent corresponding to the DigilibRequest. |
98 mtime = dd.getDirMTime() / 1000 * 1000; | 94 * |
99 } | 95 * @param dlRequest |
100 return mtime; | 96 * @return |
101 } | 97 */ |
102 | 98 public DocuDirent findFile(DigilibRequest dlRequest) { |
103 /** | 99 // find the file(set) |
104 * Returns the DocuDirent corresponding to the DigilibRequest. | 100 DocuDirent f = dirCache.getFile(dlRequest.getFilePath(), |
105 * | 101 dlRequest.getAsInt("pn"), FileOps.CLASS_IMAGE); |
106 * @param dlRequest | 102 return f; |
107 * @return | 103 } |
108 */ | 104 |
109 public DocuDirent findFile(DigilibRequest dlRequest) { | 105 /** |
110 // find the file(set) | 106 * Initialisation on first run. |
111 DocuDirent f = dirCache.getFile(dlRequest.getFilePath(), dlRequest | 107 * |
112 .getAsInt("pn"), FileOps.CLASS_IMAGE); | 108 * @throws ServletException |
113 return f; | 109 * |
114 } | 110 * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig) |
115 | 111 */ |
116 | 112 public void init(ServletConfig config) throws ServletException { |
117 | 113 super.init(config); |
118 /** | 114 |
119 * Initialisation on first run. | 115 System.out |
120 * @throws ServletException | 116 .println("***** Digital Image Library Image Scaler Servlet (version " |
121 * | 117 + dlVersion + ") *****"); |
122 * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig) | 118 // say hello in the log file |
123 */ | 119 logger.info("***** Digital Image Library Image Scaler Servlet (version " |
124 public void init(ServletConfig config) throws ServletException { | 120 + dlVersion + ") *****"); |
125 super.init(config); | 121 |
126 | 122 // get our ServletContext |
127 System.out | 123 ServletContext context = config.getServletContext(); |
128 .println("***** Digital Image Library Image Scaler Servlet (version " | 124 // see if there is a Configuration instance |
129 + dlVersion + ") *****"); | 125 dlConfig = (DigilibConfiguration) context |
130 // say hello in the log file | 126 .getAttribute("digilib.servlet.configuration"); |
131 logger | 127 if (dlConfig == null) { |
132 .info("***** Digital Image Library Image Scaler Servlet (version " | 128 // no Configuration |
133 + dlVersion + ") *****"); | 129 throw new ServletException("No Configuration!"); |
134 | 130 } |
135 // get our ServletContext | 131 // set our AuthOps |
136 ServletContext context = config.getServletContext(); | 132 useAuthorization = dlConfig.getAsBoolean("use-authorization"); |
137 // see if there is a Configuration instance | 133 authOp = (AuthOps) dlConfig.getValue("servlet.auth.op"); |
138 dlConfig = (DigilibConfiguration) context | 134 |
139 .getAttribute("digilib.servlet.configuration"); | 135 // DocuDirCache instance |
140 if (dlConfig == null) { | 136 dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache"); |
141 // no Configuration | 137 |
142 throw new ServletException("No Configuration!"); | 138 // Executor |
143 } | 139 imageJobCenter = (DigilibJobCenter) dlConfig |
144 // set our AuthOps | 140 .getValue("servlet.worker.imageexecutor"); |
145 useAuthorization = dlConfig.getAsBoolean("use-authorization"); | 141 |
146 authOp = (AuthOps) dlConfig.getValue("servlet.auth.op"); | 142 denyImgFile = ServletOps.getFile( |
147 | 143 (File) dlConfig.getValue("denied-image"), config); |
148 // DocuDirCache instance | 144 errorImgFile = ServletOps.getFile( |
149 dirCache = (DocuDirCache) dlConfig.getValue("servlet.dir.cache"); | 145 (File) dlConfig.getValue("error-image"), config); |
150 | 146 notfoundImgFile = ServletOps.getFile( |
151 // Executor | 147 (File) dlConfig.getValue("notfound-image"), config); |
152 imageJobCenter = (ExecutorService) dlConfig.get("servlet.worker.imageexecutor"); | 148 sendFileAllowed = dlConfig.getAsBoolean("sendfile-allowed"); |
153 | 149 } |
154 denyImgFile = ServletOps.getFile((File) dlConfig.getValue("denied-image"), config); | 150 |
155 errorImgFile = ServletOps.getFile((File) dlConfig.getValue("error-image"), config); | 151 @Override |
156 notfoundImgFile = ServletOps.getFile((File) dlConfig.getValue("notfound-image"), config); | 152 public void processRequest(HttpServletRequest request, |
157 sendFileAllowed = dlConfig.getAsBoolean("sendfile-allowed"); | 153 HttpServletResponse response) throws ServletException, |
158 minSubsample = dlConfig.getAsFloat("subsample-minimum"); | 154 ImageOpException { |
159 defaultQuality = dlConfig.getAsInt("default-quality"); | 155 |
160 } | 156 if (dlConfig == null) { |
161 | 157 throw new ServletException("ERROR: No Configuration!"); |
162 | 158 } |
163 | 159 |
164 | 160 accountlog.debug("request: " + request.getQueryString()); |
165 @Override | 161 logger.debug("request: " + request.getQueryString()); |
166 public void processRequest(HttpServletRequest request, | 162 long startTime = System.currentTimeMillis(); |
167 HttpServletResponse response) throws ServletException, ImageOpException { | 163 |
168 | 164 // define the job information |
169 | 165 ImageJobInformation jobdeclaration = new ImageJobInformation(dlConfig); |
170 if (dlConfig == null) { | 166 jobdeclaration.setWithRequest(request); |
171 throw new ServletException("ERROR: No Configuration!"); | 167 |
172 } | 168 // DigilibWorker1 job=null; |
173 | 169 ImageWorker job = null; |
174 accountlog.debug("request: " + request.getQueryString()); | 170 try { |
175 logger.debug("request: " + request.getQueryString()); | 171 |
176 | 172 ImageFile fileToLoad = jobdeclaration.get_fileToLoad(); |
177 | 173 |
178 // define the job information | 174 /* check permissions */ |
179 ImageJobInformation jobdeclaration = new ImageJobInformation(dlConfig); | 175 if (useAuthorization) { |
180 jobdeclaration.setWithRequest(request); | 176 // get a list of required roles (empty if no restrictions) |
181 | 177 List<String> rolesRequired = authOp.rolesForPath( |
182 ImageFile fileToLoad = null; | 178 jobdeclaration.getFilePath(), request); |
183 try { | 179 if (rolesRequired != null) { |
184 fileToLoad = jobdeclaration.get_fileToLoad(); | 180 authlog.debug("Role required: " + rolesRequired); |
185 } catch (IOException e2) { | 181 authlog.debug("User: " + request.getRemoteUser()); |
186 // TODO Auto-generated catch block | 182 // is the current request/user authorized? |
187 e2.printStackTrace(); | 183 if (!authOp.isRoleAuthorized(rolesRequired, request)) { |
188 return; | 184 // send deny answer and abort |
189 } | 185 throw new AuthOpException(); |
190 | 186 } |
191 | 187 } |
192 // if requested, send image as a file | 188 } |
193 if(sendFileAllowed && jobdeclaration.checkSendAsFile()){ | 189 |
194 String mt = null; | 190 // if requested, send image as a file |
195 if (jobdeclaration.hasOption("mo", "rawfile")) { | 191 if (sendFileAllowed && jobdeclaration.checkSendAsFile()) { |
196 mt = "application/octet-stream"; | 192 String mt = null; |
197 } | 193 if (jobdeclaration.hasOption("mo", "rawfile")) { |
198 logger.debug("Sending RAW File as is."); | 194 mt = "application/octet-stream"; |
199 try { | 195 } |
200 ServletOps.sendFile(fileToLoad.getFile(), mt, response); | 196 logger.debug("Sending RAW File as is."); |
201 } catch (FileOpException e) { | 197 logger.info("Done in " + (System.currentTimeMillis() - startTime) + "ms"); |
202 e.printStackTrace(); | 198 ServletOps.sendFile(fileToLoad.getFile(), mt, response); |
203 } | 199 return; |
204 | 200 } |
205 return; | 201 |
206 } | 202 // if possible, send the image without actually having to transform |
207 | 203 // it |
208 | 204 if (jobdeclaration.noTransformRequired()) { |
209 | 205 logger.debug("Sending File as is."); |
210 // if possible, send the image without actually having to transform it | 206 ServletOps.sendFile(fileToLoad.getFile(), null, response); |
211 if(jobdeclaration.noTransformRequired()){ | 207 logger.info("Done in " + (System.currentTimeMillis() - startTime) + "ms"); |
212 logger.debug("Sending File as is."); | 208 return; |
213 | 209 } |
214 try { | 210 |
215 ServletOps.sendFile(fileToLoad.getFile(), null, response); | 211 // check load of workers |
216 } catch (FileOpException e) { | 212 if (imageJobCenter.isBusy()) { |
217 e.printStackTrace(); | 213 logger.error("Servlet overloaded!"); |
218 } | 214 response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); |
219 | 215 return; |
220 //logger.info("Done in " | 216 } |
221 // + (System.currentTimeMillis() - startTime) + "ms"); | 217 // create job |
222 return; | 218 job = new ImageWorker(dlConfig, jobdeclaration); |
223 } | 219 // submit job |
224 | |
225 | |
226 | |
227 | |
228 if (! DigilibWorker1.canRun()) { | |
229 logger.error("Servlet overloaded!"); | |
230 try { | |
231 response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); | |
232 } catch (IOException e) { | |
233 e.printStackTrace(); | |
234 } | |
235 return; | |
236 } | |
237 | |
238 | |
239 //DigilibWorker1 job=null; | |
240 ImageWorker job = null; | |
241 try { | |
242 | |
243 long startTime = System.currentTimeMillis(); | |
244 | |
245 OutputStream outputstream = null; | |
246 outputstream = response.getOutputStream(); | |
247 | |
248 /* check permissions */ | |
249 if (useAuthorization) { | |
250 // get a list of required roles (empty if no restrictions) | |
251 List<String> rolesRequired; | |
252 try { | |
253 rolesRequired = authOp.rolesForPath(jobdeclaration.getFilePath(), request); | |
254 if (rolesRequired != null) { | |
255 authlog.debug("Role required: " + rolesRequired); | |
256 authlog.debug("User: " + request.getRemoteUser()); | |
257 // is the current request/user authorized? | |
258 if (!authOp.isRoleAuthorized(rolesRequired, request)) { | |
259 // send deny answer and abort | |
260 throw new AuthOpException(); | |
261 } | |
262 } | |
263 | |
264 } catch (AuthOpException e) { | |
265 // TODO Auto-generated catch block | |
266 e.printStackTrace(); | |
267 } | |
268 } | |
269 | |
270 | |
271 //job = new DigilibImageWorker1(dlConfig, outputstream , jobdeclaration); | |
272 //job.run(); | |
273 | |
274 // create job | |
275 job = new ImageWorker(dlConfig, jobdeclaration); | |
276 // submit job | |
277 Future<DocuImage> jobResult = imageJobCenter.submit(job); | 220 Future<DocuImage> jobResult = imageJobCenter.submit(job); |
278 // wait for result | 221 // wait for result |
279 DocuImage img = jobResult.get(); | 222 DocuImage img = jobResult.get(); |
280 // send image | 223 // send image |
281 ServletOps.writeImage(img, null, outputstream); | 224 ServletOps.sendImage(img, null, response); |
282 | 225 logger.debug("Job Processing Time: " |
283 logger.debug("Job Processing Time: "+ (System.currentTimeMillis()-startTime) + "ms"); | 226 + (System.currentTimeMillis() - startTime) + "ms"); |
284 | 227 |
285 } catch (IOException e) { | 228 } catch (IOException e) { |
286 e.printStackTrace(); | 229 logger.error(e.getClass() + ": " + e.getMessage()); |
287 logger.error(e.getClass()+": "+ e.getMessage()); | 230 // response.sendError(1); |
288 //response.sendError(1); | 231 } catch (AuthOpException e) { |
289 } catch (InterruptedException e) { | 232 logger.error(e.getClass() + ": " + e.getMessage()); |
290 // TODO Auto-generated catch block | 233 // response.sendError(1); |
291 e.printStackTrace(); | 234 } catch (InterruptedException e) { |
292 logger.error(e.getClass()+": "+ e.getMessage()); | 235 logger.error(e.getClass() + ": " + e.getMessage()); |
293 } catch (ExecutionException e) { | 236 } catch (ExecutionException e) { |
294 // TODO Auto-generated catch block | 237 logger.error(e.getClass() + ": " + e.getMessage()); |
295 e.printStackTrace(); | 238 logger.error("caused by: " + e.getCause().getMessage()); |
296 logger.error(e.getClass()+": "+ e.getMessage()); | 239 } |
297 logger.error("caused by: "+ e.getCause().getMessage()); | 240 |
298 } | 241 } |
299 | 242 |
300 } | 243 /** |
301 | 244 * Sends an error to the client as text or image. |
302 | 245 * |
303 /** | 246 * @param asHTML |
304 * Sends an error to the client as text or image. | 247 * @param type |
305 * | 248 * @param msg |
306 * @param asHTML | 249 * @param response |
307 * @param type | 250 */ |
308 * @param msg | 251 public void digilibError(boolean asHTML, int type, String msg, |
309 * @param response | 252 HttpServletResponse response) { |
310 */ | 253 try { |
311 public void digilibError(boolean asHTML, int type, String msg, | 254 File img = null; |
312 HttpServletResponse response) { | 255 if (type == ERROR_AUTH) { |
313 try { | 256 if (msg == null) { |
314 File img = null; | 257 msg = "ERROR: Unauthorized access!"; |
315 if (type == ERROR_AUTH) { | 258 } |
316 if (msg == null) { | 259 img = denyImgFile; |
317 msg = "ERROR: Unauthorized access!"; | 260 } else if (type == ERROR_FILE) { |
318 } | 261 if (msg == null) { |
319 img = denyImgFile; | 262 msg = "ERROR: Image file not found!"; |
320 } else if (type == ERROR_FILE) { | 263 } |
321 if (msg == null) { | 264 img = notfoundImgFile; |
322 msg = "ERROR: Image file not found!"; | 265 } else { |
323 } | 266 if (msg == null) { |
324 img = notfoundImgFile; | 267 msg = "ERROR: Other image error!"; |
325 } else { | 268 } |
326 if (msg == null) { | 269 img = this.errorImgFile; |
327 msg = "ERROR: Other image error!"; | 270 } |
328 } | 271 if (asHTML && (img != null)) { |
329 img = this.errorImgFile; | 272 ServletOps.htmlMessage(msg, response); |
330 } | 273 } else { |
331 if (asHTML && (img != null)) { | 274 ServletOps.sendFile(img, null, response); |
332 ServletOps.htmlMessage(msg, response); | 275 } |
333 } else { | 276 } catch (IOException e) { |
334 ServletOps.sendFile(img, null, response); | 277 logger.error("Error sending error!", e); |
335 } | 278 } |
336 } catch (IOException e) { | 279 |
337 logger.error("Error sending error!", e); | 280 } |
338 } | 281 |
339 | 282 public static String getVersion() { |
340 } | 283 return dlVersion; |
341 | 284 } |
342 public static String getVersion(){ | |
343 return dlVersion; | |
344 } | |
345 | |
346 | 285 |
347 } | 286 } |