/******************************************************************************* * 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 * * Minimal facade required to be binary-compatible with legacy Plexus API *******************************************************************************/ package org.codehaus.plexus.component.configurator.converters.composite; import java.util.Collection; import org.codehaus.plexus.component.configurator.ComponentConfigurationException; import org.codehaus.plexus.component.configurator.ConfigurationListener; import org.codehaus.plexus.component.configurator.converters.AbstractConfigurationConverter; import org.codehaus.plexus.component.configurator.converters.ConfigurationConverter; import org.codehaus.plexus.component.configurator.converters.lookup.ConverterLookup; import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator; import org.codehaus.plexus.configuration.PlexusConfiguration; import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration; public abstract class AbstractCollectionConverter extends AbstractConfigurationConverter { // ---------------------------------------------------------------------- // Customizable methods // ---------------------------------------------------------------------- protected abstract Collection<Object> instantiateCollection( final PlexusConfiguration configuration, final Class<?> type, final ClassLoader loader ) throws ComponentConfigurationException; // ---------------------------------------------------------------------- // Shared methods // ---------------------------------------------------------------------- protected final Collection<Object> fromChildren( final ConverterLookup lookup, final PlexusConfiguration configuration, final Class<?> type, final Class<?> enclosingType, final ClassLoader loader, final ExpressionEvaluator evaluator, final ConfigurationListener listener, final Class<?> elementType ) throws ComponentConfigurationException { final Collection<Object> elements = instantiateCollection( configuration, type, loader ); for ( int i = 0, size = configuration.getChildCount(); i < size; i++ ) { final PlexusConfiguration xml = configuration.getChild( i ); final Class<?> childType = getChildType( xml, enclosingType, loader, elementType ); final ConfigurationConverter converter = lookup.lookupConverterForType( childType ); elements.add( converter.fromConfiguration( lookup, xml, childType, enclosingType, // loader, evaluator, listener ) ); } return elements; } protected final Class<?> getChildType( final PlexusConfiguration childConfiguration, final Class<?> enclosingType, final ClassLoader loader, final Class<?> elementType ) throws ComponentConfigurationException { final String childName = fromXML( childConfiguration.getName() ); Class<?> childType = getClassForImplementationHint( null, childConfiguration, loader ); Throwable cause = null; if ( null == childType && childName.indexOf( '.' ) > 0 ) { try { childType = loader.loadClass( childName ); } catch ( final Exception e ) { cause = e; } catch ( final LinkageError e ) { cause = e; } } if ( null == childType ) { try { childType = loader.loadClass( alignPackageName( enclosingType.getName(), childName ) ); } catch ( final Exception e ) { cause = e; } catch ( final LinkageError e ) { cause = e; } } if ( null == childType ) { if ( null != elementType && Object.class != elementType ) { childType = elementType; } else if ( childConfiguration.getChildCount() == 0 ) { childType = String.class; } else { throw new ComponentConfigurationException( "Cannot determine child type", cause ); } } return childType; } protected final static PlexusConfiguration csvToXml( final PlexusConfiguration configuration, final String csv ) { final PlexusConfiguration xml = new XmlPlexusConfiguration( configuration.getName() ); if ( csv.length() > 0 ) { for ( final String token : csv.split( ",", -1 ) ) { xml.addChild( "#", token ); } } return xml; } // ---------------------------------------------------------------------- // Implementation methods // ---------------------------------------------------------------------- private static String alignPackageName( final String enclosingName, final String childName ) { final String pkgPrefix = enclosingName.substring( 0, enclosingName.lastIndexOf( '.' ) + 1 ); final String clzSuffix = Character.toTitleCase( childName.charAt( 0 ) ) + childName.substring( 1 ); return pkgPrefix + clzSuffix; } }