WiredComponentProvider.java
/*
* Copyright 2017 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.appformer.maven.integration.embedder;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.maven.DefaultMaven;
import org.apache.maven.Maven;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.factory.DefaultArtifactFactory;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.handler.DefaultArtifactHandler;
import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
import org.apache.maven.artifact.handler.manager.DefaultArtifactHandlerManager;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
import org.apache.maven.artifact.repository.layout.FlatRepositoryLayout;
import org.apache.maven.bridge.MavenRepositorySystem;
import org.apache.maven.eventspy.EventSpy;
import org.apache.maven.eventspy.internal.EventSpyDispatcher;
import org.apache.maven.execution.DefaultMavenExecutionRequestPopulator;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.MavenExecutionRequestPopulator;
import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory;
import org.apache.maven.model.building.DefaultModelBuilder;
import org.apache.maven.model.building.DefaultModelProcessor;
import org.apache.maven.model.building.ModelBuilder;
import org.apache.maven.model.building.ModelProcessor;
import org.apache.maven.model.composition.DefaultDependencyManagementImporter;
import org.apache.maven.model.composition.DependencyManagementImporter;
import org.apache.maven.model.inheritance.DefaultInheritanceAssembler;
import org.apache.maven.model.inheritance.InheritanceAssembler;
import org.apache.maven.model.interpolation.ModelInterpolator;
import org.apache.maven.model.interpolation.StringSearchModelInterpolator;
import org.apache.maven.model.io.DefaultModelReader;
import org.apache.maven.model.io.ModelReader;
import org.apache.maven.model.management.DefaultDependencyManagementInjector;
import org.apache.maven.model.management.DefaultPluginManagementInjector;
import org.apache.maven.model.management.DependencyManagementInjector;
import org.apache.maven.model.management.PluginManagementInjector;
import org.apache.maven.model.normalization.DefaultModelNormalizer;
import org.apache.maven.model.normalization.ModelNormalizer;
import org.apache.maven.model.path.DefaultModelPathTranslator;
import org.apache.maven.model.path.DefaultModelUrlNormalizer;
import org.apache.maven.model.path.DefaultPathTranslator;
import org.apache.maven.model.path.DefaultUrlNormalizer;
import org.apache.maven.model.path.ModelPathTranslator;
import org.apache.maven.model.path.ModelUrlNormalizer;
import org.apache.maven.model.path.PathTranslator;
import org.apache.maven.model.path.UrlNormalizer;
import org.apache.maven.model.profile.DefaultProfileInjector;
import org.apache.maven.model.profile.DefaultProfileSelector;
import org.apache.maven.model.profile.ProfileInjector;
import org.apache.maven.model.profile.ProfileSelector;
import org.apache.maven.model.superpom.DefaultSuperPomProvider;
import org.apache.maven.model.superpom.SuperPomProvider;
import org.apache.maven.model.validation.DefaultModelValidator;
import org.apache.maven.model.validation.ModelValidator;
import org.apache.maven.plugin.LegacySupport;
import org.apache.maven.plugin.internal.DefaultLegacySupport;
import org.apache.maven.project.DefaultProjectBuilder;
import org.apache.maven.project.DefaultProjectBuildingHelper;
import org.apache.maven.project.DefaultProjectDependenciesResolver;
import org.apache.maven.project.ProjectBuilder;
import org.apache.maven.project.ProjectBuildingHelper;
import org.apache.maven.project.ProjectDependenciesResolver;
import org.apache.maven.project.RepositorySessionDecorator;
import org.apache.maven.repository.DefaultMirrorSelector;
import org.apache.maven.repository.MirrorSelector;
import org.apache.maven.repository.RepositorySystem;
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.apache.maven.repository.legacy.LegacyRepositorySystem;
import org.apache.maven.repository.legacy.repository.ArtifactRepositoryFactory;
import org.apache.maven.repository.legacy.repository.DefaultArtifactRepositoryFactory;
import org.apache.maven.settings.building.DefaultSettingsBuilderFactory;
import org.apache.maven.settings.building.SettingsBuilder;
import org.apache.maven.settings.crypto.DefaultSettingsDecrypter;
import org.apache.maven.settings.crypto.SettingsDecrypter;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.logging.console.ConsoleLogger;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
import org.eclipse.aether.impl.DefaultServiceLocator;
import org.eclipse.aether.impl.RemoteRepositoryManager;
import org.eclipse.aether.internal.impl.DefaultRemoteRepositoryManager;
import org.eclipse.aether.internal.impl.DefaultRepositorySystem;
import org.eclipse.aether.internal.impl.DefaultTransporterProvider;
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
import org.eclipse.aether.spi.connector.transport.TransporterProvider;
import org.eclipse.aether.transport.file.FileTransporterFactory;
import org.eclipse.aether.transport.http.HttpTransporterFactory;
import org.eclipse.aether.transport.wagon.WagonTransporterFactory;
import org.sonatype.plexus.components.cipher.DefaultPlexusCipher;
import org.sonatype.plexus.components.cipher.PlexusCipher;
import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
public class WiredComponentProvider implements ComponentProvider {
private final DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
public WiredComponentProvider() {
initServiceLocator();
}
private void initServiceLocator() {
locator.addService( TransporterFactory.class, FileTransporterFactory.class );
locator.addService( TransporterFactory.class, HttpTransporterFactory.class );
locator.addService( TransporterFactory.class, WagonTransporterFactory.class );
locator.setServices( SettingsBuilder.class, new DefaultSettingsBuilderFactory().newInstance() );
locator.addService( RepositorySystem.class, LegacyRepositorySystem.class );
locator.addService( MavenRepositorySystem.class, MavenRepositorySystem.class );
locator.addService (DefaultRepositorySystemSessionFactory.class, DefaultRepositorySystemSessionFactory.class);
locator.addService( org.eclipse.aether.RepositorySystem.class, DefaultRepositorySystem.class );
locator.addService( PlexusCipher.class, DefaultPlexusCipher.class );
locator.addService( SecDispatcher.class, DefaultSecDispatcher.class );
locator.addService( SettingsDecrypter.class, DefaultSettingsDecrypter.class );
locator.addService( ArtifactRepositoryFactory.class, DefaultArtifactRepositoryFactory.class );
locator.addService( MirrorSelector.class, DefaultMirrorSelector.class );
locator.addService( Logger.class, ConsoleLogger.class );
locator.addService( Maven.class, DefaultMaven.class );
locator.addService( LegacySupport.class, DefaultLegacySupport.class );
locator.addService( ProjectBuilder.class, DefaultProjectBuilder.class );
locator.addService( ProjectBuildingHelper.class, DefaultProjectBuildingHelper.class );
locator.addService( ProfileSelector.class, DefaultProfileSelector.class );
locator.addService( ModelProcessor.class, DefaultModelProcessor.class );
locator.addService( ModelReader.class, DefaultModelReader.class );
locator.addService( ModelValidator.class, DefaultModelValidator.class );
locator.addService( SuperPomProvider.class, DefaultSuperPomProvider.class );
locator.addService( ModelNormalizer.class, DefaultModelNormalizer.class );
locator.addService( ProfileInjector.class, DefaultProfileInjector.class );
locator.addService( RemoteRepositoryManager.class, DefaultRemoteRepositoryManager.class );
locator.addService( InheritanceAssembler.class, DefaultInheritanceAssembler.class );
locator.addService( ModelInterpolator.class, StringSearchModelInterpolator.class );
locator.addService( ModelUrlNormalizer.class, DefaultModelUrlNormalizer.class );
locator.addService( UrlNormalizer.class, DefaultUrlNormalizer.class );
locator.addService( ModelPathTranslator.class, DefaultModelPathTranslator.class );
locator.addService( PluginManagementInjector.class, DefaultPluginManagementInjector.class );
locator.addService( DependencyManagementInjector.class, DefaultDependencyManagementInjector.class );
locator.addService( DependencyManagementImporter.class, DefaultDependencyManagementImporter.class );
locator.addService( ArtifactFactory.class, DefaultArtifactFactory.class );
locator.addService( ArtifactHandlerManager.class, DefaultArtifactHandlerManager.class );
locator.addService( ProjectDependenciesResolver.class, DefaultProjectDependenciesResolver.class );
locator.addService( PathTranslator.class, DefaultPathTranslator.class );
locator.addService( TransporterProvider.class, DefaultTransporterProvider.class );
locator.addService( RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class );
locator.addService( ModelBuilder.class, DefaultModelBuilder.class );
// DefaultMavenExecutionRequestPopulator does not have non-arg constructor so we need to create new instance
// manually and inform the locator about the new instance
MavenRepositorySystem system = locator.getService(MavenRepositorySystem.class);
locator.setServices( MavenExecutionRequestPopulator.class, new DefaultMavenExecutionRequestPopulator(system) );
Map<String, ArtifactRepositoryLayout> layouts = new HashMap<String, ArtifactRepositoryLayout>( );
layouts.put("default", new DefaultRepositoryLayout());
layouts.put("flat", new FlatRepositoryLayout());
inject( RepositorySystem.class, layouts, "layouts" );
inject( RepositorySystem.class, ArtifactRepositoryFactory.class, "artifactRepositoryFactory" );
inject( RepositorySystem.class, MirrorSelector.class, "mirrorSelector" );
inject( RepositorySystem.class, ArtifactFactory.class, "artifactFactory" );
inject( ArtifactRepositoryFactory.class, layouts, "repositoryLayouts" );
inject( ArtifactHandlerManager.class, buildArtifactHandlers(), "artifactHandlers" );
inject( ArtifactFactory.class, ArtifactHandlerManager.class, "artifactHandlerManager" );
inject( SecDispatcher.class, PlexusCipher.class, "_cipher" );
inject( SettingsDecrypter.class, SecDispatcher.class, "securityDispatcher" );
EventSpyDispatcher eventSpyDispatcher = new EventSpyDispatcher();
eventSpyDispatcher.setEventSpies( new ArrayList<EventSpy>() );
inject( DefaultRepositorySystemSessionFactory.class, Logger.class, "logger" );
inject( DefaultRepositorySystemSessionFactory.class, ArtifactHandlerManager.class, "artifactHandlerManager" );
inject( DefaultRepositorySystemSessionFactory.class, org.eclipse.aether.RepositorySystem.class, "repoSystem" );
inject( DefaultRepositorySystemSessionFactory.class, SettingsDecrypter.class, "settingsDecrypter" );
inject( DefaultRepositorySystemSessionFactory.class, eventSpyDispatcher, "eventSpyDispatcher" );
inject( DefaultRepositorySystemSessionFactory.class, MavenRepositorySystem.class, "mavenRepositorySystem" );
inject( Maven.class, Logger.class, "logger" );
inject( Maven.class, DefaultRepositorySystemSessionFactory.class, "repositorySessionFactory" );
inject( ProjectBuilder.class, ProjectBuildingHelper.class, "projectBuildingHelper" );
inject( ProjectBuildingHelper.class, RepositorySystem.class, "repositorySystem" );
inject( MavenRepositorySystem.class, ArtifactHandlerManager.class, "artifactHandlerManager" );
inject( MavenRepositorySystem.class, layouts, "layouts" );
inject( ProjectBuilder.class, MavenRepositorySystem.class, "repositorySystem" );
inject( ProjectBuilder.class, ProjectBuildingHelper.class, "projectBuildingHelper" );
inject( ProjectBuilder.class, ModelBuilder.class, "modelBuilder" );
inject( ProjectBuilder.class, org.eclipse.aether.RepositorySystem.class, "repoSystem" );
inject( ProjectBuilder.class, RemoteRepositoryManager.class, "repositoryManager" );
inject( ProjectBuilder.class, ProjectDependenciesResolver.class, "dependencyResolver" );
inject( ProjectDependenciesResolver.class, Logger.class, "logger" );
inject( ProjectDependenciesResolver.class, org.eclipse.aether.RepositorySystem.class, "repoSystem" );
List<RepositorySessionDecorator> decorators = new ArrayList<RepositorySessionDecorator>();
inject( ProjectDependenciesResolver.class, decorators, "decorators" );
inject( SuperPomProvider.class, ModelProcessor.class, "modelProcessor" );
inject( ModelUrlNormalizer.class, UrlNormalizer.class, "urlNormalizer" );
inject( ModelProcessor.class, ModelReader.class, "reader" );
inject( ModelInterpolator.class, UrlNormalizer.class, "urlNormalizer" );
inject( ModelInterpolator.class, PathTranslator.class, "pathTranslator" );
inject( ModelPathTranslator.class, PathTranslator.class, "pathTranslator" );
inject( ModelBuilder.class, ProfileSelector.class, "profileSelector" );
inject( ModelBuilder.class, ModelProcessor.class, "modelProcessor" );
inject( ModelBuilder.class, ModelValidator.class, "modelValidator" );
inject( ModelBuilder.class, SuperPomProvider.class, "superPomProvider" );
inject( ModelBuilder.class, ModelNormalizer.class, "modelNormalizer" );
inject( ModelBuilder.class, ProfileInjector.class, "profileInjector" );
inject( ModelBuilder.class, InheritanceAssembler.class, "inheritanceAssembler" );
inject( ModelBuilder.class, ModelInterpolator.class, "modelInterpolator" );
inject( ModelBuilder.class, ModelUrlNormalizer.class, "modelUrlNormalizer" );
inject( ModelBuilder.class, ModelPathTranslator.class, "modelPathTranslator" );
inject( ModelBuilder.class, PluginManagementInjector.class, "pluginManagementInjector" );
inject( ModelBuilder.class, DependencyManagementInjector.class, "dependencyManagementInjector" );
inject( ModelBuilder.class, DependencyManagementImporter.class, "dependencyManagementImporter" );
}
private Map<String, ArtifactHandler> buildArtifactHandlers() {
Map<String, ArtifactHandler> handlerMap = new HashMap<String, ArtifactHandler>();
handlerMap.put("jar", buildArtifactHandler( "jar" ));
return handlerMap;
}
private ArtifactHandler buildArtifactHandler(String type) {
DefaultArtifactHandler artifactHandler = new DefaultArtifactHandler( type );
artifactHandler.setLanguage( "java" );
artifactHandler.setAddedToClasspath( true );
return artifactHandler;
}
private void inject(Class<?> bean, Class<?> requirement, String fieldName) {
inject(bean, locator.getService( requirement ), fieldName);
}
private void inject(Class<?> bean, Object requirement, String fieldName) {
inject( locator.getService( bean ), requirement, fieldName );
}
private void inject( Object instance, Class<?> requirement, String fieldName ) {
inject(instance, locator.getService( requirement ), fieldName);
}
private void inject( Object instance, Object requirement, String fieldName ) {
inject( instance.getClass(), instance, requirement, fieldName );
}
private void inject( Class<?> clazz, Object instance, Object requirement, String fieldName ) {
try {
Field field = clazz.getDeclaredField( fieldName );
field.setAccessible( true );
field.set( instance, requirement );
} catch (NoSuchFieldException e) {
Class<?> superClass = clazz.getSuperclass();
if (superClass != null) {
inject( superClass, instance, requirement, fieldName );
} else {
throw new RuntimeException( e );
}
} catch (Exception e) {
throw new RuntimeException( e );
}
}
@Override
public <T> T lookup( Class<T> clazz ) throws ComponentLookupException {
return locator.getService( clazz );
}
@Override
public RepositorySystemSession getRepositorySystemSession( MavenExecutionRequest mavenExecutionRequest ) throws ComponentLookupException {
DefaultMaven defaultMaven = (DefaultMaven) lookup( Maven.class );
RepositorySystemSession session = defaultMaven.newRepositorySession( mavenExecutionRequest );
inject(session.getArtifactTypeRegistry(), ArtifactHandlerManager.class, "handlerManager" );
return session;
}
@Override
public PlexusContainer getPlexusContainer() {
return null;
}
@Override
public ClassLoader getSystemClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
}