mirror of https://github.com/apache/archiva.git
[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
This commit is contained in:
parent
f1c69d471f
commit
110d011627
|
@ -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<TreeEntry> childs = new ArrayList<TreeEntry>();
|
||||
|
||||
|
||||
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<TreeEntry> getChilds()
|
||||
{
|
||||
return childs;
|
||||
}
|
||||
|
||||
public void setChilds( List<TreeEntry> childs )
|
||||
{
|
||||
this.childs = childs;
|
||||
}
|
||||
}
|
|
@ -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<ManagedRepository> getUserRepositories()
|
||||
throws ArchivaRestServiceException;
|
||||
|
||||
@Path( "treeEntries/{g}/{a}/{v}" )
|
||||
@GET
|
||||
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
|
||||
@RedbackAuthorization( noPermission = true, noRestriction = true )
|
||||
List<TreeEntry> getTreeEntries( @PathParam( "g" ) String groupId, @PathParam( "a" ) String artifactId,
|
||||
@PathParam( "v" ) String version,
|
||||
@QueryParam( "repositoryId" ) String repositoryId )
|
||||
throws ArchivaRestServiceException;
|
||||
}
|
||||
|
|
|
@ -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<TreeEntry> getTreeEntries( String groupId, String artifactId, String version, String repositoryId )
|
||||
throws ArchivaRestServiceException
|
||||
{
|
||||
List<String> 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<TreeEntry> treeEntries = new ArrayList<TreeEntry>();
|
||||
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<TreeEntry> treeEntries;
|
||||
|
||||
private TreeEntry currentEntry;
|
||||
|
||||
private DependencyNode firstNode;
|
||||
|
||||
private TreeDependencyNodeVisitor( List<TreeEntry> 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<DependencyNode>) 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<ManagedRepository> getUserRepositories()
|
||||
throws ArchivaRestServiceException
|
||||
{
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -607,9 +607,7 @@
|
|||
</table>
|
||||
</div>
|
||||
|
||||
<div id="artifact-details-dependency-tree-content" class="tab-pane">
|
||||
dependency tree
|
||||
</div>
|
||||
<div id="artifact-details-dependency-tree-content" class="tab-pane"></div>
|
||||
|
||||
<div id="artifact-details-used-by-content" class="tab-pane">
|
||||
used by
|
||||
|
@ -674,4 +672,15 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script id="dependency_tree_tmpl" type="text/html">
|
||||
<ul>
|
||||
{{each(i,treeEntry) treeEntries}}
|
||||
<li>${treeEntry.artifact.groupId}:${treeEntry.artifact.artifactId}:${treeEntry.artifact.version}</li>
|
||||
{{if treeEntry.childs.length>0}}
|
||||
{{tmpl({treeEntries:treeEntry.childs}) "#dependency_tree_tmpl"}}
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</ul>
|
||||
</script>
|
Loading…
Reference in New Issue