blob: 3cdac26866f8e5cb67484b5300eee8b4d4c8160c [file] [log] [blame]
package org.apache.archiva.web.action;
/*
* 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 com.opensymphony.xwork2.Preparable;
import com.opensymphony.xwork2.Validateable;
import org.apache.archiva.admin.model.beans.ManagedRepository;
import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
import org.apache.archiva.audit.AuditEvent;
import org.apache.archiva.audit.Auditable;
import org.apache.archiva.metadata.model.ArtifactMetadata;
import org.apache.archiva.metadata.repository.MetadataRepository;
import org.apache.archiva.metadata.repository.RepositorySession;
import org.apache.archiva.metadata.repository.filter.Filter;
import org.apache.archiva.metadata.repository.filter.IncludesFilter;
import org.apache.archiva.scheduler.repository.RepositoryArchivaTaskScheduler;
import org.apache.archiva.scheduler.repository.RepositoryTask;
import org.apache.archiva.stagerepository.merge.Maven2RepositoryMerger;
import org.codehaus.plexus.taskqueue.TaskQueueException;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
/**
*
*/
@Controller( "mergeAction" )
@Scope( "prototype" )
public class MergeAction
extends AbstractActionSupport
implements Validateable, Preparable, Auditable
{
@Inject
@Named( value = "repositoryMerger#maven2" )
private Maven2RepositoryMerger repositoryMerger;
@Inject
protected ManagedRepositoryAdmin managedRepositoryAdmin;
@Inject
@Named( value = "archivaTaskScheduler#repository" )
private RepositoryArchivaTaskScheduler repositoryTaskScheduler;
private ManagedRepository repository;
private String repoid;
private Collection<ArtifactMetadata> conflictSourceArtifactsToBeDisplayed;
private static String SESSION_KEY = "default";
public String requestMerge()
throws Exception
{
if ( !repository.isStagingRequired() )
{
addActionError( "Repository [" + repository.getId() + "] is not configured for staging" );
return ERROR;
}
// check for conflicts to display
HashMap<String, ArtifactMetadata> map = new LinkedHashMap<String, ArtifactMetadata>();
for ( ArtifactMetadata metadata : getConflictSourceArtifacts() )
{
String metadataId = metadata.getNamespace() + ":" + metadata.getProject() + ":" + metadata.getVersion();
map.put( metadataId, metadata );
}
conflictSourceArtifactsToBeDisplayed = map.values();
return "confirm";
}
public String doMerge()
{
return merge( true );
}
public String mergeBySkippingConflicts()
{
return merge( false );
}
private String merge( boolean overwriteConflicts )
{
// FIXME: stage repo should only need the repoid
String sourceRepoId = null;
RepositorySession repositorySession = repositorySessionFactory.createSession();
try
{
MetadataRepository metadataRepository = repositorySession.getRepository();
List<ArtifactMetadata> sourceArtifacts = metadataRepository.getArtifacts( sourceRepoId );
if ( !overwriteConflicts )
{
sourceArtifacts.removeAll( getConflictSourceArtifacts() );
Filter<ArtifactMetadata> artifactsWithOutConflicts = new IncludesFilter<ArtifactMetadata>(
sourceArtifacts );
repositoryMerger.merge( metadataRepository, sourceRepoId, repoid, artifactsWithOutConflicts );
}
else
{
repositoryMerger.merge( metadataRepository, sourceRepoId, repoid );
}
// FIXME: this should happen in the merge itself
for ( ArtifactMetadata metadata : sourceArtifacts )
{
triggerAuditEvent( repoid, metadata.getId(), AuditEvent.MERGING_REPOSITORIES );
}
// FIXME: this should happen in the merge itself, don't re-scan the whole thing. Make sure we test the
// results
scanRepository();
addActionMessage( "Repository '" + sourceRepoId + "' successfully merged to '" + repoid + "'." );
return SUCCESS;
}
catch ( Exception e )
{
log.error( e.getMessage(), e );
addActionError( "Error occurred while merging the repositories: " + e.getMessage() );
return ERROR;
}
finally
{
repositorySession.close();
}
}
public ManagedRepository getRepository()
{
return repository;
}
public void setRepository( ManagedRepository repository )
{
this.repository = repository;
}
public void prepare()
throws Exception
{
this.repository = managedRepositoryAdmin.getManagedRepository( repoid );
}
public String getRepoid()
{
return repoid;
}
public void setRepoid( String repoid )
{
this.repoid = repoid;
}
public List<ArtifactMetadata> getConflictSourceArtifacts()
throws Exception
{
RepositorySession repositorySession = repositorySessionFactory.createSession();
try
{
return repositoryMerger.getConflictingArtifacts( repositorySession.getRepository(), repoid );
}
finally
{
repositorySession.close();
}
}
public Collection<ArtifactMetadata> getConflictSourceArtifactsToBeDisplayed()
{
return conflictSourceArtifactsToBeDisplayed;
}
private Filter<ArtifactMetadata> filterOutSnapshots( List<ArtifactMetadata> sourceArtifacts, String repoid )
{
for ( Iterator<ArtifactMetadata> i = sourceArtifacts.iterator(); i.hasNext(); )
{
ArtifactMetadata metadata = i.next();
if ( metadata.getProjectVersion().contains( "SNAPSHOT" ) )
{
i.remove();
}
else
{
triggerAuditEvent( repoid, metadata.getId(), AuditEvent.MERGING_REPOSITORIES );
}
}
return new IncludesFilter<ArtifactMetadata>( sourceArtifacts );
}
private void scanRepository()
{
RepositoryTask task = new RepositoryTask();
task.setRepositoryId( repoid );
task.setScanAll( true );
if ( repositoryTaskScheduler.isProcessingRepositoryTask( repoid ) )
{
log.info( "Repository [" + repoid + "] task was already queued." );
}
else
{
try
{
log.info( "Your request to have repository [" + repoid + "] be indexed has been queued." );
repositoryTaskScheduler.queueTask( task );
}
catch ( TaskQueueException e )
{
log.warn(
"Unable to queue your request to have repository [" + repoid + "] be indexed: " + e.getMessage() );
}
}
}
public ManagedRepositoryAdmin getManagedRepositoryAdmin()
{
return managedRepositoryAdmin;
}
public void setManagedRepositoryAdmin( ManagedRepositoryAdmin managedRepositoryAdmin )
{
this.managedRepositoryAdmin = managedRepositoryAdmin;
}
}