1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  package org.htmlunit.html;
16  
17  import java.io.File;
18  import java.net.URI;
19  import java.net.URISyntaxException;
20  import java.nio.charset.Charset;
21  import java.util.ArrayList;
22  import java.util.Collection;
23  import java.util.List;
24  import java.util.Map;
25  
26  import org.apache.commons.io.FileUtils;
27  import org.htmlunit.BrowserVersion;
28  import org.htmlunit.SgmlPage;
29  import org.htmlunit.javascript.host.event.Event;
30  import org.htmlunit.util.KeyDataPair;
31  import org.htmlunit.util.MimeType;
32  import org.htmlunit.util.NameValuePair;
33  import org.htmlunit.util.StringUtils;
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  public class HtmlFileInput extends HtmlInput implements LabelableElement {
47  
48      private String contentType_;
49      private byte[] data_;
50      private File[] files_ = new File[0];
51  
52      
53  
54  
55  
56  
57  
58  
59      HtmlFileInput(final String qualifiedName, final SgmlPage page,
60              final Map<String, DomAttr> attributes) {
61          super(qualifiedName, page, attributes);
62  
63          final DomAttr valueAttrib = attributes.get(VALUE_ATTRIBUTE);
64          if (valueAttrib != null) {
65              setDefaultValue(valueAttrib.getNodeValue());
66          }
67      }
68  
69      
70  
71  
72  
73      public final byte[] getData() {
74          return data_;
75      }
76  
77      
78  
79  
80  
81  
82  
83  
84  
85  
86  
87      public final void setData(final byte[] data) {
88          data_ = data;
89      }
90  
91      
92  
93  
94      @Override
95      public void setDefaultChecked(final boolean defaultChecked) {
96          
97      }
98  
99      
100 
101 
102     @Override
103     public NameValuePair[] getSubmitNameValuePairs() {
104         if (files_ == null || files_.length == 0) {
105             return new NameValuePair[] {new KeyDataPair(getNameAttribute(), null, null, null, (Charset) null)};
106         }
107 
108         final List<NameValuePair> list = new ArrayList<>();
109         for (final File file : files_) {
110             String contentType;
111             if (contentType_ == null) {
112                 contentType = getPage().getWebClient().getBrowserVersion().getUploadMimeType(file);
113                 if (StringUtils.isEmptyOrNull(contentType)) {
114                     contentType = MimeType.APPLICATION_OCTET_STREAM;
115                 }
116             }
117             else {
118                 contentType = contentType_;
119             }
120             final Charset charset = getPage().getCharset();
121             final KeyDataPair keyDataPair = new KeyDataPair(getNameAttribute(), file, null, contentType, charset);
122             keyDataPair.setData(data_);
123             list.add(keyDataPair);
124         }
125         return list.toArray(new NameValuePair[0]);
126     }
127 
128     
129 
130 
131 
132 
133     public void setContentType(final String contentType) {
134         contentType_ = contentType;
135     }
136 
137     
138 
139 
140 
141 
142     public String getContentType() {
143         return contentType_;
144     }
145 
146     
147 
148 
149     @Override
150     public String getValue() {
151         final File[] files = getFiles();
152         if (files == null || files.length == 0) {
153             return ATTRIBUTE_NOT_DEFINED;
154         }
155         final File first = files[0];
156         final String name = first.getName();
157         if (name.isEmpty()) {
158             return name;
159         }
160         return "C:\\fakepath\\" + name;
161     }
162 
163     
164 
165 
166 
167 
168     @Override
169     public void setDefaultValue(final String defaultValue) {
170         final String oldDefaultValue = getDefaultValue();
171         
172         super.setValueAttribute(defaultValue);
173 
174         if (oldDefaultValue.equals(getValue())) {
175             setRawValue(defaultValue);
176         }
177     }
178 
179     
180 
181 
182     @Override
183     public void setValue(final String newValue) {
184         if (StringUtils.isEmptyOrNull(newValue)) {
185             setFiles();
186             return;
187         }
188 
189         final File file = new File(newValue);
190         if (file.isDirectory()) {
191             setDirectory(file);
192             return;
193         }
194 
195         setFiles(file);
196     }
197 
198     
199 
200 
201 
202 
203 
204 
205     public void setFiles(final File... files) {
206         if (files.length > 1 && ATTRIBUTE_NOT_DEFINED == getAttributeDirect("multiple")) {
207             throw new IllegalStateException("HtmlFileInput - 'multiple' is not set.");
208         }
209 
210         for (int i = 0; i < files.length; i++) {
211             files[i] = normalizeFile(files[i]);
212         }
213         files_ = files;
214         fireEvent(Event.TYPE_CHANGE);
215     }
216 
217     
218 
219 
220 
221 
222     public void setDirectory(final File directory) {
223         if (directory == null) {
224             return;
225         }
226 
227         if (ATTRIBUTE_NOT_DEFINED == getAttributeDirect("webkitdirectory")) {
228             throw new IllegalStateException("HtmlFileInput - 'webkitdirectory' is not set.");
229         }
230 
231         if (ATTRIBUTE_NOT_DEFINED == getAttributeDirect("multiple")) {
232             throw new IllegalStateException("HtmlFileInput - 'multiple' is not set.");
233         }
234 
235         if (!directory.isDirectory()) {
236             throw new IllegalStateException("HtmlFileInput - the provided directory '"
237                         + directory.getAbsolutePath() + "' is not a directory.");
238         }
239 
240         final Collection<File> fileColl = FileUtils.listFiles(directory, null, true);
241         final File[] files = new File[fileColl.size()];
242         int i = 0;
243         for (final File file : fileColl) {
244             files[i++] = normalizeFile(file);
245         }
246         files_ = files;
247         fireEvent(Event.TYPE_CHANGE);
248     }
249 
250     
251 
252 
253     private static File normalizeFile(final File file) {
254         File f = null;
255         String path = file.getPath().replace('\\', '/');
256         if (path.startsWith("file:/")) {
257             if (path.startsWith("file://") && !path.startsWith("file:///")) {
258                 path = "file:///" + path.substring(7);
259             }
260             try {
261                 f = new File(new URI(path));
262             }
263             catch (final URISyntaxException ignored) {
264                 
265             }
266         }
267         if (f == null) {
268             f = new File(path);
269         }
270         return f;
271     }
272 
273     
274 
275 
276 
277     public File[] getFiles() {
278         return files_;
279     }
280 
281     
282 
283 
284 
285     @Override
286     public boolean isValid() {
287         return isCustomValidityValid()
288                 && (!isRequiredSupported()
289                         || ATTRIBUTE_NOT_DEFINED == getAttributeDirect("required")
290                         || files_.length > 0);
291     }
292 
293     @Override
294     protected void adjustValueAfterTypeChange(final HtmlInput oldInput, final BrowserVersion browserVersion) {
295         setValue("");
296     }
297 }