Repository: lucenenet
Updated Branches:
  refs/heads/master 4782065ca -> c14c27e76


BUG: LUCENENET-593 - Refactored Lucene.Net.Util.Constants so OS identification, 
processor architecture, and framework identification are more reliable. 
Searching for environment variables rather than using well-known APIs was 
causing a null reference exception on Linux.


Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/c14c27e7
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/c14c27e7
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/c14c27e7

Branch: refs/heads/master
Commit: c14c27e7696cf88d628dae83b5190d8c87e9fac8
Parents: 4782065
Author: Shad Storhaug <s...@shadstorhaug.com>
Authored: Sat Aug 12 03:54:13 2017 +0700
Committer: Shad Storhaug <s...@shadstorhaug.com>
Committed: Sat Aug 12 03:54:13 2017 +0700

----------------------------------------------------------------------
 src/Lucene.Net/Support/IO/FileSupport.cs |   5 +-
 src/Lucene.Net/Support/OS.cs             |  74 ---------
 src/Lucene.Net/Util/Constants.cs         | 212 +++++++++++++++-----------
 3 files changed, 123 insertions(+), 168 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c14c27e7/src/Lucene.Net/Support/IO/FileSupport.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Support/IO/FileSupport.cs 
b/src/Lucene.Net/Support/IO/FileSupport.cs
index 4724b26..5cfe641 100644
--- a/src/Lucene.Net/Support/IO/FileSupport.cs
+++ b/src/Lucene.Net/Support/IO/FileSupport.cs
@@ -19,6 +19,7 @@
  *
 */
 
+using Lucene.Net.Util;
 using System;
 using System.IO;
 using System.Linq;
@@ -99,7 +100,7 @@ namespace Lucene.Net.Support.IO
 
             fileStream.Flush(true);
 
-            if (OS.IsWindows)
+            if (Constants.WINDOWS)
             {
 #if NETSTANDARD
                 // Getting the SafeFileHandle property automatically flushes 
the
@@ -110,7 +111,7 @@ namespace Lucene.Net.Support.IO
                     throw new IOException();
 #endif
             }
-            //else if (OS.IsUnix)
+            //else if (Constants.LINUX)
             //{
             //    if (fsync(fileStream.Handle) != IntPtr.Zero)
             //    throw new System.IO.IOException();

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c14c27e7/src/Lucene.Net/Support/OS.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Support/OS.cs b/src/Lucene.Net/Support/OS.cs
deleted file mode 100644
index c74d4de..0000000
--- a/src/Lucene.Net/Support/OS.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-using System;
-using System.Runtime.InteropServices;
-
-namespace Lucene.Net.Support
-{
-    /// <summary>
-    /// Provides platform infos.
-    /// </summary>
-    public class OS
-    {
-        private static bool isUnix;
-        private static bool isWindows;
-
-        static OS()
-        {
-#if NETSTANDARD
-            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
-            {
-                isWindows = true;
-            }
-            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || 
RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
-            {
-                isUnix = true;
-            }
-#else
-            PlatformID pid = Environment.OSVersion.Platform;
-            isWindows = pid == PlatformID.Win32NT || pid == 
PlatformID.Win32Windows;
-
-            // we use integers instead of enum tags because "MacOS"
-            // requires 2.0 SP2, 3.0 SP2 or 3.5 SP1.
-            // 128 is mono's old platform tag for Unix.
-            int id = (int)pid;
-            isUnix = id == 4 || id == 6 || id == 128;
-#endif
-        }
-
-        /// <summary>
-        /// Whether we run under a Unix platform.
-        /// </summary>
-        public static bool IsUnix
-        {
-            get { return isUnix; }
-        }
-
-        /// <summary>
-        /// Whether we run under a supported Windows platform.
-        /// </summary>
-        public static bool IsWindows
-        {
-            get { return isWindows; }
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/c14c27e7/src/Lucene.Net/Util/Constants.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net/Util/Constants.cs b/src/Lucene.Net/Util/Constants.cs
index 5dfd556..1b9a12a 100644
--- a/src/Lucene.Net/Util/Constants.cs
+++ b/src/Lucene.Net/Util/Constants.cs
@@ -1,10 +1,8 @@
 using System;
-using System.Linq;
-using System.Reflection;
 #if NETSTANDARD
 using System.Runtime.InteropServices;
 #else
-using System.Diagnostics;
+using Microsoft.Win32;
 #endif
 using System.Text.RegularExpressions;
 
@@ -37,7 +35,7 @@ namespace Lucene.Net.Util
         }
 
         // LUCENENET NOTE: IMPORTANT - this line must be placed before 
RUNTIME_VERSION so it can be parsed.
-        private static Regex VERSION_PARSER = new 
Regex(@"(\d+\.\d+\.\d+\.\d+)", RegexOptions.Compiled);
+        private static Regex VERSION = new 
Regex(@"(\d+\.\d+(?:\.\d+)?(?:\.\d+)?)", RegexOptions.Compiled);
 
 #if NETSTANDARD
         /// <summary>
@@ -52,7 +50,7 @@ namespace Lucene.Net.Util
         /// NOTE: This was JAVA_VERSION in Lucene
         /// </summary>
 #endif
-        public static readonly string RUNTIME_VERSION = 
GetEnvironmentVariable("RUNTIME_VERSION", "?");
+        public static readonly string RUNTIME_VERSION;
 
 
         /// <summary>
@@ -63,32 +61,37 @@ namespace Lucene.Net.Util
         //public static readonly string JVM_VERSION = 
GetEnvironmentVariable("java.vm.version", "");
         //public static readonly string JVM_NAME = 
GetEnvironmentVariable("java.vm.name", "");
 
+#if NETSTANDARD
+        /// <summary>
+        /// The value of <see cref="RuntimeInformation.OSDescription"/>, 
excluding the version number.</summary>
+#else
         /// <summary>
-        /// The value of <see 
cref="Environment.GetEnvironmentVariable(string)"/> with parameter 
"OS".</summary>
-        public static readonly string OS_NAME = GetEnvironmentVariable("OS", 
"Windows_NT") ?? "Linux";
+        /// The value of <see cref="Environment.OSVersion.VersionString"/>, 
excluding the version number.</summary>
+#endif
+        public static readonly string OS_NAME; // = 
GetEnvironmentVariable("OS", "Windows_NT") ?? "Linux";
 
         /// <summary>
         /// True iff running on Linux. </summary>
-        public static readonly bool LINUX = OS_NAME.StartsWith("Linux", 
StringComparison.Ordinal);
+        public static readonly bool LINUX; // = OS_NAME.StartsWith("Linux", 
StringComparison.Ordinal);
 
         /// <summary>
         /// True iff running on Windows. </summary>
-        public static readonly bool WINDOWS = OS_NAME.StartsWith("Windows", 
StringComparison.Ordinal);
+        public static readonly bool WINDOWS; // = 
OS_NAME.StartsWith("Windows", StringComparison.Ordinal);
 
         /// <summary>
         /// True iff running on SunOS. </summary>
-        public static readonly bool SUN_OS = OS_NAME.StartsWith("SunOS", 
StringComparison.Ordinal);
+        public static readonly bool SUN_OS; // = OS_NAME.StartsWith("SunOS", 
StringComparison.Ordinal);
 
         /// <summary>
         /// True iff running on Mac OS X </summary>
-        public static readonly bool MAC_OS_X = OS_NAME.StartsWith("Mac OS X", 
StringComparison.Ordinal);
+        public static readonly bool MAC_OS_X; // = OS_NAME.StartsWith("Mac OS 
X", StringComparison.Ordinal);
 
         /// <summary>
         /// True iff running on FreeBSD </summary>
-        public static readonly bool FREE_BSD = OS_NAME.StartsWith("FreeBSD", 
StringComparison.Ordinal);
+        public static readonly bool FREE_BSD; // = 
OS_NAME.StartsWith("FreeBSD", StringComparison.Ordinal);
 
-        public static readonly string OS_ARCH = 
GetEnvironmentVariable("PROCESSOR_ARCHITECTURE", "x86");
-        public static readonly string OS_VERSION = 
GetEnvironmentVariable("OS_VERSION", "?");
+        public static readonly string OS_ARCH;
+        public static readonly string OS_VERSION;
 
         //[Obsolete("We are not running on Java for heavens sake")]
         //public static readonly bool JRE_IS_MINIMUM_JAVA6 = (bool)new 
bool?(true); // prevent inlining in foreign class files
@@ -106,65 +109,71 @@ namespace Lucene.Net.Util
 
         static Constants()
         {
+#if NETSTANDARD
+            // Possible Values: X86, X64, Arm, Arm64
+            OS_ARCH = RuntimeInformation.OSArchitecture.ToString();
+#else
+            if (Environment.Is64BitOperatingSystem)
+            {
+                OS_ARCH = "X64";
+            }
+            else
+            {
+                OS_ARCH = "X86";
+            }
+#endif
+
+            // LUCENENET NOTE: In Java, the check is for 
sun.misc.Unsafe.addressSize,
+            // which is the pointer size of the current environment. We don't 
need to
+            // fallback to the OS bitness in .NET because this property is 
reliable and 
+            // doesn't throw exceptions.
             if (IntPtr.Size == 8)
             {
                 RUNTIME_IS_64BIT = true;// 64 bit machine
             }
-            else if (IntPtr.Size == 4)
+            else // if (IntPtr.Size == 4)
             {
                 RUNTIME_IS_64BIT = false;// 32 bit machine
             }
 
-            //LUCENENET NOTE: Well that was all over the top to check 
architechture
-            //bool is64Bit = false;
-            //try
-            //{
-            //  Type unsafeClass = Type.GetType("sun.misc.Unsafe");
-            //  Field unsafeField = unsafeClass.getDeclaredField("theUnsafe");
-            //  unsafeField.Accessible = true;
-            //  object @unsafe = unsafeField.get(null);
-            //  int addressSize = (int)((Number) 
unsafeClass.GetMethod("addressSize").invoke(@unsafe));
-            //  is64Bit = addressSize >= 8;
-            //}
-            //catch (Exception e)
-            //{
-            //  string x = System.getProperty("sun.arch.data.model");
-            //  if (x != null)
-            //  {
-            //    is64Bit = x.IndexOf("64") != -1;
-            //  }
-            //  else
-            //  {
-            //    if (OS_ARCH != null && OS_ARCH.IndexOf("64") != -1)
-            //    {
-            //      is64Bit = true;
-            //    }
-            //    else
-            //    {
-            //      is64Bit = false;
-            //    }
-            //  }
-            //}
-            //RUNTIME_IS_64BIT = is64Bit;
-
-            //// this method only exists in Java 8:
-            //bool v8 = true;
-            //try
-            //{
-            //  typeof(Collections).getMethod("emptySortedSet");
-            //}
-            //catch (NoSuchMethodException nsme)
-            //{
-            //  v8 = false;
-            //}
-            //JRE_IS_MINIMUM_JAVA8 = v8;
-            //Package pkg = LucenePackage.Get();
-            //string v = (pkg == null) ? null : pkg.ImplementationVersion;
-            //if (v == null)
-            //{
-            //  v = MainVersionWithoutAlphaBeta() + "-SNAPSHOT";
-            //}
-            //LUCENE_VERSION = Ident(v);
+#if NETSTANDARD
+            WINDOWS = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
+            LINUX = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
+            MAC_OS_X = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
+            // LUCENENET NOTE: SunOS and FreeBSD not supported
+#else
+            // LUCENENET NOTE: On .NET Framework, our only possibilities are 
Windows or Linux
+            PlatformID pid = Environment.OSVersion.Platform;
+            WINDOWS = pid == PlatformID.Win32NT || pid == 
PlatformID.Win32Windows;
+
+            // we use integers instead of enum tags because "MacOS"
+            // requires 2.0 SP2, 3.0 SP2 or 3.5 SP1.
+            // 128 is mono's old platform tag for Unix.
+            // Reference: https://stackoverflow.com/a/5117005
+            int id = (int)pid;
+            LINUX = id == 4 || id == 6 || id == 128;
+#endif
+
+#if NETSTANDARD
+            RUNTIME_VERSION = 
ExtractString(RuntimeInformation.FrameworkDescription, VERSION);
+#else
+            if (WINDOWS)
+            {
+                RUNTIME_VERSION = GetFramework45PlusFromRegistry();
+            }
+            else
+            {
+                RUNTIME_VERSION = Environment.Version.ToString();
+            }
+#endif
+
+#if NETSTANDARD
+            OS_VERSION = ExtractString(RuntimeInformation.OSDescription, 
VERSION);
+            OS_NAME = VERSION.Replace(RuntimeInformation.OSDescription, 
string.Empty).Trim();
+#else
+            OS_VERSION = Environment.OSVersion.Version.ToString();
+            OS_NAME = VERSION.Replace(Environment.OSVersion.VersionString, 
string.Empty).Trim();
+#endif
         }
 
         // this method prevents inlining the final version constant in 
compiled classes,
@@ -209,48 +218,67 @@ namespace Lucene.Net.Util
         }
 
         private static Regex MAIN_VERSION_WITHOUT_ALPHA_BETA = new 
Regex("\\.", RegexOptions.Compiled);
-        
 
-#region MEDIUM-TRUST Support
+#if !NETSTANDARD
 
-        private static string GetEnvironmentVariable(string variable, string 
defaultValueOnSecurityException)
+        // Gets the .NET Framework Version (if at least 4.5)
+        // Reference: 
https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed
+        private static string GetFramework45PlusFromRegistry()
         {
-            try
+            const string subkey = @"SOFTWARE\Microsoft\NET Framework 
Setup\NDP\v4\Full\";
+
+            // As an alternative, if you know the computers you will query are 
running .NET Framework 4.5 
+            // or later, you can use:
+            using (RegistryKey ndpKey = 
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, 
RegistryView.Registry32).OpenSubKey(subkey))
             {
-                if (variable == "OS_VERSION")
+                if (ndpKey != null && ndpKey.GetValue("Release") != null)
                 {
-#if NETSTANDARD
-                    return RuntimeInformation.OSDescription;
-#else
-                    return Environment.OSVersion.ToString();
-#endif
+                    return 
CheckFor45PlusVersion((int)ndpKey.GetValue("Release"));
                 }
-                               
-#if NETSTANDARD
-                if (variable == "PROCESSOR_ARCHITECTURE") {
-                    
-                    return RuntimeInformation.OSArchitecture.ToString();
-                }
-#endif
-
-                if (variable == "RUNTIME_VERSION")
+                else
                 {
-#if NETSTANDARD
-                    return 
ExtractString(RuntimeInformation.FrameworkDescription, VERSION_PARSER);
-#else
+                    // Fall back to Environment.Version (probably wrong, but 
this is our best guess if the registry check fails)
                     return Environment.Version.ToString();
-#endif
+                    //Console.WriteLine(".NET Framework Version 4.5 or later 
is not detected.");
                 }
+            }
+        }
 
-                return System.Environment.GetEnvironmentVariable(variable);
+        // Checking the version using >= will enable forward compatibility.
+        private static string CheckFor45PlusVersion(int releaseKey)
+        {
+            if (releaseKey >= 460799)
+                return "4.8 or later";
+            if (releaseKey >= 460798)
+                return "4.7";
+            if (releaseKey >= 394802)
+                return "4.6.2";
+            if (releaseKey >= 394254)
+            {
+                return "4.6.1";
+            }
+            if (releaseKey >= 393295)
+            {
+                return "4.6";
+            }
+            if ((releaseKey >= 379893))
+            {
+                return "4.5.2";
             }
-            catch (System.Security.SecurityException)
+            if ((releaseKey >= 378675))
             {
-                return defaultValueOnSecurityException;
+                return "4.5.1";
             }
+            if ((releaseKey >= 378389))
+            {
+                return "4.5";
+            }
+            // This code should never execute. A non-null release key should 
mean
+            // that 4.5 or later is installed.
+            return "No 4.5 or later version detected";
         }
 
-#endregion MEDIUM-TRUST Support
+#endif
 
         // LUCENENET TODO: Move to Support ?
         /// <summary>

Reply via email to