001    /*
002      GRANITE DATA SERVICES
003      Copyright (C) 2011 GRANITE DATA SERVICES S.A.S.
004    
005      This file is part of Granite Data Services.
006    
007      Granite Data Services is free software; you can redistribute it and/or modify
008      it under the terms of the GNU Library General Public License as published by
009      the Free Software Foundation; either version 2 of the License, or (at your
010      option) any later version.
011    
012      Granite Data Services is distributed in the hope that it will be useful, but
013      WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014      FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015      for more details.
016    
017      You should have received a copy of the GNU Library General Public License
018      along with this library; if not, see <http://www.gnu.org/licenses/>.
019    */
020    
021    package org.granite.messaging.amf.io.convert.impl;
022    
023    import java.lang.reflect.Array;
024    import java.lang.reflect.Type;
025    
026    import org.granite.messaging.amf.io.convert.Converter;
027    import org.granite.messaging.amf.io.convert.Converters;
028    import org.granite.messaging.amf.io.convert.IllegalConverterArgumentException;
029    import org.granite.util.ArrayUtil;
030    
031    /**
032     * @author Franck WOLFF
033     */
034    public class Array2Array extends Converter {
035    
036        public Array2Array(Converters converters) {
037            super(converters);
038        }
039    
040        @Override
041            protected boolean internalCanConvert(Object value, Type targetType) {
042            Type targetComponentType = ArrayUtil.getComponentType(targetType);
043    
044            if (targetComponentType == null)
045                return false; // not an array.
046    
047            if (value == null)
048                return true;
049    
050            if (!value.getClass().isArray())
051                return false;
052    
053            Class<?> oComponentClass = value.getClass().getComponentType();
054            if (targetComponentType.equals(oComponentClass))
055                return true;
056    
057            Converter itemConverter = null;
058            final int length = Array.getLength(value);
059            for (int i = 0; i < length; i++) {
060                Object item = Array.get(value, i);
061    
062                if (itemConverter == null)
063                    itemConverter = converters.getConverter(item, targetComponentType);
064                else if (!itemConverter.canConvert(item, targetComponentType))
065                    itemConverter = converters.getConverter(item, targetComponentType);
066    
067                if (itemConverter == null)
068                    return false;
069            }
070    
071            return true;
072        }
073    
074        @Override
075            protected Object internalConvert(Object value, Type targetType) {
076    
077            if (value == null)
078                return null;
079    
080            if (value.getClass().isArray()) {
081                Type targetComponentType = ArrayUtil.getComponentType(targetType);
082                if (targetComponentType != null) {
083                    Class<?> oComponentClass = value.getClass().getComponentType();
084                    if (targetComponentType.equals(oComponentClass))
085                        return value;
086    
087                    Converter itemConverter = null;
088                    final int length = Array.getLength(value);
089                    final Object array = ArrayUtil.newArray(targetComponentType, length);
090                    for (int i = 0; i < length; i++) {
091                        Object item = Array.get(value, i);
092    
093                        if (itemConverter == null)
094                            itemConverter = converters.getConverter(item, targetComponentType);
095                        else if (!itemConverter.canConvert(item, targetComponentType))
096                            itemConverter = converters.getConverter(item, targetComponentType);
097    
098                        if (itemConverter == null)
099                            throw new IllegalConverterArgumentException(this, value, targetType);
100    
101                        Array.set(array, i, itemConverter.convert(item, targetComponentType));
102                    }
103                    return array;
104                }
105            }
106    
107            throw new IllegalConverterArgumentException(this, value, targetType);
108        }
109    }