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

Last change on this file since 7275 was 7224, checked in by kjdon, 20 years ago

tidied up the getXXXDir methods in Utility. Utility.getCollectionDir (which returns the path to the collect directory) has been renamed to getCollectDir, and a new Utility.getCollectionDir is provided which returns the path to an individual collection's base dir

  • Property svn:keywords set to Author Date Id Revision
File size: 12.1 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, Greenstone Digital Library, University of Waikato
11 *
12 * <BR><BR>
13 *
14 * Copyright (C) 1999 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.collection;
38
39import java.io.*;
40import java.util.*;
41import javax.swing.*;
42import org.greenstone.gatherer.Gatherer;
43import org.greenstone.gatherer.collection.Collection;
44import org.greenstone.gatherer.util.Utility;
45
46/** 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.
47 * @author John Thompson, Greenstone Digital Library, University of Waikato
48 * @version 2.3
49 */
50public class SaveCollectionTask
51 extends Thread {
52 private boolean close_after = false;
53 /** Should we exit the Gatherer once this save is complete. */
54 private boolean exit_after = false;
55 /** Do we run the import scripts once this save is complete. */
56 private boolean import_after = false;
57 /** The current collection. */
58 private Collection collection = null;
59 /** The filename of the collection we are saving. */
60 private String name = null;
61 static final private int CLOSE_COLLECTION = 0;
62 static final private int COLLECTION_COPIED = 1;
63 static final private int COLLECTION_SAVED = 2;
64 static final private int COLLECTION_CFG_SAVED = 3;
65 static final private int COPY_COLLECTION = 4;
66 static final private int MAKE_COLLECTION = 5;
67 static final private int METADATA_SAVED = 6;
68 static final private int METADATA_XML_SAVED = 7;
69 static final private int OPEN_COLLECTION = 8;
70 static final private int RESTORE_COLLECTION = 9;
71 /** Constructor.
72 * @param collection The <strong>Collection</strong> we are saving.
73 * @see org.greenstone.gatherer.collection.Collection
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.gui.GUIManager
103 * @see org.greenstone.gatherer.msm.MetadataSetManager
104 * @see org.greenstone.gatherer.util.Utility
105 */
106 public void run() {
107 // Change cursor to hourglass.
108 Gatherer.g_man.wait(true);
109 // Create progress monitor box. It will display itself as necessary.
110 // WARNING: ProgressMonitors seem to be extremely dodgy, and are not recommended!
111 // ProgressMonitor spd = new ProgressMonitor(Gatherer.g_man, Dictionary.get("SaveProgressDialog.Title", collection.getName()), null, 0, 100);
112 // spd.setMillisToDecideToPopup(100);
113 // spd.setMillisToPopup(100);
114 // 0. Force all remaining metadata.xml files to load.
115 // 1. Perform a regular collection save on what we will later refer to as the origin collection.
116 ///ystem.err.println("1. Save origin.");
117 String tmp_loc = Gatherer.c_man.getCollectionFilename();
118 String args[] = new String[1];
119 args[0] = collection.getName() + ".col";
120 try {
121 // Block until all of the metadata files have been read in.
122 collection.gdm.waitUntilComplete();
123 // Write out the metadata xml files. The destroy below is meant to do this, but never does.
124 collection.gdm.save();
125 // spd.setProgress(getValue(METADATA_XML_SAVED));
126
127 File file = new File(tmp_loc);
128 // Create backup
129 if(file.exists()) {
130 File backup = new File(tmp_loc + "~");
131 backup.deleteOnExit();
132 if(!file.renameTo(backup)) {
133 Gatherer.println("Error in CollectionManager.load(): FileRenamedException");
134 }
135 }
136
137 // Carry on.
138 collection.save();
139 // spd.setProgress(getValue(COLLECTION_SAVED));
140
141 // Write out the collection configuration file.
142 Gatherer.g_man.design_pane.saveConfiguration();
143 // spd.setProgress(getValue(COLLECTION_CFG_SAVED));
144
145 // Write out the metadata files.
146 Gatherer.c_man.msm.save();
147 // spd.setProgress(getValue(METADATA_SAVED));
148
149 collection.setSaved(true);
150 }
151 catch (Exception error) {
152 Gatherer.printStackTrace(error);
153 }
154 // Now we check whether we've finished, or is this a Save As action, in which case we've got miles to go.
155 if(name != null) {
156 // 2. Call CollectionManager.makeCollection() to create the collection structure to save into (copied collection).
157 ///ystem.err.println("2. Make copy.");
158 Gatherer.c_man.createCollection(null, null, name, null, null, null);
159 // spd.setProgress(getValue(MAKE_COLLECTION));
160 // 3. Copy files from the origin to the copied collections (except special collection files ending with ~).
161 // As part of this we must rename origin.col to copy.col
162 ///ystem.err.println("3. Copy origin.");
163 ArrayList files = new ArrayList();
164 File collection_file = new File(Gatherer.c_man.getCollectionFilename());
165 File copied_dir = new File(Utility.getCollectDir(Gatherer.config.gsdl_path) + name);
166 files.add(collection_file.getParentFile());
167 while(files.size() > 0) {
168 File file = (File) files.get(0);
169 files.remove(0);
170 if(file.isDirectory()) {
171 File children[] = file.listFiles();
172 for(int i = 0; i < children.length; i++) {
173 files.add(children[i]);
174 }
175 children = null;
176 }
177 else {
178 // Rename origin.col file.
179 if(file.equals(collection_file)) {
180 File copied_file = new File(copied_dir, name + ".col");
181 copy(collection_file, copied_file);
182 copied_file = null;
183 }
184 // Exclude *~ files from certain locations and lock.tmp file.
185 else if(!file.getName().endsWith("~") && !file.getName().equals(CollectionManager.LOCK_FILE)) {
186 StringTokenizer origin = new StringTokenizer(file.getAbsolutePath(), File.separator);
187 StringTokenizer destin = new StringTokenizer(copied_dir.getAbsolutePath(), File.separator);
188 while(destin.hasMoreTokens()) {
189 origin.nextToken();
190 destin.nextToken();
191 }
192 File copied_file = new File(copied_dir.getAbsolutePath());
193 while(origin.hasMoreTokens()) {
194 copied_file = new File(copied_file, origin.nextToken());
195 }
196 copy(file, copied_file);
197 copied_file = null;
198 origin = null;
199 destin = null;
200 }
201 }
202 file = null;
203 }
204 // spd.setProgress(getValue(COPY_COLLECTION));
205 // 4. Restore origin collection by undoing file copy actions and removing the ~ from the end of collection files.
206 ///ystem.err.println("4. Restore origin.");
207 Gatherer.c_man.undo.undoAll();
208 ///ystem.err.println(" - UndoAll complete.");
209 // Recurse collection tree restoring *~
210 files.clear(); // Should be empty anyway.
211 files.add(collection_file.getParentFile());
212 while(files.size() > 0) {
213 File file = (File) files.get(0);
214 files.remove(0);
215 if(file.isDirectory()) {
216 File children[] = file.listFiles();
217 for(int i = 0; i < children.length; i++) {
218 files.add(children[i]);
219 }
220 children = null;
221 }
222 else if(file.getName().endsWith("~")) {
223 String filename = file.getAbsolutePath();
224 File original_file = new File(filename.substring(0, filename.length() - 1));
225 ///ystem.err.println("Renaming " + filename);
226 if(!file.renameTo(original_file)) {
227 Gatherer.println("Error in SaveCollectionTask.run(): FileRenameException");
228 }
229 }
230 }
231 ///ystem.err.println(" - Restore *~ complete.");
232 // spd.setProgress(getValue(RESTORE_COLLECTION));
233 // 5. Close the origin collection.
234 ///ystem.err.println("5. Close origin.");
235 collection.setSaved(true);
236 Gatherer.c_man.closeCollection();
237 // spd.setProgress(getValue(CLOSE_COLLECTION));
238 // 6. Open the copied collection.
239 ///ystem.err.println("6. Open copy.");
240 Gatherer.c_man.loadCollection(copied_dir.getAbsolutePath() + File.separator + name + ".col");
241 // spd.setProgress(getValue(OPEN_COLLECTION));
242 copied_dir = null;
243 }
244 // spd.close();
245 // spd = null;
246 tmp_loc = null;
247 args = null;
248 // Reset undo queue.
249 if(Gatherer.c_man.ready()) {
250 Gatherer.c_man.undo.clear();
251 }
252 Gatherer.g_man.wait(false);
253
254 // Now we are finished action any necessary action.
255 if(import_after) {
256 Gatherer.c_man.importCollection();
257 }
258 if(close_after) {
259 Gatherer.c_man.closeCollection();
260 }
261 ///ystem.err.println("Save Complete.");
262 if(exit_after) {
263 Gatherer.self.exit();
264 }
265 }
266
267 public void setImportAfter(boolean state) {
268 import_after = true;
269 }
270
271 private void copy(File source, File destination) {
272 ///ystem.err.println("Copy: " + source.getAbsolutePath());
273 ///ystem.err.println(" to: " + destination.getAbsolutePath());
274 try {
275 destination.getParentFile().mkdirs();
276 FileInputStream f_in = new FileInputStream(source);
277 FileOutputStream f_out = new FileOutputStream(destination);
278 byte data[] = new byte[Utility.BUFFER_SIZE];
279 int data_size = 0;
280 while((data_size = f_in.read(data, 0, Utility.BUFFER_SIZE)) != -1) {
281 f_out.write(data, 0, data_size);
282 }
283 f_in.close();
284 f_out.close();
285 }
286 catch (Exception exception) {
287 Gatherer.printStackTrace(exception);
288 }
289 }
290
291 private int getValue(int reference) {
292 double multiplier;
293 if(name == null) {
294 multiplier = 1.0;
295 }
296 else {
297 multiplier = 0.25;
298 }
299 switch(reference) {
300 // Standard Save
301 case COLLECTION_SAVED:
302 return (int)((double)70 * multiplier);
303 case COLLECTION_CFG_SAVED:
304 case METADATA_SAVED:
305 case METADATA_XML_SAVED:
306 return (int)((double)10 * multiplier);
307 // Save As
308 case MAKE_COLLECTION:
309 return 5;
310 case COPY_COLLECTION:
311 return 30;
312 case RESTORE_COLLECTION:
313 return 30;
314 case CLOSE_COLLECTION:
315 return 10;
316 case OPEN_COLLECTION:
317 return 10;
318 }
319 return 0;
320 }
321}
322
323
324
325
326
Note: See TracBrowser for help on using the repository browser.