/******************************************************************************* * 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 java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import org.codehaus.plexus.component.annotations.Component; import org.eclipse.sisu.inject.DeferredClass; import org.eclipse.sisu.space.ClassSpace; import com.google.inject.Binder; /** * {@link PlexusBeanModule} that binds Plexus components by scanning XML resources. */ public final class PlexusXmlBeanModule implements PlexusBeanModule { // ---------------------------------------------------------------------- // Implementation fields // ---------------------------------------------------------------------- private final ClassSpace space; private final Map<?, ?> variables; private final URL plexusXml; private final boolean root; // ---------------------------------------------------------------------- // Constructors // ---------------------------------------------------------------------- /** * Creates a bean source that scans all the surrounding class spaces for XML resources. * * @param space The main class space * @param variables The filter variables * @param plexusXml The plexus.xml URL */ public PlexusXmlBeanModule( final ClassSpace space, final Map<?, ?> variables, final URL plexusXml ) { this.space = space; this.variables = variables; this.plexusXml = plexusXml; root = true; } /** * Creates a bean source that only scans the local class space for XML resources. * * @param space The local class space * @param variables The filter variables */ public PlexusXmlBeanModule( final ClassSpace space, final Map<?, ?> variables ) { this.space = space; this.variables = variables; plexusXml = null; root = false; } // ---------------------------------------------------------------------- // Public methods // ---------------------------------------------------------------------- public PlexusBeanSource configure( final Binder binder ) { binder.bind( ClassSpace.class ).toInstance( space ); final PlexusTypeBinder plexusTypeBinder = new PlexusTypeBinder( binder ); final Map<String, PlexusBeanMetadata> metadataMap = new HashMap<String, PlexusBeanMetadata>(); final PlexusXmlScanner scanner = new PlexusXmlScanner( variables, plexusXml, metadataMap ); final String source = space.toString(); for ( final Entry<Component, DeferredClass<?>> entry : scanner.scan( space, root ).entrySet() ) { plexusTypeBinder.hear( entry.getKey(), entry.getValue(), source ); } return new PlexusXmlBeanSource( metadataMap ); } // ---------------------------------------------------------------------- // Implementation types // ---------------------------------------------------------------------- /** * {@link PlexusBeanSource} backed by consumable XML metadata. */ private static final class PlexusXmlBeanSource implements PlexusBeanSource { // ---------------------------------------------------------------------- // Implementation fields // ---------------------------------------------------------------------- private Map<String, PlexusBeanMetadata> metadataMap; // ---------------------------------------------------------------------- // Constructors // ---------------------------------------------------------------------- PlexusXmlBeanSource( final Map<String, PlexusBeanMetadata> metadataMap ) { this.metadataMap = metadataMap; } // ---------------------------------------------------------------------- // Public methods // ---------------------------------------------------------------------- public PlexusBeanMetadata getBeanMetadata( final Class<?> implementation ) { if ( null == metadataMap ) { return null; } final PlexusBeanMetadata metadata = metadataMap.remove( implementation.getName() ); if ( metadataMap.isEmpty() ) { metadataMap = null; } return metadata; } } }