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