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

se.l4.silo.structured.DefaultObjectEntity Maven / Gradle / Ivy

The newest version!
package se.l4.silo.structured;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.Optional;
import java.util.function.Function;

import se.l4.commons.serialization.Serializer;
import se.l4.commons.serialization.format.BinaryInput;
import se.l4.commons.serialization.format.StreamingInput;
import se.l4.silo.FetchResult;
import se.l4.silo.StorageException;
import se.l4.silo.query.Query;
import se.l4.silo.query.QueryResult;
import se.l4.silo.query.QueryRunner;
import se.l4.silo.query.QueryType;

/**
 * Implementation of {@link ObjectEntity}.
 *
 * @author Andreas Holstenson
 *
 * @param 
 */
public class DefaultObjectEntity
	implements ObjectEntity
{
	private final StructuredEntity parent;
	private final Serializer serializer;
	private final Function identityMapper;

	public DefaultObjectEntity(
		StructuredEntity parent,
		Serializer serializer,
		Function identityMapper)
	{
		this.parent = parent;
		this.serializer = serializer;
		this.identityMapper = identityMapper;
	}

	@Override
	public String getName()
	{
		return parent.getName();
	}

	@Override
	public Optional get(Object id)
	{
		try(FetchResult fr = parent.get(id))
		{
			Iterator it = fr.iterator();
			if(! it.hasNext())
			{
				return Optional.empty();
			}

			try(StreamingInput in = it.next())
			{
				return Optional.of(serializer.read(in));
			}
			catch(IOException e)
			{
				throw new StorageException("Unable to read object; " + e.getMessage(), e);
			}
		}
	}

	@Override
	public void deleteViaId(Object id)
	{
		parent.delete(id);
	}

	@Override
	public void delete(T object)
	{
		Object id = identityMapper.apply(object);
		parent.delete(id);
	}

	@Override
	public void store(T data)
	{
		try
		{
			Object id = identityMapper.apply(data);
			byte[] binary = serializer.toBytes(data);
			parent.store(id, new BinaryInput(new ByteArrayInputStream(binary)));
		}
		catch(Exception e)
		{
			throw new StorageException("Unable to store object; " + e.getMessage(), e);
		}
	}

	@Override
	public > Q query(String engine, QueryType type)
	{
		return parent.query(engine, new TransformingQueryType(type, this::transform));
	}

	@Override
	public FetchResult stream()
	{
		return parent.stream().transform(this::transform);
	}

	private T transform(StreamingInput in)
	{
		try
		{
			return serializer.read(in);
		}
		catch(IOException e)
		{
			throw new StorageException("Unable to read object; " + e.getMessage(), e);
		}
		finally
		{
			try
			{
				in.close();
			}
			catch(Exception e)
			{
			}
		}
	}

	private static class TransformingQueryType>
		implements QueryType
	{
		private QueryType qt;
		private Function translator;

		@SuppressWarnings("unchecked")
		public TransformingQueryType(QueryType qt, Function translator)
		{
			this.qt = (QueryType) qt;
			this.translator = translator;
		}

		@Override
		public Q create(QueryRunner runner)
		{
			return qt.create((data, translator) -> {
				return runner.fetchResults(data, in -> {
					return translator.apply(new TransformedQueryResult<>(in, this.translator));
				});
			});
		}
	}

	private static class TransformedQueryResult
		implements QueryResult
	{
		private final QueryResult other;
		private final Function translator;

		public TransformedQueryResult(QueryResult other, Function translator)
		{
			this.other = other;
			this.translator = translator;
		}

		@Override
		public To getData()
		{
			return translator.apply(other.getData());
		}

		@Override
		public  R getMetadata(String key)
		{
			return other.getMetadata(key);
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy