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     */
022    package org.granite.messaging.amf.io.convert.impl;
023    
024    import java.lang.reflect.Array;
025    import java.lang.reflect.Type;
026    import java.util.Collection;
027    
028    import org.granite.messaging.amf.io.convert.Converter;
029    import org.granite.messaging.amf.io.convert.Converters;
030    import org.granite.messaging.amf.io.convert.IllegalConverterArgumentException;
031    import org.granite.util.ArrayUtil;
032    
033    /**
034     * @author Franck WOLFF
035     */
036    public class Collection2Array extends Converter {
037    
038        public Collection2Array(Converters converters) {
039            super(converters);
040        }
041    
042        @Override
043            protected boolean internalCanConvert(Object value, Type targetType) {
044            Type targetComponentType = ArrayUtil.getComponentType(targetType);
045    
046            if (targetComponentType == null)
047                return false; // not an array.
048    
049            if (value == null)
050                return true;
051    
052            if (!(value instanceof Collection<?>))
053                return false;
054    
055            if (targetComponentType.equals(Object.class))
056                return true;
057    
058            Converter itemConverter = null;
059            for (Object item : (Collection<?>)value) {
060    
061                if (itemConverter == null)
062                    itemConverter = converters.getConverter(item, targetComponentType);
063                else if (!itemConverter.canConvert(item, targetComponentType))
064                    itemConverter = converters.getConverter(item, targetComponentType);
065    
066                if (itemConverter == null)
067                    return false;
068            }
069    
070            return true;
071        }
072    
073        @Override
074            protected Object internalConvert(Object value, Type targetType) {
075    
076            if (value == null)
077                return null;
078    
079            if (value instanceof Collection<?>) {
080                Collection<?> c = (Collection<?>)value;
081    
082                Type targetComponentType = ArrayUtil.getComponentType(targetType);
083                if (targetComponentType != null) {
084                    Converter itemConverter = null;
085                    final Object array = ArrayUtil.newArray(targetComponentType, c.size());
086                    int i = 0;
087                    for (Object item : c) {
088    
089                        if (itemConverter == null)
090                            itemConverter = converters.getConverter(item, targetComponentType);
091                        else if (!itemConverter.canConvert(item, targetComponentType))
092                            itemConverter = converters.getConverter(item, targetComponentType);
093    
094                        if (itemConverter == null)
095                            throw new IllegalConverterArgumentException(this, value, targetType);
096    
097                        Array.set(array, i++, itemConverter.convert(item, targetComponentType));
098                    }
099                    return array;
100                }
101            }
102    
103            throw new IllegalConverterArgumentException(this, value, targetType);
104        }
105    }