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.Type;
025 import java.lang.reflect.WildcardType;
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.TypeUtil;
032 import org.granite.util.CollectionUtil;
033
034 /**
035 * @author Franck WOLFF
036 */
037 public class Collection2Collection extends Converter {
038
039 public Collection2Collection(Converters converters) {
040 super(converters);
041 }
042
043 @Override
044 protected boolean internalCanConvert(Object value, Type targetType) {
045
046 Type targetComponentType = CollectionUtil.getComponentType(targetType);
047 if (targetComponentType == null)
048 return false; // not a collection.
049
050 if (value == null)
051 return true;
052
053 if (!(value instanceof Collection<?>))
054 return false;
055
056 if (targetComponentType.equals(Object.class) || targetComponentType instanceof WildcardType)
057 return true;
058
059 Converter itemConverter = null;
060 for (Object item : (Collection<?>)value) {
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 instanceof Collection<?>) {
081 Collection<?> c = (Collection<?>)value;
082
083 Type targetComponentType = CollectionUtil.getComponentType(targetType);
084 if (targetComponentType != null) {
085
086 Class<?> targetClass = TypeUtil.classOfType(targetType);
087 if (targetClass.isInstance(value)) {
088 if (targetComponentType.equals(Object.class) || targetComponentType instanceof WildcardType)
089 return value;
090
091 if (targetComponentType instanceof Class<?>) {
092 boolean check = true;
093 for (Object e : c) {
094 if (!((Class<?>)targetComponentType).isInstance(e)) {
095 check = false;
096 break;
097 }
098 }
099 if (check)
100 return value;
101 }
102 }
103
104 Collection<Object> targetInstance = null;
105 try {
106 targetInstance = CollectionUtil.newCollection(targetClass, c.size());
107 } catch (Exception e) {
108 throw new IllegalConverterArgumentException(this, value, targetType, e);
109 }
110
111 Converter itemConverter = null;
112 for (Object item : c) {
113
114 if (itemConverter == null)
115 itemConverter = converters.getConverter(item, targetComponentType);
116 else if (!itemConverter.canConvert(item, targetComponentType))
117 itemConverter = converters.getConverter(item, targetComponentType);
118
119 if (itemConverter == null)
120 throw new IllegalConverterArgumentException(this, value, targetType);
121
122 targetInstance.add(itemConverter.convert(item, targetComponentType));
123 }
124
125 return targetInstance;
126 }
127 }
128
129 throw new IllegalConverterArgumentException(this, value, targetType);
130 }
131 }