1 package org.apache.maven.archiva.database.browsing;
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 java.util.Collections;
23 import java.util.HashMap;
24 import java.util.List;
26 import java.util.Map.Entry;
28 import org.apache.commons.collections.CollectionUtils;
29 import org.apache.commons.collections.PredicateUtils;
30 import org.apache.commons.collections.functors.NotPredicate;
31 import org.apache.commons.lang.StringUtils;
32 import org.apache.maven.archiva.common.utils.VersionUtil;
33 import org.apache.maven.archiva.database.ArchivaDAO;
34 import org.apache.maven.archiva.database.ArchivaDatabaseException;
35 import org.apache.maven.archiva.database.ObjectNotFoundException;
36 import org.apache.maven.archiva.database.constraints.ProjectsByArtifactUsageConstraint;
37 import org.apache.maven.archiva.database.constraints.UniqueArtifactIdConstraint;
38 import org.apache.maven.archiva.database.constraints.UniqueGroupIdConstraint;
39 import org.apache.maven.archiva.database.constraints.UniqueVersionConstraint;
40 import org.apache.maven.archiva.database.updater.DatabaseUpdater;
41 import org.apache.maven.archiva.model.ArchivaArtifact;
42 import org.apache.maven.archiva.model.ArchivaProjectModel;
43 import org.apache.maven.archiva.model.Keys;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
48 * DefaultRepositoryBrowsing
51 * @plexus.component role="org.apache.maven.archiva.database.browsing.RepositoryBrowsing"
53 public class DefaultRepositoryBrowsing
54 implements RepositoryBrowsing
56 private Logger log = LoggerFactory.getLogger( DefaultRepositoryBrowsing.class );
59 * @plexus.requirement role-hint="jdo"
61 private ArchivaDAO dao;
64 * @plexus.requirement role-hint="jdo"
66 private DatabaseUpdater dbUpdater;
68 public BrowsingResults getRoot( final String principle, final List<String> observableRepositoryIds )
70 List<String> groups = dao.query( new UniqueGroupIdConstraint( observableRepositoryIds ) );
72 BrowsingResults results = new BrowsingResults();
73 results.setSelectedRepositoryIds( observableRepositoryIds );
75 results.setGroupIds( GroupIdFilter.filterGroups( groups ) );
80 public BrowsingResults selectArtifactId( final String principle, final List<String> observableRepositoryIds, final String groupId,
81 final String artifactId )
83 // NOTE: No group Id or artifact Id's should be returned here.
84 List<String> versions = dao.query( new UniqueVersionConstraint( observableRepositoryIds, groupId, artifactId ) );
86 BrowsingResults results = new BrowsingResults( groupId, artifactId );
87 results.setSelectedRepositoryIds( observableRepositoryIds );
89 processSnapshots( versions );
91 results.setVersions( versions );
96 public BrowsingResults selectGroupId( final String principle, final List<String> observableRepositoryIds, final String groupId )
98 List<String> groups = dao.query( new UniqueGroupIdConstraint( observableRepositoryIds, groupId ) );
99 List<String> artifacts = dao.query( new UniqueArtifactIdConstraint( observableRepositoryIds, groupId ) );
101 BrowsingResults results = new BrowsingResults( groupId );
103 // Remove searched for groupId from groups list.
104 // Easier to do this here, vs doing it in the SQL query.
105 CollectionUtils.filter( groups, NotPredicate.getInstance( PredicateUtils.equalPredicate( groupId ) ) );
107 results.setGroupIds( groups );
108 results.setArtifacts( artifacts );
113 public ArchivaProjectModel selectVersion( final String principle, final List<String> observableRepositoryIds, final String groupId,
114 final String artifactId, final String version )
115 throws ObjectNotFoundException, ArchivaDatabaseException
117 ArchivaArtifact pomArtifact = getArtifact( principle, observableRepositoryIds, groupId, artifactId, version );
119 ArchivaProjectModel model;
121 if ( !pomArtifact.getModel().isProcessed() )
124 dbUpdater.updateUnprocessed( pomArtifact );
127 model = getProjectModel( groupId, artifactId, pomArtifact.getVersion() );
132 public String getRepositoryId( final String principle, final List<String> observableRepositoryIds, final String groupId,
133 final String artifactId, final String version )
134 throws ObjectNotFoundException, ArchivaDatabaseException
136 ArchivaArtifact pomArchivaArtifact =
137 getArtifact( principle, observableRepositoryIds, groupId, artifactId, version );
139 return pomArchivaArtifact.getModel().getRepositoryId();
142 private ArchivaArtifact getArtifact( final String principal, final List<String> observableRepositoryIds, final String groupId,
143 final String artifactId, final String version )
144 throws ObjectNotFoundException, ArchivaDatabaseException
146 ArchivaArtifact pomArtifact = null;
148 for (final String repositoryId : observableRepositoryIds)
152 pomArtifact = dao.getArtifactDAO().getArtifact( groupId, artifactId, version, null, "pom", repositoryId );
154 catch ( ObjectNotFoundException e )
156 pomArtifact = handleGenericSnapshots( groupId, artifactId, version, repositoryId );
161 if ( pomArtifact == null )
163 throw new ObjectNotFoundException( "Unable to find artifact [" + Keys.toKey( groupId, artifactId, version )
167 // Allowed to see this?
168 if ( observableRepositoryIds.contains( pomArtifact.getModel().getRepositoryId() ) )
174 throw new ObjectNotFoundException( "Unable to find artifact " + Keys.toKey( groupId, artifactId, version )
175 + " in observable repository [" + StringUtils.join( observableRepositoryIds.iterator(), ", " )
176 + "] for user " + principal );
180 public List<ArchivaProjectModel> getUsedBy( final String principle, final List<String> observableRepositoryIds, final String groupId,
181 final String artifactId, final String version )
182 throws ArchivaDatabaseException
184 ProjectsByArtifactUsageConstraint constraint = new ProjectsByArtifactUsageConstraint( groupId, artifactId,
186 List<ArchivaProjectModel> results = dao.getProjectModelDAO().queryProjectModels( constraint );
187 if ( results == null )
189 // defensive. to honor contract as specified. never null.
190 return Collections.EMPTY_LIST;
197 * Add generic (*-SNAPSHOT) snapshot versions in the list for artifacts with only unique version (timestamped)
201 * artifact1 has the ff. versions retrieved from the db:
203 * - 1.1-20061118.060401-2
204 * - 1.1-20061118.060402-3
205 * - 2.2-20071007.070101-1
206 * - 2.2-20071007.070110-2
209 * This method will add a '1.1-SNAPSHOT' in the list since there is no generic snapshot entry for it.
210 * When this version is browsed, the pom of the latest snapshot will be displayed.
214 private void processSnapshots( final List<String> versions )
216 Map<String, String> snapshots = new HashMap<String, String>();
218 for ( String version : versions )
220 if ( VersionUtil.isSnapshot( version ) )
222 String baseVersion = VersionUtil.getBaseVersion( version );
223 if ( !snapshots.containsKey( baseVersion ) )
225 snapshots.put( baseVersion, baseVersion );
230 for ( Entry<String, String> entry : snapshots.entrySet() )
232 String baseVersion = entry.getValue();
233 if ( !versions.contains( baseVersion ) )
235 versions.add( baseVersion );
241 * Handles querying of generic (*-SNAPSHOT) snapshot version.
243 * - Get all the timestamped/unique versions of the artifact from the db
244 * - Sort the queried project models
245 * - Reverse the list of queried project models to get the latest timestamp version
246 * - Loop through the list and get the first one to match the generic (*-SNAPHOT) version
252 * @throws ArchivaDatabaseException
254 private ArchivaArtifact handleGenericSnapshots( final String groupId, final String artifactId, final String version, final String repositoryId )
255 throws ArchivaDatabaseException
257 ArchivaArtifact result = null;
259 if ( VersionUtil.isGenericSnapshot( version ) )
261 List<String> versions = dao.query( new UniqueVersionConstraint( groupId, artifactId ) );
262 Collections.sort( versions );
263 Collections.reverse( versions );
265 for ( String uniqueVersion : versions )
267 if ( VersionUtil.getBaseVersion( uniqueVersion ).equals( version ) )
269 log.info( "Retrieving artifact with version " + uniqueVersion );
270 result = dao.getArtifactDAO().getArtifact( groupId, artifactId, uniqueVersion, null, "pom", repositoryId );
278 * Get the project model from the database.
284 * @throws ArchivaDatabaseException
286 private ArchivaProjectModel getProjectModel( String groupId, String artifactId, String version )
287 throws ArchivaDatabaseException
291 ArchivaProjectModel model = dao.getProjectModelDAO().getProjectModel( groupId, artifactId, version );
295 throw new ObjectNotFoundException( "Unable to find project model for ["
296 + Keys.toKey( groupId, artifactId, version ) + "]" );
301 catch ( ObjectNotFoundException e )