package org.infinispan.marshall.persistence.impl;

import static org.infinispan.util.logging.Log.PERSISTENCE;

import org.infinispan.factories.scopes.Scope;
import org.infinispan.factories.scopes.Scopes;
import org.infinispan.marshall.persistence.PersistenceMarshaller;
import org.infinispan.marshall.protostream.impl.AbstractInternalProtoStreamMarshaller;
import org.infinispan.marshall.protostream.impl.MarshallableUserObject;
import org.infinispan.marshall.protostream.impl.SerializationContextRegistry.MarshallerType;
import org.infinispan.protostream.ImmutableSerializationContext;
import org.infinispan.protostream.SerializationContext;
import org.infinispan.protostream.SerializationContextInitializer;

/**
 * A Protostream based {@link PersistenceMarshaller} implementation that is responsible
 * for marshalling/unmarshalling objects which are to be persisted.
 * <p>
 * Known internal objects that are required by stores and loaders, such as {@link org.infinispan.metadata.EmbeddedMetadata},
 * are registered with this marshaller's {@link SerializationContext} so that they can be natively marshalled by the
 * underlying Protostream marshaller. If no entry exists in the {@link SerializationContext} for a given object, then
 * the marshalling of said object is delegated to a user marshaller if configured
 * ({@link org.infinispan.configuration.global.SerializationConfiguration#MARSHALLER}) and the generated bytes are wrapped
 * in a {@link MarshallableUserObject} object and marshalled by ProtoStream.
 *
 * @author Ryan Emerson
 * @since 10.0
 */
@Scope(Scopes.GLOBAL)
public class PersistenceMarshallerImpl extends AbstractInternalProtoStreamMarshaller implements PersistenceMarshaller {

   public PersistenceMarshallerImpl() {
      super(PERSISTENCE);
   }

   public ImmutableSerializationContext getSerializationContext() {
      return ctxRegistry.getPersistenceCtx();
   }

   @Override
   public void register(SerializationContextInitializer initializer) {
      ctxRegistry.addContextInitializer(MarshallerType.PERSISTENCE, initializer);
   }
}
