X-Git-Url: http://source.jalview.org/gitweb/?p=jalviewjs.git;a=blobdiff_plain;f=site%2Fjs%2Fj2sSwingJS.js;fp=site%2Fjs%2Fj2sSwingJS.js;h=12f32cd743b621535d4f6aa562e62bc9d8f4c139;hp=c4e47ed1b0987ce6326668008bae1726406eccda;hb=b9b7a352eee79b7764c3b09c9d19663075061d8c;hpb=7301a2415adab88038b291fc54caeeb3a5a47a44 diff --git a/site/js/j2sSwingJS.js b/site/js/j2sSwingJS.js index c4e47ed..12f32cd 100644 --- a/site/js/j2sSwingJS.js +++ b/site/js/j2sSwingJS.js @@ -1,5427 +1,5427 @@ -// j2sjmol.js - -// latest author: Bob Hanson, St. Olaf College, hansonr@stolaf.edu - -// Requires JSmolCore.js and (for now; probably) JSmol.js -// This version of j2slib requires jQuery and works in both Chrome and MSIE locally, -// though Chrome cannot read local data files, and MSIE cannot read local binary data files. - -// Java programming notes by Bob Hanson: -// -// There are a few motifs to avoid when optimizing Java code to work smoothly -// with the J2S compiler: -// -// arrays: -// -// 1. an array with null elements cannot be typed and must be avoided. -// 2. instances of Java "instance of" involving arrays must be found and convered to calls to Clazz.isA... -// 3. new int[n][] must not be used. Use instead JU.AU.newInt2(n); -// 4. new int[] { 1, 2, 3 } has problems because it creates simply [ ] and not IntArray32 -// -// numbers: -// -// 1. Remember that EVERY number in JavaScript is a double -- doesn't matter if it is in IntArray32 or not. -// 2. You cannot reliably use Java long, because doubles consume bits for the exponent which cannot be tested. -// 3. Bit 31 of an integer is unreliable, since (int) -1 is now , not just 0zFFFFFFFF, and -// FFFFFFFF + 1 = 100000000, not 0. In JavaScript, 0xFFFFFFFF is 4294967295, not -1. -// This means that writeInt(b) will fail if b is negative. What you need is instead -// writeInt((int)(b & 0xFFFFFFFFl) so that JavaScript knocks off the high bits explicitly. -// -// general: -// -// 1. j2sRequireImport xxxx is needed if xxxx is a method used in a static function -// 2. URL.getContent() is not supported. Use other means based on URL.toString() -// 3. It is critical for performance to avoid any significant amount of function overloading. -// In particular, methods such as xxx(int a, int b) and xxx(float a, int b) MUST be renamed, -// because JavaScript only has Number, and there is absolutely no way to tell these apart. -// It's probably bad Java programming, anyway. -// 4. Calls to super(...) can almost always be avoided. These trigger the SAEM -// (searchAndExecuteMethod) call, and it is very destructive to performance. -// Just find another way to do it. - - // NOTES by Bob Hanson: - - // J2S class changes: - - // BH 7/24/2015 6:48:50 AM adding optional ?j2sdebug flag on page URL - // -- switches to using j2s/core/corexxx.js, not j2s/core/corexxx.z.js - // -- adds ";//# sourceURL="+file in eval(js) - // -- enables DebugJS.$(msg) call to debugger; - // see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger - // see https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Debug_eval_sources - // BH 7/23/2015 6:45:55 PM added sourceURL in each js class eval(), allowing full - // breakpoint debugging and code checking in Firefox and Chrome - // BH 7/19/2015 6:18:17 PM added os.name, line.separator, etc. to System.getProperty() - // BH 7/19/2015 5:39:10 PM added java.lang.System = System - // BH 7/19/2015 10:33:10 AM fix for SAEM equating "null" with number or boolean - // BH 7/18/2015 6:08:05 PM for Jmol I was able to remove the $private/$fx business, but now - // I see that in general that cannot be done. Thinking about a strategy... - // BH 7/18/2015 4:43:38 PM better handling of TypeError and InternalError for e.getMessage() and e.getStackTrace() - // BH 7/17/2015 11:51:15 AM adds class.getResource(name) and class.getResourceAsStream(name) - // BH 7/16/2015 7:56:49 PM general instantiation using any constructor (in Java here): - // BH x = class.forName("my.class.name").newInstance() - // BH or - // BH x = class.forName("my.class.name").getConstructor(String.class,String.class).newInstance(new Object[] {"test", "now"}) - // BH 7/15/2015 11:34:58 PM adding System.lineSeparator() - // BH 7/15/2015 7:32:41 AM adding class.getCanonicalName == getName - // BH 5/31/2015 5:38:14 PM NPEExceptionPredicate fix - // BH 4/25/2015 9:16:12 AM SAEM misrepresnting Number as Object in parameters and Integer as Number - // BH 4/24/2015 7:32:54 AM Object.hashCode() and System.getIdentityHashCode() fail. changed to: return this._$hashcode || (this._$hashcode = ++Clazz._hashCode) - // BH 4/23/2015 9:08:59 AM Clazz.instanceOf(a, b) needs to check for a == b. - // BH 4/23/2015 9:08:59 AM xx.getContentType() is nonfunctional. Array.newInstance now defines a wrapper for .getClass().getComponentType() that works - // BH 4/12/2015 11:48:03 AM added Clazz.getStackTrace(-n) -- reports actual parameter values for n levels - // BH 4/10/2015 8:23:05 AM adding Int32Array.prototype.clone and Float64.prototype.clone - // BH 4/5/2015 8:12:57 AM refactoring j2slib (this file) to make private functions really private using var - // BH 4/3/2015 6:14:34 AM adding anonymous local "ClazzLoader" (Clazz._Loader) --> "_Loader" - // BH 4/3/2015 6:14:34 AM adding Clazz._Loader._classPending, Clazz._Loader._classCount - // BH 4/3/2015 6:14:34 AM adding Clazz._Loader._checkLoad - // -- forces asynchronous class loading - // -- builds Clazz._Loader._classPending and Clazz._classCount - // -- allows reporting - - // BH 3/24/2015 4:11:26 AM better file load failure message in _Loader.evaluate - // BH 2/28/2015 7:30:25 AM corrects newIntArray32() and newArray() for pre-defined arrays - // int[] a = new int[] {1,2,3,343}; - // int[][] b = new int[][] {new int[]{4,5},new int[]{5,6}}; - - // BH 9/29/2014 11:34:19 PM removing support for getClass().isArray() - // BH 8/29/2014 9:15:57 AM total reworking of Java2Script in preparation for all-asynchronous loading - // (currently sync loading is only for - // LOAD command and load() function without ASYNC - // getInterface() - // see JSmol.js and Jmol._isAsync flag - // BH 5/11/2015 5:58:42 AM adding __signatures for debugging SAEM issues - // BH 3/29/2015 8:12:44 PM System.getProperty(x, "") does not return "" - // BH 8/23/2014 10:04:19 AM cleaning up a few general methods; Clazz.removeArrayItem - // BH 6/1/2014 10:58:46 AM fix for Clazz.isAP() not working - // BH 5/26/2014 5:19:29 PM removing superConstructor call in creating Enum constants - // BH 4/1/2014 7:55:54 PM removing all $fz references and instances where sub/super classes have same private function names - // BH 4/1/2014 4:47:30 PM all $_X removed; this is taken care of by Google Closure Compiler - // BH 4/1/2014 6:40:08 AM removing ClassLoader -- equals Clazz._Loader - // BH 4/1/2014 6:40:08 AM removing ClassLoaderProgressMonitor -- equals _LoaderProgressMonitor - // BH 4/1/2014 6:17:21 AM removing Class -- only used for "Class.forName" in Jmol, which ANT will now change to "Clazz._4Name" - // BH 3/7/2014 9:05:06 AM Array.prototype.toString should not be aliased. -- http://sourceforge.net/p/jmol/bugs/560/ with Google Visualization - - // BH 1/30/2014 12:54:22 PM gave all field variables prefix underscore. This allows Google Closure Compiler to skip them. - // BH 12/3/2013 3:39:57 PM window["j2s.lib"].base implemented - // BH 12/1/2013 5:34:21 AM removed _LoaderProgressMonitor.initialize and all Clazz.event business; handled by Jmol.clearVars() - // BH 11/30/2013 12:43:58 PM adding Clazz.arrayIs() -- avoids Number.constructor.toString() infinite recursion - // BH 11/29/2013 6:33:51 AM adding Clazz._profiler -- reports use of SAEM - // BH 11/10/2013 9:02:20 AM fixing fading in MSIE - // BH 11/3/2013 7:21:39 AM additional wrapping functions for better compressibility - // BH 10/30/2013 8:10:58 AM added getClass().getResource() -- returning a relative string, not a URL - // BH 10/30/2013 6:43:00 AM removed second System def and added System.$props and default System.property "line.separator" - // BH 6/15/2013 8:02:07 AM corrections to Class.isAS to return true if first element is null - // BH 6/14/2013 4:41:09 PM corrections to Clazz.isAI and related methods to include check for null object - // BH 3/17/2013 11:54:28 AM adds stackTrace for ERROR - - // BH 3/13/2013 6:58:26 PM adds Clazz.clone(me) for BS clone - // BH 3/12/2013 6:30:53 AM fixes Clazz.exceptionOf for ERROR condition trapping - // BH 3/2/2013 9:09:53 AM delete globals c$ and $fz - // BH 3/2/2013 9:10:45 AM optimizing defineMethod using "look no further" "@" parameter designation (see "\\@" below -- removed 3/23/13) - // BH 2/27/2013 optimizing Clazz.getParamsType for common cases () and (Number) - // BH 2/27/2013 optimizing SAEM delegation for hashCode and equals -- disallows overloading of equals(Object) - - // BH 2/23/2013 found String.replaceAll does not work -- solution was to never call it. - // BH 2/9/2013 9:18:03 PM Int32Array/Float64Array fixed for MSIE9 - // BH 1/25/2013 1:55:31 AM moved package.js from j2s/java to j2s/core - // BH 1/17/2013 4:37:17 PM String.compareTo() added - // BH 1/17/2013 4:52:22 PM Int32Array and Float64Array may not have .prototype.sort method - // BH 1/16/2013 6:20:34 PM Float64Array not available in Safari 5.1 - // BH 1/14/2013 11:28:58 PM Going to all doubles in JavaScript (Float64Array, not Float32Array) - // so that (new float[] {13.48f})[0] == 13.48f, effectively - - // BH 1/14/2013 12:53:41 AM Fix for Opera 10 not loading any files - // BH 1/13/2013 11:50:11 PM Fix for MSIE not loading (nonbinary) files locally - - // BH 12/1/2012 9:52:26 AM Compiler note: Thread.start() cannot be executed within the constructor; - - // BH 11/24/2012 11:08:39 AM removed unneeded sections - // BH 11/24/2012 10:23:22 AM all XHR uses sync loading (_Loader.setLoadingMode) - // BH 11/21/2012 7:30:06 PM if (base) map["@" + pkg] = base; critical for multiple applets - - // BH 10/8/2012 3:27:41 PM if (clazzName.indexOf("Array") >= 0) return "Array"; in Clazz.getClassName for function - // BH removed Clazz.ie$plit = "\\2".split (/\\/).length == 1; unnecessary; using RegEx slows process significantly in all browsers - // BH 10/6/12 added Int32Array, Float32Array, newArrayBH, upgraded java.lang and java.io - // BH added Integer.bitCount in core.z.js - // BH changed alert to Clazz.alert in java.lang.Class.js *.ClassLoader.js, java.lang.thread.js - // BH removed toString from innerFunctionNames due to infinite recursion - // BH note: Logger.error(null, e) does not work -- get no constructor for (String) (TypeError) - // BH added j2s.lib.console - // BH allowed for alias="." - // BH removed alert def --> Clazz.alert - // BH added wrapper at line 2856 - // BH newArray fix at line 2205 - // BH System.getProperty fix at line 6693 - // BH added Enum .value() method at line 2183 - // BH added System.getSecurityManager() at end - // BH added String.contains() at end - // BH added System.gc() at end - // BH added Clazz.exceptionOf = updated - // BH added String.getBytes() at end - - -LoadClazz = function() { - -// BH This is the ONLY global used in J2S now. I do not think it is necessary, -// but it is created by the compiler, and I have not found a work-around. -// it is used as a local variable in class definitions to point to the -// current method. See Clazz.p0p and Clazz.pu$h - -c$ = null; - -if (!window["j2s.clazzloaded"]) - window["j2s.clazzloaded"] = false; - -if (window["j2s.clazzloaded"])return; - -window["j2s.clazzloaded"] = true; - -window["j2s.object.native"] = true; - - // Clazz changes: - - /* http://j2s.sf.net/ *//****************************************************************************** - * Copyright (c) 2007 java2script.org and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Zhou Renjian - initial API and implementation - *****************************************************************************/ -/******* - * @author zhou renjian - * @create Nov 5, 2005 - *******/ - - -/** - * Class Clazz. All the methods are static in this class. - */ -/* static */ -/*Class = */ Clazz = { - _isQuiet: false, - _debugging: false -}; - -;(function(Clazz, Jmol) { - - -try { -Clazz._debugging = (document.location.href.indexOf("j2sdebug") >= 0); -} catch (e) { -} -var __debuggingBH = false; -var _globals = ["j2s.clazzloaded", "j2s.object.native"]; -Clazz.setGlobal = function(a, v) { - _globals.push(a); - window[a] = v; -} - -Clazz.getGlobals = function() { - return _globals.sort().join("\n"); -} - -Clazz.setConsoleDiv = function(d) { - window["j2s.lib"] && (window["j2s.lib"].console = d); -}; - -// BH Clazz.getProfile monitors exactly what is being delegated with SAEM, -// which could be a bottle-neck for function calling. -// This is critical for performance optimization. - -// Jmol.getProfile() - -var _profile = (window["j2s.doProfile"] && self.JSON ? {} : null); - -NullObject = function () {}; - -/* protected */ -Clazz._supportsNativeObject = window["j2s.object.native"]; - -if (Clazz._supportsNativeObject) { - Clazz._O = function () {}; - Clazz._O.__CLASS_NAME__ = "Object"; - Clazz._O["getClass"] = function () { return Clazz._O; }; -} else { - Clazz._O = Object; -} - -Clazz.Console = {}; -Clazz.dateToString = Date.prototype.toString; -Clazz._hashCode = 0; - -var addProto = function(proto, name, func) { - return proto[name] = func; -}; - -;(function(proto) { - addProto(proto, "equals", function (obj) { - return this == obj; - }); - - addProto(proto, "hashCode", function () { - - return this._$hashcode || (this._$hashcode = ++Clazz._hashCode) - - - try { - return this.toString ().hashCode (); - } catch (e) { - var str = ":"; - for (var s in this) { - str += s + ":" - } - return str.hashCode (); - } - }); - - addProto(proto, "getClass", function () { return Clazz.getClass (this); }); - - addProto(proto, "clone", function () { return Clazz.clone(this); }); - - Clazz.clone = function(me) { - // BH allows @j2sNative access without super constructor - var o = new me.constructor(); - for (var i in me) { - o[i] = me[i]; - } - return o; - } -/* - * Methods for thread in Object - */ - addProto(proto, "finalize", function () {}); - addProto(proto, "notify", function () {}); - addProto(proto, "notifyAll", function () {}); - addProto(proto, "wait", function () {}); - addProto(proto, "to$tring", Object.prototype.toString); - addProto(proto, "toString", function () { return (this.__CLASS_NAME__ ? "[" + this.__CLASS_NAME__ + " object]" : this.to$tring.apply(this, arguments)); }); - Clazz._extendedObjectMethods = [ "equals", "hashCode", "getClass", "clone", "finalize", "notify", "notifyAll", "wait", "to$tring", "toString" ]; - -})(Clazz._O.prototype); - -Clazz.extendJO = function(c, name) { - if (name) - c.__CLASS_NAME__ = c.prototype.__CLASS_NAME__ = name; - if (Clazz._supportsNativeObject) { - for (var i = 0; i < Clazz._extendedObjectMethods.length; i++) { - var p = Clazz._extendedObjectMethods[i]; - addProto(c.prototype, p, Clazz._O.prototype[p]); - } - } -}; - -/** - * Try to fix bug on Safari - */ -//InternalFunction = Object; - -Clazz.extractClassName = function(clazzStr) { - // [object Int32Array] - var clazzName = clazzStr.substring (1, clazzStr.length - 1); - return (clazzName.indexOf("Array") >= 0 ? "Array" // BH -- for Float64Array and Int32Array - : clazzName.indexOf ("object ") >= 0 ? clazzName.substring (7) // IE - : clazzName); -} -/** - * Return the class name of the given class or object. - * - * @param clazzHost given class or object - * @return class name - */ -/* public */ -Clazz.getClassName = function (obj) { - if (obj == null) - return "NullObject"; - if (obj instanceof Clazz.CastedNull) - return obj.clazzName; - switch(typeof obj) { - case "number": - return "n"; - case "boolean": - return "b"; - case "string": - // Always treat the constant string as String object. - // This will be compatiable with Java String instance. - return "String"; - case "function": - if (obj.__CLASS_NAME__) - return (arguments[1] ? obj.__CLASS_NAME__ : "Class"); /* user defined class name */ - var s = obj.toString(); - var idx0 = s.indexOf("function"); - if (idx0 < 0) - return (s.charAt(0) == '[' ? Clazz.extractClassName(s) : s.replace(/[^a-zA-Z0-9]/g, '')); - var idx1 = idx0 + 8; - var idx2 = s.indexOf ("(", idx1); - if (idx2 < 0) - return "Object"; - s = s.substring (idx1, idx2); - if (s.indexOf("Array") >= 0) - return "Array"; - s = s.replace (/^\s+/, "").replace (/\s+$/, ""); - return (s == "anonymous" || s == "" ? "Function" : s); - case "object": - if (obj.__CLASS_NAME__) // user defined class name - return obj.__CLASS_NAME__; - if (!obj.constructor) - return "Object"; // For HTML Element in IE - if (!obj.constructor.__CLASS_NAME__) { - if (obj instanceof Number) - return "Number"; - if (obj instanceof Boolean) - return "Boolean"; - if (obj instanceof Array) - return "Array"; - var s = obj.toString(); - // "[object Int32Array]" - if (s.charAt(0) == '[') - return Clazz.extractClassName(s); - } - return Clazz.getClassName (obj.constructor, true); - } - // some new, unidentified class - return "Object"; -}; -/** - * Return the class of the given class or object. - * - * @param clazzHost given class or object - * @return class name - */ -/* public */ -Clazz.getClass = function (clazzHost) { - if (!clazzHost) - return Clazz._O; // null/undefined is always treated as Object - if (typeof clazzHost == "function") - return clazzHost; - var clazzName; - if (clazzHost instanceof Clazz.CastedNull) { - clazzName = clazzHost.clazzName; - } else { - switch (typeof clazzHost) { - case "string": - return String; - case "object": - if (!clazzHost.__CLASS_NAME__) - return (clazzHost.constructor || Clazz._O); - clazzName = clazzHost.__CLASS_NAME__; - break; - default: - return clazzHost.constructor; - } - } - return Clazz.evalType(clazzName, true); -}; - - -/* private */ -var checkInnerFunction = function (hostSuper, funName) { - for (var k = 0; k < Clazz.innerFunctionNames.length; k++) - if (funName == Clazz.innerFunctionNames[k] && - Clazz._innerFunctions[funName] === hostSuper[funName]) - return true; - return false; -}; - -var args4InheritClass = function () {}; - -Clazz.inheritArgs = new args4InheritClass (); - -/** - * Inherit class with "extends" keyword and also copy those static members. - * Example, as in Java, if NAME is a static member of ClassA, and ClassB - * extends ClassA then ClassB.NAME can be accessed in some ways. - * - * @param clazzThis child class to be extended - * @param clazzSuper super class which is inherited from - * @param objSuper super class instance - */ -/* protected */ -Clazz.inheritClass = function (clazzThis, clazzSuper, objSuper) { - //var thisClassName = Clazz.getClassName (clazzThis); - for (var o in clazzSuper) { - if (o != "b$" && o != "prototype" && o != "superClazz" - && o != "__CLASS_NAME__" && o != "implementz" - && !checkInnerFunction (clazzSuper, o)) { - clazzThis[o] = clazzSuper[o]; - } - } - if (Clazz.unloadedClasses[Clazz.getClassName(clazzThis, true)]) { - // Don't change clazzThis.protoype! Keep it! - } else if (objSuper) { - // ! Unsafe reference prototype to an instance! - // Feb 19, 2006 --josson - // OK for this reference to an instance, as this is anonymous instance, - // which is not referenced elsewhere. - // March 13, 2006 - clazzThis.prototype = objSuper; - } else if (clazzSuper !== Number) { - clazzThis.prototype = new clazzSuper (Clazz.inheritArgs); - } else { // Number - clazzThis.prototype = new Number (); - } - clazzThis.superClazz = clazzSuper; - /* - * Is it necessary to reassign the class name? - * Mar 10, 2006 --josson - */ - //clazzThis.__CLASS_NAME__ = thisClassName; - clazzThis.prototype.__CLASS_NAME__ = clazzThis.__CLASS_NAME__; -}; - -/** - * Implementation of Java's keyword "implements". - * As in JavaScript there are on "implements" keyword implemented, a property - * of "implementz" is added to the class to record the interfaces the class - * is implemented. - * - * @param clazzThis the class to implement - * @param interfacez Array of interfaces - */ -/* public */ -Clazz.implementOf = function (clazzThis, interfacez) { - if (arguments.length >= 2) { - if (!clazzThis.implementz) - clazzThis.implementz = []; - var impls = clazzThis.implementz; - if (arguments.length == 2) { - if (typeof interfacez == "function") { - impls.push(interfacez); - copyProperties(clazzThis, interfacez); - } else if (interfacez instanceof Array) { - for (var i = 0; i < interfacez.length; i++) { - impls.push(interfacez[i]); - copyProperties(clazzThis, interfacez[i]); - } - } - } else { - for (var i = 1; i < arguments.length; i++) { - impls.push(arguments[i]); - copyProperties(clazzThis, arguments[i]); - } - } - } -}; - -/* - * Copy members of interface - */ -/* private */ -var copyProperties = function(clazzThis, clazzSuper) { - for (var o in clazzSuper) - if (o != "b$" - && o != "prototype" && o != "superClazz" - && o != "__CLASS_NAME__" && o != "implementz" - && (typeof clazzSuper[o] != "function" || !checkInnerFunction(clazzSuper, o))) - clazzThis[o] = clazzThis.prototype[o] = clazzSuper[o]; -}; - -/** - * TODO: More should be done for interface's inheritance - */ -/* public */ -Clazz.extendInterface = Clazz.implementOf; - -/* protected */ -Clazz.equalsOrExtendsLevel = function (clazzThis, clazzAncestor) { - if (clazzThis === clazzAncestor) - return 0; - if (clazzThis.implementz) { - var impls = clazzThis.implementz; - for (var i = 0; i < impls.length; i++) { - var level = Clazz.equalsOrExtendsLevel (impls[i], clazzAncestor); - if (level >= 0) - return level + 1; - } - } - return -1; -}; - -/* protected */ -Clazz.getInheritedLevel = function (clazzTarget, clazzBase) { - if (clazzTarget === clazzBase) - return 0; - var isTgtStr = (typeof clazzTarget == "string"); - if (isTgtStr && ("void" == clazzTarget || "unknown" == clazzTarget)) - return -1; - var isBaseStr = (typeof clazzBase == "string"); - if (isBaseStr && ("void" == clazzBase || "unknown" == clazzBase)) - return -1; - if (clazzTarget === (isTgtStr ? "NullObject" : NullObject)) { - switch (clazzBase) { - case "n": - case "b": - return -1; - case Number: - case Boolean: - case NullObject: - break; - default: - return 0; - } - } - if (isTgtStr) - clazzTarget = Clazz.evalType(clazzTarget); - if (isBaseStr) - clazzBase = Clazz.evalType(clazzBase); - if (!clazzBase || !clazzTarget) - return -1; - var level = 0; - var zzalc = clazzTarget; // zzalc <--> clazz - while (zzalc !== clazzBase && level < 10) { - /* maybe clazzBase is interface */ - if (zzalc.implementz) { - var impls = zzalc.implementz; - for (var i = 0; i < impls.length; i++) { - var implsLevel = Clazz.equalsOrExtendsLevel (impls[i], clazzBase); - if (implsLevel >= 0) - return level + implsLevel + 1; - } - } - zzalc = zzalc.superClazz; - if (!zzalc) - return (clazzBase === Object || clazzBase === Clazz._O ? - // getInheritedLevel(String, CharSequence) == 1 - // getInheritedLevel(String, Object) == 1.5 - // So if both #test(CharSequence) and #test(Object) existed, - // #test("hello") will correctly call #test(CharSequence) - // instead of #test(Object). - level + 1.5 // 1.5! Special! - : -1); - level++; - } - return level; -}; - - -/** - * Implements Java's keyword "instanceof" in JavaScript's way. - * As in JavaScript part of the object inheritance is implemented in only- - * JavaScript way. - * - * @param obj the object to be tested - * @param clazz the class to be checked - * @return whether the object is an instance of the class - */ -/* public */ -Clazz.instanceOf = function (obj, clazz) { - // allows obj to be a class already, from arrayX.getClass().isInstance(y) - return (obj != null && clazz && (obj == clazz || obj instanceof clazz || Clazz.getInheritedLevel(Clazz.getClassName(obj), clazz) >= 0)); -}; - -/** - * Call super method of the class. - * The same effect as Java's expression: - * super.* () - * - * @param objThis host object - * @param clazzThis class of declaring method scope. It's hard to determine - * which super class is right class for "super.*()" call when it's in runtime - * environment. For example, - * 1. ClasssA has method #run() - * 2. ClassB extends ClassA overriding method #run() with "super.run()" call - * 3. ClassC extends ClassB - * 4. objC is an instance of ClassC - * Now we have to decide which super #run() method is to be invoked. Without - * explicit clazzThis parameter, we only know that objC.getClass() is ClassC - * and current method scope is #run(). We do not known we are in scope - * ClassA#run() or scope of ClassB#run(). if ClassB is given, Clazz can search - * all super methods that are before ClassB and get the correct super method. - * This is the reason why there must be an extra clazzThis parameter. - * @param funName method name to be called - * @param funParams Array of method parameters - */ -/* public */ -Clazz.superCall = function (objThis, clazzThis, funName, funParams) { - var fx = null; - var i = -1; - var clazzFun = objThis[funName]; - if (clazzFun) { - if (clazzFun.claxxOwner) { - // claxxOwner is a mark for methods that is single. - if (clazzFun.claxxOwner !== clazzThis) { - // This is a single method, call directly! - fx = clazzFun; - - } - } else if (!clazzFun.stacks && !(clazzFun.lastClaxxRef - && clazzFun.lastClaxxRef.prototype[funName] - && clazzFun.lastClaxxRef.prototype[funName].stacks)) { // super.toString - fx = clazzFun; - } else { // normal wrapped method - var stacks = clazzFun.stacks; - if (!stacks) - stacks = clazzFun.lastClaxxRef.prototype[funName].stacks; - for (i = stacks.length; --i >= 0;) { - /* - * Once super call is computed precisely, there are no need - * to calculate the inherited level but just an equals - * comparision - */ - //var level = Clazz.getInheritedLevel (clazzThis, stacks[i]); - if (clazzThis === stacks[i]) { // level == 0 - if (i > 0) { - fx = stacks[--i].prototype[funName]; - } else { - /* - * Will this case be reachable? - * March 4, 2006 - * Should never reach here if all things are converted - * by Java2Script - */ - fx = stacks[0].prototype[funName]["\\unknown"]; - } - break; - } else if (Clazz.getInheritedLevel (clazzThis, stacks[i]) > 0) { - fx = stacks[i].prototype[funName]; - break; - } - } // end of for loop - } // end of normal wrapped method - } // end of clazzFun - if (!fx) { - if (funName != "construct") { - Clazz.alert (["j2slib","no class found",(funParams).typeString]) - newMethodNotFoundException(objThis, clazzThis, funName, - Clazz.getParamsType(funParams).typeString); - } - /* there are members which are initialized out of the constructor */ - /* No super constructor! */ - return; - } - /* there are members which are initialized out of the constructor */ - if (i == 0 && funName == "construct") { - var ss = clazzFun.stacks; - if (ss && !ss[0].superClazz && ss[0].con$truct) - ss[0].con$truct.apply (objThis, []); - } - /*# {$no.debug.support} >>x #*/ - /* not used in Jmol - if (Clazz.tracingCalling) { - var caller = arguments.callee.caller; - if (caller === Clazz.superConstructor) { - caller = caller.arguments.callee.caller; - } - Clazz._callingStackTraces.push(new Clazz.callingStack (caller, clazzThis)); - var ret = fx.apply (objThis, (funParams == null) ? [] : funParams); - Clazz._callingStackTraces.pop(); - return ret; - } - */ - /*# x<< #*/ - return fx.apply (objThis, funParams || []); -}; - -/** - * Call super constructor of the class. - * The same effect as Java's expression: - * super () - */ -/* public */ -Clazz.superConstructor = function (objThis, clazzThis, funParams) { - Clazz.superCall (objThis, clazzThis, "construct", funParams); - /* If there are members which are initialized out of the constructor */ - if (clazzThis.con$truct) { - clazzThis.con$truct.apply (objThis, []); - } -}; - -/** - * Class for null with a given class as to be casted. - * This class will be used as an implementation of Java's casting way. - * For example, - * this.call ((String) null); - */ -/* public */ -Clazz.CastedNull = function (asClazz) { - if (asClazz) { - if (asClazz instanceof String) { - this.clazzName = asClazz; - } else if (asClazz instanceof Function) { - this.clazzName = Clazz.getClassName (asClazz, true); - } else { - this.clazzName = "" + asClazz; - } - } else { - this.clazzName = "Object"; - } - this.toString = function () { - return null; - }; - this.valueOf = function () { - return null; - }; -}; - -/** - * API for Java's casting null. - * @see Clazz.CastedNull - * - * @param asClazz given class - * @return an instance of class Clazz.CastedNull - */ -/* public */ -Clazz.castNullAs = function (asClazz) { - return new Clazz.CastedNull (asClazz); -}; - -/////////////////////////// Exception handling //////////////////////////// - -/* - * Use to mark that the Throwable instance is created or not. - * - * Called from java.lang.Throwable, as defined in JSmolJavaExt.js - * - * The underscore is important - it tells the JSmol ANT task to NOT - * turn this into Clazz_initializingException, because coreBottom2.js does - * not include that call, and so Google Closure Compiler does not minify it. - * - */ -/* public */ -Clazz._initializingException = false; - -/** - * BH: used in Throwable - * - */ -/* public */ -Clazz._callingStackTraces = []; - -/** - * MethodException will be used as a signal to notify that the method is - * not found in the current clazz hierarchy. - */ -/* private */ -var MethodException = function () { - this.toString = function () { - return "J2S MethodException"; - }; -}; -/* private */ -//var MethodNotFoundException = function () { -// this.toString = function () { -// return "J2S MethodNotFoundException"; -// }; -//}; - - var _isNPEExceptionPredicate; - -/* super private */ -;(function() { - /* sgurin: native exception detection mechanism. Only NullPointerException detected and wrapped to java excepions */ - /** private utility method for creating a general regexp that can be used later - * for detecting a certain kind of native exceptions. use with error messages like "blabla IDENTIFIER blabla" - * @param msg String - the error message - * @param spliterName String, must be contained once in msg - * spliterRegex String, a string with the regexp literal for identifying the spitter in exception further error messages. - */ - // reproduce NullPointerException for knowing how to detect them, and create detector function Clazz._isNPEExceptionPredicate - var $$o$$ = null; - - try { - $$o$$.hello(); - } catch (e) { - var _ex_reg = function(msg, spliterName, spliterRegex) { - if(!spliterRegex) - spliterRegex="[^\\s]+"; - var idx = msg.indexOf (spliterName), - str = msg.substring (0, idx) + spliterRegex + msg.substring(idx + spliterName.length), - regexp = new RegExp("^"+str+"$"); - return regexp; - }; - if(/Opera[\/\s](\d+\.\d+)/.test(navigator.userAgent)) {// opera throws an exception with fixed messages like "Statement on line 23: Cannot convert undefined or null to Object Backtrace: Line....long text... " - var idx1 = e.message.indexOf(":"), idx2 = e.message.indexOf(":", idx1+2); - var _NPEMsgFragment = e.message.substr(idx1+1, idx2-idx1-20); - _isNPEExceptionPredicate = function(e) { return e.message.indexOf(_NPEMsgFragment)!=-1; }; - } else if(navigator.userAgent.toLowerCase().indexOf("webkit")!=-1) { //webkit, google chrome prints the property name accessed. - var _exceptionNPERegExp = _ex_reg(e.message, "hello"); - _isNPEExceptionPredicate = function(e) { return _exceptionNPERegExp.test(e.message); }; - } else {// ie, firefox and others print the name of the object accessed: - var _exceptionNPERegExp = _ex_reg(e.message, "$$o$$"); - _isNPEExceptionPredicate = function(e) { return _exceptionNPERegExp.test(e.message); }; - } - }; -})(); - -/**sgurin - * Implements Java's keyword "instanceof" in JavaScript's way **for exception objects**. - * - * calls Clazz.instanceOf if e is a Java exception. If not, try to detect known native - * exceptions, like native NullPointerExceptions and wrap it into a Java exception and - * call Clazz.instanceOf again. if the native exception can't be wrapped, false is returned. - * - * @param obj the object to be tested - * @param clazz the class to be checked - * @return whether the object is an instance of the class - * @author: sgurin - */ -Clazz.exceptionOf = function(e, clazz) { - if(e.__CLASS_NAME__) - return Clazz.instanceOf(e, clazz); - if (!e.getMessage) { - e.getMessage = function() {return "" + this}; - } - if (!e.printStackTrace) { - e.printStackTrace = function(){}; - alert(e + " try/catch path:" + Clazz.getStackTrace(-10)); - } - if(clazz == Error) { - if (("" + e).indexOf("Error") < 0) - return false; - System.out.println (Clazz.getStackTrace()); - return true; - // everything here is a Java Exception, not a Java Error - } - return (clazz == Exception || clazz == Throwable - || clazz == NullPointerException && _isNPEExceptionPredicate(e)); -}; - -/** - * BH need to limit this, as JavaScript call stack may be recursive - */ -Clazz.getStackTrace = function(n) { - n || (n = 25); - // updateNode and updateParents cause infinite loop here - var s = "\n"; - var c = arguments.callee; - var showParams = (n < 0); - if (showParams) - n = -n; - for (var i = 0; i < n; i++) { - if (!(c = c.caller)) - break; - var sig = (c.toString ? c.toString().substring(0, c.toString().indexOf("{")) : ""); - s += i + " " + (c.exName ? (c.claxxOwner ? c.claxxOwner.__CLASS_NAME__ + "." : "") + c.exName + sig.replace(/function /,""): sig) + "\n"; - if (c == c.caller) { - s += "\n"; - break; - } - if (showParams) { - var args = c.arguments; - for (var j = 0; j < args.length; j++) { - var sa = "" + args[j]; - if (sa.length > 60) - sa = sa.substring(0, 60) + "..."; - s += " args[" + j + "]=" + sa.replace(/\s+/g," ") + "\n"; - } - } - } - return s; -} - -///////////////////// method creation //////////////////////////////// - -/** - * Make constructor for the class with the given function body and parameters - * signature. - * - * @param clazzThis host class - * @param funBody constructor body - * @param funParams constructor parameters signature - */ -/* public */ -Clazz.makeConstructor = function (clazzThis, funBody, funParams) { - Clazz.defineMethod (clazzThis, "construct", funBody, funParams); - if (clazzThis.con$truct) { - clazzThis.con$truct.index = clazzThis.con$truct.stacks.length; - } - //clazzThis.con$truct = clazzThis.prototype.con$truct = null; -}; - -/** - * Override constructor for the class with the given function body and - * parameters signature. - * - * @param clazzThis host class - * @param funBody constructor body - * @param funParams constructor parameters signature - */ -/* public */ -Clazz.overrideConstructor = function (clazzThis, funBody, funParams) { - Clazz.overrideMethod (clazzThis, "construct", funBody, funParams); - if (clazzThis.con$truct) { - clazzThis.con$truct.index = clazzThis.con$truct.stacks.length; - } - //clazzThis.con$truct = clazzThis.prototype.con$truct = null; -}; - - -/* - * Define method for the class with the given method name and method - * body and method parameter signature. - * - * @param clazzThis host class in which the method to be defined - * @param funName method name - * @param funBody function object, e.g function () { ... } - * @param funParams paramether signature, e.g ["string", "number"] - * @return method of the given name. The method may be funBody or a wrapper - * of the given funBody. - */ -/* public */ -Clazz.defineMethod = function (clazzThis, funName, funBody, funParams) { - if (Clazz.assureInnerClass) - Clazz.assureInnerClass(clazzThis, funBody); - funBody.exName = funName; - var fpName = formatParameters(funParams); - var proto = clazzThis.prototype; - var f$ = proto[funName]; - if (Clazz._Loader._checkLoad) - checkDuplicate(clazzThis, funName, fpName); - if (!f$ || (f$.claxxOwner === clazzThis && f$.funParams == fpName)) { - // property "funParams" will be used as a mark of only-one method - funBody.funParams = fpName; - funBody.claxxOwner = clazzThis; - funBody.exClazz = clazzThis; // make it traceable - return addProto(proto, funName, funBody); - } - // we have found a duplicate - var oldFun = null; - var oldStacks = f$.stacks; - if (!oldStacks) { - /* method is not defined by Clazz.defineMethod () */ - oldStacks = []; - oldFun = f$; - if (f$.claxxOwner) { - oldStacks[0] = oldFun.claxxOwner; - } - } - /* - * Method that is already defined in super class will be overridden - * with a new proxy method with class hierarchy stored in a stack. - * That is to say, the super methods are lost in this class' proxy - * method. - * When method are being called, methods defined in the new proxy - * method will be searched through first. And if no method fitted, - * it will then try to search method in the super class stacks. - */ - if (!f$.stacks || f$.claxxReference !== clazzThis) { - //Generate a new delegating method for the class - var id = ++SAEMid; - var delegate = function () { - return searchAndExecuteMethod(id, this, arguments.callee.claxxReference, arguments.callee.methodName, arguments); - }; - delegate.methodName = funName; - delegate.claxxReference = clazzThis; - f$ = addProto(proto, funName, delegate); - // Keep the class inheritance stacks - var arr = []; - for (var i = 0; i < oldStacks.length; i++) - arr[i] = oldStacks[i]; - f$.stacks = arr; - } - var ss = f$.stacks; - if (findArrayItem(ss, clazzThis) < 0) ss.push(clazzThis); - - if (oldFun) { - if (oldFun.claxxOwner === clazzThis) { - f$[oldFun.funParams] = oldFun; - oldFun.claxxOwner = null; - // property "funParams" will be used as a mark of only-one method - oldFun.funParams = null; // null ? safe ? // safe for != null - } else if (!oldFun.claxxOwner) { - /* - * The function is not defined Clazz.defineMethod (). - * Try to fixup the method ... - * As a matter of lost method information, I just suppose - * the method to be fixed is with void parameter! - */ - f$["\\unknown"] = oldFun; - } - } - funBody.exClazz = clazzThis; // make it traceable - f$[fpName] = funBody; - return f$; -}; - -duplicatedMethods = {}; - -var checkDuplicate = function(clazzThis, funName, fpName) { - var proto = clazzThis.prototype; - var f$ = proto[funName]; - if (f$ && (f$.claxxOwner || f$.claxxReference) === clazzThis) { - key = clazzThis.__CLASS_NAME__ + "." + funName + fpName; - var m = duplicatedMethods[key]; - if (m) { - var s = "Warning! Duplicate method found for " + key; - System.out.println(s); - Clazz.alert(s); - duplicatedMethods[key] = m + 1; - } else { - duplicatedMethods[key] = 1; - } - } -} - -Clazz.showDuplicates = function(quiet) { - var s = ""; - var a = duplicatedMethods; - var n = 0; - for (var key in a) - if (a[key] > 1) { - s += a[key] + "\t" + key + "\n"; - n++; - } - s = "Duplicates: " + n + "\n\n" + s; - System.out.println(s); - if (!quiet) - alert(s); -} - -var findArrayItem = function(arr, item) { - if (arr && item) - for (var i = arr.length; --i >= 0;) - if (arr[i] === item) - return i; - return -1; -} - -var removeArrayItem = function(arr, item) { - var i = findArrayItem(arr, item); - if (i >= 0) { - var n = arr.length - 1; - for (; i < n; i++) - arr[i] = arr[i + 1]; - arr.length--; - return true; - } -} - -/* - * Other developers may need to extend this formatParameters method - * to deal complicated situation. - */ -/* protected */ -var formatParameters = function (funParams) { - return (funParams ? funParams.replace (/~([NABSO])/g, - function ($0, $1) { - switch ($1) { - case 'N': - return "n"; - case 'B': - return "b"; - case 'S': - return "String"; - case 'O': - return "Object"; - case 'A': - return "Array"; - } - return "Unknown"; - }).replace (/\s+/g, "").replace (/^|,/g, "\\").replace (/\$/g, "org.eclipse.s") : "\\void"); -}; - -/* - * Override the existed methods which are in the same name. - * Overriding methods is provided for the purpose that the JavaScript - * does not need to search the whole hierarchied methods to find the - * correct method to execute. - * Be cautious about this method. Incorrectly using this method may - * break the inheritance system. - * - * @param clazzThis host class in which the method to be defined - * @param funName method name - * @param funBody function object, e.g function () { ... } - * @param funParams paramether signature, e.g ["string", "number"] - */ -/* public */ -Clazz.overrideMethod = function(clazzThis, funName, funBody, funParams) { - if (Clazz.assureInnerClass) Clazz.assureInnerClass (clazzThis, funBody); - funBody.exName = funName; - var fpName = formatParameters(funParams); - if (Clazz._Loader._checkLoad) - checkDuplicate(clazzThis, funName, fpName); - /* - * Replace old methods with new method. No super methods are kept. - */ - funBody.funParams = fpName; - funBody.claxxOwner = clazzThis; - return addProto(clazzThis.prototype, funName, funBody); -}; - -////////////// Overridden and Overloaded Java Method Handling ////////////////// -// SAEM (SearchAndExecuteMethod) -// adapted by BH -// - -/* - * BH Clazz.getProfile monitors exactly what is being delegated with SAEM, - * which could be a bottle-neck for function calling. - * This is critical for performance optimization. - */ - - var __signatures = ""; - -Clazz.getProfile = function() { - var s = ""; - if (_profile) { - var l = []; - for (var i in _profile) { - var n = "" + _profile[i]; - l.push(" ".substring(n.length) + n + "\t" + i); - } - s = l.sort().reverse().join("\r\n"); - _profile = {}; - } - return s + __signatures; -} - -var addProfile = function(c, f, p, id) { - var s = id + " " + c.__CLASS_NAME__ + " " + f + " ";// + JSON.stringify(p); - if (__signatures.indexOf(s) < 0) - __signatures += s + "\n"; - _profile[s] || (_profile[s] = 0); - _profile[s]++; -} - -/** - * Called also by Throwable - * -/* public */ -Clazz.getParamsType = function (funParams) { - // bh: optimization here for very common cases - var n = funParams.length; - switch (n) { - case 0: - var params = ["void"]; - params.typeString = "\\void"; - return params; - case 1: - // BH just so common - switch (typeof obj) { - case "number": - var params = ["n"]; - params.typeString = "\\n"; - return params; - case "boolean": - var params = ["b"]; - params.typeString = "\\b"; - return params; - } - } - - var params = []; - params.hasCastedNull = false; - if (funParams) { - for (var i = 0; i < n; i++) { - params[i] = Clazz.getClassName (funParams[i]); - if (funParams[i] instanceof Clazz.CastedNull) { - params.hasCastedNull = true; - } - } - } - params.typeString = "\\" + params.join ('\\'); - return params; -}; - -var SAEMid = 0; -xxxSAEMlist = ""; - -//var SAEMarray = []; -/** - * BH: OK, this was an idea that doesn't work. The idea was to tag SAEM calls - * and then refer back to an array. But the id number cannot be put in the right place. - * - * Say we have this: - * - * StringBuffer sb = new StringBuffer(); - * sb.append("").append(1); - * - * Here we have two different append methods to call. They are saved under two - * names: StringBuffer.prototype.append["\\String"] - * and StringBuffer.prototype.append["\\Number"] - * - * The job of generateDelegatingMethod is to discriminate between those two. We can do - * that, but the real issue is that we have to do that EVERY time a call is made. - * This is a problem that must be handled at compile time. There is no way to - * make .append("") to go one way the first time and another way the second time. - * What we need at run time is something like this: - * - * Clazz.delegate(sb.append,1,[""]) and Clazz.delegate(sb.append,2,[1]) - * The we would be able to log those numbers at run time and refer to them. - * - * The only real way to avoid SAEM is: - * - * 1) to never call super() -- always call a differently named function in a superclass. - * 2) don't overload functions - * - */ - - -/** - * Search the given class prototype, find the method with the same - * method name and the same parameter signatures by the given - * parameters, and then run the method with the given parameters. - * - * @param objThis the current host object - * @param claxxRef the current host object's class - * @param fxName the method name - * @param funParams the given arguments - * @return the result of the specified method of the host object, - * the return maybe void. - * @throws MethodNotFoundException if no matched method is found - */ -/* protected */ -var searchAndExecuteMethod = function (id, objThis, claxxRef, fxName, args, _saem) { - -// var fx = SAEMarray[id]; -// if (fx) { -// return fx.apply(objThis, args); -// } - - - fx = objThis[fxName]; - var params = Clazz.getParamsType(args); - - -var s = "SAEM " + claxxRef.__CLASS_NAME__ + "." + fxName + "(" + params+ ")\n"; -if (xxxSAEMlist.length > 300)xxxSAEMlist = ""; -xxxSAEMlist += s; - - - if (!fx) - try {System.out.println(Clazz.getStackTrace(5))} catch (e){} - _profile && addProfile(claxxRef, fxName, params, id); - // Cache last matched method - if (fx.lastParams == params.typeString && fx.lastClaxxRef === claxxRef) { - var methodParams; - if (params.hasCastedNull) { - methodParams = []; - // For Clazz.CastedNull instances, the type name is - // already used to indentified the method in searchMethod. - for (var k = 0; k < args.length; k++) - methodParams[k] = (args[k] instanceof Clazz.CastedNull ? null : args[k]); - } else { -// if (fx.lastMethod) SAEMarray[id] = fx.lastMethod; - methodParams = args; - } - return (fx.lastMethod ? fx.lastMethod.apply(objThis, methodParams) : null); - } - fx.lastParams = params.typeString; - fx.lastClaxxRef = claxxRef; - - var stacks = fx.stacks; - if (!stacks) - stacks = claxxRef.prototype[fxName].stacks; - var length = stacks.length; - - /* - * Search the inheritance stacks to get the given class' function - */ - var began = false; // began to search its super classes - for (var i = length; --i >= 0;) { - if (began || stacks[i] === claxxRef) { - /* - * First try to search method within the same class scope - * with stacks[i] === claxxRef - */ - var clazzFun = stacks[i].prototype[fxName]; - var ret = tryToSearchAndExecute(id, fxName, objThis, clazzFun, params, - args, fx); - if (!(ret instanceof MethodException)) { - return ret; - } - /* - * As there are no such methods in current class, Clazz will try - * to search its super class stacks. Here variable began indicates - * that super searchi is began, and there is no need checking - * stacks[i] === claxxRef - */ - began = true; - } // end of if - } // end of for - if ("construct" == fxName) { - /* - * For non existed constructors, just return without throwing - * exceptions. In Java codes, extending Object can call super - * default Object#constructor, which is not defined in JS. - */ - return; - } - newMethodNotFoundException(objThis, claxxRef, - fxName, params.typeString); -}; - - -/* private */ -var tryToSearchAndExecute = function(id, fxName, objThis, clazzFun, params, args, fx, _ttsaem) { - var method = []; - var generic = true; - for (var fn in clazzFun) { - if (fn.charCodeAt(0) == 92) { // 92 == '\\'.charCodeAt (0) - var ps = fn.substring(1).split("\\"); - (ps.length == params.length) && method.push(ps); - generic = false; - continue; - } - /* - * When there is only one method in the class, use the args - * to identify the parameter type. - * - * AbstractCollection.remove (Object) - * AbstractList.remove (int) - * ArrayList.remove (int) - * - * Then calling #remove (Object) method on ArrayList instance will - * need to search up to the AbstractCollection.remove (Object), - * which contains only one method. - */ - /* - * See Clazz#defineMethod --Mar 10, 2006, josson - */ - if (generic && fn == "funParams" && clazzFun.funParams) { - fn = clazzFun.funParams; - var ps = fn.substring(1).split ("\\"); - (ps.length == params.length) && (method[0] = ps); - break; - } - } - var debug = false;//(method.length > 1 && method.join().indexOf("Listen")< 0 && params.join().indexOf("Null") >= 0) - if (debug)alert(fxName + " -- " + method.join("|") + " -- searching for method with " + params) - if (method.length == 0 || !(method = searchMethod(method, params, debug))) - return new MethodException(); - if (debug) alert("OK: \\" + method) - var f = (generic ? clazzFun : clazzFun["\\" + method]); - //if (generic) - //{ /* Use the generic method */ - /* - * Will this case be reachable? - * March 4, 2006 josson - * - * Reachable for calling #remove (Object) method on - * ArrayList instance - * May 5, 2006 josson - */ - var methodParams = null; - if (params.hasCastedNull) { - methodParams = []; - for (var k = 0; k < args.length; k++) { - if (args[k] instanceof Clazz.CastedNull) { - /* - * For Clazz.CastedNull instances, the type name is - * already used to indentify the method in searchMethod. - */ - methodParams[k] = null; - } else { - methodParams[k] = args[k]; - } - } - } else { - methodParams = args; - } - fx.lastMethod = f; - //if (!params.hasCastedNull) SAEMarray[id] = f; - return f.apply(objThis, methodParams); -}; - -/** - * Search the existed polymorphic methods to get the matched method with - * the given parameter types. - * - * @param existedMethods Array of string which contains method parameters - * @param paramTypes Array of string that is parameter type. - * @return string of method parameters seperated by "\\" - */ -/* private */ -var searchMethod = function(roundOne, paramTypes, debug) { - -// Filter out all the fitted methods for the given parameters - var roundTwo = []; - var len = roundOne.length; - for (var i = 0; i < len; i++) { - var fittedLevel = []; - var isFitted = true; - var len2 = roundOne[i].length; - for (var j = 0; j < len2; j++) { - - fittedLevel[j] = Clazz.getInheritedLevel (paramTypes[j], - roundOne[i][j]); - //if (debug)alert([paramTypes[j],fittedLevel[j],roundOne[i][j]]) - if (fittedLevel[j] < 0) { - isFitted = false; - break; - } - } - if (isFitted) { - fittedLevel[paramTypes.length] = i; // Keep index for later use - roundTwo.push(fittedLevel); - } - } - if (roundTwo.length == 0) - return null; - // Find out the best method according to the inheritance. - var resultTwo = roundTwo; - var min = resultTwo[0]; - for (var i = 1; i < resultTwo.length; i++) { - var isVectorLesser = true; - for (var j = 0; j < paramTypes.length; j++) { - if (min[j] < resultTwo[i][j]) { - isVectorLesser = false;; - break; - } - } - if (isVectorLesser) - min = resultTwo[i]; - } - var index = min[paramTypes.length]; // Get the previously stored index - /* - * Return the method parameters' type string as indentifier of the - * choosen method. - */ - return roundOne[index].join ('\\'); -}; - -////////////////////////////////// package loading /////////////////////// - -/* - * all root packages. e.g. java.*, org.*, com.* - */ -/* protected */ -Clazz.allPackage = {}; - -/** - * Will be used to keep value of whether the class is defined or not. - */ -/* protected */ -Clazz.allClasses = {}; - -Clazz.lastPackageName = null; -Clazz.lastPackage = null; - -/* protected */ -Clazz.unloadedClasses = []; - -/* public */ -Clazz.declarePackage = function (pkgName) { - if (Clazz.lastPackageName == pkgName) - return Clazz.lastPackage; - if (pkgName && pkgName.length) { - var pkgFrags = pkgName.split (/\./); - var pkg = Clazz.allPackage; - for (var i = 0; i < pkgFrags.length; i++) { - if (!pkg[pkgFrags[i]]) { - pkg[pkgFrags[i]] = { - __PKG_NAME__ : (pkg.__PKG_NAME__ ? - pkg.__PKG_NAME__ + "." + pkgFrags[i] : pkgFrags[i]) - }; - // pkg[pkgFrags[i]] = {}; - if (i == 0) { - // eval ... - Clazz.setGlobal(pkgFrags[i], pkg[pkgFrags[i]]); - } - } - pkg = pkg[pkgFrags[i]] - } - Clazz.lastPackageName = pkgName; - Clazz.lastPackage = pkg; - return pkg; - } -}; - -/* protected */ -Clazz.evalType = function (typeStr, isQualified) { - var idx = typeStr.lastIndexOf("."); - if (idx != -1) { - var pkgName = typeStr.substring (0, idx); - var pkg = Clazz.declarePackage (pkgName); - var clazzName = typeStr.substring (idx + 1); - return pkg[clazzName]; - } - if (isQualified) - return window[typeStr]; - switch (typeStr) { - case "string": - return String; - case "number": - return Number; - case "object": - return Clazz._O; - case "boolean": - return Boolean; - case "function": - return Function; - case "void": - case "undefined": - case "unknown": - return typeStr; - case "NullObject": - return NullObject; - default: - return window[typeStr]; - } -}; - -/** - * Define a class or interface. - * - * @param qClazzName String presents the qualified name of the class - * @param clazzFun Function of the body - * @param clazzParent Clazz to inherit from, may be null - * @param interfacez Clazz may implement one or many interfaces - * interfacez can be Clazz object or Array of Clazz objects. - * @return Ruturn the modified Clazz object - */ -/* public */ -Clazz.defineType = function (qClazzName, clazzFun, clazzParent, interfacez) { - var cf = Clazz.unloadedClasses[qClazzName]; - if (cf) { - clazzFun = cf; - } - var idx = qClazzName.lastIndexOf ("."); - if (idx != -1) { - var pkgName = qClazzName.substring (0, idx); - var pkg = Clazz.declarePackage (pkgName); - var clazzName = qClazzName.substring (idx + 1); - if (pkg[clazzName]) { - // already defined! Should throw exception! - return pkg[clazzName]; - } - pkg[clazzName] = clazzFun; - } else { - if (window[qClazzName]) { - // already defined! Should throw exception! - return window[qClazzName]; - } - Clazz.setGlobal(qClazzName, clazzFun); - } - Clazz.decorateAsType(clazzFun, qClazzName, clazzParent, interfacez); - /*# {$no.javascript.support} >>x #*/ - var iFun = Clazz._innerFunctions; - clazzFun.defineMethod = iFun.defineMethod; - clazzFun.defineStaticMethod = iFun.defineStaticMethod; - clazzFun.makeConstructor = iFun.makeConstructor; - /*# x<< #*/ - return clazzFun; -}; - -var isSafari = (navigator.userAgent.indexOf ("Safari") != -1); -var isSafari4Plus = false; -if (isSafari) { - var ua = navigator.userAgent; - var verIdx = ua.indexOf("Version/"); - if (verIdx != -1) { - var verStr = ua.substring(verIdx + 8); - var verNumber = parseFloat(verStr); - isSafari4Plus = verNumber >= 4.0; - } -} - -/* public */ -Clazz.instantialize = function (objThis, args) { - - - if (args && args.length == 1 && args[0] - && args[0] instanceof args4InheritClass) { - return; - } - if (objThis instanceof Number) { - objThis.valueOf = function () { - return this; - }; - } - if (isSafari4Plus) { // Fix bug of Safari 4.0+'s over-optimization - var argsClone = []; - for (var k = 0; k < args.length; k++) { - argsClone[k] = args[k]; - } - args = argsClone; - } - - var c = objThis.construct; - if (c) { - if (!objThis.con$truct) { // no need to init fields - c.apply (objThis, args); - } else if (!objThis.getClass ().superClazz) { // the base class - objThis.con$truct.apply (objThis, []); - c.apply (objThis, args); - } else if ((c.claxxOwner - && c.claxxOwner === objThis.getClass ()) - || (c.stacks - && c.stacks[c.stacks.length - 1] == objThis.getClass ())) { - /* - * This #construct is defined by this class itself. - * #construct will call Clazz.superConstructor, which will - * call #con$truct back - */ - c.apply (objThis, args); - } else { // constructor is a super constructor - if (c.claxxOwner && !c.claxxOwner.superClazz - && c.claxxOwner.con$truct) { - c.claxxOwner.con$truct.apply (objThis, []); - } else if (c.stacks && c.stacks.length == 1 - && !c.stacks[0].superClazz) { - c.stacks[0].con$truct.apply (objThis, []); - } - c.apply (objThis, args); - objThis.con$truct.apply (objThis, []); - } - } else if (objThis.con$truct) { - objThis.con$truct.apply (objThis, []); - } -}; - -/** - * Once there are other methods registered to the Function.prototype, - * those method names should be add to the following Array. - */ -/* - * static final member of interface may be a class, which may - * be function. - */ -/* protected */ -Clazz.innerFunctionNames = [ - "isInstance", "equals", "hashCode", /*"toString",*/ "getName", "getCanonicalName", "getClassLoader", "getResource", "getResourceAsStream" /*# {$no.javascript.support} >>x #*/, "defineMethod", "defineStaticMethod", - "makeConstructor" /*# x<< #*/ -]; - -/* - * Static methods - */ -Clazz._innerFunctions = { - /* - * Similar to Object#equals - */ - - isInstance: function(c) { - return Clazz.instanceOf(c, this); - }, - - equals : function (aFun) { - return this === aFun; - }, - - hashCode : function () { - return this.getName ().hashCode (); - }, - - toString : function () { - return "class " + this.getName (); - }, - - /* - * Similar to Class#getName - */ - getName : function () { - return Clazz.getClassName (this, true); - }, - getCanonicalName : function () { - return this.__CLASS_NAME__; - }, - getClassLoader : function () { - var clazzName = this.__CLASS_NAME__; - var baseFolder = Clazz._Loader.getClasspathFor(clazzName); - var x = baseFolder.lastIndexOf (clazzName.replace (/\./g, "/")); - if (x != -1) { - baseFolder = baseFolder.substring (0, x); - } else { - baseFolder = Clazz._Loader.getClasspathFor(clazzName, true); - } - var loader = Clazz._Loader.requireLoaderByBase(baseFolder); - loader.getResourceAsStream = Clazz._innerFunctions.getResourceAsStream; - loader.getResource = Clazz._innerFunctions.getResource; // BH - return loader; - }, - - getResource : function(name) { - var stream = this.getResourceAsStream(name); - return (stream ? stream.url : null); - }, - - getResourceAsStream : function (name) { - if (!name) - return null; - name = name.replace (/\\/g, '/'); - var baseFolder = null; - var fname = name; - var clazzName = this.__CLASS_NAME__; - if (arguments.length == 2 && name.indexOf ('/') != 0) { // additional argument - name = "/" + name; - } - if (name.indexOf ('/') == 0) { - //is.url = name.substring (1); - if (arguments.length == 2) { // additional argument - baseFolder = arguments[1]; - if (!baseFolder) - baseFolder = Clazz.binaryFolders[0]; - } else if (Clazz._Loader) { - baseFolder = Clazz._Loader.getClasspathFor(clazzName, true); - } - if (!baseFolder) { - fname = name.substring (1); - } else { - baseFolder = baseFolder.replace (/\\/g, '/'); - var length = baseFolder.length; - var lastChar = baseFolder.charAt (length - 1); - if (lastChar != '/') { - baseFolder += "/"; - } - fname = baseFolder + name.substring (1); - } - } else { - if (this.base) { - baseFolder = this.base; - } else if (Clazz._Loader) { - baseFolder = Clazz._Loader.getClasspathFor(clazzName); - var x = baseFolder.lastIndexOf (clazzName.replace (/\./g, "/")); - if (x != -1) { - baseFolder = baseFolder.substring (0, x); - } else { - //baseFolder = null; - var y = -1; - if (baseFolder.indexOf (".z.js") == baseFolder.length - 5 - && (y = baseFolder.lastIndexOf ("/")) != -1) { - baseFolder = baseFolder.substring (0, y + 1); - var pkgs = clazzName.split (/\./); - for (var k = 1; k < pkgs.length; k++) { - var pkgURL = "/"; - for (var j = 0; j < k; j++) { - pkgURL += pkgs[j] + "/"; - } - if (pkgURL.length > baseFolder.length) { - break; - } - if (baseFolder.indexOf (pkgURL) == baseFolder.length - pkgURL.length) { - baseFolder = baseFolder.substring (0, baseFolder.length - pkgURL.length + 1); - break; - } - } - } else { - baseFolder = Clazz._Loader.getClasspathFor(clazzName, true); - } - } - } else { - var bins = Clazz.binaryFolders; - if (bins && bins.length) { - baseFolder = bins[0]; - } - } - if (!baseFolder) - baseFolder = "j2s/"; - baseFolder = baseFolder.replace (/\\/g, '/'); - var length = baseFolder.length; - var lastChar = baseFolder.charAt (length - 1); - if (lastChar != '/') { - baseFolder += "/"; - } - if (this.base) { - fname = baseFolder + name; - } else { - var idx = clazzName.lastIndexOf ('.'); - if (idx == -1 || this.base) { - fname = baseFolder + name; - } else { - fname = baseFolder + clazzName.substring (0, idx) - .replace (/\./g, '/') + "/" + name; - } - } - } - var url = null; - try { - if (fname.indexOf(":/") < 0) { - var d = document.location.href.split("?")[0].split("/"); - d[d.length - 1] = fname; - fname = d.join("/"); - } - url = new java.net.URL(fname); - } catch (e) { - } - var data = (url == null ? null : Jmol._getFileData(fname.toString())); - if (!data || data == "error" || data.indexOf("[Exception") == 0) - return null; - var bytes = new java.lang.String(data).getBytes(); - var is = new java.io.BufferedInputStream ( new java.io.ByteArrayInputStream (bytes)); - is.url = url; - return is; - }/*# {$no.javascript.support} >>x #*/, - - /* - * For JavaScript programmers - */ - defineMethod : function (methodName, funBody, paramTypes) { - Clazz.defineMethod (this, methodName, funBody, paramTypes); - }, - - /* - * For JavaScript programmers - */ - defineStaticMethod : function (methodName, funBody, paramTypes) { - Clazz.defineMethod (this, methodName, funBody, paramTypes); - this[methodName] = this.prototype[methodName]; - }, - - /* - * For JavaScript programmers - */ - makeConstructor : function (funBody, paramTypes) { - Clazz.makeConstructor (this, funBody, paramTypes); - } - /*# x<< #*/ -}; - - -var cStack = []; - -/** - * BH: I would like to be able to remove "self.c$" here, but that is tricky. - */ - -Clazz.pu$h = function (c) { - c || (c = self.c$); // old style - c && cStack.push(c); -}; - -Clazz.p0p = function () { - return cStack.pop(); -}; - -/* protected */ -Clazz.decorateAsClass = function (clazzFun, prefix, name, clazzParent, - interfacez, parentClazzInstance, _decorateAsClass) { - - var prefixName = null; - if (prefix) { - prefixName = prefix.__PKG_NAME__; - if (!prefixName) - prefixName = prefix.__CLASS_NAME__; - } - var qName = (prefixName ? prefixName + "." : "") + name; - - if (Clazz._Loader._classPending[qName]) { - delete Clazz._Loader._classPending[qName]; - Clazz._Loader._classCountOK++; - Clazz._Loader._classCountPending--; - } - if (Clazz._Loader && Clazz._Loader._checkLoad) { - System.out.println("decorating class " + prefixName + "." + name); - } - var cf = Clazz.unloadedClasses[qName]; - if (cf) { - clazzFun = cf; - } - var qName = null; - decorateFunction(clazzFun, prefix, name); - if (parentClazzInstance) { - Clazz.inheritClass (clazzFun, clazzParent, parentClazzInstance); - } else if (clazzParent) { - Clazz.inheritClass (clazzFun, clazzParent); - } - if (interfacez) { - Clazz.implementOf (clazzFun, interfacez); - } - return clazzFun; -}; - -/* private */ -var decorateFunction = function (clazzFun, prefix, name, _decorateFunction) { - var qName; - if (!prefix) { - // e.g. Clazz.declareInterface (null, "ICorePlugin", org.eclipse.ui.IPlugin); - qName = name; - Clazz.setGlobal(name, clazzFun); - } else if (prefix.__PKG_NAME__) { - // e.g. Clazz.declareInterface (org.eclipse.ui, "ICorePlugin", org.eclipse.ui.IPlugin); - qName = prefix.__PKG_NAME__ + "." + name; - prefix[name] = clazzFun; - if (prefix === java.lang) - Clazz.setGlobal(name, clazzFun); - } else { - // e.g. Clazz.declareInterface (org.eclipse.ui.Plugin, "ICorePlugin", org.eclipse.ui.IPlugin); - qName = prefix.__CLASS_NAME__ + "." + name; - prefix[name] = clazzFun; - } - Clazz.extendJO(clazzFun, qName); - var inF = Clazz.innerFunctionNames; - for (var i = 0; i < inF.length; i++) { - clazzFun[inF[i]] = Clazz._innerFunctions[inF[i]]; - } - - if (Clazz._Loader) - Clazz._Loader.updateNodeForFunctionDecoration(qName); -}; - -/* protected */ -Clazz.declareInterface = function (prefix, name, interfacez, _declareInterface) { - var clazzFun = function () {}; - decorateFunction(clazzFun, prefix, name); - if (interfacez) { - Clazz.implementOf (clazzFun, interfacez); - } - return clazzFun; -}; - -/* public */ -Clazz.declareType = function (prefix, name, clazzParent, interfacez, - parentClazzInstance, _declareType) { - var f = function () { - Clazz.instantialize (this, arguments); - }; - return Clazz.decorateAsClass (f, prefix, name, clazzParent, interfacez, - parentClazzInstance); -}; - -/* public */ -Clazz.declareAnonymous = function (prefix, name, clazzParent, interfacez, - parentClazzInstance, _declareAnonymous) { - var f = function () { - Clazz.prepareCallback(this, arguments); - Clazz.instantialize (this, arguments); - }; - return Clazz.decorateAsClass (f, prefix, name, clazzParent, interfacez, - parentClazzInstance); -}; - -/* public */ -Clazz.decorateAsType = function (clazzFun, qClazzName, clazzParent, - interfacez, parentClazzInstance, inheritClazzFuns, _decorateAsType) { - Clazz.extendJO(clazzFun, qClazzName); - clazzFun.equals = Clazz._innerFunctions.equals; - clazzFun.getName = Clazz._innerFunctions.getName; - if (inheritClazzFuns) { - for (var i = 0; i < Clazz.innerFunctionNames.length; i++) { - var methodName = Clazz.innerFunctionNames[i]; - clazzFun[methodName] = Clazz._innerFunctions[methodName]; - } - } - if (parentClazzInstance) { - Clazz.inheritClass (clazzFun, clazzParent, parentClazzInstance); - } else if (clazzParent) { - Clazz.inheritClass (clazzFun, clazzParent); - } - if (interfacez) { - Clazz.implementOf (clazzFun, interfacez); - } - return clazzFun; -}; - - -////////////////////////// default package declarations //////////////////////// - -/* sgurin: preserve Number.prototype.toString */ -Number.prototype._numberToString=Number.prototype.toString; - - -Clazz.declarePackage ("java.io"); -//Clazz.declarePackage ("java.lang"); -Clazz.declarePackage ("java.lang.annotation"); // java.lang -Clazz.declarePackage ("java.lang.instrument"); // java.lang -Clazz.declarePackage ("java.lang.management"); // java.lang -Clazz.declarePackage ("java.lang.reflect"); // java.lang -Clazz.declarePackage ("java.lang.ref"); // java.lang.ref -java.lang.ref.reflect = java.lang.reflect; -Clazz.declarePackage ("java.util"); -//var reflect = Clazz.declarePackage ("java.lang.reflect"); -Clazz.declarePackage ("java.security"); - - -/* - * Consider these interfaces are basic! - */ -Clazz.declareInterface (java.io,"Closeable"); -Clazz.declareInterface (java.io,"DataInput"); -Clazz.declareInterface (java.io,"DataOutput"); -Clazz.declareInterface (java.io,"Externalizable"); -Clazz.declareInterface (java.io,"Flushable"); -Clazz.declareInterface (java.io,"Serializable"); -Clazz.declareInterface (java.lang,"Iterable"); -Clazz.declareInterface (java.lang,"CharSequence"); -Clazz.declareInterface (java.lang,"Cloneable"); -Clazz.declareInterface (java.lang,"Appendable"); -Clazz.declareInterface (java.lang,"Comparable"); -Clazz.declareInterface (java.lang,"Runnable"); -Clazz.declareInterface (java.util,"Comparator"); - -java.lang.ClassLoader = { - __CLASS_NAME__ : "ClassLoader" -}; - -/****************************************************************************** - * Copyright (c) 2007 java2script.org and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Zhou Renjian - initial API and implementation - *****************************************************************************/ -/******* - * @author zhou renjian - * @create March 10, 2006 - *******/ - -/** - * Once ClassExt.js is part of Class.js. - * In order to make the Class.js as small as possible, part of its content - * is moved into this ClassExt.js. - * - * See also http://j2s.sourceforge.net/j2sclazz/ - */ - -/** - * Clazz.MethodNotFoundException is used to notify the developer about calling - * methods with incorrect parameters. - */ -/* protected */ -// Override the Clazz.MethodNotFoundException in Class.js to give details -var newMethodNotFoundException = function (obj, clazz, method, params) { - var paramStr = ""; - if (params) { - paramStr = params.substring (1).replace (/\\/g, ","); - } - var leadingStr = ""; - if (method && method != "construct") { - leadingStr = "Method"; - } else { - leadingStr = "Constructor"; - } - var message = leadingStr + " " + Clazz.getClassName (clazz, true) + "." - + method + "(" + paramStr + ") is not found!"; - throw new java.lang.NoSuchMethodException(message); -}; - -/** - * Prepare "callback" for instance of anonymous Class. - * For example for the callback: - * this.callbacks.MyEditor.sayHello(); - * - * This is specifically for inner classes that are referring to - * outer class methods and fields. - * - * @param objThis the host object for callback - * @param args arguments object. args[0] will be classThisObj -- the "this" - * object to be hooked - * - * Attention: parameters should not be null! - */ -/* protected */ -Clazz.prepareCallback = function (innerObj, args) { - var outerObj = args[0]; - var cbName = "b$"; // "callbacks"; - if (innerObj && outerObj && outerObj !== window) { - var className = Clazz.getClassName(outerObj, true); - var obs = {}; - if (innerObj[cbName]) // must make a copy! - for (var s in innerObj[cbName]) - obs[s] = innerObj[cbName][s]; - innerObj[cbName] = obs; - - /* - * TODO: the following line is SWT-specific! Try to move it out! - */ - // obs[className.replace (/org\.eclipse\.swt\./, "$wt.")] = outerObj; - - // all references to outer class and its superclass objects must be here as well - obs[className] = outerObj; - var clazz = Clazz.getClass(outerObj); - while (clazz.superClazz) { - clazz = clazz.superClazz; - /* - * TODO: the following line is SWT-specific! Try to move it out! - */ - // obs[Clazz.getClassName (clazz, true) - // .replace (/org\.eclipse\.swt\./, "$wt.")] = outerObj; - obs[Clazz.getClassName(clazz, true)] = outerObj; - } - var cbs = outerObj[cbName]; - if (cbs) - for (var s in cbs) - obs[s] = cbs[s]; - } - // remove "this" argument - // note that args is an instance of arguments -- NOT an array; does not have the .shift() method! - for (var i = 0; i < args.length - 1; i++) - args[i] = args[i + 1]; - args.length--; -}; - -/** - * Construct instance of the given inner class. - * - * @param classInner given inner class, alway with name like "*$*" - * @param innerObj this instance which can be used to call back. - * @param finalVars final variables which the inner class may use - * @return the constructed object - * - * @see Clazz#cloneFinals - */ -/* public */ -Clazz.innerTypeInstance = function (clazzInner, innerObj, finalVars) { - if (!clazzInner) - clazzInner = arguments.callee.caller; - var obj; - if (finalVars || innerObj.$finals) { - obj = new clazzInner(innerObj, Clazz.inheritArgs); - // f$ is short for the once choosen "$finals" - if (finalVars) { - if (innerObj.f$) { - var o = {}; - for (var attr in innerObj.f$) - o[attr] = innerObj.f$[attr]; - for (var attr in finalVars) - o[attr] = finalVars[attr]; - obj.f$ = o; - } else { - obj.f$ = finalVars; - } - } else if (innerObj.f$) { - obj.f$ = innerObj.f$; - } - } else { - switch (arguments.length) { - case 3: - return new clazzInner(innerObj); - case 4: - return (innerObj.__CLASS_NAME__ == clazzInner.__CLASS_NAME__ - && arguments[3] === Clazz.inheritArgs ? innerObj : new clazzInner(innerObj, arguments[3])); - case 5: - return new clazzInner(innerObj, arguments[3], arguments[4]); - case 6: - return new clazzInner(innerObj, arguments[3], arguments[4], - arguments[5]); - case 7: - return new clazzInner(innerObj, arguments[3], arguments[4], - arguments[5], arguments[6]); - case 8: - return new clazzInner(innerObj, arguments[3], arguments[4], - arguments[5], arguments[6], arguments[7]); - case 9: - return new clazzInner(innerObj, arguments[3], arguments[4], - arguments[5], arguments[6], arguments[7], arguments[8]); - case 10: - return new clazzInner(innerObj, arguments[3], arguments[4], - arguments[5], arguments[6], arguments[7], arguments[8], - arguments[9]); - default: - //Should construct instance manually. - obj = new clazzInner(innerObj, Clazz.inheritArgs); - break; - } - } - var n = arguments.length - 3; - var args = new Array(n); - for (var i = n; --i >= 0;) - args[i] = arguments[i + 3]; - Clazz.instantialize(obj, args); - return obj; -}; - -/** - * Clone variables whose modifier is "final". - * Usage: var o = Clazz.cloneFinals ("name", name, "age", age); - * - * @return Object with all final variables - */ -/* public */ -Clazz.cloneFinals = function () { - var o = {}; - var len = arguments.length / 2; - for (var i = len; --i >= 0;) - o[arguments[i + i]] = arguments[i + i + 1]; - return o; -}; - -/* public */ -Clazz.isClassDefined = Clazz.isDefinedClass = function(clazzName) { - if (!clazzName) - return false; /* consider null or empty name as non-defined class */ - if (Clazz.allClasses[clazzName]) - return true; - var pkgFrags = clazzName.split (/\./); - var pkg = null; - for (var i = 0; i < pkgFrags.length; i++) - if (!(pkg = (pkg ? pkg[pkgFrags[i]] : Clazz.allPackage[pkgFrags[0]]))) { - return false; - } - return (pkg && (Clazz.allClasses[clazzName] = true)); -}; -/** - * Define the enum constant. - * @param classEnum enum type - * @param enumName enum constant - * @param enumOrdinal enum ordinal - * @param initialParams enum constant constructor parameters - * @return return defined enum constant - */ -/* public */ -Clazz.defineEnumConstant = function (clazzEnum, enumName, enumOrdinal, initialParams, clazzEnumExt) { - var o = (clazzEnumExt ? new clazzEnumExt() : new clazzEnum()); - // BH avoids unnecessary calls to SAEM - o.$name = enumName; - o.$ordinal = enumOrdinal; - //Clazz.superConstructor (o, clazzEnum, [enumName, enumOrdinal]); - if (initialParams && initialParams.length) - o.construct.apply (o, initialParams); - clazzEnum[enumName] = o; - clazzEnum.prototype[enumName] = o; - if (!clazzEnum["$ values"]) { // BH added - clazzEnum["$ values"] = [] // BH added - clazzEnum.values = function() { // BH added - return this["$ values"]; // BH added - }; // BH added - } - clazzEnum["$ values"].push(o); - return o; -}; - -//////// (int) conversions ////////// - -Clazz.floatToInt = function (x) { - return x < 0 ? Math.ceil(x) : Math.floor(x); -}; - -Clazz.floatToByte = Clazz.floatToShort = Clazz.floatToLong = Clazz.floatToInt; -Clazz.doubleToByte = Clazz.doubleToShort = Clazz.doubleToLong = Clazz.doubleToInt = Clazz.floatToInt; - -Clazz.floatToChar = function (x) { - return String.fromCharCode (x < 0 ? Math.ceil(x) : Math.floor(x)); -}; - -Clazz.doubleToChar = Clazz.floatToChar; - - - -///////////////////////////////// Array additions ////////////////////////////// -// -// BH: these are necessary for integer processing, especially -// -// - -var getArrayClone = function(nbits) { - return function() { - var me = this; - var n = me.length; - var a = (nbits == 32 ? new Int32Array(n) : new Float64Array(n)); - for (var i = n; --i >= 0;) - a[i] = me[i]; - return a; - } -} - -if (self.Int32Array && self.Int32Array != Array) { - Clazz.haveInt32 = true; - if (!Int32Array.prototype.sort) - Int32Array.prototype.sort = Array.prototype.sort - if (!Int32Array.prototype.clone) - Int32Array.prototype.clone = getArrayClone(32); -} else { - Int32Array = function(n) { - if (!n) n = 0; - var b = new Array(n); - b.toString = function(){return "[object Int32Array]"} - for (var i = 0; i < n; i++)b[i] = 0 - return b; - } - Clazz.haveInt32 = false; - Int32Array.prototype.sort = Array.prototype.sort - Int32Array.prototype.clone = getArrayClone(32); - Int32Array.prototype.int32Fake = function(){}; -} - -if (self.Float64Array && self.Float64Array != Array) { - Clazz.haveFloat64 = true; - if (!Float64Array.prototype.sort) - Float64Array.prototype.sort = Array.prototype.sort - if (!Float64Array.prototype.clone) - Float64Array.prototype.clone = getArrayClone(64); -} else { - Clazz.haveFloat64 = false; - Float64Array = function(n) { - if (!n) n = 0; - var b = new Array(n); - for (var i = 0; i < n; i++)b[i] = 0.0 - return b; - }; - Float64Array.prototype.sort = Array.prototype.sort - Float64Array.prototype.clone = getArrayClone(64); - Float64Array.prototype.float64Fake = function() {}; // "present" - Float64Array.prototype.toString = function() {return "[object Float64Array]"}; -// Darn! Mozilla makes this a double, not a float. It's 64-bit. -// and Safari 5.1 doesn't have Float64Array -} - -/** - * Make arrays. - * - * @return the created Array object - */ -/* public */ -Clazz.newArray = function () { - if (arguments[0] instanceof Array) { - // recursive, from newArray(n,m,value) - // as newArray([m, value], newInt32Array) - var args = arguments[0]; - var f = arguments[1]; - } else { - var args = arguments; - var f = Array; - } - var dim = args[0]; - if (typeof dim == "string") { - dim = dim.charCodeAt (0); // char - } - var len = args.length - 1; - var val = args[len]; - switch (args.length) { - case 0: // never - case 1: - return []; // maybe never? - case 2: - if (val == null) - return new Array(dim); - if (f === true && Clazz.haveInt32) return new Int32Array(dim); - if (f === false && Clazz.haveFloat64) return new Float64Array(dim); - var arr = (f === true ? new Int32Array() : f === false ? new Float64Array() : dim < 0 ? val : new Array(dim)); - for (var i = dim; --i >= 0;) - arr[i] = val; - return arr; - default: - var xargs = new Array (len); - for (var i = 0; i < len; i++) { - xargs[i] = args[i + 1]; - } - var arr = new Array (dim); - if (val == null || val >= 0 || len > 2) - for (var i = 0; i < dim; i++) { - // Call recursively! - arr[i] = Clazz.newArray (xargs, f); - } - return arr; - } -}; - -Clazz.newArray32 = function(args, isInt32) { - var dim = args[0]; - if (typeof dim == "string") - dim = dim.charCodeAt (0); // char - var len = args.length - 1; - var val = args[len]; - switch (args.length) { - case 0: - case 1: - alert ("ERROR IN newArray32 -- args.length < 2"); - return new Array(0); - case 2: - var isDefined = (dim < 0); - if (isDefined) - dim = val.length; - var a = (val < 0 ? new Array(dim) : isInt32 ? new Int32Array(dim) : new Float64Array(dim)); - if (isDefined) - for (var i = dim; --i >= 0;) - a[i] = val[i]; - return a; - } - var xargs = new Array(len); - for (var i = len; --i >= 0;) { - xargs[i] = args[i + 1]; - } - var arr = new Array (dim); - for (var i = 0; i < dim; i++) { - // Call newArray referencing this array type - // only for the final iteration, and only if val === 0 - arr[i] = Clazz.newArray (xargs, isInt32); - } - return arr; -}; - - -/** - * Make arrays. - * - * @return the created Array object - */ -/* public */ -Clazz.newInt32Array = function () { - return Clazz.newArray32(arguments, true); -} - -/** - * Make arrays. - * - * @return the created Array object - */ -/* public */ -Clazz.newFloat64Array = function () { - return Clazz.newArray32(arguments, false); -} - -Clazz.newFloatArray = Clazz.newDoubleArray = Clazz.newFloat64Array; -Clazz.newIntArray = Clazz.newLongArray = Clazz.newShortArray = Clazz.newByteArray = Clazz.newInt32Array; -Clazz.newCharArray = Clazz.newBooleanArray = Clazz.newArray; - -//$_AI=Clazz.newIntArray; -//$_AF=Clazz.newFloatArray; -//$_AD=Clazz.newDoubleArray; -//$_AL=Clazz.newLongArray; -//$_AS=Clazz.newShortArray; -//$_AB=Clazz.newByteArray; -//$_AC=Clazz.newCharArray; -//$_Ab=Clazz.newBooleanArray; - - -var arrayIs = function(a, what) { - // for some reason, Number.constructor.toString() now gives "too much recursion" - return a.constructor && a.constructor != Number && a.constructor.toString().indexOf(what) >= 0 -} - -Clazz.isAS = function(a) { // just checking first parameter - return (a && typeof a == "object" && arrayIs(a, " Array") && (typeof a[0] == "string" || typeof a[0] == "undefined")); -} - -Clazz.isASS = function(a) { - return (a && typeof a == "object" && Clazz.isAS(a[0])); -} - -Clazz.isAP = function(a) { - return (a && Clazz.getClassName(a[0]) == "JU.P3"); -} - -Clazz.isAI = function(a) { - return (a && typeof a == "object" && (Clazz.haveInt32 ? arrayIs(a, "Int32Array") : a.int32Fake ? true : false)); -} - -Clazz.isAII = function(a) { // assumes non-null a[0] - return (a && typeof a == "object" && Clazz.isAI(a[0])); -} - -Clazz.isAF = function(a) { - return (a && typeof a == "object" && (Clazz.haveFloat64 ? arrayIs(a, "Float64Array") : a.float64Fake ? true : false)); -} - -Clazz.isAFF = function(a) { // assumes non-null a[0] - return (a && typeof a == "object" && Clazz.isAF(a[0])); -} - -Clazz.isAFFF = function(a) { // assumes non-null a[0] - return (a && typeof a == "object" && Clazz.isAFF(a[0])); -} - -Clazz.isAFloat = function(a) { // just checking first parameter - return (a && typeof a == "object" && arrayIs(a, " Array") && Clazz.instanceOf(a[0], Float)); -} - - -/** - * Make the RunnableCompatiability instance as a JavaScript function. - * - * @param jsr Instance of RunnableCompatiability - * @return JavaScript function instance represents the method run of jsr. - */ -/* public */ -/* -Clazz.makeFunction = function (jsr) { -// never used in Jmol -- called by Enum, but not accessible to it -- part of SWT - return function(e) { - if (!e) - e = window.event; - if (jsr.setEvent) - jsr.setEvent(e); - jsr.run(); - switch (jsr.returnSet) { - case 1: - return jsr.returnNumber; - case 2: - return jsr.returnBoolean; - case 3: - return jsr.returnObject; - } - }; -}; -*/ - -/* protected */ -Clazz.defineStatics = function (clazz) { - for (var j = arguments.length, i = (j - 1) / 2; --i >= 0;) { - var val = arguments[--j] - var name = arguments[--j]; - clazz[name] = clazz.prototype[name] = val; - } -}; - -/* public */ -Clazz.prepareFields = function (clazz, fieldsFun) { - var stacks = []; - if (clazz.con$truct) { - var ss = clazz.con$truct.stacks; - var idx = 0;//clazz.con$truct.index; - for (var i = idx; i < ss.length; i++) { - stacks[i] = ss[i]; - } - } - addProto(clazz.prototype, "con$truct", clazz.con$truct = function () { - var stacks = arguments.callee.stacks; - if (stacks) { - for (var i = 0; i < stacks.length; i++) { - stacks[i].apply (this, []); - } - } - }); - stacks.push(fieldsFun); - clazz.con$truct.stacks = stacks; - clazz.con$truct.index = 0; -}; - -/* - * Serialize those public or protected fields in class - * net.sf.j2s.ajax.SimpleSerializable. - */ -/* protected */ -/* -Clazz.registerSerializableFields = function (clazz) { - var args = arguments; - var length = args.length; - var newArr = []; - if (clazz.declared$Fields) { - for (var i = 0; i < clazz.declared$Fields.length; i++) { - newArr[i] = clazz.declared$Fields[i]; - } - } - clazz.declared$Fields = newArr; - - if (length > 0 && length % 2 == 1) { - var fs = clazz.declared$Fields; - var n = (length - 1) / 2; - for (var i = 1; i <= n; i++) { - var o = { name : args[i + i - 1], type : args[i + i] }; - var existed = false; - for (var j = 0; j < fs.length; j++) { - if (fs[j].name == o.name) { // reloaded classes - fs[j].type = o.type; // update type - existed = true; - break; - } - } - if (!existed) - fs.push(o); - } - } -}; -*/ -/* - * Get the caller method for those methods that are wrapped by - * Clazz.searchAndExecuteMethod. - * - * @param args caller method's arguments - * @return caller method, null if there is not wrapped by - * Clazz.searchAndExecuteMethod or is called directly. - */ -/* protected */ -/* -Clazz.getMixedCallerMethod = function (args) { - var o = {}; - var argc = args.callee.caller; // tryToSearchAndExecute - if (argc && argc !== tryToSearchAndExecute) // inherited method's apply - argc = argc.arguments.callee.caller; - if (argc !== tryToSearchAndExecute - || (argc = argc.arguments.callee.caller) !== Clazz.searchAndExecuteMethod) - return null; - o.claxxRef = argc.arguments[1]; - o.fxName = argc.arguments[2]; - o.paramTypes = Clazz.getParamsType(argc.arguments[3]); - argc = argc.arguments.callee.caller // Clazz.generateDelegatingMethod - && argc.arguments.callee.caller; // the private method's caller - if (!argc) - return null; - o.caller = argc; - return o; -}; -*/ -/* BH -- The issue here is a subclass calling its private method FOO when - * there is also a private method of the same name in its super class. - * This can ALWAYS be avoided and, one could argue, is bad - * program design anyway. In Jmol, the presence of this possibility - * creates over 8000 references to the global $fx, which was only - * checked in a few rare cases. We can then also remove $fz references. - * - */ - -/* - * Check and return super private method. - * In order make private methods be executed correctly, some extra javascript - * must be inserted into the beggining of the method body of the non-private - * methods that with the same method signature as following: - * - * var $private = Clazz.checkPrivateMethod (arguments); - * if ($private) { - * return $private.apply (this, arguments); - * } - * - * Be cautious about this. The above codes should be insert by Java2Script - * compiler or with double checks to make sure things work correctly. - * - * @param args caller method's arguments - * @return private method if there are private method fitted for the current - * calling environment - */ -/* public */ - -Clazz.checkPrivateMethod = function () { - // get both this one and the one calling it - me = arguments.callee.caller; - caller = arguments.callee.caller.caller; - var stack = me.stacks; - // if their classes are the same, no issue - var mySig = "\\" + Clazz.getParamsType(arguments[0]).join("\\") - if (!me.privateNote) { - me.privateNote = "You are seeing this note because the method " - + me.exName + mySig + " in class " - + me.exClazz.__CLASS_NAME__ - + " has a superclass method by the same name (possibly with the same parameters) that is private and " - + " therefore might be called improperly from this class. If your " - + " code does not run properly, or you want to make it run faster, change the name of this method to something else." - System.out.println(me.privateNote); - alert(me.privateNote); - } - /* - alert([me.exClazz.__CLASS_NAME__, me.exName, - caller.exClazz.__CLASS_NAME__, caller.exName,stack,mySig]) - if (stack == null || caller.exClazz == me.exClazz) - return null; - // I am being called by a different class... - - for (var i = stack.length; --i >= 0;) { - if (stacks[i] != caller.claxxRef) - continue; - // and it is on MY class stack -// if ( - - } - */ - -/* var m = Clazz.getMixedCallerMethod (args); - if (m == null) return null; - var callerFx = m.claxxRef.prototype[m.caller.exName]; - if (callerFx == null) return null; // may not be in the class hierarchies - var ppFun = null; - if (callerFx.claxxOwner ) { - ppFun = callerFx.claxxOwner.prototype[m.fxName]; - } else { - var stacks = callerFx.stacks; - for (var i = stacks.length - 1; i >= 0; i--) { - var fx = stacks[i].prototype[m.caller.exName]; - if (fx === m.caller) { - ppFun = stacks[i].prototype[m.fxName]; - } else if (fx ) { - for (var fn in fx) { - if (fn.indexOf ('\\') == 0 && fx[fn] === m.caller) { - ppFun = stacks[i].prototype[m.fxName]; - break; - } - } - } - if (ppFun) { - break; - } - } - } - if (ppFun && ppFun.claxxOwner == null) { - ppFun = ppFun["\\" + m.paramTypes]; - } - if (ppFun && ppFun.isPrivate && ppFun !== args.callee) { - return ppFun; - } -*/ - return null; -}; - - -//$fz = null; // for private method declaration - - -// /*# {$no.debug.support} >>x #*/ -// /* -// * Option to switch on/off of stack traces. -// */ -// /* protect */ -//Clazz.tracingCalling = false; - -// /* private */ -// Clazz.callingStack = function (caller, owner) { -// this.caller = caller; -// this.owner = owner; -// }; - -/*# x<< #*/ - -/** - * The first folder is considered as the primary folder. - * And try to be compatiable with _Loader system. - */ -/* private */ - - -/*** not used in Jmol - * * -if (window["_Loader"] && _Loader.binaryFolders) { - Clazz.binaryFolders = _Loader.binaryFolders; -} else { - Clazz.binaryFolders = ["j2s/", "", "j2slib/"]; -} - -Clazz.addBinaryFolder = function (bin) { - if (bin) { - var bins = Clazz.binaryFolders; - for (var i = 0; i < bins.length; i++) { - if (bins[i] == bin) { - return ; - } - } - bins[bins.length] = bin; - } -}; -Clazz.removeBinaryFolder = function (bin) { - if (bin) { - var bins = Clazz.binaryFolders; - for (var i = 0; i < bins.length; i++) { - if (bins[i] == bin) { - for (var j = i; j < bins.length - 1; j++) { - bins[j] = bins[j + 1]; - } - bins.length--; - return bin; - } - } - } - return null; -}; -Clazz.setPrimaryFolder = function (bin) { - if (bin) { - Clazz.removeBinaryFolder (bin); - var bins = Clazz.binaryFolders; - for (var i = bins.length - 1; i >= 0; i--) { - bins[i + 1] = bins[i]; - } - bins[0] = bin; - } -}; - -***/ - - -///////////////// special definitions of standard Java class methods /////////// - -/** - * This is a simple implementation for Clazz#load. It just ignore dependencies - * of the class. This will be fine for jar *.z.js file. - * It will be overriden by _Loader#load. - * For more details, see _Loader.js - */ -/* protected */ -/* -Clazz.load = function (musts, clazz, optionals, declaration) { - // not used in Jmol - if (declaration) - declaration (); -}; -*/ - -/* - * Invade the Object prototype! - * TODO: make sure that invading Object prototype does not affect other - * existed library, such as Dojo, YUI, Prototype, ... - */ -java.lang.Object = Clazz._O; - -Clazz._O.getName = Clazz._innerFunctions.getName; - - -java.lang.System = System = { - props : null, //new java.util.Properties (), - $props : {}, - arraycopy : function (src, srcPos, dest, destPos, length) { - if (src !== dest) { - for (var i = 0; i < length; i++) { - dest[destPos + i] = src[srcPos + i]; - } - } else { - var swap = []; - for (var i = 0; i < length; i++) { - swap[i] = src[srcPos + i]; - } - for (var i = 0; i < length; i++) { - dest[destPos + i] = swap[i]; - } - } - }, - currentTimeMillis : function () { - return new Date ().getTime (); - }, - gc : function() {}, // bh - getProperties : function () { - return System.props; - }, - getProperty : function (key, def) { - if (System.props) - return System.props.getProperty (key, def); - var v = System.$props[key]; - if (typeof v != "undefined") - return v; - if (key.indexOf(".") > 0) { - v = null; - switch (key) { - case "java.version": - v = "1.6"; - case "file.separator": - case "path.separator": - v = "/"; - break; - case "line.separator": - v = (navigator.userAgent.indexOf("Windows") >= 0 ? "\r\n" : "\n"); - break; - case "os.name": - case "os.version": - v = navigator.userAgent; - break; - } - if (v) - return System.$props[key] = v; - } - return (arguments.length == 1 ? null : def == null ? key : def); // BH - }, - getSecurityManager : function() { return null }, // bh - setProperties : function (props) { - System.props = props; - }, - lineSeparator : function() { return '\n' }, // bh - setProperty : function (key, val) { - if (!System.props) - return System.$props[key] = val; // BH - System.props.setProperty (key, val); - } -}; - -System.identityHashCode=function(obj){ - if(obj==null) - return 0; - - return obj._$hashcode || (obj._$hashcode = ++Clazz._hashCode) - -/* - try{ - return obj.toString().hashCode(); - }catch(e){ - var str=":"; - for(var s in obj){ - str+=s+":" - } - return str.hashCode(); - } -*/ -} - -System.out = new Clazz._O (); -System.out.__CLASS_NAME__ = "java.io.PrintStream"; -System.out.print = function () {}; -System.out.printf = function () {}; -System.out.println = function () {}; -System.out.write = function () {}; - -System.err = new Clazz._O (); -System.err.__CLASS_NAME__ = "java.io.PrintStream"; -System.err.print = function () {}; -System.err.printf = function () {}; -System.err.println = function () {}; -System.err.write = function () {}; - -Clazz.popup = Clazz.assert = Clazz.log = Clazz.error = window.alert; - -Thread = function () {}; -Thread.J2S_THREAD = Thread.prototype.J2S_THREAD = new Thread (); -Thread.currentThread = Thread.prototype.currentThread = function () { - return this.J2S_THREAD; -}; - -/* not used in Jmol -Clazz.intCast = function (n) { // 32bit - var b1 = (n & 0xff000000) >> 24; - var b2 = (n & 0xff0000) >> 16; - var b3 = (n & 0xff00) >> 8; - var b4 = n & 0xff; - if ((b1 & 0x80) != 0) { - return -(((b1 & 0x7f) << 24) + (b2 << 16) + (b3 << 8) + b4 + 1); - } else { - return (b1 << 24) + (b2 << 16) + (b3 << 8) + b4; - } -}; -Clazz.shortCast = function (s) { // 16bit - var b1 = (n & 0xff00) >> 8; - var b2 = n & 0xff; - if ((b1 & 0x80) != 0) { - return -(((b1 & 0x7f) << 8) + b2 + 1); - } else { - return (b1 << 8) + b4; - } -}; - -Clazz.byteCast = function (b) { // 8bit - if ((b & 0x80) != 0) { - return -((b & 0x7f) + 1); - } else { - return b & 0xff; - } -}; - -Clazz.charCast = function (c) { // 8bit - return String.fromCharCode (c & 0xff).charAt (0); -}; - -Clazz.floatCast = function (f) { // 32bit - return f; -}; - -*/ - - -/* - * Try to fix JavaScript's shift operator defects on long type numbers. - */ - -/* not used in Jmol - -Clazz.longMasks = []; - -Clazz.longReverseMasks = []; - -Clazz.longBits = []; - -;(function () { - var arr = [1]; - for (var i = 1; i < 53; i++) { - arr[i] = arr[i - 1] + arr[i - 1]; // * 2 or << 1 - } - Clazz.longBits = arr; - Clazz.longMasks[52] = arr[52]; - for (var i = 51; i >= 0; i--) { - Clazz.longMasks[i] = Clazz.longMasks[i + 1] + arr[i]; - } - Clazz.longReverseMasks[0] = arr[0]; - for (var i = 1; i < 52; i++) { - Clazz.longReverseMasks[i] = Clazz.longReverseMasks[i - 1] + arr[i]; - } -}) (); - - -Clazz.longLeftShift = function (l, o) { // 64bit - if (o == 0) return l; - if (o >= 64) return 0; - if (o > 52) { - error ("[Java2Script] Error : JavaScript does not support long shift!"); - return l; - } - if ((l & Clazz.longMasks[o - 1]) != 0) { - error ("[Java2Script] Error : Such shift operator results in wrong calculation!"); - return l; - } - var high = l & Clazz.longMasks[52 - 32 + o]; - if (high != 0) { - return high * Clazz.longBits[o] + (l & Clazz.longReverseMasks[32 - o]) << 0; - } else { - return l << o; - } -}; - -Clazz.intLeftShift = function (n, o) { // 32bit - return (n << o) & 0xffffffff; -}; - -Clazz.longRightShift = function (l, o) { // 64bit - if ((l & Clazz.longMasks[52 - 32]) != 0) { - return Math.round((l & Clazz.longMasks[52 - 32]) / Clazz.longBits[32 - o]) + (l & Clazz.longReverseMasks[o]) >> o; - } else { - return l >> o; - } -}; - -Clazz.intRightShift = function (n, o) { // 32bit - return n >> o; // no needs for this shifting wrapper -}; - -Clazz.long0RightShift = function (l, o) { // 64bit - return l >>> o; -}; - -Clazz.int0RightShift = function (n, o) { // 64bit - return n >>> o; // no needs for this shifting wrapper -}; - -*/ -// Compress the common public API method in shorter name -//$_L=Clazz.load; -//$_W=Clazz.declareAnonymous;$_T=Clazz.declareType; -//$_J=Clazz.declarePackage;$_C=Clazz.decorateAsClass; -//$_Z=Clazz.instantialize;$_I=Clazz.declareInterface;$_D=Clazz.isClassDefined; -//$_H=Clazz.pu$h;$_P=Clazz.p0p;$_B=Clazz.prepareCallback; -//$_N=Clazz.innerTypeInstance;$_K=Clazz.makeConstructor;$_U=Clazz.superCall;$_R=Clazz.superConstructor; -//$_M=Clazz.defineMethod;$_V=Clazz.overrideMethod;$_S=Clazz.defineStatics; -//$_E=Clazz.defineEnumConstant; -//$_F=Clazz.cloneFinals; -//$_Y=Clazz.prepareFields;$_A=Clazz.newArray;$_O=Clazz.instanceOf; -//$_G=Clazz.inheritArgs;$_X=Clazz.checkPrivateMethod;$_Q=Clazz.makeFunction; -//$_s=Clazz.registerSerializableFields; -//$_k=Clazz.overrideConstructor; - - -/////////////////////// inner function support ///////////////////////////////// - -/* public */ -Clazz.innerFunctionNames = Clazz.innerFunctionNames.concat ([ - "getSuperclass", "isAssignableFrom", - "getConstructor", - "getDeclaredMethod", "getDeclaredMethods", - "getMethod", "getMethods", - "getModifiers", /*"isArray",*/ "newInstance"]); - -/* public */ -Clazz._innerFunctions.getSuperclass = function () { - return this.superClazz; -}; - -/* public */ -Clazz._innerFunctions.isAssignableFrom = function (clazz) { - return Clazz.getInheritedLevel (clazz, this) >= 0; -}; - -/* public */ -Clazz._innerFunctions.getConstructor = function () { - return new java.lang.reflect.Constructor (this, [], [], - java.lang.reflect.Modifier.PUBLIC); -}; -/** - * TODO: fix bug for polymorphic methods! - */ -/* public */ -Clazz._innerFunctions.getDeclaredMethods = Clazz._innerFunctions.getMethods = function () { - var ms = []; - var p = this.prototype; - for (var attr in p) { - if (typeof p[attr] == "function" && !p[attr].__CLASS_NAME__) { - /* there are polynormical methods. */ - ms.push(new java.lang.reflect.Method (this, attr, - [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC)); - } - } - p = this; - for (var attr in p) { - if (typeof p[attr] == "function" && !p[attr].__CLASS_NAME__) { - ms.push(new java.lang.reflect.Method (this, attr, - [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC - | java.lang.reflect.Modifier.STATIC)); - } - } - return ms; -}; -/* public */ -Clazz._innerFunctions.getDeclaredMethod = Clazz._innerFunctions.getMethod = function (name, clazzes) { - var p = this.prototype; - for (var attr in p) { - if (name == attr && typeof p[attr] == "function" - && !p[attr].__CLASS_NAME__) { - /* there are polynormical methods. */ - return new java.lang.reflect.Method (this, attr, - [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC); - } - } - p = this; - for (var attr in p) { - if (name == attr && typeof p[attr] == "function" - && !p[attr].__CLASS_NAME__) { - return new java.lang.reflect.Method (this, attr, - [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC - | java.lang.reflect.Modifier.STATIC); - } - } - return null; -}; -/* public */ -Clazz._innerFunctions.getModifiers = function () { - return java.lang.reflect.Modifier.PUBLIC; -}; - -Clazz._innerFunctions.newInstance = function (a) { - var clz = this; - switch(a == null ? 0 : a.length) { - case 0: - return new clz(); - case 1: - return new clz(a[0]); - case 2: - return new clz(a[0], a[1]); - case 3: - return new clz(a[0], a[1], a[2]); - case 4: - return new clz(a[0], a[1], a[2], a[3]); - default: - var x = "new " + clz.__CLASS_NAME__ + "("; - for (var i = 0; i < a.length; i++) - x += (i == 0 ? "" : ",") + "a[" + i + "]"; - x += ")"; - return eval(x); - } -}; - -//Object.newInstance = Clazz._innerFunctions.newInstance; -;(function(){ // BH added wrapper here - var inF = Clazz.innerFunctionNames; - for (var i = 0; i < inF.length; i++) { - Clazz._O[inF[i]] = Clazz._innerFunctions[inF[i]]; - Array[inF[i]] = Clazz._innerFunctions[inF[i]]; - } - //Array["isArray"] = function () { - // return true; - //}; -})(); - -//////////////////////////// hotspot and unloading ///////////////////////////// -/* For hotspot and unloading */ - -if (window["Clazz"] && !window["Clazz"].unloadClass) { - -/* public */ -Clazz.unloadClass = function (qClazzName) { - var cc = Clazz.evalType (qClazzName); - if (cc) { - Clazz.unloadedClasses[qClazzName] = cc; - var clazzName = qClazzName; - var pkgFrags = clazzName.split (/\./); - var pkg = null; - for (var i = 0; i < pkgFrags.length - 1; i++) - pkg = (pkg ? pkg[pkgFrags[i]] : Clazz.allPackage[pkgFrags[0]]); - if (!pkg) { - Clazz.allPackage[pkgFrags[0]] = null; - window[pkgFrags[0]] = null; - // also try to unload inner or anonymous classes - for (var c in window) { - if (c.indexOf (qClazzName + "$") == 0) { - Clazz.unloadClass (c); - window[c] = null; - } - } - } else { - pkg[pkgFrags[pkgFrags.length - 1]] = null; - // also try to unload inner or anonymous classes - for (var c in pkg) { - if (c.indexOf (pkgFrags[pkgFrags.length - 1] + "$") == 0) { - Clazz.unloadClass (pkg.__PKG_NAME__ + "." + c); - pkg[c] = null; - } - } - } - - if (Clazz.allClasses[qClazzName]) { - Clazz.allClasses[qClazzName] = false; - // also try to unload inner or anonymous classes - for (var c in Clazz.allClasses) { - if (c.indexOf (qClazzName + "$") == 0) { - Clazz.allClasses[c] = false; - } - } - } - - for (var m in cc) { - cleanDelegateMethod (cc[m]); - } - for (var m in cc.prototype) { - cleanDelegateMethod (cc.prototype[m]); - } - - if (Clazz._Loader) { - Clazz._Loader.unloadClassExt(qClazzName); - } - - return true; - } - return false; -}; - -/* private */ -var cleanDelegateMethod = function (m) { - if (!m) - return; - if (typeof m == "function" && m.lastMethod - && m.lastParams && m.lastClaxxRef) { - m.lastMethod = null; - m.lastParams = null; - m.lastClaxxRef = null; - } -}; - -} // if (window["Clazz"] && !window["Clazz"].unloadClass) - -/****************************************************************************** - * Copyright (c) 2007 java2script.org and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Zhou Renjian - initial API and implementation - *****************************************************************************/ -/******* - * @author zhou renjian - * @create July 10, 2006 - *******/ - -//if (window["ClazzNode"] == null) { -/** - * TODO: - * Make optimization over class dependency tree. - */ - -/* - * ClassLoader Summary - * - * ClassLoader creates SCRIPT elements and setup class path and onload - * callback to continue class loading. - * - * In the onload callbacks, _Loader will try to calculate the next-to-be- - * load *.js and load it. In *.js, it will contains some codes like - * Clazz.load (..., "$wt.widgets.Control", ...); - * to provide information to build up the class dependency tree. - * - * Some known problems of different browsers: - * 1. In IE, loading *.js through SCRIPT will first triggers onreadstatechange - * event, and then executes inner *.js source. - * 2. In Firefox, loading *.js will first executes *.js source and then - * triggers onload event. - * 3. In Opera, similar to IE, but trigger onload event. (TODO: More details - * should be studied. Currently, Opera supports no multiple-thread-loading) - * - * For class dependency tree, actually, it is not a tree. It is a reference - * net with nodes have n parents and n children. There is a root, which - * ClassLoader knows where to start searching and loading classes, for such - * a net. Each node is a class. Each class may require a set of must-classes, - * which must be loaded before itself getting initialized, and also need a set - * of optional classes, which also be loaded before being called. - * - * The class loading status will be in 6 stages. - * 1. Unknown, the class is newly introduced by other class. - * 2. Known, the class is already mentioned by other class. - * 3. Loaded, *.js source is in memory, but may not be initialized yet. It - * requires all its must-classes be intiailized, which is in the next stage. - * 4. Musts loaded, all must classes is already loaded and declared. - * 5. Delcared, the class is already declared (_Loader#isClassDefined). - * 6. Optionals loaded, all optional classes is loaded and declared. - * - * The ClassLoader tries to load all necessary classes in order, and intialize - * them in order. For such job, it will traverse the dependency tree, and try - * to next class to-be-loaded. Sometime, the class dependencies may be in one - * or more cycles, which must be broken down so classes is loaded in correct - * order. - * - * Loading order and intializing order is very important for the ClassLoader. - * The following technical options are considered: - * 1. SCRIPT is loading asynchronously, which means controling order must use - * callback methods to continue. - * 2. Multiple loading threads are later introduced, which requires the - * ClassLoader should use variables to record the class status. - * 3. Different browsers have different loading orders, which means extra tests - * should be tested to make sure loading order won't be broken. - * 4. Java2Script simulator itself have some loading orders that must be - * honored, which means it should be integrated seamlessly to Clazz system. - * 5. Packed *.z.js is introduced to avoid lots of small *.js which requires - * lots of HTTP connections, which means that packed *.z.js should be treated - * specially (There will be mappings for such packed classes). - * 6. *.js or *.css loading may fail according to network status, which means - * another loading try should be performed, so _Loader is more robust. - * 7. SWT lazy loading is later introduced, which means that class loading - * process may be paused and should be resumed later. - * - * Some known bugs: - * $_L(["$wt.graphics.Drawable","$wt.widgets.Widget"], - * "$wt.widgets.Control", ... - * has errors while must classes in different order such as - * $_L(["$wt.widgets.Widget", "$wt.graphics.Drawable"], - * "$wt.widgets.Control", ... - * has no error. - * - * Other maybe bug scenarios: - * 1. In _Loader.maxLoadingThreads = 1; single loading thread - * mode, there are no errors, but in default multiple thread loading mode, - * there are errors. - * 2. No errors in one browser, but has errors on other browsers (Browser - * script loading order differences). - * 3. First time loading has errors, but reloading it gets no errors (Maybe - * HTTP connections timeout, but should not accur in local file system, or it - * is a loading bug by using JavaScript timeout thread). - */ - -/* - * The following comments with "#" are special configurations for a much - * smaller *.js file size. - * - * @see net.sf.j2s.lib/src/net/sf/j2s/lib/build/SmartJSCompressor.java - */ -/** - * Static class loader class - */ -Clazz._Loader = Clazz.ClazzLoader = function () {}; - -/** - * Class dependency tree node - */ -/* private */ -var Node = function () { - this.parents = []; - this.musts = []; - this.optionals = []; - this.declaration = null; - this.name = null; // id - this.path = null; -// this.requires = null; -// this.requiresMap = null; - this.onLoaded = null; - this.status = 0; - this.random = 0.13412; -}; - - -;(function(Clazz, _Loader) { - -_Loader._checkLoad = Jmol._checkLoad; - -_Loader.updateNodeForFunctionDecoration = function(qName) { - var node = findNode(qName); - if (node && node.status == Node.STATUS_KNOWN) { - window.setTimeout((function(nnn) { - return function() { - updateNode(nnn); - }; - })(node), 1); - } -} - -Node.prototype.toString = function() { - return this.name || this.path || "ClazzNode"; -} - -Node.STATUS_UNKNOWN = 0; -Node.STATUS_KNOWN = 1; -Node.STATUS_CONTENT_LOADED = 2; -Node.STATUS_MUSTS_LOADED = 3; -Node.STATUS_DECLARED = 4; -Node.STATUS_LOAD_COMPLETE = 5; - - -var loaders = []; - -/* public */ -_Loader.requireLoaderByBase = function (base) { - for (var i = 0; i < loaders.length; i++) { - if (loaders[i].base == base) { - return loaders[i]; - } - } - var loader = new _Loader (); - loader.base = base; - loaders.push(loader); - return loader; -}; - -/** - * Class dependency tree - */ -var clazzTreeRoot = new Node(); - -/** - * Used to keep the status whether a given *.js path is loaded or not. - */ -/* private */ -var loadedScripts = {}; - -/** - * Multiple threads are used to speed up *.js loading. - */ -/* private */ -var inLoadingThreads = 0; - -/** - * Maximum of loading threads - */ -/* private */ -var maxLoadingThreads = 6; - -var userAgent = navigator.userAgent.toLowerCase (); -var isOpera = (userAgent.indexOf ("opera") != -1); -var isIE = (userAgent.indexOf ("msie") != -1) && !isOpera; -var isGecko = (userAgent.indexOf ("gecko") != -1); - -/* - * Opera has different loading order which will result in performance degrade! - * So just return to single thread loading in Opera! - * - * FIXME: This different loading order also causes bugs in single thread! - */ -if (isOpera) { - maxLoadingThreads = 1; - var index = userAgent.indexOf ("opera/"); - if (index != -1) { - var verNumber = 9.0; - try { - verNumber = parseFloat(userAgent.subString (index + 6)); - } catch (e) {} - if (verNumber >= 9.6) { - maxLoadingThreads = 6; - } - } -} - -/** - * Try to be compatiable with Clazz system. - * In original design _Loader and Clazz are independent! - * -- zhourenjian @ December 23, 2006 - */ -var isClassdefined; -var definedClasses; - -if (self.Clazz && Clazz.isClassDefined) { - isClassDefined = Clazz.isClassDefined; -} else { - definedClasses = {}; - isClassDefined = function (clazzName) { - return definedClasses[clazzName] == true; - }; -} - -/** - * Expand the shortened list of class names. - * For example: - * JU.Log, $.Display, $.Decorations - * will be expanded to - * JU.Log, JU.Display, JU.Decorations - * where "$." stands for the previous class name's package. - * - * This method will be used to unwrap the required/optional classes list and - * the ignored classes list. - */ -/* private */ -var unwrapArray = function (arr) { - if (!arr || arr.length == 0) - return []; - var last = null; - for (var i = 0; i < arr.length; i++) { - if (!arr[i]) - continue; - if (arr[i].charAt (0) == '$') { - if (arr[i].charAt (1) == '.') { - if (!last) - continue; - var idx = last.lastIndexOf ("."); - if (idx != -1) { - var prefix = last.substring (0, idx); - arr[i] = prefix + arr[i].substring (1); - } - } else { - arr[i] = "org.eclipse.s" + arr[i].substring (1); - } - } - last = arr[i]; - } - return arr; -}; - -/** - * Used to keep to-be-loaded classes. - */ -/* private */ -var classQueue = []; - -/* private */ -var classpathMap = {}; - -/* private */ -var pkgRefCount = 0; - -/* public */ -_Loader.loadPackageClasspath = function (pkg, base, isIndex, fSuccess, mode, pt) { - var map = classpathMap; - mode || (mode = 0); - fSuccess || (fSuccess = null); - pt || (pt = 0); - - /* - * In some situation, maybe, - * _Loader.packageClasspath ("java", ..., true); - * is called after other _Loader#packageClasspath, e.g. - * - * _Loader.packageClasspath ("org.eclipse.swt", "...", true); - * _Loader.packageClasspath ("java", "...", true); - * - * which is not recommended. But _Loader should try to adjust orders - * which requires "java" to be declared before normal _Loader - * #packageClasspath call before that line! And later that line - * should never initialize "java/package.js" again! - */ - var isPkgDeclared = (isIndex && map["@" + pkg]); - if (mode == 0 && isIndex && !map["@java"] && pkg.indexOf ("java") != 0 && needPackage("java")) { - _Loader.loadPackage("java", fSuccess ? function(_package){_Loader.loadPackageClasspath(pkg, base, isIndex, fSuccess, 1)} : null); - if (fSuccess) - return; - } - if (pkg instanceof Array) { - unwrapArray(pkg); - if (fSuccess) { - if (pt < pkg.length) - _Loader.loadPackageClasspath(pkg[pt], base, isIndex, function(_loadPackageClassPath){_Loader.loadPackageClasspath(pkg, base, isIndex, fSuccess, 1, pt + 1)}, 1); - else - fSuccess(); - } else { - for (var i = 0; i < pkg.length; i++) - _Loader.loadPackageClasspath(pkg[i], base, isIndex, null); - } - return; - } - switch (pkg) { - case "java.*": - pkg = "java"; - // fall through - case "java": - if (base) { - // support ajax for default - var key = "@net.sf.j2s.ajax"; - if (!map[key]) - map[key] = base; - key = "@net.sf.j2s"; - if (!map[key]) - map[key] = base; - } - break; - case "swt": - pkg = "org.eclipse.swt"; - break; - case "ajax": - pkg = "net.sf.j2s.ajax"; - break; - case "j2s": - pkg = "net.sf.j2s"; - break; - default: - if (pkg.lastIndexOf(".*") == pkg.length - 2) - pkg = pkg.substring(0, pkg.length - 2); - break; - } - if (base) // critical for multiple applets - map["@" + pkg] = base; - if (isIndex && !isPkgDeclared && !window[pkg + ".registered"]) { - pkgRefCount++; - if (pkg == "java") - pkg = "core" // JSmol -- moves java/package.js to core/package.js - _Loader.loadClass(pkg + ".package", function () { - if (--pkgRefCount == 0) - runtimeLoaded(); - //fSuccess && fSuccess(); - }, true, true, 1); - return; - } - fSuccess && fSuccess(); -}; - -/** - * BH: allows user/developer to load classes even though wrapping and Google - * Closure Compiler has not been run on the class. - * - */ -Clazz.loadClass = function (name, onLoaded, async) { - if (!self.Class) { - Class = Clazz; - Class.forName = Clazz._4Name; - JavaObject = Clazz._O; - // maybe more here - } - return (name && _Loader.loadClass(name, onLoaded, true, async, 1)); -} - -/** - * Load the given class ant its related classes. - */ -/* public */ -_Loader.loadClass = function (name, onLoaded, forced, async, mode) { - - mode || (mode = 0); // BH: not implemented - (async == null) && (async = false); - - if (typeof onLoaded == "boolean") - return Clazz.evalType(name); - - System.out.println("loadClass " + name) - - // Make sure that packageClasspath ("java", base, true); - // is called before any _Loader#loadClass is called. - - if (needPackage("java")) - _Loader.loadPackage("java"); - if (needPackage("core")) - _Loader.loadPackage("core"); - -// var swtPkg = "org.eclipse.swt"; -// if (name.indexOf (swtPkg) == 0 || name.indexOf ("$wt") == 0) { -// _Loader.assurePackageClasspath (swtPkg); -// } -// if (name.indexOf ("junit") == 0) { -// _Loader.assurePackageClasspath ("junit"); -// } - - // Any _Loader#loadClass calls will be queued until java.* core classes are loaded. - - _Loader.keepOnLoading = true; - - if (!forced && (pkgRefCount && name.lastIndexOf(".package") != name.length - 8 - || name.indexOf("java.") != 0 && !isClassDefined(runtimeKeyClass) - )) { - queueBe4KeyClazz.push([name, onLoaded]); - - - System.out.println("loadclass-queuing" + name+ runtimeKeyClass + " "+ isClassDefined(runtimeKeyClass)) - - return; - } - var b; - if ((b = isClassDefined(name)) || isClassExcluded(name)) { - if (b && onLoaded) { - var nn = findNode(name); - if (!nn || nn.status >= Node.STATUS_LOAD_COMPLETE) { - if (async) { - window.setTimeout(onLoaded, 25); - } else { - onLoaded(); - } - } - } - return; - } - var path = _Loader.getClasspathFor(name); - var existed = loadedScripts[path]; - var qq = classQueue; - if (!existed) - for (var i = qq.length; --i >= 0;) - if (qq[i].path == path || qq[i].name == name) { - existed = true; - break; - } - if (existed) { - if (onLoaded) { - var n = findNode(name); - if (n) { - if (!n.onLoaded) { - n.onLoaded = onLoaded; - } else if (onLoaded != n.onLoaded) { - n.onLoaded = (function (nF, oF) { return function () { nF(); oF() }; }) (n.onLoaded, onLoaded); - } - } - } - return; - } - - var n = (Clazz.unloadedClasses[name] && findNode(name) || new Node()); - n.name = name; - n.path = path; - n.isPackage = (path.lastIndexOf("package.js") == path.length - 10); - mappingPathNameNode(path, name, n); - n.onLoaded = onLoaded; - n.status = Node.STATUS_KNOWN; - var needBeingQueued = false; - for (var i = qq.length; --i >= 0;) { - if (qq[i].status != Node.STATUS_LOAD_COMPLETE) { - needBeingQueued = true; - break; - } - } - - if (n.isPackage) {//forced - // push class to queue - var pt = qq.length; - for (; --pt >= 0;) { - if (qq[pt].isPackage) - break; - qq[pt + 1] = qq[pt]; - } - qq[++pt] = n; - } else if (needBeingQueued) { - qq.push(n); - } - if (!needBeingQueued) { // can be loaded directly - var bSave = false; - if (onLoaded) { - bSave = isLoadingEntryClass; - isLoadingEntryClass = true; - } - if (forced)onLoaded = null; - addChildClassNode(clazzTreeRoot, n, true); - loadScript(n, n.path, n.requiredBy, false, onLoaded ? function(_loadClass){ isLoadingEntryClass = bSave; onLoaded()}: null); - } -}; - -/* - * Check whether given package's classpath is setup or not. - * Only "java" and "org.eclipse.swt" are accepted in argument. - */ -/* private */ -var needPackage = function(pkg) { - // note that false != null and true != null - return (window[pkg + ".registered"] != null && !classpathMap["@" + pkg]); -} - -/* private */ -_Loader.loadPackage = function(pkg, fSuccess) { - fSuccess || (fSuccess = null); - window[pkg + ".registered"] = false; - _Loader.loadPackageClasspath(pkg, - (_Loader.J2SLibBase || (_Loader.J2SLibBase = (_Loader.getJ2SLibBase() || "j2s/"))), - true, fSuccess); -}; - -/** - * Register classes to a given *.z.js path, so only a single *.z.js is loaded - * for all those classes. - */ -/* public */ -_Loader.jarClasspath = function (jar, clazzes) { - if (!(clazzes instanceof Array)) - clazzes = [classes]; - unwrapArray(clazzes); - for (var i = clazzes.length; --i >= 0;) - classpathMap["#" + clazzes[i]] = jar; - classpathMap["$" + jar] = clazzes; -}; - -/** - * Usually be used in .../package.js. All given packages will be registered - * to the same classpath of given prefix package. - */ -/* public */ -_Loader.registerPackages = function (prefix, pkgs) { - //_Loader.checkInteractive (); - var base = _Loader.getClasspathFor (prefix + ".*", true); - for (var i = 0; i < pkgs.length; i++) { - if (window["Clazz"]) { - Clazz.declarePackage (prefix + "." + pkgs[i]); - } - _Loader.loadPackageClasspath (prefix + "." + pkgs[i], base); - } -}; - -/** - * Using multiple sites to load *.js in multiple threads. Using multiple - * sites may avoid 2 HTTP 1.1 connections recommendation limit. - * Here is a default implementation for http://archive.java2script.org. - * In site archive.java2script.org, there are 6 sites: - * 1. http://archive.java2script.org or http://a.java2script.org - * 2. http://erchive.java2script.org or http://e.java2script.org - * 3. http://irchive.java2script.org or http://i.java2script.org - * 4. http://orchive.java2script.org or http://o.java2script.org - * 5. http://urchive.java2script.org or http://u.java2script.org - * 6. http://yrchive.java2script.org or http://y.java2script.org - */ -/* protected */ - /* -_Loader.multipleSites = function (path) { - var deltas = window["j2s.update.delta"]; - if (deltas && deltas instanceof Array && deltas.length >= 3) { - var lastOldVersion = null; - var lastNewVersion = null; - for (var i = 0; i < deltas.length / 3; i++) { - var oldVersion = deltas[i + i + i]; - if (oldVersion != "$") { - lastOldVersion = oldVersion; - } - var newVersion = deltas[i + i + i + 1]; - if (newVersion != "$") { - lastNewVersion = newVersion; - } - var relativePath = deltas[i + i + i + 2]; - var key = lastOldVersion + "/" + relativePath; - var idx = path.indexOf (key); - if (idx != -1 && idx == path.length - key.length) { - path = path.substring (0, idx) + lastNewVersion + "/" + relativePath; - break; - } - } - } - var length = path.length; - if (maxLoadingThreads > 1 - && ((length > 15 && path.substring (0, 15) == "http://archive.") - || (length > 9 && path.substring (0, 9) == "http://a."))) { - var index = path.lastIndexOf("/"); - if (index < length - 3) { - var arr = ['a', 'e', 'i', 'o', 'u', 'y']; - var c1 = path.charCodeAt (index + 1); - var c2 = path.charCodeAt (index + 2); - var idx = (length - index) * 3 + c1 * 5 + c2 * 7; // Hash - return path.substring (0, 7) + arr[idx % 6] + path.substring (8); - } - } - return path; -}; - */ - -/** - * Return the *.js path of the given class. Maybe the class is contained - * in a *.z.js jar file. - * @param clazz Given class that the path is to be calculated for. May - * be java.package, or java.lang.String - * @param forRoot Optional argument, if true, the return path will be root - * of the given classs' package root path. - * @param ext Optional argument, if given, it will replace the default ".js" - * extension. - */ -/* public */ -_Loader.getClasspathFor = function (clazz, forRoot, ext) { - var path = classpathMap["#" + clazz]; - if (!path || forRoot || ext) { - var base; - var idx; - if (path) { - clazz = clazz.replace(/\./g, "/"); - if ((idx = path.lastIndexOf(clazz)) >= 0 - || (idx = clazz.lastIndexOf("/")) >= 0 - && (idx = path.lastIndexOf(clazz.substring(0, idx))) >= 0) - base = path.substring(0, idx); - } else { - idx = clazz.length + 2; - while ((idx = clazz.lastIndexOf(".", idx - 2)) >= 0) - if ((base = classpathMap["@" + clazz.substring(0, idx)])) - break; - if (!forRoot) - clazz = clazz.replace (/\./g, "/"); - } - if (base == null) { - var bins = "binaryFolders"; - base = (window["Clazz"] && Clazz[bins] && Clazz[bins].length ? Clazz[bins][0] - : _Loader[bins] && _Loader[bins].length ? _Loader[bins][0] - : "j2s"); - } - path = (base.lastIndexOf("/") == base.length - 1 ? base : base + "/") + (forRoot ? "" - : clazz.lastIndexOf("/*") == clazz.length - 2 ? clazz.substring(0, idx + 1) - : clazz + (!ext ? ".js" : ext.charAt(0) != '.' ? "." + ext : ext)); - } - return path;//_Loader.multipleSites(path); -}; - -/** - * To ignore some classes. - */ -/* public */ -_Loader.ignore = function () { - var clazzes = (arguments.length == 1 && arguments[0] instanceof Array ? - clazzes = arguments[0] : null); - var n = (clazzes ? clazzes.length : arguments.length); - if (!clazzes) { - clazzes = new Array(n); - for (var i = 0; i < n; i++) - clazzes[i] = arguments[i]; - } - unwrapArray(clazzes); - for (var i = 0; i < n; i++) - excludeClassMap["@" + clazzes[i]] = 1; -}; - -/** - * The following *.script* can be overriden to indicate the - * status of classes loading. - * - * TODO: There should be a Java interface with name like INativeLoaderStatus - */ -/* public */ -_Loader.onScriptLoading = function (file){}; - -/* public */ -_Loader.onScriptLoaded = function (file, isError){}; - -/* public */ -_Loader.onScriptInitialized = function (file){}; - -/* public */ -_Loader.onScriptCompleted = function (file){}; - -/* public */ -_Loader.onClassUnloaded = function (clazz){}; - -/** - * After all the classes are loaded, this method will be called. - * Should be overriden to run *.main([]). - */ -/* public */ -_Loader.onGlobalLoaded = function () {}; - -/* public */ -_Loader.keepOnLoading = true; // never set false in this code - - -/* private */ -var mapPath2ClassNode = {}; - -/* private */ -var isClassExcluded = function (clazz) { - return excludeClassMap["@" + clazz]; -}; - -/* Used to keep ignored classes */ -/* private */ -var excludeClassMap = {}; - -/* private */ -var evaluate = function(file, file0, js) { - try { - eval(js + ";//# sourceURL="+file); - } catch (e) { - if (Clazz._isQuiet) - return; - var s = "[Java2Script] The required class file \n\n" + file + (js.indexOf("[Exception") == 0 && js.indexOf("data: no") ? - "\nwas not found.\n" - : "\ncould not be loaded. Script error: " + e.message + " \n\ndata:\n\n" + js) + "\n\n" + Clazz.getStackTrace(); - alert(s) - Clazz.alert(s); - throw e; - } - _Loader.onScriptLoaded(file, false); - tryToLoadNext(file0); -} - -/* private */ -var failedHandles = {}; - -/* private */ -var generateRemovingFunction = function (node) { - return function () { - if (node.readyState != "interactive") { - try { - if (node.parentNode) - node.parentNode.removeChild (node); - } catch (e) { } - node = null; - } - }; -}; - -/* private */ -var removeScriptNode = function (n) { - if (window["j2s.script.debugging"]) { - return; - } - // lazily remove script nodes. - window.setTimeout (generateRemovingFunction (n), 1); -}; - -/* public */ -Clazz._4Name = function(clazzName, applet, state) { - if (Clazz.isClassDefined(clazzName)) - return Clazz.evalType(clazzName); - var f = (Jmol._isAsync && applet ? applet._restoreState(clazzName, state) : null); - if (f == 1) - return null; // must be already being created - if (_Loader.setLoadingMode(f ? _Loader.MODE_SCRIPT : "xhr.sync")) { - _Loader.loadClass(clazzName, f, false, true, 1); - return null; // this will surely throw an error, but that is OK - } - //alert ("Using Java reflection: " + clazzName + " for " + applet._id + " \n"+ Clazz.getStackTrace()); - _Loader.loadClass(clazzName); - return Clazz.evalType(clazzName); -}; - -/** - * BH: possibly useful for debugging - */ -Clazz.currentPath= ""; - -/** - * Load *.js by adding script elements into head. Hook the onload event to - * load the next class in dependency tree. - */ -/* private */ -var loadScript = function (node, file, why, ignoreOnload, fSuccess, _loadScript) { - - Clazz.currentPath = file; - if (ignoreOnload)alert("WHY>>") -//BH removed // maybe some scripts are to be loaded without needs to know onload event. -// if (!ignoreOnload && loadedScripts[file]) { -// _Loader.tryToLoadNext(file); -// return; -// } - loadedScripts[file] = true; - // also remove from queue - removeArrayItem(classQueue, file); - - // forces not-found message - isUsingXMLHttpRequest = true; - isAsynchronousLoading = false; - if (_Loader._checkLoad) { - System.out.println("\t" + file + (why ? "\n -- required by " + why : "") + " ajax=" + isUsingXMLHttpRequest + " async=" + isAsynchronousLoading) - } - - var file0 = file; - if (Clazz._debugging) { - file = file.replace(/\.z\.js/,".js"); - } - - _Loader.onScriptLoading(file); - if (isUsingXMLHttpRequest && !isAsynchronousLoading) { - // alert("\t" + file + (why ? "\n -- required by " + why : "") + " ajax=" + isUsingXMLHttpRequest + " async=" + isAsynchronousLoading + " " + Clazz.getStackTrace()) - // synchronous loading - // works in MSIE locally unless a binary file :) - // from Jmol.api.Interface only - var data = Jmol._getFileData(file); - try{ - evaluate(file, file0, data); - }catch(e) { - alert(e + " loading file " + file + " " + node.name + " " + Clazz.getStackTrace()); - } - if (fSuccess) { -// System.out.println("firing in loadScript " + file + " " + (fSuccess && fSuccess.toString())) - fSuccess(); - } - return; - } - - -System.out.println("for file " + file +" fSuccess = " + (fSuccess ? fSuccess.toString() : "")) - var info = { - dataType:"script", - async:true, - type:"GET", - url:file, - success:W3CScriptOnCallback(file, false, fSuccess), - error:W3CScriptOnCallback(file, true, fSuccess) - }; - inLoadingThreads++; - Jmol.$ajax(info); -}; - -/* private */ -var W3CScriptOnCallback = function (path, forError, fSuccess) { - var s = Clazz.getStackTrace(); - // if (!fSuccess)alert("why no fSuccess?" + s) - return function () { - //System.out.println("returning " + (fSuccess ? fSuccess.toString() : "no function ") + s) - if (forError && __debuggingBH)Clazz.alert ("############ forError=" + forError + " path=" + path + " ####" + (forError ? "NOT" : "") + "LOADED###"); - if (isGecko && this.timeoutHandle) - window.clearTimeout(this.timeoutHandle), this.timeoutHandle = null; - if (inLoadingThreads > 0) - inLoadingThreads--; - //System.out.println("w3ccalback for " + path + " " + inLoadingThreads + " threads") - this.onload = null; - this.onerror = null; - if (forError) - alert ("There was a problem loading " + path); - _Loader.onScriptLoaded(path, true); - var node = this; - var f; - if (fSuccess) - f = function(_W3scriptFS){removeScriptNode(node);tryToLoadNext(path, fSuccess); }; - else - f = function(_W3script){removeScriptNode(node);tryToLoadNext(path)}; - if (loadingTimeLag >= 0) - window.setTimeout(function() { tryToLoadNext(path, f); }, loadingTimeLag); - else - tryToLoadNext(path, f); - }; -}; - -/* private */ -var isLoadingEntryClass = true; - -/* private */ -var besidesJavaPackage = false; - -/** - * After class is loaded, this method will be executed to check whether there - * are classes in the dependency tree that need to be loaded. - */ -/* private */ -var tryToLoadNext = function (file, fSuccess) { - var node = mapPath2ClassNode["@" + file]; - if (!node) // maybe class tree root - return; - var n; - // check for content loaded - var clazzes = classpathMap["$" + file]; - if (clazzes) { - for (var i = 0; i < clazzes.length; i++) { - var name = clazzes[i]; - if (name != node.name && (n = findNode(name))) { - if (n.status < Node.STATUS_CONTENT_LOADED) { - n.status = Node.STATUS_CONTENT_LOADED; - updateNode(n); - } - } else { - n = new Node(); - n.name = name; - var pp = classpathMap["#" + name]; - if (!pp) { - alert (name + " J2S error in tryToLoadNext"); - error("Java2Script implementation error! Please report this bug!"); - } - n.path = pp; - mappingPathNameNode (n.path, name, n); - n.status = Node.STATUS_CONTENT_LOADED; - addChildClassNode(clazzTreeRoot, n, false); - updateNode(n); - } - } - } - if (node instanceof Array) { - for (var i = 0; i < node.length; i++) { - if (node[i].status < Node.STATUS_CONTENT_LOADED) { - node[i].status = Node.STATUS_CONTENT_LOADED; - updateNode(node[i]); - } - } - } else if (node.status < Node.STATUS_CONTENT_LOADED) { - var stillLoading = false; - var ss = document.getElementsByTagName ("SCRIPT"); - for (var i = 0; i < ss.length; i++) { - if (isIE) { - if (ss[i].onreadystatechange && ss[i].onreadystatechange.path == node.path - && ss[i].readyState == "interactive") { - stillLoading = true; - break; - } - } else if (ss[i].onload && ss[i].onload.path == node.path) { - stillLoading = true; - break; - } - } - if (!stillLoading) { - node.status = Node.STATUS_CONTENT_LOADED; - updateNode(node); - } - } - /* - * Maybe in #optinalLoaded inside above _Loader#updateNode calls, - * _Loader.keepOnLoading is set false (Already loaded the wanted - * classes), so here check to stop. - */ - - if (!_Loader.keepOnLoading) // set externally - return; - - // check for a "must" class that has content and load it - var cq; - var working = true; - if ((n = findNextMustClass(Node.STATUS_KNOWN))) { - loadClassNode(n); - while (inLoadingThreads < maxLoadingThreads) { - if (!(n = findNextMustClass(Node.STATUS_KNOWN))) - break; - loadClassNode(n); // will increase inLoadingThreads! - } - } else if ((cq = classQueue).length != 0) { - /* queue must be loaded in order! */ - n = cq.shift(); - if (!loadedScripts[n.path] - || cq.length != 0 - || !isLoadingEntryClass - || n.musts.length - || n.optionals.length) { - addChildClassNode(clazzTreeRoot, n, true); - loadScript(n, n.path, n.requiredBy, false); - } else if (isLoadingEntryClass) { - /* - * The first time reaching here is the time when ClassLoader - * is trying to load entry class. Class with #main method and - * is to be executed is called Entry Class. - * - * Here when loading entry class, ClassLoader should not call - * the next following loading script. This is because, those - * scripts will try to mark the class as loaded directly and - * then continue to call #onLoaded callback method, - * which results in an script error! - */ - isLoadingEntryClass = false; - } - } else if ((n = findNextRequiredClass(Node.STATUS_KNOWN))) { - loadClassNode(n); - while (inLoadingThreads < maxLoadingThreads) { - if (!(n = findNextRequiredClass(Node.STATUS_KNOWN))) - break; - loadClassNode(n); // will increase inLoadingThreads! - } - } else { - working = false; - } - if (working || inLoadingThreads > 0) - return; - // - // now check all classes that MUST be loaded prior to initialization - // of some other class (static calls, extends, implements) - // and all classes REQUIRED somewhere in that class, possibly by the constructor - // (that is, "new xxxx()" called somewhere in code) and update them - // that have content but are not declared already - var f = [findNextMustClass,findNextRequiredClass]; - var lastNode = null; - for (var i = 0; i < 2; i++) - while ((n = f[i](Node.STATUS_CONTENT_LOADED))) { - if (i == 1 && lastNode === n) // Already existed cycle ? - n.status = Node.STATUS_LOAD_COMPLETE; - updateNode(n); - lastNode = n; - } - - // check for load cycles - - while (true) { - tracks = []; - if (!checkCycle(clazzTreeRoot, file)) - break; - } - - // and update all MUST and REQUIRED classes that are declared already - - for (var i = 0; i < 2; i++) { - lastNode = null; - while ((n = f[i](Node.STATUS_DECLARED))) { - if (lastNode === n) - break; - updateNode(lastNode = n); - } - } - var done = []; - for (var i = 0; i < 2; i++) - while ((n = f[i](Node.STATUS_DECLARED))) - done.push(n), n.status = Node.STATUS_LOAD_COMPLETE; - if (done.length) { - for (var i = 0; i < done.length; i++) - destroyClassNode(done[i]); - for (var i = 0; i < done.length; i++) - if ((f = done[i].onLoaded)) - done[i].onLoaded = null, f(); - } - - - - - - - - //System.out.println(node.name + " loaded completely" + _Loader.onGlobalLoaded + "\n\n") - if (fSuccess) { - //System.out.println("tryToLoadNext firing " + _Loader._classCountOK + "/" + _Loader._classCountPending + " " + fSuccess.toString() + " " + Clazz.getStackTrace()) - fSuccess(); - } else if (_Loader._classCountPending) { - for (var name in _Loader._classPending) { - var n = findNode(name); - System.out.println("class left pending " + name + " " + n); - if (n) { - updateNode(n); - break; - } - } - } else { - - // System.out.println("I think I'm done " - // + _Loader._classCountOK + "/" + _Loader._classCountPending + " " - //+ _Loader.onGlobalLoaded.toString() + " " + Clazz.getStackTrace() - // ) - if (_Loader._checkLoad) { - System.out.println("I think I'm done: SAEM call count: " + SAEMid); - Clazz.showDuplicates(true); - } - } - _Loader.onGlobalLoaded(); -}; - - -var tracks = []; - -/* - * There are classes reference cycles. Try to detect and break those cycles. - */ -/* private */ -var checkCycle = function (node, file) { - var ts = tracks; - var len = ts.length; - // add this node to tracks - ts.push(node); - var i = len; - for (; --i >= 0;) - if (ts[i] === node && ts[i].status >= Node.STATUS_DECLARED) - break; - if (i >= 0) { - // this node is already in tracks, and it has been declared already - // for each node in tracks, set its status to "LOAD_COMPLETE" - // update all parents, remove all parents, and fire its onLoaded function - // then clear tracks and return true (keep checking) - if (_Loader._checkLoad) { - var msg = "cycle found loading " + file + " for " + node; - System.out.println(msg) - } - for (; i < len; i++) { - var n = ts[i]; - n.status = Node.STATUS_LOAD_COMPLETE; - destroyClassNode(n); // Same as above - for (var k = 0; k < n.parents.length; k++) - updateNode(n.parents[k]); - n.parents = []; - var f = n.onLoaded; - if (_Loader._checkLoad) { - var msg = "cycle setting status to LOAD_COMPLETE for " + n.name + (f ? " firing " + f.toString() : ""); - System.out.println(msg) - } - if (f) - n.onLoaded = null, f(); - } - ts.length = 0; - return true; - } - var a = [node.musts, node.optionals]; - for (var j = 0; j < 2; j++) - for (var r = a[j], i = r.length; --i >= 0;) - if (r[i].status == Node.STATUS_DECLARED && checkCycle(r[i], file)) - return true; - // reset _tracks to its original length - ts.length = len; - return false; // done -}; - - -_Loader._classCountPending = 0; -_Loader._classCountOK = 0; -_Loader._classPending = {}; - -_Loader.showPending = function() { - var a = []; - for (var name in _Loader._classPending) { - var n = findNode(name); - if (!n) { - alert("No node for " + name); - continue; - } - a.push(n); - System.out.println(showNode("", "", n, "", 0)); - } - return a; -} - -var showNode = function(s, names, node, inset, level) { - names += "--" + node.name; - s += names + "\n"; - if (level > 5) { - s += inset + " ...\n"; - return s; - } - inset += "\t"; - s += inset + "status: " + node.status + "\n"; - if (node.parents && node.parents.length && node.parents[0] && node.parents[0].name) { - s += inset + "parents: " + node.parents.length + "\n"; - for (var i = 0; i < node.parents.length; i++) { - s = showNode(s, names, node.parents[i], inset + "\t", level+1); - } - s += "\n"; - } -// if (node.requiredBy) { -// s += inset + "requiredBy:\n"; -// s = showNode(s, names, node.requiredBy, inset + "\t", level+1); -// s += "\n"; -// } - return s; -} - -/** - * Update the dependency tree nodes recursively. - */ -/* private */ -updateNode = function(node, _updateNode) { - if (!node.name || node.status >= Node.STATUS_LOAD_COMPLETE) { - destroyClassNode(node); - return; - } - var ready = true; - // check for declared and also having MUSTS - if (node.musts.length && node.declaration) { - for (var mustLength = node.musts.length, i = mustLength; --i >= 0;) { - var n = node.musts[i]; - n.requiredBy = node; - if (n.status < Node.STATUS_DECLARED && isClassDefined (n.name)) { - var nns = []; // a stack for onLoaded events - n.status = Node.STATUS_LOAD_COMPLETE; - destroyClassNode(n); // Same as above - if (n.declaration && n.declaration.clazzList) { - // For those classes within one *.js file, update them synchronously. - for (var j = 0, list = n.declaration.clazzList, l = list.length; j < l; j++) { - var nn = findNode (list[j]); - if (nn && nn.status != Node.STATUS_LOAD_COMPLETE - && nn !== n) { - nn.status = n.status; - nn.declaration = null; - destroyClassNode(nn); - nn.onLoaded && nns.push(nn); - } - } - n.declaration = null; - } - // fire all onLoaded events - if (n.onLoaded) - nns.push(n); - for (var j = 0; j < nns.length; j++) { - var onLoaded = nns[j].onLoaded; - if (onLoaded) { - nns[j].onLoaded = null; - onLoaded(); - } - } - } else { - (n.status == Node.STATUS_CONTENT_LOADED) && updateNode(n); // musts may be changed - if (n.status < Node.STATUS_DECLARED) - ready = false; - } - if (node.musts.length != mustLength) { - // length changed -- restart! - i = mustLength = node.musts.length; - ready = true; - } - } - } - if (!ready) - return; - if (node.status < Node.STATUS_DECLARED) { - var decl = node.declaration; - if (decl) - decl(), decl.executed = true; - if(_Loader._checkLoad) { - if (_Loader._classPending[node.name]) { - delete _Loader._classPending[node.name]; - _Loader._classCountOK; - _Loader._classCountPending--; -// System.out.println("OK " + (_Loader._classCountOK) + " FOR " + node.name) - } - } - node.status = Node.STATUS_DECLARED; - if (definedClasses) - definedClasses[node.name] = true; - _Loader.onScriptInitialized(node.path); - if (node.declaration && node.declaration.clazzList) { - // For those classes within one *.js file, update them synchronously. - for (var j = 0, list = node.declaration.clazzList, l = list.length; j < l; j++) { - var nn = findNode(list[j]); - if (nn && nn.status != Node.STATUS_DECLARED - && nn !== node) { - nn.status = Node.STATUS_DECLARED; - if (definedClasses) - definedClasses[nn.name] = true; - _Loader.onScriptInitialized(nn.path); - } - } - } - } - var level = Node.STATUS_DECLARED; - if (node.optionals.length == 0 && node.musts.length == 0 - || node.status > Node.STATUS_KNOWN && !node.declaration - || checkStatusIs(node.musts, Node.STATUS_LOAD_COMPLETE) - && checkStatusIs(node.optionals, Node.STATUS_LOAD_COMPLETE)) { - level = Node.STATUS_LOAD_COMPLETE; - if (!doneLoading(node, level)) - return false; - // For those classes within one *.js file, update them synchronously. - if (node.declaration && node.declaration.clazzList) { - for (var j = 0, list = node.declaration.clazzList, l = list.length; j < l; j++) { - var nn = findNode(list[j]); - if (nn && nn.status != level && nn !== node) { - nn.declaration = null; - if (!doneLoading(nn, level)) - return false; - } - } - } - } - // _Loader.updateParents = function (node, level, _updateParents) - if (node.parents && node.parents.length) { - for (var i = 0; i < node.parents.length; i++) { - var p = node.parents[i]; - if (p.status < level) - updateNode(p, p.name); - } - if (level == Node.STATUS_LOAD_COMPLETE) - node.parents = []; - } -}; - -/* private */ -var checkStatusIs = function(arr, status){ - for (var i = arr.length; --i >= 0;) - if (arr[i].status < status) - return false; - return true; -} -/* private */ -var doneLoading = function(node, level, _doneLoading) { - node.status = level; - _Loader.onScriptCompleted(node.path); - - var onLoaded = node.onLoaded; - if (onLoaded) { - node.onLoaded = null; - onLoaded(); - if (!_Loader.keepOnLoading) - return false; - } - - destroyClassNode(node); - return true; -} - -/* - * Be used to record already used random numbers. And next new random - * number should not be in the property set. - */ -/* private */ -var usedRandoms = { - "r0.13412" : 1 -}; - -/* private */ -var getRnd = function() { - while (true) { // get a unique random number - var rnd = Math.random(); - var s = "r" + rnd; - if (!usedRandoms[s]) - return (usedRandoms[s] = 1, clazzTreeRoot.random = rnd); - } -} - -/* protected */ -var findNode = function(clazzName) { - getRnd(); - return findNodeUnderNode(clazzName, clazzTreeRoot); -}; - -/* private */ -var findNextRequiredClass = function(status) { - getRnd(); - return findNextRequiredNode(clazzTreeRoot, status); -}; - -/* private */ -var findNextMustClass = function(status) { - return findNextMustNode(clazzTreeRoot, status); -}; - -/* private */ -var findNodeUnderNode = function(clazzName, node) { - var n; - // node, then musts then optionals - return (node.name == clazzName ? node - : (n = findNodeWithin(clazzName, node.musts)) - || (n = findNodeWithin(clazzName, node.optionals)) - ? n : null); -}; - -/* private */ -var findNodeWithin = function(name, arr) { - var rnd = clazzTreeRoot.random; - for (var i = arr.length; --i >= 0;) { - var n = arr[i]; - if (n.name == name) - return n; - if (n.random != rnd) { - n.random = rnd; - if ((n = findNodeUnderNode(name, n))) - return n; - } - } - return null; -} - -/* private */ -var checkStatus = function(n, status) { - return (n.status == status - && (status != Node.STATUS_KNOWN || !loadedScripts[n.path]) - && (status == Node.STATUS_DECLARED || !isClassDefined (n.name))); -} - -/* private */ -var findNextMustNode = function(node, status) { - for (var i = node.musts.length; --i >= 0;) { - var n = node.musts[i]; - if (checkStatus(n, status) || (n = findNextMustNode(n, status))) - return n; - } - return (checkStatus(node, status) ? node : null); -}; - -/* private */ -var findNextRequiredNode = function (node, status) { - // search musts first - // search optionals second - // search itself last - var n; - return ((n = searchClassArray(node.musts, status)) - || (n = searchClassArray(node.optionals, status)) - || checkStatus(n = node, status) ? n : null); -}; - -/* private */ -var searchClassArray = function (arr, status) { - if (arr) { - var rnd = clazzTreeRoot.random; - for (var i = 0; i < arr.length; i++) { - var n = arr[i]; - if (checkStatus(n, status)) - return n; - if (n.random != rnd) { - n.random = rnd; // mark as visited! - if ((n = findNextRequiredNode(n, status))) - return n; - } - } - } - return null; -}; - -/** - * This map variable is used to mark that *.js is correctly loaded. - * In IE, _Loader has defects to detect whether a *.js is correctly - * loaded or not, so inner loading mark is used for detecting. - */ -/* private */ -var innerLoadedScripts = {}; - -/** - * This method will be called in almost every *.js generated by Java2Script - * compiler. - */ -/* public */ -var load = function (musts, name, optionals, declaration) { - // called as name.load in Jmol - if (name instanceof Array) { - unwrapArray(name); - for (var i = 0; i < name.length; i++) - load(musts, name[i], optionals, declaration, name); - return; - } - - if (_Loader._checkLoad) { - if (_Loader._classPending[name]) { - //alert("duplicate load for " + name) - } else { - _Loader._classPending[name] = 1; - if (_Loader._classCountPending++ == 0) - _Loader._classCountOK = 0; - System.out.println("Loading class " + name); - } - } - -// if (clazz.charAt (0) == '$') -// clazz = "org.eclipse.s" + clazz.substring (1); - var node = mapPath2ClassNode["#" + name]; - if (!node) { // load called inside *.z.js? - var n = findNode(name); - node = (n ? n : new Node()); - node.name = name; - node.path = classpathMap["#" + name] || "unknown"; - mappingPathNameNode(node.path, name, node); - node.status = Node.STATUS_KNOWN; - addChildClassNode(clazzTreeRoot, node, false); - } - processRequired(node, musts, true); - if (arguments.length == 5 && declaration) { - declaration.status = node.status; - declaration.clazzList = arguments[4]; - } - node.declaration = declaration; - if (declaration) - node.status = Node.STATUS_CONTENT_LOADED; - processRequired(node, optionals, false); -}; - -/* private */ -var processRequired = function(node, arr, isMust) { - if (arr && arr.length) { - unwrapArray(arr); - for (var i = 0; i < arr.length; i++) { - var name = arr[i]; - if (!name) - continue; - if (isClassDefined(name) - || isClassExcluded(name)) - continue; - var n = findNode(name); - if (!n) { - n = new Node(); - n.name = name; - n.status = Node.STATUS_KNOWN; - } - n.requiredBy = node; - addChildClassNode(node, n, isMust); - } - } -} - -/* - * Try to be compatiable of Clazz - */ -if (window["Clazz"]) { - Clazz.load = load; -} else { - _Loader.load = load; -} -/** - * Map different class to the same path! Many classes may be packed into - * a *.z.js already. - * - * @path *.js path - * @name class name - * @node Node object - */ -/* private */ -var mappingPathNameNode = function (path, name, node) { - var map = mapPath2ClassNode; - var keyPath = "@" + path; - var v = map[keyPath]; - if (v) { - if (v instanceof Array) { - var existed = false; - for (var i = 0; i < v.length; i++) { - if (v[i].name == name) { - existed = true; - break; - } - } - if (!existed) - v.push(node); - } else { - map[keyPath] = [v, node]; - } - } else { - map[keyPath] = node; - } - map["#" + name] = node; -}; - -/* protected */ -var loadClassNode = function (node) { - var name = node.name; - if (!isClassDefined (name) - && !isClassExcluded (name)) { - var path = _Loader.getClasspathFor (name/*, true*/); - node.path = path; - mappingPathNameNode (path, name, node); - if (!loadedScripts[path]) { - loadScript(node, path, node.requiredBy, false); - return true; - } - } - return false; -}; - - -/** - * Used in package -/* public */ -var runtimeKeyClass = _Loader.runtimeKeyClass = "java.lang.String"; - -/** - * Queue used to store classes before key class is loaded. - */ -/* private */ -var queueBe4KeyClazz = []; - -/* private */ -var J2sLibBase; - -/** - * Return J2SLib base path from existed SCRIPT src attribute. - */ -/* public */ -_Loader.getJ2SLibBase = function () { - var o = window["j2s.lib"]; - return (o ? o.base + (o.alias == "." ? "" : (o.alias ? o.alias : (o.version ? o.version : "1.0.0")) + "/") : null); -}; - -/** - * Indicate whether _Loader is loading script synchronously or - * asynchronously. - */ -/* private */ -var isAsynchronousLoading = true; - -/* private */ -var isUsingXMLHttpRequest = false; - -/* private */ -var loadingTimeLag = -1; - -_Loader.MODE_SCRIPT = 4; -_Loader.MODE_XHR = 2; -_Loader.MODE_SYNC = 1; - -/** - * String mode: - * asynchronous modes: - * async(...).script, async(...).xhr, async(...).xmlhttprequest, - * script.async(...), xhr.async(...), xmlhttprequest.async(...), - * script - * - * synchronous modes: - * sync(...).xhr, sync(...).xmlhttprequest, - * xhr.sync(...), xmlhttprequest.sync(...), - * xmlhttprequest, xhr - * - * Integer mode: - * Script 4; XHR 2; SYNC bit 1; - */ -/* public */ -_Loader.setLoadingMode = function (mode, timeLag) { - var async = true; - var ajax = true; - if (typeof mode == "string") { - mode = mode.toLowerCase(); - if (mode.indexOf("script") >= 0) - ajax = false; - else - async = (mode.indexOf("async") >=0); - async = false; // BH - } else { - if (mode & _Loader.MODE_SCRIPT) - ajax = false; - else - async = !(mode & _Loader.MODE_SYNC); - } - isUsingXMLHttpRequest = ajax; - isAsynchronousLoading = async; - loadingTimeLag = (async && timeLag >= 0 ? timeLag: -1); - return async; -}; - -/* private */ -var runtimeLoaded = function () { - if (pkgRefCount || !isClassDefined(runtimeKeyClass)) - return; - var qbs = queueBe4KeyClazz; - for (var i = 0; i < qbs.length; i++) - _Loader.loadClass(qbs[i][0], qbs[i][1]); - queueBe4KeyClazz = []; -}; - -/* - * Load those key *.z.js. This *.z.js will be surely loaded before other - * queued *.js. - */ -/* public */ -_Loader.loadZJar = function (zjarPath, keyClass) { -// used only by package.js for core.z.js - var f = null; - var isArr = (keyClass instanceof Array); - if (isArr) - keyClass = keyClass[keyClass.length - 1]; - else - f = (keyClass == runtimeKeyClass ? runtimeLoaded : null); - _Loader.jarClasspath(zjarPath, isArr ? keyClass : [keyClass]); - // BH note: runtimeKeyClass is java.lang.String - _Loader.loadClass(keyClass, f, true); -}; - -var NodeMap = {}; -var _allNodes = []; - -/** - * The method help constructing the multiple-binary class dependency tree. - */ -/* private */ -var addChildClassNode = function (parent, child, isMust) { - var existed = false; - var arr; - if (isMust) { - arr = parent.musts; - if (!child.requiredBy) - child.requiredBy = parent; -// if (!parent.requiresMap){ -// parent.requires = []; -// parent.requiresMap = {}; -// } -// if (!parent.requiresMap[child.name]) { -// parent.requiresMap[child.name] = 1; -// parent.requires.push[child]; -// } - } else { - arr = parent.optionals; - } - if (!NodeMap[child.name]) { - _allNodes.push(child) - NodeMap[child.name]=child - } - for (var i = 0; i < arr.length; i++) { - if (arr[i].name == child.name) { - existed = true; - break; - } - } - if (!existed) { - arr.push(child); - if (isLoadingEntryClass - && child.name.indexOf("java") != 0 - && child.name.indexOf("net.sf.j2s.ajax") != 0) { - if (besidesJavaPackage) - isLoadingEntryClass = false; - besidesJavaPackage = true; -// } else if (child.name.indexOf("org.eclipse.swt") == 0 -// || child.name.indexOf("$wt") == 0) { -// window["swt.lazy.loading.callback"] = swtLazyLoading; -// if (needPackage("org.eclipse.swt")) -// return _Loader.loadPackage("org.eclipse.swt", function() {addParentClassNode(child, parent)}); - } - } - addParentClassNode(child, parent); -}; - -/* private */ -var addParentClassNode = function(child, parent) { - if (parent.name && parent != clazzTreeRoot && parent != child) - for (var i = 0; i < child.parents.length; i++) - if (child.parents[i].name == parent.name) - return; - child.parents.push(parent); -} - -/* private */ -var destroyClassNode = function (node) { - var parents = node.parents; - if (parents) - for (var k = parents.length; --k >= 0;) - removeArrayItem(parents[k].musts, node) || removeArrayItem(parents[k].optionals, node); -}; - -/* public */ -_Loader.unloadClassExt = function (qClazzName) { - if (definedClasses) - definedClasses[qClazzName] = false; - if (classpathMap["#" + qClazzName]) { - var pp = classpathMap["#" + qClazzName]; - classpathMap["#" + qClazzName] = null; - var arr = classpathMap["$" + pp]; - removeArrayItem(arr, qClazzName) && (classpathMap["$" + pp] = arr); - } - var n = findNode(qClazzName); - if (n) { - n.status = Node.STATUS_KNOWN; - loadedScripts[n.path] = false; - } - var path = _Loader.getClasspathFor (qClazzName); - loadedScripts[path] = false; - innerLoadedScripts[path] && (innerLoadedScripts[path] = false); - _Loader.onClassUnloaded(qClazzName); -}; - -/* private */ -var assureInnerClass = function (clzz, fun) { - clzz = clzz.__CLASS_NAME__; - if (Clazz.unloadedClasses[clzz]) { - if (clzz.indexOf("$") >= 0) - return; - var list = []; - var key = clzz + "$"; - for (var s in Clazz.unloadedClasses) - if (Clazz.unloadedClasses[s] && s.indexOf(key) == 0) - list.push(s); - if (!list.length) - return; - fun = "" + fun; - var idx1, idx2; - if ((idx1 = fun.indexOf(key)) < 0 || (idx2 = fun.indexOf("\"", idx1 + key.length)) < 0) - return; - clzz = fun.substring(idx1, idx2); - if (!Clazz.unloadedClasses[clzz] || (idx1 = fun.indexOf("{", idx2) + 1) == 0) - return; - if ((idx2 = fun.indexOf("(" + clzz + ",", idx1 + 3)) < 0 - || (idx2 = fun.lastIndexOf("}", idx2 - 1)) < 0) - return; - eval(fun.substring(idx1, idx2)); - Clazz.unloadedClasses[clzz] = null; - } -}; - -Clazz.binaryFolders = _Loader.binaryFolders = [ _Loader.getJ2SLibBase() ]; - -})(Clazz, Clazz._Loader); - -//} -/****************************************************************************** - * Copyright (c) 2007 java2script.org and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Zhou Renjian - initial API and implementation - *****************************************************************************/ -/******* - * @author zhou renjian - * @create Jan 11, 2007 - *******/ - -Clazz._LoaderProgressMonitor = {}; - -;(function(CLPM, Jmol) { - -var fadeOutTimer = null; -var fadeAlpha = 0; -var monitorEl = null; -var lastScrollTop = 0; -var bindingParent = null; - -CLPM.DEFAULT_OPACITY = (Jmol && Jmol._j2sLoadMonitorOpacity ? Jmol._j2sLoadMonitorOpacity : 55); - -/* public */ -/*CLPM.initialize = function (parent) { - bindingParent = parent; - if (parent && !attached) { - attached = true; - //Clazz.addEvent (window, "unload", cleanup); - // window.attachEvent ("onunload", cleanup); - } -}; -*/ - -/* public */ -CLPM.hideMonitor = function () { - monitorEl.style.display = "none"; -} - -/* public */ -CLPM.showStatus = function (msg, fading) { - if (!monitorEl) { - createHandle (); - if (!attached) { - attached = true; - //Clazz.addEvent (window, "unload", cleanup); - // window.attachEvent ("onunload", cleanup); - } - } - clearChildren(monitorEl); - if (msg == null) { - if (fading) { - fadeOut(); - } else { - CLPM.hideMonitor(); - } - return; - } - - monitorEl.appendChild(document.createTextNode ("" + msg)); - if (monitorEl.style.display == "none") { - monitorEl.style.display = ""; - } - setAlpha(CLPM.DEFAULT_OPACITY); - var offTop = getFixedOffsetTop(); - if (lastScrollTop != offTop) { - lastScrollTop = offTop; - monitorEl.style.bottom = (lastScrollTop + 4) + "px"; - } - if (fading) { - fadeOut(); - } -}; - -/* private static */ -var clearChildren = function (el) { - if (!el) - return; - for (var i = el.childNodes.length; --i >= 0;) { - var child = el.childNodes[i]; - if (!child) - continue; - if (child.childNodes && child.childNodes.length) - clearChildren (child); - try { - el.removeChild (child); - } catch (e) {}; - } -}; -/* private */ -var setAlpha = function (alpha) { - if (fadeOutTimer && alpha == CLPM.DEFAULT_OPACITY) { - window.clearTimeout (fadeOutTimer); - fadeOutTimer = null; - } - fadeAlpha = alpha; - var ua = navigator.userAgent.toLowerCase(); - monitorEl.style.filter = "Alpha(Opacity=" + alpha + ")"; - monitorEl.style.opacity = alpha / 100.0; -}; -/* private */ -var hidingOnMouseOver = function () { - CLPM.hideMonitor(); -}; - -/* private */ -var attached = false; -/* private */ -var cleanup = function () { - //if (monitorEl) { - // monitorEl.onmouseover = null; - //} - monitorEl = null; - bindingParent = null; - //Clazz.removeEvent (window, "unload", cleanup); - //window.detachEvent ("onunload", cleanup); - attached = false; -}; -/* private */ -var createHandle = function () { - var div = document.createElement ("DIV"); - div.id = "_Loader-status"; - div.style.cssText = "position:absolute;bottom:4px;left:4px;padding:2px 8px;" - + "z-index:" + (window["j2s.lib"].monitorZIndex || 10000) + ";background-color:#8e0000;color:yellow;" - + "font-family:Arial, sans-serif;font-size:10pt;white-space:nowrap;"; - div.onmouseover = hidingOnMouseOver; - monitorEl = div; - if (bindingParent) { - bindingParent.appendChild(div); - } else { - document.body.appendChild(div); - } - return div; -}; -/* private */ - -var fadeOut = function () { - if (monitorEl.style.display == "none") return; - if (fadeAlpha == CLPM.DEFAULT_OPACITY) { - fadeOutTimer = window.setTimeout(function () { - fadeOut(); - }, 750); - fadeAlpha -= 5; - } else if (fadeAlpha - 10 >= 0) { - setAlpha(fadeAlpha - 10); - fadeOutTimer = window.setTimeout(function () { - fadeOut(); - }, 40); - } else { - monitorEl.style.display = "none"; - } -}; -/* private */ -var getFixedOffsetTop = function (){ - if (bindingParent) { - var b = bindingParent; - return b.scrollTop; - } - var dua = navigator.userAgent; - var b = document.body; - var p = b.parentNode; - var pcHeight = p.clientHeight; - var bcScrollTop = b.scrollTop + b.offsetTop; - var pcScrollTop = p.scrollTop + p.offsetTop; - return (dua.indexOf("Opera") < 0 && document.all ? (pcHeight == 0 ? bcScrollTop : pcScrollTop) - : dua.indexOf("Gecko") < 0 ? (pcHeight == p.offsetHeight - && pcHeight == p.scrollHeight ? bcScrollTop : pcScrollTop) : bcScrollTop); -}; - -/* not used in Jmol -if (window["ClazzLoader"]) { - _Loader.onScriptLoading = function(file) { - CLPM.showStatus("Loading " + file + "..."); - }; - _Loader.onScriptLoaded = function(file, isError) { - CLPM.showStatus(file + (isError ? " loading failed." : " loaded."), true); - }; - _Loader.onGlobalLoaded = function(file) { - CLPM.showStatus("Application loaded.", true); - }; - _Loader.onClassUnloaded = function(clazz) { - CLPM.showStatus("Class " + clazz + " is unloaded.", true); - }; -} -*/ - -})(Clazz._LoaderProgressMonitor, Jmol); - -//} -/****************************************************************************** - * Copyright (c) 2007 java2script.org and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Zhou Renjian - initial API and implementation - *****************************************************************************/ -/******* - * @author zhou renjian - * @create Nov 5, 2005 - *******/ - -;(function(Con, Sys) { -/** - * Setting maxTotalLines to -1 will not limit the console result - */ -/* protected */ -Con.maxTotalLines = 10000; - -/* protected */ -Con.setMaxTotalLines = function (lines) { - Con.maxTotalLines = (lines > 0 ? lines : 999999); -} - -/* protected */ -Con.maxLatency = 40; - -/* protected */ -Con.setMaxLatency = function (latency) { - Con.maxLatency = (latency > 0 ? latency : 40); -}; - -/* protected */ -Con.pinning = false; - -/* protected */ -Con.enablePinning = function (enabled) { - Con.pinning = enabled; -}; - -/* private */ -Con.linesCount = 0; - -/* private */ -Con.metLineBreak = false; - - -/* - * Give an extension point so external script can create and bind the console - * themself. - * - * TODO: provide more template of binding console window to browser. - */ -/* protected */ -Con.createConsoleWindow = function (parentEl) { - var console = document.createElement ("DIV"); - console.style.cssText = "font-family:monospace, Arial, sans-serif;"; - document.body.appendChild (console); - return console; -}; - -var c160 = String.fromCharCode(160); //nbsp; -c160 += c160+c160+c160; - -/* protected */ -Con.consoleOutput = function (s, color) { - var o = window["j2s.lib"]; - var console = (o && o.console); - if (console && typeof console == "string") - console = document.getElementById(console) - if (!console) - return false; // BH this just means we have turned off all console action - if (Con.linesCount > Con.maxTotalLines) { - for (var i = 0; i < Con.linesCount - Con.maxTotalLines; i++) { - if (console && console.childNodes.length > 0) { - console.removeChild (console.childNodes[0]); - } - } - Con.linesCount = Con.maxTotalLines; - } - - var willMeetLineBreak = false; - s = (typeof s == "undefined" ? "" : s == null ? "null" : "" + s); - s = s.replace (/\t/g, c160); - if (s.length > 0) - switch (s.charAt(s.length - 1)) { - case '\n': - case '\r': - s = (s.length > 1 ? s.substring (0, s.length - (s.charAt (s.length - 2) == '\r' ? 2 : 1)) : ""); - willMeetLineBreak = true; - break; - } - - var lines = null; - s = s.replace (/\t/g, c160); - lines = s.split(/\r\n|\r|\n/g); - for (var i = 0, last = lines.length - 1; i <= last; i++) { - var lastLineEl = null; - if (Con.metLineBreak || Con.linesCount == 0 - || console.childNodes.length < 1) { - lastLineEl = document.createElement ("DIV"); - console.appendChild (lastLineEl); - lastLineEl.style.whiteSpace = "nowrap"; - Con.linesCount++; - } else { - try { - lastLineEl = console.childNodes[console.childNodes.length - 1]; - } catch (e) { - lastLineEl = document.createElement ("DIV"); - console.appendChild (lastLineEl); - lastLineEl.style.whiteSpace = "nowrap"; - Con.linesCount++; - } - } - var el = document.createElement ("SPAN"); - lastLineEl.appendChild (el); - el.style.whiteSpace = "nowrap"; - if (color) - el.style.color = color; - var l = lines[i] - if (l.length == 0) - l = c160; - el.appendChild(document.createTextNode(l)); - if (!Con.pinning) - console.scrollTop += 100; - Con.metLineBreak = (i != last || willMeetLineBreak); - } - - var cssClazzName = console.parentNode.className; - if (!Con.pinning && cssClazzName - && cssClazzName.indexOf ("composite") != -1) { - console.parentNode.scrollTop = console.parentNode.scrollHeight; - } - Con.lastOutputTime = new Date ().getTime (); -}; - -/* - * Clear all contents inside the console. - */ -/* public */ -Con.clear = function () { - try { - Con.metLineBreak = true; - var o = window["j2s.lib"]; - var console = o && o.console; - if (!console || !(console = document.getElementById (console))) - return; - var childNodes = console.childNodes; - for (var i = childNodes.length; --i >= 0;) - console.removeChild (childNodes[i]); - Con.linesCount = 0; - } catch(e){}; -}; - -/* public */ -Clazz.alert = function (s) { - Con.consoleOutput (s + "\r\n"); -}; - - -/* public */ -Sys.out.print = function (s) { - Con.consoleOutput (s); -}; -/* public */ -Sys.out.println = function(s) { - Con.consoleOutput(typeof s == "undefined" ? "\r\n" : s == null ? s = "null\r\n" : s + "\r\n"); -}; - -Sys.out.write = function (buf, offset, len) { - Sys.out.print(String.instantialize(buf).substring(offset, offset+len)); -}; - -/* public */ -Sys.err.__CLASS_NAME__ = "java.io.PrintStream"; - -/* public */ -Sys.err.print = function (s) { - Con.consoleOutput (s, "red"); -}; - -/* public */ -Sys.err.println = function (s) { - Con.consoleOutput (typeof s == "undefined" ? "\r\n" : s == null ? s = "null\r\n" : s + "\r\n", "red"); -}; - -Sys.err.write = function (buf, offset, len) { - Sys.err.print(String.instantialize(buf).substring(offset, offset+len)); -}; - -})(Clazz.Console, System); - -})(Clazz, Jmol); // requires JSmolCore.js - -}; // called by external application +// j2sjmol.js + +// latest author: Bob Hanson, St. Olaf College, hansonr@stolaf.edu + +// Requires JSmolCore.js and (for now; probably) JSmol.js +// This version of j2slib requires jQuery and works in both Chrome and MSIE locally, +// though Chrome cannot read local data files, and MSIE cannot read local binary data files. + +// Java programming notes by Bob Hanson: +// +// There are a few motifs to avoid when optimizing Java code to work smoothly +// with the J2S compiler: +// +// arrays: +// +// 1. an array with null elements cannot be typed and must be avoided. +// 2. instances of Java "instance of" involving arrays must be found and convered to calls to Clazz.isA... +// 3. new int[n][] must not be used. Use instead JU.AU.newInt2(n); +// 4. new int[] { 1, 2, 3 } has problems because it creates simply [ ] and not IntArray32 +// +// numbers: +// +// 1. Remember that EVERY number in JavaScript is a double -- doesn't matter if it is in IntArray32 or not. +// 2. You cannot reliably use Java long, because doubles consume bits for the exponent which cannot be tested. +// 3. Bit 31 of an integer is unreliable, since (int) -1 is now , not just 0zFFFFFFFF, and +// FFFFFFFF + 1 = 100000000, not 0. In JavaScript, 0xFFFFFFFF is 4294967295, not -1. +// This means that writeInt(b) will fail if b is negative. What you need is instead +// writeInt((int)(b & 0xFFFFFFFFl) so that JavaScript knocks off the high bits explicitly. +// +// general: +// +// 1. j2sRequireImport xxxx is needed if xxxx is a method used in a static function +// 2. URL.getContent() is not supported. Use other means based on URL.toString() +// 3. It is critical for performance to avoid any significant amount of function overloading. +// In particular, methods such as xxx(int a, int b) and xxx(float a, int b) MUST be renamed, +// because JavaScript only has Number, and there is absolutely no way to tell these apart. +// It's probably bad Java programming, anyway. +// 4. Calls to super(...) can almost always be avoided. These trigger the SAEM +// (searchAndExecuteMethod) call, and it is very destructive to performance. +// Just find another way to do it. + + // NOTES by Bob Hanson: + + // J2S class changes: + + // BH 7/24/2015 6:48:50 AM adding optional ?j2sdebug flag on page URL + // -- switches to using j2s/core/corexxx.js, not j2s/core/corexxx.z.js + // -- adds ";//# sourceURL="+file in eval(js) + // -- enables DebugJS.$(msg) call to debugger; + // see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger + // see https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Debug_eval_sources + // BH 7/23/2015 6:45:55 PM added sourceURL in each js class eval(), allowing full + // breakpoint debugging and code checking in Firefox and Chrome + // BH 7/19/2015 6:18:17 PM added os.name, line.separator, etc. to System.getProperty() + // BH 7/19/2015 5:39:10 PM added java.lang.System = System + // BH 7/19/2015 10:33:10 AM fix for SAEM equating "null" with number or boolean + // BH 7/18/2015 6:08:05 PM for Jmol I was able to remove the $private/$fx business, but now + // I see that in general that cannot be done. Thinking about a strategy... + // BH 7/18/2015 4:43:38 PM better handling of TypeError and InternalError for e.getMessage() and e.getStackTrace() + // BH 7/17/2015 11:51:15 AM adds class.getResource(name) and class.getResourceAsStream(name) + // BH 7/16/2015 7:56:49 PM general instantiation using any constructor (in Java here): + // BH x = class.forName("my.class.name").newInstance() + // BH or + // BH x = class.forName("my.class.name").getConstructor(String.class,String.class).newInstance(new Object[] {"test", "now"}) + // BH 7/15/2015 11:34:58 PM adding System.lineSeparator() + // BH 7/15/2015 7:32:41 AM adding class.getCanonicalName == getName + // BH 5/31/2015 5:38:14 PM NPEExceptionPredicate fix + // BH 4/25/2015 9:16:12 AM SAEM misrepresnting Number as Object in parameters and Integer as Number + // BH 4/24/2015 7:32:54 AM Object.hashCode() and System.getIdentityHashCode() fail. changed to: return this._$hashcode || (this._$hashcode = ++Clazz._hashCode) + // BH 4/23/2015 9:08:59 AM Clazz.instanceOf(a, b) needs to check for a == b. + // BH 4/23/2015 9:08:59 AM xx.getContentType() is nonfunctional. Array.newInstance now defines a wrapper for .getClass().getComponentType() that works + // BH 4/12/2015 11:48:03 AM added Clazz.getStackTrace(-n) -- reports actual parameter values for n levels + // BH 4/10/2015 8:23:05 AM adding Int32Array.prototype.clone and Float64.prototype.clone + // BH 4/5/2015 8:12:57 AM refactoring j2slib (this file) to make private functions really private using var + // BH 4/3/2015 6:14:34 AM adding anonymous local "ClazzLoader" (Clazz._Loader) --> "_Loader" + // BH 4/3/2015 6:14:34 AM adding Clazz._Loader._classPending, Clazz._Loader._classCount + // BH 4/3/2015 6:14:34 AM adding Clazz._Loader._checkLoad + // -- forces asynchronous class loading + // -- builds Clazz._Loader._classPending and Clazz._classCount + // -- allows reporting + + // BH 3/24/2015 4:11:26 AM better file load failure message in _Loader.evaluate + // BH 2/28/2015 7:30:25 AM corrects newIntArray32() and newArray() for pre-defined arrays + // int[] a = new int[] {1,2,3,343}; + // int[][] b = new int[][] {new int[]{4,5},new int[]{5,6}}; + + // BH 9/29/2014 11:34:19 PM removing support for getClass().isArray() + // BH 8/29/2014 9:15:57 AM total reworking of Java2Script in preparation for all-asynchronous loading + // (currently sync loading is only for + // LOAD command and load() function without ASYNC + // getInterface() + // see JSmol.js and Jmol._isAsync flag + // BH 5/11/2015 5:58:42 AM adding __signatures for debugging SAEM issues + // BH 3/29/2015 8:12:44 PM System.getProperty(x, "") does not return "" + // BH 8/23/2014 10:04:19 AM cleaning up a few general methods; Clazz.removeArrayItem + // BH 6/1/2014 10:58:46 AM fix for Clazz.isAP() not working + // BH 5/26/2014 5:19:29 PM removing superConstructor call in creating Enum constants + // BH 4/1/2014 7:55:54 PM removing all $fz references and instances where sub/super classes have same private function names + // BH 4/1/2014 4:47:30 PM all $_X removed; this is taken care of by Google Closure Compiler + // BH 4/1/2014 6:40:08 AM removing ClassLoader -- equals Clazz._Loader + // BH 4/1/2014 6:40:08 AM removing ClassLoaderProgressMonitor -- equals _LoaderProgressMonitor + // BH 4/1/2014 6:17:21 AM removing Class -- only used for "Class.forName" in Jmol, which ANT will now change to "Clazz._4Name" + // BH 3/7/2014 9:05:06 AM Array.prototype.toString should not be aliased. -- http://sourceforge.net/p/jmol/bugs/560/ with Google Visualization + + // BH 1/30/2014 12:54:22 PM gave all field variables prefix underscore. This allows Google Closure Compiler to skip them. + // BH 12/3/2013 3:39:57 PM window["j2s.lib"].base implemented + // BH 12/1/2013 5:34:21 AM removed _LoaderProgressMonitor.initialize and all Clazz.event business; handled by Jmol.clearVars() + // BH 11/30/2013 12:43:58 PM adding Clazz.arrayIs() -- avoids Number.constructor.toString() infinite recursion + // BH 11/29/2013 6:33:51 AM adding Clazz._profiler -- reports use of SAEM + // BH 11/10/2013 9:02:20 AM fixing fading in MSIE + // BH 11/3/2013 7:21:39 AM additional wrapping functions for better compressibility + // BH 10/30/2013 8:10:58 AM added getClass().getResource() -- returning a relative string, not a URL + // BH 10/30/2013 6:43:00 AM removed second System def and added System.$props and default System.property "line.separator" + // BH 6/15/2013 8:02:07 AM corrections to Class.isAS to return true if first element is null + // BH 6/14/2013 4:41:09 PM corrections to Clazz.isAI and related methods to include check for null object + // BH 3/17/2013 11:54:28 AM adds stackTrace for ERROR + + // BH 3/13/2013 6:58:26 PM adds Clazz.clone(me) for BS clone + // BH 3/12/2013 6:30:53 AM fixes Clazz.exceptionOf for ERROR condition trapping + // BH 3/2/2013 9:09:53 AM delete globals c$ and $fz + // BH 3/2/2013 9:10:45 AM optimizing defineMethod using "look no further" "@" parameter designation (see "\\@" below -- removed 3/23/13) + // BH 2/27/2013 optimizing Clazz.getParamsType for common cases () and (Number) + // BH 2/27/2013 optimizing SAEM delegation for hashCode and equals -- disallows overloading of equals(Object) + + // BH 2/23/2013 found String.replaceAll does not work -- solution was to never call it. + // BH 2/9/2013 9:18:03 PM Int32Array/Float64Array fixed for MSIE9 + // BH 1/25/2013 1:55:31 AM moved package.js from j2s/java to j2s/core + // BH 1/17/2013 4:37:17 PM String.compareTo() added + // BH 1/17/2013 4:52:22 PM Int32Array and Float64Array may not have .prototype.sort method + // BH 1/16/2013 6:20:34 PM Float64Array not available in Safari 5.1 + // BH 1/14/2013 11:28:58 PM Going to all doubles in JavaScript (Float64Array, not Float32Array) + // so that (new float[] {13.48f})[0] == 13.48f, effectively + + // BH 1/14/2013 12:53:41 AM Fix for Opera 10 not loading any files + // BH 1/13/2013 11:50:11 PM Fix for MSIE not loading (nonbinary) files locally + + // BH 12/1/2012 9:52:26 AM Compiler note: Thread.start() cannot be executed within the constructor; + + // BH 11/24/2012 11:08:39 AM removed unneeded sections + // BH 11/24/2012 10:23:22 AM all XHR uses sync loading (_Loader.setLoadingMode) + // BH 11/21/2012 7:30:06 PM if (base) map["@" + pkg] = base; critical for multiple applets + + // BH 10/8/2012 3:27:41 PM if (clazzName.indexOf("Array") >= 0) return "Array"; in Clazz.getClassName for function + // BH removed Clazz.ie$plit = "\\2".split (/\\/).length == 1; unnecessary; using RegEx slows process significantly in all browsers + // BH 10/6/12 added Int32Array, Float32Array, newArrayBH, upgraded java.lang and java.io + // BH added Integer.bitCount in core.z.js + // BH changed alert to Clazz.alert in java.lang.Class.js *.ClassLoader.js, java.lang.thread.js + // BH removed toString from innerFunctionNames due to infinite recursion + // BH note: Logger.error(null, e) does not work -- get no constructor for (String) (TypeError) + // BH added j2s.lib.console + // BH allowed for alias="." + // BH removed alert def --> Clazz.alert + // BH added wrapper at line 2856 + // BH newArray fix at line 2205 + // BH System.getProperty fix at line 6693 + // BH added Enum .value() method at line 2183 + // BH added System.getSecurityManager() at end + // BH added String.contains() at end + // BH added System.gc() at end + // BH added Clazz.exceptionOf = updated + // BH added String.getBytes() at end + + +LoadClazz = function() { + +// BH This is the ONLY global used in J2S now. I do not think it is necessary, +// but it is created by the compiler, and I have not found a work-around. +// it is used as a local variable in class definitions to point to the +// current method. See Clazz.p0p and Clazz.pu$h + +c$ = null; + +if (!window["j2s.clazzloaded"]) + window["j2s.clazzloaded"] = false; + +if (window["j2s.clazzloaded"])return; + +window["j2s.clazzloaded"] = true; + +window["j2s.object.native"] = true; + + // Clazz changes: + + /* http://j2s.sf.net/ *//****************************************************************************** + * Copyright (c) 2007 java2script.org and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Zhou Renjian - initial API and implementation + *****************************************************************************/ +/******* + * @author zhou renjian + * @create Nov 5, 2005 + *******/ + + +/** + * Class Clazz. All the methods are static in this class. + */ +/* static */ +/*Class = */ Clazz = { + _isQuiet: false, + _debugging: false +}; + +;(function(Clazz, Jmol) { + + +try { +Clazz._debugging = (document.location.href.indexOf("j2sdebug") >= 0); +} catch (e) { +} +var __debuggingBH = false; +var _globals = ["j2s.clazzloaded", "j2s.object.native"]; +Clazz.setGlobal = function(a, v) { + _globals.push(a); + window[a] = v; +} + +Clazz.getGlobals = function() { + return _globals.sort().join("\n"); +} + +Clazz.setConsoleDiv = function(d) { + window["j2s.lib"] && (window["j2s.lib"].console = d); +}; + +// BH Clazz.getProfile monitors exactly what is being delegated with SAEM, +// which could be a bottle-neck for function calling. +// This is critical for performance optimization. + +// Jmol.getProfile() + +var _profile = (window["j2s.doProfile"] && self.JSON ? {} : null); + +NullObject = function () {}; + +/* protected */ +Clazz._supportsNativeObject = window["j2s.object.native"]; + +if (Clazz._supportsNativeObject) { + Clazz._O = function () {}; + Clazz._O.__CLASS_NAME__ = "Object"; + Clazz._O["getClass"] = function () { return Clazz._O; }; +} else { + Clazz._O = Object; +} + +Clazz.Console = {}; +Clazz.dateToString = Date.prototype.toString; +Clazz._hashCode = 0; + +var addProto = function(proto, name, func) { + return proto[name] = func; +}; + +;(function(proto) { + addProto(proto, "equals", function (obj) { + return this == obj; + }); + + addProto(proto, "hashCode", function () { + + return this._$hashcode || (this._$hashcode = ++Clazz._hashCode) + + + try { + return this.toString ().hashCode (); + } catch (e) { + var str = ":"; + for (var s in this) { + str += s + ":" + } + return str.hashCode (); + } + }); + + addProto(proto, "getClass", function () { return Clazz.getClass (this); }); + + addProto(proto, "clone", function () { return Clazz.clone(this); }); + + Clazz.clone = function(me) { + // BH allows @j2sNative access without super constructor + var o = new me.constructor(); + for (var i in me) { + o[i] = me[i]; + } + return o; + } +/* + * Methods for thread in Object + */ + addProto(proto, "finalize", function () {}); + addProto(proto, "notify", function () {}); + addProto(proto, "notifyAll", function () {}); + addProto(proto, "wait", function () {}); + addProto(proto, "to$tring", Object.prototype.toString); + addProto(proto, "toString", function () { return (this.__CLASS_NAME__ ? "[" + this.__CLASS_NAME__ + " object]" : this.to$tring.apply(this, arguments)); }); + Clazz._extendedObjectMethods = [ "equals", "hashCode", "getClass", "clone", "finalize", "notify", "notifyAll", "wait", "to$tring", "toString" ]; + +})(Clazz._O.prototype); + +Clazz.extendJO = function(c, name) { + if (name) + c.__CLASS_NAME__ = c.prototype.__CLASS_NAME__ = name; + if (Clazz._supportsNativeObject) { + for (var i = 0; i < Clazz._extendedObjectMethods.length; i++) { + var p = Clazz._extendedObjectMethods[i]; + addProto(c.prototype, p, Clazz._O.prototype[p]); + } + } +}; + +/** + * Try to fix bug on Safari + */ +//InternalFunction = Object; + +Clazz.extractClassName = function(clazzStr) { + // [object Int32Array] + var clazzName = clazzStr.substring (1, clazzStr.length - 1); + return (clazzName.indexOf("Array") >= 0 ? "Array" // BH -- for Float64Array and Int32Array + : clazzName.indexOf ("object ") >= 0 ? clazzName.substring (7) // IE + : clazzName); +} +/** + * Return the class name of the given class or object. + * + * @param clazzHost given class or object + * @return class name + */ +/* public */ +Clazz.getClassName = function (obj) { + if (obj == null) + return "NullObject"; + if (obj instanceof Clazz.CastedNull) + return obj.clazzName; + switch(typeof obj) { + case "number": + return "n"; + case "boolean": + return "b"; + case "string": + // Always treat the constant string as String object. + // This will be compatiable with Java String instance. + return "String"; + case "function": + if (obj.__CLASS_NAME__) + return (arguments[1] ? obj.__CLASS_NAME__ : "Class"); /* user defined class name */ + var s = obj.toString(); + var idx0 = s.indexOf("function"); + if (idx0 < 0) + return (s.charAt(0) == '[' ? Clazz.extractClassName(s) : s.replace(/[^a-zA-Z0-9]/g, '')); + var idx1 = idx0 + 8; + var idx2 = s.indexOf ("(", idx1); + if (idx2 < 0) + return "Object"; + s = s.substring (idx1, idx2); + if (s.indexOf("Array") >= 0) + return "Array"; + s = s.replace (/^\s+/, "").replace (/\s+$/, ""); + return (s == "anonymous" || s == "" ? "Function" : s); + case "object": + if (obj.__CLASS_NAME__) // user defined class name + return obj.__CLASS_NAME__; + if (!obj.constructor) + return "Object"; // For HTML Element in IE + if (!obj.constructor.__CLASS_NAME__) { + if (obj instanceof Number) + return "Number"; + if (obj instanceof Boolean) + return "Boolean"; + if (obj instanceof Array) + return "Array"; + var s = obj.toString(); + // "[object Int32Array]" + if (s.charAt(0) == '[') + return Clazz.extractClassName(s); + } + return Clazz.getClassName (obj.constructor, true); + } + // some new, unidentified class + return "Object"; +}; +/** + * Return the class of the given class or object. + * + * @param clazzHost given class or object + * @return class name + */ +/* public */ +Clazz.getClass = function (clazzHost) { + if (!clazzHost) + return Clazz._O; // null/undefined is always treated as Object + if (typeof clazzHost == "function") + return clazzHost; + var clazzName; + if (clazzHost instanceof Clazz.CastedNull) { + clazzName = clazzHost.clazzName; + } else { + switch (typeof clazzHost) { + case "string": + return String; + case "object": + if (!clazzHost.__CLASS_NAME__) + return (clazzHost.constructor || Clazz._O); + clazzName = clazzHost.__CLASS_NAME__; + break; + default: + return clazzHost.constructor; + } + } + return Clazz.evalType(clazzName, true); +}; + + +/* private */ +var checkInnerFunction = function (hostSuper, funName) { + for (var k = 0; k < Clazz.innerFunctionNames.length; k++) + if (funName == Clazz.innerFunctionNames[k] && + Clazz._innerFunctions[funName] === hostSuper[funName]) + return true; + return false; +}; + +var args4InheritClass = function () {}; + +Clazz.inheritArgs = new args4InheritClass (); + +/** + * Inherit class with "extends" keyword and also copy those static members. + * Example, as in Java, if NAME is a static member of ClassA, and ClassB + * extends ClassA then ClassB.NAME can be accessed in some ways. + * + * @param clazzThis child class to be extended + * @param clazzSuper super class which is inherited from + * @param objSuper super class instance + */ +/* protected */ +Clazz.inheritClass = function (clazzThis, clazzSuper, objSuper) { + //var thisClassName = Clazz.getClassName (clazzThis); + for (var o in clazzSuper) { + if (o != "b$" && o != "prototype" && o != "superClazz" + && o != "__CLASS_NAME__" && o != "implementz" + && !checkInnerFunction (clazzSuper, o)) { + clazzThis[o] = clazzSuper[o]; + } + } + if (Clazz.unloadedClasses[Clazz.getClassName(clazzThis, true)]) { + // Don't change clazzThis.protoype! Keep it! + } else if (objSuper) { + // ! Unsafe reference prototype to an instance! + // Feb 19, 2006 --josson + // OK for this reference to an instance, as this is anonymous instance, + // which is not referenced elsewhere. + // March 13, 2006 + clazzThis.prototype = objSuper; + } else if (clazzSuper !== Number) { + clazzThis.prototype = new clazzSuper (Clazz.inheritArgs); + } else { // Number + clazzThis.prototype = new Number (); + } + clazzThis.superClazz = clazzSuper; + /* + * Is it necessary to reassign the class name? + * Mar 10, 2006 --josson + */ + //clazzThis.__CLASS_NAME__ = thisClassName; + clazzThis.prototype.__CLASS_NAME__ = clazzThis.__CLASS_NAME__; +}; + +/** + * Implementation of Java's keyword "implements". + * As in JavaScript there are on "implements" keyword implemented, a property + * of "implementz" is added to the class to record the interfaces the class + * is implemented. + * + * @param clazzThis the class to implement + * @param interfacez Array of interfaces + */ +/* public */ +Clazz.implementOf = function (clazzThis, interfacez) { + if (arguments.length >= 2) { + if (!clazzThis.implementz) + clazzThis.implementz = []; + var impls = clazzThis.implementz; + if (arguments.length == 2) { + if (typeof interfacez == "function") { + impls.push(interfacez); + copyProperties(clazzThis, interfacez); + } else if (interfacez instanceof Array) { + for (var i = 0; i < interfacez.length; i++) { + impls.push(interfacez[i]); + copyProperties(clazzThis, interfacez[i]); + } + } + } else { + for (var i = 1; i < arguments.length; i++) { + impls.push(arguments[i]); + copyProperties(clazzThis, arguments[i]); + } + } + } +}; + +/* + * Copy members of interface + */ +/* private */ +var copyProperties = function(clazzThis, clazzSuper) { + for (var o in clazzSuper) + if (o != "b$" + && o != "prototype" && o != "superClazz" + && o != "__CLASS_NAME__" && o != "implementz" + && (typeof clazzSuper[o] != "function" || !checkInnerFunction(clazzSuper, o))) + clazzThis[o] = clazzThis.prototype[o] = clazzSuper[o]; +}; + +/** + * TODO: More should be done for interface's inheritance + */ +/* public */ +Clazz.extendInterface = Clazz.implementOf; + +/* protected */ +Clazz.equalsOrExtendsLevel = function (clazzThis, clazzAncestor) { + if (clazzThis === clazzAncestor) + return 0; + if (clazzThis.implementz) { + var impls = clazzThis.implementz; + for (var i = 0; i < impls.length; i++) { + var level = Clazz.equalsOrExtendsLevel (impls[i], clazzAncestor); + if (level >= 0) + return level + 1; + } + } + return -1; +}; + +/* protected */ +Clazz.getInheritedLevel = function (clazzTarget, clazzBase) { + if (clazzTarget === clazzBase) + return 0; + var isTgtStr = (typeof clazzTarget == "string"); + if (isTgtStr && ("void" == clazzTarget || "unknown" == clazzTarget)) + return -1; + var isBaseStr = (typeof clazzBase == "string"); + if (isBaseStr && ("void" == clazzBase || "unknown" == clazzBase)) + return -1; + if (clazzTarget === (isTgtStr ? "NullObject" : NullObject)) { + switch (clazzBase) { + case "n": + case "b": + return -1; + case Number: + case Boolean: + case NullObject: + break; + default: + return 0; + } + } + if (isTgtStr) + clazzTarget = Clazz.evalType(clazzTarget); + if (isBaseStr) + clazzBase = Clazz.evalType(clazzBase); + if (!clazzBase || !clazzTarget) + return -1; + var level = 0; + var zzalc = clazzTarget; // zzalc <--> clazz + while (zzalc !== clazzBase && level < 10) { + /* maybe clazzBase is interface */ + if (zzalc.implementz) { + var impls = zzalc.implementz; + for (var i = 0; i < impls.length; i++) { + var implsLevel = Clazz.equalsOrExtendsLevel (impls[i], clazzBase); + if (implsLevel >= 0) + return level + implsLevel + 1; + } + } + zzalc = zzalc.superClazz; + if (!zzalc) + return (clazzBase === Object || clazzBase === Clazz._O ? + // getInheritedLevel(String, CharSequence) == 1 + // getInheritedLevel(String, Object) == 1.5 + // So if both #test(CharSequence) and #test(Object) existed, + // #test("hello") will correctly call #test(CharSequence) + // instead of #test(Object). + level + 1.5 // 1.5! Special! + : -1); + level++; + } + return level; +}; + + +/** + * Implements Java's keyword "instanceof" in JavaScript's way. + * As in JavaScript part of the object inheritance is implemented in only- + * JavaScript way. + * + * @param obj the object to be tested + * @param clazz the class to be checked + * @return whether the object is an instance of the class + */ +/* public */ +Clazz.instanceOf = function (obj, clazz) { + // allows obj to be a class already, from arrayX.getClass().isInstance(y) + return (obj != null && clazz && (obj == clazz || obj instanceof clazz || Clazz.getInheritedLevel(Clazz.getClassName(obj), clazz) >= 0)); +}; + +/** + * Call super method of the class. + * The same effect as Java's expression: + * super.* () + * + * @param objThis host object + * @param clazzThis class of declaring method scope. It's hard to determine + * which super class is right class for "super.*()" call when it's in runtime + * environment. For example, + * 1. ClasssA has method #run() + * 2. ClassB extends ClassA overriding method #run() with "super.run()" call + * 3. ClassC extends ClassB + * 4. objC is an instance of ClassC + * Now we have to decide which super #run() method is to be invoked. Without + * explicit clazzThis parameter, we only know that objC.getClass() is ClassC + * and current method scope is #run(). We do not known we are in scope + * ClassA#run() or scope of ClassB#run(). if ClassB is given, Clazz can search + * all super methods that are before ClassB and get the correct super method. + * This is the reason why there must be an extra clazzThis parameter. + * @param funName method name to be called + * @param funParams Array of method parameters + */ +/* public */ +Clazz.superCall = function (objThis, clazzThis, funName, funParams) { + var fx = null; + var i = -1; + var clazzFun = objThis[funName]; + if (clazzFun) { + if (clazzFun.claxxOwner) { + // claxxOwner is a mark for methods that is single. + if (clazzFun.claxxOwner !== clazzThis) { + // This is a single method, call directly! + fx = clazzFun; + + } + } else if (!clazzFun.stacks && !(clazzFun.lastClaxxRef + && clazzFun.lastClaxxRef.prototype[funName] + && clazzFun.lastClaxxRef.prototype[funName].stacks)) { // super.toString + fx = clazzFun; + } else { // normal wrapped method + var stacks = clazzFun.stacks; + if (!stacks) + stacks = clazzFun.lastClaxxRef.prototype[funName].stacks; + for (i = stacks.length; --i >= 0;) { + /* + * Once super call is computed precisely, there are no need + * to calculate the inherited level but just an equals + * comparision + */ + //var level = Clazz.getInheritedLevel (clazzThis, stacks[i]); + if (clazzThis === stacks[i]) { // level == 0 + if (i > 0) { + fx = stacks[--i].prototype[funName]; + } else { + /* + * Will this case be reachable? + * March 4, 2006 + * Should never reach here if all things are converted + * by Java2Script + */ + fx = stacks[0].prototype[funName]["\\unknown"]; + } + break; + } else if (Clazz.getInheritedLevel (clazzThis, stacks[i]) > 0) { + fx = stacks[i].prototype[funName]; + break; + } + } // end of for loop + } // end of normal wrapped method + } // end of clazzFun + if (!fx) { + if (funName != "construct") { + Clazz.alert (["j2slib","no class found",(funParams).typeString]) + newMethodNotFoundException(objThis, clazzThis, funName, + Clazz.getParamsType(funParams).typeString); + } + /* there are members which are initialized out of the constructor */ + /* No super constructor! */ + return; + } + /* there are members which are initialized out of the constructor */ + if (i == 0 && funName == "construct") { + var ss = clazzFun.stacks; + if (ss && !ss[0].superClazz && ss[0].con$truct) + ss[0].con$truct.apply (objThis, []); + } + /*# {$no.debug.support} >>x #*/ + /* not used in Jmol + if (Clazz.tracingCalling) { + var caller = arguments.callee.caller; + if (caller === Clazz.superConstructor) { + caller = caller.arguments.callee.caller; + } + Clazz._callingStackTraces.push(new Clazz.callingStack (caller, clazzThis)); + var ret = fx.apply (objThis, (funParams == null) ? [] : funParams); + Clazz._callingStackTraces.pop(); + return ret; + } + */ + /*# x<< #*/ + return fx.apply (objThis, funParams || []); +}; + +/** + * Call super constructor of the class. + * The same effect as Java's expression: + * super () + */ +/* public */ +Clazz.superConstructor = function (objThis, clazzThis, funParams) { + Clazz.superCall (objThis, clazzThis, "construct", funParams); + /* If there are members which are initialized out of the constructor */ + if (clazzThis.con$truct) { + clazzThis.con$truct.apply (objThis, []); + } +}; + +/** + * Class for null with a given class as to be casted. + * This class will be used as an implementation of Java's casting way. + * For example, + * this.call ((String) null); + */ +/* public */ +Clazz.CastedNull = function (asClazz) { + if (asClazz) { + if (asClazz instanceof String) { + this.clazzName = asClazz; + } else if (asClazz instanceof Function) { + this.clazzName = Clazz.getClassName (asClazz, true); + } else { + this.clazzName = "" + asClazz; + } + } else { + this.clazzName = "Object"; + } + this.toString = function () { + return null; + }; + this.valueOf = function () { + return null; + }; +}; + +/** + * API for Java's casting null. + * @see Clazz.CastedNull + * + * @param asClazz given class + * @return an instance of class Clazz.CastedNull + */ +/* public */ +Clazz.castNullAs = function (asClazz) { + return new Clazz.CastedNull (asClazz); +}; + +/////////////////////////// Exception handling //////////////////////////// + +/* + * Use to mark that the Throwable instance is created or not. + * + * Called from java.lang.Throwable, as defined in JSmolJavaExt.js + * + * The underscore is important - it tells the JSmol ANT task to NOT + * turn this into Clazz_initializingException, because coreBottom2.js does + * not include that call, and so Google Closure Compiler does not minify it. + * + */ +/* public */ +Clazz._initializingException = false; + +/** + * BH: used in Throwable + * + */ +/* public */ +Clazz._callingStackTraces = []; + +/** + * MethodException will be used as a signal to notify that the method is + * not found in the current clazz hierarchy. + */ +/* private */ +var MethodException = function () { + this.toString = function () { + return "J2S MethodException"; + }; +}; +/* private */ +//var MethodNotFoundException = function () { +// this.toString = function () { +// return "J2S MethodNotFoundException"; +// }; +//}; + + var _isNPEExceptionPredicate; + +/* super private */ +;(function() { + /* sgurin: native exception detection mechanism. Only NullPointerException detected and wrapped to java excepions */ + /** private utility method for creating a general regexp that can be used later + * for detecting a certain kind of native exceptions. use with error messages like "blabla IDENTIFIER blabla" + * @param msg String - the error message + * @param spliterName String, must be contained once in msg + * spliterRegex String, a string with the regexp literal for identifying the spitter in exception further error messages. + */ + // reproduce NullPointerException for knowing how to detect them, and create detector function Clazz._isNPEExceptionPredicate + var $$o$$ = null; + + try { + $$o$$.hello(); + } catch (e) { + var _ex_reg = function(msg, spliterName, spliterRegex) { + if(!spliterRegex) + spliterRegex="[^\\s]+"; + var idx = msg.indexOf (spliterName), + str = msg.substring (0, idx) + spliterRegex + msg.substring(idx + spliterName.length), + regexp = new RegExp("^"+str+"$"); + return regexp; + }; + if(/Opera[\/\s](\d+\.\d+)/.test(navigator.userAgent)) {// opera throws an exception with fixed messages like "Statement on line 23: Cannot convert undefined or null to Object Backtrace: Line....long text... " + var idx1 = e.message.indexOf(":"), idx2 = e.message.indexOf(":", idx1+2); + var _NPEMsgFragment = e.message.substr(idx1+1, idx2-idx1-20); + _isNPEExceptionPredicate = function(e) { return e.message.indexOf(_NPEMsgFragment)!=-1; }; + } else if(navigator.userAgent.toLowerCase().indexOf("webkit")!=-1) { //webkit, google chrome prints the property name accessed. + var _exceptionNPERegExp = _ex_reg(e.message, "hello"); + _isNPEExceptionPredicate = function(e) { return _exceptionNPERegExp.test(e.message); }; + } else {// ie, firefox and others print the name of the object accessed: + var _exceptionNPERegExp = _ex_reg(e.message, "$$o$$"); + _isNPEExceptionPredicate = function(e) { return _exceptionNPERegExp.test(e.message); }; + } + }; +})(); + +/**sgurin + * Implements Java's keyword "instanceof" in JavaScript's way **for exception objects**. + * + * calls Clazz.instanceOf if e is a Java exception. If not, try to detect known native + * exceptions, like native NullPointerExceptions and wrap it into a Java exception and + * call Clazz.instanceOf again. if the native exception can't be wrapped, false is returned. + * + * @param obj the object to be tested + * @param clazz the class to be checked + * @return whether the object is an instance of the class + * @author: sgurin + */ +Clazz.exceptionOf = function(e, clazz) { + if(e.__CLASS_NAME__) + return Clazz.instanceOf(e, clazz); + if (!e.getMessage) { + e.getMessage = function() {return "" + this}; + } + if (!e.printStackTrace) { + e.printStackTrace = function(){}; + alert(e + " try/catch path:" + Clazz.getStackTrace(-10)); + } + if(clazz == Error) { + if (("" + e).indexOf("Error") < 0) + return false; + System.out.println (Clazz.getStackTrace()); + return true; + // everything here is a Java Exception, not a Java Error + } + return (clazz == Exception || clazz == Throwable + || clazz == NullPointerException && _isNPEExceptionPredicate(e)); +}; + +/** + * BH need to limit this, as JavaScript call stack may be recursive + */ +Clazz.getStackTrace = function(n) { + n || (n = 25); + // updateNode and updateParents cause infinite loop here + var s = "\n"; + var c = arguments.callee; + var showParams = (n < 0); + if (showParams) + n = -n; + for (var i = 0; i < n; i++) { + if (!(c = c.caller)) + break; + var sig = (c.toString ? c.toString().substring(0, c.toString().indexOf("{")) : ""); + s += i + " " + (c.exName ? (c.claxxOwner ? c.claxxOwner.__CLASS_NAME__ + "." : "") + c.exName + sig.replace(/function /,""): sig) + "\n"; + if (c == c.caller) { + s += "\n"; + break; + } + if (showParams) { + var args = c.arguments; + for (var j = 0; j < args.length; j++) { + var sa = "" + args[j]; + if (sa.length > 60) + sa = sa.substring(0, 60) + "..."; + s += " args[" + j + "]=" + sa.replace(/\s+/g," ") + "\n"; + } + } + } + return s; +} + +///////////////////// method creation //////////////////////////////// + +/** + * Make constructor for the class with the given function body and parameters + * signature. + * + * @param clazzThis host class + * @param funBody constructor body + * @param funParams constructor parameters signature + */ +/* public */ +Clazz.makeConstructor = function (clazzThis, funBody, funParams) { + Clazz.defineMethod (clazzThis, "construct", funBody, funParams); + if (clazzThis.con$truct) { + clazzThis.con$truct.index = clazzThis.con$truct.stacks.length; + } + //clazzThis.con$truct = clazzThis.prototype.con$truct = null; +}; + +/** + * Override constructor for the class with the given function body and + * parameters signature. + * + * @param clazzThis host class + * @param funBody constructor body + * @param funParams constructor parameters signature + */ +/* public */ +Clazz.overrideConstructor = function (clazzThis, funBody, funParams) { + Clazz.overrideMethod (clazzThis, "construct", funBody, funParams); + if (clazzThis.con$truct) { + clazzThis.con$truct.index = clazzThis.con$truct.stacks.length; + } + //clazzThis.con$truct = clazzThis.prototype.con$truct = null; +}; + + +/* + * Define method for the class with the given method name and method + * body and method parameter signature. + * + * @param clazzThis host class in which the method to be defined + * @param funName method name + * @param funBody function object, e.g function () { ... } + * @param funParams paramether signature, e.g ["string", "number"] + * @return method of the given name. The method may be funBody or a wrapper + * of the given funBody. + */ +/* public */ +Clazz.defineMethod = function (clazzThis, funName, funBody, funParams) { + if (Clazz.assureInnerClass) + Clazz.assureInnerClass(clazzThis, funBody); + funBody.exName = funName; + var fpName = formatParameters(funParams); + var proto = clazzThis.prototype; + var f$ = proto[funName]; + if (Clazz._Loader._checkLoad) + checkDuplicate(clazzThis, funName, fpName); + if (!f$ || (f$.claxxOwner === clazzThis && f$.funParams == fpName)) { + // property "funParams" will be used as a mark of only-one method + funBody.funParams = fpName; + funBody.claxxOwner = clazzThis; + funBody.exClazz = clazzThis; // make it traceable + return addProto(proto, funName, funBody); + } + // we have found a duplicate + var oldFun = null; + var oldStacks = f$.stacks; + if (!oldStacks) { + /* method is not defined by Clazz.defineMethod () */ + oldStacks = []; + oldFun = f$; + if (f$.claxxOwner) { + oldStacks[0] = oldFun.claxxOwner; + } + } + /* + * Method that is already defined in super class will be overridden + * with a new proxy method with class hierarchy stored in a stack. + * That is to say, the super methods are lost in this class' proxy + * method. + * When method are being called, methods defined in the new proxy + * method will be searched through first. And if no method fitted, + * it will then try to search method in the super class stacks. + */ + if (!f$.stacks || f$.claxxReference !== clazzThis) { + //Generate a new delegating method for the class + var id = ++SAEMid; + var delegate = function () { + return searchAndExecuteMethod(id, this, arguments.callee.claxxReference, arguments.callee.methodName, arguments); + }; + delegate.methodName = funName; + delegate.claxxReference = clazzThis; + f$ = addProto(proto, funName, delegate); + // Keep the class inheritance stacks + var arr = []; + for (var i = 0; i < oldStacks.length; i++) + arr[i] = oldStacks[i]; + f$.stacks = arr; + } + var ss = f$.stacks; + if (findArrayItem(ss, clazzThis) < 0) ss.push(clazzThis); + + if (oldFun) { + if (oldFun.claxxOwner === clazzThis) { + f$[oldFun.funParams] = oldFun; + oldFun.claxxOwner = null; + // property "funParams" will be used as a mark of only-one method + oldFun.funParams = null; // null ? safe ? // safe for != null + } else if (!oldFun.claxxOwner) { + /* + * The function is not defined Clazz.defineMethod (). + * Try to fixup the method ... + * As a matter of lost method information, I just suppose + * the method to be fixed is with void parameter! + */ + f$["\\unknown"] = oldFun; + } + } + funBody.exClazz = clazzThis; // make it traceable + f$[fpName] = funBody; + return f$; +}; + +duplicatedMethods = {}; + +var checkDuplicate = function(clazzThis, funName, fpName) { + var proto = clazzThis.prototype; + var f$ = proto[funName]; + if (f$ && (f$.claxxOwner || f$.claxxReference) === clazzThis) { + key = clazzThis.__CLASS_NAME__ + "." + funName + fpName; + var m = duplicatedMethods[key]; + if (m) { + var s = "Warning! Duplicate method found for " + key; + System.out.println(s); + Clazz.alert(s); + duplicatedMethods[key] = m + 1; + } else { + duplicatedMethods[key] = 1; + } + } +} + +Clazz.showDuplicates = function(quiet) { + var s = ""; + var a = duplicatedMethods; + var n = 0; + for (var key in a) + if (a[key] > 1) { + s += a[key] + "\t" + key + "\n"; + n++; + } + s = "Duplicates: " + n + "\n\n" + s; + System.out.println(s); + if (!quiet) + alert(s); +} + +var findArrayItem = function(arr, item) { + if (arr && item) + for (var i = arr.length; --i >= 0;) + if (arr[i] === item) + return i; + return -1; +} + +var removeArrayItem = function(arr, item) { + var i = findArrayItem(arr, item); + if (i >= 0) { + var n = arr.length - 1; + for (; i < n; i++) + arr[i] = arr[i + 1]; + arr.length--; + return true; + } +} + +/* + * Other developers may need to extend this formatParameters method + * to deal complicated situation. + */ +/* protected */ +var formatParameters = function (funParams) { + return (funParams ? funParams.replace (/~([NABSO])/g, + function ($0, $1) { + switch ($1) { + case 'N': + return "n"; + case 'B': + return "b"; + case 'S': + return "String"; + case 'O': + return "Object"; + case 'A': + return "Array"; + } + return "Unknown"; + }).replace (/\s+/g, "").replace (/^|,/g, "\\").replace (/\$/g, "org.eclipse.s") : "\\void"); +}; + +/* + * Override the existed methods which are in the same name. + * Overriding methods is provided for the purpose that the JavaScript + * does not need to search the whole hierarchied methods to find the + * correct method to execute. + * Be cautious about this method. Incorrectly using this method may + * break the inheritance system. + * + * @param clazzThis host class in which the method to be defined + * @param funName method name + * @param funBody function object, e.g function () { ... } + * @param funParams paramether signature, e.g ["string", "number"] + */ +/* public */ +Clazz.overrideMethod = function(clazzThis, funName, funBody, funParams) { + if (Clazz.assureInnerClass) Clazz.assureInnerClass (clazzThis, funBody); + funBody.exName = funName; + var fpName = formatParameters(funParams); + if (Clazz._Loader._checkLoad) + checkDuplicate(clazzThis, funName, fpName); + /* + * Replace old methods with new method. No super methods are kept. + */ + funBody.funParams = fpName; + funBody.claxxOwner = clazzThis; + return addProto(clazzThis.prototype, funName, funBody); +}; + +////////////// Overridden and Overloaded Java Method Handling ////////////////// +// SAEM (SearchAndExecuteMethod) +// adapted by BH +// + +/* + * BH Clazz.getProfile monitors exactly what is being delegated with SAEM, + * which could be a bottle-neck for function calling. + * This is critical for performance optimization. + */ + + var __signatures = ""; + +Clazz.getProfile = function() { + var s = ""; + if (_profile) { + var l = []; + for (var i in _profile) { + var n = "" + _profile[i]; + l.push(" ".substring(n.length) + n + "\t" + i); + } + s = l.sort().reverse().join("\r\n"); + _profile = {}; + } + return s + __signatures; +} + +var addProfile = function(c, f, p, id) { + var s = id + " " + c.__CLASS_NAME__ + " " + f + " ";// + JSON.stringify(p); + if (__signatures.indexOf(s) < 0) + __signatures += s + "\n"; + _profile[s] || (_profile[s] = 0); + _profile[s]++; +} + +/** + * Called also by Throwable + * +/* public */ +Clazz.getParamsType = function (funParams) { + // bh: optimization here for very common cases + var n = funParams.length; + switch (n) { + case 0: + var params = ["void"]; + params.typeString = "\\void"; + return params; + case 1: + // BH just so common + switch (typeof obj) { + case "number": + var params = ["n"]; + params.typeString = "\\n"; + return params; + case "boolean": + var params = ["b"]; + params.typeString = "\\b"; + return params; + } + } + + var params = []; + params.hasCastedNull = false; + if (funParams) { + for (var i = 0; i < n; i++) { + params[i] = Clazz.getClassName (funParams[i]); + if (funParams[i] instanceof Clazz.CastedNull) { + params.hasCastedNull = true; + } + } + } + params.typeString = "\\" + params.join ('\\'); + return params; +}; + +var SAEMid = 0; +xxxSAEMlist = ""; + +//var SAEMarray = []; +/** + * BH: OK, this was an idea that doesn't work. The idea was to tag SAEM calls + * and then refer back to an array. But the id number cannot be put in the right place. + * + * Say we have this: + * + * StringBuffer sb = new StringBuffer(); + * sb.append("").append(1); + * + * Here we have two different append methods to call. They are saved under two + * names: StringBuffer.prototype.append["\\String"] + * and StringBuffer.prototype.append["\\Number"] + * + * The job of generateDelegatingMethod is to discriminate between those two. We can do + * that, but the real issue is that we have to do that EVERY time a call is made. + * This is a problem that must be handled at compile time. There is no way to + * make .append("") to go one way the first time and another way the second time. + * What we need at run time is something like this: + * + * Clazz.delegate(sb.append,1,[""]) and Clazz.delegate(sb.append,2,[1]) + * The we would be able to log those numbers at run time and refer to them. + * + * The only real way to avoid SAEM is: + * + * 1) to never call super() -- always call a differently named function in a superclass. + * 2) don't overload functions + * + */ + + +/** + * Search the given class prototype, find the method with the same + * method name and the same parameter signatures by the given + * parameters, and then run the method with the given parameters. + * + * @param objThis the current host object + * @param claxxRef the current host object's class + * @param fxName the method name + * @param funParams the given arguments + * @return the result of the specified method of the host object, + * the return maybe void. + * @throws MethodNotFoundException if no matched method is found + */ +/* protected */ +var searchAndExecuteMethod = function (id, objThis, claxxRef, fxName, args, _saem) { + +// var fx = SAEMarray[id]; +// if (fx) { +// return fx.apply(objThis, args); +// } + + + fx = objThis[fxName]; + var params = Clazz.getParamsType(args); + + +var s = "SAEM " + claxxRef.__CLASS_NAME__ + "." + fxName + "(" + params+ ")\n"; +if (xxxSAEMlist.length > 300)xxxSAEMlist = ""; +xxxSAEMlist += s; + + + if (!fx) + try {System.out.println(Clazz.getStackTrace(5))} catch (e){} + _profile && addProfile(claxxRef, fxName, params, id); + // Cache last matched method + if (fx.lastParams == params.typeString && fx.lastClaxxRef === claxxRef) { + var methodParams; + if (params.hasCastedNull) { + methodParams = []; + // For Clazz.CastedNull instances, the type name is + // already used to indentified the method in searchMethod. + for (var k = 0; k < args.length; k++) + methodParams[k] = (args[k] instanceof Clazz.CastedNull ? null : args[k]); + } else { +// if (fx.lastMethod) SAEMarray[id] = fx.lastMethod; + methodParams = args; + } + return (fx.lastMethod ? fx.lastMethod.apply(objThis, methodParams) : null); + } + fx.lastParams = params.typeString; + fx.lastClaxxRef = claxxRef; + + var stacks = fx.stacks; + if (!stacks) + stacks = claxxRef.prototype[fxName].stacks; + var length = stacks.length; + + /* + * Search the inheritance stacks to get the given class' function + */ + var began = false; // began to search its super classes + for (var i = length; --i >= 0;) { + if (began || stacks[i] === claxxRef) { + /* + * First try to search method within the same class scope + * with stacks[i] === claxxRef + */ + var clazzFun = stacks[i].prototype[fxName]; + var ret = tryToSearchAndExecute(id, fxName, objThis, clazzFun, params, + args, fx); + if (!(ret instanceof MethodException)) { + return ret; + } + /* + * As there are no such methods in current class, Clazz will try + * to search its super class stacks. Here variable began indicates + * that super searchi is began, and there is no need checking + * stacks[i] === claxxRef + */ + began = true; + } // end of if + } // end of for + if ("construct" == fxName) { + /* + * For non existed constructors, just return without throwing + * exceptions. In Java codes, extending Object can call super + * default Object#constructor, which is not defined in JS. + */ + return; + } + newMethodNotFoundException(objThis, claxxRef, + fxName, params.typeString); +}; + + +/* private */ +var tryToSearchAndExecute = function(id, fxName, objThis, clazzFun, params, args, fx, _ttsaem) { + var method = []; + var generic = true; + for (var fn in clazzFun) { + if (fn.charCodeAt(0) == 92) { // 92 == '\\'.charCodeAt (0) + var ps = fn.substring(1).split("\\"); + (ps.length == params.length) && method.push(ps); + generic = false; + continue; + } + /* + * When there is only one method in the class, use the args + * to identify the parameter type. + * + * AbstractCollection.remove (Object) + * AbstractList.remove (int) + * ArrayList.remove (int) + * + * Then calling #remove (Object) method on ArrayList instance will + * need to search up to the AbstractCollection.remove (Object), + * which contains only one method. + */ + /* + * See Clazz#defineMethod --Mar 10, 2006, josson + */ + if (generic && fn == "funParams" && clazzFun.funParams) { + fn = clazzFun.funParams; + var ps = fn.substring(1).split ("\\"); + (ps.length == params.length) && (method[0] = ps); + break; + } + } + var debug = false;//(method.length > 1 && method.join().indexOf("Listen")< 0 && params.join().indexOf("Null") >= 0) + if (debug)alert(fxName + " -- " + method.join("|") + " -- searching for method with " + params) + if (method.length == 0 || !(method = searchMethod(method, params, debug))) + return new MethodException(); + if (debug) alert("OK: \\" + method) + var f = (generic ? clazzFun : clazzFun["\\" + method]); + //if (generic) + //{ /* Use the generic method */ + /* + * Will this case be reachable? + * March 4, 2006 josson + * + * Reachable for calling #remove (Object) method on + * ArrayList instance + * May 5, 2006 josson + */ + var methodParams = null; + if (params.hasCastedNull) { + methodParams = []; + for (var k = 0; k < args.length; k++) { + if (args[k] instanceof Clazz.CastedNull) { + /* + * For Clazz.CastedNull instances, the type name is + * already used to indentify the method in searchMethod. + */ + methodParams[k] = null; + } else { + methodParams[k] = args[k]; + } + } + } else { + methodParams = args; + } + fx.lastMethod = f; + //if (!params.hasCastedNull) SAEMarray[id] = f; + return f.apply(objThis, methodParams); +}; + +/** + * Search the existed polymorphic methods to get the matched method with + * the given parameter types. + * + * @param existedMethods Array of string which contains method parameters + * @param paramTypes Array of string that is parameter type. + * @return string of method parameters seperated by "\\" + */ +/* private */ +var searchMethod = function(roundOne, paramTypes, debug) { + +// Filter out all the fitted methods for the given parameters + var roundTwo = []; + var len = roundOne.length; + for (var i = 0; i < len; i++) { + var fittedLevel = []; + var isFitted = true; + var len2 = roundOne[i].length; + for (var j = 0; j < len2; j++) { + + fittedLevel[j] = Clazz.getInheritedLevel (paramTypes[j], + roundOne[i][j]); + //if (debug)alert([paramTypes[j],fittedLevel[j],roundOne[i][j]]) + if (fittedLevel[j] < 0) { + isFitted = false; + break; + } + } + if (isFitted) { + fittedLevel[paramTypes.length] = i; // Keep index for later use + roundTwo.push(fittedLevel); + } + } + if (roundTwo.length == 0) + return null; + // Find out the best method according to the inheritance. + var resultTwo = roundTwo; + var min = resultTwo[0]; + for (var i = 1; i < resultTwo.length; i++) { + var isVectorLesser = true; + for (var j = 0; j < paramTypes.length; j++) { + if (min[j] < resultTwo[i][j]) { + isVectorLesser = false;; + break; + } + } + if (isVectorLesser) + min = resultTwo[i]; + } + var index = min[paramTypes.length]; // Get the previously stored index + /* + * Return the method parameters' type string as indentifier of the + * choosen method. + */ + return roundOne[index].join ('\\'); +}; + +////////////////////////////////// package loading /////////////////////// + +/* + * all root packages. e.g. java.*, org.*, com.* + */ +/* protected */ +Clazz.allPackage = {}; + +/** + * Will be used to keep value of whether the class is defined or not. + */ +/* protected */ +Clazz.allClasses = {}; + +Clazz.lastPackageName = null; +Clazz.lastPackage = null; + +/* protected */ +Clazz.unloadedClasses = []; + +/* public */ +Clazz.declarePackage = function (pkgName) { + if (Clazz.lastPackageName == pkgName) + return Clazz.lastPackage; + if (pkgName && pkgName.length) { + var pkgFrags = pkgName.split (/\./); + var pkg = Clazz.allPackage; + for (var i = 0; i < pkgFrags.length; i++) { + if (!pkg[pkgFrags[i]]) { + pkg[pkgFrags[i]] = { + __PKG_NAME__ : (pkg.__PKG_NAME__ ? + pkg.__PKG_NAME__ + "." + pkgFrags[i] : pkgFrags[i]) + }; + // pkg[pkgFrags[i]] = {}; + if (i == 0) { + // eval ... + Clazz.setGlobal(pkgFrags[i], pkg[pkgFrags[i]]); + } + } + pkg = pkg[pkgFrags[i]] + } + Clazz.lastPackageName = pkgName; + Clazz.lastPackage = pkg; + return pkg; + } +}; + +/* protected */ +Clazz.evalType = function (typeStr, isQualified) { + var idx = typeStr.lastIndexOf("."); + if (idx != -1) { + var pkgName = typeStr.substring (0, idx); + var pkg = Clazz.declarePackage (pkgName); + var clazzName = typeStr.substring (idx + 1); + return pkg[clazzName]; + } + if (isQualified) + return window[typeStr]; + switch (typeStr) { + case "string": + return String; + case "number": + return Number; + case "object": + return Clazz._O; + case "boolean": + return Boolean; + case "function": + return Function; + case "void": + case "undefined": + case "unknown": + return typeStr; + case "NullObject": + return NullObject; + default: + return window[typeStr]; + } +}; + +/** + * Define a class or interface. + * + * @param qClazzName String presents the qualified name of the class + * @param clazzFun Function of the body + * @param clazzParent Clazz to inherit from, may be null + * @param interfacez Clazz may implement one or many interfaces + * interfacez can be Clazz object or Array of Clazz objects. + * @return Ruturn the modified Clazz object + */ +/* public */ +Clazz.defineType = function (qClazzName, clazzFun, clazzParent, interfacez) { + var cf = Clazz.unloadedClasses[qClazzName]; + if (cf) { + clazzFun = cf; + } + var idx = qClazzName.lastIndexOf ("."); + if (idx != -1) { + var pkgName = qClazzName.substring (0, idx); + var pkg = Clazz.declarePackage (pkgName); + var clazzName = qClazzName.substring (idx + 1); + if (pkg[clazzName]) { + // already defined! Should throw exception! + return pkg[clazzName]; + } + pkg[clazzName] = clazzFun; + } else { + if (window[qClazzName]) { + // already defined! Should throw exception! + return window[qClazzName]; + } + Clazz.setGlobal(qClazzName, clazzFun); + } + Clazz.decorateAsType(clazzFun, qClazzName, clazzParent, interfacez); + /*# {$no.javascript.support} >>x #*/ + var iFun = Clazz._innerFunctions; + clazzFun.defineMethod = iFun.defineMethod; + clazzFun.defineStaticMethod = iFun.defineStaticMethod; + clazzFun.makeConstructor = iFun.makeConstructor; + /*# x<< #*/ + return clazzFun; +}; + +var isSafari = (navigator.userAgent.indexOf ("Safari") != -1); +var isSafari4Plus = false; +if (isSafari) { + var ua = navigator.userAgent; + var verIdx = ua.indexOf("Version/"); + if (verIdx != -1) { + var verStr = ua.substring(verIdx + 8); + var verNumber = parseFloat(verStr); + isSafari4Plus = verNumber >= 4.0; + } +} + +/* public */ +Clazz.instantialize = function (objThis, args) { + + + if (args && args.length == 1 && args[0] + && args[0] instanceof args4InheritClass) { + return; + } + if (objThis instanceof Number) { + objThis.valueOf = function () { + return this; + }; + } + if (isSafari4Plus) { // Fix bug of Safari 4.0+'s over-optimization + var argsClone = []; + for (var k = 0; k < args.length; k++) { + argsClone[k] = args[k]; + } + args = argsClone; + } + + var c = objThis.construct; + if (c) { + if (!objThis.con$truct) { // no need to init fields + c.apply (objThis, args); + } else if (!objThis.getClass ().superClazz) { // the base class + objThis.con$truct.apply (objThis, []); + c.apply (objThis, args); + } else if ((c.claxxOwner + && c.claxxOwner === objThis.getClass ()) + || (c.stacks + && c.stacks[c.stacks.length - 1] == objThis.getClass ())) { + /* + * This #construct is defined by this class itself. + * #construct will call Clazz.superConstructor, which will + * call #con$truct back + */ + c.apply (objThis, args); + } else { // constructor is a super constructor + if (c.claxxOwner && !c.claxxOwner.superClazz + && c.claxxOwner.con$truct) { + c.claxxOwner.con$truct.apply (objThis, []); + } else if (c.stacks && c.stacks.length == 1 + && !c.stacks[0].superClazz) { + c.stacks[0].con$truct.apply (objThis, []); + } + c.apply (objThis, args); + objThis.con$truct.apply (objThis, []); + } + } else if (objThis.con$truct) { + objThis.con$truct.apply (objThis, []); + } +}; + +/** + * Once there are other methods registered to the Function.prototype, + * those method names should be add to the following Array. + */ +/* + * static final member of interface may be a class, which may + * be function. + */ +/* protected */ +Clazz.innerFunctionNames = [ + "isInstance", "equals", "hashCode", /*"toString",*/ "getName", "getCanonicalName", "getClassLoader", "getResource", "getResourceAsStream" /*# {$no.javascript.support} >>x #*/, "defineMethod", "defineStaticMethod", + "makeConstructor" /*# x<< #*/ +]; + +/* + * Static methods + */ +Clazz._innerFunctions = { + /* + * Similar to Object#equals + */ + + isInstance: function(c) { + return Clazz.instanceOf(c, this); + }, + + equals : function (aFun) { + return this === aFun; + }, + + hashCode : function () { + return this.getName ().hashCode (); + }, + + toString : function () { + return "class " + this.getName (); + }, + + /* + * Similar to Class#getName + */ + getName : function () { + return Clazz.getClassName (this, true); + }, + getCanonicalName : function () { + return this.__CLASS_NAME__; + }, + getClassLoader : function () { + var clazzName = this.__CLASS_NAME__; + var baseFolder = Clazz._Loader.getClasspathFor(clazzName); + var x = baseFolder.lastIndexOf (clazzName.replace (/\./g, "/")); + if (x != -1) { + baseFolder = baseFolder.substring (0, x); + } else { + baseFolder = Clazz._Loader.getClasspathFor(clazzName, true); + } + var loader = Clazz._Loader.requireLoaderByBase(baseFolder); + loader.getResourceAsStream = Clazz._innerFunctions.getResourceAsStream; + loader.getResource = Clazz._innerFunctions.getResource; // BH + return loader; + }, + + getResource : function(name) { + var stream = this.getResourceAsStream(name); + return (stream ? stream.url : null); + }, + + getResourceAsStream : function (name) { + if (!name) + return null; + name = name.replace (/\\/g, '/'); + var baseFolder = null; + var fname = name; + var clazzName = this.__CLASS_NAME__; + if (arguments.length == 2 && name.indexOf ('/') != 0) { // additional argument + name = "/" + name; + } + if (name.indexOf ('/') == 0) { + //is.url = name.substring (1); + if (arguments.length == 2) { // additional argument + baseFolder = arguments[1]; + if (!baseFolder) + baseFolder = Clazz.binaryFolders[0]; + } else if (Clazz._Loader) { + baseFolder = Clazz._Loader.getClasspathFor(clazzName, true); + } + if (!baseFolder) { + fname = name.substring (1); + } else { + baseFolder = baseFolder.replace (/\\/g, '/'); + var length = baseFolder.length; + var lastChar = baseFolder.charAt (length - 1); + if (lastChar != '/') { + baseFolder += "/"; + } + fname = baseFolder + name.substring (1); + } + } else { + if (this.base) { + baseFolder = this.base; + } else if (Clazz._Loader) { + baseFolder = Clazz._Loader.getClasspathFor(clazzName); + var x = baseFolder.lastIndexOf (clazzName.replace (/\./g, "/")); + if (x != -1) { + baseFolder = baseFolder.substring (0, x); + } else { + //baseFolder = null; + var y = -1; + if (baseFolder.indexOf (".z.js") == baseFolder.length - 5 + && (y = baseFolder.lastIndexOf ("/")) != -1) { + baseFolder = baseFolder.substring (0, y + 1); + var pkgs = clazzName.split (/\./); + for (var k = 1; k < pkgs.length; k++) { + var pkgURL = "/"; + for (var j = 0; j < k; j++) { + pkgURL += pkgs[j] + "/"; + } + if (pkgURL.length > baseFolder.length) { + break; + } + if (baseFolder.indexOf (pkgURL) == baseFolder.length - pkgURL.length) { + baseFolder = baseFolder.substring (0, baseFolder.length - pkgURL.length + 1); + break; + } + } + } else { + baseFolder = Clazz._Loader.getClasspathFor(clazzName, true); + } + } + } else { + var bins = Clazz.binaryFolders; + if (bins && bins.length) { + baseFolder = bins[0]; + } + } + if (!baseFolder) + baseFolder = "j2s/"; + baseFolder = baseFolder.replace (/\\/g, '/'); + var length = baseFolder.length; + var lastChar = baseFolder.charAt (length - 1); + if (lastChar != '/') { + baseFolder += "/"; + } + if (this.base) { + fname = baseFolder + name; + } else { + var idx = clazzName.lastIndexOf ('.'); + if (idx == -1 || this.base) { + fname = baseFolder + name; + } else { + fname = baseFolder + clazzName.substring (0, idx) + .replace (/\./g, '/') + "/" + name; + } + } + } + var url = null; + try { + if (fname.indexOf(":/") < 0) { + var d = document.location.href.split("?")[0].split("/"); + d[d.length - 1] = fname; + fname = d.join("/"); + } + url = new java.net.URL(fname); + } catch (e) { + } + var data = (url == null ? null : Jmol._getFileData(fname.toString())); + if (!data || data == "error" || data.indexOf("[Exception") == 0) + return null; + var bytes = new java.lang.String(data).getBytes(); + var is = new java.io.BufferedInputStream ( new java.io.ByteArrayInputStream (bytes)); + is.url = url; + return is; + }/*# {$no.javascript.support} >>x #*/, + + /* + * For JavaScript programmers + */ + defineMethod : function (methodName, funBody, paramTypes) { + Clazz.defineMethod (this, methodName, funBody, paramTypes); + }, + + /* + * For JavaScript programmers + */ + defineStaticMethod : function (methodName, funBody, paramTypes) { + Clazz.defineMethod (this, methodName, funBody, paramTypes); + this[methodName] = this.prototype[methodName]; + }, + + /* + * For JavaScript programmers + */ + makeConstructor : function (funBody, paramTypes) { + Clazz.makeConstructor (this, funBody, paramTypes); + } + /*# x<< #*/ +}; + + +var cStack = []; + +/** + * BH: I would like to be able to remove "self.c$" here, but that is tricky. + */ + +Clazz.pu$h = function (c) { + c || (c = self.c$); // old style + c && cStack.push(c); +}; + +Clazz.p0p = function () { + return cStack.pop(); +}; + +/* protected */ +Clazz.decorateAsClass = function (clazzFun, prefix, name, clazzParent, + interfacez, parentClazzInstance, _decorateAsClass) { + + var prefixName = null; + if (prefix) { + prefixName = prefix.__PKG_NAME__; + if (!prefixName) + prefixName = prefix.__CLASS_NAME__; + } + var qName = (prefixName ? prefixName + "." : "") + name; + + if (Clazz._Loader._classPending[qName]) { + delete Clazz._Loader._classPending[qName]; + Clazz._Loader._classCountOK++; + Clazz._Loader._classCountPending--; + } + if (Clazz._Loader && Clazz._Loader._checkLoad) { + System.out.println("decorating class " + prefixName + "." + name); + } + var cf = Clazz.unloadedClasses[qName]; + if (cf) { + clazzFun = cf; + } + var qName = null; + decorateFunction(clazzFun, prefix, name); + if (parentClazzInstance) { + Clazz.inheritClass (clazzFun, clazzParent, parentClazzInstance); + } else if (clazzParent) { + Clazz.inheritClass (clazzFun, clazzParent); + } + if (interfacez) { + Clazz.implementOf (clazzFun, interfacez); + } + return clazzFun; +}; + +/* private */ +var decorateFunction = function (clazzFun, prefix, name, _decorateFunction) { + var qName; + if (!prefix) { + // e.g. Clazz.declareInterface (null, "ICorePlugin", org.eclipse.ui.IPlugin); + qName = name; + Clazz.setGlobal(name, clazzFun); + } else if (prefix.__PKG_NAME__) { + // e.g. Clazz.declareInterface (org.eclipse.ui, "ICorePlugin", org.eclipse.ui.IPlugin); + qName = prefix.__PKG_NAME__ + "." + name; + prefix[name] = clazzFun; + if (prefix === java.lang) + Clazz.setGlobal(name, clazzFun); + } else { + // e.g. Clazz.declareInterface (org.eclipse.ui.Plugin, "ICorePlugin", org.eclipse.ui.IPlugin); + qName = prefix.__CLASS_NAME__ + "." + name; + prefix[name] = clazzFun; + } + Clazz.extendJO(clazzFun, qName); + var inF = Clazz.innerFunctionNames; + for (var i = 0; i < inF.length; i++) { + clazzFun[inF[i]] = Clazz._innerFunctions[inF[i]]; + } + + if (Clazz._Loader) + Clazz._Loader.updateNodeForFunctionDecoration(qName); +}; + +/* protected */ +Clazz.declareInterface = function (prefix, name, interfacez, _declareInterface) { + var clazzFun = function () {}; + decorateFunction(clazzFun, prefix, name); + if (interfacez) { + Clazz.implementOf (clazzFun, interfacez); + } + return clazzFun; +}; + +/* public */ +Clazz.declareType = function (prefix, name, clazzParent, interfacez, + parentClazzInstance, _declareType) { + var f = function () { + Clazz.instantialize (this, arguments); + }; + return Clazz.decorateAsClass (f, prefix, name, clazzParent, interfacez, + parentClazzInstance); +}; + +/* public */ +Clazz.declareAnonymous = function (prefix, name, clazzParent, interfacez, + parentClazzInstance, _declareAnonymous) { + var f = function () { + Clazz.prepareCallback(this, arguments); + Clazz.instantialize (this, arguments); + }; + return Clazz.decorateAsClass (f, prefix, name, clazzParent, interfacez, + parentClazzInstance); +}; + +/* public */ +Clazz.decorateAsType = function (clazzFun, qClazzName, clazzParent, + interfacez, parentClazzInstance, inheritClazzFuns, _decorateAsType) { + Clazz.extendJO(clazzFun, qClazzName); + clazzFun.equals = Clazz._innerFunctions.equals; + clazzFun.getName = Clazz._innerFunctions.getName; + if (inheritClazzFuns) { + for (var i = 0; i < Clazz.innerFunctionNames.length; i++) { + var methodName = Clazz.innerFunctionNames[i]; + clazzFun[methodName] = Clazz._innerFunctions[methodName]; + } + } + if (parentClazzInstance) { + Clazz.inheritClass (clazzFun, clazzParent, parentClazzInstance); + } else if (clazzParent) { + Clazz.inheritClass (clazzFun, clazzParent); + } + if (interfacez) { + Clazz.implementOf (clazzFun, interfacez); + } + return clazzFun; +}; + + +////////////////////////// default package declarations //////////////////////// + +/* sgurin: preserve Number.prototype.toString */ +Number.prototype._numberToString=Number.prototype.toString; + + +Clazz.declarePackage ("java.io"); +//Clazz.declarePackage ("java.lang"); +Clazz.declarePackage ("java.lang.annotation"); // java.lang +Clazz.declarePackage ("java.lang.instrument"); // java.lang +Clazz.declarePackage ("java.lang.management"); // java.lang +Clazz.declarePackage ("java.lang.reflect"); // java.lang +Clazz.declarePackage ("java.lang.ref"); // java.lang.ref +java.lang.ref.reflect = java.lang.reflect; +Clazz.declarePackage ("java.util"); +//var reflect = Clazz.declarePackage ("java.lang.reflect"); +Clazz.declarePackage ("java.security"); + + +/* + * Consider these interfaces are basic! + */ +Clazz.declareInterface (java.io,"Closeable"); +Clazz.declareInterface (java.io,"DataInput"); +Clazz.declareInterface (java.io,"DataOutput"); +Clazz.declareInterface (java.io,"Externalizable"); +Clazz.declareInterface (java.io,"Flushable"); +Clazz.declareInterface (java.io,"Serializable"); +Clazz.declareInterface (java.lang,"Iterable"); +Clazz.declareInterface (java.lang,"CharSequence"); +Clazz.declareInterface (java.lang,"Cloneable"); +Clazz.declareInterface (java.lang,"Appendable"); +Clazz.declareInterface (java.lang,"Comparable"); +Clazz.declareInterface (java.lang,"Runnable"); +Clazz.declareInterface (java.util,"Comparator"); + +java.lang.ClassLoader = { + __CLASS_NAME__ : "ClassLoader" +}; + +/****************************************************************************** + * Copyright (c) 2007 java2script.org and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Zhou Renjian - initial API and implementation + *****************************************************************************/ +/******* + * @author zhou renjian + * @create March 10, 2006 + *******/ + +/** + * Once ClassExt.js is part of Class.js. + * In order to make the Class.js as small as possible, part of its content + * is moved into this ClassExt.js. + * + * See also http://j2s.sourceforge.net/j2sclazz/ + */ + +/** + * Clazz.MethodNotFoundException is used to notify the developer about calling + * methods with incorrect parameters. + */ +/* protected */ +// Override the Clazz.MethodNotFoundException in Class.js to give details +var newMethodNotFoundException = function (obj, clazz, method, params) { + var paramStr = ""; + if (params) { + paramStr = params.substring (1).replace (/\\/g, ","); + } + var leadingStr = ""; + if (method && method != "construct") { + leadingStr = "Method"; + } else { + leadingStr = "Constructor"; + } + var message = leadingStr + " " + Clazz.getClassName (clazz, true) + "." + + method + "(" + paramStr + ") is not found!"; + throw new java.lang.NoSuchMethodException(message); +}; + +/** + * Prepare "callback" for instance of anonymous Class. + * For example for the callback: + * this.callbacks.MyEditor.sayHello(); + * + * This is specifically for inner classes that are referring to + * outer class methods and fields. + * + * @param objThis the host object for callback + * @param args arguments object. args[0] will be classThisObj -- the "this" + * object to be hooked + * + * Attention: parameters should not be null! + */ +/* protected */ +Clazz.prepareCallback = function (innerObj, args) { + var outerObj = args[0]; + var cbName = "b$"; // "callbacks"; + if (innerObj && outerObj && outerObj !== window) { + var className = Clazz.getClassName(outerObj, true); + var obs = {}; + if (innerObj[cbName]) // must make a copy! + for (var s in innerObj[cbName]) + obs[s] = innerObj[cbName][s]; + innerObj[cbName] = obs; + + /* + * TODO: the following line is SWT-specific! Try to move it out! + */ + // obs[className.replace (/org\.eclipse\.swt\./, "$wt.")] = outerObj; + + // all references to outer class and its superclass objects must be here as well + obs[className] = outerObj; + var clazz = Clazz.getClass(outerObj); + while (clazz.superClazz) { + clazz = clazz.superClazz; + /* + * TODO: the following line is SWT-specific! Try to move it out! + */ + // obs[Clazz.getClassName (clazz, true) + // .replace (/org\.eclipse\.swt\./, "$wt.")] = outerObj; + obs[Clazz.getClassName(clazz, true)] = outerObj; + } + var cbs = outerObj[cbName]; + if (cbs) + for (var s in cbs) + obs[s] = cbs[s]; + } + // remove "this" argument + // note that args is an instance of arguments -- NOT an array; does not have the .shift() method! + for (var i = 0; i < args.length - 1; i++) + args[i] = args[i + 1]; + args.length--; +}; + +/** + * Construct instance of the given inner class. + * + * @param classInner given inner class, alway with name like "*$*" + * @param innerObj this instance which can be used to call back. + * @param finalVars final variables which the inner class may use + * @return the constructed object + * + * @see Clazz#cloneFinals + */ +/* public */ +Clazz.innerTypeInstance = function (clazzInner, innerObj, finalVars) { + if (!clazzInner) + clazzInner = arguments.callee.caller; + var obj; + if (finalVars || innerObj.$finals) { + obj = new clazzInner(innerObj, Clazz.inheritArgs); + // f$ is short for the once choosen "$finals" + if (finalVars) { + if (innerObj.f$) { + var o = {}; + for (var attr in innerObj.f$) + o[attr] = innerObj.f$[attr]; + for (var attr in finalVars) + o[attr] = finalVars[attr]; + obj.f$ = o; + } else { + obj.f$ = finalVars; + } + } else if (innerObj.f$) { + obj.f$ = innerObj.f$; + } + } else { + switch (arguments.length) { + case 3: + return new clazzInner(innerObj); + case 4: + return (innerObj.__CLASS_NAME__ == clazzInner.__CLASS_NAME__ + && arguments[3] === Clazz.inheritArgs ? innerObj : new clazzInner(innerObj, arguments[3])); + case 5: + return new clazzInner(innerObj, arguments[3], arguments[4]); + case 6: + return new clazzInner(innerObj, arguments[3], arguments[4], + arguments[5]); + case 7: + return new clazzInner(innerObj, arguments[3], arguments[4], + arguments[5], arguments[6]); + case 8: + return new clazzInner(innerObj, arguments[3], arguments[4], + arguments[5], arguments[6], arguments[7]); + case 9: + return new clazzInner(innerObj, arguments[3], arguments[4], + arguments[5], arguments[6], arguments[7], arguments[8]); + case 10: + return new clazzInner(innerObj, arguments[3], arguments[4], + arguments[5], arguments[6], arguments[7], arguments[8], + arguments[9]); + default: + //Should construct instance manually. + obj = new clazzInner(innerObj, Clazz.inheritArgs); + break; + } + } + var n = arguments.length - 3; + var args = new Array(n); + for (var i = n; --i >= 0;) + args[i] = arguments[i + 3]; + Clazz.instantialize(obj, args); + return obj; +}; + +/** + * Clone variables whose modifier is "final". + * Usage: var o = Clazz.cloneFinals ("name", name, "age", age); + * + * @return Object with all final variables + */ +/* public */ +Clazz.cloneFinals = function () { + var o = {}; + var len = arguments.length / 2; + for (var i = len; --i >= 0;) + o[arguments[i + i]] = arguments[i + i + 1]; + return o; +}; + +/* public */ +Clazz.isClassDefined = Clazz.isDefinedClass = function(clazzName) { + if (!clazzName) + return false; /* consider null or empty name as non-defined class */ + if (Clazz.allClasses[clazzName]) + return true; + var pkgFrags = clazzName.split (/\./); + var pkg = null; + for (var i = 0; i < pkgFrags.length; i++) + if (!(pkg = (pkg ? pkg[pkgFrags[i]] : Clazz.allPackage[pkgFrags[0]]))) { + return false; + } + return (pkg && (Clazz.allClasses[clazzName] = true)); +}; +/** + * Define the enum constant. + * @param classEnum enum type + * @param enumName enum constant + * @param enumOrdinal enum ordinal + * @param initialParams enum constant constructor parameters + * @return return defined enum constant + */ +/* public */ +Clazz.defineEnumConstant = function (clazzEnum, enumName, enumOrdinal, initialParams, clazzEnumExt) { + var o = (clazzEnumExt ? new clazzEnumExt() : new clazzEnum()); + // BH avoids unnecessary calls to SAEM + o.$name = enumName; + o.$ordinal = enumOrdinal; + //Clazz.superConstructor (o, clazzEnum, [enumName, enumOrdinal]); + if (initialParams && initialParams.length) + o.construct.apply (o, initialParams); + clazzEnum[enumName] = o; + clazzEnum.prototype[enumName] = o; + if (!clazzEnum["$ values"]) { // BH added + clazzEnum["$ values"] = [] // BH added + clazzEnum.values = function() { // BH added + return this["$ values"]; // BH added + }; // BH added + } + clazzEnum["$ values"].push(o); + return o; +}; + +//////// (int) conversions ////////// + +Clazz.floatToInt = function (x) { + return x < 0 ? Math.ceil(x) : Math.floor(x); +}; + +Clazz.floatToByte = Clazz.floatToShort = Clazz.floatToLong = Clazz.floatToInt; +Clazz.doubleToByte = Clazz.doubleToShort = Clazz.doubleToLong = Clazz.doubleToInt = Clazz.floatToInt; + +Clazz.floatToChar = function (x) { + return String.fromCharCode (x < 0 ? Math.ceil(x) : Math.floor(x)); +}; + +Clazz.doubleToChar = Clazz.floatToChar; + + + +///////////////////////////////// Array additions ////////////////////////////// +// +// BH: these are necessary for integer processing, especially +// +// + +var getArrayClone = function(nbits) { + return function() { + var me = this; + var n = me.length; + var a = (nbits == 32 ? new Int32Array(n) : new Float64Array(n)); + for (var i = n; --i >= 0;) + a[i] = me[i]; + return a; + } +} + +if (self.Int32Array && self.Int32Array != Array) { + Clazz.haveInt32 = true; + if (!Int32Array.prototype.sort) + Int32Array.prototype.sort = Array.prototype.sort + if (!Int32Array.prototype.clone) + Int32Array.prototype.clone = getArrayClone(32); +} else { + Int32Array = function(n) { + if (!n) n = 0; + var b = new Array(n); + b.toString = function(){return "[object Int32Array]"} + for (var i = 0; i < n; i++)b[i] = 0 + return b; + } + Clazz.haveInt32 = false; + Int32Array.prototype.sort = Array.prototype.sort + Int32Array.prototype.clone = getArrayClone(32); + Int32Array.prototype.int32Fake = function(){}; +} + +if (self.Float64Array && self.Float64Array != Array) { + Clazz.haveFloat64 = true; + if (!Float64Array.prototype.sort) + Float64Array.prototype.sort = Array.prototype.sort + if (!Float64Array.prototype.clone) + Float64Array.prototype.clone = getArrayClone(64); +} else { + Clazz.haveFloat64 = false; + Float64Array = function(n) { + if (!n) n = 0; + var b = new Array(n); + for (var i = 0; i < n; i++)b[i] = 0.0 + return b; + }; + Float64Array.prototype.sort = Array.prototype.sort + Float64Array.prototype.clone = getArrayClone(64); + Float64Array.prototype.float64Fake = function() {}; // "present" + Float64Array.prototype.toString = function() {return "[object Float64Array]"}; +// Darn! Mozilla makes this a double, not a float. It's 64-bit. +// and Safari 5.1 doesn't have Float64Array +} + +/** + * Make arrays. + * + * @return the created Array object + */ +/* public */ +Clazz.newArray = function () { + if (arguments[0] instanceof Array) { + // recursive, from newArray(n,m,value) + // as newArray([m, value], newInt32Array) + var args = arguments[0]; + var f = arguments[1]; + } else { + var args = arguments; + var f = Array; + } + var dim = args[0]; + if (typeof dim == "string") { + dim = dim.charCodeAt (0); // char + } + var len = args.length - 1; + var val = args[len]; + switch (args.length) { + case 0: // never + case 1: + return []; // maybe never? + case 2: + if (val == null) + return new Array(dim); + if (f === true && Clazz.haveInt32) return new Int32Array(dim); + if (f === false && Clazz.haveFloat64) return new Float64Array(dim); + var arr = (f === true ? new Int32Array() : f === false ? new Float64Array() : dim < 0 ? val : new Array(dim)); + for (var i = dim; --i >= 0;) + arr[i] = val; + return arr; + default: + var xargs = new Array (len); + for (var i = 0; i < len; i++) { + xargs[i] = args[i + 1]; + } + var arr = new Array (dim); + if (val == null || val >= 0 || len > 2) + for (var i = 0; i < dim; i++) { + // Call recursively! + arr[i] = Clazz.newArray (xargs, f); + } + return arr; + } +}; + +Clazz.newArray32 = function(args, isInt32) { + var dim = args[0]; + if (typeof dim == "string") + dim = dim.charCodeAt (0); // char + var len = args.length - 1; + var val = args[len]; + switch (args.length) { + case 0: + case 1: + alert ("ERROR IN newArray32 -- args.length < 2"); + return new Array(0); + case 2: + var isDefined = (dim < 0); + if (isDefined) + dim = val.length; + var a = (val < 0 ? new Array(dim) : isInt32 ? new Int32Array(dim) : new Float64Array(dim)); + if (isDefined) + for (var i = dim; --i >= 0;) + a[i] = val[i]; + return a; + } + var xargs = new Array(len); + for (var i = len; --i >= 0;) { + xargs[i] = args[i + 1]; + } + var arr = new Array (dim); + for (var i = 0; i < dim; i++) { + // Call newArray referencing this array type + // only for the final iteration, and only if val === 0 + arr[i] = Clazz.newArray (xargs, isInt32); + } + return arr; +}; + + +/** + * Make arrays. + * + * @return the created Array object + */ +/* public */ +Clazz.newInt32Array = function () { + return Clazz.newArray32(arguments, true); +} + +/** + * Make arrays. + * + * @return the created Array object + */ +/* public */ +Clazz.newFloat64Array = function () { + return Clazz.newArray32(arguments, false); +} + +Clazz.newFloatArray = Clazz.newDoubleArray = Clazz.newFloat64Array; +Clazz.newIntArray = Clazz.newLongArray = Clazz.newShortArray = Clazz.newByteArray = Clazz.newInt32Array; +Clazz.newCharArray = Clazz.newBooleanArray = Clazz.newArray; + +//$_AI=Clazz.newIntArray; +//$_AF=Clazz.newFloatArray; +//$_AD=Clazz.newDoubleArray; +//$_AL=Clazz.newLongArray; +//$_AS=Clazz.newShortArray; +//$_AB=Clazz.newByteArray; +//$_AC=Clazz.newCharArray; +//$_Ab=Clazz.newBooleanArray; + + +var arrayIs = function(a, what) { + // for some reason, Number.constructor.toString() now gives "too much recursion" + return a.constructor && a.constructor != Number && a.constructor.toString().indexOf(what) >= 0 +} + +Clazz.isAS = function(a) { // just checking first parameter + return (a && typeof a == "object" && arrayIs(a, " Array") && (typeof a[0] == "string" || typeof a[0] == "undefined")); +} + +Clazz.isASS = function(a) { + return (a && typeof a == "object" && Clazz.isAS(a[0])); +} + +Clazz.isAP = function(a) { + return (a && Clazz.getClassName(a[0]) == "JU.P3"); +} + +Clazz.isAI = function(a) { + return (a && typeof a == "object" && (Clazz.haveInt32 ? arrayIs(a, "Int32Array") : a.int32Fake ? true : false)); +} + +Clazz.isAII = function(a) { // assumes non-null a[0] + return (a && typeof a == "object" && Clazz.isAI(a[0])); +} + +Clazz.isAF = function(a) { + return (a && typeof a == "object" && (Clazz.haveFloat64 ? arrayIs(a, "Float64Array") : a.float64Fake ? true : false)); +} + +Clazz.isAFF = function(a) { // assumes non-null a[0] + return (a && typeof a == "object" && Clazz.isAF(a[0])); +} + +Clazz.isAFFF = function(a) { // assumes non-null a[0] + return (a && typeof a == "object" && Clazz.isAFF(a[0])); +} + +Clazz.isAFloat = function(a) { // just checking first parameter + return (a && typeof a == "object" && arrayIs(a, " Array") && Clazz.instanceOf(a[0], Float)); +} + + +/** + * Make the RunnableCompatiability instance as a JavaScript function. + * + * @param jsr Instance of RunnableCompatiability + * @return JavaScript function instance represents the method run of jsr. + */ +/* public */ +/* +Clazz.makeFunction = function (jsr) { +// never used in Jmol -- called by Enum, but not accessible to it -- part of SWT + return function(e) { + if (!e) + e = window.event; + if (jsr.setEvent) + jsr.setEvent(e); + jsr.run(); + switch (jsr.returnSet) { + case 1: + return jsr.returnNumber; + case 2: + return jsr.returnBoolean; + case 3: + return jsr.returnObject; + } + }; +}; +*/ + +/* protected */ +Clazz.defineStatics = function (clazz) { + for (var j = arguments.length, i = (j - 1) / 2; --i >= 0;) { + var val = arguments[--j] + var name = arguments[--j]; + clazz[name] = clazz.prototype[name] = val; + } +}; + +/* public */ +Clazz.prepareFields = function (clazz, fieldsFun) { + var stacks = []; + if (clazz.con$truct) { + var ss = clazz.con$truct.stacks; + var idx = 0;//clazz.con$truct.index; + for (var i = idx; i < ss.length; i++) { + stacks[i] = ss[i]; + } + } + addProto(clazz.prototype, "con$truct", clazz.con$truct = function () { + var stacks = arguments.callee.stacks; + if (stacks) { + for (var i = 0; i < stacks.length; i++) { + stacks[i].apply (this, []); + } + } + }); + stacks.push(fieldsFun); + clazz.con$truct.stacks = stacks; + clazz.con$truct.index = 0; +}; + +/* + * Serialize those public or protected fields in class + * net.sf.j2s.ajax.SimpleSerializable. + */ +/* protected */ +/* +Clazz.registerSerializableFields = function (clazz) { + var args = arguments; + var length = args.length; + var newArr = []; + if (clazz.declared$Fields) { + for (var i = 0; i < clazz.declared$Fields.length; i++) { + newArr[i] = clazz.declared$Fields[i]; + } + } + clazz.declared$Fields = newArr; + + if (length > 0 && length % 2 == 1) { + var fs = clazz.declared$Fields; + var n = (length - 1) / 2; + for (var i = 1; i <= n; i++) { + var o = { name : args[i + i - 1], type : args[i + i] }; + var existed = false; + for (var j = 0; j < fs.length; j++) { + if (fs[j].name == o.name) { // reloaded classes + fs[j].type = o.type; // update type + existed = true; + break; + } + } + if (!existed) + fs.push(o); + } + } +}; +*/ +/* + * Get the caller method for those methods that are wrapped by + * Clazz.searchAndExecuteMethod. + * + * @param args caller method's arguments + * @return caller method, null if there is not wrapped by + * Clazz.searchAndExecuteMethod or is called directly. + */ +/* protected */ +/* +Clazz.getMixedCallerMethod = function (args) { + var o = {}; + var argc = args.callee.caller; // tryToSearchAndExecute + if (argc && argc !== tryToSearchAndExecute) // inherited method's apply + argc = argc.arguments.callee.caller; + if (argc !== tryToSearchAndExecute + || (argc = argc.arguments.callee.caller) !== Clazz.searchAndExecuteMethod) + return null; + o.claxxRef = argc.arguments[1]; + o.fxName = argc.arguments[2]; + o.paramTypes = Clazz.getParamsType(argc.arguments[3]); + argc = argc.arguments.callee.caller // Clazz.generateDelegatingMethod + && argc.arguments.callee.caller; // the private method's caller + if (!argc) + return null; + o.caller = argc; + return o; +}; +*/ +/* BH -- The issue here is a subclass calling its private method FOO when + * there is also a private method of the same name in its super class. + * This can ALWAYS be avoided and, one could argue, is bad + * program design anyway. In Jmol, the presence of this possibility + * creates over 8000 references to the global $fx, which was only + * checked in a few rare cases. We can then also remove $fz references. + * + */ + +/* + * Check and return super private method. + * In order make private methods be executed correctly, some extra javascript + * must be inserted into the beggining of the method body of the non-private + * methods that with the same method signature as following: + * + * var $private = Clazz.checkPrivateMethod (arguments); + * if ($private) { + * return $private.apply (this, arguments); + * } + * + * Be cautious about this. The above codes should be insert by Java2Script + * compiler or with double checks to make sure things work correctly. + * + * @param args caller method's arguments + * @return private method if there are private method fitted for the current + * calling environment + */ +/* public */ + +Clazz.checkPrivateMethod = function () { + // get both this one and the one calling it + me = arguments.callee.caller; + caller = arguments.callee.caller.caller; + var stack = me.stacks; + // if their classes are the same, no issue + var mySig = "\\" + Clazz.getParamsType(arguments[0]).join("\\") + if (!me.privateNote) { + me.privateNote = "You are seeing this note because the method " + + me.exName + mySig + " in class " + + me.exClazz.__CLASS_NAME__ + + " has a superclass method by the same name (possibly with the same parameters) that is private and " + + " therefore might be called improperly from this class. If your " + + " code does not run properly, or you want to make it run faster, change the name of this method to something else." + System.out.println(me.privateNote); + alert(me.privateNote); + } + /* + alert([me.exClazz.__CLASS_NAME__, me.exName, + caller.exClazz.__CLASS_NAME__, caller.exName,stack,mySig]) + if (stack == null || caller.exClazz == me.exClazz) + return null; + // I am being called by a different class... + + for (var i = stack.length; --i >= 0;) { + if (stacks[i] != caller.claxxRef) + continue; + // and it is on MY class stack +// if ( + + } + */ + +/* var m = Clazz.getMixedCallerMethod (args); + if (m == null) return null; + var callerFx = m.claxxRef.prototype[m.caller.exName]; + if (callerFx == null) return null; // may not be in the class hierarchies + var ppFun = null; + if (callerFx.claxxOwner ) { + ppFun = callerFx.claxxOwner.prototype[m.fxName]; + } else { + var stacks = callerFx.stacks; + for (var i = stacks.length - 1; i >= 0; i--) { + var fx = stacks[i].prototype[m.caller.exName]; + if (fx === m.caller) { + ppFun = stacks[i].prototype[m.fxName]; + } else if (fx ) { + for (var fn in fx) { + if (fn.indexOf ('\\') == 0 && fx[fn] === m.caller) { + ppFun = stacks[i].prototype[m.fxName]; + break; + } + } + } + if (ppFun) { + break; + } + } + } + if (ppFun && ppFun.claxxOwner == null) { + ppFun = ppFun["\\" + m.paramTypes]; + } + if (ppFun && ppFun.isPrivate && ppFun !== args.callee) { + return ppFun; + } +*/ + return null; +}; + + +//$fz = null; // for private method declaration + + +// /*# {$no.debug.support} >>x #*/ +// /* +// * Option to switch on/off of stack traces. +// */ +// /* protect */ +//Clazz.tracingCalling = false; + +// /* private */ +// Clazz.callingStack = function (caller, owner) { +// this.caller = caller; +// this.owner = owner; +// }; + +/*# x<< #*/ + +/** + * The first folder is considered as the primary folder. + * And try to be compatiable with _Loader system. + */ +/* private */ + + +/*** not used in Jmol + * * +if (window["_Loader"] && _Loader.binaryFolders) { + Clazz.binaryFolders = _Loader.binaryFolders; +} else { + Clazz.binaryFolders = ["j2s/", "", "j2slib/"]; +} + +Clazz.addBinaryFolder = function (bin) { + if (bin) { + var bins = Clazz.binaryFolders; + for (var i = 0; i < bins.length; i++) { + if (bins[i] == bin) { + return ; + } + } + bins[bins.length] = bin; + } +}; +Clazz.removeBinaryFolder = function (bin) { + if (bin) { + var bins = Clazz.binaryFolders; + for (var i = 0; i < bins.length; i++) { + if (bins[i] == bin) { + for (var j = i; j < bins.length - 1; j++) { + bins[j] = bins[j + 1]; + } + bins.length--; + return bin; + } + } + } + return null; +}; +Clazz.setPrimaryFolder = function (bin) { + if (bin) { + Clazz.removeBinaryFolder (bin); + var bins = Clazz.binaryFolders; + for (var i = bins.length - 1; i >= 0; i--) { + bins[i + 1] = bins[i]; + } + bins[0] = bin; + } +}; + +***/ + + +///////////////// special definitions of standard Java class methods /////////// + +/** + * This is a simple implementation for Clazz#load. It just ignore dependencies + * of the class. This will be fine for jar *.z.js file. + * It will be overriden by _Loader#load. + * For more details, see _Loader.js + */ +/* protected */ +/* +Clazz.load = function (musts, clazz, optionals, declaration) { + // not used in Jmol + if (declaration) + declaration (); +}; +*/ + +/* + * Invade the Object prototype! + * TODO: make sure that invading Object prototype does not affect other + * existed library, such as Dojo, YUI, Prototype, ... + */ +java.lang.Object = Clazz._O; + +Clazz._O.getName = Clazz._innerFunctions.getName; + + +java.lang.System = System = { + props : null, //new java.util.Properties (), + $props : {}, + arraycopy : function (src, srcPos, dest, destPos, length) { + if (src !== dest) { + for (var i = 0; i < length; i++) { + dest[destPos + i] = src[srcPos + i]; + } + } else { + var swap = []; + for (var i = 0; i < length; i++) { + swap[i] = src[srcPos + i]; + } + for (var i = 0; i < length; i++) { + dest[destPos + i] = swap[i]; + } + } + }, + currentTimeMillis : function () { + return new Date ().getTime (); + }, + gc : function() {}, // bh + getProperties : function () { + return System.props; + }, + getProperty : function (key, def) { + if (System.props) + return System.props.getProperty (key, def); + var v = System.$props[key]; + if (typeof v != "undefined") + return v; + if (key.indexOf(".") > 0) { + v = null; + switch (key) { + case "java.version": + v = "1.6"; + case "file.separator": + case "path.separator": + v = "/"; + break; + case "line.separator": + v = (navigator.userAgent.indexOf("Windows") >= 0 ? "\r\n" : "\n"); + break; + case "os.name": + case "os.version": + v = navigator.userAgent; + break; + } + if (v) + return System.$props[key] = v; + } + return (arguments.length == 1 ? null : def == null ? key : def); // BH + }, + getSecurityManager : function() { return null }, // bh + setProperties : function (props) { + System.props = props; + }, + lineSeparator : function() { return '\n' }, // bh + setProperty : function (key, val) { + if (!System.props) + return System.$props[key] = val; // BH + System.props.setProperty (key, val); + } +}; + +System.identityHashCode=function(obj){ + if(obj==null) + return 0; + + return obj._$hashcode || (obj._$hashcode = ++Clazz._hashCode) + +/* + try{ + return obj.toString().hashCode(); + }catch(e){ + var str=":"; + for(var s in obj){ + str+=s+":" + } + return str.hashCode(); + } +*/ +} + +System.out = new Clazz._O (); +System.out.__CLASS_NAME__ = "java.io.PrintStream"; +System.out.print = function () {}; +System.out.printf = function () {}; +System.out.println = function () {}; +System.out.write = function () {}; + +System.err = new Clazz._O (); +System.err.__CLASS_NAME__ = "java.io.PrintStream"; +System.err.print = function () {}; +System.err.printf = function () {}; +System.err.println = function () {}; +System.err.write = function () {}; + +Clazz.popup = Clazz.assert = Clazz.log = Clazz.error = window.alert; + +Thread = function () {}; +Thread.J2S_THREAD = Thread.prototype.J2S_THREAD = new Thread (); +Thread.currentThread = Thread.prototype.currentThread = function () { + return this.J2S_THREAD; +}; + +/* not used in Jmol +Clazz.intCast = function (n) { // 32bit + var b1 = (n & 0xff000000) >> 24; + var b2 = (n & 0xff0000) >> 16; + var b3 = (n & 0xff00) >> 8; + var b4 = n & 0xff; + if ((b1 & 0x80) != 0) { + return -(((b1 & 0x7f) << 24) + (b2 << 16) + (b3 << 8) + b4 + 1); + } else { + return (b1 << 24) + (b2 << 16) + (b3 << 8) + b4; + } +}; +Clazz.shortCast = function (s) { // 16bit + var b1 = (n & 0xff00) >> 8; + var b2 = n & 0xff; + if ((b1 & 0x80) != 0) { + return -(((b1 & 0x7f) << 8) + b2 + 1); + } else { + return (b1 << 8) + b4; + } +}; + +Clazz.byteCast = function (b) { // 8bit + if ((b & 0x80) != 0) { + return -((b & 0x7f) + 1); + } else { + return b & 0xff; + } +}; + +Clazz.charCast = function (c) { // 8bit + return String.fromCharCode (c & 0xff).charAt (0); +}; + +Clazz.floatCast = function (f) { // 32bit + return f; +}; + +*/ + + +/* + * Try to fix JavaScript's shift operator defects on long type numbers. + */ + +/* not used in Jmol + +Clazz.longMasks = []; + +Clazz.longReverseMasks = []; + +Clazz.longBits = []; + +;(function () { + var arr = [1]; + for (var i = 1; i < 53; i++) { + arr[i] = arr[i - 1] + arr[i - 1]; // * 2 or << 1 + } + Clazz.longBits = arr; + Clazz.longMasks[52] = arr[52]; + for (var i = 51; i >= 0; i--) { + Clazz.longMasks[i] = Clazz.longMasks[i + 1] + arr[i]; + } + Clazz.longReverseMasks[0] = arr[0]; + for (var i = 1; i < 52; i++) { + Clazz.longReverseMasks[i] = Clazz.longReverseMasks[i - 1] + arr[i]; + } +}) (); + + +Clazz.longLeftShift = function (l, o) { // 64bit + if (o == 0) return l; + if (o >= 64) return 0; + if (o > 52) { + error ("[Java2Script] Error : JavaScript does not support long shift!"); + return l; + } + if ((l & Clazz.longMasks[o - 1]) != 0) { + error ("[Java2Script] Error : Such shift operator results in wrong calculation!"); + return l; + } + var high = l & Clazz.longMasks[52 - 32 + o]; + if (high != 0) { + return high * Clazz.longBits[o] + (l & Clazz.longReverseMasks[32 - o]) << 0; + } else { + return l << o; + } +}; + +Clazz.intLeftShift = function (n, o) { // 32bit + return (n << o) & 0xffffffff; +}; + +Clazz.longRightShift = function (l, o) { // 64bit + if ((l & Clazz.longMasks[52 - 32]) != 0) { + return Math.round((l & Clazz.longMasks[52 - 32]) / Clazz.longBits[32 - o]) + (l & Clazz.longReverseMasks[o]) >> o; + } else { + return l >> o; + } +}; + +Clazz.intRightShift = function (n, o) { // 32bit + return n >> o; // no needs for this shifting wrapper +}; + +Clazz.long0RightShift = function (l, o) { // 64bit + return l >>> o; +}; + +Clazz.int0RightShift = function (n, o) { // 64bit + return n >>> o; // no needs for this shifting wrapper +}; + +*/ +// Compress the common public API method in shorter name +//$_L=Clazz.load; +//$_W=Clazz.declareAnonymous;$_T=Clazz.declareType; +//$_J=Clazz.declarePackage;$_C=Clazz.decorateAsClass; +//$_Z=Clazz.instantialize;$_I=Clazz.declareInterface;$_D=Clazz.isClassDefined; +//$_H=Clazz.pu$h;$_P=Clazz.p0p;$_B=Clazz.prepareCallback; +//$_N=Clazz.innerTypeInstance;$_K=Clazz.makeConstructor;$_U=Clazz.superCall;$_R=Clazz.superConstructor; +//$_M=Clazz.defineMethod;$_V=Clazz.overrideMethod;$_S=Clazz.defineStatics; +//$_E=Clazz.defineEnumConstant; +//$_F=Clazz.cloneFinals; +//$_Y=Clazz.prepareFields;$_A=Clazz.newArray;$_O=Clazz.instanceOf; +//$_G=Clazz.inheritArgs;$_X=Clazz.checkPrivateMethod;$_Q=Clazz.makeFunction; +//$_s=Clazz.registerSerializableFields; +//$_k=Clazz.overrideConstructor; + + +/////////////////////// inner function support ///////////////////////////////// + +/* public */ +Clazz.innerFunctionNames = Clazz.innerFunctionNames.concat ([ + "getSuperclass", "isAssignableFrom", + "getConstructor", + "getDeclaredMethod", "getDeclaredMethods", + "getMethod", "getMethods", + "getModifiers", /*"isArray",*/ "newInstance"]); + +/* public */ +Clazz._innerFunctions.getSuperclass = function () { + return this.superClazz; +}; + +/* public */ +Clazz._innerFunctions.isAssignableFrom = function (clazz) { + return Clazz.getInheritedLevel (clazz, this) >= 0; +}; + +/* public */ +Clazz._innerFunctions.getConstructor = function () { + return new java.lang.reflect.Constructor (this, [], [], + java.lang.reflect.Modifier.PUBLIC); +}; +/** + * TODO: fix bug for polymorphic methods! + */ +/* public */ +Clazz._innerFunctions.getDeclaredMethods = Clazz._innerFunctions.getMethods = function () { + var ms = []; + var p = this.prototype; + for (var attr in p) { + if (typeof p[attr] == "function" && !p[attr].__CLASS_NAME__) { + /* there are polynormical methods. */ + ms.push(new java.lang.reflect.Method (this, attr, + [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC)); + } + } + p = this; + for (var attr in p) { + if (typeof p[attr] == "function" && !p[attr].__CLASS_NAME__) { + ms.push(new java.lang.reflect.Method (this, attr, + [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC + | java.lang.reflect.Modifier.STATIC)); + } + } + return ms; +}; +/* public */ +Clazz._innerFunctions.getDeclaredMethod = Clazz._innerFunctions.getMethod = function (name, clazzes) { + var p = this.prototype; + for (var attr in p) { + if (name == attr && typeof p[attr] == "function" + && !p[attr].__CLASS_NAME__) { + /* there are polynormical methods. */ + return new java.lang.reflect.Method (this, attr, + [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC); + } + } + p = this; + for (var attr in p) { + if (name == attr && typeof p[attr] == "function" + && !p[attr].__CLASS_NAME__) { + return new java.lang.reflect.Method (this, attr, + [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC + | java.lang.reflect.Modifier.STATIC); + } + } + return null; +}; +/* public */ +Clazz._innerFunctions.getModifiers = function () { + return java.lang.reflect.Modifier.PUBLIC; +}; + +Clazz._innerFunctions.newInstance = function (a) { + var clz = this; + switch(a == null ? 0 : a.length) { + case 0: + return new clz(); + case 1: + return new clz(a[0]); + case 2: + return new clz(a[0], a[1]); + case 3: + return new clz(a[0], a[1], a[2]); + case 4: + return new clz(a[0], a[1], a[2], a[3]); + default: + var x = "new " + clz.__CLASS_NAME__ + "("; + for (var i = 0; i < a.length; i++) + x += (i == 0 ? "" : ",") + "a[" + i + "]"; + x += ")"; + return eval(x); + } +}; + +//Object.newInstance = Clazz._innerFunctions.newInstance; +;(function(){ // BH added wrapper here + var inF = Clazz.innerFunctionNames; + for (var i = 0; i < inF.length; i++) { + Clazz._O[inF[i]] = Clazz._innerFunctions[inF[i]]; + Array[inF[i]] = Clazz._innerFunctions[inF[i]]; + } + //Array["isArray"] = function () { + // return true; + //}; +})(); + +//////////////////////////// hotspot and unloading ///////////////////////////// +/* For hotspot and unloading */ + +if (window["Clazz"] && !window["Clazz"].unloadClass) { + +/* public */ +Clazz.unloadClass = function (qClazzName) { + var cc = Clazz.evalType (qClazzName); + if (cc) { + Clazz.unloadedClasses[qClazzName] = cc; + var clazzName = qClazzName; + var pkgFrags = clazzName.split (/\./); + var pkg = null; + for (var i = 0; i < pkgFrags.length - 1; i++) + pkg = (pkg ? pkg[pkgFrags[i]] : Clazz.allPackage[pkgFrags[0]]); + if (!pkg) { + Clazz.allPackage[pkgFrags[0]] = null; + window[pkgFrags[0]] = null; + // also try to unload inner or anonymous classes + for (var c in window) { + if (c.indexOf (qClazzName + "$") == 0) { + Clazz.unloadClass (c); + window[c] = null; + } + } + } else { + pkg[pkgFrags[pkgFrags.length - 1]] = null; + // also try to unload inner or anonymous classes + for (var c in pkg) { + if (c.indexOf (pkgFrags[pkgFrags.length - 1] + "$") == 0) { + Clazz.unloadClass (pkg.__PKG_NAME__ + "." + c); + pkg[c] = null; + } + } + } + + if (Clazz.allClasses[qClazzName]) { + Clazz.allClasses[qClazzName] = false; + // also try to unload inner or anonymous classes + for (var c in Clazz.allClasses) { + if (c.indexOf (qClazzName + "$") == 0) { + Clazz.allClasses[c] = false; + } + } + } + + for (var m in cc) { + cleanDelegateMethod (cc[m]); + } + for (var m in cc.prototype) { + cleanDelegateMethod (cc.prototype[m]); + } + + if (Clazz._Loader) { + Clazz._Loader.unloadClassExt(qClazzName); + } + + return true; + } + return false; +}; + +/* private */ +var cleanDelegateMethod = function (m) { + if (!m) + return; + if (typeof m == "function" && m.lastMethod + && m.lastParams && m.lastClaxxRef) { + m.lastMethod = null; + m.lastParams = null; + m.lastClaxxRef = null; + } +}; + +} // if (window["Clazz"] && !window["Clazz"].unloadClass) + +/****************************************************************************** + * Copyright (c) 2007 java2script.org and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Zhou Renjian - initial API and implementation + *****************************************************************************/ +/******* + * @author zhou renjian + * @create July 10, 2006 + *******/ + +//if (window["ClazzNode"] == null) { +/** + * TODO: + * Make optimization over class dependency tree. + */ + +/* + * ClassLoader Summary + * + * ClassLoader creates SCRIPT elements and setup class path and onload + * callback to continue class loading. + * + * In the onload callbacks, _Loader will try to calculate the next-to-be- + * load *.js and load it. In *.js, it will contains some codes like + * Clazz.load (..., "$wt.widgets.Control", ...); + * to provide information to build up the class dependency tree. + * + * Some known problems of different browsers: + * 1. In IE, loading *.js through SCRIPT will first triggers onreadstatechange + * event, and then executes inner *.js source. + * 2. In Firefox, loading *.js will first executes *.js source and then + * triggers onload event. + * 3. In Opera, similar to IE, but trigger onload event. (TODO: More details + * should be studied. Currently, Opera supports no multiple-thread-loading) + * + * For class dependency tree, actually, it is not a tree. It is a reference + * net with nodes have n parents and n children. There is a root, which + * ClassLoader knows where to start searching and loading classes, for such + * a net. Each node is a class. Each class may require a set of must-classes, + * which must be loaded before itself getting initialized, and also need a set + * of optional classes, which also be loaded before being called. + * + * The class loading status will be in 6 stages. + * 1. Unknown, the class is newly introduced by other class. + * 2. Known, the class is already mentioned by other class. + * 3. Loaded, *.js source is in memory, but may not be initialized yet. It + * requires all its must-classes be intiailized, which is in the next stage. + * 4. Musts loaded, all must classes is already loaded and declared. + * 5. Delcared, the class is already declared (_Loader#isClassDefined). + * 6. Optionals loaded, all optional classes is loaded and declared. + * + * The ClassLoader tries to load all necessary classes in order, and intialize + * them in order. For such job, it will traverse the dependency tree, and try + * to next class to-be-loaded. Sometime, the class dependencies may be in one + * or more cycles, which must be broken down so classes is loaded in correct + * order. + * + * Loading order and intializing order is very important for the ClassLoader. + * The following technical options are considered: + * 1. SCRIPT is loading asynchronously, which means controling order must use + * callback methods to continue. + * 2. Multiple loading threads are later introduced, which requires the + * ClassLoader should use variables to record the class status. + * 3. Different browsers have different loading orders, which means extra tests + * should be tested to make sure loading order won't be broken. + * 4. Java2Script simulator itself have some loading orders that must be + * honored, which means it should be integrated seamlessly to Clazz system. + * 5. Packed *.z.js is introduced to avoid lots of small *.js which requires + * lots of HTTP connections, which means that packed *.z.js should be treated + * specially (There will be mappings for such packed classes). + * 6. *.js or *.css loading may fail according to network status, which means + * another loading try should be performed, so _Loader is more robust. + * 7. SWT lazy loading is later introduced, which means that class loading + * process may be paused and should be resumed later. + * + * Some known bugs: + * $_L(["$wt.graphics.Drawable","$wt.widgets.Widget"], + * "$wt.widgets.Control", ... + * has errors while must classes in different order such as + * $_L(["$wt.widgets.Widget", "$wt.graphics.Drawable"], + * "$wt.widgets.Control", ... + * has no error. + * + * Other maybe bug scenarios: + * 1. In _Loader.maxLoadingThreads = 1; single loading thread + * mode, there are no errors, but in default multiple thread loading mode, + * there are errors. + * 2. No errors in one browser, but has errors on other browsers (Browser + * script loading order differences). + * 3. First time loading has errors, but reloading it gets no errors (Maybe + * HTTP connections timeout, but should not accur in local file system, or it + * is a loading bug by using JavaScript timeout thread). + */ + +/* + * The following comments with "#" are special configurations for a much + * smaller *.js file size. + * + * @see net.sf.j2s.lib/src/net/sf/j2s/lib/build/SmartJSCompressor.java + */ +/** + * Static class loader class + */ +Clazz._Loader = Clazz.ClazzLoader = function () {}; + +/** + * Class dependency tree node + */ +/* private */ +var Node = function () { + this.parents = []; + this.musts = []; + this.optionals = []; + this.declaration = null; + this.name = null; // id + this.path = null; +// this.requires = null; +// this.requiresMap = null; + this.onLoaded = null; + this.status = 0; + this.random = 0.13412; +}; + + +;(function(Clazz, _Loader) { + +_Loader._checkLoad = Jmol._checkLoad; + +_Loader.updateNodeForFunctionDecoration = function(qName) { + var node = findNode(qName); + if (node && node.status == Node.STATUS_KNOWN) { + window.setTimeout((function(nnn) { + return function() { + updateNode(nnn); + }; + })(node), 1); + } +} + +Node.prototype.toString = function() { + return this.name || this.path || "ClazzNode"; +} + +Node.STATUS_UNKNOWN = 0; +Node.STATUS_KNOWN = 1; +Node.STATUS_CONTENT_LOADED = 2; +Node.STATUS_MUSTS_LOADED = 3; +Node.STATUS_DECLARED = 4; +Node.STATUS_LOAD_COMPLETE = 5; + + +var loaders = []; + +/* public */ +_Loader.requireLoaderByBase = function (base) { + for (var i = 0; i < loaders.length; i++) { + if (loaders[i].base == base) { + return loaders[i]; + } + } + var loader = new _Loader (); + loader.base = base; + loaders.push(loader); + return loader; +}; + +/** + * Class dependency tree + */ +var clazzTreeRoot = new Node(); + +/** + * Used to keep the status whether a given *.js path is loaded or not. + */ +/* private */ +var loadedScripts = {}; + +/** + * Multiple threads are used to speed up *.js loading. + */ +/* private */ +var inLoadingThreads = 0; + +/** + * Maximum of loading threads + */ +/* private */ +var maxLoadingThreads = 6; + +var userAgent = navigator.userAgent.toLowerCase (); +var isOpera = (userAgent.indexOf ("opera") != -1); +var isIE = (userAgent.indexOf ("msie") != -1) && !isOpera; +var isGecko = (userAgent.indexOf ("gecko") != -1); + +/* + * Opera has different loading order which will result in performance degrade! + * So just return to single thread loading in Opera! + * + * FIXME: This different loading order also causes bugs in single thread! + */ +if (isOpera) { + maxLoadingThreads = 1; + var index = userAgent.indexOf ("opera/"); + if (index != -1) { + var verNumber = 9.0; + try { + verNumber = parseFloat(userAgent.subString (index + 6)); + } catch (e) {} + if (verNumber >= 9.6) { + maxLoadingThreads = 6; + } + } +} + +/** + * Try to be compatiable with Clazz system. + * In original design _Loader and Clazz are independent! + * -- zhourenjian @ December 23, 2006 + */ +var isClassdefined; +var definedClasses; + +if (self.Clazz && Clazz.isClassDefined) { + isClassDefined = Clazz.isClassDefined; +} else { + definedClasses = {}; + isClassDefined = function (clazzName) { + return definedClasses[clazzName] == true; + }; +} + +/** + * Expand the shortened list of class names. + * For example: + * JU.Log, $.Display, $.Decorations + * will be expanded to + * JU.Log, JU.Display, JU.Decorations + * where "$." stands for the previous class name's package. + * + * This method will be used to unwrap the required/optional classes list and + * the ignored classes list. + */ +/* private */ +var unwrapArray = function (arr) { + if (!arr || arr.length == 0) + return []; + var last = null; + for (var i = 0; i < arr.length; i++) { + if (!arr[i]) + continue; + if (arr[i].charAt (0) == '$') { + if (arr[i].charAt (1) == '.') { + if (!last) + continue; + var idx = last.lastIndexOf ("."); + if (idx != -1) { + var prefix = last.substring (0, idx); + arr[i] = prefix + arr[i].substring (1); + } + } else { + arr[i] = "org.eclipse.s" + arr[i].substring (1); + } + } + last = arr[i]; + } + return arr; +}; + +/** + * Used to keep to-be-loaded classes. + */ +/* private */ +var classQueue = []; + +/* private */ +var classpathMap = {}; + +/* private */ +var pkgRefCount = 0; + +/* public */ +_Loader.loadPackageClasspath = function (pkg, base, isIndex, fSuccess, mode, pt) { + var map = classpathMap; + mode || (mode = 0); + fSuccess || (fSuccess = null); + pt || (pt = 0); + + /* + * In some situation, maybe, + * _Loader.packageClasspath ("java", ..., true); + * is called after other _Loader#packageClasspath, e.g. + * + * _Loader.packageClasspath ("org.eclipse.swt", "...", true); + * _Loader.packageClasspath ("java", "...", true); + * + * which is not recommended. But _Loader should try to adjust orders + * which requires "java" to be declared before normal _Loader + * #packageClasspath call before that line! And later that line + * should never initialize "java/package.js" again! + */ + var isPkgDeclared = (isIndex && map["@" + pkg]); + if (mode == 0 && isIndex && !map["@java"] && pkg.indexOf ("java") != 0 && needPackage("java")) { + _Loader.loadPackage("java", fSuccess ? function(_package){_Loader.loadPackageClasspath(pkg, base, isIndex, fSuccess, 1)} : null); + if (fSuccess) + return; + } + if (pkg instanceof Array) { + unwrapArray(pkg); + if (fSuccess) { + if (pt < pkg.length) + _Loader.loadPackageClasspath(pkg[pt], base, isIndex, function(_loadPackageClassPath){_Loader.loadPackageClasspath(pkg, base, isIndex, fSuccess, 1, pt + 1)}, 1); + else + fSuccess(); + } else { + for (var i = 0; i < pkg.length; i++) + _Loader.loadPackageClasspath(pkg[i], base, isIndex, null); + } + return; + } + switch (pkg) { + case "java.*": + pkg = "java"; + // fall through + case "java": + if (base) { + // support ajax for default + var key = "@net.sf.j2s.ajax"; + if (!map[key]) + map[key] = base; + key = "@net.sf.j2s"; + if (!map[key]) + map[key] = base; + } + break; + case "swt": + pkg = "org.eclipse.swt"; + break; + case "ajax": + pkg = "net.sf.j2s.ajax"; + break; + case "j2s": + pkg = "net.sf.j2s"; + break; + default: + if (pkg.lastIndexOf(".*") == pkg.length - 2) + pkg = pkg.substring(0, pkg.length - 2); + break; + } + if (base) // critical for multiple applets + map["@" + pkg] = base; + if (isIndex && !isPkgDeclared && !window[pkg + ".registered"]) { + pkgRefCount++; + if (pkg == "java") + pkg = "core" // JSmol -- moves java/package.js to core/package.js + _Loader.loadClass(pkg + ".package", function () { + if (--pkgRefCount == 0) + runtimeLoaded(); + //fSuccess && fSuccess(); + }, true, true, 1); + return; + } + fSuccess && fSuccess(); +}; + +/** + * BH: allows user/developer to load classes even though wrapping and Google + * Closure Compiler has not been run on the class. + * + */ +Clazz.loadClass = function (name, onLoaded, async) { + if (!self.Class) { + Class = Clazz; + Class.forName = Clazz._4Name; + JavaObject = Clazz._O; + // maybe more here + } + return (name && _Loader.loadClass(name, onLoaded, true, async, 1)); +} + +/** + * Load the given class ant its related classes. + */ +/* public */ +_Loader.loadClass = function (name, onLoaded, forced, async, mode) { + + mode || (mode = 0); // BH: not implemented + (async == null) && (async = false); + + if (typeof onLoaded == "boolean") + return Clazz.evalType(name); + + System.out.println("loadClass " + name) + + // Make sure that packageClasspath ("java", base, true); + // is called before any _Loader#loadClass is called. + + if (needPackage("java")) + _Loader.loadPackage("java"); + if (needPackage("core")) + _Loader.loadPackage("core"); + +// var swtPkg = "org.eclipse.swt"; +// if (name.indexOf (swtPkg) == 0 || name.indexOf ("$wt") == 0) { +// _Loader.assurePackageClasspath (swtPkg); +// } +// if (name.indexOf ("junit") == 0) { +// _Loader.assurePackageClasspath ("junit"); +// } + + // Any _Loader#loadClass calls will be queued until java.* core classes are loaded. + + _Loader.keepOnLoading = true; + + if (!forced && (pkgRefCount && name.lastIndexOf(".package") != name.length - 8 + || name.indexOf("java.") != 0 && !isClassDefined(runtimeKeyClass) + )) { + queueBe4KeyClazz.push([name, onLoaded]); + + + System.out.println("loadclass-queuing" + name+ runtimeKeyClass + " "+ isClassDefined(runtimeKeyClass)) + + return; + } + var b; + if ((b = isClassDefined(name)) || isClassExcluded(name)) { + if (b && onLoaded) { + var nn = findNode(name); + if (!nn || nn.status >= Node.STATUS_LOAD_COMPLETE) { + if (async) { + window.setTimeout(onLoaded, 25); + } else { + onLoaded(); + } + } + } + return; + } + var path = _Loader.getClasspathFor(name); + var existed = loadedScripts[path]; + var qq = classQueue; + if (!existed) + for (var i = qq.length; --i >= 0;) + if (qq[i].path == path || qq[i].name == name) { + existed = true; + break; + } + if (existed) { + if (onLoaded) { + var n = findNode(name); + if (n) { + if (!n.onLoaded) { + n.onLoaded = onLoaded; + } else if (onLoaded != n.onLoaded) { + n.onLoaded = (function (nF, oF) { return function () { nF(); oF() }; }) (n.onLoaded, onLoaded); + } + } + } + return; + } + + var n = (Clazz.unloadedClasses[name] && findNode(name) || new Node()); + n.name = name; + n.path = path; + n.isPackage = (path.lastIndexOf("package.js") == path.length - 10); + mappingPathNameNode(path, name, n); + n.onLoaded = onLoaded; + n.status = Node.STATUS_KNOWN; + var needBeingQueued = false; + for (var i = qq.length; --i >= 0;) { + if (qq[i].status != Node.STATUS_LOAD_COMPLETE) { + needBeingQueued = true; + break; + } + } + + if (n.isPackage) {//forced + // push class to queue + var pt = qq.length; + for (; --pt >= 0;) { + if (qq[pt].isPackage) + break; + qq[pt + 1] = qq[pt]; + } + qq[++pt] = n; + } else if (needBeingQueued) { + qq.push(n); + } + if (!needBeingQueued) { // can be loaded directly + var bSave = false; + if (onLoaded) { + bSave = isLoadingEntryClass; + isLoadingEntryClass = true; + } + if (forced)onLoaded = null; + addChildClassNode(clazzTreeRoot, n, true); + loadScript(n, n.path, n.requiredBy, false, onLoaded ? function(_loadClass){ isLoadingEntryClass = bSave; onLoaded()}: null); + } +}; + +/* + * Check whether given package's classpath is setup or not. + * Only "java" and "org.eclipse.swt" are accepted in argument. + */ +/* private */ +var needPackage = function(pkg) { + // note that false != null and true != null + return (window[pkg + ".registered"] != null && !classpathMap["@" + pkg]); +} + +/* private */ +_Loader.loadPackage = function(pkg, fSuccess) { + fSuccess || (fSuccess = null); + window[pkg + ".registered"] = false; + _Loader.loadPackageClasspath(pkg, + (_Loader.J2SLibBase || (_Loader.J2SLibBase = (_Loader.getJ2SLibBase() || "j2s/"))), + true, fSuccess); +}; + +/** + * Register classes to a given *.z.js path, so only a single *.z.js is loaded + * for all those classes. + */ +/* public */ +_Loader.jarClasspath = function (jar, clazzes) { + if (!(clazzes instanceof Array)) + clazzes = [classes]; + unwrapArray(clazzes); + for (var i = clazzes.length; --i >= 0;) + classpathMap["#" + clazzes[i]] = jar; + classpathMap["$" + jar] = clazzes; +}; + +/** + * Usually be used in .../package.js. All given packages will be registered + * to the same classpath of given prefix package. + */ +/* public */ +_Loader.registerPackages = function (prefix, pkgs) { + //_Loader.checkInteractive (); + var base = _Loader.getClasspathFor (prefix + ".*", true); + for (var i = 0; i < pkgs.length; i++) { + if (window["Clazz"]) { + Clazz.declarePackage (prefix + "." + pkgs[i]); + } + _Loader.loadPackageClasspath (prefix + "." + pkgs[i], base); + } +}; + +/** + * Using multiple sites to load *.js in multiple threads. Using multiple + * sites may avoid 2 HTTP 1.1 connections recommendation limit. + * Here is a default implementation for http://archive.java2script.org. + * In site archive.java2script.org, there are 6 sites: + * 1. http://archive.java2script.org or http://a.java2script.org + * 2. http://erchive.java2script.org or http://e.java2script.org + * 3. http://irchive.java2script.org or http://i.java2script.org + * 4. http://orchive.java2script.org or http://o.java2script.org + * 5. http://urchive.java2script.org or http://u.java2script.org + * 6. http://yrchive.java2script.org or http://y.java2script.org + */ +/* protected */ + /* +_Loader.multipleSites = function (path) { + var deltas = window["j2s.update.delta"]; + if (deltas && deltas instanceof Array && deltas.length >= 3) { + var lastOldVersion = null; + var lastNewVersion = null; + for (var i = 0; i < deltas.length / 3; i++) { + var oldVersion = deltas[i + i + i]; + if (oldVersion != "$") { + lastOldVersion = oldVersion; + } + var newVersion = deltas[i + i + i + 1]; + if (newVersion != "$") { + lastNewVersion = newVersion; + } + var relativePath = deltas[i + i + i + 2]; + var key = lastOldVersion + "/" + relativePath; + var idx = path.indexOf (key); + if (idx != -1 && idx == path.length - key.length) { + path = path.substring (0, idx) + lastNewVersion + "/" + relativePath; + break; + } + } + } + var length = path.length; + if (maxLoadingThreads > 1 + && ((length > 15 && path.substring (0, 15) == "http://archive.") + || (length > 9 && path.substring (0, 9) == "http://a."))) { + var index = path.lastIndexOf("/"); + if (index < length - 3) { + var arr = ['a', 'e', 'i', 'o', 'u', 'y']; + var c1 = path.charCodeAt (index + 1); + var c2 = path.charCodeAt (index + 2); + var idx = (length - index) * 3 + c1 * 5 + c2 * 7; // Hash + return path.substring (0, 7) + arr[idx % 6] + path.substring (8); + } + } + return path; +}; + */ + +/** + * Return the *.js path of the given class. Maybe the class is contained + * in a *.z.js jar file. + * @param clazz Given class that the path is to be calculated for. May + * be java.package, or java.lang.String + * @param forRoot Optional argument, if true, the return path will be root + * of the given classs' package root path. + * @param ext Optional argument, if given, it will replace the default ".js" + * extension. + */ +/* public */ +_Loader.getClasspathFor = function (clazz, forRoot, ext) { + var path = classpathMap["#" + clazz]; + if (!path || forRoot || ext) { + var base; + var idx; + if (path) { + clazz = clazz.replace(/\./g, "/"); + if ((idx = path.lastIndexOf(clazz)) >= 0 + || (idx = clazz.lastIndexOf("/")) >= 0 + && (idx = path.lastIndexOf(clazz.substring(0, idx))) >= 0) + base = path.substring(0, idx); + } else { + idx = clazz.length + 2; + while ((idx = clazz.lastIndexOf(".", idx - 2)) >= 0) + if ((base = classpathMap["@" + clazz.substring(0, idx)])) + break; + if (!forRoot) + clazz = clazz.replace (/\./g, "/"); + } + if (base == null) { + var bins = "binaryFolders"; + base = (window["Clazz"] && Clazz[bins] && Clazz[bins].length ? Clazz[bins][0] + : _Loader[bins] && _Loader[bins].length ? _Loader[bins][0] + : "j2s"); + } + path = (base.lastIndexOf("/") == base.length - 1 ? base : base + "/") + (forRoot ? "" + : clazz.lastIndexOf("/*") == clazz.length - 2 ? clazz.substring(0, idx + 1) + : clazz + (!ext ? ".js" : ext.charAt(0) != '.' ? "." + ext : ext)); + } + return path;//_Loader.multipleSites(path); +}; + +/** + * To ignore some classes. + */ +/* public */ +_Loader.ignore = function () { + var clazzes = (arguments.length == 1 && arguments[0] instanceof Array ? + clazzes = arguments[0] : null); + var n = (clazzes ? clazzes.length : arguments.length); + if (!clazzes) { + clazzes = new Array(n); + for (var i = 0; i < n; i++) + clazzes[i] = arguments[i]; + } + unwrapArray(clazzes); + for (var i = 0; i < n; i++) + excludeClassMap["@" + clazzes[i]] = 1; +}; + +/** + * The following *.script* can be overriden to indicate the + * status of classes loading. + * + * TODO: There should be a Java interface with name like INativeLoaderStatus + */ +/* public */ +_Loader.onScriptLoading = function (file){}; + +/* public */ +_Loader.onScriptLoaded = function (file, isError){}; + +/* public */ +_Loader.onScriptInitialized = function (file){}; + +/* public */ +_Loader.onScriptCompleted = function (file){}; + +/* public */ +_Loader.onClassUnloaded = function (clazz){}; + +/** + * After all the classes are loaded, this method will be called. + * Should be overriden to run *.main([]). + */ +/* public */ +_Loader.onGlobalLoaded = function () {}; + +/* public */ +_Loader.keepOnLoading = true; // never set false in this code + + +/* private */ +var mapPath2ClassNode = {}; + +/* private */ +var isClassExcluded = function (clazz) { + return excludeClassMap["@" + clazz]; +}; + +/* Used to keep ignored classes */ +/* private */ +var excludeClassMap = {}; + +/* private */ +var evaluate = function(file, file0, js) { + try { + eval(js + ";//# sourceURL="+file); + } catch (e) { + if (Clazz._isQuiet) + return; + var s = "[Java2Script] The required class file \n\n" + file + (js.indexOf("[Exception") == 0 && js.indexOf("data: no") ? + "\nwas not found.\n" + : "\ncould not be loaded. Script error: " + e.message + " \n\ndata:\n\n" + js) + "\n\n" + Clazz.getStackTrace(); + alert(s) + Clazz.alert(s); + throw e; + } + _Loader.onScriptLoaded(file, false); + tryToLoadNext(file0); +} + +/* private */ +var failedHandles = {}; + +/* private */ +var generateRemovingFunction = function (node) { + return function () { + if (node.readyState != "interactive") { + try { + if (node.parentNode) + node.parentNode.removeChild (node); + } catch (e) { } + node = null; + } + }; +}; + +/* private */ +var removeScriptNode = function (n) { + if (window["j2s.script.debugging"]) { + return; + } + // lazily remove script nodes. + window.setTimeout (generateRemovingFunction (n), 1); +}; + +/* public */ +Clazz._4Name = function(clazzName, applet, state) { + if (Clazz.isClassDefined(clazzName)) + return Clazz.evalType(clazzName); + var f = (Jmol._isAsync && applet ? applet._restoreState(clazzName, state) : null); + if (f == 1) + return null; // must be already being created + if (_Loader.setLoadingMode(f ? _Loader.MODE_SCRIPT : "xhr.sync")) { + _Loader.loadClass(clazzName, f, false, true, 1); + return null; // this will surely throw an error, but that is OK + } + //alert ("Using Java reflection: " + clazzName + " for " + applet._id + " \n"+ Clazz.getStackTrace()); + _Loader.loadClass(clazzName); + return Clazz.evalType(clazzName); +}; + +/** + * BH: possibly useful for debugging + */ +Clazz.currentPath= ""; + +/** + * Load *.js by adding script elements into head. Hook the onload event to + * load the next class in dependency tree. + */ +/* private */ +var loadScript = function (node, file, why, ignoreOnload, fSuccess, _loadScript) { + + Clazz.currentPath = file; + if (ignoreOnload)alert("WHY>>") +//BH removed // maybe some scripts are to be loaded without needs to know onload event. +// if (!ignoreOnload && loadedScripts[file]) { +// _Loader.tryToLoadNext(file); +// return; +// } + loadedScripts[file] = true; + // also remove from queue + removeArrayItem(classQueue, file); + + // forces not-found message + isUsingXMLHttpRequest = true; + isAsynchronousLoading = false; + if (_Loader._checkLoad) { + System.out.println("\t" + file + (why ? "\n -- required by " + why : "") + " ajax=" + isUsingXMLHttpRequest + " async=" + isAsynchronousLoading) + } + + var file0 = file; + if (Clazz._debugging) { + file = file.replace(/\.z\.js/,".js"); + } + + _Loader.onScriptLoading(file); + if (isUsingXMLHttpRequest && !isAsynchronousLoading) { + // alert("\t" + file + (why ? "\n -- required by " + why : "") + " ajax=" + isUsingXMLHttpRequest + " async=" + isAsynchronousLoading + " " + Clazz.getStackTrace()) + // synchronous loading + // works in MSIE locally unless a binary file :) + // from Jmol.api.Interface only + var data = Jmol._getFileData(file); + try{ + evaluate(file, file0, data); + }catch(e) { + alert(e + " loading file " + file + " " + node.name + " " + Clazz.getStackTrace()); + } + if (fSuccess) { +// System.out.println("firing in loadScript " + file + " " + (fSuccess && fSuccess.toString())) + fSuccess(); + } + return; + } + + +System.out.println("for file " + file +" fSuccess = " + (fSuccess ? fSuccess.toString() : "")) + var info = { + dataType:"script", + async:true, + type:"GET", + url:file, + success:W3CScriptOnCallback(file, false, fSuccess), + error:W3CScriptOnCallback(file, true, fSuccess) + }; + inLoadingThreads++; + Jmol.$ajax(info); +}; + +/* private */ +var W3CScriptOnCallback = function (path, forError, fSuccess) { + var s = Clazz.getStackTrace(); + // if (!fSuccess)alert("why no fSuccess?" + s) + return function () { + //System.out.println("returning " + (fSuccess ? fSuccess.toString() : "no function ") + s) + if (forError && __debuggingBH)Clazz.alert ("############ forError=" + forError + " path=" + path + " ####" + (forError ? "NOT" : "") + "LOADED###"); + if (isGecko && this.timeoutHandle) + window.clearTimeout(this.timeoutHandle), this.timeoutHandle = null; + if (inLoadingThreads > 0) + inLoadingThreads--; + //System.out.println("w3ccalback for " + path + " " + inLoadingThreads + " threads") + this.onload = null; + this.onerror = null; + if (forError) + alert ("There was a problem loading " + path); + _Loader.onScriptLoaded(path, true); + var node = this; + var f; + if (fSuccess) + f = function(_W3scriptFS){removeScriptNode(node);tryToLoadNext(path, fSuccess); }; + else + f = function(_W3script){removeScriptNode(node);tryToLoadNext(path)}; + if (loadingTimeLag >= 0) + window.setTimeout(function() { tryToLoadNext(path, f); }, loadingTimeLag); + else + tryToLoadNext(path, f); + }; +}; + +/* private */ +var isLoadingEntryClass = true; + +/* private */ +var besidesJavaPackage = false; + +/** + * After class is loaded, this method will be executed to check whether there + * are classes in the dependency tree that need to be loaded. + */ +/* private */ +var tryToLoadNext = function (file, fSuccess) { + var node = mapPath2ClassNode["@" + file]; + if (!node) // maybe class tree root + return; + var n; + // check for content loaded + var clazzes = classpathMap["$" + file]; + if (clazzes) { + for (var i = 0; i < clazzes.length; i++) { + var name = clazzes[i]; + if (name != node.name && (n = findNode(name))) { + if (n.status < Node.STATUS_CONTENT_LOADED) { + n.status = Node.STATUS_CONTENT_LOADED; + updateNode(n); + } + } else { + n = new Node(); + n.name = name; + var pp = classpathMap["#" + name]; + if (!pp) { + alert (name + " J2S error in tryToLoadNext"); + error("Java2Script implementation error! Please report this bug!"); + } + n.path = pp; + mappingPathNameNode (n.path, name, n); + n.status = Node.STATUS_CONTENT_LOADED; + addChildClassNode(clazzTreeRoot, n, false); + updateNode(n); + } + } + } + if (node instanceof Array) { + for (var i = 0; i < node.length; i++) { + if (node[i].status < Node.STATUS_CONTENT_LOADED) { + node[i].status = Node.STATUS_CONTENT_LOADED; + updateNode(node[i]); + } + } + } else if (node.status < Node.STATUS_CONTENT_LOADED) { + var stillLoading = false; + var ss = document.getElementsByTagName ("SCRIPT"); + for (var i = 0; i < ss.length; i++) { + if (isIE) { + if (ss[i].onreadystatechange && ss[i].onreadystatechange.path == node.path + && ss[i].readyState == "interactive") { + stillLoading = true; + break; + } + } else if (ss[i].onload && ss[i].onload.path == node.path) { + stillLoading = true; + break; + } + } + if (!stillLoading) { + node.status = Node.STATUS_CONTENT_LOADED; + updateNode(node); + } + } + /* + * Maybe in #optinalLoaded inside above _Loader#updateNode calls, + * _Loader.keepOnLoading is set false (Already loaded the wanted + * classes), so here check to stop. + */ + + if (!_Loader.keepOnLoading) // set externally + return; + + // check for a "must" class that has content and load it + var cq; + var working = true; + if ((n = findNextMustClass(Node.STATUS_KNOWN))) { + loadClassNode(n); + while (inLoadingThreads < maxLoadingThreads) { + if (!(n = findNextMustClass(Node.STATUS_KNOWN))) + break; + loadClassNode(n); // will increase inLoadingThreads! + } + } else if ((cq = classQueue).length != 0) { + /* queue must be loaded in order! */ + n = cq.shift(); + if (!loadedScripts[n.path] + || cq.length != 0 + || !isLoadingEntryClass + || n.musts.length + || n.optionals.length) { + addChildClassNode(clazzTreeRoot, n, true); + loadScript(n, n.path, n.requiredBy, false); + } else if (isLoadingEntryClass) { + /* + * The first time reaching here is the time when ClassLoader + * is trying to load entry class. Class with #main method and + * is to be executed is called Entry Class. + * + * Here when loading entry class, ClassLoader should not call + * the next following loading script. This is because, those + * scripts will try to mark the class as loaded directly and + * then continue to call #onLoaded callback method, + * which results in an script error! + */ + isLoadingEntryClass = false; + } + } else if ((n = findNextRequiredClass(Node.STATUS_KNOWN))) { + loadClassNode(n); + while (inLoadingThreads < maxLoadingThreads) { + if (!(n = findNextRequiredClass(Node.STATUS_KNOWN))) + break; + loadClassNode(n); // will increase inLoadingThreads! + } + } else { + working = false; + } + if (working || inLoadingThreads > 0) + return; + // + // now check all classes that MUST be loaded prior to initialization + // of some other class (static calls, extends, implements) + // and all classes REQUIRED somewhere in that class, possibly by the constructor + // (that is, "new xxxx()" called somewhere in code) and update them + // that have content but are not declared already + var f = [findNextMustClass,findNextRequiredClass]; + var lastNode = null; + for (var i = 0; i < 2; i++) + while ((n = f[i](Node.STATUS_CONTENT_LOADED))) { + if (i == 1 && lastNode === n) // Already existed cycle ? + n.status = Node.STATUS_LOAD_COMPLETE; + updateNode(n); + lastNode = n; + } + + // check for load cycles + + while (true) { + tracks = []; + if (!checkCycle(clazzTreeRoot, file)) + break; + } + + // and update all MUST and REQUIRED classes that are declared already + + for (var i = 0; i < 2; i++) { + lastNode = null; + while ((n = f[i](Node.STATUS_DECLARED))) { + if (lastNode === n) + break; + updateNode(lastNode = n); + } + } + var done = []; + for (var i = 0; i < 2; i++) + while ((n = f[i](Node.STATUS_DECLARED))) + done.push(n), n.status = Node.STATUS_LOAD_COMPLETE; + if (done.length) { + for (var i = 0; i < done.length; i++) + destroyClassNode(done[i]); + for (var i = 0; i < done.length; i++) + if ((f = done[i].onLoaded)) + done[i].onLoaded = null, f(); + } + + + + + + + + //System.out.println(node.name + " loaded completely" + _Loader.onGlobalLoaded + "\n\n") + if (fSuccess) { + //System.out.println("tryToLoadNext firing " + _Loader._classCountOK + "/" + _Loader._classCountPending + " " + fSuccess.toString() + " " + Clazz.getStackTrace()) + fSuccess(); + } else if (_Loader._classCountPending) { + for (var name in _Loader._classPending) { + var n = findNode(name); + System.out.println("class left pending " + name + " " + n); + if (n) { + updateNode(n); + break; + } + } + } else { + + // System.out.println("I think I'm done " + // + _Loader._classCountOK + "/" + _Loader._classCountPending + " " + //+ _Loader.onGlobalLoaded.toString() + " " + Clazz.getStackTrace() + // ) + if (_Loader._checkLoad) { + System.out.println("I think I'm done: SAEM call count: " + SAEMid); + Clazz.showDuplicates(true); + } + } + _Loader.onGlobalLoaded(); +}; + + +var tracks = []; + +/* + * There are classes reference cycles. Try to detect and break those cycles. + */ +/* private */ +var checkCycle = function (node, file) { + var ts = tracks; + var len = ts.length; + // add this node to tracks + ts.push(node); + var i = len; + for (; --i >= 0;) + if (ts[i] === node && ts[i].status >= Node.STATUS_DECLARED) + break; + if (i >= 0) { + // this node is already in tracks, and it has been declared already + // for each node in tracks, set its status to "LOAD_COMPLETE" + // update all parents, remove all parents, and fire its onLoaded function + // then clear tracks and return true (keep checking) + if (_Loader._checkLoad) { + var msg = "cycle found loading " + file + " for " + node; + System.out.println(msg) + } + for (; i < len; i++) { + var n = ts[i]; + n.status = Node.STATUS_LOAD_COMPLETE; + destroyClassNode(n); // Same as above + for (var k = 0; k < n.parents.length; k++) + updateNode(n.parents[k]); + n.parents = []; + var f = n.onLoaded; + if (_Loader._checkLoad) { + var msg = "cycle setting status to LOAD_COMPLETE for " + n.name + (f ? " firing " + f.toString() : ""); + System.out.println(msg) + } + if (f) + n.onLoaded = null, f(); + } + ts.length = 0; + return true; + } + var a = [node.musts, node.optionals]; + for (var j = 0; j < 2; j++) + for (var r = a[j], i = r.length; --i >= 0;) + if (r[i].status == Node.STATUS_DECLARED && checkCycle(r[i], file)) + return true; + // reset _tracks to its original length + ts.length = len; + return false; // done +}; + + +_Loader._classCountPending = 0; +_Loader._classCountOK = 0; +_Loader._classPending = {}; + +_Loader.showPending = function() { + var a = []; + for (var name in _Loader._classPending) { + var n = findNode(name); + if (!n) { + alert("No node for " + name); + continue; + } + a.push(n); + System.out.println(showNode("", "", n, "", 0)); + } + return a; +} + +var showNode = function(s, names, node, inset, level) { + names += "--" + node.name; + s += names + "\n"; + if (level > 5) { + s += inset + " ...\n"; + return s; + } + inset += "\t"; + s += inset + "status: " + node.status + "\n"; + if (node.parents && node.parents.length && node.parents[0] && node.parents[0].name) { + s += inset + "parents: " + node.parents.length + "\n"; + for (var i = 0; i < node.parents.length; i++) { + s = showNode(s, names, node.parents[i], inset + "\t", level+1); + } + s += "\n"; + } +// if (node.requiredBy) { +// s += inset + "requiredBy:\n"; +// s = showNode(s, names, node.requiredBy, inset + "\t", level+1); +// s += "\n"; +// } + return s; +} + +/** + * Update the dependency tree nodes recursively. + */ +/* private */ +updateNode = function(node, _updateNode) { + if (!node.name || node.status >= Node.STATUS_LOAD_COMPLETE) { + destroyClassNode(node); + return; + } + var ready = true; + // check for declared and also having MUSTS + if (node.musts.length && node.declaration) { + for (var mustLength = node.musts.length, i = mustLength; --i >= 0;) { + var n = node.musts[i]; + n.requiredBy = node; + if (n.status < Node.STATUS_DECLARED && isClassDefined (n.name)) { + var nns = []; // a stack for onLoaded events + n.status = Node.STATUS_LOAD_COMPLETE; + destroyClassNode(n); // Same as above + if (n.declaration && n.declaration.clazzList) { + // For those classes within one *.js file, update them synchronously. + for (var j = 0, list = n.declaration.clazzList, l = list.length; j < l; j++) { + var nn = findNode (list[j]); + if (nn && nn.status != Node.STATUS_LOAD_COMPLETE + && nn !== n) { + nn.status = n.status; + nn.declaration = null; + destroyClassNode(nn); + nn.onLoaded && nns.push(nn); + } + } + n.declaration = null; + } + // fire all onLoaded events + if (n.onLoaded) + nns.push(n); + for (var j = 0; j < nns.length; j++) { + var onLoaded = nns[j].onLoaded; + if (onLoaded) { + nns[j].onLoaded = null; + onLoaded(); + } + } + } else { + (n.status == Node.STATUS_CONTENT_LOADED) && updateNode(n); // musts may be changed + if (n.status < Node.STATUS_DECLARED) + ready = false; + } + if (node.musts.length != mustLength) { + // length changed -- restart! + i = mustLength = node.musts.length; + ready = true; + } + } + } + if (!ready) + return; + if (node.status < Node.STATUS_DECLARED) { + var decl = node.declaration; + if (decl) + decl(), decl.executed = true; + if(_Loader._checkLoad) { + if (_Loader._classPending[node.name]) { + delete _Loader._classPending[node.name]; + _Loader._classCountOK; + _Loader._classCountPending--; +// System.out.println("OK " + (_Loader._classCountOK) + " FOR " + node.name) + } + } + node.status = Node.STATUS_DECLARED; + if (definedClasses) + definedClasses[node.name] = true; + _Loader.onScriptInitialized(node.path); + if (node.declaration && node.declaration.clazzList) { + // For those classes within one *.js file, update them synchronously. + for (var j = 0, list = node.declaration.clazzList, l = list.length; j < l; j++) { + var nn = findNode(list[j]); + if (nn && nn.status != Node.STATUS_DECLARED + && nn !== node) { + nn.status = Node.STATUS_DECLARED; + if (definedClasses) + definedClasses[nn.name] = true; + _Loader.onScriptInitialized(nn.path); + } + } + } + } + var level = Node.STATUS_DECLARED; + if (node.optionals.length == 0 && node.musts.length == 0 + || node.status > Node.STATUS_KNOWN && !node.declaration + || checkStatusIs(node.musts, Node.STATUS_LOAD_COMPLETE) + && checkStatusIs(node.optionals, Node.STATUS_LOAD_COMPLETE)) { + level = Node.STATUS_LOAD_COMPLETE; + if (!doneLoading(node, level)) + return false; + // For those classes within one *.js file, update them synchronously. + if (node.declaration && node.declaration.clazzList) { + for (var j = 0, list = node.declaration.clazzList, l = list.length; j < l; j++) { + var nn = findNode(list[j]); + if (nn && nn.status != level && nn !== node) { + nn.declaration = null; + if (!doneLoading(nn, level)) + return false; + } + } + } + } + // _Loader.updateParents = function (node, level, _updateParents) + if (node.parents && node.parents.length) { + for (var i = 0; i < node.parents.length; i++) { + var p = node.parents[i]; + if (p.status < level) + updateNode(p, p.name); + } + if (level == Node.STATUS_LOAD_COMPLETE) + node.parents = []; + } +}; + +/* private */ +var checkStatusIs = function(arr, status){ + for (var i = arr.length; --i >= 0;) + if (arr[i].status < status) + return false; + return true; +} +/* private */ +var doneLoading = function(node, level, _doneLoading) { + node.status = level; + _Loader.onScriptCompleted(node.path); + + var onLoaded = node.onLoaded; + if (onLoaded) { + node.onLoaded = null; + onLoaded(); + if (!_Loader.keepOnLoading) + return false; + } + + destroyClassNode(node); + return true; +} + +/* + * Be used to record already used random numbers. And next new random + * number should not be in the property set. + */ +/* private */ +var usedRandoms = { + "r0.13412" : 1 +}; + +/* private */ +var getRnd = function() { + while (true) { // get a unique random number + var rnd = Math.random(); + var s = "r" + rnd; + if (!usedRandoms[s]) + return (usedRandoms[s] = 1, clazzTreeRoot.random = rnd); + } +} + +/* protected */ +var findNode = function(clazzName) { + getRnd(); + return findNodeUnderNode(clazzName, clazzTreeRoot); +}; + +/* private */ +var findNextRequiredClass = function(status) { + getRnd(); + return findNextRequiredNode(clazzTreeRoot, status); +}; + +/* private */ +var findNextMustClass = function(status) { + return findNextMustNode(clazzTreeRoot, status); +}; + +/* private */ +var findNodeUnderNode = function(clazzName, node) { + var n; + // node, then musts then optionals + return (node.name == clazzName ? node + : (n = findNodeWithin(clazzName, node.musts)) + || (n = findNodeWithin(clazzName, node.optionals)) + ? n : null); +}; + +/* private */ +var findNodeWithin = function(name, arr) { + var rnd = clazzTreeRoot.random; + for (var i = arr.length; --i >= 0;) { + var n = arr[i]; + if (n.name == name) + return n; + if (n.random != rnd) { + n.random = rnd; + if ((n = findNodeUnderNode(name, n))) + return n; + } + } + return null; +} + +/* private */ +var checkStatus = function(n, status) { + return (n.status == status + && (status != Node.STATUS_KNOWN || !loadedScripts[n.path]) + && (status == Node.STATUS_DECLARED || !isClassDefined (n.name))); +} + +/* private */ +var findNextMustNode = function(node, status) { + for (var i = node.musts.length; --i >= 0;) { + var n = node.musts[i]; + if (checkStatus(n, status) || (n = findNextMustNode(n, status))) + return n; + } + return (checkStatus(node, status) ? node : null); +}; + +/* private */ +var findNextRequiredNode = function (node, status) { + // search musts first + // search optionals second + // search itself last + var n; + return ((n = searchClassArray(node.musts, status)) + || (n = searchClassArray(node.optionals, status)) + || checkStatus(n = node, status) ? n : null); +}; + +/* private */ +var searchClassArray = function (arr, status) { + if (arr) { + var rnd = clazzTreeRoot.random; + for (var i = 0; i < arr.length; i++) { + var n = arr[i]; + if (checkStatus(n, status)) + return n; + if (n.random != rnd) { + n.random = rnd; // mark as visited! + if ((n = findNextRequiredNode(n, status))) + return n; + } + } + } + return null; +}; + +/** + * This map variable is used to mark that *.js is correctly loaded. + * In IE, _Loader has defects to detect whether a *.js is correctly + * loaded or not, so inner loading mark is used for detecting. + */ +/* private */ +var innerLoadedScripts = {}; + +/** + * This method will be called in almost every *.js generated by Java2Script + * compiler. + */ +/* public */ +var load = function (musts, name, optionals, declaration) { + // called as name.load in Jmol + if (name instanceof Array) { + unwrapArray(name); + for (var i = 0; i < name.length; i++) + load(musts, name[i], optionals, declaration, name); + return; + } + + if (_Loader._checkLoad) { + if (_Loader._classPending[name]) { + //alert("duplicate load for " + name) + } else { + _Loader._classPending[name] = 1; + if (_Loader._classCountPending++ == 0) + _Loader._classCountOK = 0; + System.out.println("Loading class " + name); + } + } + +// if (clazz.charAt (0) == '$') +// clazz = "org.eclipse.s" + clazz.substring (1); + var node = mapPath2ClassNode["#" + name]; + if (!node) { // load called inside *.z.js? + var n = findNode(name); + node = (n ? n : new Node()); + node.name = name; + node.path = classpathMap["#" + name] || "unknown"; + mappingPathNameNode(node.path, name, node); + node.status = Node.STATUS_KNOWN; + addChildClassNode(clazzTreeRoot, node, false); + } + processRequired(node, musts, true); + if (arguments.length == 5 && declaration) { + declaration.status = node.status; + declaration.clazzList = arguments[4]; + } + node.declaration = declaration; + if (declaration) + node.status = Node.STATUS_CONTENT_LOADED; + processRequired(node, optionals, false); +}; + +/* private */ +var processRequired = function(node, arr, isMust) { + if (arr && arr.length) { + unwrapArray(arr); + for (var i = 0; i < arr.length; i++) { + var name = arr[i]; + if (!name) + continue; + if (isClassDefined(name) + || isClassExcluded(name)) + continue; + var n = findNode(name); + if (!n) { + n = new Node(); + n.name = name; + n.status = Node.STATUS_KNOWN; + } + n.requiredBy = node; + addChildClassNode(node, n, isMust); + } + } +} + +/* + * Try to be compatiable of Clazz + */ +if (window["Clazz"]) { + Clazz.load = load; +} else { + _Loader.load = load; +} +/** + * Map different class to the same path! Many classes may be packed into + * a *.z.js already. + * + * @path *.js path + * @name class name + * @node Node object + */ +/* private */ +var mappingPathNameNode = function (path, name, node) { + var map = mapPath2ClassNode; + var keyPath = "@" + path; + var v = map[keyPath]; + if (v) { + if (v instanceof Array) { + var existed = false; + for (var i = 0; i < v.length; i++) { + if (v[i].name == name) { + existed = true; + break; + } + } + if (!existed) + v.push(node); + } else { + map[keyPath] = [v, node]; + } + } else { + map[keyPath] = node; + } + map["#" + name] = node; +}; + +/* protected */ +var loadClassNode = function (node) { + var name = node.name; + if (!isClassDefined (name) + && !isClassExcluded (name)) { + var path = _Loader.getClasspathFor (name/*, true*/); + node.path = path; + mappingPathNameNode (path, name, node); + if (!loadedScripts[path]) { + loadScript(node, path, node.requiredBy, false); + return true; + } + } + return false; +}; + + +/** + * Used in package +/* public */ +var runtimeKeyClass = _Loader.runtimeKeyClass = "java.lang.String"; + +/** + * Queue used to store classes before key class is loaded. + */ +/* private */ +var queueBe4KeyClazz = []; + +/* private */ +var J2sLibBase; + +/** + * Return J2SLib base path from existed SCRIPT src attribute. + */ +/* public */ +_Loader.getJ2SLibBase = function () { + var o = window["j2s.lib"]; + return (o ? o.base + (o.alias == "." ? "" : (o.alias ? o.alias : (o.version ? o.version : "1.0.0")) + "/") : null); +}; + +/** + * Indicate whether _Loader is loading script synchronously or + * asynchronously. + */ +/* private */ +var isAsynchronousLoading = true; + +/* private */ +var isUsingXMLHttpRequest = false; + +/* private */ +var loadingTimeLag = -1; + +_Loader.MODE_SCRIPT = 4; +_Loader.MODE_XHR = 2; +_Loader.MODE_SYNC = 1; + +/** + * String mode: + * asynchronous modes: + * async(...).script, async(...).xhr, async(...).xmlhttprequest, + * script.async(...), xhr.async(...), xmlhttprequest.async(...), + * script + * + * synchronous modes: + * sync(...).xhr, sync(...).xmlhttprequest, + * xhr.sync(...), xmlhttprequest.sync(...), + * xmlhttprequest, xhr + * + * Integer mode: + * Script 4; XHR 2; SYNC bit 1; + */ +/* public */ +_Loader.setLoadingMode = function (mode, timeLag) { + var async = true; + var ajax = true; + if (typeof mode == "string") { + mode = mode.toLowerCase(); + if (mode.indexOf("script") >= 0) + ajax = false; + else + async = (mode.indexOf("async") >=0); + async = false; // BH + } else { + if (mode & _Loader.MODE_SCRIPT) + ajax = false; + else + async = !(mode & _Loader.MODE_SYNC); + } + isUsingXMLHttpRequest = ajax; + isAsynchronousLoading = async; + loadingTimeLag = (async && timeLag >= 0 ? timeLag: -1); + return async; +}; + +/* private */ +var runtimeLoaded = function () { + if (pkgRefCount || !isClassDefined(runtimeKeyClass)) + return; + var qbs = queueBe4KeyClazz; + for (var i = 0; i < qbs.length; i++) + _Loader.loadClass(qbs[i][0], qbs[i][1]); + queueBe4KeyClazz = []; +}; + +/* + * Load those key *.z.js. This *.z.js will be surely loaded before other + * queued *.js. + */ +/* public */ +_Loader.loadZJar = function (zjarPath, keyClass) { +// used only by package.js for core.z.js + var f = null; + var isArr = (keyClass instanceof Array); + if (isArr) + keyClass = keyClass[keyClass.length - 1]; + else + f = (keyClass == runtimeKeyClass ? runtimeLoaded : null); + _Loader.jarClasspath(zjarPath, isArr ? keyClass : [keyClass]); + // BH note: runtimeKeyClass is java.lang.String + _Loader.loadClass(keyClass, f, true); +}; + +var NodeMap = {}; +var _allNodes = []; + +/** + * The method help constructing the multiple-binary class dependency tree. + */ +/* private */ +var addChildClassNode = function (parent, child, isMust) { + var existed = false; + var arr; + if (isMust) { + arr = parent.musts; + if (!child.requiredBy) + child.requiredBy = parent; +// if (!parent.requiresMap){ +// parent.requires = []; +// parent.requiresMap = {}; +// } +// if (!parent.requiresMap[child.name]) { +// parent.requiresMap[child.name] = 1; +// parent.requires.push[child]; +// } + } else { + arr = parent.optionals; + } + if (!NodeMap[child.name]) { + _allNodes.push(child) + NodeMap[child.name]=child + } + for (var i = 0; i < arr.length; i++) { + if (arr[i].name == child.name) { + existed = true; + break; + } + } + if (!existed) { + arr.push(child); + if (isLoadingEntryClass + && child.name.indexOf("java") != 0 + && child.name.indexOf("net.sf.j2s.ajax") != 0) { + if (besidesJavaPackage) + isLoadingEntryClass = false; + besidesJavaPackage = true; +// } else if (child.name.indexOf("org.eclipse.swt") == 0 +// || child.name.indexOf("$wt") == 0) { +// window["swt.lazy.loading.callback"] = swtLazyLoading; +// if (needPackage("org.eclipse.swt")) +// return _Loader.loadPackage("org.eclipse.swt", function() {addParentClassNode(child, parent)}); + } + } + addParentClassNode(child, parent); +}; + +/* private */ +var addParentClassNode = function(child, parent) { + if (parent.name && parent != clazzTreeRoot && parent != child) + for (var i = 0; i < child.parents.length; i++) + if (child.parents[i].name == parent.name) + return; + child.parents.push(parent); +} + +/* private */ +var destroyClassNode = function (node) { + var parents = node.parents; + if (parents) + for (var k = parents.length; --k >= 0;) + removeArrayItem(parents[k].musts, node) || removeArrayItem(parents[k].optionals, node); +}; + +/* public */ +_Loader.unloadClassExt = function (qClazzName) { + if (definedClasses) + definedClasses[qClazzName] = false; + if (classpathMap["#" + qClazzName]) { + var pp = classpathMap["#" + qClazzName]; + classpathMap["#" + qClazzName] = null; + var arr = classpathMap["$" + pp]; + removeArrayItem(arr, qClazzName) && (classpathMap["$" + pp] = arr); + } + var n = findNode(qClazzName); + if (n) { + n.status = Node.STATUS_KNOWN; + loadedScripts[n.path] = false; + } + var path = _Loader.getClasspathFor (qClazzName); + loadedScripts[path] = false; + innerLoadedScripts[path] && (innerLoadedScripts[path] = false); + _Loader.onClassUnloaded(qClazzName); +}; + +/* private */ +var assureInnerClass = function (clzz, fun) { + clzz = clzz.__CLASS_NAME__; + if (Clazz.unloadedClasses[clzz]) { + if (clzz.indexOf("$") >= 0) + return; + var list = []; + var key = clzz + "$"; + for (var s in Clazz.unloadedClasses) + if (Clazz.unloadedClasses[s] && s.indexOf(key) == 0) + list.push(s); + if (!list.length) + return; + fun = "" + fun; + var idx1, idx2; + if ((idx1 = fun.indexOf(key)) < 0 || (idx2 = fun.indexOf("\"", idx1 + key.length)) < 0) + return; + clzz = fun.substring(idx1, idx2); + if (!Clazz.unloadedClasses[clzz] || (idx1 = fun.indexOf("{", idx2) + 1) == 0) + return; + if ((idx2 = fun.indexOf("(" + clzz + ",", idx1 + 3)) < 0 + || (idx2 = fun.lastIndexOf("}", idx2 - 1)) < 0) + return; + eval(fun.substring(idx1, idx2)); + Clazz.unloadedClasses[clzz] = null; + } +}; + +Clazz.binaryFolders = _Loader.binaryFolders = [ _Loader.getJ2SLibBase() ]; + +})(Clazz, Clazz._Loader); + +//} +/****************************************************************************** + * Copyright (c) 2007 java2script.org and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Zhou Renjian - initial API and implementation + *****************************************************************************/ +/******* + * @author zhou renjian + * @create Jan 11, 2007 + *******/ + +Clazz._LoaderProgressMonitor = {}; + +;(function(CLPM, Jmol) { + +var fadeOutTimer = null; +var fadeAlpha = 0; +var monitorEl = null; +var lastScrollTop = 0; +var bindingParent = null; + +CLPM.DEFAULT_OPACITY = (Jmol && Jmol._j2sLoadMonitorOpacity ? Jmol._j2sLoadMonitorOpacity : 55); + +/* public */ +/*CLPM.initialize = function (parent) { + bindingParent = parent; + if (parent && !attached) { + attached = true; + //Clazz.addEvent (window, "unload", cleanup); + // window.attachEvent ("onunload", cleanup); + } +}; +*/ + +/* public */ +CLPM.hideMonitor = function () { + monitorEl.style.display = "none"; +} + +/* public */ +CLPM.showStatus = function (msg, fading) { + if (!monitorEl) { + createHandle (); + if (!attached) { + attached = true; + //Clazz.addEvent (window, "unload", cleanup); + // window.attachEvent ("onunload", cleanup); + } + } + clearChildren(monitorEl); + if (msg == null) { + if (fading) { + fadeOut(); + } else { + CLPM.hideMonitor(); + } + return; + } + + monitorEl.appendChild(document.createTextNode ("" + msg)); + if (monitorEl.style.display == "none") { + monitorEl.style.display = ""; + } + setAlpha(CLPM.DEFAULT_OPACITY); + var offTop = getFixedOffsetTop(); + if (lastScrollTop != offTop) { + lastScrollTop = offTop; + monitorEl.style.bottom = (lastScrollTop + 4) + "px"; + } + if (fading) { + fadeOut(); + } +}; + +/* private static */ +var clearChildren = function (el) { + if (!el) + return; + for (var i = el.childNodes.length; --i >= 0;) { + var child = el.childNodes[i]; + if (!child) + continue; + if (child.childNodes && child.childNodes.length) + clearChildren (child); + try { + el.removeChild (child); + } catch (e) {}; + } +}; +/* private */ +var setAlpha = function (alpha) { + if (fadeOutTimer && alpha == CLPM.DEFAULT_OPACITY) { + window.clearTimeout (fadeOutTimer); + fadeOutTimer = null; + } + fadeAlpha = alpha; + var ua = navigator.userAgent.toLowerCase(); + monitorEl.style.filter = "Alpha(Opacity=" + alpha + ")"; + monitorEl.style.opacity = alpha / 100.0; +}; +/* private */ +var hidingOnMouseOver = function () { + CLPM.hideMonitor(); +}; + +/* private */ +var attached = false; +/* private */ +var cleanup = function () { + //if (monitorEl) { + // monitorEl.onmouseover = null; + //} + monitorEl = null; + bindingParent = null; + //Clazz.removeEvent (window, "unload", cleanup); + //window.detachEvent ("onunload", cleanup); + attached = false; +}; +/* private */ +var createHandle = function () { + var div = document.createElement ("DIV"); + div.id = "_Loader-status"; + div.style.cssText = "position:absolute;bottom:4px;left:4px;padding:2px 8px;" + + "z-index:" + (window["j2s.lib"].monitorZIndex || 10000) + ";background-color:#8e0000;color:yellow;" + + "font-family:Arial, sans-serif;font-size:10pt;white-space:nowrap;"; + div.onmouseover = hidingOnMouseOver; + monitorEl = div; + if (bindingParent) { + bindingParent.appendChild(div); + } else { + document.body.appendChild(div); + } + return div; +}; +/* private */ + +var fadeOut = function () { + if (monitorEl.style.display == "none") return; + if (fadeAlpha == CLPM.DEFAULT_OPACITY) { + fadeOutTimer = window.setTimeout(function () { + fadeOut(); + }, 750); + fadeAlpha -= 5; + } else if (fadeAlpha - 10 >= 0) { + setAlpha(fadeAlpha - 10); + fadeOutTimer = window.setTimeout(function () { + fadeOut(); + }, 40); + } else { + monitorEl.style.display = "none"; + } +}; +/* private */ +var getFixedOffsetTop = function (){ + if (bindingParent) { + var b = bindingParent; + return b.scrollTop; + } + var dua = navigator.userAgent; + var b = document.body; + var p = b.parentNode; + var pcHeight = p.clientHeight; + var bcScrollTop = b.scrollTop + b.offsetTop; + var pcScrollTop = p.scrollTop + p.offsetTop; + return (dua.indexOf("Opera") < 0 && document.all ? (pcHeight == 0 ? bcScrollTop : pcScrollTop) + : dua.indexOf("Gecko") < 0 ? (pcHeight == p.offsetHeight + && pcHeight == p.scrollHeight ? bcScrollTop : pcScrollTop) : bcScrollTop); +}; + +/* not used in Jmol +if (window["ClazzLoader"]) { + _Loader.onScriptLoading = function(file) { + CLPM.showStatus("Loading " + file + "..."); + }; + _Loader.onScriptLoaded = function(file, isError) { + CLPM.showStatus(file + (isError ? " loading failed." : " loaded."), true); + }; + _Loader.onGlobalLoaded = function(file) { + CLPM.showStatus("Application loaded.", true); + }; + _Loader.onClassUnloaded = function(clazz) { + CLPM.showStatus("Class " + clazz + " is unloaded.", true); + }; +} +*/ + +})(Clazz._LoaderProgressMonitor, Jmol); + +//} +/****************************************************************************** + * Copyright (c) 2007 java2script.org and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Zhou Renjian - initial API and implementation + *****************************************************************************/ +/******* + * @author zhou renjian + * @create Nov 5, 2005 + *******/ + +;(function(Con, Sys) { +/** + * Setting maxTotalLines to -1 will not limit the console result + */ +/* protected */ +Con.maxTotalLines = 10000; + +/* protected */ +Con.setMaxTotalLines = function (lines) { + Con.maxTotalLines = (lines > 0 ? lines : 999999); +} + +/* protected */ +Con.maxLatency = 40; + +/* protected */ +Con.setMaxLatency = function (latency) { + Con.maxLatency = (latency > 0 ? latency : 40); +}; + +/* protected */ +Con.pinning = false; + +/* protected */ +Con.enablePinning = function (enabled) { + Con.pinning = enabled; +}; + +/* private */ +Con.linesCount = 0; + +/* private */ +Con.metLineBreak = false; + + +/* + * Give an extension point so external script can create and bind the console + * themself. + * + * TODO: provide more template of binding console window to browser. + */ +/* protected */ +Con.createConsoleWindow = function (parentEl) { + var console = document.createElement ("DIV"); + console.style.cssText = "font-family:monospace, Arial, sans-serif;"; + document.body.appendChild (console); + return console; +}; + +var c160 = String.fromCharCode(160); //nbsp; +c160 += c160+c160+c160; + +/* protected */ +Con.consoleOutput = function (s, color) { + var o = window["j2s.lib"]; + var console = (o && o.console); + if (console && typeof console == "string") + console = document.getElementById(console) + if (!console) + return false; // BH this just means we have turned off all console action + if (Con.linesCount > Con.maxTotalLines) { + for (var i = 0; i < Con.linesCount - Con.maxTotalLines; i++) { + if (console && console.childNodes.length > 0) { + console.removeChild (console.childNodes[0]); + } + } + Con.linesCount = Con.maxTotalLines; + } + + var willMeetLineBreak = false; + s = (typeof s == "undefined" ? "" : s == null ? "null" : "" + s); + s = s.replace (/\t/g, c160); + if (s.length > 0) + switch (s.charAt(s.length - 1)) { + case '\n': + case '\r': + s = (s.length > 1 ? s.substring (0, s.length - (s.charAt (s.length - 2) == '\r' ? 2 : 1)) : ""); + willMeetLineBreak = true; + break; + } + + var lines = null; + s = s.replace (/\t/g, c160); + lines = s.split(/\r\n|\r|\n/g); + for (var i = 0, last = lines.length - 1; i <= last; i++) { + var lastLineEl = null; + if (Con.metLineBreak || Con.linesCount == 0 + || console.childNodes.length < 1) { + lastLineEl = document.createElement ("DIV"); + console.appendChild (lastLineEl); + lastLineEl.style.whiteSpace = "nowrap"; + Con.linesCount++; + } else { + try { + lastLineEl = console.childNodes[console.childNodes.length - 1]; + } catch (e) { + lastLineEl = document.createElement ("DIV"); + console.appendChild (lastLineEl); + lastLineEl.style.whiteSpace = "nowrap"; + Con.linesCount++; + } + } + var el = document.createElement ("SPAN"); + lastLineEl.appendChild (el); + el.style.whiteSpace = "nowrap"; + if (color) + el.style.color = color; + var l = lines[i] + if (l.length == 0) + l = c160; + el.appendChild(document.createTextNode(l)); + if (!Con.pinning) + console.scrollTop += 100; + Con.metLineBreak = (i != last || willMeetLineBreak); + } + + var cssClazzName = console.parentNode.className; + if (!Con.pinning && cssClazzName + && cssClazzName.indexOf ("composite") != -1) { + console.parentNode.scrollTop = console.parentNode.scrollHeight; + } + Con.lastOutputTime = new Date ().getTime (); +}; + +/* + * Clear all contents inside the console. + */ +/* public */ +Con.clear = function () { + try { + Con.metLineBreak = true; + var o = window["j2s.lib"]; + var console = o && o.console; + if (!console || !(console = document.getElementById (console))) + return; + var childNodes = console.childNodes; + for (var i = childNodes.length; --i >= 0;) + console.removeChild (childNodes[i]); + Con.linesCount = 0; + } catch(e){}; +}; + +/* public */ +Clazz.alert = function (s) { + Con.consoleOutput (s + "\r\n"); +}; + + +/* public */ +Sys.out.print = function (s) { + Con.consoleOutput (s); +}; +/* public */ +Sys.out.println = function(s) { + Con.consoleOutput(typeof s == "undefined" ? "\r\n" : s == null ? s = "null\r\n" : s + "\r\n"); +}; + +Sys.out.write = function (buf, offset, len) { + Sys.out.print(String.instantialize(buf).substring(offset, offset+len)); +}; + +/* public */ +Sys.err.__CLASS_NAME__ = "java.io.PrintStream"; + +/* public */ +Sys.err.print = function (s) { + Con.consoleOutput (s, "red"); +}; + +/* public */ +Sys.err.println = function (s) { + Con.consoleOutput (typeof s == "undefined" ? "\r\n" : s == null ? s = "null\r\n" : s + "\r\n", "red"); +}; + +Sys.err.write = function (buf, offset, len) { + Sys.err.print(String.instantialize(buf).substring(offset, offset+len)); +}; + +})(Clazz.Console, System); + +})(Clazz, Jmol); // requires JSmolCore.js + +}; // called by external application