From 110d0116270b01f63aa1c3be2668dc81681078f1 Mon Sep 17 00:00:00 2001 From: Olivier Lamy Date: Thu, 22 Mar 2012 17:52:17 +0000 Subject: [PATCH] [MRM-1615] Artifact detail view start working on dependency tree tab add a rest service. git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1303921 13f79535-47bb-0310-9956-ffa450edef68 --- .../archiva/rest/api/model/TreeEntry.java | 69 +++++++++++ .../rest/api/services/BrowseService.java | 10 ++ .../rest/services/DefaultBrowseService.java | 114 ++++++++++++++++++ .../src/main/webapp/js/archiva/search.js | 22 +++- .../webapp/js/archiva/templates/search.html | 15 ++- 5 files changed, 226 insertions(+), 4 deletions(-) create mode 100644 archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/TreeEntry.java diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/TreeEntry.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/TreeEntry.java new file mode 100644 index 000000000..6ed3b2f3a --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/model/TreeEntry.java @@ -0,0 +1,69 @@ +package org.apache.archiva.rest.api.model; +/* + * 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 javax.xml.bind.annotation.XmlRootElement; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Olivier Lamy + */ +@XmlRootElement( name = "treeEntry" ) +public class TreeEntry + implements Serializable +{ + + private List childs = new ArrayList(); + + + private Artifact artifact; + + public TreeEntry() + { + // no op + } + + public TreeEntry( Artifact artifact ) + { + this.artifact = artifact; + } + + + public Artifact getArtifact() + { + return artifact; + } + + public void setArtifact( Artifact artifact ) + { + this.artifact = artifact; + } + + public List getChilds() + { + return childs; + } + + public void setChilds( List childs ) + { + this.childs = childs; + } +} diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/BrowseService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/BrowseService.java index 92091d2ed..bd9095f19 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/BrowseService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/services/BrowseService.java @@ -21,6 +21,7 @@ package org.apache.archiva.rest.api.services; import org.apache.archiva.admin.model.beans.ManagedRepository; import org.apache.archiva.metadata.model.ProjectVersionMetadata; import org.apache.archiva.rest.api.model.BrowseResult; +import org.apache.archiva.rest.api.model.TreeEntry; import org.apache.archiva.rest.api.model.VersionsList; import org.codehaus.plexus.redback.authorization.RedbackAuthorization; @@ -86,4 +87,13 @@ public interface BrowseService @RedbackAuthorization( noPermission = true, noRestriction = true ) List getUserRepositories() throws ArchivaRestServiceException; + + @Path( "treeEntries/{g}/{a}/{v}" ) + @GET + @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } ) + @RedbackAuthorization( noPermission = true, noRestriction = true ) + List getTreeEntries( @PathParam( "g" ) String groupId, @PathParam( "a" ) String artifactId, + @PathParam( "v" ) String version, + @QueryParam( "repositoryId" ) String repositoryId ) + throws ArchivaRestServiceException; } diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java index 6889de8b6..59a922b98 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/services/DefaultBrowseService.java @@ -18,23 +18,31 @@ package org.apache.archiva.rest.services; * under the License. */ +import net.sf.beanlib.provider.replicator.BeanReplicator; import org.apache.archiva.admin.model.beans.ManagedRepository; import org.apache.archiva.common.utils.VersionComparator; +import org.apache.archiva.dependency.tree.maven2.DependencyTreeBuilder; import org.apache.archiva.metadata.model.ProjectVersionMetadata; import org.apache.archiva.metadata.repository.MetadataResolutionException; import org.apache.archiva.metadata.repository.MetadataResolver; import org.apache.archiva.metadata.repository.RepositorySession; import org.apache.archiva.metadata.repository.storage.maven2.MavenProjectFacet; +import org.apache.archiva.rest.api.model.Artifact; import org.apache.archiva.rest.api.model.BrowseResult; import org.apache.archiva.rest.api.model.BrowseResultEntry; +import org.apache.archiva.rest.api.model.TreeEntry; import org.apache.archiva.rest.api.model.VersionsList; import org.apache.archiva.rest.api.services.ArchivaRestServiceException; import org.apache.archiva.rest.api.services.BrowseService; import org.apache.archiva.security.ArchivaSecurityException; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; +import org.apache.maven.shared.dependency.tree.DependencyNode; +import org.apache.maven.shared.dependency.tree.DependencyTreeBuilderException; +import org.apache.maven.shared.dependency.tree.traversal.DependencyNodeVisitor; import org.springframework.stereotype.Service; +import javax.inject.Inject; import javax.ws.rs.core.Response; import java.util.ArrayList; import java.util.Collection; @@ -53,6 +61,9 @@ public class DefaultBrowseService implements BrowseService { + @Inject + private DependencyTreeBuilder dependencyTreeBuilder; + public BrowseResult getRootGroups( String repositoryId ) throws ArchivaRestServiceException { @@ -459,6 +470,109 @@ public class DefaultBrowseService } } + public List getTreeEntries( String groupId, String artifactId, String version, String repositoryId ) + throws ArchivaRestServiceException + { + List selectedRepos = getObservableRepos(); + + if ( CollectionUtils.isEmpty( selectedRepos ) ) + { + // FIXME 403 ??? + return null; + } + + if ( StringUtils.isNotEmpty( repositoryId ) ) + { + // check user has karma on the repository + if ( !selectedRepos.contains( repositoryId ) ) + { + throw new ArchivaRestServiceException( "browse.root.groups.repositoy.denied", + Response.Status.FORBIDDEN.getStatusCode() ); + } + selectedRepos = Collections.singletonList( repositoryId ); + } + + List treeEntries = new ArrayList(); + TreeDependencyNodeVisitor treeDependencyNodeVisitor = new TreeDependencyNodeVisitor( treeEntries ); + try + { + dependencyTreeBuilder.buildDependencyTree( selectedRepos, groupId, artifactId, version, + treeDependencyNodeVisitor ); + } + catch ( DependencyTreeBuilderException e ) + { + throw new ArchivaRestServiceException( e.getMessage(), + Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() ); + } + return treeEntries; + } + + private static class TreeDependencyNodeVisitor + implements DependencyNodeVisitor + { + final List treeEntries; + + private TreeEntry currentEntry; + + private DependencyNode firstNode; + + private TreeDependencyNodeVisitor( List treeEntries ) + { + this.treeEntries = treeEntries; + } + + public boolean visit( DependencyNode node ) + { + if ( firstNode == null ) + { + firstNode = node; + } + if ( currentEntry == null ) + { + currentEntry = + new TreeEntry( new BeanReplicator().replicateBean( node.getArtifact(), Artifact.class ) ); + treeEntries.add( currentEntry ); + } + else + { + if ( node.getChildren().isEmpty() ) + { + currentEntry.getChilds().add( + new TreeEntry( new BeanReplicator().replicateBean( node.getArtifact(), Artifact.class ) ) ); + } + } + + if ( !node.getChildren().isEmpty() ) + { + for ( DependencyNode dependencyNode : (List) node.getChildren() ) + { + if ( dependencyNode.getChildren().isEmpty() ) + { + this.currentEntry.getChilds().add( new TreeEntry( + new BeanReplicator().replicateBean( dependencyNode.getArtifact(), Artifact.class ) ) ); + } + else + { + TreeEntry backup = this.currentEntry; + this.currentEntry = new TreeEntry( + new BeanReplicator().replicateBean( dependencyNode.getArtifact(), Artifact.class ) ); + visit( dependencyNode ); + this.currentEntry = backup; + } + } + } + + return true; + } + + public boolean endVisit( DependencyNode node ) + { + firstNode = null; + return true; + } + + } + public List getUserRepositories() throws ArchivaRestServiceException { diff --git a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/search.js b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/search.js index c74476d44..fc8086833 100644 --- a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/search.js +++ b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/search.js @@ -202,7 +202,25 @@ $(function() { mainContent.find("#browse-autocomplete-divider" ).hide(); mainContent.find("#artifact-details-tabs").on('show', function (e) { if ($(e.target).attr("href")=="#artifact-details-dependency-tree-content") { - $.log("#artifact-details-dependency-tree-content"); + var treeContentDiv=$("#artifact-details-dependency-tree-content" ); + //if( $.trim(treeContentDiv.html()).length<1){ + treeContentDiv.html(mediumSpinnerImg()); + var treeDependencyUrl="restServices/archivaServices/browseService/treeEntries/"+encodeURIComponent(groupId); + treeDependencyUrl+="/"+encodeURIComponent(artifactId); + treeDependencyUrl+="/"+encodeURIComponent(version); + var selectedRepo=getSelectedBrowsingRepository(); + if (selectedRepo){ + treeDependencyUrl+="?repositoryId="+encodeURIComponent(selectedRepo); + } + var treeDependencyUrl= + $.ajax(treeDependencyUrl, { + type: "GET", + dataType: 'json', + success: function(data) { + treeContentDiv.html($("#dependency_tree_tmpl" ).tmpl({treeEntries: [data[0]]})); + } + }); + //} } if ($(e.target).attr("href")=="#artifact-details-used-by-content") { $.log("#artifact-details-used-by-content"); @@ -231,6 +249,8 @@ $(function() { } } + + displayArtifactDetail=function(groupId,artifactId,parentBrowseViewModel,restUrl){ var artifactDetailViewModel=new ArtifactDetailViewModel(groupId,artifactId); var mainContent = $("#main-content"); diff --git a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/templates/search.html b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/templates/search.html index 5f75fc32c..d10ee5dd9 100644 --- a/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/templates/search.html +++ b/archiva-modules/archiva-web/archiva-webapp-js/src/main/webapp/js/archiva/templates/search.html @@ -607,9 +607,7 @@ -
- dependency tree -
+
used by @@ -674,4 +672,15 @@
+ + + \ No newline at end of file -- 2.39.5