001    /*
002     * $HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.11/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    
032    package org.apache.commons.ssl;
033    
034    import java.io.File;
035    import java.io.IOException;
036    import java.net.URL;
037    import java.text.DateFormat;
038    import java.text.SimpleDateFormat;
039    import java.util.Date;
040    import java.util.Enumeration;
041    import java.util.jar.JarEntry;
042    import 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.11/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     */
056    public class Version {
057        public static final String HEAD_URL = "$HeadURL: http://juliusdavies.ca/svn/not-yet-commons-ssl/tags/commons-ssl-0.3.11/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    }