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.BufferedInputStream;
20 import java.io.FileNotFoundException;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.OutputStream;
24 import java.net.URL;
25 import java.security.AccessController;
26 import java.security.PrivilegedActionException;
27 import java.security.PrivilegedExceptionAction;
28 import java.security.cert.Certificate;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Collections;
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.stream.Stream;
36
37 import org.apache.commons.vfs2.Capability;
38 import org.apache.commons.vfs2.FileContent;
39 import org.apache.commons.vfs2.FileContentInfoFactory;
40 import org.apache.commons.vfs2.FileName;
41 import org.apache.commons.vfs2.FileNotFolderException;
42 import org.apache.commons.vfs2.FileObject;
43 import org.apache.commons.vfs2.FileSelector;
44 import org.apache.commons.vfs2.FileSystem;
45 import org.apache.commons.vfs2.FileSystemException;
46 import org.apache.commons.vfs2.FileType;
47 import org.apache.commons.vfs2.NameScope;
48 import org.apache.commons.vfs2.RandomAccessContent;
49 import org.apache.commons.vfs2.Selectors;
50 import org.apache.commons.vfs2.operations.DefaultFileOperations;
51 import org.apache.commons.vfs2.operations.FileOperations;
52 import org.apache.commons.vfs2.util.FileObjectUtils;
53 import org.apache.commons.vfs2.util.RandomAccessMode;
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 public abstract class AbstractFileObject<AFS extends AbstractFileSystem> implements FileObject {
69
70 private static final String DO_GET_INPUT_STREAM_INT = "doGetInputStream(int)";
71
72
73
74
75 public static final int DEFAULT_BUFFER_SIZE = 8192;
76
77 private static final int INITIAL_LIST_SIZE = 5;
78
79
80
81
82 private static void traverse(final DefaultFileSelectorInfo fileInfo, final FileSelector selector,
83 final boolean depthwise, final List<FileObject> selected) throws Exception {
84
85 final FileObject file = fileInfo.getFile();
86 final int index = selected.size();
87
88
89 if (file.getType().hasChildren() && selector.traverseDescendents(fileInfo)) {
90 final int curDepth = fileInfo.getDepth();
91 fileInfo.setDepth(curDepth + 1);
92
93
94 final FileObject[] children = file.getChildren();
95 for (final FileObject child : children) {
96 fileInfo.setFile(child);
97 traverse(fileInfo, selector, depthwise, selected);
98 }
99
100 fileInfo.setFile(file);
101 fileInfo.setDepth(curDepth);
102 }
103
104
105 if (selector.includeFile(fileInfo)) {
106 if (depthwise) {
107
108 selected.add(file);
109 } else {
110
111 selected.add(index, file);
112 }
113 }
114 }
115 private final AbstractFileName fileName;
116
117 private final AFS fileSystem;
118 private FileContent content;
119
120 private boolean attached;
121
122 private FileType type;
123 private FileObject parent;
124
125
126
127
128 private FileName[] children;
129
130 private List<Object> objects;
131
132
133
134
135 private FileOperations operations;
136
137
138
139
140
141
142
143 protected AbstractFileObject(final AbstractFileName name, final AFS fileSystem) {
144 this.fileName = name;
145 this.fileSystem = fileSystem;
146 fileSystem.fileObjectHanded(this);
147 }
148
149
150
151
152
153
154 private void attach() throws FileSystemException {
155 synchronized (fileSystem) {
156 if (attached) {
157 return;
158 }
159
160 try {
161
162 doAttach();
163 attached = true;
164
165
166
167
168
169
170 } catch (final Exception exc) {
171 throw new FileSystemException("vfs.provider/get-type.error", exc, fileName);
172 }
173
174
175 }
176 }
177
178
179
180
181
182
183
184 @Override
185 public boolean canRenameTo(final FileObject newfile) {
186 return fileSystem == newfile.getFileSystem();
187 }
188
189
190
191
192
193
194
195
196 protected void childrenChanged(final FileName childName, final FileType newType) throws Exception {
197
198
199 if (children != null && childName != null && newType != null) {
200
201 final ArrayList<FileName> list = new ArrayList<>(Arrays.asList(children));
202 if (newType.equals(FileType.IMAGINARY)) {
203 list.remove(childName);
204 } else {
205 list.add(childName);
206 }
207 children = list.toArray(FileName.EMPTY_ARRAY);
208 }
209
210
211 onChildrenChanged(childName, newType);
212 }
213
214
215
216
217
218
219 @Override
220 public void close() throws FileSystemException {
221 FileSystemException exc = null;
222
223 synchronized (fileSystem) {
224
225 if (content != null) {
226 try {
227 content.close();
228 content = null;
229 } catch (final FileSystemException e) {
230 exc = e;
231 }
232 }
233
234
235 try {
236 detach();
237 } catch (final Exception e) {
238 exc = new FileSystemException("vfs.provider/close.error", fileName, e);
239 }
240
241 if (exc != null) {
242 throw exc;
243 }
244 }
245 }
246
247
248
249
250
251
252
253
254 @Override
255 public int compareTo(final FileObject file) {
256 if (file == null) {
257 return 1;
258 }
259 return this.toString().compareToIgnoreCase(file.toString());
260 }
261
262
263
264
265
266
267
268
269 @Override
270 public void copyFrom(final FileObject file, final FileSelector selector) throws FileSystemException {
271 if (!FileObjectUtils.exists(file)) {
272 throw new FileSystemException("vfs.provider/copy-missing-file.error", file);
273 }
274
275
276 final ArrayList<FileObject> files = new ArrayList<>();
277 file.findFiles(selector, false, files);
278
279
280 for (final FileObject srcFile : files) {
281
282 final String relPath = file.getName().getRelativeName(srcFile.getName());
283 final FileObject destFile = resolveFile(relPath, NameScope.DESCENDENT_OR_SELF);
284
285
286 if (FileObjectUtils.exists(destFile) && destFile.getType() != srcFile.getType()) {
287
288
289
290 destFile.deleteAll();
291 }
292
293
294 try {
295 if (srcFile.getType().hasContent()) {
296 FileObjectUtils.writeContent(srcFile, destFile);
297 } else if (srcFile.getType().hasChildren()) {
298 destFile.createFolder();
299 }
300 } catch (final IOException e) {
301 throw new FileSystemException("vfs.provider/copy-file.error", e, srcFile, destFile);
302 }
303 }
304 }
305
306
307
308
309
310
311 @Override
312 public void createFile() throws FileSystemException {
313 synchronized (fileSystem) {
314 try {
315
316
317 if (exists() && !isFile()) {
318 throw new FileSystemException("vfs.provider/create-file.error", fileName);
319 }
320
321 if (!exists()) {
322 getOutputStream().close();
323 endOutput();
324 }
325 } catch (final RuntimeException re) {
326 throw re;
327 } catch (final Exception e) {
328 throw new FileSystemException("vfs.provider/create-file.error", fileName, e);
329 }
330 }
331 }
332
333
334
335
336
337
338 @Override
339 public void createFolder() throws FileSystemException {
340 synchronized (fileSystem) {
341
342 if (getType().hasChildren()) {
343
344 return;
345 }
346 if (getType() != FileType.IMAGINARY) {
347 throw new FileSystemException("vfs.provider/create-folder-mismatched-type.error", fileName);
348 }
349
350
351
352
353
354
355
356 final FileObject parent = getParent();
357 if (parent != null) {
358 parent.createFolder();
359 }
360
361 try {
362
363 doCreateFolder();
364
365
366 handleCreate(FileType.FOLDER);
367 } catch (final RuntimeException re) {
368 throw re;
369 } catch (final Exception exc) {
370 throw new FileSystemException("vfs.provider/create-folder.error", fileName, exc);
371 }
372 }
373 }
374
375
376
377
378
379
380
381
382
383
384 @Override
385 public boolean delete() throws FileSystemException {
386 return delete(Selectors.SELECT_SELF) > 0;
387 }
388
389
390
391
392
393
394
395
396 @Override
397 public int delete(final FileSelector selector) throws FileSystemException {
398 int nuofDeleted = 0;
399
400
401
402
403
404
405 final ArrayList<FileObject> files = new ArrayList<>();
406 findFiles(selector, true, files);
407
408
409 final int count = files.size();
410 for (final FileObject fileObject : files) {
411 final AbstractFileObject file = FileObjectUtils.getAbstractFileObject(fileObject);
412
413
414
415
416
417 if (file.getType().hasChildren() && file.getChildren().length != 0) {
418
419 continue;
420 }
421
422
423 if (file.deleteSelf()) {
424 nuofDeleted++;
425 }
426 }
427
428 return nuofDeleted;
429 }
430
431
432
433
434
435
436
437
438
439 @Override
440 public int deleteAll() throws FileSystemException {
441 return this.delete(Selectors.SELECT_ALL);
442 }
443
444
445
446
447
448
449
450 private boolean deleteSelf() throws FileSystemException {
451 synchronized (fileSystem) {
452
453
454
455
456
457
458 try {
459
460 doDelete();
461
462
463 handleDelete();
464 } catch (final RuntimeException re) {
465 throw re;
466 } catch (final Exception exc) {
467 throw new FileSystemException("vfs.provider/delete.error", exc, fileName);
468 }
469
470 return true;
471 }
472 }
473
474
475
476
477
478
479
480 private void detach() throws Exception {
481 synchronized (fileSystem) {
482 if (attached) {
483 try {
484 doDetach();
485 } finally {
486 attached = false;
487 setFileType(null);
488 parent = null;
489
490
491
492 removeChildrenCache();
493
494 }
495 }
496 }
497 }
498
499
500
501
502
503
504
505
506
507
508
509
510
511 protected void doAttach() throws Exception {
512
513 }
514
515
516
517
518
519
520
521
522 protected FileContent doCreateFileContent() throws FileSystemException {
523 return new DefaultFileContent(this, getFileContentInfoFactory());
524 }
525
526
527
528
529
530
531
532
533
534
535
536 protected void doCreateFolder() throws Exception {
537 throw new FileSystemException("vfs.provider/create-folder-not-supported.error");
538 }
539
540
541
542
543
544
545
546
547
548
549
550
551 protected void doDelete() throws Exception {
552 throw new FileSystemException("vfs.provider/delete-not-supported.error");
553 }
554
555
556
557
558
559
560
561
562
563
564
565
566
567 protected void doDetach() throws Exception {
568
569 }
570
571
572
573
574
575
576
577
578
579
580
581 protected Map<String, Object> doGetAttributes() throws Exception {
582 return Collections.emptyMap();
583 }
584
585
586
587
588
589
590
591
592
593
594
595 protected Certificate[] doGetCertificates() throws Exception {
596 return null;
597 }
598
599
600
601
602
603
604
605
606 protected abstract long doGetContentSize() throws Exception;
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621 protected InputStream doGetInputStream() throws Exception {
622
623 return doGetInputStream(DEFAULT_BUFFER_SIZE);
624 }
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639 protected InputStream doGetInputStream(final int bufferSize) throws Exception {
640 throw new UnsupportedOperationException(DO_GET_INPUT_STREAM_INT);
641 }
642
643
644
645
646
647
648
649
650
651
652 protected long doGetLastModifiedTime() throws Exception {
653 throw new FileSystemException("vfs.provider/get-last-modified-not-supported.error");
654 }
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675 protected OutputStream doGetOutputStream(final boolean bAppend) throws Exception {
676 throw new FileSystemException("vfs.provider/write-not-supported.error");
677 }
678
679
680
681
682
683
684
685
686
687
688
689 protected RandomAccessContent doGetRandomAccessContent(final RandomAccessMode mode) throws Exception {
690 throw new FileSystemException("vfs.provider/random-access-not-supported.error");
691 }
692
693
694
695
696
697
698
699
700 protected abstract FileType doGetType() throws Exception;
701
702
703
704
705
706
707
708
709
710
711
712 protected boolean doIsExecutable() throws Exception {
713 return false;
714 }
715
716
717
718
719
720
721
722
723
724
725
726 protected boolean doIsHidden() throws Exception {
727 return false;
728 }
729
730
731
732
733
734
735
736
737
738
739
740 protected boolean doIsReadable() throws Exception {
741 return true;
742 }
743
744
745
746
747
748
749
750
751
752 protected boolean doIsSameFile(final FileObject destFile) throws FileSystemException {
753 return false;
754 }
755
756
757
758
759
760
761
762
763
764
765
766
767 protected boolean doIsSymbolicLink() throws Exception {
768 return false;
769 }
770
771
772
773
774
775
776
777
778
779
780
781 protected boolean doIsWriteable() throws Exception {
782 return true;
783 }
784
785
786
787
788
789
790
791
792
793 protected abstract String[] doListChildren() throws Exception;
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811 protected FileObject[] doListChildrenResolved() throws Exception {
812 return null;
813 }
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828 protected void doRemoveAttribute(final String attrName) throws Exception {
829 throw new FileSystemException("vfs.provider/remove-attribute-not-supported.error");
830 }
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847 protected void doRename(final FileObject newFile) throws Exception {
848 throw new FileSystemException("vfs.provider/rename-not-supported.error");
849 }
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864 protected void doSetAttribute(final String attrName, final Object value) throws Exception {
865 throw new FileSystemException("vfs.provider/set-attribute-not-supported.error");
866 }
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884 protected boolean doSetExecutable(final boolean executable, final boolean ownerOnly) throws Exception {
885 return false;
886 }
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901 protected boolean doSetLastModifiedTime(final long modtime) throws Exception {
902 throw new FileSystemException("vfs.provider/set-last-modified-not-supported.error");
903 }
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921 protected boolean doSetReadable(final boolean readable, final boolean ownerOnly) throws Exception {
922 return false;
923 }
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938 protected boolean doSetWritable(final boolean writable, final boolean ownerOnly) throws Exception {
939 return false;
940 }
941
942
943
944
945
946
947 protected void endOutput() throws Exception {
948 if (getType() == FileType.IMAGINARY) {
949
950 handleCreate(FileType.FILE);
951 } else {
952
953 onChange();
954 }
955 }
956
957
958
959
960
961
962
963 @Override
964 public boolean exists() throws FileSystemException {
965 return getType() != FileType.IMAGINARY;
966 }
967
968 private FileName[] extractNames(final FileObject[] objects) {
969 if (objects == null) {
970 return null;
971 }
972 return Stream.of(objects).map(FileObject::getName).toArray(FileName[]::new);
973 }
974
975 @Override
976 protected void finalize() throws Throwable {
977 fileSystem.fileObjectDestroyed(this);
978
979 super.finalize();
980 }
981
982
983
984
985
986
987
988
989 @Override
990 public FileObject[] findFiles(final FileSelector selector) throws FileSystemException {
991 final List<FileObject> list = this.listFiles(selector);
992 return list == null ? null : list.toArray(FileObject.EMPTY_ARRAY);
993 }
994
995
996
997
998
999
1000
1001
1002
1003 @Override
1004 public void findFiles(final FileSelector selector, final boolean depthwise, final List<FileObject> selected)
1005 throws FileSystemException {
1006 try {
1007 if (exists()) {
1008
1009 final DefaultFileSelectorInfoFileSelectorInfo.html#DefaultFileSelectorInfo">DefaultFileSelectorInfo info = new DefaultFileSelectorInfo();
1010 info.setBaseFolder(this);
1011 info.setDepth(0);
1012 info.setFile(this);
1013 traverse(info, selector, depthwise, selected);
1014 }
1015 } catch (final Exception e) {
1016 throw new FileSystemException("vfs.provider/find-files.error", fileName, e);
1017 }
1018 }
1019
1020
1021
1022
1023
1024
1025 protected AFS getAbstractFileSystem() {
1026 return fileSystem;
1027 }
1028
1029
1030
1031
1032
1033
1034
1035
1036 @Override
1037 public FileObject getChild(final String name) throws FileSystemException {
1038
1039 final FileObject[] children = getChildren();
1040 for (final FileObject element : children) {
1041 final FileName child = element.getName();
1042 final String childBaseName = child.getBaseName();
1043
1044 if (childBaseName.equals(name) || UriParser.decode(childBaseName).equals(name)) {
1045 return resolveFile(child);
1046 }
1047 }
1048 return null;
1049 }
1050
1051
1052
1053
1054
1055
1056
1057 @Override
1058 public FileObject[] getChildren() throws FileSystemException {
1059 synchronized (fileSystem) {
1060
1061 if (!fileSystem.hasCapability(Capability.LIST_CHILDREN)) {
1062 throw new FileNotFolderException(fileName);
1063 }
1064
1065
1066
1067
1068
1069 attach();
1070
1071
1072 if (children != null) {
1073 return resolveFiles(children);
1074 }
1075
1076
1077 final FileObject[] childrenObjects;
1078 try {
1079 childrenObjects = doListChildrenResolved();
1080 children = extractNames(childrenObjects);
1081 } catch (final FileSystemException exc) {
1082
1083 throw exc;
1084 } catch (final Exception exc) {
1085 throw new FileSystemException("vfs.provider/list-children.error", exc, fileName);
1086 }
1087
1088 if (childrenObjects != null) {
1089 return childrenObjects;
1090 }
1091
1092
1093 final String[] files;
1094 try {
1095 files = doListChildren();
1096 } catch (final FileSystemException exc) {
1097
1098 throw exc;
1099 } catch (final Exception exc) {
1100 throw new FileSystemException("vfs.provider/list-children.error", exc, fileName);
1101 }
1102
1103 if (files == null) {
1104
1105
1106
1107 throw new FileNotFolderException(fileName);
1108 }
1109 if (files.length == 0) {
1110
1111 children = FileName.EMPTY_ARRAY;
1112 } else {
1113
1114 final FileNameName.html#FileName">FileName[] cache = new FileName[files.length];
1115 for (int i = 0; i < files.length; i++) {
1116 final String file = "./" + files[i];
1117 cache[i] = fileSystem.getFileSystemManager().resolveName(fileName, file, NameScope.CHILD);
1118 }
1119
1120
1121 children = cache;
1122 }
1123
1124 return resolveFiles(children);
1125 }
1126 }
1127
1128
1129
1130
1131
1132
1133
1134 @Override
1135 public FileContent getContent() throws FileSystemException {
1136 synchronized (fileSystem) {
1137 attach();
1138 if (content == null) {
1139 content = doCreateFileContent();
1140 }
1141 return content;
1142 }
1143 }
1144
1145
1146
1147
1148
1149
1150 protected FileContentInfoFactory getFileContentInfoFactory() {
1151 return fileSystem.getFileSystemManager().getFileContentInfoFactory();
1152 }
1153
1154
1155
1156
1157
1158 @Override
1159 public FileOperations getFileOperations() throws FileSystemException {
1160 if (operations == null) {
1161 operations = new DefaultFileOperations(this);
1162 }
1163
1164 return operations;
1165 }
1166
1167
1168
1169
1170
1171
1172 @Override
1173 public FileSystem getFileSystem() {
1174 return fileSystem;
1175 }
1176
1177
1178
1179
1180
1181
1182
1183 public InputStream getInputStream() throws FileSystemException {
1184 return getInputStream(DEFAULT_BUFFER_SIZE);
1185 }
1186
1187
1188
1189
1190
1191
1192
1193
1194 public InputStream getInputStream(final int bufferSize) throws FileSystemException {
1195
1196 try {
1197 return doGetInputStream(bufferSize);
1198 } catch (final org.apache.commons.vfs2.FileNotFoundException | FileNotFoundException exc) {
1199 throw new org.apache.commons.vfs2.FileNotFoundException(fileName, exc);
1200 } catch (final FileSystemException exc) {
1201 throw exc;
1202 } catch (final UnsupportedOperationException exc) {
1203
1204 if (DO_GET_INPUT_STREAM_INT.equals(exc.getMessage())) {
1205 try {
1206
1207 return doGetInputStream();
1208 } catch (final Exception e) {
1209 if (e instanceof FileSystemException) {
1210 throw (FileSystemException) e;
1211 }
1212 throw new FileSystemException("vfs.provider/read.error", fileName, exc);
1213 }
1214 }
1215 throw exc;
1216 } catch (final Exception exc) {
1217 throw new FileSystemException("vfs.provider/read.error", fileName, exc);
1218 }
1219 }
1220
1221
1222
1223
1224
1225
1226 @Override
1227 public FileName getName() {
1228 return fileName;
1229 }
1230
1231
1232
1233
1234
1235
1236
1237
1238 public OutputStream getOutputStream() throws FileSystemException {
1239 return getOutputStream(false);
1240 }
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252 public OutputStream getOutputStream(final boolean bAppend) throws FileSystemException {
1253
1254
1255
1256
1257
1258
1259 if (bAppend && !fileSystem.hasCapability(Capability.APPEND_CONTENT)) {
1260 throw new FileSystemException("vfs.provider/write-append-not-supported.error", fileName);
1261 }
1262
1263 if (getType() == FileType.IMAGINARY) {
1264
1265 final FileObject parent = getParent();
1266 if (parent != null) {
1267 parent.createFolder();
1268 }
1269 }
1270
1271
1272 try {
1273 return doGetOutputStream(bAppend);
1274 } catch (final RuntimeException re) {
1275 throw re;
1276 } catch (final Exception exc) {
1277 throw new FileSystemException("vfs.provider/write.error", exc, fileName);
1278 }
1279 }
1280
1281
1282
1283
1284
1285
1286
1287 @Override
1288 public FileObject getParent() throws FileSystemException {
1289 if (this.compareTo(fileSystem.getRoot()) == 0)
1290 {
1291 if (fileSystem.getParentLayer() == null) {
1292
1293 return null;
1294 }
1295
1296 return fileSystem.getParentLayer().getParent();
1297 }
1298
1299 synchronized (fileSystem) {
1300
1301 if (parent == null) {
1302 final FileName name = fileName.getParent();
1303 if (name == null) {
1304 return null;
1305 }
1306 parent = fileSystem.resolveFile(name);
1307 }
1308 return parent;
1309 }
1310 }
1311
1312
1313
1314
1315
1316
1317 @Override
1318 public String getPublicURIString() {
1319 return fileName.getFriendlyURI();
1320 }
1321
1322
1323
1324
1325
1326
1327
1328
1329 public RandomAccessContent getRandomAccessContent(final RandomAccessMode mode) throws FileSystemException {
1330
1331
1332
1333
1334
1335 if (mode.requestRead()) {
1336 if (!fileSystem.hasCapability(Capability.RANDOM_ACCESS_READ)) {
1337 throw new FileSystemException("vfs.provider/random-access-read-not-supported.error");
1338 }
1339 if (!isReadable()) {
1340 throw new FileSystemException("vfs.provider/read-not-readable.error", fileName);
1341 }
1342 }
1343
1344 if (mode.requestWrite()) {
1345 if (!fileSystem.hasCapability(Capability.RANDOM_ACCESS_WRITE)) {
1346 throw new FileSystemException("vfs.provider/random-access-write-not-supported.error");
1347 }
1348 if (!isWriteable()) {
1349 throw new FileSystemException("vfs.provider/write-read-only.error", fileName);
1350 }
1351 }
1352
1353
1354 try {
1355 return doGetRandomAccessContent(mode);
1356 } catch (final Exception exc) {
1357 throw new FileSystemException("vfs.provider/random-access.error", fileName, exc);
1358 }
1359 }
1360
1361
1362
1363
1364
1365
1366
1367 @Override
1368 public FileType getType() throws FileSystemException {
1369 synchronized (fileSystem) {
1370 attach();
1371
1372
1373 try {
1374 if (type == null) {
1375 setFileType(doGetType());
1376 }
1377 if (type == null) {
1378 setFileType(FileType.IMAGINARY);
1379 }
1380 } catch (final Exception e) {
1381 throw new FileSystemException("vfs.provider/get-type.error", e, fileName);
1382 }
1383
1384 return type;
1385 }
1386 }
1387
1388
1389
1390
1391
1392
1393
1394 @Override
1395 public URL getURL() throws FileSystemException {
1396 try {
1397 return AccessController.doPrivileged((PrivilegedExceptionAction<URL>) () -> {
1398 final StringBuilder buf = new StringBuilder();
1399 final String scheme = UriParser.extractScheme(fileSystem.getContext().getFileSystemManager().getSchemes(), fileName.getURI(), buf);
1400 return new URL(scheme, "", -1, buf.toString(),
1401 new DefaultURLStreamHandler(fileSystem.getContext(), fileSystem.getFileSystemOptions()));
1402 });
1403 } catch (final PrivilegedActionException e) {
1404 throw new FileSystemException("vfs.provider/get-url.error", fileName, e.getException());
1405 }
1406 }
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416 protected void handleChanged() throws Exception {
1417
1418 fileSystem.fireFileChanged(this);
1419 }
1420
1421
1422
1423
1424
1425
1426
1427 protected void handleCreate(final FileType newType) throws Exception {
1428 synchronized (fileSystem) {
1429 if (attached) {
1430
1431 injectType(newType);
1432
1433 removeChildrenCache();
1434
1435
1436 onChange();
1437 }
1438
1439
1440 notifyParent(this.getName(), newType);
1441
1442
1443 fileSystem.fireFileCreated(this);
1444 }
1445 }
1446
1447
1448
1449
1450
1451
1452 protected void handleDelete() throws Exception {
1453 synchronized (fileSystem) {
1454 if (attached) {
1455
1456 injectType(FileType.IMAGINARY);
1457 removeChildrenCache();
1458
1459
1460 onChange();
1461 }
1462
1463
1464 notifyParent(this.getName(), FileType.IMAGINARY);
1465
1466
1467 fileSystem.fireFileDeleted(this);
1468 }
1469 }
1470
1471
1472
1473
1474
1475
1476
1477
1478 public void holdObject(final Object strongRef) {
1479 if (objects == null) {
1480 objects = new ArrayList<>(INITIAL_LIST_SIZE);
1481 }
1482 objects.add(strongRef);
1483 }
1484
1485 protected void injectType(final FileType fileType) {
1486 setFileType(fileType);
1487 }
1488
1489
1490
1491
1492
1493
1494 @Override
1495 public boolean isAttached() {
1496 return attached;
1497 }
1498
1499
1500
1501
1502
1503
1504 @Override
1505 public boolean isContentOpen() {
1506 if (content == null) {
1507 return false;
1508 }
1509
1510 return content.isOpen();
1511 }
1512
1513
1514
1515
1516
1517
1518
1519 @Override
1520 public boolean isExecutable() throws FileSystemException {
1521 try {
1522 return exists() && doIsExecutable();
1523 } catch (final Exception exc) {
1524 throw new FileSystemException("vfs.provider/check-is-executable.error", fileName, exc);
1525 }
1526 }
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536 @Override
1537 public boolean isFile() throws FileSystemException {
1538
1539 return FileType.FILE.equals(this.getType());
1540 }
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550 @Override
1551 public boolean isFolder() throws FileSystemException {
1552
1553 return FileType.FOLDER.equals(this.getType());
1554 }
1555
1556
1557
1558
1559
1560
1561
1562 @Override
1563 public boolean isHidden() throws FileSystemException {
1564 try {
1565 return exists() && doIsHidden();
1566 } catch (final Exception exc) {
1567 throw new FileSystemException("vfs.provider/check-is-hidden.error", fileName, exc);
1568 }
1569 }
1570
1571
1572
1573
1574
1575
1576
1577 @Override
1578 public boolean isReadable() throws FileSystemException {
1579 try {
1580 return exists() && doIsReadable();
1581 } catch (final Exception exc) {
1582 throw new FileSystemException("vfs.provider/check-is-readable.error", fileName, exc);
1583 }
1584 }
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594 protected boolean isSameFile(final FileObject destFile) throws FileSystemException {
1595 attach();
1596 return doIsSameFile(destFile);
1597 }
1598
1599
1600
1601
1602
1603
1604
1605
1606 @Override
1607 public boolean isSymbolicLink() throws FileSystemException {
1608 try {
1609 return exists() && doIsSymbolicLink();
1610 } catch (final Exception exc) {
1611 throw new FileSystemException("vfs.provider/check-is-symbolic-link.error", fileName, exc);
1612 }
1613 }
1614
1615
1616
1617
1618
1619
1620
1621 @Override
1622 public boolean isWriteable() throws FileSystemException {
1623 try {
1624 if (exists()) {
1625 return doIsWriteable();
1626 }
1627 final FileObject parent = getParent();
1628 if (parent != null) {
1629 return parent.isWriteable();
1630 }
1631 return true;
1632 } catch (final Exception exc) {
1633 throw new FileSystemException("vfs.provider/check-is-writable.error", fileName, exc);
1634 }
1635 }
1636
1637
1638
1639
1640
1641
1642 @Override
1643 public Iterator<FileObject> iterator() {
1644 try {
1645 return listFiles(Selectors.SELECT_ALL).iterator();
1646 } catch (final FileSystemException e) {
1647 throw new IllegalStateException(e);
1648 }
1649 }
1650
1651
1652
1653
1654
1655
1656
1657
1658 public List<FileObject> listFiles(final FileSelector selector) throws FileSystemException {
1659 if (!exists() || selector == null) {
1660 return null;
1661 }
1662
1663 final ArrayList<FileObject> list = new ArrayList<>();
1664 this.findFiles(selector, true, list);
1665 return list;
1666 }
1667
1668
1669
1670
1671
1672
1673
1674 @Override
1675 public void moveTo(final FileObject destFile) throws FileSystemException {
1676 if (canRenameTo(destFile)) {
1677 if (!getParent().isWriteable()) {
1678 throw new FileSystemException("vfs.provider/rename-parent-read-only.error", getName(),
1679 getParent().getName());
1680 }
1681 } else if (!isWriteable()) {
1682 throw new FileSystemException("vfs.provider/rename-read-only.error", getName());
1683 }
1684
1685 if (destFile.exists() && !isSameFile(destFile)) {
1686 destFile.deleteAll();
1687
1688 }
1689
1690 if (canRenameTo(destFile)) {
1691
1692 try {
1693 attach();
1694
1695 final FileType srcType = getType();
1696
1697 doRename(destFile);
1698
1699 FileObjectUtils.getAbstractFileObject(destFile).handleCreate(srcType);
1700 destFile.close();
1701
1702 handleDelete();
1703 } catch (final RuntimeException re) {
1704 throw re;
1705 } catch (final Exception exc) {
1706 throw new FileSystemException("vfs.provider/rename.error", exc, getName(), destFile.getName());
1707 }
1708 } else {
1709
1710
1711 destFile.copyFrom(this, Selectors.SELECT_SELF);
1712
1713 if ((destFile.getType().hasContent()
1714 && destFile.getFileSystem().hasCapability(Capability.SET_LAST_MODIFIED_FILE)
1715 || destFile.getType().hasChildren()
1716 && destFile.getFileSystem().hasCapability(Capability.SET_LAST_MODIFIED_FOLDER))
1717 && fileSystem.hasCapability(Capability.GET_LAST_MODIFIED)) {
1718 destFile.getContent().setLastModifiedTime(this.getContent().getLastModifiedTime());
1719 }
1720
1721 deleteSelf();
1722 }
1723
1724 }
1725
1726
1727
1728
1729 protected void notifyAllStreamsClosed() {
1730
1731 }
1732
1733
1734
1735
1736
1737
1738
1739
1740 private void notifyParent(final FileName childName, final FileType newType) throws Exception {
1741 if (parent == null) {
1742 final FileName parentName = fileName.getParent();
1743 if (parentName != null) {
1744
1745 parent = fileSystem.getFileFromCache(parentName);
1746 }
1747 }
1748
1749 if (parent != null) {
1750 FileObjectUtils.getAbstractFileObject(parent).childrenChanged(childName, newType);
1751 }
1752 }
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762 protected void onChange() throws Exception {
1763
1764 }
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777 protected void onChildrenChanged(final FileName child, final FileType newType) throws Exception {
1778
1779 }
1780
1781
1782
1783
1784
1785
1786 @Override
1787 public void refresh() throws FileSystemException {
1788
1789 try {
1790 detach();
1791 } catch (final Exception e) {
1792 throw new FileSystemException("vfs.provider/resync.error", fileName, e);
1793 }
1794 }
1795
1796 private void removeChildrenCache() {
1797 children = null;
1798 }
1799
1800 private FileObject resolveFile(final FileName child) throws FileSystemException {
1801 return fileSystem.resolveFile(child);
1802 }
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812 @Override
1813 public FileObject resolveFile(final String path) throws FileSystemException {
1814 final FileName otherName = fileSystem.getFileSystemManager().resolveName(fileName, path);
1815 return fileSystem.resolveFile(otherName);
1816 }
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826 @Override
1827 public FileObject resolveFile(final String name, final NameScope scope) throws FileSystemException {
1828
1829 return fileSystem.resolveFile(fileSystem.getFileSystemManager().resolveName(this.fileName, name, scope));
1830 }
1831
1832 private FileObject[] resolveFiles(final FileName[] children) throws FileSystemException {
1833 if (children == null) {
1834 return null;
1835 }
1836
1837 final FileObjectct.html#FileObject">FileObject[] objects = new FileObject[children.length];
1838 for (int iterChildren = 0; iterChildren < children.length; iterChildren++) {
1839 objects[iterChildren] = resolveFile(children[iterChildren]);
1840 }
1841
1842 return objects;
1843 }
1844
1845 @Override
1846 public boolean setExecutable(final boolean readable, final boolean ownerOnly) throws FileSystemException {
1847 try {
1848 return exists() && doSetExecutable(readable, ownerOnly);
1849 } catch (final Exception exc) {
1850 throw new FileSystemException("vfs.provider/set-executable.error", fileName, exc);
1851 }
1852 }
1853
1854 private void setFileType(final FileType type) {
1855 if (type != null && type != FileType.IMAGINARY) {
1856 try {
1857 fileName.setType(type);
1858 } catch (final FileSystemException e) {
1859 throw new RuntimeException(e.getMessage());
1860 }
1861 }
1862 this.type = type;
1863 }
1864
1865 @Override
1866 public boolean setReadable(final boolean readable, final boolean ownerOnly) throws FileSystemException {
1867 try {
1868 return exists() && doSetReadable(readable, ownerOnly);
1869 } catch (final Exception exc) {
1870 throw new FileSystemException("vfs.provider/set-readable.error", fileName, exc);
1871 }
1872 }
1873
1874 @Override
1875 public boolean setWritable(final boolean readable, final boolean ownerOnly) throws FileSystemException {
1876 try {
1877 return exists() && doSetWritable(readable, ownerOnly);
1878 } catch (final Exception exc) {
1879 throw new FileSystemException("vfs.provider/set-writable.error", fileName, exc);
1880 }
1881 }
1882
1883
1884
1885
1886
1887
1888 @Override
1889 public String toString() {
1890 return fileName.getURI();
1891 }
1892 }