1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package com.ochafik.lang.jnaerator.runtime;
20
21 import java.io.File;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.OutputStream;
26 import java.net.URL;
27 import java.net.URLConnection;
28 import java.net.URLDecoder;
29 import java.util.ArrayList;
30 import java.util.Iterator;
31 import java.util.List;
32
33 import com.ochafik.net.URLUtils;
34 import com.sun.jna.Platform;
35
36
37
38
39
40
41 public class LibraryExtractor {
42 public static String getCurrentOSAndArchString() {
43 String os = System.getProperty("os.name"), arch = System.getProperty("os.arch");
44
45 if (os.equals("Mac OS X")) {
46 os = "darwin";
47 arch = "fat";
48
49 } else if (os.startsWith("Windows")) {
50 return "win" + (Platform.is64Bit() ? "64" : "32");
51 } else if (os.matches("SunOS|Solaris"))
52 os = "solaris";
53
54 return os + "-" + arch;
55 }
56 public static String getLibraryPath(String libraryName, boolean extractAllLibraries, Class<?> cl) {
57 try {
58 String customPath = System.getProperty("library." + libraryName);
59 if (customPath == null)
60 customPath = System.getenv(libraryName.toUpperCase() + "_LIBRARY");
61 if (customPath != null) {
62 File f = new File(customPath);
63 if (!f.exists())
64 System.err.println("Library file '" + customPath + "' does not exist !");
65 else
66 return f.getAbsolutePath();
67 }
68
69 String prefix = "(?i)" + (Platform.isWindows() || Platform.isWindowsCE() ? "" : "lib") + libraryName + "[^A-Za-z_].*";
70 String libsuffix = "(?i).*\\.(so|dll|dylib|jnilib)";
71 String othersuffix = "(?i).*\\.(pdb)";
72
73 URL sourceURL = null;
74 List<URL> otherURLs = new ArrayList<URL>();
75
76
77 String arch = getCurrentOSAndArchString();
78
79 List<URL> list = URLUtils.listFiles(URLUtils.getResource(cl, "libraries/" + arch), null);
80 if (list.isEmpty()) {
81 for (URL u : URLUtils.listFiles(URLUtils.getResource(cl, "libraries"), null)) {
82 String f = u.getFile();
83 int i = f.lastIndexOf('/');
84 if (i >= 0)
85 f = f.substring(i + 1);
86 if (arch.startsWith(f)) {
87 list = URLUtils.listFiles(u, null);
88 break;
89 }
90 }
91
92 }
93 for (File f : new File(".").listFiles())
94 if (f.isFile())
95 list.add(f.toURI().toURL());
96
97 for (URL url : list) {
98 String fileName = new File(url.toString()).getName();
99 boolean pref = fileName.matches(prefix), suff = fileName.matches(libsuffix);
100 if (pref && suff)
101 sourceURL = url;
102 else if (suff || fileName.matches(othersuffix))
103 otherURLs.add(url);
104 }
105 List<File> files = new ArrayList<File>();
106 if (extractAllLibraries) {
107 for (URL url : otherURLs)
108 files.add(extract(url));
109 }
110
111 if (sourceURL == null)
112 return libraryName;
113 else {
114 File file = extract(sourceURL);
115 files.add(file);
116
117 int lastSize;
118 do {
119 lastSize = files.size();
120 for (Iterator<File> it = files.iterator(); it.hasNext();) {
121 File f = it.next();
122 if (!f.getName().matches(libsuffix))
123 continue;
124
125 try {
126 System.load(f.toString());
127 it.remove();
128 } catch (Throwable ex) {
129 System.err.println("Loading " + f.getName() + " failed (" + ex + ")");
130 }
131 }
132 } while (files.size() < lastSize);
133
134 return file.getCanonicalPath();
135 }
136 } catch (Throwable ex) {
137 System.err.println("ERROR: Failed to extract library " + libraryName);
138 ex.printStackTrace();
139 return libraryName;
140 }
141 }
142 private static File extract(URL url) throws IOException {
143 File localFile;
144 if ("file".equals(url.getProtocol()))
145 localFile = new File(URLDecoder.decode(url.getFile(), "UTF-8"));
146 else {
147 File f = new File(System.getProperty("user.home"));
148 f = new File(f, ".jnaerator");
149 f = new File(f, "extractedLibraries");
150 if (!f.exists())
151 f.mkdirs();
152
153 localFile = new File(f, new File(url.getFile()).getName());
154 URLConnection c = url.openConnection();
155 if (localFile.exists() && localFile.lastModified() > c.getLastModified()) {
156 c.getInputStream().close();
157 } else {
158 System.out.println("Extracting " + url);
159 InputStream in = c.getInputStream();
160 OutputStream out = new FileOutputStream(localFile);
161 int len;
162 byte[] b = new byte[1024];
163 while ((len = in.read(b)) > 0)
164 out.write(b, 0, len);
165 out.close();
166 in.close();
167 }
168 }
169 return localFile;
170 }
171 public static void loadLibrary(String libraryName, boolean extractAllLibraries, Class<?> cl) {
172 System.loadLibrary(getLibraryPath(libraryName, extractAllLibraries, cl));
173 }
174 }