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.ArrayList;
23 import java.util.Collections;
24 import java.util.Date;
25 import java.util.List;
27 import org.apache.commons.collections.CollectionUtils;
28 import org.apache.commons.collections.PredicateUtils;
29 import org.apache.commons.collections.functors.NotPredicate;
30 import org.apache.commons.lang.StringUtils;
31 import org.apache.maven.archiva.common.utils.VersionUtil;
32 import org.apache.maven.archiva.database.ArchivaDAO;
33 import org.apache.maven.archiva.database.ArchivaDatabaseException;
34 import org.apache.maven.archiva.database.ObjectNotFoundException;
35 import org.apache.maven.archiva.database.constraints.ArtifactsRelatedConstraint;
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;
69 * @see RepositoryBrowsing#getRoot(String, List)
71 public BrowsingResults getRoot( final String principal, final List<String> observableRepositoryIds )
73 final BrowsingResults results = new BrowsingResults();
75 if ( !observableRepositoryIds.isEmpty() )
77 final List<String> groups = dao.query( new UniqueGroupIdConstraint( observableRepositoryIds ) );
78 results.setSelectedRepositoryIds( observableRepositoryIds );
79 results.setGroupIds( GroupIdFilter.filterGroups( groups ) );
85 * @see RepositoryBrowsing#selectArtifactId(String, List, String, String)
87 public BrowsingResults selectArtifactId( final String principal, final List<String> observableRepositoryIds,
88 final String groupId, final String artifactId )
90 final BrowsingResults results = new BrowsingResults( groupId, artifactId );
92 if ( !observableRepositoryIds.isEmpty() )
94 // NOTE: No group Id or artifact Id's should be returned here.
95 List<String> versions =
96 dao.query( new UniqueVersionConstraint( observableRepositoryIds, groupId, artifactId ) );
97 results.setSelectedRepositoryIds( observableRepositoryIds );
99 results.setVersions( processSnapshots( versions ) );
105 * @see RepositoryBrowsing#selectGroupId(String, List, String)
107 public BrowsingResults selectGroupId( final String principal, final List<String> observableRepositoryIds,
108 final String groupId )
110 final BrowsingResults results = new BrowsingResults( groupId );
112 if ( !observableRepositoryIds.isEmpty() )
114 final List<String> groups = dao.query( new UniqueGroupIdConstraint( observableRepositoryIds, groupId ) );
115 final List<String> artifacts =
116 dao.query( new UniqueArtifactIdConstraint( observableRepositoryIds, groupId ) );
118 // Remove searched for groupId from groups list.
119 // Easier to do this here, vs doing it in the SQL query.
120 CollectionUtils.filter( groups, NotPredicate.getInstance( PredicateUtils.equalPredicate( groupId ) ) );
122 results.setGroupIds( groups );
123 results.setArtifacts( artifacts );
130 * @see RepositoryBrowsing#selectVersion(String, List, String, String, String)
132 public ArchivaProjectModel selectVersion( final String principal, final List<String> observableRepositoryIds,
133 final String groupId, final String artifactId, final String version )
134 throws ObjectNotFoundException, ArchivaDatabaseException
136 if ( observableRepositoryIds.isEmpty() )
138 throw new ArchivaDatabaseException( "There are no observable repositories for the user " + principal );
141 ArchivaArtifact pomArtifact = getArtifact( principal, observableRepositoryIds, groupId, artifactId, version );
143 ArchivaProjectModel model;
145 if ( !pomArtifact.getModel().isProcessed() )
148 dbUpdater.updateUnprocessed( pomArtifact );
151 model = getProjectModel( groupId, artifactId, pomArtifact.getVersion() );
156 public String getRepositoryId( final String principal, final List<String> observableRepositoryIds,
157 final String groupId, final String artifactId, final String version )
158 throws ObjectNotFoundException, ArchivaDatabaseException
160 if ( observableRepositoryIds.isEmpty() )
162 throw new ArchivaDatabaseException( "There are no observable repositories for the user " + principal );
167 ArchivaArtifact pomArchivaArtifact =
168 getArtifact( principal, observableRepositoryIds, groupId, artifactId, version );
170 return pomArchivaArtifact.getModel().getRepositoryId();
172 catch ( ObjectNotFoundException e )
174 return getNoPomArtifactRepoId( principal, observableRepositoryIds, groupId, artifactId, version,
175 observableRepositoryIds.get( 0 ) );
180 * @see RepositoryBrowsing#getOtherSnapshotVersions(List, String, String, String)
182 public List<String> getOtherSnapshotVersions( List<String> observableRepositoryIds, String groupId,
183 String artifactId, String version )
184 throws ObjectNotFoundException, ArchivaDatabaseException
186 List<String> timestampedVersions = new ArrayList<String>();
188 if ( VersionUtil.isSnapshot( version ) )
190 List<String> versions =
191 dao.query( new UniqueVersionConstraint( observableRepositoryIds, groupId, artifactId ) );
193 for ( String uniqueVersion : versions )
195 if ( VersionUtil.getBaseVersion( uniqueVersion ).equals( version ) ||
196 VersionUtil.getBaseVersion( uniqueVersion ).equals( VersionUtil.getBaseVersion( version ) ) )
198 if ( !timestampedVersions.contains( uniqueVersion ) )
200 timestampedVersions.add( uniqueVersion );
206 return timestampedVersions;
209 private ArchivaArtifact getArtifact( final String principal, final List<String> observableRepositoryIds,
210 final String groupId, final String artifactId, final String version )
211 throws ObjectNotFoundException, ArchivaDatabaseException
213 ArchivaArtifact pomArtifact = null;
215 for ( final String repositoryId : observableRepositoryIds )
220 dao.getArtifactDAO().getArtifact( groupId, artifactId, version, null, "pom", repositoryId );
223 catch ( ArchivaDatabaseException e )
225 pomArtifact = handleGenericSnapshots( groupId, artifactId, version, repositoryId );
229 if ( pomArtifact == null )
231 String type = getArtifactType( groupId, artifactId, version );
233 // We dont want these to persist in the database
235 new ArchivaArtifact( groupId, artifactId, version, null, type, observableRepositoryIds.get( 0 ) );
236 pomArtifact.getModel().setWhenProcessed( new Date() );
239 // Allowed to see this?
240 if ( observableRepositoryIds.contains( pomArtifact.getModel().getRepositoryId() ) )
246 throw new ObjectNotFoundException( "Unable to find artifact " + Keys.toKey( groupId, artifactId, version ) +
247 " in observable repository [" + StringUtils.join( observableRepositoryIds.iterator(), ", " ) +
248 "] for user " + principal );
252 public List<ArchivaProjectModel> getUsedBy( final String principal, final List<String> observableRepositoryIds,
253 final String groupId, final String artifactId, final String version )
254 throws ArchivaDatabaseException
256 ProjectsByArtifactUsageConstraint constraint =
257 new ProjectsByArtifactUsageConstraint( groupId, artifactId, version );
258 List<ArchivaProjectModel> results = dao.getProjectModelDAO().queryProjectModels( constraint );
259 if ( results == null )
261 // defensive. to honor contract as specified. never null.
262 return Collections.EMPTY_LIST;
269 * Removes SNAPSHOT versions with build numbers. Retains only the generic SNAPSHOT version.
270 * Example, if the list of versions are:
273 * - 2.1-20070522.143249-1
274 * - 2.1-20070522.157829-2
276 * the returned version list would contain 2.0, 2.0.1 and 2.1-SNAPSHOT.
280 private List<String> processSnapshots( List<String> versions )
282 List<String> cleansedVersions = new ArrayList<String>();
284 for ( String version : versions )
286 if ( VersionUtil.isSnapshot( version ) )
288 String baseVersion = VersionUtil.getBaseVersion( version );
289 if ( !cleansedVersions.contains( baseVersion ) )
291 cleansedVersions.add( baseVersion );
296 cleansedVersions.add( version );
300 return cleansedVersions;
304 * Handles querying of generic (*-SNAPSHOT) snapshot version. Process: - Get all the timestamped/unique versions of
305 * the artifact from the db - Sort the queried project models - Reverse the list of queried project models to get
306 * the latest timestamp version - Loop through the list and get the first one to match the generic (*-SNAPHOT)
313 * @throws ArchivaDatabaseException
315 private ArchivaArtifact handleGenericSnapshots( final String groupId, final String artifactId,
316 final String version, final String repositoryId )
317 throws ArchivaDatabaseException
319 ArchivaArtifact result = null;
321 if ( VersionUtil.isGenericSnapshot( version ) )
323 final List<String> versions = dao.query( new UniqueVersionConstraint( groupId, artifactId ) );
324 Collections.sort( versions );
325 Collections.reverse( versions );
327 for ( String uniqueVersion : versions )
329 if ( VersionUtil.getBaseVersion( uniqueVersion ).equals( version ) )
333 log.debug( "Retrieving artifact with version " + uniqueVersion );
335 dao.getArtifactDAO().getArtifact( groupId, artifactId, uniqueVersion, null, "pom", repositoryId );
338 catch ( ObjectNotFoundException e )
340 log.debug( "Artifact '" + groupId + ":" + artifactId + ":" + uniqueVersion +
341 "' in repository '" + repositoryId + "' not found in the database." );
351 * Get the project model from the database.
357 * @throws ArchivaDatabaseException
359 private ArchivaProjectModel getProjectModel( String groupId, String artifactId, String version )
360 throws ArchivaDatabaseException
362 ArchivaProjectModel model = null;
366 model = dao.getProjectModelDAO().getProjectModel( groupId, artifactId, version );
368 catch ( ObjectNotFoundException e )
370 log.debug( "Unable to find project model for [" + Keys.toKey( groupId, artifactId, version ) + "]", e );
375 model = new ArchivaProjectModel();
376 model.setGroupId( groupId );
377 model.setArtifactId( artifactId );
378 model.setVersion( version );
384 private String getNoPomArtifactRepoId( String principal, List<String> observableRepos, String groupId,
385 String artifactId, String version, String repositoryId )
386 throws ObjectNotFoundException, ArchivaDatabaseException
388 ArchivaArtifact artifact = null;
390 String type = getArtifactType( groupId, artifactId, version );
392 artifact = dao.getArtifactDAO().createArtifact( groupId, artifactId, version, null, type, repositoryId );
394 if ( artifact == null )
396 // Lets not persist these
397 artifact = new ArchivaArtifact( groupId, artifactId, version, null, type, repositoryId );
400 // Allowed to see this?
401 if ( !observableRepos.contains( artifact.getModel().getRepositoryId() ) )
403 throw new ObjectNotFoundException( "Unable to find artifact " + Keys.toKey( groupId, artifactId, version ) +
404 " in observable repository [" + StringUtils.join( observableRepos.iterator(), ", " ) + "] for user " +
408 return artifact.getModel().getRepositoryId();
411 private String getArtifactType( String groupId, String artifactId, String version )
412 throws ObjectNotFoundException, ArchivaDatabaseException
418 List<ArchivaArtifact> artifacts =
419 dao.getArtifactDAO().queryArtifacts( new ArtifactsRelatedConstraint( groupId, artifactId, version ) );
421 if ( artifacts.size() > 0 )
423 type = artifacts.get( 0 ).getType();
426 catch ( ObjectNotFoundException e )
428 // swallow exception?