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

Last change on this file since 8313 was 8313, checked in by mdewsnip, 20 years ago

Finally committing the (many) changes to the GLI to use the new metadata code... I hope this doesn't have too many bugs in it and committing it now doesn't stuff anyone up! (Katherine said I could commit it, so blame her if anything goes wrong).

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