View Javadoc

1   /*
2    * $Source: /usr/cvsroot/melati/melati/src/main/java/org/melati/servlet/BaseFileDataAdaptor.java,v $
3    * $Revision: 1.13 $
4    *
5    * Copyright (C) 2000 Myles Chippendale
6    *
7    * Part of Melati (http://melati.org), a framework for the rapid
8    * development of clean, maintainable web applications.
9    *
10   * Melati is free software; Permission is granted to copy, distribute
11   * and/or modify this software under the terms either:
12   *
13   * a) the GNU General Public License as published by the Free Software
14   *    Foundation; either version 2 of the License, or (at your option)
15   *    any later version,
16   *
17   *    or
18   *
19   * b) any version of the Melati Software License, as published
20   *    at http://melati.org
21   *
22   * You should have received a copy of the GNU General Public License and
23   * the Melati Software License along with this program;
24   * if not, write to the Free Software Foundation, Inc.,
25   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the
26   * GNU General Public License and visit http://melati.org to obtain the
27   * Melati Software License.
28   *
29   * Feel free to contact the Developers of Melati (http://melati.org),
30   * if you would like to work out a different arrangement than the options
31   * outlined here.  It is our intention to allow Melati to be used by as
32   * wide an audience as possible.
33   *
34   * This program is distributed in the hope that it will be useful,
35   * but WITHOUT ANY WARRANTY; without even the implied warranty of
36   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37   * GNU General Public License for more details.
38   *
39   * Contact details for copyright holder:
40   *
41   *     Mylesc Chippendale <mylesc At paneris.org>
42   *     http://paneris.org/
43   *     29 Stanley Road, Oxford, OX4 1QY, UK
44   */
45  
46  
47  package org.melati.servlet;
48  
49  import java.io.OutputStream;
50  import java.io.BufferedOutputStream;
51  import java.io.ByteArrayOutputStream;
52  import java.io.FileOutputStream;
53  import java.io.BufferedInputStream;
54  import java.io.FileInputStream;
55  import java.io.InputStream;
56  import java.io.File;
57  import java.io.IOException;
58  import org.melati.util.DelimitedBufferedInputStream;
59  
60  /**
61   * Common elements of uploading a file from an HTML form.
62   *
63   * We store the data uploaded from a multipart form by saving it to
64   * a file on disk and, optionally, give it an associated URL.
65   */
66  public abstract class BaseFileDataAdaptor implements FormDataAdaptor {
67    /** Size for byte buffers. */
68    protected int BUFSIZE = 2048;
69  
70    /** The file in which to save the data. */
71    protected File file = null;
72  
73    /** A URL to the data. */
74    protected String url = null;
75  
76    /** Information about the uploaded file. */
77    public MultipartFormField field = null;
78  
79    /**
80     * @return The file in which to save the data
81     */
82    protected abstract File calculateLocalFile();
83  
84    /**
85     * Return a URL to the saved file, null if not appropriate.
86     * @return a URL to the saved file, null if not appropriate
87     */
88    protected abstract String calculateURL();
89  
90  
91    /**
92     * Return the data in the file as a byte array.
93     * @return the data in the file as a byte array
94     */
95    public byte[] getData() {
96  
97      File fileLocal = getFile();
98      if (fileLocal == null)
99        return new byte[0];
100 
101     InputStream in = null;
102     ByteArrayOutputStream out = null;
103     try {
104       in = new BufferedInputStream(new FileInputStream(fileLocal));
105       out = new ByteArrayOutputStream();
106       byte[] buff = new byte[BUFSIZE];
107       int count;
108       while ((count = in.read(buff, 0, buff.length)) > 0)
109         out.write(buff, 0, count);
110       return out.toByteArray();
111     }
112     catch (IOException e) {
113       throw new FormDataAdaptorException(
114                   "Couldn't retreive the data from the file", e);
115     }
116     finally {
117       try {
118         if (in != null) {
119           in.close();
120           in = null;
121         }
122         if (out != null) {
123           out.close();
124           out = null;
125         }
126       } catch (Exception e) {
127         //Cause already thrown
128         e = null; // shut PMD up
129       }
130     }
131   }
132 
133   /**
134    * Return the size of the data.
135    * @return the size of the data as a <code>long</code>
136    */
137   public long getSize() {
138     return (getFile() != null) ? getFile().length() : 0;
139   }
140 
141   /**
142    * Return a File object pointing to the saved data.
143    * 
144    * @return the {@link #file}
145    */
146   public File getFile() {
147     if (file == null)
148       file = calculateLocalFile();
149     return file;
150   }
151 
152   /**
153    * @return Url to the data, null if there isn't an appropriate one
154    */
155   public String getURL() {
156     if (url == null)
157       url = calculateURL();
158     return url;
159   }
160 
161   /**
162    * Read data from in until the delim, work out which file to
163    * save it in, and save it.
164    * 
165    * @param fieldP  a {@link MultipartFormField}
166    * @param in     a {@link DelimitedBufferedInputStream}
167    * @param delim  the delimiter used to denote elements
168    * @throws IOException if there is a problem reading the input 
169    */
170   public void readData(MultipartFormField fieldP,
171                        DelimitedBufferedInputStream in,
172                        byte[] delim) throws IOException {
173 
174     this.field = fieldP;
175     OutputStream out = null;
176     byte[] buff = new byte[BUFSIZE];
177     int count;
178 
179     try {
180       // This should be the first call to get file, so hopefully we get any
181       // exceptions here
182       out = new BufferedOutputStream(new FileOutputStream(getFile()));
183       while ((count = in.readToDelimiter(buff, 0, buff.length, delim)) > 0)
184         out.write(buff, 0, count);
185       if (count == -1)
186         throw new IOException(
187                             "Didn't find boundary whilst reading field data");
188     }
189     catch (IOException e) {
190       throw e;
191     }
192     finally {
193       try {
194         if (out != null) {
195           out.close();
196           out = null;
197         }
198       } catch (Exception e) {
199         //Cause already thrown
200         e = null; // shut PMD up
201       }
202     }
203   }
204 
205 
206 }
207 
208 
209 
210 
211 
212