Package org.qi4j.runtime.structure

Source Code of org.qi4j.runtime.structure.TypeToCompositeLookupTest$BasicFoo

/*
* Copyright (c) 2012, 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.structure;

import java.util.Iterator;
import org.junit.Test;
import org.qi4j.api.activation.ActivationException;
import org.qi4j.api.composite.AmbiguousTypeException;
import org.qi4j.api.entity.Identity;
import org.qi4j.api.mixin.Mixins;
import org.qi4j.api.service.ServiceReference;
import org.qi4j.api.structure.Module;
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.bootstrap.SingletonAssembler;
import org.qi4j.functional.Iterables;
import org.qi4j.test.EntityTestAssembler;

import static org.junit.Assert.*;

/**
* Theses tests ensure that Type to Composite lookup work as expected for
* Objects, Transients, Values, Entities and Services.
*/
public class TypeToCompositeLookupTest
{

    private static final String CATHEDRAL = "cathedral";
    private static final String BAZAR = "bazar";

    public interface Foo
    {

        String bar();

    }

    public static class BasicFooImpl
        implements Foo
    {

        @Override
        public String bar()
        {
            return BAZAR;
        }

    }

    public static class SomeOtherFooImpl
        extends BasicFooImpl
    {

        @Override
        public String bar()
        {
            return CATHEDRAL;
        }

    }

    @Mixins( BasicFooImpl.class )
    public interface BasicFoo
        extends Foo
    {
    }

    @Mixins( SomeOtherFooImpl.class )
    public interface SomeOtherFoo
        extends BasicFoo
    {
    }

    @Test
    public void objects()
        throws ActivationException, AssemblyException
    {
        Module module = new SingletonAssembler()
        {

            @Override
            public void assemble( ModuleAssembly module )
                throws AssemblyException
            {
                module.objects( SomeOtherFooImpl.class );
            }

        }.module();

        assertEquals( CATHEDRAL, module.newObject( SomeOtherFooImpl.class ).bar() );
        assertEquals( CATHEDRAL, module.newObject( BasicFooImpl.class ).bar() );
        assertEquals( CATHEDRAL, module.newObject( Foo.class ).bar() );
    }

    @Test
    public void objectsAmbiguousDeclaration()
        throws ActivationException, AssemblyException
    {
        Module module = new SingletonAssembler()
        {

            @Override
            public void assemble( ModuleAssembly module )
                throws AssemblyException
            {
                module.objects( SomeOtherFooImpl.class, BasicFooImpl.class );
            }

        }.module();

        assertEquals( CATHEDRAL, module.newObject( SomeOtherFooImpl.class ).bar() );
        assertEquals( BAZAR, module.newObject( BasicFooImpl.class ).bar() );

        try
        {
            module.newObject( Foo.class );
            fail( "Ambiguous type exception not detected for Objects" );
        }
        catch( AmbiguousTypeException expected )
        {
        }
    }

    @Test
    public void transients()
        throws ActivationException, AssemblyException
    {
        Module module = new SingletonAssembler()
        {

            @Override
            public void assemble( ModuleAssembly module )
                throws AssemblyException
            {
                module.transients( SomeOtherFoo.class );
            }

        }.module();

        assertEquals( CATHEDRAL, module.newTransientBuilder( SomeOtherFoo.class ).newInstance().bar() );
        assertEquals( CATHEDRAL, module.newTransientBuilder( BasicFoo.class ).newInstance().bar() );
        assertEquals( CATHEDRAL, module.newTransientBuilder( Foo.class ).newInstance().bar() );
    }

    @Test
    public void transientsAmbiguousDeclaration()
        throws ActivationException, AssemblyException
    {
        Module module = new SingletonAssembler()
        {

            @Override
            public void assemble( ModuleAssembly module )
                throws AssemblyException
            {
                module.transients( SomeOtherFoo.class, BasicFoo.class );
            }

        }.module();

        assertEquals( CATHEDRAL, module.newTransientBuilder( SomeOtherFoo.class ).newInstance().bar() );
        assertEquals( BAZAR, module.newTransientBuilder( BasicFoo.class ).newInstance().bar() );

        try
        {
            module.newTransientBuilder( Foo.class );
            fail( "Ambiguous type exception not detected for Transients" );
        }
        catch( AmbiguousTypeException expected )
        {
        }
    }

    @Test
    public void values()
        throws ActivationException, AssemblyException
    {
        Module module = new SingletonAssembler()
        {

            @Override
            public void assemble( ModuleAssembly module )
                throws AssemblyException
            {
                module.values( SomeOtherFoo.class );
            }

        }.module();

        assertEquals( CATHEDRAL, module.newValueBuilder( SomeOtherFoo.class ).newInstance().bar() );
        assertEquals( CATHEDRAL, module.newValueBuilder( BasicFoo.class ).newInstance().bar() );
        assertEquals( CATHEDRAL, module.newValueBuilder( Foo.class ).newInstance().bar() );
    }

    @Test
    public void valuesAmbiguousDeclaration()
        throws ActivationException, AssemblyException
    {
        Module module = new SingletonAssembler()
        {

            @Override
            public void assemble( ModuleAssembly module )
                throws AssemblyException
            {
                module.values( SomeOtherFoo.class, BasicFoo.class );
            }

        }.module();

        assertEquals( CATHEDRAL, module.newValueBuilder( SomeOtherFoo.class ).newInstance().bar() );
        assertEquals( BAZAR, module.newValueBuilder( BasicFoo.class ).newInstance().bar() );

        try
        {
            module.newValueBuilder( Foo.class );
            fail( "Ambiguous type exception not detected for Values" );
        }
        catch( AmbiguousTypeException expected )
        {
        }
    }

    @Test
    public void entities()
        throws UnitOfWorkCompletionException, ActivationException, AssemblyException
    {
        Module module = new SingletonAssembler()
        {

            @Override
            public void assemble( ModuleAssembly module )
                throws AssemblyException
            {
                new EntityTestAssembler().assemble( module );
                module.entities( SomeOtherFoo.class );
            }

        }.module();

        UnitOfWork uow = module.newUnitOfWork();

        SomeOtherFoo someOtherFoo = uow.newEntityBuilder( SomeOtherFoo.class ).newInstance();
        BasicFoo basicFoo = uow.newEntityBuilder( BasicFoo.class ).newInstance();
        Foo foo = uow.newEntityBuilder( Foo.class ).newInstance();

        assertEquals( CATHEDRAL, someOtherFoo.bar() );
        assertEquals( CATHEDRAL, basicFoo.bar() );
        assertEquals( CATHEDRAL, foo.bar() );

        String someOtherFooIdentity = ( (Identity) someOtherFoo ).identity().get();
        String basicFooIdentity = ( (Identity) basicFoo ).identity().get();
        String fooIdentity = ( (Identity) foo ).identity().get();

        uow.complete();

        uow = module.newUnitOfWork();

        uow.get( SomeOtherFoo.class, someOtherFooIdentity );
        uow.get( BasicFoo.class, basicFooIdentity );
        uow.get( Foo.class, fooIdentity );

        uow.discard();
    }

    @Test
    public void entitiesAmbiguousDeclaration()
        throws UnitOfWorkCompletionException, ActivationException, AssemblyException
    {
        Module module = new SingletonAssembler()
        {

            @Override
            public void assemble( ModuleAssembly module )
                throws AssemblyException
            {
                new EntityTestAssembler().assemble( module );
                module.entities( SomeOtherFoo.class, BasicFoo.class );
            }

        }.module();

        UnitOfWork uow = module.newUnitOfWork();

        SomeOtherFoo someOtherFoo = uow.newEntityBuilder( SomeOtherFoo.class ).newInstance();
        BasicFoo basicFoo = uow.newEntityBuilder( BasicFoo.class ).newInstance();
        try
        {
            uow.newEntityBuilder( Foo.class ).newInstance();
            fail( "Ambiguous type exception not detected for Entities" );
        }
        catch( AmbiguousTypeException expected )
        {
        }

        // Specific Type used
        assertEquals( CATHEDRAL, uow.newEntityBuilder( SomeOtherFoo.class ).newInstance().bar() );

        // Specific Type used
        assertEquals( BAZAR, uow.newEntityBuilder( BasicFoo.class ).newInstance().bar() );

        String someOtherFooIdentity = ( (Identity) someOtherFoo ).identity().get();
        String basicFooIdentity = ( (Identity) basicFoo ).identity().get();

        uow.complete();

        uow = module.newUnitOfWork();

        assertEquals( CATHEDRAL, uow.get( SomeOtherFoo.class, someOtherFooIdentity ).bar() );
        assertEquals( BAZAR, uow.get( BasicFoo.class, basicFooIdentity ).bar() );
        assertEquals( CATHEDRAL, uow.get( Foo.class, someOtherFooIdentity ).bar() );
        assertEquals( BAZAR, uow.get( Foo.class, basicFooIdentity ).bar() );

        uow.discard();
    }

    @Test
    public void services()
        throws ActivationException, AssemblyException
    {
        Module module = new SingletonAssembler()
        {

            @Override
            public void assemble( ModuleAssembly module )
                throws AssemblyException
            {
                module.services( SomeOtherFoo.class );
            }

        }.module();

        assertEquals( CATHEDRAL, module.findService( SomeOtherFoo.class ).get().bar() );
        assertEquals( CATHEDRAL, module.findService( BasicFoo.class ).get().bar() );
        assertEquals( CATHEDRAL, module.findService( Foo.class ).get().bar() );
    }

    @Test
    public void servicesPluralDeclaration()
        throws ActivationException, AssemblyException
    {
        Module module = new SingletonAssembler()
        {

            @Override
            public void assemble( ModuleAssembly module )
                throws AssemblyException
            {
                module.services( SomeOtherFoo.class, BasicFoo.class );
            }

        }.module();

        assertEquals( 1, Iterables.count( module.findServices( SomeOtherFoo.class ) ) );
        assertEquals( 2, Iterables.count( module.findServices( BasicFoo.class ) ) );
        assertEquals( 2, Iterables.count( module.findServices( Foo.class ) ) );

        assertEquals( CATHEDRAL, module.findService( SomeOtherFoo.class ).get().bar() );

        // Exact type match first even if it is assembled _after_ an assignable, the assignable comes after
        Iterator<ServiceReference<BasicFoo>> basicFoos = module.findServices( BasicFoo.class ).iterator();
        assertEquals( BAZAR, basicFoos.next().get().bar() );
        assertEquals( CATHEDRAL, basicFoos.next().get().bar() );
        assertFalse( basicFoos.hasNext() );

        // No exact type match, all assembled are assignable, follows assembly Type order
        Iterator<ServiceReference<Foo>> foos = module.findServices( Foo.class ).iterator();
        assertEquals( CATHEDRAL, foos.next().get().bar() );
        assertEquals( BAZAR, foos.next().get().bar() );
        assertFalse( foos.hasNext() );
    }

}
TOP

Related Classes of org.qi4j.runtime.structure.TypeToCompositeLookupTest$BasicFoo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.