View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.start;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.util.Enumeration;
25  import java.util.Map;
26  import java.util.Properties;
27  import java.util.jar.Attributes;
28  import java.util.jar.JarEntry;
29  import java.util.jar.JarFile;
30  import java.util.jar.Manifest;
31  import java.util.regex.Matcher;
32  import java.util.regex.Pattern;
33  
34  /**
35   * Attempt to determine the version of the Jar File based on common version locations.
36   */
37  public class JarVersion
38  {
39      private static JarEntry findEntry(JarFile jar, String regex)
40      {
41          Pattern pattern = Pattern.compile(regex);
42          Matcher matcher;
43          Enumeration<JarEntry> en = jar.entries();
44          while (en.hasMoreElements())
45          {
46              JarEntry entry = en.nextElement();
47              matcher = pattern.matcher(entry.getName());
48              if (matcher.matches())
49              {
50                  return entry;
51              }
52          }
53  
54          return null;
55      }
56  
57      private static String getBundleVersion(Manifest manifest)
58      {
59          Attributes attribs = manifest.getMainAttributes();
60          if (attribs == null)
61          {
62              return null;
63          }
64  
65          String version = attribs.getValue("Bundle-Version");
66          if (version == null)
67          {
68              return null;
69          }
70  
71          return stripV(version);
72      }
73  
74      private static String getMainManifestImplVersion(Manifest manifest)
75      {
76          Attributes attribs = manifest.getMainAttributes();
77          if (attribs == null)
78          {
79              return null;
80          }
81  
82          String version = attribs.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
83          if (version == null)
84          {
85              return null;
86          }
87  
88          return stripV(version);
89      }
90  
91      private static String getMavenVersion(JarFile jar) throws IOException
92      {
93          JarEntry pomProp = findEntry(jar,"META-INF/maven/.*/pom\\.properties$");
94          if (pomProp == null)
95          {
96              return null;
97          }
98  
99          InputStream stream = null;
100 
101         try
102         {
103             stream = jar.getInputStream(pomProp);
104             Properties props = new Properties();
105             props.load(stream);
106 
107             String version = props.getProperty("version");
108             if (version == null)
109             {
110                 return null;
111             }
112 
113             return stripV(version);
114         }
115         finally
116         {
117             FS.close(stream);
118         }
119     }
120 
121     private static String getSubManifestImplVersion(Manifest manifest)
122     {
123         Map<String, Attributes> entries = manifest.getEntries();
124 
125         for (Attributes attribs : entries.values())
126         {
127             if (attribs == null)
128             {
129                 continue; // skip entry
130             }
131 
132             String version = attribs.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
133             if (version == null)
134             {
135                 continue; // empty, no value, skip it
136             }
137 
138             return stripV(version);
139         }
140 
141         return null; // no valid impl version entries found
142     }
143 
144     public static String getVersion(File file)
145     {
146         try (JarFile jar = new JarFile(file))
147         {
148             String version = null;
149 
150             Manifest manifest = jar.getManifest();
151 
152             version = getMainManifestImplVersion(manifest);
153             if (version != null)
154             {
155                 return version;
156             }
157 
158             version = getSubManifestImplVersion(manifest);
159             if (version != null)
160             {
161                 return version;
162             }
163 
164             version = getBundleVersion(manifest);
165             if (version != null)
166             {
167                 return version;
168             }
169 
170             version = getMavenVersion(jar);
171             if (version != null)
172             {
173                 return version;
174             }
175 
176             return "(not specified)";
177         }
178         catch (IOException e)
179         {
180             return "(error: " + e.getClass().getSimpleName() + " " + e.getMessage() + ")";
181         }
182     }
183 
184     private static String stripV(String version)
185     {
186         if (version.charAt(0) == 'v')
187         {
188             return version.substring(1);
189         }
190 
191         return version;
192     }
193 }