blob: 81422b9620e234fb6d9db333f83b93bacdab6cd0 [file] [log] [blame]
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.jclouds;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.String.format;
import java.io.IOException;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.annotations.VisibleForTesting;
/**
* @author Andrew Phillips
*/
public class JcloudsVersion {
@VisibleForTesting
static final String VERSION_RESOURCE_FILE = "META-INF/maven/org.jclouds/jclouds-core/pom.properties";
private static final String VERSION_PROPERTY_NAME = "version";
// TODO: stop supporting x.y.z-rc-n after the 1.3.0 release
// x.y.z or x.y.z-rc.n or x.y.z-rc-n, optionally with -SNAPSHOT suffix - see http://semver.org
private static final Pattern SEMANTIC_VERSION_PATTERN =
Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)(?:-rc[-\\.](\\d+))?(?:-SNAPSHOT)?");
private static final JcloudsVersion INSTANCE = new JcloudsVersion();
public final int majorVersion;
public final int minorVersion;
public final int patchVersion;
public final boolean releaseCandidate;
private final String version;
/**
* Non-null iff {@link #releaseCandidate} is {@code true}
*/
public final @Nullable Integer releaseCandidateVersion;
public final boolean snapshot;
@VisibleForTesting
JcloudsVersion() {
this(JcloudsVersion.class.getClassLoader());
}
@VisibleForTesting
JcloudsVersion(ClassLoader resourceLoader) {
this(readVersionPropertyFromClasspath(resourceLoader));
}
private static String readVersionPropertyFromClasspath(ClassLoader resourceLoader) {
Properties versionProperties = new Properties();
try {
versionProperties.load(checkNotNull(resourceLoader.getResourceAsStream(VERSION_RESOURCE_FILE), VERSION_RESOURCE_FILE));
} catch (IOException exception) {
throw new IllegalStateException(format("Unable to load version resource file '%s'", VERSION_RESOURCE_FILE), exception);
}
return checkNotNull(versionProperties.getProperty(VERSION_PROPERTY_NAME), VERSION_PROPERTY_NAME);
}
@VisibleForTesting
JcloudsVersion(String version) {
Matcher versionMatcher = SEMANTIC_VERSION_PATTERN.matcher(version);
checkArgument(versionMatcher.matches(), "Version '%s' did not match expected pattern '%s'",
version, SEMANTIC_VERSION_PATTERN);
this.version = version;
// a match will produce three or four matching groups (release candidate version optional)
majorVersion = Integer.valueOf(versionMatcher.group(1));
minorVersion = Integer.valueOf(versionMatcher.group(2));
patchVersion = Integer.valueOf(versionMatcher.group(3));
String releaseCandidateVersionIfPresent = versionMatcher.group(4);
if (releaseCandidateVersionIfPresent != null) {
releaseCandidate = true;
releaseCandidateVersion = Integer.valueOf(releaseCandidateVersionIfPresent);
} else {
releaseCandidate = false;
releaseCandidateVersion = null;
}
// endsWith("T") would be cheaper but we only do this once...
snapshot = version.endsWith("-SNAPSHOT");
}
@Override
public String toString() {
return version;
}
public static JcloudsVersion get() {
return INSTANCE;
}
}