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

Last change on this file since 13584 was 13535, checked in by mdewsnip, 17 years ago

Removed some unused functions.

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