1 package org.apache.maven.archiva.web.action;
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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
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;
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;
37 * Browse the repository.
39 * @todo implement repository selectors (all or specific repository)
40 * @plexus.component role="com.opensymphony.xwork2.Action" role-hint="browseAction" instantiation-strategy="per-lookup"
42 public class BrowseAction
43 extends AbstractRepositoryBasedAction
48 private MetadataResolver metadataResolver;
50 private String groupId;
52 private String artifactId;
54 private String repositoryId;
56 private ProjectVersionMetadata sharedModel;
58 private Collection<String> namespaces;
60 private Collection<String> projectIds;
62 private Collection<String> projectVersions;
64 public String browse()
65 throws MetadataResolutionException
67 List<String> selectedRepos = getObservableRepos();
68 if ( CollectionUtils.isEmpty( selectedRepos ) )
70 return GlobalResults.ACCESS_TO_NO_REPOS;
73 Set<String> namespaces = new LinkedHashSet<String>();
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 )
81 namespacesToCollapse.addAll( metadataResolver.resolveRootNamespaces( repoId ) );
84 for ( String n : namespacesToCollapse )
86 // TODO: check performance of this
87 namespaces.add( collapseNamespaces( selectedRepos, n ) );
90 this.namespaces = getSortedList( namespaces );
94 private String collapseNamespaces( Collection<String> repoIds, String n )
95 throws MetadataResolutionException
97 Set<String> subNamespaces = new LinkedHashSet<String>();
98 for ( String repoId : repoIds )
100 subNamespaces.addAll( metadataResolver.resolveNamespaces( repoId, n ) );
102 if ( subNamespaces.size() != 1 )
104 if ( log.isDebugEnabled() )
106 log.debug( n + " is not collapsible as it has sub-namespaces: " + subNamespaces );
112 for ( String repoId : repoIds )
114 Collection<String> projects = metadataResolver.resolveProjects( repoId, n );
115 if ( projects != null && !projects.isEmpty() )
117 if ( log.isDebugEnabled() )
119 log.debug( n + " is not collapsible as it has projects" );
124 return collapseNamespaces( repoIds, n + "." + subNamespaces.iterator().next() );
128 public String browseGroup()
129 throws MetadataResolutionException
131 if ( StringUtils.isEmpty( groupId ) )
134 addActionError( "You must specify a group ID to browse" );
138 List<String> selectedRepos = getObservableRepos();
139 if ( CollectionUtils.isEmpty( selectedRepos ) )
141 return GlobalResults.ACCESS_TO_NO_REPOS;
144 Set<String> projects = new LinkedHashSet<String>();
146 Set<String> namespacesToCollapse = new LinkedHashSet<String>();
147 for ( String repoId : selectedRepos )
149 namespacesToCollapse.addAll( metadataResolver.resolveNamespaces( repoId, groupId ) );
151 projects.addAll( metadataResolver.resolveProjects( repoId, groupId ) );
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 )
160 // TODO: check performance of this
161 namespaces.add( collapseNamespaces( selectedRepos, groupId + "." + n ) );
164 this.namespaces = getSortedList( namespaces );
165 this.projectIds = getSortedList( projects );
169 private ArrayList<String> getSortedList( Set<String> set )
171 ArrayList<String> list = new ArrayList<String>( set );
172 Collections.sort( list );
176 public String browseArtifact()
177 throws MetadataResolutionException
179 if ( StringUtils.isEmpty( groupId ) )
182 addActionError( "You must specify a group ID to browse" );
186 if ( StringUtils.isEmpty( artifactId ) )
189 addActionError( "You must specify a artifact ID to browse" );
193 List<String> selectedRepos = getObservableRepos();
194 if ( CollectionUtils.isEmpty( selectedRepos ) )
196 return GlobalResults.ACCESS_TO_NO_REPOS;
199 Set<String> versions = new LinkedHashSet<String>();
200 for ( String repoId : selectedRepos )
202 versions.addAll( metadataResolver.resolveProjectVersions( repoId, groupId, artifactId ) );
205 // TODO: sort by known version ordering method
206 this.projectVersions = new ArrayList<String>( versions );
208 populateSharedModel( selectedRepos, versions );
213 private void populateSharedModel( Collection<String> selectedRepos, Collection<String> projectVersions )
215 sharedModel = new ProjectVersionMetadata();
217 MavenProjectFacet mavenFacet = new MavenProjectFacet();
218 mavenFacet.setGroupId( groupId );
219 mavenFacet.setArtifactId( artifactId );
220 sharedModel.addFacet( mavenFacet );
222 boolean isFirstVersion = true;
224 for ( String version : projectVersions )
226 ProjectVersionMetadata versionMetadata = null;
227 for ( String repoId : selectedRepos )
229 if ( versionMetadata == null )
233 versionMetadata = metadataResolver.resolveProjectVersion( repoId, groupId, artifactId,
236 catch ( MetadataResolutionException e )
239 "Skipping invalid metadata while compiling shared model for " + groupId + ":" + artifactId +
240 " in repo " + repoId + ": " + e.getMessage() );
245 if ( versionMetadata == null )
250 if ( isFirstVersion )
252 sharedModel = versionMetadata;
253 sharedModel.setId( null );
257 MavenProjectFacet versionMetadataMavenFacet = (MavenProjectFacet) versionMetadata.getFacet(
258 MavenProjectFacet.FACET_ID );
259 if ( versionMetadataMavenFacet != null )
261 if ( mavenFacet.getPackaging() != null && !StringUtils.equalsIgnoreCase( mavenFacet.getPackaging(),
262 versionMetadataMavenFacet.getPackaging() ) )
264 mavenFacet.setPackaging( null );
268 if ( sharedModel.getName() != null && !StringUtils.equalsIgnoreCase( sharedModel.getName(),
269 versionMetadata.getName() ) )
271 sharedModel.setName( "" );
274 if ( sharedModel.getDescription() != null && !StringUtils.equalsIgnoreCase(
275 sharedModel.getDescription(), versionMetadata.getDescription() ) )
277 sharedModel.setDescription( null );
280 if ( sharedModel.getIssueManagement() != null && versionMetadata.getIssueManagement() != null &&
281 !StringUtils.equalsIgnoreCase( sharedModel.getIssueManagement().getUrl(),
282 versionMetadata.getIssueManagement().getUrl() ) )
284 sharedModel.setIssueManagement( null );
287 if ( sharedModel.getCiManagement() != null && versionMetadata.getCiManagement() != null &&
288 !StringUtils.equalsIgnoreCase( sharedModel.getCiManagement().getUrl(),
289 versionMetadata.getCiManagement().getUrl() ) )
291 sharedModel.setCiManagement( null );
294 if ( sharedModel.getOrganization() != null && versionMetadata.getOrganization() != null &&
295 !StringUtils.equalsIgnoreCase( sharedModel.getOrganization().getName(),
296 versionMetadata.getOrganization().getName() ) )
298 sharedModel.setOrganization( null );
301 if ( sharedModel.getUrl() != null && !StringUtils.equalsIgnoreCase( sharedModel.getUrl(),
302 versionMetadata.getUrl() ) )
304 sharedModel.setUrl( null );
308 isFirstVersion = false;
312 public String getGroupId()
317 public void setGroupId( String groupId )
319 this.groupId = groupId;
322 public String getArtifactId()
327 public void setArtifactId( String artifactId )
329 this.artifactId = artifactId;
332 public Collection<String> getNamespaces()
337 public String getRepositoryId()
343 public void setRepositoryId( String repositoryId )
346 this.repositoryId = repositoryId;
349 public ProjectVersionMetadata getSharedModel()
354 public MetadataResolver getMetadataResolver()
356 return metadataResolver;
359 public Collection<String> getProjectIds()
364 public Collection<String> getProjectVersions()
366 return projectVersions;