package org.embulk.output.oracle.oci; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; import org.embulk.spi.Exec; import org.slf4j.Logger; import com.google.common.io.Files; public class OCI { private static final Logger logger = Exec.getLogger(OCI.class); private static final String PLUGIN_NAME = "embulk-output-oracle"; static { try { loadLibrary(); } catch (URISyntaxException | IOException e) { throw new RuntimeException(e); } } public native byte[] createContext(); public native byte[] getLasetMessage(byte[] context); public native boolean open(byte[] context, String dbName, String userName, String password); public native boolean prepareLoad(byte[] context, TableDefinition tableDefinition); public native boolean loadBuffer(byte[] context, byte[] buffer, int rowCount); public native boolean commit(byte[] context); public native boolean rollback(byte[] context); public native void close(byte[] context); private static void loadLibrary() throws URISyntaxException, IOException { loadLibrary(getPluginRoot()); } private static File getPluginRoot() throws MalformedURLException, URISyntaxException { URL url = OCI.class.getResource("/" + OCI.class.getName().replace('.', '/') + ".class"); if (url.toString().startsWith("jar:")) { url = new URL(url.toString().replaceAll("^jar:", "").replaceAll("![^!]*$", "")); } File folder = new File(url.toURI()).getParentFile(); for (;; folder = folder.getParentFile()) { if (folder == null) { String message = String.format("OCI : %s folder not found.", PLUGIN_NAME); throw new RuntimeException(message); } if (folder.getName().startsWith(PLUGIN_NAME)) { return folder; } } } private static void loadLibrary(File folder) throws IOException { File lib = new File(new File(folder, "lib"), "embulk"); String osName = System.getProperty("os.name"); String osArch = System.getProperty("os.arch"); String libraryName = System.mapLibraryName(PLUGIN_NAME); File libFolder = null; if (osName.startsWith("Windows")) { if (osArch.endsWith("64")) { libFolder = new File(lib, "win_x64"); } else if (osArch.equals("x86")) { libFolder = new File(lib, "win_x86"); } } else if (osName.equals("Linux")) { if (osArch.endsWith("64")) { libFolder = new File(lib, "linux_x64"); } else if (osArch.equals("x86")) { libFolder = new File(lib, "linux_x86"); } } if (libFolder == null) { logger.error(String.format("OCI : library \"%s\" for %s %s doesn't exist in lib folder.", libraryName, osName, osArch)); return; } File libFile = new File(libFolder, libraryName); if (!libFile.exists()) { logger.error(String.format("OCI : library \"%s\" doesn't exist.", libFile.getAbsolutePath())); return; } logger.info(String.format("OCI : load library \"%s\".", libFile.getAbsolutePath())); File tempFolder = new File(lib, "temp"); tempFolder.mkdirs(); long currentTime = System.currentTimeMillis(); File[] files = tempFolder.listFiles(); if (files != null) { for (File file : files) { // delete old temporary files. // if another plugin is using a file, it cannot be deleted. // don't delete a recent file because another plugin may intend to use it. if (file.isFile() && file.getName().startsWith(PLUGIN_NAME) && file.lastModified() < currentTime - 60000) { file.delete(); } } } String extension = libraryName.replaceAll("^[^\\.]*", ""); for (int i = 0; i < 10; i++) { File tempLibFile = new File(tempFolder, PLUGIN_NAME + "-" + currentTime + "-" + i + extension); if (tempLibFile.createNewFile()) { // copy and load the library because different plugins cannot load the same library. logger.info(String.format("OCI : create temporary library \"%s\".", tempLibFile.getAbsolutePath())); Files.copy(libFile, tempLibFile); System.load(tempLibFile.getAbsolutePath()); tempLibFile.deleteOnExit(); // but may not be deleted because loaded as a library. return; } } logger.error("OCI : cannot create temporary library."); } }