903
|
1 /*
|
|
2 * ServletOps -- Servlet utility class
|
|
3 *
|
|
4 * Digital Image Library servlet components
|
|
5 *
|
|
6 * Copyright (C) 2001, 2002 Robert Casties (robcast@mail.berlios.de)
|
|
7 *
|
|
8 * This program is free software; you can redistribute it and/or modify it under
|
|
9 * the terms of the GNU General Public License as published by the Free Software
|
|
10 * Foundation; either version 2 of the License, or (at your option) any later
|
|
11 * version.
|
|
12 *
|
|
13 * Please read license.txt for the full details. A copy of the GPL may be found
|
|
14 * at http://www.gnu.org/copyleft/lgpl.html
|
|
15 *
|
|
16 * You should have received a copy of the GNU General Public License along with
|
|
17 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
|
18 * Place, Suite 330, Boston, MA 02111-1307 USA
|
|
19 *
|
|
20 */
|
|
21
|
|
22 package digilib.servlet;
|
|
23
|
|
24 import java.io.File;
|
|
25 import java.io.FileInputStream;
|
|
26 import java.io.IOException;
|
|
27 import java.io.OutputStream;
|
|
28 import java.io.PrintWriter;
|
|
29 import java.util.Enumeration;
|
|
30 import java.util.StringTokenizer;
|
|
31
|
|
32 import javax.servlet.ServletContext;
|
|
33 import javax.servlet.ServletException;
|
|
34 import javax.servlet.http.HttpServletRequest;
|
|
35 import javax.servlet.http.HttpServletResponse;
|
|
36
|
|
37 import org.apache.log4j.Logger;
|
|
38
|
|
39 import digilib.image.DocuImage;
|
|
40 import digilib.image.ImageOpException;
|
|
41 import digilib.io.FileOps;
|
|
42
|
|
43 public class ServletOps {
|
|
44
|
|
45 private static Logger logger = Logger.getLogger("servlet.op");
|
|
46
|
|
47 /**
|
|
48 * convert a string with a list of pathnames into an array of strings using
|
|
49 * the system's path seperator string
|
|
50 */
|
|
51 public static String[] getPathArray(String paths) {
|
|
52 // split list into directories
|
|
53 StringTokenizer dirs = new StringTokenizer(paths,
|
|
54 java.io.File.pathSeparator);
|
|
55 int n = dirs.countTokens();
|
|
56 if (n < 1) {
|
|
57 return null;
|
|
58 }
|
|
59 // add directories into array
|
|
60 String[] pathArray = new String[n];
|
|
61 for (int i = 0; i < n; i++) {
|
|
62 pathArray[i] = dirs.nextToken();
|
|
63 }
|
|
64 return pathArray;
|
|
65 }
|
|
66
|
|
67 /**
|
|
68 * get a real File for a web app File.
|
|
69 *
|
|
70 * If the File is not absolute the path is appended to the base directory of
|
|
71 * the web-app.
|
|
72 *
|
|
73 * @param file
|
|
74 * @param sc
|
|
75 * @return
|
|
76 */
|
|
77 public static File getFile(File f, ServletContext sc) {
|
|
78 // is the filename absolute?
|
|
79 if (!f.isAbsolute()) {
|
|
80 // relative path -> use getRealPath to resolve in WEB-INF
|
|
81 String fn = sc.getRealPath(f.getPath());
|
|
82 f = new File(fn);
|
|
83 }
|
|
84 return f;
|
|
85 }
|
|
86
|
|
87 /**
|
|
88 * get a real file name for a web app file pathname.
|
|
89 *
|
|
90 * If filename starts with "/" its treated as absolute else the path is
|
|
91 * appended to the base directory of the web-app.
|
|
92 *
|
|
93 * @param filename
|
|
94 * @param sc
|
|
95 * @return
|
|
96 */
|
|
97 public static String getFile(String filename, ServletContext sc) {
|
|
98 File f = new File(filename);
|
|
99 // is the filename absolute?
|
|
100 if (!f.isAbsolute()) {
|
|
101 // relative path -> use getRealPath to resolve in WEB-INF
|
|
102 filename = sc.getRealPath(filename);
|
|
103 }
|
|
104 return filename;
|
|
105 }
|
|
106
|
|
107 /**
|
|
108 * get a real File for a config File.
|
|
109 *
|
|
110 * If the File is not absolute the path is appended to the WEB-INF directory
|
|
111 * of the web-app.
|
|
112 *
|
|
113 * @param file
|
|
114 * @param sc
|
|
115 * @return
|
|
116 */
|
|
117 public static File getConfigFile(File f, ServletContext sc) {
|
|
118 String fn = f.getPath();
|
|
119 // is the filename absolute?
|
|
120 if (f.isAbsolute()) {
|
|
121 // does it exist?
|
|
122 if (f.canRead()) {
|
|
123 // fine
|
|
124 return f;
|
|
125 } else {
|
|
126 // try just the filename as relative
|
|
127 fn = f.getName();
|
|
128 }
|
|
129 }
|
|
130 // relative path -> use getRealPath to resolve in WEB-INF
|
|
131 String newfn = sc.getRealPath("WEB-INF/" + fn);
|
|
132 f = new File(newfn);
|
|
133 return f;
|
|
134 }
|
|
135
|
|
136 /**
|
|
137 * get a real file name for a config file pathname.
|
|
138 *
|
|
139 * If filename starts with "/" its treated as absolute else the path is
|
|
140 * appended to the WEB-INF directory of the web-app.
|
|
141 *
|
|
142 * @param filename
|
|
143 * @param sc
|
|
144 * @return
|
|
145 */
|
|
146 public static String getConfigFile(String filename, ServletContext sc) {
|
|
147 File f = new File(filename);
|
|
148 // is the filename absolute?
|
|
149 if (!f.isAbsolute()) {
|
|
150 // relative path -> use getRealPath to resolve in WEB-INF
|
|
151 filename = sc.getRealPath("WEB-INF/" + filename);
|
|
152 }
|
|
153 return filename;
|
|
154 }
|
|
155
|
|
156 /**
|
|
157 * print a servlet response
|
|
158 */
|
|
159 public static void htmlMessage(String msg, HttpServletResponse response)
|
|
160 throws IOException {
|
|
161 htmlMessage("Scaler", msg, response);
|
|
162 }
|
|
163
|
|
164 /**
|
|
165 * print a servlet response
|
|
166 */
|
|
167 public static void htmlMessage(String title, String msg,
|
|
168 HttpServletResponse response) throws IOException {
|
|
169 response.setContentType("text/html; charset=iso-8859-1");
|
|
170 PrintWriter out = response.getWriter();
|
|
171 out.println("<html>");
|
|
172 out.println("<head><title>" + title + "</title></head>");
|
|
173 out.println("<body>");
|
|
174 out.println("<p>" + msg + "</p>");
|
|
175 out.println("</body></html>");
|
|
176 }
|
|
177
|
|
178 /**
|
|
179 * Transfers an image file as-is with the mime type mt.
|
|
180 *
|
|
181 * The local file is copied to the <code>OutputStream</code> of the
|
|
182 * <code>ServletResponse</code>. If mt is null then the mime-type is
|
|
183 * auto-detected with mimeForFile.
|
|
184 *
|
|
185 * @param f
|
|
186 * Image file to be sent.
|
|
187 * @param mt
|
|
188 * mime-type of the file.
|
|
189 * @param name
|
|
190 * name of the download file (for application/x)
|
|
191 * @param res
|
|
192 * ServletResponse where the image file will be sent.
|
|
193 * @throws ImageOpException
|
|
194 * @throws ServletException
|
|
195 * Exception on sending data.
|
|
196 * @throws IOException
|
|
197 */
|
|
198 public static void sendFile(File f, String mt, String name,
|
|
199 HttpServletResponse response) throws ImageOpException, IOException {
|
|
200 // use default logger
|
|
201 ServletOps.sendFile(f, mt, name, response, ServletOps.logger);
|
|
202 }
|
|
203
|
|
204 /**
|
|
205 * Transfers an image file as-is with the mime type mt.
|
|
206 *
|
|
207 * The local file is copied to the <code>OutputStream</code> of the
|
|
208 * <code>ServletResponse</code>. If mt is null then the mime-type is
|
|
209 * auto-detected with mimeForFile.
|
|
210 * @param f
|
|
211 * Image file to be sent.
|
|
212 * @param mt
|
|
213 * mime-type of the file.
|
|
214 * @param name
|
|
215 * name of the download file (for application/x)
|
|
216 * @param res
|
|
217 * ServletResponse where the image file will be sent.
|
|
218 * @param logger
|
|
219 * Logger to use
|
|
220 * @throws ImageOpException
|
|
221 * @throws ServletException Exception on sending data.
|
|
222 * @throws IOException
|
|
223 */
|
|
224 public static void sendFile(File f, String mt, String name, HttpServletResponse response, Logger logger)
|
|
225 throws ImageOpException, IOException {
|
|
226 logger.debug("sendRawFile(" + mt + ", " + f + ")");
|
|
227 if (response == null) {
|
|
228 logger.error("No response!");
|
|
229 return;
|
|
230 }
|
|
231 if (mt == null) {
|
|
232 // auto-detect mime-type
|
|
233 mt = FileOps.mimeForFile(f);
|
|
234 if (mt == null) {
|
|
235 throw new ImageOpException("Unknown file type.");
|
|
236 }
|
|
237 }
|
|
238 response.setContentType(mt);
|
|
239 // open file
|
|
240 if (mt.startsWith("application")) {
|
|
241 if (name == null) {
|
|
242 // no download name -- use filename
|
|
243 name = f.getName();
|
|
244 }
|
|
245 response.addHeader("Content-Disposition", "attachment; filename=\""+name+"\"");
|
|
246 }
|
|
247 FileInputStream inFile = null;
|
|
248 try {
|
|
249 inFile = new FileInputStream(f);
|
|
250 OutputStream outStream = response.getOutputStream();
|
|
251 // TODO: should we set content length?
|
|
252 // see http://www.prozesse-und-systeme.de/servletFlush.html
|
|
253 response.setContentLength( (int) f.length());
|
|
254 byte dataBuffer[] = new byte[4096];
|
|
255 int len;
|
|
256 while ((len = inFile.read(dataBuffer)) != -1) {
|
|
257 // copy out file
|
|
258 outStream.write(dataBuffer, 0, len);
|
|
259 }
|
|
260 } finally {
|
|
261 try {
|
|
262 if (inFile != null) {
|
|
263 inFile.close();
|
|
264 }
|
|
265 } catch (IOException e) {
|
|
266 // nothing to do
|
|
267 }
|
|
268 }
|
|
269 }
|
|
270
|
|
271 /**
|
|
272 * Write image img to ServletResponse response.
|
|
273 *
|
|
274 * @param img
|
|
275 * @param mimeType
|
|
276 * @param response
|
|
277 * @throws ImageOpException
|
|
278 * @throws ServletException Exception on sending data.
|
|
279 */
|
|
280 public static void sendImage(DocuImage img, String mimeType,
|
|
281 HttpServletResponse response) throws ImageOpException,
|
|
282 ServletException {
|
|
283 ServletOps.sendImage(img, mimeType, response, ServletOps.logger);
|
|
284 }
|
|
285
|
|
286 /**
|
|
287 * Write image img to ServletResponse response.
|
|
288 *
|
|
289 * @param img
|
|
290 * @param mimeType
|
|
291 * @param response
|
|
292 * @param logger
|
|
293 * @throws ImageOpException
|
|
294 * @throws ServletException Exception on sending data.
|
|
295 */
|
|
296 public static void sendImage(DocuImage img, String mimeType,
|
|
297 HttpServletResponse response, Logger logger) throws ImageOpException,
|
|
298 ServletException {
|
|
299 if (response == null) {
|
|
300 logger.error("No response!");
|
|
301 return;
|
|
302 }
|
|
303 //logger.debug("sending to response: ("+ headersToString(response) + ") committed=" + response.isCommitted());
|
|
304 logger.debug("sending to response. committed=" + response.isCommitted());
|
|
305 // TODO: should we erase or replace old last-modified header?
|
|
306 try {
|
|
307 OutputStream outstream = response.getOutputStream();
|
|
308 // setup output -- if mime type is set use that otherwise
|
|
309 // if source is JPG then dest will be JPG else it's PNG
|
|
310 if (mimeType == null) {
|
|
311 mimeType = img.getMimetype();
|
|
312 if (mimeType == null) {
|
|
313 // still no mime-type
|
|
314 logger.warn("sendImage without mime-type! using image/jpeg.");
|
|
315 mimeType = "image/jpeg";
|
|
316 }
|
|
317 }
|
|
318 if ((mimeType.equals("image/jpeg") || mimeType.equals("image/jp2") ||
|
|
319 mimeType.equals("image/fpx"))) {
|
|
320 mimeType = "image/jpeg";
|
|
321 } else {
|
|
322 mimeType = "image/png";
|
|
323 }
|
|
324 // write the image
|
|
325 response.setContentType(mimeType);
|
|
326 img.writeImage(mimeType, outstream);
|
|
327 } catch (IOException e) {
|
|
328 throw new ServletException("Error sending image:", e);
|
|
329 }
|
|
330 // TODO: should we: finally { img.dispose(); }
|
|
331 }
|
|
332
|
|
333 /** Returns text representation of headers for debuggging purposes.
|
|
334 * @param req
|
|
335 * @return
|
|
336 */
|
|
337 public static String headersToString(HttpServletRequest req) {
|
|
338 String s = "";
|
|
339 @SuppressWarnings("unchecked")
|
|
340 Enumeration<String> hns = req.getHeaderNames();
|
|
341 while (hns.hasMoreElements()) {
|
|
342 String hn = hns.nextElement();
|
|
343 s += hn + "=" + req.getHeader(hn) + "; ";
|
|
344 }
|
|
345 return s;
|
|
346 }
|
|
347
|
|
348
|
|
349 } |