Polygene™
Introduction
Tutorials
Javadoc
Samples
Core
Libraries
Extensions
Tools
Glossary 

Core Extension SPI

code

docs

tests

The Polygene™ Core Runtime has a number of extension points, which we call the Polygene Core Extension SPI. These are defined interfaces used only by the Core Runtime and never directly by application code. Extensions are assembled in applications during the bootstrap phase.

Table 17. Artifact

Group IDArtifact IDVersion

org.apache.polygene.core

org.apache.polygene.core.spi

3.0.0


There are currently 5 Core SPI extensions;

Polygene™ Runtime Extensions implementations may depend on Polygene™ Libraries, but Libraries are NOT ALLOWED to depend on Extensions. Applications code is NOT ALLOWED to depend on extensions. And application code SHOULD NOT depend on the Core Extension SPI. If you think that is needed, please contact users@dev.apache.org mailing list, to see if your usecase can be solved in a support manner, or that we need to extend the Core API to support it.

Serialization SPI

Tip

Find Serialization extensions in the Extensions list.

Overview

The Polygene™ Core Runtime use Serialization to provide string representation of ValueComposites via their toString() method, and, their instantiation from the very same representation via the newValueFromSerializedState(..) method of the ValueBuilderFactory API.

public interface SomeValue // (1)
{
    Property<String> foo();
}

@Override
public void assemble( ModuleAssembly module )
{
    module.values( SomeValue.class ); // (2)
      [...snip...]

    module.defaultServices(); // (3)
      [...snip...]

}
  [...snip...]

public void defaultSerialization()
{
    SomeValue someValue = someNewValueInstance(); // (4)
    String json = someValue.toString(); // (5)
    SomeValue someNewValue = valueBuilderFactory.newValueFromSerializedState( SomeValue.class, json ); // (6)
      [...snip...]

}

In each Module, if no Serialization service is assembled, a default one supporting the JSON format is used.

public interface SomeValue // (1)
{
    Property<String> foo();
}

@Override
public void assemble( ModuleAssembly module )
{
    module.values( SomeValue.class ); // (2)
      [...snip...]

    new JavaxJsonSerializationAssembler().assemble( module ); // (3)
      [...snip...]

}
  [...snip...]

@Service
private Serializer serializer; // (4)
@Service
private Deserializer deserializer; // (4)

  [...snip...]

public void assembledDefaultServiceSerialization()
{
    SomeValue someValue = someNewValueInstance(); // (5)
    String json = serializer.serialize( someValue ); // (6)
    SomeValue someNewValue = deserializer.deserialize( module, SomeValue.class, json ); // (7)
      [...snip...]

}
Text or Binary?

The Core SPI provides adapters for text or bytes based serialization, extends the following types to implement a custom serialization.

For text based serialization:

/**
 * Base Text Serializer.
 *
 * Implementations work on Strings, this base serializer encode these strings in UTF-8 to produce bytes.
 *
 * See {@link AbstractTextDeserializer}.
 */
public abstract class AbstractTextSerializer extends AbstractSerializer
/**
 * Base Text Deserializer.
 *
 * Implementations work on Strings, this base deserializer decode bytes in UTF-8 to produce strings.
 *
 * See {@link AbstractTextSerializer}.
 */
public abstract class AbstractTextDeserializer extends AbstractDeserializer

For bytes based serialization:

/**
 * Base Binary Serializer.
 *
 * Implementations work on bytes, this base serializer encode these bytes in Base64 to produce Strings.
 *
 * See {@link AbstractBinaryDeserializer}.
 */
public abstract class AbstractBinarySerializer extends AbstractSerializer
/**
 * Base Binary Deserializer.
 *
 * Implementations work on bytes, this base deserializer decode Strings from Base64 to produce bytes.
 *
 * See {@link AbstractBinarySerializer}.
 */
public abstract class AbstractBinaryDeserializer extends AbstractDeserializer
JSON or XML?

The Core SPI provides JSON and XML serialization respectively based on javax.json and javax.xml types and APIs to work directly with these types so you can work with the actual object representations without serializing to text or bytes. They both rely on the text serialization adapters shown above.

Here is an example using the JsonSerialization service:

@Service
JsonSerialization jsonSerialization;
  [...snip...]

    try( UnitOfWork uow = unitOfWorkFactory.newUnitOfWork() )
    {
        Some valueInstance = buildSomeValue( moduleInstance, uow, "42" );

        // Serialize using injected service
        JsonValue serializedJson = jsonSerialization.toJson( valueInstance );
        System.out.println( serializedJson.toString() );

        // Deserialize using Module API
        Some valueFromSerializedState = moduleInstance.newValueFromSerializedState( Some.class, serializedJson.toString() );
        assertThat( "Deserialized Value equality", valueInstance, equalTo( valueFromSerializedState ) );
          [...snip...]

    }

And another using the XmlSerialization service:

@Service
XmlSerialization xmlSerialization;
  [...snip...]

    try( UnitOfWork uow = unitOfWorkFactory.newUnitOfWork() )
    {
        Some valueInstance = buildSomeValue( moduleInstance, uow, "42" );

        // Serialize using injected service
        String serializedXml = xmlSerialization.serialize( valueInstance );
        System.out.println( serializedXml );

        // Deserialize using Module API
        Some valueFromSerializedState = moduleInstance.newValueFromSerializedState( Some.class, serializedXml );
        assertThat( "Deserialized Value equality", valueInstance, equalTo( valueFromSerializedState ) );
          [...snip...]

    }
Implementation notes

Simply implement Serialization to create an extension for the Serialization SPI. The Core SPI module provides adapters to create Serializers and Deserializers.

The behaviour described here apply to all Serialization services implemented using the Core SPI adapters. Note that nothing stops you from implementing an extension for the Serialization SPI without relying on theses adapters.

Theses adapters are tailored for serialization mechanisms that support the following two structures that can be nested:

  • a collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array,
  • an ordered list of values. In most languages, this is realized as an array, vector, list, or sequence ;

in other words, a JSON-like structure.

EntityStore SPI

Note

This SPI has no documentation yet. Learn how to contribute in Writing Documentation.

Cache SPI

Note

This SPI has no documentation yet. Learn how to contribute in Writing Documentation.

Indexing/Query SPI

Note

This SPI has no documentation yet. Learn how to contribute in Writing Documentation.

Metrics SPI

It is very easy to create an extension for the Metrics SPI, simply by implementing the MetricsProvider. If only a subset of the factories/types are supported, there is a convenience adapter call MetricsProviderAdapter in the Metrics SPI package.