mirror of https://github.com/apache/archiva.git
[MRM-1573] start work on browse screen
git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@1244606 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
dc0f7bd90d
commit
f6ec5a7e86
|
@ -0,0 +1,43 @@
|
|||
package org.apache.archiva.rest.api.services;
|
||||
/*
|
||||
* 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.rest.api.model.GroupIdList;
|
||||
import org.codehaus.plexus.redback.authorization.RedbackAuthorization;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Olivier Lamy
|
||||
* @since 1.4-M3
|
||||
*/
|
||||
@Path( "/browseService/" )
|
||||
public interface BrowseService
|
||||
{
|
||||
@Path( "rootGroups" )
|
||||
@GET
|
||||
@Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML } )
|
||||
@RedbackAuthorization( noRestriction = true, noPermission = false )
|
||||
GroupIdList getRootGroups()
|
||||
throws ArchivaRestServiceException;
|
||||
}
|
|
@ -20,8 +20,14 @@ package org.apache.archiva.rest.services;
|
|||
|
||||
import org.apache.archiva.admin.model.AuditInformation;
|
||||
import org.apache.archiva.audit.AuditListener;
|
||||
import org.apache.archiva.metadata.repository.RepositorySessionFactory;
|
||||
import org.apache.archiva.security.AccessDeniedException;
|
||||
import org.apache.archiva.security.ArchivaSecurityException;
|
||||
import org.apache.archiva.security.PrincipalNotFoundException;
|
||||
import org.apache.archiva.security.UserRepositories;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.codehaus.plexus.redback.users.User;
|
||||
import org.codehaus.plexus.redback.users.UserManager;
|
||||
import org.codehaus.redback.rest.services.RedbackAuthenticationThreadLocal;
|
||||
import org.codehaus.redback.rest.services.RedbackRequestInformation;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -29,9 +35,11 @@ import org.slf4j.LoggerFactory;
|
|||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.core.Context;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -50,6 +58,14 @@ public abstract class AbstractRestService
|
|||
@Inject
|
||||
private List<AuditListener> auditListeners = new ArrayList<AuditListener>();
|
||||
|
||||
@Inject
|
||||
private UserRepositories userRepositories;
|
||||
|
||||
|
||||
@Inject
|
||||
@Named( value = "repositorySessionFactory" )
|
||||
protected RepositorySessionFactory repositorySessionFactory;
|
||||
|
||||
@Context
|
||||
protected HttpServletRequest httpServletRequest;
|
||||
|
||||
|
@ -71,6 +87,39 @@ public abstract class AbstractRestService
|
|||
this.auditListeners = auditListeners;
|
||||
}
|
||||
|
||||
protected List<String> getObservableRepos()
|
||||
{
|
||||
try
|
||||
{
|
||||
List<String> ids = userRepositories.getObservableRepositoryIds( getPrincipal() );
|
||||
return ids == null ? Collections.<String>emptyList() : ids;
|
||||
}
|
||||
catch ( PrincipalNotFoundException e )
|
||||
{
|
||||
log.warn( e.getMessage(), e );
|
||||
}
|
||||
catch ( AccessDeniedException e )
|
||||
{
|
||||
log.warn( e.getMessage(), e );
|
||||
}
|
||||
catch ( ArchivaSecurityException e )
|
||||
{
|
||||
log.warn( e.getMessage(), e );
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
protected String getPrincipal()
|
||||
{
|
||||
RedbackRequestInformation redbackRequestInformation = RedbackAuthenticationThreadLocal.get();
|
||||
|
||||
return redbackRequestInformation == null
|
||||
? UserManager.GUEST_USERNAME
|
||||
: ( redbackRequestInformation.getUser() == null
|
||||
? UserManager.GUEST_USERNAME
|
||||
: redbackRequestInformation.getUser().getUsername() );
|
||||
}
|
||||
|
||||
protected String getBaseUrl( HttpServletRequest req )
|
||||
{
|
||||
return req.getScheme() + "://" + req.getServerName() + ( req.getServerPort() == 80
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
package org.apache.archiva.rest.services;
|
||||
/*
|
||||
* 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.repository.MetadataResolutionException;
|
||||
import org.apache.archiva.metadata.repository.MetadataResolver;
|
||||
import org.apache.archiva.metadata.repository.RepositorySession;
|
||||
import org.apache.archiva.rest.api.model.GroupIdList;
|
||||
import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
|
||||
import org.apache.archiva.rest.api.services.BrowseService;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Olivier Lamy
|
||||
* @since 1.4-M3
|
||||
*/
|
||||
@Service( "browseService#rest" )
|
||||
public class DefaultBrowseService
|
||||
extends AbstractRestService
|
||||
implements BrowseService
|
||||
{
|
||||
|
||||
public GroupIdList getRootGroups()
|
||||
throws ArchivaRestServiceException
|
||||
{
|
||||
List<String> selectedRepos = getObservableRepos();
|
||||
if ( CollectionUtils.isEmpty( selectedRepos ) )
|
||||
{
|
||||
// FIXME 403 ???
|
||||
return new GroupIdList( Collections.<String>emptyList() );
|
||||
}
|
||||
|
||||
Set<String> namespaces = new LinkedHashSet<String>();
|
||||
|
||||
// TODO: this logic should be optional, particularly remembering we want to keep this code simple
|
||||
// it is located here to avoid the content repository implementation needing to do too much for what
|
||||
// is essentially presentation code
|
||||
Set<String> namespacesToCollapse;
|
||||
RepositorySession repositorySession = repositorySessionFactory.createSession();
|
||||
try
|
||||
{
|
||||
MetadataResolver metadataResolver = repositorySession.getResolver();
|
||||
namespacesToCollapse = new LinkedHashSet<String>();
|
||||
for ( String repoId : selectedRepos )
|
||||
{
|
||||
namespacesToCollapse.addAll( metadataResolver.resolveRootNamespaces( repositorySession, repoId ) );
|
||||
}
|
||||
|
||||
for ( String n : namespacesToCollapse )
|
||||
{
|
||||
// TODO: check performance of this
|
||||
namespaces.add( collapseNamespaces( repositorySession, metadataResolver, selectedRepos, n ) );
|
||||
}
|
||||
}
|
||||
catch ( MetadataResolutionException e )
|
||||
{
|
||||
throw new ArchivaRestServiceException( e.getMessage(),
|
||||
Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
|
||||
}
|
||||
finally
|
||||
{
|
||||
repositorySession.close();
|
||||
}
|
||||
|
||||
return new GroupIdList( getSortedList( namespaces ) );
|
||||
}
|
||||
|
||||
//---------------------------
|
||||
// internals
|
||||
//---------------------------
|
||||
|
||||
private List<String> getSortedList( Set<String> set )
|
||||
{
|
||||
List<String> list = new ArrayList<String>( set );
|
||||
Collections.sort( list );
|
||||
return list;
|
||||
}
|
||||
|
||||
private String collapseNamespaces( RepositorySession repositorySession, MetadataResolver metadataResolver,
|
||||
Collection<String> repoIds, String n )
|
||||
throws MetadataResolutionException
|
||||
{
|
||||
Set<String> subNamespaces = new LinkedHashSet<String>();
|
||||
for ( String repoId : repoIds )
|
||||
{
|
||||
subNamespaces.addAll( metadataResolver.resolveNamespaces( repositorySession, repoId, n ) );
|
||||
}
|
||||
if ( subNamespaces.size() != 1 )
|
||||
{
|
||||
log.debug( "{} is not collapsible as it has sub-namespaces: {}", n, subNamespaces );
|
||||
return n;
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( String repoId : repoIds )
|
||||
{
|
||||
Collection<String> projects = metadataResolver.resolveProjects( repositorySession, repoId, n );
|
||||
if ( projects != null && !projects.isEmpty() )
|
||||
{
|
||||
log.debug( "{} is not collapsible as it has projects", n );
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return collapseNamespaces( repositorySession, metadataResolver, repoIds,
|
||||
n + "." + subNamespaces.iterator().next() );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -56,20 +56,12 @@ public class DefaultManagedRepositoriesService
|
|||
@Inject
|
||||
private ManagedRepositoryAdmin managedRepositoryAdmin;
|
||||
|
||||
@Inject
|
||||
private PlexusSisuBridge plexusSisuBridge;
|
||||
|
||||
@Inject
|
||||
private RepositoryCommonValidator repositoryCommonValidator;
|
||||
|
||||
@Inject
|
||||
private RepositoryStatisticsManager repositoryStatisticsManager;
|
||||
|
||||
@Inject
|
||||
@Named( value = "repositorySessionFactory" )
|
||||
protected RepositorySessionFactory repositorySessionFactory;
|
||||
|
||||
|
||||
public List<ManagedRepository> getManagedRepositories()
|
||||
throws ArchivaRestServiceException
|
||||
{
|
||||
|
|
|
@ -61,14 +61,10 @@ public class DefaultSearchService
|
|||
implements SearchService
|
||||
{
|
||||
|
||||
private Logger log = LoggerFactory.getLogger( getClass() );
|
||||
|
||||
@Inject
|
||||
private RepositorySearch repositorySearch;
|
||||
|
||||
@Inject
|
||||
private UserRepositories userRepositories;
|
||||
|
||||
public List<Artifact> quickSearch( String queryString )
|
||||
throws ArchivaRestServiceException
|
||||
{
|
||||
|
@ -180,40 +176,6 @@ public class DefaultSearchService
|
|||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
|
||||
protected List<String> getObservableRepos()
|
||||
{
|
||||
try
|
||||
{
|
||||
List<String> ids = userRepositories.getObservableRepositoryIds( getPrincipal() );
|
||||
return ids == null ? Collections.<String>emptyList() : ids;
|
||||
}
|
||||
catch ( PrincipalNotFoundException e )
|
||||
{
|
||||
log.warn( e.getMessage(), e );
|
||||
}
|
||||
catch ( AccessDeniedException e )
|
||||
{
|
||||
log.warn( e.getMessage(), e );
|
||||
}
|
||||
catch ( ArchivaSecurityException e )
|
||||
{
|
||||
log.warn( e.getMessage(), e );
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
protected String getPrincipal()
|
||||
{
|
||||
RedbackRequestInformation redbackRequestInformation = RedbackAuthenticationThreadLocal.get();
|
||||
|
||||
return redbackRequestInformation == null
|
||||
? UserManager.GUEST_USERNAME
|
||||
: ( redbackRequestInformation.getUser() == null
|
||||
? UserManager.GUEST_USERNAME
|
||||
: redbackRequestInformation.getUser().getUsername() );
|
||||
}
|
||||
|
||||
protected List<Artifact> getArtifacts( SearchResults searchResults )
|
||||
{
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
<ref bean="archivaAdministrationService#default"/>
|
||||
<ref bean="searchService#rest"/>
|
||||
<ref bean="commonServices#rest"/>
|
||||
<ref bean="browseService#rest"/>
|
||||
</jaxrs:serviceBeans>
|
||||
|
||||
<jaxrs:outInterceptors>
|
||||
|
|
|
@ -17,8 +17,29 @@
|
|||
* under the License.
|
||||
*/
|
||||
$(function() {
|
||||
|
||||
BrowseTopViewModel=function(groupIds){
|
||||
this.groupIds=groupIds;
|
||||
|
||||
|
||||
}
|
||||
|
||||
displayBrowse=function(){
|
||||
$("#main-content" ).html("coming soon :-)");
|
||||
var mainContent = $("#main-content");
|
||||
mainContent.html(mediumSpinnerImg());
|
||||
$.ajax("restServices/archivaServices/browseService/rootGroups", {
|
||||
type: "GET",
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
var groupdIds = $.map(data.groupIdList.groupIds,function(item){
|
||||
return item;
|
||||
});
|
||||
$.log("size:"+groupdIds.length);
|
||||
var browseTopViewModel = new BrowseTopViewModel(groupdIds);
|
||||
mainContent.html($("#browse-tmpl" ).tmpl());
|
||||
ko.applyBindings(browseTopViewModel,mainContent.find("#browse_result" ).get(0));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
displaySearch=function(){
|
||||
|
|
|
@ -15,4 +15,23 @@
|
|||
~ KIND, either express or implied. See the License for the
|
||||
~ specific language governing permissions and limitations
|
||||
~ under the License.
|
||||
-->
|
||||
-->
|
||||
|
||||
<script id="browse-tmpl" type="text/html">
|
||||
<div>
|
||||
<div class="page-header">
|
||||
<h2>${$.i18n.prop('browse.groups')}</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div id="browse_result" data-bind='template:{name:"browse-top-tmpl"}'>
|
||||
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script id="browse-top-tmpl" type="text/html">
|
||||
<ul>
|
||||
{{each(i,groupId) groupIds}}
|
||||
<li>${groupId}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</script>
|
|
@ -183,9 +183,9 @@ public class BrowseAction
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
private ArrayList<String> getSortedList( Set<String> set )
|
||||
private List<String> getSortedList( Set<String> set )
|
||||
{
|
||||
ArrayList<String> list = new ArrayList<String>( set );
|
||||
List<String> list = new ArrayList<String>( set );
|
||||
Collections.sort( list );
|
||||
return list;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue