merged MRM-980 branch to trunk

git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1002059 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Maria Odea B. Ching 2010-09-28 09:09:32 +00:00
parent 9baf9de1ce
commit e82ce0f0b5
78 changed files with 4601 additions and 140 deletions

View File

@ -18,5 +18,7 @@ Runtime Configuration of Apache Archiva
* {{{consumers.html} Configuring repository scanning and consumers}}
* {{{staging-repositories.html} Staging and merging repositories}}
[]

View File

@ -0,0 +1,59 @@
------
Staging Repositories
------
Staging Repositories
Starting with Archiva 1.4, staging repositories are supported. A staging repository is a repository you use
to stage a release (while it undergoes testing and voting), before the release is officially announced and published
to a releases repository where users can obtain it.
With the support of staging repositories comes the ability to merge repositories from the web UI. By merging, we mean
promoting the artifacts in the staging repository to the managed repository. In the current
implementation, a user with the System Administrator role can create and attach a staging repository to an existing
managed repository. An attached staging repository is a shadow of its managed repository, meaning they have the same
configuration.
We append <<-stage>> to the managed repository's ID to identify its staging repository. For example, repository
<<<test>>> would have a staging repository called <<<test-stage>>>.
If you're creating a new managed repository, just tick the <<<Create stage repository>>> check box. Otherwise, if
you already have an existing managed repository and you want to create a staging repository, just edit the managed
repository's configuration and tick the <<<Create stage repository>>> checkbox, then save the configuration. A staging
repository directory will be created beside (as a sibling of) the managed repository directory, again with -stage
appended to the name.
<<<Note:>>> By un-ticking the <<<Create stage repository>>> checkbox, the user can delete the attached staging
repository. If the managed repository is deleted, then its attached staging repository is also deleted.
The default <<<snapshots>>> and <<<internal>>> repositories do not have staging repositories configured by default,
however they can be added by editing the repository configuration.
* Populating the Staging Repository
The staging repository can be populated in the same way as a normal managed repository. You can configure your Maven
build's <<<distributionManagement>>> section to deploy to the repository, or use Archiva's web-based upload feature.
* Merging Repositories
To merge or promote the artifacts in a staging repository to the managed repository, just click the <<<Merge>>> button
in the repository configuration page.
[../images/repository-merge.png] Merge Button
Archiva will check for conflicting artifacts between the two repositories, and list them (if it finds conflicts).
The user will be asked to choose between two actions:
[[1]] <<<Merge All>>> - ignore all conflicting artifacts and perform merging for all.
[[2]] <<<Merge With Skip>>> - skip all conflicting artifacts and merge only the non-conflicting ones.
[]
[../images/conflicting-artifacts.png] Merge Actions
In future, we plan to enhance this by allowing a user to select only specific artifacts to merge.

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View File

@ -71,6 +71,7 @@
<item name="Network Proxies" href="/adminguide/network-proxies.html" />
<item name="Legacy (Maven 1) Support" href="/adminguide/legacy.html" />
<item name="Consumers" href="/adminguide/consumers.html" />
<item name="Staging Repositories" href="/adminguide/staging-repositories.html"/>
</item>
<item name="Configuration Files" href="/adminguide/configuration-files.html" />
<item name="Log Files" href="/adminguide/logging.html" collapse="true">

View File

@ -159,4 +159,8 @@ public class TestMetadataRepository
{
return null; //To change body of implemented methods use File | Settings | File Templates.
}
public List<ArtifactMetadata> getArtifacts(String repositoryId){
return null;
}
}

View File

@ -287,5 +287,10 @@ public class NewArtifactsRssFeedProcessorTest
{
this.artifactsByDateRange = artifactsByDateRange;
}
public List<ArtifactMetadata> getArtifacts( String repositoryId )
{
return artifactsByDateRange;
}
}
}

View File

@ -0,0 +1,101 @@
package org.apache.archiva.web.test;
/*
* 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.archiva.web.test.parent.AbstractMergingRepositoriesTest;
import org.testng.annotations.Test;
@Test(groups = {"merging"}, dependsOnMethods = {"testWithCorrectUsernamePassword"}, sequential = true)
public class MergingRepositoriesTest
extends AbstractMergingRepositoriesTest
{
public void testAddStagingRepository()
{
goToRepositoriesPage();
getSelenium().open( "/archiva/admin/addRepository.action" );
addStagingRepository( "merging-repo", "merging-repo", getRepositoryDir() + "merging-repo/", "",
"Maven 2.x Repository", "0 0 * * * ?", "", "" );
assertTextPresent( "merging-repo" );
}
// here we upload an artifact to the staging repository
@Test(dependsOnMethods = {"testAddStagingRepository"})
public void testAddArtifactToStagingRepository()
{
addArtifact( getGroupId(), getArtifactId(), getVersion(), getPackaging(), getValidArtifactFilePath(),
"merging-repo-stage" );
assertTextPresent( "Artifact '" + getGroupId() + ":" + getArtifactId() + ":" + getVersion() +
"' was successfully deployed to repository 'merging-repo-stage'" );
}
// here we test the merging (no conflicts artifacts are available)
@Test(dependsOnMethods = {"testAddArtifactToStagingRepository"})
public void testMerging()
{
goToRepositoriesPage();
clickButtonWithValue( "Merge" );
assertTextPresent( "No conflicting artifacts" );
clickButtonWithValue( "Merge All" );
assertTextPresent( "Repository 'merging-repo-stage' successfully merged to 'merging-repo'." );
}
// check audit updating is done properly or not
@Test(dependsOnMethods = {"testMerging"})
public void testAuditLogs()
{
goToAuditLogReports();
assertTextPresent( "Merged Artifact" );
assertTextPresent( "merging-repo" );
}
// merging is done by skipping conflicts
@Test(dependsOnMethods = {"testMerging"})
public void testMergingWithSkippingConflicts()
{
goToRepositoriesPage();
clickButtonWithValue( "Merge" );
assertTextPresent( "WARNING: The following are the artifacts in conflict." );
clickButtonWithValue( "Merge With Skip" );
assertTextPresent( "Repository 'merging-repo-stage' successfully merged to 'merging-repo'." );
}
// merging all
@Test(dependsOnMethods = {"testMerging"})
public void testMergingWithOutSkippingConflicts()
{
goToRepositoriesPage();
clickButtonWithValue( "Merge" );
assertTextPresent( "WARNING: The following are the artifacts in conflict." );
clickButtonWithValue( "Merge All" );
assertTextPresent( "Repository 'merging-repo-stage' successfully merged to 'merging-repo'." );
}
// change the configuaration first and try to upload existing artifact to the repository
public void testConfigurationChangesOfStagingRepository()
{
editManagedRepository();
addArtifact( getGroupId(), getArtifactId(), getVersion(), getPackaging(), getValidArtifactFilePath(),
"merging-repo-stage" );
assertTextPresent(
"Overwriting released artifacts in repository '" + "merging-repo-stage" + "' is not allowed." );
}
}

View File

@ -562,6 +562,23 @@ public abstract class AbstractArchivaTest
clickButtonWithValue( "Add Repository" );
}
// add managed repository and its staging repository
public void addStagingRepository( String identifier, String name, String directory, String indexDirectory,
String type, String cron, String daysOlder, String retentionCount )
{
setFieldValue( "repository.id", identifier );
setFieldValue( "repository.name", name );
setFieldValue( "repository.location", directory );
setFieldValue( "repository.indexDir", indexDirectory );
selectValue( "repository.layout", type );
setFieldValue( "repository.refreshCronExpression", cron );
setFieldValue( "repository.daysOlder", daysOlder );
setFieldValue( "repository.retentionCount", retentionCount );
checkField( "stageNeeded" );
clickButtonWithValue( "Add Repository" );
}
protected void logout()
{
clickLinkWithText( "Logout" );

View File

@ -0,0 +1,74 @@
package org.apache.archiva.web.test.parent;
/*
* 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 java.io.File;
public class AbstractMergingRepositoriesTest
extends AbstractArchivaTest
{
public void goToAuditLogReports()
{
getSelenium().open( "/archiva/report/queryAuditLogReport.action" );
}
public String getRepositoryDir()
{
File f = new File( "" );
String artifactFilePath = f.getAbsolutePath();
return artifactFilePath + "/target/";
}
public void editManagedRepository()
{
goToRepositoriesPage();
clickLinkWithXPath( "//div[@id='contentArea']/div/div[5]/div[1]/a[1]/img" );
assertPage( "Apache Archiva \\ Admin: Edit Managed Repository" );
checkField( "repository.blockRedeployments" );
clickButtonWithValue( "Update Repository" );
}
public String getGroupId()
{
return getProperty( "VALIDARTIFACT_GROUPID" );
}
public String getArtifactId()
{
return getProperty( "VALIDARTIFACT_ARTIFACTID" );
}
public String getVersion()
{
return getProperty( "VERSION" );
}
public String getPackaging()
{
return getProperty( "PACKAGING" );
}
public String getValidArtifactFilePath()
{
return "src/test/resources/snapshots/org/apache/maven/archiva/web/test/foo-bar/1.0-SNAPSHOT/foo-bar-1.0-SNAPSHOT.jar";
}
}

View File

@ -18,7 +18,8 @@
~ under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.archiva</groupId>
@ -82,6 +83,11 @@
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-lucene-consumers</artifactId>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>stage-repository-merge</artifactId>
<version>1.4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-signature-consumers</artifactId>
@ -278,7 +284,8 @@
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId> <!-- FIXME: temporary coupling to plugin, should be runtime -->
<groupId>org.apache.archiva</groupId>
<!-- FIXME: temporary coupling to plugin, should be runtime -->
<artifactId>maven2-repository</artifactId>
</dependency>
</dependencies>
@ -307,7 +314,7 @@
</excludes>
</configuration>
</plugin>
-->
-->
<!-- hack for jetty:run, archiva web config files are checked in /WEB-INF/ dir -->
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
@ -320,9 +327,9 @@
<phase>compile</phase>
<configuration>
<tasks>
<mkdir dir="${basedir}/target/archiva/WEB-INF/" />
<mkdir dir="${basedir}/target/archiva/WEB-INF/"/>
<copy todir="${basedir}/target/archiva/WEB-INF/">
<fileset dir="${basedir}/target" includes="classes/" excludes="**/struts.xml" />
<fileset dir="${basedir}/target" includes="classes/" excludes="**/struts.xml"/>
</copy>
</tasks>
</configuration>
@ -335,7 +342,7 @@
<configuration>
<tasks>
<copy todir="${basedir}/appserver-base">
<fileset dir="src/appserver-base" />
<fileset dir="src/appserver-base"/>
</copy>
</tasks>
</configuration>
@ -348,21 +355,21 @@
<execution>
<id>unpack-redback-war</id>
<goals>
<goal>unpack</goal>
<goal>unpack</goal>
</goals>
<phase>compile</phase>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.codehaus.redback</groupId>
<artifactId>redback-struts2-content</artifactId>
<version>${redback.version}</version>
<type>war</type>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/redback</outputDirectory>
<excludes>**/struts-security.xml</excludes>
</artifactItem>
</artifactItems>
<artifactItems>
<artifactItem>
<groupId>org.codehaus.redback</groupId>
<artifactId>redback-struts2-content</artifactId>
<version>${redback.version}</version>
<type>war</type>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/redback</outputDirectory>
<excludes>**/struts-security.xml</excludes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
@ -375,9 +382,12 @@
<!-- Some versions of maven-war-plugin (snapshots) have this incorrectly defaulted to true.
Specifically setting this to false to avoid accidental jar file creation. -->
<archiveClasses>false</archiveClasses>
<dependentWarExcludes>META-INF/**,WEB-INF/web.xml,WEB-INF/classes/xwork.xml,WEB-INF/lib/**</dependentWarExcludes>
<warSourceExcludes>WEB-INF/lib/xalan-*.jar,WEB-INF/lib/velocity-dep-*.jar,WEB-INF/lib/xml-apis-*.jar,WEB-INF/lib/wstx-asl-*.jar,WEB-INF/lib/stax-utils-*.jar,WEB-INF/lib/xercesImpl-*.jar</warSourceExcludes>
</configuration>
<dependentWarExcludes>META-INF/**,WEB-INF/web.xml,WEB-INF/classes/xwork.xml,WEB-INF/lib/**
</dependentWarExcludes>
<warSourceExcludes>
WEB-INF/lib/xalan-*.jar,WEB-INF/lib/velocity-dep-*.jar,WEB-INF/lib/xml-apis-*.jar,WEB-INF/lib/wstx-asl-*.jar,WEB-INF/lib/stax-utils-*.jar,WEB-INF/lib/xercesImpl-*.jar
</warSourceExcludes>
</configuration>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>

View File

@ -0,0 +1,289 @@
package org.apache.maven.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.Validateable;
import com.opensymphony.xwork2.Preparable;
import org.apache.archiva.audit.Auditable;
import org.apache.archiva.audit.AuditEvent;
import org.apache.archiva.stagerepository.merge.Maven2RepositoryMerger;
import org.apache.archiva.metadata.model.ArtifactMetadata;
import org.apache.archiva.metadata.repository.filter.Filter;
import org.apache.archiva.metadata.repository.filter.IncludesFilter;
import org.apache.archiva.metadata.repository.MetadataRepository;
import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.web.action.admin.SchedulerAction;
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
/**
* @plexus.component role="com.opensymphony.xwork2.Action" role-hint="mergeAction" instantiation-strategy="per-lookup"
*/
public class
MergeAction
extends PlexusActionSupport
implements Validateable, Preparable, Auditable
{
/**
* @plexus.requirement role="org.apache.archiva.stagerepository.merge.RepositoryMerger" role-hint="maven2"
*/
private Maven2RepositoryMerger repositoryMerger;
/**
* @plexus.requirement
*/
protected ArchivaConfiguration archivaConfiguration;
/**
* @plexus.requirement role-hint="default"
*/
private MetadataRepository metadataRepository;
/**
* @plexus.requirement role="com.opensymphony.xwork2.Action" role-hint="schedulerAction"
*/
private SchedulerAction scheduler;
private ManagedRepositoryConfiguration repository;
private String repoid;
private String sourceRepoId;
private final String action = "merge";
private final String hasConflicts = "CONFLICTS";
private List<ArtifactMetadata> conflictSourceArtifacts;
private List<ArtifactMetadata> conflictSourceArtifactsToBeDisplayed;
public String getConflicts()
{
sourceRepoId = repoid + "-stage";
Configuration config = archivaConfiguration.getConfiguration();
ManagedRepositoryConfiguration targetRepoConfig = config.findManagedRepositoryById( sourceRepoId );
if ( targetRepoConfig != null )
{
return hasConflicts;
}
else
{
return ERROR;
}
}
public String doMerge()
throws Exception
{
try
{
List<ArtifactMetadata> sourceArtifacts = metadataRepository.getArtifacts( sourceRepoId );
if ( repository.isReleases() && !repository.isSnapshots() )
{
mergeWithOutSnapshots( sourceArtifacts, sourceRepoId, repoid );
}
else
{
repositoryMerger.merge( sourceRepoId, repoid );
for ( ArtifactMetadata metadata : sourceArtifacts )
{
triggerAuditEvent( repoid, metadata.getId(), AuditEvent.MERGING_REPOSITORIES );
}
}
scheduler.scanRepository();
addActionMessage( "Repository '" + sourceRepoId + "' successfully merged to '" + repoid + "'." );
return SUCCESS;
}
catch ( Exception ex )
{
ex.printStackTrace();
addActionError( "Error occurred while merging the repositories." );
return ERROR;
}
}
public String mergeBySkippingConflicts()
{
try
{
List<ArtifactMetadata> sourceArtifacts = metadataRepository.getArtifacts( sourceRepoId );
sourceArtifacts.removeAll( conflictSourceArtifacts );
if ( repository.isReleases() && !repository.isSnapshots() )
{
mergeWithOutSnapshots( sourceArtifacts, sourceRepoId, repoid );
}
else
{
Filter<ArtifactMetadata> artifactsWithOutConflicts =
new IncludesFilter<ArtifactMetadata>( sourceArtifacts );
repositoryMerger.merge( sourceRepoId, repoid, artifactsWithOutConflicts );
for ( ArtifactMetadata metadata : sourceArtifacts )
{
triggerAuditEvent( repoid, metadata.getId(), AuditEvent.MERGING_REPOSITORIES );
}
}
scheduler.scanRepository();
addActionMessage( "Repository '" + sourceRepoId + "' successfully merged to '" + repoid + "'." );
return SUCCESS;
}
catch ( Exception ex )
{
ex.printStackTrace();
addActionError( "Error occurred while merging the repositories." );
return ERROR;
}
}
public String mergeWithOutConlficts()
{
sourceRepoId = repoid + "-stage";
try
{
conflictSourceArtifacts = repositoryMerger.getConflictsartifacts( sourceRepoId, repoid );
}
catch ( Exception e )
{
addActionError( "Error occurred while merging the repositories." );
return ERROR;
}
addActionMessage( "Repository '" + sourceRepoId + "' successfully merged to '" + repoid + "'." );
return SUCCESS;
}
public ManagedRepositoryConfiguration getRepository()
{
return repository;
}
public void setRepository( ManagedRepositoryConfiguration repository )
{
this.repository = repository;
}
public void prepare()
throws Exception
{
sourceRepoId = repoid + "-stage";
conflictSourceArtifacts = repositoryMerger.getConflictsartifacts( sourceRepoId, repoid );
this.scheduler.setRepoid( repoid );
Configuration config = archivaConfiguration.getConfiguration();
this.repository = config.findManagedRepositoryById( repoid );
setConflictSourceArtifactsToBeDisplayed( conflictSourceArtifacts );
}
public String getSourceRepoId()
{
return sourceRepoId;
}
public void setSourceRepoId( String sourceRepoId )
{
this.sourceRepoId = sourceRepoId;
}
public String getRepoid()
{
return repoid;
}
public void setRepoid( String repoid )
{
this.repoid = repoid;
}
public List<ArtifactMetadata> getConflictSourceArtifacts()
{
return conflictSourceArtifacts;
}
public void setConflictSourceArtifacts( List<ArtifactMetadata> conflictSourceArtifacts )
{
this.conflictSourceArtifacts = conflictSourceArtifacts;
}
public List<ArtifactMetadata> getConflictSourceArtifactsToBeDisplayed()
{
return conflictSourceArtifactsToBeDisplayed;
}
public void setConflictSourceArtifactsToBeDisplayed( List<ArtifactMetadata> conflictSourceArtifacts )
throws Exception
{
this.conflictSourceArtifactsToBeDisplayed = new ArrayList<ArtifactMetadata>();
HashMap<String, ArtifactMetadata> map = new HashMap<String, ArtifactMetadata>();
for ( ArtifactMetadata metadata : conflictSourceArtifacts )
{
String metadataId =
metadata.getNamespace() + metadata.getProject() + metadata.getProjectVersion() + metadata.getVersion();
map.put( metadataId, metadata );
}
Iterator iterator = map.keySet().iterator();
while ( iterator.hasNext() )
{
conflictSourceArtifactsToBeDisplayed.add( map.get( iterator.next() ) );
}
}
private void mergeWithOutSnapshots( List<ArtifactMetadata> sourceArtifacts, String sourceRepoId, String repoid )
throws Exception
{
List<ArtifactMetadata> artifactsWithOutSnapshots = new ArrayList<ArtifactMetadata>();
for ( ArtifactMetadata metadata : sourceArtifacts )
{
if ( metadata.getProjectVersion().contains( "SNAPSHOT" ) )
{
artifactsWithOutSnapshots.add( metadata );
}
else
{
triggerAuditEvent( repoid, metadata.getId(), AuditEvent.MERGING_REPOSITORIES );
}
}
sourceArtifacts.removeAll( artifactsWithOutSnapshots );
Filter<ArtifactMetadata> artifactListWithOutSnapShots = new IncludesFilter<ArtifactMetadata>( sourceArtifacts );
repositoryMerger.merge( sourceRepoId, repoid, artifactListWithOutSnapShots );
}
}

View File

@ -45,7 +45,9 @@ public class AddManagedRepositoryAction
* The model for this action.
*/
private ManagedRepositoryConfiguration repository;
private boolean stageNeeded;
private String action = "addRepository";
public void prepare()
@ -64,42 +66,53 @@ public class AddManagedRepositoryAction
return INPUT;
}
public String confirmAdd()
{
return save();
}
public String commit()
{
File location = new File( repository.getLocation() );
if( location.exists() )
{
{
return CONFIRM;
}
return save();
}
private String save()
{
Configuration configuration = archivaConfiguration.getConfiguration();
String result;
try
{
addRepository( repository, configuration );
triggerAuditEvent( repository.getId(), null, AuditEvent.ADD_MANAGED_REPO );
addRepositoryRoles( repository );
if ( stageNeeded )
{
ManagedRepositoryConfiguration stagingRepository = getStageRepoConfig();
addRepository( stagingRepository, configuration );
triggerAuditEvent( stagingRepository.getId(), null, AuditEvent.ADD_MANAGED_REPO );
addRepositoryRoles( stagingRepository );
}
result = saveConfiguration( configuration );
}
catch ( RoleManagerException e )
{
{
addActionError( "Role Manager Exception: " + e.getMessage() );
result = INPUT;
}
catch ( IOException e )
{
{
addActionError( "Role Manager Exception: " + e.getMessage() );
result = INPUT;
}
@ -107,6 +120,27 @@ public class AddManagedRepositoryAction
return result;
}
private ManagedRepositoryConfiguration getStageRepoConfig()
{
ManagedRepositoryConfiguration stagingRepository = new ManagedRepositoryConfiguration();
stagingRepository.setId( repository.getId() + "-stage" );
stagingRepository.setLayout( repository.getLayout() );
stagingRepository.setName( repository.getName() + "-stage" );
stagingRepository.setBlockRedeployments( repository.isBlockRedeployments() );
stagingRepository.setDaysOlder( repository.getDaysOlder() );
stagingRepository.setDeleteReleasedSnapshots( repository.isDeleteReleasedSnapshots() );
stagingRepository.setIndexDir( repository.getIndexDir() );
String path = repository.getLocation();
int lastIndex = path.lastIndexOf( '/' );
stagingRepository.setLocation( path.substring( 0, lastIndex ) + "/" + stagingRepository.getId() );
stagingRepository.setRefreshCronExpression( repository.getRefreshCronExpression() );
stagingRepository.setReleases( repository.isReleases() );
stagingRepository.setRetentionCount( repository.getRetentionCount() );
stagingRepository.setScanned( repository.isScanned() );
stagingRepository.setSnapshots( repository.isSnapshots() );
return stagingRepository;
}
@Override
public void validate()
{
@ -130,7 +164,12 @@ public class AddManagedRepositoryAction
addFieldError( "repository.id", "Unable to add new repository with id [" + repoId
+ "], that id already exists as a repository group." );
}
else if ( repoId.toLowerCase().contains( "stage" ) )
{
addFieldError( "repository.id", "Unable to add new repository with id [" + repoId +
"], rpository id cannot contains word stage" );
}
if ( !validator.validate( repository.getRefreshCronExpression() ) )
{
addFieldError( "repository.refreshCronExpression", "Invalid cron expression." );
@ -146,6 +185,12 @@ public class AddManagedRepositoryAction
{
this.repository = repository;
}
public void setStageNeeded( boolean stageNeeded )
{
this.stageNeeded = stageNeeded;
}
public String getAction()
{

View File

@ -45,6 +45,8 @@ public class DeleteManagedRepositoryAction
{
private ManagedRepositoryConfiguration repository;
private ManagedRepositoryConfiguration stagingRepository;
private String repoid;
/**
@ -62,6 +64,7 @@ public class DeleteManagedRepositoryAction
if ( StringUtils.isNotBlank( repoid ) )
{
this.repository = archivaConfiguration.getConfiguration().findManagedRepositoryById( repoid );
this.stagingRepository = archivaConfiguration.getConfiguration().findManagedRepositoryById( repoid +"-stage");
}
}
@ -87,8 +90,9 @@ public class DeleteManagedRepositoryAction
}
private String deleteRepository( boolean deleteContents )
{
{
ManagedRepositoryConfiguration existingRepository = repository;
ManagedRepositoryConfiguration attachedStagingRepo = stagingRepository;
if ( existingRepository == null )
{
addActionError( "A repository with that id does not exist" );
@ -103,12 +107,23 @@ public class DeleteManagedRepositoryAction
cleanupRepositoryData( existingRepository );
removeRepository( repoid, configuration );
triggerAuditEvent( repoid, null, AuditEvent.DELETE_MANAGED_REPO );
if(attachedStagingRepo !=null)
{
cleanupRepositoryData( attachedStagingRepo );
removeRepository( repoid +"-stage", configuration );
triggerAuditEvent(repoid +"-stage", null, AuditEvent.DELETE_MANAGED_REPO );
}
result = saveConfiguration( configuration );
if ( result.equals( SUCCESS ) )
{
if ( deleteContents )
{
if(attachedStagingRepo !=null)
{
removeContents( attachedStagingRepo );
}
removeContents( existingRepository );
}
}
@ -154,7 +169,7 @@ public class DeleteManagedRepositoryAction
{
archivaConfiguration.getConfiguration().findRepositoryGroupById( repoGroup ).removeRepository( cleanupRepository.getId() );
}
}
}
}
}

View File

@ -47,10 +47,14 @@ public class EditManagedRepositoryAction
*/
private ManagedRepositoryConfiguration repository;
private ManagedRepositoryConfiguration stagingRepository;
private String repoid;
private final String action = "editRepository";
private boolean stageNeeded;
/**
* @plexus.requirement
*/
@ -61,6 +65,7 @@ public class EditManagedRepositoryAction
if ( StringUtils.isNotBlank( repoid ) )
{
repository = archivaConfiguration.getConfiguration().findManagedRepositoryById( repoid );
stagingRepository = archivaConfiguration.getConfiguration().findManagedRepositoryById( repoid + "-stage" );
}
else if ( repository != null )
{
@ -90,7 +95,6 @@ public class EditManagedRepositoryAction
{
ManagedRepositoryConfiguration existingConfig =
archivaConfiguration.getConfiguration().findManagedRepositoryById( repository.getId() );
boolean resetStats = false;
// check if the location was changed
@ -115,6 +119,10 @@ public class EditManagedRepositoryAction
// We are in edit mode, remove the old repository configuration.
removeRepository( repository.getId(), configuration );
if ( stagingRepository != null )
{
removeRepository( stagingRepository.getId(), configuration );
}
// Save the repository configuration.
String result;
@ -123,6 +131,25 @@ public class EditManagedRepositoryAction
addRepository( repository, configuration );
triggerAuditEvent( repository.getId(), null, AuditEvent.MODIFY_MANAGED_REPO );
addRepositoryRoles( repository );
//update changes of the staging repo
if ( stageNeeded )
{
stagingRepository = getStageRepoConfig( configuration );
addRepository( stagingRepository, configuration );
addRepositoryRoles( stagingRepository );
}
//delete staging repo when we dont need it
if ( !stageNeeded )
{
stagingRepository = getStageRepoConfig(configuration);
removeRepository( stagingRepository.getId(), configuration );
removeContents( stagingRepository );
removeRepositoryRoles( stagingRepository );
}
result = saveConfiguration( configuration );
if ( resetStats )
{
@ -143,6 +170,44 @@ public class EditManagedRepositoryAction
return result;
}
private ManagedRepositoryConfiguration getStageRepoConfig( Configuration configuration )
{
for ( ManagedRepositoryConfiguration repoConf : configuration.getManagedRepositories() )
{
if ( repoConf.getId().equals( repository.getId() + "-stage" ) )
{
stagingRepository = repoConf;
removeRepository( repoConf .getId() , configuration);
updateStagingRepository( stagingRepository );
return stagingRepository;
}
}
stagingRepository = new ManagedRepositoryConfiguration();
updateStagingRepository( stagingRepository );
return stagingRepository;
}
private void updateStagingRepository( ManagedRepositoryConfiguration stagingRepository )
{
stagingRepository.setId( repository.getId() + "-stage" );
stagingRepository.setLayout( repository.getLayout() );
stagingRepository.setName( repository.getName() + "-stage" );
stagingRepository.setBlockRedeployments( repository.isBlockRedeployments() );
stagingRepository.setDaysOlder( repository.getDaysOlder() );
stagingRepository.setDeleteReleasedSnapshots( repository.isDeleteReleasedSnapshots() );
stagingRepository.setIndexDir( repository.getIndexDir() );
String path = repository.getLocation();
int lastIndex = path.lastIndexOf( '/' );
stagingRepository.setLocation( path.substring( 0, lastIndex ) + "/" + stagingRepository.getId() );
stagingRepository.setRefreshCronExpression( repository.getRefreshCronExpression() );
stagingRepository.setReleases( repository.isReleases() );
stagingRepository.setRetentionCount( repository.getRetentionCount() );
stagingRepository.setScanned( repository.isScanned() );
stagingRepository.setSnapshots( repository.isSnapshots() );
}
@Override
public void validate()
{
@ -157,7 +222,7 @@ public class EditManagedRepositoryAction
private void resetStatistics()
{
repositoryStatisticsManager.deleteStatistics( repository.getId() );
}
}
public String getRepoid()
{
@ -179,6 +244,16 @@ public class EditManagedRepositoryAction
this.repository = repository;
}
public boolean isStageNeeded()
{
return stageNeeded;
}
public void setStageNeeded( boolean stageNeeded )
{
this.stageNeeded = stageNeeded;
}
public String getAction()
{
return action;
@ -188,4 +263,14 @@ public class EditManagedRepositoryAction
{
this.repositoryStatisticsManager = repositoryStatisticsManager;
}
public ManagedRepositoryConfiguration getStagingRepository()
{
return stagingRepository;
}
public void setStagingRepository( ManagedRepositoryConfiguration stagingRepository )
{
this.stagingRepository = stagingRepository;
}
}

View File

@ -93,7 +93,7 @@ public class RepositoriesAction
return bundle;
}
@SuppressWarnings("unchecked")
@SuppressWarnings( "unchecked" )
public void prepare()
{
Configuration config = archivaConfiguration.getConfiguration();
@ -118,7 +118,15 @@ public class RepositoriesAction
public List<ManagedRepositoryConfiguration> getManagedRepositories()
{
return managedRepositories;
List<ManagedRepositoryConfiguration> managedRepositoriesList = new ArrayList<ManagedRepositoryConfiguration>();
for ( ManagedRepositoryConfiguration repoConfig : managedRepositories )
{
if ( !repoConfig.getId().contains( "stage" ) )
{
managedRepositoriesList.add( repoConfig );
}
}
return managedRepositoriesList;
}
public List<RemoteRepositoryConfiguration> getRemoteRepositories()

View File

@ -19,7 +19,7 @@
-->
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!-- Include plexus-security xwork configurations. -->
@ -124,10 +124,10 @@
include a result for 'error' -->
<result name="error">/WEB-INF/jsp/generalError.jsp</result>
<result name="access_to_no_repos">/WEB-INF/jsp/accessToNoRepos.jsp</result>
</global-results>
</package>
<!-- Configuration for the default package. -->
<package name="default" extends="base" namespace="/">
@ -147,7 +147,7 @@
<result>/WEB-INF/jsp/results.jsp</result>
<result name="error">/WEB-INF/jsp/quickSearch.jsp</result>
</action>
<action name="quickSearch" class="searchAction" method="quickSearch">
<result name="input">/WEB-INF/jsp/quickSearch.jsp</result>
<result>/WEB-INF/jsp/results.jsp</result>
@ -158,7 +158,7 @@
<result name="input">/WEB-INF/jsp/findArtifact.jsp</result>
</action>
<action name="upload" class="uploadAction" method="input">
<action name="upload" class="uploadAction" method="input">
<result name="input">/WEB-INF/jsp/upload.jsp</result>
<result name="error">/WEB-INF/jsp/upload.jsp</result>
<result name="success">/WEB-INF/jsp/upload.jsp</result>
@ -166,7 +166,7 @@
<interceptor-ref name="fileUpload"/>
</action>
<action name="deleteArtifact" class="deleteArtifactAction" method="input">
<action name="deleteArtifact" class="deleteArtifactAction" method="input">
<result name="input">/WEB-INF/jsp/deleteArtifact.jsp</result>
<result name="error">/WEB-INF/jsp/deleteArtifact.jsp</result>
<result name="success">/WEB-INF/jsp/deleteArtifact.jsp</result>
@ -179,7 +179,7 @@
<result name="artifact" type="redirect">
/browse/${databaseResults.get(0).getNamespace()}/${databaseResults.get(0).getProject()}/${databaseResults.get(0).getVersion()}
</result>
</action>
</action>
<action name="browse" class="browseAction" method="browse">
<result>/WEB-INF/jsp/browse.jsp</result>
@ -222,7 +222,7 @@
<result>/WEB-INF/jsp/showArtifact.jsp</result>
</action>
<action name="addMetadataProperty" class="showArtifactAction" method="addMetadataProperty">
<action name="addMetadataProperty" class="showArtifactAction" method="addMetadataProperty">
<result name="input">/WEB-INF/jsp/showArtifact.jsp</result>
<result name="success">/WEB-INF/jsp/showArtifact.jsp</result>
</action>
@ -247,53 +247,53 @@
<action name="index" class="repositoriesAction" method="input">
<result name="input">/WEB-INF/jsp/admin/repositories.jsp</result>
</action>
<!-- .\ REPOSITORY GROUPS \._______________________________________ -->
<action name="repositoryGroups" class="repositoryGroupsAction" method="input">
<result name="input">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
</action>
<action name="addRepositoryGroup" class="repositoryGroupsAction" method="addRepositoryGroup">
<result name="input">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
<result name="error">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
<result name="success" type="redirect-action">repositoryGroups</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>
<action name="confirmDeleteRepositoryGroup" class="deleteRepositoryGroupAction" method="confirmDelete">
<result name="input">/WEB-INF/jsp/admin/deleteRepositoryGroup.jsp</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>
<action name="deleteRepositoryGroup" class="deleteRepositoryGroupAction" method="delete">
<result name="input">/WEB-INF/jsp/admin/deleteRepositoryGroup.jsp</result>
<result name="error">/WEB-INF/jsp/admin/deleteRepositoryGroup.jsp</result>
<result name="success" type="redirect-action">repositoryGroups</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>
<action name="addRepositoryToGroup" class="repositoryGroupsAction" method="addRepositoryToGroup">
<result name="input">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
<result name="error">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
<result name="success" type="redirect-action">repositoryGroups</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>
<action name="removeRepositoryFromGroup" class="repositoryGroupsAction" method="removeRepositoryFromGroup">
<result name="input">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
<result name="error">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
<result name="success" type="redirect-action">repositoryGroups</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>
<action name="sortDownRepositoryFromGroup" class="sortRepositoriesAction" method="sortDown">
<result name="input">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
<result name="error">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
<result name="success" type="redirect-action">repositoryGroups</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>
<action name="sortUpRepositoryFromGroup" class="sortRepositoriesAction" method="sortUp">
<result name="input">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
<result name="error">/WEB-INF/jsp/admin/repositoryGroups.jsp</result>
@ -311,7 +311,7 @@
<action name="indexRepository" class="schedulerAction" method="scanRepository">
<result type="redirect-action">repositories</result>
</action>
<action name="addRepository" class="addManagedRepositoryAction" method="input">
<result name="input">/WEB-INF/jsp/admin/addRepository.jsp</result>
<result name="error">/WEB-INF/jsp/admin/addRepository.jsp</result>
@ -359,7 +359,14 @@
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>
<action name="deleteRemoteRepository" class="deleteRemoteRepositoryAction" method="delete">
<action name="merge" class="mergeAction" method="getConflicts">
<result name="CONFLICTS">/WEB-INF/jsp/admin/mergeExcludeConflicts.jsp</result>
<result name="success">/WEB-INF/jsp/admin/mergeResults.jsp</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>
<action name="deleteRemoteRepository" class="deleteRemoteRepositoryAction" method="input">
<result name="input">/WEB-INF/jsp/admin/deleteRemoteRepository.jsp</result>
<result name="error">/WEB-INF/jsp/admin/deleteRemoteRepository.jsp</result>
<result name="success" type="redirect-action">repositories</result>
@ -401,7 +408,7 @@
<result name="success" type="redirect-action">proxyConnectors</result>
<interceptor-ref name="configuredPrepareParamsStack"/>
</action>
<action name="enableProxyConnector" class="enableProxyConnectorAction" method="confirm">
<result name="input">/WEB-INF/jsp/admin/enableProxyConnector.jsp</result>
<result name="success" type="redirect-action">proxyConnectors</result>
@ -507,13 +514,13 @@
<result name="blank">/WEB-INF/jsp/reports/blankReport.jsp</result>
<result>/WEB-INF/jsp/reports/basicReport.jsp</result>
</action>
<action name="generateStatisticsReport" class="generateReport" method="generateStatistics">
<result name="input">/WEB-INF/jsp/reports/pickReport.jsp</result>
<result name="blank">/WEB-INF/jsp/reports/blankReport.jsp</result>
<result>/WEB-INF/jsp/reports/statisticsReport.jsp</result>
</action>
<!-- TODO: make report filename dynamic -->
<action name="downloadStatsReport" class="generateReport" method="downloadStatisticsReport">
<result name="input">/WEB-INF/jsp/reports/pickReport.jsp</result>
@ -523,17 +530,17 @@
<param name="contentDisposition">attachment; filename="archiva_statistics_report.csv"</param>
</result>
</action>
<!-- audit logs -->
<action name="queryAuditLogReport" class="viewAuditLogReport" method="input">
<result name="input">/WEB-INF/jsp/reports/auditLogReport.jsp</result>
</action>
<action name="viewAuditLogReport" class="viewAuditLogReport">
<result name="input">/WEB-INF/jsp/reports/auditLogReport.jsp</result>
<result>/WEB-INF/jsp/reports/auditLogReport.jsp</result>
</action>
</package>
</struts>

View File

@ -36,6 +36,7 @@
<s:form method="post" action="addRepository!commit" namespace="/admin" validate="true">
<s:textfield name="repository.id" label="Identifier" size="10" required="true"/>
<%@ include file="/WEB-INF/jsp/admin/include/repositoryForm.jspf" %>
<s:checkbox name="stageNeeded" value="stageNeeded" label="Create stage repository"/>
<s:submit value="Add Repository"/>
</s:form>

View File

@ -39,6 +39,17 @@
<s:hidden name="repository.id"/>
<s:label label="ID" name="repository.id" />
<%@ include file="/WEB-INF/jsp/admin/include/repositoryForm.jspf" %>
<c:set var="stats" value="${stagingRepository == null}"/>
<jsp:useBean id="stats" type="java.lang.Boolean" scope="page"/>
<c:if
test='<%= !stats.booleanValue() %>'>
<s:checkbox name="stageNeeded" value="true" label="Create stage repository"/>
</c:if>
<c:if
test='<%= stats.booleanValue() %>'>
<s:checkbox id="stageNeeded" name="stageNeeded" value="false" label="Create stage repository"/>
</c:if>
<s:submit value="Update Repository"/>
</s:form>

View File

@ -34,5 +34,3 @@
<s:checkbox name="repository.scanned" value="repository.scanned" label="Scannable"/>
<s:checkbox name="repository.deleteReleasedSnapshots" value="repository.deleteReleasedSnapshots"
label="Delete Released Snapshots"/>

View File

@ -0,0 +1,114 @@
<%--
~ 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.
--%>
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Admin: Merge Staging Repository</title>
<s:head/>
</head>
<body>
<h1>Admin: Merge Staging Repository</h1>
<p>
Are you sure you want to merge the repository?
</p>
<div class="infobox">
<table class="infotable">
<c:choose>
<c:when test="${empty (conflictSourceArtifacts)}">
<h1>No conflicting artifacts</h1>
<c:if test="${!repository.snapshots and repository.releases}">
<div class="warningbox">
<p>
<strong>WARNING: Repository "${repoid}" does not allow to merge snapshots</strong>
</p>
</div>
</c:if>
<s:form method="post" action="merge" namespace="/admin" validate="false" theme="simple">
<s:hidden name="repoid"/>
<div class="buttons">
<s:submit value="Merge All" method="doMerge"/>
</div>
</s:form>
</c:when>
<c:otherwise>
<div class="warningbox">
<c:if test="${!repository.snapshots and repository.releases}">
<p>
<strong>WARNING: Repository "${repoid}" does not allow to merge snapshots</strong>
</p>
</c:if>
<p>
<strong>WARNING: The following are the artifacts in conflict.</strong>
</p>
</div>
<c:forEach items="${conflictSourceArtifactsToBeDisplayed}" var="artifact">
<tr>
<td>Artifact Id :</td>
<%--<td><code>${artifact.id}</code></td>--%>
<td align="left"> <code>${artifact.namespace} ${" "} ${artifact.project} ${" "} ${artifact.version}</code></td>
</tr>
</c:forEach>
<tr>
<td>
<s:form action="merge" method="post" namespace="/admin" validate="false">
<s:hidden name="repoid"/>
<div class="buttons">
<table>
<tr>
<td>
<table>
<tr>
<td>
<s:submit value="Merge All" method="doMerge"/>
</td>
</tr>
</table>
</td>
<td>
<table>
<tr>
<td>
<s:submit value="Merge With Skip" method="mergeBySkippingConflicts"/>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</s:form>
</td>
</tr>
</c:otherwise>
</c:choose>
</table>
</div>
</body>
</html>

View File

@ -0,0 +1,42 @@
<%--
~ 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.
--%>
<%-- http://www.opensymphony.com/webwork/wikidocs/File%20Upload%20Interceptor.html --%>
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Admin: Merge Staging Repository</title>
<s:head/>
</head>
<body>
<h1>Admin: Merge Staging Repository</h1>
<div id="contentArea">
<s:actionerror/>
<s:actionmessage/>
</div>
</body>
</html>

View File

@ -1,21 +1,22 @@
<%@ page import="java.io.File" %>
<%--
~ 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.
--%>
~ 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.
--%>
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
@ -30,7 +31,7 @@
<script type="text/javascript" src="<c:url value='/js/jquery-1.3.2.min.js'/>"></script>
<script type="text/javascript">
$(document).ready(function(){
$(".pom").hide();
$("a.expand").click(function(event){
event.preventDefault();
@ -158,7 +159,7 @@
<th>Groups</th>
<td>
<c:forEach items="${repositoryToGroupMap[repository.id]}" varStatus="i" var="group">
${group}<c:if test="${!i.last}">,</c:if>
${group}<c:if test="${!i.last}">,</c:if>
</c:forEach>
</td>
</tr>
@ -213,7 +214,7 @@
</s:form>
</redback:ifAuthorized>
</td>
</tr>
</tr>
<tr>
<th>Stats</th>
<td>
@ -252,6 +253,47 @@
<archiva:copy-paste-snippet object="${repository}" wrapper="toggle" />
</td>
</tr>
<c:set var="str" value="${repository.id}" />
<jsp:useBean id="str" type="java.lang.String" scope="page"/>
<c:set var="location" value="${repository.location}"/>
<jsp:useBean id="location" type="java.lang.String" scope="page"/>
<c:if
test='<%= !( (str.equalsIgnoreCase("internal") ) || (str.equalsIgnoreCase( "snapshots" )) ) &&
new File (new File(location ).getParent() ,str + "-stage" ).exists()%>'>
<tr>
<th>
stage repository location
</th>
<td>
${repository.location}${'-stage'}
</td>
</tr>
<tr>
<th>Merge Actions</th>
<td>
<redback:ifAuthorized permission="archiva-run-indexer">
<s:form action="merge" theme="simple">
<s:hidden name="repoid" value="%{#attr.repository.id}"/>
<%--<s:hidden name="repository" value="%{repository}"/>--%>
<table>
<tr>
<td><s:submit id="Merge" value="Merge"/></td>
</tr>
</table>
</s:form>
</redback:ifAuthorized>
</td>
</tr>
</c:if>
</table>
</div>

View File

@ -0,0 +1,42 @@
<%--
~ 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.
--%>
<%-- http://www.opensymphony.com/webwork/wikidocs/File%20Upload%20Interceptor.html --%>
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<s:hidden name="repository.id"/>
<s:label label="ID" name="repository.id" />
<s:textfield name="repository.name" label="Name" size="50" required="true"/>
<s:textfield name="repository.location" label="Directory" size="50" required="true"/>
<s:textfield name="repository.indexDir" label="Index Directory" size="50"/>
<s:select list="#@java.util.LinkedHashMap@{'default' : 'Maven 2.x Repository', 'legacy' : 'Maven 1.x Repository'}"
name="repository.layout" label="Type"/>
<s:textfield name="repository.refreshCronExpression" label="Cron" size="40" required="true"/>
<s:textfield name="repository.daysOlder" label="Repository Purge By Days Older Than" size="5"/>
<s:textfield name="repository.retentionCount" label="Repository Purge By Retention Count" size="5"/>
<s:checkbox name="repository.releases" value="repository.releases" label="Releases Included"/>
<s:checkbox name="repository.blockRedeployments" value="repository.blockRedeployments" label="Block Re-deployment of Released Artifacts"/>
<s:checkbox name="repository.snapshots" value="repository.snapshots" label="Snapshots Included"/>
<s:checkbox name="repository.scanned" value="repository.scanned" label="Scannable"/>
<s:checkbox name="repository.deleteReleasedSnapshots" value="repository.deleteReleasedSnapshots"
label="Delete Released Snapshots"/>

View File

@ -199,4 +199,8 @@ public class TestMetadataRepository
{
return artifacts;
}
public List<ArtifactMetadata> getArtifacts(String repositoryId){
return artifacts;
}
}

View File

@ -48,7 +48,7 @@ import java.util.Collections;
import java.util.List;
/**
* DeleteManagedRepositoryActionTest
* DeleteManagedRepositoryActionTest
*
* @version $Id$
*/
@ -64,7 +64,7 @@ public class DeleteManagedRepositoryActionTest
private MockControl archivaConfigurationControl;
private ArchivaConfiguration archivaConfiguration;
private static final String REPO_ID = "repo-ident";
private File location;
@ -79,11 +79,11 @@ public class DeleteManagedRepositoryActionTest
super.setUp();
action = new DeleteManagedRepositoryAction();
archivaConfigurationControl = MockControl.createControl( ArchivaConfiguration.class );
archivaConfiguration = (ArchivaConfiguration) archivaConfigurationControl.getMock();
action.setArchivaConfiguration( archivaConfiguration );
roleManagerControl = MockControl.createControl( RoleManager.class );
roleManager = (RoleManager) roleManagerControl.getMock();
action.setRoleManager( roleManager );
@ -122,6 +122,11 @@ public class DeleteManagedRepositoryActionTest
archivaConfiguration.getConfiguration();
archivaConfigurationControl.setReturnValue( configuration );
Configuration stageRepoConfiguration = new Configuration();
stageRepoConfiguration.addManagedRepository( createSatingRepository() );
archivaConfigurationControl.setReturnValue( stageRepoConfiguration );
archivaConfigurationControl.replay();
action.setRepoid( REPO_ID );
@ -131,10 +136,10 @@ public class DeleteManagedRepositoryActionTest
ManagedRepositoryConfiguration repository = action.getRepository();
assertNotNull( repository );
assertRepositoryEquals( repository, createRepository() );
String status = action.execute();
assertEquals( Action.SUCCESS, status );
repository = action.getRepository();
assertRepositoryEquals( repository, createRepository() );
assertEquals( Collections.singletonList( originalRepository ), configuration.getManagedRepositories() );
@ -148,7 +153,7 @@ public class DeleteManagedRepositoryActionTest
repositoryStatisticsManagerControl.replay();
prepareRoleManagerMock();
Configuration configuration = prepDeletionTest( createRepository(), 4 );
MockControl control = mockAuditListeners();
@ -196,15 +201,15 @@ public class DeleteManagedRepositoryActionTest
repositoryStatisticsManagerControl.replay();
prepareRoleManagerMock();
Configuration configuration = prepDeletionTest( createRepository(), 4 );
Configuration configuration = prepDeletionTest( createRepository(), 4 );
MockControl control = mockAuditListeners();
MockControl metadataRepositoryControl = mockMetadataRepository();
String status = action.deleteContents();
assertEquals( Action.SUCCESS, status );
assertTrue( configuration.getManagedRepositories().isEmpty() );
@ -215,7 +220,7 @@ public class DeleteManagedRepositoryActionTest
control.verify();
metadataRepositoryControl.verify();
}
public void testDeleteRepositoryAndAssociatedProxyConnectors()
throws Exception
{
@ -230,11 +235,11 @@ public class DeleteManagedRepositoryActionTest
prepareRoleManagerMock();
assertEquals( 1, configuration.getProxyConnectors().size() );
MockControl control = mockAuditListeners();
MockControl metadataRepositoryControl = mockMetadataRepository();
String status = action.deleteContents();
assertEquals( Action.SUCCESS, status );
assertTrue( configuration.getManagedRepositories().isEmpty() );
@ -246,7 +251,7 @@ public class DeleteManagedRepositoryActionTest
control.verify();
metadataRepositoryControl.verify();
}
public void testDeleteRepositoryCancelled()
throws Exception
{
@ -254,7 +259,7 @@ public class DeleteManagedRepositoryActionTest
ManagedRepositoryConfiguration originalRepository = createRepository();
Configuration configuration = prepDeletionTest( originalRepository, 3 );
String status = action.execute();
assertEquals( Action.SUCCESS, status );
@ -266,36 +271,8 @@ public class DeleteManagedRepositoryActionTest
repositoryStatisticsManagerControl.verify();
}
public void testDeleteRepositoryAndReposUnderRepoGroup()
throws Exception
{
repositoryStatisticsManager.deleteStatistics( REPO_ID );
repositoryStatisticsManagerControl.replay();
Configuration configuration = prepDeletionTest( createRepository(), 5 );
List<String> repoIds = new ArrayList<String>();
repoIds.add( REPO_ID );
configuration.addRepositoryGroup( createRepoGroup( repoIds, "repo.group" ) );
prepareRoleManagerMock();
assertEquals( 1, configuration.getRepositoryGroups().size() );
MockControl control = mockAuditListeners();
MockControl metadataRepositoryControl = mockMetadataRepository();
String status = action.deleteContents();
assertEquals( Action.SUCCESS, status );
assertTrue( configuration.getManagedRepositories().isEmpty() );
assertEquals( 0, configuration.getRepositoryGroups().get( 0 ).getRepositories().size() );
assertFalse( location.exists() );
repositoryStatisticsManagerControl.verify();
control.verify();
metadataRepositoryControl.verify();
}
private Configuration prepDeletionTest( ManagedRepositoryConfiguration originalRepository, int expectCountGetConfig )
throws RegistryException, IndeterminateConfigurationException
@ -307,6 +284,11 @@ public class DeleteManagedRepositoryActionTest
archivaConfiguration.getConfiguration();
archivaConfigurationControl.setReturnValue( configuration, expectCountGetConfig );
Configuration stageRepoConfiguration = new Configuration();
stageRepoConfiguration.addManagedRepository( createSatingRepository() );
archivaConfigurationControl.setReturnValue( stageRepoConfiguration );
archivaConfiguration.save( configuration );
archivaConfigurationControl.replay();
@ -363,16 +345,33 @@ public class DeleteManagedRepositoryActionTest
return r;
}
private ManagedRepositoryConfiguration createSatingRepository()
{
ManagedRepositoryConfiguration r = new ManagedRepositoryConfiguration();
r.setId( REPO_ID +"-stage" );
r.setName( "repo name" );
r.setLocation( location.getAbsolutePath() );
r.setLayout( "default" );
r.setRefreshCronExpression( "* 0/5 * * * ?" );
r.setDaysOlder( 0 );
r.setRetentionCount( 0 );
r.setReleases( true );
r.setSnapshots( true );
r.setScanned( false );
r.setDeleteReleasedSnapshots( false );
return r;
}
private RemoteRepositoryConfiguration createRemoteRepository(String id, String url)
{
RemoteRepositoryConfiguration r = new RemoteRepositoryConfiguration();
r.setId( id );
r.setUrl( url );
r.setLayout( "default" );
return r;
}
private ProxyConnectorConfiguration createProxyConnector( String managedRepoId, String remoteRepoId )
{
ProxyConnectorConfiguration connector = new ProxyConnectorConfiguration();
@ -387,10 +386,10 @@ public class DeleteManagedRepositoryActionTest
RepositoryGroupConfiguration repoGroup = new RepositoryGroupConfiguration();
repoGroup.setId( repoGroupId );
repoGroup.setRepositories( repoIds );
return repoGroup;
}
private void prepareRoleManagerMock()
throws RoleManagerException
{

View File

@ -95,6 +95,10 @@ public class EditManagedRepositoryActionTest
archivaConfiguration.getConfiguration();
archivaConfigurationControl.setReturnValue( configuration );
Configuration stageRepoConfiguration = new Configuration();
stageRepoConfiguration.addManagedRepository( createStagingRepository() );
archivaConfigurationControl.setReturnValue( stageRepoConfiguration );
archivaConfigurationControl.replay();
action.setRepoid( REPO_ID );
@ -116,10 +120,18 @@ public class EditManagedRepositoryActionTest
{
roleManager.templatedRoleExists( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, REPO_ID );
roleManagerControl.setReturnValue( false );
roleManager.templatedRoleExists( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, REPO_ID +"-stage" );
roleManagerControl.setReturnValue( false );
roleManager.createTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, REPO_ID );
roleManagerControl.setVoidCallable();
roleManager.templatedRoleExists( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, REPO_ID );
roleManagerControl.setReturnValue( false );
roleManager.templatedRoleExists( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, REPO_ID +"-stage");
roleManagerControl.setReturnValue( false );
roleManager.createTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, REPO_ID );
roleManagerControl.setVoidCallable();
@ -128,6 +140,10 @@ public class EditManagedRepositoryActionTest
Configuration configuration = createConfigurationForEditing( createRepository() );
archivaConfiguration.getConfiguration();
archivaConfigurationControl.setReturnValue( configuration );
Configuration stageRepoConfiguration = new Configuration();
stageRepoConfiguration.addManagedRepository( createStagingRepository() );
archivaConfigurationControl.setReturnValue( stageRepoConfiguration );
archivaConfigurationControl.setReturnValue( configuration );
archivaConfigurationControl.setReturnValue( configuration );
@ -167,10 +183,18 @@ public class EditManagedRepositoryActionTest
{
roleManager.templatedRoleExists( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, REPO_ID );
roleManagerControl.setReturnValue( false );
roleManager.templatedRoleExists( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, REPO_ID +"-stage");
roleManagerControl.setReturnValue( false );
roleManager.createTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, REPO_ID );
roleManagerControl.setVoidCallable();
roleManager.templatedRoleExists( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, REPO_ID );
roleManagerControl.setReturnValue( false );
roleManager.templatedRoleExists( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, REPO_ID +"-stage");
roleManagerControl.setReturnValue( false );
roleManager.createTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, REPO_ID );
roleManagerControl.setVoidCallable();
@ -179,6 +203,11 @@ public class EditManagedRepositoryActionTest
Configuration configuration = createConfigurationForEditing( createRepository() );
archivaConfiguration.getConfiguration();
archivaConfigurationControl.setReturnValue( configuration );
Configuration stageRepoConfiguration = new Configuration();
stageRepoConfiguration.addManagedRepository( createStagingRepository() );
archivaConfigurationControl.setReturnValue( stageRepoConfiguration );
archivaConfigurationControl.setReturnValue( configuration );
archivaConfigurationControl.setReturnValue( configuration );
@ -230,9 +259,11 @@ public class EditManagedRepositoryActionTest
}
private Configuration createConfigurationForEditing( ManagedRepositoryConfiguration repositoryConfiguration )
throws Exception
{
Configuration configuration = new Configuration();
configuration.addManagedRepository( repositoryConfiguration );
// configuration.addManagedRepository( createStagingRepository() );
return configuration;
}
@ -245,6 +276,15 @@ public class EditManagedRepositoryActionTest
return r;
}
private ManagedRepositoryConfiguration createStagingRepository()
throws IOException
{
ManagedRepositoryConfiguration r = new ManagedRepositoryConfiguration();
r.setId( REPO_ID + "-stage" );
populateStagingRepository( r );
return r;
}
private void populateRepository( ManagedRepositoryConfiguration repository )
throws IOException
{
@ -260,4 +300,19 @@ public class EditManagedRepositoryActionTest
repository.setScanned( false );
repository.setDeleteReleasedSnapshots( true );
}
private void populateStagingRepository( ManagedRepositoryConfiguration repository )
throws IOException
{
repository.setId( REPO_ID + "-stage");
repository.setName( "repo name" );
repository.setLocation( location.getCanonicalPath() );
repository.setLayout( "default" );
repository.setRefreshCronExpression( "* 0/5 * * * ?" );
repository.setDaysOlder( 31 );
repository.setRetentionCount( 20 );
repository.setReleases( true );
repository.setSnapshots( true );
repository.setScanned( false );
repository.setDeleteReleasedSnapshots( true );
}
}

View File

@ -159,4 +159,7 @@ public class TestMetadataRepository
{
return null; //To change body of implemented methods use File | Settings | File Templates.
}
public List<ArtifactMetadata> getArtifacts(String repositoryId){
return null;
}
}

View File

@ -75,4 +75,6 @@ public interface MetadataRepository
* @param repositoryId the repository to delete
*/
void deleteRepository( String repositoryId );
List<ArtifactMetadata> getArtifacts(String repositoryId);
}

View File

@ -484,6 +484,17 @@ public abstract class AbstractMetadataRepositoryTest
Date upper = new Date( artifact.getWhenGathered().getTime() - 10000 );
assertTrue( repository.getArtifactsByDateRange( TEST_REPO_ID, null, upper ).isEmpty() );
}
public void testGetArtifactsByRepoId()
{
repository.updateNamespace( TEST_REPO_ID, TEST_NAMESPACE );
repository.updateProject( TEST_REPO_ID, createProject() );
ArtifactMetadata artifact = createArtifact();
repository.updateArtifact( TEST_REPO_ID, TEST_NAMESPACE, TEST_PROJECT, TEST_PROJECT_VERSION, artifact );
assertFalse( repository.getArtifacts(TEST_REPO_ID).isEmpty());
}
public void testGetNamespacesWithSparseDepth()

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva</artifactId>
<version>1.2.1</version>
</metadata>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva</artifactId>
<version>1.2.2</version>
</metadata>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva</artifactId>
<versioning>
<latest>1.2.2</latest>
<release>1.2.2</release>
<versions>
<version>1.2.1</version>
<version>1.2.2</version>
</versions>
</versioning>
</metadata>

View File

@ -69,6 +69,8 @@ public class AuditEvent
public static final String REMOVE_SCANNED = "Removed in Filesystem";
public static final String MERGING_REPOSITORIES = "Merged Artifact";
// configuration events
public static final String ADD_MANAGED_REPO = "Added Managed Repository";

View File

@ -33,7 +33,8 @@ public class MetadataAuditListener
public void auditEvent( AuditEvent event )
{
// for now we only log upload events, some of the others are quite noisy
if ( event.getAction().equals( AuditEvent.CREATE_FILE ) || event.getAction().equals( AuditEvent.UPLOAD_FILE ) )
if ( event.getAction().equals( AuditEvent.CREATE_FILE ) || event.getAction().equals( AuditEvent.UPLOAD_FILE ) ||
event.getAction().equals( AuditEvent.MERGING_REPOSITORIES ) )
{
auditManager.addAuditEvent( event );
}

View File

@ -114,4 +114,7 @@ public class TestMetadataRepository
{
//To change body of implemented methods use File | Settings | File Templates.
}
public List<ArtifactMetadata> getArtifacts(String repositoryId){
return null;
}
}

View File

@ -433,7 +433,7 @@ public class Maven2RepositoryMetadataResolverTest
assertEquals( Arrays.asList( "4", "5-SNAPSHOT" ), resolver.getProjectVersions( TEST_REPO_ID, "org.apache",
"apache" ) );
assertEquals( Arrays.asList( "1.2.1" ), resolver.getProjectVersions( TEST_REPO_ID, "org.apache.archiva",
assertEquals( Arrays.asList( "1.2.1", "1.2.2" ), resolver.getProjectVersions( TEST_REPO_ID, "org.apache.archiva",
"archiva" ) );
assertEquals( Arrays.asList( "1.2.1" ), resolver.getProjectVersions( TEST_REPO_ID, "org.apache.archiva",
"archiva-base" ) );

View File

@ -140,7 +140,7 @@ public class FileMetadataRepository
{
properties.remove( name );
}
// clear the facet contents so old properties are no longer written
clearMetadataFacetProperties( versionMetadata, properties );
}
@ -227,7 +227,7 @@ public class FileMetadataRepository
}
}
}
private void clearMetadataFacetProperties( ProjectVersionMetadata versionMetadata, Properties properties )
{
List<Object> propsToRemove = new ArrayList<Object>();
@ -242,7 +242,7 @@ public class FileMetadataRepository
}
}
}
for( Object key : propsToRemove )
{
properties.remove( key );
@ -577,7 +577,7 @@ public class FileMetadataRepository
properties.remove( "artifact:sha1:" + id );
properties.remove( "artifact:version:" + id );
properties.remove( "artifact:facetIds:" + id );
String prefix = "artifact:facet:" + id + ":";
for ( Object key : new ArrayList( properties.keySet() ) )
{
@ -1075,4 +1075,36 @@ public class FileMetadataRepository
return artifact1.getWhenGathered().compareTo( artifact2.getWhenGathered() );
}
}
public List<ArtifactMetadata> getArtifacts( String repoId )
{
List<ArtifactMetadata> artifacts = new ArrayList<ArtifactMetadata>();
for ( String ns : getRootNamespaces( repoId ) )
{
getArtifacts( artifacts, repoId, ns );
}
return artifacts;
}
private void getArtifacts( List<ArtifactMetadata> artifacts, String repoId, String ns )
{
for ( String namespace : getNamespaces( repoId, ns ) )
{
getArtifacts( artifacts, repoId, ns + "." + namespace );
}
for ( String project : getProjects( repoId, ns ) )
{
for ( String version : getProjectVersions( repoId, ns, project ) )
{
for ( ArtifactMetadata artifact : getArtifacts( repoId, ns, project, version ) )
{
artifacts.add( artifact );
}
}
}
}
}

View File

@ -50,7 +50,6 @@ public class FileMetadataRepositoryTest
FileMetadataRepository repository = new FileMetadataRepository();
repository.setConfiguration( config );
repository.setMetadataFacetFactories( factories );
this.repository = repository;
}

View File

@ -35,6 +35,7 @@
<!-- TODO: eventually not a core plugin, needs to be moved to a separate tree, with it's own Selenium tests -->
<module>npanday-support</module>
<module>maven1-repository</module>
<module>stage-repository-merge</module>
<module>generic-metadata-support</module>
</modules>
</project>
</project>

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>plugins</artifactId>
<groupId>org.apache.archiva</groupId>
<version>1.4-SNAPSHOT</version>
</parent>
<groupId>org.apache.archiva</groupId>
<artifactId>stage-repository-merge</artifactId>
<name>stage-repository-merge</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-spring</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>metadata-repository-api</artifactId>
<version>1.4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-repository-layer</artifactId>
<version>1.4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>maven2-repository</artifactId>
<version>1.4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-model</artifactId>
<version>1.4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>metadata-repository-file</artifactId>
<version>1.4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>test-repository</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>test-repository</id>
<phase>generate-test-resources</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeArtifactIds>test-repository</includeArtifactIds>
<outputDirectory>target/test-repository</outputDirectory>
<excludes>META-INF/**</excludes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-component-metadata</artifactId>
<version>1.0-beta-3.0.5</version>
<executions>
<execution>
<id>process-classes</id>
<goals>
<goal>generate-metadata</goal>
</goals>
</execution>
<execution>
<id>process-test-classes</id>
<goals>
<goal>generate-test-metadata</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@ -0,0 +1,371 @@
package org.apache.archiva.stagerepository.merge;
/*
* 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.archiva.metadata.model.ArtifactMetadata;
import org.apache.archiva.metadata.repository.filter.Filter;
import org.apache.archiva.metadata.repository.filter.IncludesFilter;
import org.apache.archiva.metadata.repository.MetadataRepository;
import org.apache.archiva.metadata.repository.storage.RepositoryPathTranslator;
import org.apache.maven.archiva.repository.RepositoryException;
import org.apache.maven.archiva.repository.metadata.RepositoryMetadataException;
import org.apache.maven.archiva.repository.metadata.RepositoryMetadataWriter;
import org.apache.maven.archiva.repository.metadata.RepositoryMetadataReader;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.maven.archiva.model.ArchivaRepositoryMetadata;
import org.apache.maven.archiva.common.utils.VersionComparator;
import org.apache.maven.archiva.common.utils.VersionUtil;
import java.util.List;
import java.util.Date;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.ArrayList;
import java.util.Collections;
import java.io.IOException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
/**
* @plexus.component role="org.apache.archiva.stagerepository.merge.RepositoryMerger" role-hint="maven2"
*/
public class Maven2RepositoryMerger
implements RepositoryMerger
{
/**
* @plexus.requirement role-hint="default"
*/
private MetadataRepository metadataRepository;
/**
* @plexus.requirement role-hint="default"
*/
private ArchivaConfiguration configuration;
/**
* @plexus.requirement role-hint="maven2"
*/
private RepositoryPathTranslator pathTranslator;
private static final String METADATA_FILENAME = "maven-metadata.xml";
public void setConfiguration( ArchivaConfiguration configuration )
{
this.configuration = configuration;
}
public void setMetadataRepository( MetadataRepository metadataRepository )
{
this.metadataRepository = metadataRepository;
}
public void merge( String sourceRepoId, String targetRepoId )
throws Exception
{
List<ArtifactMetadata> artifactsInSourceRepo = metadataRepository.getArtifacts( sourceRepoId );
for ( ArtifactMetadata artifactMetadata : artifactsInSourceRepo )
{
artifactMetadata.setRepositoryId( targetRepoId );
createFolderStructure( sourceRepoId, targetRepoId, artifactMetadata );
}
}
// TODO when UI needs a subset to merge
public void merge( String sourceRepoId, String targetRepoId, Filter<ArtifactMetadata> filter )
throws Exception
{
List<ArtifactMetadata> sourceArtifacts = metadataRepository.getArtifacts( sourceRepoId );
for ( ArtifactMetadata metadata : sourceArtifacts )
{
if ( filter.accept( metadata ) )
{
createFolderStructure( sourceRepoId, targetRepoId, metadata );
}
}
}
private void createFolderStructure( String sourceRepoId, String targetRepoId, ArtifactMetadata artifactMetadata )
throws IOException, RepositoryException
{
Configuration config = configuration.getConfiguration();
ManagedRepositoryConfiguration targetRepoConfig = config.findManagedRepositoryById( targetRepoId );
ManagedRepositoryConfiguration sourceRepoConfig = config.findManagedRepositoryById( sourceRepoId );
Date lastUpdatedTimestamp = Calendar.getInstance().getTime();
TimeZone timezone = TimeZone.getTimeZone( "UTC" );
DateFormat fmt = new SimpleDateFormat( "yyyyMMdd.HHmmss" );
fmt.setTimeZone( timezone );
String timestamp = fmt.format( lastUpdatedTimestamp );
String targetRepoPath = targetRepoConfig.getLocation();
String sourceRepoPath = sourceRepoConfig.getLocation();
String artifactPath = pathTranslator.toPath( artifactMetadata.getNamespace(), artifactMetadata.getProject(),
artifactMetadata.getProjectVersion(), artifactMetadata.getId() );
File sourceArtifactFile = new File( sourceRepoPath, artifactPath );
File targetArtifactFile = new File( targetRepoPath, artifactPath );
int lastIndex = artifactPath.lastIndexOf( '/' );
File targetFile = new File( targetRepoPath, artifactPath.substring( 0, lastIndex ) );
if ( !targetFile.exists() )
{
// create the folder structure when it does not exist
targetFile.mkdirs();
}
// artifact copying
copyFile( sourceArtifactFile, targetArtifactFile );
// pom file copying
String fileName = artifactMetadata.getProject() + "-" + artifactMetadata.getVersion() + ".pom";
// pom file copying
// TODO need to use path translator to get the pom file path
// String fileName = artifactMetadata.getProject() + "-" + artifactMetadata.getVersion() + ".pom";
//
// File sourcePomFile =
// pathTranslator.toFile( new File( sourceRepoPath ), artifactMetadata.getId(), artifactMetadata.getProject(),
// artifactMetadata.getVersion(), fileName );
//
// String relativePathToPomFile = sourcePomFile.getAbsolutePath().split( sourceRepoPath )[1];
// File targetPomFile = new File( targetRepoPath, relativePathToPomFile );
//pom file copying (file path is taken with out using path translator)
String index = artifactPath.substring( lastIndex + 1 );
int last = index.lastIndexOf( '.' );
File sourcePomFile = new File( sourceRepoPath, artifactPath.substring( 0, lastIndex ) + "/" +
artifactPath.substring( lastIndex + 1 ).substring( 0, last ) + ".pom" );
File targetPomFile = new File( targetRepoPath, artifactPath.substring( 0, lastIndex ) + "/" +
artifactPath.substring( lastIndex + 1 ).substring( 0, last ) + ".pom" );
if ( !targetPomFile.exists() && sourcePomFile.exists() )
{
copyFile( sourcePomFile, targetPomFile );
}
// explicitly update only if metadata-updater consumer is not enabled!
if ( !config.getRepositoryScanning().getKnownContentConsumers().contains( "metadata-updater" ) )
{
// updating version metadata files
File versionMetaDataFileInSourceRepo =
pathTranslator.toFile( new File( sourceRepoPath ), artifactMetadata.getNamespace(),
artifactMetadata.getProject(), artifactMetadata.getVersion(),
METADATA_FILENAME );
String relativePathToVersionMetadataFile =
versionMetaDataFileInSourceRepo.getAbsolutePath().split( sourceRepoPath )[1];
File versionMetaDataFileInTargetRepo = new File( targetRepoPath, relativePathToVersionMetadataFile );
if ( !versionMetaDataFileInTargetRepo.exists() )
{
copyFile( versionMetaDataFileInSourceRepo, versionMetaDataFileInTargetRepo );
}
else
{
updateVersionMetadata( versionMetaDataFileInTargetRepo, artifactMetadata, lastUpdatedTimestamp );
}
// updating project meta data file
String projectDirectoryInSourceRepo = new File( versionMetaDataFileInSourceRepo.getParent() ).getParent();
File projectMetadataFileInSourceRepo = new File( projectDirectoryInSourceRepo, METADATA_FILENAME );
String relativePathToProjectMetadataFile =
projectMetadataFileInSourceRepo.getAbsolutePath().split( sourceRepoPath )[1];
File projectMetadataFileInTargetRepo = new File( targetRepoPath, relativePathToProjectMetadataFile );
if ( !projectMetadataFileInTargetRepo.exists() )
{
copyFile( versionMetaDataFileInSourceRepo, projectMetadataFileInSourceRepo );
}
else
{
updateProjectMetadata( projectMetadataFileInTargetRepo, artifactMetadata, lastUpdatedTimestamp,
timestamp );
}
}
}
private void copyFile( File sourceFile, File targetFile )
throws IOException
{
FileOutputStream out = new FileOutputStream( targetFile );
FileInputStream input = new FileInputStream( sourceFile );
try
{
int i;
while ( ( i = input.read() ) != -1 )
{
out.write( i );
}
out.flush();
}
finally
{
out.close();
input.close();
}
}
private void updateProjectMetadata( File projectMetaDataFileIntargetRepo, ArtifactMetadata artifactMetadata,
Date lastUpdatedTimestamp, String timestamp )
throws RepositoryMetadataException
{
ArrayList<String> availableVersions = new ArrayList<String>();
String latestVersion = artifactMetadata.getProjectVersion();
ArchivaRepositoryMetadata projectMetadata = getMetadata( projectMetaDataFileIntargetRepo );
if ( projectMetaDataFileIntargetRepo.exists() )
{
availableVersions = (ArrayList<String>) projectMetadata.getAvailableVersions();
Collections.sort( availableVersions, VersionComparator.getInstance() );
if ( !availableVersions.contains( artifactMetadata.getVersion() ) )
{
availableVersions.add( artifactMetadata.getVersion() );
}
latestVersion = availableVersions.get( availableVersions.size() - 1 );
}
else
{
availableVersions.add( artifactMetadata.getProjectVersion() );
projectMetadata.setGroupId( artifactMetadata.getNamespace() );
projectMetadata.setArtifactId( artifactMetadata.getProject() );
}
if ( projectMetadata.getGroupId() == null )
{
projectMetadata.setGroupId( artifactMetadata.getNamespace() );
}
if ( projectMetadata.getArtifactId() == null )
{
projectMetadata.setArtifactId( artifactMetadata.getProject() );
}
projectMetadata.setLatestVersion( latestVersion );
projectMetadata.setAvailableVersions( availableVersions );
projectMetadata.setLastUpdated( timestamp );
projectMetadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
if ( !VersionUtil.isSnapshot( artifactMetadata.getVersion() ) )
{
projectMetadata.setReleasedVersion( latestVersion );
}
RepositoryMetadataWriter.write( projectMetadata, projectMetaDataFileIntargetRepo );
}
private void updateVersionMetadata( File versionMetaDataFileInTargetRepo, ArtifactMetadata artifactMetadata,
Date lastUpdatedTimestamp )
throws RepositoryMetadataException
{
ArchivaRepositoryMetadata versionMetadata = getMetadata( versionMetaDataFileInTargetRepo );
if ( !versionMetaDataFileInTargetRepo.exists() )
{
versionMetadata.setGroupId( artifactMetadata.getNamespace() );
versionMetadata.setArtifactId( artifactMetadata.getProject() );
versionMetadata.setVersion( artifactMetadata.getProjectVersion() );
}
versionMetadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
RepositoryMetadataWriter.write( versionMetadata, versionMetaDataFileInTargetRepo );
}
private ArchivaRepositoryMetadata getMetadata( File metadataFile )
throws RepositoryMetadataException
{
ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
if ( metadataFile.exists() )
{
metadata = RepositoryMetadataReader.read( metadataFile );
}
return metadata;
}
public List<ArtifactMetadata> getConflictsartifacts( String sourceRepo, String targetRepo )
throws Exception
{
List<ArtifactMetadata> targetArtifacts = metadataRepository.getArtifacts( targetRepo );
List<ArtifactMetadata> sourceArtifacts = metadataRepository.getArtifacts( sourceRepo );
List<ArtifactMetadata> conflictsArtifacts = new ArrayList<ArtifactMetadata>();
for ( ArtifactMetadata targerArtifact : targetArtifacts )
{
for ( ArtifactMetadata sourceArtifact : sourceArtifacts )
{
if ( isEquals( targerArtifact, sourceArtifact ) )
{
if ( !conflictsArtifacts.contains( sourceArtifact ) )
{
conflictsArtifacts.add( sourceArtifact );
}
}
}
}
sourceArtifacts.removeAll( conflictsArtifacts );
Filter<ArtifactMetadata> artifactsWithOutConflicts = new IncludesFilter<ArtifactMetadata>( sourceArtifacts );
// merge( sourceRepo, targetRepo, artifactsWithOutConflicts );
return conflictsArtifacts;
}
private boolean isEquals( ArtifactMetadata sourceArtifact, ArtifactMetadata targetArtifact )
{
boolean isSame = false;
if ( ( sourceArtifact.getNamespace().equals( targetArtifact.getNamespace() ) ) &&
( sourceArtifact.getProject().equals( targetArtifact.getProject() ) ) &&
( sourceArtifact.getId().equals( targetArtifact.getId() ) ) &&
( sourceArtifact.getProjectVersion().equals( targetArtifact.getProjectVersion() ) ) )
{
isSame = true;
}
return isSame;
}
}

View File

@ -0,0 +1,31 @@
package org.apache.archiva.stagerepository.merge;
/*
* 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.archiva.metadata.model.ArtifactMetadata;
import org.apache.archiva.metadata.repository.filter.Filter;
public interface RepositoryMerger
{
void merge( String sourceRepoId, String targetRepoId )
throws Exception;
void merge( String sourceRepoId, String targetRepoId, Filter<ArtifactMetadata> filter ) throws Exception;
}

View File

@ -0,0 +1,64 @@
package org.apache.archiva.configuration;
/*
* 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.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.ConfigurationListener;
import org.apache.maven.archiva.configuration.IndeterminateConfigurationException;
import org.codehaus.plexus.registry.RegistryException;
import org.codehaus.plexus.registry.RegistryListener;
public class StubConfiguration
implements ArchivaConfiguration
{
private Configuration configuration;
public Configuration getConfiguration()
{
return configuration;
}
public void save( Configuration configuration )
throws RegistryException, IndeterminateConfigurationException
{
this.configuration = configuration;
}
public boolean isDefaulted()
{
return false;
}
public void addListener( ConfigurationListener listener )
{
throw new UnsupportedOperationException();
}
public void removeListener( ConfigurationListener listener )
{
throw new UnsupportedOperationException();
}
public void addChangeListener( RegistryListener listener )
{
throw new UnsupportedOperationException();
}
}

View File

@ -0,0 +1,161 @@
package org.apache.archiva.stagerepository.merge;
/*
* 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.codehaus.plexus.spring.PlexusInSpringTestCase;
import org.apache.maven.archiva.configuration.Configuration;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.maven.archiva.configuration.RepositoryScanningConfiguration;
import org.apache.maven.archiva.repository.RepositoryContentFactory;
import org.apache.archiva.metadata.repository.MetadataRepository;
import org.apache.archiva.metadata.model.ArtifactMetadata;
import org.mockito.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;
import org.junit.Before;
import java.util.List;
import java.util.ArrayList;
import java.io.File;
public class Maven2RepositoryMergerTest
extends PlexusInSpringTestCase
{
private static final String TEST_REPO_ID = "test";
private static final String TARGET_REPOSITORY_ID = "target-repo";
private Configuration config;
@MockitoAnnotations.Mock
private MetadataRepository metadataResolver;
private RepositoryContentFactory repositoryFactory;
private ArchivaConfiguration configuration;
private Maven2RepositoryMerger repositoryMerger;
private MetadataRepository metadataRepository;
@Before
public void setUp()
throws Exception
{
super.setUp();
MockitoAnnotations.initMocks( this );
metadataRepository = mock( MetadataRepository.class );
repositoryMerger = (Maven2RepositoryMerger) lookup( RepositoryMerger.class, "maven2" );
repositoryMerger.setMetadataRepository( metadataRepository );
}
private List<ArtifactMetadata> getArtifacts()
{
List<ArtifactMetadata> metadata = new ArrayList<ArtifactMetadata>();
ArtifactMetadata artifact1 = new ArtifactMetadata();
artifact1.setNamespace( "com.example.test" );
artifact1.setProject( "test-artifact" );
artifact1.setVersion( "1.0-SNAPSHOT" );
artifact1.setProjectVersion( "1.0-SNAPSHOT" );
artifact1.setId( "test-artifact-1.0-20100308.230825-1.jar" );
metadata.add( artifact1 );
return metadata;
}
public void testMerge()
throws Exception
{
ArchivaConfiguration configuration = (ArchivaConfiguration) lookup( ArchivaConfiguration.class );
Configuration c = new Configuration();
ManagedRepositoryConfiguration testRepo = new ManagedRepositoryConfiguration();
testRepo.setId( TEST_REPO_ID );
testRepo.setLocation( getTestPath( "target/test-repository" ) );
RepositoryScanningConfiguration repoScanConfig = new RepositoryScanningConfiguration();
List<String> knownContentConsumers = new ArrayList<String>();
knownContentConsumers.add( "metadata-updater12" );
repoScanConfig.setKnownContentConsumers( knownContentConsumers );
c.setRepositoryScanning( repoScanConfig );
ManagedRepositoryConfiguration targetRepo = new ManagedRepositoryConfiguration();
targetRepo.setId( "target-rep" );
targetRepo.setLocation( getTestPath( "target" ) );
c.addManagedRepository( testRepo );
c.addManagedRepository( targetRepo );
configuration.save( c );
when( metadataRepository.getArtifacts( TEST_REPO_ID ) ).thenReturn( getArtifacts() );
repositoryMerger.merge( TEST_REPO_ID, "target-rep" );
verify( metadataRepository ).getArtifacts( TEST_REPO_ID );
}
public void testMergeWithOutConflictArtifacts()
throws Exception
{
String sourceRepoId = "source-repo";
ArtifactMetadata artifact1 = new ArtifactMetadata();
artifact1.setNamespace( "org.testng" );
artifact1.setProject( "testng" );
artifact1.setVersion( "5.8" );
artifact1.setProjectVersion( "5.8" );
artifact1.setId( "testng-5.8-jdk15.jar" );
artifact1.setRepositoryId( sourceRepoId );
List<ArtifactMetadata> sourceRepoArtifactsList = getArtifacts();
sourceRepoArtifactsList.add( artifact1 );
List<ArtifactMetadata> targetRepoArtifactsList = getArtifacts();
ArchivaConfiguration configuration = (ArchivaConfiguration) lookup( ArchivaConfiguration.class );
Configuration c = new Configuration();
ManagedRepositoryConfiguration testRepo = new ManagedRepositoryConfiguration();
testRepo.setId( TEST_REPO_ID );
testRepo.setLocation( getTestPath( "target/test-repository" ) );
String sourceRepo = "src/test/resources/test-repository-with-conflict-artifacts";
ManagedRepositoryConfiguration testRepoWithConflicts = new ManagedRepositoryConfiguration();
testRepoWithConflicts.setId( sourceRepoId );
testRepoWithConflicts.setLocation( getTestPath( sourceRepo ) );
RepositoryScanningConfiguration repoScanConfig = new RepositoryScanningConfiguration();
List<String> knownContentConsumers = new ArrayList<String>();
knownContentConsumers.add( "metadata-updater" );
repoScanConfig.setKnownContentConsumers( knownContentConsumers );
c.setRepositoryScanning( repoScanConfig );
c.addManagedRepository( testRepo );
c.addManagedRepository( testRepoWithConflicts );
configuration.save( c );
File targetRepoFile = new File( getTestPath(
"/target/test-repository/com/example/test/test-artifact/1.0-SNAPSHOT/test-artifact-1.0-20100308.230825-1.jar" ) );
targetRepoFile.setReadOnly();
when( metadataRepository.getArtifacts( sourceRepoId ) ).thenReturn( sourceRepoArtifactsList );
when( metadataRepository.getArtifacts( TEST_REPO_ID ) ).thenReturn( targetRepoArtifactsList );
assertEquals( 1, repositoryMerger.getConflictsartifacts( sourceRepoId, TEST_REPO_ID ).size() );
verify( metadataRepository ).getArtifacts( TEST_REPO_ID );
}
}

View File

@ -0,0 +1,27 @@
<!--
~ 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.
-->
<component-set>
<components>
<component>
<role>org.apache.maven.archiva.configuration.ArchivaConfiguration</role>
<implementation>org.apache.archiva.configuration.StubConfiguration</implementation>
</component>
</components>
</component-set>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva</artifactId>
<version>1.2.1</version>
<versioning>
<lastUpdated>20100702152308</lastUpdated>
</versioning>
</metadata>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva</artifactId>
<versioning>
<latest>1.2.2</latest>
<release>1.2.2</release>
<versions>
<version>1.2.1</version>
<version>1.2.2</version>
</versions>
<lastUpdated>20100704111236</lastUpdated>
</versioning>
</metadata>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>com.example.test</groupId>
<artifactId>test-artifact</artifactId>
<version>1.0-SNAPSHOT</version>
<versioning>
<snapshot>
<timestamp>20100310.014828</timestamp>
<buildNumber>2</buildNumber>
</snapshot>
<lastUpdated>20100310014828</lastUpdated>
</versioning>
</metadata>

View File

@ -0,0 +1,24 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.test</groupId>
<artifactId>test-artifact</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>test-artifact</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<distributionManagement>
<repository>
<id>test-repo</id>
<url>file:${basedir}/repository</url>
</repository>
</distributionManagement>
</project>

View File

@ -0,0 +1,24 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.test</groupId>
<artifactId>test-artifact</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>test-artifact</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<distributionManagement>
<repository>
<id>test</id>
<url>file:${basedir}/repository</url>
</repository>
</distributionManagement>
</project>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>com.example.test</groupId>
<artifactId>test-artifact</artifactId>
<version>1.0-SNAPSHOT</version>
<versioning>
<snapshot>
<timestamp>20100310.014828</timestamp>
<buildNumber>2</buildNumber>
</snapshot>
<lastUpdated>20100310014828</lastUpdated>
</versioning>
</metadata>

View File

@ -0,0 +1 @@
e20c52f8ef51c1cbd52348d40d22422da649578b testng-5.8-jdk15.jar

View File

@ -0,0 +1,58 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<!--
This POM cannot be used to build TestNG; it should only be used as part of a Maven
repository upload bundle.
See the guide to creating a bundle here:
http://maven.apache.org/guides/mini/guide-central-repository-upload.html
-->
<modelVersion>4.0.0</modelVersion>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<name>TestNG</name>
<version>5.8</version>
<description>TestNG is a testing framework inspired from JUnit and NUnit but introducing some new functionalities that make it more powerful and easier to use.</description>
<url>http://testng.org</url>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>http://apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<scm>
<connection>scm:svn:http://testng.googlecode.com/svn/trunk/</connection>
<developerConnection>scm:svn:http://testng.googlecode.com/svn/trunk/</developerConnection>
<url>http://testng.googlecode.com/svn/trunk</url>
</scm>
<dependencies>
<dependency>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
<version>1.6.5</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>qdox</groupId>
<artifactId>qdox</artifactId>
<version>1.6.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.beanshell</groupId>
<artifactId>bsh</artifactId>
<version>2.0b4</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1 @@
71df4387b8c96e5d2226cfa1e36acaebb96ba0f2 /home/maven/repository-staging/to-ibiblio/maven2/org/testng/testng/5.8/testng-5.8.pom