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