View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.statistics.examples.distribution;
18  
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.net.URL;
22  import java.util.Enumeration;
23  import java.util.jar.Attributes;
24  import java.util.jar.Manifest;
25  import picocli.CommandLine.IVersionProvider;
26  
27  /**
28   * {@link IVersionProvider} implementation that returns version information from
29   * the package jar file's {@code /META-INF/MANIFEST.MF} file.
30   *
31   * @see <a
32   * href="https://github.com/remkop/picocli/blob/master/picocli-examples/src/main/java/picocli/examples/VersionProviderDemo2.java">PicoCLI
33   * version provider demo</a>
34   */
35  class ManifestVersionProvider implements IVersionProvider {
36      /** The manifest key for the implementation title. */
37      private static final String KEY = "Implementation-Title";
38  
39      /** {@inheritDoc} */
40      @Override
41      public String[] getVersion() throws Exception {
42          final Enumeration<URL> resources = Thread.currentThread().getContextClassLoader()
43                                             .getResources("META-INF/MANIFEST.MF");
44          while (resources.hasMoreElements()) {
45              final URL url = resources.nextElement();
46              try (InputStream stream = url.openStream()) {
47                  final Manifest manifest = new Manifest(stream);
48                  if (isApplicableManifest(manifest)) {
49                      final Attributes attr = manifest.getMainAttributes();
50                      return new String[] {get(attr, KEY) + " version \"" +
51                                           get(attr, "Implementation-Version") + "\""};
52                  }
53              } catch (final IOException ex) {
54                  return new String[] {"Unable to read from " + url + ". " + ex};
55              }
56          }
57          return new String[0];
58      }
59  
60      /**
61       * Checks if this is the applicable manifest for the package.
62       *
63       * @param manifest The manifest.
64       * @return true if is the applicable manifest
65       */
66      private static boolean isApplicableManifest(Manifest manifest) {
67          final Attributes attributes = manifest.getMainAttributes();
68          return "Apache Commons Statistics Distribution Utilities".equals(get(attributes, KEY));
69      }
70  
71      /**
72       * Gets the named object from the attributes using the key.
73       *
74       * @param attributes The attributes.
75       * @param key The key.
76       * @return the object
77       */
78      private static Object get(Attributes attributes, String key) {
79          return attributes.get(new Attributes.Name(key));
80      }
81  }