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    import java.util.Collection;
026    
027    import org.granite.messaging.amf.io.convert.Converter;
028    import org.granite.messaging.amf.io.convert.Converters;
029    import org.granite.messaging.amf.io.convert.IllegalConverterArgumentException;
030    import org.granite.util.ClassUtil;
031    import org.granite.util.CollectionUtil;
032    
033    /**
034     * @author Franck WOLFF
035     */
036    public class Array2Collection extends Converter {
037    
038        public Array2Collection(Converters converters) {
039            super(converters);
040        }
041    
042        @Override
043            protected boolean internalCanConvert(Object value, Type targetType) {
044    
045            Type targetComponentType = CollectionUtil.getComponentType(targetType);
046            if (targetComponentType == null)
047                return false; // not a collection.
048    
049            if (value == null)
050                return true;
051    
052            if (!value.getClass().isArray())
053                return false;
054    
055            Class<?> oComponentClass = value.getClass().getComponentType();
056            if (targetComponentType.equals(oComponentClass))
057                return true;
058    
059            Converter itemConverter = null;
060            final int length = Array.getLength(value);
061            for (int i = 0; i < length; i++) {
062                Object item = Array.get(value, i);
063    
064                if (itemConverter == null)
065                    itemConverter = converters.getConverter(item, targetComponentType);
066                else if (!itemConverter.canConvert(item, targetComponentType))
067                    itemConverter = converters.getConverter(item, targetComponentType);
068    
069                if (itemConverter == null)
070                    return false;
071            }
072    
073            return true;
074        }
075    
076        @Override
077            protected Object internalConvert(Object value, Type targetType) {
078    
079            if (value == null)
080                return null;
081    
082            if (value.getClass().isArray()) {
083                Type targetComponentType = CollectionUtil.getComponentType(targetType);
084    
085                if (targetComponentType != null) {
086                    final int length = Array.getLength(value);
087                    Class<?> targetClass = ClassUtil.classOfType(targetType);
088    
089                    Collection<Object> targetInstance = null;
090                    try {
091                        targetInstance = CollectionUtil.newCollection(targetClass, Array.getLength(value));
092                    } catch (Exception e) {
093                        throw new IllegalConverterArgumentException(this, value, targetType, e);
094                    }
095    
096                    Converter itemConverter = null;
097                    for (int i = 0; i < length; i++) {
098                        Object item = Array.get(value, i);
099    
100                        if (itemConverter == null)
101                            itemConverter = converters.getConverter(item, targetComponentType);
102                        else if (!itemConverter.canConvert(item, targetComponentType))
103                            itemConverter = converters.getConverter(item, targetComponentType);
104    
105                        if (itemConverter == null)
106                            throw new IllegalConverterArgumentException(this, value, targetType);
107    
108                        targetInstance.add(itemConverter.convert(item, targetComponentType));
109                    }
110    
111                    return targetInstance;
112                }
113            }
114    
115            throw new IllegalConverterArgumentException(this, value, targetType);
116        }
117    }