Implemented SystemInfo for windows.

This commit is contained in:
Adam Murdoch
2012-09-09 17:07:38 +10:00
parent dd255be667
commit de4e340e2c
5 changed files with 784 additions and 721 deletions

View File

@@ -1,240 +1,266 @@
#ifdef WIN32
#include "native.h"
#include "generic.h"
#include <windows.h>
/*
* Marks the given result as failed, using the current value of GetLastError()
*/
void mark_failed_with_errno(JNIEnv *env, const char* message, jobject result) {
mark_failed_with_code(env, message, GetLastError(), result);
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_NativeLibraryFunctions_getPlatform(JNIEnv *env, jclass target) {
}
/*
* Process functions
*/
JNIEXPORT jint JNICALL
Java_net_rubygrapefruit_platform_internal_jni_PosixProcessFunctions_getPid(JNIEnv *env, jclass target) {
return GetCurrentProcessId();
}
/*
* Console functions
*/
HANDLE getHandle(JNIEnv *env, int output, jobject result) {
HANDLE handle = output == 1 ? GetStdHandle(STD_OUTPUT_HANDLE) : GetStdHandle(STD_ERROR_HANDLE);
if (handle == INVALID_HANDLE_VALUE) {
mark_failed_with_errno(env, "could not get console handle", result);
return NULL;
}
return handle;
}
JNIEXPORT jboolean JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_isConsole(JNIEnv *env, jclass target, jint output, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
HANDLE handle = getHandle(env, output, result);
if (handle == NULL) {
return JNI_FALSE;
}
if (!GetConsoleScreenBufferInfo(handle, &console_info)) {
if (GetLastError() == ERROR_INVALID_HANDLE) {
return JNI_FALSE;
}
mark_failed_with_errno(env, "could not get console buffer", result);
return JNI_FALSE;
}
return JNI_TRUE;
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_getConsoleSize(JNIEnv *env, jclass target, jint output, jobject dimension, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
HANDLE handle = getHandle(env, output, result);
if (handle == NULL) {
mark_failed_with_message(env, "not a console", result);
return;
}
if (!GetConsoleScreenBufferInfo(handle, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result);
return;
}
jclass dimensionClass = env->GetObjectClass(dimension);
jfieldID widthField = env->GetFieldID(dimensionClass, "cols", "I");
env->SetIntField(dimension, widthField, console_info.srWindow.Right - console_info.srWindow.Left + 1);
jfieldID heightField = env->GetFieldID(dimensionClass, "rows", "I");
env->SetIntField(dimension, heightField, console_info.srWindow.Bottom - console_info.srWindow.Top + 1);
}
HANDLE current_console = NULL;
WORD original_attributes = 0;
WORD current_attributes = 0;
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_initConsole(JNIEnv *env, jclass target, jint output, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
HANDLE handle = getHandle(env, output, result);
if (handle == NULL) {
mark_failed_with_message(env, "not a terminal", result);
return;
}
if (!GetConsoleScreenBufferInfo(handle, &console_info)) {
if (GetLastError() == ERROR_INVALID_HANDLE) {
mark_failed_with_message(env, "not a console", result);
} else {
mark_failed_with_errno(env, "could not get console buffer", result);
}
return;
}
current_console = handle;
original_attributes = console_info.wAttributes;
current_attributes = original_attributes;
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_normal(env, target, result);
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_bold(JNIEnv *env, jclass target, jobject result) {
current_attributes |= FOREGROUND_INTENSITY;
if (!SetConsoleTextAttribute(current_console, current_attributes)) {
mark_failed_with_errno(env, "could not set text attributes", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_normal(JNIEnv *env, jclass target, jobject result) {
current_attributes &= ~FOREGROUND_INTENSITY;
SetConsoleTextAttribute(current_console, current_attributes);
if (!SetConsoleTextAttribute(current_console, current_attributes)) {
mark_failed_with_errno(env, "could not set text attributes", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_reset(JNIEnv *env, jclass target, jobject result) {
SetConsoleTextAttribute(current_console, original_attributes);
if (!SetConsoleTextAttribute(current_console, current_attributes)) {
mark_failed_with_errno(env, "could not set text attributes", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_foreground(JNIEnv *env, jclass target, jint color, jobject result) {
current_attributes &= ~ (FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_GREEN);
switch (color) {
case 0:
break;
case 1:
current_attributes |= FOREGROUND_RED;
break;
case 2:
current_attributes |= FOREGROUND_GREEN;
break;
case 3:
current_attributes |= FOREGROUND_RED|FOREGROUND_GREEN;
break;
case 4:
current_attributes |= FOREGROUND_BLUE;
break;
case 5:
current_attributes |= FOREGROUND_RED|FOREGROUND_BLUE;
break;
case 6:
current_attributes |= FOREGROUND_GREEN|FOREGROUND_BLUE;
break;
default:
current_attributes |= FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE;
break;
}
SetConsoleTextAttribute(current_console, current_attributes);
if (!SetConsoleTextAttribute(current_console, current_attributes)) {
mark_failed_with_errno(env, "could not set text attributes", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_left(JNIEnv *env, jclass target, jint count, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result);
return;
}
console_info.dwCursorPosition.X -= count;
if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) {
mark_failed_with_errno(env, "could not set cursor position", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_right(JNIEnv *env, jclass target, jint count, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result);
return;
}
console_info.dwCursorPosition.X += count;
if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) {
mark_failed_with_errno(env, "could not set cursor position", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_up(JNIEnv *env, jclass target, jint count, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result);
return;
}
console_info.dwCursorPosition.Y -= count;
if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) {
mark_failed_with_errno(env, "could not set cursor position", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_down(JNIEnv *env, jclass target, jint count, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result);
return;
}
console_info.dwCursorPosition.Y += count;
if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) {
mark_failed_with_errno(env, "could not set cursor position", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_startLine(JNIEnv *env, jclass target, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result);
return;
}
console_info.dwCursorPosition.X = 0;
if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) {
mark_failed_with_errno(env, "could not set cursor position", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_clearToEndOfLine(JNIEnv *env, jclass target, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result);
return;
}
for (int i = console_info.dwCursorPosition.X; i < console_info.dwSize.X; i++) {
WriteConsole(current_console, " ", 1, NULL, NULL);
}
}
#endif
#ifdef WIN32
#include "native.h"
#include "generic.h"
#include <windows.h>
/*
* Marks the given result as failed, using the current value of GetLastError()
*/
void mark_failed_with_errno(JNIEnv *env, const char* message, jobject result) {
mark_failed_with_code(env, message, GetLastError(), result);
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_NativeLibraryFunctions_getSystemInfo(JNIEnv *env, jclass target, jobject info, jobject result) {
jclass infoClass = env->GetObjectClass(info);
OSVERSIONINFOEX versionInfo;
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if (GetVersionEx((OSVERSIONINFO*)&versionInfo) == 0) {
mark_failed_with_errno(env, "could not get version info", result);
return;
}
SYSTEM_INFO systemInfo;
GetNativeSystemInfo(&systemInfo);
jstring arch = NULL;
if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
arch = env->NewStringUTF("amd64");
} else if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) {
arch = env->NewStringUTF("x86");
} else if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) {
arch = env->NewStringUTF("ia64");
} else {
arch = env->NewStringUTF("unknown");
}
jmethodID method = env->GetMethodID(infoClass, "windows", "(IIIZLjava/lang/String;)V");
env->CallVoidMethod(info, method, versionInfo.dwMajorVersion, versionInfo.dwMinorVersion,
versionInfo.dwBuildNumber, versionInfo.wProductType == VER_NT_WORKSTATION,
arch);
}
/*
* Process functions
*/
JNIEXPORT jint JNICALL
Java_net_rubygrapefruit_platform_internal_jni_PosixProcessFunctions_getPid(JNIEnv *env, jclass target) {
return GetCurrentProcessId();
}
/*
* Console functions
*/
HANDLE getHandle(JNIEnv *env, int output, jobject result) {
HANDLE handle = output == 1 ? GetStdHandle(STD_OUTPUT_HANDLE) : GetStdHandle(STD_ERROR_HANDLE);
if (handle == INVALID_HANDLE_VALUE) {
mark_failed_with_errno(env, "could not get console handle", result);
return NULL;
}
return handle;
}
JNIEXPORT jboolean JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_isConsole(JNIEnv *env, jclass target, jint output, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
HANDLE handle = getHandle(env, output, result);
if (handle == NULL) {
return JNI_FALSE;
}
if (!GetConsoleScreenBufferInfo(handle, &console_info)) {
if (GetLastError() == ERROR_INVALID_HANDLE) {
return JNI_FALSE;
}
mark_failed_with_errno(env, "could not get console buffer", result);
return JNI_FALSE;
}
return JNI_TRUE;
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_getConsoleSize(JNIEnv *env, jclass target, jint output, jobject dimension, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
HANDLE handle = getHandle(env, output, result);
if (handle == NULL) {
mark_failed_with_message(env, "not a console", result);
return;
}
if (!GetConsoleScreenBufferInfo(handle, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result);
return;
}
jclass dimensionClass = env->GetObjectClass(dimension);
jfieldID widthField = env->GetFieldID(dimensionClass, "cols", "I");
env->SetIntField(dimension, widthField, console_info.srWindow.Right - console_info.srWindow.Left + 1);
jfieldID heightField = env->GetFieldID(dimensionClass, "rows", "I");
env->SetIntField(dimension, heightField, console_info.srWindow.Bottom - console_info.srWindow.Top + 1);
}
HANDLE current_console = NULL;
WORD original_attributes = 0;
WORD current_attributes = 0;
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_initConsole(JNIEnv *env, jclass target, jint output, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
HANDLE handle = getHandle(env, output, result);
if (handle == NULL) {
mark_failed_with_message(env, "not a terminal", result);
return;
}
if (!GetConsoleScreenBufferInfo(handle, &console_info)) {
if (GetLastError() == ERROR_INVALID_HANDLE) {
mark_failed_with_message(env, "not a console", result);
} else {
mark_failed_with_errno(env, "could not get console buffer", result);
}
return;
}
current_console = handle;
original_attributes = console_info.wAttributes;
current_attributes = original_attributes;
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_normal(env, target, result);
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_bold(JNIEnv *env, jclass target, jobject result) {
current_attributes |= FOREGROUND_INTENSITY;
if (!SetConsoleTextAttribute(current_console, current_attributes)) {
mark_failed_with_errno(env, "could not set text attributes", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_normal(JNIEnv *env, jclass target, jobject result) {
current_attributes &= ~FOREGROUND_INTENSITY;
SetConsoleTextAttribute(current_console, current_attributes);
if (!SetConsoleTextAttribute(current_console, current_attributes)) {
mark_failed_with_errno(env, "could not set text attributes", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_reset(JNIEnv *env, jclass target, jobject result) {
SetConsoleTextAttribute(current_console, original_attributes);
if (!SetConsoleTextAttribute(current_console, current_attributes)) {
mark_failed_with_errno(env, "could not set text attributes", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_foreground(JNIEnv *env, jclass target, jint color, jobject result) {
current_attributes &= ~ (FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_GREEN);
switch (color) {
case 0:
break;
case 1:
current_attributes |= FOREGROUND_RED;
break;
case 2:
current_attributes |= FOREGROUND_GREEN;
break;
case 3:
current_attributes |= FOREGROUND_RED|FOREGROUND_GREEN;
break;
case 4:
current_attributes |= FOREGROUND_BLUE;
break;
case 5:
current_attributes |= FOREGROUND_RED|FOREGROUND_BLUE;
break;
case 6:
current_attributes |= FOREGROUND_GREEN|FOREGROUND_BLUE;
break;
default:
current_attributes |= FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE;
break;
}
SetConsoleTextAttribute(current_console, current_attributes);
if (!SetConsoleTextAttribute(current_console, current_attributes)) {
mark_failed_with_errno(env, "could not set text attributes", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_left(JNIEnv *env, jclass target, jint count, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result);
return;
}
console_info.dwCursorPosition.X -= count;
if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) {
mark_failed_with_errno(env, "could not set cursor position", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_right(JNIEnv *env, jclass target, jint count, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result);
return;
}
console_info.dwCursorPosition.X += count;
if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) {
mark_failed_with_errno(env, "could not set cursor position", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_up(JNIEnv *env, jclass target, jint count, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result);
return;
}
console_info.dwCursorPosition.Y -= count;
if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) {
mark_failed_with_errno(env, "could not set cursor position", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_down(JNIEnv *env, jclass target, jint count, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result);
return;
}
console_info.dwCursorPosition.Y += count;
if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) {
mark_failed_with_errno(env, "could not set cursor position", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_startLine(JNIEnv *env, jclass target, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result);
return;
}
console_info.dwCursorPosition.X = 0;
if (!SetConsoleCursorPosition(current_console, console_info.dwCursorPosition)) {
mark_failed_with_errno(env, "could not set cursor position", result);
}
}
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_WindowsConsoleFunctions_clearToEndOfLine(JNIEnv *env, jclass target, jobject result) {
CONSOLE_SCREEN_BUFFER_INFO console_info;
if (!GetConsoleScreenBufferInfo(current_console, &console_info)) {
mark_failed_with_errno(env, "could not get console buffer", result);
return;
}
for (int i = console_info.dwCursorPosition.X; i < console_info.dwSize.X; i++) {
WriteConsole(current_console, " ", 1, NULL, NULL);
}
}
#endif

View File

@@ -1,21 +1,53 @@
package net.rubygrapefruit.platform.internal;
import net.rubygrapefruit.platform.SystemInfo;
public class MutableSystemInfo implements SystemInfo {
public String osName;
public String osVersion;
public String machineArchitecture;
public String getKernelName() {
return osName;
}
public String getKernelVersion() {
return osVersion;
}
public String getMachineArchitecture() {
return machineArchitecture;
}
}
package net.rubygrapefruit.platform.internal;
import net.rubygrapefruit.platform.SystemInfo;
public class MutableSystemInfo implements SystemInfo {
public String osName;
public String osVersion;
public String machineArchitecture;
public String getKernelName() {
return osName;
}
public String getKernelVersion() {
return osVersion;
}
public String getMachineArchitecture() {
return machineArchitecture;
}
void windows(int major, int minor, int build, boolean workstation, String arch) {
osName = toWindowsVersionName(major, minor, workstation);
osVersion = String.format("%s.%s (build %s)", major, minor, build);
machineArchitecture = arch;
}
private String toWindowsVersionName(int major, int minor, boolean workstation) {
switch (major) {
case 5:
switch (minor) {
case 0:
return "Windows 2000";
case 1:
return "Windows XP";
case 2:
return "Windows Server 2003";
}
break;
case 6:
switch (minor) {
case 0:
return workstation ? "Windows Vista" : "Windows Server 2008";
case 1:
return workstation ? "Windows 7" : "Windows Server 2008 R2";
case 2:
return workstation ? "Windows 8" : "Windows Server 2012";
}
break;
}
return "Windows (unknown version)";
}
}

View File

@@ -1,145 +1,152 @@
package net.rubygrapefruit.platform.internal;
import net.rubygrapefruit.platform.*;
import net.rubygrapefruit.platform.Process;
public abstract class Platform {
private static Platform platform;
public static Platform current() {
synchronized (Platform.class) {
if (platform == null) {
String osName = getOperatingSystem().toLowerCase();
String arch = getArchitecture();
if (osName.contains("windows")) {
platform = new Windows();
} else if (osName.contains("linux")) {
platform = new Linux();
} else if (osName.contains("os x") && (arch.equals("i386") || arch.equals("x86_64"))) {
platform = new OsX();
} else if (osName.contains("sunos")) {
platform = new Solaris();
} else {
platform = new Unsupported();
}
}
return platform;
}
}
public boolean isWindows() {
return false;
}
public <T extends NativeIntegration> T get(Class<T> type) {
throw new NativeIntegrationUnavailableException(String.format("Native integration %s is not supported on this operating system (%s %s)",
type.getSimpleName(), getOperatingSystem(), getArchitecture()));
}
public abstract String getLibraryName() throws NativeIntegrationUnavailableException;
private static class Windows extends Platform {
@Override
public boolean isWindows() {
return true;
}
@Override
public String getLibraryName() {
return "native-platform-win32.dll";
}
@Override
public <T extends NativeIntegration> T get(Class<T> type) {
if (type.equals(net.rubygrapefruit.platform.Process.class)) {
return type.cast(new DefaultProcess());
}
if (type.equals(Terminals.class)) {
return type.cast(new WindowsTerminals());
}
return super.get(type);
}
}
private static abstract class Posix extends Platform {
@Override
public <T extends NativeIntegration> T get(Class<T> type) {
if (type.equals(PosixFile.class)) {
return type.cast(new DefaultPosixFile());
}
if (type.equals(Process.class)) {
return type.cast(new DefaultProcess());
}
if (type.equals(Terminals.class)) {
return type.cast(new TerminfoTerminals());
}
if (type.equals(SystemInfo.class)) {
return type.cast(new DefaultSystemInfo());
}
return super.get(type);
}
}
private abstract static class Unix extends Posix {
}
private static class Linux extends Unix {
@Override
public <T extends NativeIntegration> T get(Class<T> type) {
if (type.equals(FileSystems.class)) {
return type.cast(new PosixFileSystems());
}
return super.get(type);
}
@Override
public String getLibraryName() {
if (getArchitecture().equals("amd64")) {
return "libnative-platform-linux-amd64.so";
}
if (getArchitecture().equals("i386") || getArchitecture().equals("x86")) {
return "libnative-platform-linux-i386.so";
}
throw new NativeIntegrationUnavailableException(String.format(
"Native integration is not available for this architecture (%s) on Linux.", getArchitecture()));
}
}
private static String getArchitecture() {
return System.getProperty("os.arch");
}
private static class Solaris extends Unix {
@Override
public String getLibraryName() {
return "libnative-platform-solaris.so";
}
}
private static class OsX extends Posix {
@Override
public <T extends NativeIntegration> T get(Class<T> type) {
if (type.equals(FileSystems.class)) {
return type.cast(new PosixFileSystems());
}
return super.get(type);
}
@Override
public String getLibraryName() {
return "libnative-platform-osx-universal.dylib";
}
}
private static class Unsupported extends Platform {
public String getLibraryName() {
throw new NativeIntegrationUnavailableException(String.format(
"Native integration is not available for this operating system (%s %s)", getOperatingSystem(),
getArchitecture()));
}
}
private static String getOperatingSystem() {
return System.getProperty("os.name");
}
}
package net.rubygrapefruit.platform.internal;
import net.rubygrapefruit.platform.*;
import net.rubygrapefruit.platform.Process;
public abstract class Platform {
private static Platform platform;
public static Platform current() {
synchronized (Platform.class) {
if (platform == null) {
String osName = getOperatingSystem().toLowerCase();
String arch = getArchitecture();
if (osName.contains("windows")) {
platform = new Windows();
} else if (osName.contains("linux")) {
platform = new Linux();
} else if (osName.contains("os x") && (arch.equals("i386") || arch.equals("x86_64"))) {
platform = new OsX();
} else if (osName.contains("sunos")) {
platform = new Solaris();
} else {
platform = new Unsupported();
}
}
return platform;
}
}
public boolean isWindows() {
return false;
}
public <T extends NativeIntegration> T get(Class<T> type) {
throw new NativeIntegrationUnavailableException(String.format("Native integration %s is not supported on this operating system (%s %s)",
type.getSimpleName(), getOperatingSystem(), getArchitecture()));
}
public abstract String getLibraryName() throws NativeIntegrationUnavailableException;
private static class Windows extends Platform {
@Override
public boolean isWindows() {
return true;
}
@Override
public String getLibraryName() {
if (getArchitecture().equals("x86")) {
return "native-platform-windows-i386.dll";
}
throw new NativeIntegrationUnavailableException(String.format(
"Native integration is not available for this architecture (%s) on Windows.", getArchitecture()));
}
@Override
public <T extends NativeIntegration> T get(Class<T> type) {
if (type.equals(net.rubygrapefruit.platform.Process.class)) {
return type.cast(new DefaultProcess());
}
if (type.equals(Terminals.class)) {
return type.cast(new WindowsTerminals());
}
if (type.equals(SystemInfo.class)) {
return type.cast(new DefaultSystemInfo());
}
return super.get(type);
}
}
private static abstract class Posix extends Platform {
@Override
public <T extends NativeIntegration> T get(Class<T> type) {
if (type.equals(PosixFile.class)) {
return type.cast(new DefaultPosixFile());
}
if (type.equals(Process.class)) {
return type.cast(new DefaultProcess());
}
if (type.equals(Terminals.class)) {
return type.cast(new TerminfoTerminals());
}
if (type.equals(SystemInfo.class)) {
return type.cast(new DefaultSystemInfo());
}
return super.get(type);
}
}
private abstract static class Unix extends Posix {
}
private static class Linux extends Unix {
@Override
public <T extends NativeIntegration> T get(Class<T> type) {
if (type.equals(FileSystems.class)) {
return type.cast(new PosixFileSystems());
}
return super.get(type);
}
@Override
public String getLibraryName() {
if (getArchitecture().equals("amd64")) {
return "libnative-platform-linux-amd64.so";
}
if (getArchitecture().equals("i386") || getArchitecture().equals("x86")) {
return "libnative-platform-linux-i386.so";
}
throw new NativeIntegrationUnavailableException(String.format(
"Native integration is not available for this architecture (%s) on Linux.", getArchitecture()));
}
}
private static String getArchitecture() {
return System.getProperty("os.arch");
}
private static class Solaris extends Unix {
@Override
public String getLibraryName() {
return "libnative-platform-solaris.so";
}
}
private static class OsX extends Posix {
@Override
public <T extends NativeIntegration> T get(Class<T> type) {
if (type.equals(FileSystems.class)) {
return type.cast(new PosixFileSystems());
}
return super.get(type);
}
@Override
public String getLibraryName() {
return "libnative-platform-osx-universal.dylib";
}
}
private static class Unsupported extends Platform {
public String getLibraryName() {
throw new NativeIntegrationUnavailableException(String.format(
"Native integration is not available for this operating system (%s %s)", getOperatingSystem(),
getArchitecture()));
}
}
private static String getOperatingSystem() {
return System.getProperty("os.name");
}
}