/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.util; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.List; import java.util.Properties; import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.jar.Manifest; import org.reflections.util.ClasspathHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.opengamma.util.ClasspathUtils.DependencyInfo; /** * Utility methods to work with the current OpenGamma build version. * <p> * This is a thread-safe static utility class. */ public final class VersionUtils { /** Logger. */ private static final Logger s_logger = LoggerFactory.getLogger(VersionUtils.class); /** Build name (git hash). */ private static final Attributes.Name IMPLEMENTATION_BUILD = new Attributes.Name("Implementation-Build"); /** Build ID (CI server ID). */ private static final Attributes.Name IMPLEMENTATION_BUILD_ID = new Attributes.Name("Implementation-Build-Id"); /** * The local build version number. */ private static String s_localBuildVersion; /** * Restricted constructor. */ private VersionUtils() { } //------------------------------------------------------------------------- /** * Gets the current OpenGamma build version. * <p> * The version is read from a property file in the classpath with name * <code>"/" + projectName + ".properties"</code>. * This file is created by Ant during a Bamboo build. If no such file is found, * the method assumes you are running a local build, and it will * return <code>"local-" + System.currentTimeMillis()</code> * where <code>System.currentTimeMillis()</code> becomes fixed on the first * call within this VM. * * @param projectName the name of the OpenGamma project, for example og-financial, not null * @return the current version of the specified project, not null */ public static String getVersion(String projectName) { String fileName = "/" + projectName + ".properties"; Properties properties = new Properties(); try (InputStream stream = VersionUtils.class.getResourceAsStream(fileName)) { if (stream == null) { return getLocalBuildVersion(); } properties.load(stream); } catch (IOException e) { s_logger.error("Failed to read properties", e); return getLocalBuildVersion(); } String version = properties.getProperty("version"); if (version == null) { return getLocalBuildVersion(); } return version; } private static synchronized String getLocalBuildVersion() { if (s_localBuildVersion != null) { return s_localBuildVersion; } s_localBuildVersion = "local-" + System.currentTimeMillis(); return s_localBuildVersion; } //------------------------------------------------------------------------- /** * Derives the OpenGamma version from the classpath and dependencies. * * @return the version, null if not known */ public static String deriveVersion() { URL url = ClasspathHelper.forClass(VersionUtils.class, VersionUtils.class.getClassLoader()); if (url != null && url.toString().contains(".jar")) { try { final String part = ClasspathHelper.cleanPath(url); try (JarFile myJar = new JarFile(part)) { final Manifest manifest = myJar.getManifest(); if (manifest != null) { Attributes attributes = manifest.getMainAttributes(); if (attributes != null) { if (attributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION) != null) { return attributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION); } if (attributes.getValue(Attributes.Name.SPECIFICATION_VERSION) != null) { return attributes.getValue(Attributes.Name.SPECIFICATION_VERSION); } } } } } catch (Exception ex) { s_logger.warn(ex.getMessage(), ex); } } else { List<DependencyInfo> dependencies = ClasspathUtils.getDependencies(); for (DependencyInfo dependency : dependencies) { if ("og-util".equals(dependency.getArtifactId())) { return dependency.getVersion(); } } } return null; } /** * Derives the OpenGamma build from the classpath and dependencies. * * @return the build, null if not known */ public static String deriveBuild() { URL url = ClasspathHelper.forClass(VersionUtils.class, VersionUtils.class.getClassLoader()); if (url != null && url.toString().contains(".jar")) { try { final String part = ClasspathHelper.cleanPath(url); try (JarFile myJar = new JarFile(part)) { final Manifest manifest = myJar.getManifest(); if (manifest != null) { Attributes attributes = manifest.getMainAttributes(); if (attributes != null) { if (attributes.getValue(IMPLEMENTATION_BUILD) != null) { return attributes.getValue(IMPLEMENTATION_BUILD); } } } } } catch (Exception ex) { s_logger.warn(ex.getMessage(), ex); } } return null; } /** * Derives the OpenGamma build ID from the classpath and dependencies. * <p> * This ID is derived from the CI server. * * @return the build ID, null if not known */ public static String deriveBuildId() { URL url = ClasspathHelper.forClass(VersionUtils.class, VersionUtils.class.getClassLoader()); if (url != null && url.toString().contains(".jar")) { try { final String part = ClasspathHelper.cleanPath(url); try (JarFile myJar = new JarFile(part)) { final Manifest manifest = myJar.getManifest(); if (manifest != null) { Attributes attributes = manifest.getMainAttributes(); if (attributes != null) { if (attributes.getValue(IMPLEMENTATION_BUILD_ID) != null) { return attributes.getValue(IMPLEMENTATION_BUILD_ID); } } } } } catch (Exception ex) { s_logger.warn(ex.getMessage(), ex); } } return null; } }