OsInfo.java

  1.  /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. package org.apache.commons.crypto;

  19. import java.io.File;
  20. import java.io.IOException;
  21. import java.util.HashMap;
  22. import java.util.Locale;

  23. /**
  24.  * Provides OS name and architecture name. Used by the JNI make process to get
  25.  * information from the build environment.
  26.  */
  27. final class OsInfo {

  28.     private final static HashMap<String, String> archMapping = new HashMap<>();

  29.     /**
  30.      * The constant string represents for X86 architecture, the value is:
  31.      * {@value #X86}.
  32.      */
  33.     static final String X86 = "x86";

  34.     /**
  35.      * The constant string represents for X86_64 architecture, the value is:
  36.      * {@value #X86_64}.
  37.      */
  38.     static final String X86_64 = "x86_64";

  39.     /**
  40.      * The constant string represents for IA64_32 architecture, the value is:
  41.      * {@value #IA64_32}.
  42.      */
  43.     static final String IA64_32 = "ia64_32";

  44.     /**
  45.      * The constant string represents for IA64 architecture, the value is:
  46.      * {@value #IA64}.
  47.      */
  48.     static final String IA64 = "ia64";

  49.     /**
  50.      * The constant string represents for PPC architecture, the value is:
  51.      * {@value #PPC}.
  52.      */
  53.     static final String PPC = "ppc";

  54.     /**
  55.      * The constant string represents for PPC64 architecture, the value is:
  56.      * {@value #PPC64}.
  57.      */
  58.     static final String PPC64 = "ppc64";

  59.     static {
  60.         // x86 mappings
  61.         archMapping.put(X86, X86);
  62.         archMapping.put("i386", X86);
  63.         archMapping.put("i486", X86);
  64.         archMapping.put("i586", X86);
  65.         archMapping.put("i686", X86);
  66.         archMapping.put("pentium", X86);

  67.         // x86_64 mappings
  68.         archMapping.put(X86_64, X86_64);
  69.         archMapping.put("amd64", X86_64);
  70.         archMapping.put("em64t", X86_64);
  71.         archMapping.put("universal", X86_64); // Needed for openjdk7 in Mac

  72.         // Itanium 64-bit mappings
  73.         archMapping.put(IA64, IA64);
  74.         archMapping.put("ia64w", IA64);

  75.         // Itanium 32-bit mappings, usually an HP-UX construct
  76.         archMapping.put(IA64_32, IA64_32);
  77.         archMapping.put("ia64n", IA64_32);

  78.         // PowerPC mappings
  79.         archMapping.put(PPC, PPC);
  80.         archMapping.put("power", PPC);
  81.         archMapping.put("powerpc", PPC);
  82.         archMapping.put("power_pc", PPC);
  83.         archMapping.put("power_rs", PPC);

  84.         // PowerPC 64bit mappings
  85.         archMapping.put(PPC64, PPC64);
  86.         archMapping.put("power64", PPC64);
  87.         archMapping.put("powerpc64", PPC64);
  88.         archMapping.put("power_pc64", PPC64);
  89.         archMapping.put("power_rs64", PPC64);
  90.     }

  91.     /**
  92.      * Gets the architecture name.
  93.      *
  94.      * @return the architecture name.
  95.      */
  96.     static String getArchName() {
  97.         // if running Linux on ARM, need to determine ABI of JVM
  98.         final String osArch = System.getProperty("os.arch");
  99.         if (osArch.startsWith("arm") && getOsNameProperty().contains("Linux")) {
  100.             final String javaHome = System.getProperty("java.home");
  101.             try {
  102.                 // determine if first JVM found uses ARM hard-float ABI
  103.                 final String[] cmdarray = { "/bin/sh", "-c",
  104.                         "find '" + javaHome + "' -name 'libjvm.so' | head -1 | xargs readelf -A | grep 'Tag_ABI_VFP_args: VFP registers'" };
  105.                 final int exitCode = Runtime.getRuntime().exec(cmdarray).waitFor();
  106.                 if (exitCode == 0) {
  107.                     return "armhf";
  108.                 }
  109.             } catch (final IOException | InterruptedException e) { // NOPMD
  110.                 // ignored: fall back to "arm" arch (soft-float ABI)
  111.             }
  112.         } else {
  113.             final String string = archMapping.get(osArch.toLowerCase(Locale.US));
  114.             if (string != null) {
  115.                 return string;
  116.             }
  117.         }
  118.         return translateArchNameToFolderName(osArch);
  119.     }

  120.     /**
  121.      * Gets the native lib folder.
  122.      *
  123.      * @return the current OS's native lib folder.
  124.      */
  125.     static String getNativeLibFolderPathForCurrentOS() {
  126.         return getOSName() + File.separator + getArchName();
  127.     }

  128.     /**
  129.      * Gets the OS name.
  130.      *
  131.      * @return the OS name.
  132.      */
  133.     static String getOSName() {
  134.         return translateOSNameToFolderName(getOsNameProperty());
  135.     }

  136.     static String getOsNameProperty() {
  137.         return System.getProperty("os.name");
  138.     }

  139.     /**
  140.      * The main method. This is used by the JNI make processing in Makefile.common
  141.      *
  142.      * @param args the argv.
  143.      */
  144.     public static void main(final String[] args) {
  145.         if (args.length >= 1) {
  146.             if ("--os".equals(args[0])) {
  147.                 System.out.println(getOSName());
  148.                 return;
  149.             }
  150.             if ("--arch".equals(args[0])) {
  151.                 System.out.println(getArchName());
  152.                 return;
  153.             }
  154.         }

  155.         System.out.println(getNativeLibFolderPathForCurrentOS());
  156.     }

  157.     /**
  158.      * Translates the architecture name to folder name.
  159.      *
  160.      * @param archName the architecture name.
  161.      * @return the folder name.
  162.      */
  163.     private static String translateArchNameToFolderName(final String archName) {
  164.         return archName.replaceAll("\\W", "");
  165.     }

  166.     /**
  167.      * Translates the OS name to folder name.
  168.      *
  169.      * @param osName the OS name.
  170.      * @return the folder name.
  171.      */
  172.     private static String translateOSNameToFolderName(final String osName) {
  173.         if (osName.contains("Windows")) {
  174.             return "Windows";
  175.         }
  176.         if (osName.contains("Mac")) {
  177.             return "Mac";
  178.         }
  179.         if (osName.contains("Linux")) {
  180.             return "Linux";
  181.         }
  182.         if (osName.contains("AIX")) {
  183.             return "AIX";
  184.         }
  185.         return osName.replaceAll("\\W", "");
  186.     }

  187.     /**
  188.      * The private constructor of {@link OsInfo}.
  189.      */
  190.     private OsInfo() {
  191.     }
  192. }