]> source.dussan.org Git - archiva.git/blob
4cac9168d2cb670afbf095d58239e9887b71cfc3
[archiva.git] /
1 package org.apache.maven.repository.discovery;
2
3 /*
4  * Copyright 2005-2006 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 import org.apache.maven.artifact.Artifact;
20 import org.apache.maven.artifact.factory.ArtifactFactory;
21
22 import java.io.File;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.Iterator;
26 import java.util.LinkedList;
27 import java.util.List;
28 import java.util.StringTokenizer;
29
30 /**
31  * Artifact discoverer for the legacy repository layout (Maven 1.x).
32  *
33  * @author John Casey
34  * @author Brett Porter
35  */
36 public class LegacyArtifactDiscoverer
37     extends AbstractArtifactDiscoverer
38     implements ArtifactDiscoverer
39 {
40     private ArtifactFactory artifactFactory;
41
42     public List discoverArtifacts( File repositoryBase, String blacklistedPatterns, boolean includeSnapshots )
43     {
44         List artifacts = new ArrayList();
45
46         String[] artifactPaths = scanForArtifactPaths( repositoryBase, blacklistedPatterns );
47
48         for ( int i = 0; i < artifactPaths.length; i++ )
49         {
50             String path = artifactPaths[i];
51
52             Artifact artifact = buildArtifact( path );
53             if ( artifact != null )
54             {
55                 if ( includeSnapshots || !artifact.isSnapshot() )
56                 {
57                     artifacts.add( artifact );
58                 }
59             }
60         }
61
62         return artifacts;
63     }
64
65     private Artifact buildArtifact( String path )
66     {
67         StringTokenizer tokens = new StringTokenizer( path, "/\\" );
68
69         int numberOfTokens = tokens.countTokens();
70
71         if ( numberOfTokens != 3 )
72         {
73             addKickedOutPath( path );
74
75             return null;
76         }
77
78         String groupId = tokens.nextToken();
79
80         String type = tokens.nextToken();
81
82         if ( !type.endsWith( "s" ) )
83         {
84             addKickedOutPath( path );
85
86             return null;
87         }
88         type = type.substring( 0, type.length() - 1 );
89
90         // contains artifactId, version, classifier, and extension.
91         String avceGlob = tokens.nextToken();
92
93         LinkedList avceTokenList = new LinkedList();
94
95         StringTokenizer avceTokenizer = new StringTokenizer( avceGlob, "-" );
96         while ( avceTokenizer.hasMoreTokens() )
97         {
98             avceTokenList.addLast( avceTokenizer.nextToken() );
99         }
100
101         String lastAvceToken = (String) avceTokenList.removeLast();
102
103         // TODO: share with other discoverer, use artifact handlers instead
104         if ( lastAvceToken.endsWith( ".tar.gz" ) )
105         {
106             type = "distribution-tgz";
107
108             lastAvceToken = lastAvceToken.substring( 0, lastAvceToken.length() - ".tar.gz".length() );
109
110             avceTokenList.addLast( lastAvceToken );
111         }
112         else if ( lastAvceToken.endsWith( "sources.jar" ) )
113         {
114             type = "java-source";
115
116             lastAvceToken = lastAvceToken.substring( 0, lastAvceToken.length() - ".jar".length() );
117
118             avceTokenList.addLast( lastAvceToken );
119         }
120         else if ( lastAvceToken.endsWith( ".zip" ) )
121         {
122             type = "distribution-zip";
123
124             lastAvceToken = lastAvceToken.substring( 0, lastAvceToken.length() - ".zip".length() );
125
126             avceTokenList.addLast( lastAvceToken );
127         }
128         else
129         {
130             int extPos = lastAvceToken.lastIndexOf( '.' );
131
132             if ( extPos > 0 )
133             {
134                 String ext = lastAvceToken.substring( extPos + 1 );
135                 if ( type.equals( ext ) )
136                 {
137                     lastAvceToken = lastAvceToken.substring( 0, extPos );
138
139                     avceTokenList.addLast( lastAvceToken );
140                 }
141                 else
142                 {
143                     addKickedOutPath( path );
144
145                     return null;
146                 }
147             }
148             else
149             {
150                 // no extension
151                 addKickedOutPath( path );
152
153                 return null;
154             }
155         }
156
157         // TODO: this is obscene - surely a better way?
158         String validVersionParts = "([Dd][Ee][Vv][_.0-9]*)|" + "([Ss][Nn][Aa][Pp][Ss][Hh][Oo][Tt])|" +
159             "([0-9][_.0-9a-zA-Z]*)|" + "([Gg]?[_.0-9ab]*([Pp][Rr][Ee]|[Rr][Cc]|[Gg]|[Mm])[_.0-9]*)|" +
160             "([Aa][Ll][Pp][Hh][Aa][_.0-9]*)|" + "([Bb][Ee][Tt][Aa][_.0-9]*)|" + "([Rr][Cc][_.0-9]*)|" +
161             "([Tt][Ee][Ss][Tt][_.0-9]*)|" + "([Dd][Ee][Bb][Uu][Gg][_.0-9]*)|" +
162             "([Uu][Nn][Oo][Ff][Ff][Ii][Cc][Ii][Aa][Ll][_.0-9]*)|" + "([Cc][Uu][Rr][Rr][Ee][Nn][Tt])|" +
163             "([Ll][Aa][Tt][Ee][Ss][Tt])|" + "([Ff][Cc][Ss])|" + "([Rr][Ee][Ll][Ee][Aa][Ss][Ee][_.0-9]*)|" +
164             "([Nn][Ii][Gg][Hh][Tt][Ll][Yy])|" + "([AaBb][_.0-9]*)";
165
166         // let's discover the version, and whatever's leftover will be either
167         // a classifier, or part of the artifactId, depending on position.
168         // Since version is at the end, we have to move in from the back.
169         Collections.reverse( avceTokenList );
170
171         StringBuffer classifierBuffer = new StringBuffer();
172         StringBuffer versionBuffer = new StringBuffer();
173
174         boolean firstVersionTokenEncountered = false;
175         boolean firstToken = true;
176
177         int tokensIterated = 0;
178         for ( Iterator it = avceTokenList.iterator(); it.hasNext(); )
179         {
180             String token = (String) it.next();
181
182             boolean tokenIsVersionPart = token.matches( validVersionParts );
183
184             StringBuffer bufferToUpdate;
185
186             // NOTE: logic in code is reversed, since we're peeling off the back
187             // Any token after the last versionPart will be in the classifier.
188             // Any token UP TO first non-versionPart is part of the version.
189             if ( !tokenIsVersionPart )
190             {
191                 if ( firstVersionTokenEncountered )
192                 {
193                     break;
194                 }
195                 else
196                 {
197                     bufferToUpdate = classifierBuffer;
198                 }
199             }
200             else
201             {
202                 firstVersionTokenEncountered = true;
203
204                 bufferToUpdate = versionBuffer;
205             }
206
207             if ( firstToken )
208             {
209                 firstToken = false;
210             }
211             else
212             {
213                 bufferToUpdate.insert( 0, '-' );
214             }
215
216             bufferToUpdate.insert( 0, token );
217
218             tokensIterated++;
219         }
220
221         getLogger().debug( "After parsing loop, state of buffers:\no  Version Buffer: \'" + versionBuffer +
222             "\'\no  Classifier Buffer: \'" + classifierBuffer + "\'\no Number of Tokens Iterated: " + tokensIterated );
223
224         // Now, restore the proper ordering so we can build the artifactId.
225         Collections.reverse( avceTokenList );
226
227         getLogger().debug(
228             "Before repairing bad version and/or cleaning up used tokens, avce token list is:\n" + avceTokenList );
229
230         // if we didn't find a version, then punt. Use the last token
231         // as the version, and set the classifier empty.
232         if ( versionBuffer.length() < 1 )
233         {
234             if ( avceTokenList.size() > 1 )
235             {
236                 int lastIdx = avceTokenList.size() - 1;
237
238                 versionBuffer.append( avceTokenList.get( lastIdx ) );
239                 avceTokenList.remove( lastIdx );
240             }
241             else
242             {
243                 getLogger().debug( "Cannot parse version from artifact path: \'" + path + "\'." );
244                 getLogger().debug(
245                     "artifact-version-classifier-extension remaining tokens is: \'" + avceTokenList + "\'" );
246             }
247
248             classifierBuffer.setLength( 0 );
249         }
250         else
251         {
252             getLogger().debug( "Removing " + tokensIterated + " tokens from avce token list." );
253
254             // if everything is kosher, then pop off all the classifier and
255             // version tokens, leaving the naked artifact id in the list.
256             avceTokenList = new LinkedList( avceTokenList.subList( 0, avceTokenList.size() - tokensIterated ) );
257         }
258
259         getLogger().debug( "Now, remainder of avce token list is:\n" + avceTokenList );
260
261         StringBuffer artifactIdBuffer = new StringBuffer();
262
263         firstToken = true;
264         for ( Iterator it = avceTokenList.iterator(); it.hasNext(); )
265         {
266             String token = (String) it.next();
267
268             if ( firstToken )
269             {
270                 firstToken = false;
271             }
272             else
273             {
274                 artifactIdBuffer.append( '-' );
275             }
276
277             artifactIdBuffer.append( token );
278         }
279
280         String artifactId = artifactIdBuffer.toString();
281
282         int lastVersionCharIdx = versionBuffer.length() - 1;
283         if ( lastVersionCharIdx > -1 && versionBuffer.charAt( lastVersionCharIdx ) == '-' )
284         {
285             versionBuffer.setLength( lastVersionCharIdx );
286         }
287
288         String version = versionBuffer.toString();
289
290         if ( version.length() < 1 )
291         {
292             addKickedOutPath( path );
293
294             return null;
295         }
296
297         getLogger().debug( "Extracted artifact information from path:\n" + "groupId: \'" + groupId + "\'\n" +
298             "artifactId: \'" + artifactId + "\'\n" + "type: \'" + type + "\'\n" + "version: \'" + version + "\'\n" +
299             "classifier: \'" + classifierBuffer + "\'" );
300
301         Artifact result = null;
302
303         if ( classifierBuffer.length() > 0 )
304         {
305             getLogger().debug( "Creating artifact with classifier." );
306
307             result = artifactFactory.createArtifactWithClassifier( groupId, artifactId, version, type,
308                                                                    classifierBuffer.toString() );
309         }
310         else
311         {
312             result = artifactFactory.createArtifact( groupId, artifactId, version, Artifact.SCOPE_RUNTIME, type );
313         }
314
315         result.setFile( new File( path ) );
316
317         return result;
318     }
319
320 }