http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/spi/src/main/java/org/apache/polygene/spi/value/ValueSerializerAdapter.java ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/apache/polygene/spi/value/ValueSerializerAdapter.java b/core/spi/src/main/java/org/apache/polygene/spi/value/ValueSerializerAdapter.java deleted file mode 100644 index e9313b5..0000000 --- a/core/spi/src/main/java/org/apache/polygene/spi/value/ValueSerializerAdapter.java +++ /dev/null @@ -1,570 +0,0 @@ -/* - * 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.value; - -import java.io.ByteArrayOutputStream; -import java.io.ObjectOutputStream; -import java.io.OutputStream; -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.Base64; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.function.BiFunction; -import java.util.function.Function; -import org.apache.polygene.api.PolygeneAPI; -import org.apache.polygene.api.association.Association; -import org.apache.polygene.api.association.AssociationStateHolder; -import org.apache.polygene.api.association.ManyAssociation; -import org.apache.polygene.api.association.NamedAssociation; -import org.apache.polygene.api.composite.CompositeInstance; -import org.apache.polygene.api.entity.EntityComposite; -import org.apache.polygene.api.entity.EntityReference; -import org.apache.polygene.api.identity.Identity; -import org.apache.polygene.api.property.Property; -import org.apache.polygene.api.value.ValueComposite; -import org.apache.polygene.api.value.ValueDescriptor; -import org.apache.polygene.api.value.ValueSerializationException; -import org.apache.polygene.api.value.ValueSerializer; - -/** - * Adapter for pull-parsing capable ValueSerializers. - * - * <p> - * Among Plain values (see {@link ValueSerializer}) some are considered primitives to underlying serialization - * mechanisms and by so handed/come without conversion to/from implementations. Primitive values can be one of: - * </p> - * <ul> - * <li>String,</li> - * <li>Character or char,</li> - * <li>Boolean or boolean,</li> - * <li>Integer or int,</li> - * <li>Long or long,</li> - * <li>Short or short,</li> - * <li>Byte or byte,</li> - * <li>Float or float,</li> - * <li>Double or double.</li> - * </ul> - * <p> - * Some other Plain values are transformed before being handed to implementations: - * </p> - * <ul> - * <li>BigInteger and BigDecimal depends on ValueSerializer.{@link org.apache.polygene.api.value.ValueSerializer.Options};</li> - * <li>Date as a ISO-8601 UTC String;</li> - * <li>DateTime (JodaTime) as a ISO-8601 String with timezone offset or Z for UTC;</li> - * <li>LocalDateTime (JodaTime) as a ISO-8601 String with no timezone offset;</li> - * <li>LocalDate (JodaTime) as a ISO-8601 String with no time info;</li> - * </ul> - * - * @param <OutputType> Implementor output type - */ -public abstract class ValueSerializerAdapter<OutputType> - implements ValueSerializer -{ - - public interface ComplexSerializer<T, OutputType> - { - void serialize( Options options, T object, OutputType output ) - throws Exception; - } - - private static final String UTF_8 = "UTF-8"; - - private static <TO, FROM extends TO> BiFunction<Options, FROM, TO> identitySerializer() - { - return ( options, from ) -> from; - } - - private final Map<Class<?>, BiFunction<Options, Object, Object>> serializers = new HashMap<>( 16 ); - private final Map<Class<?>, ComplexSerializer<Object, OutputType>> complexSerializers = new HashMap<>( 2 ); - - /** - * Register a Plain Value type serialization Function. - * - * @param <T> Plain Value parametrized Type - * @param type Plain Value Type - * @param serializer Serialization Function - */ - @SuppressWarnings( "unchecked" ) - protected final <T> void registerSerializer( Class<T> type, BiFunction<Options, T, Object> serializer ) - { - serializers.put( type, (BiFunction<Options, Object, Object>) serializer ); - } - - /** - * Register a Complex Value type serialization Function. - * - * @param <T> Complex Value parametrized Type - * @param type Complex Value Type - * @param serializer Serialization Function - */ - @SuppressWarnings( "unchecked" ) - protected final <T> void registerComplexSerializer( Class<T> type, ComplexSerializer<T, OutputType> serializer ) - { - complexSerializers.put( type, (ComplexSerializer<Object, OutputType>) serializer ); - } - - public ValueSerializerAdapter() - { - // Primitive Value types - registerSerializer( String.class, ValueSerializerAdapter.identitySerializer() ); - registerSerializer( Character.class, ValueSerializerAdapter.identitySerializer() ); - registerSerializer( Boolean.class, ValueSerializerAdapter.identitySerializer() ); - registerSerializer( Integer.class, ValueSerializerAdapter.identitySerializer() ); - registerSerializer( Long.class, ValueSerializerAdapter.identitySerializer() ); - registerSerializer( Short.class, ValueSerializerAdapter.identitySerializer() ); - registerSerializer( Byte.class, ValueSerializerAdapter.identitySerializer() ); - registerSerializer( Float.class, ValueSerializerAdapter.identitySerializer() ); - registerSerializer( Double.class, ValueSerializerAdapter.identitySerializer() ); - - // Number types - registerSerializer( BigDecimal.class, ( options, bigDecimal ) -> bigDecimal.toString() ); - registerSerializer( BigInteger.class, ( options, bigInteger ) -> bigInteger.toString() ); - registerSerializer( Identity.class, ( options, identity ) -> identity.toString() ); - - // Date types - registerSerializer( Instant.class, ( options, date ) -> date.toString() ); - registerSerializer( Duration.class, ( options, date ) -> date.toString() ); - registerSerializer( Period.class, ( options, date ) -> date.toString() ); - registerSerializer( ZonedDateTime.class, ( options, date ) -> date.toString() ); - registerSerializer( OffsetDateTime.class, ( options, date ) -> date.toString() ); - registerSerializer( LocalDateTime.class, ( options, date ) -> date.toString() ); - registerSerializer( LocalDate.class, ( options, date ) -> date.toString() ); - registerSerializer( LocalTime.class, ( options, date ) -> date.toString() ); - - // Other supported types - registerSerializer( EntityReference.class, ( options, ref ) -> ref.toString() ); - } - - @Override - public final <T> Function<T, String> serialize() - { - return this::serialize; - } - - @Override - public final <T> Function<T, String> serialize( final Options options ) - { - return object -> serialize( options, object ); - } - - @Override - public final String serialize( Object object ) - throws ValueSerializationException - { - return serialize( new Options(), object ); - } - - @Override - public final String serialize( Options options, Object object ) - throws ValueSerializationException - { - try - { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - serializeRoot( options, object, output ); - return output.toString( UTF_8 ); - } - catch( ValueSerializationException ex ) - { - throw ex; - } - catch( Exception ex ) - { - throw new ValueSerializationException( "Could not serialize value", ex ); - } - } - - @Override - public final void serialize( Object object, OutputStream output ) - throws ValueSerializationException - { - serialize( new Options(), object, output ); - } - - @Override - public final void serialize( Options options, Object object, OutputStream output ) - throws ValueSerializationException - { - try - { - serializeRoot( options, object, output ); - } - catch( ValueSerializationException ex ) - { - throw ex; - } - catch( Exception ex ) - { - throw new ValueSerializationException( "Could not serialize value", ex ); - } - } - - private void serializeRoot( Options options, Object object, OutputStream output ) - throws Exception - { - if( object != null ) - { - if( serializers.get( object.getClass() ) != null ) - { - // Plain Value - Object serialized = serializers.get( object.getClass() ).apply( options, object ); - output.write( serialized.toString().getBytes( UTF_8 ) ); - } - else if( object instanceof Identity ) - { - Object serialized = serializers.get( Identity.class ).apply( options, object ); - output.write( serialized.toString().getBytes( UTF_8 ) ); - } - else if( object.getClass().isEnum() ) - { - // Enum Value - output.write( object.toString().getBytes( UTF_8 ) ); - } - else if( object.getClass().isArray() ) - { - // Array Value - output.write( serializeBase64Serializable( object ).getBytes( UTF_8 ) ); - } - else - { - // Complex Value - OutputType adaptedOutput = adaptOutput( output ); - onSerializationStart( object, adaptedOutput ); - doSerialize( options, object, adaptedOutput, true ); - onSerializationEnd( object, adaptedOutput ); - } - } - } - - private void doSerialize( Options options, Object object, OutputType output, boolean rootPass ) - throws Exception - { - // Null - if( object == null ) - { - onValue( output, null ); - } - else // Registered serializer - if( serializers.get( object.getClass() ) != null ) - { - onValue( output, serializers.get( object.getClass() ).apply( options, object ) ); - } - else if( complexSerializers.get( object.getClass() ) != null ) - { - complexSerializers.get( object.getClass() ).serialize( options, object, output ); - } - else // ValueComposite - if( Identity.class.isAssignableFrom( object.getClass() ) ) - { - serializeIdentity( object, output ); - } - else if( ValueComposite.class.isAssignableFrom( object.getClass() ) ) - { - serializeValueComposite( options, object, output, rootPass ); - } - else // EntityComposite - if( EntityComposite.class.isAssignableFrom( object.getClass() ) ) - { - serializeEntityComposite( object, output ); - } - else // Collection - Iterable - if( Iterable.class.isAssignableFrom( object.getClass() ) ) - { - serializeIterable( options, object, output ); - } - else // Array - QUID Remove this and use java serialization for arrays? - if( object.getClass().isArray() ) - { - serializeBase64Serializable( object, output ); - } - else // Map - if( Map.class.isAssignableFrom( object.getClass() ) ) - { - serializeMap( options, object, output ); - } - else // Enum - if( object.getClass().isEnum() ) - { - onValue( output, object.toString() ); - } - else // Fallback to Base64 encoded Java Serialization - { - serializeBase64Serializable( object, output ); - } - } - - private void serializeIdentity( Object object, OutputType output ) - throws Exception - { - onValue( output, object.toString() ); - } - - private void serializeValueComposite( Options options, Object object, OutputType output, boolean rootPass ) - throws Exception - { - CompositeInstance valueInstance = PolygeneAPI.FUNCTION_COMPOSITE_INSTANCE_OF.apply( (ValueComposite) object ); - ValueDescriptor descriptor = (ValueDescriptor) valueInstance.descriptor(); - AssociationStateHolder state = (AssociationStateHolder) valueInstance.state(); - - onObjectStart( output ); - - //noinspection ConstantConditions - if( options.getBoolean( Options.INCLUDE_TYPE_INFO ) && !rootPass ) - { - onFieldStart( output, "_type" ); - onValueStart( output ); - onValue( output, descriptor.valueType().types().findFirst().get().getName()); - onValueEnd( output ); - onFieldEnd( output ); - } - - descriptor.valueType().properties().forEach( persistentProperty -> { - Property<?> property = state.propertyFor( persistentProperty.accessor() ); - try - { - onFieldStart( output, persistentProperty.qualifiedName().name() ); - onValueStart( output ); - doSerialize( options, property.get(), output, false ); - onValueEnd( output ); - onFieldEnd( output ); - } - catch( Exception e ) - { - throw new ValueSerializationException( "Unable to serialize property " + persistentProperty, e ); - } - } ); - descriptor.valueType().associations().forEach(associationDescriptor -> { - Association<?> association = state.associationFor( associationDescriptor.accessor() ); - try - { - onFieldStart( output, associationDescriptor.qualifiedName().name() ); - onValueStart( output ); - EntityReference ref = association.reference(); - if( ref == null ) - { - onValue( output, null ); - } - else - { - onValue( output, ref.identity().toString() ); - } - onValueEnd( output ); - onFieldEnd( output ); - } - catch( Exception e ) - { - throw new ValueSerializationException( "Unable to serialize association " + associationDescriptor, e ); - } - } ); - descriptor.valueType().manyAssociations().forEach( associationDescriptor -> { - ManyAssociation<?> manyAssociation = state.manyAssociationFor( associationDescriptor.accessor() ); - try - { - onFieldStart( output, associationDescriptor.qualifiedName().name() ); - onValueStart( output ); - onArrayStart( output ); - for( Iterator<EntityReference> it = manyAssociation.references().iterator(); it.hasNext(); ) - { - onValueStart( output ); - onValue( output, it.next().identity().toString() ); - onValueEnd( output ); - } - onArrayEnd( output ); - onValueEnd( output ); - onFieldEnd( output ); - } - catch( Exception e ) - { - throw new ValueSerializationException( "Unable to serialize manyassociation " + associationDescriptor, e ); - } - }); - descriptor.valueType().namedAssociations().forEach( associationDescriptor -> { - NamedAssociation<?> namedAssociation = state.namedAssociationFor( associationDescriptor.accessor() ); - try - { - onFieldStart( output, associationDescriptor.qualifiedName().name() ); - onValueStart( output ); - onObjectStart( output ); - for( String name : namedAssociation ) - { - onFieldStart( output, name ); - onValueStart( output ); - EntityReference ref = namedAssociation.referenceOf( name ); - onValue( output, ref.identity().toString() ); - onValueEnd( output ); - onFieldEnd( output ); - } - onObjectEnd( output ); - onValueEnd( output ); - onFieldEnd( output ); - } - catch( Exception e ) - { - throw new ValueSerializationException( "Unable to serialize namedassociation " + associationDescriptor, e ); - } - } ); - - onObjectEnd( output ); - } - - private void serializeEntityComposite( Object object, OutputType output ) - throws Exception - { - onValue( output, EntityReference.entityReferenceFor( object ) ); - } - - private void serializeIterable( Options options, Object object, OutputType output ) - throws Exception - { - @SuppressWarnings( "unchecked" ) - Iterable<Object> collection = (Iterable<Object>) object; - onArrayStart( output ); - for( Object item : collection ) - { - onValueStart( output ); - doSerialize( options, item, output, false ); - onValueEnd( output ); - } - onArrayEnd( output ); - } - - private void serializeMap( Options options, Object object, OutputType output ) - throws Exception - { - @SuppressWarnings( "unchecked" ) - Map<Object, Object> map = (Map<Object, Object>) object; - //noinspection ConstantConditions - if( options.getBoolean( Options.MAP_ENTRIES_AS_OBJECTS ) ) - { - onObjectStart( output ); - for( Map.Entry<Object, Object> entry : map.entrySet() ) - { - onFieldStart( output, entry.getKey().toString() ); - onValueStart( output ); - doSerialize( options, entry.getValue(), output, false ); - onValueEnd( output ); - onFieldEnd( output ); - } - onObjectEnd( output ); - } - else - { - onArrayStart( output ); - for( Map.Entry<Object, Object> entry : map.entrySet() ) - { - onObjectStart( output ); - - onFieldStart( output, "key" ); - onValueStart( output ); - onValue( output, entry.getKey().toString() ); - onValueEnd( output ); - onFieldEnd( output ); - - onFieldStart( output, "value" ); - onValueStart( output ); - doSerialize( options, entry.getValue(), output, false ); - onValueEnd( output ); - onFieldEnd( output ); - - onObjectEnd( output ); - } - onArrayEnd( output ); - } - } - - private void serializeBase64Serializable( Object object, OutputType output ) - throws Exception - { - onValue( output, serializeBase64Serializable( object ) ); - } - - private String serializeBase64Serializable( Object object ) - throws Exception - { - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - try (ObjectOutputStream out = new ObjectOutputStream( bout )) - { - out.writeUnshared( object ); - } - byte[] bytes = Base64.getEncoder().encode( bout.toByteArray() ); - return new String( bytes, UTF_8 ); - } - - protected abstract OutputType adaptOutput( OutputStream output ) - throws Exception; - - protected void onSerializationStart( Object object, OutputType output ) - throws Exception - { - // NOOP - } - - protected void onSerializationEnd( Object object, OutputType output ) - throws Exception - { - // NOOP - } - - protected abstract void onArrayStart( OutputType output ) - throws Exception; - - protected abstract void onArrayEnd( OutputType output ) - throws Exception; - - protected abstract void onObjectStart( OutputType output ) - throws Exception; - - protected abstract void onObjectEnd( OutputType output ) - throws Exception; - - protected abstract void onFieldStart( OutputType output, String fieldName ) - throws Exception; - - protected void onFieldEnd( OutputType output ) - throws Exception - { - // NOOP - } - - protected void onValueStart( OutputType output ) - throws Exception - { - // NOOP - } - - protected abstract void onValue( OutputType output, Object value ) - throws Exception; - - protected void onValueEnd( OutputType output ) - throws Exception - { - // NOOP - } -}
http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/spi/src/main/java/org/apache/polygene/spi/value/package.html ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/apache/polygene/spi/value/package.html b/core/spi/src/main/java/org/apache/polygene/spi/value/package.html deleted file mode 100644 index 936e083..0000000 --- a/core/spi/src/main/java/org/apache/polygene/spi/value/package.html +++ /dev/null @@ -1,24 +0,0 @@ -<!-- - ~ 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. - ~ - ~ - --> -<html> - <body> - <h2>Value SPI.</h2> - </body> -</html> http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/OrgJsonValueDeserializer.java ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/OrgJsonValueDeserializer.java b/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/OrgJsonValueDeserializer.java deleted file mode 100644 index c543b3c..0000000 --- a/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/OrgJsonValueDeserializer.java +++ /dev/null @@ -1,485 +0,0 @@ -/* - * 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.valueserialization.orgjson; - -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; -import java.util.function.Function; -import org.apache.polygene.api.structure.ModuleDescriptor; -import org.apache.polygene.api.value.ValueSerializationException; -import org.apache.polygene.spi.value.ValueDeserializerAdapter; -import org.json.JSONArray; -import org.json.JSONObject; -import org.json.JSONTokener; - -/** - * ValueDeserializer reading Values from JSON documents using org.json. - */ -public class OrgJsonValueDeserializer - extends ValueDeserializerAdapter<JSONTokener, Object> -{ - - @Override - protected JSONTokener adaptInput( ModuleDescriptor module, InputStream input ) - throws Exception - { - return new JSONTokener( new InputStreamReader( input, "UTF-8" ) ); - } - - @Override - protected Object readPlainValue( ModuleDescriptor module, JSONTokener input ) - throws Exception - { - Object nextValue = input.nextValue(); - if( JSONObject.NULL.equals( nextValue ) ) - { - return null; - } - else // Object or Array - if( JSONObject.class.isAssignableFrom( nextValue.getClass() ) - || JSONArray.class.isAssignableFrom( nextValue.getClass() ) ) - { - throw new ValueSerializationException( "Asked for a Value but found an Object or an Array." ); - } - return nextValue; - } - - @Override - protected <T> Collection<T> readArrayInCollection( ModuleDescriptor module, - JSONTokener input, - Function<JSONTokener, T> deserializer, - Collection<T> collection - ) - throws Exception - { - char c = input.nextClean(); - char q; - if( c == 'n' ) // null? - { - /* - * Handle unquoted text. This could be the values true, false, or - * null, or it can be a number. An implementation (such as this one) - * is allowed to also accept non-standard forms. - * - * Accumulate characters until we reach the end of the text or a - * formatting character. - */ - StringBuilder sb = new StringBuilder(); - sb.setLength( 0 ); - while( c >= ' ' && ",:]}/\\\"[{;=#".indexOf( c ) < 0 ) - { - sb.append( c ); - c = input.next(); - } - input.back(); - String s = sb.toString().trim(); - if( !"null".equals( s ) ) - { - input.syntaxError( "Unknown value: '" + s + "'" ); - } - return null; - } - else if( c == '[' ) - { - q = ']'; - } - else - { - throw input.syntaxError( "A JSONArray text must start with '['" ); - } - if( input.nextClean() == ']' ) - { - return collection; - } - input.back(); - for(; ; ) - { - if( input.nextClean() == ',' ) - { - input.back(); - collection.add( null ); - } - else - { - input.back(); - collection.add( deserializer.apply( input ) ); - } - c = input.nextClean(); - switch( c ) - { - case ';': - case ',': - if( input.nextClean() == ']' ) - { - return collection; - } - input.back(); - break; - case ']': - case ')': - if( q != c ) - { - throw input.syntaxError( "Expected a '" + Character.valueOf( q ) + "'" ); - } - return collection; - default: - throw input.syntaxError( "Expected a ',' or ']'" ); - } - } - } - - @Override - protected <K, V> Map<K, V> readMapInMap( ModuleDescriptor module, - JSONTokener input, - Function<JSONTokener, K> keyDeserializer, - Function<JSONTokener, V> valueDeserializer, - Map<K, V> map - ) - throws Exception - { - char c = input.nextClean(); - char q; - if( c == 'n' ) // null? - { - /* - * Handle unquoted text. This could be the values true, false, or - * null, or it can be a number. An implementation (such as this one) - * is allowed to also accept non-standard forms. - * - * Accumulate characters until we reach the end of the text or a - * formatting character. - */ - StringBuilder sb = new StringBuilder(); - sb.setLength( 0 ); - while( c >= ' ' && ",:]}/\\\"[{;=#".indexOf( c ) < 0 ) - { - sb.append( c ); - c = input.next(); - } - input.back(); - String s = sb.toString().trim(); - if( !"null".equals( s ) ) - { - input.syntaxError( "Unknown value: '" + s + "'" ); - } - return null; - } - else if( c == '[' ) - { - q = ']'; - } - else - { - throw input.syntaxError( "A JSONArray text must start with '['" ); - } - if( input.nextClean() == ']' ) - { - return map; - } - input.back(); - - for(; ; ) - { - if( input.nextClean() == ',' ) - { - input.back(); - } - else - { - input.back(); - // Map entry! - if( input.nextClean() != '{' ) - { - throw input.syntaxError( "A JSONObject text must begin with '{'" ); - } - - String objectKey; - K key = null; - V value = null; - - boolean breakIteration = false; - while( !breakIteration ) - { - c = input.nextClean(); - switch( c ) - { - case 0: - throw input.syntaxError( "A JSONObject text must end with '}'" ); - case '}': - breakIteration = true; - continue; - default: - input.back(); - objectKey = input.nextValue().toString(); - } - - /* - * The key is followed by ':'. We will also tolerate '=' or '=>'. - */ - c = input.nextClean(); - if( c == '=' ) - { - if( input.next() != '>' ) - { - input.back(); - } - } - else if( c != ':' ) - { - throw input.syntaxError( "Expected a ':' after a key" ); - } - - if( "key".equals( objectKey ) ) - { - key = keyDeserializer.apply( input ); - } - else if( "value".equals( objectKey ) ) - { - value = valueDeserializer.apply( input ); - } - else - { - input.nextValue(); - } - - /* - * Pairs are separated by ','. We will also tolerate ';'. - */ - switch( input.nextClean() ) - { - case ';': - case ',': - if( input.nextClean() == '}' ) - { - breakIteration = true; - continue; - } - input.back(); - continue; - case '}': - breakIteration = true; - continue; - default: - throw input.syntaxError( "Expected a ',' or '}'" ); - } - } - if( key != null ) - { - map.put( key, value ); - } - } - c = input.nextClean(); - switch( c ) - { - case ';': - case ',': - if( input.nextClean() == ']' ) - { - return map; - } - input.back(); - break; - case ']': - case ')': - if( q != c ) - { - throw input.syntaxError( "Expected a '" + Character.valueOf( q ) + "'" ); - } - return map; - default: - throw input.syntaxError( "Expected a ',' or ']'" ); - } - } - } - - // - // Deserialization - Tree parsing - // - @Override - protected JSONObject readObjectTree( ModuleDescriptor module, - JSONTokener input - ) - throws Exception - { - Object objectTree = input.nextValue(); - if( JSONObject.NULL.equals( objectTree ) ) - { - return null; - } - return (JSONObject) objectTree; - } - - @Override - protected Object asSimpleValue( ModuleDescriptor module, Object inputNode ) - throws Exception - { - if( JSONObject.NULL.equals( inputNode ) ) - { - return null; - } - if( inputNode instanceof JSONObject || inputNode instanceof JSONArray ) - { - throw new ValueSerializationException( "Expected a simple value but got " + inputNode ); - } - return inputNode; - } - - @Override - protected boolean isObjectValue( ModuleDescriptor module, Object inputNode ) - throws Exception - { - if( JSONObject.NULL.equals( inputNode ) ) - { - return false; - } - return inputNode instanceof JSONObject; - } - - @Override - protected boolean objectHasField( ModuleDescriptor module, Object inputNode, String key ) - throws Exception - { - if( JSONObject.NULL.equals( inputNode ) ) - { - return false; - } - if( !( inputNode instanceof JSONObject ) ) - { - throw new ValueSerializationException( "Expected an object but got " + inputNode ); - } - JSONObject json = (JSONObject) inputNode; - return json.has( key ); - } - - @Override - protected <T> T getObjectFieldValue( ModuleDescriptor module, - Object inputNode, - String key, - Function<Object, T> valueDeserializer - ) - throws Exception - { - JSONObject json = (JSONObject) inputNode; - Object valueNode = json.opt( key ); - if( JSONObject.NULL.equals( valueNode ) ) - { - return null; - } - T value = valueDeserializer.apply( valueNode ); - return value; - } - - @Override - protected <T> void putArrayNodeInCollection( ModuleDescriptor module, - Object inputNode, - Function<Object, T> deserializer, - Collection<T> collection - ) - throws Exception - { - if( JSONObject.NULL.equals( inputNode ) ) - { - return; - } - if( !( inputNode instanceof JSONArray ) ) - { - throw new ValueSerializationException( "Expected an array but got " + inputNode ); - } - JSONArray array = (JSONArray) inputNode; - for( int idx = 0; idx < array.length(); idx++ ) - { - Object item = array.get( idx ); - T value = deserializer.apply( item ); - collection.add( value ); - } - } - - @Override - protected <K, V> void putArrayNodeInMap( ModuleDescriptor module, - Object inputNode, - Function<Object, K> keyDeserializer, - Function<Object, V> valueDeserializer, - Map<K, V> map - ) - throws Exception - { - if( JSONObject.NULL.equals( inputNode ) ) - { - return; - } - if( !( inputNode instanceof JSONArray ) ) - { - throw new ValueSerializationException( "Expected an array but got " + inputNode ); - } - JSONArray array = (JSONArray) inputNode; - for( int idx = 0; idx < array.length(); idx++ ) - { - Object item = array.get( idx ); - if( !( item instanceof JSONObject ) ) - { - throw new ValueSerializationException( "Expected an object but got " + inputNode ); - } - JSONObject object = (JSONObject) item; - Object keyNode = object.get( "key" ); - Object valueNode = object.get( "value" ); - K key = keyDeserializer.apply( keyNode ); - V value = valueDeserializer.apply( valueNode ); - if( key != null ) - { - map.put( key, value ); - } - } - } - - @Override - protected <V> void putObjectNodeInMap( ModuleDescriptor module, - Object inputNode, - Function<Object, V> valueDeserializer, - Map<String, V> map - ) - throws Exception - { - if( JSONObject.NULL.equals( inputNode ) ) - { - return; - } - if( !( inputNode instanceof JSONObject ) ) - { - throw new ValueSerializationException( "Expected an object but got " + inputNode ); - } - JSONObject object = (JSONObject) inputNode; - - @SuppressWarnings( "unchecked" ) - Iterator<String> it = object.keys(); - while( it.hasNext() ) - { - String key = it.next(); - Object item = object.get( key ); - V valueValue = valueDeserializer.apply( item ); - if( key != null ) - { - map.put( key, valueValue ); - } - } - } -} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/OrgJsonValueSerializationService.java ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/OrgJsonValueSerializationService.java b/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/OrgJsonValueSerializationService.java deleted file mode 100644 index 5bf3544..0000000 --- a/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/OrgJsonValueSerializationService.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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.valueserialization.orgjson; - -import org.apache.polygene.api.mixin.Mixins; -import org.apache.polygene.api.value.ValueSerialization; - -/** - * ValueSerialization Service producing and consuming JSON documents using org.json. - */ -@Mixins( { OrgJsonValueSerializer.class, OrgJsonValueDeserializer.class } ) -public interface OrgJsonValueSerializationService - extends ValueSerialization -{ -} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/OrgJsonValueSerializer.java ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/OrgJsonValueSerializer.java b/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/OrgJsonValueSerializer.java deleted file mode 100644 index dbe658f..0000000 --- a/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/OrgJsonValueSerializer.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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.valueserialization.orgjson; - -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import org.json.JSONWriter; -import org.apache.polygene.spi.value.ValueSerializerAdapter; -import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializer.OrgJsonOutput; - -/** - * ValueSerializer producing Values state as JSON documents using org.json. - */ -public class OrgJsonValueSerializer - extends ValueSerializerAdapter<OrgJsonOutput> -{ - - /** - * Helper to pass around the Writer alongside the JSONWriter so we can flush it onSerializationEnd. - * - * This is needed because the org.json package do not allow to get a handle on the Writer from a JSONWriter. - */ - public static class OrgJsonOutput - { - - private final Writer writer; - private final JSONWriter json; - - private OrgJsonOutput( Writer writer, JSONWriter json ) - { - this.writer = writer; - this.json = json; - } - } - - // - // Serialization - // - @Override - protected OrgJsonOutput adaptOutput( OutputStream output ) - throws Exception - { - Writer writer = new OutputStreamWriter( output, "UTF-8" ); - JSONWriter json = new JSONWriter( writer ); - return new OrgJsonOutput( writer, json ); - } - - @Override - protected void onSerializationEnd( Object object, OrgJsonOutput output ) - throws Exception - { - output.writer.flush(); - } - - @Override - protected void onArrayStart( OrgJsonOutput output ) - throws Exception - { - output.json.array(); - } - - @Override - protected void onArrayEnd( OrgJsonOutput output ) - throws Exception - { - output.json.endArray(); - } - - @Override - protected void onObjectStart( OrgJsonOutput output ) - throws Exception - { - output.json.object(); - } - - @Override - protected void onObjectEnd( OrgJsonOutput output ) - throws Exception - { - output.json.endObject(); - } - - @Override - protected void onFieldStart( OrgJsonOutput output, String fieldName ) - throws Exception - { - output.json.key( fieldName ); - } - - @Override - protected void onValue( OrgJsonOutput output, Object value ) - throws Exception - { - output.json.value( value ); - } -} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/package.html ---------------------------------------------------------------------- diff --git a/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/package.html b/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/package.html deleted file mode 100644 index 4799b58..0000000 --- a/core/spi/src/main/java/org/apache/polygene/valueserialization/orgjson/package.html +++ /dev/null @@ -1,24 +0,0 @@ -<!-- - ~ 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. - ~ - ~ - --> -<html> - <body> - <h2>org.json Value Serialization.</h2> - </body> -</html> http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/spi/src/test/java/org/apache/polygene/spi/entitystore/Polygene142Test.java ---------------------------------------------------------------------- diff --git a/core/spi/src/test/java/org/apache/polygene/spi/entitystore/Polygene142Test.java b/core/spi/src/test/java/org/apache/polygene/spi/entitystore/Polygene142Test.java index 718e3b7..831cc45 100644 --- a/core/spi/src/test/java/org/apache/polygene/spi/entitystore/Polygene142Test.java +++ b/core/spi/src/test/java/org/apache/polygene/spi/entitystore/Polygene142Test.java @@ -23,10 +23,10 @@ import org.apache.polygene.api.identity.StringIdentity; import org.apache.polygene.api.injection.scope.Service; import org.apache.polygene.api.property.Property; import org.apache.polygene.api.service.qualifier.Tagged; +import org.apache.polygene.api.serialization.Serialization; import org.apache.polygene.api.unitofwork.UnitOfWork; import org.apache.polygene.api.usecase.UsecaseBuilder; import org.apache.polygene.api.value.ValueBuilder; -import org.apache.polygene.api.value.ValueSerialization; import org.apache.polygene.bootstrap.ModuleAssembly; import org.apache.polygene.test.AbstractPolygeneTest; import org.apache.polygene.test.EntityTestAssembler; @@ -43,20 +43,13 @@ public class Polygene142Test extends AbstractPolygeneTest } @Service - @Tagged( ValueSerialization.Formats.JSON ) - private ValueSerialization serialization; + @Tagged( Serialization.Formats.JSON ) + private Serialization serialization; @Test public void polygene142RegressionTest() throws Exception { - if( getClass().getName().equals( - "org.apache.polygene.valueserialization.stax.StaxPlainValueSerializationTest" ) ) - { - // This test is disabled, as this test expect a JSON capable serializer as it uses - // the JSONMapEntityStoreMixin in MemoryEntityStore. - return; - } Regression142Type value; { ValueBuilder<Regression142Type> builder = valueBuilderFactory.newValueBuilder( Regression142Type.class ); @@ -85,7 +78,7 @@ public class Polygene142Test extends AbstractPolygeneTest } } { - try( UnitOfWork uow = unitOfWorkFactory.newUnitOfWork( UsecaseBuilder.newUsecase( "create" ) ) ) + try( UnitOfWork uow = unitOfWorkFactory.newUnitOfWork( UsecaseBuilder.newUsecase( "read" ) ) ) { value = uow.get( Regression142Type.class, valueId ); System.out.println( value.price().get() ); http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/spi/src/test/java/org/apache/polygene/spi/entitystore/helpers/JSONManyAssociationStateTest.java ---------------------------------------------------------------------- diff --git a/core/spi/src/test/java/org/apache/polygene/spi/entitystore/helpers/JSONManyAssociationStateTest.java b/core/spi/src/test/java/org/apache/polygene/spi/entitystore/helpers/JSONManyAssociationStateTest.java index 9538042..67af1f8 100644 --- a/core/spi/src/test/java/org/apache/polygene/spi/entitystore/helpers/JSONManyAssociationStateTest.java +++ b/core/spi/src/test/java/org/apache/polygene/spi/entitystore/helpers/JSONManyAssociationStateTest.java @@ -21,12 +21,12 @@ package org.apache.polygene.spi.entitystore.helpers; import java.util.ArrayList; import java.util.List; +import javax.json.Json; +import javax.json.JsonObject; +import javax.json.JsonObjectBuilder; import org.apache.polygene.api.entity.EntityReference; import org.apache.polygene.api.time.SystemTime; import org.apache.polygene.spi.entity.EntityStatus; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; import org.junit.Test; import static org.hamcrest.CoreMatchers.equalTo; @@ -39,14 +39,14 @@ public class JSONManyAssociationStateTest @Test public void givenEmptyJSONManyAssociationStateWhenAddingTwoRefsAtZeroIndexExpectCorrectOrder() - throws JSONException { // Fake JSONManyAssociationState - JSONObject state = new JSONObject(); - state.put( JSONKeys.PROPERTIES, new JSONObject() ); - state.put( JSONKeys.ASSOCIATIONS, new JSONObject() ); - state.put( JSONKeys.MANY_ASSOCIATIONS, new JSONObject() ); - state.put( JSONKeys.NAMED_ASSOCIATIONS, new JSONObject() ); + JsonObjectBuilder builder = Json.createObjectBuilder(); + builder.add( JSONKeys.PROPERTIES, Json.createObjectBuilder().build() ); + builder.add( JSONKeys.ASSOCIATIONS, Json.createObjectBuilder().build() ); + builder.add( JSONKeys.MANY_ASSOCIATIONS, Json.createObjectBuilder().build() ); + builder.add( JSONKeys.NAMED_ASSOCIATIONS, Json.createObjectBuilder().build() ); + JsonObject state = builder.build(); JSONEntityState entityState = new JSONEntityState( null, null, "0", @@ -55,7 +55,7 @@ public class JSONManyAssociationStateTest EntityStatus.NEW, null, state ); - JSONManyAssociationState jsonState = new JSONManyAssociationState( entityState, new JSONArray() ); + JSONManyAssociationState jsonState = new JSONManyAssociationState( entityState, "under-test" ); jsonState.add( 0, EntityReference.parseEntityReference( "first" ) ); jsonState.add( 0, EntityReference.parseEntityReference( "second" ) ); @@ -65,14 +65,14 @@ public class JSONManyAssociationStateTest @Test public void givenJSONManyAssociationStateWhenChangingReferencesExpectCorrectBehavior() - throws JSONException { // Fake JSONManyAssociationState - JSONObject state = new JSONObject(); - state.put( JSONKeys.PROPERTIES, new JSONObject() ); - state.put( JSONKeys.ASSOCIATIONS, new JSONObject() ); - state.put( JSONKeys.MANY_ASSOCIATIONS, new JSONObject() ); - state.put( JSONKeys.NAMED_ASSOCIATIONS, new JSONObject() ); + JsonObjectBuilder builder = Json.createObjectBuilder(); + builder.add( JSONKeys.PROPERTIES, Json.createObjectBuilder().build() ); + builder.add( JSONKeys.ASSOCIATIONS, Json.createObjectBuilder().build() ); + builder.add( JSONKeys.MANY_ASSOCIATIONS, Json.createObjectBuilder().build() ); + builder.add( JSONKeys.NAMED_ASSOCIATIONS, Json.createObjectBuilder().build() ); + JsonObject state = builder.build(); JSONEntityState entityState = new JSONEntityState( null, null, "0", @@ -81,7 +81,7 @@ public class JSONManyAssociationStateTest EntityStatus.NEW, null, state ); - JSONManyAssociationState jsonState = new JSONManyAssociationState( entityState, new JSONArray() ); + JSONManyAssociationState jsonState = new JSONManyAssociationState( entityState, "under-test" ); assertThat( jsonState.contains( EntityReference.parseEntityReference( "NOT_PRESENT" ) ), is( false ) ); http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/spi/src/test/java/org/apache/polygene/spi/entitystore/helpers/JsonNamedAssociationStateTest.java ---------------------------------------------------------------------- diff --git a/core/spi/src/test/java/org/apache/polygene/spi/entitystore/helpers/JsonNamedAssociationStateTest.java b/core/spi/src/test/java/org/apache/polygene/spi/entitystore/helpers/JsonNamedAssociationStateTest.java new file mode 100644 index 0000000..8a4b7db --- /dev/null +++ b/core/spi/src/test/java/org/apache/polygene/spi/entitystore/helpers/JsonNamedAssociationStateTest.java @@ -0,0 +1,104 @@ +/* + * 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.entitystore.helpers; + +import java.util.LinkedHashMap; +import java.util.Map; +import javax.json.Json; +import javax.json.JsonObject; +import javax.json.JsonObjectBuilder; +import org.apache.polygene.api.entity.EntityReference; +import org.apache.polygene.api.time.SystemTime; +import org.apache.polygene.spi.entity.EntityStatus; +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.hasItems; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class JsonNamedAssociationStateTest +{ + @Test + public void givenJsonNamedAssociationStateWhenChangingReferencesExpectCorrectBehavior() + { + // Fake JsonNamedAssociationState + JsonObjectBuilder builder = Json.createObjectBuilder(); + builder.add( JSONKeys.PROPERTIES, Json.createObjectBuilder().build() ); + builder.add( JSONKeys.ASSOCIATIONS, Json.createObjectBuilder().build() ); + builder.add( JSONKeys.MANY_ASSOCIATIONS, Json.createObjectBuilder().build() ); + builder.add( JSONKeys.NAMED_ASSOCIATIONS, Json.createObjectBuilder().build() ); + JsonObject state = builder.build(); + JSONEntityState entityState = new JSONEntityState( null, + null, + "0", + SystemTime.now(), + EntityReference.parseEntityReference( "123" ), + EntityStatus.NEW, + null, + state ); + JSONNamedAssociationState jsonState = new JSONNamedAssociationState( entityState, "under-test" ); + + + assertThat( jsonState.containsName( "foo" ), is( false ) ); + + jsonState.put( "foo", EntityReference.parseEntityReference( "0" ) ); + jsonState.put( "bar", EntityReference.parseEntityReference( "1" ) ); + jsonState.put( "bazar", EntityReference.parseEntityReference( "2" ) ); + + assertThat( jsonState.containsName( "bar" ), is( true ) ); + + assertThat( jsonState.get( "foo" ).identity().toString(), equalTo( "0" ) ); + assertThat( jsonState.get( "bar" ).identity().toString(), equalTo( "1" ) ); + assertThat( jsonState.get( "bazar" ).identity().toString(), equalTo( "2" ) ); + + assertThat( jsonState.count(), equalTo( 3 ) ); + + jsonState.remove( "bar" ); + + assertThat( jsonState.count(), equalTo( 2 ) ); + assertThat( jsonState.containsName( "bar" ), is( false ) ); + assertThat( jsonState.get( "foo" ).identity().toString(), equalTo( "0" ) ); + assertThat( jsonState.get( "bazar" ).identity().toString(), equalTo( "2" ) ); + + jsonState.put( "bar", EntityReference.parseEntityReference( "1" ) ); + + assertThat( jsonState.count(), equalTo( 3 ) ); + + jsonState.put( "oof", EntityReference.parseEntityReference( "A" ) ); + jsonState.put( "rab", EntityReference.parseEntityReference( "B" ) ); + jsonState.put( "razab", EntityReference.parseEntityReference( "C" ) ); + + assertThat( jsonState.count(), equalTo( 6 ) ); + + assertThat( jsonState.get( "razab" ).identity().toString(), equalTo( "C" ) ); + assertThat( jsonState.get( "rab" ).identity().toString(), equalTo( "B" ) ); + assertThat( jsonState.get( "oof" ).identity().toString(), equalTo( "A" ) ); + + Map<String, String> refMap = new LinkedHashMap<>(); + for( String name : jsonState ) + { + refMap.put( name, jsonState.get( name ).identity().toString() ); + } + assertThat( refMap.isEmpty(), is( false ) ); + assertThat( refMap.keySet(), hasItems( "foo", "bar", "bazar", "oof", "rab", "razab" ) ); + assertThat( refMap.values(), hasItems( "0", "1", "2", "A", "B", "C" ) ); + } +} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/testsupport/src/main/java/org/apache/polygene/test/EntityTestAssembler.java ---------------------------------------------------------------------- diff --git a/core/testsupport/src/main/java/org/apache/polygene/test/EntityTestAssembler.java b/core/testsupport/src/main/java/org/apache/polygene/test/EntityTestAssembler.java index 945ea47..ec7237b 100644 --- a/core/testsupport/src/main/java/org/apache/polygene/test/EntityTestAssembler.java +++ b/core/testsupport/src/main/java/org/apache/polygene/test/EntityTestAssembler.java @@ -19,16 +19,14 @@ */ package org.apache.polygene.test; -import org.apache.polygene.api.value.ValueSerialization; import org.apache.polygene.bootstrap.Assemblers; import org.apache.polygene.bootstrap.AssemblyException; import org.apache.polygene.bootstrap.ModuleAssembly; import org.apache.polygene.bootstrap.ServiceDeclaration; import org.apache.polygene.entitystore.memory.MemoryEntityStoreService; -import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService; /** - * Helper assembler that adds an in-memory EntityStore, a UUID generator, and an Entity type registry to the module + * Helper assembler that adds an in-memory EntityStore to the module */ public class EntityTestAssembler extends Assemblers.VisibilityIdentity<EntityTestAssembler> @@ -42,6 +40,5 @@ public class EntityTestAssembler { service.identifiedBy( identity() ); } - module.services( OrgJsonValueSerializationService.class ).taggedWith( ValueSerialization.Formats.JSON ); } } http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractConfigurationDeserializationTest.java ---------------------------------------------------------------------- diff --git a/core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractConfigurationDeserializationTest.java b/core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractConfigurationDeserializationTest.java index b50d96d..f8877c0 100644 --- a/core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractConfigurationDeserializationTest.java +++ b/core/testsupport/src/main/java/org/apache/polygene/test/entity/AbstractConfigurationDeserializationTest.java @@ -20,7 +20,6 @@ package org.apache.polygene.test.entity; -import org.junit.Test; import org.apache.polygene.api.common.Visibility; import org.apache.polygene.api.configuration.Configuration; import org.apache.polygene.api.identity.HasIdentity; @@ -28,12 +27,11 @@ import org.apache.polygene.api.injection.scope.This; import org.apache.polygene.api.mixin.Mixins; import org.apache.polygene.api.property.Property; import org.apache.polygene.api.service.ServiceReference; -import org.apache.polygene.api.value.ValueSerialization; import org.apache.polygene.bootstrap.AssemblyException; import org.apache.polygene.bootstrap.ModuleAssembly; import org.apache.polygene.entitystore.memory.MemoryEntityStoreService; import org.apache.polygene.test.AbstractPolygeneTest; -import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService; +import org.junit.Test; import static org.hamcrest.core.IsEqual.equalTo; import static org.hamcrest.core.IsNull.notNullValue; @@ -45,14 +43,11 @@ public abstract class AbstractConfigurationDeserializationTest extends AbstractP public void assemble( ModuleAssembly module ) throws AssemblyException { -// ModuleAssembly storageModule = module.layer().module( "storage" ); - @SuppressWarnings( "UnnecessaryLocalVariable" ) - ModuleAssembly storageModule = module; // Disable the more complex set up. The entire value serialization has gotten the deserialization type lookup problem wrong. + ModuleAssembly storageModule = module.layer().module( "storage" ); module.configurations( ConfigSerializationConfig.class ); module.values( Host.class ); module.services( MyService.class ).identifiedBy( "configtest" ); storageModule.services( MemoryEntityStoreService.class ).visibleIn( Visibility.layer ); - storageModule.services( OrgJsonValueSerializationService.class ).taggedWith( ValueSerialization.Formats.JSON ); } @Test http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/testsupport/src/main/java/org/apache/polygene/test/indexing/layered/assembly/PersistenceModule.java ---------------------------------------------------------------------- diff --git a/core/testsupport/src/main/java/org/apache/polygene/test/indexing/layered/assembly/PersistenceModule.java b/core/testsupport/src/main/java/org/apache/polygene/test/indexing/layered/assembly/PersistenceModule.java index 30f4be7..b0121c7 100644 --- a/core/testsupport/src/main/java/org/apache/polygene/test/indexing/layered/assembly/PersistenceModule.java +++ b/core/testsupport/src/main/java/org/apache/polygene/test/indexing/layered/assembly/PersistenceModule.java @@ -21,13 +21,11 @@ package org.apache.polygene.test.indexing.layered.assembly; import org.apache.polygene.api.common.Visibility; -import org.apache.polygene.api.value.ValueSerialization; import org.apache.polygene.bootstrap.AssemblyException; import org.apache.polygene.bootstrap.LayerAssembly; import org.apache.polygene.bootstrap.ModuleAssembly; import org.apache.polygene.bootstrap.layered.ModuleAssembler; import org.apache.polygene.entitystore.memory.MemoryEntityStoreService; -import org.apache.polygene.valueserialization.orgjson.OrgJsonValueSerializationService; class PersistenceModule implements ModuleAssembler @@ -37,7 +35,6 @@ class PersistenceModule public ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module ) throws AssemblyException { - module.services( OrgJsonValueSerializationService.class ).taggedWith( ValueSerialization.Formats.JSON ); module.services( MemoryEntityStoreService.class ).visibleIn( Visibility.application ); return module; } http://git-wip-us.apache.org/repos/asf/polygene-java/blob/e4cca11e/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractCollectionSerializationTest.java ---------------------------------------------------------------------- diff --git a/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractCollectionSerializationTest.java b/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractCollectionSerializationTest.java new file mode 100644 index 0000000..48cdefd --- /dev/null +++ b/core/testsupport/src/main/java/org/apache/polygene/test/serialization/AbstractCollectionSerializationTest.java @@ -0,0 +1,464 @@ +/* + * 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.test.serialization; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.apache.polygene.api.common.Optional; +import org.apache.polygene.api.injection.scope.Service; +import org.apache.polygene.api.property.Property; +import org.apache.polygene.api.serialization.Serialization; +import org.apache.polygene.api.type.CollectionType; +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.value.ValueBuilder; +import org.apache.polygene.bootstrap.AssemblyException; +import org.apache.polygene.bootstrap.ModuleAssembly; +import org.apache.polygene.test.AbstractPolygeneTest; +import org.junit.Test; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +/** + * Assert that ValueSerialization behaviour on Collections and Maps is correct. + */ +// TODO Add enum collections (e.g. EnumMap etc..) +public class AbstractCollectionSerializationTest + extends AbstractPolygeneTest +{ + @Override + public void assemble( ModuleAssembly module ) + throws AssemblyException + { + module.values( SomeValue.class ); + } + + @Service + @SuppressWarnings( "ProtectedField" ) + protected Serialization stateSerialization; + + @Test + public void givenPrimitiveArrayWithIntsWhenSerializingAndDeserializingExpectEquals() + throws Exception + { + int[] primitiveArray = new int[] + { + 23, 42, -23, -42 + }; + String output = stateSerialization.serialize( primitiveArray ); + System.out.println( output ); + int[] deserialized = stateSerialization.deserialize( module, int[].class, output ); + assertArrayEquals( primitiveArray, deserialized ); + } + + @Test + public void givenArrayWithByteAndNullElementWhenSerializingAndDeserializingExpectEquals() + throws Exception + { + Byte[] array = new Byte[] + { + 9, null, -12, -12, 127, -128, 73 + }; + String output = stateSerialization.serialize( array ); + System.out.println( output ); + Byte[] deserialized = stateSerialization.deserialize( module, Byte[].class, output ); + assertArrayEquals( array, deserialized ); + } + + @Test + public void givenIterableTypeWithByteAndNullElementWhenSerializingAndDeserializingExpectEquals() + throws Exception + { + String output = stateSerialization.serialize( new AdHocIterable<>( byteCollection() ) ); + System.out.println( output ); + CollectionType collectionType = CollectionType.listOf( ValueType.BYTE ); + List<Byte> list = stateSerialization.deserialize( module, collectionType, output ); + assertEquals( byteCollection(), list ); + } + + @Test + public void givenCollectionTypeWithByteAndNullElementWhenSerializingAndDeserializingExpectEquals() + throws Exception + { + String output = stateSerialization.serialize( byteCollection() ); + System.out.println( output ); + CollectionType collectionType = CollectionType.setOf( ValueType.BYTE ); + Set<Byte> list = stateSerialization.deserialize( module, collectionType, output ); + assertEquals( new LinkedHashSet<>( byteCollection() ), list ); + } + + @Test + public void givenCollectionTypeWithCharacterAndNullElementWhenSerializingAndDeserializingExpectEquals() + throws Exception + { + String output = stateSerialization.serialize( characterCollection() ); + System.out.println( output ); + CollectionType collectionType = CollectionType.listOf( ValueType.CHARACTER ); + List<Character> list = stateSerialization.deserialize( module, collectionType, output ); + assertEquals( characterCollection(), list ); + } + + @Test + public void givenCollectionTypeWithShortAndNullElementWhenSerializingAndDeserializingExpectEquals() + throws Exception + { + String output = stateSerialization.serialize( shortCollection() ); + System.out.println( output ); + CollectionType collectionType = CollectionType.listOf( ValueType.SHORT ); + List<Short> list = stateSerialization.deserialize( module, collectionType, output ); + assertEquals( shortCollection(), list ); + } + + @Test + public void givenCollectionTypeWithIntegerAndNullElementWhenSerializingAndDeserializingExpectEquals() + throws Exception + { + String output = stateSerialization.serialize( integerCollection() ); + System.out.println( output ); + CollectionType collectionType = CollectionType.listOf( ValueType.INTEGER ); + List<Integer> list = stateSerialization.deserialize( module, collectionType, output ); + assertEquals( integerCollection(), list ); + } + + @Test + public void givenCollectionTypeWithLongAndNullElementWhenSerializingAndDeserializingExpectEquals() + throws Exception + { + String output = stateSerialization.serialize( longCollection() ); + System.out.println( output ); + CollectionType collectionType = CollectionType.listOf( ValueType.LONG ); + List<Long> list = stateSerialization.deserialize( module, collectionType, output ); + assertEquals( longCollection(), list ); + } + + @Test + public void givenCollectionTypeWithFloatAndNullElementWhenSerializingAndDeserializingExpectEquals() + throws Exception + { + String output = stateSerialization.serialize( floatCollection() ); + System.out.println( output ); + CollectionType collectionType = CollectionType.listOf( ValueType.FLOAT ); + List<Float> list = stateSerialization.deserialize( module, collectionType, output ); + assertEquals( floatCollection(), list ); + } + + @Test + public void givenCollectionTypeWithDoubleAndNullElementWhenSerializingExpectCorrectJsonOutput() + throws Exception + { + String output = stateSerialization.serialize( doubleCollection() ); + System.out.println( output ); + CollectionType collectionType = CollectionType.listOf( ValueType.DOUBLE ); + List<Double> list = stateSerialization.deserialize( module, collectionType, output ); + assertEquals( doubleCollection(), list ); + } + + @Test + public void givenCollectionTypeWithBigIntegerAndNullElementWhenSerializingAndDeserializingExpectEquals() + throws Exception + { + String output = stateSerialization.serialize( bigIntegerCollection() ); + System.out.println( output ); + CollectionType collectionType = CollectionType.listOf( ValueType.BIG_INTEGER ); + List<BigInteger> list = stateSerialization.deserialize( module, collectionType, output ); + assertEquals( bigIntegerCollection(), list ); + } + + @Test + public void givenCollectionTypeWithBigDecimalAndNullElementWhenSerializingAndDeserializingExpectEquals() + throws Exception + { + String output = stateSerialization.serialize( bigDecimalCollection() ); + System.out.println( output ); + CollectionType collectionType = CollectionType.collectionOf( ValueType.BIG_DECIMAL ); + Collection<BigDecimal> collection = stateSerialization.deserialize( module, collectionType, output ); + assertEquals( bigDecimalCollection(), collection ); + } + + @Test + public void givenMapOfStringByteAndNullElementWhenSerializingAndDeserializingExpectEquals() + throws Exception + { + String output = stateSerialization.serialize( stringByteMap() ); + System.out.println( output ); + MapType mapType = MapType.of( ValueType.STRING, ValueType.BYTE ); + Map<String, Byte> value = stateSerialization.deserialize( module, mapType, output ); + assertEquals( stringByteMap(), value ); + } + + @Test + public void givenMapOfStringListStringAndNullElementWhenSerializingAndDeserializingExpectEquals() + throws Exception + { + String output = stateSerialization.serialize( stringMultiMap() ); + System.out.println( output ); + CollectionType collectionType = CollectionType.listOf( ValueType.STRING ); + MapType mapType = MapType.of( ValueType.STRING, collectionType ); + Map<String, List<String>> value = stateSerialization.deserialize( module, mapType, output ); + assertEquals( stringMultiMap(), value ); + } + + @Test + public void givenListOfMapStringStringAndNullElementWhenSerializingAndDeserializingExpectEquals() + throws Exception + { + String output = stateSerialization.serialize( stringListOfMaps() ); + System.out.println( output ); + CollectionType collectionType = CollectionType.listOf( MapType.of( ValueType.STRING, ValueType.STRING ) ); + List<Map<String, String>> value = stateSerialization.deserialize( module, collectionType, output ); + assertEquals( stringListOfMaps(), value ); + } + + @Test + public void givenListOfValueCompositesAndNullElementWhenSerializingAndDeserializingExpectEquals() + throws Exception + { + String output = stateSerialization.serialize( valueCompositesList() ); + System.out.println( output ); + ValueCompositeType valueType = module.valueDescriptor( SomeValue.class.getName() ).valueType(); + CollectionType collectionType = CollectionType.listOf( valueType ); + List<SomeValue> value = stateSerialization.deserialize( module, collectionType, output ); + assertEquals( valueCompositesList(), value ); + } + + @Test + public void givenEnumSetWhenSerializingAndDeserializingExcepctEquals() + { + Set<SomeEnum> enumSet = EnumSet.allOf( SomeEnum.class ); + String output = stateSerialization.serialize( enumSet ); + System.out.println( output ); + Set<SomeEnum> value = stateSerialization.deserialize( module, CollectionType.setOf( SomeEnum.class ), output ); + assertEquals( enumSet, value ); + } + + private ArrayList<Byte> byteCollection() + { + ArrayList<Byte> value = new ArrayList<>(); + value.add( (byte) 9 ); + value.add( null ); + value.add( (byte) -12 ); + value.add( (byte) -12 ); + value.add( (byte) 127 ); + value.add( (byte) -128 ); + value.add( (byte) 73 ); + return value; + } + + private List<Character> characterCollection() + { + List<Character> value = new ArrayList<>(); + value.add( 'Q' ); + value.add( 'i' ); + value.add( null ); + value.add( '4' ); + value.add( 'j' ); + return value; + } + + private Collection<Short> shortCollection() + { + Collection<Short> value = new ArrayList<>(); + value.add( (short) -32768 ); + value.add( (short) 32767 ); + value.add( (short) -82 ); + value.add( null ); + return value; + } + + private Collection<Integer> integerCollection() + { + Collection<Integer> value = new ArrayList<>(); + value.add( Integer.MAX_VALUE ); + value.add( -283 ); + value.add( null ); + value.add( Integer.MIN_VALUE ); + value.add( 238 ); + return value; + } + + private Collection<Long> longCollection() + { + Collection<Long> value = new ArrayList<>(); + value.add( 98239723L ); + value.add( -1298233L ); + value.add( -1L ); + value.add( 0L ); + value.add( null ); + value.add( 1L ); + value.add( Long.MAX_VALUE ); + value.add( Long.MIN_VALUE ); + return value; + } + + private Collection<Float> floatCollection() + { + Collection<Float> value = new ArrayList<>(); + value.add( -1f ); + value.add( 1f ); + value.add( 1f ); + value.add( 0f ); + value.add( Float.MAX_VALUE ); + value.add( Float.MIN_VALUE ); + value.add( null ); + value.add( 0.123456f ); + value.add( -0.232321f ); + return value; + } + + private Collection<Double> doubleCollection() + { + Collection<Double> value = new ArrayList<>(); + value.add( -1.0 ); + value.add( 1.0 ); + value.add( 0.0 ); + value.add( Double.MAX_VALUE ); + value.add( null ); + value.add( Double.MIN_VALUE ); + value.add( 0.123456 ); + value.add( -0.232321 ); + return value; + } + + private Collection<BigInteger> bigIntegerCollection() + { + Collection<BigInteger> value = new ArrayList<>(); + value.add( new BigInteger( "-1" ) ); + value.add( BigInteger.ZERO ); + value.add( BigInteger.ONE ); + value.add( null ); + value.add( BigInteger.TEN ); + value.add( new BigInteger( "-1827368263823729372397239829332" ) ); + value.add( new BigInteger( "2398723982982379827373972398723" ) ); + return value; + } + + private Collection<BigDecimal> bigDecimalCollection() + { + Collection<BigDecimal> value = new ArrayList<>(); + value.add( new BigDecimal( "1.2" ) ); + value.add( new BigDecimal( "3.4" ) ); + value.add( null ); + value.add( new BigDecimal( "5.6" ) ); + return value; + } + + private Map<String, Byte> stringByteMap() + { + Map<String, Byte> value = new LinkedHashMap<>(); + value.put( "a", (byte) 9 ); + value.put( "b", null ); + value.put( "c", (byte) -12 ); + return value; + } + + private Map<String, List<String>> stringMultiMap() + { + Map<String, List<String>> value = new LinkedHashMap<>(); + List<String> list = new ArrayList<>(); + list.add( "foo" ); + list.add( "bar" ); + list.add( null ); + list.add( "cathedral" ); + list.add( "bazar" ); + value.put( "alpha", list ); + value.put( "beta", null ); + value.put( "gamma", Collections.emptyList() ); + return value; + } + + private List<Map<String, String>> stringListOfMaps() + { + List<Map<String, String>> value = new ArrayList<>(); + Map<String, String> map = new LinkedHashMap<>(); + map.put( "foo", "bar" ); + map.put( "cathedral", "bazar" ); + map.put( "yield", null ); + map.put( "42", "23" ); + value.add( map ); + value.add( null ); + value.add( Collections.emptyMap() ); + return value; + } + + private List<SomeValue> valueCompositesList() + { + List<SomeValue> list = new ArrayList<>(); + list.add( newSomeValue( "", "bazar" ) ); + list.add( null ); + list.add( newSomeValue( "bar", null ) ); + return list; + } + + public interface SomeValue + { + Property<String> foo(); + + @Optional + Property<String> cathedral(); + } + + private SomeValue newSomeValue( String foo, String cathedral ) + { + ValueBuilder<SomeValue> builder = module.instance().newValueBuilder( SomeValue.class ); + SomeValue value = builder.prototype(); + value.foo().set( foo ); + if( cathedral != null ) + { + value.cathedral().set( cathedral ); + } + return builder.newInstance(); + } + + private static class AdHocIterable<T> implements Iterable<T> + { + private final Iterable<T> delegate; + + private AdHocIterable( Iterable<T> delegate ) + { + this.delegate = delegate; + } + + @Override + public Iterator<T> iterator() + { + return delegate.iterator(); + } + } + + private enum SomeEnum + { + FOO, + BAR, + BAZAR, + CATHEDRAL + } +}
