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

se.l4.commons.serialization.internal.reflection.FieldDefinition Maven / Gradle / Ivy

package se.l4.commons.serialization.internal.reflection;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Objects;

import com.google.common.base.Defaults;
import com.google.common.base.Throwables;

import se.l4.commons.serialization.SerializationException;
import se.l4.commons.serialization.Serializer;
import se.l4.commons.serialization.format.StreamingInput;
import se.l4.commons.serialization.format.StreamingOutput;
import se.l4.commons.serialization.format.Token;

/**
 * Definition of a field within a reflection serializer.
 *
 * @author Andreas Holstenson
 *
 */
@SuppressWarnings("rawtypes")
public class FieldDefinition
{
	private final Field field;
	private final Serializer serializer;
	private final String name;
	private final Class type;
	private final boolean readOnly;
	private final boolean skipIfDefault;
	private final boolean nullHandling;

	public FieldDefinition(Field field, String name, Serializer serializer, Class type, boolean skipIfDefault)
	{
		this.field = field;
		this.name = name;
		this.serializer = serializer;
		this.type = type;
		this.skipIfDefault = skipIfDefault;
		this.nullHandling = serializer instanceof Serializer.NullHandling;
		readOnly = Modifier.isFinal(field.getModifiers());
	}

	public String getName()
	{
		return name;
	}

	public Serializer getSerializer()
	{
		return serializer;
	}

	public boolean isSkipIfDefault()
	{
		return skipIfDefault;
	}

	public boolean isReadOnly()
	{
		return readOnly;
	}

	public Class getType()
	{
		return type;
	}

	public Object read(StreamingInput in)
		throws IOException
	{
		if(in.peek() == Token.NULL)
		{
			if(nullHandling)
			{
				// Let the serializer handle the null value
				return serializer.read(in);
			}

			// Consume and return null
			in.next();
			return Defaults.defaultValue(type);
		}

		return serializer.read(in);
	}

	public void read(Object target, StreamingInput in)
		throws IOException
	{
		set(target, read(in));
	}

	public void set(Object target, Object value)
		throws IOException
	{
		try
		{
			if(value == null && type.isPrimitive())
			{
				value = Defaults.defaultValue(type);
			}

			field.set(target, value);
		}
		catch(Exception e)
		{
			Throwables.throwIfUnchecked(e);

			throw new SerializationException("Unable to read object; " + e.getMessage(), e);
		}
	}

	public Object getValue(Object target)
	{
		try
		{
			return field.get(target);
		}
		catch(IllegalArgumentException e)
		{
			throw new SerializationException("Unable to write object; " + e.getMessage(), e);
		}
		catch(IllegalAccessException e)
		{
			throw new SerializationException("Unable to write object; " + e.getMessage(), e);
		}

	}

	@SuppressWarnings("unchecked")
	public void write(Object target, StreamingOutput stream)
		throws IOException
	{
		Object value = getValue(target);

		if(skipIfDefault)
		{
			Object defaultValue = Defaults.defaultValue(type);
			if(Objects.equals(defaultValue, value))
			{
				// Write nothing as the default value and our value matches
				return;
			}
		}

		if(value == null)
		{
			if(nullHandling)
			{
				serializer.write(null, name, stream);
			}
			else
			{
				stream.writeNull(name);
			}
		}
		else
		{
			serializer.write(value, name, stream);
		}
	}

	public Annotation[] getHints()
	{
		return field.getAnnotations();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy