org.codehaus.plexus.component.composition.FieldComponentComposer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of virtdata-lib-realer Show documentation
Show all versions of virtdata-lib-realer Show documentation
With inspiration from other libraries
package org.codehaus.plexus.component.composition;
/*
* The MIT License
*
* Copyright (c) 2004, The Codehaus
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.component.repository.ComponentDescriptor;
import org.codehaus.plexus.component.repository.ComponentRequirement;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.util.ReflectionUtils;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author Jason van Zyl
* @author Michal Maczka
* @version $Id: FieldComponentComposer.java 2097 2005-06-07 00:08:45Z jdcasey $
*/
public class FieldComponentComposer
extends AbstractComponentComposer
{
public List assembleComponent( Object component, ComponentDescriptor componentDescriptor,
PlexusContainer container )
throws CompositionException
{
List retValue = new LinkedList();
List requirements = componentDescriptor.getRequirements();
for ( Iterator i = requirements.iterator(); i.hasNext(); )
{
ComponentRequirement requirement = (ComponentRequirement) i.next();
Field field = findMatchingField( component, componentDescriptor, requirement, container );
// we want to use private fields.
if ( !field.isAccessible() )
{
field.setAccessible( true );
}
// We have a field to which we should assigning component(s).
// Cardinality is determined by field.getType() method
// It can be array, map, collection or "ordinary" field
List descriptors = assignRequirementToField( component, field, container, requirement );
retValue.addAll( descriptors );
}
return retValue;
}
private List assignRequirementToField( Object component, Field field, PlexusContainer container,
ComponentRequirement requirement )
throws CompositionException
{
try
{
List retValue;
String role = requirement.getRole();
if ( field.getType().isArray() )
{
List dependencies = container.lookupList( role );
Object[] array = (Object[]) Array.newInstance( field.getType(), dependencies.size() );
retValue = container.getComponentDescriptorList( role );
field.set( component, dependencies.toArray( array ) );
}
else if ( Map.class.isAssignableFrom( field.getType() ) )
{
Map dependencies = container.lookupMap( role );
retValue = container.getComponentDescriptorList( role );
field.set( component, dependencies );
}
else if ( List.class.isAssignableFrom( field.getType() ) )
{
List dependencies = container.lookupList( role );
retValue = container.getComponentDescriptorList( role );
field.set( component, dependencies );
}
else if ( Set.class.isAssignableFrom( field.getType() ) )
{
Map dependencies = container.lookupMap( role );
retValue = container.getComponentDescriptorList( role );
field.set( component, dependencies.entrySet() );
}
else //"ordinary" field
{
String key = requirement.getRequirementKey();
Object dependency = container.lookup( key );
ComponentDescriptor componentDescriptor = container.getComponentDescriptor( key );
retValue = new ArrayList( 1 );
retValue.add( componentDescriptor );
field.set( component, dependency );
}
return retValue;
}
catch ( IllegalArgumentException e )
{
throw new CompositionException( "Composition failed for the field " + field.getName() + " " +
"in object of type " + component.getClass().getName(), e );
}
catch ( IllegalAccessException e )
{
throw new CompositionException( "Composition failed for the field " + field.getName() + " " +
"in object of type " + component.getClass().getName(), e );
}
catch ( ComponentLookupException e )
{
throw new CompositionException( "Composition failed of field " + field.getName() + " " +
"in object of type " +
component.getClass().getName() +
" because the requirement " + requirement + " was missing", e );
}
}
protected Field findMatchingField( Object component, ComponentDescriptor componentDescriptor,
ComponentRequirement requirement, PlexusContainer container )
throws CompositionException
{
String fieldName = requirement.getFieldName();
Field field = null;
if ( fieldName != null )
{
field = getFieldByName( component, fieldName, componentDescriptor );
}
else
{
Class fieldClass = null;
try
{
if ( container != null )
{
fieldClass =
container.getContainerRealm().loadClass( requirement.getRole() );
}
else
{
fieldClass = Thread.currentThread().getContextClassLoader().loadClass( requirement.getRole() );
}
}
catch ( ClassNotFoundException e )
{
StringBuffer msg = new StringBuffer( "Component Composition failed for component: " );
msg.append( componentDescriptor.getHumanReadableKey() );
msg.append( ": Requirement class: '" );
msg.append( requirement.getRole() );
msg.append( "' not found." );
throw new CompositionException( msg.toString(), e );
}
field = getFieldByType( component, fieldClass, componentDescriptor );
}
return field;
}
protected Field getFieldByName( Object component, String fieldName, ComponentDescriptor componentDescriptor )
throws CompositionException
{
Field field = ReflectionUtils.getFieldByNameIncludingSuperclasses( fieldName, component.getClass() );
if ( field == null )
{
StringBuffer msg = new StringBuffer( "Component Composition failed. No field of name: '" );
msg.append( fieldName );
msg.append( "' exists in component: " );
msg.append( componentDescriptor.getHumanReadableKey() );
throw new CompositionException( msg.toString() );
}
return field;
}
protected Field getFieldByTypeIncludingSuperclasses( Class componentClass, Class type,
ComponentDescriptor componentDescriptor )
throws CompositionException
{
List fields = getFieldsByTypeIncludingSuperclasses( componentClass, type, componentDescriptor );
if ( fields.size() == 0 )
{
return null;
}
if ( fields.size() == 1 )
{
return (Field) fields.get( 0 );
}
throw new CompositionException( "There are several fields of type '" + type + "', " +
"use 'field-name' to select the correct field." );
}
protected List getFieldsByTypeIncludingSuperclasses( Class componentClass, Class type,
ComponentDescriptor componentDescriptor )
throws CompositionException
{
Class arrayType = Array.newInstance( type, 0 ).getClass();
Field[] fields = componentClass.getDeclaredFields();
List foundFields = new ArrayList();
for ( int i = 0; i < fields.length; i++ )
{
Class fieldType = fields[i].getType();
if ( fieldType.isAssignableFrom( type ) || fieldType.isAssignableFrom( arrayType ) )
{
foundFields.add( fields[i] );
}
}
if ( componentClass.getSuperclass() != Object.class )
{
List superFields = getFieldsByTypeIncludingSuperclasses( componentClass.getSuperclass(), type,
componentDescriptor );
foundFields.addAll( superFields );
}
return foundFields;
}
protected Field getFieldByType( Object component, Class type, ComponentDescriptor componentDescriptor )
throws CompositionException
{
Field field = getFieldByTypeIncludingSuperclasses( component.getClass(), type, componentDescriptor );
if ( field == null )
{
StringBuffer msg = new StringBuffer( "Component composition failed. No field of type: '" );
msg.append( type );
msg.append( "' exists in class '" );
msg.append( component.getClass().getName() );
msg.append( "'." );
if ( componentDescriptor != null )
{
msg.append( " Component: " );
msg.append( componentDescriptor.getHumanReadableKey() );
}
throw new CompositionException( msg.toString() );
}
return field;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy