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

package org.apache.axis.utils;

import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;

public class ArrayUtil {
    private static class ArrayInfo {
        public Class componentType;
        public Class arrayType;
        public int dimension;       
    }
        
    public static class NonConvertable {
        public NonConvertable() { }            
    }
    
    /** An object indicating that the conversion is not possible */
    public static final NonConvertable NON_CONVERTABLE = new NonConvertable();
    
    /**
     * Convert ArrayOfT to T[].
     * @param obj        the object of type ArrayOfT to convert
     * @param arrayType  the destination array type
     * @return returns   the converted array object. 
     *                   If not convertable the original obj argument is returned.
     *                   If the obj is not type of ArrayOfT or the value is null, null is returned.
     */
    public static Object convertObjectToArray(Object obj, Class arrayType) {
        try {            
            ArrayInfo arri = new ArrayInfo();
            boolean rc = internalIsConvertable(obj.getClass(), arri, arrayType);
            if (rc == false) {
                return obj;
            }
                  
            BeanPropertyDescriptor pd = null;                   
            pd = getArrayComponentPD(obj.getClass());           
            if (pd == null) {
                return NON_CONVERTABLE;
            }
            Object comp = pd.get(obj);
            if (comp == null) {
                return null;
            }
            int arraylen = 0;
            if (comp.getClass().isArray()) {
                arraylen = Array.getLength(comp);
            } else {                
                return comp;
            }                       
                        
            int[] dims = new int[arri.dimension];
            dims[0] = arraylen;         
            Object targetArray = Array.newInstance(arri.componentType, dims);
            
            for (int i = 0; i < arraylen; i++) {
                Object subarray = Array.get(comp, i);
                Class subarrayClass = arrayType.getComponentType();
                Array.set(targetArray, i, convertObjectToArray(subarray, subarrayClass)); 
            }                        
            return targetArray;
        } catch (InvocationTargetException e) {         
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }       
        
        return null;
    }
    
    
    /**
     * Check if the clazz(perhaps ArrayOfT class) can be converted to T[].  
     * @param clazz      a class of ArrayOfT
     * @param arrayType  an array class (T[]) 
     * @return           true if converable, false if not
     */
    public static boolean isConvertable(Class clazz, Class arrayType) {
        ArrayInfo arrInfo = new ArrayInfo();
        return internalIsConvertable(clazz, arrInfo, arrayType);
    }
    
    /**
     * Check if the clazz(perhaps ArrayOfT class) can be converted to T[].  
     * @param clazz      a class of ArrayOfT
     * @param arri       convert result information
     * @param arrayType  an array class (T[]) 
     * @return           true if converable, false if not
     */
    private static boolean internalIsConvertable(Class clazz, ArrayInfo arri, Class arrayType) {
        BeanPropertyDescriptor pd = null, oldPd = null;
        if (!arrayType.isArray())
            return false;

        Class destArrCompType = arrayType.getComponentType();       
        Class src = clazz;
        int depth = 0;
        
        while (true) {
            pd = getArrayComponentPD(src);
            if (pd == null)
                break;
            depth++;            
            src = pd.getType();
            oldPd = pd;          
            if (destArrCompType.isAssignableFrom(src)) 
                break;                  
        }
        
        if (depth == 0 || oldPd.getType() == null) {           
            return false;
        }
                
        arri.componentType = oldPd.getType();
        arri.dimension = depth;
        
        Class componentType = oldPd.getType();
        int[] dims = new int[depth];
        Object array = Array.newInstance(componentType, dims);      
        arri.arrayType = array.getClass();
        
        if (arrayType.isAssignableFrom(arri.arrayType))
            return true;
        else
            return false;
    }
    
    /**
     * Gets the BeanPropertyDescriptor of ArrayOfT class's array member.
     * @param clazz a class of perhaps ArrayOfT type.
     * @return the BeanPropertyDescriptor. If the clazz is not type of ArrayOfT, null is returned.
     */
    private static BeanPropertyDescriptor getArrayComponentPD(Class clazz) {
        BeanPropertyDescriptor bpd = null;
        int count = 0;
        Class cls = clazz;
        while (!cls.getName().equals("java.lang.Object")) {                 
            BeanPropertyDescriptor bpds[] = BeanUtils.getPd(clazz);
            for (int i = 0; i < bpds.length; i++) {             
                BeanPropertyDescriptor pd = bpds[i];
                if (pd.isReadable() && pd.isWriteable() && pd.isIndexed()) {                    
                    count++;
                    if (count >= 2)
                        return null;
                    else
                        bpd = pd;
                }
            }
            cls = cls.getSuperclass();
        }
        
        if (count == 1) {
            return bpd;
        }
        else 
            return null;
    }   
    
    /**
     * Gets the dimension of arrayType
     * @param arrayType an array class
     * @return the dimension
     */
    public static int getArrayDimension(Class arrayType) {      
        if (!arrayType.isArray())
            return 0;
        int dim = 0;
        Class compType = arrayType;
        do {
            dim++;
            arrayType = compType;           
            compType = arrayType.getComponentType();
        } while (compType.isArray());
        
        return dim;             
    }
    
    private static Object createNewInstance(Class cls) throws InstantiationException, IllegalAccessException {
        Object obj = null;
        if (!cls.isPrimitive()) 
            obj = cls.newInstance();
        else {
            if (boolean.class.isAssignableFrom(cls)) 
                obj = new Boolean(false);
            else if (byte.class.isAssignableFrom(cls)) 
                obj = new Byte((byte)0);
            else if (char.class.isAssignableFrom(cls))
                obj = new Character('\u0000');
            else if (short.class.isAssignableFrom(cls))
                obj = new Short((short)0);
            else if (int.class.isAssignableFrom(cls))
                obj = new Integer(0);
            else if (long.class.isAssignableFrom(cls))
                obj = new Long(0L);
            else if (float.class.isAssignableFrom(cls))
                obj = new Float(0.0F);
            else if (double.class.isAssignableFrom(cls))
                obj = new Double(0.0D);
        }
        
        return obj;
    }
    
    /**
     * Convert an array object of which type is T[] to ArrayOfT class.
     * @param array     the array object
     * @param destClass the destination class
     * @return the object of type destClass if convertable, null if not.
     */
    public static Object convertArrayToObject(Object array, Class destClass) {        
        int dim = getArrayDimension(array.getClass());          
        if (dim == 0) {
            return null;
        }
        
        Object dest = null;
        
        try {           
            // create the destArray
            int arraylen = Array.getLength(array);
            Object destArray = null;
            Class destComp = null;
            if (!destClass.isArray()) {
                dest = destClass.newInstance();
                BeanPropertyDescriptor pd = getArrayComponentPD(destClass);
                if (pd == null)
                    return null;
            
                destComp = pd.getType();            
                destArray = Array.newInstance(destComp, arraylen);
                pd.set(dest, destArray);               
            } else {
                destComp = destClass.getComponentType();                               
                dest = Array.newInstance(destComp, arraylen);
                destArray = dest;
            }
            
            // iniialize the destArray
            for (int i = 0; i < arraylen; i++) {
                Array.set(destArray, i, createNewInstance(destComp));
            }                               
            
            // set the destArray 
            for (int i = 0; i < arraylen; i++) {
                Object comp = Array.get(array, i);

                if(comp == null)
                    continue;

                if (comp.getClass().isArray()) {
                    Class cls = Array.get(destArray, i).getClass();
                    Array.set(destArray, i, convertArrayToObject(comp, cls));
                }
                else {
                    Array.set(destArray, i, comp);                 
                }
            }
        } catch (IllegalAccessException ignore) {
            return null;
        } catch (InvocationTargetException ignore) {            
            return null;
        } catch (InstantiationException ignore) {
            return null;
        }
        
        return dest;
    }
}
