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

Last change on this file since 13455 was 13455, checked in by mdewsnip, 17 years ago

Renamed ExplodeMetadataPrompt to ExplodeMetadataDatabasePrompt, and added a new function to FileManager to open the ExplodeMetadataDatabasePrompt in a new thread, in preparation for implementing the remote building version.

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