source: trunk/gli/src/org/greenstone/gatherer/file/FileManager.java@ 11625

Last change on this file since 11625 was 11598, checked in by mdewsnip, 18 years ago

You can now delete files from the "Downloaded Files" folder when no collection is open.

  • Property svn:keywords set to Author Date Id Revision
File size: 13.7 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.CollectionTree;
44import org.greenstone.gatherer.collection.CollectionTreeNode;
45import org.greenstone.gatherer.gui.GProgressBar;
46import org.greenstone.gatherer.gui.NewFolderOrFilePrompt;
47import org.greenstone.gatherer.gui.RenamePrompt;
48import org.greenstone.gatherer.gui.tree.DragTree;
49import org.greenstone.gatherer.remote.RemoteGreenstoneServer;
50import org.greenstone.gatherer.util.DragComponent;
51import org.greenstone.gatherer.util.Utility;
52
53/** Manages the moving of files within a separate thread.
54 * @author John Thompson, NZDL Project, University of Waikato
55 */
56public class FileManager
57{
58 /** Not only the queue of files to be moved, but also the object that moves them. */
59 static private FileQueue file_queue = null;
60
61 public static int FILE_TYPE = 0;
62 public static int FOLDER_TYPE = 1;
63 protected static File startup_directory = null;
64
65
66 /** Constructor.
67 * @see org.greenstone.gatherer.file.FileQueue
68 */
69 public FileManager()
70 {
71 file_queue = new FileQueue();
72 file_queue.start();
73 }
74
75
76 /** Determine what action should be carried out by the file queue, and add all of the necessary file jobs. */
77 public void action(DragComponent source, FileNode[] source_nodes, DragComponent target, FileNode target_node)
78 {
79 // Check there is something to do
80 if (source_nodes == null || source_nodes.length == 0) {
81 return;
82 }
83
84 // We need a unique ID for each file task
85 long id = System.currentTimeMillis();
86
87 // If source and target are the same we're moving
88 if (source == target) {
89 // Start a new move FileTask and we're done
90 (new FileTask(id, source, source_nodes, target, target_node, FileJob.MOVE)).start();
91 return;
92 }
93
94 // If target isn't the RecycleBin, we're copying
95 if (!(target instanceof RecycleBin)) {
96 // Start a new copy FileTask and we're done
97 (new FileTask(id, source, source_nodes, target, target_node, FileJob.COPY)).start();
98 return;
99 }
100
101 // We're deleting... but first make sure source isn't read-only
102 boolean read_only_source = false;
103
104 // The workspace tree is read-only...
105 if (source.toString().equals("Workspace")) {
106 read_only_source = true;
107
108 // ...except for files from the "Downloaded Files" folder
109 String downloaded_files_folder_path = Gatherer.getGLIUserCacheDirectoryPath();
110 for (int i = 0; i < source_nodes.length; i++) {
111 // Is this the "Downloaded Files" folder?
112 if (source_nodes[i].getFile().getAbsolutePath().startsWith(downloaded_files_folder_path)) {
113 read_only_source = false;
114 }
115 }
116 }
117
118 // The source is read-only, so tell the user and abort
119 if (read_only_source) {
120 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.Read_Only"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
121 return;
122 }
123
124 // Start a new delete FileTask and we're done
125 (new FileTask(id, source, source_nodes, target, target_node, FileJob.DELETE)).start();
126 }
127
128
129 /** Retrieves the file queue object. */
130 public FileQueue getQueue()
131 {
132 return file_queue;
133 }
134
135
136 private class FileTask
137 extends Thread
138 {
139 private long id;
140 private DragComponent source;
141 private FileNode[] source_nodes;
142 private DragComponent target;
143 private FileNode target_node;
144 private byte type;
145
146
147 public FileTask(long id, DragComponent source, FileNode[] source_nodes, DragComponent target, FileNode target_node, byte type)
148 {
149 this.id = id;
150 this.source = source;
151 this.source_nodes = source_nodes;
152 this.target = target;
153 this.target_node = target_node;
154 this.type = type;
155 }
156
157
158 public void run()
159 {
160 // Reset the progress bar and set it to indeterminate while calculating its size
161 GProgressBar progress_bar = file_queue.getProgressBar();
162 progress_bar.reset();
163 progress_bar.setIndeterminate(true);
164
165 // Calculate the progress bar size
166 boolean cancelled = file_queue.calculateSize(source_nodes);
167 if (!cancelled) {
168 file_queue.addJob(id, source, source_nodes, target, target_node, type);
169 if (Gatherer.isGsdlRemote) {
170 String collection_name = Gatherer.c_man.getCollection().getName();
171
172 // Perform the appropriate action based on the job type (RemoteGreenstoneServer will queue)
173 if (type == FileJob.COPY) {
174 // Copies: upload all the files at once in one zip file
175 File[] source_files = new File[source_nodes.length];
176 for (int i = 0; i < source_nodes.length; i++) {
177 source_files[i] = source_nodes[i].getFile();
178 }
179 RemoteGreenstoneServer.uploadFilesIntoCollection(collection_name, source_files, target_node.getFile());
180 }
181 else if (type == FileJob.DELETE) {
182 // Deletes: delete each top-level file/directory one at a time
183 for (int i = 0; i < source_nodes.length; i++) {
184 RemoteGreenstoneServer.deleteCollectionFile(collection_name, source_nodes[i].getFile());
185 }
186 }
187 else if (type == FileJob.MOVE) {
188 // Moves: move each top-level file/directory one at a time
189 for (int i = 0; i < source_nodes.length; i++) {
190 RemoteGreenstoneServer.moveCollectionFile(collection_name, source_nodes[i].getFile(), target_node.getFile());
191 }
192 }
193 }
194 }
195
196 progress_bar.setIndeterminate(false);
197 progress_bar.clear();
198 }
199 }
200
201
202 public void openFileInExternalApplication(File file)
203 {
204 // This must go in a separate thread because we need the progress bar to work (remote Greenstone server)
205 new OpenFileInExternalApplicationTask(file).start();
206 }
207
208
209 private class OpenFileInExternalApplicationTask
210 extends Thread
211 {
212 private File file = null;
213
214 public OpenFileInExternalApplicationTask(File file)
215 {
216 this.file = file;
217 }
218
219 public void run()
220 {
221 // If we're using a remote Greenstone server, we need to download the file before viewing it...
222 if (Gatherer.isGsdlRemote) {
223 // ... but only if it is inside the collection and we haven't already downloaded it
224 if (file.getAbsolutePath().startsWith(Gatherer.getCollectDirectoryPath()) && file.length() == 0) {
225 if (RemoteGreenstoneServer.downloadCollectionFile(Gatherer.c_man.getCollection().getName(), file).equals("")) {
226 // Something has gone wrong downloading the file
227 return;
228 }
229 }
230 }
231
232 // View the file in an external application
233 Gatherer.spawnApplication(file);
234 }
235 }
236
237
238 public void newDummyDoc(DragTree tree, CollectionTreeNode parent_node){
239 newFolderOrDummyDoc(tree, parent_node, FILE_TYPE);
240 }
241
242
243 public void newFolder(DragTree tree, CollectionTreeNode parent_node) {
244 newFolderOrDummyDoc(tree, parent_node, FOLDER_TYPE);
245 }
246
247
248 protected void newFolderOrDummyDoc(DragTree tree, CollectionTreeNode parent_node, int type) {
249 (new NewFolderOrDummyDocumentTask(tree, parent_node, type)).start();
250 }
251
252
253 private class NewFolderOrDummyDocumentTask
254 extends Thread
255 {
256 private DragTree tree = null;
257 private CollectionTreeNode parent_node = null;
258 private int type;
259
260 public NewFolderOrDummyDocumentTask(DragTree tree, CollectionTreeNode parent_node, int type)
261 {
262 this.tree = tree;
263 this.parent_node = parent_node;
264 this.type = type;
265 }
266
267 public void run()
268 {
269 // Ask the user for the directories name.
270 String extension = "";
271 if (type == FILE_TYPE) {
272 extension = ".nul";
273 }
274
275 NewFolderOrFilePrompt new_folder_prompt = new NewFolderOrFilePrompt(parent_node, type, extension);
276 String name = new_folder_prompt.display();
277 new_folder_prompt.dispose();
278 new_folder_prompt = null;
279
280 // And if the name is non-null...
281 if (name != null) {
282 FileSystemModel model = (FileSystemModel) tree.getModel();
283 File folder_file = new File(parent_node.getFile(), name);
284
285 //... check if it already exists.
286 if (folder_file.exists()) {
287 if (type == FILE_TYPE) {
288 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.File_Already_Exists_No_Create", name), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
289 }
290 else {
291 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.Folder_Already_Exists", name), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
292 }
293 }
294 // Otherwise create it.
295 else {
296 try {
297 if (type == FILE_TYPE) {
298 folder_file.createNewFile();
299 }
300 else {
301 folder_file.mkdirs();
302 if (Gatherer.isGsdlRemote) {
303 long id = System.currentTimeMillis();
304 RemoteGreenstoneServer.newCollectionDirectory(Gatherer.c_man.getCollection().getName(), folder_file);
305 }
306 }
307
308 // Update the parent node to show the new folder
309 parent_node.refresh();
310
311 // Refresh workspace tree (collection tree is done automatically)
312 Gatherer.g_man.refreshWorkspaceTree(DragTree.COLLECTION_CONTENTS_CHANGED);
313 }
314 catch (Exception exception) {
315 if (type == FILE_TYPE) {
316 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.File_Create_Error", name), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
317 }
318 else {
319 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("FileActions.Folder_Create_Error", name), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
320 }
321 }
322 }
323
324 folder_file = null;
325 model = null;
326 }
327 name = null;
328 }
329 }
330
331
332 public void renameCollectionFile(CollectionTree collection_tree, CollectionTreeNode collection_tree_node)
333 {
334 // This must go in a separate thread because we need the progress bar to work (remote Greenstone server)
335 new RenameTask(collection_tree, collection_tree_node).start();
336 }
337
338
339 private class RenameTask
340 extends Thread
341 {
342 private CollectionTree collection_tree = null;
343 private CollectionTreeNode collection_tree_node = null;
344
345 public RenameTask(CollectionTree collection_tree, CollectionTreeNode collection_tree_node)
346 {
347 this.collection_tree = collection_tree;
348 this.collection_tree_node = collection_tree_node;
349 }
350
351 public void run()
352 {
353 RenamePrompt rename_prompt = new RenamePrompt(collection_tree_node);
354 String new_collection_file_name = rename_prompt.display();
355 rename_prompt.dispose();
356 rename_prompt = null;
357
358 if (new_collection_file_name != null) {
359 File collection_file = collection_tree_node.getFile();
360 File new_collection_file = new File(collection_file.getParentFile(), new_collection_file_name);
361 CollectionTreeNode new_collection_tree_node = new CollectionTreeNode(new_collection_file);
362 file_queue.addJob(System.currentTimeMillis(), collection_tree, new FileNode[] { collection_tree_node }, collection_tree, new_collection_tree_node, FileJob.RENAME);
363 }
364 }
365 }
366
367 public void replaceCollectionFile(CollectionTree collection_tree, CollectionTreeNode collection_tree_node)
368 {
369 // This must go in a separate thread because we need the progress bar to work (remote Greenstone server)
370 new ReplaceTask(collection_tree, collection_tree_node).start();
371 }
372
373
374 private class ReplaceTask
375 extends Thread
376 {
377 private CollectionTree collection_tree = null;
378 private CollectionTreeNode collection_tree_node = null;
379
380 public ReplaceTask(CollectionTree collection_tree, CollectionTreeNode collection_tree_node)
381 {
382 this.collection_tree = collection_tree;
383 this.collection_tree_node = collection_tree_node;
384 }
385
386 public void run()
387 {
388
389 JFileChooser file_chooser = new JFileChooser(startup_directory);
390 file_chooser.setDialogTitle(Dictionary.get("ReplacePrompt.Title"));
391 File new_file = null;
392 int return_val = file_chooser.showOpenDialog(null);
393 if(return_val == JFileChooser.APPROVE_OPTION) {
394 new_file = file_chooser.getSelectedFile();
395 }
396
397 if (new_file == null) {
398 return;
399 }
400
401 // save the search path for next time
402 startup_directory = new_file.getParentFile();
403 // make up a node for the file to bring in
404 WorkspaceTreeNode source_node = new WorkspaceTreeNode(new_file);
405
406 File target_directory = collection_tree_node.getFile().getParentFile();
407 CollectionTreeNode new_collection_tree_node = new CollectionTreeNode(new File(target_directory, new_file.getName()));
408 // copy the new file in - but don't bring metadata
409 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);
410 // do a replace of old file with new file
411 file_queue.addJob(System.currentTimeMillis(), collection_tree, new FileNode[] { collection_tree_node }, collection_tree, new_collection_tree_node, FileJob.REPLACE);
412
413 }
414 }
415
416}
417
418
419
420
Note: See TracBrowser for help on using the repository browser.