View Javadoc

1   // BSD License (http://www.galagosearch.org/license)
2   package org.galagosearch.tupleflow;
3   
4   import java.io.BufferedReader;
5   import java.io.File;
6   import java.io.FileInputStream;
7   import java.io.FileOutputStream;
8   import java.io.FileReader;
9   import java.io.IOException;
10  import java.io.InputStream;
11  import java.io.InputStreamReader;
12  import java.io.OutputStream;
13  import java.io.UnsupportedEncodingException;
14  import java.lang.reflect.InvocationTargetException;
15  import java.lang.reflect.Method;
16  import java.net.ServerSocket;
17  import java.security.MessageDigest;
18  import java.util.ArrayList;
19  import java.util.HashSet;
20  import java.util.logging.Logger;
21  import org.galagosearch.tupleflow.execution.Step;
22  
23  /***
24   * Lots of static methods here that have broad use.
25   *
26   * @author trevor
27   */
28  public class Utility {
29      /***
30       * Builds a simple Sorter step that can be added to a TupleFlow stage.
31       *
32       * @param sortOrder An order object representing how and what to sort.
33       * @return a Step object that can be added to a TupleFlow Stage.
34       */
35      public static Step getSorter(Order sortOrder) {
36          Parameters p = new Parameters();
37          p.add("class", sortOrder.getOrderedClass().getName());
38          p.add("order", Utility.join(sortOrder.getOrderSpec()));
39          return new Step(Sorter.class, p);
40      }
41      
42      /***
43       * Finds a free port to listen on.  Useful for starting up internal web servers.
44       * (copied from chaoticjava.com)
45       */
46      public static int getFreePort() throws IOException {
47        ServerSocket server = new ServerSocket(0);
48        int port = server.getLocalPort();
49        server.close();
50        return port;
51      }
52  
53      public static boolean isInteger(String s) {
54          try {
55              Integer.parseInt(s);
56              return true;
57          } catch (Exception e) {
58              return false;
59          }
60      }
61  
62      public static String wrap(String t) {
63          int start = 0;
64          StringBuilder result = new StringBuilder();
65  
66          while (t.length() > start + 50) {
67              int end = t.indexOf(" ", start + 50);
68  
69              if (end < 0) {
70                  break;
71              }
72              result.append(t, start, end);
73              result.append('\n');
74              start = end + 1;
75          }
76  
77          result.append(t.substring(start));
78          return result.toString();
79      }
80  
81      public static String escape(String raw) {
82          StringBuilder builder = new StringBuilder();
83  
84          for (int i = 0; i < raw.length(); i++) {
85              char c = raw.charAt(i);
86  
87              if (c == '"') {
88                  builder.append("&quot;");
89              } else if (c == '&') {
90                  builder.append("&amp;");
91              } else if (c == '<') {
92                  builder.append("&gt;");
93              } else if (c == '>') {
94                  builder.append("&lt;");
95              } else if (c <= 127) {
96                  builder.append(c);
97              } else {
98                  int unsigned = ((int) c) & 0xFFFF;
99  
100                 builder.append("&#");
101                 builder.append(unsigned);
102                 builder.append(";");
103             }
104         }
105 
106         return builder.toString();
107     }
108 
109     public static String strip(String source, String suffix) {
110         if (source.endsWith(suffix)) {
111             return source.substring(0, source.length() - suffix.length());
112         }
113 
114         return null;
115     }
116 
117     public static String makeString(byte[] word) {
118         try {
119             return new String(word, "UTF-8");
120         } catch (UnsupportedEncodingException e) {
121             throw new RuntimeException("UTF-8 is not supported by your Java Virtual Machine.");
122         }
123     }
124 
125     public static byte[] makeBytes(String word) {
126         try {
127             return word.getBytes("UTF-8");
128         } catch (UnsupportedEncodingException e) {
129             throw new RuntimeException("UTF-8 is not supported by your Java Virtual Machine.");
130         }
131     }
132 
133     /***
134      * For an array master, returns
135      * an array containing the last master.length-index elements.
136      */
137     public static String[] subarray(String[] master, int index) {
138         if (master.length <= index) {
139             return new String[0];
140         } else {
141             String[] sub = new String[master.length - index];
142             System.arraycopy(master, index, sub, 0, sub.length);
143             return sub;
144         }
145     }
146 
147     /***
148      * Returns a string containing all the elements of args, space delimited.
149      */
150     public static String join(String[] args, String delimiter) {
151         String output = "";
152         StringBuilder builder = new StringBuilder();
153 
154         for (String arg : args) {
155             if (builder.length() > 0) {
156                 builder.append(delimiter);
157             }
158             builder.append(arg);
159         }
160 
161         return builder.toString();
162     }
163 
164     public static String join(String[] args) {
165         return join(args, " ");
166     }
167 
168     public static String caps(String input) {
169         if (input.length() == 0) {
170             return input;
171         }
172         char first = Character.toUpperCase(input.charAt(0));
173         return "" + first + input.substring(1);
174     }
175 
176     public static String plural(String input) {
177         return input + "s";
178     }
179 
180     public static int compare(int one, int two) {
181         return one - two;
182     }
183 
184     public static int compare(long one, long two) {
185         long result = one - two;
186 
187         if (result > 0) {
188             return 1;
189         }
190         if (result < 0) {
191             return -1;
192         }
193         return 0;
194     }
195 
196     public static int compare(double one, double two) {
197         double result = one - two;
198 
199         if (result > 0) {
200             return 1;
201         }
202         if (result < 0) {
203             return -1;
204         }
205         return 0;
206     }
207 
208     public static int compare(float one, float two) {
209         float result = one - two;
210 
211         if (result > 0) {
212             return 1;
213         }
214         if (result < 0) {
215             return -1;
216         }
217         return 0;
218     }
219 
220     public static int compare(String one, String two) {
221         return one.compareTo(two);
222     }
223 
224     public static int compare(byte[] one, byte[] two) {
225         int sharedLength = Math.min(one.length, two.length);
226 
227         for (int i = 0; i < sharedLength; i++) {
228             int a = ((int) one[i]) & 0xFF;
229             int b = ((int) two[i]) & 0xFF;
230             int result = a - b;
231 
232             if (result < 0) {
233                 return -1;
234             }
235             if (result > 0) {
236                 return 1;
237             }
238         }
239 
240         return one.length - two.length;
241     }
242 
243     public static int hash(byte b) {
244         return ((int) b) & 0xFF;
245     }
246 
247     public static int hash(int i) {
248         return i;
249     }
250 
251     public static int hash(long l) {
252         return (int) l;
253     }
254 
255     public static int hash(double d) {
256         return (int) (d * 100000);
257     }
258 
259     public static int hash(float f) {
260         return (int) (f * 100000);
261     }
262 
263     public static int hash(String s) {
264         return s.hashCode();
265     }
266 
267     public static int hash(byte[] b) {
268         int h = 0;
269         for (int i = 0; i < b.length; i++) {
270             h += 7 * h + b[i];
271         }
272         return h;
273     }
274 
275     public static void deleteDirectory(File directory) throws IOException {
276         for (File sub : directory.listFiles()) {
277             if (sub.isDirectory()) {
278                 deleteDirectory(sub);
279             } else {
280                 sub.delete();
281             }
282         }
283 
284         directory.delete();
285     }
286 
287     public static File createTemporary() throws IOException {
288         return createTemporary(1024 * 1024 * 1024);
289     }
290 
291     public static long getUnixFreeSpace(String pathname) throws IOException {
292         try {
293             // BUGBUG: will not work on windows
294             String[] command = {"df", "-Pk", pathname};
295             Process process = Runtime.getRuntime().exec(command);
296             InputStream procOutput = process.getInputStream();
297             BufferedReader reader = new BufferedReader(new InputStreamReader(procOutput));
298 
299             // skip the first line
300             reader.readLine();
301             String line = reader.readLine();
302             String[] fields = line.split("//s+");
303             reader.close();
304 
305             process.getErrorStream().close();
306             process.getInputStream().close();
307             process.getOutputStream().close();
308             process.waitFor();
309 
310             long freeSpace = Long.parseLong(fields[3]) * 1024;
311             return freeSpace;
312         } catch (InterruptedException ex) {
313             return 0;
314         }
315     }
316 
317     public static long getFreeSpace(String pathname) throws IOException {
318         try {
319             // this will only work in Java 1.6 or later
320             Method m = File.class.getMethod("getUsableSpace");
321             Long result = (Long) m.invoke(new File(pathname));
322             return (long) result;
323         } catch (Exception e) {
324             try {
325                 return getUnixFreeSpace(pathname);
326             } catch(Exception ex) {
327                 return 1024*1024*1024; // 1GB
328             }
329         }
330     }
331 
332     public static File createTemporary(long requiredSpace) throws IOException {
333         // try to find a prefs file for this
334         String homeDirectory = System.getProperty("user.home");
335         File prefsFile = new File(homeDirectory + "/" + ".galagotmp");
336         ArrayList<String> roots = new ArrayList<String>();
337         File temporary = null;
338 
339         if (prefsFile.exists()) {
340             BufferedReader reader = new BufferedReader(new FileReader(prefsFile));
341             String line;
342 
343             while ((line = reader.readLine()) != null) {
344                 roots.add(line.trim());
345             }
346 
347             reader.close();
348         }
349 
350         for (String root : roots) {
351             long freeSpace = getFreeSpace(root);
352 
353             if (freeSpace < requiredSpace) {
354                 continue;
355             }
356             String logString = String.format("Found %6.3fMB >= %6.3fMB left on %s",
357                                              freeSpace / 1048576.0, requiredSpace / 1048576.0, root);
358             Logger.getLogger(Utility.class.toString()).info(logString);
359             temporary = File.createTempFile("tupleflow", "", new File(root));
360             break;
361         }
362 
363         if (temporary == null) {
364             temporary = File.createTempFile("tupleflow", "");
365         }
366 
367         return temporary;
368     }
369 
370     /***
371      * Copies the data from file into the stream.  Note that this method
372      * does not close the stream (in case you want to put more in it).
373      * 
374      * @param file
375      * @param stream
376      * @throws java.io.IOException
377      */
378     public static void copyFileToStream(File file, OutputStream stream) throws IOException {
379         FileInputStream input = new FileInputStream(file);
380         long longLength = file.length();
381         final int fiveMegabytes = 5 * 1024 * 1024;
382 
383         while (longLength > 0) {
384             int chunk = (int) Math.min(longLength, fiveMegabytes);
385             byte[] data = new byte[chunk];
386             input.read(data, 0, chunk);
387             stream.write(data, 0, chunk);
388             longLength -= chunk;
389         }
390 
391         input.close();
392     }
393 
394     /***
395      * Copies the data from the InputStream to a file, then closes both when
396      * finished.
397      * 
398      * @param stream
399      * @param file
400      * @throws java.io.IOException
401      */
402     public static void copyStreamToFile(InputStream stream, File file) throws IOException {
403         FileOutputStream output = new FileOutputStream(file);
404         final int oneMegabyte = 1 * 1024 * 1024;
405         byte[] data = new byte[oneMegabyte];
406 
407         while (true) {
408             int bytesRead = stream.read(data);
409 
410             if (bytesRead < 0) {
411                 break;
412             }
413             output.write(data, 0, bytesRead);
414         }
415 
416         stream.close();
417         output.close();
418     }
419 
420     public static void calculateMessageDigest(File file, MessageDigest instance) throws IOException {
421         FileInputStream input = new FileInputStream(file);
422         final int oneMegabyte = 1024 * 1024;
423         byte[] data = new byte[oneMegabyte];
424 
425         while (true) {
426             int bytesRead = input.read(data);
427 
428             if (bytesRead < 0) {
429                 break;
430             }
431             instance.update(data, 0, bytesRead);
432         }
433 
434         input.close();
435     }
436 
437     public static HashSet<String> readFileToStringSet(File file) throws IOException {
438         BufferedReader reader = new BufferedReader(new FileReader(file));
439         HashSet<String> set = new HashSet<String>();
440         String line;
441 
442         while ((line = reader.readLine()) != null) {
443             set.add(line.trim());
444         }
445 
446         reader.close();
447         return set;
448     }
449 }