修复在win上控制台无法显示彩色字体的问题
This commit is contained in:
parent
15861edb0d
commit
947d57bdb9
286
src/main/java/org/fusesource/hawtjni/runtime/Library.java
Normal file
286
src/main/java/org/fusesource/hawtjni/runtime/Library.java
Normal file
@ -0,0 +1,286 @@
|
||||
package org.fusesource.hawtjni.runtime;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Library{
|
||||
|
||||
static final String SLASH=System.getProperty("file.separator");
|
||||
private final String name;
|
||||
private final String version;
|
||||
private final ClassLoader classLoader;
|
||||
private boolean loaded;
|
||||
|
||||
public Library(String name){
|
||||
this(name,null,null);
|
||||
}
|
||||
|
||||
public Library(String name,Class<?> clazz){
|
||||
this(name,version(clazz),clazz.getClassLoader());
|
||||
}
|
||||
|
||||
public Library(String name,String version){
|
||||
this(name,version,null);
|
||||
}
|
||||
|
||||
public Library(String name,String version,ClassLoader classLoader){
|
||||
if(name==null){
|
||||
throw new IllegalArgumentException("name cannot be null");
|
||||
}
|
||||
this.name=name;
|
||||
this.version=version;
|
||||
this.classLoader=classLoader;
|
||||
}
|
||||
|
||||
private static String version(Class<?> clazz){
|
||||
try{
|
||||
return clazz.getPackage().getImplementationVersion();
|
||||
}catch(Throwable e){
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getOperatingSystem(){
|
||||
String name=System.getProperty("os.name").toLowerCase().trim();
|
||||
if(name.startsWith("linux")){
|
||||
return "linux";
|
||||
}
|
||||
if(name.startsWith("mac os x")){
|
||||
return "osx";
|
||||
}
|
||||
if(name.startsWith("win")){
|
||||
return "windows";
|
||||
}
|
||||
return name.replaceAll("\\W+","_");
|
||||
}
|
||||
|
||||
public static String getPlatform(){
|
||||
return getOperatingSystem()+getBitModel();
|
||||
}
|
||||
|
||||
public static int getBitModel(){
|
||||
String prop=System.getProperty("sun.arch.data.model");
|
||||
if(prop==null){
|
||||
prop=System.getProperty("com.ibm.vm.bitmode");
|
||||
}
|
||||
if(prop!=null){
|
||||
return Integer.parseInt(prop);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public synchronized void load(){
|
||||
if(this.loaded){
|
||||
return;
|
||||
}
|
||||
doLoad();
|
||||
this.loaded=true;
|
||||
}
|
||||
|
||||
private void doLoad(){
|
||||
String version=System.getProperty("library."+this.name+".version");
|
||||
if(version==null){
|
||||
version=this.version;
|
||||
}
|
||||
ArrayList<String> errors=new ArrayList();
|
||||
|
||||
String customPath=System.getProperty("library."+this.name+".path");
|
||||
if(customPath!=null){
|
||||
if(version!=null){
|
||||
if(load(errors,file(new String[]{customPath,map(this.name+"-"+version)}))){
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(load(errors,file(new String[]{customPath,map(this.name)}))){
|
||||
return;
|
||||
}
|
||||
}
|
||||
if((version!=null)&&(load(errors,this.name+getBitModel()+"-"+version))){
|
||||
return;
|
||||
}
|
||||
if((version!=null)&&(load(errors,this.name+"-"+version))){
|
||||
return;
|
||||
}
|
||||
if(load(errors,this.name)){
|
||||
return;
|
||||
}
|
||||
if(this.classLoader!=null){
|
||||
if(exractAndLoad(errors,version,customPath,getPlatformSpecifcResourcePath())){
|
||||
return;
|
||||
}
|
||||
if(exractAndLoad(errors,version,customPath,getOperatingSystemSpecifcResourcePath())){
|
||||
return;
|
||||
}
|
||||
if(exractAndLoad(errors,version,customPath,getResorucePath())){
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new UnsatisfiedLinkError("Could not load library. Reasons: "+errors.toString());
|
||||
}
|
||||
|
||||
public final String getOperatingSystemSpecifcResourcePath(){
|
||||
return getPlatformSpecifcResourcePath(getOperatingSystem());
|
||||
}
|
||||
|
||||
public final String getPlatformSpecifcResourcePath(){
|
||||
return getPlatformSpecifcResourcePath(getPlatform());
|
||||
}
|
||||
|
||||
public final String getPlatformSpecifcResourcePath(String platform){
|
||||
return "META-INF/native/"+platform+"/"+map(this.name);
|
||||
}
|
||||
|
||||
public final String getResorucePath(){
|
||||
return "META-INF/native/"+map(this.name);
|
||||
}
|
||||
|
||||
public final String getLibraryFileName(){
|
||||
return map(this.name);
|
||||
}
|
||||
|
||||
private boolean exractAndLoad(ArrayList<String> errors,String version,String customPath,String resourcePath){
|
||||
URL resource=this.classLoader.getResource(resourcePath);
|
||||
if(resource!=null){
|
||||
String libName=this.name+"-"+getBitModel();
|
||||
if(version!=null){
|
||||
libName=libName+"-"+version;
|
||||
}
|
||||
String[] libNameParts=map(libName).split("\\.");
|
||||
String prefix=libNameParts[0]+"-";
|
||||
String suffix="."+libNameParts[1];
|
||||
if(customPath!=null){
|
||||
File target=extract(errors,resource,prefix,suffix,file(new String[]{customPath}));
|
||||
if((target!=null)&&
|
||||
(load(errors,target))){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
customPath=System.getProperty("java.io.tmpdir");
|
||||
File target=extract(errors,resource,prefix,suffix,file(new String[]{customPath}));
|
||||
if((target!=null)&&
|
||||
(load(errors,target))){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private File extract(ArrayList<String> errors,URL source,String prefix,String suffix,File directory){
|
||||
File target=null;
|
||||
try{
|
||||
FileOutputStream os=null;
|
||||
InputStream is=null;
|
||||
try{
|
||||
target=File.createTempFile(prefix,suffix,directory);
|
||||
is=source.openStream();
|
||||
byte[] buffer;
|
||||
if(is!=null){
|
||||
buffer=new byte[64];
|
||||
os=new FileOutputStream(target);
|
||||
int read;
|
||||
while((read=is.read(buffer))!=-1){
|
||||
os.write(buffer,0,read);
|
||||
}
|
||||
chmod("755",target);
|
||||
}
|
||||
target.deleteOnExit();
|
||||
}finally{
|
||||
close(os,is);
|
||||
}
|
||||
}catch(Throwable e){
|
||||
if(target!=null){
|
||||
target.delete();
|
||||
}
|
||||
errors.add(e.getMessage());
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
private static void close(Closeable...pStreams){
|
||||
for(Closeable sStream : pStreams){
|
||||
if(sStream!=null){
|
||||
try{
|
||||
sStream.close();
|
||||
}catch(Exception ignore){
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private File file(String...paths){
|
||||
File rc=null;
|
||||
for(String path : paths){
|
||||
if(rc==null){
|
||||
rc=new File(path);
|
||||
}else{
|
||||
rc=new File(rc,path);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
private String map(String libName){
|
||||
libName=System.mapLibraryName(libName);
|
||||
String ext=".dylib";
|
||||
if(libName.endsWith(ext)){
|
||||
libName=libName.substring(0,libName.length()-ext.length())+".jnilib";
|
||||
}
|
||||
return libName;
|
||||
}
|
||||
|
||||
private boolean isStale(URL source,File target){
|
||||
if(source.getProtocol().equals("jar")){
|
||||
try{
|
||||
String[] parts=source.getFile().split(Pattern.quote("!"));
|
||||
source=new URL(parts[0]);
|
||||
}catch(MalformedURLException e){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
File sourceFile=null;
|
||||
if(source.getProtocol().equals("file")){
|
||||
sourceFile=new File(source.getFile());
|
||||
}
|
||||
if((sourceFile!=null)&&(sourceFile.exists())&&
|
||||
(sourceFile.lastModified()>target.lastModified())){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void chmod(String permision,File path){
|
||||
if(getPlatform().startsWith("windows")){
|
||||
return;
|
||||
}
|
||||
try{
|
||||
Runtime.getRuntime().exec(new String[]{"chmod",permision,path.getCanonicalPath()}).waitFor();
|
||||
}catch(Throwable e){
|
||||
}
|
||||
}
|
||||
|
||||
private boolean load(ArrayList<String> errors,File lib){
|
||||
try{
|
||||
System.load(lib.getPath());
|
||||
return true;
|
||||
}catch(UnsatisfiedLinkError e){
|
||||
errors.add(e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean load(ArrayList<String> errors,String lib){
|
||||
try{
|
||||
System.loadLibrary(lib);
|
||||
return true;
|
||||
}catch(UnsatisfiedLinkError e){
|
||||
errors.add(e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user