[MRM-1042]

o hide timestamped SNAPSHOT versions in version list browse
o add 'Other Versions' field in the artifact info page if the artifact is a snapshot & has other timestamped versions


git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@745362 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Maria Odea B. Ching 2009-02-18 02:42:23 +00:00
parent f7b27068d7
commit 243a71a586
5 changed files with 235 additions and 102 deletions

View File

@ -19,6 +19,7 @@ package org.apache.maven.archiva.database.browsing;
* under the License. * under the License.
*/ */
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
@ -56,7 +57,7 @@ public class DefaultRepositoryBrowsing
implements RepositoryBrowsing implements RepositoryBrowsing
{ {
private Logger log = LoggerFactory.getLogger( DefaultRepositoryBrowsing.class ); private Logger log = LoggerFactory.getLogger( DefaultRepositoryBrowsing.class );
/** /**
* @plexus.requirement role-hint="jdo" * @plexus.requirement role-hint="jdo"
*/ */
@ -67,11 +68,14 @@ public class DefaultRepositoryBrowsing
*/ */
private DatabaseUpdater dbUpdater; private DatabaseUpdater dbUpdater;
/**
* @see RepositoryBrowsing#getRoot(String, List)
*/
public BrowsingResults getRoot( final String principal, final List<String> observableRepositoryIds ) public BrowsingResults getRoot( final String principal, final List<String> observableRepositoryIds )
{ {
final BrowsingResults results = new BrowsingResults(); final BrowsingResults results = new BrowsingResults();
if (!observableRepositoryIds.isEmpty()) if ( !observableRepositoryIds.isEmpty() )
{ {
final List<String> groups = dao.query( new UniqueGroupIdConstraint( observableRepositoryIds ) ); final List<String> groups = dao.query( new UniqueGroupIdConstraint( observableRepositoryIds ) );
results.setSelectedRepositoryIds( observableRepositoryIds ); results.setSelectedRepositoryIds( observableRepositoryIds );
@ -80,33 +84,40 @@ public class DefaultRepositoryBrowsing
return results; return results;
} }
public BrowsingResults selectArtifactId( final String principal, final List<String> observableRepositoryIds, final String groupId, /**
final String artifactId ) * @see RepositoryBrowsing#selectArtifactId(String, List, String, String)
*/
public BrowsingResults selectArtifactId( final String principal, final List<String> observableRepositoryIds,
final String groupId, final String artifactId )
{ {
final BrowsingResults results = new BrowsingResults( groupId, artifactId ); final BrowsingResults results = new BrowsingResults( groupId, artifactId );
if (!observableRepositoryIds.isEmpty()) if ( !observableRepositoryIds.isEmpty() )
{ {
// NOTE: No group Id or artifact Id's should be returned here. // NOTE: No group Id or artifact Id's should be returned here.
final List<String> versions = dao.query( new UniqueVersionConstraint( observableRepositoryIds, groupId, artifactId ) ); List<String> versions =
dao.query( new UniqueVersionConstraint( observableRepositoryIds, groupId, artifactId ) );
results.setSelectedRepositoryIds( observableRepositoryIds ); results.setSelectedRepositoryIds( observableRepositoryIds );
processSnapshots( versions ); results.setVersions( processSnapshots( versions ) );
results.setVersions( versions );
} }
return results; return results;
} }
public BrowsingResults selectGroupId( final String principal, final List<String> observableRepositoryIds, final String groupId ) /**
* @see RepositoryBrowsing#selectGroupId(String, List, String)
*/
public BrowsingResults selectGroupId( final String principal, final List<String> observableRepositoryIds,
final String groupId )
{ {
final BrowsingResults results = new BrowsingResults( groupId ); final BrowsingResults results = new BrowsingResults( groupId );
if (!observableRepositoryIds.isEmpty()) if ( !observableRepositoryIds.isEmpty() )
{ {
final List<String> groups = dao.query( new UniqueGroupIdConstraint( observableRepositoryIds, groupId ) ); final List<String> groups = dao.query( new UniqueGroupIdConstraint( observableRepositoryIds, groupId ) );
final List<String> artifacts = dao.query( new UniqueArtifactIdConstraint( observableRepositoryIds, groupId ) ); final List<String> artifacts =
dao.query( new UniqueArtifactIdConstraint( observableRepositoryIds, groupId ) );
// Remove searched for groupId from groups list. // Remove searched for groupId from groups list.
// Easier to do this here, vs doing it in the SQL query. // Easier to do this here, vs doing it in the SQL query.
CollectionUtils.filter( groups, NotPredicate.getInstance( PredicateUtils.equalPredicate( groupId ) ) ); CollectionUtils.filter( groups, NotPredicate.getInstance( PredicateUtils.equalPredicate( groupId ) ) );
@ -118,13 +129,16 @@ public class DefaultRepositoryBrowsing
return results; return results;
} }
public ArchivaProjectModel selectVersion( final String principal, final List<String> observableRepositoryIds, final String groupId, /**
final String artifactId, final String version ) * @see RepositoryBrowsing#selectVersion(String, List, String, String, String)
*/
public ArchivaProjectModel selectVersion( final String principal, final List<String> observableRepositoryIds,
final String groupId, final String artifactId, final String version )
throws ObjectNotFoundException, ArchivaDatabaseException throws ObjectNotFoundException, ArchivaDatabaseException
{ {
if (observableRepositoryIds.isEmpty()) if ( observableRepositoryIds.isEmpty() )
{ {
throw new ArchivaDatabaseException("There are no observable repositories for the user " + principal); throw new ArchivaDatabaseException( "There are no observable repositories for the user " + principal );
} }
ArchivaArtifact pomArtifact = getArtifact( principal, observableRepositoryIds, groupId, artifactId, version ); ArchivaArtifact pomArtifact = getArtifact( principal, observableRepositoryIds, groupId, artifactId, version );
@ -141,14 +155,14 @@ public class DefaultRepositoryBrowsing
return model; return model;
} }
public String getRepositoryId( final String principal, final List<String> observableRepositoryIds, final String groupId, public String getRepositoryId( final String principal, final List<String> observableRepositoryIds,
final String artifactId, final String version ) final String groupId, final String artifactId, final String version )
throws ObjectNotFoundException, ArchivaDatabaseException throws ObjectNotFoundException, ArchivaDatabaseException
{ {
if (observableRepositoryIds.isEmpty()) if ( observableRepositoryIds.isEmpty() )
{ {
throw new ArchivaDatabaseException("There are no observable repositories for the user " + principal); throw new ArchivaDatabaseException( "There are no observable repositories for the user " + principal );
} }
try try
@ -160,24 +174,55 @@ public class DefaultRepositoryBrowsing
} }
catch ( ObjectNotFoundException e ) catch ( ObjectNotFoundException e )
{ {
return getNoPomArtifactRepoId( principal, observableRepositoryIds, groupId, artifactId, version, observableRepositoryIds.get(0) ); return getNoPomArtifactRepoId( principal, observableRepositoryIds, groupId, artifactId, version,
} observableRepositoryIds.get( 0 ) );
}
} }
private ArchivaArtifact getArtifact( final String principal, final List<String> observableRepositoryIds, final String groupId, /**
final String artifactId, final String version ) * @see RepositoryBrowsing#getTimestampedSnapshots(List, String, String, String)
*/
public List<String> getTimestampedSnapshots( List<String> observableRepositoryIds, String groupId,
String artifactId, String version )
throws ObjectNotFoundException, ArchivaDatabaseException
{
List<String> timestampedVersions = new ArrayList<String>();
if ( VersionUtil.isSnapshot( version ) )
{
List<String> versions =
dao.query( new UniqueVersionConstraint( observableRepositoryIds, groupId, artifactId ) );
for ( String uniqueVersion : versions )
{
if ( VersionUtil.getBaseVersion( uniqueVersion ).equals( version ) )
{
if ( !timestampedVersions.contains( uniqueVersion ) )
{
timestampedVersions.add( uniqueVersion );
}
}
}
}
return timestampedVersions;
}
private ArchivaArtifact getArtifact( final String principal, final List<String> observableRepositoryIds,
final String groupId, final String artifactId, final String version )
throws ObjectNotFoundException, ArchivaDatabaseException throws ObjectNotFoundException, ArchivaDatabaseException
{ {
ArchivaArtifact pomArtifact = null; ArchivaArtifact pomArtifact = null;
for (final String repositoryId : observableRepositoryIds) for ( final String repositoryId : observableRepositoryIds )
{ {
try try
{ {
pomArtifact = dao.getArtifactDAO().getArtifact( groupId, artifactId, version, null, "pom", repositoryId ); pomArtifact =
dao.getArtifactDAO().getArtifact( groupId, artifactId, version, null, "pom", repositoryId );
break; break;
} }
catch ( ObjectNotFoundException e ) catch ( ArchivaDatabaseException e )
{ {
pomArtifact = handleGenericSnapshots( groupId, artifactId, version, repositoryId ); pomArtifact = handleGenericSnapshots( groupId, artifactId, version, repositoryId );
} }
@ -187,9 +232,10 @@ public class DefaultRepositoryBrowsing
{ {
String type = getArtifactType( groupId, artifactId, version ); String type = getArtifactType( groupId, artifactId, version );
//We dont want these to persist in the database // We dont want these to persist in the database
pomArtifact = new ArchivaArtifact( groupId, artifactId, version, null, type, observableRepositoryIds.get(0) ); pomArtifact =
pomArtifact.getModel().setWhenProcessed(new Date()); new ArchivaArtifact( groupId, artifactId, version, null, type, observableRepositoryIds.get( 0 ) );
pomArtifact.getModel().setWhenProcessed( new Date() );
} }
// Allowed to see this? // Allowed to see this?
@ -199,18 +245,18 @@ public class DefaultRepositoryBrowsing
} }
else else
{ {
throw new ObjectNotFoundException( "Unable to find artifact " + Keys.toKey( groupId, artifactId, version ) throw new ObjectNotFoundException( "Unable to find artifact " + Keys.toKey( groupId, artifactId, version ) +
+ " in observable repository [" + StringUtils.join( observableRepositoryIds.iterator(), ", " ) " in observable repository [" + StringUtils.join( observableRepositoryIds.iterator(), ", " ) +
+ "] for user " + principal ); "] for user " + principal );
} }
} }
public List<ArchivaProjectModel> getUsedBy( final String principal, final List<String> observableRepositoryIds, final String groupId, public List<ArchivaProjectModel> getUsedBy( final String principal, final List<String> observableRepositoryIds,
final String artifactId, final String version ) final String groupId, final String artifactId, final String version )
throws ArchivaDatabaseException throws ArchivaDatabaseException
{ {
ProjectsByArtifactUsageConstraint constraint = new ProjectsByArtifactUsageConstraint( groupId, artifactId, ProjectsByArtifactUsageConstraint constraint =
version ); new ProjectsByArtifactUsageConstraint( groupId, artifactId, version );
List<ArchivaProjectModel> results = dao.getProjectModelDAO().queryProjectModels( constraint ); List<ArchivaProjectModel> results = dao.getProjectModelDAO().queryProjectModels( constraint );
if ( results == null ) if ( results == null )
{ {
@ -222,64 +268,54 @@ public class DefaultRepositoryBrowsing
} }
/** /**
* Add generic (*-SNAPSHOT) snapshot versions in the list for artifacts with only unique version (timestamped) * Removes SNAPSHOT versions with build numbers. Retains only the generic SNAPSHOT version.
* snapshots. * Example, if the list of versions are:
* <p/> * - 2.0
* Ex. * - 2.0.1
* artifact1 has the ff. versions retrieved from the db: * - 2.1-20070522.143249-1
* - 1.0 * - 2.1-20070522.157829-2
* - 1.1-20061118.060401-2 *
* - 1.1-20061118.060402-3 * the returned version list would contain 2.0, 2.0.1 and 2.1-SNAPSHOT.
* - 2.2-20071007.070101-1 *
* - 2.2-20071007.070110-2
* - 2.2-SNAPSHOT
* <p/>
* This method will add a '1.1-SNAPSHOT' in the list since there is no generic snapshot entry for it.
* When this version is browsed, the pom of the latest snapshot will be displayed.
*
* @param versions * @param versions
*/ */
private void processSnapshots( final List<String> versions ) private List<String> processSnapshots( List<String> versions )
{ {
Map<String, String> snapshots = new HashMap<String, String>(); List<String> cleansedVersions = new ArrayList<String>();
for ( String version : versions ) for ( String version : versions )
{ {
if ( VersionUtil.isSnapshot( version ) ) if ( VersionUtil.isSnapshot( version ) )
{ {
String baseVersion = VersionUtil.getBaseVersion( version ); String baseVersion = VersionUtil.getBaseVersion( version );
if ( !snapshots.containsKey( baseVersion ) ) if ( !cleansedVersions.contains( baseVersion ) )
{ {
snapshots.put( baseVersion, baseVersion ); cleansedVersions.add( baseVersion );
} }
} }
else
{
cleansedVersions.add( version );
}
} }
for ( Entry<String, String> entry : snapshots.entrySet() ) return cleansedVersions;
{
String baseVersion = entry.getValue();
if ( !versions.contains( baseVersion ) )
{
versions.add( baseVersion );
}
}
} }
/** /**
* Handles querying of generic (*-SNAPSHOT) snapshot version. * Handles querying of generic (*-SNAPSHOT) snapshot version. Process: - Get all the timestamped/unique versions of
* Process: * the artifact from the db - Sort the queried project models - Reverse the list of queried project models to get
* - Get all the timestamped/unique versions of the artifact from the db * the latest timestamp version - Loop through the list and get the first one to match the generic (*-SNAPHOT)
* - Sort the queried project models * version
* - Reverse the list of queried project models to get the latest timestamp version *
* - Loop through the list and get the first one to match the generic (*-SNAPHOT) version
*
* @param groupId * @param groupId
* @param artifactId * @param artifactId
* @param version * @param version
* @param pomArtifact * @param pomArtifact
* @throws ArchivaDatabaseException * @throws ArchivaDatabaseException
*/ */
private ArchivaArtifact handleGenericSnapshots( final String groupId, final String artifactId, final String version, final String repositoryId ) private ArchivaArtifact handleGenericSnapshots( final String groupId, final String artifactId,
final String version, final String repositoryId )
throws ArchivaDatabaseException throws ArchivaDatabaseException
{ {
ArchivaArtifact result = null; ArchivaArtifact result = null;
@ -294,8 +330,19 @@ public class DefaultRepositoryBrowsing
{ {
if ( VersionUtil.getBaseVersion( uniqueVersion ).equals( version ) ) if ( VersionUtil.getBaseVersion( uniqueVersion ).equals( version ) )
{ {
log.info( "Retrieving artifact with version " + uniqueVersion ); try
result = dao.getArtifactDAO().getArtifact( groupId, artifactId, uniqueVersion, null, "pom", repositoryId ); {
log.info( "Retrieving artifact with version " + uniqueVersion );
result =
dao.getArtifactDAO().getArtifact( groupId, artifactId, uniqueVersion, null, "pom", repositoryId );
break;
}
catch ( ArchivaDatabaseException e )
{
log.warn( "Artifact '" + groupId + ":" + artifactId + ":" + uniqueVersion +
"' in repository '" + repositoryId + "' not found in the database." );
continue;
}
} }
} }
} }
@ -304,7 +351,7 @@ public class DefaultRepositoryBrowsing
/** /**
* Get the project model from the database. * Get the project model from the database.
* *
* @param groupId * @param groupId
* @param artifactId * @param artifactId
* @param version * @param version
@ -320,57 +367,59 @@ public class DefaultRepositoryBrowsing
{ {
model = dao.getProjectModelDAO().getProjectModel( groupId, artifactId, version ); model = dao.getProjectModelDAO().getProjectModel( groupId, artifactId, version );
} }
catch (ObjectNotFoundException e) catch ( ObjectNotFoundException e )
{ {
log.debug("Unable to find project model for [" + Keys.toKey( groupId, artifactId, version ) + "]", e); log.debug( "Unable to find project model for [" + Keys.toKey( groupId, artifactId, version ) + "]", e );
} }
if ( model == null ) if ( model == null )
{ {
model = new ArchivaProjectModel(); model = new ArchivaProjectModel();
model.setGroupId(groupId); model.setGroupId( groupId );
model.setArtifactId(artifactId); model.setArtifactId( artifactId );
model.setVersion(version); model.setVersion( version );
} }
return model; return model;
} }
private String getNoPomArtifactRepoId( String principal, List<String> observableRepos, String groupId, String artifactId, String version, String repositoryId ) private String getNoPomArtifactRepoId( String principal, List<String> observableRepos, String groupId,
String artifactId, String version, String repositoryId )
throws ObjectNotFoundException, ArchivaDatabaseException throws ObjectNotFoundException, ArchivaDatabaseException
{ {
ArchivaArtifact artifact = null; ArchivaArtifact artifact = null;
String type = getArtifactType( groupId, artifactId, version ); String type = getArtifactType( groupId, artifactId, version );
artifact = dao.getArtifactDAO().createArtifact( groupId, artifactId, version, null, type, repositoryId ); artifact = dao.getArtifactDAO().createArtifact( groupId, artifactId, version, null, type, repositoryId );
if ( artifact == null ) if ( artifact == null )
{ {
//Lets not persist these // Lets not persist these
artifact = new ArchivaArtifact( groupId, artifactId, version, null, type, repositoryId ); artifact = new ArchivaArtifact( groupId, artifactId, version, null, type, repositoryId );
} }
// Allowed to see this? // Allowed to see this?
if ( !observableRepos.contains( artifact.getModel().getRepositoryId() ) ) if ( !observableRepos.contains( artifact.getModel().getRepositoryId() ) )
{ {
throw new ObjectNotFoundException( "Unable to find artifact " + Keys.toKey( groupId, artifactId, version ) throw new ObjectNotFoundException( "Unable to find artifact " + Keys.toKey( groupId, artifactId, version ) +
+ " in observable repository [" + StringUtils.join( observableRepos.iterator(), ", " ) " in observable repository [" + StringUtils.join( observableRepos.iterator(), ", " ) + "] for user " +
+ "] for user " + principal ); principal );
} }
return artifact.getModel().getRepositoryId(); return artifact.getModel().getRepositoryId();
} }
private String getArtifactType( String groupId, String artifactId, String version ) private String getArtifactType( String groupId, String artifactId, String version )
throws ObjectNotFoundException, ArchivaDatabaseException throws ObjectNotFoundException, ArchivaDatabaseException
{ {
String type = "jar"; String type = "jar";
try try
{ {
List<ArchivaArtifact> artifacts = dao.getArtifactDAO().queryArtifacts( new ArtifactsRelatedConstraint( groupId, artifactId, version ) ); List<ArchivaArtifact> artifacts =
dao.getArtifactDAO().queryArtifacts( new ArtifactsRelatedConstraint( groupId, artifactId, version ) );
if ( artifacts.size() > 0 ) if ( artifacts.size() > 0 )
{ {
type = artifacts.get( 0 ).getType(); type = artifacts.get( 0 ).getType();
@ -378,10 +427,10 @@ public class DefaultRepositoryBrowsing
} }
catch ( ObjectNotFoundException e ) catch ( ObjectNotFoundException e )
{ {
//swallow exception? // swallow exception?
} }
return type; return type;
} }
} }

View File

@ -89,4 +89,20 @@ public interface RepositoryBrowsing
public String getRepositoryId( String principle, List<String> observableRepositoryIds, String groupId, public String getRepositoryId( String principle, List<String> observableRepositoryIds, String groupId,
String artifactId, String version ) String artifactId, String version )
throws ObjectNotFoundException, ArchivaDatabaseException; throws ObjectNotFoundException, ArchivaDatabaseException;
/**
* Get the timestamped versions or versions with build numbers of the given SNAPSHOT artifact.
*
* @param observableRepositoryIds
* @param groupId
* @param artifactId
* @param version
* @return
* @throws ObjectNotFoundException
* @throws ArchivaDatabaseException
*/
public List<String> getTimestampedSnapshots( List<String> observableRepositoryIds,
String groupId, String artifactId, String version )
throws ObjectNotFoundException, ArchivaDatabaseException;
} }

View File

@ -89,6 +89,12 @@ public class RepositoryBrowsingTest
artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.1-SNAPSHOT" ); artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.1-SNAPSHOT" );
artifactDao.saveArtifact( artifact ); artifactDao.saveArtifact( artifact );
artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.1-20070522.143249-1" );
artifactDao.saveArtifact( artifact );
artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.1-20070522.153141-2" );
artifactDao.saveArtifact( artifact );
artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.1.1" ); artifact = createArtifact( "org.apache.maven.shared", "test-two", "2.1.1" );
artifactDao.saveArtifact( artifact ); artifactDao.saveArtifact( artifact );
@ -142,6 +148,22 @@ public class RepositoryBrowsingTest
assertEquals( "commons-lang", artifact.getArtifactId() ); assertEquals( "commons-lang", artifact.getArtifactId() );
assertEquals( "2.0", artifact.getVersion() ); assertEquals( "2.0", artifact.getVersion() );
} }
public void testSelectArtifactId()
throws Exception
{
saveTestData();
RepositoryBrowsing browser = lookupBrowser();
BrowsingResults results =
browser.selectArtifactId( USER_GUEST, GUEST_REPO_IDS, "org.apache.maven.shared", "test-two" );
assertNotNull( "Browsing results should not be null.", results );
assertEquals( 4, results.getVersions().size() );
assertTrue( results.getVersions().contains( "2.0" ) );
assertTrue( results.getVersions().contains( "2.1-SNAPSHOT" ) );
assertTrue( results.getVersions().contains( "2.1.1" ) );
assertTrue( results.getVersions().contains( "2.1-alpha-1" ) );
}
private void assertGroupIds( String msg, List actualGroupIds, String[] expectedGroupIds ) private void assertGroupIds( String msg, List actualGroupIds, String[] expectedGroupIds )
{ {

View File

@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.common.utils.VersionUtil;
import org.apache.maven.archiva.database.ArchivaDatabaseException; import org.apache.maven.archiva.database.ArchivaDatabaseException;
import org.apache.maven.archiva.database.ObjectNotFoundException; import org.apache.maven.archiva.database.ObjectNotFoundException;
import org.apache.maven.archiva.database.browsing.RepositoryBrowsing; import org.apache.maven.archiva.database.browsing.RepositoryBrowsing;
@ -94,6 +95,8 @@ public class ShowArtifactAction
private List mailingLists; private List mailingLists;
private List dependencies; private List dependencies;
private List<String> snapshotVersions;
/** /**
* Show the versioned project information tab. TODO: Change name to 'project' * Show the versioned project information tab. TODO: Change name to 'project'
@ -103,14 +106,30 @@ public class ShowArtifactAction
{ {
try try
{ {
this.model = if( VersionUtil.isSnapshot( version ) )
repoBrowsing.selectVersion( getPrincipal(), getObservableRepos(), groupId, artifactId, version ); {
this.model =
repoBrowsing.selectVersion( getPrincipal(), getObservableRepos(), groupId, artifactId, version );
this.snapshotVersions =
repoBrowsing.getTimestampedSnapshots( getObservableRepos(), groupId, artifactId, version );
if( this.snapshotVersions.contains( version ) )
{
this.snapshotVersions.remove( version );
}
}
else
{
this.model =
repoBrowsing.selectVersion( getPrincipal(), getObservableRepos(), groupId, artifactId, version );
}
this.repositoryId = this.repositoryId =
repoBrowsing.getRepositoryId( getPrincipal(), getObservableRepos(), groupId, artifactId, version ); repoBrowsing.getRepositoryId( getPrincipal(), getObservableRepos(), groupId, artifactId, version );
} }
catch ( ObjectNotFoundException e ) catch ( ObjectNotFoundException e )
{ {
getLogger().debug(e.getMessage(), e); getLogger().debug( e.getMessage(), e );
addActionError( e.getMessage() ); addActionError( e.getMessage() );
return ERROR; return ERROR;
} }
@ -292,4 +311,14 @@ public class ShowArtifactAction
this.repositoryId = repositoryId; this.repositoryId = repositoryId;
} }
public List<String> getSnapshotVersions()
{
return snapshotVersions;
}
public void setSnapshotVersions( List<String> snapshotVersions )
{
this.snapshotVersions = snapshotVersions;
}
} }

View File

@ -90,6 +90,23 @@
</td> </td>
</tr> </tr>
</c:if> </c:if>
<c:if test="${(snapshotVersions != null) && (!empty snapshotVersions)}">
<tr>
<th>Other Versions</th>
<td>
<c:forEach items="${snapshotVersions}" var="snapshot">
<c:set var="url">
<s:url action="showArtifact" namespace="/">
<s:param name="groupId" value="%{#attr.model.groupId}"/>
<s:param name="artifactId" value="%{#attr.model.artifactId}"/>
<s:param name="version" value="%{#attr.snapshot}"/>
</s:url>
</c:set>
<a href="${url}">${snapshot}</a>
</c:forEach>
</td>
</tr>
</c:if>
<%-- TODO: deployment timestamp <%-- TODO: deployment timestamp
<tr> <tr>
<th>Deployment Date</th> <th>Deployment Date</th>