KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > utils > ArrayUtil


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.axis.utils;
18
19 import java.lang.reflect.Array JavaDoc;
20 import java.lang.reflect.InvocationTargetException JavaDoc;
21
22 public class ArrayUtil {
23     private static class ArrayInfo {
24         public Class JavaDoc componentType;
25         public Class JavaDoc arrayType;
26         public int dimension;
27     }
28         
29     public static class NonConvertable {
30         public NonConvertable() { }
31     }
32     
33     /** An object indicating that the conversion is not possible */
34     public static final NonConvertable NON_CONVERTABLE = new NonConvertable();
35     
36     /**
37      * Convert ArrayOfT to T[].
38      * @param obj the object of type ArrayOfT to convert
39      * @param arrayType the destination array type
40      * @return returns the converted array object.
41      * If not convertable the original obj argument is returned.
42      * If the obj is not type of ArrayOfT or the value is null, null is returned.
43      */

44     public static Object JavaDoc convertObjectToArray(Object JavaDoc obj, Class JavaDoc arrayType) {
45         try {
46             ArrayInfo arri = new ArrayInfo();
47             boolean rc = internalIsConvertable(obj.getClass(), arri, arrayType);
48             if (rc == false) {
49                 return obj;
50             }
51                   
52             BeanPropertyDescriptor pd = null;
53             pd = getArrayComponentPD(obj.getClass());
54             if (pd == null) {
55                 return NON_CONVERTABLE;
56             }
57             Object JavaDoc comp = pd.get(obj);
58             if (comp == null) {
59                 return null;
60             }
61             int arraylen = 0;
62             if (comp.getClass().isArray()) {
63                 arraylen = Array.getLength(comp);
64             } else {
65                 return comp;
66             }
67                         
68             int[] dims = new int[arri.dimension];
69             dims[0] = arraylen;
70             Object JavaDoc targetArray = Array.newInstance(arri.componentType, dims);
71             
72             for (int i = 0; i < arraylen; i++) {
73                 Object JavaDoc subarray = Array.get(comp, i);
74                 Class JavaDoc subarrayClass = arrayType.getComponentType();
75                 Array.set(targetArray, i, convertObjectToArray(subarray, subarrayClass));
76             }
77             return targetArray;
78         } catch (InvocationTargetException JavaDoc e) {
79             e.printStackTrace();
80         } catch (IllegalAccessException JavaDoc e) {
81             e.printStackTrace();
82         }
83         
84         return null;
85     }
86     
87     
88     /**
89      * Check if the clazz(perhaps ArrayOfT class) can be converted to T[].
90      * @param clazz a class of ArrayOfT
91      * @param arrayType an array class (T[])
92      * @return true if converable, false if not
93      */

94     public static boolean isConvertable(Class JavaDoc clazz, Class JavaDoc arrayType) {
95         ArrayInfo arrInfo = new ArrayInfo();
96         return internalIsConvertable(clazz, arrInfo, arrayType);
97     }
98     
99     /**
100      * Check if the clazz(perhaps ArrayOfT class) can be converted to T[].
101      * @param clazz a class of ArrayOfT
102      * @param arri convert result information
103      * @param arrayType an array class (T[])
104      * @return true if converable, false if not
105      */

106     private static boolean internalIsConvertable(Class JavaDoc clazz, ArrayInfo arri, Class JavaDoc arrayType) {
107         BeanPropertyDescriptor pd = null, oldPd = null;
108         if (!arrayType.isArray())
109             return false;
110
111         Class JavaDoc destArrCompType = arrayType.getComponentType();
112         Class JavaDoc src = clazz;
113         int depth = 0;
114         
115         while (true) {
116             pd = getArrayComponentPD(src);
117             if (pd == null)
118                 break;
119             depth++;
120             src = pd.getType();
121             oldPd = pd;
122             if (destArrCompType.isAssignableFrom(src))
123                 break;
124         }
125         
126         if (depth == 0 || oldPd.getType() == null) {
127             return false;
128         }
129                 
130         arri.componentType = oldPd.getType();
131         arri.dimension = depth;
132         
133         Class JavaDoc componentType = oldPd.getType();
134         int[] dims = new int[depth];
135         Object JavaDoc array = Array.newInstance(componentType, dims);
136         arri.arrayType = array.getClass();
137         
138         if (arrayType.isAssignableFrom(arri.arrayType))
139             return true;
140         else
141             return false;
142     }
143     
144     /**
145      * Gets the BeanPropertyDescriptor of ArrayOfT class's array member.
146      * @param clazz a class of perhaps ArrayOfT type.
147      * @return the BeanPropertyDescriptor. If the clazz is not type of ArrayOfT, null is returned.
148      */

149     private static BeanPropertyDescriptor getArrayComponentPD(Class JavaDoc clazz) {
150         BeanPropertyDescriptor bpd = null;
151         int count = 0;
152         Class JavaDoc cls = clazz;
153         while (!cls.getName().equals("java.lang.Object")) {
154             BeanPropertyDescriptor bpds[] = BeanUtils.getPd(clazz);
155             for (int i = 0; i < bpds.length; i++) {
156                 BeanPropertyDescriptor pd = bpds[i];
157                 if (pd.isReadable() && pd.isWriteable() && pd.isIndexed()) {
158                     count++;
159                     if (count >= 2)
160                         return null;
161                     else
162                         bpd = pd;
163                 }
164             }
165             cls = cls.getSuperclass();
166         }
167         
168         if (count == 1) {
169             return bpd;
170         }
171         else
172             return null;
173     }
174     
175     /**
176      * Gets the dimension of arrayType
177      * @param arrayType an array class
178      * @return the dimension
179      */

180     public static int getArrayDimension(Class JavaDoc arrayType) {
181         if (!arrayType.isArray())
182             return 0;
183         int dim = 0;
184         Class JavaDoc compType = arrayType;
185         do {
186             dim++;
187             arrayType = compType;
188             compType = arrayType.getComponentType();
189         } while (compType.isArray());
190         
191         return dim;
192     }
193     
194     private static Object JavaDoc createNewInstance(Class JavaDoc cls) throws InstantiationException JavaDoc, IllegalAccessException JavaDoc {
195         Object JavaDoc obj = null;
196         if (!cls.isPrimitive())
197             obj = cls.newInstance();
198         else {
199             if (boolean.class.isAssignableFrom(cls))
200                 obj = new Boolean JavaDoc(false);
201             else if (byte.class.isAssignableFrom(cls))
202                 obj = new Byte JavaDoc((byte)0);
203             else if (char.class.isAssignableFrom(cls))
204                 obj = new Character JavaDoc('\u0000');
205             else if (short.class.isAssignableFrom(cls))
206                 obj = new Short JavaDoc((short)0);
207             else if (int.class.isAssignableFrom(cls))
208                 obj = new Integer JavaDoc(0);
209             else if (long.class.isAssignableFrom(cls))
210                 obj = new Long JavaDoc(0L);
211             else if (float.class.isAssignableFrom(cls))
212                 obj = new Float JavaDoc(0.0F);
213             else if (double.class.isAssignableFrom(cls))
214                 obj = new Double JavaDoc(0.0D);
215         }
216         
217         return obj;
218     }
219     
220     /**
221      * Convert an array object of which type is T[] to ArrayOfT class.
222      * @param array the array object
223      * @param destClass the destination class
224      * @return the object of type destClass if convertable, null if not.
225      */

226     public static Object JavaDoc convertArrayToObject(Object JavaDoc array, Class JavaDoc destClass) {
227         int dim = getArrayDimension(array.getClass());
228         if (dim == 0) {
229             return null;
230         }
231         
232         Object JavaDoc dest = null;
233         
234         try {
235             // create the destArray
236
int arraylen = Array.getLength(array);
237             Object JavaDoc destArray = null;
238             Class JavaDoc destComp = null;
239             if (!destClass.isArray()) {
240                 dest = destClass.newInstance();
241                 BeanPropertyDescriptor pd = getArrayComponentPD(destClass);
242                 if (pd == null)
243                     return null;
244             
245                 destComp = pd.getType();
246                 destArray = Array.newInstance(destComp, arraylen);
247                 pd.set(dest, destArray);
248             } else {
249                 destComp = destClass.getComponentType();
250                 dest = Array.newInstance(destComp, arraylen);
251                 destArray = dest;
252             }
253             
254             // iniialize the destArray
255
for (int i = 0; i < arraylen; i++) {
256                 Array.set(destArray, i, createNewInstance(destComp));
257             }
258             
259             // set the destArray
260
for (int i = 0; i < arraylen; i++) {
261                 Object JavaDoc comp = Array.get(array, i);
262
263                 if(comp == null)
264                     continue;
265
266                 if (comp.getClass().isArray()) {
267                     Class JavaDoc cls = Array.get(destArray, i).getClass();
268                     Array.set(destArray, i, convertArrayToObject(comp, cls));
269                 }
270                 else {
271                     Array.set(destArray, i, comp);
272                 }
273             }
274         } catch (IllegalAccessException JavaDoc ignore) {
275             return null;
276         } catch (InvocationTargetException JavaDoc ignore) {
277             return null;
278         } catch (InstantiationException JavaDoc ignore) {
279             return null;
280         }
281         
282         return dest;
283     }
284 }
285
Popular Tags