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