View Javadoc
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  
20  import java.io.File;
21  import java.io.IOException;
22  import java.util.HashMap;
23  import java.util.Locale;
24  
25  /**
26   * Provides OS name and architecture name. Used by the JNI make process to get
27   * information from the build environment.
28   */
29  final class OsInfo {
30  
31      private final static HashMap<String, String> archMapping = new HashMap<>();
32  
33      /**
34       * The constant string represents for X86 architecture, the value is:
35       * {@value #X86}.
36       */
37      static final String X86 = "x86";
38  
39      /**
40       * The constant string represents for X86_64 architecture, the value is:
41       * {@value #X86_64}.
42       */
43      static final String X86_64 = "x86_64";
44  
45      /**
46       * The constant string represents for IA64_32 architecture, the value is:
47       * {@value #IA64_32}.
48       */
49      static final String IA64_32 = "ia64_32";
50  
51      /**
52       * The constant string represents for IA64 architecture, the value is:
53       * {@value #IA64}.
54       */
55      static final String IA64 = "ia64";
56  
57      /**
58       * The constant string represents for PPC architecture, the value is:
59       * {@value #PPC}.
60       */
61      static final String PPC = "ppc";
62  
63      /**
64       * The constant string represents for PPC64 architecture, the value is:
65       * {@value #PPC64}.
66       */
67      static final String PPC64 = "ppc64";
68  
69      static {
70          // x86 mappings
71          archMapping.put(X86, X86);
72          archMapping.put("i386", X86);
73          archMapping.put("i486", X86);
74          archMapping.put("i586", X86);
75          archMapping.put("i686", X86);
76          archMapping.put("pentium", X86);
77  
78          // x86_64 mappings
79          archMapping.put(X86_64, X86_64);
80          archMapping.put("amd64", X86_64);
81          archMapping.put("em64t", X86_64);
82          archMapping.put("universal", X86_64); // Needed for openjdk7 in Mac
83  
84          // Itanium 64-bit mappings
85          archMapping.put(IA64, IA64);
86          archMapping.put("ia64w", IA64);
87  
88          // Itanium 32-bit mappings, usually an HP-UX construct
89          archMapping.put(IA64_32, IA64_32);
90          archMapping.put("ia64n", IA64_32);
91  
92          // PowerPC mappings
93          archMapping.put(PPC, PPC);
94          archMapping.put("power", PPC);
95          archMapping.put("powerpc", PPC);
96          archMapping.put("power_pc", PPC);
97          archMapping.put("power_rs", PPC);
98  
99          // PowerPC 64bit mappings
100         archMapping.put(PPC64, PPC64);
101         archMapping.put("power64", PPC64);
102         archMapping.put("powerpc64", PPC64);
103         archMapping.put("power_pc64", PPC64);
104         archMapping.put("power_rs64", PPC64);
105     }
106 
107     /**
108      * Gets the architecture name.
109      *
110      * @return the architecture name.
111      */
112     static String getArchName() {
113         // if running Linux on ARM, need to determine ABI of JVM
114         final String osArch = System.getProperty("os.arch");
115         if (osArch.startsWith("arm") && getOsNameProperty().contains("Linux")) {
116             final String javaHome = System.getProperty("java.home");
117             try {
118                 // determine if first JVM found uses ARM hard-float ABI
119                 final String[] cmdarray = { "/bin/sh", "-c",
120                         "find '" + javaHome + "' -name 'libjvm.so' | head -1 | xargs readelf -A | grep 'Tag_ABI_VFP_args: VFP registers'" };
121                 final int exitCode = Runtime.getRuntime().exec(cmdarray).waitFor();
122                 if (exitCode == 0) {
123                     return "armhf";
124                 }
125             } catch (final IOException | InterruptedException e) { // NOPMD
126                 // ignored: fall back to "arm" arch (soft-float ABI)
127             }
128         } else {
129             final String string = archMapping.get(osArch.toLowerCase(Locale.US));
130             if (string != null) {
131                 return string;
132             }
133         }
134         return translateArchNameToFolderName(osArch);
135     }
136 
137     /**
138      * Gets the native lib folder.
139      *
140      * @return the current OS's native lib folder.
141      */
142     static String getNativeLibFolderPathForCurrentOS() {
143         return getOSName() + File.separator + getArchName();
144     }
145 
146     /**
147      * Gets the OS name.
148      *
149      * @return the OS name.
150      */
151     static String getOSName() {
152         return translateOSNameToFolderName(getOsNameProperty());
153     }
154 
155     static String getOsNameProperty() {
156         return System.getProperty("os.name");
157     }
158 
159     /**
160      * The main method. This is used by the JNI make processing in Makefile.common
161      *
162      * @param args the argv.
163      */
164     public static void main(final String[] args) {
165         if (args.length >= 1) {
166             if ("--os".equals(args[0])) {
167                 System.out.println(getOSName());
168                 return;
169             }
170             if ("--arch".equals(args[0])) {
171                 System.out.println(getArchName());
172                 return;
173             }
174         }
175 
176         System.out.println(getNativeLibFolderPathForCurrentOS());
177     }
178 
179     /**
180      * Translates the architecture name to folder name.
181      *
182      * @param archName the architecture name.
183      * @return the folder name.
184      */
185     private static String translateArchNameToFolderName(final String archName) {
186         return archName.replaceAll("\\W", "");
187     }
188 
189     /**
190      * Translates the OS name to folder name.
191      *
192      * @param osName the OS name.
193      * @return the folder name.
194      */
195     private static String translateOSNameToFolderName(final String osName) {
196         if (osName.contains("Windows")) {
197             return "Windows";
198         }
199         if (osName.contains("Mac")) {
200             return "Mac";
201         }
202         if (osName.contains("Linux")) {
203             return "Linux";
204         }
205         if (osName.contains("AIX")) {
206             return "AIX";
207         }
208         return osName.replaceAll("\\W", "");
209     }
210 
211     /**
212      * The private constructor of {@link OsInfo}.
213      */
214     private OsInfo() {
215     }
216 }