ShopChest/libs/org/sqlite/SQLiteJDBCLoader.java
2015-09-06 11:58:25 +02:00

272 lines
8.8 KiB
Java

/*--------------------------------------------------------------------------
* Copyright 2007 Taro L. Saito
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*--------------------------------------------------------------------------*/
//--------------------------------------
// SQLite JDBC Project
//
// SQLite.java
// Since: 2007/05/10
//
// $URL$
// $Author$
//--------------------------------------
package org.sqlite;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Properties;
/**
* Set the system properties, org.sqlite.lib.path, org.sqlite.lib.name,
* appropriately so that the SQLite JDBC driver can find *.dll, *.jnilib and
* *.so files, according to the current OS (win, linux, mac).
*
* The library files are automatically extracted from this project's package
* (JAR).
*
* usage: call {@link #initialize()} before using SQLite JDBC driver.
*
* @author leo
*
*/
public class SQLiteJDBCLoader
{
private static boolean extracted = false;
public static boolean initialize() {
loadSQLiteNativeLibrary();
return extracted;
}
static boolean getPureJavaFlag() {
return Boolean.parseBoolean(System.getProperty("sqlite.purejava", "false"));
}
public static boolean isPureJavaMode() {
return !isNativeMode();
}
public static boolean isNativeMode() {
if (getPureJavaFlag())
return false;
// load the driver
initialize();
return extracted;
}
/**
* Computes the MD5 value of the input stream
*
* @param input
* @return
* @throws IOException
* @throws NoSuchAlgorithmException
*/
static String md5sum(InputStream input) throws IOException {
BufferedInputStream in = new BufferedInputStream(input);
try {
MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
DigestInputStream digestInputStream = new DigestInputStream(in, digest);
for (; digestInputStream.read() >= 0;) {
}
ByteArrayOutputStream md5out = new ByteArrayOutputStream();
md5out.write(digest.digest());
return md5out.toString();
}
catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("MD5 algorithm is not available: " + e);
}
finally {
in.close();
}
}
/**
* Extract the specified library file to the target folder
*
* @param libFolderForCurrentOS
* @param libraryFileName
* @param targetFolder
* @return
*/
private static boolean extractAndLoadLibraryFile(String libFolderForCurrentOS, String libraryFileName,
String targetFolder) {
String nativeLibraryFilePath = libFolderForCurrentOS + "/" + libraryFileName;
final String prefix = "sqlite-" + getVersion() + "-";
String extractedLibFileName = prefix + libraryFileName;
File extractedLibFile = new File(targetFolder, extractedLibFileName);
try {
if (extractedLibFile.exists()) {
// test md5sum value
String md5sum1 = md5sum(SQLiteJDBCLoader.class.getResourceAsStream(nativeLibraryFilePath));
String md5sum2 = md5sum(new FileInputStream(extractedLibFile));
if (md5sum1.equals(md5sum2)) {
return loadNativeLibrary(targetFolder, extractedLibFileName);
}
else {
// remove old native library file
boolean deletionSucceeded = extractedLibFile.delete();
if (!deletionSucceeded) {
throw new IOException("failed to remove existing native library file: "
+ extractedLibFile.getAbsolutePath());
}
}
}
// extract file into the current directory
InputStream reader = SQLiteJDBCLoader.class.getResourceAsStream(nativeLibraryFilePath);
FileOutputStream writer = new FileOutputStream(extractedLibFile);
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = reader.read(buffer)) != -1) {
writer.write(buffer, 0, bytesRead);
}
writer.close();
reader.close();
if (!System.getProperty("os.name").contains("Windows")) {
try {
Runtime.getRuntime().exec(new String[] { "chmod", "755", extractedLibFile.getAbsolutePath() })
.waitFor();
}
catch (Throwable e) {}
}
return loadNativeLibrary(targetFolder, extractedLibFileName);
}
catch (IOException e) {
System.err.println(e.getMessage());
return false;
}
}
private static synchronized boolean loadNativeLibrary(String path, String name) {
File libPath = new File(path, name);
if (libPath.exists()) {
try {
System.load(new File(path, name).getAbsolutePath());
return true;
}
catch (UnsatisfiedLinkError e) {
System.err.println(e);
return false;
}
}
else
return false;
}
private static void loadSQLiteNativeLibrary() {
if (extracted)
return;
boolean runInPureJavaMode = getPureJavaFlag();
if (runInPureJavaMode) {
extracted = false;
return;
}
// Try loading library from org.sqlite.lib.path library path */
String sqliteNativeLibraryPath = System.getProperty("org.sqlite.lib.path");
String sqliteNativeLibraryName = System.getProperty("org.sqlite.lib.name");
if (sqliteNativeLibraryName == null)
sqliteNativeLibraryName = System.mapLibraryName("sqlitejdbc");
if (sqliteNativeLibraryPath != null) {
if (loadNativeLibrary(sqliteNativeLibraryPath, sqliteNativeLibraryName)) {
extracted = true;
return;
}
}
// Load the os-dependent library from a jar file
sqliteNativeLibraryPath = "/native/" + OSInfo.getNativeLibFolderPathForCurrentOS();
if (SQLiteJDBCLoader.class.getResource(sqliteNativeLibraryPath + "/" + sqliteNativeLibraryName) == null) {
// use nested VM version
return;
}
// temporary library folder
String tempFolder = new File(System.getProperty("java.io.tmpdir")).getAbsolutePath();
// Try extracting the library from jar
if (extractAndLoadLibraryFile(sqliteNativeLibraryPath, sqliteNativeLibraryName, tempFolder)) {
extracted = true;
return;
}
extracted = false;
return;
}
private static void getNativeLibraryFolderForTheCurrentOS() {
String osName = OSInfo.getOSName();
String archName = OSInfo.getArchName();
}
public static int getMajorVersion() {
String[] c = getVersion().split("\\.");
return (c.length > 0) ? Integer.parseInt(c[0]) : 1;
}
public static int getMinorVersion() {
String[] c = getVersion().split("\\.");
return (c.length > 1) ? Integer.parseInt(c[1]) : 0;
}
public static String getVersion() {
URL versionFile = SQLiteJDBCLoader.class.getResource("/META-INF/maven/org.xerial/sqlite-jdbc/pom.properties");
if (versionFile == null)
versionFile = SQLiteJDBCLoader.class.getResource("/META-INF/maven/org.xerial/sqlite-jdbc/VERSION");
String version = "unknown";
try {
if (versionFile != null) {
Properties versionData = new Properties();
versionData.load(versionFile.openStream());
version = versionData.getProperty("version", version);
version = version.trim().replaceAll("[^0-9\\.]", "");
}
}
catch (IOException e) {
System.err.println(e);
}
return version;
}
}