/*
 * $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
