001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 *
020 */
021 package org.apache.qpid.common;
022
023 import org.slf4j.Logger;
024 import org.slf4j.LoggerFactory;
025
026 import java.io.IOException;
027 import java.io.InputStream;
028 import java.util.Map;
029 import java.util.Properties;
030
031 /**
032 * QpidProperties captures the project name, version number, and source code repository revision number from a properties
033 * file which is generated as part of the build process. Normally, the name and version number are pulled from the module
034 * name and version number of the Maven build POM, but could come from other sources if the build system is changed. The
035 * idea behind this, is that every build has these values incorporated directly into its jar file, so that code in the
036 * wild can be identified, should its origination be forgotten.
037 *
038 * <p/>To get the build version of any Qpid code call the {@link #main} method. This version string is usually also
039 * printed to the console on broker start up.
040 *
041 * <p/><table id="crc"><caption>CRC Card</caption>
042 * <tr><td>Load build versioning information into the runtime, for code identification purposes.
043 * </table>
044 *
045 * @todo Code to locate/load/log properties can be factored into a reusable properties utils class. Avoid having this
046 * same snippet of loading code scattered in many places.
047 *
048 * @todo Could also add a build number property for a sequential build number assigned by an automated build system, for
049 * build reproducability purposes.
050 */
051 public class QpidProperties
052 {
053 /** Used for debugging purposes. */
054 private static final Logger _logger = LoggerFactory.getLogger(QpidProperties.class);
055
056 /** The name of the version properties file to load from the class path. */
057 public static final String VERSION_RESOURCE = "qpidversion.properties";
058
059 /** Defines the name of the product property. */
060 public static final String PRODUCT_NAME_PROPERTY = "qpid.name";
061
062 /** Defines the name of the version property. */
063 public static final String RELEASE_VERSION_PROPERTY = "qpid.version";
064
065 /** Defines the name of the source code revision property. */
066 public static final String BUILD_VERSION_PROPERTY = "qpid.svnversion";
067
068 /** Defines the default value for all properties that cannot be loaded. */
069 private static final String DEFAULT = "unknown";
070
071 /** Holds the product name. */
072 private static String productName = DEFAULT;
073
074 /** Holds the product version. */
075 private static String releaseVersion = DEFAULT;
076
077 /** Holds the source code revision. */
078 private static String buildVersion = DEFAULT;
079
080 // Loads the values from the version properties file.
081 static
082 {
083 Properties props = new Properties();
084
085 try
086 {
087 InputStream propertyStream = QpidProperties.class.getClassLoader().getResourceAsStream(VERSION_RESOURCE);
088 if (propertyStream == null)
089 {
090 _logger.warn("Unable to find resource " + VERSION_RESOURCE + " from classloader");
091 }
092 else
093 {
094 props.load(propertyStream);
095
096 if (_logger.isDebugEnabled())
097 {
098 _logger.debug("Dumping QpidProperties");
099 for (Map.Entry<Object, Object> entry : props.entrySet())
100 {
101 _logger.debug("Property: " + entry.getKey() + " Value: " + entry.getValue());
102 }
103
104 _logger.debug("End of property dump");
105 }
106
107 productName = readPropertyValue(props, PRODUCT_NAME_PROPERTY);
108 releaseVersion = readPropertyValue(props, RELEASE_VERSION_PROPERTY);
109 buildVersion = readPropertyValue(props, BUILD_VERSION_PROPERTY);
110 }
111 }
112 catch (IOException e)
113 {
114 // Log a warning about this and leave the values initialized to unknown.
115 _logger.error("Could not load version.properties resource: " + e, e);
116 }
117 }
118
119 /**
120 * Gets the product name.
121 *
122 * @return The product name.
123 */
124 public static String getProductName()
125 {
126 return productName;
127 }
128
129 /**
130 * Gets the product version.
131 *
132 * @return The product version.
133 */
134 public static String getReleaseVersion()
135 {
136 return releaseVersion;
137 }
138
139 /**
140 * Gets the source code revision.
141 *
142 * @return The source code revision.
143 */
144 public static String getBuildVersion()
145 {
146 return buildVersion;
147 }
148
149 /**
150 * Extracts all of the version information as a printable string.
151 *
152 * @return All of the version information as a printable string.
153 */
154 public static String getVersionString()
155 {
156 return getProductName() + " - " + getReleaseVersion() + " build: " + getBuildVersion();
157 }
158
159 /**
160 * Helper method to extract a named property from properties.
161 *
162 * @param props The properties.
163 * @param propertyName The named property to extract.
164 *
165 * @return The extracted property or a default value if the properties do not contain the named property.
166 *
167 * @todo A bit pointless.
168 */
169 private static String readPropertyValue(Properties props, String propertyName)
170 {
171 String retVal = (String) props.get(propertyName);
172 if (retVal == null)
173 {
174 retVal = DEFAULT;
175 }
176
177 return retVal;
178 }
179
180 /**
181 * Prints the versioning information to the console. This is extremely usefull for identifying Qpid code in the
182 * wild, where the origination of the code has been forgotten.
183 *
184 * @param args Does not require any arguments.
185 */
186 public static void main(String[] args)
187 {
188 System.out.println(getVersionString());
189 }
190 }
|