You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by ni...@apache.org on 2015/04/17 18:05:30 UTC

[10/50] [abbrv] zest-qi4j git commit: QI-318 Documentation!

QI-318 Documentation!


Project: http://git-wip-us.apache.org/repos/asf/zest-qi4j/repo
Commit: http://git-wip-us.apache.org/repos/asf/zest-qi4j/commit/f875d7cf
Tree: http://git-wip-us.apache.org/repos/asf/zest-qi4j/tree/f875d7cf
Diff: http://git-wip-us.apache.org/repos/asf/zest-qi4j/diff/f875d7cf

Branch: refs/heads/master
Commit: f875d7cf02bcf2e0c12b1ca1ad902965b145bacf
Parents: bb5fcda
Author: Paul Merlin <pa...@nosphere.org>
Authored: Mon Feb 11 20:05:53 2013 +0100
Committer: Paul Merlin <pa...@nosphere.org>
Committed: Mon Feb 11 20:05:53 2013 +0100

----------------------------------------------------------------------
 core/api/src/docs/valuecomposite.txt            | 121 +++++++-
 .../qi4j/api/value/DocumentationSupport.java    | 298 +++++++++++++++++++
 core/spi/src/docs/metrics.txt                   |   2 +-
 core/spi/src/docs/spi.txt                       |   7 +-
 core/spi/src/docs/valueserialization.txt        |  52 ++++
 .../src/docs/vs-jackson.txt                     |  24 ++
 .../src/docs/vs-orgjson.txt                     |  24 ++
 .../src/docs/vs-stax.txt                        |  24 ++
 manual/src/docs/userguide/extensions.txt        |  13 +
 9 files changed, 562 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/f875d7cf/core/api/src/docs/valuecomposite.txt
----------------------------------------------------------------------
diff --git a/core/api/src/docs/valuecomposite.txt b/core/api/src/docs/valuecomposite.txt
index 7e003f1..7536401 100644
--- a/core/api/src/docs/valuecomposite.txt
+++ b/core/api/src/docs/valuecomposite.txt
@@ -1,5 +1,6 @@
 //////////////////////
  * Copyright (c) 2007-2012, Niclas Hedhman. All Rights Reserved.
+ * Copyright (c) 2013, Paul Merlin. 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.
@@ -28,4 +29,122 @@ The characteristics of a ValueComposite compared to other Composite meta types a
 
     * It is Immutable.
     * Its equals/hashCode works on the values of the ValueComposite.
-    * Can be used as Property types, but will not be indexed and searchable.
\ No newline at end of file
+    * Can be used as Property types.
+
+== Value Serialization ==
+Value objects can be serialized and deserialized using the ValueSerialization API which is a Service API implemented
+by SPI and extensions.
+
+TIP: +ValueSerialization extends ValueSerializer, ValueDeserializer+. See the <<javadocs>> for interfaces detail.
+
+The ValueSerialization mechanism apply to the following object types :
+
+    * ValueComposite,
+    * EntityReference,
+    * Iterable,
+    * Map,
+    * Plain Value.
+
+Nested Plain Values, EntityReferences, Iterables, Maps, ValueComposites are supported.
+EntityComposites and EntityReferences are serialized as their identity string.
+
+Plain Values can be one of :
+
+    * String,
+    * Boolean or boolean,
+    * Integer or int,
+    * Long or long,
+    * Short or short,
+    * Byte or byte,
+    * Float or float,
+    * Double or double,
+    * BigInteger,
+    * BigDecimal,
+    * Date,
+    * DateTime (JodaTime),
+    * LocalDateTime (JodaTime),
+    * LocalDate (JodaTime).
+
+Values of unknown types and all arrays are considered as +java.io.Serializable+ and by so are (de)serialized to (from)
+base64 encoded bytes using pure Java serialization. If it happens that the value is not Serializable or the input to
+deserialize is invalid, a +ValueSerializationException+ is thrown.
+
+Methods of +ValueSerializer+ allow to specify if the serialized state should contain extra type information about the
+serialized value. Having type information in the serialized payload allows to keep actual ValueComposite types and by so
+circumvent +AmbiguousTypeException+ when deserializing.
+
+Core Runtime provides a default ValueSerialization system based on the
+https://github.com/douglascrockford/JSON-java[org.json] Java library producing and consuming JSON.
+
+Let's see how it works in practice.
+
+[snippet,java]
+----
+source=core/api/src/test/java/org/qi4j/api/value/DocumentationSupport.java
+tag=default
+----
+
+Reading this first example step by step we ;
+
+    . declare a ValueComposite,
+    . assemble it,
+    . create a new Value instance,
+    . use the +ValueComposite#toString()+ method to get a JSON representation of the Value,
+    . and finally, use the +Module#newValueFromSerializedState()+ method to create a new Value instance from the JSON
+      state.
+
++ValueComposite#toString()+ method leverage Value Serialization and by so provide JSON based representation. The Module
+API allows to create new Value instances from serialized state.
+
+On top of that, Application assemblies can register different implementation of ValueSerialization as Services to
+support more formats, see the <<extensions>> section. Note that the default behaviour described above is overriden if a
+ValueSerialization Service is visible.
+
+Let's see how to use the ValueSerialization Services.
+
+[snippet,java]
+----
+source=core/api/src/test/java/org/qi4j/api/value/DocumentationSupport.java
+tag=service
+----
+
+In this second example, we ;
+
+    . declare a ValueComposite,
+    . assemble it,
+    . assemble a ValueSerialization Service backed by the +org.json+ package,
+    . get the +ValueSerializer+ and +ValueDeserializer+ Services injected,
+    . create a new Value instance,
+    . use the +ValueSerializer#serialize()+ method to get a JSON representation of the Value,
+    . and finally, use the +ValueDeserializer#eserialize()+ method to create a new Value instance from the JSON state.
+
+Many applications need to stream data. The ValueSerialization API support such use cases in two ways.
+
+The first one use classic streams.
+
+[snippet,java]
+----
+source=core/api/src/test/java/org/qi4j/api/value/DocumentationSupport.java
+tag=stream
+----
+
+    . get a handle on a source of values and an +OutputStream+,
+    . serialize data into the +OutputStream+,
+    . get a handle on an +InputStream+,
+    . deserialize data from the +InputStream+.
+
+The second one use the <<core-io>>:
+
+[snippet,java]
+----
+source=core/api/src/test/java/org/qi4j/api/value/DocumentationSupport.java
+tag=io
+----
+
+    . get a handle on a source of values and a +Writer+,
+    . prepare the serialization +Function+,
+    . serialize a collection of values, one serialized value per line,
+    . get a handle on a serialized values +Reader+ and create a new empty +List+ of values,
+    . prepare the deserialization +Function+,
+    . deserialize a collection of values from read lines.
+

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/f875d7cf/core/api/src/test/java/org/qi4j/api/value/DocumentationSupport.java
----------------------------------------------------------------------
diff --git a/core/api/src/test/java/org/qi4j/api/value/DocumentationSupport.java b/core/api/src/test/java/org/qi4j/api/value/DocumentationSupport.java
new file mode 100644
index 0000000..32595b2
--- /dev/null
+++ b/core/api/src/test/java/org/qi4j/api/value/DocumentationSupport.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2013, Paul Merlin. 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 org.qi4j.api.value;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.qi4j.api.injection.scope.Service;
+import org.qi4j.api.property.Property;
+import org.qi4j.api.structure.Application;
+import org.qi4j.api.structure.Module;
+import org.qi4j.api.type.CollectionType;
+import org.qi4j.bootstrap.ApplicationAssembler;
+import org.qi4j.bootstrap.ApplicationAssembly;
+import org.qi4j.bootstrap.ApplicationAssemblyFactory;
+import org.qi4j.bootstrap.Assembler;
+import org.qi4j.bootstrap.AssemblyException;
+import org.qi4j.bootstrap.Energy4Java;
+import org.qi4j.bootstrap.ModuleAssembly;
+import org.qi4j.functional.Function;
+import org.qi4j.io.Inputs;
+import org.qi4j.io.Outputs;
+import org.qi4j.io.Transforms;
+import org.qi4j.test.AbstractQi4jTest;
+import org.qi4j.valueserialization.orgjson.OrgJsonValueSerializationAssembler;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Snippets:
+ * - default : default ValueSerialization
+ * - service : assembled service ValueSerialization
+ * - lookup  : ValueSerialization values module finder
+ */
+public class DocumentationSupport
+    extends AbstractQi4jTest
+{
+
+    @Before
+    public void injectToThis()
+    {
+        module.injectTo( this );
+    }
+
+    // START SNIPPET: default
+    // START SNIPPET: service
+    public interface SomeValue // (1)
+    {
+
+        Property<String> foo();
+    }
+
+    @Override
+    public void assemble( ModuleAssembly module )
+        throws AssemblyException
+    {
+        module.values( SomeValue.class ); // (2)
+        // END SNIPPET: default
+        new OrgJsonValueSerializationAssembler().assemble( module ); // (3)
+        // START SNIPPET: default
+    }
+    // END SNIPPET: default
+    // END SNIPPET: service
+
+    @Test
+    // START SNIPPET: default
+    public void defaultValueSerialization()
+    {
+        SomeValue someValue = someNewValueInstance( module ); // (3)
+        String json = someValue.toString(); // (4)
+        SomeValue someNewValue = module.newValueFromSerializedState( SomeValue.class, json ); // (5)
+        // END SNIPPET: default
+
+        assertThat( json, equalTo( "{\"foo\":\"bar\"}" ) );
+        assertThat( someNewValue, equalTo( someValue ) );
+
+        // START SNIPPET: default
+    }
+    // END SNIPPET: default
+    // START SNIPPET: service
+    @Service
+    private ValueSerializer valueSerializer; // (4)
+    @Service
+    private ValueDeserializer valueDeserializer; // (4)
+
+    // END SNIPPET: service
+    @Test
+    // START SNIPPET: service
+    public void assembledDefaultServiceSerialization()
+    {
+        SomeValue someValue = someNewValueInstance( module ); // (5)
+        String json = valueSerializer.serialize( someValue ); // (6)
+        SomeValue someNewValue = valueDeserializer.deserialize( SomeValue.class, json ); // (7)
+        // END SNIPPET: service
+
+        assertThat( json, equalTo( "{\"foo\":\"bar\"}" ) );
+        assertThat( someNewValue, equalTo( someValue ) );
+
+        // START SNIPPET: service
+    }
+    // END SNIPPET: service
+
+    static enum AcmeValue
+    {
+
+        foo, bar
+    }
+
+    @Test
+    // START SNIPPET: stream
+    public void assembledServiceStreamingSerialization()
+    {
+        // END SNIPPET: stream
+
+        List<AcmeValue> dataSource = Arrays.asList( AcmeValue.values() );
+        ByteArrayOutputStream targetStream = new ByteArrayOutputStream();
+
+        // START SNIPPET: stream
+        // (1)
+        Iterable<AcmeValue> data = dataSource; // Eg. Entities converted to Values
+        OutputStream output = targetStream; // Eg. streaming JSON over HTTP
+
+        // (2)
+        valueSerializer.serialize( data, output );
+        // END SNIPPET: stream
+
+        byte[] serialized = targetStream.toByteArray();
+        ByteArrayInputStream sourceStream = new ByteArrayInputStream( serialized );
+
+        // START SNIPPET: stream
+        // (3)
+        InputStream input = sourceStream; // Eg. reading incoming JSON
+
+        // (4)
+        List<AcmeValue> values = valueDeserializer.deserialize( CollectionType.listOf( AcmeValue.class ), input );
+        // END SNIPPET: stream
+
+        assertThat( values, equalTo( dataSource ) );
+
+        // START SNIPPET: stream
+    }
+    // END SNIPPET: stream
+
+    @Test
+    // START SNIPPET: io
+    public void assembledServiceIOSerialization()
+        throws IOException
+    {
+        // END SNIPPET: io
+
+        List<AcmeValue> dataSource = Arrays.asList( AcmeValue.values() );
+        StringWriter outputWriter = new StringWriter();
+
+        // START SNIPPET: io
+        // (1)
+        Iterable<AcmeValue> queryResult = dataSource; // Eg. Entities converted to Values
+        Writer writer = outputWriter; // Eg. to pipe data to another process or to a file
+
+        // (2)
+        Function<AcmeValue, String> serialize = valueSerializer.serialize();
+
+        // (3)
+        Inputs.iterable( queryResult ).transferTo( Transforms.map( serialize, Outputs.text( writer ) ) );
+        // END SNIPPET: io
+
+        String string = writer.toString();
+        StringReader inputReader = new StringReader( string );
+
+        // START SNIPPET: io
+        // (4)
+        Reader reader = inputReader;
+        List<AcmeValue> values = new ArrayList<AcmeValue>();
+
+        // (5)
+        Function<String, AcmeValue> deserialize = valueDeserializer.deserialize( AcmeValue.class );
+
+        // Deserialization of a collection of AcmeValue from a String.
+        // One serialized AcmeValue per line.
+        // (6)
+        Inputs.text( reader ).transferTo( Transforms.map( deserialize, Outputs.collection( values ) ) );
+        // END SNIPPET: io
+
+        assertThat( dataSource, equalTo( values ) );
+
+        // START SNIPPET: io
+    }
+    // END SNIPPET: io
+
+    @Test
+    // TODO Move to SPI !
+    // TODO Include in each ValueSerialization extensions documentation
+    public void assembledWithValuesModuleSerialization()
+        throws Exception
+    {
+        Application app = new Energy4Java().newApplication( new ApplicationAssembler()
+        {
+            @Override
+            public ApplicationAssembly assemble( ApplicationAssemblyFactory applicationFactory )
+                throws AssemblyException
+            {
+                Assembler[][][] pancakes = new Assembler[][][]
+                {
+                    {
+                        {
+                            new Assembler()
+                            {
+                                @Override
+                                public void assemble( ModuleAssembly valuesModule )
+                                    throws AssemblyException
+                                {
+                                    valuesModule.layer().setName( "SINGLE-Layer" );
+                                    valuesModule.setName( "VALUES-Module" );
+
+                                    valuesModule.values( SomeValue.class );
+                                }
+                            }
+                        },
+                        {
+                            new Assembler()
+                            {
+                                @Override
+                                public void assemble( ModuleAssembly servicesModule )
+                                    throws AssemblyException
+                                {
+                                    servicesModule.setName( "SERVICES-Module" );
+
+                                    Function<Application, Module> valuesModuleFinder = new Function<Application, Module>()
+                                    {
+                                        @Override
+                                        public Module map( Application app )
+                                        {
+                                            return app.findModule( "SINGLE-Layer", "VALUES-Module" );
+                                        }
+                                    };
+                                    new OrgJsonValueSerializationAssembler().
+                                        withValuesModuleFinder( valuesModuleFinder ).
+                                        assemble( servicesModule );
+                                }
+                            }
+                        }
+                    }
+                };
+                return applicationFactory.newApplicationAssembly( pancakes );
+            }
+        } );
+        app.activate();
+        try
+        {
+            Module valuesModule = app.findModule( "SINGLE-Layer", "VALUES-Module" );
+            SomeValue someValue = someNewValueInstance( valuesModule );
+
+            Module servicesModule = app.findModule( "SINGLE-Layer", "SERVICES-Module" );
+            ValueSerialization valueSerialization = servicesModule.findService( ValueSerialization.class ).get();
+
+            String json = valueSerialization.serialize( someValue );
+            assertThat( json, equalTo( "{\"foo\":\"bar\"}" ) );
+
+            SomeValue someNewValue = valueSerialization.deserialize( SomeValue.class, json );
+            assertThat( someNewValue, equalTo( someValue ) );
+        }
+        finally
+        {
+            app.passivate();
+        }
+    }
+
+    private SomeValue someNewValueInstance( Module module )
+    {
+        ValueBuilder<SomeValue> builder = module.newValueBuilder( SomeValue.class );
+        builder.prototype().foo().set( "bar" );
+        return builder.newInstance();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/f875d7cf/core/spi/src/docs/metrics.txt
----------------------------------------------------------------------
diff --git a/core/spi/src/docs/metrics.txt b/core/spi/src/docs/metrics.txt
index 97ad11f..678db90 100644
--- a/core/spi/src/docs/metrics.txt
+++ b/core/spi/src/docs/metrics.txt
@@ -14,7 +14,7 @@
 //////////////////////
 
 [[core-spi-metrics,Metrics SPI]]
-= Qi4j Metrics SPI =
+= 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.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/f875d7cf/core/spi/src/docs/spi.txt
----------------------------------------------------------------------
diff --git a/core/spi/src/docs/spi.txt b/core/spi/src/docs/spi.txt
index 8dfb96e..df223b2 100644
--- a/core/spi/src/docs/spi.txt
+++ b/core/spi/src/docs/spi.txt
@@ -27,8 +27,9 @@ applications during the bootstrap phase.
 
 include::../../build/docs/buildinfo/artifact.txt[]
 
-There are currently 4 Core SPI extensions;
+There are currently 5 Core SPI extensions;
 
+    * ValueSerialization SPI
     * EntityStore SPI
     * Cache SPI
     * Indexing/Query SPI
@@ -41,6 +42,10 @@ can be solved in a support manner, or that we need to extend the Core API to sup
 
 :leveloffset: {level3}
 
+include::valueserialization.txt[]
+
+:leveloffset: {level3}
+
 include::entitystore.txt[]
 
 :leveloffset: {level3}

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/f875d7cf/core/spi/src/docs/valueserialization.txt
----------------------------------------------------------------------
diff --git a/core/spi/src/docs/valueserialization.txt b/core/spi/src/docs/valueserialization.txt
new file mode 100644
index 0000000..9029cbc
--- /dev/null
+++ b/core/spi/src/docs/valueserialization.txt
@@ -0,0 +1,52 @@
+[[core-spi-valueserialization,ValueSerialization SPI]]
+= ValueSerialization SPI =
+
+Simply implement ValueSerialization to create an extension for the ValueSerialization SPI.
+The Core SPI module provides adapters to create pull-parsing capable ValueSerializers and pull-parsing and tree-parsing
+capable ValueDeserializers.
+
+The behaviour described here apply to all ValueSerialization services implemented using the Core SPI adapters. Note that
+nothing stops you from implementing an extension for the ValueSerialization SPI without relying on theses adapters.
+
+Theses adapters are tailored for serialization mechanisms that support the following two structures that can be nested:
+
+    * an 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.
+
+Special attention is taken when dealing with Maps. They are serialized as an ordered list of collections of
+name/value pairs to keep the Map order for least surprise. That way, even when the underlying serialization mechanism
+do not keep the collection of name/value pairs order we can rely on it being kept.
+
+Here is a sample Map with two entries in JSON notation to make things clear:
+
+[source,javascript]
+----
+[
+    { "key": "foo",       "value": "bar"   },
+    { "key": "cathedral", "value": "bazar" }
+]
+----
+
+Among Plain Values (see the <<core-api-value,ValueSerialization API>> section) some are considered primitives to
+underlying serialization mechanisms and by so handed/come without conversion to/from implementations.
+
+Primitive values can be one of:
+
+    * String,
+    * Boolean or boolean,
+    * Integer or int,
+    * Long or long,
+    * Short or short,
+    * Byte or byte,
+    * Float or float,
+    * Double or double.
+
+Serialization is always done in a streaming manner using a pull-parsing based approach.
+
+Deserialization is done in a streaming manner using a pull-parsing based approach except when encountering a
+ValueComposite. ValueComposite types are deserialized using a tree-parsing based approach.
+
+All this means that you can serialize and deserialize large collections of values without filling the heap.

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/f875d7cf/extensions/valueserialization-jackson/src/docs/vs-jackson.txt
----------------------------------------------------------------------
diff --git a/extensions/valueserialization-jackson/src/docs/vs-jackson.txt b/extensions/valueserialization-jackson/src/docs/vs-jackson.txt
new file mode 100644
index 0000000..3071215
--- /dev/null
+++ b/extensions/valueserialization-jackson/src/docs/vs-jackson.txt
@@ -0,0 +1,24 @@
+[[extension-vs-jackson, Jackson ValueSerialization]]
+= Jackson ValueSerialization =
+
+[devstatus]
+--------------
+source=extensions/valueserialization-jackson/dev-status.xml
+--------------
+
+ValueSerialization Service backed by http://wiki.fasterxml.com/JacksonHome[Jackson].
+
+include::../../build/docs/buildinfo/artifact.txt[]
+
+== Assembly ==
+
+Assembly is done as follows:
+
+[snippet,java]
+----
+source=extensions/valueserialization-jackson/src/test/java/org/qi4j/valueserialization/jackson/JacksonPlainValueSerializationTest.java
+tag=assembly
+----
+
+See the ValueSerialization <<core-api-value,API>> and <<core-spi-valueserialization,SPI>> documentation for details and
+usage.

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/f875d7cf/extensions/valueserialization-orgjson/src/docs/vs-orgjson.txt
----------------------------------------------------------------------
diff --git a/extensions/valueserialization-orgjson/src/docs/vs-orgjson.txt b/extensions/valueserialization-orgjson/src/docs/vs-orgjson.txt
new file mode 100644
index 0000000..087a006
--- /dev/null
+++ b/extensions/valueserialization-orgjson/src/docs/vs-orgjson.txt
@@ -0,0 +1,24 @@
+[[extension-vs-orgjson, org.json ValueSerialization]]
+= org.json ValueSerialization =
+
+[devstatus]
+--------------
+source=extensions/valueserialization-orgjson/dev-status.xml
+--------------
+
+ValueSerialization Service backed by https://github.com/douglascrockford/JSON-java[org.json].
+
+include::../../build/docs/buildinfo/artifact.txt[]
+
+== Assembly ==
+
+Assembly is done as follows:
+
+[snippet,java]
+----
+source=extensions/valueserialization-orgjson/src/test/java/org/qi4j/valueserialization/orgjson/OrgJsonPlainValueSerializationTest.java
+tag=assembly
+----
+
+See the ValueSerialization <<core-api-value,API>> and <<core-spi-valueserialization,SPI>> documentation for details and
+usage.

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/f875d7cf/extensions/valueserialization-stax/src/docs/vs-stax.txt
----------------------------------------------------------------------
diff --git a/extensions/valueserialization-stax/src/docs/vs-stax.txt b/extensions/valueserialization-stax/src/docs/vs-stax.txt
new file mode 100644
index 0000000..abe9ecf
--- /dev/null
+++ b/extensions/valueserialization-stax/src/docs/vs-stax.txt
@@ -0,0 +1,24 @@
+[[extension-vs-stax, StAX ValueSerialization]]
+= StAX ValueSerialization =
+
+[devstatus]
+--------------
+source=extensions/valueserialization-stax/dev-status.xml
+--------------
+
+ValueSerialization Service backed by http://jcp.org/en/jsr/detail?id=173[StAX].
+
+include::../../build/docs/buildinfo/artifact.txt[]
+
+== Assembly ==
+
+Assembly is done as follows:
+
+[snippet,java]
+----
+source=extensions/valueserialization-stax/src/test/java/org/qi4j/valueserialization/stax/StaxPlainValueSerializationTest.java
+tag=assembly
+----
+
+See the ValueSerialization <<core-api-value,API>> and <<core-spi-valueserialization,SPI>> documentation for details and
+usage.

http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/f875d7cf/manual/src/docs/userguide/extensions.txt
----------------------------------------------------------------------
diff --git a/manual/src/docs/userguide/extensions.txt b/manual/src/docs/userguide/extensions.txt
index 56b958f..e2de272 100644
--- a/manual/src/docs/userguide/extensions.txt
+++ b/manual/src/docs/userguide/extensions.txt
@@ -9,6 +9,7 @@ We try to keep the Qi4j Core Runtime as lean as possible, and a lot of the power
 Extension SPI, which defines clear ways to extend the platform. There are currently the following Extensions types,
 each with possibly more than one implementation;
 
+   * Value Serialization
    * Entity Stores
    * Index / Query Engines
    * Entity Caches
@@ -25,6 +26,18 @@ for our users.
 
 :leveloffset: 2
 
+include::../../../../extensions/valueserialization-orgjson/src/docs/vs-orgjson.txt[]
+
+:leveloffset: 2
+
+include::../../../../extensions/valueserialization-jackson/src/docs/vs-jackson.txt[]
+
+:leveloffset: 2
+
+include::../../../../extensions/valueserialization-stax/src/docs/vs-stax.txt[]
+
+:leveloffset: 2
+
 include::../../../../extensions/cache-ehcache/src/docs/ehcache.txt[]
 
 :leveloffset: 2