blob: c2b31b293c4e0e043f79c0d274211a92a21c1b75 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.maven.mae.project;
import static org.apache.maven.mae.project.event.ModelLoaderEventBuilder.newBuiltModelEvent;
import static org.apache.maven.mae.project.event.ModelLoaderEventBuilder.newErrorEvent;
import static org.apache.maven.mae.project.event.ModelLoaderEventBuilder.newResolvedModelEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.maven.mae.MAEException;
import org.apache.maven.mae.project.event.EventDispatcher;
import org.apache.maven.mae.project.event.ModelLoaderEvent;
import org.apache.maven.mae.project.internal.SimpleModelResolver;
import org.apache.maven.mae.project.key.FullProjectKey;
import org.apache.maven.mae.project.session.ProjectToolsSession;
import org.apache.maven.mae.project.session.SessionInjector;
import org.apache.maven.model.Model;
import org.apache.maven.model.building.FileModelSource;
import org.apache.maven.model.building.ModelSource;
import org.apache.maven.model.io.ModelParseException;
import org.apache.maven.model.io.ModelReader;
import org.apache.maven.model.resolution.UnresolvableModelException;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.sonatype.aether.RepositorySystemSession;
import org.sonatype.aether.RequestTrace;
import org.sonatype.aether.impl.ArtifactResolver;
import org.sonatype.aether.impl.RemoteRepositoryManager;
import org.sonatype.aether.repository.RemoteRepository;
import org.sonatype.aether.util.DefaultRequestTrace;
@Component( role = ModelLoader.class )
public class DefaultModelLoader
implements ModelLoader
{
@Requirement
private ArtifactResolver artifactResolver;
@Requirement
private RemoteRepositoryManager remoteRepositoryManager;
@Requirement
private ModelReader modelReader;
@Requirement
private SessionInjector sessionInjector;
@Override
public List<Model> loadRawModels( final ProjectToolsSession session, final boolean processModules,
final RequestTrace trace, final File... poms )
throws ProjectToolsException
{
Map<String, Object> options = getStandardOptions();
Map<File, Model> models = new LinkedHashMap<File, Model>();
List<File> toProcess = new ArrayList<File>( Arrays.asList( poms ) );
Map<File, RequestTrace> traces = new HashMap<File, RequestTrace>();
while ( !toProcess.isEmpty() )
{
File file = toProcess.remove( 0 );
if ( !models.containsKey( file ) )
{
RequestTrace modelTrace = trace.newChild( file );
Model model = loadRaw( new FileModelSource( file ), options, modelTrace, session );
model.setPomFile( file );
models.put( file, model );
if ( processModules )
{
addModulePoms( model, modelTrace, toProcess, traces );
}
}
}
return new ArrayList<Model>( models.values() );
}
@Override
public List<Model> loadRawModel( final File pom, final boolean processModules, final RequestTrace trace,
final ProjectToolsSession session )
throws ProjectToolsException
{
Map<String, Object> options = getStandardOptions();
Map<File, Model> models = new LinkedHashMap<File, Model>();
List<File> toProcess = new ArrayList<File>( Collections.singleton( pom ) );
Map<File, RequestTrace> traces = new HashMap<File, RequestTrace>();
while ( !toProcess.isEmpty() )
{
File file = toProcess.remove( 0 );
if ( !models.containsKey( file ) )
{
RequestTrace modelTrace = trace.newChild( file );
Model model = loadRaw( new FileModelSource( file ), options, modelTrace, session );
model.setPomFile( file );
models.put( file, model );
if ( processModules )
{
addModulePoms( model, modelTrace, toProcess, traces );
}
}
}
return new ArrayList<Model>( models.values() );
}
@Override
public Model loadRawModel( final FullProjectKey key, final RequestTrace trace, final ProjectToolsSession session )
throws ProjectToolsException
{
ModelSource src = resolveModel( key, trace, session );
Map<String, Object> options = getStandardOptions();
return loadRaw( src, options, trace, session );
}
@Override
public Model loadRawModel( final String groupId, final String artifactId, final String version,
final RequestTrace trace, final ProjectToolsSession session )
throws ProjectToolsException
{
return loadRawModel( new FullProjectKey( groupId, artifactId, version ), trace, session );
}
@Override
public ModelSource resolveModel( final FullProjectKey key, final RequestTrace trace,
final ProjectToolsSession session )
throws ProjectToolsException
{
try
{
RepositorySystemSession rss = sessionInjector.getRepositorySystemSession( session );
List<RemoteRepository> repos = sessionInjector.getRemoteRepositories( session );
SimpleModelResolver resolver =
new SimpleModelResolver( rss, repos, new DefaultRequestTrace( key ), artifactResolver,
remoteRepositoryManager );
ModelSource source = resolver.resolveModel( key.getGroupId(), key.getArtifactId(), key.getVersion() );
ModelLoaderEvent event = newResolvedModelEvent( trace ).withKey( key ).withModelSource( source ).build();
getDispatcher( session ).fire( event );
return source;
}
catch ( UnresolvableModelException e )
{
ModelLoaderEvent event = newErrorEvent( trace ).withKey( key ).withError( e ).build();
getDispatcher( session ).fire( event );
throw new ProjectToolsException( "Failed to resolve model: %s. Reason: %s", e, key, e.getMessage() );
}
catch ( MAEException e )
{
ModelLoaderEvent event = newErrorEvent( trace ).withKey( key ).withError( e ).build();
getDispatcher( session ).fire( event );
throw new ProjectToolsException( "Failed to initialize model-resolving environment: %s. Reason: %s", e,
key, e.getMessage() );
}
}
@Override
public ModelSource resolveModel( final String groupId, final String artifactId, final String version,
final RequestTrace trace, final ProjectToolsSession session )
throws ProjectToolsException
{
return resolveModel( new FullProjectKey( groupId, artifactId, version ), trace, session );
}
private Model loadRaw( final ModelSource source, final Map<String, Object> options, final RequestTrace trace,
final ProjectToolsSession session )
throws ProjectToolsException
{
ModelLoaderEvent event = null;
Model model;
try
{
model = modelReader.read( source.getInputStream(), options );
event = newBuiltModelEvent( trace ).withModel( model ).withModelSource( source ).build();
return model;
}
catch ( ModelParseException e )
{
event = newErrorEvent( trace ).withModelSource( source ).withError( e ).build();
throw new ProjectToolsException( "Failed to parse model: %s. Reason: %s", e, source, e.getMessage() );
}
catch ( IOException e )
{
event = newErrorEvent( trace ).withModelSource( source ).withError( e ).build();
throw new ProjectToolsException( "Failed to read model: %s. Reason: %s", e, source, e.getMessage() );
}
finally
{
getDispatcher( session ).fire( event );
}
}
private void addModulePoms( final Model model, final RequestTrace trace, final List<File> toProcess,
final Map<File, RequestTrace> traces )
{
if ( model.getModules() != null )
{
File dir = model.getPomFile().getParentFile();
if ( dir == null )
{
dir = new File( System.getProperty( "user.dir" ) );
}
for ( String mod : model.getModules() )
{
File modFile = new File( dir, mod );
if ( !modFile.isFile() )
{
modFile = new File( modFile, "pom.xml" );
}
modFile = modFile.getAbsoluteFile();
if ( modFile.exists() )
{
traces.put( modFile, trace.newChild( modFile ) );
toProcess.add( modFile );
}
}
}
}
private synchronized EventDispatcher<ModelLoaderEvent> getDispatcher( final ProjectToolsSession session )
{
EventDispatcher<ModelLoaderEvent> d = session.getEventDispatcher( ModelLoaderEvent.class );
if ( d == null )
{
d = new EventDispatcher<ModelLoaderEvent>();
session.setEventDispatcher( ModelLoaderEvent.class, d );
}
return d;
}
private Map<String, Object> getStandardOptions()
{
Map<String, Object> options = new HashMap<String, Object>();
options.put( ModelReader.IS_STRICT, Boolean.FALSE.toString() );
return options;
}
}