1 package org.apache.maven.index.artifact;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import javax.inject.Named;
23 import javax.inject.Singleton;
24 import java.text.ParseException;
25 import java.text.SimpleDateFormat;
26
27
28
29
30
31
32
33 @Singleton
34 @Named( "maven2" )
35 public class M2GavCalculator
36 implements GavCalculator
37 {
38 public Gav pathToGav( String str )
39 {
40 try
41 {
42 String s = str.startsWith( "/" ) ? str.substring( 1 ) : str;
43
44 int vEndPos = s.lastIndexOf( '/' );
45
46 if ( vEndPos == -1 )
47 {
48 return null;
49 }
50
51 int aEndPos = s.lastIndexOf( '/', vEndPos - 1 );
52
53 if ( aEndPos == -1 )
54 {
55 return null;
56 }
57
58 int gEndPos = s.lastIndexOf( '/', aEndPos - 1 );
59
60 if ( gEndPos == -1 )
61 {
62 return null;
63 }
64
65 String groupId = s.substring( 0, gEndPos ).replace( '/', '.' );
66 String artifactId = s.substring( gEndPos + 1, aEndPos );
67 String version = s.substring( aEndPos + 1, vEndPos );
68 String fileName = s.substring( vEndPos + 1 );
69
70 boolean checksum = false;
71 boolean signature = false;
72 Gav.HashType checksumType = null;
73 Gav.SignatureType signatureType = null;
74 if ( s.endsWith( ".md5" ) )
75 {
76 checksum = true;
77 checksumType = Gav.HashType.md5;
78 s = s.substring( 0, s.length() - 4 );
79 }
80 else if ( s.endsWith( ".sha1" ) )
81 {
82 checksum = true;
83 checksumType = Gav.HashType.sha1;
84 s = s.substring( 0, s.length() - 5 );
85 }
86 else if ( s.endsWith( ".sha256" ) )
87 {
88 checksum = true;
89 checksumType = Gav.HashType.sha256;
90 s = s.substring( 0, s.length() - 7 );
91 }
92 else if ( s.endsWith( ".sha512" ) )
93 {
94 checksum = true;
95 checksumType = Gav.HashType.sha512;
96 s = s.substring( 0, s.length() - 7 );
97 }
98
99 if ( s.endsWith( ".asc" ) )
100 {
101 signature = true;
102 signatureType = Gav.SignatureType.gpg;
103 s = s.substring( 0, s.length() - 4 );
104 }
105
106 if ( s.endsWith( "maven-metadata.xml" )
107 || ( fileName.startsWith( "maven-metadata-" ) && fileName.contains( ".xml" ) )
108 || ( fileName.startsWith( "_" ) && fileName.endsWith( ".repositories" ) ) )
109 {
110 return null;
111 }
112
113 boolean snapshot = version.endsWith( "SNAPSHOT" );
114
115 if ( snapshot )
116 {
117 return getSnapshotGav( s, vEndPos, groupId, artifactId, version, fileName, checksum, signature,
118 checksumType, signatureType );
119 }
120 else
121 {
122 return getReleaseGav( s, vEndPos, groupId, artifactId, version, fileName, checksum, signature,
123 checksumType, signatureType );
124 }
125 }
126 catch ( NumberFormatException | StringIndexOutOfBoundsException e )
127 {
128 return null;
129 }
130 }
131
132 private Gav getReleaseGav( String s, int vEndPos, String groupId, String artifactId, String version,
133 String fileName, boolean checksum, boolean signature, Gav.HashType checksumType,
134 Gav.SignatureType signatureType )
135 {
136 if ( !fileName.startsWith( artifactId + "-" + version + "." )
137 && !fileName.startsWith( artifactId + "-" + version + "-" ) )
138 {
139
140 return null;
141 }
142
143 int nTailPos = vEndPos + artifactId.length() + version.length() + 2;
144
145 String tail = s.substring( nTailPos );
146
147 int nExtPos = tail.indexOf( '.' );
148
149 if ( nExtPos == -1 )
150 {
151
152 return null;
153 }
154
155 String ext = tail.substring( nExtPos + 1 );
156
157 String classifier = tail.charAt( 0 ) == '-' ? tail.substring( 1, nExtPos ) : null;
158
159 return new Gav( groupId, artifactId, version, classifier, ext, null, null, fileName, checksum, checksumType,
160 signature, signatureType );
161 }
162
163 private Gav getSnapshotGav( String s, int vEndPos, String groupId, String artifactId, String version,
164 String fileName, boolean checksum, boolean signature, Gav.HashType checksumType,
165 Gav.SignatureType signatureType )
166 {
167
168 Integer snapshotBuildNo = null;
169
170 Long snapshotTimestamp = null;
171
172 int vSnapshotStart = vEndPos + artifactId.length() + version.length() - 9 + 3;
173
174 String vSnapshot = s.substring( vSnapshotStart, vSnapshotStart + 8 );
175
176 String classifier;
177
178 String ext;
179
180 if ( "SNAPSHOT".equals( vSnapshot ) )
181 {
182 int nTailPos = vEndPos + artifactId.length() + version.length() + 2;
183
184 String tail = s.substring( nTailPos );
185
186 int nExtPos = tail.indexOf( '.' );
187
188 if ( nExtPos == -1 )
189 {
190
191 return null;
192 }
193
194 ext = tail.substring( nExtPos + 1 );
195
196 classifier = tail.charAt( 0 ) == '-' ? tail.substring( 1, nExtPos ) : null;
197 }
198 else
199 {
200 StringBuilder sb = new StringBuilder( vSnapshot );
201 sb.append( s, vSnapshotStart + sb.length(), vSnapshotStart + sb.length() + 8 );
202
203 try
204 {
205 SimpleDateFormat df = new SimpleDateFormat( "yyyyMMdd.HHmmss" );
206 snapshotTimestamp = df.parse( sb.toString() ).getTime();
207 }
208 catch ( ParseException e )
209 {
210 }
211
212 int buildNumberPos = vSnapshotStart + sb.length();
213 StringBuilder bnr = new StringBuilder();
214 while ( s.charAt( buildNumberPos ) >= '0' && s.charAt( buildNumberPos ) <= '9' )
215 {
216 sb.append( s.charAt( buildNumberPos ) );
217 bnr.append( s.charAt( buildNumberPos ) );
218 buildNumberPos++;
219 }
220 String snapshotBuildNumber = sb.toString();
221 snapshotBuildNo = Integer.parseInt( bnr.toString() );
222
223 int n = version.length() > 9 ? version.length() - 9 + 1 : 0;
224
225 String tail = s.substring( vEndPos + artifactId.length() + n + snapshotBuildNumber.length() + 2 );
226
227 int nExtPos = tail.indexOf( '.' );
228
229 if ( nExtPos == -1 )
230 {
231
232 return null;
233 }
234
235 ext = tail.substring( nExtPos + 1 );
236
237 classifier = tail.charAt( 0 ) == '-' ? tail.substring( 1, nExtPos ) : null;
238
239 version = version.substring( 0, version.length() - 8 ) + snapshotBuildNumber;
240 }
241
242 return new Gav( groupId, artifactId, version, classifier, ext, snapshotBuildNo, snapshotTimestamp, fileName,
243 checksum, checksumType, signature, signatureType );
244 }
245
246 public String gavToPath( Gav gav )
247 {
248
249 return "/" + gav.getGroupId().replaceAll( "(?m)(.)\\.",
250 "$1/" )
251 + "/" + gav.getArtifactId() + "/" + gav.getBaseVersion() + "/" + calculateArtifactName( gav );
252 }
253
254 public String calculateArtifactName( Gav gav )
255 {
256 if ( gav.getName() != null && gav.getName().trim().length() > 0 )
257 {
258 return gav.getName();
259 }
260 else
261 {
262 StringBuilder path = new StringBuilder( gav.getArtifactId() );
263
264 path.append( "-" );
265
266 path.append( gav.getVersion() );
267
268 if ( gav.getClassifier() != null && gav.getClassifier().trim().length() > 0 )
269 {
270 path.append( "-" );
271
272 path.append( gav.getClassifier() );
273 }
274
275 if ( gav.getExtension() != null )
276 {
277 path.append( "." );
278
279 path.append( gav.getExtension() );
280 }
281
282 if ( gav.isSignature() )
283 {
284 path.append( "." );
285
286 path.append( gav.getSignatureType().toString() );
287 }
288
289 if ( gav.isHash() )
290 {
291 path.append( "." );
292
293 path.append( gav.getHashType().toString() );
294 }
295
296 return path.toString();
297 }
298 }
299
300 }