1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package wjhk.jupload2.gui.filepanel.treeview;
27
28 import java.io.File;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.lang.reflect.Array;
32 import java.util.ArrayList;
33 import java.util.Date;
34 import java.util.List;
35
36 import javax.swing.tree.TreeModel;
37 import javax.swing.tree.TreePath;
38
39 import wjhk.jupload2.exception.JUploadException;
40 import wjhk.jupload2.exception.JUploadExceptionStopAddingFiles;
41 import wjhk.jupload2.exception.JUploadIOException;
42 import wjhk.jupload2.filedata.FileData;
43 import wjhk.jupload2.gui.filepanel.FilePanelFlatDataModel2;
44 import wjhk.jupload2.policies.UploadPolicy;
45 import wjhk.jupload2.upload.helper.ByteArrayEncoder;
46
47
48
49
50 public class FolderNode implements TreeFileDataNode {
51
52
53
54 MyTreeTableModel<TreeFileDataNode> treeModel = null;
55
56
57
58
59
60
61
62
63 FilePanelFlatDataModel2 flatModel = null;
64
65
66 File file = null;
67
68
69
70
71
72 TreeFileDataNode parent = null;
73
74
75 List<TreeFileDataNode> children = null;
76
77 Date fileModified;
78
79 boolean uploadFlag = true;
80
81 UploadPolicy uploadPolicy = null;
82
83
84
85
86
87
88
89
90
91 static public String getFilename(File file) {
92 String filename = file.getName();
93 try {
94 filename = (filename.equals("")) ? file.getCanonicalPath() : filename;
95 } catch (IOException e) {
96 throw new IllegalArgumentException(e.getMessage()
97 + " exception, when trying to resolve the canonical path for " + file.getAbsolutePath(), e);
98 }
99 return filename;
100 }
101
102
103
104
105
106
107
108
109 static public String getAbsolutePath(TreeFileDataNode node) {
110 StringBuffer sb = new StringBuffer();
111 int depth = 0;
112 for (Object o : node.getTreePath().getPath()) {
113 String oName = o.toString();
114
115 sb.append(oName);
116
117 if (depth == 1 && oName.substring(1, 2).equals(":")) {
118
119
120
121 sb.setLength(0);
122 sb.append(oName);
123 } else if (o != node) {
124
125 sb.append(File.separator);
126 }
127 depth += 1;
128 }
129 return sb.toString();
130 }
131
132 public static int[] getIntArray(int... indexOf) {
133 int[] ints = new int[indexOf.length];
134 for (int i = 0; i < indexOf.length; i += 1) {
135 ints[i] = indexOf[i];
136 }
137 return ints;
138 }
139
140 public static TreeFileDataNode[] getItemArray(TreeFileDataNode... child) {
141 TreeFileDataNode[] treeNodes = (TreeFileDataNode[]) Array.newInstance(TreeFileDataNode.class, child.length);
142 for (int i = 0; i < child.length; i += 1) {
143 treeNodes[i] = child[i];
144 }
145 return treeNodes;
146 }
147
148 protected FolderNode(UploadPolicy uploadPolicy, MyTreeTableModel<TreeFileDataNode> model,
149 FilePanelFlatDataModel2 flatModel) {
150 this.uploadPolicy = uploadPolicy;
151 this.treeModel = model;
152 this.flatModel = flatModel;
153 this.children = new ArrayList<TreeFileDataNode>();
154 }
155
156
157
158
159
160
161
162 public FolderNode(File file, UploadPolicy uploadPolicy, MyTreeTableModel<TreeFileDataNode> model,
163 FilePanelFlatDataModel2 flatModel) {
164
165 this(uploadPolicy, model, flatModel);
166
167 if (!file.isDirectory()) {
168 throw new IllegalArgumentException("Internal error: " + file.getAbsolutePath() + " should be a folder");
169 }
170 this.file = file;
171 }
172
173
174 public int getTotalChildCount() {
175 int total = 0;
176 for (TreeFileDataNode child : children) {
177 total += 1 + child.getTotalChildCount();
178 }
179 return total;
180 }
181
182 @SuppressWarnings("unchecked")
183
184 public List<MyTreeNode> getChildren() {
185 return (List<MyTreeNode>) (List<?>) children;
186 }
187
188
189 public void appendFileProperties(ByteArrayEncoder bae, int index) throws JUploadIOException {
190 throw new IllegalAccessError("Internal error: appendFileProperties should not be called from "
191 + this.getClass().getName());
192 }
193
194
195 public void beforeUpload(String uploadPathRoot) throws JUploadException {
196 throw new IllegalAccessError("Internal error: beforeUpload should not be called from "
197 + this.getClass().getName());
198 }
199
200
201 public long getUploadLength() {
202 throw new IllegalAccessError("Internal error: getUploadLength should not be called from "
203 + this.getClass().getName());
204 }
205
206
207 public void afterUpload() {
208 throw new IllegalAccessError("Internal error: afterUpload should not be called from "
209 + this.getClass().getName());
210 }
211
212
213 public InputStream getInputStream() throws JUploadException {
214 throw new IllegalAccessError("Internal error: getInputStream should not be called from "
215 + this.getClass().getName());
216 }
217
218
219 public String getFileName() {
220
221
222 return FolderNode.getFilename(file);
223 }
224
225
226 public String getFileExtension() {
227 throw new IllegalAccessError("Internal error: getFileExtension should not be called from "
228 + this.getClass().getName());
229 }
230
231
232 public long getFileLength() {
233 return -1;
234 }
235
236
237 public Date getLastModified() {
238 if (this.fileModified == null) {
239 this.fileModified = new Date(this.file.lastModified());
240 }
241 return this.fileModified;
242 }
243
244
245 public boolean getUploadFlag() {
246 return uploadFlag;
247 }
248
249
250 public void setUploadFlag(boolean uploadFlag) {
251 if (this.uploadFlag != uploadFlag) {
252 this.uploadFlag = uploadFlag;
253 for (TreeFileDataNode tfdn : children) {
254 tfdn.setUploadFlag(uploadFlag);
255 }
256 if (getParent() == null) {
257
258 treeModel.fireTreeNodesChanged(this, null, null, null);
259 } else {
260 treeModel.fireTreeNodesChanged(this, treeModel.getTreePath((TreeFileDataNode) getParent()),
261 getIntArray((getParent().getChildren()).indexOf(this)), getItemArray((TreeFileDataNode) this));
262 }
263 }
264 }
265
266
267 public String getDirectory() {
268 return this.file.getAbsoluteFile().getParent();
269 }
270
271
272 public String getMD5() throws JUploadException {
273 throw new IllegalAccessError("Internal error: getMD5 should not be called from " + this.getClass().getName());
274 }
275
276
277 public String getMimeType() {
278 throw new IllegalAccessError("Internal error: getMimeType should not be called from "
279 + this.getClass().getName());
280 }
281
282
283 public boolean canRead() {
284 return file.canRead();
285 }
286
287 protected File getFile() {
288 throw new IllegalAccessError("Internal error: getFile is deprecated and should not be called from "
289 + this.getClass().getName());
290 }
291
292
293 public String getRelativeDir() {
294 throw new IllegalAccessError("Internal error: getRelativeDir should not be called from "
295 + this.getClass().getName());
296 }
297
298
299 public String getAbsolutePath() {
300 return FolderNode.getAbsolutePath(this);
301 }
302
303
304 public boolean isPreparedForUpload() {
305 throw new IllegalAccessError("Internal error: isPreparedForUpload should not be called from "
306 + this.getClass().getName());
307 }
308
309
310 public int getChildCount() {
311 return (children == null) ? 0 : children.size();
312 }
313
314
315 public TreeFileDataNode getChild(int index) {
316 return (children == null) ? null : children.get(index);
317 }
318
319
320 public TreeFileDataNode getChild(String name) {
321 for (TreeFileDataNode node : children) {
322 if (node.getFileName().equals(name)) {
323 return node;
324 }
325 }
326
327
328 return null;
329 }
330
331
332 public TreeFileDataNode getChild(File file) {
333 return getChild(FolderNode.getFilename(file));
334 }
335
336
337 public MyTreeNode getParent() {
338 return this.parent;
339 }
340
341
342
343 public void setParent(MyTreeNode parent) {
344 this.parent = (TreeFileDataNode) parent;
345 }
346
347
348 @SuppressWarnings("unchecked")
349 public void setTreeModel(TreeModel model) {
350 this.treeModel = (MyTreeTableModel<TreeFileDataNode>) model;
351 }
352
353
354 public void setFlatModel(FilePanelFlatDataModel2 flatModel) {
355 this.flatModel = flatModel;
356 }
357
358
359
360
361
362
363 public void removeChild(MyTreeNode child) {
364 if (!children.remove(child)) {
365 throw new IllegalArgumentException(child.toString() + " is not a child of " + getFileName());
366 }
367
368
369
370
371
372
373 child.setParent(null);
374 child.setTreeModel(null);
375 child.setFlatModel(null);
376 ;
377
378
379
380 while (child.getChildCount() > 0) {
381
382 ((FolderNode) child).removeChild(child.getChild(0));
383 }
384 }
385
386
387
388
389
390
391
392
393 public TreeFileDataNode addChild(FileData fileData) {
394 return addChild(new FileDataNode(fileData));
395 }
396
397
398
399
400
401
402
403
404 public TreeFileDataNode addChild(TreeFileDataNode child) {
405 TreeFileDataNode alreadyExistingChild = (TreeFileDataNode) getChild(child.getFileName());
406 if (alreadyExistingChild == null) {
407
408 children.add(child);
409 child.setTreeModel(this.treeModel);
410 child.setParent(this);
411 treeModel.fireTreeNodesInserted(this, treeModel.getTreePath(this), getIntArray(children.indexOf(child)),
412 getItemArray((TreeFileDataNode) child));
413 return child;
414 } else {
415 uploadPolicy.displayWarn("The FileData for " + child.getAbsolutePath() + " already exists for the folder "
416 + getFileName());
417 return alreadyExistingChild;
418 }
419 }
420
421
422
423
424
425
426
427 public FolderNode getSubfolderOrCreateIt(File file) throws JUploadExceptionStopAddingFiles {
428 if (!file.isDirectory()) {
429 throw new JUploadExceptionStopAddingFiles(file.getAbsolutePath() + " must be a directory");
430 }
431 TreeFileDataNode child = addChild(new FolderNode(file, uploadPolicy, treeModel, flatModel));
432
433 if (!(child instanceof FolderNode)) {
434 throw new JUploadExceptionStopAddingFiles("A child with the same name (" + file.getName()
435 + ") already exists, but is not a folder");
436 } else {
437 return (FolderNode) child;
438 }
439 }
440
441
442 public boolean isLeaf() {
443 return false;
444 }
445
446
447
448
449
450
451 @Override
452 public String toString() {
453 return getFileName();
454 }
455
456
457 public TreeFileDataNode getTreeFileDataNode() {
458 return this;
459 }
460
461
462 public void setTreeFileDataNode(TreeFileDataNode node) {
463 throw new IllegalStateException("setTreeFileDataNode may not be called againts a FolderNode");
464 }
465
466
467 public TreePath getTreePath() {
468 if (parent == null) {
469 return new TreePath(this);
470 } else {
471 return parent.getTreePath().pathByAddingChild(this);
472 }
473 }
474
475
476
477
478
479
480
481
482
483 public TreeFileDataNode addChild(File f) throws JUploadExceptionStopAddingFiles {
484 if (getChild(f) != null) {
485 throw new JUploadExceptionStopAddingFiles("Internal error: " + f.getAbsolutePath()
486 + " is already a child of the node for " + this.file.getAbsolutePath());
487 }
488
489 if (f.isDirectory()) {
490 return addChild(new FolderNode(f, uploadPolicy, treeModel, flatModel));
491 } else {
492 FileData fd = flatModel.addFile(f);
493 return addChild(new FileDataNode(fd));
494 }
495 }
496
497
498
499
500
501
502
503
504 public int addChildAndDescendants(File f) throws JUploadExceptionStopAddingFiles {
505 int nbFiles = 0;
506
507 TreeFileDataNode child = getChild(f);
508 if (child == null) {
509
510 if (f.isDirectory()) {
511 child = addChild(f);
512 } else {
513 FileData fd = flatModel.addFile(f);
514
515 if (fd != null) {
516 child = addChild(new FileDataNode(fd));
517 fd.setTreeFileDataNode(child);
518 nbFiles += 1;
519 }
520 }
521 }
522
523
524
525 if (f.isDirectory()) {
526
527 for (File file : f.listFiles()) {
528 nbFiles += ((FolderNode) child).addChildAndDescendants(file);
529 }
530 }
531 return nbFiles;
532 }
533
534 }