/**
* Copyright 2010-2015 Axel Fontaine
* <p/>
* 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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.contrastsecurity.cassandra.migration.info;
import com.contrastsecurity.cassandra.migration.CassandraMigrationException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
public class MigrationVersion implements Comparable<MigrationVersion> {
public static final MigrationVersion EMPTY = new MigrationVersion(null, "<< Empty Schema >>");
public static final MigrationVersion LATEST = new MigrationVersion(BigInteger.valueOf(-1), "<< Latest Version >>");
public static final MigrationVersion CURRENT = new MigrationVersion(BigInteger.valueOf(-2), "<< Current Version >>");
private static final String TABLE = "cassandra_migration_version";
private List<BigInteger> versionParts;
private String displayText;
private static Pattern splitPattern = Pattern.compile("\\.(?=\\d)");
public MigrationVersion(BigInteger version, String displayText) {
List<BigInteger> tmp = new ArrayList<>();
tmp.add(version);
this.displayText = displayText;
init(tmp, displayText);
}
private MigrationVersion(String version) {
String normalizedVersion = version.replace('_', '.');
init(tokenize(normalizedVersion), normalizedVersion);
}
private void init(List<BigInteger> versionParts, String displayText) {
this.versionParts = versionParts;
this.displayText = displayText;
}
public static MigrationVersion fromVersion(String version) {
if ("current".equalsIgnoreCase(version)) return CURRENT;
if (LATEST.getVersion().equals(version)) return LATEST;
if (version == null) return EMPTY;
return new MigrationVersion(version);
}
public String getVersion() {
if (this.equals(EMPTY)) return null;
if (this.equals(LATEST)) return Long.toString(Long.MAX_VALUE);
return displayText;
}
/**
* @return The textual representation of the version.
*/
@Override
public String toString() {
return displayText;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MigrationVersion version1 = (MigrationVersion) o;
return compareTo(version1) == 0;
}
@Override
public int hashCode() {
return versionParts == null ? 0 : versionParts.hashCode();
}
@Override
public int compareTo(MigrationVersion o) {
if (o == null) {
return 1;
}
if (this == EMPTY) {
return o == EMPTY ? 0 : Integer.MIN_VALUE;
}
if (this == CURRENT) {
return o == CURRENT ? 0 : Integer.MIN_VALUE;
}
if (this == LATEST) {
return o == LATEST ? 0 : Integer.MAX_VALUE;
}
if (o == EMPTY) {
return Integer.MAX_VALUE;
}
if (o == CURRENT) {
return Integer.MAX_VALUE;
}
if (o == LATEST) {
return Integer.MIN_VALUE;
}
final List<BigInteger> elements1 = versionParts;
final List<BigInteger> elements2 = o.versionParts;
int largestNumberOfElements = Math.max(elements1.size(), elements2.size());
for (int i = 0; i < largestNumberOfElements; i++) {
final int compared = getOrZero(elements1, i).compareTo(getOrZero(elements2, i));
if (compared != 0) {
return compared;
}
}
return 0;
}
private BigInteger getOrZero(List<BigInteger> elements, int i) {
return i < elements.size() ? elements.get(i) : BigInteger.ZERO;
}
public String getTable() {
return TABLE;
}
private void setVersion(String version) {
String normalizedVersion = version.replace('_', '.');
this.versionParts = tokenize(normalizedVersion);
this.displayText = normalizedVersion;
}
private List<BigInteger> tokenize(String str) {
List<BigInteger> numbers = new ArrayList<>();
for (String number : splitPattern.split(str)) {
try {
numbers.add(new BigInteger(number));
} catch (NumberFormatException e) {
throw new CassandraMigrationException(
"Invalid version containing non-numeric characters. Only 0..9 and . are allowed. Invalid version: "
+ str);
}
}
for (int i = numbers.size() - 1; i > 0; i--) {
if (!numbers.get(i).equals(BigInteger.ZERO)) break;
numbers.remove(i);
}
return numbers;
}
}