diff options
11 files changed, 231 insertions, 98 deletions
diff --git a/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/utils/VersionUtil.java b/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/utils/VersionUtil.java index 228c3ff0f..69626f634 100644 --- a/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/utils/VersionUtil.java +++ b/archiva-base/archiva-common/src/main/java/org/apache/maven/archiva/common/utils/VersionUtil.java @@ -151,4 +151,20 @@ public class VersionUtil return version; } } + + public static boolean isUniqueSnapshot( String version ) + { + Matcher m = UNIQUE_SNAPSHOT_PATTERN.matcher( version ); + if( m.matches() ) + { + return true; + } + + return false; + } + + public static boolean isGenericSnapshot( String version ) + { + return version.endsWith( SNAPSHOT ); + } } diff --git a/archiva-base/archiva-consumers/archiva-database-consumers/src/main/java/org/apache/maven/archiva/consumers/database/ProjectModelToDatabaseConsumer.java b/archiva-base/archiva-consumers/archiva-database-consumers/src/main/java/org/apache/maven/archiva/consumers/database/ProjectModelToDatabaseConsumer.java index 3104dc40a..e586ac3d5 100644 --- a/archiva-base/archiva-consumers/archiva-database-consumers/src/main/java/org/apache/maven/archiva/consumers/database/ProjectModelToDatabaseConsumer.java +++ b/archiva-base/archiva-consumers/archiva-database-consumers/src/main/java/org/apache/maven/archiva/consumers/database/ProjectModelToDatabaseConsumer.java @@ -42,20 +42,20 @@ import org.apache.maven.archiva.repository.project.ProjectModelException; import org.apache.maven.archiva.repository.project.ProjectModelFilter; import org.apache.maven.archiva.repository.project.ProjectModelReader; import org.apache.maven.archiva.repository.project.filters.EffectiveProjectModelFilter; +import org.apache.maven.archiva.common.utils.VersionUtil; import java.io.File; import java.util.ArrayList; import java.util.List; /** - * ProjectModelToDatabaseConsumer + * ProjectModelToDatabaseConsumer * * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a> * @version $Id$ - * * @plexus.component role="org.apache.maven.archiva.consumers.DatabaseUnprocessedArtifactConsumer" - * role-hint="update-db-project" - * instantiation-strategy="per-lookup" + * role-hint="update-db-project" + * instantiation-strategy="per-lookup" */ public class ProjectModelToDatabaseConsumer extends AbstractMonitoredConsumer @@ -102,9 +102,8 @@ public class ProjectModelToDatabaseConsumer private ProjectModelFilter expressionModelFilter; /** - * @plexus.requirement - * role="org.apache.maven.archiva.repository.project.ProjectModelFilter" - * role-hint="effective" + * @plexus.requirement role="org.apache.maven.archiva.repository.project.ProjectModelFilter" + * role-hint="effective" */ private EffectiveProjectModelFilter effectiveModelFilter; @@ -167,13 +166,24 @@ public class ProjectModelToDatabaseConsumer // Resolve the project model model = effectiveModelFilter.filter( model ); + // The version should be updated to the filename version if it is a unique snapshot + FilenameParts parts = RepositoryLayoutUtils.splitFilename( artifactFile.getName(), null ); + if ( model.getVersion().equals( VersionUtil.getBaseVersion( parts.version ) ) && + VersionUtil.isUniqueSnapshot( parts.version ) ) + { + model.setVersion( parts.version ); + } + if ( isValidModel( model, artifact ) ) { + getLogger().info( "Add project model " + model + " to database." ); + dao.getProjectModelDAO().saveProjectModel( model ); } else { - getLogger().warn( "Invalid or corrupt pom. Project model " + model + " was not added in the database." ); + getLogger().warn( + "Invalid or corrupt pom. Project model " + model + " was not added in the database." ); } } @@ -191,9 +201,8 @@ public class ProjectModelToDatabaseConsumer catch ( Throwable t ) { // Catch the other errors in the process to allow the rest of the process to complete. - getLogger().error( - "Unable to process model " + artifactFile + " due to : " + t.getClass().getName() - + " : " + t.getMessage(), t ); + getLogger().error( "Unable to process model " + artifactFile + " due to : " + t.getClass().getName() + + " : " + t.getMessage(), t ); } } @@ -279,51 +288,26 @@ public class ProjectModelToDatabaseConsumer try { FilenameParts parts = RepositoryLayoutUtils.splitFilename( artifactFile.getName(), null ); - if ( !parts.artifactId.equalsIgnoreCase( model.getArtifactId() ) ) - { - getLogger().warn( - "Project Model " + model + " artifactId: " + model.getArtifactId() - + " does not match the pom file's artifactId: " + parts.artifactId ); - addProblem( artifact, "Project Model " + model + " artifactId: " + model.getArtifactId() - + " does not match the pom file's artifactId: " + parts.artifactId ); - - return false; - } - - if ( !parts.version.equalsIgnoreCase( model.getVersion() ) ) + if ( !parts.artifactId.equalsIgnoreCase( model.getArtifactId() ) ) { - getLogger().warn( - "Project Model " + model + " version: " + model.getVersion() - + " does not match the pom file's version: " + parts.version ); + getLogger().warn( "Project Model " + model + " artifactId: " + model.getArtifactId() + + " does not match the pom file's artifactId: " + parts.artifactId ); - addProblem( artifact, "Project Model " + model + " version: " + model.getVersion() - + " does not match the pom file's version: " + parts.version ); + addProblem( artifact, "Project Model " + model + " artifactId: " + model.getArtifactId() + + " does not match the pom file's artifactId: " + parts.artifactId ); return false; } - String constructedFilename; - - if( parts.classifier != null ) + if ( !parts.version.equalsIgnoreCase( model.getVersion() ) && + !VersionUtil.getBaseVersion( parts.version ).equalsIgnoreCase( model.getVersion() ) ) { - constructedFilename = model.getArtifactId() + "-" + model.getVersion() + "-" + - parts.classifier.trim() + ".pom"; - } - else - { - constructedFilename = model.getArtifactId() + "-" + model.getVersion() + ".pom"; - } + getLogger().warn( "Project Model " + model + " version: " + model.getVersion() + + " does not match the pom file's version: " + parts.version ); - //check if the file name matches the values indicated in the pom - if ( !artifactFile.getName().equalsIgnoreCase( constructedFilename ) ) - { - getLogger().warn( - "Artifact " + artifact + " does not match the artifactId and/or version " - + "specified in the project model " + model ); - - addProblem( artifact, "Artifact " + artifact + " does not match the artifactId and/or version " - + "specified in the project model " + model ); + addProblem( artifact, "Project Model " + model + " version: " + model.getVersion() + + " does not match the pom file's version: " + parts.version ); return false; } @@ -361,4 +345,5 @@ public class ProjectModelToDatabaseConsumer throw new ConsumerException( emsg, e ); } } + } diff --git a/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/SearchResultHit.java b/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/SearchResultHit.java index 002d02249..8b207fde8 100644 --- a/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/SearchResultHit.java +++ b/archiva-base/archiva-indexer/src/main/java/org/apache/maven/archiva/indexer/search/SearchResultHit.java @@ -90,8 +90,8 @@ public class SearchResultHit public void addArtifact( ArchivaArtifact artifact ) { this.artifacts.add( artifact ); - - String ver = artifact.getBaseVersion(); + + String ver = artifact.getVersion(); if ( !this.versions.contains( ver ) ) { @@ -110,7 +110,7 @@ public class SearchResultHit if ( StringUtils.isBlank( this.version ) ) { - this.version = ver; + this.version = ver; } } diff --git a/archiva-database/src/main/java/org/apache/maven/archiva/database/browsing/DefaultRepositoryBrowsing.java b/archiva-database/src/main/java/org/apache/maven/archiva/database/browsing/DefaultRepositoryBrowsing.java index f99e26ac7..6234952b8 100644 --- a/archiva-database/src/main/java/org/apache/maven/archiva/database/browsing/DefaultRepositoryBrowsing.java +++ b/archiva-database/src/main/java/org/apache/maven/archiva/database/browsing/DefaultRepositoryBrowsing.java @@ -32,17 +32,20 @@ import org.apache.maven.archiva.database.constraints.UniqueVersionConstraint; import org.apache.maven.archiva.database.updater.DatabaseUpdater; import org.apache.maven.archiva.model.ArchivaArtifact; import org.apache.maven.archiva.model.ArchivaProjectModel; +import org.apache.maven.archiva.common.utils.VersionUtil; import org.codehaus.plexus.logging.AbstractLogEnabled; import java.util.Collections; import java.util.List; +import java.util.Iterator; +import java.util.Map; +import java.util.HashMap; /** - * DefaultRepositoryBrowsing + * DefaultRepositoryBrowsing * * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a> * @version $Id$ - * * @plexus.component role="org.apache.maven.archiva.database.browsing.RepositoryBrowsing" */ public class DefaultRepositoryBrowsing @@ -77,6 +80,8 @@ public class DefaultRepositoryBrowsing BrowsingResults results = new BrowsingResults( groupId, artifactId ); + processSnapshots( versions ); + results.setVersions( versions ); return results; @@ -102,44 +107,167 @@ public class DefaultRepositoryBrowsing public ArchivaProjectModel selectVersion( String groupId, String artifactId, String version ) throws ObjectNotFoundException, ArchivaDatabaseException { + ArchivaArtifact pomArtifact = getArtifact( groupId, artifactId, version ); + + ArchivaProjectModel model; + version = pomArtifact.getVersion(); + + if ( !pomArtifact.getModel().isProcessed() ) + { + // Process it. + dbUpdater.updateUnprocessed( pomArtifact ); + } + + model = getProjectModel( groupId, artifactId, version ); + + return model; + } + + private ArchivaArtifact getArtifact( String groupId, String artifactId, String version ) + throws ObjectNotFoundException, ArchivaDatabaseException + { ArchivaArtifact pomArtifact = null; try { pomArtifact = dao.getArtifactDAO().getArtifact( groupId, artifactId, version, null, "pom" ); + } + catch ( ObjectNotFoundException e ) + { + pomArtifact = handleGenericSnapshots( groupId, artifactId, version, pomArtifact ); + } + + if ( pomArtifact == null ) + { + throw new ObjectNotFoundException( + "Unable to find artifact [" + groupId + ":" + artifactId + ":" + version + "]" ); + } + return pomArtifact; + } + + public List getUsedBy( String groupId, String artifactId, String version ) + throws ArchivaDatabaseException + { + ProjectsByArtifactUsageConstraint constraint = + new ProjectsByArtifactUsageConstraint( groupId, artifactId, version ); + List results = dao.getProjectModelDAO().queryProjectModels( constraint ); + if ( results == null ) + { + // defensive. to honor contract as specified. never null. + return Collections.EMPTY_LIST; + } + + return results; + } + + /** + * Add generic (*-SNAPSHOT) snapshot versions in the list for artifacts with only unique version (timestamped) + * snapshots. + * <p/> + * Ex. + * artifact1 has the ff. versions retrieved from the db: + * - 1.0 + * - 1.1-20061118.060401-2 + * - 1.1-20061118.060402-3 + * - 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 + */ + private void processSnapshots( List versions ) + { + Map snapshots = new HashMap(); - if ( pomArtifact == null ) + getLogger().info( "Processing snapshots." ); + + for ( Iterator iter = versions.iterator(); iter.hasNext(); ) + { + String version = (String) iter.next(); + if ( VersionUtil.isSnapshot( version ) ) { - throw new ObjectNotFoundException( "Unable to find artifact [" + groupId + ":" + artifactId + ":" - + version + "]" ); + String baseVersion = VersionUtil.getBaseVersion( version ); + if ( !snapshots.containsKey( baseVersion ) ) + { + snapshots.put( baseVersion, baseVersion ); + } } } - catch ( ObjectNotFoundException e ) + + for ( Iterator it = ( snapshots.entrySet() ).iterator(); it.hasNext(); ) { - throw e; + String baseVersion = (String) ( (Map.Entry) it.next() ).getValue(); + if ( !versions.contains( baseVersion ) ) + { + versions.add( baseVersion ); + } } + } - ArchivaProjectModel model; - - if ( pomArtifact.getModel().isProcessed() ) + /** + * Handles querying of generic (*-SNAPSHOT) snapshot version. + * Process: + * - Get all the timestamped/unique versions of the artifact from the db + * - Sort the queried project models + * - 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 artifactId + * @param version + * @param pomArtifact + * @throws ArchivaDatabaseException + */ + private ArchivaArtifact handleGenericSnapshots( String groupId, String artifactId, String version, + ArchivaArtifact pomArtifact ) + throws ArchivaDatabaseException + { + if ( VersionUtil.isGenericSnapshot( version ) ) { - // It's been processed. return it. - model = dao.getProjectModelDAO().getProjectModel( groupId, artifactId, version ); - return model; + List versions = dao.query( new UniqueVersionConstraint( groupId, artifactId ) ); + Collections.sort( versions ); + Collections.reverse( versions ); + + for ( Iterator iter = versions.iterator(); iter.hasNext(); ) + { + String uniqueVersion = (String) iter.next(); + + if ( VersionUtil.getBaseVersion( uniqueVersion ).equals( version ) ) + { + getLogger().info( "Retrieving artifact with version " + uniqueVersion ); + pomArtifact = dao.getArtifactDAO().getArtifact( groupId, artifactId, uniqueVersion, null, "pom" ); + + return pomArtifact; + } + } } - // Process it. - dbUpdater.updateUnprocessed( pomArtifact ); + return null; + } - // Find it. + /** + * Get the project model from the database. + * + * @param groupId + * @param artifactId + * @param version + * @return + * @throws ArchivaDatabaseException + */ + private ArchivaProjectModel getProjectModel( String groupId, String artifactId, String version ) + throws ArchivaDatabaseException + { try { - model = dao.getProjectModelDAO().getProjectModel( groupId, artifactId, version ); + ArchivaProjectModel model = dao.getProjectModelDAO().getProjectModel( groupId, artifactId, version ); if ( model == null ) { - throw new ObjectNotFoundException( "Unable to find project model for [" + groupId + ":" + artifactId - + ":" + version + "]" ); + throw new ObjectNotFoundException( + "Unable to find project model for [" + groupId + ":" + artifactId + ":" + version + "]" ); } return model; @@ -150,18 +278,4 @@ public class DefaultRepositoryBrowsing } } - public List getUsedBy( String groupId, String artifactId, String version ) - throws ArchivaDatabaseException - { - ProjectsByArtifactUsageConstraint constraint = new ProjectsByArtifactUsageConstraint( groupId, artifactId, - version ); - List results = dao.getProjectModelDAO().queryProjectModels( constraint ); - if ( results == null ) - { - // defensive. to honor contract as specified. never null. - return Collections.EMPTY_LIST; - } - - return results; - } } diff --git a/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/tags/DependencyTree.java b/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/tags/DependencyTree.java index e0ae244f5..744e393ba 100644 --- a/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/tags/DependencyTree.java +++ b/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/tags/DependencyTree.java @@ -113,7 +113,7 @@ public class DependencyTree } } - public List gatherTreeList( String groupId, String artifactId, String version, String nodevar, + public List gatherTreeList( String groupId, String artifactId, String modelVersion, String nodevar, PageContext pageContext ) throws JspException { @@ -124,7 +124,7 @@ public class DependencyTree throw new JspException( emsg ); } - DependencyGraph graph = fetchGraph( groupId, artifactId, version ); + DependencyGraph graph = fetchGraph( groupId, artifactId, modelVersion ); if ( graph == null ) { @@ -213,18 +213,20 @@ public class DependencyTree } } - private DependencyGraph fetchGraph( String groupId, String artifactId, String version ) + private DependencyGraph fetchGraph( String groupId, String artifactId, String modelVersion ) { // TODO Cache the results to disk, in XML format, in the same place as the artifact is located. VersionedReference projectRef = new VersionedReference(); projectRef.setGroupId( groupId ); projectRef.setArtifactId( artifactId ); - projectRef.setVersion( version ); + projectRef.setVersion( modelVersion ); try { - return graphFactory.getGraph( projectRef ); + DependencyGraph depGraph = graphFactory.getGraph( projectRef ); + + return depGraph; } catch ( GraphTaskException e ) { diff --git a/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/tags/DependencyTreeTag.java b/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/tags/DependencyTreeTag.java index 4dab8fc97..451daa344 100644 --- a/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/tags/DependencyTreeTag.java +++ b/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/tags/DependencyTreeTag.java @@ -68,6 +68,8 @@ public class DependencyTreeTag private TreeEntry currentTreeEntry; + private String modelVersion; + public int doAfterBody() throws JspException { @@ -123,7 +125,7 @@ public class DependencyTreeTag nodevar = "node"; } - this.tree = deptree.gatherTreeList( groupId, artifactId, version, nodevar, pageContext ); + this.tree = deptree.gatherTreeList( groupId, artifactId, modelVersion, nodevar, pageContext ); if ( CollectionUtils.isEmpty( this.tree ) ) { @@ -172,6 +174,11 @@ public class DependencyTreeTag this.version = version; } + public void setModelVersion( String modelVersion ) + { + this.modelVersion = modelVersion; + } + private void exposeVariables() throws JspException { diff --git a/archiva-web/archiva-webapp/src/main/resources/META-INF/taglib.tld b/archiva-web/archiva-webapp/src/main/resources/META-INF/taglib.tld index 5c28a40d6..43473f122 100644 --- a/archiva-web/archiva-webapp/src/main/resources/META-INF/taglib.tld +++ b/archiva-web/archiva-webapp/src/main/resources/META-INF/taglib.tld @@ -127,6 +127,14 @@ </attribute> <attribute> + <name>modelVersion</name> + <required>false</required> + <rtexprvalue>true</rtexprvalue> + + <description><![CDATA[The version of the project model. Used to verify the dependency graph for generic snapshots not yet in the repo.]]></description> + </attribute> + + <attribute> <name>nodevar</name> <required>false</required> <rtexprvalue>true</rtexprvalue> diff --git a/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/artifact/dependencyTree.jsp b/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/artifact/dependencyTree.jsp index 69144918f..da2758350 100644 --- a/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/artifact/dependencyTree.jsp +++ b/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/artifact/dependencyTree.jsp @@ -21,7 +21,8 @@ <%@ taglib prefix="my" tagdir="/WEB-INF/tags" %> <%@ taglib prefix="archiva" uri="http://maven.apache.org/archiva" %> -<archiva:dependency-tree groupId="${groupId}" artifactId="${artifactId}" version="${version}"> +<archiva:dependency-tree groupId="${groupId}" artifactId="${artifactId}" version="${version}" + modelVersion="${model.version}"> <my:showArtifactLink groupId="${node.groupId}" artifactId="${node.artifactId}" - version="${node.version}"/> + version="${node.version}"/> </archiva:dependency-tree> diff --git a/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/decorators/artifactDecorator.jsp b/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/decorators/artifactDecorator.jsp index f9debf4c6..29515ec14 100644 --- a/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/decorators/artifactDecorator.jsp +++ b/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/decorators/artifactDecorator.jsp @@ -137,7 +137,7 @@ </div> <div class="sidebar3"> - <archiva:downloadArtifact groupId="${groupId}" artifactId="${artifactId}" version="${Version}" /> + <archiva:downloadArtifact groupId="${groupId}" artifactId="${artifactId}" version="${model.version}" /> </div> <decorator:body /> diff --git a/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/include/artifactInfo.jspf b/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/include/artifactInfo.jspf index b64c51cb7..43243548b 100644 --- a/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/include/artifactInfo.jspf +++ b/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/include/artifactInfo.jspf @@ -31,7 +31,7 @@ </ww:url> </c:set> <a href="${url}">${model.artifactId}</a> / - <strong>${model.version}</strong> + <strong>${version}</strong> <%-- TODO: new versions? (<strong class="statusFailed">Newer version available:</strong> @@ -109,8 +109,8 @@ <pre class="pom"> <dependency> <groupId>${model.groupId}</groupId> - <artifactId>${model.artifactId}</artifactId> - <version>${model.version}</version><c:if test="${model.packaging != 'jar'}"> + <artifactId>${model.artifactId}</artifactId> + <version>${version}</version><c:if test="${model.packaging != 'jar'}"> <type>${model.packaging}</type></c:if> </dependency> </pre> diff --git a/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/showArtifact.jsp b/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/showArtifact.jsp index ab40ad175..3ba975c72 100644 --- a/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/showArtifact.jsp +++ b/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/showArtifact.jsp @@ -96,7 +96,7 @@ <ww:url action="showArtifactDependencyTree"> <ww:param name="groupId" value="%{groupId}"/> <ww:param name="artifactId" value="%{artifactId}"/> - <ww:param name="version" value="%{version}"/> + <ww:param name="version" value="%{version}"/> </ww:url> </c:set> <my:currentWWUrl url="${url}">Dependency Tree</my:currentWWUrl> @@ -132,8 +132,8 @@ </span> </div> -<div class="sidebar3"> - <archiva:downloadArtifact groupId="${groupId}" artifactId="${artifactId}" version="${Version}" /> +<div class="sidebar3"> + <archiva:downloadArtifact groupId="${model.groupId}" artifactId="${model.artifactId}" version="${model.version}" /> </div> <%-- TODO: perhaps using ajax? --%> |