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.apache.commons.lang3.StringUtils;
28 import org.htmlunit.BrowserVersion;
29 import org.htmlunit.SgmlPage;
30 import org.htmlunit.javascript.host.event.Event;
31 import org.htmlunit.util.KeyDataPair;
32 import org.htmlunit.util.MimeType;
33 import org.htmlunit.util.NameValuePair;
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.isEmpty(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.isEmpty(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 }