View Javadoc
1   package org.apache.maven.artifact.versioning;
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.util.StringTokenizer;
23  import java.util.regex.Pattern;
24  
25  /**
26   * Default implementation of artifact versioning.
27   *
28   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
29   */
30  public class DefaultArtifactVersion
31      implements ArtifactVersion
32  {
33      private Integer majorVersion;
34  
35      private Integer minorVersion;
36  
37      private Integer incrementalVersion;
38  
39      private Integer buildNumber;
40  
41      private String qualifier;
42  
43      private ComparableVersion comparable;
44  
45      public DefaultArtifactVersion( String version )
46      {
47          parseVersion( version );
48      }
49  
50      @Override
51      public int hashCode()
52      {
53          return 11 + comparable.hashCode();
54      }
55  
56      @Override
57      public boolean equals( Object other )
58      {
59          if ( this == other )
60          {
61              return true;
62          }
63  
64          if ( !( other instanceof ArtifactVersion ) )
65          {
66              return false;
67          }
68  
69          return compareTo( (ArtifactVersion) other ) == 0;
70      }
71  
72      public int compareTo( ArtifactVersion otherVersion )
73      {
74          if ( otherVersion instanceof DefaultArtifactVersion )
75          {
76              return this.comparable.compareTo( ( (DefaultArtifactVersion) otherVersion ).comparable );
77          }
78          else
79          {
80              return compareTo( new DefaultArtifactVersion( otherVersion.toString() ) );
81          }
82      }
83  
84      public int getMajorVersion()
85      {
86          return majorVersion != null ? majorVersion : 0;
87      }
88  
89      public int getMinorVersion()
90      {
91          return minorVersion != null ? minorVersion : 0;
92      }
93  
94      public int getIncrementalVersion()
95      {
96          return incrementalVersion != null ? incrementalVersion : 0;
97      }
98  
99      public int getBuildNumber()
100     {
101         return buildNumber != null ? buildNumber : 0;
102     }
103 
104     public String getQualifier()
105     {
106         return qualifier;
107     }
108 
109     public final void parseVersion( String version )
110     {
111         comparable = new ComparableVersion( version );
112 
113         int index = version.indexOf( "-" );
114 
115         String part1;
116         String part2 = null;
117 
118         if ( index < 0 )
119         {
120             part1 = version;
121         }
122         else
123         {
124             part1 = version.substring( 0, index );
125             part2 = version.substring( index + 1 );
126         }
127 
128         if ( part2 != null )
129         {
130             try
131             {
132                 if ( ( part2.length() == 1 ) || !part2.startsWith( "0" ) )
133                 {
134                     buildNumber = Integer.valueOf( part2 );
135                 }
136                 else
137                 {
138                     qualifier = part2;
139                 }
140             }
141             catch ( NumberFormatException e )
142             {
143                 qualifier = part2;
144             }
145         }
146 
147         if ( ( !part1.contains( "." ) ) && !part1.startsWith( "0" ) )
148         {
149             try
150             {
151                 majorVersion = Integer.valueOf( part1 );
152             }
153             catch ( NumberFormatException e )
154             {
155                 // qualifier is the whole version, including "-"
156                 qualifier = version;
157                 buildNumber = null;
158             }
159         }
160         else
161         {
162             boolean fallback = false;
163 
164             StringTokenizer tok = new StringTokenizer( part1, "." );
165             try
166             {
167                 majorVersion = getNextIntegerToken( tok );
168                 if ( tok.hasMoreTokens() )
169                 {
170                     minorVersion = getNextIntegerToken( tok );
171                 }
172                 if ( tok.hasMoreTokens() )
173                 {
174                     incrementalVersion = getNextIntegerToken( tok );
175                 }
176                 if ( tok.hasMoreTokens() )
177                 {
178                     qualifier = tok.nextToken();
179                     fallback = Pattern.compile( "\\d+" ).matcher( qualifier ).matches();
180                 }
181 
182                 // string tokenzier won't detect these and ignores them
183                 if ( part1.contains( ".." ) || part1.startsWith( "." ) || part1.endsWith( "." ) )
184                 {
185                     fallback = true;
186                 }
187             }
188             catch ( NumberFormatException e )
189             {
190                 fallback = true;
191             }
192 
193             if ( fallback )
194             {
195                 // qualifier is the whole version, including "-"
196                 qualifier = version;
197                 majorVersion = null;
198                 minorVersion = null;
199                 incrementalVersion = null;
200                 buildNumber = null;
201             }
202         }
203     }
204 
205     private static Integer getNextIntegerToken( StringTokenizer tok )
206     {
207         String s = tok.nextToken();
208         if ( ( s.length() > 1 ) && s.startsWith( "0" ) )
209         {
210             throw new NumberFormatException( "Number part has a leading 0: '" + s + "'" );
211         }
212         return Integer.valueOf( s );
213     }
214 
215     @Override
216     public String toString()
217     {
218         return comparable.toString();
219     }
220 }