Introduce serialization converters in API

Converters are “format agnostic” and convert instances to String and the
other way around. Built-in converters for base types supported by the
Polygene Runtime (Identity, EntityReference, big numbers, date types).

POLYGENE-231


Project: http://git-wip-us.apache.org/repos/asf/polygene-java/repo
Commit: http://git-wip-us.apache.org/repos/asf/polygene-java/commit/b094d05f
Tree: http://git-wip-us.apache.org/repos/asf/polygene-java/tree/b094d05f
Diff: http://git-wip-us.apache.org/repos/asf/polygene-java/diff/b094d05f

Branch: refs/heads/develop
Commit: b094d05f870cf618bd30b0708af8248a743ce3ed
Parents: 3371658
Author: Paul Merlin <[email protected]>
Authored: Mon Mar 13 09:28:42 2017 +0100
Committer: Paul Merlin <[email protected]>
Committed: Sun Apr 2 19:16:23 2017 +0200

----------------------------------------------------------------------
 .../polygene/api/serialization/Converter.java   |  49 ++++
 .../polygene/api/serialization/Converters.java  | 131 +++++++++++
 .../javaxjson/JavaxJsonDeserializer.java        |  15 +-
 .../JavaxJsonSerializationService.java          | 223 ++----------------
 .../javaxjson/JavaxJsonSerializer.java          |  15 +-
 .../spi/serialization/BuiltInConverters.java    | 235 +++++++++++++++++++
 .../javaxxml/JavaxXmlDeserializer.java          |  10 +
 .../javaxxml/JavaxXmlSerializationService.java  | 195 ++-------------
 .../javaxxml/JavaxXmlSerializer.java            |  10 +
 .../msgpack/MessagePackDeserializer.java        |  10 +
 .../MessagePackSerializationService.java        | 195 ++-------------
 .../msgpack/MessagePackSerializer.java          |  10 +
 12 files changed, 535 insertions(+), 563 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b094d05f/core/api/src/main/java/org/apache/polygene/api/serialization/Converter.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/serialization/Converter.java 
b/core/api/src/main/java/org/apache/polygene/api/serialization/Converter.java
new file mode 100644
index 0000000..b411ad3
--- /dev/null
+++ 
b/core/api/src/main/java/org/apache/polygene/api/serialization/Converter.java
@@ -0,0 +1,49 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.apache.polygene.api.serialization;
+
+/**
+ * Converter for (de)serialization.
+ *
+ * Convert instances of {@link T} to String and the other way around.
+ *
+ * @param <T> the converted type
+ */
+public interface Converter<T>
+{
+    /**
+     * @return the converted type
+     */
+    Class<T> type();
+
+    /**
+     * Convert.
+     *
+     * @param object the {@link T} to convert to String, never null
+     * @return the String representation of the given object
+     */
+    String toString( T object );
+
+    /**
+     * Revert.
+     *
+     * @param string the String to convert back to {@link T}
+     * @return the {@link T}
+     */
+    T fromString( String string );
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b094d05f/core/api/src/main/java/org/apache/polygene/api/serialization/Converters.java
----------------------------------------------------------------------
diff --git 
a/core/api/src/main/java/org/apache/polygene/api/serialization/Converters.java 
b/core/api/src/main/java/org/apache/polygene/api/serialization/Converters.java
new file mode 100644
index 0000000..6b8cbef
--- /dev/null
+++ 
b/core/api/src/main/java/org/apache/polygene/api/serialization/Converters.java
@@ -0,0 +1,131 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.apache.polygene.api.serialization;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import org.apache.polygene.api.mixin.Mixins;
+import org.apache.polygene.api.type.HasTypes;
+import org.apache.polygene.api.type.ValueType;
+
+import static org.apache.polygene.api.type.HasTypesCollectors.closestType;
+
+/**
+ * Serialization Converters.
+ */
+@Mixins( Converters.Mixin.class )
+public interface Converters
+{
+    /**
+     * Register a converter for a value type.
+     *
+     * @param valueType the value type
+     * @param converter the converter
+     */
+    void registerConverter( ValueType valueType, Converter<?> converter );
+
+    /**
+     * Find a matching converter amongst registered ones.
+     *
+     * See {@link 
org.apache.polygene.api.type.HasTypesCollectors#closestType(HasTypes)}.
+     *
+     * @param valueType the value type
+     * @param <T> the converted type
+     * @return the closest matching registered converter, or {@literal null} 
if none
+     */
+    <T> Converter<T> converterFor( ValueType valueType );
+
+    default <T> Converter<T> converterFor( Class<? extends T> type )
+    {
+        return converterFor( ValueType.of( type ) );
+    }
+
+    /**
+     * Serialization Converters default Mixin.
+     */
+    class Mixin implements Converters
+    {
+        private final Map<ValueType, Converter<?>> converters = new 
LinkedHashMap<>();
+
+        @Override
+        public void registerConverter( ValueType valueType, Converter<?> 
converter )
+        {
+            converters.put( valueType, converter );
+        }
+
+        @Override
+        public <T> Converter<T> converterFor( ValueType valueType )
+        {
+            Converter<T> converter = castConverter( 
converters.keySet().stream()
+                                                              .collect( 
closestType( valueType ) )
+                                                              .map( 
converters::get )
+                                                              .orElse( null ) 
);
+            if( converter != null )
+            {
+                return converter;
+            }
+            if( valueType.primaryType().isEnum() )
+            {
+                return new EnumConverter( valueType.primaryType() );
+            }
+            return null;
+        }
+
+        @SuppressWarnings( "unchecked" )
+        private <T> Converter<T> castConverter( Converter<?> converter )
+        {
+            return (Converter<T>) converter;
+        }
+
+        private static class EnumConverter<E extends Enum<E>> implements 
Converter<E>
+        {
+            private final Class<E> enumType;
+            private final Map<String, E> values;
+
+            private EnumConverter( final Class<E> enumType )
+            {
+                this.enumType = enumType;
+                E[] enumValues = enumType.getEnumConstants();
+                this.values = new HashMap<>( enumValues.length );
+                for( E enumValue : enumValues )
+                {
+                    values.put( enumValue.name(), enumValue );
+                }
+            }
+
+            @Override
+            public Class<E> type()
+            {
+                return enumType;
+            }
+
+            @Override
+            public String toString( E object )
+            {
+                return object.name();
+            }
+
+            @Override
+            public E fromString( String string )
+            {
+                return values.get( string );
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b094d05f/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonDeserializer.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonDeserializer.java
 
b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonDeserializer.java
index b9d9e94..a1e5d75 100644
--- 
a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonDeserializer.java
+++ 
b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonDeserializer.java
@@ -41,12 +41,13 @@ import org.apache.polygene.api.entity.EntityReference;
 import org.apache.polygene.api.injection.scope.This;
 import org.apache.polygene.api.injection.scope.Uses;
 import org.apache.polygene.api.property.PropertyDescriptor;
+import org.apache.polygene.api.serialization.Converter;
+import org.apache.polygene.api.serialization.Converters;
 import org.apache.polygene.api.serialization.SerializationException;
 import org.apache.polygene.api.service.ServiceDescriptor;
 import org.apache.polygene.api.structure.ModuleDescriptor;
 import org.apache.polygene.api.type.ArrayType;
 import org.apache.polygene.api.type.CollectionType;
-import org.apache.polygene.api.type.EnumType;
 import org.apache.polygene.api.type.MapType;
 import org.apache.polygene.api.type.ValueCompositeType;
 import org.apache.polygene.api.type.ValueType;
@@ -69,6 +70,9 @@ import static 
org.apache.polygene.serialization.javaxjson.JavaxJson.requireJsonS
 public class JavaxJsonDeserializer extends AbstractTextDeserializer implements 
JsonDeserializer
 {
     @This
+    private Converters converters;
+
+    @This
     private JavaxJsonAdapters adapters;
 
     @Uses
@@ -87,16 +91,17 @@ public class JavaxJsonDeserializer extends 
AbstractTextDeserializer implements J
         {
             return null;
         }
+        Converter<Object> converter = converters.converterFor( valueType );
+        if( converter != null )
+        {
+            return (T) converter.fromString( doDeserialize( module, 
ValueType.STRING, json ).toString() );
+        }
         JavaxJsonAdapter<?> adapter = adapters.adapterFor( valueType );
         if( adapter != null )
         {
             return (T) adapter.deserialize( json, ( jsonValue, type ) -> 
doDeserialize( module, type, jsonValue ) );
         }
         Class<? extends ValueType> valueTypeClass = valueType.getClass();
-        if( EnumType.class.isAssignableFrom( valueTypeClass ) )
-        {
-            return (T) Enum.valueOf( (Class) valueType.primaryType(), 
asString( json ) );
-        }
         if( ArrayType.class.isAssignableFrom( valueTypeClass ) )
         {
             return (T) deserializeArray( module, (ArrayType) valueType, json );

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b094d05f/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializationService.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializationService.java
 
b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializationService.java
index 2b662ea..2618db7 100644
--- 
a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializationService.java
+++ 
b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializationService.java
@@ -17,32 +17,21 @@
  */
 package org.apache.polygene.serialization.javaxjson;
 
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.time.Duration;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.OffsetDateTime;
-import java.time.Period;
-import java.time.ZonedDateTime;
 import java.util.function.BiFunction;
 import java.util.function.Function;
 import javax.json.Json;
 import javax.json.JsonNumber;
 import javax.json.JsonString;
 import javax.json.JsonValue;
-import org.apache.polygene.api.entity.EntityReference;
-import org.apache.polygene.api.identity.Identity;
-import org.apache.polygene.api.identity.StringIdentity;
 import org.apache.polygene.api.injection.scope.This;
 import org.apache.polygene.api.injection.scope.Uses;
 import org.apache.polygene.api.mixin.Mixins;
+import org.apache.polygene.api.serialization.Converters;
 import org.apache.polygene.api.serialization.SerializationException;
 import org.apache.polygene.api.service.ServiceActivation;
 import org.apache.polygene.api.service.ServiceDescriptor;
 import org.apache.polygene.api.type.ValueType;
+import org.apache.polygene.spi.serialization.BuiltInConverters;
 
 // TODO Move into JavaxJsonSerialization
 // TODO Do the same on XML & MessagePack
@@ -55,6 +44,12 @@ public interface JavaxJsonSerializationService extends 
JavaxJsonSerialization, S
         private ServiceDescriptor descriptor;
 
         @This
+        private BuiltInConverters builtInConverters;
+
+        @This
+        private Converters converters;
+
+        @This
         private JavaxJsonAdapters adapters;
 
         private boolean registrationDone = false;
@@ -64,6 +59,8 @@ public interface JavaxJsonSerializationService extends 
JavaxJsonSerialization, S
         {
             if( !registrationDone )
             {
+                registerCustomConverters();
+                registerBuiltInConverters();
                 registerCustomAdapters();
                 registerBaseAdapters();
                 registrationDone = true;
@@ -73,6 +70,16 @@ public interface JavaxJsonSerializationService extends 
JavaxJsonSerialization, S
         @Override
         public void passivateService() {}
 
+        private void registerCustomConverters()
+        {
+            // TODO register custom converters
+        }
+
+        private void registerBuiltInConverters()
+        {
+            builtInConverters.registerBuiltInConverters( converters );
+        }
+
         private void registerCustomAdapters()
         {
             JavaxJsonSettings.orDefault( descriptor.metaInfo( 
JavaxJsonSettings.class ) )
@@ -92,24 +99,6 @@ public interface JavaxJsonSerializationService extends 
JavaxJsonSerialization, S
             adapters.registerAdapter( ValueType.BYTE, new ByteAdapter() );
             adapters.registerAdapter( ValueType.FLOAT, new FloatAdapter() );
             adapters.registerAdapter( ValueType.DOUBLE, new DoubleAdapter() );
-
-            // Number types
-            adapters.registerAdapter( ValueType.BIG_DECIMAL, new 
BigDecimalAdapter() );
-            adapters.registerAdapter( ValueType.BIG_INTEGER, new 
BigIntegerAdapter() );
-
-            // Date types
-            adapters.registerAdapter( ValueType.INSTANT, new InstantAdapter() 
);
-            adapters.registerAdapter( ValueType.ZONED_DATE_TIME, new 
ZonedDateTimeAdapter() );
-            adapters.registerAdapter( ValueType.OFFSET_DATE_TIME, new 
OffsetDateTimeAdapter() );
-            adapters.registerAdapter( ValueType.LOCAL_DATE_TIME, new 
LocalDateTimeAdapter() );
-            adapters.registerAdapter( ValueType.LOCAL_DATE, new 
LocalDateAdapter() );
-            adapters.registerAdapter( ValueType.LOCAL_TIME, new 
LocalTimeAdapter() );
-            adapters.registerAdapter( ValueType.DURATION, new 
DurationAdapter() );
-            adapters.registerAdapter( ValueType.PERIOD, new PeriodAdapter() );
-
-            // Other supported types
-            adapters.registerAdapter( ValueType.IDENTITY, new 
IdentityAdapter() );
-            adapters.registerAdapter( ValueType.ENTITY_REFERENCE, new 
EntityReferenceAdapter() );
         }
 
         private static abstract class ToJsonStringAdapter<T> implements 
JavaxJsonAdapter<T>
@@ -357,177 +346,5 @@ public interface JavaxJsonSerializationService extends 
JavaxJsonSerialization, S
                 }
             }
         }
-
-        private static class BigDecimalAdapter extends 
ToJsonStringAdapter<BigDecimal>
-        {
-            @Override
-            public Class<BigDecimal> type() { return BigDecimal.class; }
-
-            @Override
-            public BigDecimal deserialize( JsonValue json,
-                                           BiFunction<JsonValue, ValueType, 
Object> deserializeFunction )
-            {
-                switch( json.getValueType() )
-                {
-                    case NULL:
-                        return null;
-                    case NUMBER:
-                        return new BigDecimal( json.toString() );
-                    case STRING:
-                        return new BigDecimal( ( (JsonString) json 
).getString() );
-                    default:
-                        throw new SerializationException(
-                            "Don't know how to deserialize BigDecimal from " + 
json );
-                }
-            }
-        }
-
-        private static class BigIntegerAdapter extends 
ToJsonStringAdapter<BigInteger>
-        {
-            @Override
-            public Class<BigInteger> type() { return BigInteger.class; }
-
-            @Override
-            public BigInteger deserialize( JsonValue json,
-                                           BiFunction<JsonValue, ValueType, 
Object> deserializeFunction )
-            {
-                switch( json.getValueType() )
-                {
-                    case NULL:
-                        return null;
-                    case NUMBER:
-                        return new BigInteger( json.toString() );
-                    case STRING:
-                        return new BigInteger( ( (JsonString) json 
).getString() );
-                    default:
-                        throw new SerializationException(
-                            "Don't know how to deserialize BigInteger from " + 
json );
-                }
-            }
-        }
-
-        private static class PeriodAdapter extends ToJsonStringAdapter<Period>
-        {
-            @Override
-            public Class<Period> type() { return Period.class; }
-
-            @Override
-            public Period deserialize( JsonValue json, BiFunction<JsonValue, 
ValueType, Object> deserializeFunction )
-            {
-                return Period.parse( JavaxJson.asString( json ) );
-            }
-        }
-
-        private static class DurationAdapter extends 
ToJsonStringAdapter<Duration>
-        {
-            @Override
-            public Class<Duration> type() { return Duration.class; }
-
-            @Override
-            public Duration deserialize( JsonValue json, BiFunction<JsonValue, 
ValueType, Object> deserializeFunction )
-            {
-                return Duration.parse( JavaxJson.asString( json ) );
-            }
-        }
-
-        private static class LocalTimeAdapter extends 
ToJsonStringAdapter<LocalTime>
-        {
-            @Override
-            public Class<LocalTime> type() { return LocalTime.class; }
-
-            @Override
-            public LocalTime deserialize( JsonValue json, 
BiFunction<JsonValue, ValueType, Object> deserializeFunction )
-            {
-                return LocalTime.parse( JavaxJson.asString( json ) );
-            }
-        }
-
-        private static class LocalDateAdapter extends 
ToJsonStringAdapter<LocalDate>
-        {
-            @Override
-            public Class<LocalDate> type() { return LocalDate.class; }
-
-            @Override
-            public LocalDate deserialize( JsonValue json, 
BiFunction<JsonValue, ValueType, Object> deserializeFunction )
-            {
-                return LocalDate.parse( JavaxJson.asString( json ) );
-            }
-        }
-
-        private static class LocalDateTimeAdapter extends 
ToJsonStringAdapter<LocalDateTime>
-        {
-            @Override
-            public Class<LocalDateTime> type() { return LocalDateTime.class; }
-
-            @Override
-            public LocalDateTime deserialize( JsonValue json,
-                                              BiFunction<JsonValue, ValueType, 
Object> deserializeFunction )
-            {
-                return LocalDateTime.parse( JavaxJson.asString( json ) );
-            }
-        }
-
-        private static class OffsetDateTimeAdapter extends 
ToJsonStringAdapter<OffsetDateTime>
-        {
-            @Override
-            public Class<OffsetDateTime> type() { return OffsetDateTime.class; 
}
-
-            @Override
-            public OffsetDateTime deserialize( JsonValue json,
-                                               BiFunction<JsonValue, 
ValueType, Object> deserializeFunction )
-            {
-                return OffsetDateTime.parse( JavaxJson.asString( json ) );
-            }
-        }
-
-        private static class ZonedDateTimeAdapter extends 
ToJsonStringAdapter<ZonedDateTime>
-        {
-            @Override
-            public Class<ZonedDateTime> type() { return ZonedDateTime.class; }
-
-            @Override
-            public ZonedDateTime deserialize( JsonValue json,
-                                              BiFunction<JsonValue, ValueType, 
Object> deserializeFunction )
-            {
-                return ZonedDateTime.parse( JavaxJson.asString( json ) );
-            }
-        }
-
-        private static class InstantAdapter extends 
ToJsonStringAdapter<Instant>
-        {
-            @Override
-            public Class<Instant> type() { return Instant.class; }
-
-            @Override
-            public Instant deserialize( JsonValue json, BiFunction<JsonValue, 
ValueType, Object> deserializeFunction )
-            {
-                return Instant.parse( JavaxJson.asString( json ) );
-            }
-        }
-
-        private static class IdentityAdapter extends 
ToJsonStringAdapter<Identity>
-        {
-            @Override
-            public Class<Identity> type() { return Identity.class; }
-
-            @Override
-            public Identity deserialize( JsonValue json, BiFunction<JsonValue, 
ValueType, Object> deserializeFunction )
-            {
-                return StringIdentity.fromString( JavaxJson.asString( json ) );
-            }
-        }
-
-        private static class EntityReferenceAdapter extends 
ToJsonStringAdapter<EntityReference>
-        {
-            @Override
-            public Class<EntityReference> type() { return 
EntityReference.class; }
-
-            @Override
-            public EntityReference deserialize( JsonValue json,
-                                                BiFunction<JsonValue, 
ValueType, Object> deserializeFunction )
-            {
-                return EntityReference.parseEntityReference( 
JavaxJson.asString( json ) );
-            }
-        }
     }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b094d05f/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializer.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializer.java
 
b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializer.java
index c93c822..07294a9 100644
--- 
a/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializer.java
+++ 
b/core/spi/src/main/java/org/apache/polygene/serialization/javaxjson/JavaxJsonSerializer.java
@@ -39,9 +39,10 @@ import 
org.apache.polygene.api.association.AssociationStateHolder;
 import org.apache.polygene.api.composite.CompositeInstance;
 import org.apache.polygene.api.injection.scope.This;
 import org.apache.polygene.api.injection.scope.Uses;
+import org.apache.polygene.api.serialization.Converter;
+import org.apache.polygene.api.serialization.Converters;
 import org.apache.polygene.api.service.ServiceDescriptor;
 import org.apache.polygene.api.type.ArrayType;
-import org.apache.polygene.api.type.EnumType;
 import org.apache.polygene.api.type.MapType;
 import org.apache.polygene.api.type.ValueCompositeType;
 import org.apache.polygene.api.type.ValueType;
@@ -58,6 +59,9 @@ import static org.apache.polygene.api.util.Collectors.toMap;
 public class JavaxJsonSerializer extends AbstractTextSerializer implements 
JsonSerializer
 {
     @This
+    private Converters converters;
+
+    @This
     private JavaxJsonAdapters adapters;
 
     @Uses
@@ -76,15 +80,16 @@ public class JavaxJsonSerializer extends 
AbstractTextSerializer implements JsonS
             return JsonValue.NULL;
         }
         Class<?> objectClass = object.getClass();
+        Converter<Object> converter = converters.converterFor( objectClass );
+        if( converter != null )
+        {
+            return doSerialize( options, converter.toString( object ), false );
+        }
         JavaxJsonAdapter<?> adapter = adapters.adapterFor( objectClass );
         if( adapter != null )
         {
             return adapter.serialize( object, obj -> doSerialize( options, 
obj, false ) );
         }
-        if( EnumType.isEnum( objectClass ) )
-        {
-            return JavaxJson.toJsonString( object.toString() );
-        }
         if( ValueCompositeType.isValueComposite( objectClass ) )
         {
             return serializeValueComposite( options, object, root );

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b094d05f/core/spi/src/main/java/org/apache/polygene/spi/serialization/BuiltInConverters.java
----------------------------------------------------------------------
diff --git 
a/core/spi/src/main/java/org/apache/polygene/spi/serialization/BuiltInConverters.java
 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/BuiltInConverters.java
new file mode 100644
index 0000000..a6392ff
--- /dev/null
+++ 
b/core/spi/src/main/java/org/apache/polygene/spi/serialization/BuiltInConverters.java
@@ -0,0 +1,235 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.apache.polygene.spi.serialization;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.time.Period;
+import java.time.ZonedDateTime;
+import org.apache.polygene.api.entity.EntityReference;
+import org.apache.polygene.api.identity.Identity;
+import org.apache.polygene.api.identity.StringIdentity;
+import org.apache.polygene.api.mixin.Mixins;
+import org.apache.polygene.api.serialization.Converter;
+import org.apache.polygene.api.serialization.Converters;
+import org.apache.polygene.api.type.ValueType;
+
+/**
+ * Built-in serialization converters.
+ */
+@Mixins( BuiltInConverters.Mixin.class )
+public interface BuiltInConverters
+{
+    void registerBuiltInConverters( Converters converters );
+
+    class Mixin implements BuiltInConverters
+    {
+        @Override
+        public void registerBuiltInConverters( Converters converters )
+        {
+            // Polygene types
+            converters.registerConverter( ValueType.IDENTITY, new 
IdentityConverter() );
+            converters.registerConverter( ValueType.ENTITY_REFERENCE, new 
EntityReferenceConverter() );
+
+            // Big numbers types
+            converters.registerConverter( ValueType.BIG_DECIMAL, new 
BigDecimalConverter() );
+            converters.registerConverter( ValueType.BIG_INTEGER, new 
BigIntegerConverter() );
+
+            // Date types
+            converters.registerConverter( ValueType.INSTANT, new 
InstantConverter() );
+            converters.registerConverter( ValueType.ZONED_DATE_TIME, new 
ZonedDateTimeConverter() );
+            converters.registerConverter( ValueType.OFFSET_DATE_TIME, new 
OffsetDateTimeConverter() );
+            converters.registerConverter( ValueType.LOCAL_DATE_TIME, new 
LocalDateTimeConverter() );
+            converters.registerConverter( ValueType.LOCAL_DATE, new 
LocalDateConverter() );
+            converters.registerConverter( ValueType.LOCAL_TIME, new 
LocalTimeConverter() );
+            converters.registerConverter( ValueType.DURATION, new 
DurationConverter() );
+            converters.registerConverter( ValueType.PERIOD, new 
PeriodConverter() );
+        }
+
+        private static abstract class ToStringConverter<T> implements 
Converter<T>
+        {
+            @Override
+            public String toString( T object )
+            {
+                return object.toString();
+            }
+        }
+
+        private static class IdentityConverter extends 
ToStringConverter<Identity>
+        {
+            @Override
+            public Class<Identity> type()
+            {
+                return Identity.class;
+            }
+
+            @Override
+            public Identity fromString( String string )
+            {
+                return StringIdentity.fromString( string );
+            }
+        }
+
+        private static class EntityReferenceConverter extends 
ToStringConverter<EntityReference>
+        {
+            @Override
+            public Class<EntityReference> type()
+            {
+                return EntityReference.class;
+            }
+
+            @Override
+            public EntityReference fromString( String string )
+            {
+                return EntityReference.parseEntityReference( string );
+            }
+        }
+
+        private static class BigDecimalConverter extends 
ToStringConverter<BigDecimal>
+        {
+            @Override
+            public Class<BigDecimal> type()
+            {
+                return BigDecimal.class;
+            }
+
+            @Override
+            public BigDecimal fromString( String string )
+            {
+                return new BigDecimal( string );
+            }
+        }
+
+        private static class BigIntegerConverter extends 
ToStringConverter<BigInteger>
+        {
+            @Override
+            public Class<BigInteger> type()
+            {
+                return BigInteger.class;
+            }
+
+            @Override
+            public BigInteger fromString( String string )
+            {
+                return new BigInteger( string );
+            }
+        }
+
+        private static class PeriodConverter extends ToStringConverter<Period>
+        {
+            @Override
+            public Class<Period> type() { return Period.class; }
+
+            @Override
+            public Period fromString( String string )
+            {
+                return Period.parse( string );
+            }
+        }
+
+        private static class DurationConverter extends 
ToStringConverter<Duration>
+        {
+            @Override
+            public Class<Duration> type() { return Duration.class; }
+
+            @Override
+            public Duration fromString( String string )
+            {
+                return Duration.parse( string );
+            }
+        }
+
+        private static class LocalTimeConverter extends 
ToStringConverter<LocalTime>
+        {
+            @Override
+            public Class<LocalTime> type() { return LocalTime.class; }
+
+            @Override
+            public LocalTime fromString( String string )
+            {
+                return LocalTime.parse( string );
+            }
+        }
+
+        private static class LocalDateConverter extends 
ToStringConverter<LocalDate>
+        {
+            @Override
+            public Class<LocalDate> type() { return LocalDate.class; }
+
+            @Override
+            public LocalDate fromString( String string )
+            {
+                return LocalDate.parse( string );
+            }
+        }
+
+        private static class LocalDateTimeConverter extends 
ToStringConverter<LocalDateTime>
+        {
+            @Override
+            public Class<LocalDateTime> type() { return LocalDateTime.class; }
+
+            @Override
+            public LocalDateTime fromString( String string )
+            {
+                return LocalDateTime.parse( string );
+            }
+        }
+
+        private static class OffsetDateTimeConverter extends 
ToStringConverter<OffsetDateTime>
+        {
+            @Override
+            public Class<OffsetDateTime> type() { return OffsetDateTime.class; 
}
+
+            @Override
+            public OffsetDateTime fromString( String string )
+            {
+                return OffsetDateTime.parse( string );
+            }
+        }
+
+        private static class ZonedDateTimeConverter extends 
ToStringConverter<ZonedDateTime>
+        {
+            @Override
+            public Class<ZonedDateTime> type() { return ZonedDateTime.class; }
+
+            @Override
+            public ZonedDateTime fromString( String string )
+            {
+                return ZonedDateTime.parse( string );
+            }
+        }
+
+        private static class InstantConverter extends 
ToStringConverter<Instant>
+        {
+            @Override
+            public Class<Instant> type() { return Instant.class; }
+
+            @Override
+            public Instant fromString( String string )
+            {
+                return Instant.parse( string );
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b094d05f/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlDeserializer.java
----------------------------------------------------------------------
diff --git 
a/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlDeserializer.java
 
b/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlDeserializer.java
index 25f5a22..f477a8c 100644
--- 
a/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlDeserializer.java
+++ 
b/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlDeserializer.java
@@ -41,6 +41,8 @@ import org.apache.polygene.api.entity.EntityReference;
 import org.apache.polygene.api.injection.scope.This;
 import org.apache.polygene.api.injection.scope.Uses;
 import org.apache.polygene.api.property.PropertyDescriptor;
+import org.apache.polygene.api.serialization.Converter;
+import org.apache.polygene.api.serialization.Converters;
 import org.apache.polygene.api.serialization.SerializationException;
 import org.apache.polygene.api.service.ServiceDescriptor;
 import org.apache.polygene.api.structure.ModuleDescriptor;
@@ -69,6 +71,9 @@ public class JavaxXmlDeserializer extends 
AbstractTextDeserializer implements Xm
     private static final String NULL_ELEMENT_NAME = "null";
 
     @This
+    private Converters converters;
+
+    @This
     private JavaxXmlAdapters adapters;
 
     @Uses
@@ -97,6 +102,11 @@ public class JavaxXmlDeserializer extends 
AbstractTextDeserializer implements Xm
         {
             return null;
         }
+        Converter<Object> converter = converters.converterFor( valueType );
+        if( converter != null )
+        {
+            return (T) converter.fromString( doDeserialize( module, 
ValueType.STRING, xml ).toString() );
+        }
         JavaxXmlAdapter<?> adapter = adapters.adapterFor( valueType );
         if( adapter != null )
         {

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b094d05f/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlSerializationService.java
----------------------------------------------------------------------
diff --git 
a/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlSerializationService.java
 
b/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlSerializationService.java
index 3917340..10b692e 100644
--- 
a/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlSerializationService.java
+++ 
b/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlSerializationService.java
@@ -17,27 +17,16 @@
  */
 package org.apache.polygene.serialization.javaxxml;
 
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.time.Duration;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.OffsetDateTime;
-import java.time.Period;
-import java.time.ZonedDateTime;
 import java.util.function.BiFunction;
 import java.util.function.Function;
-import org.apache.polygene.api.entity.EntityReference;
-import org.apache.polygene.api.identity.Identity;
-import org.apache.polygene.api.identity.StringIdentity;
 import org.apache.polygene.api.injection.scope.This;
 import org.apache.polygene.api.injection.scope.Uses;
 import org.apache.polygene.api.mixin.Mixins;
+import org.apache.polygene.api.serialization.Converters;
 import org.apache.polygene.api.service.ServiceActivation;
 import org.apache.polygene.api.service.ServiceDescriptor;
 import org.apache.polygene.api.type.ValueType;
+import org.apache.polygene.spi.serialization.BuiltInConverters;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
 
@@ -50,6 +39,12 @@ public interface JavaxXmlSerializationService extends 
JavaxXmlSerialization, Ser
         private ServiceDescriptor descriptor;
 
         @This
+        private BuiltInConverters builtInConverters;
+
+        @This
+        private Converters converters;
+
+        @This
         private JavaxXmlAdapters adapters;
 
         private boolean registrationDone = false;
@@ -59,6 +54,8 @@ public interface JavaxXmlSerializationService extends 
JavaxXmlSerialization, Ser
         {
             if( !registrationDone )
             {
+                registerCustomConverters();
+                registerBuiltInConverters();
                 registerCustomAdapters();
                 registerBaseAdapters();
                 registrationDone = true;
@@ -68,6 +65,16 @@ public interface JavaxXmlSerializationService extends 
JavaxXmlSerialization, Ser
         @Override
         public void passivateService() {}
 
+        private void registerCustomConverters()
+        {
+            // TODO register custom converters
+        }
+
+        private void registerBuiltInConverters()
+        {
+            builtInConverters.registerBuiltInConverters( converters );
+        }
+
         private void registerCustomAdapters()
         {
             JavaxXmlSettings.orDefault( descriptor.metaInfo( 
JavaxXmlSettings.class ) )
@@ -87,24 +94,6 @@ public interface JavaxXmlSerializationService extends 
JavaxXmlSerialization, Ser
             adapters.registerAdapter( ValueType.BYTE, new ByteAdapter() );
             adapters.registerAdapter( ValueType.FLOAT, new FloatAdapter() );
             adapters.registerAdapter( ValueType.DOUBLE, new DoubleAdapter() );
-
-            // Number types
-            adapters.registerAdapter( ValueType.BIG_DECIMAL, new 
BigDecimalAdapter() );
-            adapters.registerAdapter( ValueType.BIG_INTEGER, new 
BigIntegerAdapter() );
-
-            // Date types
-            adapters.registerAdapter( ValueType.INSTANT, new InstantAdapter() 
);
-            adapters.registerAdapter( ValueType.ZONED_DATE_TIME, new 
ZonedDateTimeAdapter() );
-            adapters.registerAdapter( ValueType.OFFSET_DATE_TIME, new 
OffsetDateTimeAdapter() );
-            adapters.registerAdapter( ValueType.LOCAL_DATE_TIME, new 
LocalDateTimeAdapter() );
-            adapters.registerAdapter( ValueType.LOCAL_DATE, new 
LocalDateAdapter() );
-            adapters.registerAdapter( ValueType.LOCAL_TIME, new 
LocalTimeAdapter() );
-            adapters.registerAdapter( ValueType.DURATION, new 
DurationAdapter() );
-            adapters.registerAdapter( ValueType.PERIOD, new PeriodAdapter() );
-
-            // Other supported types
-            adapters.registerAdapter( ValueType.IDENTITY, new 
IdentityAdapter() );
-            adapters.registerAdapter( ValueType.ENTITY_REFERENCE, new 
EntityReferenceAdapter() );
         }
 
         private static abstract class ToStringTextNodeAdapter<T> implements 
JavaxXmlAdapter<T>
@@ -224,149 +213,5 @@ public interface JavaxXmlSerializationService extends 
JavaxXmlSerialization, Ser
                 return Double.valueOf( node.getNodeValue() );
             }
         }
-
-        private static class BigDecimalAdapter extends 
ToStringTextNodeAdapter<BigDecimal>
-        {
-            @Override
-            public Class<BigDecimal> type() { return BigDecimal.class; }
-
-            @Override
-            public BigDecimal deserialize( Node node, BiFunction<Node, 
ValueType, Object> deserializationFunction )
-            {
-                return new BigDecimal( node.getNodeValue() );
-            }
-        }
-
-        private static class BigIntegerAdapter extends 
ToStringTextNodeAdapter<BigInteger>
-        {
-            @Override
-            public Class<BigInteger> type() { return BigInteger.class; }
-
-            @Override
-            public BigInteger deserialize( Node node, BiFunction<Node, 
ValueType, Object> deserializationFunction )
-            {
-                return new BigInteger( node.getNodeValue() );
-            }
-        }
-
-        private static class InstantAdapter extends 
ToStringTextNodeAdapter<Instant>
-        {
-            @Override
-            public Class<Instant> type() { return Instant.class; }
-
-            @Override
-            public Instant deserialize( Node node, BiFunction<Node, ValueType, 
Object> deserializationFunction )
-            {
-                return Instant.parse( node.getNodeValue() );
-            }
-        }
-
-        private static class ZonedDateTimeAdapter extends 
ToStringTextNodeAdapter<ZonedDateTime>
-        {
-            @Override
-            public Class<ZonedDateTime> type() { return ZonedDateTime.class; }
-
-            @Override
-            public ZonedDateTime deserialize( Node node, BiFunction<Node, 
ValueType, Object> deserializationFunction )
-            {
-                return ZonedDateTime.parse( node.getNodeValue() );
-            }
-        }
-
-        private static class OffsetDateTimeAdapter extends 
ToStringTextNodeAdapter<OffsetDateTime>
-        {
-            @Override
-            public Class<OffsetDateTime> type() { return OffsetDateTime.class; 
}
-
-            @Override
-            public OffsetDateTime deserialize( Node node, BiFunction<Node, 
ValueType, Object> deserializationFunction )
-            {
-                return OffsetDateTime.parse( node.getNodeValue() );
-            }
-        }
-
-        private static class LocalDateTimeAdapter extends 
ToStringTextNodeAdapter<LocalDateTime>
-        {
-            @Override
-            public Class<LocalDateTime> type() { return LocalDateTime.class; }
-
-            @Override
-            public LocalDateTime deserialize( Node node, BiFunction<Node, 
ValueType, Object> deserializationFunction )
-            {
-                return LocalDateTime.parse( node.getNodeValue() );
-            }
-        }
-
-        private static class LocalDateAdapter extends 
ToStringTextNodeAdapter<LocalDate>
-        {
-            @Override
-            public Class<LocalDate> type() { return LocalDate.class; }
-
-            @Override
-            public LocalDate deserialize( Node node, BiFunction<Node, 
ValueType, Object> deserializationFunction )
-            {
-                return LocalDate.parse( node.getNodeValue() );
-            }
-        }
-
-        private static class LocalTimeAdapter extends 
ToStringTextNodeAdapter<LocalTime>
-        {
-            @Override
-            public Class<LocalTime> type() { return LocalTime.class; }
-
-            @Override
-            public LocalTime deserialize( Node node, BiFunction<Node, 
ValueType, Object> deserializationFunction )
-            {
-                return LocalTime.parse( node.getNodeValue() );
-            }
-        }
-
-        private static class DurationAdapter extends 
ToStringTextNodeAdapter<Duration>
-        {
-            @Override
-            public Class<Duration> type() { return Duration.class; }
-
-            @Override
-            public Duration deserialize( Node node, BiFunction<Node, 
ValueType, Object> deserializationFunction )
-            {
-                return Duration.parse( node.getNodeValue() );
-            }
-        }
-
-        private static class PeriodAdapter extends 
ToStringTextNodeAdapter<Period>
-        {
-            @Override
-            public Class<Period> type() { return Period.class; }
-
-            @Override
-            public Period deserialize( Node node, BiFunction<Node, ValueType, 
Object> deserializationFunction )
-            {
-                return Period.parse( node.getNodeValue() );
-            }
-        }
-
-        private static class IdentityAdapter extends 
ToStringTextNodeAdapter<Identity>
-        {
-            @Override
-            public Class<Identity> type() { return Identity.class; }
-
-            @Override
-            public Identity deserialize( Node node, BiFunction<Node, 
ValueType, Object> deserializationFunction )
-            {
-                return StringIdentity.fromString( node.getNodeValue() );
-            }
-        }
-
-        private static class EntityReferenceAdapter extends 
ToStringTextNodeAdapter<EntityReference>
-        {
-            @Override
-            public Class<EntityReference> type() { return 
EntityReference.class; }
-
-            @Override
-            public EntityReference deserialize( Node node, BiFunction<Node, 
ValueType, Object> deserializationFunction )
-            {
-                return EntityReference.parseEntityReference( 
node.getNodeValue() );
-            }
-        }
     }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b094d05f/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlSerializer.java
----------------------------------------------------------------------
diff --git 
a/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlSerializer.java
 
b/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlSerializer.java
index f0ce0fa..49f1fa0 100644
--- 
a/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlSerializer.java
+++ 
b/extensions/serialization-javaxxml/src/main/java/org/apache/polygene/serialization/javaxxml/JavaxXmlSerializer.java
@@ -34,6 +34,8 @@ import org.apache.polygene.api.composite.CompositeInstance;
 import org.apache.polygene.api.entity.EntityReference;
 import org.apache.polygene.api.injection.scope.This;
 import org.apache.polygene.api.injection.scope.Uses;
+import org.apache.polygene.api.serialization.Converter;
+import org.apache.polygene.api.serialization.Converters;
 import org.apache.polygene.api.serialization.SerializationException;
 import org.apache.polygene.api.service.ServiceDescriptor;
 import org.apache.polygene.api.type.ArrayType;
@@ -61,6 +63,9 @@ public class JavaxXmlSerializer extends 
AbstractTextSerializer implements XmlSer
     private static final String NULL_ELEMENT_NAME = "null";
 
     @This
+    private Converters converters;
+
+    @This
     private JavaxXmlAdapters adapters;
 
     @Uses
@@ -99,6 +104,11 @@ public class JavaxXmlSerializer extends 
AbstractTextSerializer implements XmlSer
             return document.createElement( NULL_ELEMENT_NAME );
         }
         Class<?> objectClass = object.getClass();
+        Converter<Object> converter = converters.converterFor( objectClass );
+        if( converter != null )
+        {
+            return doSerialize( document, options, converter.toString( object 
), false );
+        }
         JavaxXmlAdapter<?> adapter = adapters.adapterFor( objectClass );
         if( adapter != null )
         {

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b094d05f/extensions/serialization-msgpack/src/main/java/org/apache/polygene/serialization/msgpack/MessagePackDeserializer.java
----------------------------------------------------------------------
diff --git 
a/extensions/serialization-msgpack/src/main/java/org/apache/polygene/serialization/msgpack/MessagePackDeserializer.java
 
b/extensions/serialization-msgpack/src/main/java/org/apache/polygene/serialization/msgpack/MessagePackDeserializer.java
index 70b4b8a..7a82751 100644
--- 
a/extensions/serialization-msgpack/src/main/java/org/apache/polygene/serialization/msgpack/MessagePackDeserializer.java
+++ 
b/extensions/serialization-msgpack/src/main/java/org/apache/polygene/serialization/msgpack/MessagePackDeserializer.java
@@ -39,6 +39,8 @@ import org.apache.polygene.api.entity.EntityReference;
 import org.apache.polygene.api.injection.scope.This;
 import org.apache.polygene.api.mixin.Mixins;
 import org.apache.polygene.api.property.PropertyDescriptor;
+import org.apache.polygene.api.serialization.Converter;
+import org.apache.polygene.api.serialization.Converters;
 import org.apache.polygene.api.serialization.Deserializer;
 import org.apache.polygene.api.serialization.SerializationException;
 import org.apache.polygene.api.structure.ModuleDescriptor;
@@ -70,6 +72,9 @@ public interface MessagePackDeserializer extends Deserializer
     class Mixin extends AbstractBinaryDeserializer
     {
         @This
+        private Converters converters;
+
+        @This
         private MessagePackAdapters adapters;
 
         @Override
@@ -100,6 +105,11 @@ public interface MessagePackDeserializer extends 
Deserializer
                 {
                     return null;
                 }
+                Converter<Object> converter = converters.converterFor( 
valueType );
+                if( converter != null )
+                {
+                    return (T) converter.fromString( doDeserialize( module, 
ValueType.STRING, value ).toString() );
+                }
                 MessagePackAdapter<?> adapter = adapters.adapterFor( valueType 
);
                 if( adapter != null )
                 {

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b094d05f/extensions/serialization-msgpack/src/main/java/org/apache/polygene/serialization/msgpack/MessagePackSerializationService.java
----------------------------------------------------------------------
diff --git 
a/extensions/serialization-msgpack/src/main/java/org/apache/polygene/serialization/msgpack/MessagePackSerializationService.java
 
b/extensions/serialization-msgpack/src/main/java/org/apache/polygene/serialization/msgpack/MessagePackSerializationService.java
index 4cd23b7..51badc3 100644
--- 
a/extensions/serialization-msgpack/src/main/java/org/apache/polygene/serialization/msgpack/MessagePackSerializationService.java
+++ 
b/extensions/serialization-msgpack/src/main/java/org/apache/polygene/serialization/msgpack/MessagePackSerializationService.java
@@ -17,27 +17,16 @@
  */
 package org.apache.polygene.serialization.msgpack;
 
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.time.Duration;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.OffsetDateTime;
-import java.time.Period;
-import java.time.ZonedDateTime;
 import java.util.function.BiFunction;
 import java.util.function.Function;
-import org.apache.polygene.api.entity.EntityReference;
-import org.apache.polygene.api.identity.Identity;
-import org.apache.polygene.api.identity.StringIdentity;
 import org.apache.polygene.api.injection.scope.This;
 import org.apache.polygene.api.injection.scope.Uses;
 import org.apache.polygene.api.mixin.Mixins;
+import org.apache.polygene.api.serialization.Converters;
 import org.apache.polygene.api.service.ServiceActivation;
 import org.apache.polygene.api.service.ServiceDescriptor;
 import org.apache.polygene.api.type.ValueType;
+import org.apache.polygene.spi.serialization.BuiltInConverters;
 import org.msgpack.value.Value;
 import org.msgpack.value.ValueFactory;
 
@@ -50,6 +39,12 @@ public interface MessagePackSerializationService extends 
MessagePackSerializatio
         private ServiceDescriptor descriptor;
 
         @This
+        private BuiltInConverters builtInConverters;
+
+        @This
+        private Converters converters;
+
+        @This
         private MessagePackAdapters adapters;
 
         private boolean registrationDone = false;
@@ -59,6 +54,8 @@ public interface MessagePackSerializationService extends 
MessagePackSerializatio
         {
             if( !registrationDone )
             {
+                registerCustomConverters();
+                registerBuiltInConverters();
                 registerCustomAdapters();
                 registerBaseAdapters();
                 registrationDone = true;
@@ -68,6 +65,16 @@ public interface MessagePackSerializationService extends 
MessagePackSerializatio
         @Override
         public void passivateService() {}
 
+        private void registerCustomConverters()
+        {
+            // TODO register custom converters
+        }
+
+        private void registerBuiltInConverters()
+        {
+            builtInConverters.registerBuiltInConverters( converters );
+        }
+
         private void registerCustomAdapters()
         {
             MessagePackSettings.orDefault( descriptor.metaInfo( 
MessagePackSettings.class ) )
@@ -87,24 +94,6 @@ public interface MessagePackSerializationService extends 
MessagePackSerializatio
             adapters.registerAdapter( ValueType.BYTE, new ByteAdapter() );
             adapters.registerAdapter( ValueType.FLOAT, new FloatAdapter() );
             adapters.registerAdapter( ValueType.DOUBLE, new DoubleAdapter() );
-
-            // Number types
-            adapters.registerAdapter( ValueType.BIG_DECIMAL, new 
BigDecimalAdapter() );
-            adapters.registerAdapter( ValueType.BIG_INTEGER, new 
BigIntegerAdapter() );
-
-            // Date types
-            adapters.registerAdapter( ValueType.INSTANT, new InstantAdapter() 
);
-            adapters.registerAdapter( ValueType.ZONED_DATE_TIME, new 
ZonedDateTimeAdapter() );
-            adapters.registerAdapter( ValueType.OFFSET_DATE_TIME, new 
OffsetDateTimeAdapter() );
-            adapters.registerAdapter( ValueType.LOCAL_DATE_TIME, new 
LocalDateTimeAdapter() );
-            adapters.registerAdapter( ValueType.LOCAL_DATE, new 
LocalDateAdapter() );
-            adapters.registerAdapter( ValueType.LOCAL_TIME, new 
LocalTimeAdapter() );
-            adapters.registerAdapter( ValueType.DURATION, new 
DurationAdapter() );
-            adapters.registerAdapter( ValueType.PERIOD, new PeriodAdapter() );
-
-            // Other supported types
-            adapters.registerAdapter( ValueType.IDENTITY, new 
IdentityAdapter() );
-            adapters.registerAdapter( ValueType.ENTITY_REFERENCE, new 
EntityReferenceAdapter() );
         }
 
         private static abstract class ToStringAdapter<T> implements 
MessagePackAdapter<T>
@@ -266,149 +255,5 @@ public interface MessagePackSerializationService extends 
MessagePackSerializatio
                 return value.asFloatValue().toDouble();
             }
         }
-
-        private static class BigDecimalAdapter extends 
ToStringAdapter<BigDecimal>
-        {
-            @Override
-            public Class<BigDecimal> type() { return BigDecimal.class; }
-
-            @Override
-            public BigDecimal deserialize( Value value, BiFunction<Value, 
ValueType, Object> deserializeFunction )
-            {
-                return new BigDecimal( value.asStringValue().asString() );
-            }
-        }
-
-        private static class BigIntegerAdapter extends 
ToStringAdapter<BigInteger>
-        {
-            @Override
-            public Class<BigInteger> type() { return BigInteger.class; }
-
-            @Override
-            public BigInteger deserialize( Value value, BiFunction<Value, 
ValueType, Object> deserializeFunction )
-            {
-                return new BigInteger( value.asStringValue().asString() );
-            }
-        }
-
-        private static class InstantAdapter extends ToStringAdapter<Instant>
-        {
-            @Override
-            public Class<Instant> type() { return Instant.class; }
-
-            @Override
-            public Instant deserialize( Value value, BiFunction<Value, 
ValueType, Object> deserializeFunction )
-            {
-                return Instant.parse( value.asStringValue().asString() );
-            }
-        }
-
-        private static class ZonedDateTimeAdapter extends 
ToStringAdapter<ZonedDateTime>
-        {
-            @Override
-            public Class<ZonedDateTime> type() { return ZonedDateTime.class; }
-
-            @Override
-            public ZonedDateTime deserialize( Value value, BiFunction<Value, 
ValueType, Object> deserializeFunction )
-            {
-                return ZonedDateTime.parse( value.asStringValue().asString() );
-            }
-        }
-
-        private static class OffsetDateTimeAdapter extends 
ToStringAdapter<OffsetDateTime>
-        {
-            @Override
-            public Class<OffsetDateTime> type() { return OffsetDateTime.class; 
}
-
-            @Override
-            public OffsetDateTime deserialize( Value value, BiFunction<Value, 
ValueType, Object> deserializeFunction )
-            {
-                return OffsetDateTime.parse( value.asStringValue().asString() 
);
-            }
-        }
-
-        private static class LocalDateTimeAdapter extends 
ToStringAdapter<LocalDateTime>
-        {
-            @Override
-            public Class<LocalDateTime> type() { return LocalDateTime.class; }
-
-            @Override
-            public LocalDateTime deserialize( Value value, BiFunction<Value, 
ValueType, Object> deserializeFunction )
-            {
-                return LocalDateTime.parse( value.asStringValue().asString() );
-            }
-        }
-
-        private static class LocalDateAdapter extends 
ToStringAdapter<LocalDate>
-        {
-            @Override
-            public Class<LocalDate> type() { return LocalDate.class; }
-
-            @Override
-            public LocalDate deserialize( Value value, BiFunction<Value, 
ValueType, Object> deserializeFunction )
-            {
-                return LocalDate.parse( value.asStringValue().asString() );
-            }
-        }
-
-        private static class LocalTimeAdapter extends 
ToStringAdapter<LocalTime>
-        {
-            @Override
-            public Class<LocalTime> type() { return LocalTime.class; }
-
-            @Override
-            public LocalTime deserialize( Value value, BiFunction<Value, 
ValueType, Object> deserializeFunction )
-            {
-                return LocalTime.parse( value.asStringValue().asString() );
-            }
-        }
-
-        private static class DurationAdapter extends ToStringAdapter<Duration>
-        {
-            @Override
-            public Class<Duration> type() { return Duration.class; }
-
-            @Override
-            public Duration deserialize( Value value, BiFunction<Value, 
ValueType, Object> deserializeFunction )
-            {
-                return Duration.parse( value.asStringValue().asString() );
-            }
-        }
-
-        private static class PeriodAdapter extends ToStringAdapter<Period>
-        {
-            @Override
-            public Class<Period> type() { return Period.class; }
-
-            @Override
-            public Period deserialize( Value value, BiFunction<Value, 
ValueType, Object> deserializeFunction )
-            {
-                return Period.parse( value.asStringValue().asString() );
-            }
-        }
-
-        private static class IdentityAdapter extends ToStringAdapter<Identity>
-        {
-            @Override
-            public Class<Identity> type() { return Identity.class; }
-
-            @Override
-            public Identity deserialize( Value value, BiFunction<Value, 
ValueType, Object> deserializeFunction )
-            {
-                return StringIdentity.fromString( 
value.asStringValue().asString() );
-            }
-        }
-
-        private static class EntityReferenceAdapter extends 
ToStringAdapter<EntityReference>
-        {
-            @Override
-            public Class<EntityReference> type() { return 
EntityReference.class; }
-
-            @Override
-            public EntityReference deserialize( Value value, BiFunction<Value, 
ValueType, Object> deserializeFunction )
-            {
-                return EntityReference.parseEntityReference( 
value.asStringValue().asString() );
-            }
-        }
     }
 }

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/b094d05f/extensions/serialization-msgpack/src/main/java/org/apache/polygene/serialization/msgpack/MessagePackSerializer.java
----------------------------------------------------------------------
diff --git 
a/extensions/serialization-msgpack/src/main/java/org/apache/polygene/serialization/msgpack/MessagePackSerializer.java
 
b/extensions/serialization-msgpack/src/main/java/org/apache/polygene/serialization/msgpack/MessagePackSerializer.java
index a8f396c..c01ef29 100644
--- 
a/extensions/serialization-msgpack/src/main/java/org/apache/polygene/serialization/msgpack/MessagePackSerializer.java
+++ 
b/extensions/serialization-msgpack/src/main/java/org/apache/polygene/serialization/msgpack/MessagePackSerializer.java
@@ -30,6 +30,8 @@ import org.apache.polygene.api.common.Optional;
 import org.apache.polygene.api.composite.CompositeInstance;
 import org.apache.polygene.api.injection.scope.This;
 import org.apache.polygene.api.mixin.Mixins;
+import org.apache.polygene.api.serialization.Converter;
+import org.apache.polygene.api.serialization.Converters;
 import org.apache.polygene.api.serialization.SerializationException;
 import org.apache.polygene.api.serialization.Serializer;
 import org.apache.polygene.api.type.ArrayType;
@@ -57,6 +59,9 @@ public interface MessagePackSerializer extends Serializer
     class Mixin extends AbstractBinarySerializer
     {
         @This
+        private Converters converters;
+
+        @This
         private MessagePackAdapters adapters;
 
         @Override
@@ -84,6 +89,11 @@ public interface MessagePackSerializer extends Serializer
                     return ValueFactory.newNil();
                 }
                 Class<?> objectClass = object.getClass();
+                Converter<Object> converter = converters.converterFor( 
objectClass );
+                if( converter != null )
+                {
+                    return doSerialize( options, converter.toString( object ), 
false );
+                }
                 MessagePackAdapter<?> adapter = adapters.adapterFor( 
objectClass );
                 if( adapter != null )
                 {

Reply via email to