3 // latest author: Bob Hanson, St. Olaf College, hansonr@stolaf.edu
5 // Requires JSmolCore.js and (for now; probably) JSmol.js
6 // This version of j2slib requires jQuery and works in both Chrome and MSIE locally,
7 // though Chrome cannot read local data files, and MSIE cannot read local binary data files.
9 // Java programming notes by Bob Hanson:
11 // There are a few motifs to avoid when optimizing Java code to work smoothly
12 // with the J2S compiler:
16 // 1. an array with null elements cannot be typed and must be avoided.
17 // 2. instances of Java "instance of" involving arrays must be found and convered to calls to Clazz.isA...
18 // 3. new int[n][] must not be used. Use instead JU.AU.newInt2(n);
19 // 4. new int[] { 1, 2, 3 } has problems because it creates simply [ ] and not IntArray32
23 // 1. Remember that EVERY number in JavaScript is a double -- doesn't matter if it is in IntArray32 or not.
24 // 2. You cannot reliably use Java long, because doubles consume bits for the exponent which cannot be tested.
25 // 3. Bit 31 of an integer is unreliable, since (int) -1 is now , not just 0zFFFFFFFF, and
26 // FFFFFFFF + 1 = 100000000, not 0. In JavaScript, 0xFFFFFFFF is 4294967295, not -1.
27 // This means that writeInt(b) will fail if b is negative. What you need is instead
28 // writeInt((int)(b & 0xFFFFFFFFl) so that JavaScript knocks off the high bits explicitly.
32 // 1. j2sRequireImport xxxx is needed if xxxx is a method used in a static function
33 // 2. URL.getContent() is not supported. Use other means based on URL.toString()
34 // 3. It is critical for performance to avoid any significant amount of function overloading.
35 // In particular, methods such as xxx(int a, int b) and xxx(float a, int b) MUST be renamed,
36 // because JavaScript only has Number, and there is absolutely no way to tell these apart.
37 // It's probably bad Java programming, anyway.
38 // 4. Calls to super(...) can almost always be avoided. These trigger the SAEM
39 // (searchAndExecuteMethod) call, and it is very destructive to performance.
40 // Just find another way to do it.
42 // NOTES by Bob Hanson:
46 // BH 7/24/2015 6:48:50 AM adding optional ?j2sdebug flag on page URL
47 // -- switches to using j2s/core/corexxx.js, not j2s/core/corexxx.z.js
48 // -- adds ";//# sourceURL="+file in eval(js)
49 // -- enables DebugJS.$(msg) call to debugger;
50 // see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger
51 // see https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Debug_eval_sources
52 // BH 7/23/2015 6:45:55 PM added sourceURL in each js class eval(), allowing full
53 // breakpoint debugging and code checking in Firefox and Chrome
54 // BH 7/19/2015 6:18:17 PM added os.name, line.separator, etc. to System.getProperty()
55 // BH 7/19/2015 5:39:10 PM added java.lang.System = System
56 // BH 7/19/2015 10:33:10 AM fix for SAEM equating "null" with number or boolean
57 // BH 7/18/2015 6:08:05 PM for Jmol I was able to remove the $private/$fx business, but now
58 // I see that in general that cannot be done. Thinking about a strategy...
59 // BH 7/18/2015 4:43:38 PM better handling of TypeError and InternalError for e.getMessage() and e.getStackTrace()
60 // BH 7/17/2015 11:51:15 AM adds class.getResource(name) and class.getResourceAsStream(name)
61 // BH 7/16/2015 7:56:49 PM general instantiation using any constructor (in Java here):
62 // BH x = class.forName("my.class.name").newInstance()
64 // BH x = class.forName("my.class.name").getConstructor(String.class,String.class).newInstance(new Object[] {"test", "now"})
65 // BH 7/15/2015 11:34:58 PM adding System.lineSeparator()
66 // BH 7/15/2015 7:32:41 AM adding class.getCanonicalName == getName
67 // BH 5/31/2015 5:38:14 PM NPEExceptionPredicate fix
68 // BH 4/25/2015 9:16:12 AM SAEM misrepresnting Number as Object in parameters and Integer as Number
69 // BH 4/24/2015 7:32:54 AM Object.hashCode() and System.getIdentityHashCode() fail. changed to: return this._$hashcode || (this._$hashcode = ++Clazz._hashCode)
70 // BH 4/23/2015 9:08:59 AM Clazz.instanceOf(a, b) needs to check for a == b.
71 // BH 4/23/2015 9:08:59 AM xx.getContentType() is nonfunctional. Array.newInstance now defines a wrapper for .getClass().getComponentType() that works
72 // BH 4/12/2015 11:48:03 AM added Clazz.getStackTrace(-n) -- reports actual parameter values for n levels
73 // BH 4/10/2015 8:23:05 AM adding Int32Array.prototype.clone and Float64.prototype.clone
74 // BH 4/5/2015 8:12:57 AM refactoring j2slib (this file) to make private functions really private using var
75 // BH 4/3/2015 6:14:34 AM adding anonymous local "ClazzLoader" (Clazz._Loader) --> "_Loader"
76 // BH 4/3/2015 6:14:34 AM adding Clazz._Loader._classPending, Clazz._Loader._classCount
77 // BH 4/3/2015 6:14:34 AM adding Clazz._Loader._checkLoad
78 // -- forces asynchronous class loading
79 // -- builds Clazz._Loader._classPending and Clazz._classCount
80 // -- allows reporting
82 // BH 3/24/2015 4:11:26 AM better file load failure message in _Loader.evaluate
83 // BH 2/28/2015 7:30:25 AM corrects newIntArray32() and newArray() for pre-defined arrays
84 // int[] a = new int[] {1,2,3,343};
85 // int[][] b = new int[][] {new int[]{4,5},new int[]{5,6}};
87 // BH 9/29/2014 11:34:19 PM removing support for getClass().isArray()
88 // BH 8/29/2014 9:15:57 AM total reworking of Java2Script in preparation for all-asynchronous loading
89 // (currently sync loading is only for
90 // LOAD command and load() function without ASYNC
92 // see JSmol.js and Jmol._isAsync flag
93 // BH 5/11/2015 5:58:42 AM adding __signatures for debugging SAEM issues
94 // BH 3/29/2015 8:12:44 PM System.getProperty(x, "") does not return ""
95 // BH 8/23/2014 10:04:19 AM cleaning up a few general methods; Clazz.removeArrayItem
96 // BH 6/1/2014 10:58:46 AM fix for Clazz.isAP() not working
97 // BH 5/26/2014 5:19:29 PM removing superConstructor call in creating Enum constants
98 // BH 4/1/2014 7:55:54 PM removing all $fz references and instances where sub/super classes have same private function names
99 // BH 4/1/2014 4:47:30 PM all $_X removed; this is taken care of by Google Closure Compiler
100 // BH 4/1/2014 6:40:08 AM removing ClassLoader -- equals Clazz._Loader
101 // BH 4/1/2014 6:40:08 AM removing ClassLoaderProgressMonitor -- equals _LoaderProgressMonitor
102 // 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"
103 // 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
105 // BH 1/30/2014 12:54:22 PM gave all field variables prefix underscore. This allows Google Closure Compiler to skip them.
106 // BH 12/3/2013 3:39:57 PM window["j2s.lib"].base implemented
107 // BH 12/1/2013 5:34:21 AM removed _LoaderProgressMonitor.initialize and all Clazz.event business; handled by Jmol.clearVars()
108 // BH 11/30/2013 12:43:58 PM adding Clazz.arrayIs() -- avoids Number.constructor.toString() infinite recursion
109 // BH 11/29/2013 6:33:51 AM adding Clazz._profiler -- reports use of SAEM
110 // BH 11/10/2013 9:02:20 AM fixing fading in MSIE
111 // BH 11/3/2013 7:21:39 AM additional wrapping functions for better compressibility
112 // BH 10/30/2013 8:10:58 AM added getClass().getResource() -- returning a relative string, not a URL
113 // BH 10/30/2013 6:43:00 AM removed second System def and added System.$props and default System.property "line.separator"
114 // BH 6/15/2013 8:02:07 AM corrections to Class.isAS to return true if first element is null
115 // BH 6/14/2013 4:41:09 PM corrections to Clazz.isAI and related methods to include check for null object
116 // BH 3/17/2013 11:54:28 AM adds stackTrace for ERROR
118 // BH 3/13/2013 6:58:26 PM adds Clazz.clone(me) for BS clone
119 // BH 3/12/2013 6:30:53 AM fixes Clazz.exceptionOf for ERROR condition trapping
120 // BH 3/2/2013 9:09:53 AM delete globals c$ and $fz
121 // BH 3/2/2013 9:10:45 AM optimizing defineMethod using "look no further" "@" parameter designation (see "\\@" below -- removed 3/23/13)
122 // BH 2/27/2013 optimizing Clazz.getParamsType for common cases () and (Number)
123 // BH 2/27/2013 optimizing SAEM delegation for hashCode and equals -- disallows overloading of equals(Object)
125 // BH 2/23/2013 found String.replaceAll does not work -- solution was to never call it.
126 // BH 2/9/2013 9:18:03 PM Int32Array/Float64Array fixed for MSIE9
127 // BH 1/25/2013 1:55:31 AM moved package.js from j2s/java to j2s/core
128 // BH 1/17/2013 4:37:17 PM String.compareTo() added
129 // BH 1/17/2013 4:52:22 PM Int32Array and Float64Array may not have .prototype.sort method
130 // BH 1/16/2013 6:20:34 PM Float64Array not available in Safari 5.1
131 // BH 1/14/2013 11:28:58 PM Going to all doubles in JavaScript (Float64Array, not Float32Array)
132 // so that (new float[] {13.48f})[0] == 13.48f, effectively
134 // BH 1/14/2013 12:53:41 AM Fix for Opera 10 not loading any files
135 // BH 1/13/2013 11:50:11 PM Fix for MSIE not loading (nonbinary) files locally
137 // BH 12/1/2012 9:52:26 AM Compiler note: Thread.start() cannot be executed within the constructor;
139 // BH 11/24/2012 11:08:39 AM removed unneeded sections
140 // BH 11/24/2012 10:23:22 AM all XHR uses sync loading (_Loader.setLoadingMode)
141 // BH 11/21/2012 7:30:06 PM if (base) map["@" + pkg] = base; critical for multiple applets
143 // BH 10/8/2012 3:27:41 PM if (clazzName.indexOf("Array") >= 0) return "Array"; in Clazz.getClassName for function
144 // BH removed Clazz.ie$plit = "\\2".split (/\\/).length == 1; unnecessary; using RegEx slows process significantly in all browsers
145 // BH 10/6/12 added Int32Array, Float32Array, newArrayBH, upgraded java.lang and java.io
146 // BH added Integer.bitCount in core.z.js
147 // BH changed alert to Clazz.alert in java.lang.Class.js *.ClassLoader.js, java.lang.thread.js
148 // BH removed toString from innerFunctionNames due to infinite recursion
149 // BH note: Logger.error(null, e) does not work -- get no constructor for (String) (TypeError)
150 // BH added j2s.lib.console
151 // BH allowed for alias="."
152 // BH removed alert def --> Clazz.alert
153 // BH added wrapper at line 2856
154 // BH newArray fix at line 2205
155 // BH System.getProperty fix at line 6693
156 // BH added Enum .value() method at line 2183
157 // BH added System.getSecurityManager() at end
158 // BH added String.contains() at end
159 // BH added System.gc() at end
160 // BH added Clazz.exceptionOf = updated
161 // BH added String.getBytes() at end
164 LoadClazz = function() {
166 // BH This is the ONLY global used in J2S now. I do not think it is necessary,
167 // but it is created by the compiler, and I have not found a work-around.
168 // it is used as a local variable in class definitions to point to the
169 // current method. See Clazz.p0p and Clazz.pu$h
173 if (!window["j2s.clazzloaded"])
174 window["j2s.clazzloaded"] = false;
176 if (window["j2s.clazzloaded"])return;
178 window["j2s.clazzloaded"] = true;
180 window["j2s.object.native"] = true;
184 /* http://j2s.sf.net/ *//******************************************************************************
185 * Copyright (c) 2007 java2script.org and others.
186 * All rights reserved. This program and the accompanying materials
187 * are made available under the terms of the Eclipse Public License v1.0
188 * which accompanies this distribution, and is available at
189 * http://www.eclipse.org/legal/epl-v10.html
192 * Zhou Renjian - initial API and implementation
193 *****************************************************************************/
195 * @author zhou renjian
196 * @create Nov 5, 2005
201 * Class Clazz. All the methods are static in this class.
204 /*Class = */ Clazz = {
209 ;(function(Clazz, Jmol) {
213 Clazz._debugging = (document.location.href.indexOf("j2sdebug") >= 0);
216 var __debuggingBH = false;
217 var _globals = ["j2s.clazzloaded", "j2s.object.native"];
218 Clazz.setGlobal = function(a, v) {
223 Clazz.getGlobals = function() {
224 return _globals.sort().join("\n");
227 Clazz.setConsoleDiv = function(d) {
228 window["j2s.lib"] && (window["j2s.lib"].console = d);
231 // BH Clazz.getProfile monitors exactly what is being delegated with SAEM,
232 // which could be a bottle-neck for function calling.
233 // This is critical for performance optimization.
237 var _profile = (window["j2s.doProfile"] && self.JSON ? {} : null);
239 NullObject = function () {};
242 Clazz._supportsNativeObject = window["j2s.object.native"];
244 if (Clazz._supportsNativeObject) {
245 Clazz._O = function () {};
246 Clazz._O.__CLASS_NAME__ = "Object";
247 Clazz._O["getClass"] = function () { return Clazz._O; };
253 Clazz.dateToString = Date.prototype.toString;
256 var addProto = function(proto, name, func) {
257 return proto[name] = func;
261 addProto(proto, "equals", function (obj) {
265 addProto(proto, "hashCode", function () {
267 return this._$hashcode || (this._$hashcode = ++Clazz._hashCode)
271 return this.toString ().hashCode ();
274 for (var s in this) {
277 return str.hashCode ();
281 addProto(proto, "getClass", function () { return Clazz.getClass (this); });
283 addProto(proto, "clone", function () { return Clazz.clone(this); });
285 Clazz.clone = function(me) {
286 // BH allows @j2sNative access without super constructor
287 var o = new me.constructor();
294 * Methods for thread in Object
296 addProto(proto, "finalize", function () {});
297 addProto(proto, "notify", function () {});
298 addProto(proto, "notifyAll", function () {});
299 addProto(proto, "wait", function () {});
300 addProto(proto, "to$tring", Object.prototype.toString);
301 addProto(proto, "toString", function () { return (this.__CLASS_NAME__ ? "[" + this.__CLASS_NAME__ + " object]" : this.to$tring.apply(this, arguments)); });
302 Clazz._extendedObjectMethods = [ "equals", "hashCode", "getClass", "clone", "finalize", "notify", "notifyAll", "wait", "to$tring", "toString" ];
304 })(Clazz._O.prototype);
306 Clazz.extendJO = function(c, name) {
308 c.__CLASS_NAME__ = c.prototype.__CLASS_NAME__ = name;
309 if (Clazz._supportsNativeObject) {
310 for (var i = 0; i < Clazz._extendedObjectMethods.length; i++) {
311 var p = Clazz._extendedObjectMethods[i];
312 addProto(c.prototype, p, Clazz._O.prototype[p]);
318 * Try to fix bug on Safari
320 //InternalFunction = Object;
322 Clazz.extractClassName = function(clazzStr) {
323 // [object Int32Array]
324 var clazzName = clazzStr.substring (1, clazzStr.length - 1);
325 return (clazzName.indexOf("Array") >= 0 ? "Array" // BH -- for Float64Array and Int32Array
326 : clazzName.indexOf ("object ") >= 0 ? clazzName.substring (7) // IE
330 * Return the class name of the given class or object.
332 * @param clazzHost given class or object
336 Clazz.getClassName = function (obj) {
339 if (obj instanceof Clazz.CastedNull)
340 return obj.clazzName;
347 // Always treat the constant string as String object.
348 // This will be compatiable with Java String instance.
351 if (obj.__CLASS_NAME__)
352 return (arguments[1] ? obj.__CLASS_NAME__ : "Class"); /* user defined class name */
353 var s = obj.toString();
354 var idx0 = s.indexOf("function");
356 return (s.charAt(0) == '[' ? Clazz.extractClassName(s) : s.replace(/[^a-zA-Z0-9]/g, ''));
358 var idx2 = s.indexOf ("(", idx1);
361 s = s.substring (idx1, idx2);
362 if (s.indexOf("Array") >= 0)
364 s = s.replace (/^\s+/, "").replace (/\s+$/, "");
365 return (s == "anonymous" || s == "" ? "Function" : s);
367 if (obj.__CLASS_NAME__) // user defined class name
368 return obj.__CLASS_NAME__;
369 if (!obj.constructor)
370 return "Object"; // For HTML Element in IE
371 if (!obj.constructor.__CLASS_NAME__) {
372 if (obj instanceof Number)
374 if (obj instanceof Boolean)
376 if (obj instanceof Array)
378 var s = obj.toString();
379 // "[object Int32Array]"
380 if (s.charAt(0) == '[')
381 return Clazz.extractClassName(s);
383 return Clazz.getClassName (obj.constructor, true);
385 // some new, unidentified class
389 * Return the class of the given class or object.
391 * @param clazzHost given class or object
395 Clazz.getClass = function (clazzHost) {
397 return Clazz._O; // null/undefined is always treated as Object
398 if (typeof clazzHost == "function")
401 if (clazzHost instanceof Clazz.CastedNull) {
402 clazzName = clazzHost.clazzName;
404 switch (typeof clazzHost) {
408 if (!clazzHost.__CLASS_NAME__)
409 return (clazzHost.constructor || Clazz._O);
410 clazzName = clazzHost.__CLASS_NAME__;
413 return clazzHost.constructor;
416 return Clazz.evalType(clazzName, true);
421 var checkInnerFunction = function (hostSuper, funName) {
422 for (var k = 0; k < Clazz.innerFunctionNames.length; k++)
423 if (funName == Clazz.innerFunctionNames[k] &&
424 Clazz._innerFunctions[funName] === hostSuper[funName])
429 var args4InheritClass = function () {};
431 Clazz.inheritArgs = new args4InheritClass ();
434 * Inherit class with "extends" keyword and also copy those static members.
435 * Example, as in Java, if NAME is a static member of ClassA, and ClassB
436 * extends ClassA then ClassB.NAME can be accessed in some ways.
438 * @param clazzThis child class to be extended
439 * @param clazzSuper super class which is inherited from
440 * @param objSuper super class instance
443 Clazz.inheritClass = function (clazzThis, clazzSuper, objSuper) {
444 //var thisClassName = Clazz.getClassName (clazzThis);
445 for (var o in clazzSuper) {
446 if (o != "b$" && o != "prototype" && o != "superClazz"
447 && o != "__CLASS_NAME__" && o != "implementz"
448 && !checkInnerFunction (clazzSuper, o)) {
449 clazzThis[o] = clazzSuper[o];
452 if (Clazz.unloadedClasses[Clazz.getClassName(clazzThis, true)]) {
453 // Don't change clazzThis.protoype! Keep it!
454 } else if (objSuper) {
455 // ! Unsafe reference prototype to an instance!
456 // Feb 19, 2006 --josson
457 // OK for this reference to an instance, as this is anonymous instance,
458 // which is not referenced elsewhere.
460 clazzThis.prototype = objSuper;
461 } else if (clazzSuper !== Number) {
462 clazzThis.prototype = new clazzSuper (Clazz.inheritArgs);
464 clazzThis.prototype = new Number ();
466 clazzThis.superClazz = clazzSuper;
468 * Is it necessary to reassign the class name?
469 * Mar 10, 2006 --josson
471 //clazzThis.__CLASS_NAME__ = thisClassName;
472 clazzThis.prototype.__CLASS_NAME__ = clazzThis.__CLASS_NAME__;
476 * Implementation of Java's keyword "implements".
477 * As in JavaScript there are on "implements" keyword implemented, a property
478 * of "implementz" is added to the class to record the interfaces the class
481 * @param clazzThis the class to implement
482 * @param interfacez Array of interfaces
485 Clazz.implementOf = function (clazzThis, interfacez) {
486 if (arguments.length >= 2) {
487 if (!clazzThis.implementz)
488 clazzThis.implementz = [];
489 var impls = clazzThis.implementz;
490 if (arguments.length == 2) {
491 if (typeof interfacez == "function") {
492 impls.push(interfacez);
493 copyProperties(clazzThis, interfacez);
494 } else if (interfacez instanceof Array) {
495 for (var i = 0; i < interfacez.length; i++) {
496 impls.push(interfacez[i]);
497 copyProperties(clazzThis, interfacez[i]);
501 for (var i = 1; i < arguments.length; i++) {
502 impls.push(arguments[i]);
503 copyProperties(clazzThis, arguments[i]);
510 * Copy members of interface
513 var copyProperties = function(clazzThis, clazzSuper) {
514 for (var o in clazzSuper)
516 && o != "prototype" && o != "superClazz"
517 && o != "__CLASS_NAME__" && o != "implementz"
518 && (typeof clazzSuper[o] != "function" || !checkInnerFunction(clazzSuper, o)))
519 clazzThis[o] = clazzThis.prototype[o] = clazzSuper[o];
523 * TODO: More should be done for interface's inheritance
526 Clazz.extendInterface = Clazz.implementOf;
529 Clazz.equalsOrExtendsLevel = function (clazzThis, clazzAncestor) {
530 if (clazzThis === clazzAncestor)
532 if (clazzThis.implementz) {
533 var impls = clazzThis.implementz;
534 for (var i = 0; i < impls.length; i++) {
535 var level = Clazz.equalsOrExtendsLevel (impls[i], clazzAncestor);
544 Clazz.getInheritedLevel = function (clazzTarget, clazzBase) {
545 if (clazzTarget === clazzBase)
547 var isTgtStr = (typeof clazzTarget == "string");
548 if (isTgtStr && ("void" == clazzTarget || "unknown" == clazzTarget))
550 var isBaseStr = (typeof clazzBase == "string");
551 if (isBaseStr && ("void" == clazzBase || "unknown" == clazzBase))
553 if (clazzTarget === (isTgtStr ? "NullObject" : NullObject)) {
567 clazzTarget = Clazz.evalType(clazzTarget);
569 clazzBase = Clazz.evalType(clazzBase);
570 if (!clazzBase || !clazzTarget)
573 var zzalc = clazzTarget; // zzalc <--> clazz
574 while (zzalc !== clazzBase && level < 10) {
575 /* maybe clazzBase is interface */
576 if (zzalc.implementz) {
577 var impls = zzalc.implementz;
578 for (var i = 0; i < impls.length; i++) {
579 var implsLevel = Clazz.equalsOrExtendsLevel (impls[i], clazzBase);
581 return level + implsLevel + 1;
584 zzalc = zzalc.superClazz;
586 return (clazzBase === Object || clazzBase === Clazz._O ?
587 // getInheritedLevel(String, CharSequence) == 1
588 // getInheritedLevel(String, Object) == 1.5
589 // So if both #test(CharSequence) and #test(Object) existed,
590 // #test("hello") will correctly call #test(CharSequence)
591 // instead of #test(Object).
592 level + 1.5 // 1.5! Special!
601 * Implements Java's keyword "instanceof" in JavaScript's way.
602 * As in JavaScript part of the object inheritance is implemented in only-
605 * @param obj the object to be tested
606 * @param clazz the class to be checked
607 * @return whether the object is an instance of the class
610 Clazz.instanceOf = function (obj, clazz) {
611 // allows obj to be a class already, from arrayX.getClass().isInstance(y)
612 return (obj != null && clazz && (obj == clazz || obj instanceof clazz || Clazz.getInheritedLevel(Clazz.getClassName(obj), clazz) >= 0));
616 * Call super method of the class.
617 * The same effect as Java's expression:
618 * <code> super.* () </code>
620 * @param objThis host object
621 * @param clazzThis class of declaring method scope. It's hard to determine
622 * which super class is right class for "super.*()" call when it's in runtime
623 * environment. For example,
624 * 1. ClasssA has method #run()
625 * 2. ClassB extends ClassA overriding method #run() with "super.run()" call
626 * 3. ClassC extends ClassB
627 * 4. objC is an instance of ClassC
628 * Now we have to decide which super #run() method is to be invoked. Without
629 * explicit clazzThis parameter, we only know that objC.getClass() is ClassC
630 * and current method scope is #run(). We do not known we are in scope
631 * ClassA#run() or scope of ClassB#run(). if ClassB is given, Clazz can search
632 * all super methods that are before ClassB and get the correct super method.
633 * This is the reason why there must be an extra clazzThis parameter.
634 * @param funName method name to be called
635 * @param funParams Array of method parameters
638 Clazz.superCall = function (objThis, clazzThis, funName, funParams) {
641 var clazzFun = objThis[funName];
643 if (clazzFun.claxxOwner) {
644 // claxxOwner is a mark for methods that is single.
645 if (clazzFun.claxxOwner !== clazzThis) {
646 // This is a single method, call directly!
650 } else if (!clazzFun.stacks && !(clazzFun.lastClaxxRef
651 && clazzFun.lastClaxxRef.prototype[funName]
652 && clazzFun.lastClaxxRef.prototype[funName].stacks)) { // super.toString
654 } else { // normal wrapped method
655 var stacks = clazzFun.stacks;
657 stacks = clazzFun.lastClaxxRef.prototype[funName].stacks;
658 for (i = stacks.length; --i >= 0;) {
660 * Once super call is computed precisely, there are no need
661 * to calculate the inherited level but just an equals
664 //var level = Clazz.getInheritedLevel (clazzThis, stacks[i]);
665 if (clazzThis === stacks[i]) { // level == 0
667 fx = stacks[--i].prototype[funName];
670 * Will this case be reachable?
672 * Should never reach here if all things are converted
675 fx = stacks[0].prototype[funName]["\\unknown"];
678 } else if (Clazz.getInheritedLevel (clazzThis, stacks[i]) > 0) {
679 fx = stacks[i].prototype[funName];
683 } // end of normal wrapped method
686 if (funName != "construct") {
687 Clazz.alert (["j2slib","no class found",(funParams).typeString])
688 newMethodNotFoundException(objThis, clazzThis, funName,
689 Clazz.getParamsType(funParams).typeString);
691 /* there are members which are initialized out of the constructor */
692 /* No super constructor! */
695 /* there are members which are initialized out of the constructor */
696 if (i == 0 && funName == "construct") {
697 var ss = clazzFun.stacks;
698 if (ss && !ss[0].superClazz && ss[0].con$truct)
699 ss[0].con$truct.apply (objThis, []);
701 /*# {$no.debug.support} >>x #*/
703 if (Clazz.tracingCalling) {
704 var caller = arguments.callee.caller;
705 if (caller === Clazz.superConstructor) {
706 caller = caller.arguments.callee.caller;
708 Clazz._callingStackTraces.push(new Clazz.callingStack (caller, clazzThis));
709 var ret = fx.apply (objThis, (funParams == null) ? [] : funParams);
710 Clazz._callingStackTraces.pop();
715 return fx.apply (objThis, funParams || []);
719 * Call super constructor of the class.
720 * The same effect as Java's expression:
721 * <code> super () </code>
724 Clazz.superConstructor = function (objThis, clazzThis, funParams) {
725 Clazz.superCall (objThis, clazzThis, "construct", funParams);
726 /* If there are members which are initialized out of the constructor */
727 if (clazzThis.con$truct) {
728 clazzThis.con$truct.apply (objThis, []);
733 * Class for null with a given class as to be casted.
734 * This class will be used as an implementation of Java's casting way.
736 * <code> this.call ((String) null); </code>
739 Clazz.CastedNull = function (asClazz) {
741 if (asClazz instanceof String) {
742 this.clazzName = asClazz;
743 } else if (asClazz instanceof Function) {
744 this.clazzName = Clazz.getClassName (asClazz, true);
746 this.clazzName = "" + asClazz;
749 this.clazzName = "Object";
751 this.toString = function () {
754 this.valueOf = function () {
760 * API for Java's casting null.
761 * @see Clazz.CastedNull
763 * @param asClazz given class
764 * @return an instance of class Clazz.CastedNull
767 Clazz.castNullAs = function (asClazz) {
768 return new Clazz.CastedNull (asClazz);
771 /////////////////////////// Exception handling ////////////////////////////
774 * Use to mark that the Throwable instance is created or not.
776 * Called from java.lang.Throwable, as defined in JSmolJavaExt.js
778 * The underscore is important - it tells the JSmol ANT task to NOT
779 * turn this into Clazz_initializingException, because coreBottom2.js does
780 * not include that call, and so Google Closure Compiler does not minify it.
784 Clazz._initializingException = false;
787 * BH: used in Throwable
791 Clazz._callingStackTraces = [];
794 * MethodException will be used as a signal to notify that the method is
795 * not found in the current clazz hierarchy.
798 var MethodException = function () {
799 this.toString = function () {
800 return "J2S MethodException";
804 //var MethodNotFoundException = function () {
805 // this.toString = function () {
806 // return "J2S MethodNotFoundException";
810 var _isNPEExceptionPredicate;
814 /* sgurin: native exception detection mechanism. Only NullPointerException detected and wrapped to java excepions */
815 /** private utility method for creating a general regexp that can be used later
816 * for detecting a certain kind of native exceptions. use with error messages like "blabla IDENTIFIER blabla"
817 * @param msg String - the error message
818 * @param spliterName String, must be contained once in msg
819 * spliterRegex String, a string with the regexp literal for identifying the spitter in exception further error messages.
821 // reproduce NullPointerException for knowing how to detect them, and create detector function Clazz._isNPEExceptionPredicate
827 var _ex_reg = function(msg, spliterName, spliterRegex) {
829 spliterRegex="[^\\s]+";
830 var idx = msg.indexOf (spliterName),
831 str = msg.substring (0, idx) + spliterRegex + msg.substring(idx + spliterName.length),
832 regexp = new RegExp("^"+str+"$");
835 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... "
836 var idx1 = e.message.indexOf(":"), idx2 = e.message.indexOf(":", idx1+2);
837 var _NPEMsgFragment = e.message.substr(idx1+1, idx2-idx1-20);
838 _isNPEExceptionPredicate = function(e) { return e.message.indexOf(_NPEMsgFragment)!=-1; };
839 } else if(navigator.userAgent.toLowerCase().indexOf("webkit")!=-1) { //webkit, google chrome prints the property name accessed.
840 var _exceptionNPERegExp = _ex_reg(e.message, "hello");
841 _isNPEExceptionPredicate = function(e) { return _exceptionNPERegExp.test(e.message); };
842 } else {// ie, firefox and others print the name of the object accessed:
843 var _exceptionNPERegExp = _ex_reg(e.message, "$$o$$");
844 _isNPEExceptionPredicate = function(e) { return _exceptionNPERegExp.test(e.message); };
850 * Implements Java's keyword "instanceof" in JavaScript's way **for exception objects**.
852 * calls Clazz.instanceOf if e is a Java exception. If not, try to detect known native
853 * exceptions, like native NullPointerExceptions and wrap it into a Java exception and
854 * call Clazz.instanceOf again. if the native exception can't be wrapped, false is returned.
856 * @param obj the object to be tested
857 * @param clazz the class to be checked
858 * @return whether the object is an instance of the class
861 Clazz.exceptionOf = function(e, clazz) {
863 return Clazz.instanceOf(e, clazz);
865 e.getMessage = function() {return "" + this};
867 if (!e.printStackTrace) {
868 e.printStackTrace = function(){};
869 alert(e + " try/catch path:" + Clazz.getStackTrace(-10));
872 if (("" + e).indexOf("Error") < 0)
874 System.out.println (Clazz.getStackTrace());
876 // everything here is a Java Exception, not a Java Error
878 return (clazz == Exception || clazz == Throwable
879 || clazz == NullPointerException && _isNPEExceptionPredicate(e));
883 * BH need to limit this, as JavaScript call stack may be recursive
885 Clazz.getStackTrace = function(n) {
887 // updateNode and updateParents cause infinite loop here
889 var c = arguments.callee;
890 var showParams = (n < 0);
893 for (var i = 0; i < n; i++) {
896 var sig = (c.toString ? c.toString().substring(0, c.toString().indexOf("{")) : "<native method>");
897 s += i + " " + (c.exName ? (c.claxxOwner ? c.claxxOwner.__CLASS_NAME__ + "." : "") + c.exName + sig.replace(/function /,""): sig) + "\n";
899 s += "<recursing>\n";
903 var args = c.arguments;
904 for (var j = 0; j < args.length; j++) {
905 var sa = "" + args[j];
907 sa = sa.substring(0, 60) + "...";
908 s += " args[" + j + "]=" + sa.replace(/\s+/g," ") + "\n";
915 ///////////////////// method creation ////////////////////////////////
918 * Make constructor for the class with the given function body and parameters
921 * @param clazzThis host class
922 * @param funBody constructor body
923 * @param funParams constructor parameters signature
926 Clazz.makeConstructor = function (clazzThis, funBody, funParams) {
927 Clazz.defineMethod (clazzThis, "construct", funBody, funParams);
928 if (clazzThis.con$truct) {
929 clazzThis.con$truct.index = clazzThis.con$truct.stacks.length;
931 //clazzThis.con$truct = clazzThis.prototype.con$truct = null;
935 * Override constructor for the class with the given function body and
936 * parameters signature.
938 * @param clazzThis host class
939 * @param funBody constructor body
940 * @param funParams constructor parameters signature
943 Clazz.overrideConstructor = function (clazzThis, funBody, funParams) {
944 Clazz.overrideMethod (clazzThis, "construct", funBody, funParams);
945 if (clazzThis.con$truct) {
946 clazzThis.con$truct.index = clazzThis.con$truct.stacks.length;
948 //clazzThis.con$truct = clazzThis.prototype.con$truct = null;
953 * Define method for the class with the given method name and method
954 * body and method parameter signature.
956 * @param clazzThis host class in which the method to be defined
957 * @param funName method name
958 * @param funBody function object, e.g function () { ... }
959 * @param funParams paramether signature, e.g ["string", "number"]
960 * @return method of the given name. The method may be funBody or a wrapper
961 * of the given funBody.
964 Clazz.defineMethod = function (clazzThis, funName, funBody, funParams) {
965 if (Clazz.assureInnerClass)
966 Clazz.assureInnerClass(clazzThis, funBody);
967 funBody.exName = funName;
968 var fpName = formatParameters(funParams);
969 var proto = clazzThis.prototype;
970 var f$ = proto[funName];
971 if (Clazz._Loader._checkLoad)
972 checkDuplicate(clazzThis, funName, fpName);
973 if (!f$ || (f$.claxxOwner === clazzThis && f$.funParams == fpName)) {
974 // property "funParams" will be used as a mark of only-one method
975 funBody.funParams = fpName;
976 funBody.claxxOwner = clazzThis;
977 funBody.exClazz = clazzThis; // make it traceable
978 return addProto(proto, funName, funBody);
980 // we have found a duplicate
982 var oldStacks = f$.stacks;
984 /* method is not defined by Clazz.defineMethod () */
988 oldStacks[0] = oldFun.claxxOwner;
992 * Method that is already defined in super class will be overridden
993 * with a new proxy method with class hierarchy stored in a stack.
994 * That is to say, the super methods are lost in this class' proxy
996 * When method are being called, methods defined in the new proxy
997 * method will be searched through first. And if no method fitted,
998 * it will then try to search method in the super class stacks.
1000 if (!f$.stacks || f$.claxxReference !== clazzThis) {
1001 //Generate a new delegating method for the class
1003 var delegate = function () {
1004 return searchAndExecuteMethod(id, this, arguments.callee.claxxReference, arguments.callee.methodName, arguments);
1006 delegate.methodName = funName;
1007 delegate.claxxReference = clazzThis;
1008 f$ = addProto(proto, funName, delegate);
1009 // Keep the class inheritance stacks
1011 for (var i = 0; i < oldStacks.length; i++)
1012 arr[i] = oldStacks[i];
1016 if (findArrayItem(ss, clazzThis) < 0) ss.push(clazzThis);
1019 if (oldFun.claxxOwner === clazzThis) {
1020 f$[oldFun.funParams] = oldFun;
1021 oldFun.claxxOwner = null;
1022 // property "funParams" will be used as a mark of only-one method
1023 oldFun.funParams = null; // null ? safe ? // safe for != null
1024 } else if (!oldFun.claxxOwner) {
1026 * The function is not defined Clazz.defineMethod ().
1027 * Try to fixup the method ...
1028 * As a matter of lost method information, I just suppose
1029 * the method to be fixed is with void parameter!
1031 f$["\\unknown"] = oldFun;
1034 funBody.exClazz = clazzThis; // make it traceable
1035 f$[fpName] = funBody;
1039 duplicatedMethods = {};
1041 var checkDuplicate = function(clazzThis, funName, fpName) {
1042 var proto = clazzThis.prototype;
1043 var f$ = proto[funName];
1044 if (f$ && (f$.claxxOwner || f$.claxxReference) === clazzThis) {
1045 key = clazzThis.__CLASS_NAME__ + "." + funName + fpName;
1046 var m = duplicatedMethods[key];
1048 var s = "Warning! Duplicate method found for " + key;
1049 System.out.println(s);
1051 duplicatedMethods[key] = m + 1;
1053 duplicatedMethods[key] = 1;
1058 Clazz.showDuplicates = function(quiet) {
1060 var a = duplicatedMethods;
1064 s += a[key] + "\t" + key + "\n";
1067 s = "Duplicates: " + n + "\n\n" + s;
1068 System.out.println(s);
1073 var findArrayItem = function(arr, item) {
1075 for (var i = arr.length; --i >= 0;)
1076 if (arr[i] === item)
1081 var removeArrayItem = function(arr, item) {
1082 var i = findArrayItem(arr, item);
1084 var n = arr.length - 1;
1086 arr[i] = arr[i + 1];
1093 * Other developers may need to extend this formatParameters method
1094 * to deal complicated situation.
1097 var formatParameters = function (funParams) {
1098 return (funParams ? funParams.replace (/~([NABSO])/g,
1113 }).replace (/\s+/g, "").replace (/^|,/g, "\\").replace (/\$/g, "org.eclipse.s") : "\\void");
1117 * Override the existed methods which are in the same name.
1118 * Overriding methods is provided for the purpose that the JavaScript
1119 * does not need to search the whole hierarchied methods to find the
1120 * correct method to execute.
1121 * Be cautious about this method. Incorrectly using this method may
1122 * break the inheritance system.
1124 * @param clazzThis host class in which the method to be defined
1125 * @param funName method name
1126 * @param funBody function object, e.g function () { ... }
1127 * @param funParams paramether signature, e.g ["string", "number"]
1130 Clazz.overrideMethod = function(clazzThis, funName, funBody, funParams) {
1131 if (Clazz.assureInnerClass) Clazz.assureInnerClass (clazzThis, funBody);
1132 funBody.exName = funName;
1133 var fpName = formatParameters(funParams);
1134 if (Clazz._Loader._checkLoad)
1135 checkDuplicate(clazzThis, funName, fpName);
1137 * Replace old methods with new method. No super methods are kept.
1139 funBody.funParams = fpName;
1140 funBody.claxxOwner = clazzThis;
1141 return addProto(clazzThis.prototype, funName, funBody);
1144 ////////////// Overridden and Overloaded Java Method Handling //////////////////
1145 // SAEM (SearchAndExecuteMethod)
1150 * BH Clazz.getProfile monitors exactly what is being delegated with SAEM,
1151 * which could be a bottle-neck for function calling.
1152 * This is critical for performance optimization.
1155 var __signatures = "";
1157 Clazz.getProfile = function() {
1161 for (var i in _profile) {
1162 var n = "" + _profile[i];
1163 l.push(" ".substring(n.length) + n + "\t" + i);
1165 s = l.sort().reverse().join("\r\n");
1168 return s + __signatures;
1171 var addProfile = function(c, f, p, id) {
1172 var s = id + " " + c.__CLASS_NAME__ + " " + f + " ";// + JSON.stringify(p);
1173 if (__signatures.indexOf(s) < 0)
1174 __signatures += s + "\n";
1175 _profile[s] || (_profile[s] = 0);
1180 * Called also by Throwable
1183 Clazz.getParamsType = function (funParams) {
1184 // bh: optimization here for very common cases
1185 var n = funParams.length;
1188 var params = ["void"];
1189 params.typeString = "\\void";
1192 // BH just so common
1193 switch (typeof obj) {
1196 params.typeString = "\\n";
1200 params.typeString = "\\b";
1206 params.hasCastedNull = false;
1208 for (var i = 0; i < n; i++) {
1209 params[i] = Clazz.getClassName (funParams[i]);
1210 if (funParams[i] instanceof Clazz.CastedNull) {
1211 params.hasCastedNull = true;
1215 params.typeString = "\\" + params.join ('\\');
1222 //var SAEMarray = [];
1224 * BH: OK, this was an idea that doesn't work. The idea was to tag SAEM calls
1225 * and then refer back to an array. But the id number cannot be put in the right place.
1229 * StringBuffer sb = new StringBuffer();
1230 * sb.append("").append(1);
1232 * Here we have two different append methods to call. They are saved under two
1233 * names: StringBuffer.prototype.append["\\String"]
1234 * and StringBuffer.prototype.append["\\Number"]
1236 * The job of generateDelegatingMethod is to discriminate between those two. We can do
1237 * that, but the real issue is that we have to do that EVERY time a call is made.
1238 * This is a problem that must be handled at compile time. There is no way to
1239 * make .append("") to go one way the first time and another way the second time.
1240 * What we need at run time is something like this:
1242 * Clazz.delegate(sb.append,1,[""]) and Clazz.delegate(sb.append,2,[1])
1243 * The we would be able to log those numbers at run time and refer to them.
1245 * The only real way to avoid SAEM is:
1247 * 1) to never call super() -- always call a differently named function in a superclass.
1248 * 2) don't overload functions
1254 * Search the given class prototype, find the method with the same
1255 * method name and the same parameter signatures by the given
1256 * parameters, and then run the method with the given parameters.
1258 * @param objThis the current host object
1259 * @param claxxRef the current host object's class
1260 * @param fxName the method name
1261 * @param funParams the given arguments
1262 * @return the result of the specified method of the host object,
1263 * the return maybe void.
1264 * @throws MethodNotFoundException if no matched method is found
1267 var searchAndExecuteMethod = function (id, objThis, claxxRef, fxName, args, _saem) {
1269 // var fx = SAEMarray[id];
1271 // return fx.apply(objThis, args);
1275 fx = objThis[fxName];
1276 var params = Clazz.getParamsType(args);
1279 var s = "SAEM " + claxxRef.__CLASS_NAME__ + "." + fxName + "(" + params+ ")\n";
1280 if (xxxSAEMlist.length > 300)xxxSAEMlist = "";
1285 try {System.out.println(Clazz.getStackTrace(5))} catch (e){}
1286 _profile && addProfile(claxxRef, fxName, params, id);
1287 // Cache last matched method
1288 if (fx.lastParams == params.typeString && fx.lastClaxxRef === claxxRef) {
1290 if (params.hasCastedNull) {
1292 // For Clazz.CastedNull instances, the type name is
1293 // already used to indentified the method in searchMethod.
1294 for (var k = 0; k < args.length; k++)
1295 methodParams[k] = (args[k] instanceof Clazz.CastedNull ? null : args[k]);
1297 // if (fx.lastMethod) SAEMarray[id] = fx.lastMethod;
1298 methodParams = args;
1300 return (fx.lastMethod ? fx.lastMethod.apply(objThis, methodParams) : null);
1302 fx.lastParams = params.typeString;
1303 fx.lastClaxxRef = claxxRef;
1305 var stacks = fx.stacks;
1307 stacks = claxxRef.prototype[fxName].stacks;
1308 var length = stacks.length;
1311 * Search the inheritance stacks to get the given class' function
1313 var began = false; // began to search its super classes
1314 for (var i = length; --i >= 0;) {
1315 if (began || stacks[i] === claxxRef) {
1317 * First try to search method within the same class scope
1318 * with stacks[i] === claxxRef
1320 var clazzFun = stacks[i].prototype[fxName];
1321 var ret = tryToSearchAndExecute(id, fxName, objThis, clazzFun, params,
1323 if (!(ret instanceof MethodException)) {
1327 * As there are no such methods in current class, Clazz will try
1328 * to search its super class stacks. Here variable began indicates
1329 * that super searchi is began, and there is no need checking
1330 * <code>stacks[i] === claxxRef</code>
1335 if ("construct" == fxName) {
1337 * For non existed constructors, just return without throwing
1338 * exceptions. In Java codes, extending Object can call super
1339 * default Object#constructor, which is not defined in JS.
1343 newMethodNotFoundException(objThis, claxxRef,
1344 fxName, params.typeString);
1349 var tryToSearchAndExecute = function(id, fxName, objThis, clazzFun, params, args, fx, _ttsaem) {
1352 for (var fn in clazzFun) {
1353 if (fn.charCodeAt(0) == 92) { // 92 == '\\'.charCodeAt (0)
1354 var ps = fn.substring(1).split("\\");
1355 (ps.length == params.length) && method.push(ps);
1360 * When there is only one method in the class, use the args
1361 * to identify the parameter type.
1363 * AbstractCollection.remove (Object)
1364 * AbstractList.remove (int)
1365 * ArrayList.remove (int)
1367 * Then calling #remove (Object) method on ArrayList instance will
1368 * need to search up to the AbstractCollection.remove (Object),
1369 * which contains only one method.
1372 * See Clazz#defineMethod --Mar 10, 2006, josson
1374 if (generic && fn == "funParams" && clazzFun.funParams) {
1375 fn = clazzFun.funParams;
1376 var ps = fn.substring(1).split ("\\");
1377 (ps.length == params.length) && (method[0] = ps);
1381 var debug = false;//(method.length > 1 && method.join().indexOf("Listen")< 0 && params.join().indexOf("Null") >= 0)
1382 if (debug)alert(fxName + " -- " + method.join("|") + " -- searching for method with " + params)
1383 if (method.length == 0 || !(method = searchMethod(method, params, debug)))
1384 return new MethodException();
1385 if (debug) alert("OK: \\" + method)
1386 var f = (generic ? clazzFun : clazzFun["\\" + method]);
1388 //{ /* Use the generic method */
1390 * Will this case be reachable?
1391 * March 4, 2006 josson
1393 * Reachable for calling #remove (Object) method on
1394 * ArrayList instance
1395 * May 5, 2006 josson
1397 var methodParams = null;
1398 if (params.hasCastedNull) {
1400 for (var k = 0; k < args.length; k++) {
1401 if (args[k] instanceof Clazz.CastedNull) {
1403 * For Clazz.CastedNull instances, the type name is
1404 * already used to indentify the method in searchMethod.
1406 methodParams[k] = null;
1408 methodParams[k] = args[k];
1412 methodParams = args;
1415 //if (!params.hasCastedNull) SAEMarray[id] = f;
1416 return f.apply(objThis, methodParams);
1420 * Search the existed polymorphic methods to get the matched method with
1421 * the given parameter types.
1423 * @param existedMethods Array of string which contains method parameters
1424 * @param paramTypes Array of string that is parameter type.
1425 * @return string of method parameters seperated by "\\"
1428 var searchMethod = function(roundOne, paramTypes, debug) {
1430 // Filter out all the fitted methods for the given parameters
1432 var len = roundOne.length;
1433 for (var i = 0; i < len; i++) {
1434 var fittedLevel = [];
1435 var isFitted = true;
1436 var len2 = roundOne[i].length;
1437 for (var j = 0; j < len2; j++) {
1439 fittedLevel[j] = Clazz.getInheritedLevel (paramTypes[j],
1441 //if (debug)alert([paramTypes[j],fittedLevel[j],roundOne[i][j]])
1442 if (fittedLevel[j] < 0) {
1448 fittedLevel[paramTypes.length] = i; // Keep index for later use
1449 roundTwo.push(fittedLevel);
1452 if (roundTwo.length == 0)
1454 // Find out the best method according to the inheritance.
1455 var resultTwo = roundTwo;
1456 var min = resultTwo[0];
1457 for (var i = 1; i < resultTwo.length; i++) {
1458 var isVectorLesser = true;
1459 for (var j = 0; j < paramTypes.length; j++) {
1460 if (min[j] < resultTwo[i][j]) {
1461 isVectorLesser = false;;
1468 var index = min[paramTypes.length]; // Get the previously stored index
1470 * Return the method parameters' type string as indentifier of the
1473 return roundOne[index].join ('\\');
1476 ////////////////////////////////// package loading ///////////////////////
1479 * all root packages. e.g. java.*, org.*, com.*
1482 Clazz.allPackage = {};
1485 * Will be used to keep value of whether the class is defined or not.
1488 Clazz.allClasses = {};
1490 Clazz.lastPackageName = null;
1491 Clazz.lastPackage = null;
1494 Clazz.unloadedClasses = [];
1497 Clazz.declarePackage = function (pkgName) {
1498 if (Clazz.lastPackageName == pkgName)
1499 return Clazz.lastPackage;
1500 if (pkgName && pkgName.length) {
1501 var pkgFrags = pkgName.split (/\./);
1502 var pkg = Clazz.allPackage;
1503 for (var i = 0; i < pkgFrags.length; i++) {
1504 if (!pkg[pkgFrags[i]]) {
1505 pkg[pkgFrags[i]] = {
1506 __PKG_NAME__ : (pkg.__PKG_NAME__ ?
1507 pkg.__PKG_NAME__ + "." + pkgFrags[i] : pkgFrags[i])
1509 // pkg[pkgFrags[i]] = {};
1512 Clazz.setGlobal(pkgFrags[i], pkg[pkgFrags[i]]);
1515 pkg = pkg[pkgFrags[i]]
1517 Clazz.lastPackageName = pkgName;
1518 Clazz.lastPackage = pkg;
1524 Clazz.evalType = function (typeStr, isQualified) {
1525 var idx = typeStr.lastIndexOf(".");
1527 var pkgName = typeStr.substring (0, idx);
1528 var pkg = Clazz.declarePackage (pkgName);
1529 var clazzName = typeStr.substring (idx + 1);
1530 return pkg[clazzName];
1533 return window[typeStr];
1552 return window[typeStr];
1557 * Define a class or interface.
1559 * @param qClazzName String presents the qualified name of the class
1560 * @param clazzFun Function of the body
1561 * @param clazzParent Clazz to inherit from, may be null
1562 * @param interfacez Clazz may implement one or many interfaces
1563 * interfacez can be Clazz object or Array of Clazz objects.
1564 * @return Ruturn the modified Clazz object
1567 Clazz.defineType = function (qClazzName, clazzFun, clazzParent, interfacez) {
1568 var cf = Clazz.unloadedClasses[qClazzName];
1572 var idx = qClazzName.lastIndexOf (".");
1574 var pkgName = qClazzName.substring (0, idx);
1575 var pkg = Clazz.declarePackage (pkgName);
1576 var clazzName = qClazzName.substring (idx + 1);
1577 if (pkg[clazzName]) {
1578 // already defined! Should throw exception!
1579 return pkg[clazzName];
1581 pkg[clazzName] = clazzFun;
1583 if (window[qClazzName]) {
1584 // already defined! Should throw exception!
1585 return window[qClazzName];
1587 Clazz.setGlobal(qClazzName, clazzFun);
1589 Clazz.decorateAsType(clazzFun, qClazzName, clazzParent, interfacez);
1590 /*# {$no.javascript.support} >>x #*/
1591 var iFun = Clazz._innerFunctions;
1592 clazzFun.defineMethod = iFun.defineMethod;
1593 clazzFun.defineStaticMethod = iFun.defineStaticMethod;
1594 clazzFun.makeConstructor = iFun.makeConstructor;
1599 var isSafari = (navigator.userAgent.indexOf ("Safari") != -1);
1600 var isSafari4Plus = false;
1602 var ua = navigator.userAgent;
1603 var verIdx = ua.indexOf("Version/");
1605 var verStr = ua.substring(verIdx + 8);
1606 var verNumber = parseFloat(verStr);
1607 isSafari4Plus = verNumber >= 4.0;
1612 Clazz.instantialize = function (objThis, args) {
1615 if (args && args.length == 1 && args[0]
1616 && args[0] instanceof args4InheritClass) {
1619 if (objThis instanceof Number) {
1620 objThis.valueOf = function () {
1624 if (isSafari4Plus) { // Fix bug of Safari 4.0+'s over-optimization
1626 for (var k = 0; k < args.length; k++) {
1627 argsClone[k] = args[k];
1632 var c = objThis.construct;
1634 if (!objThis.con$truct) { // no need to init fields
1635 c.apply (objThis, args);
1636 } else if (!objThis.getClass ().superClazz) { // the base class
1637 objThis.con$truct.apply (objThis, []);
1638 c.apply (objThis, args);
1639 } else if ((c.claxxOwner
1640 && c.claxxOwner === objThis.getClass ())
1642 && c.stacks[c.stacks.length - 1] == objThis.getClass ())) {
1644 * This #construct is defined by this class itself.
1645 * #construct will call Clazz.superConstructor, which will
1646 * call #con$truct back
1648 c.apply (objThis, args);
1649 } else { // constructor is a super constructor
1650 if (c.claxxOwner && !c.claxxOwner.superClazz
1651 && c.claxxOwner.con$truct) {
1652 c.claxxOwner.con$truct.apply (objThis, []);
1653 } else if (c.stacks && c.stacks.length == 1
1654 && !c.stacks[0].superClazz) {
1655 c.stacks[0].con$truct.apply (objThis, []);
1657 c.apply (objThis, args);
1658 objThis.con$truct.apply (objThis, []);
1660 } else if (objThis.con$truct) {
1661 objThis.con$truct.apply (objThis, []);
1666 * Once there are other methods registered to the Function.prototype,
1667 * those method names should be add to the following Array.
1670 * static final member of interface may be a class, which may
1674 Clazz.innerFunctionNames = [
1675 "isInstance", "equals", "hashCode", /*"toString",*/ "getName", "getCanonicalName", "getClassLoader", "getResource", "getResourceAsStream" /*# {$no.javascript.support} >>x #*/, "defineMethod", "defineStaticMethod",
1676 "makeConstructor" /*# x<< #*/
1682 Clazz._innerFunctions = {
1684 * Similar to Object#equals
1687 isInstance: function(c) {
1688 return Clazz.instanceOf(c, this);
1691 equals : function (aFun) {
1692 return this === aFun;
1695 hashCode : function () {
1696 return this.getName ().hashCode ();
1699 toString : function () {
1700 return "class " + this.getName ();
1704 * Similar to Class#getName
1706 getName : function () {
1707 return Clazz.getClassName (this, true);
1709 getCanonicalName : function () {
1710 return this.__CLASS_NAME__;
1712 getClassLoader : function () {
1713 var clazzName = this.__CLASS_NAME__;
1714 var baseFolder = Clazz._Loader.getClasspathFor(clazzName);
1715 var x = baseFolder.lastIndexOf (clazzName.replace (/\./g, "/"));
1717 baseFolder = baseFolder.substring (0, x);
1719 baseFolder = Clazz._Loader.getClasspathFor(clazzName, true);
1721 var loader = Clazz._Loader.requireLoaderByBase(baseFolder);
1722 loader.getResourceAsStream = Clazz._innerFunctions.getResourceAsStream;
1723 loader.getResource = Clazz._innerFunctions.getResource; // BH
1727 getResource : function(name) {
1728 var stream = this.getResourceAsStream(name);
1729 return (stream ? stream.url : null);
1732 getResourceAsStream : function (name) {
1735 name = name.replace (/\\/g, '/');
1736 var baseFolder = null;
1738 var clazzName = this.__CLASS_NAME__;
1739 if (arguments.length == 2 && name.indexOf ('/') != 0) { // additional argument
1742 if (name.indexOf ('/') == 0) {
1743 //is.url = name.substring (1);
1744 if (arguments.length == 2) { // additional argument
1745 baseFolder = arguments[1];
1747 baseFolder = Clazz.binaryFolders[0];
1748 } else if (Clazz._Loader) {
1749 baseFolder = Clazz._Loader.getClasspathFor(clazzName, true);
1752 fname = name.substring (1);
1754 baseFolder = baseFolder.replace (/\\/g, '/');
1755 var length = baseFolder.length;
1756 var lastChar = baseFolder.charAt (length - 1);
1757 if (lastChar != '/') {
1760 fname = baseFolder + name.substring (1);
1764 baseFolder = this.base;
1765 } else if (Clazz._Loader) {
1766 baseFolder = Clazz._Loader.getClasspathFor(clazzName);
1767 var x = baseFolder.lastIndexOf (clazzName.replace (/\./g, "/"));
1769 baseFolder = baseFolder.substring (0, x);
1771 //baseFolder = null;
1773 if (baseFolder.indexOf (".z.js") == baseFolder.length - 5
1774 && (y = baseFolder.lastIndexOf ("/")) != -1) {
1775 baseFolder = baseFolder.substring (0, y + 1);
1776 var pkgs = clazzName.split (/\./);
1777 for (var k = 1; k < pkgs.length; k++) {
1779 for (var j = 0; j < k; j++) {
1780 pkgURL += pkgs[j] + "/";
1782 if (pkgURL.length > baseFolder.length) {
1785 if (baseFolder.indexOf (pkgURL) == baseFolder.length - pkgURL.length) {
1786 baseFolder = baseFolder.substring (0, baseFolder.length - pkgURL.length + 1);
1791 baseFolder = Clazz._Loader.getClasspathFor(clazzName, true);
1795 var bins = Clazz.binaryFolders;
1796 if (bins && bins.length) {
1797 baseFolder = bins[0];
1801 baseFolder = "j2s/";
1802 baseFolder = baseFolder.replace (/\\/g, '/');
1803 var length = baseFolder.length;
1804 var lastChar = baseFolder.charAt (length - 1);
1805 if (lastChar != '/') {
1809 fname = baseFolder + name;
1811 var idx = clazzName.lastIndexOf ('.');
1812 if (idx == -1 || this.base) {
1813 fname = baseFolder + name;
1815 fname = baseFolder + clazzName.substring (0, idx)
1816 .replace (/\./g, '/') + "/" + name;
1822 if (fname.indexOf(":/") < 0) {
1823 var d = document.location.href.split("?")[0].split("/");
1824 d[d.length - 1] = fname;
1825 fname = d.join("/");
1827 url = new java.net.URL(fname);
1830 var data = (url == null ? null : Jmol._getFileData(fname.toString()));
1831 if (!data || data == "error" || data.indexOf("[Exception") == 0)
1833 var bytes = new java.lang.String(data).getBytes();
1834 var is = new java.io.BufferedInputStream ( new java.io.ByteArrayInputStream (bytes));
1837 }/*# {$no.javascript.support} >>x #*/,
1840 * For JavaScript programmers
1842 defineMethod : function (methodName, funBody, paramTypes) {
1843 Clazz.defineMethod (this, methodName, funBody, paramTypes);
1847 * For JavaScript programmers
1849 defineStaticMethod : function (methodName, funBody, paramTypes) {
1850 Clazz.defineMethod (this, methodName, funBody, paramTypes);
1851 this[methodName] = this.prototype[methodName];
1855 * For JavaScript programmers
1857 makeConstructor : function (funBody, paramTypes) {
1858 Clazz.makeConstructor (this, funBody, paramTypes);
1867 * BH: I would like to be able to remove "self.c$" here, but that is tricky.
1870 Clazz.pu$h = function (c) {
1871 c || (c = self.c$); // old style
1872 c && cStack.push(c);
1875 Clazz.p0p = function () {
1876 return cStack.pop();
1880 Clazz.decorateAsClass = function (clazzFun, prefix, name, clazzParent,
1881 interfacez, parentClazzInstance, _decorateAsClass) {
1883 var prefixName = null;
1885 prefixName = prefix.__PKG_NAME__;
1887 prefixName = prefix.__CLASS_NAME__;
1889 var qName = (prefixName ? prefixName + "." : "") + name;
1891 if (Clazz._Loader._classPending[qName]) {
1892 delete Clazz._Loader._classPending[qName];
1893 Clazz._Loader._classCountOK++;
1894 Clazz._Loader._classCountPending--;
1896 if (Clazz._Loader && Clazz._Loader._checkLoad) {
1897 System.out.println("decorating class " + prefixName + "." + name);
1899 var cf = Clazz.unloadedClasses[qName];
1904 decorateFunction(clazzFun, prefix, name);
1905 if (parentClazzInstance) {
1906 Clazz.inheritClass (clazzFun, clazzParent, parentClazzInstance);
1907 } else if (clazzParent) {
1908 Clazz.inheritClass (clazzFun, clazzParent);
1911 Clazz.implementOf (clazzFun, interfacez);
1917 var decorateFunction = function (clazzFun, prefix, name, _decorateFunction) {
1920 // e.g. Clazz.declareInterface (null, "ICorePlugin", org.eclipse.ui.IPlugin);
1922 Clazz.setGlobal(name, clazzFun);
1923 } else if (prefix.__PKG_NAME__) {
1924 // e.g. Clazz.declareInterface (org.eclipse.ui, "ICorePlugin", org.eclipse.ui.IPlugin);
1925 qName = prefix.__PKG_NAME__ + "." + name;
1926 prefix[name] = clazzFun;
1927 if (prefix === java.lang)
1928 Clazz.setGlobal(name, clazzFun);
1930 // e.g. Clazz.declareInterface (org.eclipse.ui.Plugin, "ICorePlugin", org.eclipse.ui.IPlugin);
1931 qName = prefix.__CLASS_NAME__ + "." + name;
1932 prefix[name] = clazzFun;
1934 Clazz.extendJO(clazzFun, qName);
1935 var inF = Clazz.innerFunctionNames;
1936 for (var i = 0; i < inF.length; i++) {
1937 clazzFun[inF[i]] = Clazz._innerFunctions[inF[i]];
1941 Clazz._Loader.updateNodeForFunctionDecoration(qName);
1945 Clazz.declareInterface = function (prefix, name, interfacez, _declareInterface) {
1946 var clazzFun = function () {};
1947 decorateFunction(clazzFun, prefix, name);
1949 Clazz.implementOf (clazzFun, interfacez);
1955 Clazz.declareType = function (prefix, name, clazzParent, interfacez,
1956 parentClazzInstance, _declareType) {
1957 var f = function () {
1958 Clazz.instantialize (this, arguments);
1960 return Clazz.decorateAsClass (f, prefix, name, clazzParent, interfacez,
1961 parentClazzInstance);
1965 Clazz.declareAnonymous = function (prefix, name, clazzParent, interfacez,
1966 parentClazzInstance, _declareAnonymous) {
1967 var f = function () {
1968 Clazz.prepareCallback(this, arguments);
1969 Clazz.instantialize (this, arguments);
1971 return Clazz.decorateAsClass (f, prefix, name, clazzParent, interfacez,
1972 parentClazzInstance);
1976 Clazz.decorateAsType = function (clazzFun, qClazzName, clazzParent,
1977 interfacez, parentClazzInstance, inheritClazzFuns, _decorateAsType) {
1978 Clazz.extendJO(clazzFun, qClazzName);
1979 clazzFun.equals = Clazz._innerFunctions.equals;
1980 clazzFun.getName = Clazz._innerFunctions.getName;
1981 if (inheritClazzFuns) {
1982 for (var i = 0; i < Clazz.innerFunctionNames.length; i++) {
1983 var methodName = Clazz.innerFunctionNames[i];
1984 clazzFun[methodName] = Clazz._innerFunctions[methodName];
1987 if (parentClazzInstance) {
1988 Clazz.inheritClass (clazzFun, clazzParent, parentClazzInstance);
1989 } else if (clazzParent) {
1990 Clazz.inheritClass (clazzFun, clazzParent);
1993 Clazz.implementOf (clazzFun, interfacez);
1999 ////////////////////////// default package declarations ////////////////////////
2001 /* sgurin: preserve Number.prototype.toString */
2002 Number.prototype._numberToString=Number.prototype.toString;
2005 Clazz.declarePackage ("java.io");
2006 //Clazz.declarePackage ("java.lang");
2007 Clazz.declarePackage ("java.lang.annotation"); // java.lang
2008 Clazz.declarePackage ("java.lang.instrument"); // java.lang
2009 Clazz.declarePackage ("java.lang.management"); // java.lang
2010 Clazz.declarePackage ("java.lang.reflect"); // java.lang
2011 Clazz.declarePackage ("java.lang.ref"); // java.lang.ref
2012 java.lang.ref.reflect = java.lang.reflect;
2013 Clazz.declarePackage ("java.util");
2014 //var reflect = Clazz.declarePackage ("java.lang.reflect");
2015 Clazz.declarePackage ("java.security");
2019 * Consider these interfaces are basic!
2021 Clazz.declareInterface (java.io,"Closeable");
2022 Clazz.declareInterface (java.io,"DataInput");
2023 Clazz.declareInterface (java.io,"DataOutput");
2024 Clazz.declareInterface (java.io,"Externalizable");
2025 Clazz.declareInterface (java.io,"Flushable");
2026 Clazz.declareInterface (java.io,"Serializable");
2027 Clazz.declareInterface (java.lang,"Iterable");
2028 Clazz.declareInterface (java.lang,"CharSequence");
2029 Clazz.declareInterface (java.lang,"Cloneable");
2030 Clazz.declareInterface (java.lang,"Appendable");
2031 Clazz.declareInterface (java.lang,"Comparable");
2032 Clazz.declareInterface (java.lang,"Runnable");
2033 Clazz.declareInterface (java.util,"Comparator");
2035 java.lang.ClassLoader = {
2036 __CLASS_NAME__ : "ClassLoader"
2039 /******************************************************************************
2040 * Copyright (c) 2007 java2script.org and others.
2041 * All rights reserved. This program and the accompanying materials
2042 * are made available under the terms of the Eclipse Public License v1.0
2043 * which accompanies this distribution, and is available at
2044 * http://www.eclipse.org/legal/epl-v10.html
2047 * Zhou Renjian - initial API and implementation
2048 *****************************************************************************/
2050 * @author zhou renjian
2051 * @create March 10, 2006
2055 * Once ClassExt.js is part of Class.js.
2056 * In order to make the Class.js as small as possible, part of its content
2057 * is moved into this ClassExt.js.
2059 * See also http://j2s.sourceforge.net/j2sclazz/
2063 * Clazz.MethodNotFoundException is used to notify the developer about calling
2064 * methods with incorrect parameters.
2067 // Override the Clazz.MethodNotFoundException in Class.js to give details
2068 var newMethodNotFoundException = function (obj, clazz, method, params) {
2071 paramStr = params.substring (1).replace (/\\/g, ",");
2073 var leadingStr = "";
2074 if (method && method != "construct") {
2075 leadingStr = "Method";
2077 leadingStr = "Constructor";
2079 var message = leadingStr + " " + Clazz.getClassName (clazz, true) + "."
2080 + method + "(" + paramStr + ") is not found!";
2081 throw new java.lang.NoSuchMethodException(message);
2085 * Prepare "callback" for instance of anonymous Class.
2086 * For example for the callback:
2087 * this.callbacks.MyEditor.sayHello();
2089 * This is specifically for inner classes that are referring to
2090 * outer class methods and fields.
2092 * @param objThis the host object for callback
2093 * @param args arguments object. args[0] will be classThisObj -- the "this"
2094 * object to be hooked
2096 * Attention: parameters should not be null!
2099 Clazz.prepareCallback = function (innerObj, args) {
2100 var outerObj = args[0];
2101 var cbName = "b$"; // "callbacks";
2102 if (innerObj && outerObj && outerObj !== window) {
2103 var className = Clazz.getClassName(outerObj, true);
2105 if (innerObj[cbName]) // must make a copy!
2106 for (var s in innerObj[cbName])
2107 obs[s] = innerObj[cbName][s];
2108 innerObj[cbName] = obs;
2111 * TODO: the following line is SWT-specific! Try to move it out!
2113 // obs[className.replace (/org\.eclipse\.swt\./, "$wt.")] = outerObj;
2115 // all references to outer class and its superclass objects must be here as well
2116 obs[className] = outerObj;
2117 var clazz = Clazz.getClass(outerObj);
2118 while (clazz.superClazz) {
2119 clazz = clazz.superClazz;
2121 * TODO: the following line is SWT-specific! Try to move it out!
2123 // obs[Clazz.getClassName (clazz, true)
2124 // .replace (/org\.eclipse\.swt\./, "$wt.")] = outerObj;
2125 obs[Clazz.getClassName(clazz, true)] = outerObj;
2127 var cbs = outerObj[cbName];
2132 // remove "this" argument
2133 // note that args is an instance of arguments -- NOT an array; does not have the .shift() method!
2134 for (var i = 0; i < args.length - 1; i++)
2135 args[i] = args[i + 1];
2140 * Construct instance of the given inner class.
2142 * @param classInner given inner class, alway with name like "*$*"
2143 * @param innerObj this instance which can be used to call back.
2144 * @param finalVars final variables which the inner class may use
2145 * @return the constructed object
2147 * @see Clazz#cloneFinals
2150 Clazz.innerTypeInstance = function (clazzInner, innerObj, finalVars) {
2152 clazzInner = arguments.callee.caller;
2154 if (finalVars || innerObj.$finals) {
2155 obj = new clazzInner(innerObj, Clazz.inheritArgs);
2156 // f$ is short for the once choosen "$finals"
2160 for (var attr in innerObj.f$)
2161 o[attr] = innerObj.f$[attr];
2162 for (var attr in finalVars)
2163 o[attr] = finalVars[attr];
2168 } else if (innerObj.f$) {
2169 obj.f$ = innerObj.f$;
2172 switch (arguments.length) {
2174 return new clazzInner(innerObj);
2176 return (innerObj.__CLASS_NAME__ == clazzInner.__CLASS_NAME__
2177 && arguments[3] === Clazz.inheritArgs ? innerObj : new clazzInner(innerObj, arguments[3]));
2179 return new clazzInner(innerObj, arguments[3], arguments[4]);
2181 return new clazzInner(innerObj, arguments[3], arguments[4],
2184 return new clazzInner(innerObj, arguments[3], arguments[4],
2185 arguments[5], arguments[6]);
2187 return new clazzInner(innerObj, arguments[3], arguments[4],
2188 arguments[5], arguments[6], arguments[7]);
2190 return new clazzInner(innerObj, arguments[3], arguments[4],
2191 arguments[5], arguments[6], arguments[7], arguments[8]);
2193 return new clazzInner(innerObj, arguments[3], arguments[4],
2194 arguments[5], arguments[6], arguments[7], arguments[8],
2197 //Should construct instance manually.
2198 obj = new clazzInner(innerObj, Clazz.inheritArgs);
2202 var n = arguments.length - 3;
2203 var args = new Array(n);
2204 for (var i = n; --i >= 0;)
2205 args[i] = arguments[i + 3];
2206 Clazz.instantialize(obj, args);
2211 * Clone variables whose modifier is "final".
2212 * Usage: var o = Clazz.cloneFinals ("name", name, "age", age);
2214 * @return Object with all final variables
2217 Clazz.cloneFinals = function () {
2219 var len = arguments.length / 2;
2220 for (var i = len; --i >= 0;)
2221 o[arguments[i + i]] = arguments[i + i + 1];
2226 Clazz.isClassDefined = Clazz.isDefinedClass = function(clazzName) {
2228 return false; /* consider null or empty name as non-defined class */
2229 if (Clazz.allClasses[clazzName])
2231 var pkgFrags = clazzName.split (/\./);
2233 for (var i = 0; i < pkgFrags.length; i++)
2234 if (!(pkg = (pkg ? pkg[pkgFrags[i]] : Clazz.allPackage[pkgFrags[0]]))) {
2237 return (pkg && (Clazz.allClasses[clazzName] = true));
2240 * Define the enum constant.
2241 * @param classEnum enum type
2242 * @param enumName enum constant
2243 * @param enumOrdinal enum ordinal
2244 * @param initialParams enum constant constructor parameters
2245 * @return return defined enum constant
2248 Clazz.defineEnumConstant = function (clazzEnum, enumName, enumOrdinal, initialParams, clazzEnumExt) {
2249 var o = (clazzEnumExt ? new clazzEnumExt() : new clazzEnum());
2250 // BH avoids unnecessary calls to SAEM
2252 o.$ordinal = enumOrdinal;
2253 //Clazz.superConstructor (o, clazzEnum, [enumName, enumOrdinal]);
2254 if (initialParams && initialParams.length)
2255 o.construct.apply (o, initialParams);
2256 clazzEnum[enumName] = o;
2257 clazzEnum.prototype[enumName] = o;
2258 if (!clazzEnum["$ values"]) { // BH added
2259 clazzEnum["$ values"] = [] // BH added
2260 clazzEnum.values = function() { // BH added
2261 return this["$ values"]; // BH added
2264 clazzEnum["$ values"].push(o);
2268 //////// (int) conversions //////////
2270 Clazz.floatToInt = function (x) {
2271 return x < 0 ? Math.ceil(x) : Math.floor(x);
2274 Clazz.floatToByte = Clazz.floatToShort = Clazz.floatToLong = Clazz.floatToInt;
2275 Clazz.doubleToByte = Clazz.doubleToShort = Clazz.doubleToLong = Clazz.doubleToInt = Clazz.floatToInt;
2277 Clazz.floatToChar = function (x) {
2278 return String.fromCharCode (x < 0 ? Math.ceil(x) : Math.floor(x));
2281 Clazz.doubleToChar = Clazz.floatToChar;
2285 ///////////////////////////////// Array additions //////////////////////////////
2287 // BH: these are necessary for integer processing, especially
2291 var getArrayClone = function(nbits) {
2295 var a = (nbits == 32 ? new Int32Array(n) : new Float64Array(n));
2296 for (var i = n; --i >= 0;)
2302 if (self.Int32Array && self.Int32Array != Array) {
2303 Clazz.haveInt32 = true;
2304 if (!Int32Array.prototype.sort)
2305 Int32Array.prototype.sort = Array.prototype.sort
2306 if (!Int32Array.prototype.clone)
2307 Int32Array.prototype.clone = getArrayClone(32);
2309 Int32Array = function(n) {
2311 var b = new Array(n);
2312 b.toString = function(){return "[object Int32Array]"}
2313 for (var i = 0; i < n; i++)b[i] = 0
2316 Clazz.haveInt32 = false;
2317 Int32Array.prototype.sort = Array.prototype.sort
2318 Int32Array.prototype.clone = getArrayClone(32);
2319 Int32Array.prototype.int32Fake = function(){};
2322 if (self.Float64Array && self.Float64Array != Array) {
2323 Clazz.haveFloat64 = true;
2324 if (!Float64Array.prototype.sort)
2325 Float64Array.prototype.sort = Array.prototype.sort
2326 if (!Float64Array.prototype.clone)
2327 Float64Array.prototype.clone = getArrayClone(64);
2329 Clazz.haveFloat64 = false;
2330 Float64Array = function(n) {
2332 var b = new Array(n);
2333 for (var i = 0; i < n; i++)b[i] = 0.0
2336 Float64Array.prototype.sort = Array.prototype.sort
2337 Float64Array.prototype.clone = getArrayClone(64);
2338 Float64Array.prototype.float64Fake = function() {}; // "present"
2339 Float64Array.prototype.toString = function() {return "[object Float64Array]"};
2340 // Darn! Mozilla makes this a double, not a float. It's 64-bit.
2341 // and Safari 5.1 doesn't have Float64Array
2347 * @return the created Array object
2350 Clazz.newArray = function () {
2351 if (arguments[0] instanceof Array) {
2352 // recursive, from newArray(n,m,value)
2353 // as newArray([m, value], newInt32Array)
2354 var args = arguments[0];
2355 var f = arguments[1];
2357 var args = arguments;
2361 if (typeof dim == "string") {
2362 dim = dim.charCodeAt (0); // char
2364 var len = args.length - 1;
2365 var val = args[len];
2366 switch (args.length) {
2369 return []; // maybe never?
2372 return new Array(dim);
2373 if (f === true && Clazz.haveInt32) return new Int32Array(dim);
2374 if (f === false && Clazz.haveFloat64) return new Float64Array(dim);
2375 var arr = (f === true ? new Int32Array() : f === false ? new Float64Array() : dim < 0 ? val : new Array(dim));
2376 for (var i = dim; --i >= 0;)
2380 var xargs = new Array (len);
2381 for (var i = 0; i < len; i++) {
2382 xargs[i] = args[i + 1];
2384 var arr = new Array (dim);
2385 if (val == null || val >= 0 || len > 2)
2386 for (var i = 0; i < dim; i++) {
2387 // Call recursively!
2388 arr[i] = Clazz.newArray (xargs, f);
2394 Clazz.newArray32 = function(args, isInt32) {
2396 if (typeof dim == "string")
2397 dim = dim.charCodeAt (0); // char
2398 var len = args.length - 1;
2399 var val = args[len];
2400 switch (args.length) {
2403 alert ("ERROR IN newArray32 -- args.length < 2");
2404 return new Array(0);
2406 var isDefined = (dim < 0);
2409 var a = (val < 0 ? new Array(dim) : isInt32 ? new Int32Array(dim) : new Float64Array(dim));
2411 for (var i = dim; --i >= 0;)
2415 var xargs = new Array(len);
2416 for (var i = len; --i >= 0;) {
2417 xargs[i] = args[i + 1];
2419 var arr = new Array (dim);
2420 for (var i = 0; i < dim; i++) {
2421 // Call newArray referencing this array type
2422 // only for the final iteration, and only if val === 0
2423 arr[i] = Clazz.newArray (xargs, isInt32);
2432 * @return the created Array object
2435 Clazz.newInt32Array = function () {
2436 return Clazz.newArray32(arguments, true);
2442 * @return the created Array object
2445 Clazz.newFloat64Array = function () {
2446 return Clazz.newArray32(arguments, false);
2449 Clazz.newFloatArray = Clazz.newDoubleArray = Clazz.newFloat64Array;
2450 Clazz.newIntArray = Clazz.newLongArray = Clazz.newShortArray = Clazz.newByteArray = Clazz.newInt32Array;
2451 Clazz.newCharArray = Clazz.newBooleanArray = Clazz.newArray;
2453 //$_AI=Clazz.newIntArray;
2454 //$_AF=Clazz.newFloatArray;
2455 //$_AD=Clazz.newDoubleArray;
2456 //$_AL=Clazz.newLongArray;
2457 //$_AS=Clazz.newShortArray;
2458 //$_AB=Clazz.newByteArray;
2459 //$_AC=Clazz.newCharArray;
2460 //$_Ab=Clazz.newBooleanArray;
2463 var arrayIs = function(a, what) {
2464 // for some reason, Number.constructor.toString() now gives "too much recursion"
2465 return a.constructor && a.constructor != Number && a.constructor.toString().indexOf(what) >= 0
2468 Clazz.isAS = function(a) { // just checking first parameter
2469 return (a && typeof a == "object" && arrayIs(a, " Array") && (typeof a[0] == "string" || typeof a[0] == "undefined"));
2472 Clazz.isASS = function(a) {
2473 return (a && typeof a == "object" && Clazz.isAS(a[0]));
2476 Clazz.isAP = function(a) {
2477 return (a && Clazz.getClassName(a[0]) == "JU.P3");
2480 Clazz.isAI = function(a) {
2481 return (a && typeof a == "object" && (Clazz.haveInt32 ? arrayIs(a, "Int32Array") : a.int32Fake ? true : false));
2484 Clazz.isAII = function(a) { // assumes non-null a[0]
2485 return (a && typeof a == "object" && Clazz.isAI(a[0]));
2488 Clazz.isAF = function(a) {
2489 return (a && typeof a == "object" && (Clazz.haveFloat64 ? arrayIs(a, "Float64Array") : a.float64Fake ? true : false));
2492 Clazz.isAFF = function(a) { // assumes non-null a[0]
2493 return (a && typeof a == "object" && Clazz.isAF(a[0]));
2496 Clazz.isAFFF = function(a) { // assumes non-null a[0]
2497 return (a && typeof a == "object" && Clazz.isAFF(a[0]));
2500 Clazz.isAFloat = function(a) { // just checking first parameter
2501 return (a && typeof a == "object" && arrayIs(a, " Array") && Clazz.instanceOf(a[0], Float));
2506 * Make the RunnableCompatiability instance as a JavaScript function.
2508 * @param jsr Instance of RunnableCompatiability
2509 * @return JavaScript function instance represents the method run of jsr.
2513 Clazz.makeFunction = function (jsr) {
2514 // never used in Jmol -- called by Enum, but not accessible to it -- part of SWT
2515 return function(e) {
2521 switch (jsr.returnSet) {
2523 return jsr.returnNumber;
2525 return jsr.returnBoolean;
2527 return jsr.returnObject;
2534 Clazz.defineStatics = function (clazz) {
2535 for (var j = arguments.length, i = (j - 1) / 2; --i >= 0;) {
2536 var val = arguments[--j]
2537 var name = arguments[--j];
2538 clazz[name] = clazz.prototype[name] = val;
2543 Clazz.prepareFields = function (clazz, fieldsFun) {
2545 if (clazz.con$truct) {
2546 var ss = clazz.con$truct.stacks;
2547 var idx = 0;//clazz.con$truct.index;
2548 for (var i = idx; i < ss.length; i++) {
2552 addProto(clazz.prototype, "con$truct", clazz.con$truct = function () {
2553 var stacks = arguments.callee.stacks;
2555 for (var i = 0; i < stacks.length; i++) {
2556 stacks[i].apply (this, []);
2560 stacks.push(fieldsFun);
2561 clazz.con$truct.stacks = stacks;
2562 clazz.con$truct.index = 0;
2566 * Serialize those public or protected fields in class
2567 * net.sf.j2s.ajax.SimpleSerializable.
2571 Clazz.registerSerializableFields = function (clazz) {
2572 var args = arguments;
2573 var length = args.length;
2575 if (clazz.declared$Fields) {
2576 for (var i = 0; i < clazz.declared$Fields.length; i++) {
2577 newArr[i] = clazz.declared$Fields[i];
2580 clazz.declared$Fields = newArr;
2582 if (length > 0 && length % 2 == 1) {
2583 var fs = clazz.declared$Fields;
2584 var n = (length - 1) / 2;
2585 for (var i = 1; i <= n; i++) {
2586 var o = { name : args[i + i - 1], type : args[i + i] };
2587 var existed = false;
2588 for (var j = 0; j < fs.length; j++) {
2589 if (fs[j].name == o.name) { // reloaded classes
2590 fs[j].type = o.type; // update type
2602 * Get the caller method for those methods that are wrapped by
2603 * Clazz.searchAndExecuteMethod.
2605 * @param args caller method's arguments
2606 * @return caller method, null if there is not wrapped by
2607 * Clazz.searchAndExecuteMethod or is called directly.
2611 Clazz.getMixedCallerMethod = function (args) {
2613 var argc = args.callee.caller; // tryToSearchAndExecute
2614 if (argc && argc !== tryToSearchAndExecute) // inherited method's apply
2615 argc = argc.arguments.callee.caller;
2616 if (argc !== tryToSearchAndExecute
2617 || (argc = argc.arguments.callee.caller) !== Clazz.searchAndExecuteMethod)
2619 o.claxxRef = argc.arguments[1];
2620 o.fxName = argc.arguments[2];
2621 o.paramTypes = Clazz.getParamsType(argc.arguments[3]);
2622 argc = argc.arguments.callee.caller // Clazz.generateDelegatingMethod
2623 && argc.arguments.callee.caller; // the private method's caller
2630 /* BH -- The issue here is a subclass calling its private method FOO when
2631 * there is also a private method of the same name in its super class.
2632 * This can ALWAYS be avoided and, one could argue, is bad
2633 * program design anyway. In Jmol, the presence of this possibility
2634 * creates over 8000 references to the global $fx, which was only
2635 * checked in a few rare cases. We can then also remove $fz references.
2640 * Check and return super private method.
2641 * In order make private methods be executed correctly, some extra javascript
2642 * must be inserted into the beggining of the method body of the non-private
2643 * methods that with the same method signature as following:
2645 * var $private = Clazz.checkPrivateMethod (arguments);
2647 * return $private.apply (this, arguments);
2650 * Be cautious about this. The above codes should be insert by Java2Script
2651 * compiler or with double checks to make sure things work correctly.
2653 * @param args caller method's arguments
2654 * @return private method if there are private method fitted for the current
2655 * calling environment
2659 Clazz.checkPrivateMethod = function () {
2660 // get both this one and the one calling it
2661 me = arguments.callee.caller;
2662 caller = arguments.callee.caller.caller;
2663 var stack = me.stacks;
2664 // if their classes are the same, no issue
2665 var mySig = "\\" + Clazz.getParamsType(arguments[0]).join("\\")
2666 if (!me.privateNote) {
2667 me.privateNote = "You are seeing this note because the method "
2668 + me.exName + mySig + " in class "
2669 + me.exClazz.__CLASS_NAME__
2670 + " has a superclass method by the same name (possibly with the same parameters) that is private and "
2671 + " therefore might be called improperly from this class. If your "
2672 + " code does not run properly, or you want to make it run faster, change the name of this method to something else."
2673 System.out.println(me.privateNote);
2674 alert(me.privateNote);
2677 alert([me.exClazz.__CLASS_NAME__, me.exName,
2678 caller.exClazz.__CLASS_NAME__, caller.exName,stack,mySig])
2679 if (stack == null || caller.exClazz == me.exClazz)
2681 // I am being called by a different class...
2683 for (var i = stack.length; --i >= 0;) {
2684 if (stacks[i] != caller.claxxRef)
2686 // and it is on MY class stack
2692 /* var m = Clazz.getMixedCallerMethod (args);
2693 if (m == null) return null;
2694 var callerFx = m.claxxRef.prototype[m.caller.exName];
2695 if (callerFx == null) return null; // may not be in the class hierarchies
2697 if (callerFx.claxxOwner ) {
2698 ppFun = callerFx.claxxOwner.prototype[m.fxName];
2700 var stacks = callerFx.stacks;
2701 for (var i = stacks.length - 1; i >= 0; i--) {
2702 var fx = stacks[i].prototype[m.caller.exName];
2703 if (fx === m.caller) {
2704 ppFun = stacks[i].prototype[m.fxName];
2706 for (var fn in fx) {
2707 if (fn.indexOf ('\\') == 0 && fx[fn] === m.caller) {
2708 ppFun = stacks[i].prototype[m.fxName];
2718 if (ppFun && ppFun.claxxOwner == null) {
2719 ppFun = ppFun["\\" + m.paramTypes];
2721 if (ppFun && ppFun.isPrivate && ppFun !== args.callee) {
2729 //$fz = null; // for private method declaration
2732 // /*# {$no.debug.support} >>x #*/
2734 // * Option to switch on/off of stack traces.
2737 //Clazz.tracingCalling = false;
2740 // Clazz.callingStack = function (caller, owner) {
2741 // this.caller = caller;
2742 // this.owner = owner;
2748 * The first folder is considered as the primary folder.
2749 * And try to be compatiable with _Loader system.
2754 /*** not used in Jmol
2756 if (window["_Loader"] && _Loader.binaryFolders) {
2757 Clazz.binaryFolders = _Loader.binaryFolders;
2759 Clazz.binaryFolders = ["j2s/", "", "j2slib/"];
2762 Clazz.addBinaryFolder = function (bin) {
2764 var bins = Clazz.binaryFolders;
2765 for (var i = 0; i < bins.length; i++) {
2766 if (bins[i] == bin) {
2770 bins[bins.length] = bin;
2773 Clazz.removeBinaryFolder = function (bin) {
2775 var bins = Clazz.binaryFolders;
2776 for (var i = 0; i < bins.length; i++) {
2777 if (bins[i] == bin) {
2778 for (var j = i; j < bins.length - 1; j++) {
2779 bins[j] = bins[j + 1];
2788 Clazz.setPrimaryFolder = function (bin) {
2790 Clazz.removeBinaryFolder (bin);
2791 var bins = Clazz.binaryFolders;
2792 for (var i = bins.length - 1; i >= 0; i--) {
2793 bins[i + 1] = bins[i];
2802 ///////////////// special definitions of standard Java class methods ///////////
2805 * This is a simple implementation for Clazz#load. It just ignore dependencies
2806 * of the class. This will be fine for jar *.z.js file.
2807 * It will be overriden by _Loader#load.
2808 * For more details, see _Loader.js
2812 Clazz.load = function (musts, clazz, optionals, declaration) {
2820 * Invade the Object prototype!
2821 * TODO: make sure that invading Object prototype does not affect other
2822 * existed library, such as Dojo, YUI, Prototype, ...
2824 java.lang.Object = Clazz._O;
2826 Clazz._O.getName = Clazz._innerFunctions.getName;
2829 java.lang.System = System = {
2830 props : null, //new java.util.Properties (),
2832 arraycopy : function (src, srcPos, dest, destPos, length) {
2834 for (var i = 0; i < length; i++) {
2835 dest[destPos + i] = src[srcPos + i];
2839 for (var i = 0; i < length; i++) {
2840 swap[i] = src[srcPos + i];
2842 for (var i = 0; i < length; i++) {
2843 dest[destPos + i] = swap[i];
2847 currentTimeMillis : function () {
2848 return new Date ().getTime ();
2850 gc : function() {}, // bh
2851 getProperties : function () {
2852 return System.props;
2854 getProperty : function (key, def) {
2856 return System.props.getProperty (key, def);
2857 var v = System.$props[key];
2858 if (typeof v != "undefined")
2860 if (key.indexOf(".") > 0) {
2863 case "java.version":
2865 case "file.separator":
2866 case "path.separator":
2869 case "line.separator":
2870 v = (navigator.userAgent.indexOf("Windows") >= 0 ? "\r\n" : "\n");
2874 v = navigator.userAgent;
2878 return System.$props[key] = v;
2880 return (arguments.length == 1 ? null : def == null ? key : def); // BH
2882 getSecurityManager : function() { return null }, // bh
2883 setProperties : function (props) {
2884 System.props = props;
2886 lineSeparator : function() { return '\n' }, // bh
2887 setProperty : function (key, val) {
2889 return System.$props[key] = val; // BH
2890 System.props.setProperty (key, val);
2894 System.identityHashCode=function(obj){
2898 return obj._$hashcode || (obj._$hashcode = ++Clazz._hashCode)
2902 return obj.toString().hashCode();
2908 return str.hashCode();
2913 System.out = new Clazz._O ();
2914 System.out.__CLASS_NAME__ = "java.io.PrintStream";
2915 System.out.print = function () {};
2916 System.out.printf = function () {};
2917 System.out.println = function () {};
2918 System.out.write = function () {};
2920 System.err = new Clazz._O ();
2921 System.err.__CLASS_NAME__ = "java.io.PrintStream";
2922 System.err.print = function () {};
2923 System.err.printf = function () {};
2924 System.err.println = function () {};
2925 System.err.write = function () {};
2927 Clazz.popup = Clazz.assert = Clazz.log = Clazz.error = window.alert;
2929 Thread = function () {};
2930 Thread.J2S_THREAD = Thread.prototype.J2S_THREAD = new Thread ();
2931 Thread.currentThread = Thread.prototype.currentThread = function () {
2932 return this.J2S_THREAD;
2936 Clazz.intCast = function (n) { // 32bit
2937 var b1 = (n & 0xff000000) >> 24;
2938 var b2 = (n & 0xff0000) >> 16;
2939 var b3 = (n & 0xff00) >> 8;
2941 if ((b1 & 0x80) != 0) {
2942 return -(((b1 & 0x7f) << 24) + (b2 << 16) + (b3 << 8) + b4 + 1);
2944 return (b1 << 24) + (b2 << 16) + (b3 << 8) + b4;
2947 Clazz.shortCast = function (s) { // 16bit
2948 var b1 = (n & 0xff00) >> 8;
2950 if ((b1 & 0x80) != 0) {
2951 return -(((b1 & 0x7f) << 8) + b2 + 1);
2953 return (b1 << 8) + b4;
2957 Clazz.byteCast = function (b) { // 8bit
2958 if ((b & 0x80) != 0) {
2959 return -((b & 0x7f) + 1);
2965 Clazz.charCast = function (c) { // 8bit
2966 return String.fromCharCode (c & 0xff).charAt (0);
2969 Clazz.floatCast = function (f) { // 32bit
2977 * Try to fix JavaScript's shift operator defects on long type numbers.
2982 Clazz.longMasks = [];
2984 Clazz.longReverseMasks = [];
2986 Clazz.longBits = [];
2990 for (var i = 1; i < 53; i++) {
2991 arr[i] = arr[i - 1] + arr[i - 1]; // * 2 or << 1
2993 Clazz.longBits = arr;
2994 Clazz.longMasks[52] = arr[52];
2995 for (var i = 51; i >= 0; i--) {
2996 Clazz.longMasks[i] = Clazz.longMasks[i + 1] + arr[i];
2998 Clazz.longReverseMasks[0] = arr[0];
2999 for (var i = 1; i < 52; i++) {
3000 Clazz.longReverseMasks[i] = Clazz.longReverseMasks[i - 1] + arr[i];
3005 Clazz.longLeftShift = function (l, o) { // 64bit
3006 if (o == 0) return l;
3007 if (o >= 64) return 0;
3009 error ("[Java2Script] Error : JavaScript does not support long shift!");
3012 if ((l & Clazz.longMasks[o - 1]) != 0) {
3013 error ("[Java2Script] Error : Such shift operator results in wrong calculation!");
3016 var high = l & Clazz.longMasks[52 - 32 + o];
3018 return high * Clazz.longBits[o] + (l & Clazz.longReverseMasks[32 - o]) << 0;
3024 Clazz.intLeftShift = function (n, o) { // 32bit
3025 return (n << o) & 0xffffffff;
3028 Clazz.longRightShift = function (l, o) { // 64bit
3029 if ((l & Clazz.longMasks[52 - 32]) != 0) {
3030 return Math.round((l & Clazz.longMasks[52 - 32]) / Clazz.longBits[32 - o]) + (l & Clazz.longReverseMasks[o]) >> o;
3036 Clazz.intRightShift = function (n, o) { // 32bit
3037 return n >> o; // no needs for this shifting wrapper
3040 Clazz.long0RightShift = function (l, o) { // 64bit
3044 Clazz.int0RightShift = function (n, o) { // 64bit
3045 return n >>> o; // no needs for this shifting wrapper
3049 // Compress the common public API method in shorter name
3051 //$_W=Clazz.declareAnonymous;$_T=Clazz.declareType;
3052 //$_J=Clazz.declarePackage;$_C=Clazz.decorateAsClass;
3053 //$_Z=Clazz.instantialize;$_I=Clazz.declareInterface;$_D=Clazz.isClassDefined;
3054 //$_H=Clazz.pu$h;$_P=Clazz.p0p;$_B=Clazz.prepareCallback;
3055 //$_N=Clazz.innerTypeInstance;$_K=Clazz.makeConstructor;$_U=Clazz.superCall;$_R=Clazz.superConstructor;
3056 //$_M=Clazz.defineMethod;$_V=Clazz.overrideMethod;$_S=Clazz.defineStatics;
3057 //$_E=Clazz.defineEnumConstant;
3058 //$_F=Clazz.cloneFinals;
3059 //$_Y=Clazz.prepareFields;$_A=Clazz.newArray;$_O=Clazz.instanceOf;
3060 //$_G=Clazz.inheritArgs;$_X=Clazz.checkPrivateMethod;$_Q=Clazz.makeFunction;
3061 //$_s=Clazz.registerSerializableFields;
3062 //$_k=Clazz.overrideConstructor;
3065 /////////////////////// inner function support /////////////////////////////////
3068 Clazz.innerFunctionNames = Clazz.innerFunctionNames.concat ([
3069 "getSuperclass", "isAssignableFrom",
3071 "getDeclaredMethod", "getDeclaredMethods",
3072 "getMethod", "getMethods",
3073 "getModifiers", /*"isArray",*/ "newInstance"]);
3076 Clazz._innerFunctions.getSuperclass = function () {
3077 return this.superClazz;
3081 Clazz._innerFunctions.isAssignableFrom = function (clazz) {
3082 return Clazz.getInheritedLevel (clazz, this) >= 0;
3086 Clazz._innerFunctions.getConstructor = function () {
3087 return new java.lang.reflect.Constructor (this, [], [],
3088 java.lang.reflect.Modifier.PUBLIC);
3091 * TODO: fix bug for polymorphic methods!
3094 Clazz._innerFunctions.getDeclaredMethods = Clazz._innerFunctions.getMethods = function () {
3096 var p = this.prototype;
3097 for (var attr in p) {
3098 if (typeof p[attr] == "function" && !p[attr].__CLASS_NAME__) {
3099 /* there are polynormical methods. */
3100 ms.push(new java.lang.reflect.Method (this, attr,
3101 [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC));
3105 for (var attr in p) {
3106 if (typeof p[attr] == "function" && !p[attr].__CLASS_NAME__) {
3107 ms.push(new java.lang.reflect.Method (this, attr,
3108 [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC
3109 | java.lang.reflect.Modifier.STATIC));
3115 Clazz._innerFunctions.getDeclaredMethod = Clazz._innerFunctions.getMethod = function (name, clazzes) {
3116 var p = this.prototype;
3117 for (var attr in p) {
3118 if (name == attr && typeof p[attr] == "function"
3119 && !p[attr].__CLASS_NAME__) {
3120 /* there are polynormical methods. */
3121 return new java.lang.reflect.Method (this, attr,
3122 [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC);
3126 for (var attr in p) {
3127 if (name == attr && typeof p[attr] == "function"
3128 && !p[attr].__CLASS_NAME__) {
3129 return new java.lang.reflect.Method (this, attr,
3130 [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC
3131 | java.lang.reflect.Modifier.STATIC);
3137 Clazz._innerFunctions.getModifiers = function () {
3138 return java.lang.reflect.Modifier.PUBLIC;
3141 Clazz._innerFunctions.newInstance = function (a) {
3143 switch(a == null ? 0 : a.length) {
3147 return new clz(a[0]);
3149 return new clz(a[0], a[1]);
3151 return new clz(a[0], a[1], a[2]);
3153 return new clz(a[0], a[1], a[2], a[3]);
3155 var x = "new " + clz.__CLASS_NAME__ + "(";
3156 for (var i = 0; i < a.length; i++)
3157 x += (i == 0 ? "" : ",") + "a[" + i + "]";
3163 //Object.newInstance = Clazz._innerFunctions.newInstance;
3164 ;(function(){ // BH added wrapper here
3165 var inF = Clazz.innerFunctionNames;
3166 for (var i = 0; i < inF.length; i++) {
3167 Clazz._O[inF[i]] = Clazz._innerFunctions[inF[i]];
3168 Array[inF[i]] = Clazz._innerFunctions[inF[i]];
3170 //Array["isArray"] = function () {
3175 //////////////////////////// hotspot and unloading /////////////////////////////
3176 /* For hotspot and unloading */
3178 if (window["Clazz"] && !window["Clazz"].unloadClass) {
3181 Clazz.unloadClass = function (qClazzName) {
3182 var cc = Clazz.evalType (qClazzName);
3184 Clazz.unloadedClasses[qClazzName] = cc;
3185 var clazzName = qClazzName;
3186 var pkgFrags = clazzName.split (/\./);
3188 for (var i = 0; i < pkgFrags.length - 1; i++)
3189 pkg = (pkg ? pkg[pkgFrags[i]] : Clazz.allPackage[pkgFrags[0]]);
3191 Clazz.allPackage[pkgFrags[0]] = null;
3192 window[pkgFrags[0]] = null;
3193 // also try to unload inner or anonymous classes
3194 for (var c in window) {
3195 if (c.indexOf (qClazzName + "$") == 0) {
3196 Clazz.unloadClass (c);
3201 pkg[pkgFrags[pkgFrags.length - 1]] = null;
3202 // also try to unload inner or anonymous classes
3203 for (var c in pkg) {
3204 if (c.indexOf (pkgFrags[pkgFrags.length - 1] + "$") == 0) {
3205 Clazz.unloadClass (pkg.__PKG_NAME__ + "." + c);
3211 if (Clazz.allClasses[qClazzName]) {
3212 Clazz.allClasses[qClazzName] = false;
3213 // also try to unload inner or anonymous classes
3214 for (var c in Clazz.allClasses) {
3215 if (c.indexOf (qClazzName + "$") == 0) {
3216 Clazz.allClasses[c] = false;
3222 cleanDelegateMethod (cc[m]);
3224 for (var m in cc.prototype) {
3225 cleanDelegateMethod (cc.prototype[m]);
3228 if (Clazz._Loader) {
3229 Clazz._Loader.unloadClassExt(qClazzName);
3238 var cleanDelegateMethod = function (m) {
3241 if (typeof m == "function" && m.lastMethod
3242 && m.lastParams && m.lastClaxxRef) {
3243 m.lastMethod = null;
3244 m.lastParams = null;
3245 m.lastClaxxRef = null;
3249 } // if (window["Clazz"] && !window["Clazz"].unloadClass)
3251 /******************************************************************************
3252 * Copyright (c) 2007 java2script.org and others.
3253 * All rights reserved. This program and the accompanying materials
3254 * are made available under the terms of the Eclipse Public License v1.0
3255 * which accompanies this distribution, and is available at
3256 * http://www.eclipse.org/legal/epl-v10.html
3259 * Zhou Renjian - initial API and implementation
3260 *****************************************************************************/
3262 * @author zhou renjian
3263 * @create July 10, 2006
3266 //if (window["ClazzNode"] == null) {
3269 * Make optimization over class dependency tree.
3273 * ClassLoader Summary
3275 * ClassLoader creates SCRIPT elements and setup class path and onload
3276 * callback to continue class loading.
3278 * In the onload callbacks, _Loader will try to calculate the next-to-be-
3279 * load *.js and load it. In *.js, it will contains some codes like
3280 * Clazz.load (..., "$wt.widgets.Control", ...);
3281 * to provide information to build up the class dependency tree.
3283 * Some known problems of different browsers:
3284 * 1. In IE, loading *.js through SCRIPT will first triggers onreadstatechange
3285 * event, and then executes inner *.js source.
3286 * 2. In Firefox, loading *.js will first executes *.js source and then
3287 * triggers onload event.
3288 * 3. In Opera, similar to IE, but trigger onload event. (TODO: More details
3289 * should be studied. Currently, Opera supports no multiple-thread-loading)
3291 * For class dependency tree, actually, it is not a tree. It is a reference
3292 * net with nodes have n parents and n children. There is a root, which
3293 * ClassLoader knows where to start searching and loading classes, for such
3294 * a net. Each node is a class. Each class may require a set of must-classes,
3295 * which must be loaded before itself getting initialized, and also need a set
3296 * of optional classes, which also be loaded before being called.
3298 * The class loading status will be in 6 stages.
3299 * 1. Unknown, the class is newly introduced by other class.
3300 * 2. Known, the class is already mentioned by other class.
3301 * 3. Loaded, *.js source is in memory, but may not be initialized yet. It
3302 * requires all its must-classes be intiailized, which is in the next stage.
3303 * 4. Musts loaded, all must classes is already loaded and declared.
3304 * 5. Delcared, the class is already declared (_Loader#isClassDefined).
3305 * 6. Optionals loaded, all optional classes is loaded and declared.
3307 * The ClassLoader tries to load all necessary classes in order, and intialize
3308 * them in order. For such job, it will traverse the dependency tree, and try
3309 * to next class to-be-loaded. Sometime, the class dependencies may be in one
3310 * or more cycles, which must be broken down so classes is loaded in correct
3313 * Loading order and intializing order is very important for the ClassLoader.
3314 * The following technical options are considered:
3315 * 1. SCRIPT is loading asynchronously, which means controling order must use
3316 * callback methods to continue.
3317 * 2. Multiple loading threads are later introduced, which requires the
3318 * ClassLoader should use variables to record the class status.
3319 * 3. Different browsers have different loading orders, which means extra tests
3320 * should be tested to make sure loading order won't be broken.
3321 * 4. Java2Script simulator itself have some loading orders that must be
3322 * honored, which means it should be integrated seamlessly to Clazz system.
3323 * 5. Packed *.z.js is introduced to avoid lots of small *.js which requires
3324 * lots of HTTP connections, which means that packed *.z.js should be treated
3325 * specially (There will be mappings for such packed classes).
3326 * 6. *.js or *.css loading may fail according to network status, which means
3327 * another loading try should be performed, so _Loader is more robust.
3328 * 7. SWT lazy loading is later introduced, which means that class loading
3329 * process may be paused and should be resumed later.
3332 * <code>$_L(["$wt.graphics.Drawable","$wt.widgets.Widget"],
3333 * "$wt.widgets.Control", ...</code>
3334 * has errors while must classes in different order such as
3335 * <code>$_L(["$wt.widgets.Widget", "$wt.graphics.Drawable"],
3336 * "$wt.widgets.Control", ...</code>
3339 * Other maybe bug scenarios:
3340 * 1. In <code>_Loader.maxLoadingThreads = 1;</code> single loading thread
3341 * mode, there are no errors, but in default multiple thread loading mode,
3343 * 2. No errors in one browser, but has errors on other browsers (Browser
3344 * script loading order differences).
3345 * 3. First time loading has errors, but reloading it gets no errors (Maybe
3346 * HTTP connections timeout, but should not accur in local file system, or it
3347 * is a loading bug by using JavaScript timeout thread).
3351 * The following comments with "#" are special configurations for a much
3352 * smaller *.js file size.
3354 * @see net.sf.j2s.lib/src/net/sf/j2s/lib/build/SmartJSCompressor.java
3357 * Static class loader class
3359 Clazz._Loader = Clazz.ClazzLoader = function () {};
3362 * Class dependency tree node
3365 var Node = function () {
3368 this.optionals = [];
3369 this.declaration = null;
3370 this.name = null; // id
3372 // this.requires = null;
3373 // this.requiresMap = null;
3374 this.onLoaded = null;
3376 this.random = 0.13412;
3380 ;(function(Clazz, _Loader) {
3382 _Loader._checkLoad = Jmol._checkLoad;
3384 _Loader.updateNodeForFunctionDecoration = function(qName) {
3385 var node = findNode(qName);
3386 if (node && node.status == Node.STATUS_KNOWN) {
3387 window.setTimeout((function(nnn) {
3395 Node.prototype.toString = function() {
3396 return this.name || this.path || "ClazzNode";
3399 Node.STATUS_UNKNOWN = 0;
3400 Node.STATUS_KNOWN = 1;
3401 Node.STATUS_CONTENT_LOADED = 2;
3402 Node.STATUS_MUSTS_LOADED = 3;
3403 Node.STATUS_DECLARED = 4;
3404 Node.STATUS_LOAD_COMPLETE = 5;
3410 _Loader.requireLoaderByBase = function (base) {
3411 for (var i = 0; i < loaders.length; i++) {
3412 if (loaders[i].base == base) {
3416 var loader = new _Loader ();
3418 loaders.push(loader);
3423 * Class dependency tree
3425 var clazzTreeRoot = new Node();
3428 * Used to keep the status whether a given *.js path is loaded or not.
3431 var loadedScripts = {};
3434 * Multiple threads are used to speed up *.js loading.
3437 var inLoadingThreads = 0;
3440 * Maximum of loading threads
3443 var maxLoadingThreads = 6;
3445 var userAgent = navigator.userAgent.toLowerCase ();
3446 var isOpera = (userAgent.indexOf ("opera") != -1);
3447 var isIE = (userAgent.indexOf ("msie") != -1) && !isOpera;
3448 var isGecko = (userAgent.indexOf ("gecko") != -1);
3451 * Opera has different loading order which will result in performance degrade!
3452 * So just return to single thread loading in Opera!
3454 * FIXME: This different loading order also causes bugs in single thread!
3457 maxLoadingThreads = 1;
3458 var index = userAgent.indexOf ("opera/");
3460 var verNumber = 9.0;
3462 verNumber = parseFloat(userAgent.subString (index + 6));
3464 if (verNumber >= 9.6) {
3465 maxLoadingThreads = 6;
3471 * Try to be compatiable with Clazz system.
3472 * In original design _Loader and Clazz are independent!
3473 * -- zhourenjian @ December 23, 2006
3478 if (self.Clazz && Clazz.isClassDefined) {
3479 isClassDefined = Clazz.isClassDefined;
3481 definedClasses = {};
3482 isClassDefined = function (clazzName) {
3483 return definedClasses[clazzName] == true;
3488 * Expand the shortened list of class names.
3490 * JU.Log, $.Display, $.Decorations
3491 * will be expanded to
3492 * JU.Log, JU.Display, JU.Decorations
3493 * where "$." stands for the previous class name's package.
3495 * This method will be used to unwrap the required/optional classes list and
3496 * the ignored classes list.
3499 var unwrapArray = function (arr) {
3500 if (!arr || arr.length == 0)
3503 for (var i = 0; i < arr.length; i++) {
3506 if (arr[i].charAt (0) == '$') {
3507 if (arr[i].charAt (1) == '.') {
3510 var idx = last.lastIndexOf (".");
3512 var prefix = last.substring (0, idx);
3513 arr[i] = prefix + arr[i].substring (1);
3516 arr[i] = "org.eclipse.s" + arr[i].substring (1);
3525 * Used to keep to-be-loaded classes.
3528 var classQueue = [];
3531 var classpathMap = {};
3534 var pkgRefCount = 0;
3537 _Loader.loadPackageClasspath = function (pkg, base, isIndex, fSuccess, mode, pt) {
3538 var map = classpathMap;
3540 fSuccess || (fSuccess = null);
3544 * In some situation, maybe,
3545 * _Loader.packageClasspath ("java", ..., true);
3546 * is called after other _Loader#packageClasspath, e.g.
3548 * _Loader.packageClasspath ("org.eclipse.swt", "...", true);
3549 * _Loader.packageClasspath ("java", "...", true);
3551 * which is not recommended. But _Loader should try to adjust orders
3552 * which requires "java" to be declared before normal _Loader
3553 * #packageClasspath call before that line! And later that line
3554 * should never initialize "java/package.js" again!
3556 var isPkgDeclared = (isIndex && map["@" + pkg]);
3557 if (mode == 0 && isIndex && !map["@java"] && pkg.indexOf ("java") != 0 && needPackage("java")) {
3558 _Loader.loadPackage("java", fSuccess ? function(_package){_Loader.loadPackageClasspath(pkg, base, isIndex, fSuccess, 1)} : null);
3562 if (pkg instanceof Array) {
3565 if (pt < pkg.length)
3566 _Loader.loadPackageClasspath(pkg[pt], base, isIndex, function(_loadPackageClassPath){_Loader.loadPackageClasspath(pkg, base, isIndex, fSuccess, 1, pt + 1)}, 1);
3570 for (var i = 0; i < pkg.length; i++)
3571 _Loader.loadPackageClasspath(pkg[i], base, isIndex, null);
3581 // support ajax for default
3582 var key = "@net.sf.j2s.ajax";
3585 key = "@net.sf.j2s";
3591 pkg = "org.eclipse.swt";
3594 pkg = "net.sf.j2s.ajax";
3600 if (pkg.lastIndexOf(".*") == pkg.length - 2)
3601 pkg = pkg.substring(0, pkg.length - 2);
3604 if (base) // critical for multiple applets
3605 map["@" + pkg] = base;
3606 if (isIndex && !isPkgDeclared && !window[pkg + ".registered"]) {
3609 pkg = "core" // JSmol -- moves java/package.js to core/package.js
3610 _Loader.loadClass(pkg + ".package", function () {
3611 if (--pkgRefCount == 0)
3613 //fSuccess && fSuccess();
3617 fSuccess && fSuccess();
3621 * BH: allows user/developer to load classes even though wrapping and Google
3622 * Closure Compiler has not been run on the class.
3625 Clazz.loadClass = function (name, onLoaded, async) {
3628 Class.forName = Clazz._4Name;
3629 JavaObject = Clazz._O;
3632 return (name && _Loader.loadClass(name, onLoaded, true, async, 1));
3636 * Load the given class ant its related classes.
3639 _Loader.loadClass = function (name, onLoaded, forced, async, mode) {
3641 mode || (mode = 0); // BH: not implemented
3642 (async == null) && (async = false);
3644 if (typeof onLoaded == "boolean")
3645 return Clazz.evalType(name);
3647 System.out.println("loadClass " + name)
3649 // Make sure that packageClasspath ("java", base, true);
3650 // is called before any _Loader#loadClass is called.
3652 if (needPackage("java"))
3653 _Loader.loadPackage("java");
3654 if (needPackage("core"))
3655 _Loader.loadPackage("core");
3657 // var swtPkg = "org.eclipse.swt";
3658 // if (name.indexOf (swtPkg) == 0 || name.indexOf ("$wt") == 0) {
3659 // _Loader.assurePackageClasspath (swtPkg);
3661 // if (name.indexOf ("junit") == 0) {
3662 // _Loader.assurePackageClasspath ("junit");
3665 // Any _Loader#loadClass calls will be queued until java.* core classes are loaded.
3667 _Loader.keepOnLoading = true;
3669 if (!forced && (pkgRefCount && name.lastIndexOf(".package") != name.length - 8
3670 || name.indexOf("java.") != 0 && !isClassDefined(runtimeKeyClass)
3672 queueBe4KeyClazz.push([name, onLoaded]);
3675 System.out.println("loadclass-queuing" + name+ runtimeKeyClass + " "+ isClassDefined(runtimeKeyClass))
3680 if ((b = isClassDefined(name)) || isClassExcluded(name)) {
3681 if (b && onLoaded) {
3682 var nn = findNode(name);
3683 if (!nn || nn.status >= Node.STATUS_LOAD_COMPLETE) {
3685 window.setTimeout(onLoaded, 25);
3693 var path = _Loader.getClasspathFor(name);
3694 var existed = loadedScripts[path];
3695 var qq = classQueue;
3697 for (var i = qq.length; --i >= 0;)
3698 if (qq[i].path == path || qq[i].name == name) {
3704 var n = findNode(name);
3707 n.onLoaded = onLoaded;
3708 } else if (onLoaded != n.onLoaded) {
3709 n.onLoaded = (function (nF, oF) { return function () { nF(); oF() }; }) (n.onLoaded, onLoaded);
3716 var n = (Clazz.unloadedClasses[name] && findNode(name) || new Node());
3719 n.isPackage = (path.lastIndexOf("package.js") == path.length - 10);
3720 mappingPathNameNode(path, name, n);
3721 n.onLoaded = onLoaded;
3722 n.status = Node.STATUS_KNOWN;
3723 var needBeingQueued = false;
3724 for (var i = qq.length; --i >= 0;) {
3725 if (qq[i].status != Node.STATUS_LOAD_COMPLETE) {
3726 needBeingQueued = true;
3731 if (n.isPackage) {//forced
3732 // push class to queue
3734 for (; --pt >= 0;) {
3735 if (qq[pt].isPackage)
3737 qq[pt + 1] = qq[pt];
3740 } else if (needBeingQueued) {
3743 if (!needBeingQueued) { // can be loaded directly
3746 bSave = isLoadingEntryClass;
3747 isLoadingEntryClass = true;
3749 if (forced)onLoaded = null;
3750 addChildClassNode(clazzTreeRoot, n, true);
3751 loadScript(n, n.path, n.requiredBy, false, onLoaded ? function(_loadClass){ isLoadingEntryClass = bSave; onLoaded()}: null);
3756 * Check whether given package's classpath is setup or not.
3757 * Only "java" and "org.eclipse.swt" are accepted in argument.
3760 var needPackage = function(pkg) {
3761 // note that false != null and true != null
3762 return (window[pkg + ".registered"] != null && !classpathMap["@" + pkg]);
3766 _Loader.loadPackage = function(pkg, fSuccess) {
3767 fSuccess || (fSuccess = null);
3768 window[pkg + ".registered"] = false;
3769 _Loader.loadPackageClasspath(pkg,
3770 (_Loader.J2SLibBase || (_Loader.J2SLibBase = (_Loader.getJ2SLibBase() || "j2s/"))),
3775 * Register classes to a given *.z.js path, so only a single *.z.js is loaded
3776 * for all those classes.
3779 _Loader.jarClasspath = function (jar, clazzes) {
3780 if (!(clazzes instanceof Array))
3781 clazzes = [classes];
3782 unwrapArray(clazzes);
3783 for (var i = clazzes.length; --i >= 0;)
3784 classpathMap["#" + clazzes[i]] = jar;
3785 classpathMap["$" + jar] = clazzes;
3789 * Usually be used in .../package.js. All given packages will be registered
3790 * to the same classpath of given prefix package.
3793 _Loader.registerPackages = function (prefix, pkgs) {
3794 //_Loader.checkInteractive ();
3795 var base = _Loader.getClasspathFor (prefix + ".*", true);
3796 for (var i = 0; i < pkgs.length; i++) {
3797 if (window["Clazz"]) {
3798 Clazz.declarePackage (prefix + "." + pkgs[i]);
3800 _Loader.loadPackageClasspath (prefix + "." + pkgs[i], base);
3805 * Using multiple sites to load *.js in multiple threads. Using multiple
3806 * sites may avoid 2 HTTP 1.1 connections recommendation limit.
3807 * Here is a default implementation for http://archive.java2script.org.
3808 * In site archive.java2script.org, there are 6 sites:
3809 * 1. http://archive.java2script.org or http://a.java2script.org
3810 * 2. http://erchive.java2script.org or http://e.java2script.org
3811 * 3. http://irchive.java2script.org or http://i.java2script.org
3812 * 4. http://orchive.java2script.org or http://o.java2script.org
3813 * 5. http://urchive.java2script.org or http://u.java2script.org
3814 * 6. http://yrchive.java2script.org or http://y.java2script.org
3818 _Loader.multipleSites = function (path) {
3819 var deltas = window["j2s.update.delta"];
3820 if (deltas && deltas instanceof Array && deltas.length >= 3) {
3821 var lastOldVersion = null;
3822 var lastNewVersion = null;
3823 for (var i = 0; i < deltas.length / 3; i++) {
3824 var oldVersion = deltas[i + i + i];
3825 if (oldVersion != "$") {
3826 lastOldVersion = oldVersion;
3828 var newVersion = deltas[i + i + i + 1];
3829 if (newVersion != "$") {
3830 lastNewVersion = newVersion;
3832 var relativePath = deltas[i + i + i + 2];
3833 var key = lastOldVersion + "/" + relativePath;
3834 var idx = path.indexOf (key);
3835 if (idx != -1 && idx == path.length - key.length) {
3836 path = path.substring (0, idx) + lastNewVersion + "/" + relativePath;
3841 var length = path.length;
3842 if (maxLoadingThreads > 1
3843 && ((length > 15 && path.substring (0, 15) == "http://archive.")
3844 || (length > 9 && path.substring (0, 9) == "http://a."))) {
3845 var index = path.lastIndexOf("/");
3846 if (index < length - 3) {
3847 var arr = ['a', 'e', 'i', 'o', 'u', 'y'];
3848 var c1 = path.charCodeAt (index + 1);
3849 var c2 = path.charCodeAt (index + 2);
3850 var idx = (length - index) * 3 + c1 * 5 + c2 * 7; // Hash
3851 return path.substring (0, 7) + arr[idx % 6] + path.substring (8);
3859 * Return the *.js path of the given class. Maybe the class is contained
3860 * in a *.z.js jar file.
3861 * @param clazz Given class that the path is to be calculated for. May
3862 * be java.package, or java.lang.String
3863 * @param forRoot Optional argument, if true, the return path will be root
3864 * of the given classs' package root path.
3865 * @param ext Optional argument, if given, it will replace the default ".js"
3869 _Loader.getClasspathFor = function (clazz, forRoot, ext) {
3870 var path = classpathMap["#" + clazz];
3871 if (!path || forRoot || ext) {
3875 clazz = clazz.replace(/\./g, "/");
3876 if ((idx = path.lastIndexOf(clazz)) >= 0
3877 || (idx = clazz.lastIndexOf("/")) >= 0
3878 && (idx = path.lastIndexOf(clazz.substring(0, idx))) >= 0)
3879 base = path.substring(0, idx);
3881 idx = clazz.length + 2;
3882 while ((idx = clazz.lastIndexOf(".", idx - 2)) >= 0)
3883 if ((base = classpathMap["@" + clazz.substring(0, idx)]))
3886 clazz = clazz.replace (/\./g, "/");
3889 var bins = "binaryFolders";
3890 base = (window["Clazz"] && Clazz[bins] && Clazz[bins].length ? Clazz[bins][0]
3891 : _Loader[bins] && _Loader[bins].length ? _Loader[bins][0]
3894 path = (base.lastIndexOf("/") == base.length - 1 ? base : base + "/") + (forRoot ? ""
3895 : clazz.lastIndexOf("/*") == clazz.length - 2 ? clazz.substring(0, idx + 1)
3896 : clazz + (!ext ? ".js" : ext.charAt(0) != '.' ? "." + ext : ext));
3898 return path;//_Loader.multipleSites(path);
3902 * To ignore some classes.
3905 _Loader.ignore = function () {
3906 var clazzes = (arguments.length == 1 && arguments[0] instanceof Array ?
3907 clazzes = arguments[0] : null);
3908 var n = (clazzes ? clazzes.length : arguments.length);
3910 clazzes = new Array(n);
3911 for (var i = 0; i < n; i++)
3912 clazzes[i] = arguments[i];
3914 unwrapArray(clazzes);
3915 for (var i = 0; i < n; i++)
3916 excludeClassMap["@" + clazzes[i]] = 1;
3920 * The following *.script* can be overriden to indicate the
3921 * status of classes loading.
3923 * TODO: There should be a Java interface with name like INativeLoaderStatus
3926 _Loader.onScriptLoading = function (file){};
3929 _Loader.onScriptLoaded = function (file, isError){};
3932 _Loader.onScriptInitialized = function (file){};
3935 _Loader.onScriptCompleted = function (file){};
3938 _Loader.onClassUnloaded = function (clazz){};
3941 * After all the classes are loaded, this method will be called.
3942 * Should be overriden to run *.main([]).
3945 _Loader.onGlobalLoaded = function () {};
3948 _Loader.keepOnLoading = true; // never set false in this code
3952 var mapPath2ClassNode = {};
3955 var isClassExcluded = function (clazz) {
3956 return excludeClassMap["@" + clazz];
3959 /* Used to keep ignored classes */
3961 var excludeClassMap = {};
3964 var evaluate = function(file, file0, js) {
3966 eval(js + ";//# sourceURL="+file);
3970 var s = "[Java2Script] The required class file \n\n" + file + (js.indexOf("[Exception") == 0 && js.indexOf("data: no") ?
3971 "\nwas not found.\n"
3972 : "\ncould not be loaded. Script error: " + e.message + " \n\ndata:\n\n" + js) + "\n\n" + Clazz.getStackTrace();
3977 _Loader.onScriptLoaded(file, false);
3978 tryToLoadNext(file0);
3982 var failedHandles = {};
3985 var generateRemovingFunction = function (node) {
3986 return function () {
3987 if (node.readyState != "interactive") {
3989 if (node.parentNode)
3990 node.parentNode.removeChild (node);
3998 var removeScriptNode = function (n) {
3999 if (window["j2s.script.debugging"]) {
4002 // lazily remove script nodes.
4003 window.setTimeout (generateRemovingFunction (n), 1);
4007 Clazz._4Name = function(clazzName, applet, state) {
4008 if (Clazz.isClassDefined(clazzName))
4009 return Clazz.evalType(clazzName);
4010 var f = (Jmol._isAsync && applet ? applet._restoreState(clazzName, state) : null);
4012 return null; // must be already being created
4013 if (_Loader.setLoadingMode(f ? _Loader.MODE_SCRIPT : "xhr.sync")) {
4014 _Loader.loadClass(clazzName, f, false, true, 1);
4015 return null; // this will surely throw an error, but that is OK
4017 //alert ("Using Java reflection: " + clazzName + " for " + applet._id + " \n"+ Clazz.getStackTrace());
4018 _Loader.loadClass(clazzName);
4019 return Clazz.evalType(clazzName);
4023 * BH: possibly useful for debugging
4025 Clazz.currentPath= "";
4028 * Load *.js by adding script elements into head. Hook the onload event to
4029 * load the next class in dependency tree.
4032 var loadScript = function (node, file, why, ignoreOnload, fSuccess, _loadScript) {
4034 Clazz.currentPath = file;
4035 if (ignoreOnload)alert("WHY>>")
4036 //BH removed // maybe some scripts are to be loaded without needs to know onload event.
4037 // if (!ignoreOnload && loadedScripts[file]) {
4038 // _Loader.tryToLoadNext(file);
4041 loadedScripts[file] = true;
4042 // also remove from queue
4043 removeArrayItem(classQueue, file);
4045 // forces not-found message
4046 isUsingXMLHttpRequest = true;
4047 isAsynchronousLoading = false;
4048 if (_Loader._checkLoad) {
4049 System.out.println("\t" + file + (why ? "\n -- required by " + why : "") + " ajax=" + isUsingXMLHttpRequest + " async=" + isAsynchronousLoading)
4053 if (Clazz._debugging) {
4054 file = file.replace(/\.z\.js/,".js");
4057 _Loader.onScriptLoading(file);
4058 if (isUsingXMLHttpRequest && !isAsynchronousLoading) {
4059 // alert("\t" + file + (why ? "\n -- required by " + why : "") + " ajax=" + isUsingXMLHttpRequest + " async=" + isAsynchronousLoading + " " + Clazz.getStackTrace())
4060 // synchronous loading
4061 // works in MSIE locally unless a binary file :)
4062 // from Jmol.api.Interface only
4063 var data = Jmol._getFileData(file);
4065 evaluate(file, file0, data);
4067 alert(e + " loading file " + file + " " + node.name + " " + Clazz.getStackTrace());
4070 // System.out.println("firing in loadScript " + file + " " + (fSuccess && fSuccess.toString()))
4077 System.out.println("for file " + file +" fSuccess = " + (fSuccess ? fSuccess.toString() : ""))
4083 success:W3CScriptOnCallback(file, false, fSuccess),
4084 error:W3CScriptOnCallback(file, true, fSuccess)
4091 var W3CScriptOnCallback = function (path, forError, fSuccess) {
4092 var s = Clazz.getStackTrace();
4093 // if (!fSuccess)alert("why no fSuccess?" + s)
4094 return function () {
4095 //System.out.println("returning " + (fSuccess ? fSuccess.toString() : "no function ") + s)
4096 if (forError && __debuggingBH)Clazz.alert ("############ forError=" + forError + " path=" + path + " ####" + (forError ? "NOT" : "") + "LOADED###");
4097 if (isGecko && this.timeoutHandle)
4098 window.clearTimeout(this.timeoutHandle), this.timeoutHandle = null;
4099 if (inLoadingThreads > 0)
4101 //System.out.println("w3ccalback for " + path + " " + inLoadingThreads + " threads")
4103 this.onerror = null;
4105 alert ("There was a problem loading " + path);
4106 _Loader.onScriptLoaded(path, true);
4110 f = function(_W3scriptFS){removeScriptNode(node);tryToLoadNext(path, fSuccess); };
4112 f = function(_W3script){removeScriptNode(node);tryToLoadNext(path)};
4113 if (loadingTimeLag >= 0)
4114 window.setTimeout(function() { tryToLoadNext(path, f); }, loadingTimeLag);
4116 tryToLoadNext(path, f);
4121 var isLoadingEntryClass = true;
4124 var besidesJavaPackage = false;
4127 * After class is loaded, this method will be executed to check whether there
4128 * are classes in the dependency tree that need to be loaded.
4131 var tryToLoadNext = function (file, fSuccess) {
4132 var node = mapPath2ClassNode["@" + file];
4133 if (!node) // maybe class tree root
4136 // check for content loaded
4137 var clazzes = classpathMap["$" + file];
4139 for (var i = 0; i < clazzes.length; i++) {
4140 var name = clazzes[i];
4141 if (name != node.name && (n = findNode(name))) {
4142 if (n.status < Node.STATUS_CONTENT_LOADED) {
4143 n.status = Node.STATUS_CONTENT_LOADED;
4149 var pp = classpathMap["#" + name];
4151 alert (name + " J2S error in tryToLoadNext");
4152 error("Java2Script implementation error! Please report this bug!");
4155 mappingPathNameNode (n.path, name, n);
4156 n.status = Node.STATUS_CONTENT_LOADED;
4157 addChildClassNode(clazzTreeRoot, n, false);
4162 if (node instanceof Array) {
4163 for (var i = 0; i < node.length; i++) {
4164 if (node[i].status < Node.STATUS_CONTENT_LOADED) {
4165 node[i].status = Node.STATUS_CONTENT_LOADED;
4166 updateNode(node[i]);
4169 } else if (node.status < Node.STATUS_CONTENT_LOADED) {
4170 var stillLoading = false;
4171 var ss = document.getElementsByTagName ("SCRIPT");
4172 for (var i = 0; i < ss.length; i++) {
4174 if (ss[i].onreadystatechange && ss[i].onreadystatechange.path == node.path
4175 && ss[i].readyState == "interactive") {
4176 stillLoading = true;
4179 } else if (ss[i].onload && ss[i].onload.path == node.path) {
4180 stillLoading = true;
4184 if (!stillLoading) {
4185 node.status = Node.STATUS_CONTENT_LOADED;
4190 * Maybe in #optinalLoaded inside above _Loader#updateNode calls,
4191 * _Loader.keepOnLoading is set false (Already loaded the wanted
4192 * classes), so here check to stop.
4195 if (!_Loader.keepOnLoading) // set externally
4198 // check for a "must" class that has content and load it
4201 if ((n = findNextMustClass(Node.STATUS_KNOWN))) {
4203 while (inLoadingThreads < maxLoadingThreads) {
4204 if (!(n = findNextMustClass(Node.STATUS_KNOWN)))
4206 loadClassNode(n); // will increase inLoadingThreads!
4208 } else if ((cq = classQueue).length != 0) {
4209 /* queue must be loaded in order! */
4211 if (!loadedScripts[n.path]
4213 || !isLoadingEntryClass
4215 || n.optionals.length) {
4216 addChildClassNode(clazzTreeRoot, n, true);
4217 loadScript(n, n.path, n.requiredBy, false);
4218 } else if (isLoadingEntryClass) {
4220 * The first time reaching here is the time when ClassLoader
4221 * is trying to load entry class. Class with #main method and
4222 * is to be executed is called Entry Class.
4224 * Here when loading entry class, ClassLoader should not call
4225 * the next following loading script. This is because, those
4226 * scripts will try to mark the class as loaded directly and
4227 * then continue to call #onLoaded callback method,
4228 * which results in an script error!
4230 isLoadingEntryClass = false;
4232 } else if ((n = findNextRequiredClass(Node.STATUS_KNOWN))) {
4234 while (inLoadingThreads < maxLoadingThreads) {
4235 if (!(n = findNextRequiredClass(Node.STATUS_KNOWN)))
4237 loadClassNode(n); // will increase inLoadingThreads!
4242 if (working || inLoadingThreads > 0)
4245 // now check all classes that MUST be loaded prior to initialization
4246 // of some other class (static calls, extends, implements)
4247 // and all classes REQUIRED somewhere in that class, possibly by the constructor
4248 // (that is, "new xxxx()" called somewhere in code) and update them
4249 // that have content but are not declared already
4250 var f = [findNextMustClass,findNextRequiredClass];
4251 var lastNode = null;
4252 for (var i = 0; i < 2; i++)
4253 while ((n = f[i](Node.STATUS_CONTENT_LOADED))) {
4254 if (i == 1 && lastNode === n) // Already existed cycle ?
4255 n.status = Node.STATUS_LOAD_COMPLETE;
4260 // check for load cycles
4264 if (!checkCycle(clazzTreeRoot, file))
4268 // and update all MUST and REQUIRED classes that are declared already
4270 for (var i = 0; i < 2; i++) {
4272 while ((n = f[i](Node.STATUS_DECLARED))) {
4275 updateNode(lastNode = n);
4279 for (var i = 0; i < 2; i++)
4280 while ((n = f[i](Node.STATUS_DECLARED)))
4281 done.push(n), n.status = Node.STATUS_LOAD_COMPLETE;
4283 for (var i = 0; i < done.length; i++)
4284 destroyClassNode(done[i]);
4285 for (var i = 0; i < done.length; i++)
4286 if ((f = done[i].onLoaded))
4287 done[i].onLoaded = null, f();
4296 //System.out.println(node.name + " loaded completely" + _Loader.onGlobalLoaded + "\n\n")
4298 //System.out.println("tryToLoadNext firing " + _Loader._classCountOK + "/" + _Loader._classCountPending + " " + fSuccess.toString() + " " + Clazz.getStackTrace())
4300 } else if (_Loader._classCountPending) {
4301 for (var name in _Loader._classPending) {
4302 var n = findNode(name);
4303 System.out.println("class left pending " + name + " " + n);
4311 // System.out.println("I think I'm done "
4312 // + _Loader._classCountOK + "/" + _Loader._classCountPending + " "
4313 //+ _Loader.onGlobalLoaded.toString() + " " + Clazz.getStackTrace()
4315 if (_Loader._checkLoad) {
4316 System.out.println("I think I'm done: SAEM call count: " + SAEMid);
4317 Clazz.showDuplicates(true);
4320 _Loader.onGlobalLoaded();
4327 * There are classes reference cycles. Try to detect and break those cycles.
4330 var checkCycle = function (node, file) {
4332 var len = ts.length;
4333 // add this node to tracks
4337 if (ts[i] === node && ts[i].status >= Node.STATUS_DECLARED)
4340 // this node is already in tracks, and it has been declared already
4341 // for each node in tracks, set its status to "LOAD_COMPLETE"
4342 // update all parents, remove all parents, and fire its onLoaded function
4343 // then clear tracks and return true (keep checking)
4344 if (_Loader._checkLoad) {
4345 var msg = "cycle found loading " + file + " for " + node;
4346 System.out.println(msg)
4348 for (; i < len; i++) {
4350 n.status = Node.STATUS_LOAD_COMPLETE;
4351 destroyClassNode(n); // Same as above
4352 for (var k = 0; k < n.parents.length; k++)
4353 updateNode(n.parents[k]);
4356 if (_Loader._checkLoad) {
4357 var msg = "cycle setting status to LOAD_COMPLETE for " + n.name + (f ? " firing " + f.toString() : "");
4358 System.out.println(msg)
4361 n.onLoaded = null, f();
4366 var a = [node.musts, node.optionals];
4367 for (var j = 0; j < 2; j++)
4368 for (var r = a[j], i = r.length; --i >= 0;)
4369 if (r[i].status == Node.STATUS_DECLARED && checkCycle(r[i], file))
4371 // reset _tracks to its original length
4373 return false; // done
4377 _Loader._classCountPending = 0;
4378 _Loader._classCountOK = 0;
4379 _Loader._classPending = {};
4381 _Loader.showPending = function() {
4383 for (var name in _Loader._classPending) {
4384 var n = findNode(name);
4386 alert("No node for " + name);
4390 System.out.println(showNode("", "", n, "", 0));
4395 var showNode = function(s, names, node, inset, level) {
4396 names += "--" + node.name;
4399 s += inset + " ...\n";
4403 s += inset + "status: " + node.status + "\n";
4404 if (node.parents && node.parents.length && node.parents[0] && node.parents[0].name) {
4405 s += inset + "parents: " + node.parents.length + "\n";
4406 for (var i = 0; i < node.parents.length; i++) {
4407 s = showNode(s, names, node.parents[i], inset + "\t", level+1);
4411 // if (node.requiredBy) {
4412 // s += inset + "requiredBy:\n";
4413 // s = showNode(s, names, node.requiredBy, inset + "\t", level+1);
4420 * Update the dependency tree nodes recursively.
4423 updateNode = function(node, _updateNode) {
4424 if (!node.name || node.status >= Node.STATUS_LOAD_COMPLETE) {
4425 destroyClassNode(node);
4429 // check for declared and also having MUSTS
4430 if (node.musts.length && node.declaration) {
4431 for (var mustLength = node.musts.length, i = mustLength; --i >= 0;) {
4432 var n = node.musts[i];
4433 n.requiredBy = node;
4434 if (n.status < Node.STATUS_DECLARED && isClassDefined (n.name)) {
4435 var nns = []; // a stack for onLoaded events
4436 n.status = Node.STATUS_LOAD_COMPLETE;
4437 destroyClassNode(n); // Same as above
4438 if (n.declaration && n.declaration.clazzList) {
4439 // For those classes within one *.js file, update them synchronously.
4440 for (var j = 0, list = n.declaration.clazzList, l = list.length; j < l; j++) {
4441 var nn = findNode (list[j]);
4442 if (nn && nn.status != Node.STATUS_LOAD_COMPLETE
4444 nn.status = n.status;
4445 nn.declaration = null;
4446 destroyClassNode(nn);
4447 nn.onLoaded && nns.push(nn);
4450 n.declaration = null;
4452 // fire all onLoaded events
4455 for (var j = 0; j < nns.length; j++) {
4456 var onLoaded = nns[j].onLoaded;
4458 nns[j].onLoaded = null;
4463 (n.status == Node.STATUS_CONTENT_LOADED) && updateNode(n); // musts may be changed
4464 if (n.status < Node.STATUS_DECLARED)
4467 if (node.musts.length != mustLength) {
4468 // length changed -- restart!
4469 i = mustLength = node.musts.length;
4476 if (node.status < Node.STATUS_DECLARED) {
4477 var decl = node.declaration;
4479 decl(), decl.executed = true;
4480 if(_Loader._checkLoad) {
4481 if (_Loader._classPending[node.name]) {
4482 delete _Loader._classPending[node.name];
4483 _Loader._classCountOK;
4484 _Loader._classCountPending--;
4485 // System.out.println("OK " + (_Loader._classCountOK) + " FOR " + node.name)
4488 node.status = Node.STATUS_DECLARED;
4490 definedClasses[node.name] = true;
4491 _Loader.onScriptInitialized(node.path);
4492 if (node.declaration && node.declaration.clazzList) {
4493 // For those classes within one *.js file, update them synchronously.
4494 for (var j = 0, list = node.declaration.clazzList, l = list.length; j < l; j++) {
4495 var nn = findNode(list[j]);
4496 if (nn && nn.status != Node.STATUS_DECLARED
4498 nn.status = Node.STATUS_DECLARED;
4500 definedClasses[nn.name] = true;
4501 _Loader.onScriptInitialized(nn.path);
4506 var level = Node.STATUS_DECLARED;
4507 if (node.optionals.length == 0 && node.musts.length == 0
4508 || node.status > Node.STATUS_KNOWN && !node.declaration
4509 || checkStatusIs(node.musts, Node.STATUS_LOAD_COMPLETE)
4510 && checkStatusIs(node.optionals, Node.STATUS_LOAD_COMPLETE)) {
4511 level = Node.STATUS_LOAD_COMPLETE;
4512 if (!doneLoading(node, level))
4514 // For those classes within one *.js file, update them synchronously.
4515 if (node.declaration && node.declaration.clazzList) {
4516 for (var j = 0, list = node.declaration.clazzList, l = list.length; j < l; j++) {
4517 var nn = findNode(list[j]);
4518 if (nn && nn.status != level && nn !== node) {
4519 nn.declaration = null;
4520 if (!doneLoading(nn, level))
4526 // _Loader.updateParents = function (node, level, _updateParents)
4527 if (node.parents && node.parents.length) {
4528 for (var i = 0; i < node.parents.length; i++) {
4529 var p = node.parents[i];
4530 if (p.status < level)
4531 updateNode(p, p.name);
4533 if (level == Node.STATUS_LOAD_COMPLETE)
4539 var checkStatusIs = function(arr, status){
4540 for (var i = arr.length; --i >= 0;)
4541 if (arr[i].status < status)
4546 var doneLoading = function(node, level, _doneLoading) {
4547 node.status = level;
4548 _Loader.onScriptCompleted(node.path);
4550 var onLoaded = node.onLoaded;
4552 node.onLoaded = null;
4554 if (!_Loader.keepOnLoading)
4558 destroyClassNode(node);
4563 * Be used to record already used random numbers. And next new random
4564 * number should not be in the property set.
4572 var getRnd = function() {
4573 while (true) { // get a unique random number
4574 var rnd = Math.random();
4576 if (!usedRandoms[s])
4577 return (usedRandoms[s] = 1, clazzTreeRoot.random = rnd);
4582 var findNode = function(clazzName) {
4584 return findNodeUnderNode(clazzName, clazzTreeRoot);
4588 var findNextRequiredClass = function(status) {
4590 return findNextRequiredNode(clazzTreeRoot, status);
4594 var findNextMustClass = function(status) {
4595 return findNextMustNode(clazzTreeRoot, status);
4599 var findNodeUnderNode = function(clazzName, node) {
4601 // node, then musts then optionals
4602 return (node.name == clazzName ? node
4603 : (n = findNodeWithin(clazzName, node.musts))
4604 || (n = findNodeWithin(clazzName, node.optionals))
4609 var findNodeWithin = function(name, arr) {
4610 var rnd = clazzTreeRoot.random;
4611 for (var i = arr.length; --i >= 0;) {
4615 if (n.random != rnd) {
4617 if ((n = findNodeUnderNode(name, n)))
4625 var checkStatus = function(n, status) {
4626 return (n.status == status
4627 && (status != Node.STATUS_KNOWN || !loadedScripts[n.path])
4628 && (status == Node.STATUS_DECLARED || !isClassDefined (n.name)));
4632 var findNextMustNode = function(node, status) {
4633 for (var i = node.musts.length; --i >= 0;) {
4634 var n = node.musts[i];
4635 if (checkStatus(n, status) || (n = findNextMustNode(n, status)))
4638 return (checkStatus(node, status) ? node : null);
4642 var findNextRequiredNode = function (node, status) {
4643 // search musts first
4644 // search optionals second
4645 // search itself last
4647 return ((n = searchClassArray(node.musts, status))
4648 || (n = searchClassArray(node.optionals, status))
4649 || checkStatus(n = node, status) ? n : null);
4653 var searchClassArray = function (arr, status) {
4655 var rnd = clazzTreeRoot.random;
4656 for (var i = 0; i < arr.length; i++) {
4658 if (checkStatus(n, status))
4660 if (n.random != rnd) {
4661 n.random = rnd; // mark as visited!
4662 if ((n = findNextRequiredNode(n, status)))
4671 * This map variable is used to mark that *.js is correctly loaded.
4672 * In IE, _Loader has defects to detect whether a *.js is correctly
4673 * loaded or not, so inner loading mark is used for detecting.
4676 var innerLoadedScripts = {};
4679 * This method will be called in almost every *.js generated by Java2Script
4683 var load = function (musts, name, optionals, declaration) {
4684 // called as name.load in Jmol
4685 if (name instanceof Array) {
4687 for (var i = 0; i < name.length; i++)
4688 load(musts, name[i], optionals, declaration, name);
4692 if (_Loader._checkLoad) {
4693 if (_Loader._classPending[name]) {
4694 //alert("duplicate load for " + name)
4696 _Loader._classPending[name] = 1;
4697 if (_Loader._classCountPending++ == 0)
4698 _Loader._classCountOK = 0;
4699 System.out.println("Loading class " + name);
4703 // if (clazz.charAt (0) == '$')
4704 // clazz = "org.eclipse.s" + clazz.substring (1);
4705 var node = mapPath2ClassNode["#" + name];
4706 if (!node) { // load called inside *.z.js?
4707 var n = findNode(name);
4708 node = (n ? n : new Node());
4710 node.path = classpathMap["#" + name] || "unknown";
4711 mappingPathNameNode(node.path, name, node);
4712 node.status = Node.STATUS_KNOWN;
4713 addChildClassNode(clazzTreeRoot, node, false);
4715 processRequired(node, musts, true);
4716 if (arguments.length == 5 && declaration) {
4717 declaration.status = node.status;
4718 declaration.clazzList = arguments[4];
4720 node.declaration = declaration;
4722 node.status = Node.STATUS_CONTENT_LOADED;
4723 processRequired(node, optionals, false);
4727 var processRequired = function(node, arr, isMust) {
4728 if (arr && arr.length) {
4730 for (var i = 0; i < arr.length; i++) {
4734 if (isClassDefined(name)
4735 || isClassExcluded(name))
4737 var n = findNode(name);
4741 n.status = Node.STATUS_KNOWN;
4743 n.requiredBy = node;
4744 addChildClassNode(node, n, isMust);
4750 * Try to be compatiable of Clazz
4752 if (window["Clazz"]) {
4755 _Loader.load = load;
4758 * Map different class to the same path! Many classes may be packed into
4766 var mappingPathNameNode = function (path, name, node) {
4767 var map = mapPath2ClassNode;
4768 var keyPath = "@" + path;
4769 var v = map[keyPath];
4771 if (v instanceof Array) {
4772 var existed = false;
4773 for (var i = 0; i < v.length; i++) {
4774 if (v[i].name == name) {
4782 map[keyPath] = [v, node];
4785 map[keyPath] = node;
4787 map["#" + name] = node;
4791 var loadClassNode = function (node) {
4792 var name = node.name;
4793 if (!isClassDefined (name)
4794 && !isClassExcluded (name)) {
4795 var path = _Loader.getClasspathFor (name/*, true*/);
4797 mappingPathNameNode (path, name, node);
4798 if (!loadedScripts[path]) {
4799 loadScript(node, path, node.requiredBy, false);
4810 var runtimeKeyClass = _Loader.runtimeKeyClass = "java.lang.String";
4813 * Queue used to store classes before key class is loaded.
4816 var queueBe4KeyClazz = [];
4822 * Return J2SLib base path from existed SCRIPT src attribute.
4825 _Loader.getJ2SLibBase = function () {
4826 var o = window["j2s.lib"];
4827 return (o ? o.base + (o.alias == "." ? "" : (o.alias ? o.alias : (o.version ? o.version : "1.0.0")) + "/") : null);
4831 * Indicate whether _Loader is loading script synchronously or
4835 var isAsynchronousLoading = true;
4838 var isUsingXMLHttpRequest = false;
4841 var loadingTimeLag = -1;
4843 _Loader.MODE_SCRIPT = 4;
4844 _Loader.MODE_XHR = 2;
4845 _Loader.MODE_SYNC = 1;
4849 * asynchronous modes:
4850 * async(...).script, async(...).xhr, async(...).xmlhttprequest,
4851 * script.async(...), xhr.async(...), xmlhttprequest.async(...),
4854 * synchronous modes:
4855 * sync(...).xhr, sync(...).xmlhttprequest,
4856 * xhr.sync(...), xmlhttprequest.sync(...),
4857 * xmlhttprequest, xhr
4860 * Script 4; XHR 2; SYNC bit 1;
4863 _Loader.setLoadingMode = function (mode, timeLag) {
4866 if (typeof mode == "string") {
4867 mode = mode.toLowerCase();
4868 if (mode.indexOf("script") >= 0)
4871 async = (mode.indexOf("async") >=0);
4872 async = false; // BH
4874 if (mode & _Loader.MODE_SCRIPT)
4877 async = !(mode & _Loader.MODE_SYNC);
4879 isUsingXMLHttpRequest = ajax;
4880 isAsynchronousLoading = async;
4881 loadingTimeLag = (async && timeLag >= 0 ? timeLag: -1);
4886 var runtimeLoaded = function () {
4887 if (pkgRefCount || !isClassDefined(runtimeKeyClass))
4889 var qbs = queueBe4KeyClazz;
4890 for (var i = 0; i < qbs.length; i++)
4891 _Loader.loadClass(qbs[i][0], qbs[i][1]);
4892 queueBe4KeyClazz = [];
4896 * Load those key *.z.js. This *.z.js will be surely loaded before other
4900 _Loader.loadZJar = function (zjarPath, keyClass) {
4901 // used only by package.js for core.z.js
4903 var isArr = (keyClass instanceof Array);
4905 keyClass = keyClass[keyClass.length - 1];
4907 f = (keyClass == runtimeKeyClass ? runtimeLoaded : null);
4908 _Loader.jarClasspath(zjarPath, isArr ? keyClass : [keyClass]);
4909 // BH note: runtimeKeyClass is java.lang.String
4910 _Loader.loadClass(keyClass, f, true);
4917 * The method help constructing the multiple-binary class dependency tree.
4920 var addChildClassNode = function (parent, child, isMust) {
4921 var existed = false;
4925 if (!child.requiredBy)
4926 child.requiredBy = parent;
4927 // if (!parent.requiresMap){
4928 // parent.requires = [];
4929 // parent.requiresMap = {};
4931 // if (!parent.requiresMap[child.name]) {
4932 // parent.requiresMap[child.name] = 1;
4933 // parent.requires.push[child];
4936 arr = parent.optionals;
4938 if (!NodeMap[child.name]) {
4939 _allNodes.push(child)
4940 NodeMap[child.name]=child
4942 for (var i = 0; i < arr.length; i++) {
4943 if (arr[i].name == child.name) {
4950 if (isLoadingEntryClass
4951 && child.name.indexOf("java") != 0
4952 && child.name.indexOf("net.sf.j2s.ajax") != 0) {
4953 if (besidesJavaPackage)
4954 isLoadingEntryClass = false;
4955 besidesJavaPackage = true;
4956 // } else if (child.name.indexOf("org.eclipse.swt") == 0
4957 // || child.name.indexOf("$wt") == 0) {
4958 // window["swt.lazy.loading.callback"] = swtLazyLoading;
4959 // if (needPackage("org.eclipse.swt"))
4960 // return _Loader.loadPackage("org.eclipse.swt", function() {addParentClassNode(child, parent)});
4963 addParentClassNode(child, parent);
4967 var addParentClassNode = function(child, parent) {
4968 if (parent.name && parent != clazzTreeRoot && parent != child)
4969 for (var i = 0; i < child.parents.length; i++)
4970 if (child.parents[i].name == parent.name)
4972 child.parents.push(parent);
4976 var destroyClassNode = function (node) {
4977 var parents = node.parents;
4979 for (var k = parents.length; --k >= 0;)
4980 removeArrayItem(parents[k].musts, node) || removeArrayItem(parents[k].optionals, node);
4984 _Loader.unloadClassExt = function (qClazzName) {
4986 definedClasses[qClazzName] = false;
4987 if (classpathMap["#" + qClazzName]) {
4988 var pp = classpathMap["#" + qClazzName];
4989 classpathMap["#" + qClazzName] = null;
4990 var arr = classpathMap["$" + pp];
4991 removeArrayItem(arr, qClazzName) && (classpathMap["$" + pp] = arr);
4993 var n = findNode(qClazzName);
4995 n.status = Node.STATUS_KNOWN;
4996 loadedScripts[n.path] = false;
4998 var path = _Loader.getClasspathFor (qClazzName);
4999 loadedScripts[path] = false;
5000 innerLoadedScripts[path] && (innerLoadedScripts[path] = false);
5001 _Loader.onClassUnloaded(qClazzName);
5005 var assureInnerClass = function (clzz, fun) {
5006 clzz = clzz.__CLASS_NAME__;
5007 if (Clazz.unloadedClasses[clzz]) {
5008 if (clzz.indexOf("$") >= 0)
5011 var key = clzz + "$";
5012 for (var s in Clazz.unloadedClasses)
5013 if (Clazz.unloadedClasses[s] && s.indexOf(key) == 0)
5019 if ((idx1 = fun.indexOf(key)) < 0 || (idx2 = fun.indexOf("\"", idx1 + key.length)) < 0)
5021 clzz = fun.substring(idx1, idx2);
5022 if (!Clazz.unloadedClasses[clzz] || (idx1 = fun.indexOf("{", idx2) + 1) == 0)
5024 if ((idx2 = fun.indexOf("(" + clzz + ",", idx1 + 3)) < 0
5025 || (idx2 = fun.lastIndexOf("}", idx2 - 1)) < 0)
5027 eval(fun.substring(idx1, idx2));
5028 Clazz.unloadedClasses[clzz] = null;
5032 Clazz.binaryFolders = _Loader.binaryFolders = [ _Loader.getJ2SLibBase() ];
5034 })(Clazz, Clazz._Loader);
5037 /******************************************************************************
5038 * Copyright (c) 2007 java2script.org and others.
5039 * All rights reserved. This program and the accompanying materials
5040 * are made available under the terms of the Eclipse Public License v1.0
5041 * which accompanies this distribution, and is available at
5042 * http://www.eclipse.org/legal/epl-v10.html
5045 * Zhou Renjian - initial API and implementation
5046 *****************************************************************************/
5048 * @author zhou renjian
5049 * @create Jan 11, 2007
5052 Clazz._LoaderProgressMonitor = {};
5054 ;(function(CLPM, Jmol) {
5056 var fadeOutTimer = null;
5058 var monitorEl = null;
5059 var lastScrollTop = 0;
5060 var bindingParent = null;
5062 CLPM.DEFAULT_OPACITY = (Jmol && Jmol._j2sLoadMonitorOpacity ? Jmol._j2sLoadMonitorOpacity : 55);
5065 /*CLPM.initialize = function (parent) {
5066 bindingParent = parent;
5067 if (parent && !attached) {
5069 //Clazz.addEvent (window, "unload", cleanup);
5070 // window.attachEvent ("onunload", cleanup);
5076 CLPM.hideMonitor = function () {
5077 monitorEl.style.display = "none";
5081 CLPM.showStatus = function (msg, fading) {
5086 //Clazz.addEvent (window, "unload", cleanup);
5087 // window.attachEvent ("onunload", cleanup);
5090 clearChildren(monitorEl);
5100 monitorEl.appendChild(document.createTextNode ("" + msg));
5101 if (monitorEl.style.display == "none") {
5102 monitorEl.style.display = "";
5104 setAlpha(CLPM.DEFAULT_OPACITY);
5105 var offTop = getFixedOffsetTop();
5106 if (lastScrollTop != offTop) {
5107 lastScrollTop = offTop;
5108 monitorEl.style.bottom = (lastScrollTop + 4) + "px";
5115 /* private static */
5116 var clearChildren = function (el) {
5119 for (var i = el.childNodes.length; --i >= 0;) {
5120 var child = el.childNodes[i];
5123 if (child.childNodes && child.childNodes.length)
5124 clearChildren (child);
5126 el.removeChild (child);
5131 var setAlpha = function (alpha) {
5132 if (fadeOutTimer && alpha == CLPM.DEFAULT_OPACITY) {
5133 window.clearTimeout (fadeOutTimer);
5134 fadeOutTimer = null;
5137 var ua = navigator.userAgent.toLowerCase();
5138 monitorEl.style.filter = "Alpha(Opacity=" + alpha + ")";
5139 monitorEl.style.opacity = alpha / 100.0;
5142 var hidingOnMouseOver = function () {
5147 var attached = false;
5149 var cleanup = function () {
5151 // monitorEl.onmouseover = null;
5154 bindingParent = null;
5155 //Clazz.removeEvent (window, "unload", cleanup);
5156 //window.detachEvent ("onunload", cleanup);
5160 var createHandle = function () {
5161 var div = document.createElement ("DIV");
5162 div.id = "_Loader-status";
5163 div.style.cssText = "position:absolute;bottom:4px;left:4px;padding:2px 8px;"
5164 + "z-index:" + (window["j2s.lib"].monitorZIndex || 10000) + ";background-color:#8e0000;color:yellow;"
5165 + "font-family:Arial, sans-serif;font-size:10pt;white-space:nowrap;";
5166 div.onmouseover = hidingOnMouseOver;
5168 if (bindingParent) {
5169 bindingParent.appendChild(div);
5171 document.body.appendChild(div);
5177 var fadeOut = function () {
5178 if (monitorEl.style.display == "none") return;
5179 if (fadeAlpha == CLPM.DEFAULT_OPACITY) {
5180 fadeOutTimer = window.setTimeout(function () {
5184 } else if (fadeAlpha - 10 >= 0) {
5185 setAlpha(fadeAlpha - 10);
5186 fadeOutTimer = window.setTimeout(function () {
5190 monitorEl.style.display = "none";
5194 var getFixedOffsetTop = function (){
5195 if (bindingParent) {
5196 var b = bindingParent;
5199 var dua = navigator.userAgent;
5200 var b = document.body;
5201 var p = b.parentNode;
5202 var pcHeight = p.clientHeight;
5203 var bcScrollTop = b.scrollTop + b.offsetTop;
5204 var pcScrollTop = p.scrollTop + p.offsetTop;
5205 return (dua.indexOf("Opera") < 0 && document.all ? (pcHeight == 0 ? bcScrollTop : pcScrollTop)
5206 : dua.indexOf("Gecko") < 0 ? (pcHeight == p.offsetHeight
5207 && pcHeight == p.scrollHeight ? bcScrollTop : pcScrollTop) : bcScrollTop);
5211 if (window["ClazzLoader"]) {
5212 _Loader.onScriptLoading = function(file) {
5213 CLPM.showStatus("Loading " + file + "...");
5215 _Loader.onScriptLoaded = function(file, isError) {
5216 CLPM.showStatus(file + (isError ? " loading failed." : " loaded."), true);
5218 _Loader.onGlobalLoaded = function(file) {
5219 CLPM.showStatus("Application loaded.", true);
5221 _Loader.onClassUnloaded = function(clazz) {
5222 CLPM.showStatus("Class " + clazz + " is unloaded.", true);
5227 })(Clazz._LoaderProgressMonitor, Jmol);
5230 /******************************************************************************
5231 * Copyright (c) 2007 java2script.org and others.
5232 * All rights reserved. This program and the accompanying materials
5233 * are made available under the terms of the Eclipse Public License v1.0
5234 * which accompanies this distribution, and is available at
5235 * http://www.eclipse.org/legal/epl-v10.html
5238 * Zhou Renjian - initial API and implementation
5239 *****************************************************************************/
5241 * @author zhou renjian
5242 * @create Nov 5, 2005
5245 ;(function(Con, Sys) {
5247 * Setting maxTotalLines to -1 will not limit the console result
5250 Con.maxTotalLines = 10000;
5253 Con.setMaxTotalLines = function (lines) {
5254 Con.maxTotalLines = (lines > 0 ? lines : 999999);
5258 Con.maxLatency = 40;
5261 Con.setMaxLatency = function (latency) {
5262 Con.maxLatency = (latency > 0 ? latency : 40);
5266 Con.pinning = false;
5269 Con.enablePinning = function (enabled) {
5270 Con.pinning = enabled;
5277 Con.metLineBreak = false;
5281 * Give an extension point so external script can create and bind the console
5284 * TODO: provide more template of binding console window to browser.
5287 Con.createConsoleWindow = function (parentEl) {
5288 var console = document.createElement ("DIV");
5289 console.style.cssText = "font-family:monospace, Arial, sans-serif;";
5290 document.body.appendChild (console);
5294 var c160 = String.fromCharCode(160); //nbsp;
5295 c160 += c160+c160+c160;
5298 Con.consoleOutput = function (s, color) {
5299 var o = window["j2s.lib"];
5300 var console = (o && o.console);
5301 if (console && typeof console == "string")
5302 console = document.getElementById(console)
5304 return false; // BH this just means we have turned off all console action
5305 if (Con.linesCount > Con.maxTotalLines) {
5306 for (var i = 0; i < Con.linesCount - Con.maxTotalLines; i++) {
5307 if (console && console.childNodes.length > 0) {
5308 console.removeChild (console.childNodes[0]);
5311 Con.linesCount = Con.maxTotalLines;
5314 var willMeetLineBreak = false;
5315 s = (typeof s == "undefined" ? "" : s == null ? "null" : "" + s);
5316 s = s.replace (/\t/g, c160);
5318 switch (s.charAt(s.length - 1)) {
5321 s = (s.length > 1 ? s.substring (0, s.length - (s.charAt (s.length - 2) == '\r' ? 2 : 1)) : "");
5322 willMeetLineBreak = true;
5327 s = s.replace (/\t/g, c160);
5328 lines = s.split(/\r\n|\r|\n/g);
5329 for (var i = 0, last = lines.length - 1; i <= last; i++) {
5330 var lastLineEl = null;
5331 if (Con.metLineBreak || Con.linesCount == 0
5332 || console.childNodes.length < 1) {
5333 lastLineEl = document.createElement ("DIV");
5334 console.appendChild (lastLineEl);
5335 lastLineEl.style.whiteSpace = "nowrap";
5339 lastLineEl = console.childNodes[console.childNodes.length - 1];
5341 lastLineEl = document.createElement ("DIV");
5342 console.appendChild (lastLineEl);
5343 lastLineEl.style.whiteSpace = "nowrap";
5347 var el = document.createElement ("SPAN");
5348 lastLineEl.appendChild (el);
5349 el.style.whiteSpace = "nowrap";
5351 el.style.color = color;
5355 el.appendChild(document.createTextNode(l));
5357 console.scrollTop += 100;
5358 Con.metLineBreak = (i != last || willMeetLineBreak);
5361 var cssClazzName = console.parentNode.className;
5362 if (!Con.pinning && cssClazzName
5363 && cssClazzName.indexOf ("composite") != -1) {
5364 console.parentNode.scrollTop = console.parentNode.scrollHeight;
5366 Con.lastOutputTime = new Date ().getTime ();
5370 * Clear all contents inside the console.
5373 Con.clear = function () {
5375 Con.metLineBreak = true;
5376 var o = window["j2s.lib"];
5377 var console = o && o.console;
5378 if (!console || !(console = document.getElementById (console)))
5380 var childNodes = console.childNodes;
5381 for (var i = childNodes.length; --i >= 0;)
5382 console.removeChild (childNodes[i]);
5388 Clazz.alert = function (s) {
5389 Con.consoleOutput (s + "\r\n");
5394 Sys.out.print = function (s) {
5395 Con.consoleOutput (s);
5398 Sys.out.println = function(s) {
5399 Con.consoleOutput(typeof s == "undefined" ? "\r\n" : s == null ? s = "null\r\n" : s + "\r\n");
5402 Sys.out.write = function (buf, offset, len) {
5403 Sys.out.print(String.instantialize(buf).substring(offset, offset+len));
5407 Sys.err.__CLASS_NAME__ = "java.io.PrintStream";
5410 Sys.err.print = function (s) {
5411 Con.consoleOutput (s, "red");
5415 Sys.err.println = function (s) {
5416 Con.consoleOutput (typeof s == "undefined" ? "\r\n" : s == null ? s = "null\r\n" : s + "\r\n", "red");
5419 Sys.err.write = function (buf, offset, len) {
5420 Sys.err.print(String.instantialize(buf).substring(offset, offset+len));
5423 })(Clazz.Console, System);
5425 })(Clazz, Jmol); // requires JSmolCore.js
5427 }; // called by external application