Tatu Saloranta | f15531c | 2011-12-22 23:00:40 -0800 | [diff] [blame] | 1 | package com.fasterxml.jackson.core.util; |
| 2 | |
| 3 | import java.io.*; |
| 4 | import java.util.regex.Pattern; |
| 5 | |
| 6 | import com.fasterxml.jackson.core.Version; |
| 7 | |
| 8 | /** |
| 9 | * Functionality for supporting exposing of component {@link Version}s. |
Tatu Saloranta | 48d2609 | 2011-12-28 23:11:49 -0800 | [diff] [blame^] | 10 | *<p> |
| 11 | * Note that this class can be used in two roles: first, as a static |
| 12 | * utility class for loading purposes, and second, as a singleton |
| 13 | * loader of per-module version information. |
| 14 | * In latter case one must sub-class to get proper per-module instance; |
| 15 | * and sub-class must reside in same Java package as matching "VERSION.txt" |
| 16 | * file. |
Tatu Saloranta | f15531c | 2011-12-22 23:00:40 -0800 | [diff] [blame] | 17 | */ |
| 18 | public class VersionUtil |
| 19 | { |
| 20 | public final static String VERSION_FILE = "VERSION.txt"; |
| 21 | |
| 22 | private final static Pattern VERSION_SEPARATOR = Pattern.compile("[-_./;:]"); |
Tatu Saloranta | 48d2609 | 2011-12-28 23:11:49 -0800 | [diff] [blame^] | 23 | |
| 24 | private final Version _version; |
| 25 | |
| 26 | /* |
| 27 | /********************************************************** |
| 28 | /* Instance life-cycle, accesso |
| 29 | /********************************************************** |
| 30 | */ |
| 31 | |
| 32 | protected VersionUtil() |
| 33 | { |
| 34 | Version v = null; |
| 35 | try { |
| 36 | /* Class we pass only matters for resource-loading: can't use this Class |
| 37 | * (as it's just being loaded at this point), nor anything that depends on it. |
| 38 | */ |
| 39 | v = VersionUtil.versionFor(getClass()); |
| 40 | } catch (Exception e) { // not good to dump to stderr; but that's all we have at this low level |
| 41 | System.err.println("ERROR: Failed to load Version information for bundle (via "+getClass().getName()+")."); |
| 42 | } |
| 43 | if (v == null) { |
| 44 | v = Version.unknownVersion(); |
| 45 | } |
| 46 | _version = v; |
| 47 | } |
| 48 | |
| 49 | public Version version() { return _version; } |
| 50 | |
| 51 | /* |
| 52 | /********************************************************** |
| 53 | /* Static load methods |
| 54 | /********************************************************** |
| 55 | */ |
Tatu Saloranta | f15531c | 2011-12-22 23:00:40 -0800 | [diff] [blame] | 56 | |
| 57 | /** |
| 58 | * Helper method that will try to load version information for specified |
| 59 | * class. Implementation is simple: class loader that loaded specified |
| 60 | * class is asked to load resource with name "VERSION" from same |
| 61 | * location (package) as class itself had. |
| 62 | * If no version information is found, {@link Version#unknownVersion()} is |
| 63 | * returned. |
| 64 | */ |
| 65 | public static Version versionFor(Class<?> cls) |
| 66 | { |
| 67 | InputStream in; |
| 68 | Version version = null; |
Tatu Saloranta | e6b2599 | 2011-12-28 20:33:45 -0800 | [diff] [blame] | 69 | |
Tatu Saloranta | f15531c | 2011-12-22 23:00:40 -0800 | [diff] [blame] | 70 | try { |
| 71 | in = cls.getResourceAsStream(VERSION_FILE); |
| 72 | if (in != null) { |
| 73 | try { |
| 74 | BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8")); |
Tatu Saloranta | 96e131f | 2011-12-28 22:50:23 -0800 | [diff] [blame] | 75 | String groupStr = null, artifactStr = null; |
| 76 | String versionStr = br.readLine(); |
| 77 | if (versionStr != null) { |
| 78 | groupStr = br.readLine(); |
| 79 | if (groupStr != null) { |
| 80 | groupStr = groupStr.trim(); |
| 81 | artifactStr = br.readLine(); |
| 82 | if (artifactStr != null) { |
| 83 | artifactStr = artifactStr.trim(); |
| 84 | } |
| 85 | } |
| 86 | } |
| 87 | version = parseVersion(versionStr, groupStr, artifactStr); |
Tatu Saloranta | f15531c | 2011-12-22 23:00:40 -0800 | [diff] [blame] | 88 | } finally { |
| 89 | try { |
| 90 | in.close(); |
| 91 | } catch (IOException e) { |
| 92 | throw new RuntimeException(e); |
| 93 | } |
| 94 | } |
| 95 | } |
| 96 | } catch (IOException e) { } |
| 97 | return (version == null) ? Version.unknownVersion() : version; |
| 98 | } |
| 99 | |
Tatu Saloranta | 96e131f | 2011-12-28 22:50:23 -0800 | [diff] [blame] | 100 | /** |
| 101 | * Use variant that takes three arguments instead |
| 102 | * |
| 103 | * @deprecated |
| 104 | */ |
| 105 | @Deprecated |
| 106 | public static Version parseVersion(String versionStr) { |
| 107 | return parseVersion(versionStr, null, null); |
| 108 | } |
| 109 | |
| 110 | public static Version parseVersion(String versionStr, String groupId, String artifactId) |
Tatu Saloranta | f15531c | 2011-12-22 23:00:40 -0800 | [diff] [blame] | 111 | { |
Tatu Saloranta | 96e131f | 2011-12-28 22:50:23 -0800 | [diff] [blame] | 112 | if (versionStr == null) { |
Tatu Saloranta | f15531c | 2011-12-22 23:00:40 -0800 | [diff] [blame] | 113 | return null; |
| 114 | } |
Tatu Saloranta | 96e131f | 2011-12-28 22:50:23 -0800 | [diff] [blame] | 115 | versionStr = versionStr.trim(); |
| 116 | if (versionStr.length() == 0) { |
| 117 | return null; |
| 118 | } |
| 119 | String[] parts = VERSION_SEPARATOR.split(versionStr); |
Tatu Saloranta | f15531c | 2011-12-22 23:00:40 -0800 | [diff] [blame] | 120 | int major = parseVersionPart(parts[0]); |
Tatu Saloranta | 96e131f | 2011-12-28 22:50:23 -0800 | [diff] [blame] | 121 | int minor = (parts.length > 1) ? parseVersionPart(parts[1]) : 0; |
Tatu Saloranta | f15531c | 2011-12-22 23:00:40 -0800 | [diff] [blame] | 122 | int patch = (parts.length > 2) ? parseVersionPart(parts[2]) : 0; |
| 123 | String snapshot = (parts.length > 3) ? parts[3] : null; |
Tatu Saloranta | 96e131f | 2011-12-28 22:50:23 -0800 | [diff] [blame] | 124 | |
| 125 | return new Version(major, minor, patch, snapshot, |
| 126 | groupId, artifactId); |
Tatu Saloranta | f15531c | 2011-12-22 23:00:40 -0800 | [diff] [blame] | 127 | } |
| 128 | |
| 129 | protected static int parseVersionPart(String partStr) |
| 130 | { |
| 131 | partStr = partStr.toString(); |
| 132 | int len = partStr.length(); |
| 133 | int number = 0; |
| 134 | for (int i = 0; i < len; ++i) { |
| 135 | char c = partStr.charAt(i); |
| 136 | if (c > '9' || c < '0') break; |
| 137 | number = (number * 10) + (c - '0'); |
| 138 | } |
| 139 | return number; |
| 140 | } |
| 141 | } |