/*******************************************************************************
* Copyright (c) 2010-present Sonatype, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Stuart McCulloch (Sonatype, Inc.) - initial API and implementation
*******************************************************************************/
package org.eclipse.sisu.bean;
import javax.inject.Named;
import com.google.inject.AbstractModule;
import com.google.inject.ConfigurationException;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
import com.google.inject.matcher.AbstractMatcher;
import com.google.inject.name.Names;
import com.google.inject.spi.TypeEncounter;
import junit.framework.TestCase;
public class PropertyListenerTest
extends TestCase
{
static class Base
{
String a;
}
static class Bean0
extends Base
{
String last;
}
static class Bean1
extends Base
{
String b;
Bean2 bean;
}
static class Bean2
extends Base
{
String b;
String last;
String c;
String ignore;
@Named( "injected" )
@javax.inject.Inject
int jsr330;
@Named( "injected" )
@com.google.inject.Inject
int guice;
String d;
}
static class Bean3
extends Base
{
String b;
String error;
String c;
}
static class Bean4
extends Bean1
{
void setA( @SuppressWarnings( "unused" ) final String unused )
{
assertNull( a ); // hidden by our setter method
assertNotNull( b ); // should be injected first
a = "correct order";
}
}
class NamedPropertyBinder
implements PropertyBinder
{
public <T> PropertyBinding bindProperty( final BeanProperty<T> property )
{
if ( "last".equals( property.getName() ) )
{
return PropertyBinder.LAST_BINDING;
}
if ( "ignore".equals( property.getName() ) )
{
return null;
}
if ( "error".equals( property.getName() ) )
{
throw new RuntimeException( "Broken binding" );
}
if ( "bean".equals( property.getName() ) )
{
return new PropertyBinding()
{
public void injectProperty( final Object bean )
{
property.set( bean, injector.getInstance( Key.get( property.getType() ) ) );
}
};
}
return new PropertyBinding()
{
@SuppressWarnings( "unchecked" )
public void injectProperty( final Object bean )
{
property.set( bean, (T) ( property.getName() + "Value" ) );
}
};
}
}
final PropertyBinder namedPropertyBinder = new NamedPropertyBinder();
Injector injector;
@Override
public void setUp()
{
injector = Guice.createInjector( new AbstractModule()
{
@Override
protected void configure()
{
bindListener( new AbstractMatcher<TypeLiteral<?>>()
{
public boolean matches( final TypeLiteral<?> type )
{
return Base.class.isAssignableFrom( type.getRawType() );
}
}, new BeanListener( new BeanBinder()
{
public <T> PropertyBinder bindBean( final TypeLiteral<T> type, final TypeEncounter<T> encounter )
{
return type.getRawType().getName().contains( "Bean" ) ? namedPropertyBinder : null;
}
} ) );
bindConstant().annotatedWith( Names.named( "injected" ) ).to( 42 );
}
} );
}
public void testNoBean()
{
final Base base = injector.getInstance( Base.class );
assertNull( base.a );
}
public void testNoBindings()
{
final Bean0 bean0 = injector.getInstance( Bean0.class );
assertNull( bean0.a );
}
public void testPropertyBindings()
{
final Bean1 bean1 = injector.getInstance( Bean1.class );
assertEquals( "bValue", bean1.b );
assertEquals( "aValue", bean1.a );
}
public void testSpecialProperties()
{
final Bean2 bean2 = injector.getInstance( Bean2.class );
assertEquals( "dValue", bean2.d );
assertEquals( 42, bean2.guice );
assertEquals( 42, bean2.jsr330 );
assertEquals( "cValue", bean2.c );
assertNull( bean2.b );
assertNull( bean2.a );
try
{
PropertyBinder.LAST_BINDING.injectProperty( bean2 );
fail( "Expected UnsupportedOperationException" );
}
catch ( final UnsupportedOperationException e )
{
}
}
public void testBrokenBinding()
{
try
{
injector.getInstance( Bean3.class );
fail( "Expected ConfigurationException" );
}
catch ( final ConfigurationException e )
{
e.printStackTrace();
}
}
public void testInjectionOrder()
{
assertEquals( "correct order", injector.getInstance( Bean4.class ).a );
}
}