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/51a355e2 Tree: http://git-wip-us.apache.org/repos/asf/polygene-java/tree/51a355e2 Diff: http://git-wip-us.apache.org/repos/asf/polygene-java/diff/51a355e2 Branch: refs/heads/develop Commit: 51a355e204358b31ae08354d3fdadf8a77e2b643 Parents: f939835 Author: Paul Merlin <[email protected]> Authored: Mon Mar 6 16:33:10 2017 +0100 Committer: Paul Merlin <[email protected]> Committed: Sun Apr 2 19:16:23 2017 +0200 ---------------------------------------------------------------------- .../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/51a355e2/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/51a355e2/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/51a355e2/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/51a355e2/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/51a355e2/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/51a355e2/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/51a355e2/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/51a355e2/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/51a355e2/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/51a355e2/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/51a355e2/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 ) );
