Source code: com/RuntimeCollective/webapps/bean/ServletFile.java
1 /* $Header: /home/CVS/rjp/src/com/RuntimeCollective/webapps/bean/ServletFile.java,v 1.8 2003/09/30 15:13:09 joe Exp $
2 * $Revision: 1.8 $
3 * $Date: 2003/09/30 15:13:09 $
4 *
5 * ====================================================================
6 *
7 * Josephine : http://www.runtime-collective.com/josephine/index.html
8 *
9 * Copyright (C) 2003 Runtime Collective
10 *
11 * This product includes software developed by the
12 * Apache Software Foundation (http://www.apache.org/).
13 *
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public
16 * License as published by the Free Software Foundation; either
17 * version 2.1 of the License, or (at your option) any later version.
18 *
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with this library; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28 */
29
30 package com.RuntimeCollective.webapps.bean;
31
32 import com.RuntimeCollective.webapps.RuntimeParameters;
33 import com.RuntimeCollective.webapps.RuntimeDataSource;
34
35 import javax.servlet.http.HttpServletRequest;
36 import javax.servlet.http.HttpSession;
37 import javax.servlet.http.HttpSessionBindingListener;
38 import javax.servlet.http.HttpSessionBindingEvent;
39
40 import java.io.InputStream;
41 import java.io.ByteArrayInputStream;
42 import java.io.ByteArrayOutputStream;
43 import java.io.File;
44 import java.io.FileOutputStream;
45
46 import java.io.IOException;
47 import java.sql.SQLException;
48
49 /** A wrapper to a DBFile which makes it more convenient to use in a servlet
50 * context.
51 *
52 * @version $Id: ServletFile.java,v 1.8 2003/09/30 15:13:09 joe Exp $
53 */
54 public class ServletFile implements HttpSessionBindingListener,
55 DBFile {
56
57 /** The binding name for the temporary file marker.
58 * If the user's session expires before the temporary file is deleted,
59 * then it will be deleted in the session unbind event handler.
60 */
61 public static final String TEMP_FILE_TOKEN = ".TEMP_FILE";
62
63 // == Constructors ====================================================
64
65 public ServletFile(DBFile file) {
66 setFile(file);
67 }
68
69
70 // == Persistence methods ==============================================
71
72 public void save() throws SQLException {
73 file.save();
74 }
75
76
77 public void delete() throws SQLException {
78 file.delete();
79 }
80
81
82 // == Properties =======================================================
83
84 private DBFile file;
85 /** get the file. */
86 public DBFile getFile() { return file; }
87 /** set the file. */
88 public void setFile(DBFile file) { this.file = file; }
89
90 /** get the id. */
91 public int getId() { return file.getId(); }
92 /** set the id. */
93 public void setId(int id) { file.setId(id); }
94
95 /** get the name. */
96 public String getName() { return file.getName(); }
97 /** set the name. */
98 public void setName(String name) { file.setName(name); }
99
100 /** get the mimeType. */
101 public String getMimeType() { return file.getMimeType(); }
102 /** set the mimeType. */
103 public void setMimeType(String mimeType) { file.setMimeType(mimeType); }
104
105 /** get the FileData. */
106 public byte[] getFileData() { return file.getFileData(); }
107 /** set the FileData. */
108 public void setFileData(byte[] fileData) { file.setFileData(fileData); }
109
110
111 // == Utility methods ==================================================
112
113 /** get the url for this file. */
114 // :FIXME: Lee Denison (2002/11/13)
115 // :FIXME this should be moved to a tag
116 public String getUrl() {
117 return getRealUrl(false);
118 }
119
120 public String getTempUrl() {
121 return getRealUrl(true);
122 }
123
124
125 private String getRealUrl(boolean temp) {
126
127 StringBuffer url = new StringBuffer()
128 .append("/")
129 .append(RuntimeParameters.get("servletFile.url"));
130
131 if (!url.toString().endsWith("/")) {
132 url.append("/");
133 }
134
135 if (temp) {
136 url.append(TEMP_URL);
137 } else {
138 url.append(REAL_URL);
139 }
140
141 url.append("/").append(getId());
142 url.append("/").append(getName());
143
144 // DEBUG!
145 if (temp) {
146 RuntimeParameters.logDebug(this, "getTempUrl url: "+url.toString());
147 } else {
148 RuntimeParameters.logDebug(this, "getUrl url: "+url.toString());
149 }
150
151 return url.toString();
152 }
153
154
155
156
157
158 public void saveTempFile(HttpServletRequest request)
159 throws IOException {
160
161 // Just return if no file is set
162 if (getFile() == null) {
163 RuntimeParameters.logDebug(this, "saveTempFile: no image for servlet file; returning");
164 return;
165 }
166
167 RuntimeParameters.logDebug(this,
168 "saving temp file for id "
169 + getId());
170
171 if (getFileData() != null) {
172 HttpSession session = request.getSession();
173
174
175 // fill the blank row with the blob
176 ByteArrayInputStream fileDataIS = new ByteArrayInputStream(getFileData());
177 try {
178
179 // delete old file, if it's there
180 deleteTempFile();
181
182 // insert a blank row
183 RuntimeDataSource.update(INSERT +
184 getId() +
185 COMMA +
186 getMimeType() +
187 END_VALUES);
188
189 // update (insert!) the blob
190 RuntimeDataSource.updateBlob( DATABASE_TABLE,
191 WHERE_BLOB_ID_EQUALS + getId(),
192 TEMP_BLOB_COLUMN,
193 fileDataIS,
194 getFileData().length );
195
196 if (null == session.getAttribute(TEMP_FILE_TOKEN + getId())) {
197 session.setAttribute(TEMP_FILE_TOKEN + getId(), this);
198 }
199
200 } catch (SQLException e) {
201 e.printStackTrace(System.out);
202 throw new IOException("Couldn't save temp BLOB "+getId()+" in the database: "+e);
203 }
204 }
205 }
206
207
208 public void deleteTempFile() throws SQLException {
209
210 // Just return if no file is set
211 if (getFile() == null) {
212 RuntimeParameters.logDebug(this, "deleteTempFile: no image for servlet file; returning");
213 return;
214 }
215
216 // Delete the temp file, if it exists
217 RuntimeDataSource.update(DELETE +
218 FROM_FILE +
219 WHERE_ID_EQUALS + getId());
220 }
221
222
223 // == Event handlers =====================================================
224
225 public void valueBound(HttpSessionBindingEvent event) {
226 // Do Nothing
227 }
228
229 public void valueUnbound(HttpSessionBindingEvent event) {
230 if (event.getName().startsWith(TEMP_FILE_TOKEN)) {
231 try {
232 deleteTempFile();
233 } catch (SQLException e) {
234 RuntimeParameters.logWarn(this,
235 "failed to delete temp file",
236 e);
237 }
238 }
239 }
240
241
242
243 // == Misc methods ====================================================
244
245 public static byte[] getTempFileData(int id) {
246
247 try {
248 ByteArrayOutputStream out = new ByteArrayOutputStream();
249 InputStream content = RuntimeDataSource.queryBlob(SELECT_TEMP_BLOB_WHERE_ID_EQUALS + id);
250
251 // FIXME: why 2k chunks? Why not bigger? What's the optimum? Can I use a buffered reader?
252 byte buf[] = new byte[2048];
253 int size = 0;
254 while ((size = content.read(buf)) > 0) {
255 out.write(buf, 0, size);
256 }
257 out.flush();
258
259 return out.toByteArray();
260
261 } catch (SQLException e) {
262 e.printStackTrace(System.out);
263 RuntimeParameters.logError("ServletFile", "failed to load temp file BLOB data "+id+" in the database: ", e);
264 return null;
265 } catch (IOException e) {
266 e.printStackTrace(System.out);
267 RuntimeParameters.logError("ServletFile", "failed to spool temp BLOB data "+id+" in the database: ", e);
268 return null;
269 }
270
271
272 }
273
274
275 // == Constants ========================================================
276
277 public static final String REAL_URL = "real";
278
279 public static final String TEMP_URL = "tmp";
280
281 public static final String TEMP_BLOB_COLUMN = "temp_content";
282
283 public static final String WHERE_BLOB_ID_EQUALS = "id = ";
284
285
286 public static final String DATABASE_TABLE = "rs_servlet_file";
287
288 public static final String SELECT_TEMP_BLOB_WHERE_ID_EQUALS = "SELECT "
289 + TEMP_BLOB_COLUMN
290 + " FROM "
291 + DATABASE_TABLE
292 + " WHERE id = ";
293
294 public static final String DELETE = "DELETE ";
295 public static final String FROM_FILE = "FROM " + DATABASE_TABLE + " ";
296 public static final String WHERE_ID_EQUALS = "WHERE id = ";
297
298 public static final String INSERT = "INSERT INTO " + DATABASE_TABLE + " (ID, MIME_TYPE) VALUES (";
299 public static final String COMMA = ", '";
300 public static final String END_VALUES = "')";
301
302 }