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