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.IOException;
20  import java.io.InputStream;
21  import java.nio.charset.Charset;
22  
23  import org.jboss.netty.buffer.ChannelBuffer;
24  
25  /**
26   * Mixed implementation using both in Memory and in File with a limit of size
27   */
28  public class MixedAttribute implements Attribute {
29      private Attribute attribute;
30  
31      private final long limitSize;
32      protected long maxSize = DefaultHttpDataFactory.MAXSIZE;
33  
34      public MixedAttribute(String name, long limitSize) {
35          this.limitSize = limitSize;
36          attribute = new MemoryAttribute(name);
37      }
38  
39      public MixedAttribute(String name, String value, long limitSize) {
40          this.limitSize = limitSize;
41          if (value.length() > this.limitSize) {
42              try {
43                  attribute = new DiskAttribute(name, value);
44              } catch (IOException e) {
45                  // revert to Memory mode
46                  try {
47                      attribute = new MemoryAttribute(name, value);
48                  } catch (IOException e1) {
49                      throw new IllegalArgumentException(e);
50                  }
51              }
52          } else {
53              try {
54                  attribute = new MemoryAttribute(name, value);
55              } catch (IOException e) {
56                  throw new IllegalArgumentException(e);
57              }
58          }
59      }
60  
61      public void setMaxSize(long maxSize) {
62          this.maxSize = maxSize;
63          attribute.setMaxSize(maxSize);
64      }
65  
66      public void checkSize(long newSize) throws IOException {
67          if (maxSize >= 0 && newSize > maxSize) {
68              throw new IOException("Size exceed allowed maximum capacity");
69          }
70      }
71  
72      public void addContent(ChannelBuffer buffer, boolean last) throws IOException {
73          if (attribute instanceof MemoryAttribute) {
74              checkSize(attribute.length() + buffer.readableBytes());
75              if (attribute.length() + buffer.readableBytes() > limitSize) {
76                  DiskAttribute diskAttribute = new DiskAttribute(attribute
77                          .getName());
78                  diskAttribute.setMaxSize(maxSize);
79                  if (((MemoryAttribute) attribute).getChannelBuffer() != null) {
80                      diskAttribute.addContent(((MemoryAttribute) attribute)
81                          .getChannelBuffer(), false);
82                  }
83                  attribute = diskAttribute;
84              }
85          }
86          attribute.addContent(buffer, last);
87      }
88  
89      public void delete() {
90          attribute.delete();
91      }
92  
93      public byte[] get() throws IOException {
94          return attribute.get();
95      }
96  
97      public ChannelBuffer getChannelBuffer() throws IOException {
98          return attribute.getChannelBuffer();
99      }
100 
101     public Charset getCharset() {
102         return attribute.getCharset();
103     }
104 
105     public String getString() throws IOException {
106         return attribute.getString();
107     }
108 
109     public String getString(Charset encoding) throws IOException {
110         return attribute.getString(encoding);
111     }
112 
113     public boolean isCompleted() {
114         return attribute.isCompleted();
115     }
116 
117     public boolean isInMemory() {
118         return attribute.isInMemory();
119     }
120 
121     public long length() {
122         return attribute.length();
123     }
124 
125     public boolean renameTo(File dest) throws IOException {
126         return attribute.renameTo(dest);
127     }
128 
129     public void setCharset(Charset charset) {
130         attribute.setCharset(charset);
131     }
132 
133     public void setContent(ChannelBuffer buffer) throws IOException {
134         checkSize(buffer.readableBytes());
135         if (buffer.readableBytes() > limitSize) {
136             if (attribute instanceof MemoryAttribute) {
137                 // change to Disk
138                 attribute = new DiskAttribute(attribute.getName());
139                 attribute.setMaxSize(maxSize);
140             }
141         }
142         attribute.setContent(buffer);
143     }
144 
145     public void setContent(File file) throws IOException {
146         checkSize(file.length());
147         if (file.length() > limitSize) {
148             if (attribute instanceof MemoryAttribute) {
149                 // change to Disk
150                 attribute = new DiskAttribute(attribute.getName());
151                 attribute.setMaxSize(maxSize);
152             }
153         }
154         attribute.setContent(file);
155     }
156 
157     public void setContent(InputStream inputStream) throws IOException {
158         if (attribute instanceof MemoryAttribute) {
159             // change to Disk even if we don't know the size
160             attribute = new DiskAttribute(attribute.getName());
161             attribute.setMaxSize(maxSize);
162         }
163         attribute.setContent(inputStream);
164     }
165 
166     public HttpDataType getHttpDataType() {
167         return attribute.getHttpDataType();
168     }
169 
170     public String getName() {
171         return attribute.getName();
172     }
173 
174     public int compareTo(InterfaceHttpData o) {
175         return attribute.compareTo(o);
176     }
177 
178     @Override
179     public String toString() {
180         return "Mixed: " + attribute.toString();
181     }
182 
183     public String getValue() throws IOException {
184         return attribute.getValue();
185     }
186 
187     public void setValue(String value) throws IOException {
188         if (value != null) {
189             checkSize(value.getBytes().length);
190         }
191         attribute.setValue(value);
192     }
193 
194     public ChannelBuffer getChunk(int length) throws IOException {
195         return attribute.getChunk(length);
196     }
197 
198     public File getFile() throws IOException {
199         return attribute.getFile();
200     }
201 
202 }