source: tags/gsdl-2_70u-distribution/gli/src/org/greenstone/gatherer/util/Utility.java@ 11745

Last change on this file since 11745 was 11745, checked in by (none), 18 years ago

This commit was manufactured by cvs2svn to create tag
'gsdl-2_70u-distribution'.

  • Property svn:keywords set to Author Date Id Revision
File size: 15.8 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 */
37
38package org.greenstone.gatherer.util;
39
40
41// Don't even think about adding import java.awt.* here!
42// The functions in this class should not use any graphical classes. Put your function somewhere else buster!
43import java.io.*;
44import java.net.*;
45import java.util.*;
46// Don't even think about adding import javax.swing.* here!
47// The functions in this class should not use any graphical classes. Put your function somewhere else buster!
48import org.greenstone.gatherer.Dictionary;
49// Don't even think about adding import org.greenstone.gatherer.Gatherer in here!
50// The functions in this class should be independent of the Gatherer class. Put your function somewhere else buster!
51
52
53/** To provide a library of common methods, in a static context, for use in the Gatherer.
54 * @author John Thompson, Greenstone Digital Library, University of Waikato
55 * @version 2.3b
56 */
57public class Utility
58{
59 /** The size of the io buffer, in bytes. */
60 static final public int BUFFER_SIZE = 1024;
61 static final public String CFG_CLASSIFY = "classify";
62 static final public String CFG_CLASSIFY_BUTTONNAME = "-buttonname";
63 static final public String CFG_CLASSIFY_HFILE = "-hfile";
64 static final public String CFG_CLASSIFY_METADATA = "-metadata";
65 static final public String CFG_CLASSIFY_SORT = "-sort";
66 static final public String CFG_FORMAT = "format";
67 static final public String COLLECTION_TREE = "Collection";
68 /** Definition of an important directory name, in this case the file the collection configuration is expect to be in. */
69 static final public String CONFIG_FILE = "etc" + File.separator + "collect.cfg";
70 static final public String GLI_EXTENSION = ".col";
71
72 /** Definition of an important directory name, in this case the import directory for the collection. */
73 static final public String IMPORT_DIR = "import" + File.separator;
74 /** Definition of an important directory name, in this case the macros directory for the collection. */
75 static final public String MACROS_DIR = "macros" + File.separator;
76 /** Definition of an important directory name, in this case the location of the expected collection metadata sets.. */
77 static final public String META_DIR = "metadata" + File.separator; // Col. Copy
78 /** The default name of the perl executable under unix. */
79 static final public String PERL_EXECUTABLE_UNIX = "perl";
80 /** The default name of the perl executable under windows. */
81 static final public String PERL_EXECUTABLE_WINDOWS = "Perl.exe";
82 /** The name of the GLI. */
83 static final public String PROGRAM_NAME = "Greenstone Librarian Interface";
84 /** The current version of the GLI. */
85 static final public String PROGRAM_VERSION = "v2.70u";
86 static final public String WORKSPACE_TREE = "Workspace";
87
88
89 /**
90 * Delete a file or directory
91 * @param file The <strong>File</strong> you want to delete.
92 * @return A <i>boolean</i> which is <i>true</i> if the file specified was successfully deleted, <i>false</i> otherwise.
93 */
94 static public boolean delete(File file)
95 {
96 // Nothing to do if it doesn't exist
97 if (!file.exists()) {
98 return true;
99 }
100
101 return deleteInternal(file);
102 }
103
104
105 /** Convenience function. */
106 static public boolean delete(String filename)
107 {
108 return delete(new File(filename));
109 }
110
111
112 /** In Java you have to make sure a directory is empty before you delete it, so recursively delete. */
113 static private boolean deleteInternal(File file)
114 {
115 // If file is a directory, we have to recursively delete its contents first
116 if (file.isDirectory()) {
117 File files[] = file.listFiles();
118 for (int i = 0; i < files.length; i++) {
119 if (deleteInternal(files[i]) == false) {
120 System.err.println("Error: Could not delete folder " + file);
121 return false;
122 }
123 }
124 }
125
126 // Delete file
127 if (file.delete() == false) {
128 System.err.println("Error: Could not delete file " + file);
129 return false;
130 }
131
132 return true;
133 }
134
135
136 /** Convert a long, detailing the length of a file in bytes, into a nice human readable string using b, kb, Mb and Gb. */
137 static final public String BYTE_SUFFIX = " b";
138 static final public long GIGABYTE = 1024000000l;
139 static final public String GIGABYTE_SUFFIX = " Gb";
140 static final public long KILOBYTE = 1024l;
141 static final public String KILOBYTE_SUFFIX = " kb";
142 static final public long MEGABYTE = 1024000l;
143 static final public String MEGABYTE_SUFFIX = " Mb";
144 static final public String formatFileLength(long length) {
145 StringBuffer result = new StringBuffer("");
146 float number = 0f;
147 String suffix = null;
148 // Determine the floating point number and the suffix (radix) used.
149 if(length >= GIGABYTE) {
150 number = (float) length / (float) GIGABYTE;
151 suffix = GIGABYTE_SUFFIX;
152 }
153 else if(length >= MEGABYTE) {
154 number = (float) length / (float) MEGABYTE;
155 suffix = MEGABYTE_SUFFIX;
156 }
157 else if(length >= KILOBYTE) {
158 number = (float) length / (float) KILOBYTE;
159 suffix = KILOBYTE_SUFFIX;
160 }
161 else {
162 // Don't need to do anything fancy if the file is smaller than a kilobyte
163 return length + BYTE_SUFFIX;
164 }
165 // 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.
166 String number_str = Float.toString(number);
167 char number_char[] = number_str.toCharArray();
168 int pos = 0;
169 // Print the characters up to the '.'
170 while(number_char != null && pos < number_char.length && number_char[pos] != '.') {
171 result.append(number_char[pos]);
172 pos++;
173 }
174 if(pos < number_char.length) {
175 // Print the '.' and at most two characters after it
176 result.append(number_char[pos]);
177 pos++;
178 for(int i = 0; i < 2 && pos < number_char.length; i++, pos++) {
179 result.append(number_char[pos]);
180 }
181 // Search through the remaining string for 'E'
182 while(pos < number_char.length && number_char[pos] != 'E') {
183 pos++;
184 }
185 // If we still have string then we found an E. Copy the remaining string.
186 while(pos < number_char.length) {
187 result.append(number_char[pos]);
188 pos++;
189 }
190 }
191 // Add suffix
192 result.append(suffix);
193 // Done
194 return result.toString();
195 }
196
197 /** This method formats a given string, using HTML markup, so its width does not exceed the given width and its appearance if justified.
198 * @param text The <strong>String</strong> requiring formatting.
199 * @param width The maximum width per line as an <i>int</i>.
200 * @return A <strong>String</strong> formatted so as to have no line longer than the specified width.
201 * 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.
202 */
203 static public String formatHTMLWidth(String text, int width) {
204 if(text == null) {
205 return "Error";
206 }
207 HTMLStringTokenizer html = new HTMLStringTokenizer(text);
208 int current_width = 0;
209 int threshold = width / 2;
210 Stack lines = new Stack();
211 String line = "";
212 while(html.hasMoreTokens()) {
213 String token = html.nextToken();
214 while(token != null) {
215 if(html.isTag()) {
216 // Insert smart HTML tag code here.
217 token = null;
218 }
219 else {
220 // If the token is bigger than two thirds width, before we've even started break it down.
221 if(current_width + 1 + token.length() > width && token.length() > threshold) {
222 if(width == current_width) {
223 lines.push(line);
224 line = token;
225 current_width = token.length();
226 }
227 else {
228 String prefix = token.substring(0, width - 1 - current_width);
229 token = token.substring(prefix.length());
230 if(current_width == 0) {
231 line = line + prefix;
232 }
233 else {
234 line = line + " " + prefix;
235 }
236 lines.push(line);
237 line = "";
238 current_width = 0;
239 }
240 }
241 // If adding the next token would push us over the maximum line width.
242 else if(current_width + 1 + token.length() > width) {
243 lines.push(line);
244 line = token;
245 current_width = token.length();
246 token = null;
247 }
248 // Otherwise we should be able to just add the token, give or take.
249 else {
250 if(current_width == 0) {
251 line = line + token;
252 current_width = token.length();
253 }
254 else {
255 // Special case for standard punctuation which may exist after a tag like so:
256 // My name is <scratchy>Slim Shady</scratchy>. <-- Annoying punctuation.
257 if(token.equals(".") || token.equals(",") || token.equals("!") || token.equals("?")) {
258 line = line + token;
259 current_width = current_width + 1;
260 }
261 else {
262 line = line + " " + token;
263 current_width = current_width + 1 + token.length();
264 }
265 }
266 token = null;
267 }
268 }
269 }
270 }
271 String result = line;
272 while(!lines.empty()) {
273 result = (String)lines.pop() + "<BR>" + result;
274 }
275 // Replace ' ' with "&nbsp;"
276 boolean tag = false;
277 int pos = 0;
278 while(pos < result.length()) {
279 if(result.charAt(pos) == '<') {
280 tag = true;
281 }
282 else if(result.charAt(pos) == '>') {
283 tag = false;
284 }
285 else if(result.charAt(pos) == ' ' && !tag) {
286 String prefix = result.substring(0, pos);
287 String suffix = result.substring(pos + 1);
288 result = prefix + "&nbsp;" + suffix;
289 }
290 pos++;
291 }
292 result = "<HTML>" + result + "</HTML>";
293 return result;
294 }
295
296
297 static public String getDateString() {
298 Calendar current = Calendar.getInstance();
299 String day_name = null;
300 switch(current.get(Calendar.DAY_OF_WEEK)) {
301 case Calendar.MONDAY: day_name = "Dates.Mon"; break;
302 case Calendar.TUESDAY: day_name = "Dates.Tue"; break;
303 case Calendar.WEDNESDAY: day_name = "Dates.Wed"; break;
304 case Calendar.THURSDAY: day_name = "Dates.Thu"; break;
305 case Calendar.FRIDAY: day_name = "Dates.Fri"; break;
306 case Calendar.SATURDAY: day_name = "Dates.Sat"; break;
307 case Calendar.SUNDAY: day_name = "Dates.Sun"; break;
308 default: day_name = "";
309 }
310 String month_name = null;
311 switch(current.get(Calendar.MONTH)) {
312 case Calendar.JANUARY: month_name = "Dates.Jan"; break;
313 case Calendar.FEBRUARY: month_name = "Dates.Feb"; break;
314 case Calendar.MARCH: month_name = "Dates.Mar"; break;
315 case Calendar.APRIL: month_name = "Dates.Apr"; break;
316 case Calendar.MAY: month_name = "Dates.May"; break;
317 case Calendar.JUNE: month_name = "Dates.Jun"; break;
318 case Calendar.JULY: month_name = "Dates.Jul"; break;
319 case Calendar.AUGUST: month_name = "Dates.Aug"; break;
320 case Calendar.SEPTEMBER: month_name = "Dates.Sep"; break;
321 case Calendar.OCTOBER: month_name = "Dates.Oct"; break;
322 case Calendar.NOVEMBER: month_name = "Dates.Nov"; break;
323 case Calendar.DECEMBER: month_name = "Dates.Dec"; break;
324 default: month_name = "";
325 }
326 int day = current.get(Calendar.DAY_OF_MONTH);
327 int hour = current.get(Calendar.HOUR_OF_DAY);
328 int minute = current.get(Calendar.MINUTE);
329 int second = current.get(Calendar.SECOND);
330 int year = current.get(Calendar.YEAR);
331
332 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);
333 }
334
335
336 /** Determine this machines name.
337 * @return The name as a <strong>String</strong>.
338 */
339 static public String getMachineName() {
340 try {
341 return InetAddress.getLocalHost().getHostName();
342 }
343 catch(UnknownHostException ex) {
344 }
345 return "Unknown Machine";
346 }
347
348
349 static public String getSitesDir(String gsdl3_path) {
350 return gsdl3_path + "sites" + File.separator;
351
352 }
353
354
355 /** Method to determine if the host system is MacOS based.
356 * @return a boolean which is true if the platform is MacOS, false otherwise
357 */
358 public static boolean isMac() {
359 Properties props = System.getProperties();
360 String os_name = props.getProperty("os.name","");
361 if(os_name.startsWith("Mac OS")) {
362 return true;
363 }
364 return false;
365 }
366
367
368 /** Method to determine if the host system is Microsoft Windows based.
369 * @return A <i>boolean</i> which is <i>true</i> if the platform is Windows, <i>false</i> otherwise.
370 */
371 public static boolean isWindows() {
372 Properties props = System.getProperties();
373 String os_name = props.getProperty("os.name","");
374 if(os_name.startsWith("Windows")) {
375 return true;
376 }
377 return false;
378 }
379
380 public static boolean isWindows9x() {
381 Properties props = System.getProperties();
382 String os_name = props.getProperty("os.name","");
383 if(os_name.startsWith("Windows") && os_name.indexOf("9") != -1) {
384 return true;
385 }
386 return false;
387 }
388 /** Takes a string and a desired length and pads out the string to the length by adding spaces to the left.
389 * @param str The target <strong>String</strong> that needs to be padded.
390 * @param length The desired length of the string as an <i>int</i>.
391 * @return A <strong>String</strong> made from appending space characters with the string until it has a length equal to length.
392 */
393 static private String pad(String str_raw, int length, char fill, boolean end) {
394 StringBuffer str = new StringBuffer(str_raw);
395 while(str.length() < length) {
396 if(end) {
397 str.insert(0, fill);
398 }
399 else {
400 str.append(fill);
401 }
402 }
403 return str.toString();
404 }
405
406
407 static public StringBuffer readXMLStream(InputStream input_stream)
408 {
409 StringBuffer xml = new StringBuffer("");
410
411 try {
412 InputStreamReader isr = new InputStreamReader(input_stream, "UTF-8");
413 BufferedReader buffered_in = new BufferedReader(isr);
414
415 String line = "";
416 boolean xml_content = false;
417 while((line = buffered_in.readLine()) != null) {
418 if(xml_content) {
419 xml.append(line);
420 xml.append("\n");
421 }
422 else if(line.trim().startsWith("<?xml")) {
423 xml_content = true;
424 xml.append(line);
425 xml.append("\n");
426 }
427 }
428 buffered_in = null;
429 }
430 catch (Exception error) {
431 System.err.println("Failed when trying to parse XML stream");
432 error.printStackTrace();
433 }
434
435 return xml;
436 }
437
438
439 /** I think this works a bit better on Unicode strings. */
440 static public String stripNL(String raw_string)
441 {
442 String stripped_string = new String();
443 for (int i = 0; i < raw_string.length(); i++) {
444 char raw_character = raw_string.charAt(i);
445 if (raw_character != '\n' && raw_character != '\t') {
446 stripped_string = stripped_string + raw_character;
447 }
448 }
449 return stripped_string;
450 }
451}
Note: See TracBrowser for help on using the repository browser.