View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 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             if (manifest == null)
153             {
154                 return "(none specified)";
155             }
156 
157             version = getMainManifestImplVersion(manifest);
158             if (version != null)
159             {
160                 return version;
161             }
162 
163             version = getSubManifestImplVersion(manifest);
164             if (version != null)
165             {
166                 return version;
167             }
168 
169             version = getBundleVersion(manifest);
170             if (version != null)
171             {
172                 return version;
173             }
174 
175             version = getMavenVersion(jar);
176             if (version != null)
177             {
178                 return version;
179             }
180 
181             return "(none specified)";
182         }
183         catch (IOException e)
184         {
185             return "(error: " + e.getClass().getSimpleName() + " " + e.getMessage() + ")";
186         }
187     }
188 
189     private static String stripV(String version)
190     {
191         if (version.charAt(0) == 'v')
192         {
193             return version.substring(1);
194         }
195 
196         return version;
197     }
198 }