View Javadoc

    1   /*
    2    * Copyright 2012 The Netty Project
    3    *
    4    * The Netty Project licenses this file to you under the Apache License,
    5    * version 2.0 (the "License"); you may not use this file except in compliance
    6    * with the License. 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, WITHOUT
    12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    13   * License for the specific language governing permissions and limitations
    14   * under the License.
    15   */
    16  package org.jboss.netty.handler.codec.http.multipart;
    17
    18  import java.io.File;
    19  import java.io.FileInputStream;
    20  import java.io.FileOutputStream;
    21  import java.io.IOException;
    22  import java.io.InputStream;
    23  import java.nio.ByteBuffer;
    24  import java.nio.channels.FileChannel;
    25  import java.nio.charset.Charset;
    26
    27  import org.jboss.netty.buffer.ChannelBuffer;
    28  import org.jboss.netty.buffer.ChannelBuffers;
    29  import org.jboss.netty.handler.codec.http.HttpConstants;
    30
    31  /**
    32   * Abstract Memory HttpData implementation
    33   */
    34  public abstract class AbstractMemoryHttpData extends AbstractHttpData {
    35
    36      private ChannelBuffer channelBuffer;
    37      private int chunkPosition;
    38      protected boolean isRenamed;
    39
    40      public AbstractMemoryHttpData(String name, Charset charset, long size) {
    41          super(name, charset, size);
    42      }
    43
    44      public void setContent(ChannelBuffer buffer) throws IOException {
    45          if (buffer == null) {
    46              throw new NullPointerException("buffer");
    47          }
    48          long localsize = buffer.readableBytes();
    49          if (definedSize > 0 && definedSize < localsize) {
    50              throw new IOException("Out of size: " + localsize + " > " +
    51                      definedSize);
    52          }
    53          channelBuffer = buffer;
    54          size = localsize;
    55          completed = true;
    56      }
    57
    58      public void setContent(InputStream inputStream) throws IOException {
    59          if (inputStream == null) {
    60              throw new NullPointerException("inputStream");
    61          }
    62          ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
    63          byte[] bytes = new byte[4096 * 4];
    64          int read = inputStream.read(bytes);
    65          int written = 0;
    66          while (read > 0) {
    67              buffer.writeBytes(bytes);
    68              written += read;
    69              read = inputStream.read(bytes);
    70          }
    71          size = written;
    72          if (definedSize > 0 && definedSize < size) {
    73              throw new IOException("Out of size: " + size + " > " + definedSize);
    74          }
    75          channelBuffer = buffer;
    76          completed = true;
    77      }
    78
    79      public void addContent(ChannelBuffer buffer, boolean last)
    80              throws IOException {
    81          if (buffer != null) {
    82              long localsize = buffer.readableBytes();
    83              if (definedSize > 0 && definedSize < size + localsize) {
    84                  throw new IOException("Out of size: " + (size + localsize) +
    85                          " > " + definedSize);
    86              }
    87              size += localsize;
    88              if (channelBuffer == null) {
    89                  channelBuffer = buffer;
    90              } else {
    91                  channelBuffer = ChannelBuffers.wrappedBuffer(
    92                          channelBuffer, buffer);
    93              }
    94          }
    95          if (last) {
    96              completed = true;
    97          } else {
    98              if (buffer == null) {
    99                  throw new NullPointerException("buffer");
    100             }
    101         }
    102     }
    103
    104     public void setContent(File file) throws IOException {
    105         if (file == null) {
    106             throw new NullPointerException("file");
    107         }
    108         long newsize = file.length();
    109         if (newsize > Integer.MAX_VALUE) {
    110             throw new IllegalArgumentException(
    111                     "File too big to be loaded in memory");
    112         }
    113         FileInputStream inputStream = new FileInputStream(file);
    114         FileChannel fileChannel = inputStream.getChannel();
    115         byte[] array = new byte[(int) newsize];
    116         ByteBuffer byteBuffer = ByteBuffer.wrap(array);
    117         int read = 0;
    118         while (read < newsize) {
    119             read += fileChannel.read(byteBuffer);
    120         }
    121         fileChannel.close();
    122         byteBuffer.flip();
    123         channelBuffer = ChannelBuffers.wrappedBuffer(byteBuffer);
    124         size = newsize;
    125         completed = true;
    126     }
    127
    128     public void delete() {
    129         // nothing to do
    130     }
    131
    132     public byte[] get() {
    133         if (channelBuffer == null) {
    134             return new byte[0];
    135         }
    136         byte[] array = new byte[channelBuffer.readableBytes()];
    137         channelBuffer.getBytes(channelBuffer.readerIndex(), array);
    138         return array;
    139     }
    140
    141     public String getString() {
    142         return getString(HttpConstants.DEFAULT_CHARSET);
    143     }
    144
    145     public String getString(Charset encoding) {
    146         if (channelBuffer == null) {
    147             return "";
    148         }
    149         if (encoding == null) {
    150             return getString(HttpConstants.DEFAULT_CHARSET);
    151         }
    152         return channelBuffer.toString(encoding);
    153     }
    154
    155     /**
    156      * Utility to go from a In Memory FileUpload
    157      * to a Disk (or another implementation) FileUpload
    158      * @return the attached ChannelBuffer containing the actual bytes
    159      */
    160     public ChannelBuffer getChannelBuffer() {
    161         return channelBuffer;
    162     }
    163
    164     public ChannelBuffer getChunk(int length) throws IOException {
    165         if (channelBuffer == null || length == 0 || channelBuffer.readableBytes() == 0) {
    166             chunkPosition = 0;
    167             return ChannelBuffers.EMPTY_BUFFER;
    168         }
    169         int sizeLeft = channelBuffer.readableBytes() - chunkPosition;
    170         if (sizeLeft == 0) {
    171             chunkPosition = 0;
    172             return ChannelBuffers.EMPTY_BUFFER;
    173         }
    174         int sliceLength = length;
    175         if (sizeLeft < length) {
    176             sliceLength = sizeLeft;
    177         }
    178         ChannelBuffer chunk = channelBuffer.slice(chunkPosition, sliceLength);
    179         chunkPosition += sliceLength;
    180         return chunk;
    181     }
    182
    183     public boolean isInMemory() {
    184         return true;
    185     }
    186
    187     public boolean renameTo(File dest) throws IOException {
    188         if (dest == null) {
    189             throw new NullPointerException("dest");
    190         }
    191         if (channelBuffer == null) {
    192             // empty file
    193             dest.createNewFile();
    194             isRenamed = true;
    195             return true;
    196         }
    197         int length = channelBuffer.readableBytes();
    198         FileOutputStream outputStream = new FileOutputStream(dest);
    199         FileChannel fileChannel = outputStream.getChannel();
    200         ByteBuffer byteBuffer = channelBuffer.toByteBuffer();
    201         int written = 0;
    202         while (written < length) {
    203             written += fileChannel.write(byteBuffer);
    204         }
    205         fileChannel.force(false);
    206         fileChannel.close();
    207         isRenamed = true;
    208         return written == length;
    209     }
    210
    211     public File getFile() throws IOException {
    212         throw new IOException("Not represented by a file");
    213     }
    214 }