com.arakelian.jq.NativeLib Maven / Gradle / Ivy
The newest version!
/*
* 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.
*/
package com.arakelian.jq;
import static java.util.logging.Level.INFO;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.util.List;
import java.util.Locale;
import java.util.logging.Logger;
import org.immutables.value.Value;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.sun.jna.NativeLibrary;
import com.sun.jna.Platform;
@Value.Immutable(copy = false)
public abstract class NativeLib {
private static final Logger LOGGER = Logger.getLogger(NativeLib.class.getName());
@Value.Derived
@Value.Auxiliary
public String getArchitecture() {
return getOsName() + ":" + getOsArch();
}
@Value.Default
@Value.Auxiliary
public List getDependencies() {
return ImmutableList.of();
}
@Value.Derived
public List getFilenames() {
final ImmutableList.Builder builder = ImmutableList.builder();
final String name = getName();
if (Platform.isWindows()) {
builder.add(name + ".dll");
} else if (Platform.isLinux()) {
builder.add("lib" + name + ".so");
} else if (Platform.isMac()) {
builder.add("lib" + name + ".dylib");
} else {
throw new IllegalStateException("Unsupported architecture: " + getArchitecture());
}
for (final String dependency : getDependencies()) {
builder.add(dependency);
}
return builder.build();
}
@Value.Lazy
@Value.Auxiliary
public File getLocalCopy() throws UncheckedIOException {
final File tmpdir = getTemporaryFolder();
for (final String filename : getFilenames()) {
try {
final File local = new File(tmpdir, filename);
// local.deleteOnExit();
final String resource = "lib/" + getPath() + filename;
LOGGER.log(INFO, "Copying resource {0} to: {1}", new Object[] { resource, local });
try (InputStream in = this.getClass().getClassLoader().getResourceAsStream(resource);
OutputStream out = new FileOutputStream(local)) {
Preconditions.checkState(in != null, "Cannot find resource %s", resource);
final byte buf[] = new byte[1024 * 1024];
int n;
while (-1 != (n = in.read(buf))) {
out.write(buf, 0, n);
}
}
} catch (final IOException e) {
throw new UncheckedIOException(
"Unable to copy library " + filename + " to temporary folder " + tmpdir, e);
}
}
return tmpdir;
}
public abstract String getName();
@Value.Lazy
@Value.Auxiliary
public NativeLibrary getNativeLibrary() throws UncheckedIOException {
final String name = getName();
final File libPath = getLocalCopy();
LOGGER.log(INFO, "{0} library path: {1}", new Object[] { name, libPath });
NativeLibrary.addSearchPath(name, libPath.getAbsolutePath());
final NativeLibrary instance = NativeLibrary.getInstance(name);
LOGGER.log(INFO, "{0} loaded from path: {1} ", new Object[] { name, libPath });
return instance;
}
@Value.Derived
public String getOsArch() {
final String arch = System.getProperty("os.arch");
return arch != null ? arch.toLowerCase(Locale.ROOT) : "";
}
@Value.Derived
public String getOsName() {
final String name = System.getProperty("os.name");
return name != null ? name.toLowerCase(Locale.ROOT) : "";
}
@Value.Derived
public String getPath() {
final String osArch = getOsArch();
if (Platform.isWindows()) {
if ("x86".equalsIgnoreCase(osArch)) {
return "win-x86/";
}
} else if (Platform.isLinux()) {
if ("amd64".equalsIgnoreCase(osArch)) {
return "linux-x86_64/";
} else if ("ia64".equalsIgnoreCase(osArch)) {
return "linux-ia64/";
} else if ("i386".equalsIgnoreCase(osArch)) {
return "linux-x86/";
} else if ("aarch64".equalsIgnoreCase(osArch)) {
return "linux-aarch64/";
}
} else if (Platform.isMac()) {
if ("aarch64".equalsIgnoreCase(osArch)) {
return "darwin-aarch64/";
} else if ("x86_64".equalsIgnoreCase(osArch)) {
return "darwin-x86_64/";
}
}
throw new IllegalStateException("Unsupported architecture: " + getArchitecture());
}
@Value.Default
@Value.Auxiliary
public File getTemporaryFolder() throws UncheckedIOException {
// must create a temp directory, required for NativeLibrary.addSearchPath
File baseDir = new File(System.getProperty("java.io.tmpdir"));
String baseName = System.currentTimeMillis() + "-";
for (int counter = 0; counter < 10000; counter++) {
File tmpDir = new File(baseDir, baseName + counter);
if (tmpDir.mkdir()) {
return tmpDir;
}
}
throw new IllegalStateException("Failed to create temp directory");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy