/* * Copyright (c) www.bugull.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.bugull.mongo.encoder; import com.bugull.mongo.annotations.Default; import com.bugull.mongo.annotations.EmbedList; import com.bugull.mongo.utils.FieldUtil; import com.bugull.mongo.utils.MapperUtil; import com.mongodb.DBObject; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.GenericArrayType; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; /** * * @author Frank Wen([email protected]) */ @SuppressWarnings("unchecked") public class EmbedListEncoder extends AbstractEncoder{ public EmbedListEncoder(Object obj, Field field){ super(obj, field); } @Override public String getFieldName() { String fieldName = field.getName(); EmbedList embedList = field.getAnnotation(EmbedList.class); String name = embedList.name(); if(!name.equals(Default.NAME)){ fieldName = name; } return fieldName; } @Override public Object encode() { Object result = null; Class<?> type = field.getType(); if(type.isArray()){ Class<?> comType = type.getComponentType(); if(comType.isEnum()){ result = encodeEnumArray(value); }else{ result = encodeArray(value); } }else{ ParameterizedType paramType = (ParameterizedType)field.getGenericType(); Type[] types = paramType.getActualTypeArguments(); int len = types.length; if(len == 1){ Class<?> realCls = (Class)types[0]; if(realCls.isEnum()){ result = encodeEnumCollection(value); }else{ result = encodeCollection(value); } }else if(len == 2){ result = encodeMap(); } } return result; } private Object encodeEnumArray(Object arr){ int len = Array.getLength(arr); List<String> result = new ArrayList<>(); for(int i=0; i<len; i++){ Object o = Array.get(arr, i); if(o != null){ result.add(o.toString()); } } return result; } private Object encodeArray(Object arr){ int len = Array.getLength(arr); List<DBObject> result = new ArrayList<>(); for(int i=0; i<len; i++){ Object o = Array.get(arr, i); if(o != null){ result.add(MapperUtil.toDBObject(o)); } } return result; } private Object encodeEnumCollection(Object coll){ List<String> result = new ArrayList<>(); Collection collection = (Collection)coll; for(Object o : collection){ if(o != null){ result.add(o.toString()); } } return result; } private Object encodeCollection(Object coll){ List<DBObject> result = new ArrayList<>(); Collection collection = (Collection)coll; for(Object o : collection){ if(o != null){ result.add(MapperUtil.toDBObject(o)); } } return result; } private Object encodeMap(){ //for Map<K,V>, first to check the type of V ParameterizedType paramType = (ParameterizedType)field.getGenericType(); Type[] types = paramType.getActualTypeArguments(); boolean isArray = false; boolean isCollection = false; boolean isSingle = false; if(types[1] instanceof GenericArrayType){ isArray = true; }else if(types[1] instanceof ParameterizedType){ isCollection = true; }else{ //in JDK8, type[1] of array, is a class, not array Class<?> actualType = FieldUtil.getClassOfType(types[1]); if(actualType.isArray()){ isArray = true; }else{ isSingle = true; } } //encode value by different type of V Map map = (Map)value; Map result = new HashMap(); for(Object key : map.keySet()){ Object entryValue = map.get(key); if(entryValue == null){ result.put(key, null); continue; } if(isSingle){ result.put(key, MapperUtil.toDBObject(entryValue)); }else if(isArray){ result.put(key, encodeArray(entryValue)); }else if(isCollection){ result.put(key, encodeCollection(entryValue)); } } return result; } }