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