polygene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nic...@apache.org
Subject zest-java git commit: ZEST-141 - First implementation of values in @UseDefaults, however it doesn't work properly for lists and maps and complex types has not been tested yet. Removed a lot of duplicated code in CompositeAssemblyImpl and its subclasses.
Date Fri, 10 Jun 2016 08:34:03 GMT
Repository: zest-java
Updated Branches:
  refs/heads/develop 037e56a63 -> 92e5605ad


ZEST-141 - First implementation of values in @UseDefaults, however it doesn't work properly for lists and maps and complex types has not been tested yet.
Removed a lot of duplicated code in CompositeAssemblyImpl and its subclasses.


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

Branch: refs/heads/develop
Commit: 92e5605ad891ca0806f9688c14dace57b2237342
Parents: 037e56a
Author: Niclas Hedhman <niclas@hedhman.org>
Authored: Fri Jun 10 16:05:05 2016 +0800
Committer: Niclas Hedhman <niclas@hedhman.org>
Committed: Fri Jun 10 16:05:05 2016 +0800

----------------------------------------------------------------------
 .../org/apache/zest/api/common/UseDefaults.java |   8 +
 .../MissingValueSerializationException.java     |  43 +++++
 .../zest/bootstrap/MetaInfoDeclaration.java     |  14 +-
 .../bootstrap/CompositeAssemblyImpl.java        | 143 +++++++++++++-
 .../runtime/bootstrap/EntityAssemblyImpl.java   | 186 +++----------------
 .../runtime/bootstrap/ServiceAssemblyImpl.java  |   3 +
 .../bootstrap/TransientAssemblyImpl.java        |   3 +
 .../runtime/bootstrap/ValueAssemblyImpl.java    | 136 +-------------
 .../zest/runtime/property/PropertyModel.java    |  40 +++-
 .../zest/runtime/defaults/UseDefaultsTest.java  |  44 ++++-
 .../spi/value/ValueDeserializerAdapter.java     |  11 +-
 11 files changed, 309 insertions(+), 322 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zest-java/blob/92e5605a/core/api/src/main/java/org/apache/zest/api/common/UseDefaults.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/common/UseDefaults.java b/core/api/src/main/java/org/apache/zest/api/common/UseDefaults.java
index d72b483..5a36824 100644
--- a/core/api/src/main/java/org/apache/zest/api/common/UseDefaults.java
+++ b/core/api/src/main/java/org/apache/zest/api/common/UseDefaults.java
@@ -51,6 +51,13 @@ import java.lang.annotation.Target;
  * is not allowed.
  * </p>
  * <p>
+ * The <code>&#64;UseDefaults</code> annotation can also have a value in its declaration. This value is used,
+ * unless it is overridden in the assembly (see below). Java does not support generic types of annotation values,
+ * so it accepts String values, which are deserialized from JSON using the ValueSerialization SPI. This allows
+ * for (albeit somewhat tedious) any object type to have a default value declared on it. If the property type is
+ * String, then no value deserialization is done.
+ * </p>
+ * <p>
  * It is also possible to change the default values for Composites during the assembly. This is done by calling the
  * {@code org.apache.zest.bootstrap.ModuleAssembly#forMixin(Class)} method.
  * </p>
@@ -81,4 +88,5 @@ import java.lang.annotation.Target;
 @Documented
 public @interface UseDefaults
 {
+    String value() default "";
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zest-java/blob/92e5605a/core/api/src/main/java/org/apache/zest/api/value/MissingValueSerializationException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/value/MissingValueSerializationException.java b/core/api/src/main/java/org/apache/zest/api/value/MissingValueSerializationException.java
new file mode 100644
index 0000000..c5507ac
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/value/MissingValueSerializationException.java
@@ -0,0 +1,43 @@
+/*
+ *  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.zest.api.value;
+
+public class MissingValueSerializationException extends ValueSerializationException
+{
+    public MissingValueSerializationException()
+    {
+    }
+
+    public MissingValueSerializationException( String message )
+    {
+        super( message );
+    }
+
+    public MissingValueSerializationException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+
+    public MissingValueSerializationException( Throwable cause )
+    {
+        super( cause );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/92e5605a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/MetaInfoDeclaration.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/MetaInfoDeclaration.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/MetaInfoDeclaration.java
index 67a0f24..2feafd3 100644
--- a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/MetaInfoDeclaration.java
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/MetaInfoDeclaration.java
@@ -144,18 +144,12 @@ public final class MetaInfoDeclaration
             try
             {
                 return Proxy.newProxyInstance( returnType.getClassLoader(), new Class[]{ returnType },
-                                               new InvocationHandler()
-                                               {
-                                                   @Override
-                                                   public Object invoke( Object o, Method method, Object[] objects )
-                                                       throws Throwable
+                                               ( o1, method1, objects1 ) -> {
+                                                   if( method1.getName().equals( "set" ) )
                                                    {
-                                                       if( method.getName().equals( "set" ) )
-                                                       {
-                                                           methodInfo.initialValue = objects[ 0 ];
-                                                       }
-                                                       return null;
+                                                       methodInfo.initialValue = objects1[ 0 ];
                                                    }
+                                                   return null;
                                                } );
             }
             catch( IllegalArgumentException e )

http://git-wip-us.apache.org/repos/asf/zest-java/blob/92e5605a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/CompositeAssemblyImpl.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/CompositeAssemblyImpl.java b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/CompositeAssemblyImpl.java
index 211b2f5..1d1f096 100755
--- a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/CompositeAssemblyImpl.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/CompositeAssemblyImpl.java
@@ -39,6 +39,10 @@ import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
+import org.apache.zest.api.association.Association;
+import org.apache.zest.api.association.GenericAssociationInfo;
+import org.apache.zest.api.association.ManyAssociation;
+import org.apache.zest.api.association.NamedAssociation;
 import org.apache.zest.api.common.MetaInfo;
 import org.apache.zest.api.common.Optional;
 import org.apache.zest.api.common.QualifiedName;
@@ -65,6 +69,12 @@ import org.apache.zest.api.util.Classes;
 import org.apache.zest.api.util.Fields;
 import org.apache.zest.bootstrap.StateDeclarations;
 import org.apache.zest.functional.HierarchicalVisitorAdapter;
+import org.apache.zest.runtime.association.AssociationModel;
+import org.apache.zest.runtime.association.AssociationsModel;
+import org.apache.zest.runtime.association.ManyAssociationModel;
+import org.apache.zest.runtime.association.ManyAssociationsModel;
+import org.apache.zest.runtime.association.NamedAssociationModel;
+import org.apache.zest.runtime.association.NamedAssociationsModel;
 import org.apache.zest.runtime.composite.AbstractConstraintModel;
 import org.apache.zest.runtime.composite.CompositeConstraintModel;
 import org.apache.zest.runtime.composite.CompositeMethodModel;
@@ -410,9 +420,7 @@ public abstract class CompositeAssemblyImpl
         } );
     }
 
-    protected void addStateFor( AccessibleObject accessor,
-                                List<Class<?>> constraintClasses
-    )
+    protected void addStateFor( AccessibleObject accessor, List<Class<?>> constraintClasses )
     {
         String stateName = QualifiedName.fromAccessor( accessor ).name();
 
@@ -421,11 +429,42 @@ public abstract class CompositeAssemblyImpl
             return; // Skip already registered names
         }
 
-        if( Property.class.isAssignableFrom( Classes.RAW_CLASS.apply( typeOf( accessor ) ) ) )
+        Class<?> accessorType = Classes.RAW_CLASS.apply( typeOf( accessor ) );
+        if( Property.class.isAssignableFrom( accessorType ) )
         {
             propertiesModel.addProperty( newPropertyModel( accessor, constraintClasses ) );
             registeredStateNames.add( stateName );
         }
+        else if( Association.class.isAssignableFrom( accessorType ) )
+        {
+            associationsModel().addAssociation( newAssociationModel( accessor, constraintClasses ) );
+            registeredStateNames.add( stateName );
+        }
+        else if( ManyAssociation.class.isAssignableFrom( accessorType ) )
+        {
+            manyAssociationsModel().addManyAssociation( newManyAssociationModel( accessor, constraintClasses ) );
+            registeredStateNames.add( stateName );
+        }
+        else if( NamedAssociation.class.isAssignableFrom( accessorType ) )
+        {
+            namedAssociationsModel().addNamedAssociation( newNamedAssociationModel( accessor, constraintClasses ) );
+            registeredStateNames.add( stateName );
+        }
+    }
+
+    protected AssociationsModel associationsModel()
+    {
+        return null;
+    }
+
+    protected ManyAssociationsModel manyAssociationsModel()
+    {
+        return null;
+    }
+
+    protected NamedAssociationsModel namedAssociationsModel()
+    {
+        return null;
     }
 
     protected PropertyModel newPropertyModel( AccessibleObject accessor,
@@ -447,8 +486,13 @@ public abstract class CompositeAssemblyImpl
             valueConstraintsInstance = valueConstraintsModel.newInstance();
         }
         MetaInfo metaInfo = stateDeclarations.metaInfoFor( accessor );
+        UseDefaults useDefaultsDeclaration = metaInfo.get( UseDefaults.class );
         Object initialValue = stateDeclarations.initialValueOf( accessor );
-        boolean useDefaults = metaInfo.get( UseDefaults.class ) != null || stateDeclarations.useDefaults( accessor );
+        if( initialValue == null && useDefaultsDeclaration != null )
+        {
+            initialValue = useDefaultsDeclaration.value();
+        }
+        boolean useDefaults = useDefaultsDeclaration != null || stateDeclarations.useDefaults( accessor );
         boolean immutable = this.immutable || metaInfo.get( Immutable.class ) != null;
         return new PropertyModel(
             accessor,
@@ -456,7 +500,8 @@ public abstract class CompositeAssemblyImpl
             useDefaults,
             valueConstraintsInstance,
             metaInfo,
-            initialValue );
+            initialValue
+        );
     }
 
     // Model
@@ -710,7 +755,9 @@ public abstract class CompositeAssemblyImpl
         }
     }
 
-    private void addSideEffectOrRepositionIfExists( List<SideEffectModel> sideEffectsFor, SideEffectModel sideEffectModel )
+    private void addSideEffectOrRepositionIfExists( List<SideEffectModel> sideEffectsFor,
+                                                    SideEffectModel sideEffectModel
+    )
     {
         // This add/remove is to allow reording of SideEffects.
         sideEffectsFor.remove( sideEffectModel );
@@ -795,4 +842,86 @@ public abstract class CompositeAssemblyImpl
             return classHierarchy( clazz ).map( Classes.RAW_CLASS );
         }
     }
+
+    public AssociationModel newAssociationModel( AccessibleObject accessor,
+                                                 List<Class<?>> constraintClasses
+    )
+    {
+        List<Annotation> annotations = Annotations.findAccessorAndTypeAnnotationsIn( accessor );
+        boolean optional = annotations.stream().anyMatch( isType( Optional.class ) );
+
+        // Constraints for Association references
+        ValueConstraintsModel valueConstraintsModel = constraintsFor( annotations.stream(), GenericAssociationInfo
+            .associationTypeOf( accessor ), ( (Member) accessor ).getName(), optional, constraintClasses, accessor );
+        ValueConstraintsInstance valueConstraintsInstance = null;
+        if( valueConstraintsModel.isConstrained() )
+        {
+            valueConstraintsInstance = valueConstraintsModel.newInstance();
+        }
+
+        // Constraints for the Association itself
+        valueConstraintsModel = constraintsFor( annotations.stream(), Association.class, ( (Member) accessor ).getName(), optional, constraintClasses, accessor );
+        ValueConstraintsInstance associationValueConstraintsInstance = null;
+        if( valueConstraintsModel.isConstrained() )
+        {
+            associationValueConstraintsInstance = valueConstraintsModel.newInstance();
+        }
+
+        MetaInfo metaInfo = stateDeclarations.metaInfoFor( accessor );
+        return new AssociationModel( accessor, valueConstraintsInstance, associationValueConstraintsInstance, metaInfo );
+    }
+
+    public ManyAssociationModel newManyAssociationModel( AccessibleObject accessor,
+                                                         List<Class<?>> constraintClasses
+    )
+    {
+        List<Annotation> annotations = Annotations.findAccessorAndTypeAnnotationsIn( accessor );
+        boolean optional = annotations.stream().anyMatch( isType( Optional.class ) );
+
+        // Constraints for entities in ManyAssociation
+        ValueConstraintsModel valueConstraintsModel = constraintsFor( annotations.stream(), GenericAssociationInfo
+            .associationTypeOf( accessor ), ( (Member) accessor ).getName(), optional, constraintClasses, accessor );
+        ValueConstraintsInstance valueConstraintsInstance = null;
+        if( valueConstraintsModel.isConstrained() )
+        {
+            valueConstraintsInstance = valueConstraintsModel.newInstance();
+        }
+
+        // Constraints for the ManyAssociation itself
+        valueConstraintsModel = constraintsFor( annotations.stream(), ManyAssociation.class, ( (Member) accessor ).getName(), optional, constraintClasses, accessor );
+        ValueConstraintsInstance manyValueConstraintsInstance = null;
+        if( valueConstraintsModel.isConstrained() )
+        {
+            manyValueConstraintsInstance = valueConstraintsModel.newInstance();
+        }
+        MetaInfo metaInfo = stateDeclarations.metaInfoFor( accessor );
+        return new ManyAssociationModel( accessor, valueConstraintsInstance, manyValueConstraintsInstance, metaInfo );
+    }
+
+    public NamedAssociationModel newNamedAssociationModel( AccessibleObject accessor,
+                                                           List<Class<?>> constraintClasses
+    )
+    {
+        List<Annotation> annotations = Annotations.findAccessorAndTypeAnnotationsIn( accessor );
+        boolean optional = annotations.stream().anyMatch( isType( Optional.class ) );
+
+        // Constraints for entities in NamedAssociation
+        ValueConstraintsModel valueConstraintsModel = constraintsFor( annotations.stream(), GenericAssociationInfo
+            .associationTypeOf( accessor ), ( (Member) accessor ).getName(), optional, constraintClasses, accessor );
+        ValueConstraintsInstance valueConstraintsInstance = null;
+        if( valueConstraintsModel.isConstrained() )
+        {
+            valueConstraintsInstance = valueConstraintsModel.newInstance();
+        }
+
+        // Constraints for the NamedAssociation itself
+        valueConstraintsModel = constraintsFor( annotations.stream(), NamedAssociation.class, ( (Member) accessor ).getName(), optional, constraintClasses, accessor );
+        ValueConstraintsInstance namedValueConstraintsInstance = null;
+        if( valueConstraintsModel.isConstrained() )
+        {
+            namedValueConstraintsInstance = valueConstraintsModel.newInstance();
+        }
+        MetaInfo metaInfo = stateDeclarations.metaInfoFor( accessor );
+        return new NamedAssociationModel( accessor, valueConstraintsInstance, namedValueConstraintsInstance, metaInfo );
+    }
 }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/92e5605a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/EntityAssemblyImpl.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/EntityAssemblyImpl.java b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/EntityAssemblyImpl.java
index d5d0834..4a775f9 100755
--- a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/EntityAssemblyImpl.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/EntityAssemblyImpl.java
@@ -19,36 +19,22 @@
  */
 package org.apache.zest.runtime.bootstrap;
 
-import org.apache.zest.api.association.Association;
-import org.apache.zest.api.association.GenericAssociationInfo;
-import org.apache.zest.api.association.ManyAssociation;
-import org.apache.zest.api.association.NamedAssociation;
-import org.apache.zest.api.common.*;
+import org.apache.zest.api.common.InvalidApplicationException;
 import org.apache.zest.api.entity.EntityComposite;
-import org.apache.zest.api.property.GenericPropertyInfo;
-import org.apache.zest.api.property.Immutable;
-import org.apache.zest.api.property.Property;
 import org.apache.zest.api.structure.ModuleDescriptor;
-import org.apache.zest.api.util.Annotations;
-import org.apache.zest.api.util.Classes;
-import org.apache.zest.bootstrap.*;
-import org.apache.zest.runtime.association.*;
+import org.apache.zest.bootstrap.AssociationDeclarations;
+import org.apache.zest.bootstrap.EntityAssembly;
+import org.apache.zest.bootstrap.ManyAssociationDeclarations;
+import org.apache.zest.bootstrap.NamedAssociationDeclarations;
+import org.apache.zest.bootstrap.StateDeclarations;
+import org.apache.zest.runtime.association.AssociationsModel;
+import org.apache.zest.runtime.association.ManyAssociationsModel;
+import org.apache.zest.runtime.association.NamedAssociationsModel;
 import org.apache.zest.runtime.composite.MixinsModel;
 import org.apache.zest.runtime.composite.StateModel;
-import org.apache.zest.runtime.composite.ValueConstraintsInstance;
-import org.apache.zest.runtime.composite.ValueConstraintsModel;
 import org.apache.zest.runtime.entity.EntityMixinsModel;
 import org.apache.zest.runtime.entity.EntityModel;
 import org.apache.zest.runtime.entity.EntityStateModel;
-import org.apache.zest.runtime.property.PropertyModel;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Member;
-import java.util.List;
-
-import static org.apache.zest.api.util.Annotations.isType;
-import static org.apache.zest.api.util.Classes.typeOf;
 
 /**
  * Declaration of a EntityComposite.
@@ -81,6 +67,24 @@ public final class EntityAssemblyImpl
     }
 
     @Override
+    protected AssociationsModel associationsModel()
+    {
+        return associationsModel;
+    }
+
+    @Override
+    protected ManyAssociationsModel manyAssociationsModel()
+    {
+        return manyAssociationsModel;
+    }
+
+    @Override
+    protected NamedAssociationsModel namedAssociationsModel()
+    {
+        return namedAssociationsModel;
+    }
+
+    @Override
     protected StateModel createStateModel()
     {
         return new EntityStateModel( propertiesModel, associationsModel, manyAssociationsModel, namedAssociationsModel );
@@ -114,140 +118,4 @@ public final class EntityAssemblyImpl
             throw new InvalidApplicationException( "Could not register " + types, e );
         }
     }
-
-    @Override
-    protected void addStateFor( AccessibleObject accessor, List<Class<?>> constraintClasses )
-    {
-        String stateName = QualifiedName.fromAccessor( accessor ).name();
-
-        if( registeredStateNames.contains( stateName ) )
-        {
-            return; // Skip already registered names
-        }
-
-        Class<?> accessorType = Classes.RAW_CLASS.apply( typeOf( accessor ) );
-        if( Property.class.isAssignableFrom( accessorType ) )
-        {
-            propertiesModel.addProperty( newPropertyModel( accessor, constraintClasses ) );
-            registeredStateNames.add( stateName );
-        }
-        else if( Association.class.isAssignableFrom( accessorType ) )
-        {
-            associationsModel.addAssociation( newAssociationModel( accessor, constraintClasses ) );
-            registeredStateNames.add( stateName );
-        }
-        else if( ManyAssociation.class.isAssignableFrom( accessorType ) )
-        {
-            manyAssociationsModel.addManyAssociation( newManyAssociationModel( accessor, constraintClasses ) );
-            registeredStateNames.add( stateName );
-        }
-        else if( NamedAssociation.class.isAssignableFrom( accessorType ) )
-        {
-            namedAssociationsModel.addNamedAssociation( newNamedAssociationModel( accessor, constraintClasses ) );
-            registeredStateNames.add( stateName );
-        }
-    }
-
-    @Override
-    protected PropertyModel newPropertyModel( AccessibleObject accessor,
-                                              List<Class<?>> constraintClasses
-    )
-    {
-        List<Annotation> annotations = Annotations.findAccessorAndTypeAnnotationsIn(accessor);
-        boolean optional = annotations.stream().anyMatch( isType( Optional.class ) );
-        ValueConstraintsModel valueConstraintsModel = constraintsFor( annotations.stream(), GenericPropertyInfo.propertyTypeOf( accessor ), ( (Member) accessor )
-            .getName(), optional, constraintClasses, accessor );
-        ValueConstraintsInstance valueConstraintsInstance = null;
-        if( valueConstraintsModel.isConstrained() )
-        {
-            valueConstraintsInstance = valueConstraintsModel.newInstance();
-        }
-        MetaInfo metaInfo = stateDeclarations.metaInfoFor( accessor );
-        Object defaultValue = stateDeclarations.initialValueOf( accessor );
-        boolean useDefaults = metaInfo.get( UseDefaults.class ) != null || stateDeclarations.useDefaults( accessor );
-        boolean immutable = this.immutable || metaInfo.get( Immutable.class ) != null;
-        return new PropertyModel( accessor, immutable, useDefaults, valueConstraintsInstance, metaInfo, defaultValue );
-    }
-
-    public AssociationModel newAssociationModel( AccessibleObject accessor,
-                                                 Iterable<Class<?>> constraintClasses
-    )
-    {
-        List<Annotation> annotations = Annotations.findAccessorAndTypeAnnotationsIn(accessor);
-        boolean optional = annotations.stream().anyMatch(isType(Optional.class));
-
-        // Constraints for Association references
-        ValueConstraintsModel valueConstraintsModel = constraintsFor( annotations.stream(), GenericAssociationInfo
-            .associationTypeOf( accessor ), ( (Member) accessor ).getName(), optional, constraintClasses, accessor );
-        ValueConstraintsInstance valueConstraintsInstance = null;
-        if( valueConstraintsModel.isConstrained() )
-        {
-            valueConstraintsInstance = valueConstraintsModel.newInstance();
-        }
-
-        // Constraints for the Association itself
-        valueConstraintsModel = constraintsFor( annotations.stream(), Association.class, ( (Member) accessor ).getName(), optional, constraintClasses, accessor );
-        ValueConstraintsInstance associationValueConstraintsInstance = null;
-        if( valueConstraintsModel.isConstrained() )
-        {
-            associationValueConstraintsInstance = valueConstraintsModel.newInstance();
-        }
-
-        MetaInfo metaInfo = associationDeclarations.metaInfoFor( accessor );
-        return new AssociationModel( accessor, valueConstraintsInstance, associationValueConstraintsInstance, metaInfo );
-    }
-
-    public ManyAssociationModel newManyAssociationModel( AccessibleObject accessor,
-                                                         List<Class<?>> constraintClasses
-    )
-    {
-        List<Annotation> annotations = Annotations.findAccessorAndTypeAnnotationsIn(accessor);
-        boolean optional = annotations.stream().anyMatch(isType(Optional.class));
-
-        // Constraints for entities in ManyAssociation
-        ValueConstraintsModel valueConstraintsModel = constraintsFor( annotations.stream(), GenericAssociationInfo
-            .associationTypeOf( accessor ), ( (Member) accessor ).getName(), optional, constraintClasses, accessor );
-        ValueConstraintsInstance valueConstraintsInstance = null;
-        if( valueConstraintsModel.isConstrained() )
-        {
-            valueConstraintsInstance = valueConstraintsModel.newInstance();
-        }
-
-        // Constraints for the ManyAssociation itself
-        valueConstraintsModel = constraintsFor( annotations.stream(), ManyAssociation.class, ( (Member) accessor ).getName(), optional, constraintClasses, accessor );
-        ValueConstraintsInstance manyValueConstraintsInstance = null;
-        if( valueConstraintsModel.isConstrained() )
-        {
-            manyValueConstraintsInstance = valueConstraintsModel.newInstance();
-        }
-        MetaInfo metaInfo = manyAssociationDeclarations.metaInfoFor( accessor );
-        return new ManyAssociationModel( accessor, valueConstraintsInstance, manyValueConstraintsInstance, metaInfo );
-    }
-
-    public NamedAssociationModel newNamedAssociationModel( AccessibleObject accessor,
-                                                           List<Class<?>> constraintClasses
-    )
-    {
-        List<Annotation> annotations = Annotations.findAccessorAndTypeAnnotationsIn(accessor);
-        boolean optional = annotations.stream().anyMatch( isType( Optional.class ) );
-
-        // Constraints for entities in NamedAssociation
-        ValueConstraintsModel valueConstraintsModel = constraintsFor( annotations.stream(), GenericAssociationInfo
-            .associationTypeOf( accessor ), ( (Member) accessor ).getName(), optional, constraintClasses, accessor );
-        ValueConstraintsInstance valueConstraintsInstance = null;
-        if( valueConstraintsModel.isConstrained() )
-        {
-            valueConstraintsInstance = valueConstraintsModel.newInstance();
-        }
-
-        // Constraints for the NamedAssociation itself
-        valueConstraintsModel = constraintsFor( annotations.stream(), NamedAssociation.class, ( (Member) accessor ).getName(), optional, constraintClasses, accessor );
-        ValueConstraintsInstance namedValueConstraintsInstance = null;
-        if( valueConstraintsModel.isConstrained() )
-        {
-            namedValueConstraintsInstance = valueConstraintsModel.newInstance();
-        }
-        MetaInfo metaInfo = namedAssociationDeclarations.metaInfoFor( accessor );
-        return new NamedAssociationModel( accessor, valueConstraintsInstance, namedValueConstraintsInstance, metaInfo );
-    }
 }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/92e5605a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ServiceAssemblyImpl.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ServiceAssemblyImpl.java b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ServiceAssemblyImpl.java
index 7180012..6cdcaf4 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ServiceAssemblyImpl.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ServiceAssemblyImpl.java
@@ -35,6 +35,9 @@ import org.apache.zest.bootstrap.ServiceAssembly;
 import org.apache.zest.bootstrap.StateDeclarations;
 import org.apache.zest.functional.Iterables;
 import org.apache.zest.runtime.activation.ActivatorsModel;
+import org.apache.zest.runtime.association.AssociationsModel;
+import org.apache.zest.runtime.association.ManyAssociationsModel;
+import org.apache.zest.runtime.association.NamedAssociationsModel;
 import org.apache.zest.runtime.service.ServiceModel;
 import org.apache.zest.runtime.structure.ModuleModel;
 

http://git-wip-us.apache.org/repos/asf/zest-java/blob/92e5605a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/TransientAssemblyImpl.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/TransientAssemblyImpl.java b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/TransientAssemblyImpl.java
index 52e436f..f2b531d 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/TransientAssemblyImpl.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/TransientAssemblyImpl.java
@@ -25,6 +25,9 @@ import org.apache.zest.api.composite.TransientComposite;
 import org.apache.zest.api.structure.ModuleDescriptor;
 import org.apache.zest.bootstrap.StateDeclarations;
 import org.apache.zest.bootstrap.TransientAssembly;
+import org.apache.zest.runtime.association.AssociationsModel;
+import org.apache.zest.runtime.association.ManyAssociationsModel;
+import org.apache.zest.runtime.association.NamedAssociationsModel;
 import org.apache.zest.runtime.composite.TransientModel;
 
 /**

http://git-wip-us.apache.org/repos/asf/zest-java/blob/92e5605a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ValueAssemblyImpl.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ValueAssemblyImpl.java b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ValueAssemblyImpl.java
index f5fed54..9b8db5d 100755
--- a/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ValueAssemblyImpl.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/bootstrap/ValueAssemblyImpl.java
@@ -33,6 +33,7 @@ import org.apache.zest.api.common.Optional;
 import org.apache.zest.api.common.QualifiedName;
 import org.apache.zest.api.common.UseDefaults;
 import org.apache.zest.api.property.GenericPropertyInfo;
+import org.apache.zest.api.property.Immutable;
 import org.apache.zest.api.property.Property;
 import org.apache.zest.api.structure.ModuleDescriptor;
 import org.apache.zest.api.util.Annotations;
@@ -94,7 +95,6 @@ public final class ValueAssemblyImpl
             manyAssociationsModel = new ManyAssociationsModel();
             namedAssociationsModel = new NamedAssociationsModel();
             buildComposite( helper, stateDeclarations );
-
             return new ValueModel(
                 module, types, visibility, metaInfo, mixinsModel, (ValueStateModel) stateModel, compositeMethodsModel );
         }
@@ -104,140 +104,18 @@ public final class ValueAssemblyImpl
         }
     }
 
-    @Override
-    protected void addStateFor( AccessibleObject accessor,
-                                List<Class<?>> constraintClasses
-    )
+    protected AssociationsModel associationsModel()
     {
-        String stateName = QualifiedName.fromAccessor( accessor ).name();
-
-        if( registeredStateNames.contains( stateName ) )
-        {
-            return; // Skip already registered names
-        }
-
-        Class<?> accessorType = Classes.RAW_CLASS.apply( typeOf( accessor ) );
-        if( Property.class.isAssignableFrom( accessorType ) )
-        {
-            propertiesModel.addProperty( newPropertyModel( accessor, constraintClasses ) );
-            registeredStateNames.add( stateName );
-        }
-        else if( Association.class.isAssignableFrom( accessorType ) )
-        {
-            associationsModel.addAssociation( newAssociationModel( accessor, constraintClasses ) );
-            registeredStateNames.add( stateName );
-        }
-        else if( ManyAssociation.class.isAssignableFrom( accessorType ) )
-        {
-            manyAssociationsModel.addManyAssociation( newManyAssociationModel( accessor, constraintClasses ) );
-            registeredStateNames.add( stateName );
-        }
-        else if( NamedAssociation.class.isAssignableFrom( accessorType ) )
-        {
-            namedAssociationsModel.addNamedAssociation( newNamedAssociationModel( accessor, constraintClasses ) );
-            registeredStateNames.add( stateName );
-        }
+        return associationsModel;
     }
 
-    @Override
-    protected PropertyModel newPropertyModel( AccessibleObject accessor,
-                                              List<Class<?>> constraintClasses
-    )
+    protected ManyAssociationsModel manyAssociationsModel()
     {
-        List<Annotation> annotations = Annotations.findAccessorAndTypeAnnotationsIn( accessor );
-        boolean optional = annotations.stream().anyMatch( isType( Optional.class ) );
-        ValueConstraintsModel valueConstraintsModel = constraintsFor( annotations.stream(), GenericPropertyInfo.propertyTypeOf( accessor ), ( (Member) accessor )
-            .getName(), optional, constraintClasses, accessor );
-        ValueConstraintsInstance valueConstraintsInstance = null;
-        if( valueConstraintsModel.isConstrained() )
-        {
-            valueConstraintsInstance = valueConstraintsModel.newInstance();
-        }
-        MetaInfo metaInfo = stateDeclarations.metaInfoFor( accessor );
-        boolean useDefaults = metaInfo.get( UseDefaults.class ) != null || stateDeclarations.useDefaults( accessor );
-        Object initialValue = stateDeclarations.initialValueOf( accessor );
-        return new PropertyModel( accessor, true, useDefaults, valueConstraintsInstance, metaInfo, initialValue );
+        return manyAssociationsModel;
     }
 
-    public AssociationModel newAssociationModel( AccessibleObject accessor,
-                                                 List<Class<?>> constraintClasses
-    )
+    protected NamedAssociationsModel namedAssociationsModel()
     {
-        List<Annotation> annotations = Annotations.findAccessorAndTypeAnnotationsIn( accessor );
-        boolean optional = annotations.stream().anyMatch( isType( Optional.class ) );
-
-        // Constraints for Association references
-        ValueConstraintsModel valueConstraintsModel = constraintsFor( annotations.stream(), GenericAssociationInfo
-            .associationTypeOf( accessor ), ( (Member) accessor ).getName(), optional, constraintClasses, accessor );
-        ValueConstraintsInstance valueConstraintsInstance = null;
-        if( valueConstraintsModel.isConstrained() )
-        {
-            valueConstraintsInstance = valueConstraintsModel.newInstance();
-        }
-
-        // Constraints for the Association itself
-        valueConstraintsModel = constraintsFor( annotations.stream(), Association.class, ( (Member) accessor ).getName(), optional, constraintClasses, accessor );
-        ValueConstraintsInstance associationValueConstraintsInstance = null;
-        if( valueConstraintsModel.isConstrained() )
-        {
-            associationValueConstraintsInstance = valueConstraintsModel.newInstance();
-        }
-
-        MetaInfo metaInfo = stateDeclarations.metaInfoFor( accessor );
-        return new AssociationModel( accessor, valueConstraintsInstance, associationValueConstraintsInstance, metaInfo );
-    }
-
-    public ManyAssociationModel newManyAssociationModel( AccessibleObject accessor,
-                                                         List<Class<?>> constraintClasses
-    )
-    {
-        List<Annotation> annotations = Annotations.findAccessorAndTypeAnnotationsIn( accessor );
-        boolean optional = annotations.stream().anyMatch( isType( Optional.class ) );
-
-        // Constraints for entities in ManyAssociation
-        ValueConstraintsModel valueConstraintsModel = constraintsFor( annotations.stream(), GenericAssociationInfo
-            .associationTypeOf( accessor ), ( (Member) accessor ).getName(), optional, constraintClasses, accessor );
-        ValueConstraintsInstance valueConstraintsInstance = null;
-        if( valueConstraintsModel.isConstrained() )
-        {
-            valueConstraintsInstance = valueConstraintsModel.newInstance();
-        }
-
-        // Constraints for the ManyAssociation itself
-        valueConstraintsModel = constraintsFor( annotations.stream(), ManyAssociation.class, ( (Member) accessor ).getName(), optional, constraintClasses, accessor );
-        ValueConstraintsInstance manyValueConstraintsInstance = null;
-        if( valueConstraintsModel.isConstrained() )
-        {
-            manyValueConstraintsInstance = valueConstraintsModel.newInstance();
-        }
-        MetaInfo metaInfo = stateDeclarations.metaInfoFor( accessor );
-        return new ManyAssociationModel( accessor, valueConstraintsInstance, manyValueConstraintsInstance, metaInfo );
-    }
-
-    public NamedAssociationModel newNamedAssociationModel( AccessibleObject accessor,
-                                                           List<Class<?>> constraintClasses
-    )
-    {
-        List<Annotation> annotations = Annotations.findAccessorAndTypeAnnotationsIn( accessor );
-        boolean optional = annotations.stream().anyMatch( isType( Optional.class ) );
-
-        // Constraints for entities in NamedAssociation
-        ValueConstraintsModel valueConstraintsModel = constraintsFor( annotations.stream(), GenericAssociationInfo
-            .associationTypeOf( accessor ), ( (Member) accessor ).getName(), optional, constraintClasses, accessor );
-        ValueConstraintsInstance valueConstraintsInstance = null;
-        if( valueConstraintsModel.isConstrained() )
-        {
-            valueConstraintsInstance = valueConstraintsModel.newInstance();
-        }
-
-        // Constraints for the NamedAssociation itself
-        valueConstraintsModel = constraintsFor( annotations.stream(), NamedAssociation.class, ( (Member) accessor ).getName(), optional, constraintClasses, accessor );
-        ValueConstraintsInstance namedValueConstraintsInstance = null;
-        if( valueConstraintsModel.isConstrained() )
-        {
-            namedValueConstraintsInstance = valueConstraintsModel.newInstance();
-        }
-        MetaInfo metaInfo = stateDeclarations.metaInfoFor( accessor );
-        return new NamedAssociationModel( accessor, valueConstraintsInstance, namedValueConstraintsInstance, metaInfo );
+        return namedAssociationsModel;
     }
 }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/92e5605a/core/runtime/src/main/java/org/apache/zest/runtime/property/PropertyModel.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/zest/runtime/property/PropertyModel.java b/core/runtime/src/main/java/org/apache/zest/runtime/property/PropertyModel.java
index 981f09d..807194f 100644
--- a/core/runtime/src/main/java/org/apache/zest/runtime/property/PropertyModel.java
+++ b/core/runtime/src/main/java/org/apache/zest/runtime/property/PropertyModel.java
@@ -38,12 +38,14 @@ import org.apache.zest.api.property.GenericPropertyInfo;
 import org.apache.zest.api.property.InvalidPropertyTypeException;
 import org.apache.zest.api.property.Property;
 import org.apache.zest.api.property.PropertyDescriptor;
-import org.apache.zest.api.structure.Module;
+import org.apache.zest.api.service.NoSuchServiceException;
 import org.apache.zest.api.structure.ModuleDescriptor;
 import org.apache.zest.api.type.Serialization;
 import org.apache.zest.api.type.ValueCompositeType;
 import org.apache.zest.api.type.ValueType;
 import org.apache.zest.api.util.Classes;
+import org.apache.zest.api.value.MissingValueSerializationException;
+import org.apache.zest.api.value.ValueDeserializer;
 import org.apache.zest.bootstrap.BindingException;
 import org.apache.zest.functional.Visitable;
 import org.apache.zest.functional.Visitor;
@@ -176,18 +178,44 @@ public class PropertyModel
         Object value = initialValue;
 
         // Check for @UseDefaults annotation
-        if( value == null && useDefaults )
+        if( useDefaults )
         {
-            if( valueType instanceof ValueCompositeType )
+            if( value == null || ( ( value instanceof String ) && ( (String) value ).length() == 0 ) )
             {
-                return module.instance().newValue( valueType().types().findFirst().orElse( null ) );
+                if( valueType instanceof ValueCompositeType )
+                {
+                    Class<?> propertyType = valueType().types().findFirst().orElse( null );
+                    value = module.instance().newValue( propertyType );
+                }
+                else
+                {
+                    value = DefaultValues.getDefaultValueOf( type );
+                }
             }
             else
             {
-                value = DefaultValues.getDefaultValueOf( type );
+                Class<?> propertyType = valueType().types().findFirst().orElse( null );
+                if( value instanceof String && !propertyType.equals( String.class ) )
+                {
+                    try
+                    {
+                        // here we could possibly deserialize json to other types...
+                        ValueDeserializer deserializer = module.instance()
+                            .serviceFinder()
+                            .findService( ValueDeserializer.class )
+                            .get();
+                        if( deserializer != null )
+                        {
+                            value = deserializer.deserialize( module, propertyType ).apply( (String) value );
+                        }
+                    }
+                    catch( NoSuchServiceException e )
+                    {
+                        throw new MissingValueSerializationException( "@UseDefaults with initialization value requires that there is a visible ValueDeserializer service available.", e);
+                    }
+                }
             }
         }
-
         return value;
     }
 

http://git-wip-us.apache.org/repos/asf/zest-java/blob/92e5605a/core/runtime/src/test/java/org/apache/zest/runtime/defaults/UseDefaultsTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/zest/runtime/defaults/UseDefaultsTest.java b/core/runtime/src/test/java/org/apache/zest/runtime/defaults/UseDefaultsTest.java
index 4354a2d..9f9ac92 100644
--- a/core/runtime/src/test/java/org/apache/zest/runtime/defaults/UseDefaultsTest.java
+++ b/core/runtime/src/test/java/org/apache/zest/runtime/defaults/UseDefaultsTest.java
@@ -20,15 +20,20 @@
 
 package org.apache.zest.runtime.defaults;
 
-import org.junit.Test;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
 import org.apache.zest.api.common.Optional;
 import org.apache.zest.api.common.UseDefaults;
 import org.apache.zest.api.composite.TransientBuilder;
 import org.apache.zest.api.composite.TransientComposite;
 import org.apache.zest.api.property.Property;
+import org.apache.zest.api.value.ValueDeserializer;
 import org.apache.zest.bootstrap.AssemblyException;
 import org.apache.zest.bootstrap.ModuleAssembly;
 import org.apache.zest.test.AbstractZestTest;
+import org.apache.zest.valueserialization.orgjson.OrgJsonValueDeserializer;
+import org.junit.Test;
 
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.nullValue;
@@ -44,7 +49,8 @@ public class UseDefaultsTest
         throws AssemblyException
     {
         module.transients( TestComposite.class );
-        module.forMixin( TestComposite.class ).declareDefaults().assemblyString();
+        module.services( ValueDeserializer.class ).withMixins( OrgJsonValueDeserializer.class );
+        module.forMixin( TestComposite.class ).declareDefaults().assemblyString().set( "habba" );
     }
 
     @Test
@@ -57,7 +63,22 @@ public class UseDefaultsTest
         assertThat( "zeroInt is zero", testComposite.defaultInt().get(), equalTo( 0 ) );
         assertThat( "nullString is null", testComposite.nullString().get(), nullValue() );
         assertThat( "defaultString is empty string", testComposite.defaultString().get(), equalTo( "" ) );
-        assertThat( "assemblyString is empty string", testComposite.assemblyString().get(), equalTo( "" ) );
+        assertThat( "assemblyString is empty string", testComposite.assemblyString().get(), equalTo( "habba" ) );
+    }
+
+    @Test
+    public void givenPropertyWithValuedUseDefaultsWhenInstantiatedExpectCorrectDefaultValues()
+    {
+        TransientBuilder<TestComposite> builder = transientBuilderFactory.newTransientBuilder( TestComposite.class );
+        TestComposite testComposite = builder.newInstance();
+
+        assertThat( testComposite.initializedStringDefault().get(), equalTo( "abc" ) );
+        assertThat( testComposite.initializedIntegerDefaultValue().get(), equalTo( 123 ) );
+        assertThat( testComposite.initializedFloatDefaultValue().get(), equalTo( 123.45f ) );
+        List<String> expectedList = Collections.singletonList( "abcde" );
+//        assertThat( testComposite.initializedStringListDefultString().get(), equalTo( expectedList) );
+        Map<String, Integer> expectedMap = Collections.singletonMap( "abcd", 345 );
+//        assertThat( testComposite.initializedMapDefaultValue().get(), equalTo( expectedMap) );
     }
 
     interface TestComposite
@@ -78,5 +99,22 @@ public class UseDefaultsTest
         Property<String> defaultString();
 
         Property<String> assemblyString();
+
+        @UseDefaults( "abc" )
+        Property<String> initializedStringDefault();
+
+        @UseDefaults( "123" )
+        Property<Integer> initializedIntegerDefaultValue();
+
+        @UseDefaults( "123.45" )
+        Property<Float> initializedFloatDefaultValue();
+
+// TODO: Seems that OrgJsonValueDeserializer has problem with arrays.
+//        @UseDefaults( "[\"abcde\"]" )
+//        Property<List<String>> initializedStringListDefultString();
+
+// TODO: Seems that OrgJsonValueDeserializer has problem with arrays.
+//        @UseDefaults( "{\"abcd\" : 345 }" )
+//        Property<Map<String, Integer>> initializedMapDefaultValue();
     }
 }

http://git-wip-us.apache.org/repos/asf/zest-java/blob/92e5605a/core/spi/src/main/java/org/apache/zest/spi/value/ValueDeserializerAdapter.java
----------------------------------------------------------------------
diff --git a/core/spi/src/main/java/org/apache/zest/spi/value/ValueDeserializerAdapter.java b/core/spi/src/main/java/org/apache/zest/spi/value/ValueDeserializerAdapter.java
index b46c27a..a3c72e1 100644
--- a/core/spi/src/main/java/org/apache/zest/spi/value/ValueDeserializerAdapter.java
+++ b/core/spi/src/main/java/org/apache/zest/spi/value/ValueDeserializerAdapter.java
@@ -188,12 +188,6 @@ public abstract class ValueDeserializerAdapter<InputType, InputNodeType>
         return input -> deserialize( module, valueType, input );
     }
 
-//    @Override
-//    public final <T> BiFunction<ValueType, String, T> deserialize()
-//    {
-//        return this::deserialize;
-//    }
-
     @Override
     public final <T> T deserialize( ModuleDescriptor module, Class<?> type, String input )
         throws ValueSerializationException
@@ -270,7 +264,8 @@ public abstract class ValueDeserializerAdapter<InputType, InputNodeType>
     {
         final Class<?> type = valueType.types().findFirst().orElse( null );
         // Plain ValueType
-        if( deserializers.get( type ) != null )
+        Function<Object, Object> deserializationFunction = deserializers.get( type );
+        if( deserializationFunction != null )
         {
             Scanner scanner = new Scanner( input, UTF_8 ).useDelimiter( "\\A" );
             if( !scanner.hasNext() )
@@ -278,7 +273,7 @@ public abstract class ValueDeserializerAdapter<InputType, InputNodeType>
                 return String.class.equals( type ) ? (T) "" : null;
             }
             String string = scanner.next();
-            return (T) deserializers.get( type ).apply( string );
+            return (T) deserializationFunction.apply( string );
         }
         else // Array ValueType
             if( type.isArray() )


Mime
View raw message