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.Iterator;
36  import java.util.List;
37  import java.util.Map;
38  import java.util.regex.Matcher;
39  
40  /**
41   * @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
42   * @version $Id: DefaultArtifact.java 745955 2009-02-19 18:39:09Z jdcasey $
43   * @todo this should possibly be replaced by type handler
44   */
45  public class DefaultArtifact
46      implements Artifact
47  {
48      private String groupId;
49  
50      private String artifactId;
51  
52      /**
53       * The resolved version for the artifact after conflict resolution, that has not been transformed.
54       *
55       * @todo should be final
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     // Object overrides
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         // We don't consider the version range in the comparison, just the resolved version
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                         // We don't consider the version range in the comparison, just the resolved version
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         // I am assuming this is happening as a result of the MNG-1577 work, but somehow the value
508         // of versionRange just goes null or is not set. But this is happeningin Yoko and the value is
509         // set when attaching the JAR and not set when attaching the test JAR.
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         // retain baseVersion
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 }