source: other-projects/FileTransfer-WebSocketPair/testGXTWithGreenstone/src/org/greenstone/gatherer/file/FileManager.java@ 33053

Last change on this file since 33053 was 33053, checked in by ak19, 5 years ago

I still had some stuff of Nathan Kelly's (FileTransfer-WebSocketPair) sitting on my USB. Had already commited the Themes folder at the time, 2 years back. Not sure if he wanted this additional folder commited. But I didn't want to delete it and decided it will be better off on SVN. When we use his project, if we find we didn't need this test folder, we can remove it from svn then.

File size: 18.9 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * <BR><BR>
9 *
10 * Author: John Thompson, NZDL Project, University of Waikato
11 *
12 * <BR><BR>
13 *
14 * Copyright (C) 2005 New Zealand Digital Library Project
15 *
16 * <BR><BR>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * <BR><BR>
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * <BR><BR>
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 *########################################################################
36 */
37package org.greenstone.gatherer.file;
38
39import java.io.File;
40import javax.swing.*;
41import org.greenstone.gatherer.Dictionary;
42import org.greenstone.gatherer.Gatherer;
43import org.greenstone.gatherer.collection.CollectionManager;
44import org.greenstone.gatherer.collection.CollectionTree;
45import org.greenstone.gatherer.collection.CollectionTreeNode;
46import org.greenstone.gatherer.gui.ExplodeMetadataDatabasePrompt;
47import org.greenstone.gatherer.gui.ReplaceSrcDocWithHtmlPrompt;
48import org.greenstone.gatherer.gui.GProgressBar;
49import org.greenstone.gatherer.gui.NewFolderOrFilePrompt;
50import org.greenstone.gatherer.gui.RenamePrompt;
51import org.greenstone.gatherer.gui.tree.DragTree;
52import org.greenstone.gatherer.remote.RemoteGreenstoneServer;
53import org.greenstone.gatherer.util.DragComponent;
54import org.greenstone.gatherer.util.Utility;
55
56/** Manages the moving of files within a separate thread.
57 * @author John Thompson, NZDL Project, University of Waikato
58 */
59public class FileManager
60{
61 /** Not only the queue of files to be moved, but also the object that moves them. */
62 static private FileQueue file_queue = null;
63
64 public static final int COPY = 0;
65 public static final int MOVE = 1;
66
67 public static final int FILE_TYPE = 0;
68 public static final int FOLDER_TYPE = 1;
69 protected static File startup_directory = null;
70
71
72 /** Constructor.
73 * @see org.greenstone.gatherer.file.FileQueue
74 */
75 public FileManager()
76 {
77 file_queue = new FileQueue();
78 file_queue.start();
79 }
80
81
82 /** Determine what action should be carried out by the file queue, and add all of the necessary file jobs. */
83 public void action(DragComponent source, FileNode[] source_nodes, DragComponent target, FileNode target_node)
84 {
85 // Check there is something to do
86 if (source_nodes == null || source_nodes.length == 0) {
87 return;
88 }
89
90 // We need a unique ID for each file task
91 long id = System.currentTimeMillis();
92
93 // If source and target are the same we're moving
94 if (source == target) {
95 // Start a new move FileTask and we're done
96 (new FileTask(id, source, source_nodes, target, target_node, FileJob.MOVE)).start();
97 return;
98 }
99
100 // If target isn't the RecycleBin, we're copying
101 if (!(target instanceof RecycleBin)) {
102 // Start a new copy FileTask and we're done
103 (new FileTask(id, source, source_nodes, target, target_node, FileJob.COPY)).start();
104 return;
105 }
106
107 // We're deleting... but first make sure source isn't read-only
108 boolean read_only_source = false;
109
110 // The workspace tree is read-only...
111 if (source.toString().equals("Workspace")) {
112 read_only_source = true;
113
114 // ...except for files from the "Downloaded Files" folder
115 String downloaded_files_folder_path = Gatherer.getGLIUserCacheDirectoryPath();
116 for (int i = 0; i < source_nodes.length; i++) {
117 // Is this the "Downloaded Files" folder?
118 if (source_nodes[i].getFile().getAbsolutePath().startsWith(downloaded_files_folder_path)) {
119 read_only_source = false;
120 }
121 }
122 }
123
124 // The source is read-only, so tell the user and abort
125 if (read_only_source) {
126 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.Read_Only"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
127 return;
128 }
129
130 // Start a new delete FileTask and we're done
131 (new FileTask(id, source, source_nodes, target, target_node, FileJob.DELETE)).start();
132 }
133
134 /** For moving and copying of folders. */
135 public void action(File sourceFolder, File targetFolder, int operation) {
136 (new SimpleFileTask(sourceFolder, targetFolder, operation)).start();
137 }
138
139
140 /** Retrieves the file queue object. */
141 public FileQueue getQueue()
142 {
143 return file_queue;
144 }
145
146 /** Performs the simple file task of moving or copying folders. */
147 private class SimpleFileTask
148 extends Thread
149 {
150 private File sourceFolder;
151 private File targetFolder;
152 int operation; // MOVE or COPY
153
154 public SimpleFileTask(File sourceFolder, File targetFolder, int operation)
155 {
156 this.sourceFolder = sourceFolder;
157 this.targetFolder = targetFolder;
158 this.operation = operation;
159 }
160
161
162 public void run()
163 {
164 // check if we're moving or overwriting the current collection
165 String currentColPath = Gatherer.getCollectDirectoryPath()+CollectionManager.getLoadedCollectionName();
166 if(currentColPath.equals(sourceFolder.getAbsolutePath())
167 || currentColPath.equals(targetFolder.getAbsolutePath())) {
168 Gatherer.g_man.saveThenCloseCurrentCollection();
169 }
170
171 // if moving, try a simple move operation (if it works, it
172 // shouldn't take long at all and doesn't need a progress bar)
173 if(operation == MOVE && sourceFolder.renameTo(targetFolder)) {
174 //System.err.println("**** A simple renameTo() worked.");
175 WorkspaceTreeModel.refreshGreenstoneCollectionsNode();
176 return;
177 }
178
179 // Reset the progress bar and set it to indeterminate while calculating its size
180 GProgressBar progress_bar = file_queue.getProgressBar();
181 progress_bar.reset();
182 progress_bar.setIndeterminate(true);
183
184 String status = "FileActions.Moving";
185 if(operation == COPY) {
186 status = "FileActions.Copying";
187 }
188 progress_bar.setString(Dictionary.get(status));
189 file_queue.getFileStatus().setText(Dictionary.get(status,
190 file_queue.formatPath(status,
191 sourceFolder.getAbsolutePath(),
192 file_queue.getFileStatus().getSize().width)));
193
194 // do the move or copy operation
195 try {
196 //System.err.println("**** Copying " + sourceFolder + " to: " + targetFolder);
197 file_queue.copyDirectoryContents(sourceFolder, targetFolder);
198 } catch(Exception e) {
199 JOptionPane.showMessageDialog(Gatherer.g_man, e.getMessage(),
200 "Can't perform file operation", JOptionPane.ERROR_MESSAGE);
201
202 progress_bar.setIndeterminate(false);
203 progress_bar.clear();
204 return;
205 }
206
207 // if moving, delete the original source folder and
208 // update the docs in GS collections node in the workspace tree
209
210 if(operation == MOVE) {
211 Utility.delete(sourceFolder);
212 WorkspaceTreeModel.refreshGreenstoneCollectionsNode();
213 }
214
215
216 progress_bar.setIndeterminate(false);
217 progress_bar.clear();
218 file_queue.getFileStatus().setText(Dictionary.get("FileActions.No_Activity"));
219 progress_bar.setString(Dictionary.get("FileActions.No_Activity"));
220 }
221 }
222
223 private class FileTask
224 extends Thread
225 {
226 private long id;
227 private DragComponent source;
228 private FileNode[] source_nodes;
229 private DragComponent target;
230 private FileNode target_node;
231 private byte type;
232
233
234 public FileTask(long id, DragComponent source, FileNode[] source_nodes, DragComponent target, FileNode target_node, byte type)
235 {
236 this.id = id;
237 this.source = source;
238 this.source_nodes = source_nodes;
239 this.target = target;
240 this.target_node = target_node;
241 this.type = type;
242 }
243
244
245 public void run()
246 {
247 // Reset the progress bar and set it to indeterminate while calculating its size
248 GProgressBar progress_bar = file_queue.getProgressBar();
249 progress_bar.reset();
250 progress_bar.setIndeterminate(true);
251
252 // Calculate the progress bar size
253 boolean cancelled = file_queue.calculateSize(source_nodes);
254 if (!cancelled) {
255 file_queue.addJob(id, source, source_nodes, target, target_node, type);
256 if (Gatherer.isGsdlRemote) {
257 String collection_name = CollectionManager.getLoadedCollectionName();
258
259 // Perform the appropriate action based on the job type (RemoteGreenstoneServer will queue)
260 if (type == FileJob.COPY) {
261 // Copies: upload all the files at once in one zip file
262 File[] source_files = new File[source_nodes.length];
263 for (int i = 0; i < source_nodes.length; i++) {
264 source_files[i] = source_nodes[i].getFile();
265 }
266 Gatherer.remoteGreenstoneServer.uploadFilesIntoCollection(collection_name, source_files, target_node.getFile());
267 }
268 else if (type == FileJob.DELETE) {
269 // Deletes: delete each top-level file/directory one at a time
270 for (int i = 0; i < source_nodes.length; i++) {
271 Gatherer.remoteGreenstoneServer.deleteCollectionFile(collection_name, source_nodes[i].getFile());
272 }
273 }
274 else if (type == FileJob.MOVE) {
275 // Moves: move each top-level file/directory one at a time
276 for (int i = 0; i < source_nodes.length; i++) {
277 Gatherer.remoteGreenstoneServer.moveCollectionFile(
278 collection_name, source_nodes[i].getFile(), target_node.getFile());
279 }
280 }
281 }
282 }
283
284 progress_bar.setIndeterminate(false);
285 progress_bar.clear();
286 }
287 }
288
289 public void explodeMetadataDatabase(File file)
290 {
291 // This must go in a separate thread because we need the progress bar to work (remote Greenstone server)
292 new ExplodeMetadataDatabasePromptTask(file).start();
293 }
294
295 // Works with replace_srcdoc_with_html.pl
296 public void replaceSrcDocWithHtml(File[] files)
297 {
298 // This must go in a separate thread because we need the progress bar to work (remote Greenstone server)
299 new ReplaceSrcDocWithHtmlPromptTask(files).start();
300 }
301
302 private class ExplodeMetadataDatabasePromptTask
303 extends Thread
304 {
305 private File metadata_database_file = null;
306
307 public ExplodeMetadataDatabasePromptTask(File metadata_database_file)
308 {
309 this.metadata_database_file = metadata_database_file;
310 }
311
312 public void run()
313 {
314 ExplodeMetadataDatabasePrompt emp = new ExplodeMetadataDatabasePrompt(metadata_database_file);
315 }
316 }
317
318 // Works with replace_srcdoc_with_html.pl
319 private class ReplaceSrcDocWithHtmlPromptTask
320 extends Thread
321 {
322 private File[] replace_these_srcdoc_files = null;
323
324 public ReplaceSrcDocWithHtmlPromptTask(File[] replace_these_srcdoc_files)
325 {
326 this.replace_these_srcdoc_files = replace_these_srcdoc_files;
327 }
328
329 public void run()
330 {
331 ReplaceSrcDocWithHtmlPrompt prompt = new ReplaceSrcDocWithHtmlPrompt(replace_these_srcdoc_files);
332 }
333 }
334
335
336 public void openFileInExternalApplication(File file)
337 {
338 // This must go in a separate thread because we need the progress bar to work (remote Greenstone server)
339 new OpenFileInExternalApplicationTask(file).start();
340 }
341
342
343 private class OpenFileInExternalApplicationTask
344 extends Thread
345 {
346 private File file = null;
347
348 public OpenFileInExternalApplicationTask(File file)
349 {
350 this.file = file;
351 }
352
353 public void run()
354 {
355 // If we're using a remote Greenstone server, we need to download the file before viewing it...
356 if (Gatherer.isGsdlRemote) {
357 // ... but only if it is inside the collection and we haven't already downloaded it
358 if (file.getAbsolutePath().startsWith(Gatherer.getCollectDirectoryPath()) && file.length() == 0) {
359 if (Gatherer.remoteGreenstoneServer.downloadCollectionFile(
360 CollectionManager.getLoadedCollectionName(), file).equals("")) {
361 // Something has gone wrong downloading the file
362 return;
363 }
364 }
365 }
366
367 // View the file in an external application
368 Gatherer.spawnApplication(file);
369 }
370 }
371
372
373 public void newDummyDoc(DragTree tree, CollectionTreeNode parent_node){
374 newFolderOrDummyDoc(tree, parent_node, FILE_TYPE);
375 }
376
377
378 public void newFolder(DragTree tree, CollectionTreeNode parent_node) {
379 newFolderOrDummyDoc(tree, parent_node, FOLDER_TYPE);
380 }
381
382
383 protected void newFolderOrDummyDoc(DragTree tree, CollectionTreeNode parent_node, int type) {
384 (new NewFolderOrDummyDocumentTask(tree, parent_node, type)).start();
385 }
386
387
388 private class NewFolderOrDummyDocumentTask
389 extends Thread
390 {
391 private DragTree tree = null;
392 private CollectionTreeNode parent_node = null;
393 private int type;
394
395 public NewFolderOrDummyDocumentTask(DragTree tree, CollectionTreeNode parent_node, int type)
396 {
397 this.tree = tree;
398 this.parent_node = parent_node;
399 this.type = type;
400 }
401
402 public void run()
403 {
404 // Ask the user for the directories name.
405 String extension = "";
406 if (type == FILE_TYPE) {
407 extension = ".nul";
408 }
409
410 NewFolderOrFilePrompt new_folder_prompt = new NewFolderOrFilePrompt(parent_node, type, extension);
411 String name = new_folder_prompt.display();
412 new_folder_prompt.dispose();
413 new_folder_prompt = null;
414
415 // And if the name is non-null...
416 if (name != null) {
417 FileSystemModel model = (FileSystemModel) tree.getModel();
418 File folder_file = new File(parent_node.getFile(), name);
419
420 //... check if it already exists.
421 if (folder_file.exists()) {
422 if (type == FILE_TYPE) {
423 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.File_Already_Exists_No_Create", name), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
424 }
425 else {
426 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.Folder_Already_Exists", name), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
427 }
428 }
429 // Otherwise create it.
430 else {
431 try {
432 if (type == FILE_TYPE) {
433 folder_file.createNewFile();
434 if (Gatherer.isGsdlRemote) {
435 Gatherer.remoteGreenstoneServer.uploadCollectionFile(
436 CollectionManager.getLoadedCollectionName(), folder_file);
437 }
438 }
439 else {
440 folder_file.mkdirs();
441 if (Gatherer.isGsdlRemote) {
442 Gatherer.remoteGreenstoneServer.newCollectionDirectory(
443 CollectionManager.getLoadedCollectionName(), folder_file);
444 }
445 }
446
447 // Update the parent node to show the new folder
448 parent_node.refresh();
449
450 // Refresh workspace tree (collection tree is done automatically)
451 Gatherer.g_man.refreshWorkspaceTree(DragTree.COLLECTION_CONTENTS_CHANGED);
452 }
453 catch (Exception exception) {
454 if (type == FILE_TYPE) {
455 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.File_Create_Error", name), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
456 }
457 else {
458 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.Folder_Create_Error", name), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
459 }
460 }
461 }
462
463 folder_file = null;
464 model = null;
465 }
466 name = null;
467 }
468 }
469
470
471 public void renameCollectionFile(CollectionTree collection_tree, CollectionTreeNode collection_tree_node)
472 {
473 // This must go in a separate thread because we need the progress bar to work (remote Greenstone server)
474 new RenameTask(collection_tree, collection_tree_node).start();
475 }
476
477
478 private class RenameTask
479 extends Thread
480 {
481 private CollectionTree collection_tree = null;
482 private CollectionTreeNode collection_tree_node = null;
483
484 public RenameTask(CollectionTree collection_tree, CollectionTreeNode collection_tree_node)
485 {
486 this.collection_tree = collection_tree;
487 this.collection_tree_node = collection_tree_node;
488 }
489
490 public void run()
491 {
492 RenamePrompt rename_prompt = new RenamePrompt(collection_tree_node);
493 String new_collection_file_name = rename_prompt.display();
494 rename_prompt.dispose();
495 rename_prompt = null;
496
497 if (new_collection_file_name != null) {
498 File collection_file = collection_tree_node.getFile();
499 File new_collection_file = new File(collection_file.getParentFile(), new_collection_file_name);
500 CollectionTreeNode new_collection_tree_node = new CollectionTreeNode(new_collection_file);
501 file_queue.addJob(System.currentTimeMillis(), collection_tree, new FileNode[] { collection_tree_node }, collection_tree, new_collection_tree_node, FileJob.RENAME);
502 if (Gatherer.isGsdlRemote) {
503 Gatherer.remoteGreenstoneServer.moveCollectionFile(
504 CollectionManager.getLoadedCollectionName(), collection_file, new_collection_file);
505 }
506 }
507 }
508 }
509
510 public void replaceCollectionFile(CollectionTree collection_tree, CollectionTreeNode collection_tree_node)
511 {
512 // This must go in a separate thread because we need the progress bar to work (remote Greenstone server)
513 new ReplaceTask(collection_tree, collection_tree_node).start();
514 }
515
516
517 private class ReplaceTask
518 extends Thread
519 {
520 private CollectionTree collection_tree = null;
521 private CollectionTreeNode collection_tree_node = null;
522
523 public ReplaceTask(CollectionTree collection_tree, CollectionTreeNode collection_tree_node)
524 {
525 this.collection_tree = collection_tree;
526 this.collection_tree_node = collection_tree_node;
527 }
528
529 public void run()
530 {
531 JFileChooser file_chooser = new JFileChooser(startup_directory);
532 file_chooser.setDialogTitle(Dictionary.get("ReplacePrompt.Title"));
533 File new_file = null;
534 int return_val = file_chooser.showOpenDialog(null);
535 if(return_val == JFileChooser.APPROVE_OPTION) {
536 new_file = file_chooser.getSelectedFile();
537 }
538
539 if (new_file == null) {
540 return;
541 }
542
543 // save the search path for next time
544 startup_directory = new_file.getParentFile();
545 // make up a node for the file to bring in
546 WorkspaceTreeNode source_node = new WorkspaceTreeNode(new_file);
547
548 File target_directory = collection_tree_node.getFile().getParentFile();
549 CollectionTreeNode new_collection_tree_node = new CollectionTreeNode(new File(target_directory, new_file.getName()));
550 // copy the new file in - but don't bring metadata
551 file_queue.addJob(System.currentTimeMillis(), Gatherer.g_man.gather_pane.workspace_tree, new FileNode[] { source_node }, collection_tree, (FileNode)collection_tree_node.getParent(), FileJob.COPY_FILE_ONLY);
552 if (Gatherer.isGsdlRemote) {
553 String collection_name = CollectionManager.getLoadedCollectionName();
554 Gatherer.remoteGreenstoneServer.deleteCollectionFile(collection_name, collection_tree_node.getFile());
555 Gatherer.remoteGreenstoneServer.uploadFilesIntoCollection(collection_name, new File[] { new_file }, target_directory);
556 }
557 // do a replace of old file with new file
558 file_queue.addJob(System.currentTimeMillis(), collection_tree, new FileNode[] { collection_tree_node }, collection_tree, new_collection_tree_node, FileJob.REPLACE);
559 }
560 }
561}
Note: See TracBrowser for help on using the repository browser.