blob: 469022e05ab7060177953f0c73ade45b05c41509 [file] [log] [blame]
/*
* 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 org.apache.cassandra.distributed.shared;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Versions
{
private static final Logger logger = LoggerFactory.getLogger(Versions.class);
public static final String PROPERTY_PREFIX = "cassandra.";
public static URL[] getClassPath()
{
// In Java 9 the default system ClassLoader got changed from URLClassLoader to AppClassLoader which
// does not extend URLClassLoader nor does it give access to the class path array.
// Java requires the system property 'java.class.path' to be setup with the classpath seperated by :
// so this logic parses that string into the URL[] needed to build later
String cp = System.getProperty("java.class.path");
assert cp != null && !cp.isEmpty();
String[] split = cp.split(File.pathSeparator);
assert split.length > 0;
URL[] urls = new URL[split.length];
try
{
for (int i = 0; i < split.length; i++)
urls[i] = Paths.get(split[i]).toUri().toURL();
}
catch (MalformedURLException e)
{
throw new RuntimeException(e);
}
return urls;
}
public enum Major
{
v22("2\\.2\\.([0-9]+)"),
v30("3\\.0\\.([0-9]+)"),
v3X("3\\.([1-9]|1[01])(\\.([0-9]+))?"),
v4("4\\.([0-9]+)");
final Pattern pattern;
Major(String verify)
{
this.pattern = Pattern.compile(verify);
}
static Major fromFull(String version)
{
if (version.isEmpty())
throw new IllegalArgumentException(version);
switch (version.charAt(0))
{
case '2':
if (version.startsWith("2.2"))
return v22;
throw new IllegalArgumentException(version);
case '3':
if (version.startsWith("3.0"))
return v30;
return v3X;
case '4':
return v4;
default:
throw new IllegalArgumentException(version);
}
}
// verify that the version string is valid for this major version
boolean verify(String version)
{
return pattern.matcher(version).matches();
}
// sort two strings of the same major version as this enum instance
int compare(String a, String b)
{
Matcher ma = pattern.matcher(a);
Matcher mb = pattern.matcher(a);
if (!ma.matches()) throw new IllegalArgumentException(a);
if (!mb.matches()) throw new IllegalArgumentException(b);
int result = Integer.compare(Integer.parseInt(ma.group(1)), Integer.parseInt(mb.group(1)));
if (result == 0 && this == v3X && (ma.group(3) != null || mb.group(3) != null))
{
if (ma.group(3) != null && mb.group(3) != null)
{
result = Integer.compare(Integer.parseInt(ma.group(3)), Integer.parseInt(mb.group(3)));
}
else
{
result = ma.group(3) != null ? 1 : -1;
}
}
// sort descending
return -result;
}
}
public static class Version
{
public final Major major;
public final String version;
public final URL[] classpath;
public Version(String version, URL[] classpath)
{
this(Major.fromFull(version), version, classpath);
}
public Version(Major major, String version, URL[] classpath)
{
this.major = major;
this.version = version;
this.classpath = classpath;
}
}
private final Map<Major, List<Version>> versions;
public Versions(Map<Major, List<Version>> versions)
{
this.versions = versions;
}
public Version get(String full)
{
return versions.get(Major.fromFull(full))
.stream()
.filter(v -> full.equals(v.version))
.findFirst()
.orElseThrow(() -> new RuntimeException("No version " + full + " found"));
}
public Version getLatest(Major major)
{
return versions.get(major).stream().findFirst().orElseThrow(() -> new RuntimeException("No " + major + " versions found"));
}
public static Versions find()
{
final String dtestJarDirectory = System.getProperty(PROPERTY_PREFIX + "test.dtest_jar_path", "build");
final File sourceDirectory = new File(dtestJarDirectory);
logger.info("Looking for dtest jars in " + sourceDirectory.getAbsolutePath());
final Pattern pattern = Pattern.compile("dtest-(?<fullversion>(\\d+)\\.(\\d+)(\\.\\d+)?(\\.\\d+)?)([~\\-]\\w[.\\w]*(?:\\-\\w[.\\w]*)*)?(\\+[.\\w]+)?\\.jar");
final Map<Major, List<Version>> versions = new HashMap<>();
for (Major major : Major.values())
versions.put(major, new ArrayList<>());
for (File file : sourceDirectory.listFiles())
{
Matcher m = pattern.matcher(file.getName());
if (!m.matches())
continue;
String version = m.group(1);
Major major = Major.fromFull(version);
versions.get(major).add(new Version(major, version, new URL[]{ toURL(file) }));
}
for (Map.Entry<Major, List<Version>> e : versions.entrySet())
{
if (e.getValue().isEmpty())
continue;
Collections.sort(e.getValue(), Comparator.comparing(v -> v.version, e.getKey()::compare));
System.out.println("Found " + e.getValue().stream().map(v -> v.version).collect(Collectors.joining(", ")));
}
return new Versions(versions);
}
public static URL toURL(File file)
{
try
{
return file.toURI().toURL();
}
catch (MalformedURLException e)
{
throw new IllegalArgumentException(e);
}
}
}