View Javadoc

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.commons.util;
20  
21  import java.lang.reflect.Array;
22  
23  /**
24   * Utility class for managing arrays
25   *
26   * @since 1.0.1
27   * @author Anton Koinov (latest modification by $Author: matzew $)
28   * @version $Revision: 557350 $ $Date: 2007-07-18 13:19:50 -0500 (miƩ, 18 jul 2007) $
29   */
30  public final 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      private 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     public static boolean contains(Object[] array, Object value)
211     {
212         if (array == null || array.length == 0)
213         {
214             return false;
215         }
216 
217         for (int i = 0; i < array.length; i++)
218         {
219             Object o = array[i];
220             if ((o == null && value == null) ||
221                 (o != null && o.equals(value)))
222             {
223                 return true;
224             }
225         }
226 
227         return false;
228     }
229 }