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  		/** フィールド名。 */
    79  		private String fieldName;
    80
    81  		/** コンテントタイプ。 */
    82  		private final String contentType;
    83
    84  		/** フォームフィールドか。 */
    85  		private boolean isFormField;
    86
    87  		/** ファイル名。 */
    88  		private final String fileName;
    89
    90  		/** 初期バッファサイズ。 */
    91  		private final int initialBufferSize;
    92
    93  		/** 出力ストリーム。 */
    94  		private transient ByteArrayOutputStream outputStream;
    95
    96  		/** データ。 */
    97  		private byte[] data;
    98
    99  		/**
    100 		 * インスタンス化します。
    101 		 *
    102 		 * @param fieldName
    103 		 *            フィールド名
    104 		 * @param contentType
    105 		 *            コンテントタイプ
    106 		 * @param isFormField
    107 		 *            フォームフィールドか
    108 		 * @param fileName
    109 		 *            ファイル名
    110 		 * @param initialBufferSize
    111 		 *            初期バッファサイズ
    112 		 */
    113 		public ByteArrayFileItem(final String fieldName,
    114 				final String contentType, final boolean isFormField,
    115 				final String fileName, final int initialBufferSize) {
    116 			this.fieldName = fieldName;
    117 			this.contentType = contentType;
    118 			this.isFormField = isFormField;
    119 			this.fileName = fileName;
    120 			this.initialBufferSize = initialBufferSize;
    121 		}
    122
    123 		/**
    124 		 * {@inheritDoc}
    125 		 */
    126 		public InputStream getInputStream() throws IOException {
    127 			return new ByteArrayInputStream(get());
    128 		}
    129
    130 		/**
    131 		 * {@inheritDoc}
    132 		 */
    133 		public String getContentType() {
    134 			return contentType;
    135 		}
    136
    137 		/**
    138 		 * {@inheritDoc}
    139 		 */
    140 		public String getName() {
    141 			return fileName;
    142 		}
    143
    144 		/**
    145 		 * {@inheritDoc}
    146 		 */
    147 		public boolean isInMemory() {
    148 			return true;
    149 		}
    150
    151 		/**
    152 		 * {@inheritDoc}
    153 		 */
    154 		public long getSize() {
    155 			return get().length;
    156 		}
    157
    158 		/**
    159 		 * {@inheritDoc}
    160 		 */
    161 		public byte[] get() {
    162 			if (data == null) {
    163 				data = outputStream.toByteArray();
    164 			}
    165 			return data;
    166 		}
    167
    168 		/**
    169 		 * {@inheritDoc}
    170 		 */
    171 		public String getString(final String encoding)
    172 				throws UnsupportedEncodingException {
    173 			return new String(get(), encoding);
    174 		}
    175
    176 		/**
    177 		 * {@inheritDoc}
    178 		 */
    179 		public String getString() {
    180 			return new String(get());
    181 		}
    182
    183 		/**
    184 		 * {@inheritDoc}
    185 		 */
    186 		public void write(final File file) throws Exception {
    187 			final FileOutputStream out = new FileOutputStream(file);
    188 			try {
    189 				out.write(get());
    190 			} finally {
    191 				if (out != null) {
    192 					out.close();
    193 				}
    194 			}
    195 		}
    196
    197 		/**
    198 		 * {@inheritDoc}
    199 		 */
    200 		public void delete() {
    201 			this.data = null;
    202 		}
    203
    204 		/**
    205 		 * {@inheritDoc}
    206 		 */
    207 		public String getFieldName() {
    208 			return fieldName;
    209 		}
    210
    211 		/**
    212 		 * {@inheritDoc}
    213 		 */
    214 		public void setFieldName(final String name) {
    215 			this.fieldName = name;
    216 		}
    217
    218 		/**
    219 		 * {@inheritDoc}
    220 		 */
    221 		public boolean isFormField() {
    222 			return isFormField;
    223 		}
    224
    225 		/**
    226 		 * {@inheritDoc}
    227 		 */
    228 		public void setFormField(final boolean state) {
    229 			this.isFormField = state;
    230 		}
    231
    232 		/**
    233 		 * {@inheritDoc}
    234 		 */
    235 		public OutputStream getOutputStream() {
    236 			if (outputStream == null) {
    237 				outputStream = new ByteArrayOutputStream(initialBufferSize);
    238 			}
    239 			return outputStream;
    240 		}
    241
    242 	}
    243 }