View Javadoc
1   package org.apache.maven.artifact;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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  
29  import org.apache.maven.artifact.handler.ArtifactHandler;
30  import org.apache.maven.artifact.metadata.ArtifactMetadata;
31  import org.apache.maven.artifact.repository.ArtifactRepository;
32  import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
33  import org.apache.maven.artifact.versioning.ArtifactVersion;
34  import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
35  import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
36  import org.apache.maven.artifact.versioning.VersionRange;
37  import org.codehaus.plexus.util.StringUtils;
38  
39  /**
40   * @author Jason van Zyl
41   */
42  public class DefaultArtifact
43      implements Artifact
44  {
45      private String groupId;
46  
47      private String artifactId;
48  
49      private String baseVersion;
50  
51      private final String type;
52  
53      private final String classifier;
54  
55      private volatile String scope;
56  
57      private volatile File file;
58  
59      private ArtifactRepository repository;
60  
61      private String downloadUrl;
62  
63      private ArtifactFilter dependencyFilter;
64  
65      private ArtifactHandler artifactHandler;
66  
67      private List<String> dependencyTrail;
68  
69      private volatile String version;
70  
71      private VersionRange versionRange;
72  
73      private volatile boolean resolved;
74  
75      private boolean release;
76  
77      private List<ArtifactVersion> availableVersions;
78  
79      private Map<Object, ArtifactMetadata> metadataMap;
80  
81      private boolean optional;
82  
83      public DefaultArtifact( String groupId, String artifactId, String version, String scope, String type,
84                              String classifier, ArtifactHandler artifactHandler )
85      {
86          this( groupId, artifactId, VersionRange.createFromVersion( version ), scope, type, classifier, artifactHandler,
87                false );
88      }
89  
90      public DefaultArtifact( String groupId, String artifactId, VersionRange versionRange, String scope, String type,
91                              String classifier, ArtifactHandler artifactHandler )
92      {
93          this( groupId, artifactId, versionRange, scope, type, classifier, artifactHandler, false );
94      }
95  
96      @SuppressWarnings( "checkstyle:parameternumber" )
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 Collections.unmodifiableCollection( metadataMap.values() );
276     }
277 
278     // ----------------------------------------------------------------------
279     // Object overrides
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         // We don't consider the version range in the comparison, just the resolved version
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         this.baseVersion = ArtifactUtils.toSnapshotVersion( baseVersion );
390     }
391 
392     public int compareTo( Artifact a )
393     {
394         int result = groupId.compareTo( a.getGroupId() );
395         if ( result == 0 )
396         {
397             result = artifactId.compareTo( a.getArtifactId() );
398             if ( result == 0 )
399             {
400                 result = type.compareTo( a.getType() );
401                 if ( result == 0 )
402                 {
403                     if ( classifier == null )
404                     {
405                         if ( a.getClassifier() != null )
406                         {
407                             result = 1;
408                         }
409                     }
410                     else
411                     {
412                         if ( a.getClassifier() != null )
413                         {
414                             result = classifier.compareTo( a.getClassifier() );
415                         }
416                         else
417                         {
418                             result = -1;
419                         }
420                     }
421                     if ( result == 0 )
422                     {
423                         // We don't consider the version range in the comparison, just the resolved version
424                         result = new DefaultArtifactVersion( version ).compareTo(
425                             new DefaultArtifactVersion( a.getVersion() ) );
426                     }
427                 }
428             }
429         }
430         return result;
431     }
432 
433     public void updateVersion( String version, ArtifactRepository localRepository )
434     {
435         setResolvedVersion( version );
436         setFile( new File( localRepository.getBasedir(), localRepository.pathOf( this ) ) );
437     }
438 
439     public String getDownloadUrl()
440     {
441         return downloadUrl;
442     }
443 
444     public void setDownloadUrl( String downloadUrl )
445     {
446         this.downloadUrl = downloadUrl;
447     }
448 
449     public ArtifactFilter getDependencyFilter()
450     {
451         return dependencyFilter;
452     }
453 
454     public void setDependencyFilter( ArtifactFilter artifactFilter )
455     {
456         dependencyFilter = artifactFilter;
457     }
458 
459     public ArtifactHandler getArtifactHandler()
460     {
461         return artifactHandler;
462     }
463 
464     public List<String> getDependencyTrail()
465     {
466         return dependencyTrail;
467     }
468 
469     public void setDependencyTrail( List<String> dependencyTrail )
470     {
471         this.dependencyTrail = dependencyTrail;
472     }
473 
474     public void setScope( String scope )
475     {
476         this.scope = scope;
477     }
478 
479     public VersionRange getVersionRange()
480     {
481         return versionRange;
482     }
483 
484     public void setVersionRange( VersionRange versionRange )
485     {
486         this.versionRange = versionRange;
487         selectVersionFromNewRangeIfAvailable();
488     }
489 
490     private void selectVersionFromNewRangeIfAvailable()
491     {
492         if ( ( versionRange != null ) && ( versionRange.getRecommendedVersion() != null ) )
493         {
494             selectVersion( versionRange.getRecommendedVersion().toString() );
495         }
496         else
497         {
498             version = null;
499             baseVersion = null;
500         }
501     }
502 
503     public void selectVersion( String version )
504     {
505         this.version = version;
506         setBaseVersionInternal( version );
507     }
508 
509     public void setGroupId( String groupId )
510     {
511         this.groupId = groupId;
512     }
513 
514     public void setArtifactId( String artifactId )
515     {
516         this.artifactId = artifactId;
517     }
518 
519     public boolean isSnapshot()
520     {
521         return getBaseVersion() != null
522             && ( getBaseVersion().endsWith( SNAPSHOT_VERSION ) || getBaseVersion().equals( LATEST_VERSION ) );
523     }
524 
525     public void setResolved( boolean resolved )
526     {
527         this.resolved = resolved;
528     }
529 
530     public boolean isResolved()
531     {
532         return resolved;
533     }
534 
535     public void setResolvedVersion( String version )
536     {
537         this.version = version;
538         // retain baseVersion
539     }
540 
541     public void setArtifactHandler( ArtifactHandler artifactHandler )
542     {
543         this.artifactHandler = artifactHandler;
544     }
545 
546     public void setRelease( boolean release )
547     {
548         this.release = release;
549     }
550 
551     public boolean isRelease()
552     {
553         return release;
554     }
555 
556     public List<ArtifactVersion> getAvailableVersions()
557     {
558         return availableVersions;
559     }
560 
561     public void setAvailableVersions( List<ArtifactVersion> availableVersions )
562     {
563         this.availableVersions = availableVersions;
564     }
565 
566     public boolean isOptional()
567     {
568         return optional;
569     }
570 
571     public ArtifactVersion getSelectedVersion()
572         throws OverConstrainedVersionException
573     {
574         return versionRange.getSelectedVersion( this );
575     }
576 
577     public boolean isSelectedVersionKnown()
578         throws OverConstrainedVersionException
579     {
580         return versionRange.isSelectedVersionKnown( this );
581     }
582 
583     public void setOptional( boolean optional )
584     {
585         this.optional = optional;
586     }
587 
588 }