View Javadoc
1   package org.codehaus.plexus.languages.java.version;
2   
3   import java.util.Objects;
4   import java.util.regex.Matcher;
5   import java.util.regex.Pattern;
6   
7   /*
8    * Licensed to the Apache Software Foundation (ASF) under one
9    * or more contributor license agreements.  See the NOTICE file
10   * distributed with this work for additional information
11   * regarding copyright ownership.  The ASF licenses this file
12   * to you under the Apache License, Version 2.0 (the
13   * "License"); you may not use this file except in compliance
14   * with the License.  You may obtain a copy of the License at
15   *
16   *   http://www.apache.org/licenses/LICENSE-2.0
17   *
18   * Unless required by applicable law or agreed to in writing,
19   * software distributed under the License is distributed on an
20   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21   * KIND, either express or implied.  See the License for the
22   * specific language governing permissions and limitations
23   * under the License.
24   */
25  
26  /**
27   * @author Robert Scholte
28   * @since 1.0.0
29   * 
30   * @see <a href="http://www.oracle.com/technetwork/java/javase/namechange-140185.html">Java SE Naming and Versions</a>
31   * @see <a href="http://openjdk.java.net/jeps/223">JEP 223: New Version-String Scheme</a>
32   * @see <a href="http://openjdk.java.net/jeps/322">JEP 322: Time-Based Release Versioning</a>
33   */
34  public class JavaVersion implements Comparable<JavaVersion>
35  {
36      /**
37       * Represents the System property {@code java.specification.version}
38       */
39      public static final JavaVersion JAVA_SPECIFICATION_VERSION = parse( System.getProperty( "java.specification.version" ) );
40  
41      /**
42       * Represents the System property {@code java.version}
43       */
44      public static final JavaVersion JAVA_VERSION = parse( System.getProperty( "java.version" ) );
45      
46      private static final Pattern startingDigits = Pattern.compile( "(\\d+)(.*)" );
47      
48      private String rawVersion;
49  
50      private JavaVersion( String rawVersion )
51      {
52          this.rawVersion = rawVersion;
53      }
54  
55      /**
56       * Lazy parse the version-scheme.
57       * Actual parsing is done when calling {@link #compareTo(JavaVersion)}  
58       * 
59       * @param s the version string
60       * @return the version wrapped in a JavadocVersion
61       */
62      public static JavaVersion parse( String s ) 
63      {
64          return new JavaVersion( s );
65      }
66  
67      @Override
68      public int compareTo( JavaVersion other )
69      {
70          String[] thisSegments = this.rawVersion.split( "\\." );
71          String[] otherSegments = other.rawVersion.split( "\\." );
72          
73          int minSegments = Math.min( thisSegments.length, otherSegments.length );
74          
75          for ( int index = 0; index < minSegments; index++ )
76          {
77              Matcher thisMatcher = startingDigits.matcher( thisSegments[index] );
78              
79              int thisValue;
80              
81              if( thisMatcher.find() )
82              {
83                  thisValue = Integer.parseInt( thisMatcher.group( 1 ) );
84              }
85              else
86              {
87                  thisValue = -1;
88              }
89              
90              Matcher otherMatcher = startingDigits.matcher( otherSegments[index] );
91              
92              int otherValue;
93              
94              if( otherMatcher.find() )
95              {
96                  otherValue = Integer.parseInt( otherMatcher.group( 1 ) );
97              }
98              else
99              {
100                 otherValue = -1;
101             }
102             
103             int compareValue = Integer.compare( thisValue, otherValue );
104             
105             if ( compareValue != 0 )
106             {
107                 return compareValue;
108             }
109 
110             compareValue = suffixRate( thisMatcher.group( 2 ) ) - suffixRate( otherMatcher.group( 2 ) );
111             if ( compareValue != 0 )
112             {
113                 return compareValue;
114             }
115             
116             // works for now, but needs improvement
117             compareValue = thisMatcher.group( 2 ).compareTo( otherMatcher.group( 2 ) );
118             
119             if ( compareValue != 0 )
120             {
121                 return compareValue;
122             }
123         }
124         
125         return ( thisSegments.length - otherSegments.length );
126     }
127     
128     private int suffixRate( String suffix ) {
129         if ( "-ea".equals( suffix ) )
130         {
131             return -100;
132         }
133         else if ( "".equals( suffix ) )
134         {
135             return 0;
136         }
137         else 
138         {
139             return 10;
140         }
141     }
142 
143     /**
144      * Verify if this version is before some other version
145      * 
146      * @param other the version to compare with
147      * @return {@code true} is this is less than {@code other}, otherwise {@code false}
148      */
149     public boolean isBefore( JavaVersion other )
150     {
151         return this.compareTo( other ) < 0;
152     }
153 
154     /**
155      * Verify if this version is before some other version
156      * 
157      * @param other the version to compare with
158      * @return {@code true}  is this is less than {@code other}, otherwise {@code false}
159      */
160     public boolean isBefore( String other )
161     {
162         return this.compareTo( parse( other ) ) < 0;
163     }
164 
165     /**
166      * Verify if this version is at least some other version
167      * 
168      * @param other the version to compare with
169      * @return  {@code true}  is this is greater than or equal to {@code other}, otherwise {@code false}
170      */
171     public boolean isAtLeast( JavaVersion other )
172     {
173         return this.compareTo( other ) >= 0;
174     }
175 
176     /**
177      * Verify if this version is at least some other version
178      * 
179      * @param other the version to compare with
180      * @return  {@code true} is this is greater than or equal to {@code other}, otherwise {@code false}
181      */
182     public boolean isAtLeast( String other )
183     {
184         return this.compareTo( parse( other ) ) >= 0;
185     }
186 
187     @Override
188     public String toString()
189     {
190         return rawVersion;
191     }
192 
193     @Override
194     public int hashCode()
195     {
196         return Objects.hashCode( rawVersion );
197     }
198 
199     @Override
200     public boolean equals( Object obj )
201     {
202         if ( this == obj )
203         {
204             return true;
205         }
206         if ( obj == null )
207         {
208             return false;
209         }
210         if ( getClass() != obj.getClass() )
211         {
212             return false;
213         }
214         
215         JavaVersion other = (JavaVersion) obj;
216         if ( !Objects.equals( rawVersion, other.rawVersion ) )
217         {
218                 return false;
219         }
220         return true;
221     }
222 }