d381efc24c71caa485c9bdb5ae1b03e30a1545ee
[splitter-ng] / Splitter-ng-plugin-bitsplitter / src / cz / adamh / utils / NativeUtils.java
1 package cz.adamh.utils;
2  
3 import java.io.File;
4 import java.io.FileNotFoundException;
5 import java.io.FileOutputStream;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.OutputStream;
9 import java.lang.reflect.Field;
10 import java.nio.file.Files;
11 import java.nio.file.Path;
12 import java.nio.file.Paths;
13 import java.util.Vector;
14  
15 /**
16  * Simple library class for working with JNI (Java Native Interface)
17  * 
18  * @see http://frommyplayground.com/how-to-load-native-jni-library-from-jar
19  *
20  * @author Adam Heirnich <adam@adamh.cz>, http://www.adamh.cz
21  */
22 public class NativeUtils {
23  
24         /**
25          * Private constructor - this class will never be instanced
26          */
27         private NativeUtils() {
28         }
29  
30         /**
31          * Loads library from current JAR archive
32          * 
33          * The file from JAR is copied into system temporary directory and then loaded. The temporary file is deleted after exiting.
34          * Method uses String as filename because the pathname is "abstract", not system-dependent.
35          * 
36          * @param filename The filename inside JAR as absolute path (beginning with '/'), e.g. /package/File.ext
37          * @throws IOException If temporary file creation or read/write operation fails
38          * @throws IllegalArgumentException If source file (param path) does not exist
39          * @throws IllegalArgumentException If the path is not absolute or if the filename is shorter than three characters (restriction of {@see File#createTempFile(java.lang.String, java.lang.String)}).
40          */
41         public static void loadLibraryFromJar(String path) throws IOException {
42  
43                 if (!path.startsWith("/")) {
44                         throw new IllegalArgumentException("The path to be absolute (start with '/').");
45                 }
46  
47                 // Obtain filename from path
48                 String[] parts = path.split("/");
49                 String filename = (parts.length > 1) ? parts[parts.length - 1] : null;
50  
51                 // Split filename to prexif and suffix (extension)
52                 String prefix = "";
53                 String suffix = null;
54                 if (filename != null) {
55                         parts = filename.split("\\.", 2);
56                         prefix = parts[0];
57                         suffix = (parts.length > 1) ? "."+parts[parts.length - 1] : null; // Thanks, davs! :-)
58                 }
59  
60                 // Check if the filename is okay
61                 if (filename == null || prefix.length() < 3) {
62                         throw new IllegalArgumentException("The filename has to be at least 3 characters long.");
63                 }
64  
65                 // Prepare temporary file
66                 //Path tempDir = Files.createTempDirectory("tempfiles");
67                 Path tempDir = Paths.get(System.getProperty("java.io.tmpdir"));
68                 File temp = new File(tempDir.toString(),prefix+suffix);
69                 Files.createFile(temp.toPath());
70                 temp.deleteOnExit();
71                 
72                 // Prepare temporary file
73                 //File temp = File.createTempFile(prefix, suffix);
74                 //temp.deleteOnExit();
75                  
76                 if (!temp.exists()) {
77                         throw new FileNotFoundException("File " + temp.getAbsolutePath() + " does not exist.");
78                 }
79  
80                 // Prepare buffer for data copying
81                 byte[] buffer = new byte[1024];
82                 int readBytes;
83  
84                 // Open and check input stream
85                 InputStream is = NativeUtils.class.getResourceAsStream(path);
86                 if (is == null) {
87                         throw new FileNotFoundException("File " + path + " was not found inside JAR.");
88                 }
89  
90                 // Open output stream and copy data between source file in JAR and the temporary file
91                 OutputStream os = new FileOutputStream(temp);
92                 try {
93                         while ((readBytes = is.read(buffer)) != -1) {
94                                 os.write(buffer, 0, readBytes);
95                         }
96                 } finally {
97                         // If read/write fails, close streams safely before throwing an exception
98                         os.close();
99                         is.close();
100                 }
101  
102                 // Finally, load the library
103                 System.load(temp.getAbsolutePath());
104                 //System.out.println(temp.getAbsolutePath()+" geladen");
105
106         }
107 }