blob: 315c15bc46e0cb593e91980cdf1fa573dc7e669c [file] [log] [blame]
/*******************************************************************************
* 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.plexus;
import javax.inject.Provider;
import org.codehaus.plexus.component.annotations.Configuration;
import org.codehaus.plexus.component.annotations.Requirement;
import org.eclipse.sisu.bean.BeanManager;
import org.eclipse.sisu.bean.BeanProperty;
import org.eclipse.sisu.bean.PropertyBinder;
import org.eclipse.sisu.bean.PropertyBinding;
import com.google.inject.spi.TypeEncounter;
/**
* {@link BeanPropertyBinder} that auto-binds properties according to Plexus metadata.
*/
final class PlexusPropertyBinder
implements PropertyBinder
{
// ----------------------------------------------------------------------
// Static initialization
// ----------------------------------------------------------------------
static
{
boolean optionalSupported = true;
try
{
// support both old and new forms of @Requirement
Requirement.class.getDeclaredMethod( "optional" );
}
catch ( final Exception e )
{
optionalSupported = false;
}
catch ( final LinkageError e )
{
optionalSupported = false;
}
OPTIONAL_SUPPORTED = optionalSupported;
}
// ----------------------------------------------------------------------
// Constants
// ----------------------------------------------------------------------
private static final boolean OPTIONAL_SUPPORTED;
// ----------------------------------------------------------------------
// Implementation fields
// ----------------------------------------------------------------------
private final BeanManager manager;
private final PlexusBeanMetadata metadata;
private final PlexusConfigurations configurations;
private final PlexusRequirements requirements;
// ----------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------
PlexusPropertyBinder( final BeanManager manager, final TypeEncounter<?> encounter,
final PlexusBeanMetadata metadata )
{
this.manager = manager;
this.metadata = metadata;
configurations = new PlexusConfigurations( encounter );
requirements = new PlexusRequirements( encounter );
}
// ----------------------------------------------------------------------
// Public methods
// ----------------------------------------------------------------------
public <T> PropertyBinding bindProperty( final BeanProperty<T> property )
{
if ( metadata.isEmpty() )
{
return PropertyBinder.LAST_BINDING;
}
/*
* @Configuration binding
*/
final Configuration configuration = metadata.getConfiguration( property );
if ( null != configuration )
{
final Provider<T> valueProvider = configurations.lookup( configuration, property );
return new ProvidedPropertyBinding<T>( property, valueProvider );
}
/*
* @Requirement binding
*/
final Requirement requirement = metadata.getRequirement( property );
if ( null != requirement )
{
if ( null != manager )
{
final PropertyBinding managedBinding = manager.manage( property );
if ( null != managedBinding )
{
return managedBinding; // the bean manager will handle this property
}
}
final Provider<T> roleProvider = requirements.lookup( requirement, property );
if ( OPTIONAL_SUPPORTED && requirement.optional() )
{
return new OptionalPropertyBinding<T>( property, roleProvider );
}
return new ProvidedPropertyBinding<T>( property, roleProvider );
}
return null; // nothing to bind
}
}