This project has retired. For details please refer to its Attic page.
Source code
001package org.apache.archiva.repository.content.maven2;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.archiva.admin.model.beans.ManagedRepository;
023import org.apache.archiva.common.utils.PathUtil;
024import org.apache.archiva.configuration.FileTypes;
025import org.apache.archiva.metadata.repository.storage.maven2.DefaultArtifactMappingProvider;
026import org.apache.archiva.model.ArchivaArtifact;
027import org.apache.archiva.model.ArtifactReference;
028import org.apache.archiva.model.ProjectReference;
029import org.apache.archiva.model.VersionedReference;
030import org.apache.archiva.repository.ContentNotFoundException;
031import org.apache.archiva.repository.ManagedRepositoryContent;
032import org.apache.archiva.repository.RepositoryException;
033import org.apache.archiva.repository.layout.LayoutException;
034import org.apache.commons.io.FileUtils;
035import org.apache.commons.lang.StringUtils;
036import org.springframework.context.annotation.Scope;
037import org.springframework.stereotype.Service;
038
039import javax.inject.Inject;
040import javax.inject.Named;
041import java.io.File;
042import java.io.IOException;
043import java.util.Collections;
044import java.util.HashSet;
045import java.util.Set;
046
047/**
048 * ManagedDefaultRepositoryContent
049 */
050@Service ("managedRepositoryContent#default")
051@Scope ("prototype")
052public class ManagedDefaultRepositoryContent
053    extends AbstractDefaultRepositoryContent
054    implements ManagedRepositoryContent
055{
056    @Inject
057    @Named ( "fileTypes" )
058    private FileTypes filetypes;
059
060    private ManagedRepository repository;
061
062    public ManagedDefaultRepositoryContent()
063    {
064        // default to use if there are none supplied as components
065        this.artifactMappingProviders = Collections.singletonList( new DefaultArtifactMappingProvider() );
066    }
067
068    @Override
069    public void deleteVersion( VersionedReference reference )
070    {
071        String path = toMetadataPath( reference );
072        File projectPath = new File( getRepoRoot(), path );
073
074        File projectDir = projectPath.getParentFile();
075        if ( projectDir.exists() && projectDir.isDirectory() )
076        {
077            FileUtils.deleteQuietly( projectDir );
078        }
079    }
080
081    @Override
082    public void deleteProject( String namespace, String projectId )
083        throws RepositoryException, ContentNotFoundException
084    {
085        ArtifactReference artifactReference = new ArtifactReference();
086        artifactReference.setGroupId( namespace );
087        artifactReference.setArtifactId( projectId );
088        String path = toPath( artifactReference );
089        File directory = new File( getRepoRoot(), path );
090        if ( !directory.exists() )
091        {
092            throw new ContentNotFoundException( "cannot found project " + namespace + ":" + projectId );
093        }
094        if ( directory.isDirectory() )
095        {
096            try
097            {
098                FileUtils.deleteDirectory( directory );
099            }
100            catch ( IOException e )
101            {
102                throw new RepositoryException( e.getMessage(), e );
103            }
104        }
105        else
106        {
107            log.warn( "project {}:{} is not a directory", namespace, projectId );
108        }
109
110    }
111
112    @Override
113    public void deleteArtifact( ArtifactReference artifactReference )
114    {
115        String path = toPath( artifactReference );
116        File filePath = new File( getRepoRoot(), path );
117
118        if ( filePath.exists() )
119        {
120            FileUtils.deleteQuietly( filePath );
121        }
122
123        File filePathmd5 = new File( getRepoRoot(), path + ".md5" );
124
125        if ( filePathmd5.exists() )
126        {
127            FileUtils.deleteQuietly( filePathmd5 );
128        }
129
130        File filePathsha1 = new File( getRepoRoot(), path + ".sha1" );
131
132        if ( filePathsha1.exists() )
133        {
134            FileUtils.deleteQuietly( filePathsha1 );
135        }
136    }
137
138    @Override
139    public void deleteGroupId( String groupId )
140        throws ContentNotFoundException
141    {
142
143        String path = StringUtils.replaceChars( groupId, '.', '/' );
144
145        File directory = new File( getRepoRoot(), path );
146
147        if ( directory.exists() )
148        {
149            try
150            {
151                FileUtils.deleteDirectory( directory );
152            }
153            catch ( IOException e )
154            {
155                log.warn( "skip error deleting directory {}:", directory.getPath(), e );
156            }
157        }
158    }
159
160    @Override
161    public String getId()
162    {
163        return repository.getId();
164    }
165
166    @Override
167    public Set<ArtifactReference> getRelatedArtifacts( ArtifactReference reference )
168        throws ContentNotFoundException
169    {
170        File artifactFile = toFile( reference );
171        File repoDir = artifactFile.getParentFile();
172
173        if ( !repoDir.exists() )
174        {
175            throw new ContentNotFoundException(
176                "Unable to get related artifacts using a non-existant directory: " + repoDir.getAbsolutePath() );
177        }
178
179        if ( !repoDir.isDirectory() )
180        {
181            throw new ContentNotFoundException(
182                "Unable to get related artifacts using a non-directory: " + repoDir.getAbsolutePath() );
183        }
184
185        Set<ArtifactReference> foundArtifacts = new HashSet<>();
186
187        // First gather up the versions found as artifacts in the managed repository.
188        File repoFiles[] = repoDir.listFiles();
189        for (File repoFile : repoFiles) 
190        {
191            if (repoFile.isDirectory()) {
192                // Skip it. it's a directory.
193                continue;
194            }
195            String relativePath = PathUtil.getRelative(repository.getLocation(), repoFile);
196            if ( filetypes.matchesArtifactPattern( relativePath ) )
197            {
198                try
199                {
200                    ArtifactReference artifact = toArtifactReference( relativePath );
201
202                    // Test for related, groupId / artifactId / version must match.
203                    if ( artifact.getGroupId().equals( reference.getGroupId() ) && artifact.getArtifactId().equals(
204                            reference.getArtifactId() ) && artifact.getVersion().equals( reference.getVersion() ) )
205                    {
206                        foundArtifacts.add( artifact );
207                    }
208                }
209                catch ( LayoutException e )
210                {
211                    log.debug( "Not processing file that is not an artifact: {}", e.getMessage() );
212                }
213            }
214        }
215
216        return foundArtifacts;
217    }
218
219    @Override
220    public String getRepoRoot()
221    {
222        return repository.getLocation();
223    }
224
225    @Override
226    public ManagedRepository getRepository()
227    {
228        return repository;
229    }
230
231    /**
232     * Gather the Available Versions (on disk) for a specific Project Reference, based on filesystem
233     * information.
234     *
235     * @return the Set of available versions, based on the project reference.
236     * @throws org.apache.archiva.repository.layout.LayoutException
237     * @throws org.apache.archiva.repository.layout.LayoutException
238     */
239    @Override
240    public Set<String> getVersions( ProjectReference reference )
241        throws ContentNotFoundException, LayoutException
242    {
243        String path = toMetadataPath( reference );
244
245        int idx = path.lastIndexOf( '/' );
246        if ( idx > 0 )
247        {
248            path = path.substring( 0, idx );
249        }
250
251        File repoDir = new File( repository.getLocation(), path );
252
253        if ( !repoDir.exists() )
254        {
255            throw new ContentNotFoundException(
256                "Unable to get Versions on a non-existant directory: " + repoDir.getAbsolutePath() );
257        }
258
259        if ( !repoDir.isDirectory() )
260        {
261            throw new ContentNotFoundException(
262                "Unable to get Versions on a non-directory: " + repoDir.getAbsolutePath() );
263        }
264
265        Set<String> foundVersions = new HashSet<>();
266        VersionedReference versionRef = new VersionedReference();
267        versionRef.setGroupId( reference.getGroupId() );
268        versionRef.setArtifactId( reference.getArtifactId() );
269
270        File repoFiles[] = repoDir.listFiles();
271        for (File repoFile : repoFiles) 
272        {
273            if (!repoFile.isDirectory()) {
274                // Skip it. not a directory.
275                continue;
276            }
277            // Test if dir has an artifact, which proves to us that it is a valid version directory.
278            String version = repoFile.getName();
279            versionRef.setVersion( version );
280            if ( hasArtifact( versionRef ) )
281            {
282                // Found an artifact, must be a valid version.
283                foundVersions.add( version );
284            }
285        }
286
287        return foundVersions;
288    }
289
290    @Override
291    public Set<String> getVersions( VersionedReference reference )
292        throws ContentNotFoundException
293    {
294        String path = toMetadataPath( reference );
295
296        int idx = path.lastIndexOf( '/' );
297        if ( idx > 0 )
298        {
299            path = path.substring( 0, idx );
300        }
301
302        File repoDir = new File( repository.getLocation(), path );
303
304        if ( !repoDir.exists() )
305        {
306            throw new ContentNotFoundException(
307                "Unable to get versions on a non-existant directory: " + repoDir.getAbsolutePath() );
308        }
309
310        if ( !repoDir.isDirectory() )
311        {
312            throw new ContentNotFoundException(
313                "Unable to get versions on a non-directory: " + repoDir.getAbsolutePath() );
314        }
315
316        Set<String> foundVersions = new HashSet<>();
317
318        // First gather up the versions found as artifacts in the managed repository.
319        File repoFiles[] = repoDir.listFiles();
320        for (File repoFile : repoFiles) 
321        {
322            if (repoFile.isDirectory()) {
323                // Skip it. it's a directory.
324                continue;
325            }
326            String relativePath = PathUtil.getRelative(repository.getLocation(), repoFile);
327            if ( filetypes.matchesDefaultExclusions( relativePath ) )
328            {
329                // Skip it, it's metadata or similar
330                continue;
331            }
332            if ( filetypes.matchesArtifactPattern( relativePath ) )
333            {
334                try
335                {
336                    ArtifactReference artifact = toArtifactReference( relativePath );
337
338                    foundVersions.add( artifact.getVersion() );
339                }
340                catch ( LayoutException e )
341                {
342                    log.debug( "Not processing file that is not an artifact: {}", e.getMessage() );
343                }
344            }
345        }
346
347        return foundVersions;
348    }
349
350    @Override
351    public boolean hasContent( ArtifactReference reference )
352    {
353        File artifactFile = toFile( reference );
354        return artifactFile.exists() && artifactFile.isFile();
355    }
356
357    @Override
358    public boolean hasContent( ProjectReference reference )
359    {
360        try
361        {
362            Set<String> versions = getVersions( reference );
363            return !versions.isEmpty();
364        }
365        catch ( ContentNotFoundException | LayoutException e )
366        {
367            return false;
368        }
369    }
370
371    @Override
372    public boolean hasContent( VersionedReference reference )
373    {
374        try
375        {
376            return ( getFirstArtifact( reference ) != null );
377        }
378        catch ( IOException | LayoutException e )
379        {
380            return false;
381        }
382    }
383
384    @Override
385    public void setRepository( ManagedRepository repository )
386    {
387        this.repository = repository;
388    }
389
390    /**
391     * Convert a path to an artifact reference.
392     *
393     * @param path the path to convert. (relative or full location path)
394     * @throws org.apache.archiva.repository.layout.LayoutException if the path cannot be converted to an artifact reference.
395     */
396    @Override
397    public ArtifactReference toArtifactReference( String path )
398        throws LayoutException
399    {
400        if ( ( path != null ) && path.startsWith( repository.getLocation() ) && repository.getLocation().length() > 0 )
401        {
402            return super.toArtifactReference( path.substring( repository.getLocation().length() + 1 ) );
403        }
404
405        return super.toArtifactReference( path );
406    }
407
408    @Override
409    public File toFile( ArtifactReference reference )
410    {
411        return new File( repository.getLocation(), toPath( reference ) );
412    }
413
414    @Override
415    public File toFile( ArchivaArtifact reference )
416    {
417        return new File( repository.getLocation(), toPath( reference ) );
418    }
419
420    /**
421     * Get the first Artifact found in the provided VersionedReference location.
422     *
423     * @param reference the reference to the versioned reference to search within
424     * @return the ArtifactReference to the first artifact located within the versioned reference. or null if
425     *         no artifact was found within the versioned reference.
426     * @throws java.io.IOException     if the versioned reference is invalid (example: doesn't exist, or isn't a directory)
427     * @throws org.apache.archiva.repository.layout.LayoutException
428     */
429    private ArtifactReference getFirstArtifact( VersionedReference reference )
430        throws LayoutException, IOException
431    {
432        String path = toMetadataPath( reference );
433
434        int idx = path.lastIndexOf( '/' );
435        if ( idx > 0 )
436        {
437            path = path.substring( 0, idx );
438        }
439
440        File repoDir = new File( repository.getLocation(), path );
441
442        if ( !repoDir.exists() )
443        {
444            throw new IOException( "Unable to gather the list of snapshot versions on a non-existant directory: "
445                                       + repoDir.getAbsolutePath() );
446        }
447
448        if ( !repoDir.isDirectory() )
449        {
450            throw new IOException(
451                "Unable to gather the list of snapshot versions on a non-directory: " + repoDir.getAbsolutePath() );
452        }
453
454        File repoFiles[] = repoDir.listFiles();
455        for (File repoFile : repoFiles) 
456        {
457            if (repoFile.isDirectory()) {
458                // Skip it. it's a directory.
459                continue;
460            }
461            String relativePath = PathUtil.getRelative(repository.getLocation(), repoFile);
462            if ( filetypes.matchesArtifactPattern( relativePath ) )
463            {
464                ArtifactReference artifact = toArtifactReference( relativePath );
465
466                return artifact;
467            }
468        }
469
470        // No artifact was found.
471        return null;
472    }
473
474    private boolean hasArtifact( VersionedReference reference )
475        throws LayoutException
476    {
477        try
478        {
479            return ( getFirstArtifact( reference ) != null );
480        }
481        catch ( IOException e )
482        {
483            return false;
484        }
485    }
486
487    public void setFiletypes( FileTypes filetypes )
488    {
489        this.filetypes = filetypes;
490    }
491}