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
353         {
354             return a.getClassifier() == null ? classifier == null : a.getClassifier().equals( classifier );
355         }
356 
357         // We don't consider the version range in the comparison, just the resolved version
358     }
359 
360     public String getBaseVersion()
361     {
362         if ( baseVersion == null && version != null )
363         {
364             setBaseVersionInternal( version );
365         }
366 
367         return baseVersion;
368     }
369 
370     protected String getBaseVersionInternal()
371     {
372         if ( ( baseVersion == null ) && ( version != null ) )
373         {
374             setBaseVersionInternal( version );
375         }
376 
377         return baseVersion;
378     }
379 
380     public void setBaseVersion( String baseVersion )
381     {
382         setBaseVersionInternal( baseVersion );
383     }
384 
385     protected void setBaseVersionInternal( String baseVersion )
386     {
387         this.baseVersion = ArtifactUtils.toSnapshotVersion( baseVersion );
388     }
389 
390     public int compareTo( Artifact a )
391     {
392         int result = groupId.compareTo( a.getGroupId() );
393         if ( result == 0 )
394         {
395             result = artifactId.compareTo( a.getArtifactId() );
396             if ( result == 0 )
397             {
398                 result = type.compareTo( a.getType() );
399                 if ( result == 0 )
400                 {
401                     if ( classifier == null )
402                     {
403                         if ( a.getClassifier() != null )
404                         {
405                             result = 1;
406                         }
407                     }
408                     else
409                     {
410                         if ( a.getClassifier() != null )
411                         {
412                             result = classifier.compareTo( a.getClassifier() );
413                         }
414                         else
415                         {
416                             result = -1;
417                         }
418                     }
419                     if ( result == 0 )
420                     {
421                         // We don't consider the version range in the comparison, just the resolved version
422                         result = new DefaultArtifactVersion( version ).compareTo(
423                             new DefaultArtifactVersion( a.getVersion() ) );
424                     }
425                 }
426             }
427         }
428         return result;
429     }
430 
431     public void updateVersion( String version, ArtifactRepository localRepository )
432     {
433         setResolvedVersion( version );
434         setFile( new File( localRepository.getBasedir(), localRepository.pathOf( this ) ) );
435     }
436 
437     public String getDownloadUrl()
438     {
439         return downloadUrl;
440     }
441 
442     public void setDownloadUrl( String downloadUrl )
443     {
444         this.downloadUrl = downloadUrl;
445     }
446 
447     public ArtifactFilter getDependencyFilter()
448     {
449         return dependencyFilter;
450     }
451 
452     public void setDependencyFilter( ArtifactFilter artifactFilter )
453     {
454         dependencyFilter = artifactFilter;
455     }
456 
457     public ArtifactHandler getArtifactHandler()
458     {
459         return artifactHandler;
460     }
461 
462     public List<String> getDependencyTrail()
463     {
464         return dependencyTrail;
465     }
466 
467     public void setDependencyTrail( List<String> dependencyTrail )
468     {
469         this.dependencyTrail = dependencyTrail;
470     }
471 
472     public void setScope( String scope )
473     {
474         this.scope = scope;
475     }
476 
477     public VersionRange getVersionRange()
478     {
479         return versionRange;
480     }
481 
482     public void setVersionRange( VersionRange versionRange )
483     {
484         this.versionRange = versionRange;
485         selectVersionFromNewRangeIfAvailable();
486     }
487 
488     private void selectVersionFromNewRangeIfAvailable()
489     {
490         if ( ( versionRange != null ) && ( versionRange.getRecommendedVersion() != null ) )
491         {
492             selectVersion( versionRange.getRecommendedVersion().toString() );
493         }
494         else
495         {
496             version = null;
497             baseVersion = null;
498         }
499     }
500 
501     public void selectVersion( String version )
502     {
503         this.version = version;
504         setBaseVersionInternal( version );
505     }
506 
507     public void setGroupId( String groupId )
508     {
509         this.groupId = groupId;
510     }
511 
512     public void setArtifactId( String artifactId )
513     {
514         this.artifactId = artifactId;
515     }
516 
517     public boolean isSnapshot()
518     {
519         return getBaseVersion() != null
520             && ( getBaseVersion().endsWith( SNAPSHOT_VERSION ) || getBaseVersion().equals( LATEST_VERSION ) );
521     }
522 
523     public void setResolved( boolean resolved )
524     {
525         this.resolved = resolved;
526     }
527 
528     public boolean isResolved()
529     {
530         return resolved;
531     }
532 
533     public void setResolvedVersion( String version )
534     {
535         this.version = version;
536         // retain baseVersion
537     }
538 
539     public void setArtifactHandler( ArtifactHandler artifactHandler )
540     {
541         this.artifactHandler = artifactHandler;
542     }
543 
544     public void setRelease( boolean release )
545     {
546         this.release = release;
547     }
548 
549     public boolean isRelease()
550     {
551         return release;
552     }
553 
554     public List<ArtifactVersion> getAvailableVersions()
555     {
556         return availableVersions;
557     }
558 
559     public void setAvailableVersions( List<ArtifactVersion> availableVersions )
560     {
561         this.availableVersions = availableVersions;
562     }
563 
564     public boolean isOptional()
565     {
566         return optional;
567     }
568 
569     public ArtifactVersion getSelectedVersion()
570         throws OverConstrainedVersionException
571     {
572         return versionRange.getSelectedVersion( this );
573     }
574 
575     public boolean isSelectedVersionKnown()
576         throws OverConstrainedVersionException
577     {
578         return versionRange.isSelectedVersionKnown( this );
579     }
580 
581     public void setOptional( boolean optional )
582     {
583         this.optional = optional;
584     }
585 
586 }