1 /* 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /** 27 * This script contains non-standard, Mozilla compatibility functionality on 28 * the standard global objects. Please note that it is incomplete. Only the most 29 * often used functionality is supported. 30 */ 31 32 // JavaAdapter 33 Object.defineProperty(this, "JavaAdapter", { 34 configurable: true, enumerable: false, writable: true, 35 value: function() { 36 if (arguments.length < 2) { 37 throw new TypeError("JavaAdapter requires atleast two arguments"); 38 } 39 40 var types = Array.prototype.slice.call(arguments, 0, arguments.length - 1); 41 var NewType = Java.extend.apply(Java, types); 42 return new NewType(arguments[arguments.length - 1]); 43 } 44 }); 45 46 47 // importPackage 48 // avoid unnecessary chaining of __noSuchProperty__ again 49 // in case user loads this script more than once. 50 if (typeof importPackage == 'undefined' || !(importPackage instanceof Function)) { 51 52 Object.defineProperty(this, "importPackage", { 53 configurable: true, enumerable: false, writable: true, 54 value: (function() { 55 var _packages = []; 56 var global = this; 57 var oldNoSuchProperty = global.__noSuchProperty__; 58 var __noSuchProperty__ = function(name) { 59 'use strict'; 60 for (var i in _packages) { 61 try { 62 var type = Java.type(_packages[i] + "." + name); 63 global[name] = type; 64 return type; 65 } catch (e) {} 66 } 67 68 if (oldNoSuchProperty) { 69 return oldNoSuchProperty.call(this, name); 70 } else { 71 if (this === undefined) { 72 throw new ReferenceError(name + " is not defined"); 73 } else { 74 return undefined; 75 } 76 } 77 } 78 79 Object.defineProperty(global, "__noSuchProperty__", { 80 writable: true, configurable: true, enumerable: false, 81 value: __noSuchProperty__ 82 }); 83 84 var prefix = "[JavaPackage "; 85 return function() { 86 for (var i in arguments) { 87 var pkgName = arguments[i]; 88 if ((typeof pkgName) != 'string') { 89 pkgName = String(pkgName); 90 // extract name from JavaPackage object 91 if (pkgName.startsWith(prefix)) { 92 pkgName = pkgName.substring(prefix.length, pkgName.length - 1); 93 } 94 } 95 _packages.push(pkgName); 96 } 97 } 98 })() 99 }); 100 101 } 102 103 // sync 104 Object.defineProperty(this, "sync", { 105 configurable: true, enumerable: false, writable: true, 106 value: function(func, syncobj) { 107 if (arguments.length < 1 || arguments.length > 2 ) { 108 throw "sync(function [,object]) parameter count mismatch"; 109 } 110 return Java.synchronized(func, syncobj); 111 } 112 }); 113 114 // Object.prototype.__defineGetter__ 115 Object.defineProperty(Object.prototype, "__defineGetter__", { 116 configurable: true, enumerable: false, writable: true, 117 value: function(name, func) { 118 Object.defineProperty(this, name, { 119 configurable: true, enumerable: true, get: func }); 120 } 121 }); 122 123 // Object.prototype.__defineSetter__ 124 Object.defineProperty(Object.prototype, "__defineSetter__", { 125 configurable: true, enumerable: false, writable: true, 126 value: function(name, func) { 127 Object.defineProperty(this, name, { 128 configurable: true, enumerable: true, set: func }); 129 } 130 }); 131 132 // Object.prototype.__lookupGetter__ 133 Object.defineProperty(Object.prototype, "__lookupGetter__", { 134 configurable: true, enumerable: false, writable: true, 135 value: function(name) { 136 var obj = this; 137 while (obj) { 138 var desc = Object.getOwnPropertyDescriptor(obj, name); 139 if (desc) return desc.get; 140 obj = Object.getPrototypeOf(obj); 141 } 142 return undefined; 143 } 144 }); 145 146 // Object.prototype.__lookupSetter__ 147 Object.defineProperty(Object.prototype, "__lookupSetter__", { 148 configurable: true, enumerable: false, writable: true, 149 value: function(name) { 150 var obj = this; 151 while (obj) { 152 var desc = Object.getOwnPropertyDescriptor(obj, name); 153 if (desc) return desc.set; 154 obj = Object.getPrototypeOf(obj); 155 } 156 return undefined; 157 } 158 }); 159 160 // Object.prototype.toSource 161 Object.defineProperty(Object.prototype, "toSource", { 162 configurable: true, enumerable: false, writable: true, 163 value: function(state) { 164 if (! state) { 165 state = java.util.Collections.newSetFromMap(new java.util.HashMap()); 166 } 167 if (state.contains(this)) { 168 return "{}"; 169 } 170 state.add(this); 171 var str = new java.lang.StringBuffer('({'); 172 for (i in this) { 173 str.append(i); 174 str.append(':'); 175 if (this[i] instanceof Object && typeof(this[i].toSource) == 'function') { 176 str.append(this[i].toSource(state)); 177 } else { 178 str.append(String(this[i])); 179 } 180 str.append(', '); 181 } 182 // delete last extra command and space 183 str = str.deleteCharAt(str.length() - 1); 184 str = str.deleteCharAt(str.length() - 1); 185 str.append('})'); 186 return str.toString(); 187 } 188 }); 189 190 // Boolean.prototype.toSource 191 Object.defineProperty(Boolean.prototype, "toSource", { 192 configurable: true, enumerable: false, writable: true, 193 value: function() { 194 return '(new Boolean(' + this.toString() + '))'; 195 } 196 }); 197 198 // Date.prototype.toSource 199 Object.defineProperty(Date.prototype, "toSource", { 200 configurable: true, enumerable: false, writable: true, 201 value: function() { 202 return '(new Date(' + this.valueOf() + '))'; 203 } 204 }); 205 206 // Function.prototype.toSource -- already implemented in nashorn 207 208 // Number.prototype.toSource 209 Object.defineProperty(Number.prototype, "toSource", { 210 configurable: true, enumerable: false, writable: true, 211 value: function() { 212 return '(new Number(' + this.toString() + '))'; 213 } 214 }); 215 216 // RegExp.prototype.toSource 217 Object.defineProperty(RegExp.prototype, "toSource", { 218 configurable: true, enumerable: false, writable: true, 219 value: function() { 220 return this.toString(); 221 } 222 }); 223 224 // String.prototype.toSource 225 Object.defineProperty(String.prototype, "toSource", { 226 configurable: true, enumerable: false, writable: true, 227 value: function() { 228 return '(new String(' + this.quote() + '))'; 229 } 230 }); 231 232 // Error.prototype.toSource 233 Object.defineProperty(Error.prototype, "toSource", { 234 configurable: true, enumerable: false, writable: true, 235 value: function() { 236 var msg = this.message? String(this.message).quote() : "''"; 237 return '(new ' + this.name + '(' + msg + '))'; 238 } 239 }); 240 241 // Function.prototype.arity 242 Object.defineProperty(Function.prototype, "arity", { 243 configurable: true, enumerable: false, 244 get: function() { return this.length; }, 245 set: function(x) { 246 throw new TypeError("Function arity can not be modified"); 247 } 248 }); 249 250 // String.prototype.quote 251 Object.defineProperty(String.prototype, "quote", { 252 configurable: true, enumerable: false, writable: true, 253 value: function() { 254 return JSON.stringify(this); 255 } 256 }); 257 258 // HTML generation methods of String.prototype 259 260 // String.prototype.anchor 261 Object.defineProperty(String.prototype, "anchor", { 262 configurable: true, enumerable: false, writable: true, 263 value: function(name) { 264 return '<a name="' + name + '">' + this + '</a>'; 265 } 266 }); 267 268 // String.prototype.big 269 Object.defineProperty(String.prototype, "big", { 270 configurable: true, enumerable: false, writable: true, 271 value: function() { 272 return '<big>' + this + '</big>'; 273 } 274 }); 275 276 // String.prototype.blink 277 Object.defineProperty(String.prototype, "blink", { 278 configurable: true, enumerable: false, writable: true, 279 value: function() { 280 return '<blink>' + this + '</blink>'; 281 } 282 }); 283 284 // String.prototype.bold 285 Object.defineProperty(String.prototype, "bold", { 286 configurable: true, enumerable: false, writable: true, 287 value: function() { 288 return '<b>' + this + '</b>'; 289 } 290 }); 291 292 // String.prototype.fixed 293 Object.defineProperty(String.prototype, "fixed", { 294 configurable: true, enumerable: false, writable: true, 295 value: function() { 296 return '<tt>' + this + '</tt>'; 297 } 298 }); 299 300 // String.prototype.fontcolor 301 Object.defineProperty(String.prototype, "fontcolor", { 302 configurable: true, enumerable: false, writable: true, 303 value: function(clr) { 304 return '<font color="' + clr + '">' + this + '</font>'; 305 } 306 }); 307 308 // String.prototype.fontsize 309 Object.defineProperty(String.prototype, "fontsize", { 310 configurable: true, enumerable: false, writable: true, 311 value: function(size) { 312 return '<font size="' + size + '">' + this + '</font>'; 313 } 314 }); 315 316 // String.prototype.italics 317 Object.defineProperty(String.prototype, "italics", { 318 configurable: true, enumerable: false, writable: true, 319 value: function() { 320 return '<i>' + this + '</i>'; 321 } 322 }); 323 324 // String.prototype.link 325 Object.defineProperty(String.prototype, "link", { 326 configurable: true, enumerable: false, writable: true, 327 value: function(url) { 328 return '<a href="' + url + '">' + this + '</a>'; 329 } 330 }); 331 332 // String.prototype.small 333 Object.defineProperty(String.prototype, "small", { 334 configurable: true, enumerable: false, writable: true, 335 value: function() { 336 return '<small>' + this + '</small>'; 337 } 338 }); 339 340 // String.prototype.strike 341 Object.defineProperty(String.prototype, "strike", { 342 configurable: true, enumerable: false, writable: true, 343 value: function() { 344 return '<strike>' + this + '</strike>'; 345 } 346 }); 347 348 // String.prototype.sub 349 Object.defineProperty(String.prototype, "sub", { 350 configurable: true, enumerable: false, writable: true, 351 value: function() { 352 return '<sub>' + this + '</sub>'; 353 } 354 }); 355 356 // String.prototype.sup 357 Object.defineProperty(String.prototype, "sup", { 358 configurable: true, enumerable: false, writable: true, 359 value: function() { 360 return '<sup>' + this + '</sup>'; 361 } 362 }); 363 364 // Rhino: global.importClass 365 Object.defineProperty(this, "importClass", { 366 configurable: true, enumerable: false, writable: true, 367 value: function() { 368 for (var arg in arguments) { 369 var clazz = arguments[arg]; 370 if (Java.isType(clazz)) { 371 var className = Java.typeName(clazz); 372 var simpleName = className.substring(className.lastIndexOf('.') + 1); 373 this[simpleName] = clazz; 374 } else { 375 throw new TypeError(clazz + " is not a Java class"); 376 } 377 } 378 } 379 });