| | 1 | /* |
| | 2 | * IkvmSite.java |
| | 3 | * |
| | 4 | * Copyright (C) 2003-2005 Peter Graves |
| | 5 | * $Id: Site.java 11391 2008-11-15 22:38:34Z vvoutilainen $ |
| | 6 | * |
| | 7 | * This program is free software; you can redistribute it and/or |
| | 8 | * modify it under the terms of the GNU General Public License |
| | 9 | * as published by the Free Software Foundation; either version 2 |
| | 10 | * of the License, or (at your option) any later version. |
| | 11 | * |
| | 12 | * This program is distributed in the hope that it will be useful, |
| | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| | 15 | * GNU General Public License for more details. |
| | 16 | * |
| | 17 | * You should have received a copy of the GNU General Public License |
| | 18 | * along with this program; if not, write to the Free Software |
| | 19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| | 20 | * |
| | 21 | * As a special exception, the copyright holders of this library give you |
| | 22 | * permission to link this library with independent modules to produce an |
| | 23 | * executable, regardless of the license terms of these independent |
| | 24 | * modules, and to copy and distribute the resulting executable under |
| | 25 | * terms of your choice, provided that you also meet, for each linked |
| | 26 | * independent module, the terms and conditions of the license of that |
| | 27 | * module. An independent module is a module which is not derived from |
| | 28 | * or based on this library. If you modify this library, you may extend |
| | 29 | * this exception to your version of the library, but you are not |
| | 30 | * obligated to do so. If you do not wish to do so, delete this |
| | 31 | * exception statement from your version. |
| | 32 | */ |
| | 33 | |
| | 34 | package org.armedbear.lisp; |
| | 35 | |
| | 36 | import java.io.DataInputStream; |
| | 37 | import java.io.File; |
| | 38 | import java.io.FileOutputStream; |
| | 39 | import java.io.IOException; |
| | 40 | import java.io.InputStream; |
| | 41 | import java.io.OutputStream; |
| | 42 | import java.lang.reflect.Method; |
| | 43 | import java.lang.reflect.Modifier; |
| | 44 | import java.net.URL; |
| | 45 | import java.net.URLConnection; |
| | 46 | import java.util.HashMap; |
| | 47 | |
| | 48 | public final class IkvmSite extends Lisp { |
| | 49 | |
| | 50 | /** |
| | 51 | * Unpack and create a temporary file from a .NET Assembly if needed |
| | 52 | * |
| | 53 | * @param {@link java.io.File} jfile |
| | 54 | * @return temporary {@link java.io.File} unpacked from a .NET Assembly |
| | 55 | */ |
| | 56 | public static File ikvmFileSafe(File jfile) { |
| | 57 | // if (!Site.isIKVMDll()) return filename; |
| | 58 | try { |
| | 59 | final File ifile = ikvmFile(jfile.getPath()); |
| | 60 | if (ifile.exists()) return ifile; |
| | 61 | } catch (IOException e) { |
| | 62 | } |
| | 63 | return jfile; |
| | 64 | } |
| | 65 | |
| | 66 | final static HashMap extractionMap = new HashMap(); |
| | 67 | |
| | 68 | /** |
| | 69 | * Unpack and create a temporary file from a .NET Assembly |
| | 70 | * |
| | 71 | * @param {@link java.lang.String} filename |
| | 72 | * @return temporary {@link java.io.File} unpacked from a .NET Assembly |
| | 73 | */ |
| | 74 | public static File ikvmFile(String filename) throws IOException { |
| | 75 | File file = new File(filename); |
| | 76 | // System.err.println("// IKVM = " + file); |
| | 77 | if (file.exists()) return file; |
| | 78 | // directories are real even when they do not yet exist |
| | 79 | try { |
| | 80 | if (file.isDirectory()) return file; |
| | 81 | } catch (Throwable dotnetOnly) { |
| | 82 | |
| | 83 | } |
| | 84 | // if (!Site.isIKVMDll()) return file; |
| | 85 | // if (file.getPath().endsWith("top-level.abcl")) return file; |
| | 86 | { |
| | 87 | File knownFile = (File) extractionMap.get(filename); |
| | 88 | if (knownFile != null) return knownFile; |
| | 89 | } |
| | 90 | |
| | 91 | URL res = Lisp.class.getResource(filename); |
| | 92 | if (res == null) { |
| | 93 | if (Utilities.isPlatformWindows) { |
| | 94 | String revSlash = filename.replace("\\", "/"); |
| | 95 | //someone stripped the "/" ? |
| | 96 | if (revSlash.charAt(0) != '/') revSlash = "/" + revSlash; |
| | 97 | if (!revSlash.equals(filename)) { |
| | 98 | res = Lisp.class.getResource(revSlash); |
| | 99 | } |
| | 100 | } |
| | 101 | } |
| | 102 | if (res == null) { |
| | 103 | // System.err.println("// No File = " + file); |
| | 104 | return file;//throw new FileNotFoundException(filename); |
| | 105 | } |
| | 106 | // System.err.println("// IKVM = " + file); |
| | 107 | if (res.getProtocol().equals("ikvmres")) { |
| | 108 | URLConnection connection = res.openConnection(); |
| | 109 | InputStream in = connection.getInputStream(); |
| | 110 | if (in != null) { |
| | 111 | { |
| | 112 | String ikvmFileWithExt = new File(filename).getName(); |
| | 113 | int index = ikvmFileWithExt.lastIndexOf(File.separatorChar); |
| | 114 | if (index > 0) ikvmFileWithExt = ikvmFileWithExt.substring(index); |
| | 115 | // index = ext.lastIndexOf('.'); |
| | 116 | //if (index > 0) ext = ext.substring(index); |
| | 117 | file = new File(IKVM_LISP_TEMP, ikvmFileWithExt); |
| | 118 | // file = File.createTempFile(IKVM_LISP_TEMP.getParent(), ext);//.getTempFile(cacheDir); |
| | 119 | //System.err.println("// IKVM Unpacking Dll file " + filename + " to " + file);//IKVM_LISP_TEMP.getParent() +"$"+ ext); |
| | 120 | } |
| | 121 | if (!file.exists()) { |
| | 122 | file.getParentFile().mkdirs(); |
| | 123 | } |
| | 124 | System.out.println(";;IKVM baking " + file + " from " + filename); |
| | 125 | OutputStream out = new FileOutputStream(file); |
| | 126 | byte[] buf = new byte[4096]; |
| | 127 | int bytesRead; |
| | 128 | in = new DataInputStream(in); |
| | 129 | // int total = 0; |
| | 130 | while ((bytesRead = in.read(buf)) > 0) { |
| | 131 | // System.err.println("// read="+bytesRead); |
| | 132 | // int print = 10; |
| | 133 | // if (bytesRead<print) print = bytesRead; |
| | 134 | // for (int printi=0;printi<print;printi++) { |
| | 135 | // System.out.println(" // byte="+buf[printi] + " c="+((char)buf[printi])); |
| | 136 | // } |
| | 137 | // total += bytesRead; |
| | 138 | |
| | 139 | out.write(buf, 0, bytesRead); |
| | 140 | } |
| | 141 | // System.err.println("// write="+total); |
| | 142 | out.close(); |
| | 143 | in.close(); |
| | 144 | extractionMap.put(filename, file); |
| | 145 | // System.err.println("// zipFileName 1.1 = " + file); |
| | 146 | return file; |
| | 147 | } |
| | 148 | } |
| | 149 | return file; |
| | 150 | } |
| | 151 | |
| | 152 | private static final String IKVM_LISP_HOME; |
| | 153 | private static final File IKVM_LISP_TEMP; |
| | 154 | |
| | 155 | private static boolean knowsAboutIKVM = false; |
| | 156 | private static boolean isIKVM = false; |
| | 157 | private static boolean isIKVMDll = false; |
| | 158 | |
| | 159 | public static synchronized boolean isIKVM() /*throws ConditionThrowable*/{ |
| | 160 | if (!knowsAboutIKVM) { |
| | 161 | knowsAboutIKVM = true; |
| | 162 | String vmname = System.getProperty("java.vm.name"); |
| | 163 | if (vmname == null || !vmname.toLowerCase().contains("ikvm")) return false; |
| | 164 | isIKVM = true; |
| | 165 | try { |
| | 166 | addIkvmFeature(); |
| | 167 | } catch (ConditionThrowable e) { |
| | 168 | } |
| | 169 | URL url = Lisp.class.getResource("boot.lisp"); |
| | 170 | if (url != null) { |
| | 171 | String protocol = url.getProtocol(); |
| | 172 | if (protocol != null && protocol.equals("ikvmres")) { |
| | 173 | isIKVMDll = true; |
| | 174 | |
| | 175 | } |
| | 176 | } |
| | 177 | } |
| | 178 | return isIKVM; |
| | 179 | } |
| | 180 | |
| | 181 | /** |
| | 182 | * |
| | 183 | */ |
| | 184 | private static void addIkvmFeature() throws ConditionThrowable { |
| | 185 | // TODO Auto-generated method stub |
| | 186 | Symbol featureVar = Symbol.FEATURES; |
| | 187 | LispObject features = featureVar.symbolValue(); |
| | 188 | features = features.push(Lisp.internKeyword("IKVM")); |
| | 189 | featureVar.setSymbolValue(features); |
| | 190 | } |
| | 191 | |
| | 192 | public static boolean isIKVMDll() { |
| | 193 | return isIKVM() && isIKVMDll; |
| | 194 | } |
| | 195 | |
| | 196 | static { |
| | 197 | String lispHome = null; |
| | 198 | File lispTemp = null; |
| | 199 | isIKVM(); |
| | 200 | URL url = Lisp.class.getResource("boot.lisp"); |
| | 201 | if (url != null) { |
| | 202 | String protocol = url.getProtocol(); |
| | 203 | if (protocol != null && (protocol.equals("file") || (protocol.equals("ikvmres")))) { |
| | 204 | String path = url.getPath(); |
| | 205 | int index = path.lastIndexOf('/'); |
| | 206 | if (index >= 0) { |
| | 207 | lispHome = path.substring(0, index + 1); |
| | 208 | if (Utilities.isPlatformWindows) { |
| | 209 | if (lispHome.length() > 0 && lispHome.charAt(0) == '/') lispHome = lispHome.substring(1); |
| | 210 | } |
| | 211 | } |
| | 212 | } |
| | 213 | } |
| | 214 | //System.out.println("// IKVM Lisp home = " + lispHome); |
| | 215 | try { |
| | 216 | lispTemp = File.createTempFile("ikvm", null).getParentFile(); |
| | 217 | File subdir = new File(lispTemp.getAbsolutePath()+"/ikvm"); |
| | 218 | subdir.mkdirs(); |
| | 219 | if (subdir.isDirectory()) |
| | 220 | lispTemp = subdir; |
| | 221 | } catch (IOException e) { |
| | 222 | // TODO Auto-generated catch block |
| | 223 | e.printStackTrace(); |
| | 224 | } |
| | 225 | IKVM_LISP_TEMP = lispTemp; |
| | 226 | IKVM_LISP_HOME = lispHome; |
| | 227 | } |
| | 228 | |
| | 229 | public static final String getIKVMLispHome() { |
| | 230 | return IKVM_LISP_HOME; |
| | 231 | } |
| | 232 | |
| | 233 | // ### *ikvm-lisp-home* |
| | 234 | private static final Symbol _IKVM_LISP_HOME_ = exportSpecial("*IKVM-LISP-HOME*", PACKAGE_EXT, NIL); |
| | 235 | |
| | 236 | static { |
| | 237 | try { |
| | 238 | String s = getIKVMLispHome(); |
| | 239 | if (s != null) _IKVM_LISP_HOME_.setSymbolValue(new Pathname(s)); |
| | 240 | } catch (Throwable t) { |
| | 241 | Debug.trace(t); |
| | 242 | } |
| | 243 | } |
| | 244 | } |
| | 245 | No newline at end of file |