/**
* Copyright (c) 2008-2011 Sonatype, Inc.
* All rights reserved. Includes the third-party code listed at http://www.sonatype.com/products/nexus/attributions.
*
* This program is free software: you can redistribute it and/or modify it only under the terms of the GNU Affero General
* Public License Version 3 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License Version 3
* for more details.
*
* You should have received a copy of the GNU Affero General Public License Version 3 along with this program. If not, see
* http://www.gnu.org/licenses.
*
* Sonatype Nexus (TM) Open Source Version is available from Sonatype, Inc. Sonatype and Sonatype Nexus are trademarks of
* Sonatype, Inc. Apache Maven is a trademark of the Apache Foundation. M2Eclipse is a trademark of the Eclipse Foundation.
* All other trademarks are the property of their respective owners.
*/
package org.sonatype.nexus.proxy.maven.metadata.operations;
import java.util.ArrayList;
import java.util.List;
import org.apache.maven.artifact.repository.metadata.Metadata;
import org.apache.maven.artifact.repository.metadata.Plugin;
import org.apache.maven.artifact.repository.metadata.Snapshot;
import org.codehaus.plexus.util.StringUtils;
import org.sonatype.nexus.proxy.maven.metadata.operations.ModelVersionUtility.Version;
public class NexusMergeOperation
implements MetadataOperation
{
private Metadata sourceMetadata;
private Version sourceModelVersion;
public NexusMergeOperation( final MetadataOperand data )
throws MetadataException
{
setOperand( data );
}
/**
* always return true (known issue)
*/
public boolean perform( Metadata targetMetadata )
throws MetadataException
{
if ( sourceMetadata == null || targetMetadata == null )
{
return false;
}
// we first record the versioning.lastUpdated since it might be changed by MetadataOpersions
String lastUpdated = null;
if ( !hasLastUpdatedSet( sourceMetadata ) && !hasLastUpdatedSet( targetMetadata ) )
{
// neither has set, set it to now
lastUpdated = Long.toString( System.currentTimeMillis() );
}
else if ( !hasLastUpdatedSet( sourceMetadata ) && hasLastUpdatedSet( targetMetadata ) )
{
lastUpdated = targetMetadata.getVersioning().getLastUpdated();
}
else if ( !hasLastUpdatedSet( targetMetadata ) && hasLastUpdatedSet( sourceMetadata ) )
{
lastUpdated = sourceMetadata.getVersioning().getLastUpdated();
}
else if ( hasLastUpdatedSet( targetMetadata ) && hasLastUpdatedSet( sourceMetadata ) )
{
long sourceLU = -1;
long targetLU = -1;
try
{
sourceLU = Long.parseLong( sourceMetadata.getVersioning().getLastUpdated() );
}
catch ( NumberFormatException e )
{
// nothing, bad metadata
// TODO: we should do something here, but surely not die
}
try
{
targetLU = Long.parseLong( targetMetadata.getVersioning().getLastUpdated() );
}
catch ( NumberFormatException e )
{
// nothing, bad metadata
// TODO: we should do something here, but surely not die
}
lastUpdated = sourceLU >= targetLU ? Long.toString( sourceLU ) : Long.toString( targetLU );
}
List<MetadataOperation> ops = new ArrayList<MetadataOperation>();
// plugins
for ( Plugin plugin : sourceMetadata.getPlugins() )
{
ops.add( new AddPluginOperation( new PluginOperand( sourceModelVersion, plugin ) ) );
}
// gav
if ( targetMetadata.getGroupId() == null )
{
targetMetadata.setGroupId( sourceMetadata.getGroupId() );
}
if ( targetMetadata.getArtifactId() == null )
{
targetMetadata.setArtifactId( sourceMetadata.getArtifactId() );
}
if ( targetMetadata.getVersion() == null )
{
targetMetadata.setVersion( sourceMetadata.getVersion() );
}
if ( sourceMetadata.getGroupId() != null && targetMetadata.getGroupId() != null
&& !sourceMetadata.getGroupId().equals( targetMetadata.getGroupId() ) )
{
throw new MetadataException( "Could not merge metadata with different groupId: '"
+ sourceMetadata.getGroupId() + "' and '" + targetMetadata.getGroupId() + "'" );
}
if ( sourceMetadata.getArtifactId() != null && targetMetadata.getArtifactId() != null
&& !sourceMetadata.getArtifactId().equals( targetMetadata.getArtifactId() ) )
{
throw new MetadataException( "Could not merge metadata with different artifactId: '"
+ sourceMetadata.getArtifactId() + "' and '" + targetMetadata.getArtifactId() + "'" );
}
// versioning
if ( sourceMetadata.getVersioning() != null )
{
// versioning.verions
// merge all versions together
for ( String version : sourceMetadata.getVersioning().getVersions() )
{
ops.add( new AddVersionOperation( new StringOperand( sourceModelVersion, version ) ) );
}
// versioning.snapshot
// use the snapshot with newest timestamp
Snapshot sourceSnapshot = sourceMetadata.getVersioning().getSnapshot();
if ( sourceSnapshot != null )
{
long timestamp = -1;
if ( targetMetadata.getVersioning() != null && targetMetadata.getVersioning().getSnapshot() != null
&& targetMetadata.getVersioning().getSnapshot().getTimestamp() != null )
{
try
{
timestamp =
Long.parseLong( targetMetadata.getVersioning().getSnapshot().getTimestamp().replace( ".",
"" ) );
}
catch ( NumberFormatException e )
{
}
}
if ( sourceSnapshot.getTimestamp() != null )
{
long sourceTimestamp = -1;
try
{
sourceTimestamp = Long.parseLong( sourceSnapshot.getTimestamp().replace( ".", "" ) );
}
catch ( NumberFormatException e )
{
}
if ( sourceTimestamp > timestamp )
{
ops.add( new SetSnapshotOperation( new SnapshotOperand( sourceModelVersion,
sourceSnapshot.getTimestamp().replace( ".", "" ), sourceSnapshot,
sourceMetadata.getVersioning().getSnapshotVersions() ) ) );
}
}
}
}
MetadataBuilder.changeMetadata( targetMetadata, ops );
// versioning.lastUpdate
// choose the latest
if ( targetMetadata.getVersioning() != null && lastUpdated != null )
{
targetMetadata.getVersioning().setLastUpdated( lastUpdated );
}
return true;
}
public void setOperand( AbstractOperand data )
throws MetadataException
{
if ( data == null || !( data instanceof MetadataOperand ) )
{
throw new MetadataException( "Operand is not correct: expected MetadataOperand, but got "
+ ( data == null ? "null" : data.getClass().getName() ) );
}
sourceMetadata = ( (MetadataOperand) data ).getOperand();
sourceModelVersion = ( (MetadataOperand) data ).getOriginModelVersion();
}
// ==
protected boolean hasLastUpdatedSet( Metadata md )
{
return md.getVersioning() != null && StringUtils.isNotBlank( md.getVersioning().getLastUpdated() );
}
}