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