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
206 public void setFiles(final File... files) {
207 if (files.length > 1 && ATTRIBUTE_NOT_DEFINED == getAttributeDirect("multiple")) {
208 throw new IllegalStateException("HtmlFileInput - 'multiple' is not set.");
209 }
210
211 for (int i = 0; i < files.length; i++) {
212 files[i] = normalizeFile(files[i]);
213 }
214 files_ = files;
215 fireEvent(Event.TYPE_CHANGE);
216 }
217
218
219
220
221
222
223 public void setDirectory(final File directory) {
224 if (directory == null) {
225 return;
226 }
227
228 if (ATTRIBUTE_NOT_DEFINED == getAttributeDirect("webkitdirectory")) {
229 throw new IllegalStateException("HtmlFileInput - 'webkitdirectory' is not set.");
230 }
231
232 if (ATTRIBUTE_NOT_DEFINED == getAttributeDirect("multiple")) {
233 throw new IllegalStateException("HtmlFileInput - 'multiple' is not set.");
234 }
235
236 if (!directory.isDirectory()) {
237 throw new IllegalStateException("HtmlFileInput - the provided directory '"
238 + directory.getAbsolutePath() + "' is not a directory.");
239 }
240
241 final Collection<File> fileColl = FileUtils.listFiles(directory, null, true);
242 final File[] files = new File[fileColl.size()];
243 int i = 0;
244 for (final File file : fileColl) {
245 files[i++] = normalizeFile(file);
246 }
247 files_ = files;
248 fireEvent(Event.TYPE_CHANGE);
249 }
250
251
252
253
254 private static File normalizeFile(final File file) {
255 File f = null;
256 String path = file.getPath().replace('\\', '/');
257 if (path.startsWith("file:/")) {
258 if (path.startsWith("file://") && !path.startsWith("file:///")) {
259 path = "file:///" + path.substring(7);
260 }
261 try {
262 f = new File(new URI(path));
263 }
264 catch (final URISyntaxException ignored) {
265
266 }
267 }
268 if (f == null) {
269 f = new File(path);
270 }
271 return f;
272 }
273
274
275
276
277
278 public File[] getFiles() {
279 return files_;
280 }
281
282
283
284
285
286 @Override
287 public boolean isValid() {
288 return isCustomValidityValid()
289 && (!isRequiredSupported()
290 || ATTRIBUTE_NOT_DEFINED == getAttributeDirect("required")
291 || files_.length > 0);
292 }
293
294 @Override
295 protected void adjustValueAfterTypeChange(final HtmlInput oldInput, final BrowserVersion browserVersion) {
296 setValue("");
297 }
298 }