KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jgroups > util > Util


1 // $Id: Util.java,v 1.36 2005/04/26 15:22:14 belaban Exp $
2

3 package org.jgroups.util;
4
5 import org.apache.commons.logging.Log;
6 import org.apache.commons.logging.LogFactory;
7 import org.jgroups.*;
8 import org.jgroups.protocols.FD;
9 import org.jgroups.protocols.PingHeader;
10 import org.jgroups.protocols.UdpHeader;
11 import org.jgroups.protocols.pbcast.NakAckHeader;
12 import org.jgroups.conf.ClassConfigurator;
13 import org.jgroups.stack.IpAddress;
14
15 import java.io.*;
16 import java.net.BindException JavaDoc;
17 import java.net.DatagramSocket JavaDoc;
18 import java.net.InetAddress JavaDoc;
19 import java.net.ServerSocket JavaDoc;
20 import java.util.*;
21
22
23 /**
24  * Collection of various utility routines that can not be assigned to other classes.
25  */

26 public class Util {
27     private static final Object JavaDoc mutex=new Object JavaDoc();
28     private static final ByteArrayOutputStream out_stream=new ByteArrayOutputStream(512);
29
30     protected static final Log log=LogFactory.getLog(Util.class);
31
32     // constants
33
public static final int MAX_PORT=65535; // highest port allocatable
34
public static final String JavaDoc DIAG_GROUP="DIAG_GROUP-BELA-322649"; // unique
35
static boolean resolve_dns=false;
36
37     static {
38         /* Trying to get value of resolve_dns. PropertyPermission not granted if
39         * running in an untrusted environment with JNLP */

40         try {
41             resolve_dns=Boolean.valueOf(System.getProperty("resolve.dns", "false")).booleanValue();
42         }
43         catch (SecurityException JavaDoc ex){
44             resolve_dns=false;
45         }
46     }
47
48
49     public static void closeInputStream(InputStream inp) {
50         if(inp != null)
51             try {inp.close();} catch(IOException e) {}
52     }
53
54     public static void closeOutputStream(OutputStream out) {
55         if(out != null) {
56             try {out.close();} catch(IOException e) {}
57         }
58     }
59
60
61     /**
62      * Creates an object from a byte buffer
63      */

64     public static Object JavaDoc objectFromByteBuffer(byte[] buffer) throws Exception JavaDoc {
65         synchronized(mutex) {
66             if(buffer == null) return null;
67             Object JavaDoc retval=null;
68             ByteArrayInputStream in_stream=new ByteArrayInputStream(buffer);
69             ObjectInputStream in=new ContextObjectInputStream(in_stream); // changed Nov 29 2004 (bela)
70
retval=in.readObject();
71             in.close();
72             if(retval == null)
73                 return null;
74             return retval;
75         }
76     }
77
78     /**
79      * Serializes an object into a byte buffer.
80      * The object has to implement interface Serializable or Externalizable
81      */

82     public static byte[] objectToByteBuffer(Object JavaDoc obj) throws Exception JavaDoc {
83         byte[] result=null;
84         synchronized(out_stream) {
85             out_stream.reset();
86             ObjectOutputStream out=new ObjectOutputStream(out_stream);
87             out.writeObject(obj);
88             result=out_stream.toByteArray();
89             out.close();
90         }
91         return result;
92     }
93
94
95     public static void writeAddress(Address addr, DataOutputStream out) throws IOException {
96         if(addr == null) {
97             out.writeBoolean(false);
98             return;
99         }
100
101         out.writeBoolean(true);
102         if(addr instanceof IpAddress) {
103             // regular case, we don't need to include class information about the type of Address, e.g. JmsAddress
104
out.writeBoolean(true);
105             addr.writeTo(out);
106         }
107         else {
108             out.writeBoolean(false);
109             writeOtherAddress(addr, out);
110         }
111     }
112
113
114
115     public static Address readAddress(DataInputStream in) throws IOException, IllegalAccessException JavaDoc, InstantiationException JavaDoc {
116         Address addr=null;
117         if(in.readBoolean() == false)
118             return null;
119         if(in.readBoolean()) {
120             addr=new IpAddress();
121             addr.readFrom(in);
122         }
123         else {
124             addr=readOtherAddress(in);
125         }
126         return addr;
127     }
128
129     private static Address readOtherAddress(DataInputStream in) throws IOException, IllegalAccessException JavaDoc, InstantiationException JavaDoc {
130         ClassConfigurator conf=null;
131         try {conf=ClassConfigurator.getInstance(false);} catch(Exception JavaDoc e) {}
132         int b=in.read();
133         int magic_number;
134         String JavaDoc classname;
135         Class JavaDoc cl=null;
136         Address addr;
137         if(b == 1) {
138             magic_number=in.readInt();
139             cl=conf.get(magic_number);
140         }
141         else {
142             classname=in.readUTF();
143             cl=conf.get(classname);
144         }
145         addr=(Address)cl.newInstance();
146         addr.readFrom(in);
147         return addr;
148     }
149
150     private static void writeOtherAddress(Address addr, DataOutputStream out) throws IOException {
151         ClassConfigurator conf=null;
152         try {conf=ClassConfigurator.getInstance(false);} catch(Exception JavaDoc e) {}
153         int magic_number=conf != null? conf.getMagicNumber(addr.getClass()) : -1;
154
155         // write the class info
156
if(magic_number == -1) {
157             out.write(0);
158             out.writeUTF(addr.getClass().getName());
159         }
160         else {
161             out.write(1);
162             out.writeInt(magic_number);
163         }
164
165         // write the data itself
166
addr.writeTo(out);
167     }
168
169
170     public static void writeStreamable(Streamable obj, DataOutputStream out) throws IOException {
171         if(obj == null) {
172             out.writeBoolean(false);
173             return;
174         }
175         out.writeBoolean(true);
176         obj.writeTo(out);
177     }
178
179
180     public static Streamable readStreamable(Class JavaDoc clazz, DataInputStream in) throws IOException, IllegalAccessException JavaDoc, InstantiationException JavaDoc {
181         Streamable retval=null;
182         if(in.readBoolean() == false)
183             return null;
184         retval=(Streamable)clazz.newInstance();
185         retval.readFrom(in);
186         return retval;
187     }
188
189
190     public static void writeGenericStreamable(Streamable obj, DataOutputStream out) throws IOException {
191         int magic_number;
192         String JavaDoc classname;
193
194         if(obj == null) {
195             out.write(0);
196             return;
197         }
198
199         try {
200             out.write(1);
201             magic_number=ClassConfigurator.getInstance(false).getMagicNumber(obj.getClass());
202             // write the magic number or the class name
203
if(magic_number == -1) {
204                 out.write(0);
205                 classname=obj.getClass().getName();
206                 out.writeUTF(classname);
207             }
208             else {
209                 out.write(1);
210                 out.writeInt(magic_number);
211             }
212
213             // write the contents
214
obj.writeTo(out);
215         }
216         catch(ChannelException e) {
217             throw new IOException("failed writing object of type " + obj.getClass() + " to stream: " + e.toString());
218         }
219     }
220
221
222
223     public static Streamable readGenericStreamable(DataInputStream in) throws IOException {
224         Streamable retval=null;
225         int b=in.read();
226         if(b == 0)
227             return null;
228
229         int use_magic_number=in.read(), magic_number;
230         String JavaDoc classname;
231         Class JavaDoc clazz;
232
233         try {
234             if(use_magic_number == 1) {
235                 magic_number=in.readInt();
236                 clazz=ClassConfigurator.getInstance(false).get(magic_number);
237             }
238             else {
239                 classname=in.readUTF();
240                 clazz=ClassConfigurator.getInstance(false).get(classname);
241             }
242
243             retval=(Streamable)clazz.newInstance();
244             retval.readFrom(in);
245             return retval;
246         }
247         catch(Exception JavaDoc ex) {
248             throw new IOException("failed reading object: " + ex.toString());
249         }
250     }
251
252
253     public static void writeString(String JavaDoc s, DataOutputStream out) throws IOException {
254         if(s != null) {
255             out.write(1);
256             out.writeUTF(s);
257         }
258         else {
259             out.write(0);
260         }
261     }
262
263     public static String JavaDoc readString(DataInputStream in) throws IOException {
264         int b=in.read();
265         if(b == 1)
266             return in.readUTF();
267         return null;
268     }
269
270     public static void writeByteBuffer(byte[] buf, DataOutputStream out) throws IOException {
271         if(buf != null) {
272             out.write(1);
273             out.writeInt(buf.length);
274             out.write(buf, 0, buf.length);
275         }
276         else {
277             out.write(0);
278         }
279     }
280
281     public static byte[] readByteBuffer(DataInputStream in) throws IOException {
282         int b=in.read();
283         if(b == 1) {
284             b=in.readInt();
285             byte[] buf=new byte[b];
286             in.read(buf, 0, buf.length);
287             return buf;
288         }
289         return null;
290     }
291
292
293     /**
294        * Marshalls a list of messages
295        * @param xmit_list LinkedList<Message>
296        * @return
297        * @throws IOException
298        */

299     public static Buffer msgListToByteBuffer(LinkedList xmit_list) throws IOException {
300         ExposedByteArrayOutputStream output=new ExposedByteArrayOutputStream(512);
301         DataOutputStream out=new DataOutputStream(output);
302         Message msg;
303         Buffer retval=null;
304
305         out.writeInt(xmit_list.size());
306         for(Iterator it=xmit_list.iterator(); it.hasNext();) {
307             msg=(Message)it.next();
308             msg.writeTo(out);
309         }
310         out.flush();
311         retval=new Buffer(output.getRawBuffer(), 0, output.size());
312         out.close();
313         output.close();
314         return retval;
315     }
316
317     public static LinkedList byteBufferToMessageList(byte[] buffer, int offset, int length) throws Exception JavaDoc {
318         LinkedList retval=null;
319         ByteArrayInputStream input=new ByteArrayInputStream(buffer, offset, length);
320         DataInputStream in=new DataInputStream(input);
321         int size=in.readInt();
322
323         if(size == 0)
324             return null;
325
326         Message msg;
327         retval=new LinkedList();
328         for(int i=0; i < size; i++) {
329             msg=new Message();
330             msg.readFrom(in);
331             retval.add(msg);
332         }
333
334         return retval;
335     }
336
337
338
339
340
341     public static boolean match(Object JavaDoc obj1, Object JavaDoc obj2) {
342         if(obj1 == null && obj2 == null)
343             return true;
344         if(obj1 != null)
345             return obj1.equals(obj2);
346         else
347             return obj2.equals(obj1);
348     }
349
350
351     public static boolean match(long[] a1, long[] a2) {
352         if(a1 == null && a2 == null)
353             return true;
354         if(a1 == null || a2 == null)
355             return false;
356
357         if(a1 == a2) // identity
358
return true;
359
360         // at this point, a1 != null and a2 != null
361
if(a1.length != a2.length)
362             return false;
363
364         for(int i=0; i < a1.length; i++) {
365             if(a1[i] != a2[i])
366                 return false;
367         }
368         return true;
369     }
370
371     /** Sleep for timeout msecs. Returns when timeout has elapsed or thread was interrupted */
372     public static void sleep(long timeout) {
373         try {
374             Thread.sleep(timeout);
375         }
376         catch(Exception JavaDoc e) {
377         }
378     }
379
380
381     /**
382      * On most UNIX systems, the minimum sleep time is 10-20ms. Even if we specify sleep(1), the thread will
383      * sleep for at least 10-20ms. On Windows, sleep() seems to be implemented as a busy sleep, that is the
384      * thread never relinquishes control and therefore the sleep(x) is exactly x ms long.
385      */

386     public static void sleep(long msecs, boolean busy_sleep) {
387         if(!busy_sleep) {
388             sleep(msecs);
389             return;
390         }
391
392         long start=System.currentTimeMillis();
393         long stop=start + msecs;
394
395         while(stop > start) {
396             start=System.currentTimeMillis();
397         }
398     }
399
400
401     /** Returns a random value in the range [1 - range] */
402     public static long random(long range) {
403         return (long)((Math.random() * 100000) % range) + 1;
404     }
405
406
407     /** Sleeps between 1 and timeout milliseconds, chosen randomly. Timeout must be > 1 */
408     public static void sleepRandom(long timeout) {
409         if(timeout <= 0) {
410             log.error("timeout must be > 0 !");
411             return;
412         }
413
414         long r=(int)((Math.random() * 100000) % timeout) + 1;
415         sleep(r);
416     }
417
418
419     /**
420      Tosses a coin weighted with probability and returns true or false. Example: if probability=0.8,
421      chances are that in 80% of all cases, true will be returned and false in 20%.
422      */

423     public static boolean tossWeightedCoin(double probability) {
424         long r=random(100);
425         long cutoff=(long)(probability * 100);
426         if(r < cutoff)
427             return true;
428         else
429             return false;
430     }
431
432
433     public static String JavaDoc getHostname() {
434         try {
435             return InetAddress.getLocalHost().getHostName();
436         }
437         catch(Exception JavaDoc ex) {
438         }
439         return "localhost";
440     }
441
442
443     public static void dumpStack(boolean exit) {
444         try {
445             throw new Exception JavaDoc("Dumping stack:");
446         }
447         catch(Exception JavaDoc e) {
448             e.printStackTrace();
449             if(exit)
450                 System.exit(0);
451         }
452     }
453
454
455     /**
456      * Debugging method used to dump the content of a protocol queue in a condensed form. Useful
457      * to follow the evolution of the queue's content in time.
458      */

459     public static String JavaDoc dumpQueue(Queue q) {
460         StringBuffer JavaDoc sb=new StringBuffer JavaDoc();
461         LinkedList values=q.values();
462         if(values.size() == 0) {
463             sb.append("empty");
464         }
465         else {
466             for(Iterator it=values.iterator(); it.hasNext();) {
467                 Object JavaDoc o=it.next();
468                 String JavaDoc s=null;
469                 if(o instanceof Event) {
470                     Event event=(Event)o;
471                     int type=event.getType();
472                     s=Event.type2String(type);
473
474                     if(type == Event.MSG) {
475                         s+="[";
476                         Message m=(Message)event.getArg();
477                         Map headers=m.getHeaders();
478                         for(Iterator i=headers.keySet().iterator(); i.hasNext();) {
479                             Object JavaDoc headerKey=i.next();
480                             Object JavaDoc value=headers.get(headerKey);
481                             String JavaDoc headerToString=null;
482                             if(value instanceof FD.FdHeader) {
483                                 headerToString=value.toString();
484                             }
485                             else
486                                 if(value instanceof PingHeader) {
487                                     headerToString=headerKey + "-";
488                                     if(((PingHeader)value).type == PingHeader.GET_MBRS_REQ) {
489                                         headerToString+="GMREQ";
490                                     }
491                                     else
492                                         if(((PingHeader)value).type == PingHeader.GET_MBRS_RSP) {
493                                             headerToString+="GMRSP";
494                                         }
495                                         else {
496                                             headerToString+="UNKNOWN";
497                                         }
498                                 }
499                                 else {
500                                     headerToString=headerKey + "-" + (value == null ? "null" : value.toString());
501                                 }
502                             s+=headerToString;
503
504                             if(i.hasNext()) {
505                                 s+=",";
506                             }
507                         }
508                         s+="]";
509                     }
510                 }
511                 else {
512                     s=o.toString();
513                 }
514                 sb.append(s).append(" ");
515             }
516         }
517         return sb.toString();
518     }
519
520
521     /**
522      * Use with caution: lots of overhead
523      */

524     public static String JavaDoc printStackTrace(Throwable JavaDoc t) {
525         StringWriter s=new StringWriter();
526         PrintWriter p=new PrintWriter(s);
527         t.printStackTrace(p);
528         return s.toString();
529     }
530
531     public static String JavaDoc getStackTrace(Throwable JavaDoc t) {
532         return printStackTrace(t);
533     }
534
535     /**
536      * Use with caution: lots of overhead
537      */

538     public static String JavaDoc printStackTrace() {
539         try {
540             throw new Exception JavaDoc("Dumping stack:");
541         }
542         catch(Throwable JavaDoc t) {
543             StringWriter s=new StringWriter();
544             PrintWriter p=new PrintWriter(s);
545             t.printStackTrace(p);
546             return s.toString();
547         }
548     }
549
550     public static String JavaDoc print(Throwable JavaDoc t) {
551         return printStackTrace(t);
552     }
553
554
555     public static void crash() {
556         System.exit(-1);
557     }
558
559
560     public static String JavaDoc printEvent(Event evt) {
561         Message msg;
562
563         if(evt.getType() == Event.MSG) {
564             msg=(Message)evt.getArg();
565             if(msg != null) {
566                 if(msg.getLength() > 0)
567                     return printMessage(msg);
568                 else
569                     return msg.printObjectHeaders();
570             }
571         }
572         return evt.toString();
573     }
574
575
576     /** Tries to read an object from the message's buffer and prints it */
577     public static String JavaDoc printMessage(Message msg) {
578         if(msg == null)
579             return "";
580         if(msg.getLength() == 0)
581             return null;
582
583         try {
584             return msg.getObject().toString();
585         }
586         catch(Exception JavaDoc e) { // it is not an object
587
return "";
588         }
589
590     }
591
592
593     /** Tries to read a <code>MethodCall</code> object from the message's buffer and prints it.
594      Returns empty string if object is not a method call */

595     public static String JavaDoc printMethodCall(Message msg) {
596         Object JavaDoc obj;
597         if(msg == null)
598             return "";
599         if(msg.getLength() == 0)
600             return "";
601
602         try {
603             obj=msg.getObject();
604             return obj.toString();
605         }
606         catch(Exception JavaDoc e) { // it is not an object
607
return "";
608         }
609
610     }
611
612
613     public static void printThreads() {
614         Thread JavaDoc threads[]=new Thread JavaDoc[Thread.activeCount()];
615         Thread.enumerate(threads);
616         System.out.println("------- Threads -------");
617         for(int i=0; i < threads.length; i++) {
618             System.out.println("#" + i + ": " + threads[i]);
619         }
620         System.out.println("------- Threads -------\n");
621     }
622
623
624     public static String JavaDoc activeThreads() {
625         StringBuffer JavaDoc sb=new StringBuffer JavaDoc();
626         Thread JavaDoc threads[]=new Thread JavaDoc[Thread.activeCount()];
627         Thread.enumerate(threads);
628         sb.append("------- Threads -------\n");
629         for(int i=0; i < threads.length; i++) {
630             sb.append("#" + i + ": " + threads[i] + '\n');
631         }
632         sb.append("------- Threads -------\n");
633         return sb.toString();
634     }
635
636
637     /**
638      Fragments a byte buffer into smaller fragments of (max.) frag_size.
639      Example: a byte buffer of 1024 bytes and a frag_size of 248 gives 4 fragments
640      of 248 bytes each and 1 fragment of 32 bytes.
641      @return An array of byte buffers (<code>byte[]</code>).
642      */

643     public static byte[][] fragmentBuffer(byte[] buf, int frag_size, int length) {
644         byte[] retval[];
645         long total_size=length;
646         int accumulated_size=0;
647         byte[] fragment;
648         int tmp_size=0;
649         int num_frags;
650         int index=0;
651
652         num_frags=length % frag_size == 0 ? length / frag_size : length / frag_size + 1;
653         retval=new byte[num_frags][];
654
655         while(accumulated_size < total_size) {
656             if(accumulated_size + frag_size <= total_size)
657                 tmp_size=frag_size;
658             else
659                 tmp_size=(int)(total_size - accumulated_size);
660             fragment=new byte[tmp_size];
661             System.arraycopy(buf, accumulated_size, fragment, 0, tmp_size);
662             retval[index++]=fragment;
663             accumulated_size+=tmp_size;
664         }
665         return retval;
666     }
667
668     public static byte[][] fragmentBuffer(byte[] buf, int frag_size) {
669         return fragmentBuffer(buf, frag_size, buf.length);
670     }
671
672
673
674     /**
675      * Given a buffer and a fragmentation size, compute a list of fragmentation offset/length pairs, and
676      * return them in a list. Example:<br/>
677      * Buffer is 10 bytes, frag_size is 4 bytes. Return value will be ({0,4}, {4,4}, {8,2}).
678      * This is a total of 3 fragments: the first fragment starts at 0, and has a length of 4 bytes, the second fragment
679      * starts at offset 4 and has a length of 4 bytes, and the last fragment starts at offset 8 and has a length
680      * of 2 bytes.
681      * @param frag_size
682      * @return List. A List<Range> of offset/length pairs
683      */

684     public static java.util.List JavaDoc computeFragOffsets(int offset, int length, int frag_size) {
685         java.util.List JavaDoc retval=new ArrayList();
686         long total_size=length + offset;
687         int index=offset;
688         int tmp_size=0;
689         Range r;
690
691         while(index < total_size) {
692             if(index + frag_size <= total_size)
693                 tmp_size=frag_size;
694             else
695                 tmp_size=(int)(total_size - index);
696             r=new Range(index, tmp_size);
697             retval.add(r);
698             index+=tmp_size;
699         }
700         return retval;
701     }
702
703     public static java.util.List JavaDoc computeFragOffsets(byte[] buf, int frag_size) {
704         return computeFragOffsets(0, buf.length, frag_size);
705     }
706
707     /**
708      Concatenates smaller fragments into entire buffers.
709      @param fragments An array of byte buffers (<code>byte[]</code>)
710      @return A byte buffer
711      */

712     public static byte[] defragmentBuffer(byte[] fragments[]) {
713         int total_length=0;
714         byte[] ret;
715         int index=0;
716
717         if(fragments == null) return null;
718         for(int i=0; i < fragments.length; i++) {
719             if(fragments[i] == null) continue;
720             total_length+=fragments[i].length;
721         }
722         ret=new byte[total_length];
723         for(int i=0; i < fragments.length; i++) {
724             if(fragments[i] == null) continue;
725             System.arraycopy(fragments[i], 0, ret, index, fragments[i].length);
726             index+=fragments[i].length;
727         }
728         return ret;
729     }
730
731
732     public static void printFragments(byte[] frags[]) {
733         for(int i=0; i < frags.length; i++)
734             System.out.println('\'' + new String JavaDoc(frags[i]) + '\'');
735     }
736
737
738
739 // /**
740
// Peeks for view on the channel until n views have been received or timeout has elapsed.
741
// Used to determine the view in which we want to start work. Usually, we start as only
742
// member in our own view (1st view) and the next view (2nd view) will be the full view
743
// of all members, or a timeout if we're the first member. If a non-view (a message or
744
// block) is received, the method returns immediately.
745
// @param channel The channel used to peek for views. Has to be operational.
746
// @param number_of_views The number of views to wait for. 2 is a good number to ensure that,
747
// if there are other members, we start working with them included in our view.
748
// @param timeout Number of milliseconds to wait until view is forced to return. A value
749
// of <= 0 means wait forever.
750
// */
751
// public static View peekViews(Channel channel, int number_of_views, long timeout) {
752
// View retval=null;
753
// Object obj=null;
754
// int num=0;
755
// long start_time=System.currentTimeMillis();
756

757 // if(timeout <= 0) {
758
// while(true) {
759
// try {
760
// obj=channel.peek(0);
761
// if(obj == null || !(obj instanceof View))
762
// break;
763
// else {
764
// retval=(View)channel.receive(0);
765
// num++;
766
// if(num >= number_of_views)
767
// break;
768
// }
769
// }
770
// catch(Exception ex) {
771
// break;
772
// }
773
// }
774
// }
775
// else {
776
// while(timeout > 0) {
777
// try {
778
// obj=channel.peek(timeout);
779
// if(obj == null || !(obj instanceof View))
780
// break;
781
// else {
782
// retval=(View)channel.receive(timeout);
783
// num++;
784
// if(num >= number_of_views)
785
// break;
786
// }
787
// }
788
// catch(Exception ex) {
789
// break;
790
// }
791
// timeout=timeout - (System.currentTimeMillis() - start_time);
792
// }
793
// }
794

795 // return retval;
796
// }
797

798
799
800
801     public static String JavaDoc array2String(long[] array) {
802         StringBuffer JavaDoc ret=new StringBuffer JavaDoc("[");
803
804         if(array != null) {
805             for(int i=0; i < array.length; i++)
806                 ret.append(array[i] + " ");
807         }
808
809         ret.append(']');
810         return ret.toString();
811     }
812
813     public static String JavaDoc array2String(int[] array) {
814         StringBuffer JavaDoc ret=new StringBuffer JavaDoc("[");
815
816         if(array != null) {
817             for(int i=0; i < array.length; i++)
818                 ret.append(array[i] + " ");
819         }
820
821         ret.append(']');
822         return ret.toString();
823     }
824
825     public static String JavaDoc array2String(boolean[] array) {
826         StringBuffer JavaDoc ret=new StringBuffer JavaDoc("[");
827
828         if(array != null) {
829             for