1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript.host.file;
16
17 import static org.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
18 import static org.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
19
20 import java.io.IOException;
21 import java.nio.charset.Charset;
22 import java.nio.charset.StandardCharsets;
23 import java.time.Instant;
24 import java.time.ZoneId;
25 import java.time.format.DateTimeFormatter;
26
27 import org.apache.commons.io.FileUtils;
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.htmlunit.BrowserVersion;
31 import org.htmlunit.corejs.javascript.Context;
32 import org.htmlunit.corejs.javascript.NativeArray;
33 import org.htmlunit.corejs.javascript.ScriptableObject;
34 import org.htmlunit.javascript.JavaScriptEngine;
35 import org.htmlunit.javascript.configuration.JsxClass;
36 import org.htmlunit.javascript.configuration.JsxConstructor;
37 import org.htmlunit.javascript.configuration.JsxFunction;
38 import org.htmlunit.javascript.configuration.JsxGetter;
39 import org.htmlunit.util.KeyDataPair;
40
41
42
43
44
45
46
47 @JsxClass
48 public class File extends Blob {
49
50 private static final DateTimeFormatter LAST_MODIFIED_DATE_FORMATTER
51 = DateTimeFormatter.ofPattern("EEE MMM dd yyyy HH:mm:ss 'GMT'Z");
52
53 private static class FileBackend extends Backend {
54 private static final Log LOG = LogFactory.getLog(FileBackend.class);
55
56 private final java.io.File file_;
57
58 FileBackend(final String pathname) {
59 super();
60 file_ = new java.io.File(pathname);
61 }
62
63 @Override
64 public String getName() {
65 return file_.getName();
66 }
67
68 @Override
69 public long getLastModified() {
70 return file_.lastModified();
71 }
72
73 @Override
74 public long getSize() {
75 return file_.length();
76 }
77
78 @Override
79 public String getType(final BrowserVersion browserVersion) {
80 return browserVersion.getUploadMimeType(file_);
81 }
82
83 @Override
84 public String getText() throws IOException {
85 return FileUtils.readFileToString(file_, StandardCharsets.UTF_8);
86 }
87
88 @Override
89 byte[] getBytes(final int start, final int end) {
90 final byte[] result = new byte[end - start];
91 try {
92 System.arraycopy(FileUtils.readFileToByteArray(file_), start, result, 0, result.length);
93 }
94 catch (final IOException e) {
95 LOG.error("FileBackend.getBytes failed", e);
96 }
97 return result;
98 }
99
100
101
102
103 @Override
104 public KeyDataPair getKeyDataPair(final String name, final String fileName, final String contentType) {
105 return new KeyDataPair(name, file_, fileName, contentType, (Charset) null);
106 }
107 }
108
109
110
111
112 public File() {
113 super();
114 }
115
116
117
118
119
120
121
122 @JsxConstructor
123 public void jsConstructor(final NativeArray fileBits, final String fileName, final ScriptableObject properties) {
124 if (fileBits == null
125 || JavaScriptEngine.isUndefined(fileBits)
126 || fileName == null
127 || JavaScriptEngine.isUndefined(fileName)) {
128 throw JavaScriptEngine.typeError("Failed to construct 'File': 2 arguments required.");
129 }
130
131 setBackend(InMemoryBackend.create(fileBits, fileName,
132 extractFileTypeOrDefault(properties),
133 extractLastModifiedOrDefault(properties)));
134 }
135
136 File(final String pathname) {
137 super();
138 setBackend(new FileBackend(pathname));
139 }
140
141
142
143
144
145 @JsxGetter
146 public String getName() {
147 return getBackend().getName();
148 }
149
150
151
152
153
154 @JsxGetter({CHROME, EDGE})
155 public String getLastModifiedDate() {
156 final Context cx = Context.getCurrentContext();
157 final ZoneId zoneid = cx.getTimeZone().toZoneId();
158
159
160 String date = LAST_MODIFIED_DATE_FORMATTER.format(Instant.ofEpochMilli(getLastModified()).atZone(zoneid));
161 date += DateTimeFormatter.ofPattern(" (zzzz)", cx.getLocale())
162 .format(Instant.ofEpochMilli(getLastModified()).atZone(zoneid));
163 return date;
164 }
165
166
167
168
169
170 @JsxGetter
171 public long getLastModified() {
172 return getBackend().getLastModified();
173 }
174
175
176
177
178
179 @JsxGetter
180 public String getWebkitRelativePath() {
181 return "";
182 }
183
184
185
186
187 @JsxFunction
188 public void slice() {
189
190 }
191 }