]> source.dussan.org Git - archiva.git/blob
c83b9f19cc8aa0ec24e4b6010c29c4c54119232e
[archiva.git] /
1 package org.apache.archiva.rest.services;
2 /*
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  */
20
21 import org.apache.archiva.metadata.repository.MetadataResolutionException;
22 import org.apache.archiva.metadata.repository.MetadataResolver;
23 import org.apache.archiva.metadata.repository.RepositorySession;
24 import org.apache.archiva.rest.api.model.GroupIdList;
25 import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
26 import org.apache.archiva.rest.api.services.BrowseService;
27 import org.apache.commons.collections.CollectionUtils;
28 import org.springframework.stereotype.Service;
29
30 import javax.ws.rs.core.Response;
31 import java.util.ArrayList;
32 import java.util.Collection;
33 import java.util.Collections;
34 import java.util.LinkedHashSet;
35 import java.util.List;
36 import java.util.Set;
37
38 /**
39  * @author Olivier Lamy
40  * @since 1.4-M3
41  */
42 @Service( "browseService#rest" )
43 public class DefaultBrowseService
44     extends AbstractRestService
45     implements BrowseService
46 {
47
48     public GroupIdList getRootGroups()
49         throws ArchivaRestServiceException
50     {
51         List<String> selectedRepos = getObservableRepos();
52         if ( CollectionUtils.isEmpty( selectedRepos ) )
53         {
54             // FIXME 403 ???
55             return new GroupIdList( Collections.<String>emptyList() );
56         }
57
58         Set<String> namespaces = new LinkedHashSet<String>();
59
60         // TODO: this logic should be optional, particularly remembering we want to keep this code simple
61         //       it is located here to avoid the content repository implementation needing to do too much for what
62         //       is essentially presentation code
63         Set<String> namespacesToCollapse;
64         RepositorySession repositorySession = repositorySessionFactory.createSession();
65         try
66         {
67             MetadataResolver metadataResolver = repositorySession.getResolver();
68             namespacesToCollapse = new LinkedHashSet<String>();
69             for ( String repoId : selectedRepos )
70             {
71                 namespacesToCollapse.addAll( metadataResolver.resolveRootNamespaces( repositorySession, repoId ) );
72             }
73
74             for ( String n : namespacesToCollapse )
75             {
76                 // TODO: check performance of this
77                 namespaces.add( collapseNamespaces( repositorySession, metadataResolver, selectedRepos, n ) );
78             }
79         }
80         catch ( MetadataResolutionException e )
81         {
82             throw new ArchivaRestServiceException( e.getMessage(),
83                                                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
84         }
85         finally
86         {
87             repositorySession.close();
88         }
89
90         return new GroupIdList( getSortedList( namespaces ) );
91     }
92
93     //---------------------------
94     // internals
95     //---------------------------
96
97     private List<String> getSortedList( Set<String> set )
98     {
99         List<String> list = new ArrayList<String>( set );
100         Collections.sort( list );
101         return list;
102     }
103
104     private String collapseNamespaces( RepositorySession repositorySession, MetadataResolver metadataResolver,
105                                        Collection<String> repoIds, String n )
106         throws MetadataResolutionException
107     {
108         Set<String> subNamespaces = new LinkedHashSet<String>();
109         for ( String repoId : repoIds )
110         {
111             subNamespaces.addAll( metadataResolver.resolveNamespaces( repositorySession, repoId, n ) );
112         }
113         if ( subNamespaces.size() != 1 )
114         {
115             log.debug( "{} is not collapsible as it has sub-namespaces: {}", n, subNamespaces );
116             return n;
117         }
118         else
119         {
120             for ( String repoId : repoIds )
121             {
122                 Collection<String> projects = metadataResolver.resolveProjects( repositorySession, repoId, n );
123                 if ( projects != null && !projects.isEmpty() )
124                 {
125                     log.debug( "{} is not collapsible as it has projects", n );
126                     return n;
127                 }
128             }
129             return collapseNamespaces( repositorySession, metadataResolver, repoIds,
130                                        n + "." + subNamespaces.iterator().next() );
131         }
132     }
133 }