001    package org.apache.archiva.repository.content.legacy;
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    
022    import org.apache.archiva.admin.model.beans.ManagedRepository;
023    import org.apache.archiva.common.utils.PathUtil;
024    import org.apache.archiva.configuration.FileTypes;
025    import org.apache.archiva.model.ArchivaArtifact;
026    import org.apache.archiva.model.ArtifactReference;
027    import org.apache.archiva.model.ProjectReference;
028    import org.apache.archiva.model.VersionedReference;
029    import org.apache.archiva.repository.ContentNotFoundException;
030    import org.apache.archiva.repository.ManagedRepositoryContent;
031    import org.apache.archiva.repository.RepositoryException;
032    import org.apache.archiva.repository.layout.LayoutException;
033    import org.apache.commons.collections.CollectionUtils;
034    import org.apache.commons.lang.StringUtils;
035    import org.springframework.context.annotation.Scope;
036    import org.springframework.stereotype.Service;
037    
038    import javax.inject.Inject;
039    import java.io.File;
040    import java.util.HashSet;
041    import java.util.Set;
042    
043    /**
044     * ManagedLegacyRepositoryContent
045     *
046     *
047     * @todo no need to be a component when filetypes, legacy path parser is not
048     */
049    @Service( "managedRepositoryContent#legacy" )
050    @Scope( "prototype" )
051    public class ManagedLegacyRepositoryContent
052        extends AbstractLegacyRepositoryContent
053        implements ManagedRepositoryContent
054    {
055        /**
056         *
057         */
058        @Inject
059        private FileTypes filetypes;
060    
061        private ManagedRepository repository;
062    
063        public void deleteVersion( VersionedReference reference )
064            throws ContentNotFoundException
065        {
066            File groupDir = new File( repository.getLocation(), reference.getGroupId() );
067    
068            if ( !groupDir.exists() )
069            {
070                throw new ContentNotFoundException(
071                    "Unable to get versions using a non-existant groupId directory: " + groupDir.getAbsolutePath() );
072            }
073    
074            if ( !groupDir.isDirectory() )
075            {
076                throw new ContentNotFoundException(
077                    "Unable to get versions using a non-directory: " + groupDir.getAbsolutePath() );
078            }
079    
080            // First gather up the versions found as artifacts in the managed repository.
081            File typeDirs[] = groupDir.listFiles();
082            for ( File typeDir : typeDirs )
083            {
084                if ( !typeDir.isDirectory() )
085                {
086                    // Skip it, we only care about directories.
087                    continue;
088                }
089    
090                if ( !typeDir.getName().endsWith( "s" ) )
091                {
092                    // Skip it, we only care about directories that end in "s".
093                }
094    
095                deleteVersions( typeDir, reference );
096            }
097        }
098    
099        private void deleteVersions( File typeDir, VersionedReference reference )
100        {
101            File repoFiles[] = typeDir.listFiles();
102            for ( File repoFile : repoFiles )
103            {
104                if ( repoFile.isDirectory() )
105                {
106                    // Skip it. it's a directory.
107                    continue;
108                }
109    
110                String relativePath = PathUtil.getRelative( repository.getLocation(), repoFile );
111    
112                if ( filetypes.matchesArtifactPattern( relativePath ) )
113                {
114                    try
115                    {
116                        ArtifactReference artifact = toArtifactReference( relativePath );
117                        if ( StringUtils.equals( artifact.getArtifactId(), reference.getArtifactId() )
118                            && StringUtils.equals( artifact.getVersion(), reference.getVersion() ) )
119                        {
120                            repoFile.delete();
121                            deleteSupportFiles( repoFile );
122                        }
123                    }
124                    catch ( LayoutException e )
125                    {
126                        /* don't fail the process if there is a bad artifact within the directory. */
127                    }
128                }
129            }
130        }
131    
132        public void deleteProject( String namespace, String projectId )
133            throws RepositoryException
134        {
135            // TODO implements ??
136        }
137    
138        private void deleteSupportFiles( File repoFile )
139        {
140            deleteSupportFile( repoFile, ".sha1" );
141            deleteSupportFile( repoFile, ".md5" );
142            deleteSupportFile( repoFile, ".asc" );
143            deleteSupportFile( repoFile, ".gpg" );
144        }
145    
146        private void deleteSupportFile( File repoFile, String supportExtension )
147        {
148            File supportFile = new File( repoFile.getAbsolutePath() + supportExtension );
149            if ( supportFile.exists() && supportFile.isFile() )
150            {
151                supportFile.delete();
152            }
153        }
154    
155        public String getId()
156        {
157            return repository.getId();
158        }
159    
160        public Set<ArtifactReference> getRelatedArtifacts( ArtifactReference reference )
161            throws ContentNotFoundException
162        {
163            File artifactFile = toFile( reference );
164            File repoDir = artifactFile.getParentFile();
165    
166            if ( !repoDir.exists() )
167            {
168                throw new ContentNotFoundException(
169                    "Unable to get related artifacts using a non-existant directory: " + repoDir.getAbsolutePath() );
170            }
171    
172            if ( !repoDir.isDirectory() )
173            {
174                throw new ContentNotFoundException(
175                    "Unable to get related artifacts using a non-directory: " + repoDir.getAbsolutePath() );
176            }
177    
178            Set<ArtifactReference> foundArtifacts = new HashSet<ArtifactReference>();
179    
180            // First gather up the versions found as artifacts in the managed repository.
181            File projectParentDir = repoDir.getParentFile();
182            File typeDirs[] = projectParentDir.listFiles();
183            for ( File typeDir : typeDirs )
184            {
185                if ( !typeDir.isDirectory() )
186                {
187                    // Skip it, we only care about directories.
188                    continue;
189                }
190    
191                if ( !typeDir.getName().endsWith( "s" ) )
192                {
193                    // Skip it, we only care about directories that end in "s".
194                }
195    
196                getRelatedArtifacts( typeDir, reference, foundArtifacts );
197            }
198    
199            return foundArtifacts;
200        }
201    
202        public String getRepoRoot()
203        {
204            return repository.getLocation();
205        }
206    
207        public ManagedRepository getRepository()
208        {
209            return repository;
210        }
211    
212        public Set<String> getVersions( ProjectReference reference )
213            throws ContentNotFoundException
214        {
215            File groupDir = new File( repository.getLocation(), reference.getGroupId() );
216    
217            if ( !groupDir.exists() )
218            {
219                throw new ContentNotFoundException(
220                    "Unable to get versions using a non-existant groupId directory: " + groupDir.getAbsolutePath() );
221            }
222    
223            if ( !groupDir.isDirectory() )
224            {
225                throw new ContentNotFoundException(
226                    "Unable to get versions using a non-directory: " + groupDir.getAbsolutePath() );
227            }
228    
229            Set<String> foundVersions = new HashSet<String>();
230    
231            // First gather up the versions found as artifacts in the managed repository.
232            File typeDirs[] = groupDir.listFiles();
233            for ( File typeDir : typeDirs )
234            {
235                if ( !typeDir.isDirectory() )
236                {
237                    // Skip it, we only care about directories.
238                    continue;
239                }
240    
241                if ( !typeDir.getName().endsWith( "s" ) )
242                {
243                    // Skip it, we only care about directories that end in "s".
244                }
245    
246                getProjectVersions( typeDir, reference, foundVersions );
247            }
248    
249            return foundVersions;
250        }
251    
252        public Set<String> getVersions( VersionedReference reference )
253            throws ContentNotFoundException
254        {
255            File groupDir = new File( repository.getLocation(), reference.getGroupId() );
256    
257            if ( !groupDir.exists() )
258            {
259                throw new ContentNotFoundException(
260                    "Unable to get versions using a non-existant groupId directory: " + groupDir.getAbsolutePath() );
261            }
262    
263            if ( !groupDir.isDirectory() )
264            {
265                throw new ContentNotFoundException(
266                    "Unable to get versions using a non-directory: " + groupDir.getAbsolutePath() );
267            }
268    
269            Set<String> foundVersions = new HashSet<String>();
270    
271            // First gather up the versions found as artifacts in the managed repository.
272            File typeDirs[] = groupDir.listFiles();
273            for ( File typeDir : typeDirs )
274            {
275                if ( !typeDir.isDirectory() )
276                {
277                    // Skip it, we only care about directories.
278                    continue;
279                }
280    
281                if ( !typeDir.getName().endsWith( "s" ) )
282                {
283                    // Skip it, we only care about directories that end in "s".
284                }
285    
286                getVersionedVersions( typeDir, reference, foundVersions );
287            }
288    
289            return foundVersions;
290        }
291    
292        public boolean hasContent( ArtifactReference reference )
293        {
294            File artifactFile = toFile( reference );
295            return artifactFile.exists() && artifactFile.isFile();
296        }
297    
298        public boolean hasContent( ProjectReference reference )
299        {
300            try
301            {
302                Set<String> versions = getVersions( reference );
303                return CollectionUtils.isNotEmpty( versions );
304            }
305            catch ( ContentNotFoundException e )
306            {
307                return false;
308            }
309        }
310    
311        public boolean hasContent( VersionedReference reference )
312        {
313            try
314            {
315                Set<String> versions = getVersions( reference );
316                return CollectionUtils.isNotEmpty( versions );
317            }
318            catch ( ContentNotFoundException e )
319            {
320                return false;
321            }
322        }
323    
324        public void setRepository( ManagedRepository repository )
325        {
326            this.repository = repository;
327        }
328    
329        /**
330         * Convert a path to an artifact reference.
331         *
332         * @param path the path to convert. (relative or full location path)
333         * @throws org.apache.archiva.repository.layout.LayoutException if the path cannot be converted to an artifact reference.
334         */
335        @Override
336        public ArtifactReference toArtifactReference( String path )
337            throws LayoutException
338        {
339            if ( ( path != null ) && path.startsWith( repository.getLocation() ) )
340            {
341                return super.toArtifactReference( path.substring( repository.getLocation().length() ) );
342            }
343    
344            return super.toArtifactReference( path );
345        }
346    
347        public File toFile( ArchivaArtifact reference )
348        {
349            return new File( repository.getLocation(), toPath( reference ) );
350        }
351    
352        public File toFile( ArtifactReference reference )
353        {
354            return new File( repository.getLocation(), toPath( reference ) );
355        }
356    
357        public String toMetadataPath( ProjectReference reference )
358        {
359            // No metadata present in legacy repository.
360            return null;
361        }
362    
363        public String toMetadataPath( VersionedReference reference )
364        {
365            // No metadata present in legacy repository.
366            return null;
367        }
368    
369        private void getProjectVersions( File typeDir, ProjectReference reference, Set<String> foundVersions )
370        {
371            File repoFiles[] = typeDir.listFiles();
372            for ( File repoFile : repoFiles )
373            {
374                if ( repoFile.isDirectory() )
375                {
376                    // Skip it. it's a directory.
377                    continue;
378                }
379    
380                String relativePath = PathUtil.getRelative( repository.getLocation(), repoFile );
381    
382                if ( filetypes.matchesArtifactPattern( relativePath ) )
383                {
384                    try
385                    {
386                        ArtifactReference artifact = toArtifactReference( relativePath );
387                        if ( StringUtils.equals( artifact.getArtifactId(), reference.getArtifactId() ) )
388                        {
389                            foundVersions.add( artifact.getVersion() );
390                        }
391                    }
392                    catch ( LayoutException e )
393                    {
394                        /* don't fail the process if there is a bad artifact within the directory. */
395                    }
396                }
397            }
398        }
399    
400        private void getRelatedArtifacts( File typeDir, ArtifactReference reference, Set<ArtifactReference> foundArtifacts )
401        {
402            File repoFiles[] = typeDir.listFiles();
403            for ( int i = 0; i < repoFiles.length; i++ )
404            {
405                if ( repoFiles[i].isDirectory() )
406                {
407                    // Skip it. it's a directory.
408                    continue;
409                }
410    
411                String relativePath = PathUtil.getRelative( repository.getLocation(), repoFiles[i] );
412    
413                if ( filetypes.matchesArtifactPattern( relativePath ) )
414                {
415                    try
416                    {
417                        ArtifactReference artifact = toArtifactReference( relativePath );
418                        if ( StringUtils.equals( artifact.getArtifactId(), reference.getArtifactId() )
419                            && artifact.getVersion().startsWith( reference.getVersion() ) )
420                        {
421                            foundArtifacts.add( artifact );
422                        }
423                    }
424                    catch ( LayoutException e )
425                    {
426                        /* don't fail the process if there is a bad artifact within the directory. */
427                    }
428                }
429            }
430        }
431    
432        private void getVersionedVersions( File typeDir, VersionedReference reference, Set<String> foundVersions )
433        {
434            File repoFiles[] = typeDir.listFiles();
435            for ( int i = 0; i < repoFiles.length; i++ )
436            {
437                if ( repoFiles[i].isDirectory() )
438                {
439                    // Skip it. it's a directory.
440                    continue;
441                }
442    
443                String relativePath = PathUtil.getRelative( repository.getLocation(), repoFiles[i] );
444    
445                if ( filetypes.matchesArtifactPattern( relativePath ) )
446                {
447                    try
448                    {
449                        ArtifactReference artifact = toArtifactReference( relativePath );
450                        if ( StringUtils.equals( artifact.getArtifactId(), reference.getArtifactId() )
451                            && artifact.getVersion().startsWith( reference.getVersion() ) )
452                        {
453                            foundVersions.add( artifact.getVersion() );
454                        }
455                    }
456                    catch ( LayoutException e )
457                    {
458                        /* don't fail the process if there is a bad artifact within the directory. */
459                    }
460                }
461            }
462        }
463    
464        public void setFileTypes( FileTypes fileTypes )
465        {
466            this.filetypes = fileTypes;
467        }
468    
469        public void deleteArtifact( ArtifactReference artifactReference )
470            throws ContentNotFoundException
471        {
472            // TODO implements for legacy ??
473        }
474    
475        public void deleteGroupId( String groupId )
476            throws ContentNotFoundException
477        {
478            // TODO implements for legacy ??
479        }
480    }