All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.esotericsoftware.kryo.serializers.CollectionSerializer Maven / Gradle / Ivy

/* Copyright (c) 2008, Nathan Sweet
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
 * conditions are met:
 * 
 * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
 * disclaimer in the documentation and/or other materials provided with the distribution.
 * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived
 * from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
 * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */

package com.esotericsoftware.kryo.serializers;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.Collection;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;

/** Serializes objects that implement the {@link Collection} interface.
 * 

* With the default constructor, a collection requires a 1-3 byte header and an extra 2-3 bytes is written for each element in the * collection. The alternate constructor can be used to improve efficiency to match that of using an array instead of a * collection. * @author Nathan Sweet */ public class CollectionSerializer extends Serializer { private boolean elementsCanBeNull = true; private Serializer serializer; private Class elementClass; private Class genericType; public CollectionSerializer () { } /** @see #setElementClass(Class, Serializer) */ public CollectionSerializer (Class elementClass, Serializer serializer) { setElementClass(elementClass, serializer); } /** @see #setElementClass(Class, Serializer) * @see #setElementsCanBeNull(boolean) */ public CollectionSerializer (Class elementClass, Serializer serializer, boolean elementsCanBeNull) { setElementClass(elementClass, serializer); this.elementsCanBeNull = elementsCanBeNull; } /** @param elementsCanBeNull False if all elements are not null. This saves 1 byte per element if elementClass is set. True if it * is not known (default). */ public void setElementsCanBeNull (boolean elementsCanBeNull) { this.elementsCanBeNull = elementsCanBeNull; } /** @param elementClass The concrete class of each element. This saves 1-2 bytes per element. Set to null if the class is not * known or varies per element (default). * @param serializer The serializer to use for each element. */ public void setElementClass (Class elementClass, Serializer serializer) { this.elementClass = elementClass; this.serializer = serializer; } public void setGenerics (Kryo kryo, Class[] generics) { genericType = null; if (generics != null && generics.length > 0) { if (kryo.isFinal(generics[0])) genericType = generics[0]; } } public void write (Kryo kryo, Output output, Collection collection) { int length = collection.size(); output.writeVarInt(length, true); Serializer serializer = this.serializer; if (genericType != null) { if (serializer == null) serializer = kryo.getSerializer(genericType); genericType = null; } if (serializer != null) { if (elementsCanBeNull) { for (Object element : collection) kryo.writeObjectOrNull(output, element, serializer); } else { for (Object element : collection) kryo.writeObject(output, element, serializer); } } else { for (Object element : collection) kryo.writeClassAndObject(output, element); } } /** Used by {@link #read(Kryo, Input, Class)} to create the new object. This can be overridden to customize object creation, eg * to call a constructor with arguments. The default implementation uses {@link Kryo#newInstance(Class)}. */ protected Collection create (Kryo kryo, Input input, Class type) { return kryo.newInstance(type); } public Collection read (Kryo kryo, Input input, Class type) { Collection collection = create(kryo, input, type); kryo.reference(collection); int length = input.readVarInt(true); if (collection instanceof ArrayList) ((ArrayList)collection).ensureCapacity(length); Class elementClass = this.elementClass; Serializer serializer = this.serializer; if (genericType != null) { if (serializer == null) { elementClass = genericType; serializer = kryo.getSerializer(genericType); } genericType = null; } if (serializer != null) { if (elementsCanBeNull) { for (int i = 0; i < length; i++) collection.add(kryo.readObjectOrNull(input, elementClass, serializer)); } else { for (int i = 0; i < length; i++) collection.add(kryo.readObject(input, elementClass, serializer)); } } else { for (int i = 0; i < length; i++) collection.add(kryo.readClassAndObject(input)); } return collection; } /** Used by {@link #copy(Kryo, Collection)} to create the new object. This can be overridden to customize object creation, eg to * call a constructor with arguments. The default implementation uses {@link Kryo#newInstance(Class)}. */ protected Collection createCopy (Kryo kryo, Collection original) { return kryo.newInstance(original.getClass()); } public Collection copy (Kryo kryo, Collection original) { Collection copy = createCopy(kryo, original); kryo.reference(copy); for (Object element : original) copy.add(kryo.copy(element)); return copy; } /** * Used to annotate fields that are collections with specific Kryo serializers * for their values. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface BindCollection { /** * Serializer to be used for values * * @return the class used for values serialization */ @SuppressWarnings("rawtypes") Class elementSerializer() default Serializer.class; /** * Class used for elements * * @return the class used for elements */ Class elementClass() default Object.class; /** * Indicates if elements can be null * * @return true, if elements can be null */ boolean elementsCanBeNull() default true; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy