You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by pa...@apache.org on 2017/03/13 15:29:00 UTC

[37/48] polygene-java git commit: POLYGENE-231 value state can now contain arrays

POLYGENE-231 value state can now contain arrays

byte[] are serialized as such, Base64 encoded in text-based formats.
Other arrays, including primitive ones, are (de)serialized like
collections.

Supported by json, xml & msgpack serialization extensions


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

Branch: refs/heads/serialization-3.0
Commit: 7a574037d0cdacf6c892011e2ceb32e140a9f553
Parents: 1d8f6fb
Author: Paul Merlin <pa...@apache.org>
Authored: Mon Mar 6 16:33:10 2017 +0100
Committer: Paul Merlin <pa...@apache.org>
Committed: Mon Mar 13 16:27:47 2017 +0100

----------------------------------------------------------------------
 .../org/apache/polygene/api/type/ArrayType.java | 97 ++++++++++++++++++++
 .../apache/polygene/api/util/ArrayIterable.java | 75 +++++++++++++++
 .../runtime/property/PropertyInstance.java      | 45 +++++++++
 .../runtime/type/ValueTypeFactoryInstance.java  |  5 +
 .../javaxjson/JavaxJsonDeserializer.java        | 29 ++++++
 .../javaxjson/JavaxJsonSerializer.java          | 30 +++++-
 ...AbstractValueCompositeSerializationTest.java | 38 +++-----
 .../javaxxml/JavaxXmlDeserializer.java          | 23 +++++
 .../javaxxml/JavaxXmlSerializer.java            | 21 +++++
 .../msgpack/MessagePackDeserializer.java        | 22 +++++
 .../msgpack/MessagePackSerializer.java          | 20 ++++
 11 files changed, 379 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/polygene-java/blob/7a574037/core/api/src/main/java/org/apache/polygene/api/type/ArrayType.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/type/ArrayType.java b/core/api/src/main/java/org/apache/polygene/api/type/ArrayType.java
new file mode 100644
index 0000000..29834ce
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/type/ArrayType.java
@@ -0,0 +1,97 @@
+/*
+ *  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.type;
+
+import java.lang.reflect.Type;
+import java.util.Objects;
+import org.apache.polygene.api.util.Classes;
+
+/**
+ * Array ValueType.
+ * <p>This handles arrays of primitives and values</p>
+ */
+public class ArrayType extends ValueType
+{
+    public static boolean isArray( Type type )
+    {
+        return Classes.RAW_CLASS.apply( type ).isArray();
+    }
+
+    public static ArrayType of( Class<?> arrayType )
+    {
+        return new ArrayType( arrayType, ValueType.of( arrayType.getComponentType() ) );
+    }
+
+    private ValueType collectedType;
+
+    public ArrayType( Class<?> type, ValueType collectedType )
+    {
+        super( type );
+        this.collectedType = collectedType;
+        if( !isArray( type ) )
+        {
+            throw new IllegalArgumentException( type + " is not an array" );
+        }
+    }
+
+    public ValueType collectedType()
+    {
+        return collectedType;
+    }
+
+    public boolean isArrayOfPrimitives()
+    {
+        return hasType( boolean[].class )
+               || hasType( char[].class )
+               || hasType( short[].class )
+               || hasType( int[].class )
+               || hasType( byte[].class )
+               || hasType( long[].class )
+               || hasType( float[].class )
+               || hasType( double[].class );
+    }
+
+    public boolean isArrayOfPrimitiveBytes()
+    {
+        return hasType( byte[].class );
+    }
+
+    @Override
+    public boolean equals( final Object o )
+    {
+        if( this == o ) { return true; }
+        if( o == null || getClass() != o.getClass() ) { return false; }
+        if( !super.equals( o ) ) { return false; }
+        ArrayType that = (ArrayType) o;
+        return Objects.equals( collectedType, that.collectedType );
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return Objects.hash( super.hashCode(), collectedType );
+    }
+
+    @Override
+    public String toString()
+    {
+        return collectedType + "[]";
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/7a574037/core/api/src/main/java/org/apache/polygene/api/util/ArrayIterable.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/util/ArrayIterable.java b/core/api/src/main/java/org/apache/polygene/api/util/ArrayIterable.java
new file mode 100644
index 0000000..707eaca
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/util/ArrayIterable.java
@@ -0,0 +1,75 @@
+/*
+ *  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.util;
+
+import java.lang.reflect.Array;
+import java.util.Iterator;
+
+/**
+ * Iterate over arrays, both primitive arrays and Object[].
+ */
+public class ArrayIterable implements Iterable<Object>
+{
+    private final Object array;
+
+    public ArrayIterable( final Object array )
+    {
+        if( !array.getClass().isArray() )
+        {
+            throw new IllegalArgumentException( array + " is not an array" );
+        }
+        this.array = array;
+    }
+
+    @Override
+    public Iterator<Object> iterator()
+    {
+        return new ArrayIterator( array );
+    }
+
+    private class ArrayIterator implements Iterator<Object>
+    {
+        private final Object array;
+        private int currentIndex = 0;
+
+        private ArrayIterator( Object array )
+        {
+            this.array = array;
+        }
+
+        @Override
+        public boolean hasNext()
+        {
+            return currentIndex < Array.getLength( array );
+        }
+
+        @Override
+        public Object next()
+        {
+            return Array.get( array, currentIndex++ );
+        }
+
+        @Override
+        public void remove()
+        {
+            throw new UnsupportedOperationException( "cannot remove items from an array" );
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/7a574037/core/runtime/src/main/java/org/apache/polygene/runtime/property/PropertyInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/property/PropertyInstance.java b/core/runtime/src/main/java/org/apache/polygene/runtime/property/PropertyInstance.java
index 72d39cb..41d5e3c 100644
--- a/core/runtime/src/main/java/org/apache/polygene/runtime/property/PropertyInstance.java
+++ b/core/runtime/src/main/java/org/apache/polygene/runtime/property/PropertyInstance.java
@@ -20,6 +20,7 @@
 package org.apache.polygene.runtime.property;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashMap;
@@ -139,6 +140,50 @@ public class PropertyInstance<T>
         {
             return that.get() == null;
         }
+        Class<?> valueClass = value.getClass();
+        // Handling arrays
+        if( valueClass.isArray() )
+        {
+            Object thatValue = that.get();
+            if( !thatValue.getClass().isArray() )
+            {
+                return false;
+            }
+            Class<?> componentType = valueClass.getComponentType();
+            if( boolean.class.equals( componentType ) )
+            {
+                return Arrays.equals( (boolean[]) value, (boolean[]) thatValue );
+            }
+            if( char.class.equals( componentType ) )
+            {
+                return Arrays.equals( (char[]) value, (char[]) thatValue );
+            }
+            if( short.class.equals( componentType ) )
+            {
+                return Arrays.equals( (short[]) value, (short[]) thatValue );
+            }
+            if( int.class.equals( componentType ) )
+            {
+                return Arrays.equals( (int[]) value, (int[]) thatValue );
+            }
+            if( byte.class.equals( componentType ) )
+            {
+                return Arrays.equals( (byte[]) value, (byte[]) thatValue );
+            }
+            if( long.class.equals( componentType ) )
+            {
+                return Arrays.equals( (long[]) value, (long[]) thatValue );
+            }
+            if( float.class.equals( componentType ) )
+            {
+                return Arrays.equals( (float[]) value, (float[]) thatValue );
+            }
+            if( double.class.equals( componentType ) )
+            {
+                return Arrays.equals( (double[]) value, (double[]) thatValue );
+            }
+            return Arrays.deepEquals( (Object[]) value, (Object[]) thatValue );
+        }
         return value.equals( that.get() );
     }
 

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/7a574037/core/runtime/src/main/java/org/apache/polygene/runtime/type/ValueTypeFactoryInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/polygene/runtime/type/ValueTypeFactoryInstance.java b/core/runtime/src/main/java/org/apache/polygene/runtime/type/ValueTypeFactoryInstance.java
index 37a1b91..21134e8 100644
--- a/core/runtime/src/main/java/org/apache/polygene/runtime/type/ValueTypeFactoryInstance.java
+++ b/core/runtime/src/main/java/org/apache/polygene/runtime/type/ValueTypeFactoryInstance.java
@@ -25,6 +25,7 @@ import java.lang.reflect.Type;
 import java.lang.reflect.TypeVariable;
 import org.apache.polygene.api.common.InvalidApplicationException;
 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;
@@ -77,6 +78,10 @@ public class ValueTypeFactoryInstance implements ValueTypeFactory
         {
             valueType = EnumType.of( Classes.RAW_CLASS.apply( type ) );
         }
+        else if( ArrayType.isArray( type ) )
+        {
+            valueType = ArrayType.of( Classes.RAW_CLASS.apply( type ) );
+        }
         else if( CollectionType.isCollection( type ) )
         {
             if( type instanceof ParameterizedType )

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/7a574037/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 721c884..b9d9e94 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
@@ -20,6 +20,7 @@ package org.apache.polygene.serialization.javaxjson;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.ObjectInputStream;
+import java.lang.reflect.Array;
 import java.util.AbstractMap;
 import java.util.ArrayList;
 import java.util.Base64;
@@ -43,6 +44,7 @@ import org.apache.polygene.api.property.PropertyDescriptor;
 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;
@@ -95,6 +97,10 @@ public class JavaxJsonDeserializer extends AbstractTextDeserializer implements J
         {
             return (T) Enum.valueOf( (Class) valueType.primaryType(), asString( json ) );
         }
+        if( ArrayType.class.isAssignableFrom( valueTypeClass ) )
+        {
+            return (T) deserializeArray( module, (ArrayType) valueType, json );
+        }
         if( CollectionType.class.isAssignableFrom( valueTypeClass ) )
         {
             return (T) deserializeCollection( module, (CollectionType) valueType, requireJsonArray( json ) );
@@ -110,6 +116,29 @@ public class JavaxJsonDeserializer extends AbstractTextDeserializer implements J
         return doGuessDeserialize( module, valueType, json );
     }
 
+    private Object deserializeArray( ModuleDescriptor module, ArrayType arrayType, JsonValue json )
+    {
+        if( arrayType.isArrayOfPrimitiveBytes() && json.getValueType() == JsonValue.ValueType.STRING )
+        {
+            byte[] bytes = asString( json ).getBytes( UTF_8 );
+            return Base64.getDecoder().decode( bytes );
+        }
+        if( json.getValueType() == JsonValue.ValueType.ARRAY )
+        {
+            CollectionType collectionType = CollectionType.listOf( arrayType.collectedType() );
+            List<Object> collection = (List<Object>) deserializeCollection( module,
+                                                                            collectionType,
+                                                                            requireJsonArray( json ) );
+            Object array = Array.newInstance( arrayType.collectedType().primaryType(), collection.size() );
+            for( int idx = 0; idx < collection.size(); idx++ )
+            {
+                Array.set( array, idx, collection.get( idx ) );
+            }
+            return array;
+        }
+        throw new SerializationException( "Don't know how to deserialize " + arrayType + " from " + json );
+    }
+
     @SuppressWarnings( "unchecked" )
     private <T> T doGuessDeserialize( ModuleDescriptor module, ValueType valueType, JsonValue json )
     {

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/7a574037/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 5450ec9..c93c822 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
@@ -40,10 +40,12 @@ 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.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;
+import org.apache.polygene.api.util.ArrayIterable;
 import org.apache.polygene.api.value.ValueComposite;
 import org.apache.polygene.api.value.ValueDescriptor;
 import org.apache.polygene.spi.serialization.AbstractTextSerializer;
@@ -91,6 +93,10 @@ public class JavaxJsonSerializer extends AbstractTextSerializer implements JsonS
         {
             return serializeMap( options, (Map<?, ?>) object );
         }
+        if( ArrayType.isArray( objectClass ) )
+        {
+            return serializeArray( options, object );
+        }
         if( Iterable.class.isAssignableFrom( objectClass ) )
         {
             return serializeIterable( options, (Iterable<?>) object );
@@ -181,6 +187,21 @@ public class JavaxJsonSerializer extends AbstractTextSerializer implements JsonS
         }
     }
 
+    private JsonValue serializeArray( Options options, Object object )
+    {
+        ArrayType valueType = ArrayType.of( object.getClass() );
+        if( valueType.isArrayOfPrimitiveBytes() )
+        {
+            byte[] base64 = Base64.getEncoder().encode( (byte[]) object );
+            return JavaxJson.toJsonString( new String( base64, UTF_8 ) );
+        }
+        if( valueType.isArrayOfPrimitives() )
+        {
+            return serializeIterable( options, new ArrayIterable( object ) );
+        }
+        return serializeStream( options, Stream.of( (Object[]) object ) );
+    }
+
     private JsonArray serializeIterable( Options options, Iterable<?> iterable )
     {
         return serializeStream( options, StreamSupport.stream( iterable.spliterator(), false ) );
@@ -195,12 +216,17 @@ public class JavaxJsonSerializer extends AbstractTextSerializer implements JsonS
 
     private JsonString serializeBase64( Object object )
     {
+        byte[] bytes = Base64.getEncoder().encode( javaSerialization( object ) );
+        return JavaxJson.toJsonString( new String( bytes, UTF_8 ) );
+    }
+
+    private byte[] javaSerialization( Object object )
+    {
         ByteArrayOutputStream bout = new ByteArrayOutputStream();
         try( ObjectOutputStream out = new ObjectOutputStream( bout ) )
         {
             out.writeUnshared( object );
-            byte[] bytes = Base64.getEncoder().encode( bout.toByteArray() );
-            return JavaxJson.toJsonString( new String( bytes, UTF_8 ) );
+            return bout.toByteArray();
         }
         catch( IOException ex )
         {

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/7a574037/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractValueCompositeSerializationTest.java
----------------------------------------------------------------------
diff --git a/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractValueCompositeSerializationTest.java b/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractValueCompositeSerializationTest.java
index dced530..a0975ee 100644
--- a/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractValueCompositeSerializationTest.java
+++ b/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractValueCompositeSerializationTest.java
@@ -61,6 +61,7 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TestName;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.apache.polygene.api.usecase.UsecaseBuilder.newUsecase;
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.is;
@@ -69,7 +70,6 @@ import static org.junit.Assert.assertThat;
 /**
  * Assert that ValueSerialization behaviour on ValueComposites is correct.
  */
-// TODO Assert Arrays behaviour!
 // TODO Assert Generics behaviour!
 public abstract class AbstractValueCompositeSerializationTest
     extends AbstractPolygeneTest
@@ -320,24 +320,15 @@ public abstract class AbstractValueCompositeSerializationTest
 
         some.stringValueMap().get().put( "foo", anotherValue1 );
         some.another().set( anotherValue1 );
-        // some.arrayOfValues().set( new AnotherValue[] { anotherValue1, anotherValue2, anotherValue3 } );
+        some.arrayOfValues().set( new AnotherValue[] { anotherValue1, anotherValue2, anotherValue3 } );
+        some.primitiveByteArray().set( "foo".getBytes( UTF_8 ) );
+        some.byteArray().set( new Byte[] { 23, null, 42 } );
         some.serializable().set( new SerializableObject() );
         some.foo().set( module.newValue( FooValue.class ) );
         some.fooValue().set( module.newValue( FooValue.class ) );
         some.customFoo().set( module.newValue( CustomFooValue.class ) );
         some.customFooValue().set( module.newValue( CustomFooValue.class ) );
 
-        // Arrays
-        // TODO FIXME Disabled as ValueComposite equality fails here
-        //proto.primitiveByteArray().set( new byte[]
-        //    {
-        //        9, -12, 42, -12, 127, 23, -128, 73
-        //    } );
-        //proto.byteArray().set( new Byte[]
-        //    {
-        //        9, null, -12, 23, -12, 127, -128, 73
-        //    } );
-
         // NestedEntities
         some.barAssociation().set( buildBarEntity( uow, "bazar in barAssociation" ) );
         some.barEntityAssociation().set( buildBarEntity( uow, "bazar in barEntityAssociation" ) );
@@ -410,7 +401,7 @@ public abstract class AbstractValueCompositeSerializationTest
 
         Property<AnotherValue> another();
 
-        // Property<AnotherValue[]> arrayOfValues();
+        Property<AnotherValue[]> arrayOfValues();
 
         @Optional
         Property<AnotherValue> anotherNull();
@@ -427,16 +418,15 @@ public abstract class AbstractValueCompositeSerializationTest
         @UseDefaults
         Property<TestEnum> testEnum();
 
-        // TODO FIXME Disabled as ValueComposite equality fails here
-        //Property<byte[]> primitiveByteArray();
-        //
-        //@Optional
-        //Property<byte[]> primitiveByteArrayNull();
-        //
-        //Property<Byte[]> byteArray();
-        //
-        //@Optional
-        //Property<Byte[]> byteArrayNull();
+        Property<byte[]> primitiveByteArray();
+
+        @Optional
+        Property<byte[]> primitiveByteArrayNull();
+
+        Property<Byte[]> byteArray();
+
+        @Optional
+        Property<Byte[]> byteArrayNull();
 
         Property<Object> serializable();
 

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/7a574037/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 d556f09..25f5a22 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
@@ -20,6 +20,7 @@ package org.apache.polygene.serialization.javaxxml;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.ObjectInputStream;
+import java.lang.reflect.Array;
 import java.util.ArrayList;
 import java.util.Base64;
 import java.util.Collection;
@@ -43,6 +44,7 @@ import org.apache.polygene.api.property.PropertyDescriptor;
 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;
@@ -104,6 +106,10 @@ public class JavaxXmlDeserializer extends AbstractTextDeserializer implements Xm
         {
             return (T) Enum.valueOf( (Class) valueType.primaryType(), xml.getNodeValue() );
         }
+        if( ArrayType.class.isAssignableFrom( valueType.getClass() ) )
+        {
+            return (T) deserializeArray( module, (ArrayType) valueType, xml );
+        }
         if( CollectionType.class.isAssignableFrom( valueType.getClass() ) )
         {
             return (T) deserializeCollection( module, (CollectionType) valueType, xml );
@@ -209,6 +215,23 @@ public class JavaxXmlDeserializer extends AbstractTextDeserializer implements Xm
                              .orElse( Stream.empty() );
     }
 
+
+    private Object deserializeArray( ModuleDescriptor module, ArrayType arrayType, Node xml )
+    {
+        if( arrayType.isArrayOfPrimitiveBytes() )
+        {
+            return Base64.getDecoder().decode( xml.getNodeValue().getBytes( UTF_8 ) );
+        }
+        CollectionType collectionType = CollectionType.listOf( arrayType.collectedType() );
+        List collection = (List) deserializeCollection( module, collectionType, xml );
+        Object array = Array.newInstance( arrayType.collectedType().primaryType(), collection.size() );
+        for( int idx = 0; idx < collection.size(); idx++ )
+        {
+            Array.set( array, idx, collection.get( idx ) );
+        }
+        return array;
+    }
+
     @SuppressWarnings( "unchecked" )
     private Collection deserializeCollection( ModuleDescriptor module, CollectionType collectionType, Node xml )
     {

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/7a574037/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 bf26f0c..f0ce0fa 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
@@ -36,9 +36,11 @@ import org.apache.polygene.api.injection.scope.This;
 import org.apache.polygene.api.injection.scope.Uses;
 import org.apache.polygene.api.serialization.SerializationException;
 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.util.ArrayIterable;
 import org.apache.polygene.api.value.ValueComposite;
 import org.apache.polygene.api.value.ValueDescriptor;
 import org.apache.polygene.spi.serialization.AbstractTextSerializer;
@@ -114,6 +116,10 @@ public class JavaxXmlSerializer extends AbstractTextSerializer implements XmlSer
         {
             return serializeMap( document, options, (Map<?, ?>) object );
         }
+        if( ArrayType.isArray( objectClass ) )
+        {
+            return serializeArray( document, options, object );
+        }
         if( Iterable.class.isAssignableFrom( objectClass ) )
         {
             return serializeIterable( document, options, (Iterable<?>) object );
@@ -230,6 +236,21 @@ public class JavaxXmlSerializer extends AbstractTextSerializer implements XmlSer
         return mapElement;
     }
 
+    private <T> Node serializeArray( Document document, Options options, T object )
+    {
+        ArrayType valueType = ArrayType.of( object.getClass() );
+        if( valueType.isArrayOfPrimitiveBytes() )
+        {
+            byte[] base64 = Base64.getEncoder().encode( (byte[]) object );
+            return document.createCDATASection( new String( base64, UTF_8 ) );
+        }
+        if( valueType.isArrayOfPrimitives() )
+        {
+            return serializeIterable( document, options, new ArrayIterable( object ) );
+        }
+        return serializeStream( document, options, Stream.of( (Object[]) object ) );
+    }
+
     private Node serializeIterable( Document document, Options options, Iterable<?> object )
     {
         return serializeStream( document, options, StreamSupport.stream( object.spliterator(), false ) );

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/7a574037/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 56f32e6..70b4b8a 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
@@ -21,6 +21,7 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.ObjectInputStream;
+import java.lang.reflect.Array;
 import java.util.AbstractMap;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -41,6 +42,7 @@ import org.apache.polygene.api.property.PropertyDescriptor;
 import org.apache.polygene.api.serialization.Deserializer;
 import org.apache.polygene.api.serialization.SerializationException;
 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;
@@ -107,6 +109,10 @@ public interface MessagePackDeserializer extends Deserializer
                 {
                     return (T) Enum.valueOf( (Class) valueType.primaryType(), value.asStringValue().asString() );
                 }
+                if( ArrayType.class.isAssignableFrom( valueType.getClass() ) )
+                {
+                    return (T) deserializeArray( module, (ArrayType) valueType, value );
+                }
                 if( CollectionType.class.isAssignableFrom( valueType.getClass() ) )
                 {
                     return (T) deserializeCollection( module, (CollectionType) valueType, value.asArrayValue() );
@@ -127,6 +133,22 @@ public interface MessagePackDeserializer extends Deserializer
             }
         }
 
+        private Object deserializeArray( ModuleDescriptor module, ArrayType arrayType, Value value ) throws IOException
+        {
+            if( arrayType.isArrayOfPrimitiveBytes() )
+            {
+                return value.asBinaryValue().asByteArray();
+            }
+            CollectionType collectionType = CollectionType.listOf( arrayType.collectedType() );
+            List collection = (List) deserializeCollection( module, collectionType, value.asArrayValue() );
+            Object array = Array.newInstance( arrayType.collectedType().primaryType(), collection.size() );
+            for( int idx = 0; idx < collection.size(); idx++ )
+            {
+                Array.set( array, idx, collection.get( idx ) );
+            }
+            return array;
+        }
+
         private Collection<?> deserializeCollection( ModuleDescriptor module, CollectionType collectionType,
                                                      ArrayValue value ) throws IOException
         {

http://git-wip-us.apache.org/repos/asf/polygene-java/blob/7a574037/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 7321e6d..a8f396c 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
@@ -32,9 +32,11 @@ import org.apache.polygene.api.injection.scope.This;
 import org.apache.polygene.api.mixin.Mixins;
 import org.apache.polygene.api.serialization.SerializationException;
 import org.apache.polygene.api.serialization.Serializer;
+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.util.ArrayIterable;
 import org.apache.polygene.api.value.ValueComposite;
 import org.apache.polygene.api.value.ValueDescriptor;
 import org.apache.polygene.spi.serialization.AbstractBinarySerializer;
@@ -99,6 +101,10 @@ public interface MessagePackSerializer extends Serializer
                 {
                     return serializeMap( options, (Map<?, ?>) object );
                 }
+                if( ArrayType.isArray( objectClass ) )
+                {
+                    return serializeArray( options, object );
+                }
                 if( Iterable.class.isAssignableFrom( objectClass ) )
                 {
                     return serializeIterable( options, (Iterable<?>) object );
@@ -162,6 +168,20 @@ public interface MessagePackSerializer extends Serializer
             return builder.build();
         }
 
+        private Value serializeArray( Options options, Object object )
+        {
+            ArrayType valueType = ArrayType.of( object.getClass() );
+            if( valueType.isArrayOfPrimitiveBytes() )
+            {
+                return ValueFactory.newBinary( (byte[]) object );
+            }
+            if( valueType.isArrayOfPrimitives() )
+            {
+                return serializeIterable( options, new ArrayIterable( object ) );
+            }
+            return serializeStream( options, Stream.of( (Object[]) object ) );
+        }
+
         private ArrayValue serializeIterable( Options options, Iterable<?> iterable )
         {
             return serializeStream( options, StreamSupport.stream( iterable.spliterator(), false ) );