1 package org.apache.maven.artifact;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.regex.Matcher;
29
30 import org.apache.maven.artifact.handler.ArtifactHandler;
31 import org.apache.maven.artifact.metadata.ArtifactMetadata;
32 import org.apache.maven.artifact.repository.ArtifactRepository;
33 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
34 import org.apache.maven.artifact.versioning.ArtifactVersion;
35 import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
36 import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
37 import org.apache.maven.artifact.versioning.VersionRange;
38 import org.codehaus.plexus.util.StringUtils;
39
40
41
42
43 public class DefaultArtifact
44 implements Artifact
45 {
46 private String groupId;
47
48 private String artifactId;
49
50 private String baseVersion;
51
52 private final String type;
53
54 private final String classifier;
55
56 private volatile String scope;
57
58 private volatile File file;
59
60 private ArtifactRepository repository;
61
62 private String downloadUrl;
63
64 private ArtifactFilter dependencyFilter;
65
66 private ArtifactHandler artifactHandler;
67
68 private List<String> dependencyTrail;
69
70 private volatile String version;
71
72 private VersionRange versionRange;
73
74 private volatile boolean resolved;
75
76 private boolean release;
77
78 private List<ArtifactVersion> availableVersions;
79
80 private Map<Object, ArtifactMetadata> metadataMap;
81
82 private boolean optional;
83
84 public DefaultArtifact( String groupId, String artifactId, String version, String scope, String type,
85 String classifier, ArtifactHandler artifactHandler )
86 {
87 this( groupId, artifactId, VersionRange.createFromVersion( version ), scope, type, classifier, artifactHandler,
88 false );
89 }
90
91 public DefaultArtifact( String groupId, String artifactId, VersionRange versionRange, String scope, String type,
92 String classifier, ArtifactHandler artifactHandler )
93 {
94 this( groupId, artifactId, versionRange, scope, type, classifier, artifactHandler, false );
95 }
96
97 @SuppressWarnings( "checkstyle:parameternumber" )
98 public DefaultArtifact( String groupId, String artifactId, VersionRange versionRange, String scope, String type,
99 String classifier, ArtifactHandler artifactHandler, boolean optional )
100 {
101 this.groupId = groupId;
102
103 this.artifactId = artifactId;
104
105 this.versionRange = versionRange;
106
107 selectVersionFromNewRangeIfAvailable();
108
109 this.artifactHandler = artifactHandler;
110
111 this.scope = scope;
112
113 this.type = type;
114
115 if ( classifier == null )
116 {
117 classifier = artifactHandler.getClassifier();
118 }
119
120 this.classifier = classifier;
121
122 this.optional = optional;
123
124 validateIdentity();
125 }
126
127 private void validateIdentity()
128 {
129 if ( empty( groupId ) )
130 {
131 throw new InvalidArtifactRTException( groupId, artifactId, getVersion(), type,
132 "The groupId cannot be empty." );
133 }
134
135 if ( artifactId == null )
136 {
137 throw new InvalidArtifactRTException( groupId, artifactId, getVersion(), type,
138 "The artifactId cannot be empty." );
139 }
140
141 if ( type == null )
142 {
143 throw new InvalidArtifactRTException( groupId, artifactId, getVersion(), type,
144 "The type cannot be empty." );
145 }
146
147 if ( ( version == null ) && ( versionRange == null ) )
148 {
149 throw new InvalidArtifactRTException( groupId, artifactId, getVersion(), type,
150 "The version cannot be empty." );
151 }
152 }
153
154 private boolean empty( String value )
155 {
156 return ( value == null ) || ( value.trim().length() < 1 );
157 }
158
159 public String getClassifier()
160 {
161 return classifier;
162 }
163
164 public boolean hasClassifier()
165 {
166 return StringUtils.isNotEmpty( classifier );
167 }
168
169 public String getScope()
170 {
171 return scope;
172 }
173
174 public String getGroupId()
175 {
176 return groupId;
177 }
178
179 public String getArtifactId()
180 {
181 return artifactId;
182 }
183
184 public String getVersion()
185 {
186 return version;
187 }
188
189 public void setVersion( String version )
190 {
191 this.version = version;
192 setBaseVersionInternal( version );
193 versionRange = null;
194 }
195
196 public String getType()
197 {
198 return type;
199 }
200
201 public void setFile( File file )
202 {
203 this.file = file;
204 }
205
206 public File getFile()
207 {
208 return file;
209 }
210
211 public ArtifactRepository getRepository()
212 {
213 return repository;
214 }
215
216 public void setRepository( ArtifactRepository repository )
217 {
218 this.repository = repository;
219 }
220
221
222
223
224
225 public String getId()
226 {
227 return getDependencyConflictId() + ":" + getBaseVersion();
228 }
229
230 public String getDependencyConflictId()
231 {
232 StringBuilder sb = new StringBuilder( 128 );
233 sb.append( getGroupId() );
234 sb.append( ':' );
235 appendArtifactTypeClassifierString( sb );
236 return sb.toString();
237 }
238
239 private void appendArtifactTypeClassifierString( StringBuilder sb )
240 {
241 sb.append( getArtifactId() );
242 sb.append( ':' );
243 sb.append( getType() );
244 if ( hasClassifier() )
245 {
246 sb.append( ':' );
247 sb.append( getClassifier() );
248 }
249 }
250
251 public void addMetadata( ArtifactMetadata metadata )
252 {
253 if ( metadataMap == null )
254 {
255 metadataMap = new HashMap<>();
256 }
257
258 ArtifactMetadata m = metadataMap.get( metadata.getKey() );
259 if ( m != null )
260 {
261 m.merge( metadata );
262 }
263 else
264 {
265 metadataMap.put( metadata.getKey(), metadata );
266 }
267 }
268
269 public Collection<ArtifactMetadata> getMetadataList()
270 {
271 if ( metadataMap == null )
272 {
273 return Collections.emptyList();
274 }
275
276 return Collections.unmodifiableCollection( metadataMap.values() );
277 }
278
279
280
281
282
283 public String toString()
284 {
285 StringBuilder sb = new StringBuilder();
286 if ( getGroupId() != null )
287 {
288 sb.append( getGroupId() );
289 sb.append( ':' );
290 }
291 appendArtifactTypeClassifierString( sb );
292 sb.append( ':' );
293 if ( getBaseVersionInternal() != null )
294 {
295 sb.append( getBaseVersionInternal() );
296 }
297 else
298 {
299 sb.append( versionRange.toString() );
300 }
301 if ( scope != null )
302 {
303 sb.append( ':' );
304 sb.append( scope );
305 }
306 return sb.toString();
307 }
308
309 public int hashCode()
310 {
311 int result = 17;
312 result = 37 * result + groupId.hashCode();
313 result = 37 * result + artifactId.hashCode();
314 result = 37 * result + type.hashCode();
315 if ( version != null )
316 {
317 result = 37 * result + version.hashCode();
318 }
319 result = 37 * result + ( classifier != null ? classifier.hashCode() : 0 );
320 return result;
321 }
322
323 public boolean equals( Object o )
324 {
325 if ( o == this )
326 {
327 return true;
328 }
329
330 if ( !( o instanceof Artifact ) )
331 {
332 return false;
333 }
334
335 Artifact a = (Artifact) o;
336
337 if ( !a.getGroupId().equals( groupId ) )
338 {
339 return false;
340 }
341 else if ( !a.getArtifactId().equals( artifactId ) )
342 {
343 return false;
344 }
345 else if ( !a.getVersion().equals( version ) )
346 {
347 return false;
348 }
349 else if ( !a.getType().equals( type ) )
350 {
351 return false;
352 }
353 else if ( a.getClassifier() == null ? classifier != null : !a.getClassifier().equals( classifier ) )
354 {
355 return false;
356 }
357
358
359
360 return true;
361 }
362
363 public String getBaseVersion()
364 {
365 if ( baseVersion == null && version != null )
366 {
367 setBaseVersionInternal( version );
368 }
369
370 return baseVersion;
371 }
372
373 protected String getBaseVersionInternal()
374 {
375 if ( ( baseVersion == null ) && ( version != null ) )
376 {
377 setBaseVersionInternal( version );
378 }
379
380 return baseVersion;
381 }
382
383 public void setBaseVersion( String baseVersion )
384 {
385 setBaseVersionInternal( baseVersion );
386 }
387
388 protected void setBaseVersionInternal( String baseVersion )
389 {
390 Matcher m = VERSION_FILE_PATTERN.matcher( baseVersion );
391
392 if ( m.matches() )
393 {
394 this.baseVersion = m.group( 1 ) + "-" + SNAPSHOT_VERSION;
395 }
396 else
397 {
398 this.baseVersion = baseVersion;
399 }
400 }
401
402 public int compareTo( Artifact a )
403 {
404 int result = groupId.compareTo( a.getGroupId() );
405 if ( result == 0 )
406 {
407 result = artifactId.compareTo( a.getArtifactId() );
408 if ( result == 0 )
409 {
410 result = type.compareTo( a.getType() );
411 if ( result == 0 )
412 {
413 if ( classifier == null )
414 {
415 if ( a.getClassifier() != null )
416 {
417 result = 1;
418 }
419 }
420 else
421 {
422 if ( a.getClassifier() != null )
423 {
424 result = classifier.compareTo( a.getClassifier() );
425 }
426 else
427 {
428 result = -1;
429 }
430 }
431 if ( result == 0 )
432 {
433
434 result = new DefaultArtifactVersion( version ).compareTo(
435 new DefaultArtifactVersion( a.getVersion() ) );
436 }
437 }
438 }
439 }
440 return result;
441 }
442
443 public void updateVersion( String version, ArtifactRepository localRepository )
444 {
445 setResolvedVersion( version );
446 setFile( new File( localRepository.getBasedir(), localRepository.pathOf( this ) ) );
447 }
448
449 public String getDownloadUrl()
450 {
451 return downloadUrl;
452 }
453
454 public void setDownloadUrl( String downloadUrl )
455 {
456 this.downloadUrl = downloadUrl;
457 }
458
459 public ArtifactFilter getDependencyFilter()
460 {
461 return dependencyFilter;
462 }
463
464 public void setDependencyFilter( ArtifactFilter artifactFilter )
465 {
466 dependencyFilter = artifactFilter;
467 }
468
469 public ArtifactHandler getArtifactHandler()
470 {
471 return artifactHandler;
472 }
473
474 public List<String> getDependencyTrail()
475 {
476 return dependencyTrail;
477 }
478
479 public void setDependencyTrail( List<String> dependencyTrail )
480 {
481 this.dependencyTrail = dependencyTrail;
482 }
483
484 public void setScope( String scope )
485 {
486 this.scope = scope;
487 }
488
489 public VersionRange getVersionRange()
490 {
491 return versionRange;
492 }
493
494 public void setVersionRange( VersionRange versionRange )
495 {
496 this.versionRange = versionRange;
497 selectVersionFromNewRangeIfAvailable();
498 }
499
500 private void selectVersionFromNewRangeIfAvailable()
501 {
502 if ( ( versionRange != null ) && ( versionRange.getRecommendedVersion() != null ) )
503 {
504 selectVersion( versionRange.getRecommendedVersion().toString() );
505 }
506 else
507 {
508 version = null;
509 baseVersion = null;
510 }
511 }
512
513 public void selectVersion( String version )
514 {
515 this.version = version;
516 setBaseVersionInternal( version );
517 }
518
519 public void setGroupId( String groupId )
520 {
521 this.groupId = groupId;
522 }
523
524 public void setArtifactId( String artifactId )
525 {
526 this.artifactId = artifactId;
527 }
528
529 public boolean isSnapshot()
530 {
531 return getBaseVersion() != null
532 && ( getBaseVersion().endsWith( SNAPSHOT_VERSION ) || getBaseVersion().equals( LATEST_VERSION ) );
533 }
534
535 public void setResolved( boolean resolved )
536 {
537 this.resolved = resolved;
538 }
539
540 public boolean isResolved()
541 {
542 return resolved;
543 }
544
545 public void setResolvedVersion( String version )
546 {
547 this.version = version;
548
549 }
550
551 public void setArtifactHandler( ArtifactHandler artifactHandler )
552 {
553 this.artifactHandler = artifactHandler;
554 }
555
556 public void setRelease( boolean release )
557 {
558 this.release = release;
559 }
560
561 public boolean isRelease()
562 {
563 return release;
564 }
565
566 public List<ArtifactVersion> getAvailableVersions()
567 {
568 return availableVersions;
569 }
570
571 public void setAvailableVersions( List<ArtifactVersion> availableVersions )
572 {
573 this.availableVersions = availableVersions;
574 }
575
576 public boolean isOptional()
577 {
578 return optional;
579 }
580
581 public ArtifactVersion getSelectedVersion()
582 throws OverConstrainedVersionException
583 {
584 return versionRange.getSelectedVersion( this );
585 }
586
587 public boolean isSelectedVersionKnown()
588 throws OverConstrainedVersionException
589 {
590 return versionRange.isSelectedVersionKnown( this );
591 }
592
593 public void setOptional( boolean optional )
594 {
595 this.optional = optional;
596 }
597
598 }