KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > util > ProductInfo


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

5 package com.tc.util;
6
7 import org.apache.commons.cli.CommandLine;
8 import org.apache.commons.cli.CommandLineParser;
9 import org.apache.commons.cli.GnuParser;
10 import org.apache.commons.cli.HelpFormatter;
11 import org.apache.commons.cli.Options;
12 import org.apache.commons.lang.StringUtils;
13
14 import com.tc.logging.TCLogger;
15 import com.tc.logging.TCLogging;
16
17 import java.io.IOException JavaDoc;
18 import java.io.InputStream JavaDoc;
19 import java.text.DateFormat JavaDoc;
20 import java.text.ParseException JavaDoc;
21 import java.text.SimpleDateFormat JavaDoc;
22 import java.util.Date JavaDoc;
23 import java.util.Properties JavaDoc;
24
25 /**
26  * Utility class to retrieve the build information for the product.
27  */

28 public final class ProductInfo {
29   private static final ResourceBundleHelper bundleHelper = new ResourceBundleHelper(ProductInfo.class);
30
31   private static final DateFormat JavaDoc DATE_FORMAT = new SimpleDateFormat JavaDoc("yyyyMMdd-HHmmss");
32
33   private static final String JavaDoc BUILD_DATA_RESOURCE_NAME = "/build-data.txt";
34
35   private static final String JavaDoc BUILD_DATA_ROOT_KEY = "terracotta.build.";
36   private static final String JavaDoc BUILD_DATA_VERSION_KEY = "version";
37   private static final String JavaDoc BUILD_DATA_TIMESTAMP_KEY = "timestamp";
38   private static final String JavaDoc BUILD_DATA_HOST_KEY = "host";
39   private static final String JavaDoc BUILD_DATA_USER_KEY = "user";
40   private static final String JavaDoc BUILD_DATA_CHANGESET_KEY = "revision";
41   private static final String JavaDoc BUILD_DATA_CHANGE_TAG_KEY = "change-tag";
42   private static final String JavaDoc BUILD_DATA_BRANCH_KEY = "branch";
43
44   private static final String JavaDoc UNKNOWN_VALUE = "[unknown]";
45
46   // WARNING: DO NOT DO NOT DO NOT MOVE THIS DECLARATION HIGHER!
47
//
48
// Yes, this is really obnoxious. What's going on is this: TCLogging, in its static initializer, actually calls back
49
// into this class so that it can write out the product version. However, if this class (ProductInfo) is actually
50
// initialized first, before TCLogging (as, for example, is the case when you invoke its main() method to print out
51
// the version), then what *was* happening is that it would first try to initialize the logger, which triggers
52
// TCLogging's static initializer, which calls back into this class's getThisProductInfo() method, which in turn calls
53
// the constructor, which would try to use the DATE_FORMAT constant...which is a perfectly reasonable thing to do, but
54
// in this one case, DATE_FORMAT wouldn't be initialized yet, since this declaration used to be above all the
55
// constants above and thus would be called first. Moving it lower, below all the other constants, corrects this
56
// problem.
57
//
58
// Yup, order of static initializers still *can* be a problem in Java, clearly. At least the order is defined, though.
59
// ;)
60
private static final TCLogger logger = TCLogging.getLogger(ProductInfo.class);
61
62   private final String JavaDoc moniker;
63   private final String JavaDoc version;
64   private final Date JavaDoc timestamp;
65   private final String JavaDoc host;
66   private final String JavaDoc user;
67   private final String JavaDoc changeset;
68   private final String JavaDoc changeTag;
69   private final String JavaDoc branch;
70
71   private ProductInfo(InputStream JavaDoc in, String JavaDoc fromWhere) {
72     Properties JavaDoc properties = new Properties JavaDoc();
73
74     moniker = bundleHelper.getString("moniker");
75
76     if (in != null) {
77       try {
78         properties.load(in);
79       } catch (IOException JavaDoc ioe) {
80         logger.warn(bundleHelper.format("load.properties.failure", new Object JavaDoc[] { fromWhere }));
81       }
82     }
83
84     this.version = getProperty(properties, BUILD_DATA_VERSION_KEY, UNKNOWN_VALUE);
85     String JavaDoc timestampString = getProperty(properties, BUILD_DATA_TIMESTAMP_KEY, null);
86     this.host = getProperty(properties, BUILD_DATA_HOST_KEY, UNKNOWN_VALUE);
87     this.user = getProperty(properties, BUILD_DATA_USER_KEY, UNKNOWN_VALUE);
88     this.changeset = getProperty(properties, BUILD_DATA_CHANGESET_KEY, UNKNOWN_VALUE);
89     this.changeTag = getProperty(properties, BUILD_DATA_CHANGE_TAG_KEY, null);
90     this.branch = getProperty(properties, BUILD_DATA_BRANCH_KEY, UNKNOWN_VALUE);
91
92     Date JavaDoc realTimestamp = null;
93     if (timestampString != null) {
94       try {
95         realTimestamp = DATE_FORMAT.parse(timestampString);
96       } catch (ParseException JavaDoc pe) {
97         logger.warn(bundleHelper.format("invalid.timestamp", new Object JavaDoc[] { timestampString }));
98       }
99     }
100
101     this.timestamp = realTimestamp;
102   }
103
104   private String JavaDoc getProperty(Properties JavaDoc properties, String JavaDoc name, String JavaDoc defaultValue) {
105     String JavaDoc out = properties.getProperty(BUILD_DATA_ROOT_KEY + name);
106     if (StringUtils.isBlank(out)) out = defaultValue;
107     return out;
108   }
109
110   private static ProductInfo thisProductInfo = null;
111
112   public static synchronized ProductInfo getThisProductInfo() {
113     if (thisProductInfo == null) {
114       InputStream JavaDoc in = ProductInfo.class.getResourceAsStream(BUILD_DATA_RESOURCE_NAME);
115       thisProductInfo = new ProductInfo(in, "resource '" + BUILD_DATA_RESOURCE_NAME + "'");
116     }
117
118     return thisProductInfo;
119   }
120
121   public boolean isDevMode() {
122     return this.version.endsWith(UNKNOWN_VALUE);
123   }
124
125   public String JavaDoc moniker() {
126     return this.moniker;
127   }
128
129   public String JavaDoc rawVersion() {
130     return this.version;
131   }
132
133   public String JavaDoc buildVersion() {
134     return this.version;
135   }
136
137   public Date JavaDoc buildTimestamp() {
138     return this.timestamp;
139   }
140
141   public String JavaDoc buildTimestampAsString() {
142     if (this.timestamp == null) return UNKNOWN_VALUE;
143     else return DATE_FORMAT.format(this.timestamp);
144   }
145
146   public String JavaDoc buildHost() {
147     return this.host;
148   }
149
150   public String JavaDoc buildUser() {
151     return this.user;
152   }
153
154   public String JavaDoc buildChangeset() {
155     return this.changeset;
156   }
157
158   public String JavaDoc buildChangeTag() {
159     return this.changeTag;
160   }
161
162   public String JavaDoc buildBranch() {
163     return this.branch;
164   }
165
166   public String JavaDoc copyright() {
167     return bundleHelper.getString("copyright");
168   }
169
170   public String JavaDoc toShortString() {
171     return this.moniker + " version " + buildVersion();
172   }
173
174   public String JavaDoc toLongString() {
175     return toShortString() + ", as of " + buildTimestampAsString() + " (Revision " + buildChangeset()
176         + (buildChangeTag() != null ? " (" + buildChangeTag() + ")" : "") + " by " + buildUser() + "@" + buildHost()
177         + " from " + buildBranch() + ")";
178   }
179
180   public String JavaDoc toString() {
181     return toShortString();
182   }
183
184   public static void main(String JavaDoc[] args) throws Exception JavaDoc {
185     Options options = new Options();
186     options.addOption("v", "verbose", false, bundleHelper.getString("option.verbose"));
187     options.addOption("h", "help", false, bundleHelper.getString("option.help"));
188
189     CommandLineParser parser = new GnuParser();
190     CommandLine cli = parser.parse(options, args);
191
192     if (cli.hasOption("h")) {
193       new HelpFormatter().printHelp("java " + ProductInfo.class.getName(), options);
194     }
195
196     if (cli.hasOption("v")) {
197       System.out.println(getThisProductInfo().toLongString());
198     } else {
199       System.out.println(getThisProductInfo().toShortString());
200     }
201   }
202 }
203
Popular Tags