package org.codehaus.mojo.mockrepo;
/*
* 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.
*/
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.model.Model;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.codehaus.mojo.mockrepo.server.SimpleHttpServer;
import org.codehaus.mojo.mockrepo.utils.MockRepoUtils;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.StringUtils;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Starts the mock maven remote repository.
*
* @author Stephen Connolly
* @goal start
* @description Starts the mock maven remote repository.
* @since 1.0-alpha-1
*/
public class StartMojo
extends AbstractMockRepoMojo
{
/**
* @component
* @required
* @readonly
*/
private RepositoryMetadataManager repositoryMetadataManager;
/**
* @parameter expression="${project.remoteArtifactRepositories}"
* @readonly
* @since 1.0-alpha-3
*/
protected List remoteArtifactRepositories;
/**
* @parameter expression="${project.pluginArtifactRepositories}"
* @readonly
* @since 1.0-alpha-3
*/
protected List remotePluginRepositories;
/**
* @parameter expression="${localRepository}"
* @readonly
* @since 1.0-alpha-1
*/
protected ArtifactRepository localRepository;
/**
* @component
* @since 1.0-alpha-1
*/
protected ArtifactFactory artifactFactory;
/**
* @component
* @since 1.0-alpha-1
*/
protected ArtifactResolver artifactResolver;
/**
* The Maven Project.
*
* @parameter expression="${project}"
* @readonly
* @since 1.0-alpha-1
*/
private MavenProject project;
/**
* The port to serve the remote repository on.
*
* @parameter expression="${mock-repository.port}" default-value="8080"
* @since 1.0-alpha-1
*/
private int port;
/**
* The property to set the bound port to.
*
* @parameter expression="${mock-repository.propertyName}" default-value="mock-repository.port"
* @since 1.0-alpha-1
*/
private String property;
/**
* Determines whether or not the server blocks when started. The default
* behavior (daemon = true) will cause the server start and continue running subsequent
* processes in an automated build environment.
* <p/>
* Often, it is desirable to let the server pause other processes
* while it continues to handle web requests. This is useful when starting the
* server with the intent to work with it interactively. This can be facilitated by setting
* daemon to false.
*
* @parameter expression="${mock-repository.daemon}" default-value="true"
* @since 1.0-alpha-1
*/
protected boolean daemon;
/**
* {@inheritDoc}
*/
public void execute()
throws MojoExecutionException, MojoFailureException
{
getLog().info( "Starting mock maven remote repository" );
int boundPort;
synchronized ( serverLock )
{
if ( server != null )
{
throw new MojoFailureException( "Mock maven remote repository is already running" );
}
server = new SimpleHttpServer( getLog(), port, makeRepository() );
try
{
server.start();
}
catch ( InterruptedException e )
{
throw new MojoExecutionException( "Could not start mock maven remote repository", e );
}
boundPort = server.getBoundPort();
}
getLog().info( "Mock maven remote repository started on port " + boundPort + "." );
if ( project != null )
{
getLog().debug( "Setting property " + property + " to " + boundPort );
project.getProperties().setProperty( property, Integer.toString( boundPort ) );
}
if ( !daemon )
{
try
{
server.join();
}
catch ( InterruptedException e )
{
throw new MojoFailureException( "Non-daemon mode stopped" );
}
finally
{
synchronized ( serverLock )
{
server.stop();
getLog().info( "Mock maven repository stopped" );
server = null;
}
}
}
}
private Repository makeRepository()
throws MojoExecutionException
{
byte[] emptyJar = MockRepoUtils.newEmptyJarContent();
ByteArrayContent emptyJarContent = new ByteArrayContent( emptyJar );
HostedRepository hosted = new HostedRepository();
try
{
final List pomFiles = FileUtils.getFiles( sourceDirectory, "**/*.pom", null, true );
final List artifactFiles = FileUtils.getFiles( sourceDirectory, "**", "**/*.pom", true );
getLog().info( "Found " + pomFiles.size() + " pom files to host" );
Iterator i = pomFiles.iterator();
while ( i.hasNext() )
{
File file = (File) i.next();
getLog().debug( "Parsing " + file );
if ( file.isFile() )
{
try
{
final Model model = hosted.deployPom( new FileContent( file ) );
String groupId = MockRepoUtils.getGroupId( model );
String artifactId = MockRepoUtils.getArtifactId( model );
String version = MockRepoUtils.getVersion( model );
String packaging = model.getPackaging() == null ? "jar" : model.getPackaging();
final String basePath = MockRepoUtils.getGAVPathName( groupId, artifactId, version );
String baseName = StringUtils.chompLast( file.getName(), ".pom" );
List related = new ArrayList();
Iterator k = artifactFiles.iterator();
while ( k.hasNext() )
{
File artifactFile = (File) k.next();
if ( artifactFile.getParentFile().equals( file.getParentFile() )
&& artifactFile.getName().startsWith( baseName ) )
{
related.add( artifactFile );
k.remove();
}
}
if ( !related.isEmpty() )
{
Iterator k1 = related.iterator();
while ( k1.hasNext() )
{
File associatedFile = (File) k1.next();
String associatedName = associatedFile.getName().substring( baseName.length() );
hosted.deploy( basePath + associatedName, new FileContent( associatedFile ) );
}
}
else
{
if ( "jar".equals( packaging ) || "maven-plugin".equals( packaging ) )
{
hosted.deploy( basePath + ".jar", emptyJarContent );
}
else if ( "war".equals( packaging ) || "ear".equals( packaging )
|| "rar".equals( packaging ) || "zip".equals( packaging ) || "sar".equals( packaging )
|| "par".equals( packaging ) )
{
hosted.deploy( basePath + "." + packaging, emptyJarContent );
}
hosted.deploy( basePath + "-sources.jar", emptyJarContent );
}
}
catch ( IOException e )
{
// ignore
}
}
}
}
catch ( IOException e )
{
throw new MojoExecutionException( e.getMessage(), e );
}
ProxyRepository proxy = null;
try
{
proxy =
new ProxyRepository( repositoryMetadataManager, remoteArtifactRepositories, remotePluginRepositories,
localRepository, artifactFactory, getLog(), artifactResolver );
}
catch ( InvalidVersionSpecificationException e )
{
throw new MojoExecutionException( e.getMessage(), e );
}
return new CompositeRepository( new Repository[]{hosted, proxy}, getLog() );
}
}