]> source.dussan.org Git - archiva.git/blob
bd7ef5155656632c1e794a10367677a3622c10db
[archiva.git] /
1 package org.apache.maven.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.storage.maven2.MavenProjectFacet;
26 import org.apache.commons.collections.CollectionUtils;
27 import org.apache.commons.lang.StringUtils;
28
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.LinkedHashSet;
33 import java.util.List;
34 import java.util.Set;
35
36 /**
37  * Browse the repository.
38  *
39  * @todo implement repository selectors (all or specific repository)
40  * @plexus.component role="com.opensymphony.xwork2.Action" role-hint="browseAction" instantiation-strategy="per-lookup"
41  */
42 public class BrowseAction
43     extends AbstractRepositoryBasedAction
44 {
45     /**
46      * @plexus.requirement
47      */
48     private MetadataResolver metadataResolver;
49
50     private String groupId;
51
52     private String artifactId;
53
54     private String repositoryId;
55
56     private ProjectVersionMetadata sharedModel;
57
58     private Collection<String> namespaces;
59
60     private Collection<String> projectIds;
61
62     private Collection<String> projectVersions;
63
64     public String browse()
65         throws MetadataResolutionException
66     {
67         List<String> selectedRepos = getObservableRepos();
68         if ( CollectionUtils.isEmpty( selectedRepos ) )
69         {
70             return GlobalResults.ACCESS_TO_NO_REPOS;
71         }
72
73         Set<String> namespaces = new LinkedHashSet<String>();
74
75         // TODO: this logic should be optional, particularly remembering we want to keep this code simple
76         //       it is located here to avoid the content repository implementation needing to do too much for what
77         //       is essentially presentation code
78         Set<String> namespacesToCollapse = new LinkedHashSet<String>();
79         for ( String repoId : selectedRepos )
80         {
81             namespacesToCollapse.addAll( metadataResolver.resolveRootNamespaces( repoId ) );
82         }
83
84         for ( String n : namespacesToCollapse )
85         {
86             // TODO: check performance of this
87             namespaces.add( collapseNamespaces( selectedRepos, n ) );
88         }
89
90         this.namespaces = getSortedList( namespaces );
91         return SUCCESS;
92     }
93
94     private String collapseNamespaces( Collection<String> repoIds, String n )
95         throws MetadataResolutionException
96     {
97         Set<String> subNamespaces = new LinkedHashSet<String>();
98         for ( String repoId : repoIds )
99         {
100             subNamespaces.addAll( metadataResolver.resolveNamespaces( repoId, n ) );
101         }
102         if ( subNamespaces.size() != 1 )
103         {
104             if ( log.isDebugEnabled() )
105             {
106                 log.debug( n + " is not collapsible as it has sub-namespaces: " + subNamespaces );
107             }
108             return n;
109         }
110         else
111         {
112             for ( String repoId : repoIds )
113             {
114                 Collection<String> projects = metadataResolver.resolveProjects( repoId, n );
115                 if ( projects != null && !projects.isEmpty() )
116                 {
117                     if ( log.isDebugEnabled() )
118                     {
119                         log.debug( n + " is not collapsible as it has projects" );
120                     }
121                     return n;
122                 }
123             }
124             return collapseNamespaces( repoIds, n + "." + subNamespaces.iterator().next() );
125         }
126     }
127
128     public String browseGroup()
129         throws MetadataResolutionException
130     {
131         if ( StringUtils.isEmpty( groupId ) )
132         {
133             // TODO: i18n
134             addActionError( "You must specify a group ID to browse" );
135             return ERROR;
136         }
137
138         List<String> selectedRepos = getObservableRepos();
139         if ( CollectionUtils.isEmpty( selectedRepos ) )
140         {
141             return GlobalResults.ACCESS_TO_NO_REPOS;
142         }
143
144         Set<String> projects = new LinkedHashSet<String>();
145
146         Set<String> namespacesToCollapse = new LinkedHashSet<String>();
147         for ( String repoId : selectedRepos )
148         {
149             namespacesToCollapse.addAll( metadataResolver.resolveNamespaces( repoId, groupId ) );
150
151             projects.addAll( metadataResolver.resolveProjects( repoId, groupId ) );
152         }
153
154         // TODO: this logic should be optional, particularly remembering we want to keep this code simple
155         //       it is located here to avoid the content repository implementation needing to do too much for what
156         //       is essentially presentation code
157         Set<String> namespaces = new LinkedHashSet<String>();
158         for ( String n : namespacesToCollapse )
159         {
160             // TODO: check performance of this
161             namespaces.add( collapseNamespaces( selectedRepos, groupId + "." + n ) );
162         }
163
164         this.namespaces = getSortedList( namespaces );
165         this.projectIds = getSortedList( projects );
166         return SUCCESS;
167     }
168
169     private ArrayList<String> getSortedList( Set<String> set )
170     {
171         ArrayList<String> list = new ArrayList<String>( set );
172         Collections.sort( list );
173         return list;
174     }
175
176     public String browseArtifact()
177         throws MetadataResolutionException
178     {
179         if ( StringUtils.isEmpty( groupId ) )
180         {
181             // TODO: i18n
182             addActionError( "You must specify a group ID to browse" );
183             return ERROR;
184         }
185
186         if ( StringUtils.isEmpty( artifactId ) )
187         {
188             // TODO: i18n
189             addActionError( "You must specify a artifact ID to browse" );
190             return ERROR;
191         }
192
193         List<String> selectedRepos = getObservableRepos();
194         if ( CollectionUtils.isEmpty( selectedRepos ) )
195         {
196             return GlobalResults.ACCESS_TO_NO_REPOS;
197         }
198
199         Set<String> versions = new LinkedHashSet<String>();
200         for ( String repoId : selectedRepos )
201         {
202             versions.addAll( metadataResolver.resolveProjectVersions( repoId, groupId, artifactId ) );
203         }
204
205         // TODO: sort by known version ordering method
206         this.projectVersions = new ArrayList<String>( versions );
207
208         populateSharedModel( selectedRepos, versions );
209
210         return SUCCESS;
211     }
212
213     private void populateSharedModel( Collection<String> selectedRepos, Collection<String> projectVersions )
214     {
215         sharedModel = new ProjectVersionMetadata();
216
217         MavenProjectFacet mavenFacet = new MavenProjectFacet();
218         mavenFacet.setGroupId( groupId );
219         mavenFacet.setArtifactId( artifactId );
220         sharedModel.addFacet( mavenFacet );
221
222         boolean isFirstVersion = true;
223
224         for ( String version : projectVersions )
225         {
226             ProjectVersionMetadata versionMetadata = null;
227             for ( String repoId : selectedRepos )
228             {
229                 if ( versionMetadata == null )
230                 {
231                     try
232                     {
233                         versionMetadata = metadataResolver.resolveProjectVersion( repoId, groupId, artifactId,
234                                                                                   version );
235                     }
236                     catch ( MetadataResolutionException e )
237                     {
238                         log.error(
239                             "Skipping invalid metadata while compiling shared model for " + groupId + ":" + artifactId +
240                                 " in repo " + repoId + ": " + e.getMessage() );
241                     }
242                 }
243             }
244
245             if ( versionMetadata == null )
246             {
247                 continue;
248             }
249
250             if ( isFirstVersion )
251             {
252                 sharedModel = versionMetadata;
253                 sharedModel.setId( null );
254             }
255             else
256             {
257                 MavenProjectFacet versionMetadataMavenFacet = (MavenProjectFacet) versionMetadata.getFacet(
258                     MavenProjectFacet.FACET_ID );
259                 if ( versionMetadataMavenFacet != null )
260                 {
261                     if ( mavenFacet.getPackaging() != null && !StringUtils.equalsIgnoreCase( mavenFacet.getPackaging(),
262                                                                                              versionMetadataMavenFacet.getPackaging() ) )
263                     {
264                         mavenFacet.setPackaging( null );
265                     }
266                 }
267
268                 if ( sharedModel.getName() != null && !StringUtils.equalsIgnoreCase( sharedModel.getName(),
269                                                                                      versionMetadata.getName() ) )
270                 {
271                     sharedModel.setName( "" );
272                 }
273
274                 if ( sharedModel.getDescription() != null && !StringUtils.equalsIgnoreCase(
275                     sharedModel.getDescription(), versionMetadata.getDescription() ) )
276                 {
277                     sharedModel.setDescription( null );
278                 }
279
280                 if ( sharedModel.getIssueManagement() != null && versionMetadata.getIssueManagement() != null &&
281                     !StringUtils.equalsIgnoreCase( sharedModel.getIssueManagement().getUrl(),
282                                                    versionMetadata.getIssueManagement().getUrl() ) )
283                 {
284                     sharedModel.setIssueManagement( null );
285                 }
286
287                 if ( sharedModel.getCiManagement() != null && versionMetadata.getCiManagement() != null &&
288                     !StringUtils.equalsIgnoreCase( sharedModel.getCiManagement().getUrl(),
289                                                    versionMetadata.getCiManagement().getUrl() ) )
290                 {
291                     sharedModel.setCiManagement( null );
292                 }
293
294                 if ( sharedModel.getOrganization() != null && versionMetadata.getOrganization() != null &&
295                     !StringUtils.equalsIgnoreCase( sharedModel.getOrganization().getName(),
296                                                    versionMetadata.getOrganization().getName() ) )
297                 {
298                     sharedModel.setOrganization( null );
299                 }
300
301                 if ( sharedModel.getUrl() != null && !StringUtils.equalsIgnoreCase( sharedModel.getUrl(),
302                                                                                     versionMetadata.getUrl() ) )
303                 {
304                     sharedModel.setUrl( null );
305                 }
306             }
307
308             isFirstVersion = false;
309         }
310     }
311
312     public String getGroupId()
313     {
314         return groupId;
315     }
316
317     public void setGroupId( String groupId )
318     {
319         this.groupId = groupId;
320     }
321
322     public String getArtifactId()
323     {
324         return artifactId;
325     }
326
327     public void setArtifactId( String artifactId )
328     {
329         this.artifactId = artifactId;
330     }
331
332     public Collection<String> getNamespaces()
333     {
334         return namespaces;
335     }
336
337     public String getRepositoryId()
338     {
339
340         return repositoryId;
341     }
342
343     public void setRepositoryId( String repositoryId )
344     {
345
346         this.repositoryId = repositoryId;
347     }
348
349     public ProjectVersionMetadata getSharedModel()
350     {
351         return sharedModel;
352     }
353
354     public MetadataResolver getMetadataResolver()
355     {
356         return metadataResolver;
357     }
358
359     public Collection<String> getProjectIds()
360     {
361         return projectIds;
362     }
363
364     public Collection<String> getProjectVersions()
365     {
366         return projectVersions;
367     }
368 }