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.IOException;
19  import java.nio.charset.Charset;
20  import java.util.ArrayList;
21  import java.util.List;
22  import java.util.concurrent.ConcurrentHashMap;
23  
24  import org.jboss.netty.handler.codec.http.HttpRequest;
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 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       * @param useDisk
64       */
65      public DefaultHttpDataFactory(boolean useDisk) {
66          this.useDisk = useDisk;
67          checkSize = false;
68      }
69  
70      /**
71       * HttpData will be on Disk if the size of the file is greater than minSize, else it
72       * will be in memory. The type will be Mixed.
73       * @param minSize
74       */
75      public DefaultHttpDataFactory(long minSize) {
76          useDisk = false;
77          checkSize = true;
78          this.minSize = minSize;
79      }
80  
81      /**
82       *
83       * @param request
84       * @return the associated list of Files for the request
85       */
86      private List<HttpData> getList(HttpRequest request) {
87          List<HttpData> list = requestFileDeleteMap.get(request);
88          if (list == null) {
89              list = new ArrayList<HttpData>();
90              requestFileDeleteMap.put(request, list);
91          }
92          return list;
93      }
94  
95      public Attribute createAttribute(HttpRequest request, String name) {
96          if (useDisk) {
97              Attribute attribute = new DiskAttribute(name);
98              List<HttpData> fileToDelete = getList(request);
99              fileToDelete.add(attribute);
100             return attribute;
101         } else if (checkSize) {
102             Attribute attribute = new MixedAttribute(name, minSize);
103             List<HttpData> fileToDelete = getList(request);
104             fileToDelete.add(attribute);
105             return attribute;
106         }
107         return new MemoryAttribute(name);
108     }
109 
110     public Attribute createAttribute(HttpRequest request, String name, String value) {
111         if (useDisk) {
112             Attribute attribute;
113             try {
114                 attribute = new DiskAttribute(name, value);
115             } catch (IOException e) {
116                 // revert to Mixed mode
117                 attribute = new MixedAttribute(name, value, minSize);
118             }
119             List<HttpData> fileToDelete = getList(request);
120             fileToDelete.add(attribute);
121             return attribute;
122         } else if (checkSize) {
123             Attribute attribute = new MixedAttribute(name, value, minSize);
124             List<HttpData> fileToDelete = getList(request);
125             fileToDelete.add(attribute);
126             return attribute;
127         }
128         try {
129             return new MemoryAttribute(name, value);
130         } catch (IOException e) {
131             throw new IllegalArgumentException(e);
132         }
133     }
134 
135     public FileUpload createFileUpload(HttpRequest request, String name, String filename,
136             String contentType, String contentTransferEncoding, Charset charset,
137             long size) {
138         if (useDisk) {
139             FileUpload fileUpload = new DiskFileUpload(name, filename, contentType,
140                     contentTransferEncoding, charset, size);
141             List<HttpData> fileToDelete = getList(request);
142             fileToDelete.add(fileUpload);
143             return fileUpload;
144         } else if (checkSize) {
145             FileUpload fileUpload = new MixedFileUpload(name, filename, contentType,
146                     contentTransferEncoding, charset, size, minSize);
147             List<HttpData> fileToDelete = getList(request);
148             fileToDelete.add(fileUpload);
149             return fileUpload;
150         }
151         return new MemoryFileUpload(name, filename, contentType,
152                 contentTransferEncoding, charset, size);
153     }
154 
155     public void removeHttpDataFromClean(HttpRequest request, InterfaceHttpData data) {
156         if (data instanceof HttpData) {
157             List<HttpData> fileToDelete = getList(request);
158             fileToDelete.remove(data);
159         }
160     }
161 
162     public void cleanRequestHttpDatas(HttpRequest request) {
163         List<HttpData> fileToDelete = requestFileDeleteMap.remove(request);
164         if (fileToDelete != null) {
165             for (HttpData data: fileToDelete) {
166                 data.delete();
167             }
168             fileToDelete.clear();
169         }
170     }
171 
172     public void cleanAllHttpDatas() {
173         for (HttpRequest request : requestFileDeleteMap.keySet()) {
174             List<HttpData> fileToDelete = requestFileDeleteMap.get(request);
175             if (fileToDelete != null) {
176                 for (HttpData data: fileToDelete) {
177                     data.delete();
178                 }
179                 fileToDelete.clear();
180             }
181             requestFileDeleteMap.remove(request);
182         }
183     }
184 }