001    /*
002     * Written by Dawid Kurzyniec, based on code written by Doug Lea with assistance
003     * from members of JCP JSR-166 Expert Group. Released to the public domain,
004     * as explained at http://creativecommons.org/licenses/publicdomain.
005     */
006    
007    /*
008     * Copied from backport-util-concurrent so that weaved code can also be used
009     * with 1.2 and 1.3 JVMs. Only 1.5+ methods are copied.
010     */
011    package net.sourceforge.retroweaver.runtime.java.util;
012    
013    import java.lang.reflect.Array;
014    import java.util.ArrayList;
015    import java.util.List;
016    
017    public class Arrays_ {
018    
019        private Arrays_() {}
020    
021        // Cloning
022    
023        /**
024         * @since 1.6
025         */
026        public static Object[] copyOf(Object[] original, int newLength) {
027            return copyOf(original, newLength, original.getClass());
028        }
029    
030        /**
031         * @since 1.6
032         */
033        public static Object[] copyOf(Object[] original, int newLength, Class newType) {
034            Object[] arr = (newType == Object[].class) ? new Object[newLength] :
035                (Object[])Array.newInstance(newType.getComponentType(), newLength);
036            int len  = (original.length < newLength ? original.length : newLength);
037            System.arraycopy(original, 0, arr, 0, len);
038            return arr;
039        }
040    
041        /**
042         * @since 1.6
043         */
044        public static byte[] copyOf(byte[] original, int newLength) {
045            byte[] arr = new byte[newLength];
046            int len  = (original.length < newLength ? original.length : newLength);
047            System.arraycopy(original, 0, arr, 0, len);
048            return arr;
049        }
050    
051        /**
052         * @since 1.6
053         */
054        public static short[] copyOf(short[] original, int newLength) {
055            short[] arr = new short[newLength];
056            int len  = (original.length < newLength ? original.length : newLength);
057            System.arraycopy(original, 0, arr, 0, len);
058            return arr;
059        }
060    
061        /**
062         * @since 1.6
063         */
064        public static int[] copyOf(int[] original, int newLength) {
065            int[] arr = new int[newLength];
066            int len  = (original.length < newLength ? original.length : newLength);
067            System.arraycopy(original, 0, arr, 0, len);
068            return arr;
069        }
070    
071        /**
072         * @since 1.6
073         */
074        public static long[] copyOf(long[] original, int newLength) {
075            long[] arr = new long[newLength];
076            int len  = (original.length < newLength ? original.length : newLength);
077            System.arraycopy(original, 0, arr, 0, len);
078            return arr;
079        }
080    
081        /**
082         * @since 1.6
083         */
084        public static char[] copyOf(char[] original, int newLength) {
085            char[] arr = new char[newLength];
086            int len  = (original.length < newLength ? original.length : newLength);
087            System.arraycopy(original, 0, arr, 0, len);
088            return arr;
089        }
090    
091        /**
092         * @since 1.6
093         */
094        public static float[] copyOf(float[] original, int newLength) {
095            float[] arr = new float[newLength];
096            int len  = (original.length < newLength ? original.length : newLength);
097            System.arraycopy(original, 0, arr, 0, len);
098            return arr;
099        }
100    
101        /**
102         * @since 1.6
103         */
104        public static double[] copyOf(double[] original, int newLength) {
105            double[] arr = new double[newLength];
106            int len  = (original.length < newLength ? original.length : newLength);
107            System.arraycopy(original, 0, arr, 0, len);
108            return arr;
109        }
110    
111        /**
112         * @since 1.6
113         */
114        public static boolean[] copyOf(boolean[] original, int newLength) {
115            boolean[] arr = new boolean[newLength];
116            int len  = (original.length < newLength ? original.length : newLength);
117            System.arraycopy(original, 0, arr, 0, len);
118            return arr;
119        }
120    
121        /**
122         * @since 1.6
123         */
124        public static Object[] copyOfRange(Object[] original, int from, int to) {
125            return copyOfRange(original, from, to, original.getClass());
126        }
127    
128        /**
129         * @since 1.6
130         */
131        public static Object[] copyOfRange(Object[] original, int from, int to, Class newType) {
132            int newLength = to - from;
133            if (newLength < 0) throw new IllegalArgumentException(from + " > " + to);
134            Object[] arr = (newType == Object[].class) ? new Object[newLength] :
135                (Object[])Array.newInstance(newType.getComponentType(), newLength);
136            int ceil = original.length-from;
137            int len = (ceil < newLength) ? ceil : newLength;
138            System.arraycopy(original, from, arr, 0, len);
139            return arr;
140        }
141    
142        /**
143         * @since 1.6
144         */
145        public static byte[] copyOfRange(byte[] original, int from, int to) {
146            int newLength = to - from;
147            if (newLength < 0) throw new IllegalArgumentException(from + " > " + to);
148            byte[] arr = new byte[newLength];
149            int ceil = original.length-from;
150            int len = (ceil < newLength) ? ceil : newLength;
151            System.arraycopy(original, from, arr, 0, len);
152            return arr;
153        }
154    
155        /**
156         * @since 1.6
157         */
158        public static short[] copyOfRange(short[] original, int from, int to) {
159            int newLength = to - from;
160            if (newLength < 0) throw new IllegalArgumentException(from + " > " + to);
161            short[] arr = new short[newLength];
162            int ceil = original.length-from;
163            int len = (ceil < newLength) ? ceil : newLength;
164            System.arraycopy(original, from, arr, 0, len);
165            return arr;
166        }
167    
168        /**
169         * @since 1.6
170         */
171        public static int[] copyOfRange(int[] original, int from, int to) {
172            int newLength = to - from;
173            if (newLength < 0) throw new IllegalArgumentException(from + " > " + to);
174            int[] arr = new int[newLength];
175            int ceil = original.length-from;
176            int len = (ceil < newLength) ? ceil : newLength;
177            System.arraycopy(original, from, arr, 0, len);
178            return arr;
179        }
180    
181        /**
182         * @since 1.6
183         */
184        public static long[] copyOfRange(long[] original, int from, int to) {
185            int newLength = to - from;
186            if (newLength < 0) throw new IllegalArgumentException(from + " > " + to);
187            long[] arr = new long[newLength];
188            int ceil = original.length-from;
189            int len = (ceil < newLength) ? ceil : newLength;
190            System.arraycopy(original, from, arr, 0, len);
191            return arr;
192        }
193    
194        /**
195         * @since 1.6
196         */
197        public static char[] copyOfRange(char[] original, int from, int to) {
198            int newLength = to - from;
199            if (newLength < 0) throw new IllegalArgumentException(from + " > " + to);
200            char[] arr = new char[newLength];
201            int ceil = original.length-from;
202            int len = (ceil < newLength) ? ceil : newLength;
203            System.arraycopy(original, from, arr, 0, len);
204            return arr;
205        }
206    
207        /**
208         * @since 1.6
209         */
210        public static float[] copyOfRange(float[] original, int from, int to) {
211            int newLength = to - from;
212            if (newLength < 0) throw new IllegalArgumentException(from + " > " + to);
213            float[] arr = new float[newLength];
214            int ceil = original.length-from;
215            int len = (ceil < newLength) ? ceil : newLength;
216            System.arraycopy(original, from, arr, 0, len);
217            return arr;
218        }
219    
220        /**
221         * @since 1.6
222         */
223        public static double[] copyOfRange(double[] original, int from, int to) {
224            int newLength = to - from;
225            if (newLength < 0) throw new IllegalArgumentException(from + " > " + to);
226            double[] arr = new double[newLength];
227            int ceil = original.length-from;
228            int len = (ceil < newLength) ? ceil : newLength;
229            System.arraycopy(original, from, arr, 0, len);
230            return arr;
231        }
232    
233        /**
234         * @since 1.6
235         */
236        public static boolean[] copyOfRange(boolean[] original, int from, int to) {
237            int newLength = to - from;
238            if (newLength < 0) throw new IllegalArgumentException(from + " > " + to);
239            boolean[] arr = new boolean[newLength];
240            int ceil = original.length-from;
241            int len = (ceil < newLength) ? ceil : newLength;
242            System.arraycopy(original, from, arr, 0, len);
243            return arr;
244        }
245    
246        /**
247         * @since 1.5
248         */
249        public static int hashCode(long a[]) {
250            if (a == null) return 0;
251            int hash = 1;
252            for (int i=0; i<a.length; i++) {
253                long e = a[i];
254                hash = 31*hash + (int)(e ^ (e >>> 32));
255            }
256            return hash;
257        }
258    
259        /**
260         * @since 1.5
261         */
262        public static int hashCode(int a[]) {
263            if (a == null) return 0;
264            int hash = 1;
265            for (int i=0; i<a.length; i++) {
266                hash = 31*hash + a[i];
267            }
268            return hash;
269        }
270    
271        /**
272         * @since 1.5
273         */
274        public static int hashCode(short a[]) {
275            if (a == null) return 0;
276            int hash = 1;
277            for (int i=0; i<a.length; i++) {
278                hash = 31*hash + a[i];
279            }
280            return hash;
281        }
282    
283        /**
284         * @since 1.5
285         */
286        public static int hashCode(char a[]) {
287            if (a == null) return 0;
288            int hash = 1;
289            for (int i=0; i<a.length; i++) {
290                hash = 31*hash + a[i];
291            }
292            return hash;
293        }
294    
295        /**
296         * @since 1.5
297         */
298        public static int hashCode(byte a[]) {
299            if (a == null) return 0;
300            int hash = 1;
301            for (int i=0; i<a.length; i++) {
302                hash = 31*hash + a[i];
303            }
304            return hash;
305        }
306    
307        /**
308         * @since 1.5
309         */
310        public static int hashCode(boolean a[]) {
311            if (a == null) return 0;
312            int hash = 1;
313            for (int i=0; i<a.length; i++) {
314                hash = 31*hash + (a[i] ? 1231 : 1237);
315            }
316            return hash;
317        }
318    
319        /**
320         * @since 1.5
321         */
322        public static int hashCode(float a[]) {
323            if (a == null) return 0;
324            int hash = 1;
325            for (int i=0; i<a.length; i++) {
326                hash = 31*hash + Float.floatToIntBits(a[i]);
327            }
328            return hash;
329        }
330    
331        /**
332         * @since 1.5
333         */
334        public static int hashCode(double a[]) {
335            if (a == null) return 0;
336            int hash = 1;
337            for (int i=0; i<a.length; i++) {
338                long e = Double.doubleToLongBits(a[i]);
339                hash = 31*hash + (int)(e ^ (e >>> 32));
340            }
341            return hash;
342        }
343    
344        /**
345         * @since 1.5
346         */
347        public static int hashCode(Object a[]) {
348            if (a == null) return 0;
349            int hash = 1;
350            for (int i=0; i<a.length; i++) {
351                Object e = a[i];
352                hash = 31*hash + (e == null ? 0 : e.hashCode());
353            }
354            return hash;
355        }
356    
357        /**
358         * @since 1.5
359         */
360        public static int deepHashCode(Object a[]) {
361            if (a == null) return 0;
362            int hash = 1;
363            for (int i=0; i<a.length; i++) {
364                Object e = a[i];
365                hash = 31*hash +
366                       (e instanceof Object[]  ? deepHashCode((Object[])e) :
367                       (e instanceof byte[]    ? hashCode((byte[])e) :
368                       (e instanceof short[]   ? hashCode((short[])e) :
369                       (e instanceof int[]     ? hashCode((int[])e) :
370                       (e instanceof long[]    ? hashCode((long[])e) :
371                       (e instanceof char[]    ? hashCode((char[])e) :
372                       (e instanceof boolean[] ? hashCode((boolean[])e) :
373                       (e instanceof float[]   ? hashCode((float[])e) :
374                       (e instanceof double[]  ? hashCode((double[])e) :
375                       (e != null              ? e.hashCode() : 0))))))))));
376            }
377            return hash;
378    
379        }
380    
381        /**
382         * @since 1.5
383         */
384        public static boolean deepEquals(Object[] a1, Object[] a2) {
385            if (a1 == a2) return true;
386            if (a1 == null || a2==null) return false;
387            int len = a1.length;
388            if (len != a2.length) return false;
389            for (int i = 0; i < len; i++) {
390                Object e1 = a1[i];
391                Object e2 = a2[i];
392                if (e1 == e2) continue;
393                if (e1 == null) return false;
394                boolean eq =
395                    (e1.getClass() != e2.getClass() || e1.getClass().isArray()) ?
396                            e1.equals(e2) :
397                    (e1 instanceof Object[] && e2 instanceof Object[]) ?
398                            deepEquals((Object[])e1, (Object[])e2) :
399                    (e1 instanceof byte[] && e2 instanceof byte[]) ?
400                            java.util.Arrays.equals((byte[])e1, (byte[])e2) :
401                    (e1 instanceof short[] && e2 instanceof short[]) ?
402                                    java.util.Arrays.equals((short[])e1, (short[])e2) :
403                    (e1 instanceof int[] && e2 instanceof int[]) ?
404                                    java.util.Arrays. equals((int[])e1, (int[])e2) :
405                    (e1 instanceof long[] && e2 instanceof long[]) ?
406                                    java.util.Arrays.equals((long[])e1, (long[])e2) :
407                    (e1 instanceof char[] && e2 instanceof char[]) ?
408                                    java.util.Arrays.equals((char[])e1, (char[])e2) :
409                    (e1 instanceof boolean[] && e2 instanceof boolean[]) ?
410                                    java.util.Arrays.equals((boolean[])e1, (boolean[])e2) :
411                    (e1 instanceof float[] && e2 instanceof float[]) ?
412                                    java.util.Arrays.equals((float[])e1, (float[])e2) :
413                    (e1 instanceof double[] && e2 instanceof double[]) ?
414                                    java.util.Arrays.equals((double[])e1, (double[])e2) :
415                    e1.equals(e2);
416    
417                if (!eq) return false;
418            }
419            return true;
420        }
421    
422        /**
423         * @since 1.5
424         */
425        public static String toString(long[] a) {
426            if (a == null) return "null";
427            if (a.length == 0) return "[]";
428            StringBuffer buf = new StringBuffer();
429            buf.append('[').append(a[0]);
430            for (int i=1; i<a.length; i++) buf.append(", ").append(a[i]);
431            buf.append(']');
432            return buf.toString();
433        }
434    
435        /**
436         * @since 1.5
437         */
438        public static String toString(int[] a) {
439            if (a == null) return "null";
440            if (a.length == 0) return "[]";
441            StringBuffer buf = new StringBuffer();
442            buf.append('[').append(a[0]);
443            for (int i=1; i<a.length; i++) buf.append(", ").append(a[i]);
444            buf.append(']');
445            return buf.toString();
446        }
447    
448        /**
449         * @since 1.5
450         */
451        public static String toString(short[] a) {
452            if (a == null) return "null";
453            if (a.length == 0) return "[]";
454            StringBuffer buf = new StringBuffer();
455            buf.append('[').append(a[0]);
456            for (int i=1; i<a.length; i++) buf.append(", ").append(a[i]);
457            buf.append(']');
458            return buf.toString();
459        }
460    
461        /**
462         * @since 1.5
463         */
464        public static String toString(char[] a) {
465            if (a == null) return "null";
466            if (a.length == 0) return "[]";
467            StringBuffer buf = new StringBuffer();
468            buf.append('[').append(a[0]);
469            for (int i=1; i<a.length; i++) buf.append(", ").append(a[i]);
470            buf.append(']');
471            return buf.toString();
472        }
473    
474        /**
475         * @since 1.5
476         */
477        public static String toString(byte[] a) {
478            if (a == null) return "null";
479            if (a.length == 0) return "[]";
480            StringBuffer buf = new StringBuffer();
481            buf.append('[').append(a[0]);
482            for (int i=1; i<a.length; i++) buf.append(", ").append(a[i]);
483            buf.append(']');
484            return buf.toString();
485        }
486    
487        /**
488         * @since 1.5
489         */
490        public static String toString(boolean[] a) {
491            if (a == null) return "null";
492            if (a.length == 0) return "[]";
493            StringBuffer buf = new StringBuffer();
494            buf.append('[').append(a[0]);
495            for (int i=1; i<a.length; i++) buf.append(", ").append(a[i]);
496            buf.append(']');
497            return buf.toString();
498        }
499    
500        /**
501         * @since 1.5
502         */
503        public static String toString(float[] a) {
504            if (a == null) return "null";
505            if (a.length == 0) return "[]";
506            StringBuffer buf = new StringBuffer();
507            buf.append('[').append(a[0]);
508            for (int i=1; i<a.length; i++) buf.append(", ").append(a[i]);
509            buf.append(']');
510            return buf.toString();
511        }
512    
513        /**
514         * @since 1.5
515         */
516        public static String toString(double[] a) {
517            if (a == null) return "null";
518            if (a.length == 0) return "[]";
519            StringBuffer buf = new StringBuffer();
520            buf.append('[').append(a[0]);
521            for (int i=1; i<a.length; i++) buf.append(", ").append(a[i]);
522            buf.append(']');
523            return buf.toString();
524        }
525    
526        /**
527         * @since 1.5
528         */
529        public static String toString(Object[] a) {
530            if (a == null) return "null";
531            if (a.length == 0) return "[]";
532            StringBuffer buf = new StringBuffer();
533            buf.append('[').append(a[0]);
534            for (int i=1; i<a.length; i++) buf.append(", ").append(a[i]);
535            buf.append(']');
536            return buf.toString();
537        }
538    
539        /**
540         * @since 1.5
541         */
542        public static String deepToString(Object[] a) {
543            if (a == null) return "null";
544            StringBuffer buf = new StringBuffer();
545            deepToString(a, buf, new ArrayList());
546            return buf.toString();
547        }
548    
549        private static void deepToString(Object[] a, StringBuffer buf, List seen) {
550            seen.add(a);
551            buf.append('[');
552            for (int i = 0; i < a.length; i++) {
553                if (i>0) buf.append(", ");
554                Object e = a[i];
555                if (e == null) {
556                    buf.append("null");
557                }
558                else if (!e.getClass().isArray()) {
559                    buf.append(e.toString());
560                }
561                else if (e instanceof Object[]) {
562                    if (seen.contains(e)) buf.append("[...]");
563                    else deepToString((Object[])e, buf, seen);
564                }
565                else {
566                    // primitive arr
567                    buf.append(
568                        (e instanceof byte[]) ? toString( (byte[]) e) :
569                        (e instanceof short[]) ? toString( (short[]) e) :
570                        (e instanceof int[]) ? toString( (int[]) e) :
571                        (e instanceof long[]) ? toString( (long[]) e) :
572                        (e instanceof char[]) ? toString( (char[]) e) :
573                        (e instanceof boolean[]) ? toString( (boolean[]) e) :
574                        (e instanceof float[]) ? toString( (float[]) e) :
575                        (e instanceof double[]) ? toString( (double[]) e) : "");
576                }
577            }
578            buf.append(']');
579            seen.remove(seen.size()-1);
580        }
581    }