]> source.dussan.org Git - archiva.git/blob
b269a564e65e6b2b034cf9834ce05331fe090062
[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.BrowseResultEntry;
25 import org.apache.archiva.rest.api.model.BrowseResult;
26 import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
27 import org.apache.archiva.rest.api.services.BrowseService;
28 import org.apache.commons.collections.CollectionUtils;
29 import org.springframework.stereotype.Service;
30
31 import javax.ws.rs.core.Response;
32 import java.util.ArrayList;
33 import java.util.Collection;
34 import java.util.Collections;
35 import java.util.LinkedHashSet;
36 import java.util.List;
37 import java.util.Set;
38
39 /**
40  * @author Olivier Lamy
41  * @since 1.4-M3
42  */
43 @Service( "browseService#rest" )
44 public class DefaultBrowseService
45     extends AbstractRestService
46     implements BrowseService
47 {
48
49     public BrowseResult getRootGroups()
50         throws ArchivaRestServiceException
51     {
52         List<String> selectedRepos = getObservableRepos();
53         if ( CollectionUtils.isEmpty( selectedRepos ) )
54         {
55             // FIXME 403 ???
56             return new BrowseResult();
57         }
58
59         Set<String> namespaces = new LinkedHashSet<String>();
60
61         // TODO: this logic should be optional, particularly remembering we want to keep this code simple
62         //       it is located here to avoid the content repository implementation needing to do too much for what
63         //       is essentially presentation code
64         Set<String> namespacesToCollapse;
65         RepositorySession repositorySession = repositorySessionFactory.createSession();
66         try
67         {
68             MetadataResolver metadataResolver = repositorySession.getResolver();
69             namespacesToCollapse = new LinkedHashSet<String>();
70             for ( String repoId : selectedRepos )
71             {
72                 namespacesToCollapse.addAll( metadataResolver.resolveRootNamespaces( repositorySession, repoId ) );
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         List<BrowseResultEntry> browseGroupResultEntries = new ArrayList<BrowseResultEntry>( namespaces.size() );
91         for ( String namespace : namespaces )
92         {
93             browseGroupResultEntries.add( new BrowseResultEntry( namespace, false ) );
94         }
95
96         Collections.sort( browseGroupResultEntries );
97         return new BrowseResult( browseGroupResultEntries );
98     }
99
100     public BrowseResult browseGroupId( String groupId )
101         throws ArchivaRestServiceException
102     {
103
104         List<String> selectedRepos = getObservableRepos();
105         if ( CollectionUtils.isEmpty( selectedRepos ) )
106         {
107             // FIXME 403 ???
108             return new BrowseResult();
109         }
110
111         Set<String> projects = new LinkedHashSet<String>();
112
113         RepositorySession repositorySession = repositorySessionFactory.createSession();
114         Set<String> namespaces;
115         try
116         {
117             MetadataResolver metadataResolver = repositorySession.getResolver();
118
119             Set<String> namespacesToCollapse = new LinkedHashSet<String>();
120             for ( String repoId : selectedRepos )
121             {
122                 namespacesToCollapse.addAll( metadataResolver.resolveNamespaces( repositorySession, repoId, groupId ) );
123
124                 projects.addAll( metadataResolver.resolveProjects( repositorySession, repoId, groupId ) );
125             }
126
127             // TODO: this logic should be optional, particularly remembering we want to keep this code simple
128             // it is located here to avoid the content repository implementation needing to do too much for what
129             // is essentially presentation code
130             namespaces = new LinkedHashSet<String>();
131             for ( String n : namespacesToCollapse )
132             {
133                 // TODO: check performance of this
134                 namespaces.add(
135                     collapseNamespaces( repositorySession, metadataResolver, selectedRepos, groupId + "." + n ) );
136             }
137         }
138         catch ( MetadataResolutionException e )
139         {
140             throw new ArchivaRestServiceException( e.getMessage(),
141                                                    Response.Status.INTERNAL_SERVER_ERROR.getStatusCode() );
142         }
143         finally
144         {
145             repositorySession.close();
146         }
147         List<BrowseResultEntry> browseGroupResultEntries = new ArrayList<BrowseResultEntry>( namespaces.size() + projects.size() );
148         for ( String namespace : namespaces )
149         {
150             browseGroupResultEntries.add( new BrowseResultEntry( namespace, false ) );
151         }
152         for ( String project : projects )
153         {
154             browseGroupResultEntries.add( new BrowseResultEntry( project, true ) );
155         }
156         Collections.sort( browseGroupResultEntries );
157         return new BrowseResult( browseGroupResultEntries );
158
159     }
160
161     //---------------------------
162     // internals
163     //---------------------------
164
165     private List<String> getSortedList( Set<String> set )
166     {
167         List<String> list = new ArrayList<String>( set );
168         Collections.sort( list );
169         return list;
170     }
171
172     private String collapseNamespaces( RepositorySession repositorySession, MetadataResolver metadataResolver,
173                                        Collection<String> repoIds, String n )
174         throws MetadataResolutionException
175     {
176         Set<String> subNamespaces = new LinkedHashSet<String>();
177         for ( String repoId : repoIds )
178         {
179             subNamespaces.addAll( metadataResolver.resolveNamespaces( repositorySession, repoId, n ) );
180         }
181         if ( subNamespaces.size() != 1 )
182         {
183             log.debug( "{} is not collapsible as it has sub-namespaces: {}", n, subNamespaces );
184             return n;
185         }
186         else
187         {
188             for ( String repoId : repoIds )
189             {
190                 Collection<String> projects = metadataResolver.resolveProjects( repositorySession, repoId, n );
191                 if ( projects != null && !projects.isEmpty() )
192                 {
193                     log.debug( "{} is not collapsible as it has projects", n );
194                     return n;
195                 }
196             }
197             return collapseNamespaces( repositorySession, metadataResolver, repoIds,
198                                        n + "." + subNamespaces.iterator().next() );
199         }
200     }
201 }