• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
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 
17 package android.server.wm.jetpack.utils;
18 
19 import android.text.TextUtils;
20 
21 import androidx.annotation.NonNull;
22 import androidx.annotation.Nullable;
23 
24 import java.math.BigInteger;
25 import java.util.regex.Matcher;
26 import java.util.regex.Pattern;
27 
28 
29 /**
30  * Class encapsulating a version with major, minor, patch and description values. Copied from
31  * androidx.window.Version.
32  */
33 public final class Version implements Comparable<Version> {
34     public static final Version UNKNOWN = new Version(0, 0, 0, "");
35 
36     private static final String VERSION_PATTERN_STRING =
37             "(\\d+)(?:\\.(\\d+))(?:\\.(\\d+))(?:-(.+))?";
38 
39     private final int mMajor;
40     private final int mMinor;
41     private final int mPatch;
42     private final String mDescription;
43     // Cached BigInteger value of the version.
44     private BigInteger mBigInteger;
45 
Version(int major, int minor, int patch, String description)46     public Version(int major, int minor, int patch, String description) {
47         mMajor = major;
48         mMinor = minor;
49         mPatch = patch;
50         mDescription = description;
51     }
52 
53     /**
54      * Parses a string to a version object.
55      *
56      * @param versionString string in the format "1.2.3" or "1.2.3-Description"
57      *                      (major.minor.patch[-description])
58      * @return the parsed Version object or {@code null}> if the versionString format is invalid.
59      */
60     @Nullable
parse(String versionString)61     public static Version parse(String versionString) {
62         if (TextUtils.isEmpty(versionString)) {
63             return null;
64         }
65 
66         Matcher matcher = Pattern.compile(VERSION_PATTERN_STRING).matcher(versionString);
67         if (!matcher.matches()) {
68             return null;
69         }
70 
71         int major = Integer.parseInt(matcher.group(1));
72         int minor = Integer.parseInt(matcher.group(2));
73         int patch = Integer.parseInt(matcher.group(3));
74         String description = matcher.group(4) != null ? matcher.group(4) : "";
75         return new Version(major, minor, patch, description);
76     }
77 
78     /** Checks whether the version is in the correct format. */
isValidVersion(String versionString)79     public static boolean isValidVersion(String versionString) {
80         Matcher matcher = Pattern.compile(VERSION_PATTERN_STRING).matcher(versionString);
81         return matcher.matches();
82     }
83 
84     /** Major version of the vendor implementation. */
getMajor()85     public int getMajor() {
86         return mMajor;
87     }
88 
getMinor()89     int getMinor() {
90         return mMinor;
91     }
92 
getPatch()93     int getPatch() {
94         return mPatch;
95     }
96 
getDescription()97     String getDescription() {
98         return mDescription;
99     }
100 
101     @NonNull
102     @Override
toString()103     public String toString() {
104         final StringBuilder sb = new StringBuilder()
105                 .append(getMajor())
106                 .append(".")
107                 .append(getMinor())
108                 .append(".")
109                 .append(getPatch());
110         if (!TextUtils.isEmpty(getDescription())) {
111             sb.append("-").append(getDescription());
112         }
113         return sb.toString();
114     }
115 
116     /**
117      * To compare the major, minor and patch version with another.
118      *
119      * @param other The version to compare to this one.
120      * @return 0 if it have the same major minor and patch version; less than 0 if this version
121      * sorts ahead of <var>other</var>; greater than 0 if this version sorts after <var>other</var>.
122      */
123     @Override
compareTo(@onNull Version other)124     public int compareTo(@NonNull Version other) {
125         return toBigInteger().compareTo(other.toBigInteger());
126     }
127 
128     @NonNull
toBigInteger()129     private BigInteger toBigInteger() {
130         if (mBigInteger == null) {
131             mBigInteger = BigInteger.valueOf(mMajor)
132                     .shiftLeft(32)
133                     .or(BigInteger.valueOf(mMinor))
134                     .shiftLeft(32)
135                     .or(BigInteger.valueOf(mPatch));
136         }
137         return mBigInteger;
138     }
139 
140     @Override
equals(Object obj)141     public boolean equals(Object obj) {
142         if (!(obj instanceof Version)) {
143             return false;
144         }
145 
146         Version otherVersionObj = (Version) obj;
147 
148         // The equals checking ignores the description.
149         return mMajor == otherVersionObj.mMajor
150                 && mMinor == otherVersionObj.mMinor
151                 && mPatch == otherVersionObj.mPatch;
152     }
153 
154     @Override
hashCode()155     public int hashCode() {
156         // The hash code ignores the description.
157         int result = 17;
158         result = result * 31 + mMajor;
159         result = result * 31 + mMinor;
160         result = result * 31 + mPatch;
161         return result;
162     }
163 }
164