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        try {
095            if (!directory.getCanonicalPath().equals(directory.getAbsolutePath())) {
096                throw new ContentNotFoundException( "Invalid directory for project " + namespace + ":" + projectId );
097            }
098        } catch (IOException e) {
099            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}