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 2015/04/24 08:36:55 UTC
[42/50] [abbrv] zest-qi4j git commit: QI-413
UnitOfWork::newEntityBuilderWithState()
QI-413 UnitOfWork::newEntityBuilderWithState()
Project: http://git-wip-us.apache.org/repos/asf/zest-qi4j/repo
Commit: http://git-wip-us.apache.org/repos/asf/zest-qi4j/commit/355ea47d
Tree: http://git-wip-us.apache.org/repos/asf/zest-qi4j/tree/355ea47d
Diff: http://git-wip-us.apache.org/repos/asf/zest-qi4j/diff/355ea47d
Branch: refs/heads/master
Commit: 355ea47da44f7d4e22133f06cd742f1fe4a12f39
Parents: 118928a
Author: Paul Merlin <pa...@nosphere.org>
Authored: Wed Mar 25 16:02:13 2015 +0100
Committer: Paul Merlin <pa...@nosphere.org>
Committed: Wed Mar 25 16:02:13 2015 +0100
----------------------------------------------------------------------
.../org/qi4j/api/unitofwork/UnitOfWork.java | 60 +++++++-
.../composite/FunctionStateResolver.java | 71 +++++++++
.../qi4j/runtime/composite/StateResolver.java | 36 +++++
.../qi4j/runtime/entity/EntityStateModel.java | 2 +-
.../qi4j/runtime/structure/ModuleInstance.java | 87 ++++-------
.../runtime/structure/ModuleUnitOfWork.java | 109 ++++++++++++--
.../unitofwork/EntityBuilderInstance.java | 50 ++++++-
.../runtime/value/ValueBuilderInstance.java | 3 +-
.../runtime/value/ValueBuilderWithState.java | 19 ++-
.../qi4j/runtime/value/ValueStateInstance.java | 4 +-
.../org/qi4j/runtime/value/ValueStateModel.java | 21 +--
.../entity/EntityBuilderWithStateTest.java | 148 +++++++++++++++++++
12 files changed, 510 insertions(+), 100 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/355ea47d/core/api/src/main/java/org/qi4j/api/unitofwork/UnitOfWork.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/unitofwork/UnitOfWork.java b/core/api/src/main/java/org/qi4j/api/unitofwork/UnitOfWork.java
index a0ea959..e17bc07 100644
--- a/core/api/src/main/java/org/qi4j/api/unitofwork/UnitOfWork.java
+++ b/core/api/src/main/java/org/qi4j/api/unitofwork/UnitOfWork.java
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2007-2011, Rickard Öberg. All Rights Reserved.
* Copyright (c) 2007-2012, Niclas Hedhman. All Rights Reserved.
- * Copyright (c) 2013-2014, Paul Merlin. All Rights Reserved.
+ * Copyright (c) 2013-2015, Paul Merlin. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,13 +15,18 @@
*/
package org.qi4j.api.unitofwork;
+import java.util.Map;
+import org.qi4j.api.association.AssociationDescriptor;
import org.qi4j.api.composite.AmbiguousTypeException;
import org.qi4j.api.entity.EntityBuilder;
+import org.qi4j.api.entity.EntityReference;
import org.qi4j.api.entity.LifecycleException;
+import org.qi4j.api.property.PropertyDescriptor;
import org.qi4j.api.query.Query;
import org.qi4j.api.query.QueryBuilder;
import org.qi4j.api.structure.MetaInfoHolder;
import org.qi4j.api.usecase.Usecase;
+import org.qi4j.functional.Function;
/**
* All operations on entities goes through an UnitOfWork.
@@ -178,6 +183,59 @@ public interface UnitOfWork extends MetaInfoHolder, AutoCloseable
throws EntityTypeNotFoundException, AmbiguousTypeException;
/**
+ * Create a new EntityBuilder for an EntityComposite wich implements the given mixin type starting with the given
+ * state.
+ * <p>
+ * An EntityComposite will be chosen according to what has been registered and the visibility rules for Modules and
+ * Layers will be considered.
+ *
+ * @param <T> Entity type
+ * @param type Entity type
+ * @param propertyFunction a function providing the state of properties
+ * @param associationFunction a function providing the state of associations
+ * @param manyAssociationFunction a function providing the state of many associations
+ * @param namedAssociationFunction a function providing the state of named associations
+ *
+ * @return a new EntityBuilder starting with the given state
+ *
+ * @throws EntityTypeNotFoundException if no EntityComposite type of the given mixin type has been registered
+ * @throws AmbiguousTypeException If several mixins implement the given type
+ */
+ <T> EntityBuilder<T> newEntityBuilderWithState( Class<T> type,
+ Function<PropertyDescriptor, Object> propertyFunction,
+ Function<AssociationDescriptor, EntityReference> associationFunction,
+ Function<AssociationDescriptor, Iterable<EntityReference>> manyAssociationFunction,
+ Function<AssociationDescriptor, Map<String, EntityReference>> namedAssociationFunction )
+ throws EntityTypeNotFoundException, AmbiguousTypeException;
+
+ /**
+ * Create a new EntityBuilder for an EntityComposite wich implements the given mixin type starting with the given
+ * state.
+ * <p>
+ * An EntityComposite will be chosen according to what has been registered and the visibility rules for Modules and
+ * Layers will be considered.
+ *
+ * @param <T> Entity type
+ * @param type Entity type
+ * @param identity the identity of the new Entity
+ * @param propertyFunction a function providing the state of properties
+ * @param associationFunction a function providing the state of associations
+ * @param manyAssociationFunction a function providing the state of many associations
+ * @param namedAssociationFunction a function providing the state of named associations
+ *
+ * @return a new EntityBuilder starting with the given state
+ *
+ * @throws EntityTypeNotFoundException If no mixins implements the given type
+ * @throws AmbiguousTypeException If several mixins implement the given type
+ */
+ <T> EntityBuilder<T> newEntityBuilderWithState( Class<T> type, String identity,
+ Function<PropertyDescriptor, Object> propertyFunction,
+ Function<AssociationDescriptor, EntityReference> associationFunction,
+ Function<AssociationDescriptor, Iterable<EntityReference>> manyAssociationFunction,
+ Function<AssociationDescriptor, Map<String, EntityReference>> namedAssociationFunction )
+ throws EntityTypeNotFoundException, AmbiguousTypeException;
+
+ /**
* Find an Entity of the given mixin type with the give identity. This
* method verifies that it exists by asking the underlying EntityStore.
*
http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/355ea47d/core/runtime/src/main/java/org/qi4j/runtime/composite/FunctionStateResolver.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/composite/FunctionStateResolver.java b/core/runtime/src/main/java/org/qi4j/runtime/composite/FunctionStateResolver.java
new file mode 100644
index 0000000..284929d
--- /dev/null
+++ b/core/runtime/src/main/java/org/qi4j/runtime/composite/FunctionStateResolver.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012, Kent Sølvsten.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.qi4j.runtime.composite;
+
+import java.util.List;
+import java.util.Map;
+import org.qi4j.api.association.AssociationDescriptor;
+import org.qi4j.api.entity.EntityReference;
+import org.qi4j.api.property.PropertyDescriptor;
+import org.qi4j.functional.Function;
+import org.qi4j.functional.Iterables;
+
+/**
+ * Function based StateResolver.
+ */
+public class FunctionStateResolver
+ implements StateResolver
+{
+ final Function<PropertyDescriptor, Object> propertyFunction;
+ final Function<AssociationDescriptor, EntityReference> associationFunction;
+ final Function<AssociationDescriptor, Iterable<EntityReference>> manyAssociationFunction;
+ final Function<AssociationDescriptor, Map<String, EntityReference>> namedAssociationFunction;
+
+ public FunctionStateResolver( Function<PropertyDescriptor, Object> propertyFunction,
+ Function<AssociationDescriptor, EntityReference> associationFunction,
+ Function<AssociationDescriptor, Iterable<EntityReference>> manyAssociationFunction,
+ Function<AssociationDescriptor, Map<String, EntityReference>> namedAssociationFunction )
+ {
+ this.propertyFunction = propertyFunction;
+ this.associationFunction = associationFunction;
+ this.manyAssociationFunction = manyAssociationFunction;
+ this.namedAssociationFunction = namedAssociationFunction;
+ }
+
+ @Override
+ public Object getPropertyState( PropertyDescriptor propertyDescriptor )
+ {
+ return propertyFunction.map( propertyDescriptor );
+ }
+
+ @Override
+ public EntityReference getAssociationState( AssociationDescriptor associationDescriptor )
+ {
+ return associationFunction.map( associationDescriptor );
+ }
+
+ @Override
+ public List<EntityReference> getManyAssociationState( AssociationDescriptor associationDescriptor )
+ {
+ return Iterables.toList( manyAssociationFunction.map( associationDescriptor ) );
+ }
+
+ @Override
+ public Map<String, EntityReference> getNamedAssociationState( AssociationDescriptor associationDescriptor )
+ {
+ return namedAssociationFunction.map( associationDescriptor );
+ }
+}
http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/355ea47d/core/runtime/src/main/java/org/qi4j/runtime/composite/StateResolver.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/composite/StateResolver.java b/core/runtime/src/main/java/org/qi4j/runtime/composite/StateResolver.java
new file mode 100644
index 0000000..1f7072a
--- /dev/null
+++ b/core/runtime/src/main/java/org/qi4j/runtime/composite/StateResolver.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, Kent Sølvsten.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.qi4j.runtime.composite;
+
+import java.util.List;
+import java.util.Map;
+import org.qi4j.api.association.AssociationDescriptor;
+import org.qi4j.api.entity.EntityReference;
+import org.qi4j.api.property.PropertyDescriptor;
+
+/**
+ * StateResolver.
+ */
+public interface StateResolver
+{
+ Object getPropertyState( PropertyDescriptor propertyDescriptor );
+
+ EntityReference getAssociationState( AssociationDescriptor associationDescriptor );
+
+ List<EntityReference> getManyAssociationState( AssociationDescriptor associationDescriptor );
+
+ Map<String, EntityReference> getNamedAssociationState( AssociationDescriptor associationDescriptor );
+}
http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/355ea47d/core/runtime/src/main/java/org/qi4j/runtime/entity/EntityStateModel.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/entity/EntityStateModel.java b/core/runtime/src/main/java/org/qi4j/runtime/entity/EntityStateModel.java
index 20d397e..5fae1a2 100644
--- a/core/runtime/src/main/java/org/qi4j/runtime/entity/EntityStateModel.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/entity/EntityStateModel.java
@@ -129,7 +129,7 @@ public final class EntityStateModel
}
@Override
- public Iterable<? extends AssociationDescriptor> namedAssociations()
+ public Iterable<NamedAssociationModel> namedAssociations()
{
return namedAssociationsModel.namedAssociations();
}
http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/355ea47d/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleInstance.java b/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleInstance.java
index 551999e..c009c75 100644
--- a/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleInstance.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleInstance.java
@@ -1,7 +1,8 @@
/*
* Copyright (c) 2008-2012, Rickard Öberg. All Rights Reserved.
+ * Copyright (c) 2012, Kent Sølvsten. All Rights Reserved.
* Copyright (c) 2008-2013, Niclas Hedhman. All Rights Reserved.
- * Copyright (c) 2012-2014, Paul Merlin. All Rights Reserved.
+ * Copyright (c) 2012-2015, Paul Merlin. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -67,6 +68,7 @@ import org.qi4j.functional.Function2;
import org.qi4j.functional.Specification;
import org.qi4j.functional.Specifications;
import org.qi4j.runtime.activation.ActivationDelegate;
+import org.qi4j.runtime.composite.FunctionStateResolver;
import org.qi4j.runtime.composite.TransientBuilderInstance;
import org.qi4j.runtime.composite.TransientModel;
import org.qi4j.runtime.composite.TransientStateInstance;
@@ -86,12 +88,12 @@ import org.qi4j.runtime.service.ImportedServicesModel;
import org.qi4j.runtime.service.ServicesInstance;
import org.qi4j.runtime.service.ServicesModel;
import org.qi4j.runtime.unitofwork.UnitOfWorkInstance;
+import org.qi4j.runtime.composite.StateResolver;
import org.qi4j.runtime.value.ValueBuilderInstance;
import org.qi4j.runtime.value.ValueBuilderWithPrototype;
import org.qi4j.runtime.value.ValueBuilderWithState;
import org.qi4j.runtime.value.ValueInstance;
import org.qi4j.runtime.value.ValueModel;
-import org.qi4j.runtime.value.ValueStateModel;
import org.qi4j.runtime.value.ValuesModel;
import org.qi4j.spi.entitystore.EntityStore;
import org.qi4j.spi.metrics.MetricsProviderAdapter;
@@ -113,7 +115,6 @@ import static org.qi4j.functional.Iterables.toList;
public class ModuleInstance
implements Module, Activation
{
-
// Constructor parameters
private final ModuleModel model;
private final LayerInstance layer;
@@ -350,7 +351,7 @@ public class ModuleInstance
throw new NoSuchValueException( mixinType.getName(), name() );
}
- ValueStateModel.StateResolver stateResolver = new InitialStateResolver( compositeModelModule.module() );
+ StateResolver stateResolver = new InitialStateResolver( compositeModelModule.module() );
return new ValueBuilderInstance<>( compositeModelModule, this, stateResolver );
}
@@ -373,14 +374,15 @@ public class ModuleInstance
throw new NoSuchValueException( mixinType.getName(), name() );
}
- ValueStateModel.StateResolver stateResolver = new FunctionStateResolver( propertyFunction, associationFunction, manyAssociationFunction, namedAssociationFunction );
+ StateResolver stateResolver = new FunctionStateResolver(
+ propertyFunction, associationFunction, manyAssociationFunction, namedAssociationFunction
+ );
return new ValueBuilderWithState<>( compositeModelModule, this, stateResolver );
}
private static class InitialStateResolver
- implements ValueStateModel.StateResolver
+ implements StateResolver
{
-
private final ModuleInstance module;
private InitialStateResolver( ModuleInstance module )
@@ -411,53 +413,6 @@ public class ModuleInstance
{
return new HashMap<>();
}
-
- }
-
- private static class FunctionStateResolver
- implements ValueStateModel.StateResolver
- {
-
- private final Function<PropertyDescriptor, Object> propertyFunction;
- private final Function<AssociationDescriptor, EntityReference> associationFunction;
- private final Function<AssociationDescriptor, Iterable<EntityReference>> manyAssociationFunction;
- private final Function<AssociationDescriptor, Map<String, EntityReference>> namedAssociationFunction;
-
- private FunctionStateResolver( Function<PropertyDescriptor, Object> propertyFunction,
- Function<AssociationDescriptor, EntityReference> associationFunction,
- Function<AssociationDescriptor, Iterable<EntityReference>> manyAssociationFunction,
- Function<AssociationDescriptor, Map<String, EntityReference>> namedAssociationFunction )
- {
- this.propertyFunction = propertyFunction;
- this.associationFunction = associationFunction;
- this.manyAssociationFunction = manyAssociationFunction;
- this.namedAssociationFunction = namedAssociationFunction;
- }
-
- @Override
- public Object getPropertyState( PropertyDescriptor propertyDescriptor )
- {
- return propertyFunction.map( propertyDescriptor );
- }
-
- @Override
- public EntityReference getAssociationState( AssociationDescriptor associationDescriptor )
- {
- return associationFunction.map( associationDescriptor );
- }
-
- @Override
- public List<EntityReference> getManyAssociationState( AssociationDescriptor associationDescriptor )
- {
- return toList( manyAssociationFunction.map( associationDescriptor ) );
- }
-
- @Override
- public Map<String, EntityReference> getNamedAssociationState( AssociationDescriptor associationDescriptor )
- {
- return namedAssociationFunction.map( associationDescriptor );
- }
-
}
@Override
@@ -792,8 +747,12 @@ public class ModuleInstance
if( iter.hasNext() )
{
// Ambiguous exception
- throw new ClassNotFoundException( name, new AmbiguousTypeException(
- "More than one model matches the classname " + name + ":" + toList( moduleModels ) ) );
+ throw new ClassNotFoundException(
+ name,
+ new AmbiguousTypeException(
+ "More than one model matches the classname " + name + ":" + toList( moduleModels )
+ )
+ );
}
}
}
@@ -819,8 +778,11 @@ public class ModuleInstance
if( iter.hasNext() )
{
// Ambiguous exception
- throw new ClassNotFoundException( name, new AmbiguousTypeException(
- "More than one model matches the classname " + name + ":" + toList( layerModels ) ) );
+ throw new ClassNotFoundException(
+ name,
+ new AmbiguousTypeException(
+ "More than one model matches the classname " + name + ":" + toList( layerModels ) )
+ );
}
}
}
@@ -842,8 +804,12 @@ public class ModuleInstance
if( iter.hasNext() )
{
// Ambiguous exception
- throw new ClassNotFoundException( name, new AmbiguousTypeException(
- "More than one model matches the classname " + name + ":" + toList( usedLayersModels ) ) );
+ throw new ClassNotFoundException(
+ name,
+ new AmbiguousTypeException(
+ "More than one model matches the classname " + name + ":" + toList( usedLayersModels )
+ )
+ );
}
}
}
@@ -858,5 +824,4 @@ public class ModuleInstance
return clazz;
}
}
-
}
http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/355ea47d/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleUnitOfWork.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleUnitOfWork.java b/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleUnitOfWork.java
index bdadb75..dd1a830 100644
--- a/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleUnitOfWork.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/structure/ModuleUnitOfWork.java
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2009, Rickard Öberg. All Rights Reserved.
* Copyright (c) 2013, Niclas Hedhman. All Rights Reserved.
- * Copyright (c) 2013, Paul Merlin. All Rights Reserved.
+ * Copyright (c) 2013-2015, Paul Merlin. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,12 +18,16 @@ package org.qi4j.runtime.structure;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
+import org.qi4j.api.association.AssociationDescriptor;
+import org.qi4j.api.common.QualifiedName;
import org.qi4j.api.composite.Composite;
import org.qi4j.api.entity.EntityBuilder;
import org.qi4j.api.entity.EntityComposite;
import org.qi4j.api.entity.EntityReference;
+import org.qi4j.api.entity.Identity;
import org.qi4j.api.entity.IdentityGenerator;
import org.qi4j.api.entity.LifecycleException;
+import org.qi4j.api.property.PropertyDescriptor;
import org.qi4j.api.query.Query;
import org.qi4j.api.query.QueryBuilder;
import org.qi4j.api.query.QueryExecutionException;
@@ -37,12 +41,18 @@ import org.qi4j.api.unitofwork.UnitOfWorkCallback;
import org.qi4j.api.unitofwork.UnitOfWorkCompletionException;
import org.qi4j.api.unitofwork.UnitOfWorkFactory;
import org.qi4j.api.usecase.Usecase;
+import org.qi4j.api.util.NullArgumentException;
+import org.qi4j.functional.Function;
import org.qi4j.functional.Iterables;
import org.qi4j.functional.Specification;
+import org.qi4j.runtime.composite.FunctionStateResolver;
import org.qi4j.runtime.entity.EntityInstance;
import org.qi4j.runtime.entity.EntityModel;
+import org.qi4j.runtime.property.PropertyModel;
import org.qi4j.runtime.unitofwork.EntityBuilderInstance;
import org.qi4j.runtime.unitofwork.UnitOfWorkInstance;
+import org.qi4j.runtime.composite.StateResolver;
+import org.qi4j.runtime.value.ValueStateModel;
import org.qi4j.spi.entity.EntityStatus;
import org.qi4j.spi.entitystore.EntityStore;
import org.qi4j.spi.query.EntityFinder;
@@ -59,20 +69,20 @@ import static org.qi4j.functional.Iterables.first;
public class ModuleUnitOfWork
implements UnitOfWork
{
-// private static final QualifiedName IDENTITY_STATE_NAME;
-//
-// static
-// {
-// try
-// {
-// IDENTITY_STATE_NAME = QualifiedName.fromAccessor( Identity.class.getMethod( "identity" ) );
-// }
-// catch( NoSuchMethodException e )
-// {
-// throw new InternalError( "Qi4j Core Runtime codebase is corrupted. Contact Qi4j team: ModuleUnitOfWork" );
-// }
-// }
-//
+ private static final QualifiedName IDENTITY_STATE_NAME;
+
+ static
+ {
+ try
+ {
+ IDENTITY_STATE_NAME = QualifiedName.fromAccessor( Identity.class.getMethod( "identity" ) );
+ }
+ catch( NoSuchMethodException e )
+ {
+ throw new InternalError( "Qi4j Core Runtime codebase is corrupted. Contact Qi4j team: ModuleUnitOfWork" );
+ }
+ }
+
private final UnitOfWorkInstance uow;
private final ModuleInstance moduleInstance;
@@ -185,6 +195,75 @@ public class ModuleUnitOfWork
}
@Override
+ public <T> EntityBuilder<T> newEntityBuilderWithState(
+ Class<T> type,
+ Function<PropertyDescriptor, Object> propertyFunction,
+ Function<AssociationDescriptor, EntityReference> associationFunction,
+ Function<AssociationDescriptor, Iterable<EntityReference>> manyAssociationFunction,
+ Function<AssociationDescriptor, Map<String, EntityReference>> namedAssociationFunction
+ )
+ throws EntityTypeNotFoundException
+ {
+ return newEntityBuilderWithState( type, null,
+ propertyFunction,
+ associationFunction,
+ manyAssociationFunction,
+ namedAssociationFunction );
+ }
+
+ @Override
+ public <T> EntityBuilder<T> newEntityBuilderWithState(
+ Class<T> type, String identity,
+ Function<PropertyDescriptor, Object> propertyFunction,
+ Function<AssociationDescriptor, EntityReference> associationFunction,
+ Function<AssociationDescriptor, Iterable<EntityReference>> manyAssociationFunction,
+ Function<AssociationDescriptor, Map<String, EntityReference>> namedAssociationFunction
+ )
+ throws EntityTypeNotFoundException
+ {
+ NullArgumentException.validateNotNull( "propertyFunction", propertyFunction );
+ NullArgumentException.validateNotNull( "associationFunction", associationFunction );
+ NullArgumentException.validateNotNull( "manyAssociationFunction", manyAssociationFunction );
+ NullArgumentException.validateNotNull( "namedAssociationFunction", namedAssociationFunction );
+
+ ModelModule<EntityModel> model = moduleInstance.typeLookup().lookupEntityModel( type );
+
+ if( model == null )
+ {
+ throw new EntityTypeNotFoundException( type.getName() );
+ }
+
+ EntityStore entityStore = model.module().entityStore();
+
+ StateResolver stateResolver = new FunctionStateResolver(
+ propertyFunction, associationFunction, manyAssociationFunction, namedAssociationFunction
+ );
+
+ if( identity == null )
+ {
+ // Use identity from StateResolver if available
+ PropertyModel identityModel = model.model().state().findPropertyModelByQualifiedName( IDENTITY_STATE_NAME );
+ identity = (String) stateResolver.getPropertyState( identityModel );
+ if( identity == null )
+ {
+ // Generate identity
+ IdentityGenerator idGen = model.module().identityGenerator();
+ if( idGen == null )
+ {
+ throw new NoSuchServiceException( IdentityGenerator.class.getName(), model.module().name() );
+ }
+ identity = idGen.generate( first( model.model().types() ) );
+ }
+ }
+
+ return new EntityBuilderInstance<>( model,
+ this,
+ uow.getEntityStoreUnitOfWork( entityStore, moduleInstance ),
+ identity,
+ stateResolver );
+ }
+
+ @Override
public <T> T get( Class<T> type, String identity )
throws EntityTypeNotFoundException, NoSuchEntityException
{
http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/355ea47d/core/runtime/src/main/java/org/qi4j/runtime/unitofwork/EntityBuilderInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/unitofwork/EntityBuilderInstance.java b/core/runtime/src/main/java/org/qi4j/runtime/unitofwork/EntityBuilderInstance.java
index 74d1cf2..8bb0ffd 100644
--- a/core/runtime/src/main/java/org/qi4j/runtime/unitofwork/EntityBuilderInstance.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/unitofwork/EntityBuilderInstance.java
@@ -1,5 +1,8 @@
/*
- * Copyright (c) 2007, Rickard Öberg. All Rights Reserved.
+ * Copyright (c) 2007-2009, Rickard Öberg. All Rights Reserved.
+ * Copyright (c) 2008, Alin Dreghiciu. All Rights Reserved.
+ * Copyright (c) 2008, Edward Yakop. All Rights Reserved.
+ * Copyright (c) 2014-2015, Paul Merlin. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,15 +16,22 @@
*/
package org.qi4j.runtime.unitofwork;
+import java.util.Map;
+import org.qi4j.api.association.AssociationDescriptor;
import org.qi4j.api.common.QualifiedName;
import org.qi4j.api.entity.EntityBuilder;
import org.qi4j.api.entity.EntityReference;
import org.qi4j.api.entity.Identity;
import org.qi4j.api.entity.LifecycleException;
+import org.qi4j.api.property.PropertyDescriptor;
+import org.qi4j.runtime.association.ManyAssociationModel;
+import org.qi4j.runtime.association.NamedAssociationModel;
import org.qi4j.runtime.entity.EntityInstance;
import org.qi4j.runtime.entity.EntityModel;
import org.qi4j.runtime.structure.ModelModule;
import org.qi4j.runtime.structure.ModuleUnitOfWork;
+import org.qi4j.runtime.composite.StateResolver;
+import org.qi4j.runtime.value.ValueStateModel;
import org.qi4j.spi.entity.EntityState;
import org.qi4j.spi.entitystore.EntityStoreUnitOfWork;
@@ -61,6 +71,17 @@ public final class EntityBuilderInstance<T>
String identity
)
{
+ this( model, uow, store, identity, null );
+ }
+
+ public EntityBuilderInstance(
+ ModelModule<EntityModel> model,
+ ModuleUnitOfWork uow,
+ EntityStoreUnitOfWork store,
+ String identity,
+ StateResolver stateResolver
+ )
+ {
this.model = model;
this.uow = uow;
this.store = store;
@@ -68,6 +89,33 @@ public final class EntityBuilderInstance<T>
EntityReference reference = new EntityReference( identity );
entityState = new BuilderEntityState( model.model(), reference );
model.model().initState( model.module(), entityState );
+ if( stateResolver != null )
+ {
+ for( PropertyDescriptor propDesc : model.model().state().properties() )
+ {
+ Object value = stateResolver.getPropertyState( propDesc );
+ entityState.setPropertyValue( propDesc.qualifiedName(), value );
+ }
+ for( AssociationDescriptor assDesc : model.model().state().associations() )
+ {
+ EntityReference ref = stateResolver.getAssociationState( assDesc );
+ entityState.setAssociationValue( assDesc.qualifiedName(), ref );
+ }
+ for( ManyAssociationModel manyAssDesc : model.model().state().manyAssociations() )
+ {
+ for( EntityReference ref : stateResolver.getManyAssociationState( manyAssDesc ) )
+ {
+ entityState.manyAssociationValueOf( manyAssDesc.qualifiedName() ).add( 0, ref );
+ }
+ }
+ for( NamedAssociationModel namedAssDesc : model.model().state().namedAssociations() )
+ {
+ for( Map.Entry<String, EntityReference> entry : stateResolver.getNamedAssociationState( namedAssDesc ).entrySet() )
+ {
+ entityState.namedAssociationValueOf( namedAssDesc.qualifiedName() ).put( entry.getKey(), entry.getValue() );
+ }
+ }
+ }
entityState.setPropertyValue( IDENTITY_STATE_NAME, identity );
prototypeInstance = model.model().newInstance( uow, model.module(), entityState );
}
http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/355ea47d/core/runtime/src/main/java/org/qi4j/runtime/value/ValueBuilderInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/value/ValueBuilderInstance.java b/core/runtime/src/main/java/org/qi4j/runtime/value/ValueBuilderInstance.java
index f1f59de..0d70463 100644
--- a/core/runtime/src/main/java/org/qi4j/runtime/value/ValueBuilderInstance.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/value/ValueBuilderInstance.java
@@ -18,6 +18,7 @@ import org.qi4j.api.common.ConstructionException;
import org.qi4j.api.composite.Composite;
import org.qi4j.api.value.NoSuchValueException;
import org.qi4j.api.value.ValueBuilder;
+import org.qi4j.runtime.composite.StateResolver;
import org.qi4j.runtime.structure.ModelModule;
import org.qi4j.runtime.structure.ModuleInstance;
@@ -33,7 +34,7 @@ public final class ValueBuilderInstance<T>
private final ModuleInstance currentModule;
private final ValueInstance prototypeInstance;
- public ValueBuilderInstance( ModelModule<ValueModel> compositeModelModule, ModuleInstance currentModule, ValueStateModel.StateResolver stateResolver )
+ public ValueBuilderInstance( ModelModule<ValueModel> compositeModelModule, ModuleInstance currentModule, StateResolver stateResolver )
{
ValueStateInstance state = new ValueStateInstance( compositeModelModule, currentModule, stateResolver );
prototypeInstance = compositeModelModule.model().newValueInstance( compositeModelModule.module(), state );
http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/355ea47d/core/runtime/src/main/java/org/qi4j/runtime/value/ValueBuilderWithState.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/value/ValueBuilderWithState.java b/core/runtime/src/main/java/org/qi4j/runtime/value/ValueBuilderWithState.java
index d5ed565..ec1f7b3 100644
--- a/core/runtime/src/main/java/org/qi4j/runtime/value/ValueBuilderWithState.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/value/ValueBuilderWithState.java
@@ -1,8 +1,22 @@
+/*
+ * Copyright (c) 2012, Kent Sølvsten. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
package org.qi4j.runtime.value;
import org.qi4j.api.association.AssociationStateHolder;
import org.qi4j.api.common.ConstructionException;
import org.qi4j.api.value.ValueBuilder;
+import org.qi4j.runtime.composite.StateResolver;
import org.qi4j.runtime.structure.ModelModule;
import org.qi4j.runtime.structure.ModuleInstance;
@@ -11,7 +25,10 @@ public class ValueBuilderWithState<T> implements ValueBuilder<T>
private final ModelModule<ValueModel> model;
private ValueInstance prototypeInstance;
- public ValueBuilderWithState( ModelModule<ValueModel> compositeModelModule, ModuleInstance currentModule, ValueStateModel.StateResolver stateResolver ) {
+ public ValueBuilderWithState( ModelModule<ValueModel> compositeModelModule,
+ ModuleInstance currentModule,
+ StateResolver stateResolver )
+ {
ValueStateInstance state = new ValueStateInstance( compositeModelModule, currentModule, stateResolver );
ValueInstance instance = compositeModelModule.model().newValueInstance( compositeModelModule.module(), state );
instance.prepareToBuild();
http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/355ea47d/core/runtime/src/main/java/org/qi4j/runtime/value/ValueStateInstance.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/value/ValueStateInstance.java b/core/runtime/src/main/java/org/qi4j/runtime/value/ValueStateInstance.java
index 660e2e2..68dd5c7 100644
--- a/core/runtime/src/main/java/org/qi4j/runtime/value/ValueStateInstance.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/value/ValueStateInstance.java
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2008-2011, Rickard Öberg. All Rights Reserved.
* Copyright (c) 2008-2013, Niclas Hedhman. All Rights Reserved.
+ * Copyright (c) 2012, Kent Sølvsten. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,6 +35,7 @@ import org.qi4j.runtime.association.ManyAssociationInstance;
import org.qi4j.runtime.association.ManyAssociationModel;
import org.qi4j.runtime.association.NamedAssociationInstance;
import org.qi4j.runtime.association.NamedAssociationModel;
+import org.qi4j.runtime.composite.StateResolver;
import org.qi4j.runtime.property.PropertyInfo;
import org.qi4j.runtime.property.PropertyInstance;
import org.qi4j.runtime.property.PropertyModel;
@@ -65,7 +67,7 @@ public final class ValueStateInstance
public ValueStateInstance( ModelModule<ValueModel> compositeModelModule,
ModuleInstance currentModule,
- ValueStateModel.StateResolver stateResolver )
+ StateResolver stateResolver )
{
ValueModel valueModel = compositeModelModule.model();
this.properties = new LinkedHashMap<>();
http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/355ea47d/core/runtime/src/main/java/org/qi4j/runtime/value/ValueStateModel.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/qi4j/runtime/value/ValueStateModel.java b/core/runtime/src/main/java/org/qi4j/runtime/value/ValueStateModel.java
index 8c5ecf7..d3f8060 100644
--- a/core/runtime/src/main/java/org/qi4j/runtime/value/ValueStateModel.java
+++ b/core/runtime/src/main/java/org/qi4j/runtime/value/ValueStateModel.java
@@ -1,5 +1,7 @@
/*
- * Copyright (c) 2008-2011, Rickard Öberg. All Rights Reserved.
+ * Copyright (c) 2008-2011, Rickard Öberg.
+ * Copyright (c) 2012, Kent Sølvsten.
+ * Copyright (c) 2014-2015, Paul Merlin.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,13 +19,9 @@
*/
package org.qi4j.runtime.value;
-import java.util.List;
-import java.util.Map;
import org.qi4j.api.association.AssociationDescriptor;
import org.qi4j.api.association.AssociationStateDescriptor;
import org.qi4j.api.common.QualifiedName;
-import org.qi4j.api.entity.EntityReference;
-import org.qi4j.api.property.PropertyDescriptor;
import org.qi4j.functional.HierarchicalVisitor;
import org.qi4j.functional.VisitableHierarchy;
import org.qi4j.runtime.association.AssociationModel;
@@ -129,19 +127,6 @@ public final class ValueStateModel
}
}
}
-
return visitor.visitLeave( this );
}
-
- public interface StateResolver
- {
- public Object getPropertyState( PropertyDescriptor propertyDescriptor );
-
- public EntityReference getAssociationState( AssociationDescriptor associationDescriptor );
-
- public List<EntityReference> getManyAssociationState( AssociationDescriptor associationDescriptor );
-
- public Map<String, EntityReference> getNamedAssociationState( AssociationDescriptor associationDescriptor );
- }
-
}
http://git-wip-us.apache.org/repos/asf/zest-qi4j/blob/355ea47d/core/runtime/src/test/java/org/qi4j/runtime/entity/EntityBuilderWithStateTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/qi4j/runtime/entity/EntityBuilderWithStateTest.java b/core/runtime/src/test/java/org/qi4j/runtime/entity/EntityBuilderWithStateTest.java
new file mode 100644
index 0000000..a949419
--- /dev/null
+++ b/core/runtime/src/test/java/org/qi4j/runtime/entity/EntityBuilderWithStateTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2015 Paul Merlin.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.qi4j.runtime.entity;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+import org.junit.Test;
+import org.qi4j.api.association.Association;
+import org.qi4j.api.association.AssociationDescriptor;
+import org.qi4j.api.association.ManyAssociation;
+import org.qi4j.api.association.NamedAssociation;
+import org.qi4j.api.common.Optional;
+import org.qi4j.api.entity.EntityBuilder;
+import org.qi4j.api.entity.EntityReference;
+import org.qi4j.api.entity.Identity;
+import org.qi4j.api.property.Property;
+import org.qi4j.api.property.PropertyDescriptor;
+import org.qi4j.api.unitofwork.UnitOfWork;
+import org.qi4j.api.unitofwork.UnitOfWorkCompletionException;
+import org.qi4j.bootstrap.AssemblyException;
+import org.qi4j.bootstrap.ModuleAssembly;
+import org.qi4j.functional.Function;
+import org.qi4j.test.AbstractQi4jTest;
+import org.qi4j.test.EntityTestAssembler;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+/**
+ * EntityBuilder With State Test.
+ */
+public class EntityBuilderWithStateTest
+ extends AbstractQi4jTest
+{
+ @Override
+ public void assemble( ModuleAssembly module )
+ throws AssemblyException
+ {
+ new EntityTestAssembler().assemble( module );
+ module.entities( SomeEntity.class );
+ }
+
+ @Test
+ public void test()
+ throws UnitOfWorkCompletionException
+ {
+ final String associatedIdentity;
+ try( UnitOfWork uow = module.newUnitOfWork() )
+ {
+ EntityBuilder<SomeEntity> builder = uow.newEntityBuilder( SomeEntity.class );
+ builder.instance().prop().set( "Associated" );
+ SomeEntity entity = builder.newInstance();
+ associatedIdentity = entity.identity().get();
+ uow.complete();
+ }
+ try( UnitOfWork uow = module.newUnitOfWork() )
+ {
+ SomeEntity entity = uow.newEntityBuilderWithState(
+ SomeEntity.class,
+ new Function<PropertyDescriptor, Object>()
+ {
+ @Override
+ public Object map( PropertyDescriptor descriptor )
+ {
+ if( "prop".equals( descriptor.qualifiedName().name() ) )
+ {
+ return "Foo";
+ }
+ return null;
+ }
+ },
+ new Function<AssociationDescriptor, EntityReference>()
+ {
+ @Override
+ public EntityReference map( AssociationDescriptor descriptor )
+ {
+ if( "ass".equals( descriptor.qualifiedName().name() ) )
+ {
+ return EntityReference.parseEntityReference( associatedIdentity );
+ }
+ return null;
+ }
+ },
+ new Function<AssociationDescriptor, Iterable<EntityReference>>()
+ {
+ @Override
+ public Iterable<EntityReference> map( AssociationDescriptor descriptor )
+ {
+ if( "manyAss".equals( descriptor.qualifiedName().name() ) )
+ {
+ return Arrays.asList( EntityReference.parseEntityReference( associatedIdentity ) );
+ }
+ return null;
+ }
+ },
+ new Function<AssociationDescriptor, Map<String, EntityReference>>()
+ {
+ @Override
+ public Map<String, EntityReference> map( AssociationDescriptor descriptor )
+ {
+ if( "namedAss".equals( descriptor.qualifiedName().name() ) )
+ {
+ return Collections.singletonMap(
+ "foo",
+ EntityReference.parseEntityReference( associatedIdentity )
+ );
+ }
+ return null;
+ }
+ }
+ ).newInstance();
+ assertThat( entity.prop().get(), equalTo( "Foo" ) );
+ assertThat( entity.ass().get().identity().get(), equalTo( associatedIdentity ) );
+ assertThat( entity.manyAss().get( 0 ).identity().get(), equalTo( associatedIdentity ) );
+ assertThat( entity.namedAss().get( "foo" ).identity().get(), equalTo( associatedIdentity ) );
+ uow.complete();
+ }
+ }
+
+ public interface SomeEntity
+ extends Identity
+ {
+ Property<String> prop();
+
+ @Optional
+ Association<SomeEntity> ass();
+
+ @Optional
+ ManyAssociation<SomeEntity> manyAss();
+
+ @Optional
+ NamedAssociation<SomeEntity> namedAss();
+ }
+}