]> source.dussan.org Git - archiva.git/blob
aa4ca8a5adc79a1207a7603ca8abf0cc752e707d
[archiva.git] /
1 package org.apache.archiva.repository.content.maven2;
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.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;
38
39 import javax.inject.Inject;
40 import javax.inject.Named;
41 import java.io.File;
42 import java.io.IOException;
43 import java.util.Collections;
44 import java.util.HashSet;
45 import java.util.Set;
46
47 /**
48  * ManagedDefaultRepositoryContent
49  */
50 @Service ("managedRepositoryContent#default")
51 @Scope ("prototype")
52 public class ManagedDefaultRepositoryContent
53     extends AbstractDefaultRepositoryContent
54     implements ManagedRepositoryContent
55 {
56     @Inject
57     @Named ( "fileTypes" )
58     private FileTypes filetypes;
59
60     private ManagedRepository repository;
61
62     public ManagedDefaultRepositoryContent()
63     {
64         // default to use if there are none supplied as components
65         this.artifactMappingProviders = Collections.singletonList( new DefaultArtifactMappingProvider() );
66     }
67
68     @Override
69     public void deleteVersion( VersionedReference reference )
70     {
71         String path = toMetadataPath( reference );
72         File projectPath = new File( getRepoRoot(), path );
73
74         File projectDir = projectPath.getParentFile();
75         if ( projectDir.exists() && projectDir.isDirectory() )
76         {
77             FileUtils.deleteQuietly( projectDir );
78         }
79     }
80
81     @Override
82     public void deleteProject( String namespace, String projectId )
83         throws RepositoryException, ContentNotFoundException
84     {
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() )
91         {
92             throw new ContentNotFoundException( "cannot found project " + namespace + ":" + projectId );
93         }
94         if ( directory.isDirectory() )
95         {
96             try
97             {
98                 FileUtils.deleteDirectory( directory );
99             }
100             catch ( IOException e )
101             {
102                 throw new RepositoryException( e.getMessage(), e );
103             }
104         }
105         else
106         {
107             log.warn( "project {}:{} is not a directory", namespace, projectId );
108         }
109
110     }
111
112     @Override
113     public void deleteArtifact( ArtifactReference artifactReference )
114     {
115         String path = toPath( artifactReference );
116         File filePath = new File( getRepoRoot(), path );
117
118         if ( filePath.exists() )
119         {
120             FileUtils.deleteQuietly( filePath );
121         }
122
123         File filePathmd5 = new File( getRepoRoot(), path + ".md5" );
124
125         if ( filePathmd5.exists() )
126         {
127             FileUtils.deleteQuietly( filePathmd5 );
128         }
129
130         File filePathsha1 = new File( getRepoRoot(), path + ".sha1" );
131
132         if ( filePathsha1.exists() )
133         {
134             FileUtils.deleteQuietly( filePathsha1 );
135         }
136     }
137
138     @Override
139     public void deleteGroupId( String groupId )
140         throws ContentNotFoundException
141     {
142
143         String path = StringUtils.replaceChars( groupId, '.', '/' );
144
145         File directory = new File( getRepoRoot(), path );
146
147         if ( directory.exists() )
148         {
149             try
150             {
151                 FileUtils.deleteDirectory( directory );
152             }
153             catch ( IOException e )
154             {
155                 log.warn( "skip error deleting directory {}:", directory.getPath(), e );
156             }
157         }
158     }
159
160     @Override
161     public String getId()
162     {
163         return repository.getId();
164     }
165
166     @Override
167     public Set<ArtifactReference> getRelatedArtifacts( ArtifactReference reference )
168         throws ContentNotFoundException
169     {
170         File artifactFile = toFile( reference );
171         File repoDir = artifactFile.getParentFile();
172
173         if ( !repoDir.exists() )
174         {
175             throw new ContentNotFoundException(
176                 "Unable to get related artifacts using a non-existant directory: " + repoDir.getAbsolutePath() );
177         }
178
179         if ( !repoDir.isDirectory() )
180         {
181             throw new ContentNotFoundException(
182                 "Unable to get related artifacts using a non-directory: " + repoDir.getAbsolutePath() );
183         }
184
185         Set<ArtifactReference> foundArtifacts = new HashSet<>();
186
187         // First gather up the versions found as artifacts in the managed repository.
188         File repoFiles[] = repoDir.listFiles();
189         for (File repoFile : repoFiles) 
190         {
191             if (repoFile.isDirectory()) {
192                 // Skip it. it's a directory.
193                 continue;
194             }
195             String relativePath = PathUtil.getRelative(repository.getLocation(), repoFile);
196             if ( filetypes.matchesArtifactPattern( relativePath ) )
197             {
198                 try
199                 {
200                     ArtifactReference artifact = toArtifactReference( relativePath );
201
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() ) )
205                     {
206                         foundArtifacts.add( artifact );
207                     }
208                 }
209                 catch ( LayoutException e )
210                 {
211                     log.debug( "Not processing file that is not an artifact: {}", e.getMessage() );
212                 }
213             }
214         }
215
216         return foundArtifacts;
217     }
218
219     @Override
220     public String getRepoRoot()
221     {
222         return repository.getLocation();
223     }
224
225     @Override
226     public ManagedRepository getRepository()
227     {
228         return repository;
229     }
230
231     /**
232      * Gather the Available Versions (on disk) for a specific Project Reference, based on filesystem
233      * information.
234      *
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
238      */
239     @Override
240     public Set<String> getVersions( ProjectReference reference )
241         throws ContentNotFoundException, LayoutException
242     {
243         String path = toMetadataPath( reference );
244
245         int idx = path.lastIndexOf( '/' );
246         if ( idx > 0 )
247         {
248             path = path.substring( 0, idx );
249         }
250
251         File repoDir = new File( repository.getLocation(), path );
252
253         if ( !repoDir.exists() )
254         {
255             throw new ContentNotFoundException(
256                 "Unable to get Versions on a non-existant directory: " + repoDir.getAbsolutePath() );
257         }
258
259         if ( !repoDir.isDirectory() )
260         {
261             throw new ContentNotFoundException(
262                 "Unable to get Versions on a non-directory: " + repoDir.getAbsolutePath() );
263         }
264
265         Set<String> foundVersions = new HashSet<>();
266         VersionedReference versionRef = new VersionedReference();
267         versionRef.setGroupId( reference.getGroupId() );
268         versionRef.setArtifactId( reference.getArtifactId() );
269
270         File repoFiles[] = repoDir.listFiles();
271         for (File repoFile : repoFiles) 
272         {
273             if (!repoFile.isDirectory()) {
274                 // Skip it. not a directory.
275                 continue;
276             }
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 ) )
281             {
282                 // Found an artifact, must be a valid version.
283                 foundVersions.add( version );
284             }
285         }
286
287         return foundVersions;
288     }
289
290     @Override
291     public Set<String> getVersions( VersionedReference reference )
292         throws ContentNotFoundException
293     {
294         String path = toMetadataPath( reference );
295
296         int idx = path.lastIndexOf( '/' );
297         if ( idx > 0 )
298         {
299             path = path.substring( 0, idx );
300         }
301
302         File repoDir = new File( repository.getLocation(), path );
303
304         if ( !repoDir.exists() )
305         {
306             throw new ContentNotFoundException(
307                 "Unable to get versions on a non-existant directory: " + repoDir.getAbsolutePath() );
308         }
309
310         if ( !repoDir.isDirectory() )
311         {
312             throw new ContentNotFoundException(
313                 "Unable to get versions on a non-directory: " + repoDir.getAbsolutePath() );
314         }
315
316         Set<String> foundVersions = new HashSet<>();
317
318         // First gather up the versions found as artifacts in the managed repository.
319         File repoFiles[] = repoDir.listFiles();
320         for (File repoFile : repoFiles) 
321         {
322             if (repoFile.isDirectory()) {
323                 // Skip it. it's a directory.
324                 continue;
325             }
326             String relativePath = PathUtil.getRelative(repository.getLocation(), repoFile);
327             if ( filetypes.matchesDefaultExclusions( relativePath ) )
328             {
329                 // Skip it, it's metadata or similar
330                 continue;
331             }
332             if ( filetypes.matchesArtifactPattern( relativePath ) )
333             {
334                 try
335                 {
336                     ArtifactReference artifact = toArtifactReference( relativePath );
337
338                     foundVersions.add( artifact.getVersion() );
339                 }
340                 catch ( LayoutException e )
341                 {
342                     log.debug( "Not processing file that is not an artifact: {}", e.getMessage() );
343                 }
344             }
345         }
346
347         return foundVersions;
348     }
349
350     @Override
351     public boolean hasContent( ArtifactReference reference )
352     {
353         File artifactFile = toFile( reference );
354         return artifactFile.exists() && artifactFile.isFile();
355     }
356
357     @Override
358     public boolean hasContent( ProjectReference reference )
359     {
360         try
361         {
362             Set<String> versions = getVersions( reference );
363             return !versions.isEmpty();
364         }
365         catch ( ContentNotFoundException | LayoutException e )
366         {
367             return false;
368         }
369     }
370
371     @Override
372     public boolean hasContent( VersionedReference reference )
373     {
374         try
375         {
376             return ( getFirstArtifact( reference ) != null );
377         }
378         catch ( IOException | LayoutException e )
379         {
380             return false;
381         }
382     }
383
384     @Override
385     public void setRepository( ManagedRepository repository )
386     {
387         this.repository = repository;
388     }
389
390     /**
391      * Convert a path to an artifact reference.
392      *
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.
395      */
396     @Override
397     public ArtifactReference toArtifactReference( String path )
398         throws LayoutException
399     {
400         if ( ( path != null ) && path.startsWith( repository.getLocation() ) && repository.getLocation().length() > 0 )
401         {
402             return super.toArtifactReference( path.substring( repository.getLocation().length() + 1 ) );
403         }
404
405         return super.toArtifactReference( path );
406     }
407
408     @Override
409     public File toFile( ArtifactReference reference )
410     {
411         return new File( repository.getLocation(), toPath( reference ) );
412     }
413
414     @Override
415     public File toFile( ArchivaArtifact reference )
416     {
417         return new File( repository.getLocation(), toPath( reference ) );
418     }
419
420     /**
421      * Get the first Artifact found in the provided VersionedReference location.
422      *
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
428      */
429     private ArtifactReference getFirstArtifact( VersionedReference reference )
430         throws LayoutException, IOException
431     {
432         String path = toMetadataPath( reference );
433
434         int idx = path.lastIndexOf( '/' );
435         if ( idx > 0 )
436         {
437             path = path.substring( 0, idx );
438         }
439
440         File repoDir = new File( repository.getLocation(), path );
441
442         if ( !repoDir.exists() )
443         {
444             throw new IOException( "Unable to gather the list of snapshot versions on a non-existant directory: "
445                                        + repoDir.getAbsolutePath() );
446         }
447
448         if ( !repoDir.isDirectory() )
449         {
450             throw new IOException(
451                 "Unable to gather the list of snapshot versions on a non-directory: " + repoDir.getAbsolutePath() );
452         }
453
454         File repoFiles[] = repoDir.listFiles();
455         for (File repoFile : repoFiles) 
456         {
457             if (repoFile.isDirectory()) {
458                 // Skip it. it's a directory.
459                 continue;
460             }
461             String relativePath = PathUtil.getRelative(repository.getLocation(), repoFile);
462             if ( filetypes.matchesArtifactPattern( relativePath ) )
463             {
464                 ArtifactReference artifact = toArtifactReference( relativePath );
465
466                 return artifact;
467             }
468         }
469
470         // No artifact was found.
471         return null;
472     }
473
474     private boolean hasArtifact( VersionedReference reference )
475         throws LayoutException
476     {
477         try
478         {
479             return ( getFirstArtifact( reference ) != null );
480         }
481         catch ( IOException e )
482         {
483             return false;
484         }
485     }
486
487     public void setFiletypes( FileTypes filetypes )
488     {
489         this.filetypes = filetypes;
490     }
491 }