| 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 |