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

Last change on this file since 11082 was 11073, checked in by mdewsnip, 18 years ago

Renamed LongProgressBar to GProgressBar, and tidied up a great deal. Removed the BigInteger sillyness and used longs instead, so should be slightly more efficient. This will now be used for all progress bars in the GLI, as it sets indeterminate/string/value safely (should avoid NPEs when setting indeterminate).

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