View Javadoc

1   /*
2    * Copyright 2004-2009 the Seasar Foundation and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.seasar.cubby.fileupload;
17  
18  import java.io.ByteArrayInputStream;
19  import java.io.ByteArrayOutputStream;
20  import java.io.File;
21  import java.io.FileOutputStream;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.io.OutputStream;
25  import java.io.UnsupportedEncodingException;
26  
27  import org.apache.commons.fileupload.FileItem;
28  import org.apache.commons.fileupload.FileItemFactory;
29  import org.apache.commons.fileupload.disk.DiskFileItemFactory;
30  
31  /**
32   * Streaming API によってマルチパートリクエストを処理するための {@link FileItemFactory} の実装です。
33   * <p>
34   * ローカルファイルへの書き込みに制限がある環境で {@link DiskFileItemFactory} の代わりに使用してください。
35   * </p>
36   * 
37   * @see <a
38   *      href="http://commons.apache.org/fileupload/streaming.html">Streaming&nbsp;API&nbsp;(commons-fileupload)</a>
39   * @author baba
40   */
41  public class StreamFileItemFactory implements FileItemFactory {
42  
43  	/** 初期バッファサイズのデフォルト。 */
44  	public static final int DEFAULT_INITIAL_BUFFER_SIZE = 8192;
45  
46  	/** 初期バッファサイズ。 */
47  	private int initialBufferSize = DEFAULT_INITIAL_BUFFER_SIZE;
48  
49  	/**
50  	 * 初期バッファサイズを設定します。
51  	 * 
52  	 * @param initialBufferSize
53  	 *            初期バッファサイズ
54  	 */
55  	public void setInitialBufferSize(final int initialBufferSize) {
56  		this.initialBufferSize = initialBufferSize;
57  	}
58  
59  	/**
60  	 * {@inheritDoc}
61  	 */
62  	public FileItem createItem(final String fieldName,
63  			final String contentType, final boolean isFormField,
64  			final String fileName) {
65  		return new ByteArrayFileItem(fieldName, contentType, isFormField,
66  				fileName, initialBufferSize);
67  	}
68  
69  	/**
70  	 * バイト配列にデータを保持する {@link FileItem} の実装です。
71  	 * 
72  	 * @author baba
73  	 */
74  	private static class ByteArrayFileItem implements FileItem {
75  
76  		private static final long serialVersionUID = 1L;
77  
78  		private final ByteArrayOutputStream outputStream;
79  
80  		/** フィールド名。 */
81  		private String fieldName;
82  
83  		/** コンテントタイプ。 */
84  		private final String contentType;
85  
86  		/** フォームフィールドか。 */
87  		private boolean isFormField;
88  
89  		/** ファイル名。 */
90  		private final String fileName;
91  
92  		/** データ。 */
93  		private byte[] data;
94  
95  		/**
96  		 * インスタンス化します。
97  		 * 
98  		 * @param fieldName
99  		 *            フィールド名
100 		 * @param contentType
101 		 *            コンテントタイプ
102 		 * @param isFormField
103 		 *            フォームフィールドか
104 		 * @param fileName
105 		 *            ファイル名
106 		 * @param initialBufferSize
107 		 *            初期バッファサイズ
108 		 */
109 		public ByteArrayFileItem(final String fieldName,
110 				final String contentType, final boolean isFormField,
111 				final String fileName, final int initialBufferSize) {
112 			this.fieldName = fieldName;
113 			this.contentType = contentType;
114 			this.isFormField = isFormField;
115 			this.fileName = fileName;
116 			this.outputStream = new ByteArrayOutputStream(initialBufferSize);
117 		}
118 
119 		/**
120 		 * {@inheritDoc}
121 		 */
122 		public InputStream getInputStream() throws IOException {
123 			return new ByteArrayInputStream(get());
124 		}
125 
126 		/**
127 		 * {@inheritDoc}
128 		 */
129 		public String getContentType() {
130 			return contentType;
131 		}
132 
133 		/**
134 		 * {@inheritDoc}
135 		 */
136 		public String getName() {
137 			return fileName;
138 		}
139 
140 		/**
141 		 * {@inheritDoc}
142 		 */
143 		public boolean isInMemory() {
144 			return true;
145 		}
146 
147 		/**
148 		 * {@inheritDoc}
149 		 */
150 		public long getSize() {
151 			return get().length;
152 		}
153 
154 		/**
155 		 * {@inheritDoc}
156 		 */
157 		public byte[] get() {
158 			if (data == null) {
159 				data = outputStream.toByteArray();
160 			}
161 			return data;
162 		}
163 
164 		/**
165 		 * {@inheritDoc}
166 		 */
167 		public String getString(final String encoding)
168 				throws UnsupportedEncodingException {
169 			return new String(get(), encoding);
170 		}
171 
172 		/**
173 		 * {@inheritDoc}
174 		 */
175 		public String getString() {
176 			return new String(get());
177 		}
178 
179 		/**
180 		 * {@inheritDoc}
181 		 */
182 		public void write(final File file) throws Exception {
183 			final FileOutputStream out = new FileOutputStream(file);
184 			try {
185 				out.write(get());
186 			} finally {
187 				if (out != null) {
188 					out.close();
189 				}
190 			}
191 		}
192 
193 		/**
194 		 * {@inheritDoc}
195 		 */
196 		public void delete() {
197 			this.data = null;
198 		}
199 
200 		/**
201 		 * {@inheritDoc}
202 		 */
203 		public String getFieldName() {
204 			return fieldName;
205 		}
206 
207 		/**
208 		 * {@inheritDoc}
209 		 */
210 		public void setFieldName(final String name) {
211 			this.fieldName = name;
212 		}
213 
214 		/**
215 		 * {@inheritDoc}
216 		 */
217 		public boolean isFormField() {
218 			return isFormField;
219 		}
220 
221 		/**
222 		 * {@inheritDoc}
223 		 */
224 		public void setFormField(final boolean state) {
225 			this.isFormField = state;
226 		}
227 
228 		/**
229 		 * {@inheritDoc}
230 		 */
231 		public OutputStream getOutputStream() {
232 			return outputStream;
233 		}
234 
235 	}
236 }