    001/*
    002 * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/Version.java $
    003 * $Revision: 130 $
    004 * $Date: 2007-11-14 19:24:15 -0800 (Wed, 14 Nov 2007) $
    005 *
    006 * ====================================================================
    007 * Licensed to the Apache Software Foundation (ASF) under one
    008 * or more contributor license agreements.  See the NOTICE file
    009 * distributed with this work for additional information
    010 * regarding copyright ownership.  The ASF licenses this file
    011 * to you under the Apache License, Version 2.0 (the
    012 * "License"); you may not use this file except in compliance
    013 * with the License.  You may obtain a copy of the License at
    014 *
    015 *   http://www.apache.org/licenses/LICENSE-2.0
    016 *
    017 * Unless required by applicable law or agreed to in writing,
    018 * software distributed under the License is distributed on an
    019 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    020 * KIND, either express or implied.  See the License for the
    021 * specific language governing permissions and limitations
    022 * under the License.
    023 * ====================================================================
    024 *
    025 * This software consists of voluntary contributions made by many
    026 * individuals on behalf of the Apache Software Foundation.  For more
    027 * information on the Apache Software Foundation, please see
    028 * <http://www.apache.org/>.
    029 *
    030 */
    031
    032package org.apache.commons.ssl;
    033
    034import java.io.File;
    035import java.io.IOException;
    036import java.net.URL;
    037import java.text.DateFormat;
    038import java.text.SimpleDateFormat;
    039import java.util.Date;
    040import java.util.Enumeration;
    041import java.util.jar.JarEntry;
    042import java.util.jar.JarFile;
    043
    044/**
    045 * Extracts tagged version from a subversion $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/Version.java $ property, and prints it
    046 * out nicely on standard out.
    047 * <p/>
    048 * e.g. If this version came from /tags/commons-ssl-0_3_9/, then Version.java
    049 * will print:  "Version: 0.3.9" on standard out.
    050 *
    051 * @author Credit Union Central of British Columbia
    052 * @author <a href="http://www.cucbc.com/">www.cucbc.com</a>
    053 * @author <a href="mailto:juliusdavies@cucbc.com">juliusdavies@cucbc.com</a>
    054 * @since 14-Nov-2007
    055 */
    056public class Version {
    057    public static final String HEAD_URL = "$HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.15/src/java/org/apache/commons/ssl/Version.java $";
    058    public static final String VERSION;
    059    public static final String COMPILE_TIME;
    060
    061    static {
    062        // Try to extract a clean version number from svn's HeadURL property:
    063        String v = "UNKNOWN";
    064        boolean fromBranch = false;
    065        int x = HEAD_URL.lastIndexOf("/tags/");
    066        if (x >= 0) {
    067            int y = HEAD_URL.indexOf("/", x + "/tags/".length());
    068            if (y >= 0) {
    069                v = HEAD_URL.substring(x + "/tags/".length(), y);
    070            }
    071            v = v.replace('_', '.');
    072            v = v.replace('-', '.');
    073        } else if (HEAD_URL.indexOf("/trunk/") >= 0) {
    074            v = "trunk";
    075        } else if (HEAD_URL.indexOf("/branches/") >= 0) {
    076            fromBranch = true;
    077            x = HEAD_URL.indexOf("/branches/");
    078            int y = HEAD_URL.indexOf("/", x + "/branches/".length());
    079            if (y >= 0) {
    080                v = HEAD_URL.substring(x + "/branches/".length(), y);
    081            }
    082            v = v.replace('_', '.');
    083            v = v.replace('-', '.');
    084        }
    085
    086        String V = v.toUpperCase();
    087        x = V.indexOf("COMMONS.SSL.");
    088        if (x >= 0) {
    089            v = v.substring(x + "commons.ssl.".length());
    090        }
    091        VERSION = fromBranch ? "***Branch*** " + v : v;
    092
    093        // Try to calculate when jar file was compiled:
    094        String s;
    095        try {
    096            s = CompileTime.getCompileTimeString(Version.class);
    097        }
    098        catch (NoClassDefFoundError e) {
    099            s = null;
    100        }
    101        COMPILE_TIME = s;
    102    }
    103
    104    public static String versionString() {
    105        String v;
    106        if (COMPILE_TIME != null) {
    107            v = CompileTime.formatVersion(VERSION, COMPILE_TIME);
    108        } else {
    109            v = VERSION;
    110        }
    111        return "Version: " + v;
    112    }
    113
    114    public static void main(String[] args) {
    115        System.out.println(versionString());
    116    }
    117
    118    public String toString() {
    119        return versionString();
    120    }
    121
    122
    123    /**
    124     * Searches through a jar file to the find the most recent timestamp of
    125     * all the class files.
    126     */
    127    private static class CompileTime {
    128        private final static String PATTERN = ".jar!";
    129        private final static String PREFIX = "file:";
    130        private final static String DF_FORMAT = "zzz:yyyy-MM-dd/HH:mm:ss.SSS";
    131        private final static DateFormat DF = new SimpleDateFormat(DF_FORMAT);
    132
    133        public static String getCompileTimeString(Class clazz) {
    134            String s = clazz.getName();
    135            s = "/" + s.replace('.', '/') + ".class";
    136            return getCompileTimeString(s);
    137        }
    138
    139        private static String getCompileTimeString(String resource) {
    140            try {
    141                Date d = getCompileTime(resource);
    142                return d != null ? DF.format(d) : "[unknown]";
    143            }
    144            catch (IOException ioe) {
    145                return ioe.toString();
    146            }
    147        }
    148
    149        public static Date getCompileTime(String resource) throws IOException {
    150            URL url = CompileTime.class.getResource(resource);
    151            if (url != null) {
    152                String urlString = url.getFile();
    153                String fileLocation;
    154                int i = urlString.indexOf(PATTERN);
    155                if (i > 0) {
    156                    int x = i + PATTERN.length() - 1;
    157                    fileLocation = urlString.substring(0, x);
    158                    if (fileLocation.startsWith(PREFIX)) {
    159                        fileLocation = fileLocation.substring(PREFIX.length());
    160                    }
    161                    JarFile jf = new JarFile(fileLocation);
    162                    long newestTime = 0;
    163                    Enumeration entries = jf.entries();
    164                    while (entries.hasMoreElements()) {
    165                        JarEntry entry = (JarEntry) entries.nextElement();
    166                        if (entry.getName().endsWith(".class")) {
    167                            newestTime = Math.max(newestTime, entry.getTime());
    168                        }
    169                    }
    170                    if (newestTime > 0) {
    171                        return new Date(newestTime);
    172                    }
    173                } else {
    174                    File f = new File(urlString);
    175                    try {
    176                        return new Date(f.lastModified());
    177                    }
    178                    catch (Exception e) {
    179                        return null;
    180                    }
    181                }
    182            }
    183            return null;
    184        }
    185
    186        public static String formatVersion(String version, String compileTime) {
    187            StringBuffer buf = new StringBuffer();
    188            buf.append(version);
    189            buf.append("   Compiled: [");
    190            buf.append(compileTime);
    191            buf.append("]");
    192            return buf.toString();
    193        }
    194
    195    }
    196
    197}