KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dspace > core > Utils


1 /*
2  * Utils.java
3  *
4  * Version: $Revision: 1.13 $
5  *
6  * Date: $Date: 2006/11/30 01:01:15 $
7  *
8  * Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
9  * Institute of Technology. All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions are
13  * met:
14  *
15  * - Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  *
18  * - Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution.
21  *
22  * - Neither the name of the Hewlett-Packard Company nor the name of the
23  * Massachusetts Institute of Technology nor the names of their
24  * contributors may be used to endorse or promote products derived from
25  * this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
34  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
36  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
38  * DAMAGE.
39  */

40 package org.dspace.core;
41
42 import java.io.BufferedInputStream JavaDoc;
43 import java.io.BufferedOutputStream JavaDoc;
44 import java.io.IOException JavaDoc;
45 import java.io.InputStream JavaDoc;
46 import java.io.OutputStream JavaDoc;
47 import java.math.BigInteger JavaDoc;
48 import java.rmi.dgc.VMID JavaDoc;
49 import java.security.MessageDigest JavaDoc;
50 import java.security.NoSuchAlgorithmException JavaDoc;
51 import java.text.ParseException JavaDoc;
52 import java.util.Random JavaDoc;
53 import java.util.regex.Matcher JavaDoc;
54 import java.util.regex.Pattern JavaDoc;
55
56 /**
57  * Utility functions for DSpace.
58  *
59  * @author Peter Breton
60  * @version $Revision: 1.13 $
61  */

62 public class Utils
63 {
64     private static final Pattern JavaDoc DURATION_PATTERN = Pattern
65             .compile("(\\d+)([smhdwy])");
66
67     private static final long MS_IN_SECOND = 1000L;
68
69     private static final long MS_IN_MINUTE = 60000L;
70
71     private static final long MS_IN_HOUR = 3600000L;
72
73     private static final long MS_IN_DAY = 86400000L;
74
75     private static final long MS_IN_WEEK = 604800000L;
76
77     private static final long MS_IN_YEAR = 31536000000L;
78
79     private static int counter = 0;
80
81     private static Random JavaDoc random = new Random JavaDoc();
82
83     private static VMID JavaDoc vmid = new VMID JavaDoc();
84
85     /** Private Constructor */
86     private Utils()
87     {
88     }
89
90     /**
91      * Return an MD5 checksum for data in hex format.
92      *
93      * @param data
94      * The data to checksum.
95      * @return MD5 checksum for the data in hex format.
96      */

97     public static String JavaDoc getMD5(String JavaDoc data)
98     {
99         return getMD5(data.getBytes());
100     }
101
102     /**
103      * Return an MD5 checksum for data in hex format.
104      *
105      * @param data
106      * The data to checksum.
107      * @return MD5 checksum for the data in hex format.
108      */

109     public static String JavaDoc getMD5(byte[] data)
110     {
111         return toHex(getMD5Bytes(data));
112     }
113
114     /**
115      * Return an MD5 checksum for data as a byte array.
116      *
117      * @param data
118      * The data to checksum.
119      * @return MD5 checksum for the data as a byte array.
120      */

121     public static byte[] getMD5Bytes(byte[] data)
122     {
123         try
124         {
125             MessageDigest JavaDoc digest = MessageDigest.getInstance("MD5");
126
127             return digest.digest(data);
128         }
129         catch (NoSuchAlgorithmException JavaDoc nsae)
130         {
131         }
132
133         // Should never happen
134
return null;
135     }
136
137     /**
138      * Return a hex representation of the byte array
139      *
140      * @param data
141      * The data to transform.
142      * @return A hex representation of the data.
143      */

144     public static String JavaDoc toHex(byte[] data)
145     {
146         if ((data == null) || (data.length == 0))
147         {
148             return null;
149         }
150
151         StringBuffer JavaDoc result = new StringBuffer JavaDoc();
152
153         // This is far from the most efficient way to do things...
154
for (int i = 0; i < data.length; i++)
155         {
156             int low = (int) (data[i] & 0x0F);
157             int high = (int) (data[i] & 0xF0);
158
159             result.append(Integer.toHexString(high).substring(0, 1));
160             result.append(Integer.toHexString(low));
161         }
162
163         return result.toString();
164     }
165
166     /**
167      * Generate a unique key. The key is a long (length 38 to 40) sequence of
168      * digits.
169      *
170      * @return A unique key as a long sequence of base-10 digits.
171      */

172     public static String JavaDoc generateKey()
173     {
174         return new BigInteger JavaDoc(generateBytesKey()).abs().toString();
175     }
176
177     /**
178      * Generate a unique key. The key is a 32-character long sequence of hex
179      * digits.
180      *
181      * @return A unique key as a long sequence of hex digits.
182      */

183     public static String JavaDoc generateHexKey()
184     {
185         return toHex(generateBytesKey());
186     }
187
188     /**
189      * Generate a unique key as a byte array.
190      *
191      * @return A unique key as a byte array.
192      */

193     public static synchronized byte[] generateBytesKey()
194     {
195         byte[] junk = new byte[16];
196
197         random.nextBytes(junk);
198
199         String JavaDoc input = new StringBuffer JavaDoc().append(vmid).append(
200                 new java.util.Date JavaDoc()).append(junk).append(counter++).toString();
201
202         return getMD5Bytes(input.getBytes());
203     }
204
205     // The following two methods are taken from the Jakarta IOUtil class.
206

207     /**
208      * Copy stream-data from source to destination. This method does not buffer,
209      * flush or close the streams, as to do so would require making non-portable
210      * assumptions about the streams' origin and further use. If you wish to
211      * perform a buffered copy, use {@link #bufferedCopy}.
212      *
213      * @param input
214      * The InputStream to obtain data from.
215      * @param output
216      * The OutputStream to copy data to.
217      */

218     public static void copy(final InputStream JavaDoc input, final OutputStream JavaDoc output)
219             throws IOException JavaDoc
220     {
221         final int BUFFER_SIZE = 1024 * 4;
222         final byte[] buffer = new byte[BUFFER_SIZE];
223
224         while (true)
225         {
226             final int count = input.read(buffer, 0, BUFFER_SIZE);
227
228             if (-1 == count)
229             {
230                 break;
231             }
232
233             // write out those same bytes
234
output.write(buffer, 0, count);
235         }
236
237         // needed to flush cache
238
// output.flush();
239
}
240
241     /**
242      * Copy stream-data from source to destination, with buffering. This is
243      * equivalent to passing {@link #copy}a
244      * <code>java.io.BufferedInputStream</code> and
245      * <code>java.io.BufferedOuputStream</code> to {@link #copy}, and
246      * flushing the output stream afterwards. The streams are not closed after
247      * the copy.
248      *
249      * @param source
250      * The InputStream to obtain data from.
251      * @param destination
252      * The OutputStream to copy data to.
253      */

254     public static void bufferedCopy(final InputStream JavaDoc source,
255             final OutputStream JavaDoc destination) throws IOException JavaDoc
256     {
257         final BufferedInputStream JavaDoc input = new BufferedInputStream JavaDoc(source);
258         final BufferedOutputStream JavaDoc output = new BufferedOutputStream JavaDoc(
259                 destination);
260         copy(input, output);
261         output.flush();
262     }
263
264     /**
265      * Replace characters that could be interpreted as HTML codes with symbolic
266      * references (entities). This function should be called before displaying
267      * any metadata fields that could contain the characters " <", ">", "&",
268      * "'", and double quotation marks. This will effectively disable HTML links
269      * in metadata.
270      *
271      * @param value
272      * the metadata value to be scrubbed for display
273      *
274      * @return the passed-in string, with html special characters replaced with
275      * entities.
276      */

277     public static String JavaDoc addEntities(String JavaDoc value)
278     {
279         if (value==null || value.length() == 0)
280             return value;
281         
282         value = value.replaceAll("&", "&amp;");
283         value = value.replaceAll("\"", "&quot;");
284
285         // actually, &apos; is an XML entity, not in HTML.
286
// that's why it's commented out.
287
// value = value.replaceAll("'", "&apos;");
288
value = value.replaceAll("<", "&lt;");
289         value = value.replaceAll(">", "&gt;");
290
291         return value;
292     }
293
294     /**
295      * Utility method to parse durations defined as \d+[smhdwy] (seconds,
296      * minutes, hours, days, weeks, years)
297      *
298      * @param duration
299      * specified duration
300      *
301      * @return number of milliseconds equivalent to duration.
302      *
303      * @throws ParseException
304      * if the duration is of incorrect format
305      */

306     public static long parseDuration(String JavaDoc duration) throws ParseException JavaDoc
307     {
308         Matcher JavaDoc m = DURATION_PATTERN.matcher(duration.trim());
309         if (!m.matches())
310         {
311             throw new ParseException JavaDoc("'" + duration
312                     + "' is not a valid duration definition", 0);
313         }
314
315         String JavaDoc units = m.group(2);
316         long multiplier = MS_IN_SECOND;
317
318         if ("s".equals(units))
319         {
320             multiplier = MS_IN_SECOND;
321         }
322         else if ("m".equals(units))
323         {
324             multiplier = MS_IN_MINUTE;
325         }
326         else if ("h".equals(units))
327         {
328             multiplier = MS_IN_HOUR;
329         }
330         else if ("d".equals(units))
331         {
332             multiplier = MS_IN_DAY;
333         }
334         else if ("w".equals(units))
335         {
336             multiplier = MS_IN_WEEK;
337         }
338         else if ("y".equals(units))
339         {
340             multiplier = MS_IN_YEAR;
341         }
342         else
343         {
344             throw new ParseException JavaDoc(units
345                     + " is not a valid time unit (must be 'y', "
346                     + "'w', 'd', 'h', 'm' or 's')", duration.indexOf(units));
347         }
348
349         long qint = Long.parseLong(m.group(1));
350
351         return qint * multiplier;
352     }
353 }
354
Popular Tags