/** *######################################################################### * * A component of the Gatherer application, part of the Greenstone digital * library suite from the New Zealand Digital Library Project at the * University of Waikato, New Zealand. * *

* * Author: John Thompson, Greenstone Digital Library, University of Waikato * *

* * Copyright (C) 1999 New Zealand Digital Library Project * *

* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * *

* * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * *

* * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *######################################################################## */ package org.greenstone.gatherer.util; import java.awt.*; import java.io.*; import java.net.*; import java.util.*; import java.util.zip.*; import javax.swing.*; import javax.swing.tree.*; import org.apache.xerces.parsers.*; import org.apache.xerces.dom.DocumentImpl; import org.apache.xml.serialize.*; import org.greenstone.gatherer.Configuration; import org.greenstone.gatherer.DebugStream; import org.greenstone.gatherer.Dictionary; import org.greenstone.gatherer.shell.GShell; // Don't even think about adding import org.greenstone.gatherer.Gatherer in here! // The functions in this class should be independent of the Gatherer class. Put your function somewhere else buster! import org.w3c.dom.*; import org.xml.sax.*; /** To provide a library of common methods, in a static context, for use in the Gatherer. * @author John Thompson, Greenstone Digital Library, University of Waikato * @version 2.3b */ public class Utility { static final public Dimension MINIMUM_BUTTON_SIZE = new Dimension(100, 25); // static final public Dimension DOUBLE_IMAGE_BUTTON_SIZE = new Dimension(190, 35); static final public Dimension LABEL_SIZE = new Dimension(150, 25); /** The default size of a gatherer progress bar, in either the download view or the build view. */ static final public Dimension PROGRESS_BAR_SIZE = new Dimension(580,65); /** The number of kilobytes to use as a io buffer. */ static final public int FACTOR = 1; /** The size of the io buffer, calculated as FACTOR * 1024. */ static final public int BUFFER_SIZE = FACTOR * 1024; /** Definition of an important directory name, in this case the base dir, or the working directory of the Gatherer. */ static public String BASE_DIR = System.getProperty("user.dir") + File.separator; static final public String BUILD_CFG_FILENAME = "build.cfg"; static final public String CFG_COLLECTIONMETA_COLLECTIONNAME = "collectionmeta\tcollectionname"; static final public String CFG_COLLECTIONMETA_COLLECTIONEXTRA = "collectionmeta\tcollectionextra"; static final public String CFG_COLLECTIONMETA_ICONCOLLECTION = "collectionmeta\ticoncollection"; static final public String CFG_CLASSIFY = "classify"; static final public String CFG_CLASSIFY_BUTTONNAME = "-buttonname"; static final public String CFG_CLASSIFY_HFILE = "-hfile"; static final public String CFG_CLASSIFY_METADATA = "-metadata"; static final public String CFG_CLASSIFY_SORT = "-sort"; static final public String CFG_CREATOR = "creator"; static final public String CFG_FORMAT = "format"; static final public String CFG_MAINTAINER = "maintainer"; /** Definition of an important directory name, in this case the parent directory of all the collections in the gsdl. */ static final public String COL_DIR = "collect" + File.separator; static final public String COLLECTION_TREE = "Collection"; /** Definition of an important directory name, in this case the file the collection configuration is expect to be in. */ static final public String CONFIG_FILE = "etc" + File.separator + "collect.cfg"; static final public String EXTRACTED_METADATA_NAMESPACE = "ex"; /** The location of the default greenstone metadata file. */ static final public String GREENSTONEDIRECTORYMETADATA_TEMPLATE = "xml/metadata.xml"; static final public String GLI_ARCHIVE = "GLI.jar"; static final public String GLI_EXTENSION = ".col"; /** Definition of an important directory name, in this case the images directory for the collection. */ static final public String IMAGES_DIR = "images" + File.separator; /** Definition of an important directory name, in this case the import directory for the collection. */ static final public String IMPORT_DIR = "import" + File.separator; /** Definition of an important directory name, in this case the backup import directory for the collection. */ static final public String IMPORT_BAK_DIR = "import.bak" + File.separator; /** Definition of an important directory name, in this case the log directory for the collection. */ static final public String LOG_DIR = "log" + File.separator; /** Definition of an important directory name, in this case the macros directory for the collection. */ static final public String MACROS_DIR = "macros" + File.separator; /** Definition of an important directory name, in this case the location of the expected collection metadata sets.. */ static final public String META_DIR = "metadata" + File.separator; // Col. Copy /** Definition of an important directory name, in this case the location of the default metadata sets. */ static public String METADATA_DIR = BASE_DIR + "metadata" + File.separator; /** Definition of an important zip file, in this case zipped up version of metadata file stored in JAR file */ static final public String METADATA_ZIP = "metadata.zip"; /** The default name of the perl executable under unix. */ static final public String PERL_EXECUTABLE_UNIX = "perl"; /** The default name of the perl executable under windows. */ static final public String PERL_EXECUTABLE_WINDOWS = "Perl.exe"; /** The name of the Gatherer. */ static final public String PROGRAM_NAME = "Greenstone Librarian Interface"; /** The current version of the Gatherer. */ static final public String PROGRAM_VERSION = "v2.53"; static final public String WORKSPACE_TREE = "Workspace"; static final public String XML_DIRECTORY = "xml" + File.separator; // These are out of alphabetic order to avoid forward reference error. /** The default icon to produce a 'help-icon' sized blank space before a menu entry. */ static public Class base = null; static public ImageIcon BLANK_ICON = null; /** The default error icon image. */ static public ImageIcon ERROR_ICON = null; static public ImageIcon HELP_ICON = null; /** 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. * @param file The File you want to delete. * @return A boolean which is true if the file specified was successfully deleted, false otherwise. */ static public boolean delete(File file) { // Nothing to do if it doesn't exist if (!file.exists()) { return true; } // If file is a directory, we have to recursively delete its contents first if (file.isDirectory()) { File files[] = file.listFiles(); for (int i = 0; i < files.length; i++) { if (delete(files[i]) == false) { System.err.println("Error: Could not delete folder " + file); return false; } } } // Delete file if (file.delete() == false) { System.err.println("Error: Could not delete file " + file); return false; } return true; } static public boolean delete(String filename) { return delete(new File(filename)); } /** Convert a long, detailing the length of a file in bytes, into a nice human readable string using b, kb, Mb and Gb. */ static final public String BYTE_SUFFIX = " b"; static final public long GIGABYTE = 1024000000l; static final public String GIGABYTE_SUFFIX = " Gb"; static final public long KILOBYTE = 1024l; static final public String KILOBYTE_SUFFIX = " kb"; static final public long MEGABYTE = 1024000l; static final public String MEGABYTE_SUFFIX = " mb"; static final public String formatFileLength(long length) { StringBuffer result = new StringBuffer(""); float number = 0f; String suffix = null; // Determine the floating point number and the suffix (radix) used. if(length >= GIGABYTE) { number = (float) length / (float) GIGABYTE; suffix = GIGABYTE_SUFFIX; } else if(length >= MEGABYTE) { number = (float) length / (float) MEGABYTE; suffix = MEGABYTE_SUFFIX; } else if(length >= KILOBYTE) { number = (float) length / (float) KILOBYTE; suffix = KILOBYTE_SUFFIX; } else { // Don't need to do anything fancy if the file is smaller than a kilobyte return length + BYTE_SUFFIX; } // 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. String number_str = Float.toString(number); char number_char[] = number_str.toCharArray(); int pos = 0; // Print the characters up to the '.' while(number_char != null && pos < number_char.length && number_char[pos] != '.') { result.append(number_char[pos]); pos++; } if(pos < number_char.length) { // Print the '.' and at most two characters after it result.append(number_char[pos]); pos++; for(int i = 0; i < 2 && pos < number_char.length; i++, pos++) { result.append(number_char[pos]); } // Search through the remaining string for 'E' while(pos < number_char.length && number_char[pos] != 'E') { pos++; } // If we still have string then we found an E. Copy the remaining string. while(pos < number_char.length) { result.append(number_char[pos]); pos++; } } // Add suffix result.append(suffix); // Done return result.toString(); } /** This method formats a given string, using HTML markup, so its width does not exceed the given width and its appearance if justified. * @param text The String requiring formatting. * @param width The maximum width per line as an int. * @return A String formatted so as to have no line longer than the specified width. * 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. */ static public String formatHTMLWidth(String text, int width) { if(text == null) { return "Error"; } HTMLStringTokenizer html = new HTMLStringTokenizer(text); int current_width = 0; int threshold = width / 2; Stack lines = new Stack(); String line = ""; while(html.hasMoreTokens()) { String token = html.nextToken(); while(token != null) { if(html.isTag()) { // Insert smart HTML tag code here. token = null; } else { // If the token is bigger than two thirds width, before we've even started break it down. if(current_width + 1 + token.length() > width && token.length() > threshold) { if(width == current_width) { lines.push(line); line = token; current_width = token.length(); } else { String prefix = token.substring(0, width - 1 - current_width); token = token.substring(prefix.length()); if(current_width == 0) { line = line + prefix; } else { line = line + " " + prefix; } lines.push(line); line = ""; current_width = 0; } } // If adding the next token would push us over the maximum line width. else if(current_width + 1 + token.length() > width) { lines.push(line); line = token; current_width = token.length(); token = null; } // Otherwise we should be able to just add the token, give or take. else { if(current_width == 0) { line = line + token; current_width = token.length(); } else { // Special case for standard punctuation which may exist after a tag like so: // My name is Slim Shady. <-- Annoying punctuation. if(token.equals(".") || token.equals(",") || token.equals("!") || token.equals("?")) { line = line + token; current_width = current_width + 1; } else { line = line + " " + token; current_width = current_width + 1 + token.length(); } } token = null; } } } } String result = line; while(!lines.empty()) { result = (String)lines.pop() + "
" + result; } // Replace ' ' with " " boolean tag = false; int pos = 0; while(pos < result.length()) { if(result.charAt(pos) == '<') { tag = true; } else if(result.charAt(pos) == '>') { tag = false; } else if(result.charAt(pos) == ' ' && !tag) { String prefix = result.substring(0, pos); String suffix = result.substring(pos + 1); result = prefix + " " + suffix; } pos++; } result = "" + result + ""; return result; } /** Format the given filename path string so that it is no longer than the given width. If it is wider replace starting directories with ... * @param key The key String used to retrieve a phrase from the dictionary for this item. * @param raw The raw filename path String. * @param width The maximum width as an int. * @return A path String no longer than width. */ static public String formatPath(String key, String raw, int width) { JLabel label = new JLabel(Dictionary.get(key, raw)); int position = -1; while(label.getPreferredSize().width > width && (position = raw.indexOf(File.separator)) != -1) { raw = "..." + raw.substring(position + 1); label.setText(Dictionary.get(key, raw)); } if(raw.indexOf(File.separator) == -1 && raw.startsWith("...")) { raw = raw.substring(3); } return raw; } /** Builds the cache dir by appending the user path and 'cache'. * @return a File representing the path to the private file cache within the current collection. */ public static File getCacheDir() { return new File(getGLIUserFolder(), StaticStrings.CACHE_FOLDER); } /** Method which constructs the configuration file given a certain collection. * @param col_dir The location of the collection directory as a String. * @return The location of the given collections configuration file, also as a String. */ static public String getConfigFile(String col_dir) { return col_dir + CONFIG_FILE; } static public String getDateString() { Calendar current = Calendar.getInstance(); String day_name = null; switch(current.get(Calendar.DAY_OF_WEEK)) { case Calendar.MONDAY: day_name = "Dates.Mon"; break; case Calendar.TUESDAY: day_name = "Dates.Tue"; break; case Calendar.WEDNESDAY: day_name = "Dates.Wed"; break; case Calendar.THURSDAY: day_name = "Dates.Thu"; break; case Calendar.FRIDAY: day_name = "Dates.Fri"; break; case Calendar.SATURDAY: day_name = "Dates.Sat"; break; case Calendar.SUNDAY: day_name = "Dates.Sun"; break; default: day_name = ""; } String month_name = null; switch(current.get(Calendar.MONTH)) { case Calendar.JANUARY: month_name = "Dates.Jan"; break; case Calendar.FEBRUARY: month_name = "Dates.Feb"; break; case Calendar.MARCH: month_name = "Dates.Mar"; break; case Calendar.APRIL: month_name = "Dates.Apr"; break; case Calendar.MAY: month_name = "Dates.May"; break; case Calendar.JUNE: month_name = "Dates.Jun"; break; case Calendar.JULY: month_name = "Dates.Jul"; break; case Calendar.AUGUST: month_name = "Dates.Aug"; break; case Calendar.SEPTEMBER: month_name = "Dates.Sep"; break; case Calendar.OCTOBER: month_name = "Dates.Oct"; break; case Calendar.NOVEMBER: month_name = "Dates.Nov"; break; case Calendar.DECEMBER: month_name = "Dates.Dec"; break; default: month_name = ""; } int day = current.get(Calendar.DAY_OF_MONTH); int hour = current.get(Calendar.HOUR_OF_DAY); int minute = current.get(Calendar.MINUTE); int second = current.get(Calendar.SECOND); int year = current.get(Calendar.YEAR); 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); } static final private String APPLICATION_DATA_FOLDER = "Application Data"; static final private String UNIX_GLI_CONFIG_FOLDER = ".gli"; static final private String USER_HOME_PROPERTY = "user.home"; static final private String WIN_GLI_CONFIG_FOLDER = "Greenstone" + File.separator + "GLI"; static public File getGLIUserFolder() { if (Utility.isWindows()) { return new File(System.getProperty(USER_HOME_PROPERTY) + File.separator + APPLICATION_DATA_FOLDER + File.separator + WIN_GLI_CONFIG_FOLDER + File.separator); } else { return new File(System.getProperty(USER_HOME_PROPERTY) + File.separator + UNIX_GLI_CONFIG_FOLDER + File.separator); } } /** Retrieve the full file path to the help index xml file. * @return the full path as a String */ static public String getHelpFolder() { String help_folder = "help/" + Configuration.getLanguage() + "/"; // Try in the JAR/classes directory first URL help_folder_url = base.getResource("/" + help_folder); if (help_folder_url != null) { return help_folder; } // Look in the base directory next File help_folder_file = new File(help_folder); if (help_folder_file.exists()) { return help_folder; } // Resort to English return "help/" + StaticStrings.ENGLISH_LANGUAGE_STR + "/"; } /** Method to retrieve an image icon with the given filename found in classpath or the resouces directory. * @return The specified ImageIcon, or an error image replacement if no such images exists. */ static public ImageIcon getImage(String filename) { return getImage(filename, false); } static public ImageIcon getImage(String filename, boolean wait_until_complete) { ImageIcon image = null; try { image = new ImageIcon(base.getResource("/images/" + Dictionary.get("Version") + "/" + filename)); } catch(NullPointerException exception) { image = new ImageIcon(base.getResource("/images/" + filename)); } if(image == null) { image = ERROR_ICON; } if(wait_until_complete) { int load_status; do { load_status = image.getImageLoadStatus(); } while(load_status != MediaTracker.ABORTED && load_status != MediaTracker.ERRORED && load_status != MediaTracker.COMPLETE); } return image; } /** Method which constructs the import directory given a certain collection. * @param col_dir The location of the collection directory as a String. * @return The location of the given collections import directory, also as a String. */ public static String getImportDir(String col_dir) { return col_dir + IMPORT_DIR; } /** Method which constructs the log directory given a certain collection. * @param col_dir The location of the collection directory as a String. * @return The location of the given collections log directory, also as a String. */ public static String getLogDir(String col_dir) { if(col_dir != null) { return col_dir + LOG_DIR; } else { return getGLIUserFolder().getAbsolutePath() + File.separator + LOG_DIR; } } /** Determine this machines name. * @return The name as a String. */ static public String getMachineName() { try { return InetAddress.getLocalHost().getHostName(); } catch(UnknownHostException ex) { } return "Unknown Machine"; } static public void extractFromJar(String filename, String dst_dir, boolean must_be_present) { try { // setup input stream for slurping out file InputStream fis = base.getResourceAsStream("/"+filename); BufferedInputStream fbis = new BufferedInputStream(fis); DataInputStream fdbis = new DataInputStream(fbis); // set up output stream for writing to disk String ofname = dst_dir + filename; FileOutputStream fos = new FileOutputStream(ofname); BufferedOutputStream bfos = new BufferedOutputStream(fos); byte[] buf = new byte[1024]; int len; int total_bytes = 0; while ((len = fdbis.read(buf)) >= 0) { bfos.write(buf,0,len); total_bytes += len; } fdbis.close(); bfos.close(); } catch (Exception error) { if (must_be_present) { error.printStackTrace(); } } } /** Method which unzips a given metadata resoure * @param zip_fname The name of the zip file as a String. * @param dst_dir The destination directory for unzipping, also as a String. * @param use_classloader Used to determine whether or not to look in resource bundle. */ static public void unzipFromJar(String jar_zip_fname, String dst_dir) { File file = null; if (!dst_dir.endsWith(File.separator)) { dst_dir += File.separator; } extractFromJar(jar_zip_fname,dst_dir,true); String zip_ofname = dst_dir + jar_zip_fname; File zip_file = new File(zip_ofname); try { ZipFile zipfile = new ZipFile(zip_file); Enumeration e = zipfile.entries(); while (e.hasMoreElements()) { ZipEntry zipentry = (ZipEntry) e.nextElement(); String zentryname = dst_dir + zipentry.getName(); DebugStream.println(" Unzipping: " + zentryname); if (zipentry.isDirectory()) { // Create named directory, if it doesn't already exist File zip_entry_file = new File(zentryname); if (!zip_entry_file.exists() && !zip_entry_file.mkdirs()) { System.err.println("Error: unable to create directory " + zip_entry_file); } } else { // Write out file to disk // set up input stream InputStream zis = zipfile.getInputStream(zipentry); BufferedInputStream bzis = new BufferedInputStream(zis); DataInputStream dbzis = new DataInputStream(bzis); // set up output stream FileOutputStream fzos = new FileOutputStream(zentryname); BufferedOutputStream bfzos = new BufferedOutputStream(fzos); byte[] buf = new byte[1024]; int len; while ((len = dbzis.read(buf)) >= 0) { bfzos.write(buf,0,len); } dbzis.close(); bfzos.close(); } } } catch (ZipException error) { System.err.println("Error: Unable to open '"+zip_file.getAbsolutePath()+"'"); DebugStream.printStackTrace(error); } catch (Exception error) { error.printStackTrace(); } } static protected String unixStylePath(String path) { String unix_path = path.replace('\\','/'); return unix_path; } /* Method to handle zipping up of a file. Called by zipup and dirFunc. @param zos the zip output stream, as a ZipOutputStream @param file_path the String containing the path to the file/directory tozip up @param prefix_strip the int used to substring the file_path @param source the GShell that is calling this method, so that we can check to see if the process has been cancelled. null if GShell is not the calling object. @param accept_expr a String containing a regular expression of files to include in the archive. All other files will be excluded. @param reject_expr a String containing a regular expression of files not to include in the archive. @return boolean @see dirFunc @see zipup */ static protected boolean zipFunc (ZipOutputStream zos, String file_path, int prefix_strip, GShell source, boolean encountered_file, String accept_expr, String reject_expr) { String new_file_path = file_path; if((reject_expr != "") && (file_path.matches(reject_expr))) { // matches reject expression //DebugStream.println("File \'" + file_path + "\' matches the reject expression \'" + reject_expr + "\'"); return encountered_file; } if ((accept_expr != "") && (!file_path.matches(accept_expr))) { // does not match accept expression //DebugStream.println("File \'" + file_path + "\' doesn't match accept expression \'" + accept_expr + "\'"); return encountered_file; } //Special case: we only want the metadata. Parse the xml files. if(accept_expr.compareTo(".*doc.xml") == 0) { DebugStream.println("Only want to get metadata"); Document old_document = XMLTools.parseXMLFile(new File(file_path)); NodeList content = old_document.getElementsByTagName("Content"); try { for(int i=content.getLength()-1; i >= 0; i--) { //Remove all content - just leave the metadata. content.item(i).getParentNode().removeChild(content.item(i)); } } catch (Exception ex) { ex.printStackTrace(); } new_file_path = file_path.substring(0, file_path.lastIndexOf(File.separator) + 1) + "new.xml"; //Is there any better way than writing out as a new file, then reading back in?? XMLTools.writeXMLFile(new File(new_file_path), old_document); } // Using try is required because of file io. try { // Exit if pressed cancel. if (source != null && source.hasSignalledStop()) { return false; } // Create a Zip Entry and put it into the archive (no data yet). // Strip off col_dir prefix String zip_path = file_path.substring(prefix_strip); // Zip files use '/' for directory separator String unix_style_path = unixStylePath(zip_path); ZipEntry fileEntry = new ZipEntry(unix_style_path); zos.putNextEntry(fileEntry); // Create a file input stream and a buffered input stream. FileInputStream fis = new FileInputStream(new_file_path); BufferedInputStream bis = new BufferedInputStream(fis); // Create a byte array object named data and declare byte count variable. byte[] data = new byte[1024]; int byteCount; // Create a loop that reads from the buffered input stream and writes // to the zip output stream until the bis has been entirely read. while ((byteCount = bis.read(data, 0, 1024)) > -1) { //Check for cancell if(source != null) { if(source.hasSignalledStop()) { break; } } zos.write(data, 0, byteCount); } encountered_file = true; } catch (IOException e) { e.printStackTrace(); } DebugStream.println("Zipping up: " + file_path); return encountered_file; } /* Method to handle ziping up of a directory. @param zos @param dir_name @param prefix_strip @param source @param encountered_file ??What's this?? @param accept_expr @param reject_expr @see zipup @see zipFunc */ static protected boolean dirFunc (ZipOutputStream zos, String dir_name, int prefix_strip, GShell source, boolean encountered_file, String accept_expr, String reject_expr) { File dirObj = new File(dir_name); if (dirObj.exists() == true) { if (dirObj.isDirectory() == true) { // Create an array of File objects, one for each file or directory in dirObj. File [] fileList = dirObj.listFiles(); // Loop through File array and display. for (int i = 0; i < fileList.length; i++) { if(source != null && source.hasSignalledStop()) { break; } File file = fileList[i]; if (file.isDirectory()) { String dir_path = file.getPath(); String zip_path = dir_path.substring(prefix_strip); // Zip files use '/' for directory separator String unix_style_path = unixStylePath(zip_path+File.separator); ZipEntry dirEntry = new ZipEntry(unix_style_path); try { zos.putNextEntry(dirEntry); } catch (IOException e) { e.printStackTrace(); } encountered_file = dirFunc(zos, dir_path, prefix_strip, source, encountered_file, accept_expr, reject_expr); } else if (file.isFile()) { // Call the zipFunc function String file_path = fileList[i].getPath(); encountered_file = zipFunc(zos,file_path,prefix_strip, source, encountered_file, accept_expr, reject_expr); } } } else { System.err.println (dir_name+" is not a directory."); } } else { System.err.println ("Directory "+dir_name+" does not exist."); } return encountered_file; } /** Method to zip up a given file or directory @param col_dir @param col_name @param dir_or_file @param source @param filter @see zipFunc @see dirFunc */ static public boolean zipup(String col_dir, String col_name, String dir_or_file, GShell source, String accept_expr, String reject_expr) { int prefix_strip = col_dir.length(); boolean encountered_file = false; String zip_fname = col_dir + col_name + ".zip"; String zip_dir_or_file = col_dir + col_name + File.separator + dir_or_file; File zip_dof = new File(zip_dir_or_file); try { FileOutputStream fos = new FileOutputStream(zip_fname); ZipOutputStream zos = new ZipOutputStream(fos); if (zip_dof.exists()) { if (zip_dof.isDirectory()) { String zip_dir = zip_dir_or_file; encountered_file = dirFunc(zos, zip_dir, prefix_strip, source, encountered_file, accept_expr, reject_expr); } else { String zip_full_file = zip_dir_or_file; String zip_path = zip_full_file.substring(prefix_strip); for (int i=1; i= 0) { bfzos.write(buf,0,len); } dbzis.close(); bfzos.close(); } } } catch (ZipException error) { System.err.println("Error: Unable to open '"+zip_fname+"'"); System.err.println("This maybe caused by the zip file being empty."); DebugStream.printStackTrace(error); } catch (Exception error) { error.printStackTrace(); } } static public String getSitesDir(String gsdl3_path) { return gsdl3_path + File.separator + "web" + File.separator + "sites" + File.separator; } /** returns the path to the greenstone version of wget */ static public String getWGetPath(String gsdl_path) { if (isWindows()) { return gsdl_path + "bin" + File.separator + "windows" + File.separator +"wget.exe"; } // is it the same for macs?? return gsdl_path + "bin" + File.separator + "linux" + File.separator + "wget"; } static public void initImages(Object base_object) { base = base_object.getClass(); BLANK_ICON = new ImageIcon(base.getResource("/images/blank.gif")); ERROR_ICON = new ImageIcon(base.getResource("/images/error.gif")); HELP_ICON = new ImageIcon(base.getResource("/images/help.gif")); } /** Method to determine if the host system is MacOS based. * @return a boolean which is true if the platform is MacOS, false otherwise */ public static boolean isMac() { Properties props = System.getProperties(); String os_name = props.getProperty("os.name",""); if(os_name.startsWith("Mac OS")) { return true; } return false; } /** Method to determine if the host system is Microsoft Windows based. * @return A boolean which is true if the platform is Windows, false otherwise. */ public static boolean isWindows() { Properties props = System.getProperties(); String os_name = props.getProperty("os.name",""); if(os_name.startsWith("Windows")) { return true; } return false; } public static boolean isWindows9x() { Properties props = System.getProperties(); String os_name = props.getProperty("os.name",""); if(os_name.startsWith("Windows") && os_name.indexOf("9") != -1) { return true; } return false; } /** Takes a string and a desired length and pads out the string to the length by adding spaces to the left. * @param str The target String that needs to be padded. * @param length The desired length of the string as an int. * @return A String made from appending space characters with the string until it has a length equal to length. */ static private String pad(String str_raw, int length, char fill, boolean end) { StringBuffer str = new StringBuffer(str_raw); while(str.length() < length) { if(end) { str.insert(0, fill); } else { str.append(fill); } } return str.toString(); } /** 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. */ static public Document parse(String filename, boolean use_classloader) { // Try the class loader if desired (for the applet JAR file) if (use_classloader) { InputStream is = base.getResourceAsStream("/" + filename); if (is != null) { return XMLTools.parseXML(is); } } // Try the file outside the classes directory return XMLTools.parseXMLFile(new File(filename)); } static public StringBuffer readXMLStream(InputStream input_stream) { StringBuffer xml = new StringBuffer(""); try { InputStreamReader isr = new InputStreamReader(input_stream, "UTF-8"); BufferedReader buffered_in = new BufferedReader(isr); String line = ""; boolean xml_content = false; while((line = buffered_in.readLine()) != null) { if(xml_content) { xml.append(line); xml.append("\n"); } else if(line.trim().startsWith("