/*******************************************************************************
* Copyright (c) 2015 IBH SYSTEMS GmbH.
* 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:
* IBH SYSTEMS GmbH - initial API and implementation
*******************************************************************************/
package org.eclipse.packagedrone.repo.adapter.maven.upload;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.io.CharStreams;
/**
* An upload helper for maven
*/
public class Uploader
{
private final static Logger logger = LoggerFactory.getLogger ( Uploader.class );
public static enum NoParentMode
{
IGNORE,
ADD,
FAIL;
}
private final Options options;
private final UploadTarget target;
public Uploader ( final UploadTarget target, final Options options )
{
this.target = target;
this.options = new Options ( options );
}
public boolean receive ( final String path, final InputStream stream ) throws ChecksumValidationException, IOException
{
final Coordinates c = Coordinates.parse ( path );
if ( c == null )
{
// unable to parse coordinates
logger.info ( "Unable to parse maven coordinates from path: {}", path );
return false;
}
if ( this.options.getIgnoreExtensions ().contains ( c.getExtension () ) )
{
return false;
}
final String alg = isCheckSum ( c );
if ( alg != null )
{
// process checksum
this.target.validateChecksum ( c.replaceExtension ( c.getExtension ().substring ( 0, c.getExtension ().length () - ( alg.length () + 1 ) ) ), alg, toChecksumString ( stream ) );
return false;
}
if ( c.getClassifier () == null )
{
// primary
return this.target.createArtifact ( c, stream, null ) != null;
}
else
{
// secondary
Coordinates cp = c.makeUnclassified ();
if ( !"jar".equals ( cp.getExtension () ) )
{
cp = cp.replaceExtension ( "pom" );
}
final Set<String> parents = this.target.findArtifacts ( cp );
if ( parents.isEmpty () )
{
switch ( this.options.getNoParentMode () )
{
case ADD:
return this.target.createArtifact ( c, stream, null ) != null;
case IGNORE:
return false;
case FAIL:
throw new IOException ( String.format ( "No parent found for: %s (parent: %s)", c, cp ) );
default:
throw new RuntimeException ( String.format ( "Unknown mode: %s", this.options.getNoParentMode () ) );
}
}
else if ( parents.size () > 1 )
{
throw new IOException ( String.format ( "Duplicate parents detected: %s", parents ) );
}
else
{
return this.target.createArtifact ( parents.iterator ().next (), c, stream, null ) != null;
}
}
}
private String toChecksumString ( final InputStream stream ) throws IOException
{
if ( stream == null )
{
return "";
}
return CharStreams.toString ( new InputStreamReader ( stream, StandardCharsets.UTF_8 ) );
}
/**
* Check if the uploaded artifact is actually a checksum file
*
* @param c
* the extracted coordinates
* @return {@code true} if the upload is definitely a checksum file,
* {@code false} otherwise
*/
private String isCheckSum ( final Coordinates c )
{
final String cext = c.getExtension ();
if ( cext == null )
{
return null;
}
for ( final String ext : this.options.getChecksumExtensions () )
{
if ( cext.endsWith ( "." + ext ) )
{
return ext;
}
}
return null;
}
}