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