View Javadoc

1   package org.apache.continuum.purge.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.commons.lang.StringUtils;
23  import org.apache.continuum.model.repository.LocalRepository;
24  import org.apache.continuum.purge.repository.utils.FileTypes;
25  import org.apache.maven.archiva.common.utils.PathUtil;
26  import org.apache.maven.archiva.model.ArtifactReference;
27  import org.apache.maven.archiva.model.ProjectReference;
28  import org.apache.maven.archiva.model.VersionedReference;
29  import org.apache.maven.archiva.repository.ContentNotFoundException;
30  import org.apache.maven.archiva.repository.content.ArtifactExtensionMapping;
31  import org.apache.maven.archiva.repository.content.PathParser;
32  import org.apache.maven.archiva.repository.layout.LayoutException;
33  
34  import java.io.File;
35  import java.util.HashMap;
36  import java.util.HashSet;
37  import java.util.Map;
38  import java.util.Set;
39  
40  /**
41   * Taken from Archiva's ManagedLegacyRepositoryContent and made some few changes
42   *
43   * @plexus.component role="org.apache.continuum.purge.repository.content.RepositoryManagedContent"
44   * role-hint="legacy"
45   * instantiation-strategy="per-lookup"
46   */
47  public class ManagedLegacyRepositoryContent
48      implements RepositoryManagedContent
49  {
50      private static final String PATH_SEPARATOR = "/";
51  
52      private static final Map<String, String> typeToDirectoryMap;
53  
54      static
55      {
56          typeToDirectoryMap = new HashMap<String, String>();
57          typeToDirectoryMap.put( "ejb-client", "ejb" );
58          typeToDirectoryMap.put( ArtifactExtensionMapping.MAVEN_PLUGIN, "maven-plugin" );
59          typeToDirectoryMap.put( ArtifactExtensionMapping.MAVEN_ONE_PLUGIN, "plugin" );
60          typeToDirectoryMap.put( "distribution-tgz", "distribution" );
61          typeToDirectoryMap.put( "distribution-zip", "distribution" );
62          typeToDirectoryMap.put( "javadoc", "javadoc.jar" );
63      }
64  
65      /**
66       * @plexus.requirement role-hint="legacy-parser"
67       */
68      private PathParser legacyPathParser;
69  
70      /**
71       * @plexus.requirement role-hint="file-types"
72       */
73      private FileTypes filetypes;
74  
75      private LocalRepository repository;
76  
77      public void deleteVersion( VersionedReference reference )
78          throws ContentNotFoundException
79      {
80          File groupDir = new File( repository.getLocation(), reference.getGroupId() );
81  
82          if ( !groupDir.exists() )
83          {
84              throw new ContentNotFoundException(
85                  "Unable to get versions using a non-existant groupId directory: " + groupDir.getAbsolutePath() );
86          }
87  
88          if ( !groupDir.isDirectory() )
89          {
90              throw new ContentNotFoundException(
91                  "Unable to get versions using a non-directory: " + groupDir.getAbsolutePath() );
92          }
93  
94          // First gather up the versions found as artifacts in the managed repository.
95          File typeDirs[] = groupDir.listFiles();
96          for ( File typeDir : typeDirs )
97          {
98              if ( !typeDir.isDirectory() )
99              {
100                 // Skip it, we only care about directories.
101                 continue;
102             }
103 
104             if ( !typeDir.getName().endsWith( "s" ) )
105             {
106                 // Skip it, we only care about directories that end in "s".
107             }
108 
109             deleteVersions( typeDir, reference );
110         }
111     }
112 
113     private void deleteVersions( File typeDir, VersionedReference reference )
114     {
115         File repoFiles[] = typeDir.listFiles();
116         for ( File repoFile : repoFiles )
117         {
118             if ( repoFile.isDirectory() )
119             {
120                 // Skip it. it's a directory.
121                 continue;
122             }
123 
124             String relativePath = PathUtil.getRelative( repository.getLocation(), repoFile );
125 
126             if ( filetypes.matchesArtifactPattern( relativePath ) )
127             {
128                 try
129                 {
130                     ArtifactReference artifact = toArtifactReference( relativePath );
131                     if ( StringUtils.equals( artifact.getArtifactId(), reference.getArtifactId() ) &&
132                         StringUtils.equals( artifact.getVersion(), reference.getVersion() ) )
133                     {
134                         repoFile.delete();
135                         deleteSupportFiles( repoFile );
136                     }
137                 }
138                 catch ( LayoutException e )
139                 {
140                     /* don't fail the process if there is a bad artifact within the directory. */
141                 }
142             }
143         }
144     }
145 
146     private void deleteSupportFiles( File repoFile )
147     {
148         deleteSupportFile( repoFile, ".sha1" );
149         deleteSupportFile( repoFile, ".md5" );
150         deleteSupportFile( repoFile, ".asc" );
151         deleteSupportFile( repoFile, ".gpg" );
152     }
153 
154     private void deleteSupportFile( File repoFile, String supportExtension )
155     {
156         File supportFile = new File( repoFile.getAbsolutePath() + supportExtension );
157         if ( supportFile.exists() && supportFile.isFile() )
158         {
159             supportFile.delete();
160         }
161     }
162 
163     public int getId()
164     {
165         return repository.getId();
166     }
167 
168     public Set<ArtifactReference> getRelatedArtifacts( ArtifactReference reference )
169         throws ContentNotFoundException, LayoutException
170     {
171         File artifactFile = toFile( reference );
172         File repoDir = artifactFile.getParentFile();
173 
174         if ( !repoDir.exists() )
175         {
176             throw new ContentNotFoundException(
177                 "Unable to get related artifacts using a non-existant directory: " + repoDir.getAbsolutePath() );
178         }
179 
180         if ( !repoDir.isDirectory() )
181         {
182             throw new ContentNotFoundException(
183                 "Unable to get related artifacts using a non-directory: " + repoDir.getAbsolutePath() );
184         }
185 
186         Set<ArtifactReference> foundArtifacts = new HashSet<ArtifactReference>();
187 
188         // First gather up the versions found as artifacts in the managed repository.
189         File projectParentDir = repoDir.getParentFile();
190         File typeDirs[] = projectParentDir.listFiles();
191         for ( File typeDir : typeDirs )
192         {
193             if ( !typeDir.isDirectory() )
194             {
195                 // Skip it, we only care about directories.
196                 continue;
197             }
198 
199             if ( !typeDir.getName().endsWith( "s" ) )
200             {
201                 // Skip it, we only care about directories that end in "s".
202             }
203 
204             getRelatedArtifacts( typeDir, reference, foundArtifacts );
205         }
206 
207         return foundArtifacts;
208     }
209 
210     public String getRepoRoot()
211     {
212         return repository.getLocation();
213     }
214 
215     public LocalRepository getRepository()
216     {
217         return repository;
218     }
219 
220     public Set<String> getVersions( ProjectReference reference )
221         throws ContentNotFoundException
222     {
223         File groupDir = new File( repository.getLocation(), reference.getGroupId() );
224 
225         if ( !groupDir.exists() )
226         {
227             throw new ContentNotFoundException(
228                 "Unable to get versions using a non-existant groupId directory: " + groupDir.getAbsolutePath() );
229         }
230 
231         if ( !groupDir.isDirectory() )
232         {
233             throw new ContentNotFoundException(
234                 "Unable to get versions using a non-directory: " + groupDir.getAbsolutePath() );
235         }
236 
237         Set<String> foundVersions = new HashSet<String>();
238 
239         // First gather up the versions found as artifacts in the managed repository.
240         File typeDirs[] = groupDir.listFiles();
241         for ( File typeDir : typeDirs )
242         {
243             if ( !typeDir.isDirectory() )
244             {
245                 // Skip it, we only care about directories.
246                 continue;
247             }
248 
249             if ( !typeDir.getName().endsWith( "s" ) )
250             {
251                 // Skip it, we only care about directories that end in "s".
252             }
253 
254             getProjectVersions( typeDir, reference, foundVersions );
255         }
256 
257         return foundVersions;
258     }
259 
260     public Set<String> getVersions( VersionedReference reference )
261         throws ContentNotFoundException
262     {
263         File groupDir = new File( repository.getLocation(), reference.getGroupId() );
264 
265         if ( !groupDir.exists() )
266         {
267             throw new ContentNotFoundException(
268                 "Unable to get versions using a non-existant groupId directory: " + groupDir.getAbsolutePath() );
269         }
270 
271         if ( !groupDir.isDirectory() )
272         {
273             throw new ContentNotFoundException(
274                 "Unable to get versions using a non-directory: " + groupDir.getAbsolutePath() );
275         }
276 
277         Set<String> foundVersions = new HashSet<String>();
278 
279         // First gather up the versions found as artifacts in the managed repository.
280         File typeDirs[] = groupDir.listFiles();
281         for ( File typeDir : typeDirs )
282         {
283             if ( !typeDir.isDirectory() )
284             {
285                 // Skip it, we only care about directories.
286                 continue;
287             }
288 
289             if ( !typeDir.getName().endsWith( "s" ) )
290             {
291                 // Skip it, we only care about directories that end in "s".
292             }
293 
294             getVersionedVersions( typeDir, reference, foundVersions );
295         }
296 
297         return foundVersions;
298     }
299 
300     /**
301      * Convert a path to an artifact reference.
302      *
303      * @param path the path to convert. (relative or full location path)
304      * @throws LayoutException if the path cannot be converted to an artifact reference.
305      */
306     public ArtifactReference toArtifactReference( String path )
307         throws LayoutException
308     {
309         if ( ( path != null ) && path.startsWith( repository.getLocation() ) )
310         {
311             return legacyPathParser.toArtifactReference( path.substring( repository.getLocation().length() ) );
312         }
313 
314         return legacyPathParser.toArtifactReference( path );
315     }
316 
317     public File toFile( ArtifactReference reference )
318     {
319         return new File( repository.getLocation(), toPath( reference ) );
320     }
321 
322     public String toMetadataPath( ProjectReference reference )
323     {
324         // No metadata present in legacy repository.
325         return null;
326     }
327 
328     public String toMetadataPath( VersionedReference reference )
329     {
330         // No metadata present in legacy repository.
331         return null;
332     }
333 
334     public String toPath( ArtifactReference reference )
335     {
336         if ( reference == null )
337         {
338             throw new IllegalArgumentException( "Artifact reference cannot be null" );
339         }
340 
341         return toPath( reference.getGroupId(), reference.getArtifactId(), reference.getVersion(),
342                        reference.getClassifier(), reference.getType() );
343     }
344 
345     public void setRepository( LocalRepository repo )
346     {
347         this.repository = repo;
348     }
349 
350     private void getProjectVersions( File typeDir, ProjectReference reference, Set<String> foundVersions )
351     {
352         File repoFiles[] = typeDir.listFiles();
353         for ( File repoFile : repoFiles )
354         {
355             if ( repoFile.isDirectory() )
356             {
357                 // Skip it. it's a directory.
358                 continue;
359             }
360 
361             String relativePath = PathUtil.getRelative( repository.getLocation(), repoFile );
362 
363             if ( filetypes.matchesArtifactPattern( relativePath ) )
364             {
365                 try
366                 {
367                     ArtifactReference artifact = toArtifactReference( relativePath );
368                     if ( StringUtils.equals( artifact.getArtifactId(), reference.getArtifactId() ) )
369                     {
370                         foundVersions.add( artifact.getVersion() );
371                     }
372                 }
373                 catch ( LayoutException e )
374                 {
375                     /* don't fail the process if there is a bad artifact within the directory. */
376                 }
377             }
378         }
379     }
380 
381     private void getRelatedArtifacts( File typeDir, ArtifactReference reference, Set<ArtifactReference> foundArtifacts )
382     {
383         for ( File repoFile : typeDir.listFiles() )
384         {
385             if ( repoFile.isDirectory() )
386             {
387                 // Skip it. it's a directory.
388                 continue;
389             }
390 
391             String relativePath = PathUtil.getRelative( repository.getLocation(), repoFile );
392 
393             if ( filetypes.matchesArtifactPattern( relativePath ) )
394             {
395                 try
396                 {
397                     ArtifactReference artifact = toArtifactReference( relativePath );
398                     if ( StringUtils.equals( artifact.getArtifactId(), reference.getArtifactId() ) &&
399                         artifact.getVersion().startsWith( reference.getVersion() ) )
400                     {
401                         foundArtifacts.add( artifact );
402                     }
403                 }
404                 catch ( LayoutException e )
405                 {
406                     /* don't fail the process if there is a bad artifact within the directory. */
407                 }
408             }
409         }
410     }
411 
412     private void getVersionedVersions( File typeDir, VersionedReference reference, Set<String> foundVersions )
413     {
414         for ( File repoFile : typeDir.listFiles() )
415         {
416             if ( repoFile.isDirectory() )
417             {
418                 // Skip it. it's a directory.
419                 continue;
420             }
421 
422             String relativePath = PathUtil.getRelative( repository.getLocation(), repoFile );
423 
424             if ( filetypes.matchesArtifactPattern( relativePath ) )
425             {
426                 try
427                 {
428                     ArtifactReference artifact = toArtifactReference( relativePath );
429                     if ( StringUtils.equals( artifact.getArtifactId(), reference.getArtifactId() ) &&
430                         artifact.getVersion().startsWith( reference.getVersion() ) )
431                     {
432                         foundVersions.add( artifact.getVersion() );
433                     }
434                 }
435                 catch ( LayoutException e )
436                 {
437                     /* don't fail the process if there is a bad artifact within the directory. */
438                 }
439             }
440         }
441     }
442 
443     private String toPath( String groupId, String artifactId, String version, String classifier, String type )
444     {
445         StringBuffer path = new StringBuffer();
446 
447         path.append( groupId ).append( PATH_SEPARATOR );
448         path.append( getDirectory( type ) ).append( PATH_SEPARATOR );
449 
450         if ( version != null )
451         {
452             path.append( artifactId ).append( '-' ).append( version );
453 
454             if ( StringUtils.isNotBlank( classifier ) )
455             {
456                 path.append( '-' ).append( classifier );
457             }
458 
459             path.append( '.' ).append( ArtifactExtensionMapping.getExtension( type ) );
460         }
461 
462         return path.toString();
463     }
464 
465     private String getDirectory( String type )
466     {
467         String dirname = typeToDirectoryMap.get( type );
468 
469         if ( dirname != null )
470         {
471             return dirname + "s";
472         }
473 
474         // Default process.
475         return type + "s";
476     }
477 }