/* * Copyright 1999-2017 Alibaba Group. * * 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.alibaba.fastjson.serializer; import java.io.IOException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.WildcardType; import java.util.Collection; import java.util.HashSet; import java.util.TreeSet; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; import com.alibaba.fastjson.util.TypeUtils; /** * @author wenshao[szujobs@hotmail.com] */ public class CollectionCodec implements ObjectSerializer, ObjectDeserializer { public final static CollectionCodec instance = new CollectionCodec(); public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { SerializeWriter out = serializer.out; if (object == null) { out.writeNull(SerializerFeature.WriteNullListAsEmpty); return; } Type elementType = null; if (out.isEnabled(SerializerFeature.WriteClassName)) { elementType = TypeUtils.getCollectionItemType(fieldType); } Collection<?> collection = (Collection<?>) object; SerialContext context = serializer.context; serializer.setContext(context, object, fieldName, 0); if (out.isEnabled(SerializerFeature.WriteClassName)) { if (HashSet.class == collection.getClass()) { out.append("Set"); } else if (TreeSet.class == collection.getClass()) { out.append("TreeSet"); } } try { int i = 0; out.append('['); for (Object item : collection) { if (i++ != 0) { out.append(','); } if (item == null) { out.writeNull(); continue; } Class<?> clazz = item.getClass(); if (clazz == Integer.class) { out.writeInt(((Integer) item).intValue()); continue; } if (clazz == Long.class) { out.writeLong(((Long) item).longValue()); if (out.isEnabled(SerializerFeature.WriteClassName)) { out.write('L'); } continue; } ObjectSerializer itemSerializer = serializer.getObjectWriter(clazz); itemSerializer.write(serializer, item, i - 1, elementType, 0); } out.append(']'); } finally { serializer.context = context; } } @SuppressWarnings({ "unchecked", "rawtypes" }) public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { if (parser.lexer.token() == JSONToken.NULL) { parser.lexer.nextToken(JSONToken.COMMA); return null; } if (type == JSONArray.class) { JSONArray array = new JSONArray(); parser.parseArray(array); return (T) array; } Collection list = TypeUtils.createCollection(type); Type itemType = TypeUtils.getCollectionItemType(type); parser.parseArray(itemType, list, fieldName); return (T) list; } public int getFastMatchToken() { return JSONToken.LBRACKET; } }