1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.vfs2.provider;
18
19 import java.io.InputStream;
20 import java.io.OutputStream;
21 import java.security.cert.Certificate;
22 import java.util.HashSet;
23 import java.util.Map;
24 import java.util.Objects;
25 import java.util.Set;
26 import java.util.stream.Stream;
27
28 import org.apache.commons.lang3.ArrayUtils;
29 import org.apache.commons.vfs2.FileChangeEvent;
30 import org.apache.commons.vfs2.FileContent;
31 import org.apache.commons.vfs2.FileContentInfo;
32 import org.apache.commons.vfs2.FileListener;
33 import org.apache.commons.vfs2.FileName;
34 import org.apache.commons.vfs2.FileNotFolderException;
35 import org.apache.commons.vfs2.FileObject;
36 import org.apache.commons.vfs2.FileSystemException;
37 import org.apache.commons.vfs2.FileType;
38 import org.apache.commons.vfs2.RandomAccessContent;
39 import org.apache.commons.vfs2.util.RandomAccessMode;
40 import org.apache.commons.vfs2.util.WeakRefFileListener;
41
42
43
44
45
46
47
48
49
50 public class DelegateFileObject<AFS extends AbstractFileSystem> extends AbstractFileObject<AFS> implements FileListener {
51
52 private FileObject fileObject;
53 private final Set<String> children = new HashSet<>();
54 private boolean ignoreEvent;
55
56
57
58
59
60
61
62
63
64 public DelegateFileObject(final AbstractFileName fileName, final AFS fileSystem, final FileObject fileObject) throws FileSystemException {
65 super(fileName, fileSystem);
66 this.fileObject = fileObject;
67 if (fileObject != null) {
68 WeakRefFileListener.installListener(fileObject, this);
69 }
70 }
71
72
73
74
75
76
77
78
79 public void attachChild(final FileName baseName, final FileType type) throws Exception {
80 final FileType oldType = doGetType();
81 if (children.add(baseName.getBaseName())) {
82 childrenChanged(baseName, type);
83 }
84 maybeTypeChanged(oldType);
85 }
86
87
88
89
90
91
92 @Override
93 public void close() throws FileSystemException {
94 super.close();
95
96 if (fileObject != null) {
97 fileObject.close();
98 }
99 }
100
101
102
103
104 @Override
105 protected void doCreateFolder() throws Exception {
106 ignoreEvent = true;
107 try {
108 fileObject.createFolder();
109 } finally {
110 ignoreEvent = false;
111 }
112 }
113
114
115
116
117 @Override
118 protected void doDelete() throws Exception {
119 ignoreEvent = true;
120 try {
121 fileObject.delete();
122 } finally {
123 ignoreEvent = false;
124 }
125 }
126
127
128
129
130 @Override
131 protected Map<String, Object> doGetAttributes() throws Exception {
132 return getFileContent().getAttributes();
133 }
134
135
136
137
138 @Override
139 protected Certificate[] doGetCertificates() throws Exception {
140 return getFileContent().getCertificates();
141 }
142
143
144
145
146
147
148
149
150 protected FileContentInfo doGetContentInfo() throws Exception {
151 return getFileContent().getContentInfo();
152 }
153
154
155
156
157
158 @Override
159 protected long doGetContentSize() throws Exception {
160 return getFileContent().getSize();
161 }
162
163
164
165
166 @Override
167 protected InputStream doGetInputStream(final int bufferSize) throws Exception {
168 return getFileContent().getInputStream(bufferSize);
169 }
170
171
172
173
174 @Override
175 protected long doGetLastModifiedTime() throws Exception {
176 return getFileContent().getLastModifiedTime();
177 }
178
179
180
181
182 @Override
183 protected OutputStream doGetOutputStream(final boolean bAppend) throws Exception {
184 return getFileContent().getOutputStream(bAppend);
185 }
186
187
188
189
190
191
192 @Override
193 protected RandomAccessContent doGetRandomAccessContent(final RandomAccessMode mode) throws Exception {
194 return getFileContent().getRandomAccessContent(mode);
195 }
196
197
198
199
200 @Override
201 protected FileType doGetType() throws FileSystemException {
202 if (fileObject != null) {
203 return fileObject.getType();
204 }
205 if (children.isEmpty()) {
206 return FileType.IMAGINARY;
207 }
208 return FileType.FOLDER;
209 }
210
211
212
213
214 @Override
215 protected boolean doIsExecutable() throws FileSystemException {
216 if (fileObject != null) {
217 return fileObject.isExecutable();
218 }
219 return false;
220 }
221
222
223
224
225 @Override
226 protected boolean doIsHidden() throws FileSystemException {
227 if (fileObject != null) {
228 return fileObject.isHidden();
229 }
230 return false;
231 }
232
233
234
235
236 @Override
237 protected boolean doIsReadable() throws FileSystemException {
238 if (fileObject != null) {
239 return fileObject.isReadable();
240 }
241 return true;
242 }
243
244
245
246
247 @Override
248 protected boolean doIsWriteable() throws FileSystemException {
249 if (fileObject != null) {
250 return fileObject.isWriteable();
251 }
252 return false;
253 }
254
255
256
257
258 @Override
259 protected String[] doListChildren() throws Exception {
260 if (fileObject != null) {
261 final FileObject[] children;
262
263 try {
264 children = fileObject.getChildren();
265 } catch (final FileNotFolderException e) {
266
267 throw new FileNotFolderException(getName(), e);
268 }
269
270 return Stream.of(children).filter(Objects::nonNull).map(child -> child.getName().getBaseName()).toArray(String[]::new);
271 }
272 return children.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
273 }
274
275
276
277
278
279
280 @Override
281 protected void doRemoveAttribute(final String attrName) throws Exception {
282 getFileContent().removeAttribute(attrName);
283 }
284
285
286
287
288
289
290
291
292 @Override
293 protected void doRename(final FileObject newFile) throws Exception {
294 fileObject.moveTo(((DelegateFileObject) newFile).fileObject);
295 }
296
297
298
299
300 @Override
301 protected void doSetAttribute(final String attrName, final Object value) throws Exception {
302 getFileContent().setAttribute(attrName, value);
303 }
304
305
306
307
308
309
310 @Override
311 protected boolean doSetLastModifiedTime(final long modtime) throws Exception {
312 getFileContent().setLastModifiedTime(modtime);
313 return true;
314 }
315
316
317
318
319
320
321
322
323
324
325 @Override
326 public void fileChanged(final FileChangeEvent event) throws Exception {
327 if (event.getFileObject() != fileObject) {
328 return;
329 }
330 if (!ignoreEvent) {
331 handleChanged();
332 }
333 }
334
335
336
337
338
339
340
341 @Override
342 public void fileCreated(final FileChangeEvent event) throws Exception {
343 if (event.getFileObject() != fileObject) {
344 return;
345 }
346 if (!ignoreEvent) {
347 handleCreate(fileObject.getType());
348 }
349 }
350
351
352
353
354
355
356
357 @Override
358 public void fileDeleted(final FileChangeEvent event) throws Exception {
359 if (event.getFileObject() != fileObject) {
360 return;
361 }
362 if (!ignoreEvent) {
363 handleDelete();
364 }
365 }
366
367
368
369
370
371
372
373 public FileObject getDelegateFile() {
374 return fileObject;
375 }
376
377 FileContent getFileContent() throws FileSystemException {
378 return fileObject.getContent();
379 }
380
381
382
383
384
385
386
387 private void maybeTypeChanged(final FileType oldType) throws Exception {
388 final FileType newType = doGetType();
389 if (oldType == FileType.IMAGINARY && newType != FileType.IMAGINARY) {
390 handleCreate(newType);
391 } else if (oldType != FileType.IMAGINARY && newType == FileType.IMAGINARY) {
392 handleDelete();
393 }
394 }
395
396
397
398
399
400
401
402 @Override
403 public void refresh() throws FileSystemException {
404 super.refresh();
405 if (fileObject != null) {
406 fileObject.refresh();
407 }
408 }
409
410
411
412
413
414
415
416 public void setFile(final FileObject fileObject) throws Exception {
417 final FileType oldType = doGetType();
418 if (fileObject != null) {
419 WeakRefFileListener.installListener(fileObject, this);
420 }
421 this.fileObject = fileObject;
422 maybeTypeChanged(oldType);
423 }
424 }