Introducing @Serialization annotations to mark Property methods on which variant should be used.
Project: http://git-wip-us.apache.org/repos/asf/zest-qi4j/repo Commit: http://git-wip-us.apache.org/repos/asf/zest-qi4j/commit/2a5405c5 Tree: http://git-wip-us.apache.org/repos/asf/zest-qi4j/tree/2a5405c5 Diff: http://git-wip-us.apache.org/repos/asf/zest-qi4j/diff/2a5405c5 Branch: refs/heads/develop Commit: 2a5405c57978b8f2d01be2c7ab3d792550a0eabc Parents: 279164e Author: Niclas Hedhman <[email protected]> Authored: Fri Jul 17 10:45:12 2015 +0300 Committer: Niclas Hedhman <[email protected]> Committed: Fri Jul 17 10:45:12 2015 +0300 ---------------------------------------------------------------------- .../main/java/org/qi4j/api/type/MapType.java | 20 ++----- .../java/org/qi4j/api/type/Serialization.java | 56 ++++++++++++++++++++ .../qi4j/runtime/property/PropertyModel.java | 23 ++++++-- .../qi4j/runtime/types/ValueTypeFactory.java | 23 ++++---- .../spi/value/ValueDeserializerAdapter.java | 5 +- 5 files changed, 95 insertions(+), 32 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/2a5405c5/core/api/src/main/java/org/qi4j/api/type/MapType.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/type/MapType.java b/core/api/src/main/java/org/qi4j/api/type/MapType.java index 753500a..1cb1700 100644 --- a/core/api/src/main/java/org/qi4j/api/type/MapType.java +++ b/core/api/src/main/java/org/qi4j/api/type/MapType.java @@ -27,17 +27,7 @@ public final class MapType private ValueType keyType; private ValueType valueType; - private final Variant variant; - - /** Two Variants are made distinct. - * <p> - * The {@code entry} type represents the explicit key=keyValue, value=valueValue. - * </p> - * <p> - * The {@code object} type represents the explicit keyValue=valueValue. - * </p> - */ - public enum Variant { entry, object } + private final Serialization.Variant variant; public static boolean isMap( Type type ) { @@ -50,17 +40,17 @@ public final class MapType return new MapType( Map.class, ValueType.of( keyType ), ValueType.of( valueType ) ); } - public static MapType of( Class<?> keyType, Class<?> valueType, Variant variant ) + public static MapType of( Class<?> keyType, Class<?> valueType, Serialization.Variant variant ) { return new MapType( Map.class, ValueType.of( keyType ), ValueType.of( valueType ), variant ); } public MapType( Class<?> type, ValueType keyType, ValueType valueType ) { - this( type, keyType, valueType, Variant.entry ); + this( type, keyType, valueType, Serialization.Variant.entry ); } - public MapType( Class<?> type, ValueType keyType, ValueType valueType, Variant variant ) + public MapType( Class<?> type, ValueType keyType, ValueType valueType, Serialization.Variant variant ) { super( type ); this.keyType = keyType; @@ -82,7 +72,7 @@ public final class MapType return valueType; } - public Variant variant() + public Serialization.Variant variant() { return variant; } http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/2a5405c5/core/api/src/main/java/org/qi4j/api/type/Serialization.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/type/Serialization.java b/core/api/src/main/java/org/qi4j/api/type/Serialization.java new file mode 100644 index 0000000..57184a0 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/api/type/Serialization.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2009, Rickard Ãberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.qi4j.api.type; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Serialization options for Property intstances. + * <p> + * The {@code entry} type represents the explicit key=keyValue, value=valueValue. For JSON serialization; + * </p> + * <pre> + * [ + * { "key1" : "value1" }, + * { "key2" : "value2" } + * ] + * </pre> + * <p> + * For XML serialization; + * </p> + * <pre> + * <object> + * < + * </object> + * </pre> + * <p> + * The {@code object} type represents the explicit keyValue=valueValue. + * </p> + */ +@Retention( RetentionPolicy.RUNTIME ) +@Target( { ElementType.TYPE, ElementType.METHOD } ) +@Documented +public @interface Serialization +{ + Variant value(); + + enum Variant + { + entry, object + } +} http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/2a5405c5/core/runtime/src/main/java/org/qi4j/runtime/property/PropertyModel.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/qi4j/runtime/property/PropertyModel.java b/core/runtime/src/main/java/org/qi4j/runtime/property/PropertyModel.java index 235a86a..3d38927 100644 --- a/core/runtime/src/main/java/org/qi4j/runtime/property/PropertyModel.java +++ b/core/runtime/src/main/java/org/qi4j/runtime/property/PropertyModel.java @@ -32,6 +32,7 @@ import org.qi4j.api.property.InvalidPropertyTypeException; import org.qi4j.api.property.Property; import org.qi4j.api.property.PropertyDescriptor; import org.qi4j.api.structure.Module; +import org.qi4j.api.type.Serialization; import org.qi4j.api.type.ValueCompositeType; import org.qi4j.api.type.ValueType; import org.qi4j.api.util.Classes; @@ -171,7 +172,7 @@ public class PropertyModel { if( valueType instanceof ValueCompositeType ) { - return module.newValue( (Class<?>) first( valueType().types() ) ); + return module.newValue( first( valueType().types() ) ); } else { @@ -189,16 +190,30 @@ public class PropertyModel ValueTypeFactory factory = ValueTypeFactory.instance(); Class<?> declaringClass = ( (Member) accessor() ).getDeclaringClass(); Class<?> mainType = first( resolution.model().types() ); - valueType = factory.newValueType( type(), declaringClass, mainType, resolution.layer(), resolution.module() ); - + Serialization.Variant variant = findVariant(); + valueType = factory.newValueType( type(), declaringClass, mainType, resolution.layer(), resolution.module(), variant ); builderInfo = new BuilderPropertyInfo(); - if( type instanceof TypeVariable ) { type = Classes.resolveTypeVariable( (TypeVariable) type, declaringClass, mainType ); } } + private Serialization.Variant findVariant() + { + Serialization serialization = metaInfo.get( Serialization.class ); + Serialization.Variant variant = null; + if( serialization != null ) + { + variant = serialization.value(); + } + if( variant == null ) + { + variant = Serialization.Variant.entry; + } + return variant; + } + @Override public <ThrowableType extends Throwable> boolean accept( Visitor<? super PropertyModel, ThrowableType> visitor ) throws ThrowableType http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/2a5405c5/core/runtime/src/main/java/org/qi4j/runtime/types/ValueTypeFactory.java ---------------------------------------------------------------------- diff --git a/core/runtime/src/main/java/org/qi4j/runtime/types/ValueTypeFactory.java b/core/runtime/src/main/java/org/qi4j/runtime/types/ValueTypeFactory.java index 0910293..9f49953 100644 --- a/core/runtime/src/main/java/org/qi4j/runtime/types/ValueTypeFactory.java +++ b/core/runtime/src/main/java/org/qi4j/runtime/types/ValueTypeFactory.java @@ -27,6 +27,7 @@ import org.qi4j.api.common.Visibility; import org.qi4j.api.type.CollectionType; import org.qi4j.api.type.EnumType; import org.qi4j.api.type.MapType; +import org.qi4j.api.type.Serialization; import org.qi4j.api.type.ValueCompositeType; import org.qi4j.api.type.ValueType; import org.qi4j.api.util.Classes; @@ -61,7 +62,8 @@ public class ValueTypeFactory Class declaringClass, Class compositeType, LayerModel layer, - ModuleModel module + ModuleModel module, + Serialization.Variant variant ) { ValueType valueType = null; @@ -76,13 +78,13 @@ public class ValueTypeFactory TypeVariable collectionTypeVariable = (TypeVariable) collectionType; collectionType = Classes.resolveTypeVariable( collectionTypeVariable, declaringClass, compositeType ); } - ValueType collectedType = newValueType( collectionType, declaringClass, compositeType, layer, module ); + ValueType collectedType = newValueType( collectionType, declaringClass, compositeType, layer, module, variant ); valueType = new CollectionType( Classes.RAW_CLASS.map( type ), collectedType ); } else { - valueType = new CollectionType( Classes.RAW_CLASS - .map( type ), newValueType( Object.class, declaringClass, compositeType, layer, module ) ); + ValueType collectedType = newValueType( Object.class, declaringClass, compositeType, layer, module, variant ); + valueType = new CollectionType( Classes.RAW_CLASS.map( type ), collectedType ); } } else if( MapType.isMap( type ) ) @@ -96,22 +98,21 @@ public class ValueTypeFactory TypeVariable keyTypeVariable = (TypeVariable) keyType; keyType = Classes.resolveTypeVariable( keyTypeVariable, declaringClass, compositeType ); } - ValueType keyedType = newValueType( keyType, declaringClass, compositeType, layer, module ); - + ValueType keyedType = newValueType( keyType, declaringClass, compositeType, layer, module, variant ); Type valType = pt.getActualTypeArguments()[ 1 ]; if( valType instanceof TypeVariable ) { TypeVariable valueTypeVariable = (TypeVariable) valType; valType = Classes.resolveTypeVariable( valueTypeVariable, declaringClass, compositeType ); } - ValueType valuedType = newValueType( valType, declaringClass, compositeType, layer, module ); - - valueType = new MapType( Classes.RAW_CLASS.map( type ), keyedType, valuedType ); + ValueType valuedType = newValueType( valType, declaringClass, compositeType, layer, module, variant ); + valueType = new MapType( Classes.RAW_CLASS.map( type ), keyedType, valuedType, variant ); } else { - valueType = new MapType( Classes.RAW_CLASS - .map( type ), newValueType( Object.class, declaringClass, compositeType, layer, module ), newValueType( Object.class, declaringClass, compositeType, layer, module ) ); + ValueType keyType = newValueType( Object.class, declaringClass, compositeType, layer, module, variant ); + ValueType valuesType = newValueType( Object.class, declaringClass, compositeType, layer, module, variant ); + valueType = new MapType( Classes.RAW_CLASS.map( type ), keyType, valuesType, variant ); } } else if( ValueCompositeType.isValueComposite( type ) ) http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/2a5405c5/core/spi/src/main/java/org/qi4j/spi/value/ValueDeserializerAdapter.java ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/qi4j/spi/value/ValueDeserializerAdapter.java b/core/spi/src/main/java/org/qi4j/spi/value/ValueDeserializerAdapter.java index b20bd79..53cf81d 100644 --- a/core/spi/src/main/java/org/qi4j/spi/value/ValueDeserializerAdapter.java +++ b/core/spi/src/main/java/org/qi4j/spi/value/ValueDeserializerAdapter.java @@ -48,6 +48,7 @@ import org.qi4j.api.type.EnumType; import org.qi4j.api.type.MapType; import org.qi4j.api.type.ValueCompositeType; import org.qi4j.api.type.ValueType; +import org.qi4j.api.type.Serialization; import org.qi4j.api.util.Base64Encoder; import org.qi4j.api.util.Dates; import org.qi4j.api.value.ValueBuilder; @@ -686,7 +687,7 @@ public abstract class ValueDeserializerAdapter<InputType, InputNodeType> Object value = getObjectFieldValue( inputNode, namedAssociationName, - buildDeserializeInputNodeFunction( MapType.of( String.class, EntityReference.class, MapType.Variant.object ) ) ); + buildDeserializeInputNodeFunction( MapType.of( String.class, EntityReference.class, Serialization.Variant.object ) ) ); stateMap.put( namedAssociationName, value ); } } @@ -755,7 +756,7 @@ public abstract class ValueDeserializerAdapter<InputType, InputNodeType> if( MapType.class.isAssignableFrom( valueType.getClass() ) ) { MapType mapType = (MapType) valueType; - if( mapType.variant().equals( MapType.Variant.entry ) ) + if( mapType.variant().equals( Serialization.Variant.entry ) ) { return (T) deserializeNodeEntryMap( (MapType) valueType, inputNode ); }
