]> source.dussan.org Git - archiva.git/blob
ade81214a292e52fbb07fbb3236655f10f99ae69
[archiva.git] /
1 package org.apache.archiva.repository.scanner.mock;
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.common.utils.VersionUtil;
23 import org.apache.archiva.metadata.model.ArtifactMetadata;
24 import org.apache.archiva.metadata.model.maven2.MavenArtifactFacet;
25 import org.apache.archiva.model.ArchivaArtifact;
26 import org.apache.archiva.model.ArtifactReference;
27 import org.apache.archiva.model.ProjectReference;
28 import org.apache.archiva.model.VersionedReference;
29 import org.apache.archiva.repository.*;
30 import org.apache.archiva.repository.content.StorageAsset;
31 import org.apache.commons.lang.StringUtils;
32
33 import java.nio.file.Paths;
34 import java.util.HashMap;
35 import java.util.Map;
36 import java.util.Set;
37 import java.util.regex.Matcher;
38 import java.util.regex.Pattern;
39
40 /**
41  * @author Martin Stockhammer <martin_s@apache.org>
42  */
43 public class ManagedRepositoryContentMock implements ManagedRepositoryContent
44 {
45     private static final String PATH_SEPARATOR = "/";
46     private static final String GROUP_SEPARATOR = ".";
47     public static final String MAVEN_METADATA = "maven-metadata.xml";
48
49
50     private ManagedRepository repository;
51
52     public ManagedRepositoryContentMock(ManagedRepository repo) {
53         this.repository = repo;
54     }
55
56     @Override
57     public void deleteVersion( VersionedReference reference ) throws ContentNotFoundException
58     {
59
60     }
61
62     @Override
63     public void deleteArtifact( ArtifactReference artifactReference ) throws ContentNotFoundException
64     {
65
66     }
67
68     @Override
69     public void deleteGroupId( String groupId ) throws ContentNotFoundException
70     {
71
72     }
73
74     @Override
75     public void deleteProject( String namespace, String projectId ) throws RepositoryException
76     {
77
78     }
79
80     @Override
81     public String getId( )
82     {
83         return repository.getId();
84     }
85
86     @Override
87     public Set<ArtifactReference> getRelatedArtifacts( ArtifactReference reference ) throws ContentNotFoundException
88     {
89         return null;
90     }
91
92     @Override
93     public String getRepoRoot( )
94     {
95         return Paths.get("", "target", "test-repository", "managed").toString();
96     }
97
98     @Override
99     public ManagedRepository getRepository( )
100     {
101         return repository;
102     }
103
104     @Override
105     public Set<String> getVersions( ProjectReference reference ) throws ContentNotFoundException, LayoutException
106     {
107         return null;
108     }
109
110     @Override
111     public Set<String> getVersions( VersionedReference reference ) throws ContentNotFoundException
112     {
113         return null;
114     }
115
116     @Override
117     public boolean hasContent( ArtifactReference reference )
118     {
119         return false;
120     }
121
122     @Override
123     public boolean hasContent( ProjectReference reference )
124     {
125         return false;
126     }
127
128     @Override
129     public boolean hasContent( VersionedReference reference )
130     {
131         return false;
132     }
133
134     @Override
135     public void setRepository( ManagedRepository repo )
136     {
137         this.repository = repo;
138     }
139
140     private Map<ArtifactReference, String> refs = new HashMap<>();
141
142     @Override
143     public ArtifactReference toArtifactReference( String path ) throws LayoutException
144     {
145         if ( StringUtils.isBlank( path ) )
146         {
147             throw new LayoutException( "Unable to convert blank path." );
148         }
149
150         ArtifactMetadata metadata = getArtifactForPath("test-repository", path);
151
152         ArtifactReference artifact = new ArtifactReference();
153         artifact.setGroupId( metadata.getNamespace() );
154         artifact.setArtifactId( metadata.getProject() );
155         artifact.setVersion( metadata.getVersion() );
156         MavenArtifactFacet facet = (MavenArtifactFacet) metadata.getFacet( MavenArtifactFacet.FACET_ID );
157         if ( facet != null )
158         {
159             artifact.setClassifier( facet.getClassifier() );
160             artifact.setType( facet.getType() );
161         }
162         refs.put(artifact, path);
163         return artifact;
164     }
165
166     public ArtifactMetadata getArtifactForPath( String repoId, String relativePath )
167     {
168         String[] parts = relativePath.replace( '\\', '/' ).split( "/" );
169
170         int len = parts.length;
171         if ( len < 4 )
172         {
173             throw new IllegalArgumentException(
174                     "Not a valid artifact path in a Maven 2 repository, not enough directories: " + relativePath );
175         }
176
177         String id = parts[--len];
178         String baseVersion = parts[--len];
179         String artifactId = parts[--len];
180         StringBuilder groupIdBuilder = new StringBuilder();
181         for ( int i = 0; i < len - 1; i++ )
182         {
183             groupIdBuilder.append( parts[i] );
184             groupIdBuilder.append( '.' );
185         }
186         groupIdBuilder.append( parts[len - 1] );
187
188         return getArtifactFromId( repoId, groupIdBuilder.toString(), artifactId, baseVersion, id );
189     }
190
191     private static final Pattern TIMESTAMP_PATTERN = Pattern.compile( "([0-9]{8}.[0-9]{6})-([0-9]+).*" );
192
193
194
195     public ArtifactMetadata getArtifactFromId( String repoId, String namespace, String projectId, String projectVersion,
196                                                String id )
197     {
198         if ( !id.startsWith( projectId + "-" ) )
199         {
200             throw new IllegalArgumentException( "Not a valid artifact path in a Maven 2 repository, filename '" + id
201                     + "' doesn't start with artifact ID '" + projectId + "'" );
202         }
203
204         MavenArtifactFacet facet = new MavenArtifactFacet();
205
206         int index = projectId.length() + 1;
207         String version;
208         String idSubStrFromVersion = id.substring( index );
209         if ( idSubStrFromVersion.startsWith( projectVersion ) && !VersionUtil.isUniqueSnapshot( projectVersion ) )
210         {
211             // non-snapshot versions, or non-timestamped snapshot versions
212             version = projectVersion;
213         }
214         else if ( VersionUtil.isGenericSnapshot( projectVersion ) )
215         {
216             // timestamped snapshots
217             try
218             {
219                 int mainVersionLength = projectVersion.length() - 8; // 8 is length of "SNAPSHOT"
220                 if ( mainVersionLength == 0 )
221                 {
222                     throw new IllegalArgumentException(
223                             "Timestamped snapshots must contain the main version, filename was '" + id + "'" );
224                 }
225
226                 Matcher m = TIMESTAMP_PATTERN.matcher( idSubStrFromVersion.substring( mainVersionLength ) );
227                 m.matches();
228                 String timestamp = m.group( 1 );
229                 String buildNumber = m.group( 2 );
230                 facet.setTimestamp( timestamp );
231                 facet.setBuildNumber( Integer.parseInt( buildNumber ) );
232                 version = idSubStrFromVersion.substring( 0, mainVersionLength ) + timestamp + "-" + buildNumber;
233             }
234             catch ( IllegalStateException e )
235             {
236                 throw new IllegalArgumentException( "Not a valid artifact path in a Maven 2 repository, filename '" + id
237                         + "' doesn't contain a timestamped version matching snapshot '"
238                         + projectVersion + "'", e);
239             }
240         }
241         else
242         {
243             // invalid
244             throw new IllegalArgumentException(
245                     "Not a valid artifact path in a Maven 2 repository, filename '" + id + "' doesn't contain version '"
246                             + projectVersion + "'" );
247         }
248
249         String classifier;
250         String ext;
251         index += version.length();
252         if ( index == id.length() )
253         {
254             // no classifier or extension
255             classifier = null;
256             ext = null;
257         }
258         else
259         {
260             char c = id.charAt( index );
261             if ( c == '-' )
262             {
263                 // classifier up until '.'
264                 int extIndex = id.indexOf( '.', index );
265                 if ( extIndex >= 0 )
266                 {
267                     classifier = id.substring( index + 1, extIndex );
268                     ext = id.substring( extIndex + 1 );
269                 }
270                 else
271                 {
272                     classifier = id.substring( index + 1 );
273                     ext = null;
274                 }
275             }
276             else if ( c == '.' )
277             {
278                 // rest is the extension
279                 classifier = null;
280                 ext = id.substring( index + 1 );
281             }
282             else
283             {
284                 throw new IllegalArgumentException( "Not a valid artifact path in a Maven 2 repository, filename '" + id
285                         + "' expected classifier or extension but got '"
286                         + id.substring( index ) + "'" );
287             }
288         }
289
290         ArtifactMetadata metadata = new ArtifactMetadata();
291         metadata.setId( id );
292         metadata.setNamespace( namespace );
293         metadata.setProject( projectId );
294         metadata.setRepositoryId( repoId );
295         metadata.setProjectVersion( projectVersion );
296         metadata.setVersion( version );
297
298         facet.setClassifier( classifier );
299
300         // we use our own provider here instead of directly accessing Maven's artifact handlers as it has no way
301         // to select the correct order to apply multiple extensions mappings to a preferred type
302         // TODO: this won't allow the user to decide order to apply them if there are conflicts or desired changes -
303         //       perhaps the plugins could register missing entries in configuration, then we just use configuration
304         //       here?
305
306         String type = null;
307
308
309         // use extension as default
310         if ( type == null )
311         {
312             type = ext;
313         }
314
315         // TODO: should we allow this instead?
316         if ( type == null )
317         {
318             throw new IllegalArgumentException(
319                     "Not a valid artifact path in a Maven 2 repository, filename '" + id + "' does not have a type" );
320         }
321
322         facet.setType( type );
323         metadata.addFacet( facet );
324
325         return metadata;
326     }
327
328
329     @Override
330     public StorageAsset toFile( ArtifactReference reference )
331     {
332         return Paths.get(getRepoRoot(), refs.get(reference));
333     }
334
335     @Override
336     public StorageAsset toFile( ArchivaArtifact reference )
337     {
338         return null;
339     }
340
341     private String formatAsDirectory( String directory )
342     {
343         return directory.replace( GROUP_SEPARATOR, PATH_SEPARATOR );
344     }
345
346     public String toMetadataPath( ProjectReference reference )
347     {
348         StringBuilder path = new StringBuilder();
349
350         path.append( formatAsDirectory( reference.getGroupId() ) ).append( PATH_SEPARATOR );
351         path.append( reference.getArtifactId() ).append( PATH_SEPARATOR );
352         path.append( MAVEN_METADATA );
353
354         return path.toString();
355     }
356
357     public String toMetadataPath( VersionedReference reference )
358     {
359         StringBuilder path = new StringBuilder();
360
361         path.append( formatAsDirectory( reference.getGroupId() ) ).append( PATH_SEPARATOR );
362         path.append( reference.getArtifactId() ).append( PATH_SEPARATOR );
363         if ( reference.getVersion() != null )
364         {
365             // add the version only if it is present
366             path.append( VersionUtil.getBaseVersion( reference.getVersion() ) ).append( PATH_SEPARATOR );
367         }
368         path.append( MAVEN_METADATA );
369
370         return path.toString();
371     }
372
373     @Override
374     public String toPath( ArtifactReference reference )
375     {
376         return null;
377     }
378
379     @Override
380     public String toPath( ArchivaArtifact reference )
381     {
382         return null;
383     }
384
385 }