source: trunk/gli/src/org/greenstone/gatherer/util/Utility.java@ 8809

Last change on this file since 8809 was 8809, checked in by mdewsnip, 19 years ago

Minor changes.

  • Property svn:keywords set to Author Date Id Revision
File size: 34.3 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.util;
38
39import java.awt.*;
40import java.io.*;
41import java.net.*;
42import java.util.*;
43import java.util.zip.*;
44import javax.swing.*;
45import javax.swing.tree.*;
46import org.apache.xerces.parsers.*;
47import org.apache.xml.serialize.*;
48import org.greenstone.gatherer.Configuration;
49import org.greenstone.gatherer.DebugStream;
50import org.greenstone.gatherer.Dictionary;
51// Don't even think about adding import org.greenstone.gatherer.Gatherer in here!
52// The functions in this class should be independent of the Gatherer class. Put your function somewhere else buster!
53import org.w3c.dom.*;
54import org.xml.sax.*;
55
56/** To provide a library of common methods, in a static context, for use in the Gatherer.
57 * @author John Thompson, Greenstone Digital Library, University of Waikato
58 * @version 2.3b
59 */
60public class Utility {
61 static final public Dimension MINIMUM_BUTTON_SIZE = new Dimension(100, 25);
62 // static final public Dimension DOUBLE_IMAGE_BUTTON_SIZE = new Dimension(190, 35);
63 static final public Dimension LABEL_SIZE = new Dimension(150, 25);
64 /** The default size of a gatherer progress bar, in either the download view or the build view. */
65 static final public Dimension PROGRESS_BAR_SIZE = new Dimension(580,65);
66 /** The number of kilobytes to use as a io buffer. */
67 static final public int FACTOR = 1;
68 /** The size of the io buffer, calculated as FACTOR * 1024. */
69 static final public int BUFFER_SIZE = FACTOR * 1024;
70 /** Definition of an important directory name, in this case the base dir, or the working directory of the Gatherer. */
71 static public String BASE_DIR = System.getProperty("user.dir") + File.separator;
72 static final public String BUILD_CFG_FILENAME = "build.cfg";
73 static final public String CFG_COLLECTIONMETA_COLLECTIONNAME = "collectionmeta\tcollectionname";
74 static final public String CFG_COLLECTIONMETA_COLLECTIONEXTRA = "collectionmeta\tcollectionextra";
75 static final public String CFG_COLLECTIONMETA_ICONCOLLECTION = "collectionmeta\ticoncollection";
76 static final public String CFG_CLASSIFY = "classify";
77 static final public String CFG_CLASSIFY_BUTTONNAME = "-buttonname";
78 static final public String CFG_CLASSIFY_HFILE = "-hfile";
79 static final public String CFG_CLASSIFY_METADATA = "-metadata";
80 static final public String CFG_CLASSIFY_SORT = "-sort";
81 static final public String CFG_CREATOR = "creator";
82 static final public String CFG_FORMAT = "format";
83 static final public String CFG_MAINTAINER = "maintainer";
84 /** Definition of an important directory name, in this case the parent directory of all the collections in the gsdl. */
85 static final public String COL_DIR = "collect" + File.separator;
86 static final public String COLLECTION_TREE = "Collection";
87 /** Definition of an important directory name, in this case the file the collection configuration is expect to be in. */
88 static final public String CONFIG_FILE = "etc" + File.separator + "collect.cfg";
89 static final public String EXTRACTED_METADATA_NAMESPACE = "ex";
90 /** The location of the default greenstone metadata file. */
91 static final public String GREENSTONEDIRECTORYMETADATA_TEMPLATE = "xml/metadata.xml";
92 static final public String GLI_ARCHIVE = "GLI.jar";
93 static final public String GLI_EXTENSION = ".col";
94 /** Definition of an important directory name, in this case the images directory for the collection. */
95 static final public String IMAGES_DIR = "images" + File.separator;
96 /** Definition of an important directory name, in this case the import directory for the collection. */
97 static final public String IMPORT_DIR = "import" + File.separator;
98 /** Definition of an important directory name, in this case the backup import directory for the collection. */
99 static final public String IMPORT_BAK_DIR = "import.bak" + File.separator;
100 /** Definition of an important directory name, in this case the log directory for the collection. */
101 static final public String LOG_DIR = "log" + File.separator;
102 /** Definition of an important directory name, in this case the macros directory for the collection. */
103 static final public String MACROS_DIR = "macros" + File.separator;
104 /** Definition of an important directory name, in this case the location of the expected collection metadata sets.. */
105 static final public String META_DIR = "metadata" + File.separator; // Col. Copy
106 /** Definition of an important directory name, in this case the location of the default metadata sets. */
107 static public String METADATA_DIR = BASE_DIR + "metadata" + File.separator;
108 /** Definition of an important zip file, in this case zipped up version of metadata file stored in JAR file */
109 static final public String METADATA_ZIP = "metadata.zip";
110 /** The default name of the perl executable under unix. */
111 static final public String PERL_EXECUTABLE_UNIX = "perl";
112 /** The default name of the perl executable under windows. */
113 static final public String PERL_EXECUTABLE_WINDOWS = "Perl.exe";
114 /** The name of the Gatherer. */
115 static final public String PROGRAM_NAME = "Greenstone Librarian Interface";
116 /** The current version of the Gatherer. */
117 static final public String PROGRAM_VERSION = "v2.52";
118 static final public String WORKSPACE_TREE = "Workspace";
119 static final public String XML_DIRECTORY = "xml" + File.separator;
120
121 // These are out of alphabetic order to avoid forward reference error.
122 /** The default icon to produce a 'help-icon' sized blank space before a menu entry. */
123 static public Class base = null;
124 static public ImageIcon BLANK_ICON = null;
125 /** The default error icon image. */
126 static public ImageIcon ERROR_ICON = null;
127 static public ImageIcon HELP_ICON = null;
128
129
130 /** It turns out that in Java you have to make sure a directory is empty before you delete it (much like unix I suppose), and so just like unix I'll have to set up a recursive delete function.
131 * @param file The <strong>File</strong> you want to delete.
132 * @return A <i>boolean</i> which is <i>true</i> if the file specified was successfully deleted, <i>false</i> otherwise.
133 */
134 static public boolean delete(File file) {
135 boolean result = true;
136 // If file is a directory, delete the file's children.
137 if(file.isDirectory()) {
138 File files[] = file.listFiles();
139 for(int i = 0; files != null && result && i < files.length; i++) {
140 result = delete(files[i]);
141 }
142 }
143 if(result) {
144 // Delete file.
145 return file.delete();
146 }
147 return result;
148 }
149
150 static public boolean delete(String filename) {
151 return delete(new File(filename));
152 }
153
154
155 /** Convert a long, detailing the length of a file in bytes, into a nice human readable string using b, kb, Mb and Gb. */
156 static final public String BYTE_SUFFIX = " b";
157 static final public long GIGABYTE = 1024000000l;
158 static final public String GIGABYTE_SUFFIX = " Gb";
159 static final public long KILOBYTE = 1024l;
160 static final public String KILOBYTE_SUFFIX = " kb";
161 static final public long MEGABYTE = 1024000l;
162 static final public String MEGABYTE_SUFFIX = " mb";
163 static final public String formatFileLength(long length) {
164 StringBuffer result = new StringBuffer("");
165 float number = 0f;
166 String suffix = null;
167 // Determine the floating point number and the suffix (radix) used.
168 if(length >= GIGABYTE) {
169 number = (float) length / (float) GIGABYTE;
170 suffix = GIGABYTE_SUFFIX;
171 }
172 else if(length >= MEGABYTE) {
173 number = (float) length / (float) MEGABYTE;
174 suffix = MEGABYTE_SUFFIX;
175 }
176 else if(length >= KILOBYTE) {
177 number = (float) length / (float) KILOBYTE;
178 suffix = KILOBYTE_SUFFIX;
179 }
180 else {
181 // Don't need to do anything fancy if the file is smaller than a kilobyte
182 return length + BYTE_SUFFIX;
183 }
184 // Create the formatted string remembering to round the number to 2.d.p. To do this copy everything in the number string from the start to the first occurance of '.' then copy two more digits. Finally search for and print anything that appears after (and including) the optional 'E' delimter.
185 String number_str = Float.toString(number);
186 char number_char[] = number_str.toCharArray();
187 int pos = 0;
188 // Print the characters up to the '.'
189 while(number_char != null && pos < number_char.length && number_char[pos] != '.') {
190 result.append(number_char[pos]);
191 pos++;
192 }
193 if(pos < number_char.length) {
194 // Print the '.' and at most two characters after it
195 result.append(number_char[pos]);
196 pos++;
197 for(int i = 0; i < 2 && pos < number_char.length; i++, pos++) {
198 result.append(number_char[pos]);
199 }
200 // Search through the remaining string for 'E'
201 while(pos < number_char.length && number_char[pos] != 'E') {
202 pos++;
203 }
204 // If we still have string then we found an E. Copy the remaining string.
205 while(pos < number_char.length) {
206 result.append(number_char[pos]);
207 pos++;
208 }
209 }
210 // Add suffix
211 result.append(suffix);
212 // Done
213 return result.toString();
214 }
215
216 /** This method formats a given string, using HTML markup, so its width does not exceed the given width and its appearance if justified.
217 * @param text The <strong>String</strong> requiring formatting.
218 * @param width The maximum width per line as an <i>int</i>.
219 * @return A <strong>String</strong> formatted so as to have no line longer than the specified width.
220 * TODO Currently HTML formatting tags are simply removed from the text, as the effects of spreading HTML tags over a break are undetermined. To solve this we need to associate tags with a certain text token so if it gets broken on to the next line the tags go with it, or if the tags cover a sequence of words that are broken we need to close then reopen the tags. However all this is a major task and well beyond anything I have time to 'muck-round' on.
221 */
222 static public String formatHTMLWidth(String text, int width) {
223 if(text == null) {
224 return "Error";
225 }
226 HTMLStringTokenizer html = new HTMLStringTokenizer(text);
227 int current_width = 0;
228 int threshold = width / 2;
229 Stack lines = new Stack();
230 String line = "";
231 while(html.hasMoreTokens()) {
232 String token = html.nextToken();
233 while(token != null) {
234 if(html.isTag()) {
235 // Insert smart HTML tag code here.
236 token = null;
237 }
238 else {
239 // If the token is bigger than two thirds width, before we've even started break it down.
240 if(current_width + 1 + token.length() > width && token.length() > threshold) {
241 if(width == current_width) {
242 lines.push(line);
243 line = token;
244 current_width = token.length();
245 }
246 else {
247 String prefix = token.substring(0, width - 1 - current_width);
248 token = token.substring(prefix.length());
249 if(current_width == 0) {
250 line = line + prefix;
251 }
252 else {
253 line = line + " " + prefix;
254 }
255 lines.push(line);
256 line = "";
257 current_width = 0;
258 }
259 }
260 // If adding the next token would push us over the maximum line width.
261 else if(current_width + 1 + token.length() > width) {
262 lines.push(line);
263 line = token;
264 current_width = token.length();
265 token = null;
266 }
267 // Otherwise we should be able to just add the token, give or take.
268 else {
269 if(current_width == 0) {
270 line = line + token;
271 current_width = token.length();
272 }
273 else {
274 // Special case for standard punctuation which may exist after a tag like so:
275 // My name is <scratchy>Slim Shady</scratchy>. <-- Annoying punctuation.
276 if(token.equals(".") || token.equals(",") || token.equals("!") || token.equals("?")) {
277 line = line + token;
278 current_width = current_width + 1;
279 }
280 else {
281 line = line + " " + token;
282 current_width = current_width + 1 + token.length();
283 }
284 }
285 token = null;
286 }
287 }
288 }
289 }
290 String result = line;
291 while(!lines.empty()) {
292 result = (String)lines.pop() + "<BR>" + result;
293 }
294 // Replace ' ' with "&nbsp;"
295 boolean tag = false;
296 int pos = 0;
297 while(pos < result.length()) {
298 if(result.charAt(pos) == '<') {
299 tag = true;
300 }
301 else if(result.charAt(pos) == '>') {
302 tag = false;
303 }
304 else if(result.charAt(pos) == ' ' && !tag) {
305 String prefix = result.substring(0, pos);
306 String suffix = result.substring(pos + 1);
307 result = prefix + "&nbsp;" + suffix;
308 }
309 pos++;
310 }
311 result = "<HTML>" + result + "</HTML>";
312 return result;
313 }
314 /** Format the given filename path string so that it is no longer than the given width. If it is wider replace starting directories with ...
315 * @param key The key <strong>String</Strong> used to retrieve a phrase from the dictionary for this item.
316 * @param raw The raw filename path <strong>String</strong>.
317 * @param width The maximum width as an <i>int</i>.
318 * @return A path <strong>String</strong> no longer than width.
319 */
320 static public String formatPath(String key, String raw, int width) {
321 JLabel label = new JLabel(Dictionary.get(key, raw));
322 int position = -1;
323 while(label.getPreferredSize().width > width && (position = raw.indexOf(File.separator)) != -1) {
324 raw = "..." + raw.substring(position + 1);
325 label.setText(Dictionary.get(key, raw));
326 }
327 if(raw.indexOf(File.separator) == -1 && raw.startsWith("...")) {
328 raw = raw.substring(3);
329 }
330 return raw;
331 }
332
333
334 /** Builds the cache dir by appending the user path and 'cache'.
335 * @return a File representing the path to the private file cache within the current collection.
336 */
337 public static File getCacheDir() {
338 return new File(getGLIUserFolder(), StaticStrings.CACHE_FOLDER);
339 }
340 /** Method which constructs the collect directory for Greenstone.
341 * @param gsdl_path The location of the gsdl installation directory as a <strong>String</strong>.
342 * @return The location of the collection directory, also as a <strong>String</strong>.
343 */
344 public static String getCollectDir(String gsdl_path) {
345 return gsdl_path + COL_DIR;
346 }
347 static public String getCollectDir(String gsdl3_path, String site_name) {
348 return getSitesDir(gsdl3_path) + site_name + File.separator + COL_DIR;
349 }
350
351
352 /** Method which constructs a collection's top level directory
353 * @@param gsdl_path The location of the gsdl installation directory as a <strong>String</strong>.
354 * @param The name of the collection as a <strong>String</strong>.
355 * @return The location of the collection's base directory
356 */
357 public static String getCollectionDir(String gsdl_path, String coll_name) {
358 return getCollectDir(gsdl_path) + coll_name + File.separator;
359 }
360 public static String getCollectionDir(String gsdl3_path, String site_name, String coll_name) {
361 return getCollectDir(gsdl3_path, site_name) + coll_name + File.separator;
362 }
363
364
365 /** Method which constructs the configuration file given a certain collection.
366 * @param col_dir The location of the collection directory as a <strong>String</strong>.
367 * @return The location of the given collections configuration file, also as a <strong>String</strong>.
368 */
369 static public String getConfigFile(String col_dir) {
370 return col_dir + CONFIG_FILE;
371 }
372
373 static public String getDateString() {
374 Calendar current = Calendar.getInstance();
375 String day_name = null;
376 switch(current.get(Calendar.DAY_OF_WEEK)) {
377 case Calendar.MONDAY: day_name = "Dates.Mon"; break;
378 case Calendar.TUESDAY: day_name = "Dates.Tue"; break;
379 case Calendar.WEDNESDAY: day_name = "Dates.Wed"; break;
380 case Calendar.THURSDAY: day_name = "Dates.Thu"; break;
381 case Calendar.FRIDAY: day_name = "Dates.Fri"; break;
382 case Calendar.SATURDAY: day_name = "Dates.Sat"; break;
383 case Calendar.SUNDAY: day_name = "Dates.Sun"; break;
384 default: day_name = "";
385 }
386 String month_name = null;
387 switch(current.get(Calendar.MONTH)) {
388 case Calendar.JANUARY: month_name = "Dates.Jan"; break;
389 case Calendar.FEBRUARY: month_name = "Dates.Feb"; break;
390 case Calendar.MARCH: month_name = "Dates.Mar"; break;
391 case Calendar.APRIL: month_name = "Dates.Apr"; break;
392 case Calendar.MAY: month_name = "Dates.May"; break;
393 case Calendar.JUNE: month_name = "Dates.Jun"; break;
394 case Calendar.JULY: month_name = "Dates.Jul"; break;
395 case Calendar.AUGUST: month_name = "Dates.Aug"; break;
396 case Calendar.SEPTEMBER: month_name = "Dates.Sep"; break;
397 case Calendar.OCTOBER: month_name = "Dates.Oct"; break;
398 case Calendar.NOVEMBER: month_name = "Dates.Nov"; break;
399 case Calendar.DECEMBER: month_name = "Dates.Dec"; break;
400 default: month_name = "";
401 }
402 int day = current.get(Calendar.DAY_OF_MONTH);
403 int hour = current.get(Calendar.HOUR_OF_DAY);
404 int minute = current.get(Calendar.MINUTE);
405 int second = current.get(Calendar.SECOND);
406 int year = current.get(Calendar.YEAR);
407
408 return Dictionary.get(day_name) + " " + Dictionary.get(month_name) + " " + day + " " + year + " " + Utility.pad(String.valueOf(hour), 2, '0', true) + ":" + Utility.pad(String.valueOf(minute), 2, '0', true) + ":" + Utility.pad(String.valueOf(second), 2, '0', true);
409 }
410
411
412 static final private String APPLICATION_DATA_FOLDER = "Application Data";
413 static final private String UNIX_GLI_CONFIG_FOLDER = ".gli";
414 static final private String USER_HOME_PROPERTY = "user.home";
415 static final private String WIN_GLI_CONFIG_FOLDER = "Greenstone" + File.separator + "GLI";
416
417 static public File getGLIUserFolder()
418 {
419 if (Utility.isWindows()) {
420 return new File(System.getProperty(USER_HOME_PROPERTY) + File.separator + APPLICATION_DATA_FOLDER + File.separator + WIN_GLI_CONFIG_FOLDER + File.separator);
421 }
422 else {
423 return new File(System.getProperty(USER_HOME_PROPERTY) + File.separator + UNIX_GLI_CONFIG_FOLDER + File.separator);
424 }
425 }
426
427
428 /** Retrieve the full file path to the help index xml file.
429 * @return the full path as a String
430 */
431 static public String getHelpFolder() {
432
433 String help_folder = "help/" + Configuration.getLanguage() + "/";
434
435 // Try in the JAR/classes directory first
436 URL help_folder_url = base.getResource("/" + help_folder);
437 if (help_folder_url != null) {
438 return help_folder;
439 }
440
441 // Look in the base directory next
442 File help_folder_file = new File(help_folder);
443 if (help_folder_file.exists()) {
444 return help_folder;
445 }
446
447 // Resort to English
448 return "help/" + StaticStrings.ENGLISH_LANGUAGE_STR + "/";
449 }
450
451 /** Method to retrieve an image icon with the given filename found in classpath or the resouces directory.
452 * @return The specified <strong>ImageIcon</strong>, or an error image replacement if no such images exists.
453 */
454 static public ImageIcon getImage(String filename) {
455 return getImage(filename, false);
456 }
457
458 static public ImageIcon getImage(String filename, boolean wait_until_complete) {
459 ImageIcon image = null;
460 try {
461 image = new ImageIcon(base.getResource("/images/" + Dictionary.get("Version") + "/" + filename));
462 }
463 catch(NullPointerException exception) {
464 image = new ImageIcon(base.getResource("/images/" + filename));
465 }
466 if(image == null) {
467 image = ERROR_ICON;
468 }
469
470 if(wait_until_complete) {
471 int load_status;
472 do {
473 load_status = image.getImageLoadStatus();
474 }
475 while(load_status != MediaTracker.ABORTED && load_status != MediaTracker.ERRORED && load_status != MediaTracker.COMPLETE);
476 }
477 return image;
478 }
479
480 /** Method which constructs the images directory given a certain collection.
481 * @param col_dir The location of the collection directory as a <strong>String</strong>.
482 * @return The location of the given collections images directory, also as a <strong>String</strong>.
483 */
484 public static String getImagesDir(String col_dir) {
485 return col_dir + IMAGES_DIR;
486 }
487 /** Method which constructs the import directory given a certain collection.
488 * @param col_dir The location of the collection directory as a <strong>String</strong>.
489 * @return The location of the given collections import directory, also as a <strong>String</strong>.
490 */
491 public static String getImportDir(String col_dir) {
492 return col_dir + IMPORT_DIR;
493 }
494
495 /** Method which constructs the log directory given a certain collection.
496 * @param col_dir The location of the collection directory as a <strong>String</strong>.
497 * @return The location of the given collections log directory, also as a <strong>String</strong>.
498 */
499 public static String getLogDir(String col_dir) {
500 if(col_dir != null) {
501 return col_dir + LOG_DIR;
502 }
503 else {
504 return getGLIUserFolder().getAbsolutePath() + File.separator + LOG_DIR;
505 }
506 }
507 /** Determine this machines name.
508 * @return The name as a <strong>String</strong>.
509 */
510 static public String getMachineName() {
511 try {
512 return InetAddress.getLocalHost().getHostName();
513 }
514 catch(UnknownHostException ex) {
515 }
516 return "Unknown Machine";
517 }
518
519
520 static public void extractFromJar(String filename, String dst_dir, boolean must_be_present)
521 {
522 try {
523 // setup input stream for slurping out file
524 InputStream fis = base.getResourceAsStream("/"+filename);
525 BufferedInputStream fbis = new BufferedInputStream(fis);
526 DataInputStream fdbis = new DataInputStream(fbis);
527
528 // set up output stream for writing to disk
529 String ofname = dst_dir + filename;
530 FileOutputStream fos = new FileOutputStream(ofname);
531 BufferedOutputStream bfos = new BufferedOutputStream(fos);
532
533 byte[] buf = new byte[1024];
534 int len;
535 int total_bytes = 0;
536 while ((len = fdbis.read(buf)) >= 0) {
537 bfos.write(buf,0,len);
538 total_bytes += len;
539 }
540
541 fdbis.close();
542 bfos.close();
543 }
544 catch (Exception error) {
545 if (must_be_present) {
546 error.printStackTrace();
547 }
548 }
549 }
550
551
552 /** Method which unzips a given metadata resoure
553 * @param zip_fname The name of the zip file as a <strong>String</strong>.
554 * @param dst_dir The destination directory for unzipping, also as a <strong>String</strong>.
555 * @param use_classloader Used to determine whether or not to look in resource bundle.
556 */
557 static public void unzipFromJar(String jar_zip_fname, String dst_dir) {
558
559 File file = null;
560 if (!dst_dir.endsWith(File.separator)) {
561 dst_dir += File.separator;
562 }
563
564 extractFromJar(jar_zip_fname,dst_dir,true);
565
566 String zip_ofname = dst_dir + jar_zip_fname;
567 File zip_file = new File(zip_ofname);
568
569 try {
570 ZipFile zipfile = new ZipFile(zip_file);
571
572 Enumeration e = zipfile.entries();
573 while (e.hasMoreElements()) {
574 ZipEntry zipentry = (ZipEntry) e.nextElement();
575 String zentryname = dst_dir + zipentry.getName();
576 DebugStream.println(" Unzipping: " + zentryname);
577
578 if (zipentry.isDirectory()) {
579 // Create named directory
580 boolean success = (new File(zentryname)).mkdir();
581 if (!success) {
582 System.err.println("Error: unable to create directory '"+zentryname+"'");
583 }
584 }
585 else {
586 // Write out file to disk
587
588 // set up input stream
589 InputStream zis = zipfile.getInputStream(zipentry);
590 BufferedInputStream bzis = new BufferedInputStream(zis);
591 DataInputStream dbzis = new DataInputStream(bzis);
592
593 // set up output stream
594 FileOutputStream fzos = new FileOutputStream(zentryname);
595 BufferedOutputStream bfzos = new BufferedOutputStream(fzos);
596
597 byte[] buf = new byte[1024];
598 int len;
599 while ((len = dbzis.read(buf)) >= 0) {
600 bfzos.write(buf,0,len);
601 }
602
603 dbzis.close();
604 bfzos.close();
605 }
606 }
607 }
608 catch (ZipException error) {
609 System.err.println("Error: Unable to open '"+zip_file.getAbsolutePath()+"'");
610 DebugStream.printStackTrace(error);
611 }
612
613 catch (Exception error) {
614 error.printStackTrace();
615 }
616 }
617
618
619 static protected String unixStylePath(String path)
620 {
621 String unix_path = path.replace('\\','/');
622 return unix_path;
623 }
624
625 static protected void zipFunc (ZipOutputStream zos, String file_path, int prefix_strip)
626 {
627 // Using try is required because of file io.
628 try {
629 // Create a Zip Entry and put it into the archive (no data yet).
630
631 // Strip off col_dir prefix
632 String zip_path = file_path.substring(prefix_strip);
633 // Zip files use '/' for directory separator
634 String unix_style_path = unixStylePath(zip_path);
635 ZipEntry fileEntry = new ZipEntry(unix_style_path);
636 zos.putNextEntry(fileEntry);
637
638 // Create a file input stream and a buffered input stream.
639 FileInputStream fis = new FileInputStream(file_path);
640 BufferedInputStream bis = new BufferedInputStream(fis);
641
642 // Create a byte array object named data and declare byte count variable.
643 byte[] data = new byte[1024];
644 int byteCount;
645 // Create a loop that reads from the buffered input stream and writes
646 // to the zip output stream until the bis has been entirely read.
647 while ((byteCount = bis.read(data, 0, 1024)) > -1) {
648 zos.write(data, 0, byteCount);
649 }
650 }
651 catch (IOException e) {
652 e.printStackTrace();
653 }
654
655 DebugStream.println(" Zipping up: " + file_path);
656 }
657
658 static protected void dirFunc (ZipOutputStream zos, String dir_name, int prefix_strip)
659 {
660 File dirObj = new File(dir_name);
661
662 if (dirObj.exists() == true) {
663 if (dirObj.isDirectory() == true) {
664 // Create an array of File objects, one for each file or directory in dirObj.
665 File [] fileList = dirObj.listFiles();
666
667 // Loop through File array and display.
668 for (int i = 0; i < fileList.length; i++) {
669 File file = fileList[i];
670 if (file.isDirectory()) {
671 String dir_path = file.getPath();
672 String zip_path = dir_path.substring(prefix_strip);
673 // Zip files use '/' for directory separator
674 String unix_style_path
675 = unixStylePath(zip_path+File.separator);
676 ZipEntry dirEntry = new ZipEntry(unix_style_path);
677
678 try {
679 zos.putNextEntry(dirEntry);
680 }
681 catch (IOException e) {
682 e.printStackTrace();
683 }
684
685 dirFunc(zos,dir_path,prefix_strip);
686 } else if (file.isFile()) {
687 // Call the zipFunc function
688 String file_path = fileList[i].getPath();
689 zipFunc(zos,file_path,prefix_strip);
690 }
691 }
692 }
693 else {
694 System.err.println (dir_name+" is not a directory.");
695 }
696 }
697 else {
698 System.err.println ("Directory "+dir_name+" does not exist.");
699 }
700 }
701
702
703
704 static public void zipup(String col_name, String dir_or_file)
705 {
706 String col_dir = Utility.getCollectDir(Configuration.gsdl_path);
707 int prefix_strip = col_dir.length();
708
709 String zip_fname = col_dir + col_name + ".zip";
710 String zip_dir_or_file = col_dir + col_name + File.separator + dir_or_file;
711 File zip_dof = new File(zip_dir_or_file);
712
713 try {
714 FileOutputStream fos = new FileOutputStream(zip_fname);
715 ZipOutputStream zos = new ZipOutputStream(fos);
716
717 if (zip_dof.exists()) {
718 if (zip_dof.isDirectory()) {
719 String zip_dir = zip_dir_or_file;
720 dirFunc(zos,zip_dir,prefix_strip);
721 }
722 else {
723 String zip_full_file = zip_dir_or_file;
724
725 String zip_path = zip_full_file.substring(prefix_strip);
726
727 for (int i=1; i<zip_path.length(); i++) {
728 String ch = String.valueOf(zip_path.charAt(i));
729
730 if (ch.equals(File.separator)) {
731 String dir_path = zip_path.substring(0,i);
732 // Zip files use '/' for directory separator
733 String unix_style_path
734 = unixStylePath(dir_path+File.separator);
735 ZipEntry dirEntry = new ZipEntry(unix_style_path);
736 zos.putNextEntry(dirEntry);
737 }
738 }
739 zipFunc(zos,zip_full_file,prefix_strip);
740 }
741 }
742 else {
743 System.err.println("Warning: " + zip_dir_or_file + " does not exist!");
744 }
745
746 // Close the file output streams for both the file and the zip.
747 zos.flush();
748 zos.close();
749 fos.close();
750 }
751 catch (IOException e) {
752 e.printStackTrace();
753 }
754 }
755
756
757 static public void unzip(String col_name)
758 {
759 String col_dir = Utility.getCollectDir(Configuration.gsdl_path);
760 String zip_fname = col_dir + col_name + ".zip";
761 int zip_mode = ZipFile.OPEN_READ | ZipFile.OPEN_DELETE;
762
763 try {
764 ZipFile zipfile = new ZipFile(new File(zip_fname), zip_mode);
765
766 Enumeration e = zipfile.entries();
767 while (e.hasMoreElements()) {
768 ZipEntry zipentry = (ZipEntry) e.nextElement();
769 String zentryname = col_dir + zipentry.getName();
770 DebugStream.println(" Unzipping: " + zentryname);
771
772 if (zipentry.isDirectory()) {
773 // Create named directory
774 boolean success = (new File(zentryname)).mkdir();
775 if (!success) {
776 System.err.println("Error: unable to create directory '"+zentryname+"'");
777 }
778 }
779 else {
780 // Write out file to disk
781
782 // set up input stream
783 InputStream zis = zipfile.getInputStream(zipentry);
784 BufferedInputStream bzis = new BufferedInputStream(zis);
785 DataInputStream dbzis = new DataInputStream(bzis);
786
787 // set up output stream
788 FileOutputStream fzos = new FileOutputStream(zentryname);
789 BufferedOutputStream bfzos = new BufferedOutputStream(fzos);
790
791 byte[] buf = new byte[1024];
792 int len;
793 while ((len = dbzis.read(buf)) >= 0) {
794 bfzos.write(buf,0,len);
795 }
796
797 dbzis.close();
798 bfzos.close();
799 }
800 }
801 }
802 catch (ZipException error) {
803 System.err.println("Error: Unable to open '"+zip_fname+"'");
804 DebugStream.printStackTrace(error);
805 }
806
807 catch (Exception error) {
808 error.printStackTrace();
809 }
810 }
811
812
813 static public String getSitesDir(String gsdl3_path) {
814 return gsdl3_path + File.separator + "web"
815 + File.separator + "sites" + File.separator;
816
817 }
818
819
820 /** returns the path to the greenstone version of wget */
821 static public String getWGetPath(String gsdl_path) {
822 if (isWindows()) {
823 return gsdl_path + "bin" + File.separator +
824 "windows" + File.separator +"wget.exe";
825 }
826 // is it the same for macs??
827 return gsdl_path + "bin" + File.separator +
828 "linux" + File.separator + "wget";
829 }
830
831
832 static public void initImages(Object base_object)
833 {
834 base = base_object.getClass();
835
836 BLANK_ICON = new ImageIcon(base.getResource("/images/blank.gif"));
837 ERROR_ICON = new ImageIcon(base.getResource("/images/error.gif"));
838 HELP_ICON = new ImageIcon(base.getResource("/images/help.gif"));
839 }
840
841
842 /** Method to determine if the host system is MacOS based.
843 * @return a boolean which is true if the platform is MacOS, false otherwise
844 */
845 public static boolean isMac() {
846 Properties props = System.getProperties();
847 String os_name = props.getProperty("os.name","");
848 if(os_name.startsWith("Mac OS")) {
849 return true;
850 }
851 return false;
852 }
853
854
855 /** Method to determine if the host system is Microsoft Windows based.
856 * @return A <i>boolean</i> which is <i>true</i> if the platform is Windows, <i>false</i> otherwise.
857 */
858 public static boolean isWindows() {
859 Properties props = System.getProperties();
860 String os_name = props.getProperty("os.name","");
861 if(os_name.startsWith("Windows")) {
862 return true;
863 }
864 return false;
865 }
866
867 public static boolean isWindows9x() {
868 Properties props = System.getProperties();
869 String os_name = props.getProperty("os.name","");
870 if(os_name.startsWith("Windows") && os_name.indexOf("9") != -1) {
871 return true;
872 }
873 return false;
874 }
875 /** Takes a string and a desired length and pads out the string to the length by adding spaces to the left.
876 * @param str The target <strong>String</strong> that needs to be padded.
877 * @param length The desired length of the string as an <i>int</i>.
878 * @return A <strong>String</strong> made from appending space characters with the string until it has a length equal to length.
879 */
880 static private String pad(String str_raw, int length, char fill, boolean end) {
881 StringBuffer str = new StringBuffer(str_raw);
882 while(str.length() < length) {
883 if(end) {
884 str.insert(0, fill);
885 }
886 else {
887 str.append(fill);
888 }
889 }
890 return str.toString();
891 }
892
893
894 /** Parse in a xml document from a given filename. Note that this filename may need to be resolved by the class loader, especially for template files within a jar. */
895 static public Document parse(String filename, boolean use_classloader)
896 {
897 // Try the class loader if desired (for the applet JAR file)
898 if (use_classloader) {
899 InputStream is = base.getResourceAsStream("/" + filename);
900 if (is != null) {
901 return XMLTools.parse(is, true);
902 }
903 }
904
905 // Try the file outside the classes directory
906 return XMLTools.parse(new File(filename), true);
907 }
908
909
910 static public StringBuffer readXMLStream(InputStream input_stream)
911 {
912 StringBuffer xml = new StringBuffer("");
913
914 try {
915 InputStreamReader isr = new InputStreamReader(input_stream, "UTF-8");
916 BufferedReader buffered_in = new BufferedReader(isr);
917
918 String line = "";
919 boolean xml_content = false;
920 while((line = buffered_in.readLine()) != null) {
921 if(xml_content) {
922 xml.append(line);
923 xml.append("\n");
924 }
925 else if(line.trim().startsWith("<?xml")) {
926 xml_content = true;
927 xml.append(line);
928 xml.append("\n");
929 }
930 }
931 buffered_in = null;
932 }
933 catch (Exception error) {
934 System.err.println("Failed when trying to parse XML stream");
935 error.printStackTrace();
936 }
937
938 return xml;
939 }
940
941
942 /** I think this works a bit better on Unicode strings. */
943 static public String stripNL(String raw_string)
944 {
945 String stripped_string = new String();
946 for (int i = 0; i < raw_string.length(); i++) {
947 char raw_character = raw_string.charAt(i);
948 if (raw_character != '\n' && raw_character != '\t') {
949 stripped_string = stripped_string + raw_character;
950 }
951 }
952 return stripped_string;
953 }
954}
Note: See TracBrowser for help on using the repository browser.