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 io.netty.handler.codec.http.multipart;
17  
18  import io.netty.buffer.ByteBuf;
19  
20  import java.io.File;
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.nio.charset.Charset;
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  
33      public MixedAttribute(String name, long limitSize) {
34          this.limitSize = limitSize;
35          attribute = new MemoryAttribute(name);
36      }
37  
38      public MixedAttribute(String name, String value, long limitSize) {
39          this.limitSize = limitSize;
40          if (value.length() > this.limitSize) {
41              try {
42                  attribute = new DiskAttribute(name, value);
43              } catch (IOException e) {
44                  // revert to Memory mode
45                  try {
46                      attribute = new MemoryAttribute(name, value);
47                  } catch (IOException e1) {
48                      throw new IllegalArgumentException(e);
49                  }
50              }
51          } else {
52              try {
53                  attribute = new MemoryAttribute(name, value);
54              } catch (IOException e) {
55                  throw new IllegalArgumentException(e);
56              }
57          }
58      }
59  
60      @Override
61      public void addContent(ByteBuf buffer, boolean last) throws IOException {
62          if (attribute instanceof MemoryAttribute) {
63              if (attribute.length() + buffer.readableBytes() > limitSize) {
64                  DiskAttribute diskAttribute = new DiskAttribute(attribute
65                          .getName());
66                  if (((MemoryAttribute) attribute).getByteBuf() != null) {
67                      diskAttribute.addContent(((MemoryAttribute) attribute)
68                          .getByteBuf(), false);
69                  }
70                  attribute = diskAttribute;
71              }
72          }
73          attribute.addContent(buffer, last);
74      }
75  
76      @Override
77      public void delete() {
78          attribute.delete();
79      }
80  
81      @Override
82      public byte[] get() throws IOException {
83          return attribute.get();
84      }
85  
86      @Override
87      public ByteBuf getByteBuf() throws IOException {
88          return attribute.getByteBuf();
89      }
90  
91      @Override
92      public Charset getCharset() {
93          return attribute.getCharset();
94      }
95  
96      @Override
97      public String getString() throws IOException {
98          return attribute.getString();
99      }
100 
101     @Override
102     public String getString(Charset encoding) throws IOException {
103         return attribute.getString(encoding);
104     }
105 
106     @Override
107     public boolean isCompleted() {
108         return attribute.isCompleted();
109     }
110 
111     @Override
112     public boolean isInMemory() {
113         return attribute.isInMemory();
114     }
115 
116     @Override
117     public long length() {
118         return attribute.length();
119     }
120 
121     @Override
122     public boolean renameTo(File dest) throws IOException {
123         return attribute.renameTo(dest);
124     }
125 
126     @Override
127     public void setCharset(Charset charset) {
128         attribute.setCharset(charset);
129     }
130 
131     @Override
132     public void setContent(ByteBuf buffer) throws IOException {
133         if (buffer.readableBytes() > limitSize) {
134             if (attribute instanceof MemoryAttribute) {
135                 // change to Disk
136                 attribute = new DiskAttribute(attribute.getName());
137             }
138         }
139         attribute.setContent(buffer);
140     }
141 
142     @Override
143     public void setContent(File file) throws IOException {
144         if (file.length() > limitSize) {
145             if (attribute instanceof MemoryAttribute) {
146                 // change to Disk
147                 attribute = new DiskAttribute(attribute.getName());
148             }
149         }
150         attribute.setContent(file);
151     }
152 
153     @Override
154     public void setContent(InputStream inputStream) throws IOException {
155         if (attribute instanceof MemoryAttribute) {
156             // change to Disk even if we don't know the size
157             attribute = new DiskAttribute(attribute.getName());
158         }
159         attribute.setContent(inputStream);
160     }
161 
162     @Override
163     public HttpDataType getHttpDataType() {
164         return attribute.getHttpDataType();
165     }
166 
167     @Override
168     public String getName() {
169         return attribute.getName();
170     }
171 
172     @Override
173     public int compareTo(InterfaceHttpData o) {
174         return attribute.compareTo(o);
175     }
176 
177     @Override
178     public String toString() {
179         return "Mixed: " + attribute.toString();
180     }
181 
182     @Override
183     public String getValue() throws IOException {
184         return attribute.getValue();
185     }
186 
187     @Override
188     public void setValue(String value) throws IOException {
189         attribute.setValue(value);
190     }
191 
192     @Override
193     public ByteBuf getChunk(int length) throws IOException {
194         return attribute.getChunk(length);
195     }
196 
197     @Override
198     public File getFile() throws IOException {
199         return attribute.getFile();
200     }
201 
202     @Override
203     public Attribute copy() {
204         return attribute.copy();
205     }
206 
207     @Override
208     public Attribute duplicate() {
209         return attribute.duplicate();
210     }
211 
212     @Override
213     public ByteBuf content() {
214         return attribute.content();
215     }
216 
217     @Override
218     public int refCnt() {
219         return attribute.refCnt();
220     }
221 
222     @Override
223     public Attribute retain() {
224         attribute.retain();
225         return this;
226     }
227 
228     @Override
229     public Attribute retain(int increment) {
230         attribute.retain(increment);
231         return this;
232     }
233 
234     @Override
235     public boolean release() {
236         return attribute.release();
237     }
238 
239     @Override
240     public boolean release(int decrement) {
241         return attribute.release(decrement);
242     }
243 }