View Javadoc

1   package com.atlassian.plugins.rest.common.version;
2   
3   import com.google.common.base.Function;
4   import org.apache.commons.lang.StringUtils;
5   import org.apache.commons.lang.builder.EqualsBuilder;
6   import org.apache.commons.lang.builder.HashCodeBuilder;
7   
8   import javax.annotation.Nullable;
9   import java.util.regex.Matcher;
10  import java.util.regex.Pattern;
11  
12  /**
13   * This class supersedes {@link com.atlassian.plugins.rest.module.ApiVersion}.
14   * New functionality should be added here
15   */
16  public class ApiVersion implements Comparable {
17      public static final String NONE_STRING = "none";
18      public static final ApiVersion NONE = new ApiVersion(NONE_STRING);
19  
20      private static final String DOT = ".";
21  
22      private static final Pattern VERSION_PATTERN = Pattern.compile("(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?(?:\\.([\\w-]*))?");
23  
24      private final Integer major;
25  
26      private final Integer minor;
27  
28      private final Integer micro;
29  
30      private final String classifier;
31  
32      private static RuntimeException defaultVersionExceptionMapping(String version) {
33          if (version == null) {
34              throw new NullPointerException();
35          } else {
36              throw new IllegalArgumentException(version);
37          }
38      }
39  
40      public ApiVersion(String version) {
41          this(version, new Function<String, RuntimeException>() {
42              @Nullable
43              @Override
44              public RuntimeException apply(String input) {
45                  return defaultVersionExceptionMapping(input);
46              }
47          });
48      }
49  
50      protected ApiVersion(String version, Function<String, RuntimeException> exceptionMapper) {
51          if (version == null) {
52              throw exceptionMapper.apply(version);
53          }
54  
55          // forcing clients to specify a "version=none" string in the URL prevents then from accidentally going versionless
56          if (NONE_STRING.equals(version)) {
57              major = minor = micro = null;
58              classifier = null;
59          } else {
60              final Matcher matcher = VERSION_PATTERN.matcher(version);
61              if (!matcher.matches()) {
62                  throw exceptionMapper.apply(version);
63              }
64  
65              major = Integer.valueOf(matcher.group(1));
66              minor = matcher.group(2) != null ? Integer.valueOf(matcher.group(2)) : null;
67              micro = matcher.group(3) != null ? Integer.valueOf(matcher.group(3)) : null;
68              classifier = matcher.group(4);
69          }
70      }
71  
72      public boolean isNone() {
73          return this.equals(NONE);
74      }
75  
76      public static boolean isNone(String version) {
77          return NONE_STRING.equals(version);
78      }
79  
80      public Integer getMajor() {
81          return major;
82      }
83  
84      public Integer getMinor() {
85          return minor;
86      }
87  
88      public Integer getMicro() {
89          return micro;
90      }
91  
92      public String getClassifier() {
93          return classifier;
94      }
95  
96      @Override
97      public boolean equals(Object o) {
98          if (o == null) {
99              return false;
100         }
101         if (o == this) {
102             return true;
103         }
104         if (!(o instanceof ApiVersion)) {
105             return false;
106         }
107 
108         final ApiVersion version = (ApiVersion) o;
109         return new EqualsBuilder()
110                 .append(this.major, version.major)
111                 .append(this.minor, version.minor)
112                 .append(this.micro, version.micro)
113                 .append(this.classifier, version.classifier).isEquals();
114     }
115 
116     @Override
117     public int hashCode() {
118         return new HashCodeBuilder(3, 41).append(major).append(minor).append(micro).append(classifier).toHashCode();
119     }
120 
121     public int compareTo(Object o) {
122         if (o == null) {
123             return 1;
124         }
125         if (o == this) {
126             return 0;
127         }
128         if (!(o instanceof ApiVersion)) {
129             return 1;
130         }
131 
132         final ApiVersion that = (ApiVersion) o;
133 
134         final int majorDifference = compare(this.major, that.major);
135         if (majorDifference != 0) {
136             return majorDifference;
137         }
138         final int minorDifference = compare(this.minor, that.minor);
139         if (minorDifference != 0) {
140             return minorDifference;
141         }
142         final int microDifference = compare(this.micro, that.micro);
143         if (microDifference != 0) {
144             return microDifference;
145         }
146         return compare(this.classifier, that.classifier);
147     }
148 
149     private <T extends Comparable<T>> int compare(T n, T m) {
150         if (n == null && m == null) {
151             return 0;
152         }
153         if (n == null) {
154             return -1;
155         }
156         if (m == null) {
157             return +1;
158         }
159         return n.compareTo(m);
160     }
161 
162     @Override
163     public String toString() {
164         return isNone()
165                 ? NONE_STRING
166                 : major
167                 + (minor != null ? DOT + minor : "")
168                 + (micro != null ? DOT + micro : "")
169                 + (StringUtils.isNotBlank(classifier) ? DOT + classifier : "");
170     }
171 }