3 // latest author: Bob Hanson, St. Olaf College, hansonr@stolaf.edu
\r
5 // Requires JSmolCore.js and (for now; probably) JSmol.js
\r
6 // This version of j2slib requires jQuery and works in both Chrome and MSIE locally,
\r
7 // though Chrome cannot read local data files, and MSIE cannot read local binary data files.
\r
9 // Java programming notes by Bob Hanson:
\r
11 // There are a few motifs to avoid when optimizing Java code to work smoothly
\r
12 // with the J2S compiler:
\r
16 // 1. an array with null elements cannot be typed and must be avoided.
\r
17 // 2. instances of Java "instance of" involving arrays must be found and convered to calls to Clazz.isA...
\r
18 // 3. new int[n][] must not be used. Use instead JU.AU.newInt2(n);
\r
19 // 4. new int[] { 1, 2, 3 } has problems because it creates simply [ ] and not IntArray32
\r
23 // 1. Remember that EVERY number in JavaScript is a double -- doesn't matter if it is in IntArray32 or not.
\r
24 // 2. You cannot reliably use Java long, because doubles consume bits for the exponent which cannot be tested.
\r
25 // 3. Bit 31 of an integer is unreliable, since (int) -1 is now , not just 0zFFFFFFFF, and
\r
26 // FFFFFFFF + 1 = 100000000, not 0. In JavaScript, 0xFFFFFFFF is 4294967295, not -1.
\r
27 // This means that writeInt(b) will fail if b is negative. What you need is instead
\r
28 // writeInt((int)(b & 0xFFFFFFFFl) so that JavaScript knocks off the high bits explicitly.
\r
32 // 1. j2sRequireImport xxxx is needed if xxxx is a method used in a static function
\r
33 // 2. URL.getContent() is not supported. Use other means based on URL.toString()
\r
34 // 3. It is critical for performance to avoid any significant amount of function overloading.
\r
35 // In particular, methods such as xxx(int a, int b) and xxx(float a, int b) MUST be renamed,
\r
36 // because JavaScript only has Number, and there is absolutely no way to tell these apart.
\r
37 // It's probably bad Java programming, anyway.
\r
38 // 4. Calls to super(...) can almost always be avoided. These trigger the SAEM
\r
39 // (searchAndExecuteMethod) call, and it is very destructive to performance.
\r
40 // Just find another way to do it.
\r
42 // NOTES by Bob Hanson:
\r
44 // J2S class changes:
\r
46 // BH 7/19/2015 6:18:17 PM added os.name, line.separator, etc. to System.getProperty()
\r
47 // BH 7/19/2015 5:39:10 PM added java.lang.System = System
\r
48 // BH 7/19/2015 10:33:10 AM fix for SAEM equating "null" with number or boolean
\r
49 // BH 7/18/2015 6:08:05 PM for Jmol I was able to remove the $private/$fx business, but now
\r
50 // I see that in general that cannot be done. Thinking about a strategy...
\r
51 // BH 7/18/2015 4:43:38 PM better handling of TypeError and InternalError for e.getMessage() and e.getStackTrace()
\r
52 // BH 7/17/2015 11:51:15 AM adds class.getResource(name) and class.getResourceAsStream(name)
\r
53 // BH 7/16/2015 7:56:49 PM general instantiation using any constructor (in Java here):
\r
54 // BH x = class.forName("my.class.name").newInstance()
\r
56 // BH x = class.forName("my.class.name").getConstructor(String.class,String.class).newInstance(new Object[] {"test", "now"})
\r
57 // BH 7/15/2015 11:34:58 PM adding System.lineSeparator()
\r
58 // BH 7/15/2015 7:32:41 AM adding class.getCanonicalName == getName
\r
59 // BH 5/31/2015 5:38:14 PM NPEExceptionPredicate fix
\r
60 // BH 4/25/2015 9:16:12 AM SAEM misrepresnting Number as Object in parameters and Integer as Number
\r
61 // BH 4/24/2015 7:32:54 AM Object.hashCode() and System.getIdentityHashCode() fail. changed to: return this._$hashcode || (this._$hashcode = ++Clazz._hashCode)
\r
62 // BH 4/23/2015 9:08:59 AM Clazz.instanceOf(a, b) needs to check for a == b.
\r
63 // BH 4/23/2015 9:08:59 AM xx.getContentType() is nonfunctional. Array.newInstance now defines a wrapper for .getClass().getComponentType() that works
\r
64 // BH 4/12/2015 11:48:03 AM added Clazz.getStackTrace(-n) -- reports actual parameter values for n levels
\r
65 // BH 4/10/2015 8:23:05 AM adding Int32Array.prototype.clone and Float64.prototype.clone
\r
66 // BH 4/5/2015 8:12:57 AM refactoring j2slib (this file) to make private functions really private using var
\r
67 // BH 4/3/2015 6:14:34 AM adding anonymous local "ClazzLoader" (Clazz._Loader) --> "_Loader"
\r
68 // BH 4/3/2015 6:14:34 AM adding Clazz._Loader._classPending, Clazz._Loader._classCount
\r
69 // BH 4/3/2015 6:14:34 AM adding Clazz._Loader._checkLoad
\r
70 // -- forces asynchronous class loading
\r
71 // -- builds Clazz._Loader._classPending and Clazz._classCount
\r
72 // -- allows reporting
\r
74 // BH 3/24/2015 4:11:26 AM better file load failure message in _Loader.evaluate
\r
75 // BH 2/28/2015 7:30:25 AM corrects newIntArray32() and newArray() for pre-defined arrays
\r
76 // int[] a = new int[] {1,2,3,343};
\r
77 // int[][] b = new int[][] {new int[]{4,5},new int[]{5,6}};
\r
79 // BH 9/29/2014 11:34:19 PM removing support for getClass().isArray()
\r
80 // BH 8/29/2014 9:15:57 AM total reworking of Java2Script in preparation for all-asynchronous loading
\r
81 // (currently sync loading is only for
\r
82 // LOAD command and load() function without ASYNC
\r
84 // see JSmol.js and Jmol._isAsync flag
\r
85 // BH 5/11/2015 5:58:42 AM adding __signatures for debugging SAEM issues
\r
86 // BH 3/29/2015 8:12:44 PM System.getProperty(x, "") does not return ""
\r
87 // BH 8/23/2014 10:04:19 AM cleaning up a few general methods; Clazz.removeArrayItem
\r
88 // BH 6/1/2014 10:58:46 AM fix for Clazz.isAP() not working
\r
89 // BH 5/26/2014 5:19:29 PM removing superConstructor call in creating Enum constants
\r
90 // BH 4/1/2014 7:55:54 PM removing all $fz references and instances where sub/super classes have same private function names
\r
91 // BH 4/1/2014 4:47:30 PM all $_X removed; this is taken care of by Google Closure Compiler
\r
92 // BH 4/1/2014 6:40:08 AM removing ClassLoader -- equals Clazz._Loader
\r
93 // BH 4/1/2014 6:40:08 AM removing ClassLoaderProgressMonitor -- equals _LoaderProgressMonitor
\r
94 // 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"
\r
95 // 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
\r
97 // BH 1/30/2014 12:54:22 PM gave all field variables prefix underscore. This allows Google Closure Compiler to skip them.
\r
98 // BH 12/3/2013 3:39:57 PM window["j2s.lib"].base implemented
\r
99 // BH 12/1/2013 5:34:21 AM removed _LoaderProgressMonitor.initialize and all Clazz.event business; handled by Jmol.clearVars()
\r
100 // BH 11/30/2013 12:43:58 PM adding Clazz.arrayIs() -- avoids Number.constructor.toString() infinite recursion
\r
101 // BH 11/29/2013 6:33:51 AM adding Clazz._profiler -- reports use of SAEM
\r
102 // BH 11/10/2013 9:02:20 AM fixing fading in MSIE
\r
103 // BH 11/3/2013 7:21:39 AM additional wrapping functions for better compressibility
\r
104 // BH 10/30/2013 8:10:58 AM added getClass().getResource() -- returning a relative string, not a URL
\r
105 // BH 10/30/2013 6:43:00 AM removed second System def and added System.$props and default System.property "line.separator"
\r
106 // BH 6/15/2013 8:02:07 AM corrections to Class.isAS to return true if first element is null
\r
107 // BH 6/14/2013 4:41:09 PM corrections to Clazz.isAI and related methods to include check for null object
\r
108 // BH 3/17/2013 11:54:28 AM adds stackTrace for ERROR
\r
110 // BH 3/13/2013 6:58:26 PM adds Clazz.clone(me) for BS clone
\r
111 // BH 3/12/2013 6:30:53 AM fixes Clazz.exceptionOf for ERROR condition trapping
\r
112 // BH 3/2/2013 9:09:53 AM delete globals c$ and $fz
\r
113 // BH 3/2/2013 9:10:45 AM optimizing defineMethod using "look no further" "@" parameter designation (see "\\@" below -- removed 3/23/13)
\r
114 // BH 2/27/2013 optimizing Clazz.getParamsType for common cases () and (Number)
\r
115 // BH 2/27/2013 optimizing SAEM delegation for hashCode and equals -- disallows overloading of equals(Object)
\r
117 // BH 2/23/2013 found String.replaceAll does not work -- solution was to never call it.
\r
118 // BH 2/9/2013 9:18:03 PM Int32Array/Float64Array fixed for MSIE9
\r
119 // BH 1/25/2013 1:55:31 AM moved package.js from j2s/java to j2s/core
\r
120 // BH 1/17/2013 4:37:17 PM String.compareTo() added
\r
121 // BH 1/17/2013 4:52:22 PM Int32Array and Float64Array may not have .prototype.sort method
\r
122 // BH 1/16/2013 6:20:34 PM Float64Array not available in Safari 5.1
\r
123 // BH 1/14/2013 11:28:58 PM Going to all doubles in JavaScript (Float64Array, not Float32Array)
\r
124 // so that (new float[] {13.48f})[0] == 13.48f, effectively
\r
126 // BH 1/14/2013 12:53:41 AM Fix for Opera 10 not loading any files
\r
127 // BH 1/13/2013 11:50:11 PM Fix for MSIE not loading (nonbinary) files locally
\r
129 // BH 12/1/2012 9:52:26 AM Compiler note: Thread.start() cannot be executed within the constructor;
\r
131 // BH 11/24/2012 11:08:39 AM removed unneeded sections
\r
132 // BH 11/24/2012 10:23:22 AM all XHR uses sync loading (_Loader.setLoadingMode)
\r
133 // BH 11/21/2012 7:30:06 PM if (base) map["@" + pkg] = base; critical for multiple applets
\r
135 // BH 10/8/2012 3:27:41 PM if (clazzName.indexOf("Array") >= 0) return "Array"; in Clazz.getClassName for function
\r
136 // BH removed Clazz.ie$plit = "\\2".split (/\\/).length == 1; unnecessary; using RegEx slows process significantly in all browsers
\r
137 // BH 10/6/12 added Int32Array, Float32Array, newArrayBH, upgraded java.lang and java.io
\r
138 // BH added Integer.bitCount in core.z.js
\r
139 // BH changed alert to Clazz.alert in java.lang.Class.js *.ClassLoader.js, java.lang.thread.js
\r
140 // BH removed toString from innerFunctionNames due to infinite recursion
\r
141 // BH note: Logger.error(null, e) does not work -- get no constructor for (String) (TypeError)
\r
142 // BH added j2s.lib.console
\r
143 // BH allowed for alias="."
\r
144 // BH removed alert def --> Clazz.alert
\r
145 // BH added wrapper at line 2856
\r
146 // BH newArray fix at line 2205
\r
147 // BH System.getProperty fix at line 6693
\r
148 // BH added Enum .value() method at line 2183
\r
149 // BH added System.getSecurityManager() at end
\r
150 // BH added String.contains() at end
\r
151 // BH added System.gc() at end
\r
152 // BH added Clazz.exceptionOf = updated
\r
153 // BH added String.getBytes() at end
\r
156 LoadClazz = function() {
\r
158 // BH This is the ONLY global used in J2S now. I do not think it is necessary,
\r
159 // but it is created by the compiler, and I have not found a work-around.
\r
160 // it is used as a local variable in class definitions to point to the
\r
161 // current method. See Clazz.p0p and Clazz.pu$h
\r
165 if (!window["j2s.clazzloaded"])
\r
166 window["j2s.clazzloaded"] = false;
\r
168 if (window["j2s.clazzloaded"])return;
\r
170 window["j2s.clazzloaded"] = true;
\r
172 window["j2s.object.native"] = true;
\r
176 /* http://j2s.sf.net/ *//******************************************************************************
\r
177 * Copyright (c) 2007 java2script.org and others.
\r
178 * All rights reserved. This program and the accompanying materials
\r
179 * are made available under the terms of the Eclipse Public License v1.0
\r
180 * which accompanies this distribution, and is available at
\r
181 * http://www.eclipse.org/legal/epl-v10.html
\r
184 * Zhou Renjian - initial API and implementation
\r
185 *****************************************************************************/
\r
187 * @author zhou renjian
\r
188 * @create Nov 5, 2005
\r
193 * Class Clazz. All the methods are static in this class.
\r
196 /*Class = */ Clazz = {
\r
200 ;(function(Clazz, Jmol) {
\r
202 var __debuggingBH = false;
\r
203 var _globals = ["j2s.clazzloaded", "j2s.object.native"];
\r
204 Clazz.setGlobal = function(a, v) {
\r
209 Clazz.getGlobals = function() {
\r
210 return _globals.sort().join("\n");
\r
213 Clazz.setConsoleDiv = function(d) {
\r
214 window["j2s.lib"] && (window["j2s.lib"].console = d);
\r
217 // BH Clazz.getProfile monitors exactly what is being delegated with SAEM,
\r
218 // which could be a bottle-neck for function calling.
\r
219 // This is critical for performance optimization.
\r
221 // Jmol.getProfile()
\r
223 var _profile = (window["j2s.doProfile"] && self.JSON ? {} : null);
\r
225 NullObject = function () {};
\r
228 Clazz._supportsNativeObject = window["j2s.object.native"];
\r
230 if (Clazz._supportsNativeObject) {
\r
231 Clazz._O = function () {};
\r
232 Clazz._O.__CLASS_NAME__ = "Object";
\r
233 Clazz._O["getClass"] = function () { return Clazz._O; };
\r
238 Clazz.Console = {};
\r
239 Clazz.dateToString = Date.prototype.toString;
\r
240 Clazz._hashCode = 0;
\r
242 var addProto = function(proto, name, func) {
\r
243 return proto[name] = func;
\r
246 ;(function(proto) {
\r
247 addProto(proto, "equals", function (obj) {
\r
248 return this == obj;
\r
251 addProto(proto, "hashCode", function () {
\r
253 return this._$hashcode || (this._$hashcode = ++Clazz._hashCode)
\r
257 return this.toString ().hashCode ();
\r
260 for (var s in this) {
\r
263 return str.hashCode ();
\r
267 addProto(proto, "getClass", function () { return Clazz.getClass (this); });
\r
269 addProto(proto, "clone", function () { return Clazz.clone(this); });
\r
271 Clazz.clone = function(me) {
\r
272 // BH allows @j2sNative access without super constructor
\r
273 var o = new me.constructor();
\r
274 for (var i in me) {
\r
280 * Methods for thread in Object
\r
282 addProto(proto, "finalize", function () {});
\r
283 addProto(proto, "notify", function () {});
\r
284 addProto(proto, "notifyAll", function () {});
\r
285 addProto(proto, "wait", function () {});
\r
286 addProto(proto, "to$tring", Object.prototype.toString);
\r
287 addProto(proto, "toString", function () { return (this.__CLASS_NAME__ ? "[" + this.__CLASS_NAME__ + " object]" : this.to$tring.apply(this, arguments)); });
\r
288 Clazz._extendedObjectMethods = [ "equals", "hashCode", "getClass", "clone", "finalize", "notify", "notifyAll", "wait", "to$tring", "toString" ];
\r
290 })(Clazz._O.prototype);
\r
292 Clazz.extendJO = function(c, name) {
\r
294 c.__CLASS_NAME__ = c.prototype.__CLASS_NAME__ = name;
\r
295 if (Clazz._supportsNativeObject) {
\r
296 for (var i = 0; i < Clazz._extendedObjectMethods.length; i++) {
\r
297 var p = Clazz._extendedObjectMethods[i];
\r
298 addProto(c.prototype, p, Clazz._O.prototype[p]);
\r
304 * Try to fix bug on Safari
\r
306 //InternalFunction = Object;
\r
308 Clazz.extractClassName = function(clazzStr) {
\r
309 // [object Int32Array]
\r
310 var clazzName = clazzStr.substring (1, clazzStr.length - 1);
\r
311 return (clazzName.indexOf("Array") >= 0 ? "Array" // BH -- for Float64Array and Int32Array
\r
312 : clazzName.indexOf ("object ") >= 0 ? clazzName.substring (7) // IE
\r
316 * Return the class name of the given class or object.
\r
318 * @param clazzHost given class or object
\r
319 * @return class name
\r
322 Clazz.getClassName = function (obj) {
\r
324 return "NullObject";
\r
325 if (obj instanceof Clazz.CastedNull)
\r
326 return obj.clazzName;
\r
327 switch(typeof obj) {
\r
333 // Always treat the constant string as String object.
\r
334 // This will be compatiable with Java String instance.
\r
337 if (obj.__CLASS_NAME__)
\r
338 return (arguments[1] ? obj.__CLASS_NAME__ : "Class"); /* user defined class name */
\r
339 var s = obj.toString();
\r
340 var idx0 = s.indexOf("function");
\r
342 return (s.charAt(0) == '[' ? Clazz.extractClassName(s) : s.replace(/[^a-zA-Z0-9]/g, ''));
\r
343 var idx1 = idx0 + 8;
\r
344 var idx2 = s.indexOf ("(", idx1);
\r
347 s = s.substring (idx1, idx2);
\r
348 if (s.indexOf("Array") >= 0)
\r
350 s = s.replace (/^\s+/, "").replace (/\s+$/, "");
\r
351 return (s == "anonymous" || s == "" ? "Function" : s);
\r
353 if (obj.__CLASS_NAME__) // user defined class name
\r
354 return obj.__CLASS_NAME__;
\r
355 if (!obj.constructor)
\r
356 return "Object"; // For HTML Element in IE
\r
357 if (!obj.constructor.__CLASS_NAME__) {
\r
358 if (obj instanceof Number)
\r
360 if (obj instanceof Boolean)
\r
362 if (obj instanceof Array)
\r
364 var s = obj.toString();
\r
365 // "[object Int32Array]"
\r
366 if (s.charAt(0) == '[')
\r
367 return Clazz.extractClassName(s);
\r
369 return Clazz.getClassName (obj.constructor, true);
\r
371 // some new, unidentified class
\r
375 * Return the class of the given class or object.
\r
377 * @param clazzHost given class or object
\r
378 * @return class name
\r
381 Clazz.getClass = function (clazzHost) {
\r
383 return Clazz._O; // null/undefined is always treated as Object
\r
384 if (typeof clazzHost == "function")
\r
387 if (clazzHost instanceof Clazz.CastedNull) {
\r
388 clazzName = clazzHost.clazzName;
\r
390 switch (typeof clazzHost) {
\r
394 if (!clazzHost.__CLASS_NAME__)
\r
395 return (clazzHost.constructor || Clazz._O);
\r
396 clazzName = clazzHost.__CLASS_NAME__;
\r
399 return clazzHost.constructor;
\r
402 return Clazz.evalType(clazzName, true);
\r
407 var checkInnerFunction = function (hostSuper, funName) {
\r
408 for (var k = 0; k < Clazz.innerFunctionNames.length; k++)
\r
409 if (funName == Clazz.innerFunctionNames[k] &&
\r
410 Clazz._innerFunctions[funName] === hostSuper[funName])
\r
415 var args4InheritClass = function () {};
\r
417 Clazz.inheritArgs = new args4InheritClass ();
\r
420 * Inherit class with "extends" keyword and also copy those static members.
\r
421 * Example, as in Java, if NAME is a static member of ClassA, and ClassB
\r
422 * extends ClassA then ClassB.NAME can be accessed in some ways.
\r
424 * @param clazzThis child class to be extended
\r
425 * @param clazzSuper super class which is inherited from
\r
426 * @param objSuper super class instance
\r
429 Clazz.inheritClass = function (clazzThis, clazzSuper, objSuper) {
\r
430 //var thisClassName = Clazz.getClassName (clazzThis);
\r
431 for (var o in clazzSuper) {
\r
432 if (o != "b$" && o != "prototype" && o != "superClazz"
\r
433 && o != "__CLASS_NAME__" && o != "implementz"
\r
434 && !checkInnerFunction (clazzSuper, o)) {
\r
435 clazzThis[o] = clazzSuper[o];
\r
438 if (Clazz.unloadedClasses[Clazz.getClassName(clazzThis, true)]) {
\r
439 // Don't change clazzThis.protoype! Keep it!
\r
440 } else if (objSuper) {
\r
441 // ! Unsafe reference prototype to an instance!
\r
442 // Feb 19, 2006 --josson
\r
443 // OK for this reference to an instance, as this is anonymous instance,
\r
444 // which is not referenced elsewhere.
\r
446 clazzThis.prototype = objSuper;
\r
447 } else if (clazzSuper !== Number) {
\r
448 clazzThis.prototype = new clazzSuper (Clazz.inheritArgs);
\r
450 clazzThis.prototype = new Number ();
\r
452 clazzThis.superClazz = clazzSuper;
\r
454 * Is it necessary to reassign the class name?
\r
455 * Mar 10, 2006 --josson
\r
457 //clazzThis.__CLASS_NAME__ = thisClassName;
\r
458 clazzThis.prototype.__CLASS_NAME__ = clazzThis.__CLASS_NAME__;
\r
462 * Implementation of Java's keyword "implements".
\r
463 * As in JavaScript there are on "implements" keyword implemented, a property
\r
464 * of "implementz" is added to the class to record the interfaces the class
\r
467 * @param clazzThis the class to implement
\r
468 * @param interfacez Array of interfaces
\r
471 Clazz.implementOf = function (clazzThis, interfacez) {
\r
472 if (arguments.length >= 2) {
\r
473 if (!clazzThis.implementz)
\r
474 clazzThis.implementz = [];
\r
475 var impls = clazzThis.implementz;
\r
476 if (arguments.length == 2) {
\r
477 if (typeof interfacez == "function") {
\r
478 impls.push(interfacez);
\r
479 copyProperties(clazzThis, interfacez);
\r
480 } else if (interfacez instanceof Array) {
\r
481 for (var i = 0; i < interfacez.length; i++) {
\r
482 impls.push(interfacez[i]);
\r
483 copyProperties(clazzThis, interfacez[i]);
\r
487 for (var i = 1; i < arguments.length; i++) {
\r
488 impls.push(arguments[i]);
\r
489 copyProperties(clazzThis, arguments[i]);
\r
496 * Copy members of interface
\r
499 var copyProperties = function(clazzThis, clazzSuper) {
\r
500 for (var o in clazzSuper)
\r
502 && o != "prototype" && o != "superClazz"
\r
503 && o != "__CLASS_NAME__" && o != "implementz"
\r
504 && (typeof clazzSuper[o] != "function" || !checkInnerFunction(clazzSuper, o)))
\r
505 clazzThis[o] = clazzThis.prototype[o] = clazzSuper[o];
\r
509 * TODO: More should be done for interface's inheritance
\r
512 Clazz.extendInterface = Clazz.implementOf;
\r
515 Clazz.equalsOrExtendsLevel = function (clazzThis, clazzAncestor) {
\r
516 if (clazzThis === clazzAncestor)
\r
518 if (clazzThis.implementz) {
\r
519 var impls = clazzThis.implementz;
\r
520 for (var i = 0; i < impls.length; i++) {
\r
521 var level = Clazz.equalsOrExtendsLevel (impls[i], clazzAncestor);
\r
530 Clazz.getInheritedLevel = function (clazzTarget, clazzBase) {
\r
531 if (clazzTarget === clazzBase)
\r
533 var isTgtStr = (typeof clazzTarget == "string");
\r
534 if (isTgtStr && ("void" == clazzTarget || "unknown" == clazzTarget))
\r
536 var isBaseStr = (typeof clazzBase == "string");
\r
537 if (isBaseStr && ("void" == clazzBase || "unknown" == clazzBase))
\r
539 if (clazzTarget === (isTgtStr ? "NullObject" : NullObject)) {
\r
540 switch (clazzBase) {
\r
553 clazzTarget = Clazz.evalType(clazzTarget);
\r
555 clazzBase = Clazz.evalType(clazzBase);
\r
556 if (!clazzBase || !clazzTarget)
\r
559 var zzalc = clazzTarget; // zzalc <--> clazz
\r
560 while (zzalc !== clazzBase && level < 10) {
\r
561 /* maybe clazzBase is interface */
\r
562 if (zzalc.implementz) {
\r
563 var impls = zzalc.implementz;
\r
564 for (var i = 0; i < impls.length; i++) {
\r
565 var implsLevel = Clazz.equalsOrExtendsLevel (impls[i], clazzBase);
\r
566 if (implsLevel >= 0)
\r
567 return level + implsLevel + 1;
\r
570 zzalc = zzalc.superClazz;
\r
572 return (clazzBase === Object || clazzBase === Clazz._O ?
\r
573 // getInheritedLevel(String, CharSequence) == 1
\r
574 // getInheritedLevel(String, Object) == 1.5
\r
575 // So if both #test(CharSequence) and #test(Object) existed,
\r
576 // #test("hello") will correctly call #test(CharSequence)
\r
577 // instead of #test(Object).
\r
578 level + 1.5 // 1.5! Special!
\r
587 * Implements Java's keyword "instanceof" in JavaScript's way.
\r
588 * As in JavaScript part of the object inheritance is implemented in only-
\r
591 * @param obj the object to be tested
\r
592 * @param clazz the class to be checked
\r
593 * @return whether the object is an instance of the class
\r
596 Clazz.instanceOf = function (obj, clazz) {
\r
597 // allows obj to be a class already, from arrayX.getClass().isInstance(y)
\r
598 return (obj != null && clazz && (obj == clazz || obj instanceof clazz || Clazz.getInheritedLevel(Clazz.getClassName(obj), clazz) >= 0));
\r
602 * Call super method of the class.
\r
603 * The same effect as Java's expression:
\r
604 * <code> super.* () </code>
\r
606 * @param objThis host object
\r
607 * @param clazzThis class of declaring method scope. It's hard to determine
\r
608 * which super class is right class for "super.*()" call when it's in runtime
\r
609 * environment. For example,
\r
610 * 1. ClasssA has method #run()
\r
611 * 2. ClassB extends ClassA overriding method #run() with "super.run()" call
\r
612 * 3. ClassC extends ClassB
\r
613 * 4. objC is an instance of ClassC
\r
614 * Now we have to decide which super #run() method is to be invoked. Without
\r
615 * explicit clazzThis parameter, we only know that objC.getClass() is ClassC
\r
616 * and current method scope is #run(). We do not known we are in scope
\r
617 * ClassA#run() or scope of ClassB#run(). if ClassB is given, Clazz can search
\r
618 * all super methods that are before ClassB and get the correct super method.
\r
619 * This is the reason why there must be an extra clazzThis parameter.
\r
620 * @param funName method name to be called
\r
621 * @param funParams Array of method parameters
\r
624 Clazz.superCall = function (objThis, clazzThis, funName, funParams) {
\r
627 var clazzFun = objThis[funName];
\r
629 if (clazzFun.claxxOwner) {
\r
630 // claxxOwner is a mark for methods that is single.
\r
631 if (clazzFun.claxxOwner !== clazzThis) {
\r
632 // This is a single method, call directly!
\r
636 } else if (!clazzFun.stacks && !(clazzFun.lastClaxxRef
\r
637 && clazzFun.lastClaxxRef.prototype[funName]
\r
638 && clazzFun.lastClaxxRef.prototype[funName].stacks)) { // super.toString
\r
640 } else { // normal wrapped method
\r
641 var stacks = clazzFun.stacks;
\r
643 stacks = clazzFun.lastClaxxRef.prototype[funName].stacks;
\r
644 for (i = stacks.length; --i >= 0;) {
\r
646 * Once super call is computed precisely, there are no need
\r
647 * to calculate the inherited level but just an equals
\r
650 //var level = Clazz.getInheritedLevel (clazzThis, stacks[i]);
\r
651 if (clazzThis === stacks[i]) { // level == 0
\r
653 fx = stacks[--i].prototype[funName];
\r
656 * Will this case be reachable?
\r
658 * Should never reach here if all things are converted
\r
661 fx = stacks[0].prototype[funName]["\\unknown"];
\r
664 } else if (Clazz.getInheritedLevel (clazzThis, stacks[i]) > 0) {
\r
665 fx = stacks[i].prototype[funName];
\r
668 } // end of for loop
\r
669 } // end of normal wrapped method
\r
670 } // end of clazzFun
\r
672 if (funName != "construct") {
\r
673 Clazz.alert (["j2slib","no class found",(funParams).typeString])
\r
674 newMethodNotFoundException(objThis, clazzThis, funName,
\r
675 Clazz.getParamsType(funParams).typeString);
\r
677 /* there are members which are initialized out of the constructor */
\r
678 /* No super constructor! */
\r
681 /* there are members which are initialized out of the constructor */
\r
682 if (i == 0 && funName == "construct") {
\r
683 var ss = clazzFun.stacks;
\r
684 if (ss && !ss[0].superClazz && ss[0].con$truct)
\r
685 ss[0].con$truct.apply (objThis, []);
\r
687 /*# {$no.debug.support} >>x #*/
\r
688 /* not used in Jmol
\r
689 if (Clazz.tracingCalling) {
\r
690 var caller = arguments.callee.caller;
\r
691 if (caller === Clazz.superConstructor) {
\r
692 caller = caller.arguments.callee.caller;
\r
694 Clazz._callingStackTraces.push(new Clazz.callingStack (caller, clazzThis));
\r
695 var ret = fx.apply (objThis, (funParams == null) ? [] : funParams);
\r
696 Clazz._callingStackTraces.pop();
\r
701 return fx.apply (objThis, funParams || []);
\r
705 * Call super constructor of the class.
\r
706 * The same effect as Java's expression:
\r
707 * <code> super () </code>
\r
710 Clazz.superConstructor = function (objThis, clazzThis, funParams) {
\r
711 Clazz.superCall (objThis, clazzThis, "construct", funParams);
\r
712 /* If there are members which are initialized out of the constructor */
\r
713 if (clazzThis.con$truct) {
\r
714 clazzThis.con$truct.apply (objThis, []);
\r
719 * Class for null with a given class as to be casted.
\r
720 * This class will be used as an implementation of Java's casting way.
\r
722 * <code> this.call ((String) null); </code>
\r
725 Clazz.CastedNull = function (asClazz) {
\r
727 if (asClazz instanceof String) {
\r
728 this.clazzName = asClazz;
\r
729 } else if (asClazz instanceof Function) {
\r
730 this.clazzName = Clazz.getClassName (asClazz, true);
\r
732 this.clazzName = "" + asClazz;
\r
735 this.clazzName = "Object";
\r
737 this.toString = function () {
\r
740 this.valueOf = function () {
\r
746 * API for Java's casting null.
\r
747 * @see Clazz.CastedNull
\r
749 * @param asClazz given class
\r
750 * @return an instance of class Clazz.CastedNull
\r
753 Clazz.castNullAs = function (asClazz) {
\r
754 return new Clazz.CastedNull (asClazz);
\r
757 /////////////////////////// Exception handling ////////////////////////////
\r
760 * Use to mark that the Throwable instance is created or not.
\r
762 * Called from java.lang.Throwable, as defined in JSmolJavaExt.js
\r
764 * The underscore is important - it tells the JSmol ANT task to NOT
\r
765 * turn this into Clazz_initializingException, because coreBottom2.js does
\r
766 * not include that call, and so Google Closure Compiler does not minify it.
\r
770 Clazz._initializingException = false;
\r
773 * BH: used in Throwable
\r
777 Clazz._callingStackTraces = [];
\r
780 * MethodException will be used as a signal to notify that the method is
\r
781 * not found in the current clazz hierarchy.
\r
784 var MethodException = function () {
\r
785 this.toString = function () {
\r
786 return "J2S MethodException";
\r
790 //var MethodNotFoundException = function () {
\r
791 // this.toString = function () {
\r
792 // return "J2S MethodNotFoundException";
\r
796 var _isNPEExceptionPredicate;
\r
798 /* super private */
\r
800 /* sgurin: native exception detection mechanism. Only NullPointerException detected and wrapped to java excepions */
\r
801 /** private utility method for creating a general regexp that can be used later
\r
802 * for detecting a certain kind of native exceptions. use with error messages like "blabla IDENTIFIER blabla"
\r
803 * @param msg String - the error message
\r
804 * @param spliterName String, must be contained once in msg
\r
805 * spliterRegex String, a string with the regexp literal for identifying the spitter in exception further error messages.
\r
807 // reproduce NullPointerException for knowing how to detect them, and create detector function Clazz._isNPEExceptionPredicate
\r
813 var _ex_reg = function(msg, spliterName, spliterRegex) {
\r
815 spliterRegex="[^\\s]+";
\r
816 var idx = msg.indexOf (spliterName),
\r
817 str = msg.substring (0, idx) + spliterRegex + msg.substring(idx + spliterName.length),
\r
818 regexp = new RegExp("^"+str+"$");
\r
821 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... "
\r
822 var idx1 = e.message.indexOf(":"), idx2 = e.message.indexOf(":", idx1+2);
\r
823 var _NPEMsgFragment = e.message.substr(idx1+1, idx2-idx1-20);
\r
824 _isNPEExceptionPredicate = function(e) { return e.message.indexOf(_NPEMsgFragment)!=-1; };
\r
825 } else if(navigator.userAgent.toLowerCase().indexOf("webkit")!=-1) { //webkit, google chrome prints the property name accessed.
\r
826 var _exceptionNPERegExp = _ex_reg(e.message, "hello");
\r
827 _isNPEExceptionPredicate = function(e) { return _exceptionNPERegExp.test(e.message); };
\r
828 } else {// ie, firefox and others print the name of the object accessed:
\r
829 var _exceptionNPERegExp = _ex_reg(e.message, "$$o$$");
\r
830 _isNPEExceptionPredicate = function(e) { return _exceptionNPERegExp.test(e.message); };
\r
836 * Implements Java's keyword "instanceof" in JavaScript's way **for exception objects**.
\r
838 * calls Clazz.instanceOf if e is a Java exception. If not, try to detect known native
\r
839 * exceptions, like native NullPointerExceptions and wrap it into a Java exception and
\r
840 * call Clazz.instanceOf again. if the native exception can't be wrapped, false is returned.
\r
842 * @param obj the object to be tested
\r
843 * @param clazz the class to be checked
\r
844 * @return whether the object is an instance of the class
\r
847 Clazz.exceptionOf = function(e, clazz) {
\r
848 if(e.__CLASS_NAME__)
\r
849 return Clazz.instanceOf(e, clazz);
\r
850 if (!e.getMessage) {
\r
851 e.getMessage = function() {return "" + this};
\r
853 if (!e.printStackTrace) {
\r
854 e.printStackTrace = function(){};
\r
855 alert(e + " try/catch path:" + Clazz.getStackTrace(-10));
\r
857 if(clazz == Error) {
\r
858 if (("" + e).indexOf("Error") < 0)
\r
860 System.out.println (Clazz.getStackTrace());
\r
862 // everything here is a Java Exception, not a Java Error
\r
864 return (clazz == Exception || clazz == Throwable
\r
865 || clazz == NullPointerException && _isNPEExceptionPredicate(e));
\r
869 * BH need to limit this, as JavaScript call stack may be recursive
\r
871 Clazz.getStackTrace = function(n) {
\r
873 // updateNode and updateParents cause infinite loop here
\r
875 var c = arguments.callee;
\r
876 var showParams = (n < 0);
\r
879 for (var i = 0; i < n; i++) {
\r
880 if (!(c = c.caller))
\r
882 var sig = (c.toString ? c.toString().substring(0, c.toString().indexOf("{")) : "<native method>");
\r
883 s += i + " " + (c.exName ? (c.claxxOwner ? c.claxxOwner.__CLASS_NAME__ + "." : "") + c.exName + sig.replace(/function /,""): sig) + "\n";
\r
884 if (c == c.caller) {
\r
885 s += "<recursing>\n";
\r
889 var args = c.arguments;
\r
890 for (var j = 0; j < args.length; j++) {
\r
891 var sa = "" + args[j];
\r
892 if (sa.length > 60)
\r
893 sa = sa.substring(0, 60) + "...";
\r
894 s += " args[" + j + "]=" + sa.replace(/\s+/g," ") + "\n";
\r
901 ///////////////////// method creation ////////////////////////////////
\r
904 * Make constructor for the class with the given function body and parameters
\r
907 * @param clazzThis host class
\r
908 * @param funBody constructor body
\r
909 * @param funParams constructor parameters signature
\r
912 Clazz.makeConstructor = function (clazzThis, funBody, funParams) {
\r
913 Clazz.defineMethod (clazzThis, "construct", funBody, funParams);
\r
914 if (clazzThis.con$truct) {
\r
915 clazzThis.con$truct.index = clazzThis.con$truct.stacks.length;
\r
917 //clazzThis.con$truct = clazzThis.prototype.con$truct = null;
\r
921 * Override constructor for the class with the given function body and
\r
922 * parameters signature.
\r
924 * @param clazzThis host class
\r
925 * @param funBody constructor body
\r
926 * @param funParams constructor parameters signature
\r
929 Clazz.overrideConstructor = function (clazzThis, funBody, funParams) {
\r
930 Clazz.overrideMethod (clazzThis, "construct", funBody, funParams);
\r
931 if (clazzThis.con$truct) {
\r
932 clazzThis.con$truct.index = clazzThis.con$truct.stacks.length;
\r
934 //clazzThis.con$truct = clazzThis.prototype.con$truct = null;
\r
939 * Define method for the class with the given method name and method
\r
940 * body and method parameter signature.
\r
942 * @param clazzThis host class in which the method to be defined
\r
943 * @param funName method name
\r
944 * @param funBody function object, e.g function () { ... }
\r
945 * @param funParams paramether signature, e.g ["string", "number"]
\r
946 * @return method of the given name. The method may be funBody or a wrapper
\r
947 * of the given funBody.
\r
950 Clazz.defineMethod = function (clazzThis, funName, funBody, funParams) {
\r
951 if (Clazz.assureInnerClass)
\r
952 Clazz.assureInnerClass(clazzThis, funBody);
\r
953 funBody.exName = funName;
\r
954 var fpName = formatParameters(funParams);
\r
955 var proto = clazzThis.prototype;
\r
956 var f$ = proto[funName];
\r
957 if (Clazz._Loader._checkLoad)
\r
958 checkDuplicate(clazzThis, funName, fpName);
\r
959 if (!f$ || (f$.claxxOwner === clazzThis && f$.funParams == fpName)) {
\r
960 // property "funParams" will be used as a mark of only-one method
\r
961 funBody.funParams = fpName;
\r
962 funBody.claxxOwner = clazzThis;
\r
963 funBody.exClazz = clazzThis; // make it traceable
\r
964 return addProto(proto, funName, funBody);
\r
966 // we have found a duplicate
\r
968 var oldStacks = f$.stacks;
\r
970 /* method is not defined by Clazz.defineMethod () */
\r
973 if (f$.claxxOwner) {
\r
974 oldStacks[0] = oldFun.claxxOwner;
\r
978 * Method that is already defined in super class will be overridden
\r
979 * with a new proxy method with class hierarchy stored in a stack.
\r
980 * That is to say, the super methods are lost in this class' proxy
\r
982 * When method are being called, methods defined in the new proxy
\r
983 * method will be searched through first. And if no method fitted,
\r
984 * it will then try to search method in the super class stacks.
\r
986 if (!f$.stacks || f$.claxxReference !== clazzThis) {
\r
987 //Generate a new delegating method for the class
\r
989 var delegate = function () {
\r
990 return searchAndExecuteMethod(id, this, arguments.callee.claxxReference, arguments.callee.methodName, arguments);
\r
992 delegate.methodName = funName;
\r
993 delegate.claxxReference = clazzThis;
\r
994 f$ = addProto(proto, funName, delegate);
\r
995 // Keep the class inheritance stacks
\r
997 for (var i = 0; i < oldStacks.length; i++)
\r
998 arr[i] = oldStacks[i];
\r
1001 var ss = f$.stacks;
\r
1002 if (findArrayItem(ss, clazzThis) < 0) ss.push(clazzThis);
\r
1005 if (oldFun.claxxOwner === clazzThis) {
\r
1006 f$[oldFun.funParams] = oldFun;
\r
1007 oldFun.claxxOwner = null;
\r
1008 // property "funParams" will be used as a mark of only-one method
\r
1009 oldFun.funParams = null; // null ? safe ? // safe for != null
\r
1010 } else if (!oldFun.claxxOwner) {
\r
1012 * The function is not defined Clazz.defineMethod ().
\r
1013 * Try to fixup the method ...
\r
1014 * As a matter of lost method information, I just suppose
\r
1015 * the method to be fixed is with void parameter!
\r
1017 f$["\\unknown"] = oldFun;
\r
1020 funBody.exClazz = clazzThis; // make it traceable
\r
1021 f$[fpName] = funBody;
\r
1025 duplicatedMethods = {};
\r
1027 var checkDuplicate = function(clazzThis, funName, fpName) {
\r
1028 var proto = clazzThis.prototype;
\r
1029 var f$ = proto[funName];
\r
1030 if (f$ && (f$.claxxOwner || f$.claxxReference) === clazzThis) {
\r
1031 key = clazzThis.__CLASS_NAME__ + "." + funName + fpName;
\r
1032 var m = duplicatedMethods[key];
\r
1034 var s = "Warning! Duplicate method found for " + key;
\r
1035 System.out.println(s);
\r
1037 duplicatedMethods[key] = m + 1;
\r
1039 duplicatedMethods[key] = 1;
\r
1044 Clazz.showDuplicates = function(quiet) {
\r
1046 var a = duplicatedMethods;
\r
1048 for (var key in a)
\r
1050 s += a[key] + "\t" + key + "\n";
\r
1053 s = "Duplicates: " + n + "\n\n" + s;
\r
1054 System.out.println(s);
\r
1059 var findArrayItem = function(arr, item) {
\r
1061 for (var i = arr.length; --i >= 0;)
\r
1062 if (arr[i] === item)
\r
1067 var removeArrayItem = function(arr, item) {
\r
1068 var i = findArrayItem(arr, item);
\r
1070 var n = arr.length - 1;
\r
1071 for (; i < n; i++)
\r
1072 arr[i] = arr[i + 1];
\r
1079 * Other developers may need to extend this formatParameters method
\r
1080 * to deal complicated situation.
\r
1083 var formatParameters = function (funParams) {
\r
1084 return (funParams ? funParams.replace (/~([NABSO])/g,
\r
1085 function ($0, $1) {
\r
1099 }).replace (/\s+/g, "").replace (/^|,/g, "\\").replace (/\$/g, "org.eclipse.s") : "\\void");
\r
1103 * Override the existed methods which are in the same name.
\r
1104 * Overriding methods is provided for the purpose that the JavaScript
\r
1105 * does not need to search the whole hierarchied methods to find the
\r
1106 * correct method to execute.
\r
1107 * Be cautious about this method. Incorrectly using this method may
\r
1108 * break the inheritance system.
\r
1110 * @param clazzThis host class in which the method to be defined
\r
1111 * @param funName method name
\r
1112 * @param funBody function object, e.g function () { ... }
\r
1113 * @param funParams paramether signature, e.g ["string", "number"]
\r
1116 Clazz.overrideMethod = function(clazzThis, funName, funBody, funParams) {
\r
1117 if (Clazz.assureInnerClass) Clazz.assureInnerClass (clazzThis, funBody);
\r
1118 funBody.exName = funName;
\r
1119 var fpName = formatParameters(funParams);
\r
1120 if (Clazz._Loader._checkLoad)
\r
1121 checkDuplicate(clazzThis, funName, fpName);
\r
1123 * Replace old methods with new method. No super methods are kept.
\r
1125 funBody.funParams = fpName;
\r
1126 funBody.claxxOwner = clazzThis;
\r
1127 return addProto(clazzThis.prototype, funName, funBody);
\r
1130 ////////////// Overridden and Overloaded Java Method Handling //////////////////
\r
1131 // SAEM (SearchAndExecuteMethod)
\r
1136 * BH Clazz.getProfile monitors exactly what is being delegated with SAEM,
\r
1137 * which could be a bottle-neck for function calling.
\r
1138 * This is critical for performance optimization.
\r
1141 var __signatures = "";
\r
1143 Clazz.getProfile = function() {
\r
1147 for (var i in _profile) {
\r
1148 var n = "" + _profile[i];
\r
1149 l.push(" ".substring(n.length) + n + "\t" + i);
\r
1151 s = l.sort().reverse().join("\r\n");
\r
1154 return s + __signatures;
\r
1157 var addProfile = function(c, f, p, id) {
\r
1158 var s = id + " " + c.__CLASS_NAME__ + " " + f + " ";// + JSON.stringify(p);
\r
1159 if (__signatures.indexOf(s) < 0)
\r
1160 __signatures += s + "\n";
\r
1161 _profile[s] || (_profile[s] = 0);
\r
1166 * Called also by Throwable
\r
1169 Clazz.getParamsType = function (funParams) {
\r
1170 // bh: optimization here for very common cases
\r
1171 var n = funParams.length;
\r
1174 var params = ["void"];
\r
1175 params.typeString = "\\void";
\r
1178 // BH just so common
\r
1179 switch (typeof obj) {
\r
1181 var params = ["n"];
\r
1182 params.typeString = "\\n";
\r
1185 var params = ["b"];
\r
1186 params.typeString = "\\b";
\r
1192 params.hasCastedNull = false;
\r
1194 for (var i = 0; i < n; i++) {
\r
1195 params[i] = Clazz.getClassName (funParams[i]);
\r
1196 if (funParams[i] instanceof Clazz.CastedNull) {
\r
1197 params.hasCastedNull = true;
\r
1201 params.typeString = "\\" + params.join ('\\');
\r
1208 //var SAEMarray = [];
\r
1210 * BH: OK, this was an idea that doesn't work. The idea was to tag SAEM calls
\r
1211 * and then refer back to an array. But the id number cannot be put in the right place.
\r
1213 * Say we have this:
\r
1215 * StringBuffer sb = new StringBuffer();
\r
1216 * sb.append("").append(1);
\r
1218 * Here we have two different append methods to call. They are saved under two
\r
1219 * names: StringBuffer.prototype.append["\\String"]
\r
1220 * and StringBuffer.prototype.append["\\Number"]
\r
1222 * The job of generateDelegatingMethod is to discriminate between those two. We can do
\r
1223 * that, but the real issue is that we have to do that EVERY time a call is made.
\r
1224 * This is a problem that must be handled at compile time. There is no way to
\r
1225 * make .append("") to go one way the first time and another way the second time.
\r
1226 * What we need at run time is something like this:
\r
1228 * Clazz.delegate(sb.append,1,[""]) and Clazz.delegate(sb.append,2,[1])
\r
1229 * The we would be able to log those numbers at run time and refer to them.
\r
1231 * The only real way to avoid SAEM is:
\r
1233 * 1) to never call super() -- always call a differently named function in a superclass.
\r
1234 * 2) don't overload functions
\r
1240 * Search the given class prototype, find the method with the same
\r
1241 * method name and the same parameter signatures by the given
\r
1242 * parameters, and then run the method with the given parameters.
\r
1244 * @param objThis the current host object
\r
1245 * @param claxxRef the current host object's class
\r
1246 * @param fxName the method name
\r
1247 * @param funParams the given arguments
\r
1248 * @return the result of the specified method of the host object,
\r
1249 * the return maybe void.
\r
1250 * @throws MethodNotFoundException if no matched method is found
\r
1253 var searchAndExecuteMethod = function (id, objThis, claxxRef, fxName, args, _saem) {
\r
1255 // var fx = SAEMarray[id];
\r
1257 // return fx.apply(objThis, args);
\r
1261 fx = objThis[fxName];
\r
1262 var params = Clazz.getParamsType(args);
\r
1265 var s = "SAEM " + claxxRef.__CLASS_NAME__ + "." + fxName + "(" + params+ ")\n";
\r
1266 if (xxxSAEMlist.length > 300)xxxSAEMlist = "";
\r
1271 try {System.out.println(Clazz.getStackTrace(5))} catch (e){}
\r
1272 _profile && addProfile(claxxRef, fxName, params, id);
\r
1273 // Cache last matched method
\r
1274 if (fx.lastParams == params.typeString && fx.lastClaxxRef === claxxRef) {
\r
1276 if (params.hasCastedNull) {
\r
1277 methodParams = [];
\r
1278 // For Clazz.CastedNull instances, the type name is
\r
1279 // already used to indentified the method in searchMethod.
\r
1280 for (var k = 0; k < args.length; k++)
\r
1281 methodParams[k] = (args[k] instanceof Clazz.CastedNull ? null : args[k]);
\r
1283 // if (fx.lastMethod) SAEMarray[id] = fx.lastMethod;
\r
1284 methodParams = args;
\r
1286 return (fx.lastMethod ? fx.lastMethod.apply(objThis, methodParams) : null);
\r
1288 fx.lastParams = params.typeString;
\r
1289 fx.lastClaxxRef = claxxRef;
\r
1291 var stacks = fx.stacks;
\r
1293 stacks = claxxRef.prototype[fxName].stacks;
\r
1294 var length = stacks.length;
\r
1297 * Search the inheritance stacks to get the given class' function
\r
1299 var began = false; // began to search its super classes
\r
1300 for (var i = length; --i >= 0;) {
\r
1301 if (began || stacks[i] === claxxRef) {
\r
1303 * First try to search method within the same class scope
\r
1304 * with stacks[i] === claxxRef
\r
1306 var clazzFun = stacks[i].prototype[fxName];
\r
1307 var ret = tryToSearchAndExecute(id, fxName, objThis, clazzFun, params,
\r
1309 if (!(ret instanceof MethodException)) {
\r
1313 * As there are no such methods in current class, Clazz will try
\r
1314 * to search its super class stacks. Here variable began indicates
\r
1315 * that super searchi is began, and there is no need checking
\r
1316 * <code>stacks[i] === claxxRef</code>
\r
1321 if ("construct" == fxName) {
\r
1323 * For non existed constructors, just return without throwing
\r
1324 * exceptions. In Java codes, extending Object can call super
\r
1325 * default Object#constructor, which is not defined in JS.
\r
1329 newMethodNotFoundException(objThis, claxxRef,
\r
1330 fxName, params.typeString);
\r
1335 var tryToSearchAndExecute = function(id, fxName, objThis, clazzFun, params, args, fx, _ttsaem) {
\r
1337 var generic = true;
\r
1338 for (var fn in clazzFun) {
\r
1339 if (fn.charCodeAt(0) == 92) { // 92 == '\\'.charCodeAt (0)
\r
1340 var ps = fn.substring(1).split("\\");
\r
1341 (ps.length == params.length) && method.push(ps);
\r
1346 * When there is only one method in the class, use the args
\r
1347 * to identify the parameter type.
\r
1349 * AbstractCollection.remove (Object)
\r
1350 * AbstractList.remove (int)
\r
1351 * ArrayList.remove (int)
\r
1353 * Then calling #remove (Object) method on ArrayList instance will
\r
1354 * need to search up to the AbstractCollection.remove (Object),
\r
1355 * which contains only one method.
\r
1358 * See Clazz#defineMethod --Mar 10, 2006, josson
\r
1360 if (generic && fn == "funParams" && clazzFun.funParams) {
\r
1361 fn = clazzFun.funParams;
\r
1362 var ps = fn.substring(1).split ("\\");
\r
1363 (ps.length == params.length) && (method[0] = ps);
\r
1367 var debug = false;//(method.length > 1 && method.join().indexOf("Listen")< 0 && params.join().indexOf("Null") >= 0)
\r
1368 if (debug)alert(fxName + " -- " + method.join("|") + " -- searching for method with " + params)
\r
1369 if (method.length == 0 || !(method = searchMethod(method, params, debug)))
\r
1370 return new MethodException();
\r
1371 if (debug) alert("OK: \\" + method)
\r
1372 var f = (generic ? clazzFun : clazzFun["\\" + method]);
\r
1374 //{ /* Use the generic method */
\r
1376 * Will this case be reachable?
\r
1377 * March 4, 2006 josson
\r
1379 * Reachable for calling #remove (Object) method on
\r
1380 * ArrayList instance
\r
1381 * May 5, 2006 josson
\r
1383 var methodParams = null;
\r
1384 if (params.hasCastedNull) {
\r
1385 methodParams = [];
\r
1386 for (var k = 0; k < args.length; k++) {
\r
1387 if (args[k] instanceof Clazz.CastedNull) {
\r
1389 * For Clazz.CastedNull instances, the type name is
\r
1390 * already used to indentify the method in searchMethod.
\r
1392 methodParams[k] = null;
\r
1394 methodParams[k] = args[k];
\r
1398 methodParams = args;
\r
1400 fx.lastMethod = f;
\r
1401 //if (!params.hasCastedNull) SAEMarray[id] = f;
\r
1402 return f.apply(objThis, methodParams);
\r
1406 * Search the existed polymorphic methods to get the matched method with
\r
1407 * the given parameter types.
\r
1409 * @param existedMethods Array of string which contains method parameters
\r
1410 * @param paramTypes Array of string that is parameter type.
\r
1411 * @return string of method parameters seperated by "\\"
\r
1414 var searchMethod = function(roundOne, paramTypes, debug) {
\r
1416 // Filter out all the fitted methods for the given parameters
\r
1417 var roundTwo = [];
\r
1418 var len = roundOne.length;
\r
1419 for (var i = 0; i < len; i++) {
\r
1420 var fittedLevel = [];
\r
1421 var isFitted = true;
\r
1422 var len2 = roundOne[i].length;
\r
1423 for (var j = 0; j < len2; j++) {
\r
1425 fittedLevel[j] = Clazz.getInheritedLevel (paramTypes[j],
\r
1427 //if (debug)alert([paramTypes[j],fittedLevel[j],roundOne[i][j]])
\r
1428 if (fittedLevel[j] < 0) {
\r
1434 fittedLevel[paramTypes.length] = i; // Keep index for later use
\r
1435 roundTwo.push(fittedLevel);
\r
1438 if (roundTwo.length == 0)
\r
1440 // Find out the best method according to the inheritance.
\r
1441 var resultTwo = roundTwo;
\r
1442 var min = resultTwo[0];
\r
1443 for (var i = 1; i < resultTwo.length; i++) {
\r
1444 var isVectorLesser = true;
\r
1445 for (var j = 0; j < paramTypes.length; j++) {
\r
1446 if (min[j] < resultTwo[i][j]) {
\r
1447 isVectorLesser = false;;
\r
1451 if (isVectorLesser)
\r
1452 min = resultTwo[i];
\r
1454 var index = min[paramTypes.length]; // Get the previously stored index
\r
1456 * Return the method parameters' type string as indentifier of the
\r
1459 return roundOne[index].join ('\\');
\r
1462 ////////////////////////////////// package loading ///////////////////////
\r
1465 * all root packages. e.g. java.*, org.*, com.*
\r
1468 Clazz.allPackage = {};
\r
1471 * Will be used to keep value of whether the class is defined or not.
\r
1474 Clazz.allClasses = {};
\r
1476 Clazz.lastPackageName = null;
\r
1477 Clazz.lastPackage = null;
\r
1480 Clazz.unloadedClasses = [];
\r
1483 Clazz.declarePackage = function (pkgName) {
\r
1484 if (Clazz.lastPackageName == pkgName)
\r
1485 return Clazz.lastPackage;
\r
1486 if (pkgName && pkgName.length) {
\r
1487 var pkgFrags = pkgName.split (/\./);
\r
1488 var pkg = Clazz.allPackage;
\r
1489 for (var i = 0; i < pkgFrags.length; i++) {
\r
1490 if (!pkg[pkgFrags[i]]) {
\r
1491 pkg[pkgFrags[i]] = {
\r
1492 __PKG_NAME__ : (pkg.__PKG_NAME__ ?
\r
1493 pkg.__PKG_NAME__ + "." + pkgFrags[i] : pkgFrags[i])
\r
1495 // pkg[pkgFrags[i]] = {};
\r
1498 Clazz.setGlobal(pkgFrags[i], pkg[pkgFrags[i]]);
\r
1501 pkg = pkg[pkgFrags[i]]
\r
1503 Clazz.lastPackageName = pkgName;
\r
1504 Clazz.lastPackage = pkg;
\r
1510 Clazz.evalType = function (typeStr, isQualified) {
\r
1511 var idx = typeStr.lastIndexOf(".");
\r
1513 var pkgName = typeStr.substring (0, idx);
\r
1514 var pkg = Clazz.declarePackage (pkgName);
\r
1515 var clazzName = typeStr.substring (idx + 1);
\r
1516 return pkg[clazzName];
\r
1519 return window[typeStr];
\r
1520 switch (typeStr) {
\r
1535 case "NullObject":
\r
1536 return NullObject;
\r
1538 return window[typeStr];
\r
1543 * Define a class or interface.
\r
1545 * @param qClazzName String presents the qualified name of the class
\r
1546 * @param clazzFun Function of the body
\r
1547 * @param clazzParent Clazz to inherit from, may be null
\r
1548 * @param interfacez Clazz may implement one or many interfaces
\r
1549 * interfacez can be Clazz object or Array of Clazz objects.
\r
1550 * @return Ruturn the modified Clazz object
\r
1553 Clazz.defineType = function (qClazzName, clazzFun, clazzParent, interfacez) {
\r
1554 var cf = Clazz.unloadedClasses[qClazzName];
\r
1558 var idx = qClazzName.lastIndexOf (".");
\r
1560 var pkgName = qClazzName.substring (0, idx);
\r
1561 var pkg = Clazz.declarePackage (pkgName);
\r
1562 var clazzName = qClazzName.substring (idx + 1);
\r
1563 if (pkg[clazzName]) {
\r
1564 // already defined! Should throw exception!
\r
1565 return pkg[clazzName];
\r
1567 pkg[clazzName] = clazzFun;
\r
1569 if (window[qClazzName]) {
\r
1570 // already defined! Should throw exception!
\r
1571 return window[qClazzName];
\r
1573 Clazz.setGlobal(qClazzName, clazzFun);
\r
1575 Clazz.decorateAsType(clazzFun, qClazzName, clazzParent, interfacez);
\r
1576 /*# {$no.javascript.support} >>x #*/
\r
1577 var iFun = Clazz._innerFunctions;
\r
1578 clazzFun.defineMethod = iFun.defineMethod;
\r
1579 clazzFun.defineStaticMethod = iFun.defineStaticMethod;
\r
1580 clazzFun.makeConstructor = iFun.makeConstructor;
\r
1585 var isSafari = (navigator.userAgent.indexOf ("Safari") != -1);
\r
1586 var isSafari4Plus = false;
\r
1588 var ua = navigator.userAgent;
\r
1589 var verIdx = ua.indexOf("Version/");
\r
1590 if (verIdx != -1) {
\r
1591 var verStr = ua.substring(verIdx + 8);
\r
1592 var verNumber = parseFloat(verStr);
\r
1593 isSafari4Plus = verNumber >= 4.0;
\r
1598 Clazz.instantialize = function (objThis, args) {
\r
1601 if (args && args.length == 1 && args[0]
\r
1602 && args[0] instanceof args4InheritClass) {
\r
1605 if (objThis instanceof Number) {
\r
1606 objThis.valueOf = function () {
\r
1610 if (isSafari4Plus) { // Fix bug of Safari 4.0+'s over-optimization
\r
1611 var argsClone = [];
\r
1612 for (var k = 0; k < args.length; k++) {
\r
1613 argsClone[k] = args[k];
\r
1618 var c = objThis.construct;
\r
1620 if (!objThis.con$truct) { // no need to init fields
\r
1621 c.apply (objThis, args);
\r
1622 } else if (!objThis.getClass ().superClazz) { // the base class
\r
1623 objThis.con$truct.apply (objThis, []);
\r
1624 c.apply (objThis, args);
\r
1625 } else if ((c.claxxOwner
\r
1626 && c.claxxOwner === objThis.getClass ())
\r
1628 && c.stacks[c.stacks.length - 1] == objThis.getClass ())) {
\r
1630 * This #construct is defined by this class itself.
\r
1631 * #construct will call Clazz.superConstructor, which will
\r
1632 * call #con$truct back
\r
1634 c.apply (objThis, args);
\r
1635 } else { // constructor is a super constructor
\r
1636 if (c.claxxOwner && !c.claxxOwner.superClazz
\r
1637 && c.claxxOwner.con$truct) {
\r
1638 c.claxxOwner.con$truct.apply (objThis, []);
\r
1639 } else if (c.stacks && c.stacks.length == 1
\r
1640 && !c.stacks[0].superClazz) {
\r
1641 c.stacks[0].con$truct.apply (objThis, []);
\r
1643 c.apply (objThis, args);
\r
1644 objThis.con$truct.apply (objThis, []);
\r
1646 } else if (objThis.con$truct) {
\r
1647 objThis.con$truct.apply (objThis, []);
\r
1652 * Once there are other methods registered to the Function.prototype,
\r
1653 * those method names should be add to the following Array.
\r
1656 * static final member of interface may be a class, which may
\r
1660 Clazz.innerFunctionNames = [
\r
1661 "isInstance", "equals", "hashCode", /*"toString",*/ "getName", "getCanonicalName", "getClassLoader", "getResource", "getResourceAsStream" /*# {$no.javascript.support} >>x #*/, "defineMethod", "defineStaticMethod",
\r
1662 "makeConstructor" /*# x<< #*/
\r
1668 Clazz._innerFunctions = {
\r
1670 * Similar to Object#equals
\r
1673 isInstance: function(c) {
\r
1674 return Clazz.instanceOf(c, this);
\r
1677 equals : function (aFun) {
\r
1678 return this === aFun;
\r
1681 hashCode : function () {
\r
1682 return this.getName ().hashCode ();
\r
1685 toString : function () {
\r
1686 return "class " + this.getName ();
\r
1690 * Similar to Class#getName
\r
1692 getName : function () {
\r
1693 return Clazz.getClassName (this, true);
\r
1695 getCanonicalName : function () {
\r
1696 return this.__CLASS_NAME__;
\r
1698 getClassLoader : function () {
\r
1699 var clazzName = this.__CLASS_NAME__;
\r
1700 var baseFolder = Clazz._Loader.getClasspathFor(clazzName);
\r
1701 var x = baseFolder.lastIndexOf (clazzName.replace (/\./g, "/"));
\r
1703 baseFolder = baseFolder.substring (0, x);
\r
1705 baseFolder = Clazz._Loader.getClasspathFor(clazzName, true);
\r
1707 var loader = Clazz._Loader.requireLoaderByBase(baseFolder);
\r
1708 loader.getResourceAsStream = Clazz._innerFunctions.getResourceAsStream;
\r
1709 loader.getResource = Clazz._innerFunctions.getResource; // BH
\r
1713 getResource : function(name) {
\r
1714 var stream = this.getResourceAsStream(name);
\r
1715 return (stream ? stream.url : null);
\r
1718 getResourceAsStream : function (name) {
\r
1721 name = name.replace (/\\/g, '/');
\r
1722 var baseFolder = null;
\r
1724 var clazzName = this.__CLASS_NAME__;
\r
1725 if (arguments.length == 2 && name.indexOf ('/') != 0) { // additional argument
\r
1726 name = "/" + name;
\r
1728 if (name.indexOf ('/') == 0) {
\r
1729 //is.url = name.substring (1);
\r
1730 if (arguments.length == 2) { // additional argument
\r
1731 baseFolder = arguments[1];
\r
1733 baseFolder = Clazz.binaryFolders[0];
\r
1734 } else if (Clazz._Loader) {
\r
1735 baseFolder = Clazz._Loader.getClasspathFor(clazzName, true);
\r
1737 if (!baseFolder) {
\r
1738 fname = name.substring (1);
\r
1740 baseFolder = baseFolder.replace (/\\/g, '/');
\r
1741 var length = baseFolder.length;
\r
1742 var lastChar = baseFolder.charAt (length - 1);
\r
1743 if (lastChar != '/') {
\r
1744 baseFolder += "/";
\r
1746 fname = baseFolder + name.substring (1);
\r
1750 baseFolder = this.base;
\r
1751 } else if (Clazz._Loader) {
\r
1752 baseFolder = Clazz._Loader.getClasspathFor(clazzName);
\r
1753 var x = baseFolder.lastIndexOf (clazzName.replace (/\./g, "/"));
\r
1755 baseFolder = baseFolder.substring (0, x);
\r
1757 //baseFolder = null;
\r
1759 if (baseFolder.indexOf (".z.js") == baseFolder.length - 5
\r
1760 && (y = baseFolder.lastIndexOf ("/")) != -1) {
\r
1761 baseFolder = baseFolder.substring (0, y + 1);
\r
1762 var pkgs = clazzName.split (/\./);
\r
1763 for (var k = 1; k < pkgs.length; k++) {
\r
1765 for (var j = 0; j < k; j++) {
\r
1766 pkgURL += pkgs[j] + "/";
\r
1768 if (pkgURL.length > baseFolder.length) {
\r
1771 if (baseFolder.indexOf (pkgURL) == baseFolder.length - pkgURL.length) {
\r
1772 baseFolder = baseFolder.substring (0, baseFolder.length - pkgURL.length + 1);
\r
1777 baseFolder = Clazz._Loader.getClasspathFor(clazzName, true);
\r
1781 var bins = Clazz.binaryFolders;
\r
1782 if (bins && bins.length) {
\r
1783 baseFolder = bins[0];
\r
1787 baseFolder = "j2s/";
\r
1788 baseFolder = baseFolder.replace (/\\/g, '/');
\r
1789 var length = baseFolder.length;
\r
1790 var lastChar = baseFolder.charAt (length - 1);
\r
1791 if (lastChar != '/') {
\r
1792 baseFolder += "/";
\r
1795 fname = baseFolder + name;
\r
1797 var idx = clazzName.lastIndexOf ('.');
\r
1798 if (idx == -1 || this.base) {
\r
1799 fname = baseFolder + name;
\r
1801 fname = baseFolder + clazzName.substring (0, idx)
\r
1802 .replace (/\./g, '/') + "/" + name;
\r
1808 if (fname.indexOf(":/") < 0) {
\r
1809 var d = document.location.href.split("?")[0].split("/");
\r
1810 d[d.length - 1] = fname;
\r
1811 fname = d.join("/");
\r
1813 url = new java.net.URL(fname);
\r
1816 var data = (url == null ? null : Jmol._getFileData(fname.toString()));
\r
1817 if (!data || data == "error" || data.indexOf("[Exception") == 0)
\r
1819 var bytes = new java.lang.String(data).getBytes();
\r
1820 var is = new java.io.BufferedInputStream ( new java.io.ByteArrayInputStream (bytes));
\r
1823 }/*# {$no.javascript.support} >>x #*/,
\r
1826 * For JavaScript programmers
\r
1828 defineMethod : function (methodName, funBody, paramTypes) {
\r
1829 Clazz.defineMethod (this, methodName, funBody, paramTypes);
\r
1833 * For JavaScript programmers
\r
1835 defineStaticMethod : function (methodName, funBody, paramTypes) {
\r
1836 Clazz.defineMethod (this, methodName, funBody, paramTypes);
\r
1837 this[methodName] = this.prototype[methodName];
\r
1841 * For JavaScript programmers
\r
1843 makeConstructor : function (funBody, paramTypes) {
\r
1844 Clazz.makeConstructor (this, funBody, paramTypes);
\r
1853 * BH: I would like to be able to remove "self.c$" here, but that is tricky.
\r
1856 Clazz.pu$h = function (c) {
\r
1857 c || (c = self.c$); // old style
\r
1858 c && cStack.push(c);
\r
1861 Clazz.p0p = function () {
\r
1862 return cStack.pop();
\r
1866 Clazz.decorateAsClass = function (clazzFun, prefix, name, clazzParent,
\r
1867 interfacez, parentClazzInstance, _decorateAsClass) {
\r
1869 var prefixName = null;
\r
1871 prefixName = prefix.__PKG_NAME__;
\r
1873 prefixName = prefix.__CLASS_NAME__;
\r
1875 var qName = (prefixName ? prefixName + "." : "") + name;
\r
1877 if (Clazz._Loader._classPending[qName]) {
\r
1878 delete Clazz._Loader._classPending[qName];
\r
1879 Clazz._Loader._classCountOK++;
\r
1880 Clazz._Loader._classCountPending--;
\r
1882 if (Clazz._Loader && Clazz._Loader._checkLoad) {
\r
1883 System.out.println("decorating class " + prefixName + "." + name);
\r
1885 var cf = Clazz.unloadedClasses[qName];
\r
1890 decorateFunction(clazzFun, prefix, name);
\r
1891 if (parentClazzInstance) {
\r
1892 Clazz.inheritClass (clazzFun, clazzParent, parentClazzInstance);
\r
1893 } else if (clazzParent) {
\r
1894 Clazz.inheritClass (clazzFun, clazzParent);
\r
1897 Clazz.implementOf (clazzFun, interfacez);
\r
1903 var decorateFunction = function (clazzFun, prefix, name, _decorateFunction) {
\r
1906 // e.g. Clazz.declareInterface (null, "ICorePlugin", org.eclipse.ui.IPlugin);
\r
1908 Clazz.setGlobal(name, clazzFun);
\r
1909 } else if (prefix.__PKG_NAME__) {
\r
1910 // e.g. Clazz.declareInterface (org.eclipse.ui, "ICorePlugin", org.eclipse.ui.IPlugin);
\r
1911 qName = prefix.__PKG_NAME__ + "." + name;
\r
1912 prefix[name] = clazzFun;
\r
1913 if (prefix === java.lang)
\r
1914 Clazz.setGlobal(name, clazzFun);
\r
1916 // e.g. Clazz.declareInterface (org.eclipse.ui.Plugin, "ICorePlugin", org.eclipse.ui.IPlugin);
\r
1917 qName = prefix.__CLASS_NAME__ + "." + name;
\r
1918 prefix[name] = clazzFun;
\r
1920 Clazz.extendJO(clazzFun, qName);
\r
1921 var inF = Clazz.innerFunctionNames;
\r
1922 for (var i = 0; i < inF.length; i++) {
\r
1923 clazzFun[inF[i]] = Clazz._innerFunctions[inF[i]];
\r
1926 if (Clazz._Loader)
\r
1927 Clazz._Loader.updateNodeForFunctionDecoration(qName);
\r
1931 Clazz.declareInterface = function (prefix, name, interfacez, _declareInterface) {
\r
1932 var clazzFun = function () {};
\r
1933 decorateFunction(clazzFun, prefix, name);
\r
1935 Clazz.implementOf (clazzFun, interfacez);
\r
1941 Clazz.declareType = function (prefix, name, clazzParent, interfacez,
\r
1942 parentClazzInstance, _declareType) {
\r
1943 var f = function () {
\r
1944 Clazz.instantialize (this, arguments);
\r
1946 return Clazz.decorateAsClass (f, prefix, name, clazzParent, interfacez,
\r
1947 parentClazzInstance);
\r
1951 Clazz.declareAnonymous = function (prefix, name, clazzParent, interfacez,
\r
1952 parentClazzInstance, _declareAnonymous) {
\r
1953 var f = function () {
\r
1954 Clazz.prepareCallback(this, arguments);
\r
1955 Clazz.instantialize (this, arguments);
\r
1957 return Clazz.decorateAsClass (f, prefix, name, clazzParent, interfacez,
\r
1958 parentClazzInstance);
\r
1962 Clazz.decorateAsType = function (clazzFun, qClazzName, clazzParent,
\r
1963 interfacez, parentClazzInstance, inheritClazzFuns, _decorateAsType) {
\r
1964 Clazz.extendJO(clazzFun, qClazzName);
\r
1965 clazzFun.equals = Clazz._innerFunctions.equals;
\r
1966 clazzFun.getName = Clazz._innerFunctions.getName;
\r
1967 if (inheritClazzFuns) {
\r
1968 for (var i = 0; i < Clazz.innerFunctionNames.length; i++) {
\r
1969 var methodName = Clazz.innerFunctionNames[i];
\r
1970 clazzFun[methodName] = Clazz._innerFunctions[methodName];
\r
1973 if (parentClazzInstance) {
\r
1974 Clazz.inheritClass (clazzFun, clazzParent, parentClazzInstance);
\r
1975 } else if (clazzParent) {
\r
1976 Clazz.inheritClass (clazzFun, clazzParent);
\r
1979 Clazz.implementOf (clazzFun, interfacez);
\r
1985 ////////////////////////// default package declarations ////////////////////////
\r
1987 /* sgurin: preserve Number.prototype.toString */
\r
1988 Number.prototype._numberToString=Number.prototype.toString;
\r
1991 Clazz.declarePackage ("java.io");
\r
1992 //Clazz.declarePackage ("java.lang");
\r
1993 Clazz.declarePackage ("java.lang.annotation"); // java.lang
\r
1994 Clazz.declarePackage ("java.lang.instrument"); // java.lang
\r
1995 Clazz.declarePackage ("java.lang.management"); // java.lang
\r
1996 Clazz.declarePackage ("java.lang.reflect"); // java.lang
\r
1997 Clazz.declarePackage ("java.lang.ref"); // java.lang.ref
\r
1998 java.lang.ref.reflect = java.lang.reflect;
\r
1999 Clazz.declarePackage ("java.util");
\r
2000 //var reflect = Clazz.declarePackage ("java.lang.reflect");
\r
2001 Clazz.declarePackage ("java.security");
\r
2005 * Consider these interfaces are basic!
\r
2007 Clazz.declareInterface (java.io,"Closeable");
\r
2008 Clazz.declareInterface (java.io,"DataInput");
\r
2009 Clazz.declareInterface (java.io,"DataOutput");
\r
2010 Clazz.declareInterface (java.io,"Externalizable");
\r
2011 Clazz.declareInterface (java.io,"Flushable");
\r
2012 Clazz.declareInterface (java.io,"Serializable");
\r
2013 Clazz.declareInterface (java.lang,"Iterable");
\r
2014 Clazz.declareInterface (java.lang,"CharSequence");
\r
2015 Clazz.declareInterface (java.lang,"Cloneable");
\r
2016 Clazz.declareInterface (java.lang,"Appendable");
\r
2017 Clazz.declareInterface (java.lang,"Comparable");
\r
2018 Clazz.declareInterface (java.lang,"Runnable");
\r
2019 Clazz.declareInterface (java.util,"Comparator");
\r
2021 java.lang.ClassLoader = {
\r
2022 __CLASS_NAME__ : "ClassLoader"
\r
2025 /******************************************************************************
\r
2026 * Copyright (c) 2007 java2script.org and others.
\r
2027 * All rights reserved. This program and the accompanying materials
\r
2028 * are made available under the terms of the Eclipse Public License v1.0
\r
2029 * which accompanies this distribution, and is available at
\r
2030 * http://www.eclipse.org/legal/epl-v10.html
\r
2033 * Zhou Renjian - initial API and implementation
\r
2034 *****************************************************************************/
\r
2036 * @author zhou renjian
\r
2037 * @create March 10, 2006
\r
2041 * Once ClassExt.js is part of Class.js.
\r
2042 * In order to make the Class.js as small as possible, part of its content
\r
2043 * is moved into this ClassExt.js.
\r
2045 * See also http://j2s.sourceforge.net/j2sclazz/
\r
2049 * Clazz.MethodNotFoundException is used to notify the developer about calling
\r
2050 * methods with incorrect parameters.
\r
2053 // Override the Clazz.MethodNotFoundException in Class.js to give details
\r
2054 var newMethodNotFoundException = function (obj, clazz, method, params) {
\r
2055 var paramStr = "";
\r
2057 paramStr = params.substring (1).replace (/\\/g, ",");
\r
2059 var leadingStr = "";
\r
2060 if (method && method != "construct") {
\r
2061 leadingStr = "Method";
\r
2063 leadingStr = "Constructor";
\r
2065 var message = leadingStr + " " + Clazz.getClassName (clazz, true) + "."
\r
2066 + method + "(" + paramStr + ") is not found!";
\r
2067 throw new java.lang.NoSuchMethodException(message);
\r
2071 * Prepare "callback" for instance of anonymous Class.
\r
2072 * For example for the callback:
\r
2073 * this.callbacks.MyEditor.sayHello();
\r
2075 * This is specifically for inner classes that are referring to
\r
2076 * outer class methods and fields.
\r
2078 * @param objThis the host object for callback
\r
2079 * @param args arguments object. args[0] will be classThisObj -- the "this"
\r
2080 * object to be hooked
\r
2082 * Attention: parameters should not be null!
\r
2085 Clazz.prepareCallback = function (innerObj, args) {
\r
2086 var outerObj = args[0];
\r
2087 var cbName = "b$"; // "callbacks";
\r
2088 if (innerObj && outerObj && outerObj !== window) {
\r
2089 var className = Clazz.getClassName(outerObj, true);
\r
2091 if (innerObj[cbName]) // must make a copy!
\r
2092 for (var s in innerObj[cbName])
\r
2093 obs[s] = innerObj[cbName][s];
\r
2094 innerObj[cbName] = obs;
\r
2097 * TODO: the following line is SWT-specific! Try to move it out!
\r
2099 // obs[className.replace (/org\.eclipse\.swt\./, "$wt.")] = outerObj;
\r
2101 // all references to outer class and its superclass objects must be here as well
\r
2102 obs[className] = outerObj;
\r
2103 var clazz = Clazz.getClass(outerObj);
\r
2104 while (clazz.superClazz) {
\r
2105 clazz = clazz.superClazz;
\r
2107 * TODO: the following line is SWT-specific! Try to move it out!
\r
2109 // obs[Clazz.getClassName (clazz, true)
\r
2110 // .replace (/org\.eclipse\.swt\./, "$wt.")] = outerObj;
\r
2111 obs[Clazz.getClassName(clazz, true)] = outerObj;
\r
2113 var cbs = outerObj[cbName];
\r
2115 for (var s in cbs)
\r
2118 // remove "this" argument
\r
2119 // note that args is an instance of arguments -- NOT an array; does not have the .shift() method!
\r
2120 for (var i = 0; i < args.length - 1; i++)
\r
2121 args[i] = args[i + 1];
\r
2126 * Construct instance of the given inner class.
\r
2128 * @param classInner given inner class, alway with name like "*$*"
\r
2129 * @param innerObj this instance which can be used to call back.
\r
2130 * @param finalVars final variables which the inner class may use
\r
2131 * @return the constructed object
\r
2133 * @see Clazz#cloneFinals
\r
2136 Clazz.innerTypeInstance = function (clazzInner, innerObj, finalVars) {
\r
2138 clazzInner = arguments.callee.caller;
\r
2140 if (finalVars || innerObj.$finals) {
\r
2141 obj = new clazzInner(innerObj, Clazz.inheritArgs);
\r
2142 // f$ is short for the once choosen "$finals"
\r
2144 if (innerObj.f$) {
\r
2146 for (var attr in innerObj.f$)
\r
2147 o[attr] = innerObj.f$[attr];
\r
2148 for (var attr in finalVars)
\r
2149 o[attr] = finalVars[attr];
\r
2152 obj.f$ = finalVars;
\r
2154 } else if (innerObj.f$) {
\r
2155 obj.f$ = innerObj.f$;
\r
2158 switch (arguments.length) {
\r
2160 return new clazzInner(innerObj);
\r
2162 return (innerObj.__CLASS_NAME__ == clazzInner.__CLASS_NAME__
\r
2163 && arguments[3] === Clazz.inheritArgs ? innerObj : new clazzInner(innerObj, arguments[3]));
\r
2165 return new clazzInner(innerObj, arguments[3], arguments[4]);
\r
2167 return new clazzInner(innerObj, arguments[3], arguments[4],
\r
2170 return new clazzInner(innerObj, arguments[3], arguments[4],
\r
2171 arguments[5], arguments[6]);
\r
2173 return new clazzInner(innerObj, arguments[3], arguments[4],
\r
2174 arguments[5], arguments[6], arguments[7]);
\r
2176 return new clazzInner(innerObj, arguments[3], arguments[4],
\r
2177 arguments[5], arguments[6], arguments[7], arguments[8]);
\r
2179 return new clazzInner(innerObj, arguments[3], arguments[4],
\r
2180 arguments[5], arguments[6], arguments[7], arguments[8],
\r
2183 //Should construct instance manually.
\r
2184 obj = new clazzInner(innerObj, Clazz.inheritArgs);
\r
2188 var n = arguments.length - 3;
\r
2189 var args = new Array(n);
\r
2190 for (var i = n; --i >= 0;)
\r
2191 args[i] = arguments[i + 3];
\r
2192 Clazz.instantialize(obj, args);
\r
2197 * Clone variables whose modifier is "final".
\r
2198 * Usage: var o = Clazz.cloneFinals ("name", name, "age", age);
\r
2200 * @return Object with all final variables
\r
2203 Clazz.cloneFinals = function () {
\r
2205 var len = arguments.length / 2;
\r
2206 for (var i = len; --i >= 0;)
\r
2207 o[arguments[i + i]] = arguments[i + i + 1];
\r
2212 Clazz.isClassDefined = Clazz.isDefinedClass = function(clazzName) {
\r
2214 return false; /* consider null or empty name as non-defined class */
\r
2215 if (Clazz.allClasses[clazzName])
\r
2217 var pkgFrags = clazzName.split (/\./);
\r
2219 for (var i = 0; i < pkgFrags.length; i++)
\r
2220 if (!(pkg = (pkg ? pkg[pkgFrags[i]] : Clazz.allPackage[pkgFrags[0]]))) {
\r
2223 return (pkg && (Clazz.allClasses[clazzName] = true));
\r
2226 * Define the enum constant.
\r
2227 * @param classEnum enum type
\r
2228 * @param enumName enum constant
\r
2229 * @param enumOrdinal enum ordinal
\r
2230 * @param initialParams enum constant constructor parameters
\r
2231 * @return return defined enum constant
\r
2234 Clazz.defineEnumConstant = function (clazzEnum, enumName, enumOrdinal, initialParams, clazzEnumExt) {
\r
2235 var o = (clazzEnumExt ? new clazzEnumExt() : new clazzEnum());
\r
2236 // BH avoids unnecessary calls to SAEM
\r
2237 o.$name = enumName;
\r
2238 o.$ordinal = enumOrdinal;
\r
2239 //Clazz.superConstructor (o, clazzEnum, [enumName, enumOrdinal]);
\r
2240 if (initialParams && initialParams.length)
\r
2241 o.construct.apply (o, initialParams);
\r
2242 clazzEnum[enumName] = o;
\r
2243 clazzEnum.prototype[enumName] = o;
\r
2244 if (!clazzEnum["$ values"]) { // BH added
\r
2245 clazzEnum["$ values"] = [] // BH added
\r
2246 clazzEnum.values = function() { // BH added
\r
2247 return this["$ values"]; // BH added
\r
2250 clazzEnum["$ values"].push(o);
\r
2254 //////// (int) conversions //////////
\r
2256 Clazz.floatToInt = function (x) {
\r
2257 return x < 0 ? Math.ceil(x) : Math.floor(x);
\r
2260 Clazz.floatToByte = Clazz.floatToShort = Clazz.floatToLong = Clazz.floatToInt;
\r
2261 Clazz.doubleToByte = Clazz.doubleToShort = Clazz.doubleToLong = Clazz.doubleToInt = Clazz.floatToInt;
\r
2263 Clazz.floatToChar = function (x) {
\r
2264 return String.fromCharCode (x < 0 ? Math.ceil(x) : Math.floor(x));
\r
2267 Clazz.doubleToChar = Clazz.floatToChar;
\r
2271 ///////////////////////////////// Array additions //////////////////////////////
\r
2273 // BH: these are necessary for integer processing, especially
\r
2277 var getArrayClone = function(nbits) {
\r
2278 return function() {
\r
2280 var n = me.length;
\r
2281 var a = (nbits == 32 ? new Int32Array(n) : new Float64Array(n));
\r
2282 for (var i = n; --i >= 0;)
\r
2288 if (self.Int32Array && self.Int32Array != Array) {
\r
2289 Clazz.haveInt32 = true;
\r
2290 if (!Int32Array.prototype.sort)
\r
2291 Int32Array.prototype.sort = Array.prototype.sort
\r
2292 if (!Int32Array.prototype.clone)
\r
2293 Int32Array.prototype.clone = getArrayClone(32);
\r
2295 Int32Array = function(n) {
\r
2297 var b = new Array(n);
\r
2298 b.toString = function(){return "[object Int32Array]"}
\r
2299 for (var i = 0; i < n; i++)b[i] = 0
\r
2302 Clazz.haveInt32 = false;
\r
2303 Int32Array.prototype.sort = Array.prototype.sort
\r
2304 Int32Array.prototype.clone = getArrayClone(32);
\r
2305 Int32Array.prototype.int32Fake = function(){};
\r
2308 if (self.Float64Array && self.Float64Array != Array) {
\r
2309 Clazz.haveFloat64 = true;
\r
2310 if (!Float64Array.prototype.sort)
\r
2311 Float64Array.prototype.sort = Array.prototype.sort
\r
2312 if (!Float64Array.prototype.clone)
\r
2313 Float64Array.prototype.clone = getArrayClone(64);
\r
2315 Clazz.haveFloat64 = false;
\r
2316 Float64Array = function(n) {
\r
2318 var b = new Array(n);
\r
2319 for (var i = 0; i < n; i++)b[i] = 0.0
\r
2322 Float64Array.prototype.sort = Array.prototype.sort
\r
2323 Float64Array.prototype.clone = getArrayClone(64);
\r
2324 Float64Array.prototype.float64Fake = function() {}; // "present"
\r
2325 Float64Array.prototype.toString = function() {return "[object Float64Array]"};
\r
2326 // Darn! Mozilla makes this a double, not a float. It's 64-bit.
\r
2327 // and Safari 5.1 doesn't have Float64Array
\r
2333 * @return the created Array object
\r
2336 Clazz.newArray = function () {
\r
2337 if (arguments[0] instanceof Array) {
\r
2338 // recursive, from newArray(n,m,value)
\r
2339 // as newArray([m, value], newInt32Array)
\r
2340 var args = arguments[0];
\r
2341 var f = arguments[1];
\r
2343 var args = arguments;
\r
2346 var dim = args[0];
\r
2347 if (typeof dim == "string") {
\r
2348 dim = dim.charCodeAt (0); // char
\r
2350 var len = args.length - 1;
\r
2351 var val = args[len];
\r
2352 switch (args.length) {
\r
2355 return []; // maybe never?
\r
2358 return new Array(dim);
\r
2359 if (f === true && Clazz.haveInt32) return new Int32Array(dim);
\r
2360 if (f === false && Clazz.haveFloat64) return new Float64Array(dim);
\r
2361 var arr = (f === true ? new Int32Array() : f === false ? new Float64Array() : dim < 0 ? val : new Array(dim));
\r
2362 for (var i = dim; --i >= 0;)
\r
2366 var xargs = new Array (len);
\r
2367 for (var i = 0; i < len; i++) {
\r
2368 xargs[i] = args[i + 1];
\r
2370 var arr = new Array (dim);
\r
2371 if (val == null || val >= 0 || len > 2)
\r
2372 for (var i = 0; i < dim; i++) {
\r
2373 // Call recursively!
\r
2374 arr[i] = Clazz.newArray (xargs, f);
\r
2380 Clazz.newArray32 = function(args, isInt32) {
\r
2381 var dim = args[0];
\r
2382 if (typeof dim == "string")
\r
2383 dim = dim.charCodeAt (0); // char
\r
2384 var len = args.length - 1;
\r
2385 var val = args[len];
\r
2386 switch (args.length) {
\r
2389 alert ("ERROR IN newArray32 -- args.length < 2");
\r
2390 return new Array(0);
\r
2392 var isDefined = (dim < 0);
\r
2395 var a = (val < 0 ? new Array(dim) : isInt32 ? new Int32Array(dim) : new Float64Array(dim));
\r
2397 for (var i = dim; --i >= 0;)
\r
2401 var xargs = new Array(len);
\r
2402 for (var i = len; --i >= 0;) {
\r
2403 xargs[i] = args[i + 1];
\r
2405 var arr = new Array (dim);
\r
2406 for (var i = 0; i < dim; i++) {
\r
2407 // Call newArray referencing this array type
\r
2408 // only for the final iteration, and only if val === 0
\r
2409 arr[i] = Clazz.newArray (xargs, isInt32);
\r
2418 * @return the created Array object
\r
2421 Clazz.newInt32Array = function () {
\r
2422 return Clazz.newArray32(arguments, true);
\r
2428 * @return the created Array object
\r
2431 Clazz.newFloat64Array = function () {
\r
2432 return Clazz.newArray32(arguments, false);
\r
2435 Clazz.newFloatArray = Clazz.newDoubleArray = Clazz.newFloat64Array;
\r
2436 Clazz.newIntArray = Clazz.newLongArray = Clazz.newShortArray = Clazz.newByteArray = Clazz.newInt32Array;
\r
2437 Clazz.newCharArray = Clazz.newBooleanArray = Clazz.newArray;
\r
2439 //$_AI=Clazz.newIntArray;
\r
2440 //$_AF=Clazz.newFloatArray;
\r
2441 //$_AD=Clazz.newDoubleArray;
\r
2442 //$_AL=Clazz.newLongArray;
\r
2443 //$_AS=Clazz.newShortArray;
\r
2444 //$_AB=Clazz.newByteArray;
\r
2445 //$_AC=Clazz.newCharArray;
\r
2446 //$_Ab=Clazz.newBooleanArray;
\r
2449 var arrayIs = function(a, what) {
\r
2450 // for some reason, Number.constructor.toString() now gives "too much recursion"
\r
2451 return a.constructor && a.constructor != Number && a.constructor.toString().indexOf(what) >= 0
\r
2454 Clazz.isAS = function(a) { // just checking first parameter
\r
2455 return (a && typeof a == "object" && arrayIs(a, " Array") && (typeof a[0] == "string" || typeof a[0] == "undefined"));
\r
2458 Clazz.isASS = function(a) {
\r
2459 return (a && typeof a == "object" && Clazz.isAS(a[0]));
\r
2462 Clazz.isAP = function(a) {
\r
2463 return (a && Clazz.getClassName(a[0]) == "JU.P3");
\r
2466 Clazz.isAI = function(a) {
\r
2467 return (a && typeof a == "object" && (Clazz.haveInt32 ? arrayIs(a, "Int32Array") : a.int32Fake ? true : false));
\r
2470 Clazz.isAII = function(a) { // assumes non-null a[0]
\r
2471 return (a && typeof a == "object" && Clazz.isAI(a[0]));
\r
2474 Clazz.isAF = function(a) {
\r
2475 return (a && typeof a == "object" && (Clazz.haveFloat64 ? arrayIs(a, "Float64Array") : a.float64Fake ? true : false));
\r
2478 Clazz.isAFF = function(a) { // assumes non-null a[0]
\r
2479 return (a && typeof a == "object" && Clazz.isAF(a[0]));
\r
2482 Clazz.isAFFF = function(a) { // assumes non-null a[0]
\r
2483 return (a && typeof a == "object" && Clazz.isAFF(a[0]));
\r
2486 Clazz.isAFloat = function(a) { // just checking first parameter
\r
2487 return (a && typeof a == "object" && arrayIs(a, " Array") && Clazz.instanceOf(a[0], Float));
\r
2492 * Make the RunnableCompatiability instance as a JavaScript function.
\r
2494 * @param jsr Instance of RunnableCompatiability
\r
2495 * @return JavaScript function instance represents the method run of jsr.
\r
2499 Clazz.makeFunction = function (jsr) {
\r
2500 // never used in Jmol -- called by Enum, but not accessible to it -- part of SWT
\r
2501 return function(e) {
\r
2507 switch (jsr.returnSet) {
\r
2509 return jsr.returnNumber;
\r
2511 return jsr.returnBoolean;
\r
2513 return jsr.returnObject;
\r
2520 Clazz.defineStatics = function (clazz) {
\r
2521 for (var j = arguments.length, i = (j - 1) / 2; --i >= 0;) {
\r
2522 var val = arguments[--j]
\r
2523 var name = arguments[--j];
\r
2524 clazz[name] = clazz.prototype[name] = val;
\r
2529 Clazz.prepareFields = function (clazz, fieldsFun) {
\r
2531 if (clazz.con$truct) {
\r
2532 var ss = clazz.con$truct.stacks;
\r
2533 var idx = 0;//clazz.con$truct.index;
\r
2534 for (var i = idx; i < ss.length; i++) {
\r
2535 stacks[i] = ss[i];
\r
2538 addProto(clazz.prototype, "con$truct", clazz.con$truct = function () {
\r
2539 var stacks = arguments.callee.stacks;
\r
2541 for (var i = 0; i < stacks.length; i++) {
\r
2542 stacks[i].apply (this, []);
\r
2546 stacks.push(fieldsFun);
\r
2547 clazz.con$truct.stacks = stacks;
\r
2548 clazz.con$truct.index = 0;
\r
2552 * Serialize those public or protected fields in class
\r
2553 * net.sf.j2s.ajax.SimpleSerializable.
\r
2557 Clazz.registerSerializableFields = function (clazz) {
\r
2558 var args = arguments;
\r
2559 var length = args.length;
\r
2561 if (clazz.declared$Fields) {
\r
2562 for (var i = 0; i < clazz.declared$Fields.length; i++) {
\r
2563 newArr[i] = clazz.declared$Fields[i];
\r
2566 clazz.declared$Fields = newArr;
\r
2568 if (length > 0 && length % 2 == 1) {
\r
2569 var fs = clazz.declared$Fields;
\r
2570 var n = (length - 1) / 2;
\r
2571 for (var i = 1; i <= n; i++) {
\r
2572 var o = { name : args[i + i - 1], type : args[i + i] };
\r
2573 var existed = false;
\r
2574 for (var j = 0; j < fs.length; j++) {
\r
2575 if (fs[j].name == o.name) { // reloaded classes
\r
2576 fs[j].type = o.type; // update type
\r
2588 * Get the caller method for those methods that are wrapped by
\r
2589 * Clazz.searchAndExecuteMethod.
\r
2591 * @param args caller method's arguments
\r
2592 * @return caller method, null if there is not wrapped by
\r
2593 * Clazz.searchAndExecuteMethod or is called directly.
\r
2597 Clazz.getMixedCallerMethod = function (args) {
\r
2599 var argc = args.callee.caller; // tryToSearchAndExecute
\r
2600 if (argc && argc !== tryToSearchAndExecute) // inherited method's apply
\r
2601 argc = argc.arguments.callee.caller;
\r
2602 if (argc !== tryToSearchAndExecute
\r
2603 || (argc = argc.arguments.callee.caller) !== Clazz.searchAndExecuteMethod)
\r
2605 o.claxxRef = argc.arguments[1];
\r
2606 o.fxName = argc.arguments[2];
\r
2607 o.paramTypes = Clazz.getParamsType(argc.arguments[3]);
\r
2608 argc = argc.arguments.callee.caller // Clazz.generateDelegatingMethod
\r
2609 && argc.arguments.callee.caller; // the private method's caller
\r
2616 /* BH -- The issue here is a subclass calling its private method FOO when
\r
2617 * there is also a private method of the same name in its super class.
\r
2618 * This can ALWAYS be avoided and, one could argue, is bad
\r
2619 * program design anyway. In Jmol, the presence of this possibility
\r
2620 * creates over 8000 references to the global $fx, which was only
\r
2621 * checked in a few rare cases. We can then also remove $fz references.
\r
2626 * Check and return super private method.
\r
2627 * In order make private methods be executed correctly, some extra javascript
\r
2628 * must be inserted into the beggining of the method body of the non-private
\r
2629 * methods that with the same method signature as following:
\r
2631 * var $private = Clazz.checkPrivateMethod (arguments);
\r
2633 * return $private.apply (this, arguments);
\r
2636 * Be cautious about this. The above codes should be insert by Java2Script
\r
2637 * compiler or with double checks to make sure things work correctly.
\r
2639 * @param args caller method's arguments
\r
2640 * @return private method if there are private method fitted for the current
\r
2641 * calling environment
\r
2645 Clazz.checkPrivateMethod = function () {
\r
2646 // get both this one and the one calling it
\r
2647 me = arguments.callee.caller;
\r
2648 caller = arguments.callee.caller.caller;
\r
2649 var stack = me.stacks;
\r
2650 // if their classes are the same, no issue
\r
2651 var mySig = "\\" + Clazz.getParamsType(arguments[0]).join("\\")
\r
2652 if (!me.privateNote) {
\r
2653 me.privateNote = "You are seeing this note because the method "
\r
2654 + me.exName + mySig + " in class "
\r
2655 + me.exClazz.__CLASS_NAME__
\r
2656 + " has a superclass method by the same name (possibly with the same parameters) that is private and "
\r
2657 + " therefore might be called improperly from this class. If your "
\r
2658 + " code does not run properly, or you want to make it run faster, change the name of this method to something else."
\r
2659 System.out.println(me.privateNote);
\r
2660 alert(me.privateNote);
\r
2663 alert([me.exClazz.__CLASS_NAME__, me.exName,
\r
2664 caller.exClazz.__CLASS_NAME__, caller.exName,stack,mySig])
\r
2665 if (stack == null || caller.exClazz == me.exClazz)
\r
2667 // I am being called by a different class...
\r
2669 for (var i = stack.length; --i >= 0;) {
\r
2670 if (stacks[i] != caller.claxxRef)
\r
2672 // and it is on MY class stack
\r
2678 /* var m = Clazz.getMixedCallerMethod (args);
\r
2679 if (m == null) return null;
\r
2680 var callerFx = m.claxxRef.prototype[m.caller.exName];
\r
2681 if (callerFx == null) return null; // may not be in the class hierarchies
\r
2683 if (callerFx.claxxOwner ) {
\r
2684 ppFun = callerFx.claxxOwner.prototype[m.fxName];
\r
2686 var stacks = callerFx.stacks;
\r
2687 for (var i = stacks.length - 1; i >= 0; i--) {
\r
2688 var fx = stacks[i].prototype[m.caller.exName];
\r
2689 if (fx === m.caller) {
\r
2690 ppFun = stacks[i].prototype[m.fxName];
\r
2692 for (var fn in fx) {
\r
2693 if (fn.indexOf ('\\') == 0 && fx[fn] === m.caller) {
\r
2694 ppFun = stacks[i].prototype[m.fxName];
\r
2704 if (ppFun && ppFun.claxxOwner == null) {
\r
2705 ppFun = ppFun["\\" + m.paramTypes];
\r
2707 if (ppFun && ppFun.isPrivate && ppFun !== args.callee) {
\r
2715 //$fz = null; // for private method declaration
\r
2718 // /*# {$no.debug.support} >>x #*/
\r
2720 // * Option to switch on/off of stack traces.
\r
2723 //Clazz.tracingCalling = false;
\r
2726 // Clazz.callingStack = function (caller, owner) {
\r
2727 // this.caller = caller;
\r
2728 // this.owner = owner;
\r
2734 * The first folder is considered as the primary folder.
\r
2735 * And try to be compatiable with _Loader system.
\r
2740 /*** not used in Jmol
\r
2742 if (window["_Loader"] && _Loader.binaryFolders) {
\r
2743 Clazz.binaryFolders = _Loader.binaryFolders;
\r
2745 Clazz.binaryFolders = ["j2s/", "", "j2slib/"];
\r
2748 Clazz.addBinaryFolder = function (bin) {
\r
2750 var bins = Clazz.binaryFolders;
\r
2751 for (var i = 0; i < bins.length; i++) {
\r
2752 if (bins[i] == bin) {
\r
2756 bins[bins.length] = bin;
\r
2759 Clazz.removeBinaryFolder = function (bin) {
\r
2761 var bins = Clazz.binaryFolders;
\r
2762 for (var i = 0; i < bins.length; i++) {
\r
2763 if (bins[i] == bin) {
\r
2764 for (var j = i; j < bins.length - 1; j++) {
\r
2765 bins[j] = bins[j + 1];
\r
2774 Clazz.setPrimaryFolder = function (bin) {
\r
2776 Clazz.removeBinaryFolder (bin);
\r
2777 var bins = Clazz.binaryFolders;
\r
2778 for (var i = bins.length - 1; i >= 0; i--) {
\r
2779 bins[i + 1] = bins[i];
\r
2788 ///////////////// special definitions of standard Java class methods ///////////
\r
2791 * This is a simple implementation for Clazz#load. It just ignore dependencies
\r
2792 * of the class. This will be fine for jar *.z.js file.
\r
2793 * It will be overriden by _Loader#load.
\r
2794 * For more details, see _Loader.js
\r
2798 Clazz.load = function (musts, clazz, optionals, declaration) {
\r
2799 // not used in Jmol
\r
2806 * Invade the Object prototype!
\r
2807 * TODO: make sure that invading Object prototype does not affect other
\r
2808 * existed library, such as Dojo, YUI, Prototype, ...
\r
2810 java.lang.Object = Clazz._O;
\r
2812 Clazz._O.getName = Clazz._innerFunctions.getName;
\r
2815 java.lang.System = System = {
\r
2816 props : null, //new java.util.Properties (),
\r
2818 arraycopy : function (src, srcPos, dest, destPos, length) {
\r
2819 if (src !== dest) {
\r
2820 for (var i = 0; i < length; i++) {
\r
2821 dest[destPos + i] = src[srcPos + i];
\r
2825 for (var i = 0; i < length; i++) {
\r
2826 swap[i] = src[srcPos + i];
\r
2828 for (var i = 0; i < length; i++) {
\r
2829 dest[destPos + i] = swap[i];
\r
2833 currentTimeMillis : function () {
\r
2834 return new Date ().getTime ();
\r
2836 gc : function() {}, // bh
\r
2837 getProperties : function () {
\r
2838 return System.props;
\r
2840 getProperty : function (key, def) {
\r
2842 return System.props.getProperty (key, def);
\r
2843 var v = System.$props[key];
\r
2844 if (typeof v != "undefined")
\r
2846 if (key.indexOf(".") > 0) {
\r
2849 case "java.version":
\r
2851 case "file.separator":
\r
2852 case "path.separator":
\r
2855 case "line.separator":
\r
2856 v = (navigator.userAgent.indexOf("Windows") >= 0 ? "\r\n" : "\n");
\r
2859 case "os.version":
\r
2860 v = navigator.userAgent;
\r
2864 return System.$props[key] = v;
\r
2866 return (arguments.length == 1 ? null : def == null ? key : def); // BH
\r
2868 getSecurityManager : function() { return null }, // bh
\r
2869 setProperties : function (props) {
\r
2870 System.props = props;
\r
2872 lineSeparator : function() { return '\n' }, // bh
\r
2873 setProperty : function (key, val) {
\r
2874 if (!System.props)
\r
2875 return System.$props[key] = val; // BH
\r
2876 System.props.setProperty (key, val);
\r
2880 System.identityHashCode=function(obj){
\r
2884 return obj._$hashcode || (obj._$hashcode = ++Clazz._hashCode)
\r
2888 return obj.toString().hashCode();
\r
2891 for(var s in obj){
\r
2894 return str.hashCode();
\r
2899 System.out = new Clazz._O ();
\r
2900 System.out.__CLASS_NAME__ = "java.io.PrintStream";
\r
2901 System.out.print = function () {};
\r
2902 System.out.printf = function () {};
\r
2903 System.out.println = function () {};
\r
2904 System.out.write = function () {};
\r
2906 System.err = new Clazz._O ();
\r
2907 System.err.__CLASS_NAME__ = "java.io.PrintStream";
\r
2908 System.err.print = function () {};
\r
2909 System.err.printf = function () {};
\r
2910 System.err.println = function () {};
\r
2911 System.err.write = function () {};
\r
2913 Clazz.popup = Clazz.assert = Clazz.log = Clazz.error = window.alert;
\r
2915 Thread = function () {};
\r
2916 Thread.J2S_THREAD = Thread.prototype.J2S_THREAD = new Thread ();
\r
2917 Thread.currentThread = Thread.prototype.currentThread = function () {
\r
2918 return this.J2S_THREAD;
\r
2921 /* not used in Jmol
\r
2922 Clazz.intCast = function (n) { // 32bit
\r
2923 var b1 = (n & 0xff000000) >> 24;
\r
2924 var b2 = (n & 0xff0000) >> 16;
\r
2925 var b3 = (n & 0xff00) >> 8;
\r
2926 var b4 = n & 0xff;
\r
2927 if ((b1 & 0x80) != 0) {
\r
2928 return -(((b1 & 0x7f) << 24) + (b2 << 16) + (b3 << 8) + b4 + 1);
\r
2930 return (b1 << 24) + (b2 << 16) + (b3 << 8) + b4;
\r
2933 Clazz.shortCast = function (s) { // 16bit
\r
2934 var b1 = (n & 0xff00) >> 8;
\r
2935 var b2 = n & 0xff;
\r
2936 if ((b1 & 0x80) != 0) {
\r
2937 return -(((b1 & 0x7f) << 8) + b2 + 1);
\r
2939 return (b1 << 8) + b4;
\r
2943 Clazz.byteCast = function (b) { // 8bit
\r
2944 if ((b & 0x80) != 0) {
\r
2945 return -((b & 0x7f) + 1);
\r
2951 Clazz.charCast = function (c) { // 8bit
\r
2952 return String.fromCharCode (c & 0xff).charAt (0);
\r
2955 Clazz.floatCast = function (f) { // 32bit
\r
2963 * Try to fix JavaScript's shift operator defects on long type numbers.
\r
2966 /* not used in Jmol
\r
2968 Clazz.longMasks = [];
\r
2970 Clazz.longReverseMasks = [];
\r
2972 Clazz.longBits = [];
\r
2976 for (var i = 1; i < 53; i++) {
\r
2977 arr[i] = arr[i - 1] + arr[i - 1]; // * 2 or << 1
\r
2979 Clazz.longBits = arr;
\r
2980 Clazz.longMasks[52] = arr[52];
\r
2981 for (var i = 51; i >= 0; i--) {
\r
2982 Clazz.longMasks[i] = Clazz.longMasks[i + 1] + arr[i];
\r
2984 Clazz.longReverseMasks[0] = arr[0];
\r
2985 for (var i = 1; i < 52; i++) {
\r
2986 Clazz.longReverseMasks[i] = Clazz.longReverseMasks[i - 1] + arr[i];
\r
2991 Clazz.longLeftShift = function (l, o) { // 64bit
\r
2992 if (o == 0) return l;
\r
2993 if (o >= 64) return 0;
\r
2995 error ("[Java2Script] Error : JavaScript does not support long shift!");
\r
2998 if ((l & Clazz.longMasks[o - 1]) != 0) {
\r
2999 error ("[Java2Script] Error : Such shift operator results in wrong calculation!");
\r
3002 var high = l & Clazz.longMasks[52 - 32 + o];
\r
3004 return high * Clazz.longBits[o] + (l & Clazz.longReverseMasks[32 - o]) << 0;
\r
3010 Clazz.intLeftShift = function (n, o) { // 32bit
\r
3011 return (n << o) & 0xffffffff;
\r
3014 Clazz.longRightShift = function (l, o) { // 64bit
\r
3015 if ((l & Clazz.longMasks[52 - 32]) != 0) {
\r
3016 return Math.round((l & Clazz.longMasks[52 - 32]) / Clazz.longBits[32 - o]) + (l & Clazz.longReverseMasks[o]) >> o;
\r
3022 Clazz.intRightShift = function (n, o) { // 32bit
\r
3023 return n >> o; // no needs for this shifting wrapper
\r
3026 Clazz.long0RightShift = function (l, o) { // 64bit
\r
3030 Clazz.int0RightShift = function (n, o) { // 64bit
\r
3031 return n >>> o; // no needs for this shifting wrapper
\r
3035 // Compress the common public API method in shorter name
\r
3037 //$_W=Clazz.declareAnonymous;$_T=Clazz.declareType;
\r
3038 //$_J=Clazz.declarePackage;$_C=Clazz.decorateAsClass;
\r
3039 //$_Z=Clazz.instantialize;$_I=Clazz.declareInterface;$_D=Clazz.isClassDefined;
\r
3040 //$_H=Clazz.pu$h;$_P=Clazz.p0p;$_B=Clazz.prepareCallback;
\r
3041 //$_N=Clazz.innerTypeInstance;$_K=Clazz.makeConstructor;$_U=Clazz.superCall;$_R=Clazz.superConstructor;
\r
3042 //$_M=Clazz.defineMethod;$_V=Clazz.overrideMethod;$_S=Clazz.defineStatics;
\r
3043 //$_E=Clazz.defineEnumConstant;
\r
3044 //$_F=Clazz.cloneFinals;
\r
3045 //$_Y=Clazz.prepareFields;$_A=Clazz.newArray;$_O=Clazz.instanceOf;
\r
3046 //$_G=Clazz.inheritArgs;$_X=Clazz.checkPrivateMethod;$_Q=Clazz.makeFunction;
\r
3047 //$_s=Clazz.registerSerializableFields;
\r
3048 //$_k=Clazz.overrideConstructor;
\r
3051 /////////////////////// inner function support /////////////////////////////////
\r
3054 Clazz.innerFunctionNames = Clazz.innerFunctionNames.concat ([
\r
3055 "getSuperclass", "isAssignableFrom",
\r
3056 "getConstructor",
\r
3057 "getDeclaredMethod", "getDeclaredMethods",
\r
3058 "getMethod", "getMethods",
\r
3059 "getModifiers", /*"isArray",*/ "newInstance"]);
\r
3062 Clazz._innerFunctions.getSuperclass = function () {
\r
3063 return this.superClazz;
\r
3067 Clazz._innerFunctions.isAssignableFrom = function (clazz) {
\r
3068 return Clazz.getInheritedLevel (clazz, this) >= 0;
\r
3072 Clazz._innerFunctions.getConstructor = function () {
\r
3073 return new java.lang.reflect.Constructor (this, [], [],
\r
3074 java.lang.reflect.Modifier.PUBLIC);
\r
3077 * TODO: fix bug for polymorphic methods!
\r
3080 Clazz._innerFunctions.getDeclaredMethods = Clazz._innerFunctions.getMethods = function () {
\r
3082 var p = this.prototype;
\r
3083 for (var attr in p) {
\r
3084 if (typeof p[attr] == "function" && !p[attr].__CLASS_NAME__) {
\r
3085 /* there are polynormical methods. */
\r
3086 ms.push(new java.lang.reflect.Method (this, attr,
\r
3087 [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC));
\r
3091 for (var attr in p) {
\r
3092 if (typeof p[attr] == "function" && !p[attr].__CLASS_NAME__) {
\r
3093 ms.push(new java.lang.reflect.Method (this, attr,
\r
3094 [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC
\r
3095 | java.lang.reflect.Modifier.STATIC));
\r
3101 Clazz._innerFunctions.getDeclaredMethod = Clazz._innerFunctions.getMethod = function (name, clazzes) {
\r
3102 var p = this.prototype;
\r
3103 for (var attr in p) {
\r
3104 if (name == attr && typeof p[attr] == "function"
\r
3105 && !p[attr].__CLASS_NAME__) {
\r
3106 /* there are polynormical methods. */
\r
3107 return new java.lang.reflect.Method (this, attr,
\r
3108 [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC);
\r
3112 for (var attr in p) {
\r
3113 if (name == attr && typeof p[attr] == "function"
\r
3114 && !p[attr].__CLASS_NAME__) {
\r
3115 return new java.lang.reflect.Method (this, attr,
\r
3116 [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC
\r
3117 | java.lang.reflect.Modifier.STATIC);
\r
3123 Clazz._innerFunctions.getModifiers = function () {
\r
3124 return java.lang.reflect.Modifier.PUBLIC;
\r
3127 Clazz._innerFunctions.newInstance = function (a) {
\r
3129 switch(a == null ? 0 : a.length) {
\r
3133 return new clz(a[0]);
\r
3135 return new clz(a[0], a[1]);
\r
3137 return new clz(a[0], a[1], a[2]);
\r
3139 return new clz(a[0], a[1], a[2], a[3]);
\r
3141 var x = "new " + clz.__CLASS_NAME__ + "(";
\r
3142 for (var i = 0; i < a.length; i++)
\r
3143 x += (i == 0 ? "" : ",") + "a[" + i + "]";
\r
3149 //Object.newInstance = Clazz._innerFunctions.newInstance;
\r
3150 ;(function(){ // BH added wrapper here
\r
3151 var inF = Clazz.innerFunctionNames;
\r
3152 for (var i = 0; i < inF.length; i++) {
\r
3153 Clazz._O[inF[i]] = Clazz._innerFunctions[inF[i]];
\r
3154 Array[inF[i]] = Clazz._innerFunctions[inF[i]];
\r
3156 //Array["isArray"] = function () {
\r
3161 //////////////////////////// hotspot and unloading /////////////////////////////
\r
3162 /* For hotspot and unloading */
\r
3164 if (window["Clazz"] && !window["Clazz"].unloadClass) {
\r
3167 Clazz.unloadClass = function (qClazzName) {
\r
3168 var cc = Clazz.evalType (qClazzName);
\r
3170 Clazz.unloadedClasses[qClazzName] = cc;
\r
3171 var clazzName = qClazzName;
\r
3172 var pkgFrags = clazzName.split (/\./);
\r
3174 for (var i = 0; i < pkgFrags.length - 1; i++)
\r
3175 pkg = (pkg ? pkg[pkgFrags[i]] : Clazz.allPackage[pkgFrags[0]]);
\r
3177 Clazz.allPackage[pkgFrags[0]] = null;
\r
3178 window[pkgFrags[0]] = null;
\r
3179 // also try to unload inner or anonymous classes
\r
3180 for (var c in window) {
\r
3181 if (c.indexOf (qClazzName + "$") == 0) {
\r
3182 Clazz.unloadClass (c);
\r
3187 pkg[pkgFrags[pkgFrags.length - 1]] = null;
\r
3188 // also try to unload inner or anonymous classes
\r
3189 for (var c in pkg) {
\r
3190 if (c.indexOf (pkgFrags[pkgFrags.length - 1] + "$") == 0) {
\r
3191 Clazz.unloadClass (pkg.__PKG_NAME__ + "." + c);
\r
3197 if (Clazz.allClasses[qClazzName]) {
\r
3198 Clazz.allClasses[qClazzName] = false;
\r
3199 // also try to unload inner or anonymous classes
\r
3200 for (var c in Clazz.allClasses) {
\r
3201 if (c.indexOf (qClazzName + "$") == 0) {
\r
3202 Clazz.allClasses[c] = false;
\r
3207 for (var m in cc) {
\r
3208 cleanDelegateMethod (cc[m]);
\r
3210 for (var m in cc.prototype) {
\r
3211 cleanDelegateMethod (cc.prototype[m]);
\r
3214 if (Clazz._Loader) {
\r
3215 Clazz._Loader.unloadClassExt(qClazzName);
\r
3224 var cleanDelegateMethod = function (m) {
\r
3227 if (typeof m == "function" && m.lastMethod
\r
3228 && m.lastParams && m.lastClaxxRef) {
\r
3229 m.lastMethod = null;
\r
3230 m.lastParams = null;
\r
3231 m.lastClaxxRef = null;
\r
3235 } // if (window["Clazz"] && !window["Clazz"].unloadClass)
\r
3237 /******************************************************************************
\r
3238 * Copyright (c) 2007 java2script.org and others.
\r
3239 * All rights reserved. This program and the accompanying materials
\r
3240 * are made available under the terms of the Eclipse Public License v1.0
\r
3241 * which accompanies this distribution, and is available at
\r
3242 * http://www.eclipse.org/legal/epl-v10.html
\r
3245 * Zhou Renjian - initial API and implementation
\r
3246 *****************************************************************************/
\r
3248 * @author zhou renjian
\r
3249 * @create July 10, 2006
\r
3252 //if (window["ClazzNode"] == null) {
\r
3255 * Make optimization over class dependency tree.
\r
3259 * ClassLoader Summary
\r
3261 * ClassLoader creates SCRIPT elements and setup class path and onload
\r
3262 * callback to continue class loading.
\r
3264 * In the onload callbacks, _Loader will try to calculate the next-to-be-
\r
3265 * load *.js and load it. In *.js, it will contains some codes like
\r
3266 * Clazz.load (..., "$wt.widgets.Control", ...);
\r
3267 * to provide information to build up the class dependency tree.
\r
3269 * Some known problems of different browsers:
\r
3270 * 1. In IE, loading *.js through SCRIPT will first triggers onreadstatechange
\r
3271 * event, and then executes inner *.js source.
\r
3272 * 2. In Firefox, loading *.js will first executes *.js source and then
\r
3273 * triggers onload event.
\r
3274 * 3. In Opera, similar to IE, but trigger onload event. (TODO: More details
\r
3275 * should be studied. Currently, Opera supports no multiple-thread-loading)
\r
3277 * For class dependency tree, actually, it is not a tree. It is a reference
\r
3278 * net with nodes have n parents and n children. There is a root, which
\r
3279 * ClassLoader knows where to start searching and loading classes, for such
\r
3280 * a net. Each node is a class. Each class may require a set of must-classes,
\r
3281 * which must be loaded before itself getting initialized, and also need a set
\r
3282 * of optional classes, which also be loaded before being called.
\r
3284 * The class loading status will be in 6 stages.
\r
3285 * 1. Unknown, the class is newly introduced by other class.
\r
3286 * 2. Known, the class is already mentioned by other class.
\r
3287 * 3. Loaded, *.js source is in memory, but may not be initialized yet. It
\r
3288 * requires all its must-classes be intiailized, which is in the next stage.
\r
3289 * 4. Musts loaded, all must classes is already loaded and declared.
\r
3290 * 5. Delcared, the class is already declared (_Loader#isClassDefined).
\r
3291 * 6. Optionals loaded, all optional classes is loaded and declared.
\r
3293 * The ClassLoader tries to load all necessary classes in order, and intialize
\r
3294 * them in order. For such job, it will traverse the dependency tree, and try
\r
3295 * to next class to-be-loaded. Sometime, the class dependencies may be in one
\r
3296 * or more cycles, which must be broken down so classes is loaded in correct
\r
3299 * Loading order and intializing order is very important for the ClassLoader.
\r
3300 * The following technical options are considered:
\r
3301 * 1. SCRIPT is loading asynchronously, which means controling order must use
\r
3302 * callback methods to continue.
\r
3303 * 2. Multiple loading threads are later introduced, which requires the
\r
3304 * ClassLoader should use variables to record the class status.
\r
3305 * 3. Different browsers have different loading orders, which means extra tests
\r
3306 * should be tested to make sure loading order won't be broken.
\r
3307 * 4. Java2Script simulator itself have some loading orders that must be
\r
3308 * honored, which means it should be integrated seamlessly to Clazz system.
\r
3309 * 5. Packed *.z.js is introduced to avoid lots of small *.js which requires
\r
3310 * lots of HTTP connections, which means that packed *.z.js should be treated
\r
3311 * specially (There will be mappings for such packed classes).
\r
3312 * 6. *.js or *.css loading may fail according to network status, which means
\r
3313 * another loading try should be performed, so _Loader is more robust.
\r
3314 * 7. SWT lazy loading is later introduced, which means that class loading
\r
3315 * process may be paused and should be resumed later.
\r
3317 * Some known bugs:
\r
3318 * <code>$_L(["$wt.graphics.Drawable","$wt.widgets.Widget"],
\r
3319 * "$wt.widgets.Control", ...</code>
\r
3320 * has errors while must classes in different order such as
\r
3321 * <code>$_L(["$wt.widgets.Widget", "$wt.graphics.Drawable"],
\r
3322 * "$wt.widgets.Control", ...</code>
\r
3325 * Other maybe bug scenarios:
\r
3326 * 1. In <code>_Loader.maxLoadingThreads = 1;</code> single loading thread
\r
3327 * mode, there are no errors, but in default multiple thread loading mode,
\r
3328 * there are errors.
\r
3329 * 2. No errors in one browser, but has errors on other browsers (Browser
\r
3330 * script loading order differences).
\r
3331 * 3. First time loading has errors, but reloading it gets no errors (Maybe
\r
3332 * HTTP connections timeout, but should not accur in local file system, or it
\r
3333 * is a loading bug by using JavaScript timeout thread).
\r
3337 * The following comments with "#" are special configurations for a much
\r
3338 * smaller *.js file size.
\r
3340 * @see net.sf.j2s.lib/src/net/sf/j2s/lib/build/SmartJSCompressor.java
\r
3343 * Static class loader class
\r
3345 Clazz._Loader = Clazz.ClazzLoader = function () {};
\r
3348 * Class dependency tree node
\r
3351 var Node = function () {
\r
3352 this.parents = [];
\r
3354 this.optionals = [];
\r
3355 this.declaration = null;
\r
3356 this.name = null; // id
\r
3358 // this.requires = null;
\r
3359 // this.requiresMap = null;
\r
3360 this.onLoaded = null;
\r
3362 this.random = 0.13412;
\r
3366 ;(function(Clazz, _Loader) {
\r
3368 _Loader._checkLoad = Jmol._checkLoad;
\r
3370 _Loader.updateNodeForFunctionDecoration = function(qName) {
\r
3371 var node = findNode(qName);
\r
3372 if (node && node.status == Node.STATUS_KNOWN) {
\r
3373 window.setTimeout((function(nnn) {
\r
3374 return function() {
\r
3381 Node.prototype.toString = function() {
\r
3382 return this.name || this.path || "ClazzNode";
\r
3385 Node.STATUS_UNKNOWN = 0;
\r
3386 Node.STATUS_KNOWN = 1;
\r
3387 Node.STATUS_CONTENT_LOADED = 2;
\r
3388 Node.STATUS_MUSTS_LOADED = 3;
\r
3389 Node.STATUS_DECLARED = 4;
\r
3390 Node.STATUS_LOAD_COMPLETE = 5;
\r
3396 _Loader.requireLoaderByBase = function (base) {
\r
3397 for (var i = 0; i < loaders.length; i++) {
\r
3398 if (loaders[i].base == base) {
\r
3399 return loaders[i];
\r
3402 var loader = new _Loader ();
\r
3403 loader.base = base;
\r
3404 loaders.push(loader);
\r
3409 * Class dependency tree
\r
3411 var clazzTreeRoot = new Node();
\r
3414 * Used to keep the status whether a given *.js path is loaded or not.
\r
3417 var loadedScripts = {};
\r
3420 * Multiple threads are used to speed up *.js loading.
\r
3423 var inLoadingThreads = 0;
\r
3426 * Maximum of loading threads
\r
3429 var maxLoadingThreads = 6;
\r
3431 var userAgent = navigator.userAgent.toLowerCase ();
\r
3432 var isOpera = (userAgent.indexOf ("opera") != -1);
\r
3433 var isIE = (userAgent.indexOf ("msie") != -1) && !isOpera;
\r
3434 var isGecko = (userAgent.indexOf ("gecko") != -1);
\r
3437 * Opera has different loading order which will result in performance degrade!
\r
3438 * So just return to single thread loading in Opera!
\r
3440 * FIXME: This different loading order also causes bugs in single thread!
\r
3443 maxLoadingThreads = 1;
\r
3444 var index = userAgent.indexOf ("opera/");
\r
3445 if (index != -1) {
\r
3446 var verNumber = 9.0;
\r
3448 verNumber = parseFloat(userAgent.subString (index + 6));
\r
3450 if (verNumber >= 9.6) {
\r
3451 maxLoadingThreads = 6;
\r
3457 * Try to be compatiable with Clazz system.
\r
3458 * In original design _Loader and Clazz are independent!
\r
3459 * -- zhourenjian @ December 23, 2006
\r
3461 var isClassdefined;
\r
3462 var definedClasses;
\r
3464 if (self.Clazz && Clazz.isClassDefined) {
\r
3465 isClassDefined = Clazz.isClassDefined;
\r
3467 definedClasses = {};
\r
3468 isClassDefined = function (clazzName) {
\r
3469 return definedClasses[clazzName] == true;
\r
3474 * Expand the shortened list of class names.
\r
3476 * JU.Log, $.Display, $.Decorations
\r
3477 * will be expanded to
\r
3478 * JU.Log, JU.Display, JU.Decorations
\r
3479 * where "$." stands for the previous class name's package.
\r
3481 * This method will be used to unwrap the required/optional classes list and
\r
3482 * the ignored classes list.
\r
3485 var unwrapArray = function (arr) {
\r
3486 if (!arr || arr.length == 0)
\r
3489 for (var i = 0; i < arr.length; i++) {
\r
3492 if (arr[i].charAt (0) == '$') {
\r
3493 if (arr[i].charAt (1) == '.') {
\r
3496 var idx = last.lastIndexOf (".");
\r
3498 var prefix = last.substring (0, idx);
\r
3499 arr[i] = prefix + arr[i].substring (1);
\r
3502 arr[i] = "org.eclipse.s" + arr[i].substring (1);
\r
3511 * Used to keep to-be-loaded classes.
\r
3514 var classQueue = [];
\r
3517 var classpathMap = {};
\r
3520 var pkgRefCount = 0;
\r
3523 _Loader.loadPackageClasspath = function (pkg, base, isIndex, fSuccess, mode, pt) {
\r
3524 var map = classpathMap;
\r
3525 mode || (mode = 0);
\r
3526 fSuccess || (fSuccess = null);
\r
3530 * In some situation, maybe,
\r
3531 * _Loader.packageClasspath ("java", ..., true);
\r
3532 * is called after other _Loader#packageClasspath, e.g.
\r
3534 * _Loader.packageClasspath ("org.eclipse.swt", "...", true);
\r
3535 * _Loader.packageClasspath ("java", "...", true);
\r
3537 * which is not recommended. But _Loader should try to adjust orders
\r
3538 * which requires "java" to be declared before normal _Loader
\r
3539 * #packageClasspath call before that line! And later that line
\r
3540 * should never initialize "java/package.js" again!
\r
3542 var isPkgDeclared = (isIndex && map["@" + pkg]);
\r
3543 if (mode == 0 && isIndex && !map["@java"] && pkg.indexOf ("java") != 0 && needPackage("java")) {
\r
3544 _Loader.loadPackage("java", fSuccess ? function(_package){_Loader.loadPackageClasspath(pkg, base, isIndex, fSuccess, 1)} : null);
\r
3548 if (pkg instanceof Array) {
\r
3551 if (pt < pkg.length)
\r
3552 _Loader.loadPackageClasspath(pkg[pt], base, isIndex, function(_loadPackageClassPath){_Loader.loadPackageClasspath(pkg, base, isIndex, fSuccess, 1, pt + 1)}, 1);
\r
3556 for (var i = 0; i < pkg.length; i++)
\r
3557 _Loader.loadPackageClasspath(pkg[i], base, isIndex, null);
\r
3567 // support ajax for default
\r
3568 var key = "@net.sf.j2s.ajax";
\r
3571 key = "@net.sf.j2s";
\r
3577 pkg = "org.eclipse.swt";
\r
3580 pkg = "net.sf.j2s.ajax";
\r
3583 pkg = "net.sf.j2s";
\r
3586 if (pkg.lastIndexOf(".*") == pkg.length - 2)
\r
3587 pkg = pkg.substring(0, pkg.length - 2);
\r
3590 if (base) // critical for multiple applets
\r
3591 map["@" + pkg] = base;
\r
3592 if (isIndex && !isPkgDeclared && !window[pkg + ".registered"]) {
\r
3594 if (pkg == "java")
\r
3595 pkg = "core" // JSmol -- moves java/package.js to core/package.js
\r
3596 _Loader.loadClass(pkg + ".package", function () {
\r
3597 if (--pkgRefCount == 0)
\r
3599 //fSuccess && fSuccess();
\r
3600 }, true, true, 1);
\r
3603 fSuccess && fSuccess();
\r
3607 * BH: allows user/developer to load classes even though wrapping and Google
\r
3608 * Closure Compiler has not been run on the class.
\r
3611 Clazz.loadClass = function (name, onLoaded, async) {
\r
3612 if (!self.Class) {
\r
3614 Class.forName = Clazz._4Name;
\r
3615 JavaObject = Clazz._O;
\r
3616 // maybe more here
\r
3618 return (name && _Loader.loadClass(name, onLoaded, true, async, 1));
\r
3622 * Load the given class ant its related classes.
\r
3625 _Loader.loadClass = function (name, onLoaded, forced, async, mode) {
\r
3627 mode || (mode = 0); // BH: not implemented
\r
3628 (async == null) && (async = false);
\r
3630 if (typeof onLoaded == "boolean")
\r
3631 return Clazz.evalType(name);
\r
3633 System.out.println("loadClass " + name)
\r
3635 // Make sure that packageClasspath ("java", base, true);
\r
3636 // is called before any _Loader#loadClass is called.
\r
3638 if (needPackage("java"))
\r
3639 _Loader.loadPackage("java");
\r
3640 if (needPackage("core"))
\r
3641 _Loader.loadPackage("core");
\r
3643 // var swtPkg = "org.eclipse.swt";
\r
3644 // if (name.indexOf (swtPkg) == 0 || name.indexOf ("$wt") == 0) {
\r
3645 // _Loader.assurePackageClasspath (swtPkg);
\r
3647 // if (name.indexOf ("junit") == 0) {
\r
3648 // _Loader.assurePackageClasspath ("junit");
\r
3651 // Any _Loader#loadClass calls will be queued until java.* core classes are loaded.
\r
3653 _Loader.keepOnLoading = true;
\r
3655 if (!forced && (pkgRefCount && name.lastIndexOf(".package") != name.length - 8
\r
3656 || name.indexOf("java.") != 0 && !isClassDefined(runtimeKeyClass)
\r
3658 queueBe4KeyClazz.push([name, onLoaded]);
\r
3661 System.out.println("loadclass-queuing" + name+ runtimeKeyClass + " "+ isClassDefined(runtimeKeyClass))
\r
3666 if ((b = isClassDefined(name)) || isClassExcluded(name)) {
\r
3667 if (b && onLoaded) {
\r
3668 var nn = findNode(name);
\r
3669 if (!nn || nn.status >= Node.STATUS_LOAD_COMPLETE) {
\r
3671 window.setTimeout(onLoaded, 25);
\r
3679 var path = _Loader.getClasspathFor(name);
\r
3680 var existed = loadedScripts[path];
\r
3681 var qq = classQueue;
\r
3683 for (var i = qq.length; --i >= 0;)
\r
3684 if (qq[i].path == path || qq[i].name == name) {
\r
3690 var n = findNode(name);
\r
3692 if (!n.onLoaded) {
\r
3693 n.onLoaded = onLoaded;
\r
3694 } else if (onLoaded != n.onLoaded) {
\r
3695 n.onLoaded = (function (nF, oF) { return function () { nF(); oF() }; }) (n.onLoaded, onLoaded);
\r
3702 var n = (Clazz.unloadedClasses[name] && findNode(name) || new Node());
\r
3705 n.isPackage = (path.lastIndexOf("package.js") == path.length - 10);
\r
3706 mappingPathNameNode(path, name, n);
\r
3707 n.onLoaded = onLoaded;
\r
3708 n.status = Node.STATUS_KNOWN;
\r
3709 var needBeingQueued = false;
\r
3710 for (var i = qq.length; --i >= 0;) {
\r
3711 if (qq[i].status != Node.STATUS_LOAD_COMPLETE) {
\r
3712 needBeingQueued = true;
\r
3717 if (n.isPackage) {//forced
\r
3718 // push class to queue
\r
3719 var pt = qq.length;
\r
3720 for (; --pt >= 0;) {
\r
3721 if (qq[pt].isPackage)
\r
3723 qq[pt + 1] = qq[pt];
\r
3726 } else if (needBeingQueued) {
\r
3729 if (!needBeingQueued) { // can be loaded directly
\r
3730 var bSave = false;
\r
3732 bSave = isLoadingEntryClass;
\r
3733 isLoadingEntryClass = true;
\r
3735 if (forced)onLoaded = null;
\r
3736 addChildClassNode(clazzTreeRoot, n, true);
\r
3737 loadScript(n, n.path, n.requiredBy, false, onLoaded ? function(_loadClass){ isLoadingEntryClass = bSave; onLoaded()}: null);
\r
3742 * Check whether given package's classpath is setup or not.
\r
3743 * Only "java" and "org.eclipse.swt" are accepted in argument.
\r
3746 var needPackage = function(pkg) {
\r
3747 // note that false != null and true != null
\r
3748 return (window[pkg + ".registered"] != null && !classpathMap["@" + pkg]);
\r
3752 _Loader.loadPackage = function(pkg, fSuccess) {
\r
3753 fSuccess || (fSuccess = null);
\r
3754 window[pkg + ".registered"] = false;
\r
3755 _Loader.loadPackageClasspath(pkg,
\r
3756 (_Loader.J2SLibBase || (_Loader.J2SLibBase = (_Loader.getJ2SLibBase() || "j2s/"))),
\r
3761 * Register classes to a given *.z.js path, so only a single *.z.js is loaded
\r
3762 * for all those classes.
\r
3765 _Loader.jarClasspath = function (jar, clazzes) {
\r
3766 if (!(clazzes instanceof Array))
\r
3767 clazzes = [classes];
\r
3768 unwrapArray(clazzes);
\r
3769 for (var i = clazzes.length; --i >= 0;)
\r
3770 classpathMap["#" + clazzes[i]] = jar;
\r
3771 classpathMap["$" + jar] = clazzes;
\r
3775 * Usually be used in .../package.js. All given packages will be registered
\r
3776 * to the same classpath of given prefix package.
\r
3779 _Loader.registerPackages = function (prefix, pkgs) {
\r
3780 //_Loader.checkInteractive ();
\r
3781 var base = _Loader.getClasspathFor (prefix + ".*", true);
\r
3782 for (var i = 0; i < pkgs.length; i++) {
\r
3783 if (window["Clazz"]) {
\r
3784 Clazz.declarePackage (prefix + "." + pkgs[i]);
\r
3786 _Loader.loadPackageClasspath (prefix + "." + pkgs[i], base);
\r
3791 * Using multiple sites to load *.js in multiple threads. Using multiple
\r
3792 * sites may avoid 2 HTTP 1.1 connections recommendation limit.
\r
3793 * Here is a default implementation for http://archive.java2script.org.
\r
3794 * In site archive.java2script.org, there are 6 sites:
\r
3795 * 1. http://archive.java2script.org or http://a.java2script.org
\r
3796 * 2. http://erchive.java2script.org or http://e.java2script.org
\r
3797 * 3. http://irchive.java2script.org or http://i.java2script.org
\r
3798 * 4. http://orchive.java2script.org or http://o.java2script.org
\r
3799 * 5. http://urchive.java2script.org or http://u.java2script.org
\r
3800 * 6. http://yrchive.java2script.org or http://y.java2script.org
\r
3804 _Loader.multipleSites = function (path) {
\r
3805 var deltas = window["j2s.update.delta"];
\r
3806 if (deltas && deltas instanceof Array && deltas.length >= 3) {
\r
3807 var lastOldVersion = null;
\r
3808 var lastNewVersion = null;
\r
3809 for (var i = 0; i < deltas.length / 3; i++) {
\r
3810 var oldVersion = deltas[i + i + i];
\r
3811 if (oldVersion != "$") {
\r
3812 lastOldVersion = oldVersion;
\r
3814 var newVersion = deltas[i + i + i + 1];
\r
3815 if (newVersion != "$") {
\r
3816 lastNewVersion = newVersion;
\r
3818 var relativePath = deltas[i + i + i + 2];
\r
3819 var key = lastOldVersion + "/" + relativePath;
\r
3820 var idx = path.indexOf (key);
\r
3821 if (idx != -1 && idx == path.length - key.length) {
\r
3822 path = path.substring (0, idx) + lastNewVersion + "/" + relativePath;
\r
3827 var length = path.length;
\r
3828 if (maxLoadingThreads > 1
\r
3829 && ((length > 15 && path.substring (0, 15) == "http://archive.")
\r
3830 || (length > 9 && path.substring (0, 9) == "http://a."))) {
\r
3831 var index = path.lastIndexOf("/");
\r
3832 if (index < length - 3) {
\r
3833 var arr = ['a', 'e', 'i', 'o', 'u', 'y'];
\r
3834 var c1 = path.charCodeAt (index + 1);
\r
3835 var c2 = path.charCodeAt (index + 2);
\r
3836 var idx = (length - index) * 3 + c1 * 5 + c2 * 7; // Hash
\r
3837 return path.substring (0, 7) + arr[idx % 6] + path.substring (8);
\r
3845 * Return the *.js path of the given class. Maybe the class is contained
\r
3846 * in a *.z.js jar file.
\r
3847 * @param clazz Given class that the path is to be calculated for. May
\r
3848 * be java.package, or java.lang.String
\r
3849 * @param forRoot Optional argument, if true, the return path will be root
\r
3850 * of the given classs' package root path.
\r
3851 * @param ext Optional argument, if given, it will replace the default ".js"
\r
3855 _Loader.getClasspathFor = function (clazz, forRoot, ext) {
\r
3856 var path = classpathMap["#" + clazz];
\r
3857 if (!path || forRoot || ext) {
\r
3861 clazz = clazz.replace(/\./g, "/");
\r
3862 if ((idx = path.lastIndexOf(clazz)) >= 0
\r
3863 || (idx = clazz.lastIndexOf("/")) >= 0
\r
3864 && (idx = path.lastIndexOf(clazz.substring(0, idx))) >= 0)
\r
3865 base = path.substring(0, idx);
\r
3867 idx = clazz.length + 2;
\r
3868 while ((idx = clazz.lastIndexOf(".", idx - 2)) >= 0)
\r
3869 if ((base = classpathMap["@" + clazz.substring(0, idx)]))
\r
3872 clazz = clazz.replace (/\./g, "/");
\r
3874 if (base == null) {
\r
3875 var bins = "binaryFolders";
\r
3876 base = (window["Clazz"] && Clazz[bins] && Clazz[bins].length ? Clazz[bins][0]
\r
3877 : _Loader[bins] && _Loader[bins].length ? _Loader[bins][0]
\r
3880 path = (base.lastIndexOf("/") == base.length - 1 ? base : base + "/") + (forRoot ? ""
\r
3881 : clazz.lastIndexOf("/*") == clazz.length - 2 ? clazz.substring(0, idx + 1)
\r
3882 : clazz + (!ext ? ".js" : ext.charAt(0) != '.' ? "." + ext : ext));
\r
3884 return path;//_Loader.multipleSites(path);
\r
3888 * To ignore some classes.
\r
3891 _Loader.ignore = function () {
\r
3892 var clazzes = (arguments.length == 1 && arguments[0] instanceof Array ?
\r
3893 clazzes = arguments[0] : null);
\r
3894 var n = (clazzes ? clazzes.length : arguments.length);
\r
3896 clazzes = new Array(n);
\r
3897 for (var i = 0; i < n; i++)
\r
3898 clazzes[i] = arguments[i];
\r
3900 unwrapArray(clazzes);
\r
3901 for (var i = 0; i < n; i++)
\r
3902 excludeClassMap["@" + clazzes[i]] = 1;
\r
3906 * The following *.script* can be overriden to indicate the
\r
3907 * status of classes loading.
\r
3909 * TODO: There should be a Java interface with name like INativeLoaderStatus
\r
3912 _Loader.onScriptLoading = function (file){};
\r
3915 _Loader.onScriptLoaded = function (file, isError){};
\r
3918 _Loader.onScriptInitialized = function (file){};
\r
3921 _Loader.onScriptCompleted = function (file){};
\r
3924 _Loader.onClassUnloaded = function (clazz){};
\r
3927 * After all the classes are loaded, this method will be called.
\r
3928 * Should be overriden to run *.main([]).
\r
3931 _Loader.onGlobalLoaded = function () {};
\r
3934 _Loader.keepOnLoading = true; // never set false in this code
\r
3938 var mapPath2ClassNode = {};
\r
3941 var isClassExcluded = function (clazz) {
\r
3942 return excludeClassMap["@" + clazz];
\r
3945 /* Used to keep ignored classes */
\r
3947 var excludeClassMap = {};
\r
3950 var evaluate = function(file, js) {
\r
3954 if (Clazz._isQuiet)
\r
3956 var s = "[Java2Script] The required class file \n\n" + file + (js.indexOf("[Exception") == 0 && js.indexOf("data: no") ?
\r
3957 "\nwas not found.\n"
\r
3958 : "\ncould not be loaded. Script error: " + e.message + " \n\ndata:\n\n" + js) + "\n\n" + Clazz.getStackTrace();
\r
3963 _Loader.onScriptLoaded(file, false);
\r
3964 tryToLoadNext(file);
\r
3968 var failedHandles = {};
\r
3971 var generateRemovingFunction = function (node) {
\r
3972 return function () {
\r
3973 if (node.readyState != "interactive") {
\r
3975 if (node.parentNode)
\r
3976 node.parentNode.removeChild (node);
\r
3984 var removeScriptNode = function (n) {
\r
3985 if (window["j2s.script.debugging"]) {
\r
3988 // lazily remove script nodes.
\r
3989 window.setTimeout (generateRemovingFunction (n), 1);
\r
3993 Clazz._4Name = function(clazzName, applet, state) {
\r
3994 if (Clazz.isClassDefined(clazzName))
\r
3995 return Clazz.evalType(clazzName);
\r
3996 var f = (Jmol._isAsync && applet ? applet._restoreState(clazzName, state) : null);
\r
3998 return null; // must be already being created
\r
3999 if (_Loader.setLoadingMode(f ? _Loader.MODE_SCRIPT : "xhr.sync")) {
\r
4000 _Loader.loadClass(clazzName, f, false, true, 1);
\r
4001 return null; // this will surely throw an error, but that is OK
\r
4003 //alert ("Using Java reflection: " + clazzName + " for " + applet._id + " \n"+ Clazz.getStackTrace());
\r
4004 _Loader.loadClass(clazzName);
\r
4005 return Clazz.evalType(clazzName);
\r
4009 * BH: possibly useful for debugging
\r
4011 Clazz.currentPath= "";
\r
4014 * Load *.js by adding script elements into head. Hook the onload event to
\r
4015 * load the next class in dependency tree.
\r
4018 var loadScript = function (node, file, why, ignoreOnload, fSuccess, _loadScript) {
\r
4019 Clazz.currentPath = file;
\r
4020 if (ignoreOnload)alert("WHY>>")
\r
4021 //BH removed // maybe some scripts are to be loaded without needs to know onload event.
\r
4022 // if (!ignoreOnload && loadedScripts[file]) {
\r
4023 // _Loader.tryToLoadNext(file);
\r
4026 loadedScripts[file] = true;
\r
4027 // also remove from queue
\r
4028 removeArrayItem(classQueue, file);
\r
4030 // forces not-found message
\r
4031 isUsingXMLHttpRequest = true;
\r
4032 isAsynchronousLoading = false;
\r
4033 if (_Loader._checkLoad) {
\r
4034 System.out.println("\t" + file + (why ? "\n -- required by " + why : "") + " ajax=" + isUsingXMLHttpRequest + " async=" + isAsynchronousLoading)
\r
4037 _Loader.onScriptLoading(file);
\r
4038 if (isUsingXMLHttpRequest && !isAsynchronousLoading) {
\r
4039 // alert("\t" + file + (why ? "\n -- required by " + why : "") + " ajax=" + isUsingXMLHttpRequest + " async=" + isAsynchronousLoading + " " + Clazz.getStackTrace())
\r
4040 // synchronous loading
\r
4041 // works in MSIE locally unless a binary file :)
\r
4042 // from Jmol.api.Interface only
\r
4043 var data = Jmol._getFileData(file);
\r
4045 evaluate(file, data);
\r
4047 alert(e + " loading file " + file + " " + node.name + " " + Clazz.getStackTrace());
\r
4050 // System.out.println("firing in loadScript " + file + " " + (fSuccess && fSuccess.toString()))
\r
4057 System.out.println("for file " + file +" fSuccess = " + (fSuccess ? fSuccess.toString() : ""))
\r
4059 dataType:"script",
\r
4063 success:W3CScriptOnCallback(file, false, fSuccess),
\r
4064 error:W3CScriptOnCallback(file, true, fSuccess)
\r
4066 inLoadingThreads++;
\r
4071 var W3CScriptOnCallback = function (path, forError, fSuccess) {
\r
4072 var s = Clazz.getStackTrace();
\r
4073 // if (!fSuccess)alert("why no fSuccess?" + s)
\r
4074 return function () {
\r
4075 //System.out.println("returning " + (fSuccess ? fSuccess.toString() : "no function ") + s)
\r
4076 if (forError && __debuggingBH)Clazz.alert ("############ forError=" + forError + " path=" + path + " ####" + (forError ? "NOT" : "") + "LOADED###");
\r
4077 if (isGecko && this.timeoutHandle)
\r
4078 window.clearTimeout(this.timeoutHandle), this.timeoutHandle = null;
\r
4079 if (inLoadingThreads > 0)
\r
4080 inLoadingThreads--;
\r
4081 //System.out.println("w3ccalback for " + path + " " + inLoadingThreads + " threads")
\r
4082 this.onload = null;
\r
4083 this.onerror = null;
\r
4085 alert ("There was a problem loading " + path);
\r
4086 _Loader.onScriptLoaded(path, true);
\r
4090 f = function(_W3scriptFS){removeScriptNode(node);tryToLoadNext(path, fSuccess); };
\r
4092 f = function(_W3script){removeScriptNode(node);tryToLoadNext(path)};
\r
4093 if (loadingTimeLag >= 0)
\r
4094 window.setTimeout(function() { tryToLoadNext(path, f); }, loadingTimeLag);
\r
4096 tryToLoadNext(path, f);
\r
4101 var isLoadingEntryClass = true;
\r
4104 var besidesJavaPackage = false;
\r
4107 * After class is loaded, this method will be executed to check whether there
\r
4108 * are classes in the dependency tree that need to be loaded.
\r
4111 var tryToLoadNext = function (file, fSuccess) {
\r
4112 var node = mapPath2ClassNode["@" + file];
\r
4113 if (!node) // maybe class tree root
\r
4116 // check for content loaded
\r
4117 var clazzes = classpathMap["$" + file];
\r
4119 for (var i = 0; i < clazzes.length; i++) {
\r
4120 var name = clazzes[i];
\r
4121 if (name != node.name && (n = findNode(name))) {
\r
4122 if (n.status < Node.STATUS_CONTENT_LOADED) {
\r
4123 n.status = Node.STATUS_CONTENT_LOADED;
\r
4129 var pp = classpathMap["#" + name];
\r
4131 alert (name + " J2S error in tryToLoadNext");
\r
4132 error("Java2Script implementation error! Please report this bug!");
\r
4135 mappingPathNameNode (n.path, name, n);
\r
4136 n.status = Node.STATUS_CONTENT_LOADED;
\r
4137 addChildClassNode(clazzTreeRoot, n, false);
\r
4142 if (node instanceof Array) {
\r
4143 for (var i = 0; i < node.length; i++) {
\r
4144 if (node[i].status < Node.STATUS_CONTENT_LOADED) {
\r
4145 node[i].status = Node.STATUS_CONTENT_LOADED;
\r
4146 updateNode(node[i]);
\r
4149 } else if (node.status < Node.STATUS_CONTENT_LOADED) {
\r
4150 var stillLoading = false;
\r
4151 var ss = document.getElementsByTagName ("SCRIPT");
\r
4152 for (var i = 0; i < ss.length; i++) {
\r
4154 if (ss[i].onreadystatechange && ss[i].onreadystatechange.path == node.path
\r
4155 && ss[i].readyState == "interactive") {
\r
4156 stillLoading = true;
\r
4159 } else if (ss[i].onload && ss[i].onload.path == node.path) {
\r
4160 stillLoading = true;
\r
4164 if (!stillLoading) {
\r
4165 node.status = Node.STATUS_CONTENT_LOADED;
\r
4170 * Maybe in #optinalLoaded inside above _Loader#updateNode calls,
\r
4171 * _Loader.keepOnLoading is set false (Already loaded the wanted
\r
4172 * classes), so here check to stop.
\r
4175 if (!_Loader.keepOnLoading) // set externally
\r
4178 // check for a "must" class that has content and load it
\r
4180 var working = true;
\r
4181 if ((n = findNextMustClass(Node.STATUS_KNOWN))) {
\r
4183 while (inLoadingThreads < maxLoadingThreads) {
\r
4184 if (!(n = findNextMustClass(Node.STATUS_KNOWN)))
\r
4186 loadClassNode(n); // will increase inLoadingThreads!
\r
4188 } else if ((cq = classQueue).length != 0) {
\r
4189 /* queue must be loaded in order! */
\r
4191 if (!loadedScripts[n.path]
\r
4192 || cq.length != 0
\r
4193 || !isLoadingEntryClass
\r
4195 || n.optionals.length) {
\r
4196 addChildClassNode(clazzTreeRoot, n, true);
\r
4197 loadScript(n, n.path, n.requiredBy, false);
\r
4198 } else if (isLoadingEntryClass) {
\r
4200 * The first time reaching here is the time when ClassLoader
\r
4201 * is trying to load entry class. Class with #main method and
\r
4202 * is to be executed is called Entry Class.
\r
4204 * Here when loading entry class, ClassLoader should not call
\r
4205 * the next following loading script. This is because, those
\r
4206 * scripts will try to mark the class as loaded directly and
\r
4207 * then continue to call #onLoaded callback method,
\r
4208 * which results in an script error!
\r
4210 isLoadingEntryClass = false;
\r
4212 } else if ((n = findNextRequiredClass(Node.STATUS_KNOWN))) {
\r
4214 while (inLoadingThreads < maxLoadingThreads) {
\r
4215 if (!(n = findNextRequiredClass(Node.STATUS_KNOWN)))
\r
4217 loadClassNode(n); // will increase inLoadingThreads!
\r
4222 if (working || inLoadingThreads > 0)
\r
4225 // now check all classes that MUST be loaded prior to initialization
\r
4226 // of some other class (static calls, extends, implements)
\r
4227 // and all classes REQUIRED somewhere in that class, possibly by the constructor
\r
4228 // (that is, "new xxxx()" called somewhere in code) and update them
\r
4229 // that have content but are not declared already
\r
4230 var f = [findNextMustClass,findNextRequiredClass];
\r
4231 var lastNode = null;
\r
4232 for (var i = 0; i < 2; i++)
\r
4233 while ((n = f[i](Node.STATUS_CONTENT_LOADED))) {
\r
4234 if (i == 1 && lastNode === n) // Already existed cycle ?
\r
4235 n.status = Node.STATUS_LOAD_COMPLETE;
\r
4240 // check for load cycles
\r
4244 if (!checkCycle(clazzTreeRoot, file))
\r
4248 // and update all MUST and REQUIRED classes that are declared already
\r
4250 for (var i = 0; i < 2; i++) {
\r
4252 while ((n = f[i](Node.STATUS_DECLARED))) {
\r
4253 if (lastNode === n)
\r
4255 updateNode(lastNode = n);
\r
4259 for (var i = 0; i < 2; i++)
\r
4260 while ((n = f[i](Node.STATUS_DECLARED)))
\r
4261 done.push(n), n.status = Node.STATUS_LOAD_COMPLETE;
\r
4262 if (done.length) {
\r
4263 for (var i = 0; i < done.length; i++)
\r
4264 destroyClassNode(done[i]);
\r
4265 for (var i = 0; i < done.length; i++)
\r
4266 if ((f = done[i].onLoaded))
\r
4267 done[i].onLoaded = null, f();
\r
4276 //System.out.println(node.name + " loaded completely" + _Loader.onGlobalLoaded + "\n\n")
\r
4278 //System.out.println("tryToLoadNext firing " + _Loader._classCountOK + "/" + _Loader._classCountPending + " " + fSuccess.toString() + " " + Clazz.getStackTrace())
\r
4280 } else if (_Loader._classCountPending) {
\r
4281 for (var name in _Loader._classPending) {
\r
4282 var n = findNode(name);
\r
4283 System.out.println("class left pending " + name + " " + n);
\r
4291 // System.out.println("I think I'm done "
\r
4292 // + _Loader._classCountOK + "/" + _Loader._classCountPending + " "
\r
4293 //+ _Loader.onGlobalLoaded.toString() + " " + Clazz.getStackTrace()
\r
4295 if (_Loader._checkLoad) {
\r
4296 System.out.println("I think I'm done: SAEM call count: " + SAEMid);
\r
4297 Clazz.showDuplicates(true);
\r
4300 _Loader.onGlobalLoaded();
\r
4307 * There are classes reference cycles. Try to detect and break those cycles.
\r
4310 var checkCycle = function (node, file) {
\r
4312 var len = ts.length;
\r
4313 // add this node to tracks
\r
4317 if (ts[i] === node && ts[i].status >= Node.STATUS_DECLARED)
\r
4320 // this node is already in tracks, and it has been declared already
\r
4321 // for each node in tracks, set its status to "LOAD_COMPLETE"
\r
4322 // update all parents, remove all parents, and fire its onLoaded function
\r
4323 // then clear tracks and return true (keep checking)
\r
4324 if (_Loader._checkLoad) {
\r
4325 var msg = "cycle found loading " + file + " for " + node;
\r
4326 System.out.println(msg)
\r
4328 for (; i < len; i++) {
\r
4330 n.status = Node.STATUS_LOAD_COMPLETE;
\r
4331 destroyClassNode(n); // Same as above
\r
4332 for (var k = 0; k < n.parents.length; k++)
\r
4333 updateNode(n.parents[k]);
\r
4335 var f = n.onLoaded;
\r
4336 if (_Loader._checkLoad) {
\r
4337 var msg = "cycle setting status to LOAD_COMPLETE for " + n.name + (f ? " firing " + f.toString() : "");
\r
4338 System.out.println(msg)
\r
4341 n.onLoaded = null, f();
\r
4346 var a = [node.musts, node.optionals];
\r
4347 for (var j = 0; j < 2; j++)
\r
4348 for (var r = a[j], i = r.length; --i >= 0;)
\r
4349 if (r[i].status == Node.STATUS_DECLARED && checkCycle(r[i], file))
\r
4351 // reset _tracks to its original length
\r
4353 return false; // done
\r
4357 _Loader._classCountPending = 0;
\r
4358 _Loader._classCountOK = 0;
\r
4359 _Loader._classPending = {};
\r
4361 _Loader.showPending = function() {
\r
4363 for (var name in _Loader._classPending) {
\r
4364 var n = findNode(name);
\r
4366 alert("No node for " + name);
\r
4370 System.out.println(showNode("", "", n, "", 0));
\r
4375 var showNode = function(s, names, node, inset, level) {
\r
4376 names += "--" + node.name;
\r
4377 s += names + "\n";
\r
4379 s += inset + " ...\n";
\r
4383 s += inset + "status: " + node.status + "\n";
\r
4384 if (node.parents && node.parents.length && node.parents[0] && node.parents[0].name) {
\r
4385 s += inset + "parents: " + node.parents.length + "\n";
\r
4386 for (var i = 0; i < node.parents.length; i++) {
\r
4387 s = showNode(s, names, node.parents[i], inset + "\t", level+1);
\r
4391 // if (node.requiredBy) {
\r
4392 // s += inset + "requiredBy:\n";
\r
4393 // s = showNode(s, names, node.requiredBy, inset + "\t", level+1);
\r
4400 * Update the dependency tree nodes recursively.
\r
4403 updateNode = function(node, _updateNode) {
\r
4404 if (!node.name || node.status >= Node.STATUS_LOAD_COMPLETE) {
\r
4405 destroyClassNode(node);
\r
4409 // check for declared and also having MUSTS
\r
4410 if (node.musts.length && node.declaration) {
\r
4411 for (var mustLength = node.musts.length, i = mustLength; --i >= 0;) {
\r
4412 var n = node.musts[i];
\r
4413 n.requiredBy = node;
\r
4414 if (n.status < Node.STATUS_DECLARED && isClassDefined (n.name)) {
\r
4415 var nns = []; // a stack for onLoaded events
\r
4416 n.status = Node.STATUS_LOAD_COMPLETE;
\r
4417 destroyClassNode(n); // Same as above
\r
4418 if (n.declaration && n.declaration.clazzList) {
\r
4419 // For those classes within one *.js file, update them synchronously.
\r
4420 for (var j = 0, list = n.declaration.clazzList, l = list.length; j < l; j++) {
\r
4421 var nn = findNode (list[j]);
\r
4422 if (nn && nn.status != Node.STATUS_LOAD_COMPLETE
\r
4424 nn.status = n.status;
\r
4425 nn.declaration = null;
\r
4426 destroyClassNode(nn);
\r
4427 nn.onLoaded && nns.push(nn);
\r
4430 n.declaration = null;
\r
4432 // fire all onLoaded events
\r
4435 for (var j = 0; j < nns.length; j++) {
\r
4436 var onLoaded = nns[j].onLoaded;
\r
4438 nns[j].onLoaded = null;
\r
4443 (n.status == Node.STATUS_CONTENT_LOADED) && updateNode(n); // musts may be changed
\r
4444 if (n.status < Node.STATUS_DECLARED)
\r
4447 if (node.musts.length != mustLength) {
\r
4448 // length changed -- restart!
\r
4449 i = mustLength = node.musts.length;
\r
4456 if (node.status < Node.STATUS_DECLARED) {
\r
4457 var decl = node.declaration;
\r
4459 decl(), decl.executed = true;
\r
4460 if(_Loader._checkLoad) {
\r
4461 if (_Loader._classPending[node.name]) {
\r
4462 delete _Loader._classPending[node.name];
\r
4463 _Loader._classCountOK;
\r
4464 _Loader._classCountPending--;
\r
4465 // System.out.println("OK " + (_Loader._classCountOK) + " FOR " + node.name)
\r
4468 node.status = Node.STATUS_DECLARED;
\r
4469 if (definedClasses)
\r
4470 definedClasses[node.name] = true;
\r
4471 _Loader.onScriptInitialized(node.path);
\r
4472 if (node.declaration && node.declaration.clazzList) {
\r
4473 // For those classes within one *.js file, update them synchronously.
\r
4474 for (var j = 0, list = node.declaration.clazzList, l = list.length; j < l; j++) {
\r
4475 var nn = findNode(list[j]);
\r
4476 if (nn && nn.status != Node.STATUS_DECLARED
\r
4478 nn.status = Node.STATUS_DECLARED;
\r
4479 if (definedClasses)
\r
4480 definedClasses[nn.name] = true;
\r
4481 _Loader.onScriptInitialized(nn.path);
\r
4486 var level = Node.STATUS_DECLARED;
\r
4487 if (node.optionals.length == 0 && node.musts.length == 0
\r
4488 || node.status > Node.STATUS_KNOWN && !node.declaration
\r
4489 || checkStatusIs(node.musts, Node.STATUS_LOAD_COMPLETE)
\r
4490 && checkStatusIs(node.optionals, Node.STATUS_LOAD_COMPLETE)) {
\r
4491 level = Node.STATUS_LOAD_COMPLETE;
\r
4492 if (!doneLoading(node, level))
\r
4494 // For those classes within one *.js file, update them synchronously.
\r
4495 if (node.declaration && node.declaration.clazzList) {
\r
4496 for (var j = 0, list = node.declaration.clazzList, l = list.length; j < l; j++) {
\r
4497 var nn = findNode(list[j]);
\r
4498 if (nn && nn.status != level && nn !== node) {
\r
4499 nn.declaration = null;
\r
4500 if (!doneLoading(nn, level))
\r
4506 // _Loader.updateParents = function (node, level, _updateParents)
\r
4507 if (node.parents && node.parents.length) {
\r
4508 for (var i = 0; i < node.parents.length; i++) {
\r
4509 var p = node.parents[i];
\r
4510 if (p.status < level)
\r
4511 updateNode(p, p.name);
\r
4513 if (level == Node.STATUS_LOAD_COMPLETE)
\r
4514 node.parents = [];
\r
4519 var checkStatusIs = function(arr, status){
\r
4520 for (var i = arr.length; --i >= 0;)
\r
4521 if (arr[i].status < status)
\r
4526 var doneLoading = function(node, level, _doneLoading) {
\r
4527 node.status = level;
\r
4528 _Loader.onScriptCompleted(node.path);
\r
4530 var onLoaded = node.onLoaded;
\r
4532 node.onLoaded = null;
\r
4534 if (!_Loader.keepOnLoading)
\r
4538 destroyClassNode(node);
\r
4543 * Be used to record already used random numbers. And next new random
\r
4544 * number should not be in the property set.
\r
4547 var usedRandoms = {
\r
4552 var getRnd = function() {
\r
4553 while (true) { // get a unique random number
\r
4554 var rnd = Math.random();
\r
4555 var s = "r" + rnd;
\r
4556 if (!usedRandoms[s])
\r
4557 return (usedRandoms[s] = 1, clazzTreeRoot.random = rnd);
\r
4562 var findNode = function(clazzName) {
\r
4564 return findNodeUnderNode(clazzName, clazzTreeRoot);
\r
4568 var findNextRequiredClass = function(status) {
\r
4570 return findNextRequiredNode(clazzTreeRoot, status);
\r
4574 var findNextMustClass = function(status) {
\r
4575 return findNextMustNode(clazzTreeRoot, status);
\r
4579 var findNodeUnderNode = function(clazzName, node) {
\r
4581 // node, then musts then optionals
\r
4582 return (node.name == clazzName ? node
\r
4583 : (n = findNodeWithin(clazzName, node.musts))
\r
4584 || (n = findNodeWithin(clazzName, node.optionals))
\r
4589 var findNodeWithin = function(name, arr) {
\r
4590 var rnd = clazzTreeRoot.random;
\r
4591 for (var i = arr.length; --i >= 0;) {
\r
4593 if (n.name == name)
\r
4595 if (n.random != rnd) {
\r
4597 if ((n = findNodeUnderNode(name, n)))
\r
4605 var checkStatus = function(n, status) {
\r
4606 return (n.status == status
\r
4607 && (status != Node.STATUS_KNOWN || !loadedScripts[n.path])
\r
4608 && (status == Node.STATUS_DECLARED || !isClassDefined (n.name)));
\r
4612 var findNextMustNode = function(node, status) {
\r
4613 for (var i = node.musts.length; --i >= 0;) {
\r
4614 var n = node.musts[i];
\r
4615 if (checkStatus(n, status) || (n = findNextMustNode(n, status)))
\r
4618 return (checkStatus(node, status) ? node : null);
\r
4622 var findNextRequiredNode = function (node, status) {
\r
4623 // search musts first
\r
4624 // search optionals second
\r
4625 // search itself last
\r
4627 return ((n = searchClassArray(node.musts, status))
\r
4628 || (n = searchClassArray(node.optionals, status))
\r
4629 || checkStatus(n = node, status) ? n : null);
\r
4633 var searchClassArray = function (arr, status) {
\r
4635 var rnd = clazzTreeRoot.random;
\r
4636 for (var i = 0; i < arr.length; i++) {
\r
4638 if (checkStatus(n, status))
\r
4640 if (n.random != rnd) {
\r
4641 n.random = rnd; // mark as visited!
\r
4642 if ((n = findNextRequiredNode(n, status)))
\r
4651 * This map variable is used to mark that *.js is correctly loaded.
\r
4652 * In IE, _Loader has defects to detect whether a *.js is correctly
\r
4653 * loaded or not, so inner loading mark is used for detecting.
\r
4656 var innerLoadedScripts = {};
\r
4659 * This method will be called in almost every *.js generated by Java2Script
\r
4663 var load = function (musts, name, optionals, declaration) {
\r
4664 // called as name.load in Jmol
\r
4665 if (name instanceof Array) {
\r
4666 unwrapArray(name);
\r
4667 for (var i = 0; i < name.length; i++)
\r
4668 load(musts, name[i], optionals, declaration, name);
\r
4672 if (_Loader._checkLoad) {
\r
4673 if (_Loader._classPending[name]) {
\r
4674 //alert("duplicate load for " + name)
\r
4676 _Loader._classPending[name] = 1;
\r
4677 if (_Loader._classCountPending++ == 0)
\r
4678 _Loader._classCountOK = 0;
\r
4679 System.out.println("Loading class " + name);
\r
4683 // if (clazz.charAt (0) == '$')
\r
4684 // clazz = "org.eclipse.s" + clazz.substring (1);
\r
4685 var node = mapPath2ClassNode["#" + name];
\r
4686 if (!node) { // load called inside *.z.js?
\r
4687 var n = findNode(name);
\r
4688 node = (n ? n : new Node());
\r
4690 node.path = classpathMap["#" + name] || "unknown";
\r
4691 mappingPathNameNode(node.path, name, node);
\r
4692 node.status = Node.STATUS_KNOWN;
\r
4693 addChildClassNode(clazzTreeRoot, node, false);
\r
4695 processRequired(node, musts, true);
\r
4696 if (arguments.length == 5 && declaration) {
\r
4697 declaration.status = node.status;
\r
4698 declaration.clazzList = arguments[4];
\r
4700 node.declaration = declaration;
\r
4702 node.status = Node.STATUS_CONTENT_LOADED;
\r
4703 processRequired(node, optionals, false);
\r
4707 var processRequired = function(node, arr, isMust) {
\r
4708 if (arr && arr.length) {
\r
4710 for (var i = 0; i < arr.length; i++) {
\r
4711 var name = arr[i];
\r
4714 if (isClassDefined(name)
\r
4715 || isClassExcluded(name))
\r
4717 var n = findNode(name);
\r
4721 n.status = Node.STATUS_KNOWN;
\r
4723 n.requiredBy = node;
\r
4724 addChildClassNode(node, n, isMust);
\r
4730 * Try to be compatiable of Clazz
\r
4732 if (window["Clazz"]) {
\r
4733 Clazz.load = load;
\r
4735 _Loader.load = load;
\r
4738 * Map different class to the same path! Many classes may be packed into
\r
4739 * a *.z.js already.
\r
4742 * @name class name
\r
4743 * @node Node object
\r
4746 var mappingPathNameNode = function (path, name, node) {
\r
4747 var map = mapPath2ClassNode;
\r
4748 var keyPath = "@" + path;
\r
4749 var v = map[keyPath];
\r
4751 if (v instanceof Array) {
\r
4752 var existed = false;
\r
4753 for (var i = 0; i < v.length; i++) {
\r
4754 if (v[i].name == name) {
\r
4762 map[keyPath] = [v, node];
\r
4765 map[keyPath] = node;
\r
4767 map["#" + name] = node;
\r
4771 var loadClassNode = function (node) {
\r
4772 var name = node.name;
\r
4773 if (!isClassDefined (name)
\r
4774 && !isClassExcluded (name)) {
\r
4775 var path = _Loader.getClasspathFor (name/*, true*/);
\r
4777 mappingPathNameNode (path, name, node);
\r
4778 if (!loadedScripts[path]) {
\r
4779 loadScript(node, path, node.requiredBy, false);
\r
4790 var runtimeKeyClass = _Loader.runtimeKeyClass = "java.lang.String";
\r
4793 * Queue used to store classes before key class is loaded.
\r
4796 var queueBe4KeyClazz = [];
\r
4802 * Return J2SLib base path from existed SCRIPT src attribute.
\r
4805 _Loader.getJ2SLibBase = function () {
\r
4806 var o = window["j2s.lib"];
\r
4807 return (o ? o.base + (o.alias == "." ? "" : (o.alias ? o.alias : (o.version ? o.version : "1.0.0")) + "/") : null);
\r
4811 * Indicate whether _Loader is loading script synchronously or
\r
4815 var isAsynchronousLoading = true;
\r
4818 var isUsingXMLHttpRequest = false;
\r
4821 var loadingTimeLag = -1;
\r
4823 _Loader.MODE_SCRIPT = 4;
\r
4824 _Loader.MODE_XHR = 2;
\r
4825 _Loader.MODE_SYNC = 1;
\r
4829 * asynchronous modes:
\r
4830 * async(...).script, async(...).xhr, async(...).xmlhttprequest,
\r
4831 * script.async(...), xhr.async(...), xmlhttprequest.async(...),
\r
4834 * synchronous modes:
\r
4835 * sync(...).xhr, sync(...).xmlhttprequest,
\r
4836 * xhr.sync(...), xmlhttprequest.sync(...),
\r
4837 * xmlhttprequest, xhr
\r
4840 * Script 4; XHR 2; SYNC bit 1;
\r
4843 _Loader.setLoadingMode = function (mode, timeLag) {
\r
4846 if (typeof mode == "string") {
\r
4847 mode = mode.toLowerCase();
\r
4848 if (mode.indexOf("script") >= 0)
\r
4851 async = (mode.indexOf("async") >=0);
\r
4852 async = false; // BH
\r
4854 if (mode & _Loader.MODE_SCRIPT)
\r
4857 async = !(mode & _Loader.MODE_SYNC);
\r
4859 isUsingXMLHttpRequest = ajax;
\r
4860 isAsynchronousLoading = async;
\r
4861 loadingTimeLag = (async && timeLag >= 0 ? timeLag: -1);
\r
4866 var runtimeLoaded = function () {
\r
4867 if (pkgRefCount || !isClassDefined(runtimeKeyClass))
\r
4869 var qbs = queueBe4KeyClazz;
\r
4870 for (var i = 0; i < qbs.length; i++)
\r
4871 _Loader.loadClass(qbs[i][0], qbs[i][1]);
\r
4872 queueBe4KeyClazz = [];
\r
4876 * Load those key *.z.js. This *.z.js will be surely loaded before other
\r
4880 _Loader.loadZJar = function (zjarPath, keyClass) {
\r
4881 // used only by package.js for core.z.js
\r
4883 var isArr = (keyClass instanceof Array);
\r
4885 keyClass = keyClass[keyClass.length - 1];
\r
4887 f = (keyClass == runtimeKeyClass ? runtimeLoaded : null);
\r
4888 _Loader.jarClasspath(zjarPath, isArr ? keyClass : [keyClass]);
\r
4889 // BH note: runtimeKeyClass is java.lang.String
\r
4890 _Loader.loadClass(keyClass, f, true);
\r
4894 var _allNodes = [];
\r
4897 * The method help constructing the multiple-binary class dependency tree.
\r
4900 var addChildClassNode = function (parent, child, isMust) {
\r
4901 var existed = false;
\r
4904 arr = parent.musts;
\r
4905 if (!child.requiredBy)
\r
4906 child.requiredBy = parent;
\r
4907 // if (!parent.requiresMap){
\r
4908 // parent.requires = [];
\r
4909 // parent.requiresMap = {};
\r
4911 // if (!parent.requiresMap[child.name]) {
\r
4912 // parent.requiresMap[child.name] = 1;
\r
4913 // parent.requires.push[child];
\r
4916 arr = parent.optionals;
\r
4918 if (!NodeMap[child.name]) {
\r
4919 _allNodes.push(child)
\r
4920 NodeMap[child.name]=child
\r
4922 for (var i = 0; i < arr.length; i++) {
\r
4923 if (arr[i].name == child.name) {
\r
4930 if (isLoadingEntryClass
\r
4931 && child.name.indexOf("java") != 0
\r
4932 && child.name.indexOf("net.sf.j2s.ajax") != 0) {
\r
4933 if (besidesJavaPackage)
\r
4934 isLoadingEntryClass = false;
\r
4935 besidesJavaPackage = true;
\r
4936 // } else if (child.name.indexOf("org.eclipse.swt") == 0
\r
4937 // || child.name.indexOf("$wt") == 0) {
\r
4938 // window["swt.lazy.loading.callback"] = swtLazyLoading;
\r
4939 // if (needPackage("org.eclipse.swt"))
\r
4940 // return _Loader.loadPackage("org.eclipse.swt", function() {addParentClassNode(child, parent)});
\r
4943 addParentClassNode(child, parent);
\r
4947 var addParentClassNode = function(child, parent) {
\r
4948 if (parent.name && parent != clazzTreeRoot && parent != child)
\r
4949 for (var i = 0; i < child.parents.length; i++)
\r
4950 if (child.parents[i].name == parent.name)
\r
4952 child.parents.push(parent);
\r
4956 var destroyClassNode = function (node) {
\r
4957 var parents = node.parents;
\r
4959 for (var k = parents.length; --k >= 0;)
\r
4960 removeArrayItem(parents[k].musts, node) || removeArrayItem(parents[k].optionals, node);
\r
4964 _Loader.unloadClassExt = function (qClazzName) {
\r
4965 if (definedClasses)
\r
4966 definedClasses[qClazzName] = false;
\r
4967 if (classpathMap["#" + qClazzName]) {
\r
4968 var pp = classpathMap["#" + qClazzName];
\r
4969 classpathMap["#" + qClazzName] = null;
\r
4970 var arr = classpathMap["$" + pp];
\r
4971 removeArrayItem(arr, qClazzName) && (classpathMap["$" + pp] = arr);
\r
4973 var n = findNode(qClazzName);
\r
4975 n.status = Node.STATUS_KNOWN;
\r
4976 loadedScripts[n.path] = false;
\r
4978 var path = _Loader.getClasspathFor (qClazzName);
\r
4979 loadedScripts[path] = false;
\r
4980 innerLoadedScripts[path] && (innerLoadedScripts[path] = false);
\r
4981 _Loader.onClassUnloaded(qClazzName);
\r
4985 var assureInnerClass = function (clzz, fun) {
\r
4986 clzz = clzz.__CLASS_NAME__;
\r
4987 if (Clazz.unloadedClasses[clzz]) {
\r
4988 if (clzz.indexOf("$") >= 0)
\r
4991 var key = clzz + "$";
\r
4992 for (var s in Clazz.unloadedClasses)
\r
4993 if (Clazz.unloadedClasses[s] && s.indexOf(key) == 0)
\r
4995 if (!list.length)
\r
4999 if ((idx1 = fun.indexOf(key)) < 0 || (idx2 = fun.indexOf("\"", idx1 + key.length)) < 0)
\r
5001 clzz = fun.substring(idx1, idx2);
\r
5002 if (!Clazz.unloadedClasses[clzz] || (idx1 = fun.indexOf("{", idx2) + 1) == 0)
\r
5004 if ((idx2 = fun.indexOf("(" + clzz + ",", idx1 + 3)) < 0
\r
5005 || (idx2 = fun.lastIndexOf("}", idx2 - 1)) < 0)
\r
5007 eval(fun.substring(idx1, idx2));
\r
5008 Clazz.unloadedClasses[clzz] = null;
\r
5012 Clazz.binaryFolders = _Loader.binaryFolders = [ _Loader.getJ2SLibBase() ];
\r
5014 })(Clazz, Clazz._Loader);
\r
5017 /******************************************************************************
\r
5018 * Copyright (c) 2007 java2script.org and others.
\r
5019 * All rights reserved. This program and the accompanying materials
\r
5020 * are made available under the terms of the Eclipse Public License v1.0
\r
5021 * which accompanies this distribution, and is available at
\r
5022 * http://www.eclipse.org/legal/epl-v10.html
\r
5025 * Zhou Renjian - initial API and implementation
\r
5026 *****************************************************************************/
\r
5028 * @author zhou renjian
\r
5029 * @create Jan 11, 2007
\r
5032 Clazz._LoaderProgressMonitor = {};
\r
5034 ;(function(CLPM, Jmol) {
\r
5036 var fadeOutTimer = null;
\r
5037 var fadeAlpha = 0;
\r
5038 var monitorEl = null;
\r
5039 var lastScrollTop = 0;
\r
5040 var bindingParent = null;
\r
5042 CLPM.DEFAULT_OPACITY = (Jmol && Jmol._j2sLoadMonitorOpacity ? Jmol._j2sLoadMonitorOpacity : 55);
\r
5045 /*CLPM.initialize = function (parent) {
\r
5046 bindingParent = parent;
\r
5047 if (parent && !attached) {
\r
5049 //Clazz.addEvent (window, "unload", cleanup);
\r
5050 // window.attachEvent ("onunload", cleanup);
\r
5056 CLPM.hideMonitor = function () {
\r
5057 monitorEl.style.display = "none";
\r
5061 CLPM.showStatus = function (msg, fading) {
\r
5066 //Clazz.addEvent (window, "unload", cleanup);
\r
5067 // window.attachEvent ("onunload", cleanup);
\r
5070 clearChildren(monitorEl);
\r
5071 if (msg == null) {
\r
5075 CLPM.hideMonitor();
\r
5080 monitorEl.appendChild(document.createTextNode ("" + msg));
\r
5081 if (monitorEl.style.display == "none") {
\r
5082 monitorEl.style.display = "";
\r
5084 setAlpha(CLPM.DEFAULT_OPACITY);
\r
5085 var offTop = getFixedOffsetTop();
\r
5086 if (lastScrollTop != offTop) {
\r
5087 lastScrollTop = offTop;
\r
5088 monitorEl.style.bottom = (lastScrollTop + 4) + "px";
\r
5095 /* private static */
\r
5096 var clearChildren = function (el) {
\r
5099 for (var i = el.childNodes.length; --i >= 0;) {
\r
5100 var child = el.childNodes[i];
\r
5103 if (child.childNodes && child.childNodes.length)
\r
5104 clearChildren (child);
\r
5106 el.removeChild (child);
\r
5111 var setAlpha = function (alpha) {
\r
5112 if (fadeOutTimer && alpha == CLPM.DEFAULT_OPACITY) {
\r
5113 window.clearTimeout (fadeOutTimer);
\r
5114 fadeOutTimer = null;
\r
5116 fadeAlpha = alpha;
\r
5117 var ua = navigator.userAgent.toLowerCase();
\r
5118 monitorEl.style.filter = "Alpha(Opacity=" + alpha + ")";
\r
5119 monitorEl.style.opacity = alpha / 100.0;
\r
5122 var hidingOnMouseOver = function () {
\r
5123 CLPM.hideMonitor();
\r
5127 var attached = false;
\r
5129 var cleanup = function () {
\r
5130 //if (monitorEl) {
\r
5131 // monitorEl.onmouseover = null;
\r
5134 bindingParent = null;
\r
5135 //Clazz.removeEvent (window, "unload", cleanup);
\r
5136 //window.detachEvent ("onunload", cleanup);
\r
5140 var createHandle = function () {
\r
5141 var div = document.createElement ("DIV");
\r
5142 div.id = "_Loader-status";
\r
5143 div.style.cssText = "position:absolute;bottom:4px;left:4px;padding:2px 8px;"
\r
5144 + "z-index:" + (window["j2s.lib"].monitorZIndex || 10000) + ";background-color:#8e0000;color:yellow;"
\r
5145 + "font-family:Arial, sans-serif;font-size:10pt;white-space:nowrap;";
\r
5146 div.onmouseover = hidingOnMouseOver;
\r
5148 if (bindingParent) {
\r
5149 bindingParent.appendChild(div);
\r
5151 document.body.appendChild(div);
\r
5157 var fadeOut = function () {
\r
5158 if (monitorEl.style.display == "none") return;
\r
5159 if (fadeAlpha == CLPM.DEFAULT_OPACITY) {
\r
5160 fadeOutTimer = window.setTimeout(function () {
\r
5164 } else if (fadeAlpha - 10 >= 0) {
\r
5165 setAlpha(fadeAlpha - 10);
\r
5166 fadeOutTimer = window.setTimeout(function () {
\r
5170 monitorEl.style.display = "none";
\r
5174 var getFixedOffsetTop = function (){
\r
5175 if (bindingParent) {
\r
5176 var b = bindingParent;
\r
5177 return b.scrollTop;
\r
5179 var dua = navigator.userAgent;
\r
5180 var b = document.body;
\r
5181 var p = b.parentNode;
\r
5182 var pcHeight = p.clientHeight;
\r
5183 var bcScrollTop = b.scrollTop + b.offsetTop;
\r
5184 var pcScrollTop = p.scrollTop + p.offsetTop;
\r
5185 return (dua.indexOf("Opera") < 0 && document.all ? (pcHeight == 0 ? bcScrollTop : pcScrollTop)
\r
5186 : dua.indexOf("Gecko") < 0 ? (pcHeight == p.offsetHeight
\r
5187 && pcHeight == p.scrollHeight ? bcScrollTop : pcScrollTop) : bcScrollTop);
\r
5190 /* not used in Jmol
\r
5191 if (window["ClazzLoader"]) {
\r
5192 _Loader.onScriptLoading = function(file) {
\r
5193 CLPM.showStatus("Loading " + file + "...");
\r
5195 _Loader.onScriptLoaded = function(file, isError) {
\r
5196 CLPM.showStatus(file + (isError ? " loading failed." : " loaded."), true);
\r
5198 _Loader.onGlobalLoaded = function(file) {
\r
5199 CLPM.showStatus("Application loaded.", true);
\r
5201 _Loader.onClassUnloaded = function(clazz) {
\r
5202 CLPM.showStatus("Class " + clazz + " is unloaded.", true);
\r
5207 })(Clazz._LoaderProgressMonitor, Jmol);
\r
5210 /******************************************************************************
\r
5211 * Copyright (c) 2007 java2script.org and others.
\r
5212 * All rights reserved. This program and the accompanying materials
\r
5213 * are made available under the terms of the Eclipse Public License v1.0
\r
5214 * which accompanies this distribution, and is available at
\r
5215 * http://www.eclipse.org/legal/epl-v10.html
\r
5218 * Zhou Renjian - initial API and implementation
\r
5219 *****************************************************************************/
\r
5221 * @author zhou renjian
\r
5222 * @create Nov 5, 2005
\r
5225 ;(function(Con, Sys) {
\r
5227 * Setting maxTotalLines to -1 will not limit the console result
\r
5230 Con.maxTotalLines = 10000;
\r
5233 Con.setMaxTotalLines = function (lines) {
\r
5234 Con.maxTotalLines = (lines > 0 ? lines : 999999);
\r
5238 Con.maxLatency = 40;
\r
5241 Con.setMaxLatency = function (latency) {
\r
5242 Con.maxLatency = (latency > 0 ? latency : 40);
\r
5246 Con.pinning = false;
\r
5249 Con.enablePinning = function (enabled) {
\r
5250 Con.pinning = enabled;
\r
5254 Con.linesCount = 0;
\r
5257 Con.metLineBreak = false;
\r
5261 * Give an extension point so external script can create and bind the console
\r
5264 * TODO: provide more template of binding console window to browser.
\r
5267 Con.createConsoleWindow = function (parentEl) {
\r
5268 var console = document.createElement ("DIV");
\r
5269 console.style.cssText = "font-family:monospace, Arial, sans-serif;";
\r
5270 document.body.appendChild (console);
\r
5274 var c160 = String.fromCharCode(160); //nbsp;
\r
5275 c160 += c160+c160+c160;
\r
5278 Con.consoleOutput = function (s, color) {
\r
5279 var o = window["j2s.lib"];
\r
5280 var console = (o && o.console);
\r
5281 if (console && typeof console == "string")
\r
5282 console = document.getElementById(console)
\r
5284 return false; // BH this just means we have turned off all console action
\r
5285 if (Con.linesCount > Con.maxTotalLines) {
\r
5286 for (var i = 0; i < Con.linesCount - Con.maxTotalLines; i++) {
\r
5287 if (console && console.childNodes.length > 0) {
\r
5288 console.removeChild (console.childNodes[0]);
\r
5291 Con.linesCount = Con.maxTotalLines;
\r
5294 var willMeetLineBreak = false;
\r
5295 s = (typeof s == "undefined" ? "" : s == null ? "null" : "" + s);
\r
5296 s = s.replace (/\t/g, c160);
\r
5298 switch (s.charAt(s.length - 1)) {
\r
5301 s = (s.length > 1 ? s.substring (0, s.length - (s.charAt (s.length - 2) == '\r' ? 2 : 1)) : "");
\r
5302 willMeetLineBreak = true;
\r
5307 s = s.replace (/\t/g, c160);
\r
5308 lines = s.split(/\r\n|\r|\n/g);
\r
5309 for (var i = 0, last = lines.length - 1; i <= last; i++) {
\r
5310 var lastLineEl = null;
\r
5311 if (Con.metLineBreak || Con.linesCount == 0
\r
5312 || console.childNodes.length < 1) {
\r
5313 lastLineEl = document.createElement ("DIV");
\r
5314 console.appendChild (lastLineEl);
\r
5315 lastLineEl.style.whiteSpace = "nowrap";
\r
5319 lastLineEl = console.childNodes[console.childNodes.length - 1];
\r
5321 lastLineEl = document.createElement ("DIV");
\r
5322 console.appendChild (lastLineEl);
\r
5323 lastLineEl.style.whiteSpace = "nowrap";
\r
5327 var el = document.createElement ("SPAN");
\r
5328 lastLineEl.appendChild (el);
\r
5329 el.style.whiteSpace = "nowrap";
\r
5331 el.style.color = color;
\r
5333 if (l.length == 0)
\r
5335 el.appendChild(document.createTextNode(l));
\r
5337 console.scrollTop += 100;
\r
5338 Con.metLineBreak = (i != last || willMeetLineBreak);
\r
5341 var cssClazzName = console.parentNode.className;
\r
5342 if (!Con.pinning && cssClazzName
\r
5343 && cssClazzName.indexOf ("composite") != -1) {
\r
5344 console.parentNode.scrollTop = console.parentNode.scrollHeight;
\r
5346 Con.lastOutputTime = new Date ().getTime ();
\r
5350 * Clear all contents inside the console.
\r
5353 Con.clear = function () {
\r
5355 Con.metLineBreak = true;
\r
5356 var o = window["j2s.lib"];
\r
5357 var console = o && o.console;
\r
5358 if (!console || !(console = document.getElementById (console)))
\r
5360 var childNodes = console.childNodes;
\r
5361 for (var i = childNodes.length; --i >= 0;)
\r
5362 console.removeChild (childNodes[i]);
\r
5363 Con.linesCount = 0;
\r
5368 Clazz.alert = function (s) {
\r
5369 Con.consoleOutput (s + "\r\n");
\r
5374 Sys.out.print = function (s) {
\r
5375 Con.consoleOutput (s);
\r
5378 Sys.out.println = function(s) {
\r
5379 Con.consoleOutput(typeof s == "undefined" ? "\r\n" : s == null ? s = "null\r\n" : s + "\r\n");
\r
5382 Sys.out.write = function (buf, offset, len) {
\r
5383 Sys.out.print(String.instantialize(buf).substring(offset, offset+len));
\r
5387 Sys.err.__CLASS_NAME__ = "java.io.PrintStream";
\r
5390 Sys.err.print = function (s) {
\r
5391 Con.consoleOutput (s, "red");
\r
5395 Sys.err.println = function (s) {
\r
5396 Con.consoleOutput (typeof s == "undefined" ? "\r\n" : s == null ? s = "null\r\n" : s + "\r\n", "red");
\r
5399 Sys.err.write = function (buf, offset, len) {
\r
5400 Sys.err.print(String.instantialize(buf).substring(offset, offset+len));
\r
5403 })(Clazz.Console, System);
\r
5405 })(Clazz, Jmol); // requires JSmolCore.js
\r
5407 }; // called by external application
\r