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
021package org.granite.messaging.amf.io.convert.impl;
022
023import java.lang.reflect.Array;
024import java.lang.reflect.Type;
025import java.util.Collection;
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 Collection2Array extends Converter {
036
037    public Collection2Array(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 instanceof Collection<?>))
052            return false;
053
054        if (targetComponentType.equals(Object.class))
055            return true;
056
057        Converter itemConverter = null;
058        for (Object item : (Collection<?>)value) {
059
060            if (itemConverter == null)
061                itemConverter = converters.getConverter(item, targetComponentType);
062            else if (!itemConverter.canConvert(item, targetComponentType))
063                itemConverter = converters.getConverter(item, targetComponentType);
064
065            if (itemConverter == null)
066                return false;
067        }
068
069        return true;
070    }
071
072    @Override
073        protected Object internalConvert(Object value, Type targetType) {
074
075        if (value == null)
076            return null;
077
078        if (value instanceof Collection<?>) {
079            Collection<?> c = (Collection<?>)value;
080
081            Type targetComponentType = ArrayUtil.getComponentType(targetType);
082            if (targetComponentType != null) {
083                Converter itemConverter = null;
084                final Object array = ArrayUtil.newArray(targetComponentType, c.size());
085                int i = 0;
086                for (Object item : c) {
087
088                    if (itemConverter == null)
089                        itemConverter = converters.getConverter(item, targetComponentType);
090                    else if (!itemConverter.canConvert(item, targetComponentType))
091                        itemConverter = converters.getConverter(item, targetComponentType);
092
093                    if (itemConverter == null)
094                        throw new IllegalConverterArgumentException(this, value, targetType);
095
096                    Array.set(array, i++, itemConverter.convert(item, targetComponentType));
097                }
098                return array;
099            }
100        }
101
102        throw new IllegalConverterArgumentException(this, value, targetType);
103    }
104}