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 org.apache.maven.artifact.handler.ArtifactHandler;
23 import org.apache.maven.artifact.metadata.ArtifactMetadata;
24 import org.apache.maven.artifact.repository.ArtifactRepository;
25 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
26 import org.apache.maven.artifact.versioning.ArtifactVersion;
27 import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
28 import org.apache.maven.artifact.versioning.VersionRange;
29 import org.codehaus.plexus.util.StringUtils;
30
31 import java.io.File;
32 import java.util.Collection;
33 import java.util.Collections;
34 import java.util.HashMap;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.regex.Matcher;
39
40
41
42
43
44
45 public class DefaultArtifact
46 implements Artifact
47 {
48 private String groupId;
49
50 private String artifactId;
51
52
53
54
55
56
57 private String baseVersion;
58
59 private final String type;
60
61 private final String classifier;
62
63 private String scope;
64
65 private File file;
66
67 private ArtifactRepository repository;
68
69 private String downloadUrl;
70
71 private ArtifactFilter dependencyFilter;
72
73 private ArtifactHandler artifactHandler;
74
75 private List dependencyTrail;
76
77 private String version;
78
79 private VersionRange versionRange;
80
81 private boolean resolved;
82
83 private boolean release;
84
85 private List availableVersions;
86
87 private Map metadataMap;
88
89 private boolean optional;
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 StringBuffer sb = new StringBuffer();
232 sb.append( getGroupId() );
233 sb.append( ":" );
234 appendArtifactTypeClassifierString( sb );
235 return sb.toString();
236 }
237
238 private void appendArtifactTypeClassifierString( StringBuffer 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 = (ArtifactMetadata) 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 ArtifactMetadata getMetadata( Class metadataClass )
269 {
270 Collection metadata = getMetadataList();
271
272 if ( metadata != null )
273 {
274 for ( Iterator it = metadata.iterator(); it.hasNext(); )
275 {
276 ArtifactMetadata m = (ArtifactMetadata) it.next();
277 if ( metadataClass.isAssignableFrom( m.getClass() ) )
278 {
279 return m;
280 }
281 }
282 }
283
284 return null;
285 }
286
287 public Collection getMetadataList()
288 {
289 return metadataMap == null ? Collections.EMPTY_LIST : metadataMap.values();
290 }
291
292
293
294
295
296 public String toString()
297 {
298 StringBuffer sb = new StringBuffer();
299 if ( getGroupId() != null )
300 {
301 sb.append( getGroupId() );
302 sb.append( ":" );
303 }
304 appendArtifactTypeClassifierString( sb );
305 sb.append( ":" );
306 if ( getBaseVersionInternal() != null )
307 {
308 sb.append( getBaseVersionInternal() );
309 }
310 else
311 {
312 sb.append( versionRange.toString() );
313 }
314 if ( scope != null )
315 {
316 sb.append( ":" );
317 sb.append( scope );
318 }
319 return sb.toString();
320 }
321
322 public int hashCode()
323 {
324 int result = 17;
325 result = 37 * result + groupId.hashCode();
326 result = 37 * result + artifactId.hashCode();
327 result = 37 * result + type.hashCode();
328 if ( version != null )
329 {
330 result = 37 * result + version.hashCode();
331 }
332 result = 37 * result + ( classifier != null ? classifier.hashCode() : 0 );
333 return result;
334 }
335
336 public boolean equals( Object o )
337 {
338 if ( o == this )
339 {
340 return true;
341 }
342
343 if ( !( o instanceof Artifact ) )
344 {
345 return false;
346 }
347
348 Artifact a = (Artifact) o;
349
350 if ( !a.getGroupId().equals( groupId ) )
351 {
352 return false;
353 }
354 else if ( !a.getArtifactId().equals( artifactId ) )
355 {
356 return false;
357 }
358 else if ( !a.getVersion().equals( version ) )
359 {
360 return false;
361 }
362 else if ( !a.getType().equals( type ) )
363 {
364 return false;
365 }
366 else if ( a.getClassifier() == null ? classifier != null : !a.getClassifier().equals( classifier ) )
367 {
368 return false;
369 }
370
371
372
373 return true;
374 }
375
376 public String getBaseVersion()
377 {
378 if ( baseVersion == null )
379 {
380 if ( version == null )
381 {
382 throw new NullPointerException( "version was null for " + groupId + ":" + artifactId );
383 }
384 setBaseVersionInternal( version );
385 }
386 return baseVersion;
387 }
388
389 protected String getBaseVersionInternal()
390 {
391 if ( ( baseVersion == null ) && ( version != null ) )
392 {
393 setBaseVersionInternal( version );
394 }
395
396 return baseVersion;
397 }
398
399 public void setBaseVersion( String baseVersion )
400 {
401 setBaseVersionInternal( baseVersion );
402 }
403
404 protected void setBaseVersionInternal( String baseVersion )
405 {
406 Matcher m = VERSION_FILE_PATTERN.matcher( baseVersion );
407 if ( m.matches() )
408 {
409 this.baseVersion = m.group( 1 ) + "-" + SNAPSHOT_VERSION;
410 }
411 else
412 {
413 this.baseVersion = baseVersion;
414 }
415 }
416
417 public int compareTo( Object o )
418 {
419 Artifact a = (Artifact) o;
420
421 int result = groupId.compareTo( a.getGroupId() );
422 if ( result == 0 )
423 {
424 result = artifactId.compareTo( a.getArtifactId() );
425 if ( result == 0 )
426 {
427 result = type.compareTo( a.getType() );
428 if ( result == 0 )
429 {
430 if ( classifier == null )
431 {
432 if ( a.getClassifier() != null )
433 {
434 result = 1;
435 }
436 }
437 else
438 {
439 if ( a.getClassifier() != null )
440 {
441 result = classifier.compareTo( a.getClassifier() );
442 }
443 else
444 {
445 result = -1;
446 }
447 }
448 if ( result == 0 )
449 {
450
451 result = version.compareTo( a.getVersion() );
452 }
453 }
454 }
455 }
456 return result;
457 }
458
459 public void updateVersion( String version, ArtifactRepository localRepository )
460 {
461 setResolvedVersion( version );
462 setFile( new File( localRepository.getBasedir(), localRepository.pathOf( this ) ) );
463 }
464
465 public String getDownloadUrl()
466 {
467 return downloadUrl;
468 }
469
470 public void setDownloadUrl( String downloadUrl )
471 {
472 this.downloadUrl = downloadUrl;
473 }
474
475 public ArtifactFilter getDependencyFilter()
476 {
477 return dependencyFilter;
478 }
479
480 public void setDependencyFilter( ArtifactFilter artifactFilter )
481 {
482 dependencyFilter = artifactFilter;
483 }
484
485 public ArtifactHandler getArtifactHandler()
486 {
487 return artifactHandler;
488 }
489
490 public List getDependencyTrail()
491 {
492 return dependencyTrail;
493 }
494
495 public void setDependencyTrail( List dependencyTrail )
496 {
497 this.dependencyTrail = dependencyTrail;
498 }
499
500 public void setScope( String scope )
501 {
502 this.scope = scope;
503 }
504
505 public VersionRange getVersionRange()
506 {
507
508
509
510 if ( versionRange == null )
511 {
512 versionRange = VersionRange.createFromVersion( version );
513 }
514
515 return versionRange;
516 }
517
518 public void setVersionRange( VersionRange versionRange )
519 {
520 this.versionRange = versionRange;
521
522 selectVersionFromNewRangeIfAvailable();
523 }
524
525 private void selectVersionFromNewRangeIfAvailable()
526 {
527 if ( ( versionRange != null ) && ( versionRange.getRecommendedVersion() != null ) )
528 {
529 selectVersion( versionRange.getRecommendedVersion().toString() );
530 }
531 else
532 {
533 version = null;
534 baseVersion = null;
535 }
536 }
537
538 public void selectVersion( String version )
539 {
540 this.version = version;
541 setBaseVersionInternal( version );
542 }
543
544 public void setGroupId( String groupId )
545 {
546 this.groupId = groupId;
547 }
548
549 public void setArtifactId( String artifactId )
550 {
551 this.artifactId = artifactId;
552 }
553
554 public boolean isSnapshot()
555 {
556 if ( getBaseVersion() != null )
557 {
558 return getBaseVersion().endsWith( SNAPSHOT_VERSION ) || getBaseVersion().equals( LATEST_VERSION );
559 }
560 else
561 {
562 return false;
563 }
564 }
565
566 public void setResolved( boolean resolved )
567 {
568 this.resolved = resolved;
569 }
570
571 public boolean isResolved()
572 {
573 return resolved;
574 }
575
576 public void setResolvedVersion( String version )
577 {
578 this.version = version;
579
580 }
581
582 public void setArtifactHandler( ArtifactHandler artifactHandler )
583 {
584 this.artifactHandler = artifactHandler;
585 }
586
587 public void setRelease( boolean release )
588 {
589 this.release = release;
590 }
591
592 public boolean isRelease()
593 {
594 return release;
595 }
596
597 public List getAvailableVersions()
598 {
599 return availableVersions;
600 }
601
602 public void setAvailableVersions( List availableVersions )
603 {
604 this.availableVersions = availableVersions;
605 }
606
607 public boolean isOptional()
608 {
609 return optional;
610 }
611
612 public ArtifactVersion getSelectedVersion()
613 throws OverConstrainedVersionException
614 {
615 return versionRange.getSelectedVersion( this );
616 }
617
618 public boolean isSelectedVersionKnown()
619 throws OverConstrainedVersionException
620 {
621 return versionRange.isSelectedVersionKnown( this );
622 }
623
624 public void setOptional( boolean optional )
625 {
626 this.optional = optional;
627 }
628 }