1 package org.apache.archiva.repository.content.maven2;
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.admin.model.beans.ManagedRepository;
23 import org.apache.archiva.common.utils.PathUtil;
24 import org.apache.archiva.configuration.FileTypes;
25 import org.apache.archiva.metadata.repository.storage.maven2.DefaultArtifactMappingProvider;
26 import org.apache.archiva.model.ArchivaArtifact;
27 import org.apache.archiva.model.ArtifactReference;
28 import org.apache.archiva.model.ProjectReference;
29 import org.apache.archiva.model.VersionedReference;
30 import org.apache.archiva.repository.ContentNotFoundException;
31 import org.apache.archiva.repository.ManagedRepositoryContent;
32 import org.apache.archiva.repository.RepositoryException;
33 import org.apache.archiva.repository.layout.LayoutException;
34 import org.apache.commons.io.FileUtils;
35 import org.apache.commons.lang.StringUtils;
36 import org.springframework.context.annotation.Scope;
37 import org.springframework.stereotype.Service;
39 import javax.inject.Inject;
40 import javax.inject.Named;
42 import java.io.IOException;
43 import java.util.Collections;
44 import java.util.HashSet;
48 * ManagedDefaultRepositoryContent
50 @Service ("managedRepositoryContent#default")
52 public class ManagedDefaultRepositoryContent
53 extends AbstractDefaultRepositoryContent
54 implements ManagedRepositoryContent
57 @Named ( "fileTypes" )
58 private FileTypes filetypes;
60 private ManagedRepository repository;
62 public ManagedDefaultRepositoryContent()
64 // default to use if there are none supplied as components
65 this.artifactMappingProviders = Collections.singletonList( new DefaultArtifactMappingProvider() );
69 public void deleteVersion( VersionedReference reference )
71 String path = toMetadataPath( reference );
72 File projectPath = new File( getRepoRoot(), path );
74 File projectDir = projectPath.getParentFile();
75 if ( projectDir.exists() && projectDir.isDirectory() )
77 FileUtils.deleteQuietly( projectDir );
82 public void deleteProject( String namespace, String projectId )
83 throws RepositoryException, ContentNotFoundException
85 ArtifactReference artifactReference = new ArtifactReference();
86 artifactReference.setGroupId( namespace );
87 artifactReference.setArtifactId( projectId );
88 String path = toPath( artifactReference );
89 File directory = new File( getRepoRoot(), path );
90 if ( !directory.exists() )
92 throw new ContentNotFoundException( "cannot found project " + namespace + ":" + projectId );
94 if ( directory.isDirectory() )
98 FileUtils.deleteDirectory( directory );
100 catch ( IOException e )
102 throw new RepositoryException( e.getMessage(), e );
107 log.warn( "project {}:{} is not a directory", namespace, projectId );
113 public void deleteArtifact( ArtifactReference artifactReference )
115 String path = toPath( artifactReference );
116 File filePath = new File( getRepoRoot(), path );
118 if ( filePath.exists() )
120 FileUtils.deleteQuietly( filePath );
123 File filePathmd5 = new File( getRepoRoot(), path + ".md5" );
125 if ( filePathmd5.exists() )
127 FileUtils.deleteQuietly( filePathmd5 );
130 File filePathsha1 = new File( getRepoRoot(), path + ".sha1" );
132 if ( filePathsha1.exists() )
134 FileUtils.deleteQuietly( filePathsha1 );
139 public void deleteGroupId( String groupId )
140 throws ContentNotFoundException
143 String path = StringUtils.replaceChars( groupId, '.', '/' );
145 File directory = new File( getRepoRoot(), path );
147 if ( directory.exists() )
151 FileUtils.deleteDirectory( directory );
153 catch ( IOException e )
155 log.warn( "skip error deleting directory {}:", directory.getPath(), e );
161 public String getId()
163 return repository.getId();
167 public Set<ArtifactReference> getRelatedArtifacts( ArtifactReference reference )
168 throws ContentNotFoundException
170 File artifactFile = toFile( reference );
171 File repoDir = artifactFile.getParentFile();
173 if ( !repoDir.exists() )
175 throw new ContentNotFoundException(
176 "Unable to get related artifacts using a non-existant directory: " + repoDir.getAbsolutePath() );
179 if ( !repoDir.isDirectory() )
181 throw new ContentNotFoundException(
182 "Unable to get related artifacts using a non-directory: " + repoDir.getAbsolutePath() );
185 Set<ArtifactReference> foundArtifacts = new HashSet<>();
187 // First gather up the versions found as artifacts in the managed repository.
188 File repoFiles[] = repoDir.listFiles();
189 for (File repoFile : repoFiles)
191 if (repoFile.isDirectory()) {
192 // Skip it. it's a directory.
195 String relativePath = PathUtil.getRelative(repository.getLocation(), repoFile);
196 if ( filetypes.matchesArtifactPattern( relativePath ) )
200 ArtifactReference artifact = toArtifactReference( relativePath );
202 // Test for related, groupId / artifactId / version must match.
203 if ( artifact.getGroupId().equals( reference.getGroupId() ) && artifact.getArtifactId().equals(
204 reference.getArtifactId() ) && artifact.getVersion().equals( reference.getVersion() ) )
206 foundArtifacts.add( artifact );
209 catch ( LayoutException e )
211 log.debug( "Not processing file that is not an artifact: {}", e.getMessage() );
216 return foundArtifacts;
220 public String getRepoRoot()
222 return repository.getLocation();
226 public ManagedRepository getRepository()
232 * Gather the Available Versions (on disk) for a specific Project Reference, based on filesystem
235 * @return the Set of available versions, based on the project reference.
236 * @throws org.apache.archiva.repository.layout.LayoutException
237 * @throws org.apache.archiva.repository.layout.LayoutException
240 public Set<String> getVersions( ProjectReference reference )
241 throws ContentNotFoundException, LayoutException
243 String path = toMetadataPath( reference );
245 int idx = path.lastIndexOf( '/' );
248 path = path.substring( 0, idx );
251 File repoDir = new File( repository.getLocation(), path );
253 if ( !repoDir.exists() )
255 throw new ContentNotFoundException(
256 "Unable to get Versions on a non-existant directory: " + repoDir.getAbsolutePath() );
259 if ( !repoDir.isDirectory() )
261 throw new ContentNotFoundException(
262 "Unable to get Versions on a non-directory: " + repoDir.getAbsolutePath() );
265 Set<String> foundVersions = new HashSet<>();
266 VersionedReference versionRef = new VersionedReference();
267 versionRef.setGroupId( reference.getGroupId() );
268 versionRef.setArtifactId( reference.getArtifactId() );
270 File repoFiles[] = repoDir.listFiles();
271 for (File repoFile : repoFiles)
273 if (!repoFile.isDirectory()) {
274 // Skip it. not a directory.
277 // Test if dir has an artifact, which proves to us that it is a valid version directory.
278 String version = repoFile.getName();
279 versionRef.setVersion( version );
280 if ( hasArtifact( versionRef ) )
282 // Found an artifact, must be a valid version.
283 foundVersions.add( version );
287 return foundVersions;
291 public Set<String> getVersions( VersionedReference reference )
292 throws ContentNotFoundException
294 String path = toMetadataPath( reference );
296 int idx = path.lastIndexOf( '/' );
299 path = path.substring( 0, idx );
302 File repoDir = new File( repository.getLocation(), path );
304 if ( !repoDir.exists() )
306 throw new ContentNotFoundException(
307 "Unable to get versions on a non-existant directory: " + repoDir.getAbsolutePath() );
310 if ( !repoDir.isDirectory() )
312 throw new ContentNotFoundException(
313 "Unable to get versions on a non-directory: " + repoDir.getAbsolutePath() );
316 Set<String> foundVersions = new HashSet<>();
318 // First gather up the versions found as artifacts in the managed repository.
319 File repoFiles[] = repoDir.listFiles();
320 for (File repoFile : repoFiles)
322 if (repoFile.isDirectory()) {
323 // Skip it. it's a directory.
326 String relativePath = PathUtil.getRelative(repository.getLocation(), repoFile);
327 if ( filetypes.matchesDefaultExclusions( relativePath ) )
329 // Skip it, it's metadata or similar
332 if ( filetypes.matchesArtifactPattern( relativePath ) )
336 ArtifactReference artifact = toArtifactReference( relativePath );
338 foundVersions.add( artifact.getVersion() );
340 catch ( LayoutException e )
342 log.debug( "Not processing file that is not an artifact: {}", e.getMessage() );
347 return foundVersions;
351 public boolean hasContent( ArtifactReference reference )
353 File artifactFile = toFile( reference );
354 return artifactFile.exists() && artifactFile.isFile();
358 public boolean hasContent( ProjectReference reference )
362 Set<String> versions = getVersions( reference );
363 return !versions.isEmpty();
365 catch ( ContentNotFoundException | LayoutException e )
372 public boolean hasContent( VersionedReference reference )
376 return ( getFirstArtifact( reference ) != null );
378 catch ( IOException | LayoutException e )
385 public void setRepository( ManagedRepository repository )
387 this.repository = repository;
391 * Convert a path to an artifact reference.
393 * @param path the path to convert. (relative or full location path)
394 * @throws org.apache.archiva.repository.layout.LayoutException if the path cannot be converted to an artifact reference.
397 public ArtifactReference toArtifactReference( String path )
398 throws LayoutException
400 if ( ( path != null ) && path.startsWith( repository.getLocation() ) && repository.getLocation().length() > 0 )
402 return super.toArtifactReference( path.substring( repository.getLocation().length() + 1 ) );
405 return super.toArtifactReference( path );
409 public File toFile( ArtifactReference reference )
411 return new File( repository.getLocation(), toPath( reference ) );
415 public File toFile( ArchivaArtifact reference )
417 return new File( repository.getLocation(), toPath( reference ) );
421 * Get the first Artifact found in the provided VersionedReference location.
423 * @param reference the reference to the versioned reference to search within
424 * @return the ArtifactReference to the first artifact located within the versioned reference. or null if
425 * no artifact was found within the versioned reference.
426 * @throws java.io.IOException if the versioned reference is invalid (example: doesn't exist, or isn't a directory)
427 * @throws org.apache.archiva.repository.layout.LayoutException
429 private ArtifactReference getFirstArtifact( VersionedReference reference )
430 throws LayoutException, IOException
432 String path = toMetadataPath( reference );
434 int idx = path.lastIndexOf( '/' );
437 path = path.substring( 0, idx );
440 File repoDir = new File( repository.getLocation(), path );
442 if ( !repoDir.exists() )
444 throw new IOException( "Unable to gather the list of snapshot versions on a non-existant directory: "
445 + repoDir.getAbsolutePath() );
448 if ( !repoDir.isDirectory() )
450 throw new IOException(
451 "Unable to gather the list of snapshot versions on a non-directory: " + repoDir.getAbsolutePath() );
454 File repoFiles[] = repoDir.listFiles();
455 for (File repoFile : repoFiles)
457 if (repoFile.isDirectory()) {
458 // Skip it. it's a directory.
461 String relativePath = PathUtil.getRelative(repository.getLocation(), repoFile);
462 if ( filetypes.matchesArtifactPattern( relativePath ) )
464 ArtifactReference artifact = toArtifactReference( relativePath );
470 // No artifact was found.
474 private boolean hasArtifact( VersionedReference reference )
475 throws LayoutException
479 return ( getFirstArtifact( reference ) != null );
481 catch ( IOException e )
487 public void setFiletypes( FileTypes filetypes )
489 this.filetypes = filetypes;