KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jcorporate > expresso > services > controller > dbmaint > ViewBlob


1 /* ====================================================================
2  * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
3  *
4  * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution,
19  * if any, must include the following acknowledgment:
20  * "This product includes software developed by Jcorporate Ltd.
21  * (http://www.jcorporate.com/)."
22  * Alternately, this acknowledgment may appear in the software itself,
23  * if and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. "Jcorporate" and product names such as "Expresso" must
26  * not be used to endorse or promote products derived from this
27  * software without prior written permission. For written permission,
28  * please contact info@jcorporate.com.
29  *
30  * 5. Products derived from this software may not be called "Expresso",
31  * or other Jcorporate product names; nor may "Expresso" or other
32  * Jcorporate product names appear in their name, without prior
33  * written permission of Jcorporate Ltd.
34  *
35  * 6. No product derived from this software may compete in the same
36  * market space, i.e. framework, without prior written permission
37  * of Jcorporate Ltd. For written permission, please contact
38  * partners@jcorporate.com.
39  *
40  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
41  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43  * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
44  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
46  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
47  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This software consists of voluntary contributions made by many
55  * individuals on behalf of the Jcorporate Ltd. Contributions back
56  * to the project(s) are encouraged when you make modifications.
57  * Please send them to support@jcorporate.com. For more information
58  * on Jcorporate Ltd. and its products, please see
59  * <http://www.jcorporate.com/>.
60  *
61  * Portions of this software are based upon other open source
62  * products and are subject to their respective licenses.
63  */

64 package com.jcorporate.expresso.services.controller.dbmaint;
65
66 import com.jcorporate.expresso.core.controller.ControllerException;
67 import com.jcorporate.expresso.core.controller.ControllerRequest;
68 import com.jcorporate.expresso.core.controller.ControllerResponse;
69 import com.jcorporate.expresso.core.controller.ErrorCollection;
70 import com.jcorporate.expresso.core.controller.NonHandleableException;
71 import com.jcorporate.expresso.core.controller.ServletControllerRequest;
72 import com.jcorporate.expresso.core.dataobjects.DataObject;
73 import com.jcorporate.expresso.core.dataobjects.NestableDataObject;
74 import com.jcorporate.expresso.core.dataobjects.Securable;
75 import com.jcorporate.expresso.core.dataobjects.jdbc.JDBCDataObject;
76 import com.jcorporate.expresso.core.dataobjects.jdbc.LobField;
77 import com.jcorporate.expresso.core.db.DBException;
78 import com.jcorporate.expresso.core.dbobj.SecuredDBObject;
79 import com.jcorporate.expresso.core.misc.StringUtil;
80 import com.jcorporate.expresso.core.security.User;
81 import com.jcorporate.expresso.services.dbobj.MediaDBObject;
82 import com.jcorporate.expresso.services.dbobj.MimeTypes;
83 import com.jcorporate.expresso.services.dbobj.Setup;
84 import org.apache.log4j.Logger;
85
86 import javax.servlet.ServletOutputStream JavaDoc;
87 import javax.servlet.ServletResponse JavaDoc;
88 import javax.servlet.http.HttpServletResponse JavaDoc;
89 import java.io.InputStream JavaDoc;
90
91
92 /**
93  * This state allows for viewing of BLOB data types. It supports standard
94  * blob types by sending a mime type of application/x-unknown, and is supports
95  * MediaDbObjects be setting MIME type, file name, and size to that of the
96  * file that was originally uploaded to the database table.
97  *
98  * @author Michael Rimov
99  * @version $Revision: 1.11 $ on $Date: 2004/11/17 20:48:18 $
100  */

101
102 public class ViewBlob extends DynamicCmd {
103
104     /**
105      * The log4j Logger.
106      */

107     private static Logger log = Logger.getLogger(ViewBlob.class);
108
109     /**
110      * Constructor that sets the necessary description and key name.
111      */

112     public ViewBlob() {
113         super("ViewBlob", "Binary File Contents");
114         this.addRequiredParameter("fieldName");
115     }
116
117     /**
118      * Download the BLOB field.
119      *
120      * @param newRequest The ControllerRequest Object
121      * @param newResponse The ControllerREsponse OBject
122      */

123     public void run(ControllerRequest newRequest, ControllerResponse newResponse)
124             throws com.jcorporate.expresso.core.controller.NonHandleableException,
125             com.jcorporate.expresso.core.controller.ControllerException {
126         super.run(newRequest, newResponse);
127
128         DataObject curDBObj = null;
129         try {
130             curDBObj = this.retrieveMyDBObject();
131
132
133             //
134
//Check = Is curDBObj an instance of JDBCDataObject OR if it is
135
//a nested object, then is the embedded data object that we're going to
136
//use a JDBCDataObject?
137
//
138

139             if (curDBObj instanceof NestableDataObject) {
140                 if (!(((NestableDataObject) curDBObj).getNestedFromFieldName(newRequest.getParameter("fieldName")) instanceof JDBCDataObject)) {
141                     ErrorCollection ee = new ErrorCollection();
142                     ee.addError("Blob viewing is only possible under nested JDBC dataobjects.");
143                     newResponse.saveErrors(ee);
144                     this.transition("Update", newRequest, newResponse);
145                     return;
146                 }
147             } else if (!(curDBObj instanceof JDBCDataObject)) {
148                 ErrorCollection ee = new ErrorCollection();
149                 ee.addError("Blob viewing is only possible under JDBC dataobjects.");
150                 newResponse.saveErrors(ee);
151                 this.transition("Update", newRequest, newResponse);
152                 return;
153             }
154         } catch (DBException ex) {
155             ErrorCollection ee = new ErrorCollection();
156             ee.addError(ex);
157             newResponse.saveErrors(ee);
158             this.transition("Update", newRequest, newResponse);
159             return;
160         }
161
162         if (!(newRequest instanceof ServletControllerRequest)) {
163             throw new ControllerException("This state can only be" +
164                     " run inside an HTTP Servlet Environment");
165         }
166
167         try {
168             //Check Security
169
if (curDBObj instanceof Securable) {
170                 ((Securable) curDBObj).isAllowed("S");
171             } else {
172                 if (getUid() == SecuredDBObject.SYSTEM_ACCOUNT
173                         || User.getUserFromId(getUid(), this.getControllerRequest().getDataContext()).isAdmin()) {
174                     // all access ok
175
} else {
176                     String JavaDoc allowInsecure = Setup.getValue(newRequest.getDataContext(),
177                             com.jcorporate.expresso.core.ExpressoSchema.class.getName(),
178                             "insecureDBMaint");
179                     if (!(StringUtil.toBoolean(allowInsecure))) {
180                         throw new SecurityException JavaDoc("Access to unsecured Objects not allowed");
181                     }
182                 }
183             }
184         } catch (DBException ex) {
185             throw new ControllerException("Not allowed.", ex);
186         }
187
188
189         //
190
//Get the field Name
191
//
192
String JavaDoc fieldName = newRequest.getParameter("fieldName");
193
194
195         DataObject curDataObjectToUse = curDBObj;
196         if (curDataObjectToUse instanceof NestableDataObject) {
197             String JavaDoc fullFieldName = fieldName;
198             fieldName = ((NestableDataObject) curDataObjectToUse).getFieldFromNestedName(fieldName);
199             curDataObjectToUse = ((NestableDataObject) curDataObjectToUse).getNestedFromFieldName(fullFieldName);
200         }
201
202
203         //
204
//Parameter and environment Checks
205
//
206
if (curDataObjectToUse instanceof MediaDBObject) {
207             sendMediaObjectField(newRequest, newResponse,
208                     (MediaDBObject) curDataObjectToUse, fieldName);
209             return;
210         } else {
211             sendBlobField(newRequest, newResponse,
212                     (JDBCDataObject) curDataObjectToUse, fieldName);
213             return;
214         }
215
216
217     }
218
219     /**
220      * Sends a BLOB field to the client browser.
221      *
222      * @param newRequest The ControllerRequest object
223      * @param newResponse The ControllerResponse object
224      * @param dbobj the DBObject to get the BLOB field from.
225      * @param fieldName the name of the field in the DBObject to send
226      * @throws ControllerException upon error
227      * @throws NonHandleableException upon fatal error
228      */

229     protected void sendBlobField(ControllerRequest newRequest, ControllerResponse newResponse,
230                                  JDBCDataObject dbobj, String JavaDoc fieldName) throws ControllerException,
231             NonHandleableException {
232         ServletControllerRequest request = (ServletControllerRequest) newRequest;
233         ServletResponse JavaDoc sResponse = request.getServletResponse();
234
235
236         LobField lf = new LobField();
237         try {
238             lf.setCriteria(dbobj);
239
240             InputStream JavaDoc theBlob = lf.getBlobStream(fieldName);
241             if (theBlob == null) {
242                 newResponse.addError("No Data Saved For This Record");
243                 this.transition("Update", newRequest, newResponse);
244                 lf.close();
245                 return;
246             }
247
248             String JavaDoc fileName = (String JavaDoc) dbobj.getDataField(fieldName).getAttribute("fileName");
249             if (fileName == null || fileName.length() == 0) {
250                 fileName = fieldName;
251             }
252
253             ((HttpServletResponse JavaDoc) sResponse).setHeader("Content-Disposition",
254                     "inline;filename=" + fileName);
255             newResponse.setCustomResponse(true);
256
257             String JavaDoc mimeType = (String JavaDoc) dbobj.getDataField(fieldName).getAttribute("mimeType");
258             if (mimeType == null || mimeType.length() == 0) {
259                 sResponse.setContentType("application/x-unknown");
260             } else {
261                 sResponse.setContentType(mimeType);
262             }
263
264             sendStream(theBlob, sResponse);
265         } catch (DBException ex) {
266             throw new ControllerException("Error getting BLOB field: ", ex);
267         } catch (java.io.IOException JavaDoc ex) {
268             log.error("I/O Error transferring BLOB", ex);
269         } finally {
270             lf.close();
271         }
272     }
273
274     /**
275      * Sends a Media DBObject's BLOB fields to the client.
276      *
277      * @param newRequest the controller request object
278      * @param newResponse the controller response object (Must be in a Servlet
279      * environment)
280      * @param dbobj THe Media DBObject derived class to send
281      * @param fieldName the field name in the dbobject to send
282      * @throws ControllerException upon error
283      * @throws NonHandleableException upon fatal error
284      */

285     protected void sendMediaObjectField(ControllerRequest newRequest,
286                                         ControllerResponse newResponse,
287                                         MediaDBObject dbobj,
288                                         String JavaDoc fieldName) throws ControllerException, NonHandleableException {
289         ServletControllerRequest request = (ServletControllerRequest) newRequest;
290         ServletResponse JavaDoc sResponse = request.getServletResponse();
291         try {
292
293             //
294
//Attempt to get the BLOB stream
295
//
296
InputStream JavaDoc theBlob = dbobj.retrieveBlob(fieldName);
297             if (theBlob == null) {
298                 dbobj.release();
299                 newResponse.addError("No Data Saved For This Record");
300                 this.transition("Update", newRequest, newResponse);
301                 return;
302             }
303
304             String JavaDoc fileName = dbobj.getField(fieldName + MediaDBObject.FLD_FILE_SUFFIX);
305
306             newResponse.setCustomResponse(true);
307
308             //
309
//Set the file name if it exists.
310
//
311
if (fileName != null && fileName.length() > 0) {
312                 ((HttpServletResponse JavaDoc) sResponse).setHeader("Content-Disposition",
313                         "inline;filename=" + fileName);
314             }
315
316             //
317
//Set the application mime type
318
//
319
int mimeNumber = dbobj.getFieldInt(fieldName + MediaDBObject.FLD_MIME_SUFFIX);
320
321             if (mimeNumber <= 0) {
322                 sResponse.setContentType("application/x-unknown");
323             } else {
324                 try {
325                     MimeTypes contentType = new MimeTypes(SecuredDBObject.SYSTEM_ACCOUNT);
326                     contentType.setField("MimeNumber", mimeNumber);
327                     contentType.retrieve();
328                     sResponse.setContentType(contentType.getField("MimeType"));
329                 } catch (DBException ex) {
330                     sResponse.setContentType("application/x-unknown");
331                 }
332             }
333
334
335             //
336
//Check to see if we have the file size stored in memory. If we
337
//do, then set the content length to the size of the object. Makes
338
//downloading the streams more browser friendly.
339
//
340
int tempLength = dbobj.getFieldInt(fieldName + MediaDBObject.FLD_SIZE_SUFFIX);
341
342             //Set the content length if we can cope with it. This will have
343
//a max length of 2 Gb.
344
if (tempLength > 0) {
345                 sResponse.setContentLength(tempLength);
346             }
347
348             sendStream(theBlob, sResponse);
349
350
351         } catch (DBException ex) {
352             throw new ControllerException("Error getting BLOB field: ", ex);
353         } catch (java.io.IOException JavaDoc ex) {
354             log.error("I/O Error transferring BLOB", ex);
355         } finally {
356             dbobj.release();
357         }
358
359     }
360
361     /**
362      * Sends the given stream to the client servlet output stream.
363      *
364      * @param is The InputStream to send to the client.
365      * @param response The ServletResponse by which to get the OutputStream.
366      * @throws java.io.IOException upon error getting the OutputStream to
367      * the client.
368      */

369     protected void sendStream(InputStream JavaDoc is, ServletResponse JavaDoc response)
370             throws java.io.IOException JavaDoc {
371         //
372
//Now send the file
373
//
374
ServletOutputStream JavaDoc out = response.getOutputStream();
375         byte[] buf = new byte[4096]; // 4K buffer
376
int bytesRead;
377
378         while ((bytesRead = is.read(buf)) != -1) {
379             out.write(buf, 0, bytesRead);
380         }
381
382         try {
383             out.flush();
384         } catch (java.io.IOException JavaDoc ex) {
385             log.error("I/O Error flushing BLOB stream", ex);
386         }
387
388         try {
389             out.close();
390         } catch (java.io.IOException JavaDoc ex) {
391             log.error("I/O Error closing BLOB output stream", ex);
392         }
393
394     }
395 }
Popular Tags