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