1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.myfaces.shared_orchestra.util;
20
21 import java.lang.reflect.Array;
22
23
24 /**
25 * Utility class for managing arrays
26 *
27 * @author Anton Koinov (latest modification by $Author: grantsmith $)
28 * @version $Revision: 472630 $ $Date: 2006-11-08 15:40:03 -0500 (Wed, 08 Nov 2006) $
29 */
30 public class ArrayUtils
31 {
32 public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
33 public static final String[] EMPTY_STRING_ARRAY = new String[0];
34
35 //~ Constructors -------------------------------------------------------------------------------
36
37 protected ArrayUtils()
38 {
39 // hide from public access
40 }
41
42 //~ Methods ------------------------------------------------------------------------------------
43
44 public static Class commonClass(Class c1, Class c2)
45 {
46 if (c1 == c2)
47 {
48 return c1;
49 }
50
51 if ((c1 == Object.class) || c1.isAssignableFrom(c2))
52 {
53 return c1;
54 }
55
56 if (c2.isAssignableFrom(c1))
57 {
58 return c2;
59 }
60
61 if (c1.isPrimitive() || c2.isPrimitive())
62 {
63 // REVISIT: we could try to autoconvert to Object or something appropriate
64 throw new IllegalArgumentException("incompatible types " + c1 + " and " + c2);
65 }
66
67 // REVISIT: we could try to find a common supper class or interface
68 return Object.class;
69 }
70
71 /**
72 * Concatenates two arrays into one. If arr1 is null or empty, returns arr2.
73 * If arr2 is null or empty, returns arr1. May return null if both arrays are null,
74 * or one is empty and the other null. <br>
75 * The concatenated array has componentType which is compatible with both input arrays (or Object[])
76 *
77 * @param arr1 input array
78 * @param arr2 input array
79 *
80 * @return Object the concatenated array, elements of arr1 first
81 */
82 public static Object concat(Object arr1, Object arr2)
83 {
84 int len1 = (arr1 == null) ? (-1) : Array.getLength(arr1);
85
86 if (len1 <= 0)
87 {
88 return arr2;
89 }
90
91 int len2 = (arr2 == null) ? (-1) : Array.getLength(arr2);
92
93 if (len2 <= 0)
94 {
95 return arr1;
96 }
97
98 Class commonComponentType =
99 commonClass(arr1.getClass().getComponentType(), arr2.getClass().getComponentType());
100 Object newArray = Array.newInstance(commonComponentType, len1 + len2);
101 System.arraycopy(arr1, 0, newArray, 0, len1);
102 System.arraycopy(arr2, 0, newArray, len1, len2);
103
104 return newArray;
105 }
106
107 /**
108 * Concatenates arrays into one. Any null or empty arrays are ignored.
109 * If all arrays are null or empty, returns null.
110 * Elements will be ordered in the order in which the arrays are supplied.
111 *
112 * @param arrs array of arrays
113 * @return the concatenated array
114 */
115 public static Object concat(Object[] arrs)
116 {
117 int totalLen = 0;
118 Class commonComponentType = null;
119 for (int i = 0, len = arrs.length; i < len; i++)
120 {
121 // skip all null arrays
122 if (arrs[i] == null)
123 {
124 continue;
125 }
126
127 int arrayLen = Array.getLength(arrs[i]);
128
129 // skip all empty arrays
130 if (arrayLen == 0)
131 {
132 continue;
133 }
134
135 totalLen += arrayLen;
136
137 Class componentType = arrs[i].getClass().getComponentType();
138 commonComponentType =
139 (commonComponentType == null) ? componentType
140 : commonClass(commonComponentType, componentType);
141 }
142
143 if (commonComponentType == null)
144 {
145 return null;
146 }
147
148 return concat(Array.newInstance(commonComponentType, totalLen), totalLen, arrs);
149 }
150
151 public static Object concat(Object toArray, int totalLen, Object[] arrs)
152 {
153 if (totalLen == 0)
154 {
155 // Should we allocate an empty array instead?
156 return toArray;
157 }
158
159 if (totalLen > Array.getLength(toArray))
160 {
161 toArray = Array.newInstance(toArray.getClass().getComponentType(), totalLen);
162 }
163
164 for (int i = 0, len = arrs.length, offset = 0; i < len; i++)
165 {
166 final Object arr = arrs[i];
167 if (arr != null)
168 {
169 int arrayLen = Array.getLength(arr);
170 if (arrayLen > 0)
171 {
172 System.arraycopy(arr, 0, toArray, offset, arrayLen);
173 offset += arrayLen;
174 }
175 }
176 }
177
178 return toArray;
179 }
180
181 public static Object concat(Object arr1, Object arr2, Object arr3)
182 {
183 return concat(new Object[] {arr1, arr2, arr3});
184 }
185
186 public static Object concat(Object arr1, Object arr2, Object arr3, Object arr4)
187 {
188 return concat(new Object[] {arr1, arr2, arr3, arr4});
189 }
190
191 public static Object concat(Object arr1, Object arr2, Object arr3, Object arr4, Object arr5)
192 {
193 return concat(new Object[] {arr1, arr2, arr3, arr4, arr5});
194 }
195
196 public static Object concatSameType(Object toArray, Object[] arrs)
197 {
198 int totalLen = 0;
199 for (int i = 0, len = arrs.length; i < len; i++)
200 {
201 if (arrs[i] != null)
202 {
203 totalLen += Array.getLength(arrs[i]);
204 }
205 }
206
207 return concat(toArray, totalLen, arrs);
208 }
209
210
211
212 public static boolean contains(Object[] array, Object value)
213 {
214 if (array == null || array.length == 0)
215 {
216 return false;
217 }
218
219 for (int i = 0; i < array.length; i++)
220 {
221 Object o = array[i];
222 if ((o == null && value == null) ||
223 (o != null && o.equals(value)))
224 {
225 return true;
226 }
227 }
228
229 return false;
230 }
231
232
233
234 // public static void main(String[] args)
235 // {
236 // // test code
237 // System.out.println(concat(new String[] {"a"}, new Object[] {"b"}));
238 // System.out.println(concat(new String[] {"a"}, new Integer[] {new Integer(0)}));
239 // System.out.println(concat(new Number[] {new Double(0)}, new Integer[] {new Integer(0)}));
240 // System.out.println(concat(new Number[] {}, new Integer[0]));
241 // System.out.println(concat(new Integer[] {new Integer(0)}, new Number[0]));
242 // System.out.println(concat(new Integer[] {new Integer(0)}, new Number[0], new int[0]));
243 // System.out.println(
244 // concat(new Integer[] {new Integer(0)}, new Number[] {new Double(0)}, new int[0]));
245 // System.out.println(concat(new int[] {1}, new int[] {2}));
246 // System.out.println(
247 // concat(new String[] {"a"}, new Integer[] {new Integer(0)}, new Object[] {"b"}));
248 // System.out.println(
249 // concat(new String[0], new Object[] {new String[] {"a"}, new Object[] {"b"}}));
250 // System.out.println(
251 // concat(new Integer[] {new Integer(0)}, new Number[] {new Double(0)}, new int[] {1}));
252 // }
253 }