| /* |
| * Copyright 2017 HugeGraph Authors |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with this |
| * work for additional information regarding copyright ownership. The ASF |
| * licenses this file to You under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package com.baidu.hugegraph.util; |
| |
| import java.io.BufferedReader; |
| import java.io.IOException; |
| import java.io.InputStreamReader; |
| import java.net.URL; |
| import java.util.jar.Attributes; |
| import java.util.jar.Manifest; |
| |
| public final class VersionUtil { |
| |
| /** |
| * Compare if a version is inside a range [begin, end) |
| * @param version The version to be compared |
| * @param begin The lower bound of the range |
| * @param end The upper bound of the range |
| * @return true if belong to the range, otherwise false |
| */ |
| public static boolean match(Version version, String begin, String end) { |
| E.checkArgumentNotNull(version, "The version to match is null"); |
| return version.compareTo(new Version(begin)) >= 0 && |
| version.compareTo(new Version(end)) < 0; |
| } |
| |
| /** |
| * Compare if a version is greater than the other one (inclusive) |
| * @param version The version to be compared |
| * @param other The lower bound of the range |
| * @return true if it's greater than the other, otherwise false |
| */ |
| public static boolean gte(String version, String other) { |
| E.checkArgumentNotNull(version, "The version to match is null"); |
| return new Version(version).compareTo(new Version(other)) >= 0; |
| } |
| |
| /** |
| * Check whether a component version is matched expected range, |
| * throw an exception if it's not matched. |
| * @param version The version to be checked |
| * @param begin The lower bound of the range |
| * @param end The upper bound of the range |
| * @param component The owner component of version |
| */ |
| public static void check(Version version, String begin, String end, |
| String component) { |
| E.checkState(VersionUtil.match(version, begin, end), |
| "The version %s of '%s' is not in [%s, %s)", |
| version, component, begin, end); |
| } |
| |
| /** |
| * Get implementation version from manifest in jar |
| * @param clazz The class to be load from jar package |
| * @return The implementation version |
| */ |
| public static String getImplementationVersion(Class<?> clazz) { |
| /* |
| * We don't use Package.getImplementationVersion() due to |
| * a duplicate package would override the origin package info. |
| * https://stackoverflow.com/questions/1272648/reading-my-own-jars-manifest |
| */ |
| String className = clazz.getSimpleName() + ".class"; |
| String classPath = clazz.getResource(className).toString(); |
| if (!classPath.startsWith("jar:file:")) { |
| // Class not from JAR |
| return null; |
| } |
| int offset = classPath.lastIndexOf("!"); |
| assert offset > 0; |
| // Get manifest file path |
| String manifestPath = classPath.substring(0, offset + 1); |
| return getImplementationVersion(manifestPath); |
| } |
| |
| public static String getImplementationVersion(String manifestPath) { |
| manifestPath += "/META-INF/MANIFEST.MF"; |
| |
| Manifest manifest = null; |
| try { |
| manifest = new Manifest(new URL(manifestPath).openStream()); |
| } catch (IOException ignored) { |
| return null; |
| } |
| return manifest.getMainAttributes() |
| .getValue(Attributes.Name.IMPLEMENTATION_VERSION); |
| } |
| |
| /** |
| * Get version from pom.xml |
| * @return The pom version |
| */ |
| public static String getPomVersion() { |
| String cmd = "mvn help:evaluate -Dexpression=project.version " + |
| "-q -DforceStdout"; |
| Process process = null; |
| InputStreamReader isr = null; |
| try { |
| process = Runtime.getRuntime().exec(cmd); |
| process.waitFor(); |
| |
| isr = new InputStreamReader(process.getInputStream()); |
| BufferedReader br = new BufferedReader(isr); |
| return br.readLine(); |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } finally { |
| if (isr != null) { |
| try { |
| isr.close(); |
| } catch (Exception ignored) { |
| // pass |
| } |
| } |
| |
| // Destroy child process |
| if (process != null) { |
| process.destroy(); |
| } |
| } |
| } |
| |
| /** |
| * class Version for compare |
| * https://stackoverflow.com/questions/198431/how-do-you-compare-two-version-strings-in-java |
| */ |
| public static class Version implements Comparable<Version> { |
| |
| public static Version of(Class<?> clazz) { |
| return Version.of(clazz, null); |
| } |
| |
| public static Version of(Class<?> clazz, String defaultValue) { |
| String v = getImplementationVersion(clazz); |
| if (v == null) { |
| v = defaultValue; |
| } |
| return v == null ? null : new Version(v); |
| } |
| |
| public static Version of(String version) { |
| return new Version(version); |
| } |
| |
| /************************** Version define **************************/ |
| |
| private final String version; |
| private final int[] parts; |
| |
| public Version(String version) { |
| E.checkArgumentNotNull(version, "The version is null"); |
| E.checkArgument(version.matches("[0-9]+(\\.[0-9]+)*"), |
| "Invalid version format: %s", version); |
| this.version = version; |
| this.parts = parseVersion(version); |
| } |
| |
| private static int[] parseVersion(String version) { |
| String[] parts = version.split("\\."); |
| int[] partsNumber = new int[parts.length]; |
| for (int i = 0; i < parts.length; i++) { |
| partsNumber[i] = Integer.parseInt(parts[i]); |
| } |
| return partsNumber; |
| } |
| |
| public final String get() { |
| return this.version; |
| } |
| |
| @Override |
| public int compareTo(Version that) { |
| if (that == null) { |
| return 1; |
| } |
| int[] thisParts = this.parts; |
| int[] thatParts = that.parts; |
| int length = Math.max(thisParts.length, thatParts.length); |
| for (int i = 0; i < length; i++) { |
| int thisPart = i < thisParts.length ? thisParts[i] : 0; |
| int thatPart = i < thatParts.length ? thatParts[i] : 0; |
| if (thisPart < thatPart) { |
| return -1; |
| } |
| if (thisPart > thatPart) { |
| return 1; |
| } |
| } |
| return 0; |
| } |
| |
| @Override |
| public boolean equals(Object that) { |
| if (this == that) { |
| return true; |
| } |
| if (that == null) { |
| return false; |
| } |
| if (this.getClass() != that.getClass()) { |
| return false; |
| } |
| return this.compareTo((Version) that) == 0; |
| } |
| |
| @Override |
| public int hashCode() { |
| int hash = 0; |
| for (int i = this.parts.length - 1; i >= 0; i--) { |
| int part = this.parts[i]; |
| if (part == 0 && hash == 0) { |
| continue; |
| } |
| hash = 31 * hash + Integer.hashCode(part); |
| } |
| return hash; |
| } |
| |
| @Override |
| public String toString() { |
| return this.version; |
| } |
| } |
| } |