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