| /* |
| * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/util/VersionInfo.java $ |
| * $Revision: 554888 $ |
| * $Date: 2007-07-10 02:46:36 -0700 (Tue, 10 Jul 2007) $ |
| * |
| * ==================================================================== |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * ==================================================================== |
| * |
| * This software consists of voluntary contributions made by many |
| * individuals on behalf of the Apache Software Foundation. For more |
| * information on the Apache Software Foundation, please see |
| * <http://www.apache.org/>. |
| * |
| */ |
| |
| package org.apache.http.util; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.Map; |
| import java.util.Properties; |
| import java.util.ArrayList; |
| |
| |
| /** |
| * Provides access to version information for HTTP components. |
| * Instances of this class provide version information for a single module |
| * or informal unit, as explained |
| * <a href="http://wiki.apache.org/jakarta-httpclient/HttpComponents">here</a>. |
| * Static methods are used to extract version information from property |
| * files that are automatically packaged with HTTP component release JARs. |
| * <br/> |
| * All available version information is provided in strings, where |
| * the string format is informal and subject to change without notice. |
| * Version information is provided for debugging output and interpretation |
| * by humans, not for automated processing in applications. |
| * |
| * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a> |
| * @author and others |
| */ |
| public class VersionInfo { |
| |
| /** A string constant for unavailable information. */ |
| public final static String UNAVAILABLE = "UNAVAILABLE"; |
| |
| /** The filename of the version information files. */ |
| public final static String VERSION_PROPERTY_FILE = "version.properties"; |
| |
| // the property names |
| public final static String PROPERTY_MODULE = "info.module"; |
| public final static String PROPERTY_RELEASE = "info.release"; |
| public final static String PROPERTY_TIMESTAMP = "info.timestamp"; |
| |
| |
| /** The package that contains the version information. */ |
| private final String infoPackage; |
| |
| /** The module from the version info. */ |
| private final String infoModule; |
| |
| /** The release from the version info. */ |
| private final String infoRelease; |
| |
| /** The timestamp from the version info. */ |
| private final String infoTimestamp; |
| |
| /** The classloader from which the version info was obtained. */ |
| private final String infoClassloader; |
| |
| |
| /** |
| * Instantiates version information. |
| * |
| * @param pckg the package |
| * @param module the module, or <code>null</code> |
| * @param release the release, or <code>null</code> |
| * @param time the build time, or <code>null</code> |
| * @param clsldr the class loader, or <code>null</code> |
| */ |
| protected VersionInfo(String pckg, String module, |
| String release, String time, String clsldr) { |
| if (pckg == null) { |
| throw new IllegalArgumentException |
| ("Package identifier must not be null."); |
| } |
| |
| infoPackage = pckg; |
| infoModule = (module != null) ? module : UNAVAILABLE; |
| infoRelease = (release != null) ? release : UNAVAILABLE; |
| infoTimestamp = (time != null) ? time : UNAVAILABLE; |
| infoClassloader = (clsldr != null) ? clsldr : UNAVAILABLE; |
| } |
| |
| |
| /** |
| * Obtains the package name. |
| * The package name identifies the module or informal unit. |
| * |
| * @return the package name, never <code>null</code> |
| */ |
| public final String getPackage() { |
| return infoPackage; |
| } |
| |
| /** |
| * Obtains the name of the versioned module or informal unit. |
| * This data is read from the version information for the package. |
| * |
| * @return the module name, never <code>null</code> |
| */ |
| public final String getModule() { |
| return infoModule; |
| } |
| |
| /** |
| * Obtains the release of the versioned module or informal unit. |
| * This data is read from the version information for the package. |
| * |
| * @return the release version, never <code>null</code> |
| */ |
| public final String getRelease() { |
| return infoRelease; |
| } |
| |
| /** |
| * Obtains the timestamp of the versioned module or informal unit. |
| * This data is read from the version information for the package. |
| * |
| * @return the timestamp, never <code>null</code> |
| */ |
| public final String getTimestamp() { |
| return infoTimestamp; |
| } |
| |
| /** |
| * Obtains the classloader used to read the version information. |
| * This is just the <code>toString</code> output of the classloader, |
| * since the version information should not keep a reference to |
| * the classloader itself. That could prevent garbage collection. |
| * |
| * @return the classloader description, never <code>null</code> |
| */ |
| public final String getClassloader() { |
| return infoClassloader; |
| } |
| |
| |
| /** |
| * Provides the version information in human-readable format. |
| * |
| * @return a string holding this version information |
| */ |
| public String toString() { |
| StringBuffer sb = new StringBuffer |
| (20 + infoPackage.length() + infoModule.length() + |
| infoRelease.length() + infoTimestamp.length() + |
| infoClassloader.length()); |
| |
| sb.append("VersionInfo(") |
| .append(infoPackage).append(':').append(infoModule); |
| |
| // If version info is missing, a single "UNAVAILABLE" for the module |
| // is sufficient. Everything else just clutters the output. |
| if (!UNAVAILABLE.equals(infoRelease)) |
| sb.append(':').append(infoRelease); |
| if (!UNAVAILABLE.equals(infoTimestamp)) |
| sb.append(':').append(infoTimestamp); |
| |
| sb.append(')'); |
| |
| if (!UNAVAILABLE.equals(infoClassloader)) |
| sb.append('@').append(infoClassloader); |
| |
| return sb.toString(); |
| } |
| |
| |
| /** |
| * Loads version information for a list of packages. |
| * |
| * @param pckgs the packages for which to load version info |
| * @param clsldr the classloader to load from, or |
| * <code>null</code> for the thread context classloader |
| * |
| * @return the version information for all packages found, |
| * never <code>null</code> |
| */ |
| public final static VersionInfo[] loadVersionInfo(String[] pckgs, |
| ClassLoader clsldr) { |
| if (pckgs == null) { |
| throw new IllegalArgumentException |
| ("Package identifier list must not be null."); |
| } |
| |
| ArrayList vil = new ArrayList(pckgs.length); |
| for (int i=0; i<pckgs.length; i++) { |
| VersionInfo vi = loadVersionInfo(pckgs[i], clsldr); |
| if (vi != null) |
| vil.add(vi); |
| } |
| |
| return (VersionInfo[]) vil.toArray(new VersionInfo[vil.size()]); |
| } |
| |
| |
| /** |
| * Loads version information for a package. |
| * |
| * @param pckg the package for which to load version information, |
| * for example "org.apache.http". |
| * The package name should NOT end with a dot. |
| * @param clsldr the classloader to load from, or |
| * <code>null</code> for the thread context classloader |
| * |
| * @return the version information for the argument package, or |
| * <code>null</code> if not available |
| */ |
| public final static VersionInfo loadVersionInfo(final String pckg, |
| ClassLoader clsldr) { |
| if (pckg == null) { |
| throw new IllegalArgumentException |
| ("Package identifier must not be null."); |
| } |
| |
| if (clsldr == null) |
| clsldr = Thread.currentThread().getContextClassLoader(); |
| |
| Properties vip = null; // version info properties, if available |
| try { |
| // org.apache.http becomes |
| // org/apache/http/version.properties |
| InputStream is = clsldr.getResourceAsStream |
| (pckg.replace('.', '/') + "/" + VERSION_PROPERTY_FILE); |
| if (is != null) { |
| try { |
| Properties props = new Properties(); |
| props.load(is); |
| vip = props; |
| } finally { |
| is.close(); |
| } |
| } |
| } catch (IOException ex) { |
| // shamelessly munch this exception |
| } |
| |
| VersionInfo result = null; |
| if (vip != null) |
| result = fromMap(pckg, vip, clsldr); |
| |
| return result; |
| } |
| |
| |
| /** |
| * Instantiates version information from properties. |
| * |
| * @param pckg the package for the version information |
| * @param info the map from string keys to string values, |
| * for example {@link java.util.Properties} |
| * @param clsldr the classloader, or <code>null</code> |
| * |
| * @return the version information |
| */ |
| protected final static VersionInfo fromMap(String pckg, Map info, |
| ClassLoader clsldr) { |
| if (pckg == null) { |
| throw new IllegalArgumentException |
| ("Package identifier must not be null."); |
| } |
| |
| String module = null; |
| String release = null; |
| String timestamp = null; |
| |
| if (info != null) { |
| module = (String) info.get(PROPERTY_MODULE); |
| if ((module != null) && (module.length() < 1)) |
| module = null; |
| |
| release = (String) info.get(PROPERTY_RELEASE); |
| if ((release != null) && ((release.length() < 1) || |
| (release.equals("${pom.version}")))) |
| release = null; |
| |
| timestamp = (String) info.get(PROPERTY_TIMESTAMP); |
| if ((timestamp != null) && |
| ((timestamp.length() < 1) || |
| (timestamp.equals("${mvn.timestamp}"))) |
| ) |
| timestamp = null; |
| } // if info |
| |
| String clsldrstr = null; |
| if (clsldr != null) |
| clsldrstr = clsldr.toString(); |
| |
| return new VersionInfo(pckg, module, release, timestamp, clsldrstr); |
| } |
| |
| } // class VersionInfo |