1 /* 2 * ilib-rhino.js - glue code for rhino apps to load local ilib code and 3 * data in a plain rhino environment. If you are using ringojs, use the 4 * ilib-ringo.js loader instead. 5 * 6 * Copyright © 2015, JEDLSoft 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22 var module = { 23 exports: {}, 24 filename:null 25 }; 26 27 var console = { 28 log: function() { 29 print.apply(undefined, arguments); 30 } 31 }; 32 33 console.log("root environment is " + JSON.stringify(environment, undefined, 4)); 34 35 var requireClass = function() { 36 this.cache = {}; 37 this.loading = {}; 38 this.updateRequire = /require\(("[^/][^"+]*")\)/g; 39 40 this.root = environment["user.dir"]; 41 if (this.root[this.root.length-1] === '/') { 42 this.root = this.normalize(this.root.substring(0,this.root.length-1)); 43 } 44 }; 45 46 requireClass.prototype.dirname = function(pathname) { 47 pathname = pathname.replace("\\", "/"); 48 var i = pathname.lastIndexOf("/"); 49 return i !== -1 ? pathname.substring(0,i) : pathname; 50 }; 51 52 requireClass.prototype.normalize = function(pathname) { 53 if (pathname) { 54 var previousLen; 55 pathname = pathname.replace(/\\/g, "/"); 56 do { 57 previousLen = pathname.length; 58 pathname = pathname.replace(/\/\//g, "/"); 59 pathname = pathname.replace(/\/[^/]*[^\./]\/\.\./g, "/."); 60 pathname = pathname.replace(/\/\.\//g, "/"); 61 pathname = pathname.replace(/^\.\//, ""); 62 pathname = pathname.replace(/\/\.$/, "/"); 63 if (pathname.length > 1) pathname = pathname.replace(/\/$/, ""); 64 if (pathname.length === 0) pathname = '.'; 65 } while (pathname.length < previousLen); 66 } 67 return pathname; 68 }; 69 70 requireClass.prototype._loadFile = function (pathname) { 71 console.log("requireClass._loadFile: attempting to load " + pathname); 72 var text = ""; 73 var reader; 74 try { 75 reader = new BufferedReader(new InputStreamReader(new FileInputStream(pathname), "utf-8")); 76 var tmp; 77 while ((tmp = reader.readLine()) !== null) { 78 text += tmp + '\n'; 79 } 80 } catch (e) { 81 // ignore 82 text = undefined; 83 } finally { 84 if (reader) { 85 try { 86 reader.close(); 87 } catch (e2) {} 88 } 89 cb && typeof(cb) === 'function' && cb(text); 90 } 91 return text; 92 }; 93 94 requireClass.prototype.require = function(parent, pathname) { 95 console.log("------------------------\nrequire: called with " + pathname); 96 97 console.log("this.root is " + this.root + " and pathname before was " + pathname); 98 console.log("require: module.filename is " + module.filename); 99 console.log("require: parent is " + parent); 100 101 var base = parent || (module.filename && this.dirname(module.filename)) || this.root; 102 103 console.log("require: base is " + base); 104 105 if (pathname.charAt(0) !== '/') { 106 pathname = base + "/" + pathname; 107 } 108 109 pathname = this.normalize(pathname); 110 console.log("require: pathname after is " + pathname); 111 112 if (this.cache[pathname]) { 113 console.log("require: cache hit"); 114 return this.cache[pathname]; 115 } 116 117 // don't try to load things that are currently in the process of loading 118 if (this.loading[pathname]) { 119 console.log("require: already loading..."); 120 return {}; 121 } 122 console.log("require: loading the file"); 123 124 try { 125 var text = this._loadFile(pathname); 126 var dirname = path.dirname(pathname); 127 var match, replacement; 128 129 if (text) { 130 var tmp = module.filename; 131 module.filename = pathname; 132 module.exports = null; 133 this.loading[pathname] = true; 134 module.require = requireClass.prototype.require.bind(r, this.dirname(pathname)); 135 136 while ((match = this.updateRequire.exec(text)) !== null) { 137 replacement = path.normalize(path.join(dirname, match[1])); 138 text = text.replace(new RegExp('"' + match[1] + '"', "g"), '"' + replacement + '"'); 139 this.updateRequire.lastIndex = match.index + replacement.length + 2; 140 } 141 142 // console.log("text is " + text); 143 try { 144 eval(text); 145 146 this.cache[pathname] = module.exports; 147 module.exports.module = { 148 filename: pathname, 149 require: requireClass.prototype.require.bind(r, this.dirname(pathname)) 150 }; 151 } finally { 152 this.loading[pathname] = undefined; 153 module.filename = tmp; 154 } 155 156 return module.exports; 157 } 158 } catch (e) { 159 console.log("Failed loading " + pathname); 160 console.log("exception was " + e); 161 } 162 163 return undefined; 164 }; 165 166 var r = new requireClass(); 167 var require = requireClass.prototype.require.bind(r, undefined); 168 169 var RhinoLoader = require("../lib/RhinoLoader.js"); 170 var ilib = require("../lib/ilib.js"); 171 ilib._dyncode = true; // indicate that we are using dynamically loaded code 172 ilib._dyndata = true; 173 174 ilib.setLoaderCallback(new RhinoLoader());