]> source.dussan.org Git - archiva.git/blob
5c040c7290c64ef05f38db5d4566518c2c333489
[archiva.git] /
1 package org.apache.archiva.web.action;
2
3 /*
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements.  See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership.  The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License.  You may obtain a copy of the License at
11  *
12  *   http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied.  See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  */
21
22 import org.apache.archiva.metadata.model.ProjectVersionMetadata;
23 import org.apache.archiva.metadata.repository.MetadataResolutionException;
24 import org.apache.archiva.metadata.repository.MetadataResolver;
25 import org.apache.archiva.metadata.repository.RepositorySession;
26 import org.apache.archiva.metadata.repository.storage.maven2.MavenProjectFacet;
27 import org.apache.commons.collections.CollectionUtils;
28 import org.apache.commons.lang.StringUtils;
29 import org.springframework.context.annotation.Scope;
30 import org.springframework.stereotype.Controller;
31
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  * Browse the repository.
41  *
42  * @todo implement repository selectors (all or specific repository)
43  */
44 @Controller( "browseAction" )
45 @Scope( "prototype" )
46 public class BrowseAction
47     extends AbstractRepositoryBasedAction
48 {
49     private String groupId;
50
51     private String artifactId;
52
53     private String repositoryId;
54
55     private ProjectVersionMetadata sharedModel;
56
57     private Collection<String> namespaces;
58
59     private Collection<String> projectIds;
60
61     private Collection<String> projectVersions;
62
63     public String browse()
64         throws MetadataResolutionException
65     {
66         List<String> selectedRepos = getObservableRepos();
67         if ( CollectionUtils.isEmpty( selectedRepos ) )
68         {
69             return GlobalResults.ACCESS_TO_NO_REPOS;
70         }
71
72         Set<String> namespaces = new LinkedHashSet<String>();
73
74         // TODO: this logic should be optional, particularly remembering we want to keep this code simple
75         //       it is located here to avoid the content repository implementation needing to do too much for what
76         //       is essentially presentation code
77         Set<String> namespacesToCollapse;
78         RepositorySession repositorySession = repositorySessionFactory.createSession();
79         try
80         {
81             MetadataResolver metadataResolver = repositorySession.getResolver();
82             namespacesToCollapse = new LinkedHashSet<String>();
83             for ( String repoId : selectedRepos )
84             {
85                 namespacesToCollapse.addAll( metadataResolver.resolveRootNamespaces( repositorySession, repoId ) );
86             }
87
88             for ( String n : namespacesToCollapse )
89             {
90                 // TODO: check performance of this
91                 namespaces.add( collapseNamespaces( repositorySession, metadataResolver, selectedRepos, n ) );
92             }
93         }
94         finally
95         {
96             repositorySession.close();
97         }
98
99         this.namespaces = getSortedList( namespaces );
100         return SUCCESS;
101     }
102
103     private String collapseNamespaces( RepositorySession repositorySession, MetadataResolver metadataResolver,
104                                        Collection<String> repoIds, String n )
105         throws MetadataResolutionException
106     {
107         Set<String> subNamespaces = new LinkedHashSet<String>();
108         for ( String repoId : repoIds )
109         {
110             subNamespaces.addAll( metadataResolver.resolveNamespaces( repositorySession, repoId, n ) );
111         }
112         if ( subNamespaces.size() != 1 )
113         {
114             log.debug( "{} is not collapsible as it has sub-namespaces: {}", n, subNamespaces );
115             return n;
116         }
117         else
118         {
119             for ( String repoId : repoIds )
120             {
121                 Collection<String> projects = metadataResolver.resolveProjects( repositorySession, repoId, n );
122                 if ( projects != null && !projects.isEmpty() )
123                 {
124                     log.debug( "{} is not collapsible as it has projects", n );
125                     return n;
126                 }
127             }
128             return collapseNamespaces( repositorySession, metadataResolver, repoIds,
129                                        n + "." + subNamespaces.iterator().next() );
130         }
131     }
132
133     public String browseGroup()
134         throws MetadataResolutionException
135     {
136         if ( StringUtils.isEmpty( groupId ) )
137         {
138             // TODO: i18n
139             addActionError( "You must specify a group ID to browse" );
140             return ERROR;
141         }
142
143         List<String> selectedRepos = getObservableRepos();
144         if ( CollectionUtils.isEmpty( selectedRepos ) )
145         {
146             return GlobalResults.ACCESS_TO_NO_REPOS;
147         }
148
149         Set<String> projects = new LinkedHashSet<String>();
150
151         RepositorySession repositorySession = repositorySessionFactory.createSession();
152         Set<String> namespaces;
153         try
154         {
155             MetadataResolver metadataResolver = repositorySession.getResolver();
156
157             Set<String> namespacesToCollapse = new LinkedHashSet<String>();
158             for ( String repoId : selectedRepos )
159             {
160                 namespacesToCollapse.addAll( metadataResolver.resolveNamespaces( repositorySession, repoId, groupId ) );
161
162                 projects.addAll( metadataResolver.resolveProjects( repositorySession, repoId, groupId ) );
163             }
164
165             // TODO: this logic should be optional, particularly remembering we want to keep this code simple
166             // it is located here to avoid the content repository implementation needing to do too much for what
167             // is essentially presentation code
168             namespaces = new LinkedHashSet<String>();
169             for ( String n : namespacesToCollapse )
170             {
171                 // TODO: check performance of this
172                 namespaces.add(
173                     collapseNamespaces( repositorySession, metadataResolver, selectedRepos, groupId + "." + n ) );
174             }
175         }
176         finally
177         {
178             repositorySession.close();
179         }
180
181         this.namespaces = getSortedList( namespaces );
182         this.projectIds = getSortedList( projects );
183         return SUCCESS;
184     }
185
186     private List<String> getSortedList( Set<String> set )
187     {
188         List<String> list = new ArrayList<String>( set );
189         Collections.sort( list );
190         return list;
191     }
192
193     public String browseArtifact()
194         throws MetadataResolutionException
195     {
196         if ( StringUtils.isEmpty( groupId ) )
197         {
198             // TODO: i18n
199             addActionError( "You must specify a group ID to browse" );
200             return ERROR;
201         }
202
203         if ( StringUtils.isEmpty( artifactId ) )
204         {
205             // TODO: i18n
206             addActionError( "You must specify a artifact ID to browse" );
207             return ERROR;
208         }
209
210         List<String> selectedRepos = getObservableRepos();
211         if ( CollectionUtils.isEmpty( selectedRepos ) )
212         {
213             return GlobalResults.ACCESS_TO_NO_REPOS;
214         }
215
216         RepositorySession repositorySession = repositorySessionFactory.createSession();
217         try
218         {
219             MetadataResolver metadataResolver = repositorySession.getResolver();
220
221             Set<String> versions = new LinkedHashSet<String>();
222             for ( String repoId : selectedRepos )
223             {
224                 versions.addAll(
225                     metadataResolver.resolveProjectVersions( repositorySession, repoId, groupId, artifactId ) );
226             }
227
228             // TODO: sort by known version ordering method
229             this.projectVersions = new ArrayList<String>( versions );
230
231             populateSharedModel( repositorySession, metadataResolver, selectedRepos, versions );
232         }
233         finally
234         {
235             repositorySession.close();
236         }
237
238         return SUCCESS;
239     }
240
241     private void populateSharedModel( RepositorySession repositorySession, MetadataResolver metadataResolver,
242                                       Collection<String> selectedRepos, Collection<String> projectVersions )
243     {
244         sharedModel = new ProjectVersionMetadata();
245
246         MavenProjectFacet mavenFacet = new MavenProjectFacet();
247         mavenFacet.setGroupId( groupId );
248         mavenFacet.setArtifactId( artifactId );
249         sharedModel.addFacet( mavenFacet );
250
251         boolean isFirstVersion = true;
252
253         for ( String version : projectVersions )
254         {
255             ProjectVersionMetadata versionMetadata = null;
256             for ( String repoId : selectedRepos )
257             {
258                 if ( versionMetadata == null )
259                 {
260                     try
261                     {
262                         versionMetadata =
263                             metadataResolver.resolveProjectVersion( repositorySession, repoId, groupId, artifactId,
264                                                                     version );
265                     }
266                     catch ( MetadataResolutionException e )
267                     {
268                         log.error(
269                             "Skipping invalid metadata while compiling shared model for " + groupId + ":" + artifactId
270                                 + " in repo " + repoId + ": " + e.getMessage() );
271                     }
272                 }
273             }
274
275             if ( versionMetadata == null )
276             {
277                 continue;
278             }
279
280             if ( isFirstVersion )
281             {
282                 sharedModel = versionMetadata;
283                 sharedModel.setId( null );
284             }
285             else
286             {
287                 MavenProjectFacet versionMetadataMavenFacet =
288                     (MavenProjectFacet) versionMetadata.getFacet( MavenProjectFacet.FACET_ID );
289                 if ( versionMetadataMavenFacet != null )
290                 {
291                     if ( mavenFacet.getPackaging() != null && !StringUtils.equalsIgnoreCase( mavenFacet.getPackaging(),
292                                                                                              versionMetadataMavenFacet.getPackaging() ) )
293                     {
294                         mavenFacet.setPackaging( null );
295                     }
296                 }
297
298                 if ( sharedModel.getName() != null && !StringUtils.equalsIgnoreCase( sharedModel.getName(),
299                                                                                      versionMetadata.getName() ) )
300                 {
301                     sharedModel.setName( "" );
302                 }
303
304                 if ( sharedModel.getDescription() != null && !StringUtils.equalsIgnoreCase(
305                     sharedModel.getDescription(), versionMetadata.getDescription() ) )
306                 {
307                     sharedModel.setDescription( null );
308                 }
309
310                 if ( sharedModel.getIssueManagement() != null && versionMetadata.getIssueManagement() != null
311                     && !StringUtils.equalsIgnoreCase( sharedModel.getIssueManagement().getUrl(),
312                                                       versionMetadata.getIssueManagement().getUrl() ) )
313                 {
314                     sharedModel.setIssueManagement( null );
315                 }
316
317                 if ( sharedModel.getCiManagement() != null && versionMetadata.getCiManagement() != null
318                     && !StringUtils.equalsIgnoreCase( sharedModel.getCiManagement().getUrl(),
319                                                       versionMetadata.getCiManagement().getUrl() ) )
320                 {
321                     sharedModel.setCiManagement( null );
322                 }
323
324                 if ( sharedModel.getOrganization() != null && versionMetadata.getOrganization() != null
325                     && !StringUtils.equalsIgnoreCase( sharedModel.getOrganization().getName(),
326                                                       versionMetadata.getOrganization().getName() ) )
327                 {
328                     sharedModel.setOrganization( null );
329                 }
330
331                 if ( sharedModel.getUrl() != null && !StringUtils.equalsIgnoreCase( sharedModel.getUrl(),
332                                                                                     versionMetadata.getUrl() ) )
333                 {
334                     sharedModel.setUrl( null );
335                 }
336             }
337
338             isFirstVersion = false;
339         }
340     }
341
342     public String getGroupId()
343     {
344         return groupId;
345     }
346
347     public void setGroupId( String groupId )
348     {
349         this.groupId = groupId;
350     }
351
352     public String getArtifactId()
353     {
354         return artifactId;
355     }
356
357     public void setArtifactId( String artifactId )
358     {
359         this.artifactId = artifactId;
360     }
361
362     public Collection<String> getNamespaces()
363     {
364         return namespaces;
365     }
366
367     public String getRepositoryId()
368     {
369
370         return repositoryId;
371     }
372
373     public void setRepositoryId( String repositoryId )
374     {
375
376         this.repositoryId = repositoryId;
377     }
378
379     public ProjectVersionMetadata getSharedModel()
380     {
381         return sharedModel;
382     }
383
384     public Collection<String> getProjectIds()
385     {
386         return projectIds;
387     }
388
389     public Collection<String> getProjectVersions()
390     {
391         return projectVersions;
392     }
393 }