1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.netty.util;
18
19 import io.netty.util.internal.PlatformDependent;
20
21 import java.io.InputStream;
22 import java.net.URL;
23 import java.text.ParseException;
24 import java.text.SimpleDateFormat;
25 import java.util.Enumeration;
26 import java.util.HashSet;
27 import java.util.Map;
28 import java.util.Properties;
29 import java.util.Set;
30 import java.util.TreeMap;
31
32
33
34
35
36
37
38
39
40 public final class Version {
41
42 private static final String PROP_VERSION = ".version";
43 private static final String PROP_BUILD_DATE = ".buildDate";
44 private static final String PROP_COMMIT_DATE = ".commitDate";
45 private static final String PROP_SHORT_COMMIT_HASH = ".shortCommitHash";
46 private static final String PROP_LONG_COMMIT_HASH = ".longCommitHash";
47 private static final String PROP_REPO_STATUS = ".repoStatus";
48
49
50
51
52
53
54
55 public static Map<String, Version> identify() {
56 return identify(null);
57 }
58
59
60
61
62
63
64 public static Map<String, Version> identify(ClassLoader classLoader) {
65 if (classLoader == null) {
66 classLoader = PlatformDependent.getContextClassLoader();
67 }
68
69
70 Properties props = new Properties();
71 try {
72 Enumeration<URL> resources = classLoader.getResources("META-INF/io.netty.versions.properties");
73 while (resources.hasMoreElements()) {
74 URL url = resources.nextElement();
75 InputStream in = url.openStream();
76 try {
77 props.load(in);
78 } finally {
79 try {
80 in.close();
81 } catch (Exception ignore) {
82
83 }
84 }
85 }
86 } catch (Exception ignore) {
87
88 }
89
90
91 Set<String> artifactIds = new HashSet<String>();
92 for (Object o: props.keySet()) {
93 String k = (String) o;
94
95 int dotIndex = k.indexOf('.');
96 if (dotIndex <= 0) {
97 continue;
98 }
99
100 String artifactId = k.substring(0, dotIndex);
101
102
103 if (!props.containsKey(artifactId + PROP_VERSION) ||
104 !props.containsKey(artifactId + PROP_BUILD_DATE) ||
105 !props.containsKey(artifactId + PROP_COMMIT_DATE) ||
106 !props.containsKey(artifactId + PROP_SHORT_COMMIT_HASH) ||
107 !props.containsKey(artifactId + PROP_LONG_COMMIT_HASH) ||
108 !props.containsKey(artifactId + PROP_REPO_STATUS)) {
109 continue;
110 }
111
112 artifactIds.add(artifactId);
113 }
114
115 Map<String, Version> versions = new TreeMap<String, Version>();
116 for (String artifactId: artifactIds) {
117 versions.put(
118 artifactId,
119 new Version(
120 artifactId,
121 props.getProperty(artifactId + PROP_VERSION),
122 parseIso8601(props.getProperty(artifactId + PROP_BUILD_DATE)),
123 parseIso8601(props.getProperty(artifactId + PROP_COMMIT_DATE)),
124 props.getProperty(artifactId + PROP_SHORT_COMMIT_HASH),
125 props.getProperty(artifactId + PROP_LONG_COMMIT_HASH),
126 props.getProperty(artifactId + PROP_REPO_STATUS)));
127 }
128
129 return versions;
130 }
131
132 private static long parseIso8601(String value) {
133 try {
134 return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z").parse(value).getTime();
135 } catch (ParseException ignored) {
136 return 0;
137 }
138 }
139
140
141
142
143 public static void main(String[] args) {
144 for (Version v: identify().values()) {
145 System.err.println(v);
146 }
147 }
148
149 private final String artifactId;
150 private final String artifactVersion;
151 private final long buildTimeMillis;
152 private final long commitTimeMillis;
153 private final String shortCommitHash;
154 private final String longCommitHash;
155 private final String repositoryStatus;
156
157 private Version(
158 String artifactId, String artifactVersion,
159 long buildTimeMillis, long commitTimeMillis,
160 String shortCommitHash, String longCommitHash, String repositoryStatus) {
161 this.artifactId = artifactId;
162 this.artifactVersion = artifactVersion;
163 this.buildTimeMillis = buildTimeMillis;
164 this.commitTimeMillis = commitTimeMillis;
165 this.shortCommitHash = shortCommitHash;
166 this.longCommitHash = longCommitHash;
167 this.repositoryStatus = repositoryStatus;
168 }
169
170 public String artifactId() {
171 return artifactId;
172 }
173
174 public String artifactVersion() {
175 return artifactVersion;
176 }
177
178 public long buildTimeMillis() {
179 return buildTimeMillis;
180 }
181
182 public long commitTimeMillis() {
183 return commitTimeMillis;
184 }
185
186 public String shortCommitHash() {
187 return shortCommitHash;
188 }
189
190 public String longCommitHash() {
191 return longCommitHash;
192 }
193
194 public String repositoryStatus() {
195 return repositoryStatus;
196 }
197
198 @Override
199 public String toString() {
200 return artifactId + '-' + artifactVersion + '.' + shortCommitHash +
201 ("clean".equals(repositoryStatus)? "" : " (repository: " + repositoryStatus + ')');
202 }
203 }