/* * Copyright (c) 2015-2016, Christoph Engelbert (aka noctarius) and * contributors. All rights reserved. * * 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.noctarius.tengi.spi.serialization; import com.noctarius.tengi.core.config.MarshallerConfiguration; import com.noctarius.tengi.core.serialization.codec.Decoder; import com.noctarius.tengi.core.serialization.codec.Encoder; import com.noctarius.tengi.spi.buffer.MemoryBuffer; import com.noctarius.tengi.spi.serialization.codec.AutoClosableDecoder; import com.noctarius.tengi.spi.serialization.codec.AutoClosableEncoder; import com.noctarius.tengi.spi.serialization.impl.DefaultProtocol; import com.noctarius.tengi.spi.serialization.impl.DefaultSerializer; import java.util.Collection; /** * The <tt>Serializer</tt> interface is the entry point into any serialization process. * It provides functionality to directly read or write objects as well as offering access * to {@link com.noctarius.tengi.core.serialization.codec.Encoder}s and * {@link com.noctarius.tengi.core.serialization.codec.Decoder}s, both in an auto-closable * fashion. */ public interface Serializer { /** * Returns the bound <tt>Protocol</tt> implementation. * * @return the underlying <tt>Protocol</tt> */ Protocol getProtocol(); /** * <p>Reads the content of a <b>non-null</b> object from the underlying byte-stream buffer. The content itself * will be deserialized using a registered {@link com.noctarius.tengi.core.serialization.marshaller.Marshaller} * or as an internally handled object type. It is up to the * {@link com.noctarius.tengi.spi.serialization.codec.Codec} implementation on how to read a type tag for the * object inside the data stream.</p> * <p>If the underlying buffer is to small to read all of the content, an * {@link java.lang.IndexOutOfBoundsException} is thrown.</p> * <p><b>The given <tt>fieldName</tt> is strictly used for debugging purpose.</b> The implementation * of the {@link com.noctarius.tengi.core.serialization.debugger.SerializationDebugger} might have * decided to write the value to the stream but this is not required.</p> * * @param <O> the type of the object to write * @param fieldName the name of the field to be read, strictly for debugging purpose only * @param decoder the <tt>Decoder</tt> to read the object from * @return the non-null object value read from the buffer * @throws java.lang.IndexOutOfBoundsException whenever the buffer is too small to read all elements * @throws java.lang.Exception whenever any other unexpected situation occurs */ <O> O readObject(String fieldName, Decoder decoder) throws Exception; /** * <p>Transfers a <b>non-null</b> object to a new {@link com.noctarius.tengi.spi.buffer.MemoryBuffer} and * returns this buffer instance. The content itself will be serialized using a registered * {@link com.noctarius.tengi.core.serialization.marshaller.Marshaller} ir as an internally handled object * type. It is up to the {@link com.noctarius.tengi.spi.serialization.codec.Codec} implementation on how * to tag the type of the object inside the data stream.</p> * <p>If the underlying buffer is to small to store all of the content, an * {@link java.lang.IndexOutOfBoundsException} is thrown.</p> * <p><b>The given <tt>fieldName</tt> is strictly used for debugging purpose.</b> The implementation * of the {@link com.noctarius.tengi.core.serialization.debugger.SerializationDebugger} might decide * to write the value to the stream but is not required to.</p> * * @param <O> the type of the object to write * @param object the object value to be written to the buffer * @param fieldName the name of the field to be written, strictly for debugging purpose only * @return the <tt>MemoryBuffer</tt> instance that contains the objects content * @throws java.lang.IndexOutOfBoundsException whenever the buffer is too small to store all elements * @throws java.lang.NullPointerException whenever the given object is null * @throws java.lang.Exception whenever any other unexpected situation occurs */ <O> MemoryBuffer writeObject(String fieldName, O object) throws Exception; /** * <p>Transfers a <b>non-null</b> object to the underlying byte-stream buffer. The content itself will * be serialized using a registered {@link com.noctarius.tengi.core.serialization.marshaller.Marshaller} * or as an internally handled object type. It is up to the * {@link com.noctarius.tengi.spi.serialization.codec.Codec} implementation on how to tag the type of the * object inside the data stream.</p> * <p>If the underlying buffer is to small to store all of the content, an * {@link java.lang.IndexOutOfBoundsException} is thrown.</p> * <p><b>The given <tt>fieldName</tt> is strictly used for debugging purpose.</b> The implementation * of the {@link com.noctarius.tengi.core.serialization.debugger.SerializationDebugger} might decide * to write the value to the stream but is not required to.</p> * * @param <O> the type of the object to write * @param object the object value to be written to the buffer * @param fieldName the name of the field to be written, strictly for debugging purpose only * @param encoder the <tt>Encoder</tt> to write the object to * @throws java.lang.IndexOutOfBoundsException whenever the buffer is too small to store all elements * @throws java.lang.NullPointerException whenever the given object is null * @throws java.lang.Exception whenever any other unexpected situation occurs */ <O> void writeObject(String fieldName, O object, Encoder encoder) throws Exception; /** * Returns an {@link com.noctarius.tengi.spi.serialization.codec.AutoClosableEncoder} instance bound * to the underlying protocol and the given {@link com.noctarius.tengi.spi.buffer.MemoryBuffer}. * * @param memoryBuffer the <tt>MemoryBuffer</tt> to bind * @return the auto-closable <tt>Encoder</tt> instance */ AutoClosableEncoder retrieveEncoder(MemoryBuffer memoryBuffer); /** * Returns an {@link com.noctarius.tengi.spi.serialization.codec.AutoClosableDecoder} instance bound * to the underlying protocol and the given {@link com.noctarius.tengi.spi.buffer.MemoryBuffer}. * * @param memoryBuffer the <tt>MemoryBuffer</tt> to bind * @return the auto-closable <tt>Decoder</tt> instance */ AutoClosableDecoder retrieveDecoder(MemoryBuffer memoryBuffer); /** * Creates a new <tt>Serializer</tt> instance with the default * {@link com.noctarius.tengi.spi.serialization.Protocol} implementation and binds the given * {@link com.noctarius.tengi.core.config.MarshallerConfiguration}s collection. * * @param marshallerConfigurations the <tt>MarshallerConfiguration</tt> collection to bind * @return the <tt>Serializer</tt> instance with bound <tt>Marshaller</tt>s */ public static Serializer create(Collection<MarshallerConfiguration> marshallerConfigurations) { return create(new DefaultProtocol(marshallerConfigurations)); } /** * Creates a new <tt>Serializer</tt> instance with the given * {@link com.noctarius.tengi.spi.serialization.Protocol} implementation. * * @param protocol the <tt>Protocol</tt> instance to bind * @return the <tt>Serializer</tt> instance bound to the given <tt>Protocol</tt> */ public static Serializer create(Protocol protocol) { return new DefaultSerializer(protocol); } }