
org.semver.Version Maven / Gradle / Ivy
/**
* This software is licensed under the Apache 2 license, quoted below.
*
* Copyright 2010 Julien Eluard
*
* Licensed 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 org.semver;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
/**
*
* Version following semantic defined by Semantic Versioning document.
*
*/
@Immutable
public final class Version implements Comparable {
/**
* {@link Version} element. From most meaningful to less meaningful.
*/
public enum Element {
MAJOR, MINOR, PATCH, SPECIAL;
}
private static final String FORMAT = "(\\d)\\.(\\d)\\.(\\d)([A-Za-z][0-9A-Za-z-]*)?";
private static final Pattern PATTERN = Pattern.compile(Version.FORMAT);
private final int major;
private final int minor;
private final int patch;
private final String special;
public Version(@Nonnegative final int major, @Nonnegative final int minor, @Nonnegative final int patch) {
this(major, minor, patch, null);
}
public Version(@Nonnegative final int major, @Nonnegative final int minor, @Nonnegative final int patch, @Nullable final String special) {
if (major < 0) {
throw new IllegalArgumentException(Element.MAJOR+" must be positive");
}
if (minor < 0) {
throw new IllegalArgumentException(Element.MINOR+" must be positive");
}
if (patch < 0) {
throw new IllegalArgumentException(Element.PATCH+" must be positive");
}
this.major = major;
this.minor = minor;
this.patch = patch;
this.special = special;
}
/**
*
* Creates a Version from a string representation. Must match Version#FORMAT.
*
* @param version
* @return
*/
public static Version parse(@Nonnull final String version) {
final Matcher matcher = Version.PATTERN.matcher(version);
if (!matcher.matches()) {
throw new IllegalArgumentException("<"+version+"> does not match format "+Version.FORMAT);
}
final int major = Integer.valueOf(matcher.group(1));
final int minor = Integer.valueOf(matcher.group(2));
final int patch = Integer.valueOf(matcher.group(3));
return new Version(major, minor, patch, matcher.group(4));
}
/**
* @param type
* @return next {@link Version} regarding specified {@link Version.Element}
*/
public Version next(@Nonnull final Version.Element element) {
if (element == null) {
throw new IllegalArgumentException("null element");
}
switch (element) {
case MAJOR:
return new Version(this.major+1, 0, 0);
case MINOR:
return new Version(this.major, this.minor+1, 0);
case PATCH:
return new Version(this.major, this.minor, this.patch+1);
default:
throw new IllegalArgumentException("Unknown element <"+element+">");
}
}
public boolean isInDevelopment() {
return this.major == 0;
}
public boolean isStable() {
return !isInDevelopment();
}
@Override
public int hashCode() {
int hash = 5;
hash = 43 * hash + this.major;
hash = 43 * hash + this.minor;
hash = 43 * hash + this.patch;
hash = 43 * hash + (this.special != null ? this.special.hashCode() : 0);
return hash;
}
@Override
public boolean equals(@Nullable final Object object) {
if (!(object instanceof Version)) {
return false;
}
final Version other = (Version) object;
if (other.major != this.major || other.minor != this.minor || other.patch != this.patch) {
return false;
}
return (this.special == null) ? other.special == null : this.special.equals(other.special);
}
@Override
public int compareTo(final Version other) {
if (equals(other)) {
return 0;
}
if (other.major > this.major) {
return 1;
} else if (other.major == this.major) {
if (other.minor > this.minor) {
return 1;
} else if (other.minor == this.minor) {
if (other.patch > this.patch) {
return 1;
} else if (other.special != null) {
return other.special.compareTo(this.special);
}
}
}
return -1;
}
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append(this.major).append(".").append(this.minor).append(".").append(this.patch);
if (this.special != null) {
builder.append(this.special);
}
return builder.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy