You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by ni...@apache.org on 2016/06/10 08:34:03 UTC
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.
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 <ni...@hedhman.org>
Authored: Fri Jun 10 16:05:05 2016 +0800
Committer: Niclas Hedhman <ni...@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>@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() )