nodejs: better sorting of node interpreters (first sort by version, then by path)
[idea/community.git] / platform / util / src / com / intellij / util / text / SemVer.java
1 /*
2  * Copyright 2000-2013 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.util.text;
17
18 import org.jetbrains.annotations.NotNull;
19 import org.jetbrains.annotations.Nullable;
20
21 import java.util.regex.Pattern;
22
23 /**
24  * See http://semver.org
25  */
26 public class SemVer implements Comparable<SemVer> {
27   private final int myMajor;
28   private final int myMinor;
29   private final int myPatch;
30   private final String myRawVersion;
31
32   public SemVer(@NotNull String rawVersion, int major, int minor, int patch) {
33     myRawVersion = rawVersion;
34     myMajor = major;
35     myMinor = minor;
36     myPatch = patch;
37   }
38
39   @NotNull
40   public String getRawVersion() {
41     return myRawVersion;
42   }
43
44   public int getMajor() {
45     return myMajor;
46   }
47
48   public int getMinor() {
49     return myMinor;
50   }
51
52   public int getPatch() {
53     return myPatch;
54   }
55
56   @NotNull
57   public String getParsedVersion() {
58     return myMajor + "." + myMinor + "." + myPatch;
59   }
60
61   @Override
62   public boolean equals(Object o) {
63     if (this == o) return true;
64     if (o == null || getClass() != o.getClass()) return false;
65
66     SemVer semVer = (SemVer)o;
67
68     if (myMajor != semVer.myMajor) return false;
69     if (myMinor != semVer.myMinor) return false;
70     if (myPatch != semVer.myPatch) return false;
71
72     return true;
73   }
74
75   @Override
76   public int hashCode() {
77     int result = myMajor;
78     result = 31 * result + myMinor;
79     result = 31 * result + myPatch;
80     return result;
81   }
82
83   @Override
84   public String toString() {
85     return myRawVersion;
86   }
87
88   @Nullable
89   public static SemVer parseFromText(@NotNull String text) {
90     String[] comps = text.split(Pattern.quote("."), 3);
91     if (comps.length != 3) {
92       return null;
93     }
94     Integer major = toInteger(comps[0]);
95     Integer minor = toInteger(comps[1]);
96     String patchStr = comps[2];
97     int dashInd = patchStr.indexOf('-');
98     if (dashInd >= 0) {
99       patchStr = patchStr.substring(0, dashInd);
100     }
101     Integer patch = toInteger(patchStr);
102     if (major != null && minor != null && patch != null) {
103       return new SemVer(text, major, minor, patch);
104     }
105     return null;
106   }
107
108   private static Integer toInteger(@NotNull String str) {
109     try {
110       return Integer.parseInt(str);
111     }
112     catch (NumberFormatException e) {
113       return null;
114     }
115   }
116
117
118   @Override
119   public int compareTo(SemVer other) {
120     // null is not permitted
121     if (getMajor() != other.getMajor()) {
122       return getMajor() - other.getMajor();
123     }
124     if (getMinor() != other.getMinor()) {
125       return getMinor() - other.getMinor();
126     }
127     if (getPatch() != other.getPatch()) {
128       return getPatch() - other.getPatch();
129     }
130     return 0;
131   }
132 }