| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| * |
| */ |
| |
| package org.apache.polygene.runtime.value; |
| |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.function.BiFunction; |
| import org.apache.polygene.api.association.ManyAssociation; |
| import org.apache.polygene.api.association.NamedAssociation; |
| import org.apache.polygene.api.identity.HasIdentity; |
| import org.apache.polygene.api.identity.StringIdentity; |
| import org.apache.polygene.api.injection.scope.Service; |
| import org.apache.polygene.api.injection.scope.Structure; |
| import org.apache.polygene.api.mixin.Mixins; |
| import org.apache.polygene.api.unitofwork.UnitOfWork; |
| import org.apache.polygene.api.unitofwork.UnitOfWorkFactory; |
| import org.apache.polygene.api.unitofwork.concern.UnitOfWorkConcern; |
| import org.apache.polygene.api.unitofwork.concern.UnitOfWorkPropagation; |
| import org.apache.polygene.bootstrap.AssemblyException; |
| import org.apache.polygene.bootstrap.ModuleAssembly; |
| import org.apache.polygene.test.AbstractPolygeneTest; |
| import org.apache.polygene.test.EntityTestAssembler; |
| import org.junit.Test; |
| |
| import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder; |
| import static org.junit.Assert.assertThat; |
| |
| public class AssociationToValueTest extends AbstractPolygeneTest |
| { |
| @Service |
| PersonRepository repo; |
| |
| @Test |
| public void givenAdamWhenRequestingChildrenListExpectAbelAndKain() |
| { |
| Person adam = repo.findPersonByName( "Adam" ); |
| Person abel = repo.findPersonByName( "Abel" ); |
| Person kain = repo.findPersonByName( "Kain" ); |
| List<Person> children = repo.transact( adam, ( p, uow ) -> uow.toValueList( p.children() ) ); |
| assertThat( children, containsInAnyOrder( kain, abel ) ); |
| } |
| |
| @Test |
| public void givenAbelWhenRequestingChildrenSetExpectAdamAndEve() |
| { |
| Person abel = repo.findPersonByName( "Abel" ); |
| Person adam = repo.findPersonByName( "Adam" ); |
| Person eve = repo.findPersonByName( "Eve" ); |
| Set<Person> children = repo.transact( abel, ( p, uow ) -> uow.toValueSet( p.children() ) ); |
| assertThat( children, containsInAnyOrder( adam, eve ) ); |
| } |
| |
| @Test |
| public void givenBobWhenRequestingRolesExpectAllRolesWithCorrectPerson() |
| { |
| Person bob = repo.findPersonByName( "Bob" ); |
| Person alice = repo.findPersonByName( "Alice" ); |
| Person john = repo.findPersonByName( "John" ); |
| Person jane = repo.findPersonByName( "Jane" ); |
| Person kim = repo.findPersonByName( "Kim" ); |
| Person robin = repo.findPersonByName( "Robin" ); |
| Map<String, Person> roles = repo.transact( bob, ( p, uow ) -> uow.toValueMap( p.roles() ) ); |
| assertThat( roles.keySet(), containsInAnyOrder( "spouse", "mechanic", "maid", "plumber", "electrician" ) ); |
| assertThat( roles.values(), containsInAnyOrder( alice, john, jane, kim, robin ) ); |
| } |
| |
| @Test |
| public void givenLouisWhenRequestingRolesExpectAllRolesOfMarie() |
| { |
| Person louis = repo.findPersonByName( "Louis" ); |
| Person marie = repo.findPersonByName( "Marie" ); |
| Map<String, Person> roles = repo.transact( louis, ( p, uow ) -> uow.toValueMap( p.roles() ) ); |
| assertThat( roles.keySet(), containsInAnyOrder( "spouse", "lover", "death-mate" ) ); |
| assertThat( roles.values(), containsInAnyOrder( marie, marie, marie ) ); |
| } |
| |
| @Override |
| public void assemble( ModuleAssembly module ) |
| throws AssemblyException |
| { |
| module.entities( Person.class ); |
| module.values( Person.class ); |
| module.services( PersonRepository.class ).withConcerns( UnitOfWorkConcern.class ); |
| |
| module.services( Runnable.class ) |
| .withMixins( LoadData.class ) |
| .withConcerns( UnitOfWorkConcern.class ) |
| .instantiateOnStartup(); |
| |
| new EntityTestAssembler().assemble( module ); |
| } |
| |
| @Override |
| public void setUp() |
| throws Exception |
| { |
| super.setUp(); |
| serviceFinder.findService( Runnable.class ).get().run(); |
| } |
| |
| public interface Person extends HasIdentity |
| { |
| ManyAssociation<Person> children(); |
| |
| NamedAssociation<Person> roles(); |
| } |
| |
| @Mixins( PersonRepositoryMixin.class ) |
| public interface PersonRepository |
| { |
| @UnitOfWorkPropagation |
| <T, R> R transact( T arg, BiFunction<T, UnitOfWork, R> closure ); |
| |
| @UnitOfWorkPropagation |
| Person findPersonByName( String name ); |
| } |
| |
| protected static class PersonRepositoryMixin |
| implements PersonRepository |
| { |
| @Structure |
| UnitOfWorkFactory unitOfWorkFactory; |
| |
| @Override |
| public <T, R> R transact( T arg, BiFunction<T, UnitOfWork, R> closure ) |
| { |
| UnitOfWork uow = unitOfWorkFactory.currentUnitOfWork(); |
| return closure.apply( arg, uow ); |
| } |
| |
| @Override |
| public Person findPersonByName( String name ) |
| { |
| UnitOfWork uow = unitOfWorkFactory.currentUnitOfWork(); |
| return uow.toValue( Person.class, uow.get( Person.class, StringIdentity.identity( name ) ) ); |
| } |
| } |
| |
| public static class LoadData |
| implements Runnable |
| { |
| @Structure |
| UnitOfWorkFactory uowf; |
| |
| @Override |
| @UnitOfWorkPropagation |
| public void run() |
| { |
| Person bob = createPerson( "Bob" ); |
| Person alice = createPerson( "Alice" ); |
| Person john = createPerson( "John" ); |
| Person jane = createPerson( "Jane" ); |
| Person kim = createPerson( "Kim" ); |
| Person robin = createPerson( "Robin" ); |
| Person william = createPerson( "William" ); |
| Person adam = createPerson( "Adam" ); |
| Person eve = createPerson( "Eve" ); |
| Person abel = createPerson( "Abel" ); |
| Person kain = createPerson( "Kain" ); |
| Person louis = createPerson( "Louis" ); |
| Person marie = createPerson( "Marie" ); |
| Person romeo = createPerson( "Romeo" ); |
| Person juliette = createPerson( "Juliette" ); |
| adam.children().add( abel ); |
| adam.children().add( kain ); |
| eve.children().add( abel ); |
| eve.children().add( kain ); |
| abel.children().add( adam ); |
| abel.children().add( eve ); |
| abel.children().add( adam ); |
| abel.children().add( eve ); |
| abel.children().add( eve ); |
| bob.roles().put( "spouse", alice ); |
| bob.roles().put( "mechanic", john ); |
| bob.roles().put( "maid", jane ); |
| bob.roles().put( "plumber", kim ); |
| bob.roles().put( "electrician", robin ); |
| louis.roles().put( "spouse", marie ); |
| louis.roles().put( "lover", marie ); |
| louis.roles().put( "death-mate", marie ); |
| juliette.roles().put( "lover", romeo ); |
| juliette.roles().put( "author", william ); |
| romeo.roles().put( "lover", juliette ); |
| romeo.roles().put( "author", william ); |
| } |
| |
| private Person createPerson( String name ) |
| { |
| UnitOfWork uow = uowf.currentUnitOfWork(); |
| return uow.newEntity( Person.class, StringIdentity.identity( name ) ); |
| } |
| } |
| } |