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 FileObject.close(fileObject);
96 }
97
98
99
100
101 @Override
102 protected void doCreateFolder() throws Exception {
103 ignoreEvent = true;
104 try {
105 fileObject.createFolder();
106 } finally {
107 ignoreEvent = false;
108 }
109 }
110
111
112
113
114 @Override
115 protected void doDelete() throws Exception {
116 ignoreEvent = true;
117 try {
118 fileObject.delete();
119 } finally {
120 ignoreEvent = false;
121 }
122 }
123
124
125
126
127 @Override
128 protected Map<String, Object> doGetAttributes() throws Exception {
129 return getFileContent().getAttributes();
130 }
131
132
133
134
135 @Override
136 protected Certificate[] doGetCertificates() throws Exception {
137 return getFileContent().getCertificates();
138 }
139
140
141
142
143
144
145
146
147 protected FileContentInfo doGetContentInfo() throws Exception {
148 return getFileContent().getContentInfo();
149 }
150
151
152
153
154
155 @Override
156 protected long doGetContentSize() throws Exception {
157 return getFileContent().getSize();
158 }
159
160
161
162
163 @Override
164 protected InputStream doGetInputStream(final int bufferSize) throws Exception {
165 return getFileContent().getInputStream(bufferSize);
166 }
167
168
169
170
171 @Override
172 protected long doGetLastModifiedTime() throws Exception {
173 return getFileContent().getLastModifiedTime();
174 }
175
176
177
178
179 @Override
180 protected OutputStream doGetOutputStream(final boolean bAppend) throws Exception {
181 return getFileContent().getOutputStream(bAppend);
182 }
183
184
185
186
187
188
189 @Override
190 protected RandomAccessContent doGetRandomAccessContent(final RandomAccessMode mode) throws Exception {
191 return getFileContent().getRandomAccessContent(mode);
192 }
193
194
195
196
197 @Override
198 protected FileType doGetType() throws FileSystemException {
199 if (fileObject != null) {
200 return fileObject.getType();
201 }
202 if (children.isEmpty()) {
203 return FileType.IMAGINARY;
204 }
205 return FileType.FOLDER;
206 }
207
208
209
210
211 @Override
212 protected boolean doIsExecutable() throws FileSystemException {
213 if (fileObject != null) {
214 return fileObject.isExecutable();
215 }
216 return false;
217 }
218
219
220
221
222 @Override
223 protected boolean doIsHidden() throws FileSystemException {
224 if (fileObject != null) {
225 return fileObject.isHidden();
226 }
227 return false;
228 }
229
230
231
232
233 @Override
234 protected boolean doIsReadable() throws FileSystemException {
235 if (fileObject != null) {
236 return fileObject.isReadable();
237 }
238 return true;
239 }
240
241
242
243
244 @Override
245 protected boolean doIsWriteable() throws FileSystemException {
246 if (fileObject != null) {
247 return fileObject.isWriteable();
248 }
249 return false;
250 }
251
252
253
254
255 @Override
256 protected String[] doListChildren() throws Exception {
257 if (fileObject != null) {
258 final FileObject[] children;
259
260 try {
261 children = fileObject.getChildren();
262 } catch (final FileNotFolderException e) {
263
264 throw new FileNotFolderException(getName(), e);
265 }
266
267 return Stream.of(children).filter(Objects::nonNull).map(child -> child.getName().getBaseName()).toArray(String[]::new);
268 }
269 return children.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
270 }
271
272
273
274
275
276
277 @Override
278 protected void doRemoveAttribute(final String attrName) throws Exception {
279 getFileContent().removeAttribute(attrName);
280 }
281
282
283
284
285
286
287
288
289 @Override
290 protected void doRename(final FileObject newFile) throws Exception {
291 fileObject.moveTo(((DelegateFileObject) newFile).fileObject);
292 }
293
294
295
296
297 @Override
298 protected void doSetAttribute(final String attrName, final Object value) throws Exception {
299 getFileContent().setAttribute(attrName, value);
300 }
301
302
303
304
305
306
307 @Override
308 protected boolean doSetLastModifiedTime(final long modtime) throws Exception {
309 getFileContent().setLastModifiedTime(modtime);
310 return true;
311 }
312
313
314
315
316
317
318
319
320
321
322 @Override
323 public void fileChanged(final FileChangeEvent event) throws Exception {
324 if (event.getFileObject() != fileObject) {
325 return;
326 }
327 if (!ignoreEvent) {
328 handleChanged();
329 }
330 }
331
332
333
334
335
336
337
338 @Override
339 public void fileCreated(final FileChangeEvent event) throws Exception {
340 if (event.getFileObject() != fileObject) {
341 return;
342 }
343 if (!ignoreEvent) {
344 handleCreate(fileObject.getType());
345 }
346 }
347
348
349
350
351
352
353
354 @Override
355 public void fileDeleted(final FileChangeEvent event) throws Exception {
356 if (event.getFileObject() != fileObject) {
357 return;
358 }
359 if (!ignoreEvent) {
360 handleDelete();
361 }
362 }
363
364
365
366
367
368
369
370 public FileObject getDelegateFile() {
371 return fileObject;
372 }
373
374 FileContent getFileContent() throws FileSystemException {
375 return fileObject.getContent();
376 }
377
378
379
380
381
382
383
384 private void maybeTypeChanged(final FileType oldType) throws Exception {
385 final FileType newType = doGetType();
386 if (oldType == FileType.IMAGINARY && newType != FileType.IMAGINARY) {
387 handleCreate(newType);
388 } else if (oldType != FileType.IMAGINARY && newType == FileType.IMAGINARY) {
389 handleDelete();
390 }
391 }
392
393
394
395
396
397
398
399 @Override
400 public void refresh() throws FileSystemException {
401 super.refresh();
402 if (fileObject != null) {
403 fileObject.refresh();
404 }
405 }
406
407
408
409
410
411
412
413 public void setFile(final FileObject fileObject) throws Exception {
414 final FileType oldType = doGetType();
415 if (fileObject != null) {
416 WeakRefFileListener.installListener(fileObject, this);
417 }
418 this.fileObject = fileObject;
419 maybeTypeChanged(oldType);
420 }
421 }