2013-11-26 12:27:58 +01:00
|
|
|
/*
|
|
|
|
* Copyright 2013 The Netty Project
|
|
|
|
*
|
|
|
|
* The Netty Project 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 io.netty.util;
|
|
|
|
|
2014-04-08 13:56:14 +02:00
|
|
|
import io.netty.util.internal.PlatformDependent;
|
|
|
|
|
2013-11-26 12:27:58 +01:00
|
|
|
import java.io.InputStream;
|
|
|
|
import java.net.URL;
|
|
|
|
import java.text.ParseException;
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
|
import java.util.Enumeration;
|
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Properties;
|
|
|
|
import java.util.Set;
|
|
|
|
import java.util.TreeMap;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves the version information of available Netty artifacts.
|
|
|
|
* <p>
|
|
|
|
* This class retrieves the version information from {@code META-INF/io.netty.versions.properties}, which is
|
|
|
|
* generated in build time. Note that it may not be possible to retrieve the information completely, depending on
|
|
|
|
* your environment, such as the specified {@link ClassLoader}, the current {@link SecurityManager}.
|
|
|
|
* </p>
|
|
|
|
*/
|
|
|
|
public final class Version {
|
|
|
|
|
|
|
|
private static final String PROP_VERSION = ".version";
|
|
|
|
private static final String PROP_BUILD_DATE = ".buildDate";
|
|
|
|
private static final String PROP_COMMIT_DATE = ".commitDate";
|
|
|
|
private static final String PROP_SHORT_COMMIT_HASH = ".shortCommitHash";
|
|
|
|
private static final String PROP_LONG_COMMIT_HASH = ".longCommitHash";
|
|
|
|
private static final String PROP_REPO_STATUS = ".repoStatus";
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves the version information of Netty artifacts using the current
|
|
|
|
* {@linkplain Thread#getContextClassLoader() context class loader}.
|
|
|
|
*
|
|
|
|
* @return A {@link Map} whose keys are Maven artifact IDs and whose values are {@link Version}s
|
|
|
|
*/
|
|
|
|
public static Map<String, Version> identify() {
|
|
|
|
return identify(null);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves the version information of Netty artifacts using the specified {@link ClassLoader}.
|
|
|
|
*
|
|
|
|
* @return A {@link Map} whose keys are Maven artifact IDs and whose values are {@link Version}s
|
|
|
|
*/
|
|
|
|
public static Map<String, Version> identify(ClassLoader classLoader) {
|
|
|
|
if (classLoader == null) {
|
2014-04-08 13:56:14 +02:00
|
|
|
classLoader = PlatformDependent.getContextClassLoader();
|
2013-11-26 12:27:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Collect all properties.
|
|
|
|
Properties props = new Properties();
|
|
|
|
try {
|
|
|
|
Enumeration<URL> resources = classLoader.getResources("META-INF/io.netty.versions.properties");
|
|
|
|
while (resources.hasMoreElements()) {
|
|
|
|
URL url = resources.nextElement();
|
|
|
|
InputStream in = url.openStream();
|
|
|
|
try {
|
|
|
|
props.load(in);
|
|
|
|
} finally {
|
|
|
|
try {
|
|
|
|
in.close();
|
|
|
|
} catch (Exception ignore) {
|
|
|
|
// Ignore.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (Exception ignore) {
|
|
|
|
// Not critical. Just ignore.
|
|
|
|
}
|
|
|
|
|
|
|
|
// Collect all artifactIds.
|
|
|
|
Set<String> artifactIds = new HashSet<String>();
|
|
|
|
for (Object o: props.keySet()) {
|
|
|
|
String k = (String) o;
|
|
|
|
|
|
|
|
int dotIndex = k.indexOf('.');
|
|
|
|
if (dotIndex <= 0) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
String artifactId = k.substring(0, dotIndex);
|
|
|
|
|
|
|
|
// Skip the entries without required information.
|
|
|
|
if (!props.containsKey(artifactId + PROP_VERSION) ||
|
|
|
|
!props.containsKey(artifactId + PROP_BUILD_DATE) ||
|
|
|
|
!props.containsKey(artifactId + PROP_COMMIT_DATE) ||
|
|
|
|
!props.containsKey(artifactId + PROP_SHORT_COMMIT_HASH) ||
|
|
|
|
!props.containsKey(artifactId + PROP_LONG_COMMIT_HASH) ||
|
|
|
|
!props.containsKey(artifactId + PROP_REPO_STATUS)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
artifactIds.add(artifactId);
|
|
|
|
}
|
|
|
|
|
|
|
|
Map<String, Version> versions = new TreeMap<String, Version>();
|
|
|
|
for (String artifactId: artifactIds) {
|
|
|
|
versions.put(
|
|
|
|
artifactId,
|
|
|
|
new Version(
|
|
|
|
artifactId,
|
|
|
|
props.getProperty(artifactId + PROP_VERSION),
|
|
|
|
parseIso8601(props.getProperty(artifactId + PROP_BUILD_DATE)),
|
|
|
|
parseIso8601(props.getProperty(artifactId + PROP_COMMIT_DATE)),
|
|
|
|
props.getProperty(artifactId + PROP_SHORT_COMMIT_HASH),
|
|
|
|
props.getProperty(artifactId + PROP_LONG_COMMIT_HASH),
|
|
|
|
props.getProperty(artifactId + PROP_REPO_STATUS)));
|
|
|
|
}
|
|
|
|
|
|
|
|
return versions;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static long parseIso8601(String value) {
|
|
|
|
try {
|
|
|
|
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z").parse(value).getTime();
|
2014-07-02 12:04:11 +02:00
|
|
|
} catch (ParseException ignored) {
|
2013-11-26 12:27:58 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Prints the version information to {@link System#err}.
|
|
|
|
*/
|
|
|
|
public static void main(String[] args) {
|
|
|
|
for (Version v: identify().values()) {
|
|
|
|
System.err.println(v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private final String artifactId;
|
|
|
|
private final String artifactVersion;
|
|
|
|
private final long buildTimeMillis;
|
|
|
|
private final long commitTimeMillis;
|
|
|
|
private final String shortCommitHash;
|
|
|
|
private final String longCommitHash;
|
|
|
|
private final String repositoryStatus;
|
|
|
|
|
|
|
|
private Version(
|
|
|
|
String artifactId, String artifactVersion,
|
|
|
|
long buildTimeMillis, long commitTimeMillis,
|
|
|
|
String shortCommitHash, String longCommitHash, String repositoryStatus) {
|
|
|
|
this.artifactId = artifactId;
|
|
|
|
this.artifactVersion = artifactVersion;
|
|
|
|
this.buildTimeMillis = buildTimeMillis;
|
|
|
|
this.commitTimeMillis = commitTimeMillis;
|
|
|
|
this.shortCommitHash = shortCommitHash;
|
|
|
|
this.longCommitHash = longCommitHash;
|
|
|
|
this.repositoryStatus = repositoryStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String artifactId() {
|
|
|
|
return artifactId;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String artifactVersion() {
|
|
|
|
return artifactVersion;
|
|
|
|
}
|
|
|
|
|
|
|
|
public long buildTimeMillis() {
|
|
|
|
return buildTimeMillis;
|
|
|
|
}
|
|
|
|
|
|
|
|
public long commitTimeMillis() {
|
|
|
|
return commitTimeMillis;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String shortCommitHash() {
|
|
|
|
return shortCommitHash;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String longCommitHash() {
|
|
|
|
return longCommitHash;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String repositoryStatus() {
|
|
|
|
return repositoryStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return artifactId + '-' + artifactVersion + '.' + shortCommitHash +
|
|
|
|
("clean".equals(repositoryStatus)? "" : " (repository: " + repositoryStatus + ')');
|
|
|
|
}
|
|
|
|
}
|