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.Type; 025import java.lang.reflect.WildcardType; 026import java.util.Collection; 027 028import org.granite.messaging.amf.io.convert.Converter; 029import org.granite.messaging.amf.io.convert.Converters; 030import org.granite.messaging.amf.io.convert.IllegalConverterArgumentException; 031import org.granite.util.TypeUtil; 032import org.granite.util.CollectionUtil; 033 034/** 035 * @author Franck WOLFF 036 */ 037public 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}