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.rng.examples.sampling;
18  
19  import picocli.CommandLine.IVersionProvider;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.net.URL;
24  import java.util.Enumeration;
25  import java.util.jar.Attributes;
26  import java.util.jar.Manifest;
27  
28  /**
29   * {@link IVersionProvider} implementation that returns version information from
30   * the package jar file's {@code /META-INF/MANIFEST.MF} file.
31   *
32   * @see <a
33   * href="https://github.com/remkop/picocli/blob/master/picocli-examples/src/main/java/picocli/examples/VersionProviderDemo2.java">PicoCLI
34   * version provider demo</a>
35   */
36  class ManifestVersionProvider implements IVersionProvider {
37      /** {@inheritDoc} */
38      @Override
39      public String[] getVersion() throws Exception {
40          final Enumeration<URL> resources = Thread.currentThread().getContextClassLoader()
41                                             .getResources("META-INF/MANIFEST.MF");
42          while (resources.hasMoreElements()) {
43              final URL url = resources.nextElement();
44              try (InputStream stream = url.openStream()) {
45                  final Manifest manifest = new Manifest(stream);
46                  if (isApplicableManifest(manifest)) {
47                      final Attributes attr = manifest.getMainAttributes();
48                      return new String[] {get(attr, "Implementation-Title") + " version \"" +
49                                           get(attr, "Implementation-Version") + "\""};
50                  }
51              } catch (final IOException ex) {
52                  return new String[] {"Unable to read from " + url + ". " + ex};
53              }
54          }
55          return new String[0];
56      }
57  
58      /**
59       * Checks if this is the applicable manifest for the package.
60       *
61       * @param manifest The manifest.
62       * @return true if is the applicable manifest
63       */
64      private static boolean isApplicableManifest(Manifest manifest) {
65          final Attributes attributes = manifest.getMainAttributes();
66          return "org.apache.commons.rng.examples.sampling".equals(get(attributes, "Automatic-Module-Name"));
67      }
68  
69      /**
70       * Gets the named object from the attributes using the key.
71       *
72       * @param attributes The attributes.
73       * @param key The key.
74       * @return the object
75       */
76      private static Object get(Attributes attributes, String key) {
77          return attributes.get(new Attributes.Name(key));
78      }
79  }