001 package com.github.sarxos.webcam.ds.civil; 002 003 import java.io.File; 004 import java.io.FileNotFoundException; 005 import java.io.FileOutputStream; 006 import java.io.IOException; 007 import java.io.InputStream; 008 import java.io.OutputStream; 009 010 import org.slf4j.Logger; 011 import org.slf4j.LoggerFactory; 012 013 014 public class LtiCivilLoader { 015 016 private static final Logger LOG = LoggerFactory.getLogger(LtiCivilLoader.class); 017 018 /** 019 * Will be called until JVM shutdown. 020 * 021 * @author Bartosz Firyn (SarXos) 022 */ 023 private static class Deleter extends Thread { 024 025 private File file = null; 026 027 public Deleter(File file) { 028 super("lti-civil-binary-deleter"); 029 this.file = file; 030 } 031 032 @Override 033 public void run() { 034 super.run(); 035 if (file.exists()) { 036 if (!file.delete()) { 037 LOG.warn(String.format("JVM was not able to remove file %s", file)); 038 } 039 } 040 } 041 } 042 043 /** 044 * Copy bytes from a large (over 2GB) InputStream to an OutputStream. 045 * 046 * @param input the InputStream to read from 047 * @param output the OutputStream to write to 048 * @return the number of bytes copied 049 * @throws NullPointerException if the input or output is null 050 * @throws IOException if an I/O error occurs 051 */ 052 public static long copy(InputStream input, OutputStream output) throws IOException { 053 byte[] buffer = new byte[1024 * 4]; 054 long count = 0; 055 int n = 0; 056 while (-1 != (n = input.read(buffer))) { 057 output.write(buffer, 0, n); 058 count += n; 059 } 060 return count; 061 } 062 063 public static void load(String lib) { 064 LOG.info("Loading native library: " + lib); 065 try { 066 System.loadLibrary(lib); 067 LOG.info("DLL has been loaded from memory: " + lib); 068 } catch (UnsatisfiedLinkError e) { 069 try { 070 load("webcam-capture-lib-" + System.currentTimeMillis(), lib); 071 } catch (Exception e2) { 072 LOG.error("Exception when loading DLL library", e2); 073 throw new RuntimeException(e2); 074 } 075 } 076 } 077 078 public static void load(String path, String name) { 079 080 String libroot = "/META-INF/lib"; 081 String libpath = null; 082 String libfile = null; 083 084 boolean arch64 = System.getProperty("os.arch").indexOf("64") != -1; 085 boolean linux = System.getProperty("os.name").toLowerCase().indexOf("linux") != -1; 086 087 if (linux) { 088 if (arch64) { 089 libpath = libroot + "/linux64/"; 090 libfile = "lib" + name + ".so"; 091 } else { 092 libpath = libroot + "/linux32/"; 093 libfile = "lib" + name + ".so"; 094 } 095 } else { 096 libpath = libroot + "/win32/"; 097 libfile = name + ".dll"; 098 } 099 100 File parent = new File(System.getProperty("java.io.tmpdir") + "/" + path); 101 if (!parent.exists()) { 102 if (!parent.mkdirs()) { 103 throw new RuntimeException("Cannot create directory: " + parent.getAbsolutePath()); 104 } 105 } 106 107 File file = new File(parent, libfile); 108 if (!file.exists()) { 109 110 boolean created = false; 111 try { 112 created = file.createNewFile(); 113 } catch (IOException e) { 114 throw new RuntimeException("Not able to create file: " + file, e); 115 } 116 if (!created) { 117 throw new RuntimeException("File cannot be created: " + file); 118 } 119 120 Runtime.getRuntime().addShutdownHook(new Deleter(file)); 121 } 122 123 String resource = libpath + libfile; 124 125 InputStream in = LtiCivilDriver.class.getResourceAsStream(resource); 126 if (in == null) { 127 throw new RuntimeException("Resource not found: " + resource); 128 } 129 130 FileOutputStream fos = null; 131 132 try { 133 fos = new FileOutputStream(file); 134 copy(in, fos); 135 } catch (FileNotFoundException e) { 136 throw new RuntimeException("File not found " + file, e); 137 } catch (IOException e) { 138 throw new RuntimeException("IO exception", e); 139 } finally { 140 if (in != null) { 141 try { 142 in.close(); 143 } catch (IOException e) { 144 throw new RuntimeException("Cannot close input stream", e); 145 } 146 } 147 if (fos != null) { 148 try { 149 fos.close(); 150 } catch (IOException e) { 151 throw new RuntimeException("Cannot close file output stream", e); 152 } 153 } 154 } 155 156 try { 157 System.load(file.getAbsolutePath()); 158 } catch (UnsatisfiedLinkError e) { 159 throw new RuntimeException("Library file cannot be loaded: " + file, e); 160 } 161 } 162 }