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