source: trunk/gli/src/org/greenstone/gatherer/collection/SaveCollectionTask.java@ 4571

Last change on this file since 4571 was 4571, checked in by mdewsnip, 21 years ago

Removed ProgressMonitor, which for some reason was locking up when saving collections.

  • Property svn:keywords set to Author Date Id Revision
File size: 12.3 KB
Line 
1package org.greenstone.gatherer.collection;
2/**
3 *#########################################################################
4 *
5 * A component of the Gatherer application, part of the Greenstone digital
6 * library suite from the New Zealand Digital Library Project at the
7 * University of Waikato, New Zealand.
8 *
9 * <BR><BR>
10 *
11 * Author: John Thompson, Greenstone Digital Library, University of Waikato
12 *
13 * <BR><BR>
14 *
15 * Copyright (C) 1999 New Zealand Digital Library Project
16 *
17 * <BR><BR>
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * <BR><BR>
25 *
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 *
31 * <BR><BR>
32 *
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the Free Software
35 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
36 *########################################################################
37 */
38import java.io.*;
39import java.util.*;
40import javax.swing.*;
41import org.greenstone.gatherer.Gatherer;
42import org.greenstone.gatherer.Message;
43import org.greenstone.gatherer.collection.Collection;
44import org.greenstone.gatherer.gui.GUIManager;
45import org.greenstone.gatherer.undo.UndoManager;
46import org.greenstone.gatherer.util.Utility;
47/** The actually saving of a collection must run in a thread other than the AWTEvent thread, or else the save progress box will never get updated. To that end this class provides a threaded save method, which saves the various parts of the collection to the appropriate disk location.
48 * @author John Thompson, Greenstone Digital Library, University of Waikato
49 * @version 2.3
50 */
51public class SaveCollectionTask
52 extends Thread {
53 private boolean close_after = false;
54 /** Should we exit the Gatherer once this save is complete. */
55 private boolean exit_after = false;
56 /** Do we run the import scripts once this save is complete. */
57 private boolean import_after = false;
58 /** The current collection. */
59 private Collection collection = null;
60 /** The filename of the collection we are saving. */
61 private String name = null;
62 static final private int CLOSE_COLLECTION = 0;
63 static final private int COLLECTION_COPIED = 1;
64 static final private int COLLECTION_SAVED = 2;
65 static final private int COLLECTION_CFG_SAVED = 3;
66 static final private int COPY_COLLECTION = 4;
67 static final private int MAKE_COLLECTION = 5;
68 static final private int METADATA_SAVED = 6;
69 static final private int METADATA_XML_SAVED = 7;
70 static final private int OPEN_COLLECTION = 8;
71 static final private int RESTORE_COLLECTION = 9;
72 /** Constructor.
73 * @param name The filename of the collection we are saving as.
74 */
75 public SaveCollectionTask(Collection collection) {
76 this.collection = collection;
77 }
78 /** Constructor.
79 * @param exit_after <i>true</i> to cause the Gatherer to exit once save is complete, <i>false</i> otherwise.
80 */
81 public SaveCollectionTask(Collection collection, boolean close_after, boolean exit_after) {
82 this.close_after = close_after;
83 this.collection = collection;
84 this.exit_after = exit_after;
85 }
86 /** Constructor.
87 * @param name The filename of the collection we are saving as.
88 */
89 public SaveCollectionTask(Collection collection, String name) {
90 this.collection = collection;
91 this.name = name;
92 }
93 /** <p>This method, when created in a forked process by start(), performs the actions necessary to save a collection. If this is a regular save it saves the state of the current collection, ensuring all files, metadata files, and configuration files are written to disk. If, instead, this is a "Save As" action then there as several more steps involved:</p>
94 * <p>1. Perform a regular collection save on what we will later refer to as the origin collection.</p>
95 * <p>2. Call CollectionManager.makeCollection() to create the collection structure to save into (copied collection).</p>
96 * <p>3. Copy files from the origin to the copied collections (except special collection files ending with ~).</p>
97 * <p>4. Restore origin collection by undoing file copy actions and removing the ~ from the end of collection files.</p>
98 * <p>5. Close the origin collection.</p>
99 * <p>6. Open the copied collection.</p>
100 * <p>Of course all of this takes a while, and depends on several other bits of code to work properly.</p>.
101 * @see org.greenstone.gatherer.collection.Collection
102 * @see org.greenstone.gatherer.collection.CollectionModel
103 * @see org.greenstone.gatherer.gui.GUIManager
104 * @see org.greenstone.gatherer.gui.GConfigPane
105 * @see org.greenstone.gatherer.msm.MetadataSetManager
106 * @see org.greenstone.gatherer.util.Utility
107 */
108 public void run() {
109 // Change cursor to hourglass.
110 Gatherer.g_man.wait(true);
111 // Create progress monitor box. It will display itself as necessary.
112 // WARNING: ProgressMonitors seem to be extremely dodgy, and are not recommended!
113 // ProgressMonitor spd = new ProgressMonitor(Gatherer.g_man, Gatherer.dictionary.get("SaveProgressDialog.Title", collection.getName()), null, 0, 100);
114 // spd.setMillisToDecideToPopup(100);
115 // spd.setMillisToPopup(100);
116 // 0. Force all remaining metadata.xml files to load.
117 // 1. Perform a regular collection save on what we will later refer to as the origin collection.
118 ///ystem.err.println("1. Save origin.");
119 String tmp_loc = Gatherer.c_man.getCollectionFilename();
120 String args[] = new String[1];
121 args[0] = collection.getName() + ".col";
122 try {
123 // Block until all of the metadata files have been read in.
124 collection.gdm.waitUntilComplete();
125 // Write out the metadata xml files. The destroy below is meant to do this, but never does.
126 collection.gdm.save();
127 // spd.setProgress(getValue(METADATA_XML_SAVED));
128
129 File file = new File(tmp_loc);
130 // Create backup
131 if(file.exists()) {
132 File backup = new File(tmp_loc + "~");
133 backup.deleteOnExit();
134 if(!file.renameTo(backup)) {
135 Gatherer.println("Error in CollectionManager.load(): FileNotRenamedException");
136 }
137 }
138
139 // Carry on.
140 collection.save();
141 // spd.setProgress(getValue(COLLECTION_SAVED));
142
143 // Write out the collection configuration file.
144 Gatherer.g_man.config_pane.saveConfiguration();
145 // spd.setProgress(getValue(COLLECTION_CFG_SAVED));
146
147 // Write out the metadata files.
148 Gatherer.c_man.msm.save();
149 // spd.setProgress(getValue(METADATA_SAVED));
150
151 collection.setSaved(true);
152 }
153 catch (Exception error) {
154 Gatherer.printStackTrace(error);
155 }
156 // Now we check whether we've finished, or is this a Save As action, in which case we've got miles to go.
157 if(name != null) {
158 // 2. Call CollectionManager.makeCollection() to create the collection structure to save into (copied collection).
159 ///ystem.err.println("2. Make copy.");
160 Gatherer.c_man.createCollection(null, null, name, null, null, null);
161 // spd.setProgress(getValue(MAKE_COLLECTION));
162 // 3. Copy files from the origin to the copied collections (except special collection files ending with ~).
163 // As part of this we must rename origin.col to copy.col
164 ///ystem.err.println("3. Copy origin.");
165 ArrayList files = new ArrayList();
166 File collection_file = new File(Gatherer.c_man.getCollectionFilename());
167 File copied_dir = new File(Utility.getCollectionDir(Gatherer.config.gsdl_path) + name);
168 files.add(collection_file.getParentFile());
169 while(files.size() > 0) {
170 File file = (File) files.get(0);
171 files.remove(0);
172 if(file.isDirectory()) {
173 File children[] = file.listFiles();
174 for(int i = 0; i < children.length; i++) {
175 files.add(children[i]);
176 }
177 children = null;
178 }
179 else {
180 // Rename origin.col file.
181 if(file.equals(collection_file)) {
182 File copied_file = new File(copied_dir, name + ".col");
183 copy(collection_file, copied_file);
184 copied_file = null;
185 }
186 // Exclude *~ files from certain locations and lock.tmp file.
187 else if(!file.getName().endsWith("~") && !file.getName().equals(CollectionManager.LOCK_FILE)) {
188 StringTokenizer origin = new StringTokenizer(file.getAbsolutePath(), File.separator);
189 StringTokenizer destin = new StringTokenizer(copied_dir.getAbsolutePath(), File.separator);
190 while(destin.hasMoreTokens()) {
191 origin.nextToken();
192 destin.nextToken();
193 }
194 File copied_file = new File(copied_dir.getAbsolutePath());
195 while(origin.hasMoreTokens()) {
196 copied_file = new File(copied_file, origin.nextToken());
197 }
198 copy(file, copied_file);
199 copied_file = null;
200 origin = null;
201 destin = null;
202 }
203 }
204 file = null;
205 }
206 // spd.setProgress(getValue(COPY_COLLECTION));
207 // 4. Restore origin collection by undoing file copy actions and removing the ~ from the end of collection files.
208 ///ystem.err.println("4. Restore origin.");
209 Gatherer.c_man.undo.undoAll();
210 ///ystem.err.println(" - UndoAll complete.");
211 // Recurse collection tree restoring *~
212 files.clear(); // Should be empty anyway.
213 files.add(collection_file.getParentFile());
214 while(files.size() > 0) {
215 File file = (File) files.get(0);
216 files.remove(0);
217 if(file.isDirectory()) {
218 File children[] = file.listFiles();
219 for(int i = 0; i < children.length; i++) {
220 files.add(children[i]);
221 }
222 children = null;
223 }
224 else if(file.getName().endsWith("~")) {
225 String filename = file.getAbsolutePath();
226 File original_file = new File(filename.substring(0, filename.length() - 1));
227 ///ystem.err.println("Renaming " + filename);
228 if(!file.renameTo(original_file)) {
229 Gatherer.println("Error in SaveCollectionTask.run(): FileRenameException");
230 }
231 }
232 }
233 ///ystem.err.println(" - Restore *~ complete.");
234 // spd.setProgress(getValue(RESTORE_COLLECTION));
235 // 5. Close the origin collection.
236 ///ystem.err.println("5. Close origin.");
237 collection.setSaved(true);
238 Gatherer.c_man.closeCollection();
239 // spd.setProgress(getValue(CLOSE_COLLECTION));
240 // 6. Open the copied collection.
241 ///ystem.err.println("6. Open copy.");
242 Gatherer.c_man.loadCollection(copied_dir.getAbsolutePath() + File.separator + name + ".col");
243 // spd.setProgress(getValue(OPEN_COLLECTION));
244 copied_dir = null;
245 }
246 // spd.close();
247 // spd = null;
248 tmp_loc = null;
249 args = null;
250 // Reset undo queue.
251 if(Gatherer.c_man.ready()) {
252 Gatherer.c_man.undo.clear();
253 }
254 Gatherer.g_man.wait(false);
255
256 // Now we are finished action any necessary action.
257 if(import_after) {
258 Gatherer.c_man.importCollection();
259 }
260 if(close_after) {
261 Gatherer.c_man.closeCollection();
262 }
263 ///ystem.err.println("Save Complete.");
264 if(exit_after) {
265 Gatherer.self.exit();
266 }
267 }
268
269 public void setImportAfter(boolean state) {
270 import_after = true;
271 }
272
273 private void copy(File source, File destination) {
274 ///ystem.err.println("Copy: " + source.getAbsolutePath());
275 ///ystem.err.println(" to: " + destination.getAbsolutePath());
276 try {
277 destination.getParentFile().mkdirs();
278 FileInputStream f_in = new FileInputStream(source);
279 FileOutputStream f_out = new FileOutputStream(destination);
280 byte data[] = new byte[Utility.BUFFER_SIZE];
281 int data_size = 0;
282 while((data_size = f_in.read(data, 0, Utility.BUFFER_SIZE)) != -1) {
283 f_out.write(data, 0, data_size);
284 }
285 f_in.close();
286 f_out.close();
287 }
288 catch (Exception exception) {
289 Gatherer.printStackTrace(exception);
290 }
291 }
292
293 private int getValue(int reference) {
294 double multiplier;
295 if(name == null) {
296 multiplier = 1.0;
297 }
298 else {
299 multiplier = 0.25;
300 }
301 switch(reference) {
302 // Standard Save
303 case COLLECTION_SAVED:
304 return (int)((double)70 * multiplier);
305 case COLLECTION_CFG_SAVED:
306 case METADATA_SAVED:
307 case METADATA_XML_SAVED:
308 return (int)((double)10 * multiplier);
309 // Save As
310 case MAKE_COLLECTION:
311 return 5;
312 case COPY_COLLECTION:
313 return 30;
314 case RESTORE_COLLECTION:
315 return 30;
316 case CLOSE_COLLECTION:
317 return 10;
318 case OPEN_COLLECTION:
319 return 10;
320 }
321 return 0;
322 }
323}
324
325
326
327
328
Note: See TracBrowser for help on using the repository browser.