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 org.jboss.netty.handler.codec.http.HttpRequest;
19  
20  import java.io.IOException;
21  import java.nio.charset.Charset;
22  import java.util.ArrayList;
23  import java.util.List;
24  import java.util.concurrent.ConcurrentHashMap;
25  
26  /**
27   * Default factory giving Attribute and FileUpload according to constructor
28   *
29   * Attribute and FileUpload could be :<br>
30   * - MemoryAttribute, DiskAttribute or MixedAttribute<br>
31   * - MemoryFileUpload, DiskFileUpload or MixedFileUpload<br>
32   * according to the constructor.
33   */
34  public class DefaultHttpDataFactory implements HttpDataFactory {
35      /**
36       * Proposed default MINSIZE as 16 KB.
37       */
38      public static final long MINSIZE = 0x4000;
39  
40      private final boolean useDisk;
41  
42      private final boolean checkSize;
43  
44      private long minSize;
45  
46      /**
47       * Keep all HttpDatas until cleanAllHttpDatas() is called.
48       */
49      private final ConcurrentHashMap<HttpRequest, List<HttpData>> requestFileDeleteMap =
50          new ConcurrentHashMap<HttpRequest, List<HttpData>>();
51      /**
52       * HttpData will be in memory if less than default size (16KB).
53       * The type will be Mixed.
54       */
55      public DefaultHttpDataFactory() {
56          useDisk = false;
57          checkSize = true;
58          minSize = MINSIZE;
59      }
60  
61      /**
62       * HttpData will be always on Disk if useDisk is True, else always in Memory if False
63       */
64      public DefaultHttpDataFactory(boolean useDisk) {
65          this.useDisk = useDisk;
66          checkSize = false;
67      }
68  
69      /**
70       * HttpData will be on Disk if the size of the file is greater than minSize, else it
71       * will be in memory. The type will be Mixed.
72       */
73      public DefaultHttpDataFactory(long minSize) {
74          useDisk = false;
75          checkSize = true;
76          this.minSize = minSize;
77      }
78  
79      /**
80       * @return the associated list of Files for the request
81       */
82      private List<HttpData> getList(HttpRequest request) {
83          List<HttpData> list = requestFileDeleteMap.get(request);
84          if (list == null) {
85              list = new ArrayList<HttpData>();
86              requestFileDeleteMap.put(request, list);
87          }
88          return list;
89      }
90  
91      public Attribute createAttribute(HttpRequest request, String name) {
92          if (useDisk) {
93              Attribute attribute = new DiskAttribute(name);
94              List<HttpData> fileToDelete = getList(request);
95              fileToDelete.add(attribute);
96              return attribute;
97          }
98          if (checkSize) {
99              Attribute attribute = new MixedAttribute(name, minSize);
100             List<HttpData> fileToDelete = getList(request);
101             fileToDelete.add(attribute);
102             return attribute;
103         }
104         return new MemoryAttribute(name);
105     }
106 
107     public Attribute createAttribute(HttpRequest request, String name, String value) {
108         if (useDisk) {
109             Attribute attribute;
110             try {
111                 attribute = new DiskAttribute(name, value);
112             } catch (IOException e) {
113                 // revert to Mixed mode
114                 attribute = new MixedAttribute(name, value, minSize);
115             }
116             List<HttpData> fileToDelete = getList(request);
117             fileToDelete.add(attribute);
118             return attribute;
119         }
120         if (checkSize) {
121             Attribute attribute = new MixedAttribute(name, value, minSize);
122             List<HttpData> fileToDelete = getList(request);
123             fileToDelete.add(attribute);
124             return attribute;
125         }
126         try {
127             return new MemoryAttribute(name, value);
128         } catch (IOException e) {
129             throw new IllegalArgumentException(e);
130         }
131     }
132 
133     public FileUpload createFileUpload(HttpRequest request, String name, String filename,
134             String contentType, String contentTransferEncoding, Charset charset,
135             long size) {
136         if (useDisk) {
137             FileUpload fileUpload = new DiskFileUpload(name, filename, contentType,
138                     contentTransferEncoding, charset, size);
139             List<HttpData> fileToDelete = getList(request);
140             fileToDelete.add(fileUpload);
141             return fileUpload;
142         }
143         if (checkSize) {
144             FileUpload fileUpload = new MixedFileUpload(name, filename, contentType,
145                     contentTransferEncoding, charset, size, minSize);
146             List<HttpData> fileToDelete = getList(request);
147             fileToDelete.add(fileUpload);
148             return fileUpload;
149         }
150         return new MemoryFileUpload(name, filename, contentType,
151                 contentTransferEncoding, charset, size);
152     }
153 
154     public void removeHttpDataFromClean(HttpRequest request, InterfaceHttpData data) {
155         if (data instanceof HttpData) {
156             List<HttpData> fileToDelete = getList(request);
157             fileToDelete.remove(data);
158         }
159     }
160 
161     public void cleanRequestHttpDatas(HttpRequest request) {
162         List<HttpData> fileToDelete = requestFileDeleteMap.remove(request);
163         if (fileToDelete != null) {
164             for (HttpData data: fileToDelete) {
165                 data.delete();
166             }
167             fileToDelete.clear();
168         }
169     }
170 
171     public void cleanAllHttpDatas() {
172         for (HttpRequest request : requestFileDeleteMap.keySet()) {
173             List<HttpData> fileToDelete = requestFileDeleteMap.get(request);
174             if (fileToDelete != null) {
175                 for (HttpData data: fileToDelete) {
176                     data.delete();
177                 }
178                 fileToDelete.clear();
179             }
180             requestFileDeleteMap.remove(request);
181         }
182     }
183 }