All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.quarkus.launcher.shaded.org.eclipse.sisu.plexus.PlexusRequirements Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 2010, 2015 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.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.inject.Provider;

import org.codehaus.plexus.component.annotations.Requirement;
import org.eclipse.sisu.bean.BeanProperty;
import org.eclipse.sisu.wire.EntryListAdapter;
import org.eclipse.sisu.wire.EntryMapAdapter;
import org.eclipse.sisu.wire.EntrySetAdapter;

import com.google.inject.ProvisionException;
import com.google.inject.TypeLiteral;
import com.google.inject.spi.TypeEncounter;

/**
 * Creates {@link Provider}s for properties with @{@link Requirement} metadata.
 */
final class PlexusRequirements
{
    // ----------------------------------------------------------------------
    // Implementation fields
    // ----------------------------------------------------------------------

    private final Provider locatorProvider;

    // ----------------------------------------------------------------------
    // Constructors
    // ----------------------------------------------------------------------

    PlexusRequirements( final TypeEncounter encounter )
    {
        locatorProvider = encounter.getProvider( PlexusBeanLocator.class );
    }

    // ----------------------------------------------------------------------
    // Public methods
    // ----------------------------------------------------------------------

    /**
     * Creates a {@link Provider} that provides Plexus components that match the given property requirement.
     * 
     * @param requirement The Plexus requirement
     * @param property The bean property
     * @return Provider that provides required Plexus components for the given property
     */
    @SuppressWarnings( { "unchecked", "rawtypes" } )
    public  Provider lookup( final Requirement requirement, final BeanProperty property )
    {
        try
        {
            // deduce lookup from metadata + property details
            final TypeLiteral expectedType = property.getType();
            final TypeLiteral roleType = (TypeLiteral) Roles.roleType( requirement, expectedType );
            final Class rawType = expectedType.getRawType();

            final String[] hints = Hints.canonicalHints( requirement );

            if ( Map.class == rawType )
            {
                return new RequirementMapProvider( locatorProvider, roleType, hints );
            }
            else if ( List.class == rawType || Collection.class == rawType || Iterable.class == rawType )
            {
                return new RequirementListProvider( locatorProvider, roleType, hints );
            }
            else if ( Set.class == rawType )
            {
                return new RequirementSetProvider( locatorProvider, roleType, hints );
            }

            return new RequirementProvider( locatorProvider, roleType, hints );
        }
        catch ( final RuntimeException e )
        {
            // defer until later...
            return new Provider()
            {
                public T get()
                {
                    throw new ProvisionException( "Error in requirement: " + property, e );
                }
            };
        }
    }

    // ----------------------------------------------------------------------
    // Implementation types
    // ----------------------------------------------------------------------

    /**
     * Abstract {@link Provider} that locates Plexus beans on-demand.
     */
    private static abstract class AbstractRequirementProvider
        implements Provider
    {
        // ----------------------------------------------------------------------
        // Implementation fields
        // ----------------------------------------------------------------------

        private final Provider locatorProvider;

        final TypeLiteral type;

        private final String[] hints;

        // ----------------------------------------------------------------------
        // Constructors
        // ----------------------------------------------------------------------

        AbstractRequirementProvider( final Provider locatorProvider, final TypeLiteral type,
                                     final String[] hints )
        {
            this.locatorProvider = locatorProvider;

            this.type = type;
            this.hints = hints;
        }

        // ----------------------------------------------------------------------
        // Locally-shared methods
        // ----------------------------------------------------------------------

        final Iterable> locate()
        {
            return locatorProvider.get().locate( type, hints );
        }
    }

    /**
     * {@link Provider} of Plexus requirement maps.
     */
    private static final class RequirementMapProvider
        extends AbstractRequirementProvider, T>
    {
        // ----------------------------------------------------------------------
        // Constructors
        // ----------------------------------------------------------------------

        RequirementMapProvider( final Provider locatorProvider, final TypeLiteral type,
                                final String[] hints )
        {
            super( locatorProvider, type, hints );
        }

        // ----------------------------------------------------------------------
        // Public methods
        // ----------------------------------------------------------------------

        public Map get()
        {
            return new EntryMapAdapter( locate() );
        }
    }

    /**
     * {@link Provider} of Plexus requirement lists.
     */
    private static final class RequirementListProvider
        extends AbstractRequirementProvider, T>
    {
        // ----------------------------------------------------------------------
        // Constructors
        // ----------------------------------------------------------------------

        RequirementListProvider( final Provider locatorProvider, final TypeLiteral type,
                                 final String[] hints )
        {
            super( locatorProvider, type, hints );
        }

        // ----------------------------------------------------------------------
        // Public methods
        // ----------------------------------------------------------------------

        public List get()
        {
            return new EntryListAdapter( locate() );
        }
    }

    /**
     * {@link Provider} of Plexus requirement sets.
     */
    private static final class RequirementSetProvider
        extends AbstractRequirementProvider, T>
    {
        // ----------------------------------------------------------------------
        // Constructors
        // ----------------------------------------------------------------------

        RequirementSetProvider( final Provider locatorProvider, final TypeLiteral type,
                                final String[] hints )
        {
            super( locatorProvider, type, hints );
        }

        // ----------------------------------------------------------------------
        // Public methods
        // ----------------------------------------------------------------------

        public Set get()
        {
            return new EntrySetAdapter( locate() );
        }
    }

    /**
     * {@link Provider} of a single Plexus requirement.
     */
    private static final class RequirementProvider
        extends AbstractRequirementProvider
    {
        // ----------------------------------------------------------------------
        // Constructors
        // ----------------------------------------------------------------------

        RequirementProvider( final Provider locatorProvider, final TypeLiteral type,
                             final String[] hints )
        {
            super( locatorProvider, type, hints );
        }

        // ----------------------------------------------------------------------
        // Public methods
        // ----------------------------------------------------------------------

        public T get()
        {
            // pick first bean: supports both specific and wildcard lookup
            final Iterator> i = locate().iterator();
            if ( i.hasNext() )
            {
                return i.next().getValue();
            }
            return Roles.throwMissingComponentException( type, null );
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy