KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > hudson > Util


1 package hudson;
2
3 import hudson.model.TaskListener;
4 import hudson.util.IOException2;
5 import org.apache.tools.ant.BuildException;
6 import org.apache.tools.ant.taskdefs.Chmod;
7 import org.apache.tools.ant.taskdefs.Copy;
8
9 import java.io.BufferedReader JavaDoc;
10 import java.io.ByteArrayOutputStream JavaDoc;
11 import java.io.File JavaDoc;
12 import java.io.FileOutputStream JavaDoc;
13 import java.io.FileReader JavaDoc;
14 import java.io.IOException JavaDoc;
15 import java.io.InputStream JavaDoc;
16 import java.io.OutputStream JavaDoc;
17 import java.io.OutputStreamWriter JavaDoc;
18 import java.net.InetAddress JavaDoc;
19 import java.net.UnknownHostException JavaDoc;
20 import java.security.DigestInputStream JavaDoc;
21 import java.security.MessageDigest JavaDoc;
22 import java.security.NoSuchAlgorithmException JavaDoc;
23 import java.text.SimpleDateFormat JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Collection JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Locale JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.ResourceBundle JavaDoc;
30 import java.util.SimpleTimeZone JavaDoc;
31 import java.util.StringTokenizer JavaDoc;
32 import java.util.logging.Level JavaDoc;
33 import java.util.logging.Logger JavaDoc;
34 import java.util.regex.Matcher JavaDoc;
35 import java.util.regex.Pattern JavaDoc;
36
37 /**
38  * @author Kohsuke Kawaguchi
39  */

40 public class Util {
41
42     /**
43      * Creates a filtered sublist.
44      */

45     public static <T> List JavaDoc<T> filter( List JavaDoc<?> base, Class JavaDoc<T> type ) {
46         List JavaDoc<T> r = new ArrayList JavaDoc<T>();
47         for (Object JavaDoc i : base) {
48             if(type.isInstance(i))
49                 r.add(type.cast(i));
50         }
51         return r;
52     }
53
54     /**
55      * Replaces the occurrence of '$key' by <tt>properties.get('key')</tt>.
56      *
57      * <p>
58      * This is a rather naive implementation that causes somewhat unexpected
59      * behavior when the expansion contains other macros.
60      */

61     public static String JavaDoc replaceMacro(String JavaDoc s, Map JavaDoc<String JavaDoc,String JavaDoc> properties) {
62         int idx=0;
63         while((idx=s.indexOf('$',idx))>=0) {
64             // identify the key
65
int end=idx+1;
66             while(end<s.length()) {
67                 char ch = s.charAt(end);
68                 if(!Character.isJavaIdentifierPart(ch))
69                     break;
70                 else
71                     end++;
72             }
73             String JavaDoc key = s.substring(idx+1,end);
74             String JavaDoc value = properties.get(key);
75             if(value==null) {
76                 idx++; // skip this '$' mark
77
} else {
78                 s = s.substring(0,idx)+value+s.substring(end);
79             }
80         }
81         
82         return s;
83     }
84
85     /**
86      * Loads the contents of a file into a string.
87      */

88     public static String JavaDoc loadFile(File JavaDoc logfile) throws IOException JavaDoc {
89         if(!logfile.exists())
90             return "";
91
92         StringBuffer JavaDoc str = new StringBuffer JavaDoc((int)logfile.length());
93
94         BufferedReader JavaDoc r = new BufferedReader JavaDoc(new FileReader JavaDoc(logfile));
95         char[] buf = new char[1024];
96         int len;
97         while((len=r.read(buf,0,buf.length))>0)
98            str.append(buf,0,len);
99         r.close();
100
101         return str.toString();
102     }
103
104     /**
105      * Deletes the contents of the given directory (but not the directory itself)
106      * recursively.
107      *
108      * @throws IOException
109      * if the operation fails.
110      */

111     public static void deleteContentsRecursive(File JavaDoc file) throws IOException JavaDoc {
112         File JavaDoc[] files = file.listFiles();
113         if(files==null)
114             return; // the directory didn't exist in the first place
115
for (File JavaDoc child : files) {
116             if (child.isDirectory())
117                 deleteContentsRecursive(child);
118             deleteFile(child);
119         }
120     }
121
122     private static void deleteFile(File JavaDoc f) throws IOException JavaDoc {
123         if (!f.delete()) {
124             if(!f.exists())
125                 // we are trying to delete a file that no longer exists, so this is not an error
126
return;
127
128             // perhaps this file is read-only?
129
// try chmod. this becomes no-op if this is not Unix.
130
try {
131                 Chmod chmod = new Chmod();
132                 chmod.setProject(new org.apache.tools.ant.Project());
133                 chmod.setFile(f);
134                 chmod.setPerm("u+w");
135                 chmod.execute();
136             } catch (BuildException e) {
137                 LOGGER.log(Level.INFO,"Failed to chmod "+f,e);
138             }
139
140             throw new IOException JavaDoc("Unable to delete " + f.getPath());
141
142         }
143     }
144
145     public static void deleteRecursive(File JavaDoc dir) throws IOException JavaDoc {
146         deleteContentsRecursive(dir);
147         deleteFile(dir);
148     }
149
150     /**
151      * Creates a new temporary directory.
152      */

153     public static File JavaDoc createTempDir() throws IOException JavaDoc {
154         File JavaDoc tmp = File.createTempFile("hudson", "tmp");
155         if(!tmp.delete())
156             throw new IOException JavaDoc("Failed to delete "+tmp);
157         if(!tmp.mkdirs())
158             throw new IOException JavaDoc("Failed to create a new directory "+tmp);
159         return tmp;
160     }
161
162     private static final Pattern JavaDoc errorCodeParser = Pattern.compile(".*CreateProcess.*error=([0-9]+).*");
163
164     /**
165      * On Windows, error messages for IOException aren't very helpful.
166      * This method generates additional user-friendly error message to the listener
167      */

168     public static void displayIOException( IOException JavaDoc e, TaskListener listener ) {
169         String JavaDoc msg = getWin32ErrorMessage(e);
170         if(msg!=null)
171             listener.getLogger().println(msg);
172     }
173
174     /**
175      * Extracts the Win32 error message from {@link IOException} if possible.
176      *
177      * @return
178      * null if there seems to be no error code or if the platform is not Win32.
179      */

180     public static String JavaDoc getWin32ErrorMessage(IOException JavaDoc e) {
181         String JavaDoc msg = e.getMessage();
182         if(msg==null)
183             return null; // no message
184
Matcher JavaDoc m = errorCodeParser.matcher(msg);
185         if(!m.matches())
186             return null; // failed to parse
187

188         try {
189             ResourceBundle JavaDoc rb = ResourceBundle.getBundle("/hudson/win32errors");
190             return rb.getString("error"+m.group(1));
191         } catch (Exception JavaDoc _) {
192             // silently recover from resource related failures
193
return null;
194         }
195     }
196
197     /**
198      * Guesses the current host name.
199      */

200     public static String JavaDoc getHostName() {
201         try {
202             return InetAddress.getLocalHost().getHostName();
203         } catch (UnknownHostException JavaDoc e) {
204             return "localhost";
205         }
206     }
207
208     public static void copyStream(InputStream JavaDoc in,OutputStream JavaDoc out) throws IOException JavaDoc {
209         byte[] buf = new byte[8192];
210         int len;
211         while((len=in.read(buf))>0)
212             out.write(buf,0,len);
213     }
214
215     public static String JavaDoc[] tokenize(String JavaDoc s) {
216         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(s);
217         String JavaDoc[] a = new String JavaDoc[st.countTokens()];
218         for (int i = 0; st.hasMoreTokens(); i++)
219             a[i] = st.nextToken();
220         return a;
221     }
222
223     public static String JavaDoc[] mapToEnv(Map JavaDoc<String JavaDoc,String JavaDoc> m) {
224         String JavaDoc[] r = new String JavaDoc[m.size()];
225         int idx=0;
226
227         for (final Map.Entry JavaDoc<String JavaDoc,String JavaDoc> e : m.entrySet()) {
228             r[idx++] = e.getKey() + '=' + e.getValue();
229         }
230         return r;
231     }
232
233     public static int min(int x, int... values) {
234         for (int i : values) {
235             if(i<x)
236                 x=i;
237         }
238         return x;
239     }
240
241     public static String JavaDoc nullify(String JavaDoc v) {
242         if(v!=null && v.length()==0) v=null;
243         return v;
244     }
245
246     /**
247      * Write-only buffer.
248      */

249     private static final byte[] garbage = new byte[8192];
250
251     /**
252      * Computes MD5 digest of the given input stream.
253      *
254      * @param source
255      * The stream will be closed by this method at the end of this method.
256      */

257     public static String JavaDoc getDigestOf(InputStream JavaDoc source) throws IOException JavaDoc {
258         try {
259             MessageDigest JavaDoc md5 = MessageDigest.getInstance("MD5");
260
261             DigestInputStream JavaDoc in =new DigestInputStream JavaDoc(source,md5);
262             try {
263                 while(in.read(garbage)>0)
264                     ; // simply discard the input
265
} finally {
266                 in.close();
267             }
268             return toHexString(md5.digest());
269         } catch (NoSuchAlgorithmException JavaDoc e) {
270             throw new IOException2("MD5 not installed",e); // impossible
271
}
272     }
273
274     public static String JavaDoc toHexString(byte[] data, int start, int len) {
275         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
276         for( int i=0; i<len; i++ ) {
277             int b = data[start+i]&0xFF;
278             if(b<16) buf.append('0');
279             buf.append(Integer.toHexString(b));
280         }
281         return buf.toString();
282     }
283
284     public static String JavaDoc toHexString(byte[] bytes) {
285         return toHexString(bytes,0,bytes.length);
286     }
287
288     public static String JavaDoc getTimeSpanString(long duration) {
289         duration /= 1000;
290         if(duration<60)
291             return combine(duration,"second");
292         duration /= 60;
293         if(duration<60)
294             return combine(duration,"minute");
295         duration /= 60;
296         if(duration<24)
297             return combine(duration,"hour");
298         duration /= 24;
299         if(duration<30)
300             return combine(duration,"day");
301         duration /= 30;
302         if(duration<12)
303             return combine(duration,"month");
304         duration /= 12;
305         return combine(duration,"year");
306     }
307
308     /**
309      * Combines number and unit, with a plural suffix if needed.
310      */

311     public static String JavaDoc combine(long n, String JavaDoc suffix) {
312         String JavaDoc s = Long.toString(n)+' '+suffix;
313         if(n!=1)
314             s += 's';
315         return s;
316     }
317
318     /**
319      * Create a sub-list by only picking up instances of the specified type.
320      */

321     public static <T> List JavaDoc<T> createSubList( Collection JavaDoc<?> source, Class JavaDoc<T> type ) {
322         List JavaDoc<T> r = new ArrayList JavaDoc<T>();
323         for (Object JavaDoc item : source) {
324             if(type.isInstance(item))
325                 r.add(type.cast(item));
326         }
327         return r;
328     }
329
330     /**
331      * Escapes non-ASCII characters.
332      */

333     public static String JavaDoc encode(String JavaDoc s) {
334         try {
335             boolean escaped = false;
336
337             StringBuffer JavaDoc out = new StringBuffer JavaDoc(s.length());
338
339             ByteArrayOutputStream JavaDoc buf = new ByteArrayOutputStream JavaDoc();
340             OutputStreamWriter JavaDoc w = new OutputStreamWriter JavaDoc(buf,"UTF-8");
341
342             for (int i = 0; i < s.length(); i++) {
343                 int c = (int) s.charAt(i);
344                 if (c<128 && c!=' ') {
345                     out.append((char) c);
346                 } else {
347                     // 1 char -> UTF8
348
w.write(c);
349                     w.flush();
350                     for (byte b : buf.toByteArray()) {
351                         out.append('%');
352                         out.append(toDigit((b >> 4) & 0xF));
353                         out.append(toDigit(b & 0xF));
354                     }
355                     buf.reset();
356                     escaped = true;
357                 }
358             }
359
360             return escaped ? out.toString() : s;
361         } catch (IOException JavaDoc e) {
362             throw new Error JavaDoc(e); // impossible
363
}
364     }
365
366     /**
367      * Escapes HTML unsafe characters like &lt;, &amp;to the respective character entities.
368      */

369     public static String JavaDoc escape(String JavaDoc text) {
370         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(text.length()+64);
371         for( int i=0; i<text.length(); i++ ) {
372             char ch = text.charAt(i);
373             if(ch=='\n')
374                 buf.append("<br>");
375             else
376             if(ch=='<')
377                 buf.append("&lt;");
378             else
379             if(ch=='&')
380                 buf.append("&amp;");
381             else
382             if(ch==' ')
383                 buf.append("&nbsp;");
384             else
385                 buf.append(ch);
386         }
387         return buf.toString();
388     }
389
390     private static char toDigit(int n) {
391         char ch = Character.forDigit(n,16);
392         if(ch>='a') ch = (char)(ch-'a'+'A');
393         return ch;
394     }
395
396     /**
397      * Creates an empty file.
398      */

399     public static void touch(File JavaDoc file) throws IOException JavaDoc {
400         new FileOutputStream JavaDoc(file).close();
401     }
402
403     /**
404      * Copies a single file by using Ant.
405      */

406     public static void copyFile(File JavaDoc src, File JavaDoc dst) throws BuildException {
407         Copy cp = new Copy();
408         cp.setProject(new org.apache.tools.ant.Project());
409         cp.setTofile(dst);
410         cp.setFile(src);
411         cp.setOverwrite(true);
412         cp.execute();
413     }
414
415     /**
416      * Convert null to "".
417      */

418     public static String JavaDoc fixNull(String JavaDoc s) {
419         if(s==null) return "";
420         else return s;
421     }
422
423     /**
424      * Convert empty string to null.
425      */

426     public static String JavaDoc fixEmpty(String JavaDoc s) {
427         if(s==null || s.length()==0) return null;
428         return s;
429     }
430
431     /**
432      * Cuts all the leading path portion and get just the file name.
433      */

434     public static String JavaDoc getFileName(String JavaDoc filePath) {
435         int idx = filePath.lastIndexOf('\\');
436         if(idx>=0)
437             return getFileName(filePath.substring(idx+1));
438         idx = filePath.lastIndexOf('/');
439         if(idx>=0)
440             return getFileName(filePath.substring(idx+1));
441         return filePath;
442     }
443
444     public static final SimpleDateFormat JavaDoc XS_DATETIME_FORMATTER = new SimpleDateFormat JavaDoc("yyyy-MM-dd'T'HH:mm:ss'Z'");
445
446     // Note: RFC822 dates must not be localized!
447
public static final SimpleDateFormat JavaDoc RFC822_DATETIME_FORMATTER
448             = new SimpleDateFormat JavaDoc("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);
449
450     static {
451         XS_DATETIME_FORMATTER.setTimeZone(new SimpleTimeZone JavaDoc(0,"GMT"));
452     }
453
454
455
456     private static final Logger JavaDoc LOGGER = Logger.getLogger(Util.class.getName());
457
458 }
459
Popular Tags