package com.revolsys.jar;
import java.io.File;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import com.revolsys.io.FileUtil;
import com.revolsys.logging.Logs;
import com.revolsys.util.OS;
public class ClasspathNativeLibraryUtil {
private static final Map<String, Boolean> LIBRARY_LOADED_MAP = new HashMap<>();
public static String getLibraryExtension() {
if (OS.IS_WINDOWS) {
return "dll";
} else if (OS.IS_MAC) {
return "dylib";
} else {
return "so";
}
}
public static String getLibraryPrefix() {
if (OS.IS_WINDOWS) {
return "";
} else {
return "lib";
}
}
private static String getOperatingSystemName() {
if (OS.IS_WINDOWS) {
return "winnt";
} else if (OS.IS_MAC) {
return "macosx";
} else if (OS.IS_LINUX) {
return "linux";
} else if (OS.IS_SOLARIS) {
return "solaris";
} else {
return OS.OS_NAME;
}
}
public static boolean loadLibrary(final String name) {
synchronized (LIBRARY_LOADED_MAP) {
final Boolean loaded = LIBRARY_LOADED_MAP.get(name);
if (loaded == null) {
final String prefix = getLibraryPrefix();
final String ext = getLibraryExtension();
final String arch = OS.getArch();
final String operatingSystemName = getOperatingSystemName();
return loadLibrary(prefix, name, arch, operatingSystemName, ext);
} else {
return loaded;
}
}
}
public static boolean loadLibrary(final String path, final String name) {
final URL url = ClasspathNativeLibraryUtil.class.getResource(path);
boolean loaded = false;
if (url == null) {
try {
System.loadLibrary(name);
loaded = true;
} catch (final Throwable e) {
Logs.debug(ClasspathNativeLibraryUtil.class, "Unable to load shared library " + name, e);
}
} else {
try {
final File directory = FileUtil.newTempDirectory("jni", "name");
final File file = new File(directory, name + ".dll");
file.deleteOnExit();
FileUtil.copy(url.openStream(), file);
System.load(file.getCanonicalPath());
loaded = true;
} catch (final Throwable e) {
Logs.error(ClasspathNativeLibraryUtil.class,
"Unable to load shared library from classpath " + url, e);
}
}
LIBRARY_LOADED_MAP.put(name, loaded);
return loaded;
}
private static boolean loadLibrary(final String prefix, final String name, final String arch,
final String operatingSystemName, final String ext) {
boolean loaded = false;
final String fileName = prefix + name + "." + ext;
final String libraryName = "/native/" + operatingSystemName + "/" + arch + "/" + fileName;
final URL url = ClasspathNativeLibraryUtil.class.getResource(libraryName);
if (url == null) {
if (arch.equals("x86_64")) {
loaded = loadLibrary(prefix, libraryName, "x86", operatingSystemName, ext);
} else {
try {
System.loadLibrary(name);
loaded = true;
} catch (final Throwable e) {
Logs.debug(ClasspathNativeLibraryUtil.class,
"Unable to load shared library from classpath " + libraryName + " " + fileName, e);
}
}
} else {
try {
final File directory = FileUtil.newTempDirectory("jni", "name");
final File file = new File(directory, fileName);
file.deleteOnExit();
FileUtil.copy(url.openStream(), file);
System.load(file.getCanonicalPath());
loaded = true;
} catch (final Throwable e) {
Logs.debug(ClasspathNativeLibraryUtil.class,
"Unable to load shared library from classpath " + libraryName + " " + fileName, e);
}
}
LIBRARY_LOADED_MAP.put(name, loaded);
return loaded;
}
}