JAL-1807 Bob's JalviewJS prototype first commit
[jalviewjs.git] / site / js / j2sjmol.js
1 // j2sjmol.js \r
2 \r
3 // latest author: Bob Hanson, St. Olaf College, hansonr@stolaf.edu\r
4  \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
8 \r
9 // Java programming notes by Bob Hanson:\r
10 //   \r
11 //   There are a few motifs to avoid when optimizing Java code to work smoothly\r
12 //   with the J2S compiler:\r
13 //   \r
14 //   arrays: \r
15 //   \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
20 //   \r
21 //   numbers:\r
22 //   \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
29 //\r
30 //   general:\r
31 //\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
41 \r
42  // NOTES by Bob Hanson: \r
43  \r
44  // J2S class changes:\r
45 \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
55  // BH or\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
73  \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
78 \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
83  //                            getInterface() \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
96 \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
109 \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
116  \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
125 \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
128  \r
129  // BH 12/1/2012 9:52:26 AM Compiler note: Thread.start() cannot be executed within the constructor;\r
130  \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
134 \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
154  \r
155 \r
156 LoadClazz = function() {\r
157 \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
162 \r
163 c$ = null;\r
164 \r
165 if (!window["j2s.clazzloaded"])\r
166         window["j2s.clazzloaded"] = false;\r
167 \r
168 if (window["j2s.clazzloaded"])return;\r
169 \r
170 window["j2s.clazzloaded"] = true;\r
171 \r
172 window["j2s.object.native"] = true;\r
173 \r
174  // Clazz changes:\r
175 \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
182  *\r
183  * Contributors:\r
184  *     Zhou Renjian - initial API and implementation\r
185  *****************************************************************************/\r
186 /*******\r
187  * @author zhou renjian\r
188  * @create Nov 5, 2005\r
189  *******/\r
190  \r
191 \r
192 /**\r
193  * Class Clazz. All the methods are static in this class.\r
194  */\r
195 /* static */\r
196 /*Class = */ Clazz = {\r
197   _isQuiet: false\r
198 };\r
199 \r
200 ;(function(Clazz, Jmol) {\r
201 \r
202 var __debuggingBH = false;\r
203 var _globals = ["j2s.clazzloaded", "j2s.object.native"];\r
204 Clazz.setGlobal = function(a, v) {\r
205         _globals.push(a);\r
206         window[a] = v;\r
207 }\r
208 \r
209 Clazz.getGlobals = function() {\r
210         return _globals.sort().join("\n");\r
211 }\r
212 \r
213 Clazz.setConsoleDiv = function(d) {\r
214         window["j2s.lib"] && (window["j2s.lib"].console = d);\r
215 };\r
216 \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
220 \r
221 // Jmol.getProfile()\r
222 \r
223 var _profile = (window["j2s.doProfile"]  && self.JSON ? {} : null);\r
224 \r
225 NullObject = function () {};\r
226 \r
227 /* protected */\r
228 Clazz._supportsNativeObject = window["j2s.object.native"];\r
229 \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
234 } else {\r
235         Clazz._O = Object;\r
236 }\r
237 \r
238 Clazz.Console = {};\r
239 Clazz.dateToString = Date.prototype.toString;\r
240 Clazz._hashCode = 0;\r
241 \r
242 var addProto = function(proto, name, func) {\r
243         return proto[name] = func;\r
244 };\r
245 \r
246 ;(function(proto) {\r
247         addProto(proto, "equals", function (obj) {\r
248                 return this == obj;\r
249         });\r
250 \r
251         addProto(proto, "hashCode", function () {\r
252   \r
253     return this._$hashcode || (this._$hashcode = ++Clazz._hashCode)\r
254 \r
255   \r
256                 try {\r
257                         return this.toString ().hashCode ();\r
258                 } catch (e) {\r
259                         var str = ":";\r
260                         for (var s in this) {\r
261                                 str += s + ":"\r
262                         }\r
263                         return str.hashCode ();\r
264                 }\r
265         });\r
266 \r
267         addProto(proto, "getClass", function () { return Clazz.getClass (this); });\r
268 \r
269         addProto(proto, "clone", function () { return Clazz.clone(this); });\r
270 \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
275                         o[i] = me[i];\r
276       }\r
277                 return o;\r
278         }\r
279 /*\r
280  * Methods for thread in Object\r
281  */\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
289 \r
290 })(Clazz._O.prototype);\r
291 \r
292 Clazz.extendJO = function(c, name) {  \r
293         if (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
299                 }\r
300         }\r
301 };\r
302 \r
303 /**\r
304  * Try to fix bug on Safari\r
305  */\r
306 //InternalFunction = Object;\r
307 \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
313                 : clazzName);\r
314 }\r
315 /**\r
316  * Return the class name of the given class or object.\r
317  *\r
318  * @param clazzHost given class or object\r
319  * @return class name\r
320  */\r
321 /* public */\r
322 Clazz.getClassName = function (obj) {\r
323         if (obj == null)\r
324                 return "NullObject";\r
325         if (obj instanceof Clazz.CastedNull)\r
326                 return obj.clazzName;\r
327         switch(typeof obj) {\r
328         case "number":\r
329                 return "n";\r
330         case "boolean":\r
331                 return "b";\r
332         case "string":\r
333                 // Always treat the constant string as String object.\r
334                 // This will be compatiable with Java String instance.\r
335                 return "String";\r
336         case "function":\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
341                 if (idx0 < 0)\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
345                 if (idx2 < 0)\r
346                         return "Object";\r
347                 s = s.substring (idx1, idx2);\r
348                 if (s.indexOf("Array") >= 0)\r
349                         return "Array"; \r
350                 s = s.replace (/^\s+/, "").replace (/\s+$/, "");\r
351                 return (s == "anonymous" || s == "" ? "Function" : s);\r
352         case "object":\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
359                                 return "Number";\r
360                         if (obj instanceof Boolean)\r
361                                 return "Boolean";\r
362                         if (obj instanceof Array)\r
363                                 return "Array";\r
364                         var s = obj.toString();\r
365       // "[object Int32Array]"\r
366                         if (s.charAt(0) == '[')\r
367                                 return Clazz.extractClassName(s);\r
368                 }\r
369         return Clazz.getClassName (obj.constructor, true);\r
370         }\r
371   // some new, unidentified class\r
372   return "Object";\r
373 };\r
374 /**\r
375  * Return the class of the given class or object.\r
376  *\r
377  * @param clazzHost given class or object\r
378  * @return class name\r
379  */\r
380 /* public */\r
381 Clazz.getClass = function (clazzHost) {\r
382         if (!clazzHost)\r
383                 return Clazz._O;        // null/undefined is always treated as Object\r
384         if (typeof clazzHost == "function")\r
385                 return clazzHost;\r
386         var clazzName;\r
387         if (clazzHost instanceof Clazz.CastedNull) {\r
388                 clazzName = clazzHost.clazzName;\r
389         } else {\r
390                 switch (typeof clazzHost) {\r
391                 case "string":\r
392                         return String;\r
393           case "object":\r
394                         if (!clazzHost.__CLASS_NAME__)\r
395                                 return (clazzHost.constructor || Clazz._O);\r
396                         clazzName = clazzHost.__CLASS_NAME__;\r
397                 break;\r
398                 default:\r
399                         return clazzHost.constructor;\r
400                 }\r
401         }\r
402         return Clazz.evalType(clazzName, true);\r
403 };\r
404 \r
405 \r
406 /* private */\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
411                         return true;\r
412         return false;\r
413 };\r
414 \r
415 var args4InheritClass = function () {};\r
416 \r
417 Clazz.inheritArgs = new args4InheritClass ();\r
418 \r
419 /**\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
423  *\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
427  */\r
428 /* protected */\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
436                 }\r
437         }\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
445                 // March 13, 2006\r
446                 clazzThis.prototype = objSuper; \r
447         } else if (clazzSuper !== Number) {\r
448                 clazzThis.prototype = new clazzSuper (Clazz.inheritArgs);\r
449         } else { // Number\r
450                 clazzThis.prototype = new Number ();\r
451         }\r
452         clazzThis.superClazz = clazzSuper;\r
453         /*\r
454          * Is it necessary to reassign the class name?\r
455          * Mar 10, 2006 --josson\r
456          */\r
457         //clazzThis.__CLASS_NAME__ = thisClassName;\r
458         clazzThis.prototype.__CLASS_NAME__ = clazzThis.__CLASS_NAME__;\r
459 };\r
460 \r
461 /**\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
465  * is implemented.\r
466  * \r
467  * @param clazzThis the class to implement\r
468  * @param interfacez Array of interfaces\r
469  */\r
470 /* public */\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
484                                 }\r
485                         }\r
486                 } else {\r
487                         for (var i = 1; i < arguments.length; i++) {\r
488                                 impls.push(arguments[i]);\r
489                                 copyProperties(clazzThis, arguments[i]);\r
490                         }\r
491                 }\r
492         }\r
493 };\r
494 \r
495 /*\r
496  * Copy members of interface\r
497  */\r
498 /* private */\r
499 var copyProperties = function(clazzThis, clazzSuper) {\r
500         for (var o in clazzSuper)\r
501                 if (o != "b$" \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
506 };\r
507 \r
508 /**\r
509  * TODO: More should be done for interface's inheritance\r
510  */\r
511 /* public */\r
512 Clazz.extendInterface = Clazz.implementOf;\r
513 \r
514 /* protected */\r
515 Clazz.equalsOrExtendsLevel = function (clazzThis, clazzAncestor) {\r
516         if (clazzThis === clazzAncestor)\r
517                 return 0;\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
522                         if (level >= 0)\r
523                                 return level + 1;\r
524                 }\r
525         }\r
526         return -1;\r
527 };\r
528 \r
529 /* protected */\r
530 Clazz.getInheritedLevel = function (clazzTarget, clazzBase) {\r
531         if (clazzTarget === clazzBase)\r
532                 return 0;\r
533         var isTgtStr = (typeof clazzTarget == "string");\r
534         if (isTgtStr && ("void" == clazzTarget || "unknown" == clazzTarget))\r
535                 return -1;\r
536         var isBaseStr = (typeof clazzBase == "string");\r
537         if (isBaseStr && ("void" == clazzBase || "unknown" == clazzBase))\r
538                 return -1;\r
539         if (clazzTarget === (isTgtStr ? "NullObject" : NullObject)) {\r
540                 switch (clazzBase) {\r
541     case "n":\r
542     case "b":\r
543       return -1;\r
544                 case Number:\r
545                 case Boolean:\r
546                 case NullObject:\r
547                         break;\r
548                 default:\r
549                         return 0;\r
550                 }\r
551         }\r
552         if (isTgtStr)\r
553                 clazzTarget = Clazz.evalType(clazzTarget);\r
554         if (isBaseStr)\r
555                 clazzBase = Clazz.evalType(clazzBase);\r
556         if (!clazzBase || !clazzTarget)\r
557                 return -1;\r
558         var level = 0;\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
568                         }\r
569                 }\r
570                 zzalc = zzalc.superClazz;\r
571                 if (!zzalc)\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
579                         : -1);\r
580                 level++;\r
581         }\r
582         return level;\r
583 };\r
584 \r
585 \r
586 /**\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
589  * JavaScript way.\r
590  *\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
594  */\r
595 /* public */\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
599 };\r
600 \r
601 /**\r
602  * Call super method of the class. \r
603  * The same effect as Java's expression:\r
604  * <code> super.* () </code>\r
605  * \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
622  */\r
623 /* public */\r
624 Clazz.superCall = function (objThis, clazzThis, funName, funParams) {\r
625         var fx = null;\r
626         var i = -1;\r
627         var clazzFun = objThis[funName];\r
628         if (clazzFun) {\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
633                                 fx = clazzFun;\r
634         \r
635                         }\r
636                 } else if (!clazzFun.stacks && !(clazzFun.lastClaxxRef\r
637                                         && clazzFun.lastClaxxRef.prototype[funName]\r
638                                         && clazzFun.lastClaxxRef.prototype[funName].stacks)) { // super.toString\r
639                         fx = clazzFun;\r
640                 } else { // normal wrapped method\r
641                         var stacks = clazzFun.stacks;\r
642                         if (!stacks)\r
643                                 stacks = clazzFun.lastClaxxRef.prototype[funName].stacks;\r
644                         for (i = stacks.length; --i >= 0;) {\r
645                                 /*\r
646                                  * Once super call is computed precisely, there are no need \r
647                                  * to calculate the inherited level but just an equals\r
648                                  * comparision\r
649                                  */\r
650                                 //var level = Clazz.getInheritedLevel (clazzThis, stacks[i]);\r
651                                 if (clazzThis === stacks[i]) { // level == 0\r
652                                         if (i > 0) {\r
653                                                 fx = stacks[--i].prototype[funName];\r
654                                         } else {\r
655                                                 /*\r
656                                                  * Will this case be reachable?\r
657                                                  * March 4, 2006\r
658                                                  * Should never reach here if all things are converted\r
659                                                  * by Java2Script\r
660                                                  */\r
661                                                 fx = stacks[0].prototype[funName]["\\unknown"];\r
662                                         }\r
663                                         break;\r
664                                 } else if (Clazz.getInheritedLevel (clazzThis, stacks[i]) > 0) {\r
665                                         fx = stacks[i].prototype[funName];\r
666                                         break;\r
667                                 }\r
668                         } // end of for loop\r
669                 } // end of normal wrapped method\r
670         } // end of clazzFun\r
671         if (!fx) {\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
676                 }\r
677                 /* there are members which are initialized out of the constructor */\r
678                 /* No super constructor! */\r
679                 return;\r
680         }\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
686         }\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
693                 }\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
697                 return ret;\r
698         }\r
699         */\r
700         /*# x<< #*/\r
701         return fx.apply (objThis, funParams || []);\r
702 };\r
703 \r
704 /**\r
705  * Call super constructor of the class. \r
706  * The same effect as Java's expression: \r
707  * <code> super () </code>\r
708  */\r
709 /* public */\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
715         }\r
716 };\r
717 \r
718 /**\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
721  * For example,\r
722  * <code> this.call ((String) null); </code>\r
723  */\r
724 /* public */\r
725 Clazz.CastedNull = function (asClazz) {\r
726         if (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
731                 } else {\r
732                         this.clazzName = "" + asClazz;\r
733                 }\r
734         } else {\r
735                 this.clazzName = "Object";\r
736         }\r
737         this.toString = function () {\r
738                 return null;\r
739         };\r
740         this.valueOf = function () {\r
741                 return null;\r
742         };\r
743 };\r
744 \r
745 /**\r
746  * API for Java's casting null.\r
747  * @see Clazz.CastedNull\r
748  *\r
749  * @param asClazz given class\r
750  * @return an instance of class Clazz.CastedNull\r
751  */\r
752 /* public */\r
753 Clazz.castNullAs = function (asClazz) {\r
754         return new Clazz.CastedNull (asClazz);\r
755 };\r
756 \r
757 /////////////////////////// Exception handling ////////////////////////////\r
758 \r
759 /*\r
760  * Use to mark that the Throwable instance is created or not.\r
761  * \r
762  * Called from java.lang.Throwable, as defined in JSmolJavaExt.js\r
763  * \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
767  *        \r
768  */\r
769 /* public */\r
770 Clazz._initializingException = false;\r
771 \r
772 /**\r
773  * BH: used in Throwable\r
774  *  \r
775  */  \r
776 /* public */\r
777 Clazz._callingStackTraces = [];\r
778 \r
779 /** \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
782  */\r
783 /* private */\r
784 var MethodException = function () {\r
785         this.toString = function () {\r
786                 return "J2S MethodException";\r
787         };\r
788 };\r
789 /* private */\r
790 //var MethodNotFoundException = function () {\r
791 //      this.toString = function () {\r
792 //              return "J2S MethodNotFoundException";\r
793 //      };\r
794 //};\r
795 \r
796   var _isNPEExceptionPredicate;\r
797 \r
798 /* super private */\r
799 ;(function() { \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
806    */\r
807   // reproduce NullPointerException for knowing how to detect them, and create detector function Clazz._isNPEExceptionPredicate\r
808   var $$o$$ = null;\r
809   \r
810   try {\r
811         $$o$$.hello();\r
812   } catch (e) {\r
813     var _ex_reg = function(msg, spliterName, spliterRegex) {\r
814         if(!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
819         return regexp;\r
820     };\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
831         }               \r
832   };\r
833 })();\r
834 \r
835 /**sgurin\r
836  * Implements Java's keyword "instanceof" in JavaScript's way **for exception objects**.\r
837  * \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
841  * \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
845  * @author: sgurin\r
846  */\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
852   }\r
853   if (!e.printStackTrace) {\r
854     e.printStackTrace = function(){};\r
855     alert(e + " try/catch path:" + Clazz.getStackTrace(-10));\r
856   }\r
857         if(clazz == Error) {\r
858                 if (("" + e).indexOf("Error") < 0)\r
859       return false;\r
860                 System.out.println (Clazz.getStackTrace());\r
861     return true;\r
862                 // everything here is a Java Exception, not a Java Error\r
863         }\r
864         return (clazz == Exception || clazz == Throwable\r
865                 || clazz == NullPointerException && _isNPEExceptionPredicate(e));\r
866 };\r
867 \r
868 /**\r
869  * BH need to limit this, as JavaScript call stack may be recursive\r
870  */ \r
871 Clazz.getStackTrace = function(n) {\r
872         n || (n = 25);\r
873   // updateNode and updateParents cause infinite loop here\r
874         var s = "\n";\r
875         var c = arguments.callee;\r
876   var showParams = (n < 0);\r
877   if (showParams)\r
878     n = -n;\r
879         for (var i = 0; i < n; i++) {\r
880                 if (!(c = c.caller))\r
881       break;\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
886       break;\r
887     }\r
888     if (showParams) {\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
895       }\r
896     }\r
897         }\r
898         return s;\r
899 }\r
900 \r
901 ///////////////////// method creation ////////////////////////////////\r
902 \r
903 /**\r
904  * Make constructor for the class with the given function body and parameters\r
905  * signature.\r
906  * \r
907  * @param clazzThis host class\r
908  * @param funBody constructor body\r
909  * @param funParams constructor parameters signature\r
910  */\r
911 /* public */\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
916         }\r
917         //clazzThis.con$truct = clazzThis.prototype.con$truct = null;\r
918 };\r
919 \r
920 /**\r
921  * Override constructor for the class with the given function body and\r
922  * parameters signature.\r
923  * \r
924  * @param clazzThis host class\r
925  * @param funBody constructor body\r
926  * @param funParams constructor parameters signature\r
927  */\r
928 /* public */\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
933         }\r
934         //clazzThis.con$truct = clazzThis.prototype.con$truct = null;\r
935 };\r
936 \r
937 \r
938 /*\r
939  * Define method for the class with the given method name and method\r
940  * body and method parameter signature.\r
941  *\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
948  */\r
949 /* public */\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
965         }\r
966   // we have found a duplicate\r
967         var oldFun = null;\r
968         var oldStacks = f$.stacks;\r
969                 if (!oldStacks) {\r
970                         /* method is not defined by Clazz.defineMethod () */\r
971       oldStacks = [];\r
972                         oldFun = f$;\r
973                         if (f$.claxxOwner) {\r
974                                 oldStacks[0] = oldFun.claxxOwner;\r
975                         }\r
976                 }\r
977                 /*\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
981          * method. \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
985          */\r
986         if (!f$.stacks || f$.claxxReference !== clazzThis) {\r
987                 //Generate a new delegating method for the class                \r
988     var id = ++SAEMid;\r
989         var delegate = function () {\r
990                 return searchAndExecuteMethod(id, this, arguments.callee.claxxReference, arguments.callee.methodName, arguments);\r
991         };\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
996                 var arr = [];\r
997                 for (var i = 0; i < oldStacks.length; i++)\r
998                         arr[i] = oldStacks[i];\r
999                 f$.stacks = arr;\r
1000         }\r
1001         var ss = f$.stacks;\r
1002         if (findArrayItem(ss, clazzThis) < 0) ss.push(clazzThis);\r
1003 \r
1004         if (oldFun) {\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
1011                         /*\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
1016                          */\r
1017                         f$["\\unknown"] = oldFun;\r
1018                 }\r
1019         }\r
1020         funBody.exClazz = clazzThis; // make it traceable\r
1021         f$[fpName] = funBody;\r
1022         return f$;\r
1023 };                                                \r
1024 \r
1025 duplicatedMethods = {};\r
1026 \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
1033     if (m) {\r
1034       var s = "Warning! Duplicate method found for " + key;\r
1035       System.out.println(s);\r
1036       Clazz.alert(s);\r
1037       duplicatedMethods[key] = m + 1; \r
1038     } else {\r
1039       duplicatedMethods[key] = 1;\r
1040     }\r
1041   }\r
1042 }\r
1043 \r
1044 Clazz.showDuplicates = function(quiet) {\r
1045   var s = "";\r
1046   var a = duplicatedMethods;\r
1047   var n = 0;\r
1048   for (var key in a)\r
1049     if (a[key] > 1) {\r
1050       s += a[key] + "\t" + key + "\n";\r
1051       n++;\r
1052     }\r
1053   s = "Duplicates: " + n + "\n\n" + s;\r
1054   System.out.println(s);\r
1055   if (!quiet)\r
1056     alert(s);\r
1057 }\r
1058 \r
1059 var findArrayItem = function(arr, item) {\r
1060         if (arr && item)\r
1061                 for (var i = arr.length; --i >= 0;)\r
1062                         if (arr[i] === item)\r
1063                                 return i;\r
1064         return -1;\r
1065 }\r
1066 \r
1067 var removeArrayItem = function(arr, item) {\r
1068         var i = findArrayItem(arr, item);\r
1069         if (i >= 0) {\r
1070                 var n = arr.length - 1;\r
1071                 for (; i < n; i++)\r
1072                         arr[i] = arr[i + 1];\r
1073                 arr.length--;\r
1074                 return true;\r
1075         }\r
1076 }\r
1077 \r
1078 /*\r
1079  * Other developers may need to extend this formatParameters method\r
1080  * to deal complicated situation.\r
1081  */\r
1082 /* protected */\r
1083 var formatParameters = function (funParams) {\r
1084         return (funParams ? funParams.replace (/~([NABSO])/g, \r
1085       function ($0, $1) {\r
1086         switch ($1) {\r
1087         case 'N':\r
1088                 return "n";\r
1089         case 'B':\r
1090                 return "b";\r
1091         case 'S':\r
1092                 return "String";\r
1093         case 'O':\r
1094                 return "Object";\r
1095         case 'A':\r
1096                 return "Array";\r
1097         }\r
1098         return "Unknown";\r
1099       }).replace (/\s+/g, "").replace (/^|,/g, "\\").replace (/\$/g, "org.eclipse.s") : "\\void");\r
1100 };\r
1101 \r
1102 /*\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
1109  *\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
1114  */\r
1115 /* public */\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
1122         /*\r
1123          * Replace old methods with new method. No super methods are kept.\r
1124          */\r
1125         funBody.funParams = fpName; \r
1126         funBody.claxxOwner = clazzThis;\r
1127         return addProto(clazzThis.prototype, funName, funBody);\r
1128 };\r
1129 \r
1130 //////////////  Overridden and Overloaded Java Method Handling //////////////////\r
1131 //                       SAEM (SearchAndExecuteMethod)\r
1132 // adapted by BH\r
1133 //\r
1134 \r
1135 /*\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
1139  */ \r
1140 \r
1141   var __signatures = ""; \r
1142 \r
1143 Clazz.getProfile = function() {\r
1144         var s = "";\r
1145         if (_profile) {\r
1146                 var l = [];\r
1147                 for (var i in _profile) {\r
1148                         var n = "" + _profile[i];\r
1149                         l.push("        ".substring(n.length) + n + "\t" + i);\r
1150                 }\r
1151                 s = l.sort().reverse().join("\r\n");\r
1152                 _profile = {};\r
1153         }\r
1154         return s + __signatures;\r
1155 }\r
1156 \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
1162         _profile[s]++;\r
1163 }\r
1164 \r
1165 /**\r
1166  * Called also by Throwable\r
1167  *  \r
1168 /* public */\r
1169 Clazz.getParamsType = function (funParams) {\r
1170         // bh: optimization here for very common cases\r
1171         var n = funParams.length;\r
1172         switch (n) {\r
1173         case 0:\r
1174                 var params = ["void"];\r
1175                 params.typeString = "\\void";\r
1176                 return params;\r
1177         case 1:\r
1178           // BH just so common\r
1179     switch (typeof obj) {\r
1180     case "number":\r
1181                         var params = ["n"];\r
1182                         params.typeString = "\\n";\r
1183                         return params;\r
1184     case "boolean":\r
1185                         var params = ["b"];\r
1186                         params.typeString = "\\b";\r
1187                         return params;\r
1188                 }\r
1189         }\r
1190 \r
1191         var params = [];\r
1192         params.hasCastedNull = false;\r
1193         if (funParams) {\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
1198                         }\r
1199                 }\r
1200         }\r
1201         params.typeString = "\\" + params.join ('\\');\r
1202         return params;\r
1203 };\r
1204 \r
1205 var SAEMid = 0;\r
1206 xxxSAEMlist = "";\r
1207 \r
1208 //var SAEMarray = [];\r
1209 /**\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
1212  * \r
1213  * Say we have this:\r
1214  * \r
1215  * StringBuffer sb = new StringBuffer(); \r
1216  * sb.append("").append(1);\r
1217  * \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
1221  * \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
1227  * \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
1230  *                     \r
1231  * The only real way to avoid SAEM is: \r
1232  * \r
1233  * 1) to never call super() -- always call a differently named function in a superclass.\r
1234  * 2) don't overload functions \r
1235  *  \r
1236  */   \r
1237 \r
1238 \r
1239 /**\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
1243  *\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
1251  */\r
1252 /* protected */\r
1253 var searchAndExecuteMethod = function (id, objThis, claxxRef, fxName, args, _saem) {\r
1254 \r
1255 //  var fx = SAEMarray[id];\r
1256 //  if (fx) {\r
1257 //    return fx.apply(objThis, args);\r
1258 //  }\r
1259 \r
1260 \r
1261         fx = objThis[fxName];\r
1262         var params = Clazz.getParamsType(args);\r
1263 \r
1264 \r
1265 var s = "SAEM " + claxxRef.__CLASS_NAME__ + "." + fxName + "(" + params+ ")\n";\r
1266 if (xxxSAEMlist.length > 300)xxxSAEMlist = "";\r
1267 xxxSAEMlist += s;\r
1268  \r
1269 \r
1270   if (!fx)    \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
1275                 var methodParams;\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
1282                 } else {\r
1283 //      if (fx.lastMethod) SAEMarray[id] = fx.lastMethod;\r
1284                         methodParams = args;\r
1285                 }\r
1286                 return (fx.lastMethod ? fx.lastMethod.apply(objThis, methodParams) : null);\r
1287         }\r
1288         fx.lastParams = params.typeString;\r
1289         fx.lastClaxxRef = claxxRef;\r
1290 \r
1291         var stacks = fx.stacks;\r
1292         if (!stacks)\r
1293                 stacks = claxxRef.prototype[fxName].stacks;\r
1294         var length = stacks.length;\r
1295 \r
1296         /*\r
1297          * Search the inheritance stacks to get the given class' function\r
1298          */\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
1302                         /*\r
1303                          * First try to search method within the same class scope\r
1304                          * with stacks[i] === claxxRef\r
1305                          */\r
1306                         var clazzFun = stacks[i].prototype[fxName];\r
1307                         var ret = tryToSearchAndExecute(id, fxName, objThis, clazzFun, params,\r
1308                                         args, fx);\r
1309                         if (!(ret instanceof MethodException)) {\r
1310                                 return ret;\r
1311                         }\r
1312                         /*\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
1317                          */\r
1318                         began = true; \r
1319                 } // end of if\r
1320         } // end of for\r
1321         if ("construct" == fxName) {\r
1322                 /*\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
1326                  */\r
1327                 return;\r
1328         }\r
1329         newMethodNotFoundException(objThis, claxxRef, \r
1330                         fxName, params.typeString);\r
1331 };\r
1332 \r
1333 \r
1334 /* private */\r
1335 var tryToSearchAndExecute = function(id, fxName, objThis, clazzFun, params, args, fx, _ttsaem) {\r
1336         var method = [];\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
1342                 generic = false;\r
1343                         continue;\r
1344                 }\r
1345                 /*\r
1346                  * When there is only one method in the class, use the args\r
1347                  * to identify the parameter type.\r
1348                  *\r
1349                  * AbstractCollection.remove (Object)\r
1350                  * AbstractList.remove (int)\r
1351                  * ArrayList.remove (int)\r
1352                  *\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
1356                  */\r
1357                 /*\r
1358                  * See Clazz#defineMethod --Mar 10, 2006, josson\r
1359                  */\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
1364                         break;\r
1365                 }\r
1366         }\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
1373         //if (generic) \r
1374   //{ /* Use the generic method */\r
1375                 /*\r
1376                  * Will this case be reachable?\r
1377                  * March 4, 2006 josson\r
1378                  * \r
1379                  * Reachable for calling #remove (Object) method on \r
1380                  * ArrayList instance\r
1381                  * May 5, 2006 josson\r
1382                  */\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
1388                                 /*\r
1389                                  * For Clazz.CastedNull instances, the type name is\r
1390                                  * already used to indentify the method in searchMethod.\r
1391                                  */\r
1392                                 methodParams[k] = null;\r
1393                         } else {\r
1394                                 methodParams[k] = args[k];\r
1395                         }\r
1396                 }\r
1397         } else {\r
1398                 methodParams = args;\r
1399         }\r
1400         fx.lastMethod = f;\r
1401   //if (!params.hasCastedNull) SAEMarray[id] = f;\r
1402         return f.apply(objThis, methodParams);\r
1403 };\r
1404 \r
1405 /**\r
1406  * Search the existed polymorphic methods to get the matched method with\r
1407  * the given parameter types.\r
1408  *\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
1412  */\r
1413 /* private */\r
1414 var searchMethod = function(roundOne, paramTypes, debug) {\r
1415 \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
1424     \r
1425                         fittedLevel[j] = Clazz.getInheritedLevel (paramTypes[j], \r
1426                                         roundOne[i][j]);\r
1427       //if (debug)alert([paramTypes[j],fittedLevel[j],roundOne[i][j]])    \r
1428                         if (fittedLevel[j] < 0) {\r
1429                                 isFitted = false;\r
1430                                 break;\r
1431                         }\r
1432                 }\r
1433                 if (isFitted) {\r
1434                         fittedLevel[paramTypes.length] = i; // Keep index for later use\r
1435                         roundTwo.push(fittedLevel);\r
1436                 }\r
1437         }\r
1438         if (roundTwo.length == 0)\r
1439                 return null;\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
1448                                 break;\r
1449                         }\r
1450                 }\r
1451                 if (isVectorLesser)\r
1452                         min = resultTwo[i];\r
1453         }\r
1454         var index = min[paramTypes.length]; // Get the previously stored index\r
1455         /*\r
1456          * Return the method parameters' type string as indentifier of the\r
1457          * choosen method.\r
1458          */\r
1459         return roundOne[index].join ('\\');\r
1460 };\r
1461 \r
1462 ////////////////////////////////// package loading ///////////////////////\r
1463 \r
1464 /*\r
1465  * all root packages. e.g. java.*, org.*, com.*\r
1466  */\r
1467 /* protected */\r
1468 Clazz.allPackage = {};\r
1469 \r
1470 /**\r
1471  * Will be used to keep value of whether the class is defined or not.\r
1472  */\r
1473 /* protected */\r
1474 Clazz.allClasses = {};\r
1475 \r
1476 Clazz.lastPackageName = null;\r
1477 Clazz.lastPackage = null;\r
1478 \r
1479 /* protected */\r
1480 Clazz.unloadedClasses = [];\r
1481 \r
1482 /* public */\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
1494                                 }; \r
1495                                 // pkg[pkgFrags[i]] = {};\r
1496                                 if (i == 0) {\r
1497                                         // eval ...\r
1498                                         Clazz.setGlobal(pkgFrags[i], pkg[pkgFrags[i]]);\r
1499                                 }\r
1500                         }\r
1501                         pkg = pkg[pkgFrags[i]]\r
1502                 }\r
1503                 Clazz.lastPackageName = pkgName;\r
1504                 Clazz.lastPackage = pkg;\r
1505                 return pkg;\r
1506         }\r
1507 };\r
1508 \r
1509 /* protected */\r
1510 Clazz.evalType = function (typeStr, isQualified) {\r
1511         var idx = typeStr.lastIndexOf(".");\r
1512         if (idx != -1) {\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
1517         } \r
1518         if (isQualified)\r
1519                 return window[typeStr];\r
1520         switch (typeStr) {\r
1521         case "string":\r
1522                 return String;\r
1523         case "number":\r
1524                 return Number;\r
1525   case "object":\r
1526                 return Clazz._O;\r
1527         case "boolean":\r
1528                 return Boolean;\r
1529         case "function":\r
1530                 return Function;\r
1531   case "void":\r
1532   case "undefined":\r
1533   case "unknown":\r
1534                 return typeStr;\r
1535         case "NullObject":\r
1536                 return NullObject;\r
1537         default:\r
1538                 return window[typeStr];\r
1539         }\r
1540 };\r
1541 \r
1542 /**\r
1543  * Define a class or interface.\r
1544  *\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
1551  */\r
1552 /* public */\r
1553 Clazz.defineType = function (qClazzName, clazzFun, clazzParent, interfacez) {\r
1554         var cf = Clazz.unloadedClasses[qClazzName];\r
1555         if (cf) {\r
1556                 clazzFun = cf;\r
1557         }\r
1558         var idx = qClazzName.lastIndexOf (".");\r
1559         if (idx != -1) {\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
1566                 }\r
1567                 pkg[clazzName] = clazzFun;\r
1568         } else {\r
1569                 if (window[qClazzName]) {\r
1570                         // already defined! Should throw exception!\r
1571                         return window[qClazzName];\r
1572                 }\r
1573                 Clazz.setGlobal(qClazzName, clazzFun);\r
1574         }\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
1581         /*# x<< #*/\r
1582         return clazzFun;\r
1583 };\r
1584 \r
1585 var isSafari = (navigator.userAgent.indexOf ("Safari") != -1);\r
1586 var isSafari4Plus = false;\r
1587 if (isSafari) {\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
1594         }\r
1595 }\r
1596 \r
1597 /* public */\r
1598 Clazz.instantialize = function (objThis, args) {\r
1599 \r
1600 \r
1601         if (args && args.length == 1 && args[0] \r
1602                         && args[0] instanceof args4InheritClass) {\r
1603                 return;\r
1604         }\r
1605         if (objThis instanceof Number) {\r
1606                 objThis.valueOf = function () {\r
1607                         return this;\r
1608                 };\r
1609         }\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
1614                 }\r
1615                 args = argsClone;\r
1616         }\r
1617 \r
1618         var c = objThis.construct;\r
1619         if (c) {\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
1627                                 || (c.stacks \r
1628                                 && c.stacks[c.stacks.length - 1] == objThis.getClass ())) {\r
1629                         /*\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
1633                          */\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
1642                         }\r
1643                         c.apply (objThis, args);\r
1644                         objThis.con$truct.apply (objThis, []);\r
1645                 }\r
1646         } else if (objThis.con$truct) {\r
1647                 objThis.con$truct.apply (objThis, []);\r
1648         }\r
1649 };\r
1650 \r
1651 /**\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
1654  */\r
1655 /*\r
1656  * static final member of interface may be a class, which may\r
1657  * be function.\r
1658  */\r
1659 /* protected */\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
1663 ];\r
1664 \r
1665 /*\r
1666  * Static methods\r
1667  */\r
1668 Clazz._innerFunctions = {\r
1669         /*\r
1670          * Similar to Object#equals\r
1671          */\r
1672    \r
1673   isInstance: function(c) {\r
1674     return Clazz.instanceOf(c, this);\r
1675   },\r
1676   \r
1677         equals : function (aFun) {\r
1678                 return this === aFun;\r
1679         },\r
1680 \r
1681         hashCode : function () {\r
1682                 return this.getName ().hashCode ();\r
1683         },\r
1684 \r
1685         toString : function () {\r
1686                 return "class " + this.getName ();\r
1687         },\r
1688 \r
1689         /*\r
1690          * Similar to Class#getName\r
1691          */\r
1692         getName : function () {\r
1693                 return Clazz.getClassName (this, true);\r
1694         },\r
1695         getCanonicalName : function () {\r
1696                 return this.__CLASS_NAME__;\r
1697         },\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
1702                 if (x != -1) {\r
1703                         baseFolder = baseFolder.substring (0, x);\r
1704                 } else {\r
1705                         baseFolder = Clazz._Loader.getClasspathFor(clazzName, true);\r
1706                 }\r
1707                 var loader = Clazz._Loader.requireLoaderByBase(baseFolder);\r
1708                 loader.getResourceAsStream = Clazz._innerFunctions.getResourceAsStream;\r
1709                 loader.getResource = Clazz._innerFunctions.getResource; // BH\r
1710                 return loader;\r
1711         },\r
1712 \r
1713         getResource : function(name) {\r
1714                 var stream = this.getResourceAsStream(name);\r
1715     return (stream ? stream.url : null);\r
1716         },\r
1717 \r
1718         getResourceAsStream : function (name) {\r
1719                 if (!name)\r
1720                         return null;\r
1721                 name = name.replace (/\\/g, '/');\r
1722                 var baseFolder = null;\r
1723     var fname = name;\r
1724                 var clazzName = this.__CLASS_NAME__;\r
1725                 if (arguments.length == 2 && name.indexOf ('/') != 0) { // additional argument\r
1726                         name = "/" + name;\r
1727                 }\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
1732                                 if (!baseFolder)\r
1733                                         baseFolder = Clazz.binaryFolders[0];\r
1734                         } else if (Clazz._Loader) {\r
1735                                 baseFolder = Clazz._Loader.getClasspathFor(clazzName, true);\r
1736                         }\r
1737                         if (!baseFolder) {\r
1738                                 fname = name.substring (1);\r
1739                         } else {\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
1745                                 }\r
1746                                 fname = baseFolder + name.substring (1);\r
1747                         }\r
1748                 } else {\r
1749                         if (this.base) {\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
1754                                 if (x != -1) {\r
1755                                         baseFolder = baseFolder.substring (0, x);\r
1756                                 } else {\r
1757                                         //baseFolder = null;\r
1758                                         var y = -1;\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
1764                                                         var pkgURL = "/";\r
1765                                                         for (var j = 0; j < k; j++) {\r
1766                                                                 pkgURL += pkgs[j] + "/";\r
1767                                                         }\r
1768                                                         if (pkgURL.length > baseFolder.length) {\r
1769                                                                 break;\r
1770                                                         }\r
1771                                                         if (baseFolder.indexOf (pkgURL) == baseFolder.length - pkgURL.length) {\r
1772                                                                 baseFolder = baseFolder.substring (0, baseFolder.length - pkgURL.length + 1);\r
1773                                                                 break;\r
1774                                                         }\r
1775                                                 }\r
1776                                         } else {\r
1777                                                 baseFolder = Clazz._Loader.getClasspathFor(clazzName, true);\r
1778                                         }\r
1779                                 }\r
1780                         } else {\r
1781                                 var bins = Clazz.binaryFolders;\r
1782                                 if (bins && bins.length) {\r
1783                                         baseFolder = bins[0];\r
1784                                 }\r
1785                         }\r
1786                         if (!baseFolder)\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
1793                         }\r
1794                         if (this.base) {\r
1795                                 fname = baseFolder + name;\r
1796                         } else {\r
1797                                 var idx = clazzName.lastIndexOf ('.');\r
1798                                 if (idx == -1 || this.base) {\r
1799                                         fname = baseFolder + name;\r
1800                                 } else {\r
1801                                         fname = baseFolder + clazzName.substring (0, idx)\r
1802                                                         .replace (/\./g, '/') +  "/" + name;\r
1803                                 }\r
1804                         }            \r
1805                 }\r
1806     var url = null;\r
1807     try {\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
1812       }\r
1813       url = new java.net.URL(fname);\r
1814     } catch (e) {\r
1815     }\r
1816                 var data = (url == null ? null : Jmol._getFileData(fname.toString()));\r
1817     if (!data || data == "error" || data.indexOf("[Exception") == 0)\r
1818       return null;\r
1819     var bytes = new java.lang.String(data).getBytes();      \r
1820     var is = new java.io.BufferedInputStream ( new java.io.ByteArrayInputStream (bytes)); \r
1821     is.url = url;\r
1822                 return is;\r
1823         }/*# {$no.javascript.support} >>x #*/,\r
1824 \r
1825         /*\r
1826          * For JavaScript programmers\r
1827          */\r
1828         defineMethod : function (methodName, funBody, paramTypes) {\r
1829                 Clazz.defineMethod (this, methodName, funBody, paramTypes);\r
1830         },\r
1831 \r
1832         /*\r
1833          * For JavaScript programmers\r
1834          */\r
1835         defineStaticMethod : function (methodName, funBody, paramTypes) {\r
1836                 Clazz.defineMethod (this, methodName, funBody, paramTypes);\r
1837                 this[methodName] = this.prototype[methodName];\r
1838         },\r
1839 \r
1840         /*\r
1841          * For JavaScript programmers\r
1842          */\r
1843         makeConstructor : function (funBody, paramTypes) {\r
1844                 Clazz.makeConstructor (this, funBody, paramTypes);\r
1845         }\r
1846         /*# x<< #*/\r
1847 };\r
1848 \r
1849 \r
1850 var cStack = [];\r
1851 \r
1852 /**\r
1853  * BH: I would like to be able to remove "self.c$" here, but that is tricky.\r
1854  */\r
1855   \r
1856 Clazz.pu$h = function (c) {\r
1857   c || (c = self.c$); // old style\r
1858         c && cStack.push(c);\r
1859 };\r
1860 \r
1861 Clazz.p0p = function () {\r
1862         return cStack.pop();\r
1863 };\r
1864 \r
1865 /* protected */\r
1866 Clazz.decorateAsClass = function (clazzFun, prefix, name, clazzParent, \r
1867                 interfacez, parentClazzInstance, _decorateAsClass) {\r
1868     \r
1869         var prefixName = null;\r
1870         if (prefix) {\r
1871                 prefixName = prefix.__PKG_NAME__;\r
1872                 if (!prefixName)\r
1873                         prefixName = prefix.__CLASS_NAME__;      \r
1874         }\r
1875         var qName = (prefixName ? prefixName + "." : "") + name;\r
1876   \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
1881     }\r
1882   if (Clazz._Loader && Clazz._Loader._checkLoad) {\r
1883     System.out.println("decorating class " + prefixName + "." + name);\r
1884   }\r
1885         var cf = Clazz.unloadedClasses[qName];\r
1886         if (cf) {\r
1887                 clazzFun = cf;\r
1888         }\r
1889         var qName = null;\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
1895         }\r
1896         if (interfacez) {\r
1897                 Clazz.implementOf (clazzFun, interfacez);\r
1898         }\r
1899         return clazzFun;\r
1900 };\r
1901 \r
1902 /* private */\r
1903 var decorateFunction = function (clazzFun, prefix, name, _decorateFunction) {\r
1904         var qName;\r
1905         if (!prefix) {\r
1906                 // e.g. Clazz.declareInterface (null, "ICorePlugin", org.eclipse.ui.IPlugin);\r
1907                 qName = name;\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
1915         } else {\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
1919         }\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
1924         }\r
1925 \r
1926         if (Clazz._Loader) \r
1927     Clazz._Loader.updateNodeForFunctionDecoration(qName);\r
1928 };\r
1929 \r
1930 /* protected */\r
1931 Clazz.declareInterface = function (prefix, name, interfacez, _declareInterface) {\r
1932         var clazzFun = function () {};\r
1933         decorateFunction(clazzFun, prefix, name);\r
1934         if (interfacez) {\r
1935                 Clazz.implementOf (clazzFun, interfacez);\r
1936         }\r
1937         return clazzFun;\r
1938 };\r
1939 \r
1940 /* public */\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
1945         };\r
1946         return Clazz.decorateAsClass (f, prefix, name, clazzParent, interfacez, \r
1947                         parentClazzInstance);\r
1948 };\r
1949 \r
1950 /* public */\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
1956         };\r
1957         return Clazz.decorateAsClass (f, prefix, name, clazzParent, interfacez, \r
1958                         parentClazzInstance);\r
1959 };\r
1960 \r
1961 /* public */\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
1971                 }\r
1972         }\r
1973         if (parentClazzInstance) {\r
1974                 Clazz.inheritClass (clazzFun, clazzParent, parentClazzInstance);\r
1975         } else if (clazzParent) {\r
1976                 Clazz.inheritClass (clazzFun, clazzParent);\r
1977         }\r
1978         if (interfacez) {\r
1979                 Clazz.implementOf (clazzFun, interfacez);\r
1980         }\r
1981         return clazzFun;\r
1982 };\r
1983 \r
1984 \r
1985 ////////////////////////// default package declarations ////////////////////////\r
1986 \r
1987 /* sgurin: preserve Number.prototype.toString */\r
1988 Number.prototype._numberToString=Number.prototype.toString;\r
1989 \r
1990 \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
2002 \r
2003 \r
2004 /*\r
2005  * Consider these interfaces are basic!\r
2006  */\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
2020 \r
2021 java.lang.ClassLoader = {\r
2022         __CLASS_NAME__ : "ClassLoader"\r
2023 };\r
2024 \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
2031  *\r
2032  * Contributors:\r
2033  *     Zhou Renjian - initial API and implementation\r
2034  *****************************************************************************/\r
2035 /*******\r
2036  * @author zhou renjian\r
2037  * @create March 10, 2006\r
2038  *******/\r
2039 \r
2040 /**\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
2044  *\r
2045  * See also http://j2s.sourceforge.net/j2sclazz/\r
2046  */\r
2047  \r
2048 /**\r
2049  * Clazz.MethodNotFoundException is used to notify the developer about calling\r
2050  * methods with incorrect parameters.\r
2051  */\r
2052 /* protected */\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
2056         if (params) {\r
2057                 paramStr = params.substring (1).replace (/\\/g, ",");\r
2058         }\r
2059         var leadingStr = "";\r
2060         if (method && method != "construct") {\r
2061                 leadingStr = "Method";\r
2062         } else {\r
2063                 leadingStr = "Constructor";\r
2064         }\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
2068 };\r
2069 \r
2070 /**\r
2071  * Prepare "callback" for instance of anonymous Class.\r
2072  * For example for the callback:\r
2073  *     this.callbacks.MyEditor.sayHello();\r
2074  *     \r
2075  * This is specifically for inner classes that are referring to \r
2076  * outer class methods and fields.   \r
2077  *\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
2081  * \r
2082  * Attention: parameters should not be null!\r
2083  */\r
2084 /* protected */\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
2090                 var obs = {};\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
2095                 \r
2096                 /*\r
2097                  * TODO: the following line is SWT-specific! Try to move it out!\r
2098                  */\r
2099                 //                      obs[className.replace (/org\.eclipse\.swt\./, "$wt.")] = outerObj;\r
2100 \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
2106                         /*\r
2107                          * TODO: the following line is SWT-specific! Try to move it out!\r
2108                          */\r
2109                         //                              obs[Clazz.getClassName (clazz, true)\r
2110                         //                                              .replace (/org\.eclipse\.swt\./, "$wt.")] = outerObj;\r
2111                         obs[Clazz.getClassName(clazz, true)] = outerObj;\r
2112                 }\r
2113                 var cbs = outerObj[cbName];\r
2114                 if (cbs)\r
2115                         for (var s in cbs)\r
2116                                 obs[s] = cbs[s];\r
2117         }\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
2122         args.length--;\r
2123 };\r
2124 \r
2125 /**\r
2126  * Construct instance of the given inner class.\r
2127  *\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
2132  *\r
2133  * @see Clazz#cloneFinals\r
2134  */\r
2135 /* public */\r
2136 Clazz.innerTypeInstance = function (clazzInner, innerObj, finalVars) {\r
2137         if (!clazzInner)\r
2138                 clazzInner = arguments.callee.caller;\r
2139         var obj;\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
2143                 if (finalVars) {\r
2144                         if (innerObj.f$) {\r
2145                                 var o = {};\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
2150                                 obj.f$ = o;\r
2151                         } else {\r
2152                                 obj.f$ = finalVars;\r
2153                         }\r
2154                 } else if (innerObj.f$) {\r
2155                         obj.f$ = innerObj.f$;\r
2156                 }\r
2157         } else {\r
2158                 switch (arguments.length) {\r
2159                 case 3:\r
2160                         return new clazzInner(innerObj);\r
2161                 case 4:\r
2162                         return (innerObj.__CLASS_NAME__ == clazzInner.__CLASS_NAME__\r
2163                                         && arguments[3] === Clazz.inheritArgs ? innerObj : new clazzInner(innerObj, arguments[3]));\r
2164                 case 5:\r
2165                         return new clazzInner(innerObj, arguments[3], arguments[4]);\r
2166                 case 6:\r
2167                         return new clazzInner(innerObj, arguments[3], arguments[4], \r
2168                                         arguments[5]);\r
2169                 case 7:\r
2170                         return new clazzInner(innerObj, arguments[3], arguments[4], \r
2171                                         arguments[5], arguments[6]);\r
2172                 case 8:\r
2173                         return new clazzInner(innerObj, arguments[3], arguments[4], \r
2174                                         arguments[5], arguments[6], arguments[7]);\r
2175                 case 9:\r
2176                         return new clazzInner(innerObj, arguments[3], arguments[4], \r
2177                                         arguments[5], arguments[6], arguments[7], arguments[8]);\r
2178                 case 10:\r
2179                         return new clazzInner(innerObj, arguments[3], arguments[4], \r
2180                                         arguments[5], arguments[6], arguments[7], arguments[8],\r
2181                                         arguments[9]);\r
2182                 default:\r
2183                         //Should construct instance manually.\r
2184                         obj = new clazzInner(innerObj, Clazz.inheritArgs);\r
2185                         break;\r
2186                 }\r
2187         }\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
2193         return obj;\r
2194 };\r
2195 \r
2196 /**\r
2197  * Clone variables whose modifier is "final".\r
2198  * Usage: var o = Clazz.cloneFinals ("name", name, "age", age);\r
2199  *\r
2200  * @return Object with all final variables\r
2201  */\r
2202 /* public */\r
2203 Clazz.cloneFinals = function () {\r
2204         var o = {};\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
2208         return o;\r
2209 };\r
2210 \r
2211 /* public */\r
2212 Clazz.isClassDefined = Clazz.isDefinedClass = function(clazzName) {\r
2213         if (!clazzName) \r
2214                 return false;           /* consider null or empty name as non-defined class */\r
2215         if (Clazz.allClasses[clazzName])\r
2216                 return true;\r
2217         var pkgFrags = clazzName.split (/\./);\r
2218         var pkg = null;\r
2219         for (var i = 0; i < pkgFrags.length; i++)\r
2220                 if (!(pkg = (pkg ? pkg[pkgFrags[i]] : Clazz.allPackage[pkgFrags[0]]))) {\r
2221                         return false;\r
2222     }\r
2223   return (pkg && (Clazz.allClasses[clazzName] = true));\r
2224 };\r
2225 /**\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
2232  */\r
2233 /* public */\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
2248                 };                                  // BH added\r
2249         }\r
2250         clazzEnum["$ values"].push(o);\r
2251         return o;\r
2252 };\r
2253 \r
2254 //////// (int) conversions //////////\r
2255 \r
2256 Clazz.floatToInt = function (x) {\r
2257         return x < 0 ? Math.ceil(x) : Math.floor(x);\r
2258 };\r
2259 \r
2260 Clazz.floatToByte = Clazz.floatToShort = Clazz.floatToLong = Clazz.floatToInt;\r
2261 Clazz.doubleToByte = Clazz.doubleToShort = Clazz.doubleToLong = Clazz.doubleToInt = Clazz.floatToInt;\r
2262 \r
2263 Clazz.floatToChar = function (x) {\r
2264         return String.fromCharCode (x < 0 ? Math.ceil(x) : Math.floor(x));\r
2265 };\r
2266 \r
2267 Clazz.doubleToChar = Clazz.floatToChar;\r
2268 \r
2269 \r
2270 \r
2271 ///////////////////////////////// Array additions //////////////////////////////\r
2272 //\r
2273 // BH: these are necessary for integer processing, especially\r
2274 //\r
2275 //\r
2276 \r
2277 var getArrayClone = function(nbits) {\r
2278   return function() {\r
2279     var me = this;\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
2283       a[i] = me[i];\r
2284     return a; \r
2285   }\r
2286 }\r
2287 \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
2294 } else {\r
2295         Int32Array = function(n) {\r
2296                 if (!n) n = 0;\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
2300                 return b;\r
2301         }\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
2306 }\r
2307 \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
2314 } else {\r
2315         Clazz.haveFloat64 = false;\r
2316         Float64Array = function(n) {\r
2317                 if (!n) n = 0;\r
2318                 var b = new Array(n);\r
2319                 for (var i = 0; i < n; i++)b[i] = 0.0\r
2320                 return b;\r
2321         };\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
2328 }\r
2329 \r
2330 /**\r
2331  * Make arrays.\r
2332  *\r
2333  * @return the created Array object\r
2334  */\r
2335 /* public */\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
2342         } else {\r
2343                 var args = arguments;\r
2344                 var f = Array;\r
2345         }\r
2346         var dim = args[0];\r
2347         if (typeof dim == "string") {\r
2348                 dim = dim.charCodeAt (0); // char\r
2349         }\r
2350         var len = args.length - 1;\r
2351         var val = args[len];\r
2352   switch (args.length) {\r
2353   case 0: // never\r
2354   case 1:\r
2355                 return []; // maybe never?\r
2356   case 2:\r
2357                 if (val == null)\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
2363                 arr[i] = val;\r
2364           return arr;\r
2365   default:\r
2366         var xargs = new Array (len);\r
2367         for (var i = 0; i < len; i++) {\r
2368                 xargs[i] = args[i + 1];\r
2369         }\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
2375                 }\r
2376         return arr;\r
2377         }\r
2378 };\r
2379 \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
2387         case 0:\r
2388         case 1:  \r
2389                 alert ("ERROR IN newArray32 -- args.length < 2");\r
2390                 return new Array(0);\r
2391         case 2:\r
2392     var isDefined = (dim < 0);\r
2393     if (isDefined)\r
2394       dim = val.length;\r
2395     var a = (val < 0 ? new Array(dim) : isInt32 ? new Int32Array(dim) : new Float64Array(dim));\r
2396     if (isDefined)\r
2397       for (var i = dim; --i >= 0;)\r
2398         a[i] = val[i];\r
2399     return a;\r
2400         }\r
2401         var xargs = new Array(len);\r
2402         for (var i = len; --i >= 0;) {\r
2403                 xargs[i] = args[i + 1];\r
2404         }\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
2410         }\r
2411         return arr;\r
2412 };\r
2413 \r
2414 \r
2415 /**\r
2416  * Make arrays.\r
2417  *\r
2418  * @return the created Array object\r
2419  */\r
2420 /* public */\r
2421 Clazz.newInt32Array  = function () {\r
2422         return Clazz.newArray32(arguments, true);\r
2423 }\r
2424 \r
2425 /**\r
2426  * Make arrays.\r
2427  *\r
2428  * @return the created Array object\r
2429  */\r
2430 /* public */\r
2431 Clazz.newFloat64Array  = function () {\r
2432         return Clazz.newArray32(arguments, false);\r
2433 }\r
2434 \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
2438 \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
2447 \r
2448 \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
2452 }\r
2453 \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
2456 }\r
2457 \r
2458 Clazz.isASS = function(a) {\r
2459         return (a && typeof a == "object" && Clazz.isAS(a[0]));\r
2460 }\r
2461 \r
2462 Clazz.isAP = function(a) {\r
2463         return (a && Clazz.getClassName(a[0]) == "JU.P3");\r
2464 }\r
2465 \r
2466 Clazz.isAI = function(a) {\r
2467         return (a && typeof a == "object" && (Clazz.haveInt32 ? arrayIs(a, "Int32Array") : a.int32Fake ? true : false));\r
2468 }\r
2469 \r
2470 Clazz.isAII = function(a) { // assumes non-null a[0]\r
2471         return (a && typeof a == "object" && Clazz.isAI(a[0]));\r
2472 }\r
2473 \r
2474 Clazz.isAF = function(a) {\r
2475         return (a && typeof a == "object" && (Clazz.haveFloat64 ? arrayIs(a, "Float64Array") : a.float64Fake ? true : false));\r
2476 }\r
2477 \r
2478 Clazz.isAFF = function(a) { // assumes non-null a[0]\r
2479         return (a && typeof a == "object" && Clazz.isAF(a[0]));\r
2480 }\r
2481 \r
2482 Clazz.isAFFF = function(a) { // assumes non-null a[0]\r
2483         return (a && typeof a == "object" && Clazz.isAFF(a[0]));\r
2484 }\r
2485 \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
2488 }\r
2489 \r
2490 \r
2491 /**\r
2492  * Make the RunnableCompatiability instance as a JavaScript function.\r
2493  *\r
2494  * @param jsr Instance of RunnableCompatiability\r
2495  * @return JavaScript function instance represents the method run of jsr.\r
2496  */\r
2497 /* public */\r
2498 /*\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
2502                 if (!e)\r
2503                         e = window.event;\r
2504                 if (jsr.setEvent)\r
2505                         jsr.setEvent(e);\r
2506                 jsr.run();\r
2507                 switch (jsr.returnSet) {\r
2508                 case 1: \r
2509                         return jsr.returnNumber;\r
2510                 case 2:\r
2511                         return jsr.returnBoolean;\r
2512                 case 3:\r
2513                         return jsr.returnObject;\r
2514                 }\r
2515         };\r
2516 };\r
2517 */\r
2518 \r
2519 /* protected */\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
2525         }\r
2526 };\r
2527 \r
2528 /* public */\r
2529 Clazz.prepareFields = function (clazz, fieldsFun) {\r
2530         var stacks = [];\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
2536                 }\r
2537         }\r
2538         addProto(clazz.prototype, "con$truct", clazz.con$truct = function () {\r
2539                 var stacks = arguments.callee.stacks;\r
2540                 if (stacks) {\r
2541                         for (var i = 0; i < stacks.length; i++) {\r
2542                                 stacks[i].apply (this, []);\r
2543                         }\r
2544                 }\r
2545         });\r
2546         stacks.push(fieldsFun);\r
2547         clazz.con$truct.stacks = stacks;\r
2548         clazz.con$truct.index = 0;\r
2549 };\r
2550 \r
2551 /*\r
2552  * Serialize those public or protected fields in class \r
2553  * net.sf.j2s.ajax.SimpleSerializable.\r
2554  */\r
2555 /* protected */\r
2556 /*\r
2557 Clazz.registerSerializableFields = function (clazz) {\r
2558         var args = arguments;\r
2559         var length = args.length;\r
2560         var newArr = [];\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
2564                 }\r
2565         }\r
2566         clazz.declared$Fields = newArr;\r
2567 \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
2577                                         existed = true;\r
2578                                         break;\r
2579                                 }\r
2580                         }\r
2581                         if (!existed)\r
2582                                 fs.push(o);\r
2583                 }\r
2584         }\r
2585 };\r
2586 */\r
2587 /*\r
2588  * Get the caller method for those methods that are wrapped by \r
2589  * Clazz.searchAndExecuteMethod.\r
2590  *\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
2594  */\r
2595 /* protected */\r
2596 /*\r
2597 Clazz.getMixedCallerMethod = function (args) {\r
2598         var o = {};\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
2604                 return null;\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
2610         if (!argc)\r
2611                 return null;\r
2612         o.caller = argc;\r
2613         return o;\r
2614 };\r
2615 */\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
2622  *         \r
2623  */\r
2624 \r
2625 /*\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
2630  * <code>\r
2631  *                      var $private = Clazz.checkPrivateMethod (arguments);\r
2632  *                      if ($private) {\r
2633  *                              return $private.apply (this, arguments);\r
2634  *                      }\r
2635  * </code>\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
2638  *\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
2642  */\r
2643 /* public */\r
2644 \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
2661   }\r
2662   /*\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
2666     return null;\r
2667   // I am being called by a different class...\r
2668   \r
2669   for (var i = stack.length; --i >= 0;) {\r
2670     if (stacks[i] != caller.claxxRef)\r
2671       continue;\r
2672     // and it is on MY class stack\r
2673 //    if (\r
2674      \r
2675   }\r
2676   */\r
2677   \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
2682         var ppFun = null;\r
2683         if (callerFx.claxxOwner ) {\r
2684                 ppFun = callerFx.claxxOwner.prototype[m.fxName];\r
2685         } else {\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
2691                         } else if (fx ) {\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
2695                                                 break;\r
2696                                         }\r
2697                                 }\r
2698                         }\r
2699                         if (ppFun) {\r
2700                                 break;\r
2701                         }\r
2702                 }\r
2703         }\r
2704         if (ppFun && ppFun.claxxOwner == null) {\r
2705                 ppFun = ppFun["\\" + m.paramTypes];\r
2706         }\r
2707         if (ppFun && ppFun.isPrivate && ppFun !== args.callee) {\r
2708                 return ppFun;\r
2709         }\r
2710 */  \r
2711         return null;\r
2712 };\r
2713 \r
2714 \r
2715 //$fz = null; // for private method declaration\r
2716 \r
2717 \r
2718 // /*# {$no.debug.support} >>x #*/\r
2719 // /*\r
2720 //  * Option to switch on/off of stack traces.\r
2721 //  */\r
2722 // /* protect */\r
2723 //Clazz.tracingCalling = false;\r
2724 \r
2725 // /* private */\r
2726 // Clazz.callingStack = function (caller, owner) {\r
2727 //      this.caller = caller;\r
2728 //      this.owner = owner;\r
2729 // };\r
2730 \r
2731 /*# x<< #*/\r
2732 \r
2733 /**\r
2734  * The first folder is considered as the primary folder.\r
2735  * And try to be compatiable with _Loader system.\r
2736  */\r
2737 /* private */\r
2738 \r
2739 \r
2740 /*** not used in Jmol\r
2741  * *\r
2742 if (window["_Loader"] && _Loader.binaryFolders) {\r
2743         Clazz.binaryFolders = _Loader.binaryFolders;\r
2744 } else {\r
2745         Clazz.binaryFolders = ["j2s/", "", "j2slib/"];\r
2746 }\r
2747 \r
2748 Clazz.addBinaryFolder = function (bin) {\r
2749         if (bin) {\r
2750                 var bins = Clazz.binaryFolders;\r
2751                 for (var i = 0; i < bins.length; i++) {\r
2752                         if (bins[i] == bin) {\r
2753                                 return ;\r
2754                         }\r
2755                 }\r
2756                 bins[bins.length] = bin;\r
2757         }\r
2758 };\r
2759 Clazz.removeBinaryFolder = function (bin) {\r
2760         if (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
2766                                 }\r
2767                                 bins.length--;\r
2768                                 return bin;\r
2769                         }\r
2770                 }\r
2771         }\r
2772         return null;\r
2773 };\r
2774 Clazz.setPrimaryFolder = function (bin) {\r
2775         if (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
2780                 }\r
2781                 bins[0] = bin;\r
2782         }\r
2783 };\r
2784 \r
2785 ***/\r
2786 \r
2787 \r
2788 ///////////////// special definitions of standard Java class methods ///////////\r
2789 \r
2790 /**\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
2795  */\r
2796 /* protected */\r
2797 /*\r
2798 Clazz.load = function (musts, clazz, optionals, declaration) {\r
2799         // not used in Jmol\r
2800         if (declaration)\r
2801                 declaration ();\r
2802 };\r
2803 */\r
2804 \r
2805 /*\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
2809  */\r
2810 java.lang.Object = Clazz._O;\r
2811 \r
2812 Clazz._O.getName = Clazz._innerFunctions.getName;\r
2813 \r
2814 \r
2815 java.lang.System = System = {\r
2816         props : null, //new java.util.Properties (),\r
2817         $props : {},\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
2822                         }\r
2823                 } else {\r
2824                         var swap = [];\r
2825                         for (var i = 0; i < length; i++) {\r
2826                                 swap[i] = src[srcPos + i];\r
2827                         }\r
2828                         for (var i = 0; i < length; i++) {\r
2829                                 dest[destPos + i] = swap[i];\r
2830                         }\r
2831                 }\r
2832         },\r
2833         currentTimeMillis : function () {\r
2834                 return new Date ().getTime ();\r
2835         },\r
2836         gc : function() {}, // bh\r
2837         getProperties : function () {\r
2838                 return System.props;\r
2839         },\r
2840         getProperty : function (key, def) {\r
2841                 if (System.props)\r
2842                         return System.props.getProperty (key, def);\r
2843                 var v = System.$props[key];\r
2844     if (typeof v != "undefined")\r
2845       return v;\r
2846     if (key.indexOf(".") > 0) {\r
2847       v = null;    \r
2848       switch (key) {\r
2849       case "java.version":\r
2850         v = "1.6";\r
2851       case "file.separator":\r
2852       case "path.separator":\r
2853         v = "/";\r
2854         break;        \r
2855       case "line.separator":\r
2856         v = (navigator.userAgent.indexOf("Windows") >= 0 ? "\r\n" : "\n");\r
2857         break;\r
2858       case "os.name":\r
2859       case "os.version":\r
2860         v = navigator.userAgent;\r
2861         break;\r
2862       }\r
2863       if (v)\r
2864         return System.$props[key] = v;\r
2865     }\r
2866     return (arguments.length == 1 ? null : def == null ? key : def); // BH\r
2867         },\r
2868         getSecurityManager : function() { return null },  // bh\r
2869         setProperties : function (props) {\r
2870                 System.props = props;\r
2871         },\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
2877         }\r
2878 };\r
2879 \r
2880 System.identityHashCode=function(obj){\r
2881   if(obj==null)\r
2882     return 0;\r
2883     \r
2884         return obj._$hashcode || (obj._$hashcode = ++Clazz._hashCode)\r
2885 \r
2886 /*    \r
2887   try{\r
2888     return obj.toString().hashCode();\r
2889   }catch(e){\r
2890     var str=":";\r
2891     for(var s in obj){\r
2892      str+=s+":"\r
2893     }\r
2894     return str.hashCode();\r
2895   }\r
2896 */  \r
2897 }\r
2898 \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
2905 \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
2912 \r
2913 Clazz.popup = Clazz.assert = Clazz.log = Clazz.error = window.alert;\r
2914 \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
2919 };\r
2920 \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
2929         } else {\r
2930                 return (b1 << 24) + (b2 << 16) + (b3 << 8) + b4;\r
2931         }\r
2932 };\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
2938         } else {\r
2939                 return (b1 << 8) + b4;\r
2940         }\r
2941 };\r
2942 \r
2943 Clazz.byteCast = function (b) { // 8bit\r
2944         if ((b & 0x80) != 0) {\r
2945                 return -((b & 0x7f) + 1);\r
2946         } else {\r
2947                 return b & 0xff;\r
2948         }\r
2949 };\r
2950 \r
2951 Clazz.charCast = function (c) { // 8bit\r
2952         return String.fromCharCode (c & 0xff).charAt (0);\r
2953 };\r
2954 \r
2955 Clazz.floatCast = function (f) { // 32bit\r
2956         return f;\r
2957 };\r
2958 \r
2959 */\r
2960 \r
2961 \r
2962 /*\r
2963  * Try to fix JavaScript's shift operator defects on long type numbers.\r
2964  */\r
2965 \r
2966 /* not used in Jmol\r
2967 \r
2968 Clazz.longMasks = [];\r
2969 \r
2970 Clazz.longReverseMasks = [];\r
2971 \r
2972 Clazz.longBits = [];\r
2973 \r
2974 ;(function () {\r
2975         var arr = [1];\r
2976         for (var i = 1; i < 53; i++) {\r
2977                 arr[i] = arr[i - 1] + arr[i - 1]; // * 2 or << 1\r
2978         }\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
2983         }\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
2987         }\r
2988 }) ();\r
2989 \r
2990 \r
2991 Clazz.longLeftShift = function (l, o) { // 64bit\r
2992         if (o == 0) return l;\r
2993         if (o >= 64) return 0;\r
2994         if (o > 52) {\r
2995                 error ("[Java2Script] Error : JavaScript does not support long shift!");\r
2996                 return l;\r
2997         }\r
2998         if ((l & Clazz.longMasks[o - 1]) != 0) {\r
2999                 error ("[Java2Script] Error : Such shift operator results in wrong calculation!");\r
3000                 return l;\r
3001         }\r
3002         var high = l & Clazz.longMasks[52 - 32 + o];\r
3003         if (high != 0) {\r
3004                 return high * Clazz.longBits[o] + (l & Clazz.longReverseMasks[32 - o]) << 0;\r
3005         } else {\r
3006                 return l << o;\r
3007         }\r
3008 };\r
3009 \r
3010 Clazz.intLeftShift = function (n, o) { // 32bit\r
3011         return (n << o) & 0xffffffff;\r
3012 };\r
3013 \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
3017         } else {\r
3018                 return l >> o;\r
3019         }\r
3020 };\r
3021 \r
3022 Clazz.intRightShift = function (n, o) { // 32bit\r
3023         return n >> o; // no needs for this shifting wrapper\r
3024 };\r
3025 \r
3026 Clazz.long0RightShift = function (l, o) { // 64bit\r
3027         return l >>> o;\r
3028 };\r
3029 \r
3030 Clazz.int0RightShift = function (n, o) { // 64bit\r
3031         return n >>> o; // no needs for this shifting wrapper\r
3032 };\r
3033 \r
3034 */\r
3035 // Compress the common public API method in shorter name\r
3036 //$_L=Clazz.load;\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
3049 \r
3050 \r
3051 /////////////////////// inner function support /////////////////////////////////\r
3052 \r
3053 /* public */\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
3060 \r
3061 /* public */\r
3062 Clazz._innerFunctions.getSuperclass = function () {\r
3063         return this.superClazz; \r
3064 };\r
3065 \r
3066 /* public */\r
3067 Clazz._innerFunctions.isAssignableFrom = function (clazz) {\r
3068         return Clazz.getInheritedLevel (clazz, this) >= 0;      \r
3069 };\r
3070 \r
3071 /* public */\r
3072 Clazz._innerFunctions.getConstructor = function () {\r
3073         return new java.lang.reflect.Constructor (this, [], [], \r
3074                         java.lang.reflect.Modifier.PUBLIC);\r
3075 };\r
3076 /**\r
3077  * TODO: fix bug for polymorphic methods!\r
3078  */\r
3079 /* public */\r
3080 Clazz._innerFunctions.getDeclaredMethods = Clazz._innerFunctions.getMethods = function () {\r
3081         var ms = [];\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
3088                 }\r
3089         }\r
3090         p = this;\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
3096                 }\r
3097         }\r
3098         return ms;\r
3099 };\r
3100 /* public */\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
3109                 }\r
3110         }\r
3111         p = this;\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
3118                 }\r
3119         }\r
3120         return null;\r
3121 };\r
3122 /* public */\r
3123 Clazz._innerFunctions.getModifiers = function () {\r
3124         return java.lang.reflect.Modifier.PUBLIC;\r
3125 };\r
3126 \r
3127 Clazz._innerFunctions.newInstance = function (a) {\r
3128         var clz = this;\r
3129   switch(a == null ? 0 : a.length) {\r
3130   case 0:\r
3131     return new clz();\r
3132   case 1:\r
3133         return new clz(a[0]);\r
3134   case 2:\r
3135         return new clz(a[0], a[1]);\r
3136   case 3:\r
3137         return new clz(a[0], a[1], a[2]);\r
3138   case 4:\r
3139         return new clz(a[0], a[1], a[2], a[3]);\r
3140   default:\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
3144     x += ")";\r
3145     return eval(x);\r
3146   }\r
3147 };\r
3148 \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
3155         }\r
3156         //Array["isArray"] = function () {\r
3157         //      return true;\r
3158         //};\r
3159 })();\r
3160 \r
3161 //////////////////////////// hotspot and unloading /////////////////////////////\r
3162 /* For hotspot and unloading */\r
3163 \r
3164 if (window["Clazz"] && !window["Clazz"].unloadClass) {\r
3165 \r
3166 /* public */\r
3167 Clazz.unloadClass = function (qClazzName) {\r
3168         var cc = Clazz.evalType (qClazzName);\r
3169         if (cc) {\r
3170                 Clazz.unloadedClasses[qClazzName] = cc;\r
3171                 var clazzName = qClazzName;\r
3172                 var pkgFrags = clazzName.split (/\./);\r
3173                 var pkg = null;\r
3174                 for (var i = 0; i < pkgFrags.length - 1; i++)\r
3175                         pkg = (pkg ? pkg[pkgFrags[i]] : Clazz.allPackage[pkgFrags[0]]);\r
3176                 if (!pkg) {\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
3183                                         window[c] = null;\r
3184                                 }\r
3185                         }\r
3186                 } else {\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
3192                                         pkg[c] = null;\r
3193                                 }\r
3194                         }\r
3195                 }\r
3196 \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
3203                                 }\r
3204                         }\r
3205                 }\r
3206 \r
3207                 for (var m in cc) {\r
3208                         cleanDelegateMethod (cc[m]);\r
3209                 }\r
3210                 for (var m in cc.prototype) {\r
3211                         cleanDelegateMethod (cc.prototype[m]);\r
3212                 }\r
3213 \r
3214                 if (Clazz._Loader) {\r
3215                         Clazz._Loader.unloadClassExt(qClazzName);\r
3216                 }\r
3217 \r
3218                 return true;\r
3219         }\r
3220         return false;\r
3221 };\r
3222 \r
3223 /* private */\r
3224 var cleanDelegateMethod = function (m) {\r
3225         if (!m) \r
3226                 return;\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
3232         }\r
3233 };\r
3234 \r
3235 } // if (window["Clazz"] && !window["Clazz"].unloadClass)\r
3236 \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
3243  *\r
3244  * Contributors:\r
3245  *     Zhou Renjian - initial API and implementation\r
3246  *****************************************************************************/\r
3247 /*******\r
3248  * @author zhou renjian\r
3249  * @create July 10, 2006\r
3250  *******/\r
3251 \r
3252 //if (window["ClazzNode"] == null) {\r
3253 /**\r
3254  * TODO:\r
3255  * Make optimization over class dependency tree.\r
3256  */\r
3257 \r
3258 /*\r
3259  * ClassLoader Summary\r
3260  * \r
3261  * ClassLoader creates SCRIPT elements and setup class path and onload \r
3262  * callback to continue class loading.\r
3263  *\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
3268  *\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
3276  * \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
3283  *\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
3292  *\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
3297  * order.\r
3298  *\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
3316  *\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
3323  * has no error.\r
3324  * \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
3334  */\r
3335 \r
3336 /*\r
3337  * The following comments with "#" are special configurations for a much\r
3338  * smaller *.js file size.\r
3339  *\r
3340  * @see net.sf.j2s.lib/src/net/sf/j2s/lib/build/SmartJSCompressor.java\r
3341  */\r
3342 /**\r
3343  * Static class loader class\r
3344  */\r
3345 Clazz._Loader = Clazz.ClazzLoader = function () {};\r
3346 \r
3347 /**\r
3348  * Class dependency tree node\r
3349  */\r
3350 /* private */\r
3351 var Node = function () {\r
3352         this.parents = [];\r
3353         this.musts = [];\r
3354         this.optionals = [];\r
3355         this.declaration = null;\r
3356         this.name = null; // id\r
3357         this.path = null;\r
3358 //      this.requires = null;\r
3359 //      this.requiresMap = null;\r
3360         this.onLoaded = null;\r
3361         this.status = 0;\r
3362         this.random = 0.13412;\r
3363 };\r
3364 \r
3365 \r
3366 ;(function(Clazz, _Loader) {\r
3367 \r
3368 _Loader._checkLoad = Jmol._checkLoad;\r
3369  \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
3375                                 updateNode(nnn);\r
3376                         };\r
3377                 })(node), 1);\r
3378         }\r
3379 }\r
3380 \r
3381 Node.prototype.toString = function() {\r
3382         return this.name || this.path || "ClazzNode";\r
3383 }\r
3384 \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
3391 \r
3392                                                  \r
3393 var loaders = [];\r
3394 \r
3395 /* public */\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
3400                 }\r
3401         }\r
3402         var loader = new _Loader ();\r
3403         loader.base = base; \r
3404         loaders.push(loader);\r
3405         return loader;\r
3406 };\r
3407 \r
3408 /**\r
3409  * Class dependency tree\r
3410  */\r
3411 var clazzTreeRoot = new Node();\r
3412 \r
3413 /**\r
3414  * Used to keep the status whether a given *.js path is loaded or not.\r
3415  */\r
3416 /* private */\r
3417 var loadedScripts = {};\r
3418 \r
3419 /**\r
3420  * Multiple threads are used to speed up *.js loading.\r
3421  */\r
3422 /* private */\r
3423 var inLoadingThreads = 0;\r
3424 \r
3425 /**\r
3426  * Maximum of loading threads\r
3427  */\r
3428 /* private */\r
3429 var maxLoadingThreads = 6;\r
3430 \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
3435 \r
3436 /*\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
3439  *\r
3440  * FIXME: This different loading order also causes bugs in single thread!\r
3441  */\r
3442 if (isOpera) {\r
3443         maxLoadingThreads = 1;\r
3444         var index = userAgent.indexOf ("opera/");\r
3445         if (index != -1) {\r
3446                 var verNumber = 9.0;\r
3447                 try {\r
3448                         verNumber = parseFloat(userAgent.subString (index + 6));\r
3449                 } catch (e) {}\r
3450                 if (verNumber >= 9.6) {\r
3451                         maxLoadingThreads = 6;\r
3452                 }\r
3453         } \r
3454 }\r
3455 \r
3456 /**\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
3460  */\r
3461 var isClassdefined;\r
3462 var definedClasses;\r
3463 \r
3464 if (self.Clazz && Clazz.isClassDefined) {\r
3465         isClassDefined = Clazz.isClassDefined;\r
3466 } else {\r
3467         definedClasses = {};\r
3468         isClassDefined = function (clazzName) {\r
3469                 return definedClasses[clazzName] == true;\r
3470         };\r
3471 }\r
3472 \r
3473 /**\r
3474  * Expand the shortened list of class names.\r
3475  * For example:\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
3480  *\r
3481  * This method will be used to unwrap the required/optional classes list and \r
3482  * the ignored classes list.\r
3483  */\r
3484 /* private */\r
3485 var unwrapArray = function (arr) {\r
3486         if (!arr || arr.length == 0)\r
3487                 return [];\r
3488         var last = null;\r
3489         for (var i = 0; i < arr.length; i++) {\r
3490                 if (!arr[i])\r
3491                         continue;\r
3492                 if (arr[i].charAt (0) == '$') {\r
3493                         if (arr[i].charAt (1) == '.') {\r
3494                                 if (!last)\r
3495                                         continue;\r
3496                                 var idx = last.lastIndexOf (".");\r
3497                                 if (idx != -1) {\r
3498                                         var prefix = last.substring (0, idx);\r
3499                                         arr[i] = prefix + arr[i].substring (1);\r
3500                                 }\r
3501                         } else {\r
3502                                 arr[i] = "org.eclipse.s" + arr[i].substring (1);\r
3503                         }\r
3504                 }\r
3505                 last = arr[i];\r
3506         }\r
3507         return arr;\r
3508 };\r
3509 \r
3510 /**\r
3511  * Used to keep to-be-loaded classes.\r
3512  */\r
3513 /* private */\r
3514 var classQueue = [];\r
3515 \r
3516 /* private */\r
3517 var classpathMap = {};\r
3518 \r
3519 /* private */\r
3520 var pkgRefCount = 0;\r
3521 \r
3522 /* public */\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
3527         pt || (pt = 0);\r
3528 \r
3529         /*\r
3530          * In some situation, maybe,\r
3531          * _Loader.packageClasspath ("java", ..., true);\r
3532          * is called after other _Loader#packageClasspath, e.g.\r
3533          * <code>\r
3534          * _Loader.packageClasspath ("org.eclipse.swt", "...", true);\r
3535          * _Loader.packageClasspath ("java", "...", true);\r
3536          * </code>\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
3541          */\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
3545                 if (fSuccess)\r
3546                         return;\r
3547         }\r
3548         if (pkg instanceof Array) {\r
3549                 unwrapArray(pkg);\r
3550                 if (fSuccess) {\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
3553                         else\r
3554                                 fSuccess();\r
3555                 } else {\r
3556                         for (var i = 0; i < pkg.length; i++)\r
3557                                 _Loader.loadPackageClasspath(pkg[i], base, isIndex, null);\r
3558                 }\r
3559                 return;\r
3560         }\r
3561         switch (pkg) {\r
3562         case "java.*":\r
3563                 pkg = "java";\r
3564                 // fall through\r
3565         case "java":\r
3566                 if (base) {\r
3567                         // support ajax for default\r
3568                         var key = "@net.sf.j2s.ajax";\r
3569                         if (!map[key])\r
3570                                 map[key] = base;\r
3571                         key = "@net.sf.j2s";\r
3572                         if (!map[key])\r
3573                                 map[key] = base;\r
3574                 }               \r
3575                 break;\r
3576         case "swt":\r
3577                 pkg = "org.eclipse.swt";\r
3578                 break;\r
3579         case "ajax":\r
3580                 pkg = "net.sf.j2s.ajax";\r
3581                 break;\r
3582         case "j2s":\r
3583                 pkg = "net.sf.j2s";\r
3584                 break;\r
3585         default:\r
3586                 if (pkg.lastIndexOf(".*") == pkg.length - 2)\r
3587                         pkg = pkg.substring(0, pkg.length - 2);\r
3588                 break;\r
3589         }\r
3590         if (base) // critical for multiple applets\r
3591                 map["@" + pkg] = base;\r
3592         if (isIndex && !isPkgDeclared && !window[pkg + ".registered"]) {\r
3593                 pkgRefCount++;\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
3598                                                 runtimeLoaded();\r
3599                                         //fSuccess && fSuccess();\r
3600                                 }, true, true, 1);\r
3601                 return;\r
3602         }\r
3603         fSuccess && fSuccess();\r
3604 };\r
3605 \r
3606 /**\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
3609  *   \r
3610  */\r
3611 Clazz.loadClass = function (name, onLoaded, async) {\r
3612   if (!self.Class) {\r
3613     Class = Clazz;\r
3614     Class.forName = Clazz._4Name;\r
3615     JavaObject = Clazz._O;\r
3616     // maybe more here\r
3617   }\r
3618   return (name && _Loader.loadClass(name, onLoaded, true, async, 1));\r
3619 }\r
3620 \r
3621 /**\r
3622  * Load the given class ant its related classes.\r
3623  */\r
3624 /* public */\r
3625 _Loader.loadClass = function (name, onLoaded, forced, async, mode) {\r
3626 \r
3627   mode || (mode = 0); // BH: not implemented\r
3628   (async == null) && (async = false);\r
3629   \r
3630         if (typeof onLoaded == "boolean")\r
3631                 return Clazz.evalType(name);\r
3632 \r
3633   System.out.println("loadClass " + name)\r
3634 \r
3635         // Make sure that packageClasspath ("java", base, true); \r
3636         // is called before any _Loader#loadClass is called.\r
3637 \r
3638         if (needPackage("java"))\r
3639                 _Loader.loadPackage("java");\r
3640         if (needPackage("core"))\r
3641                 _Loader.loadPackage("core");    \r
3642 \r
3643 //      var swtPkg = "org.eclipse.swt";\r
3644 //      if (name.indexOf (swtPkg) == 0 || name.indexOf ("$wt") == 0) {\r
3645 //              _Loader.assurePackageClasspath (swtPkg);\r
3646 //      }\r
3647 //      if (name.indexOf ("junit") == 0) {\r
3648 //              _Loader.assurePackageClasspath ("junit");\r
3649 //      }\r
3650 \r
3651         // Any _Loader#loadClass calls will be queued until java.* core classes are loaded.\r
3652 \r
3653         _Loader.keepOnLoading = true;\r
3654         \r
3655         if (!forced && (pkgRefCount && name.lastIndexOf(".package") != name.length - 8\r
3656                         || name.indexOf("java.") != 0 && !isClassDefined(runtimeKeyClass)\r
3657                  )) {   \r
3658                 queueBe4KeyClazz.push([name, onLoaded]);\r
3659     \r
3660     \r
3661   System.out.println("loadclass-queuing" + name+ runtimeKeyClass + " "+ isClassDefined(runtimeKeyClass))\r
3662 \r
3663                 return;    \r
3664         }\r
3665         var b;\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
3670                                 if (async) {\r
3671                                         window.setTimeout(onLoaded, 25);\r
3672                                 } else {\r
3673                                         onLoaded();\r
3674                                 }\r
3675                         }\r
3676                 }\r
3677                 return;\r
3678         }\r
3679         var path = _Loader.getClasspathFor(name);\r
3680   var existed = loadedScripts[path];\r
3681         var qq = classQueue;\r
3682         if (!existed)\r
3683                 for (var i = qq.length; --i >= 0;)\r
3684                         if (qq[i].path == path || qq[i].name == name) {\r
3685                                 existed = true;\r
3686                                 break;\r
3687                         }\r
3688         if (existed) {\r
3689                 if (onLoaded) {\r
3690                         var n = findNode(name);\r
3691                         if (n) {\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
3696                                 }\r
3697                         }\r
3698                 }\r
3699                 return;\r
3700         }\r
3701 \r
3702         var n = (Clazz.unloadedClasses[name] && findNode(name) || new Node());\r
3703         n.name = name;\r
3704         n.path = path;\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
3713                         break;\r
3714                 }\r
3715         }\r
3716         \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
3722                                 break;\r
3723                         qq[pt + 1] = qq[pt];\r
3724                 }\r
3725                 qq[++pt] = n;\r
3726         } else if (needBeingQueued) {\r
3727                 qq.push(n);\r
3728         }\r
3729         if (!needBeingQueued) { // can be loaded directly\r
3730                 var bSave = false;\r
3731                 if (onLoaded) { \r
3732                         bSave = isLoadingEntryClass;\r
3733                         isLoadingEntryClass = true;\r
3734                 }\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
3738         }\r
3739 };\r
3740 \r
3741 /*\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
3744  */\r
3745 /* private */\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
3749 }\r
3750 \r
3751 /* private */\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
3757                 true, fSuccess);\r
3758 };\r
3759 \r
3760 /**\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
3763  */\r
3764 /* public */\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
3772 };\r
3773 \r
3774 /**\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
3777  */\r
3778 /* public */\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
3785                 }\r
3786                 _Loader.loadPackageClasspath (prefix + "." + pkgs[i], base);\r
3787         }\r
3788 };\r
3789 \r
3790 /**\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
3801  */\r
3802 /* protected */\r
3803         /*\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
3813                         }\r
3814                         var newVersion = deltas[i + i + i + 1];\r
3815                         if (newVersion != "$") {\r
3816                                 lastNewVersion = newVersion;\r
3817                         }\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
3823                                 break;\r
3824                         }\r
3825                 }\r
3826         }\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
3838                 }\r
3839         }\r
3840         return path;\r
3841 };\r
3842         */\r
3843 \r
3844 /**\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
3852  * extension.\r
3853  */\r
3854 /* public */\r
3855 _Loader.getClasspathFor = function (clazz, forRoot, ext) {\r
3856         var path = classpathMap["#" + clazz];\r
3857         if (!path || forRoot || ext) {\r
3858                 var base;\r
3859                 var idx;\r
3860                 if (path) {\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
3866                 } else {\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
3870                                         break;\r
3871                         if (!forRoot)\r
3872                                 clazz = clazz.replace (/\./g, "/");     \r
3873                 }\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
3878                                 : "j2s");\r
3879                 }\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
3883         }               \r
3884         return path;//_Loader.multipleSites(path);\r
3885 };\r
3886 \r
3887 /**\r
3888  * To ignore some classes.\r
3889  */\r
3890 /* public */\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
3895         if (!clazzes) {\r
3896                 clazzes = new Array(n);\r
3897                 for (var i = 0; i < n; i++)\r
3898                         clazzes[i] = arguments[i];\r
3899         }\r
3900         unwrapArray(clazzes);\r
3901         for (var i = 0; i < n; i++)\r
3902                 excludeClassMap["@" + clazzes[i]] = 1;\r
3903 };\r
3904 \r
3905 /**\r
3906  * The following *.script* can be overriden to indicate the \r
3907  * status of classes loading.\r
3908  *\r
3909  * TODO: There should be a Java interface with name like INativeLoaderStatus\r
3910  */\r
3911 /* public */\r
3912 _Loader.onScriptLoading = function (file){};\r
3913 \r
3914 /* public */\r
3915 _Loader.onScriptLoaded = function (file, isError){};\r
3916 \r
3917 /* public */\r
3918 _Loader.onScriptInitialized = function (file){};\r
3919 \r
3920 /* public */\r
3921 _Loader.onScriptCompleted = function (file){};\r
3922 \r
3923 /* public */\r
3924 _Loader.onClassUnloaded = function (clazz){};\r
3925 \r
3926 /**\r
3927  * After all the classes are loaded, this method will be called.\r
3928  * Should be overriden to run *.main([]).\r
3929  */\r
3930 /* public */\r
3931 _Loader.onGlobalLoaded = function () {};\r
3932 \r
3933 /* public */\r
3934 _Loader.keepOnLoading = true; // never set false in this code\r
3935 \r
3936 \r
3937 /* private */\r
3938 var mapPath2ClassNode = {};\r
3939 \r
3940 /* private */\r
3941 var isClassExcluded = function (clazz) {\r
3942         return excludeClassMap["@" + clazz];\r
3943 };\r
3944 \r
3945 /* Used to keep ignored classes */\r
3946 /* private */\r
3947 var excludeClassMap = {};\r
3948 \r
3949 /* private */\r
3950 var evaluate = function(file, js) {\r
3951                 try {\r
3952                         eval(js);\r
3953                 } catch (e) {      \r
3954       if (Clazz._isQuiet) \r
3955         return;\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
3959                 alert(s)\r
3960                         Clazz.alert(s);\r
3961                         throw e;\r
3962                 }\r
3963                 _Loader.onScriptLoaded(file, false);\r
3964                 tryToLoadNext(file);\r
3965 }\r
3966 \r
3967 /* private */\r
3968 var failedHandles = {};\r
3969 \r
3970 /* private */\r
3971 var generateRemovingFunction = function (node) {\r
3972         return function () {\r
3973                 if (node.readyState != "interactive") {\r
3974                         try {\r
3975                                 if (node.parentNode)\r
3976                                         node.parentNode.removeChild (node);\r
3977                         } catch (e) { }\r
3978                         node = null;\r
3979                 }\r
3980         };\r
3981 };\r
3982 \r
3983 /* private */\r
3984 var removeScriptNode = function (n) {\r
3985         if (window["j2s.script.debugging"]) {\r
3986                 return;\r
3987         }\r
3988         // lazily remove script nodes.\r
3989         window.setTimeout (generateRemovingFunction (n), 1);\r
3990 };\r
3991 \r
3992 /* public */\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
3997         if (f == 1)\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
4002         }\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
4006 };\r
4007 \r
4008 /**\r
4009  * BH: possibly useful for debugging\r
4010  */ \r
4011 Clazz.currentPath= "";\r
4012 \r
4013 /**\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
4016  */\r
4017 /* private */\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
4024 //              return;\r
4025 //      }\r
4026         loadedScripts[file] = true;\r
4027         // also remove from queue\r
4028         removeArrayItem(classQueue, file);\r
4029 \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
4035   }\r
4036 \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
4044     try{\r
4045                   evaluate(file, data);\r
4046     }catch(e) {\r
4047       alert(e + " loading file " + file + " " + node.name + " " + Clazz.getStackTrace());\r
4048     }\r
4049     if (fSuccess) {\r
4050 //      System.out.println("firing in loadScript " + file + " " + (fSuccess && fSuccess.toString()))\r
4051       fSuccess(); \r
4052     }\r
4053                 return;\r
4054         }\r
4055   \r
4056   \r
4057 System.out.println("for file " + file +" fSuccess = " + (fSuccess ? fSuccess.toString() : ""))\r
4058         var info = {\r
4059                 dataType:"script",\r
4060                 async:true, \r
4061                 type:"GET", \r
4062                 url:file,\r
4063                 success:W3CScriptOnCallback(file, false, fSuccess),\r
4064                 error:W3CScriptOnCallback(file, true, fSuccess)\r
4065         };\r
4066         inLoadingThreads++;\r
4067         Jmol.$ajax(info);\r
4068 };\r
4069 \r
4070 /* private */\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
4084                 if (forError) \r
4085                         alert ("There was a problem loading " + path);\r
4086                 _Loader.onScriptLoaded(path, true);\r
4087                 var node = this;                        \r
4088                 var f;\r
4089     if (fSuccess)\r
4090       f = function(_W3scriptFS){removeScriptNode(node);tryToLoadNext(path, fSuccess); };\r
4091     else\r
4092       f = function(_W3script){removeScriptNode(node);tryToLoadNext(path)};\r
4093                 if (loadingTimeLag >= 0)\r
4094                         window.setTimeout(function() { tryToLoadNext(path, f); }, loadingTimeLag);\r
4095                 else\r
4096                         tryToLoadNext(path, f);\r
4097         };\r
4098 };\r
4099 \r
4100 /* private */\r
4101 var isLoadingEntryClass = true;\r
4102 \r
4103 /* private */\r
4104 var besidesJavaPackage = false;\r
4105 \r
4106 /**\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
4109  */\r
4110 /* private */\r
4111 var tryToLoadNext = function (file, fSuccess) {\r
4112         var node = mapPath2ClassNode["@" + file];\r
4113         if (!node) // maybe class tree root\r
4114                 return;\r
4115         var n;\r
4116   // check for content loaded\r
4117         var clazzes = classpathMap["$" + file];\r
4118         if (clazzes) {\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
4124                                         updateNode(n);\r
4125                                 }\r
4126                         } else {\r
4127                                 n = new Node();\r
4128                                 n.name = name;\r
4129                                 var pp = classpathMap["#" + name];\r
4130                                 if (!pp) {\r
4131                                         alert (name + " J2S error in tryToLoadNext");\r
4132                                         error("Java2Script implementation error! Please report this bug!");\r
4133                                 }\r
4134                                 n.path = pp;\r
4135                                 mappingPathNameNode (n.path, name, n);\r
4136                                 n.status = Node.STATUS_CONTENT_LOADED;\r
4137                                 addChildClassNode(clazzTreeRoot, n, false);\r
4138                                 updateNode(n);\r
4139                         }\r
4140                 }\r
4141         }\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
4147                         }\r
4148                 }\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
4153                         if (isIE) {\r
4154                                 if (ss[i].onreadystatechange && ss[i].onreadystatechange.path == node.path\r
4155                                                 && ss[i].readyState == "interactive") {\r
4156                                         stillLoading = true;\r
4157                                         break;\r
4158                                 }\r
4159                         } else if (ss[i].onload && ss[i].onload.path == node.path) {\r
4160                                 stillLoading = true;\r
4161                                 break;\r
4162                         }\r
4163                 }\r
4164                 if (!stillLoading) {\r
4165                         node.status = Node.STATUS_CONTENT_LOADED;\r
4166                         updateNode(node);\r
4167                 }\r
4168         }\r
4169         /*\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
4173          */\r
4174          \r
4175         if (!_Loader.keepOnLoading) // set externally\r
4176                 return;\r
4177 \r
4178  // check for a "must" class that has content and load it\r
4179         var cq;\r
4180         var working = true;\r
4181         if ((n = findNextMustClass(Node.STATUS_KNOWN))) {\r
4182                 loadClassNode(n);\r
4183                 while (inLoadingThreads < maxLoadingThreads) {\r
4184                         if (!(n = findNextMustClass(Node.STATUS_KNOWN)))\r
4185                                 break;\r
4186                         loadClassNode(n); // will increase inLoadingThreads!\r
4187                 }\r
4188         } else if ((cq = classQueue).length != 0) { \r
4189                 /* queue must be loaded in order! */\r
4190                 n = cq.shift();\r
4191                 if (!loadedScripts[n.path] \r
4192                                 || cq.length != 0 \r
4193                                 || !isLoadingEntryClass\r
4194                                 || n.musts.length\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
4199                         /*\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
4203                          *\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
4209                          */\r
4210                         isLoadingEntryClass = false;\r
4211                 }\r
4212         } else if ((n = findNextRequiredClass(Node.STATUS_KNOWN))) {\r
4213                 loadClassNode(n);\r
4214                 while (inLoadingThreads < maxLoadingThreads) {\r
4215                         if (!(n = findNextRequiredClass(Node.STATUS_KNOWN)))\r
4216                                 break;\r
4217                         loadClassNode(n); // will increase inLoadingThreads!\r
4218                 }\r
4219         } else {\r
4220                 working = false;\r
4221         }\r
4222         if (working || inLoadingThreads > 0)\r
4223                 return;\r
4224   // \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
4236                         updateNode(n);\r
4237                         lastNode = n;\r
4238                 }\r
4239     \r
4240   // check for load cycles\r
4241   \r
4242         while (true) {\r
4243                 tracks = [];\r
4244                 if (!checkCycle(clazzTreeRoot, file))\r
4245                         break;\r
4246         }\r
4247   \r
4248   // and update all MUST and REQUIRED classes that are declared already \r
4249   \r
4250         for (var i = 0; i < 2; i++) {\r
4251                 lastNode = null;\r
4252                 while ((n = f[i](Node.STATUS_DECLARED))) {\r
4253                         if (lastNode === n) \r
4254                                 break;\r
4255                         updateNode(lastNode = n);\r
4256                 }\r
4257         }\r
4258         var done = [];\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
4268         }\r
4269   \r
4270   \r
4271   \r
4272   \r
4273   \r
4274   \r
4275   \r
4276         //System.out.println(node.name + " loaded completely" + _Loader.onGlobalLoaded + "\n\n")\r
4277   if (fSuccess) {\r
4278     //System.out.println("tryToLoadNext firing " + _Loader._classCountOK + "/" + _Loader._classCountPending + " "   + fSuccess.toString() + " " + Clazz.getStackTrace())\r
4279           fSuccess();\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
4284       if (n) {\r
4285         updateNode(n);\r
4286         break;\r
4287       }\r
4288     }\r
4289   } else {\r
4290     \r
4291  // System.out.println("I think I'm done " \r
4292   // + _Loader._classCountOK + "/" + _Loader._classCountPending + " " \r
4293    //+ _Loader.onGlobalLoaded.toString() + " " + Clazz.getStackTrace()\r
4294  //  )\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
4298     }\r
4299   }\r
4300         _Loader.onGlobalLoaded();\r
4301 };\r
4302 \r
4303 \r
4304 var tracks = [];\r
4305 \r
4306 /*\r
4307  * There are classes reference cycles. Try to detect and break those cycles.\r
4308  */\r
4309 /* private */\r
4310 var checkCycle = function (node, file) {\r
4311         var ts = tracks;\r
4312         var len = ts.length;\r
4313   // add this node to tracks\r
4314         ts.push(node);\r
4315         var i = len;\r
4316         for (; --i >= 0;)\r
4317                 if (ts[i] === node && ts[i].status >= Node.STATUS_DECLARED) \r
4318                         break;\r
4319         if (i >= 0) {\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
4327     } \r
4328                 for (; i < len; i++) {\r
4329       var n = ts[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
4334                         n.parents = [];\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
4339       } \r
4340                         if (f)\r
4341                                 n.onLoaded = null, f();\r
4342                 }\r
4343                 ts.length = 0;\r
4344                 return true;\r
4345         }\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
4350                                 return true;\r
4351   // reset _tracks to its original length      \r
4352         ts.length = len;\r
4353         return false; // done \r
4354 };\r
4355 \r
4356 \r
4357 _Loader._classCountPending = 0;\r
4358 _Loader._classCountOK = 0;\r
4359 _Loader._classPending = {};\r
4360 \r
4361 _Loader.showPending = function() {\r
4362   var a = [];\r
4363   for (var name in _Loader._classPending) {\r
4364     var n = findNode(name);\r
4365     if (!n) {\r
4366       alert("No node for " + name);\r
4367       continue;\r
4368     }\r
4369     a.push(n);\r
4370     System.out.println(showNode("", "", n, "", 0));     \r
4371   }  \r
4372   return a;\r
4373 }\r
4374 \r
4375 var showNode = function(s, names, node, inset, level) {\r
4376   names += "--" + node.name;\r
4377   s += names + "\n";\r
4378   if (level > 5) {\r
4379     s += inset + " ...\n";\r
4380     return s;\r
4381   }\r
4382   inset += "\t";\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
4388     }\r
4389     s += "\n";\r
4390   }\r
4391 //  if (node.requiredBy) {\r
4392 //    s += inset + "requiredBy:\n";\r
4393 //    s = showNode(s, names, node.requiredBy, inset + "\t", level+1);\r
4394 //    s += "\n";\r
4395 //  }\r
4396   return s;    \r
4397 }     \r
4398 \r
4399 /**\r
4400  * Update the dependency tree nodes recursively.\r
4401  */\r
4402 /* private */\r
4403 updateNode = function(node, _updateNode) {\r
4404         if (!node.name || node.status >= Node.STATUS_LOAD_COMPLETE) {\r
4405                 destroyClassNode(node);\r
4406                 return;\r
4407         }\r
4408         var ready = true;\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
4423                                                                 && nn !== n) {\r
4424                                                         nn.status = n.status;\r
4425                                                         nn.declaration = null;\r
4426                                                         destroyClassNode(nn);\r
4427                                                         nn.onLoaded && nns.push(nn);\r
4428                                                 }\r
4429                                         }\r
4430                                         n.declaration = null;\r
4431                                 }\r
4432         // fire all onLoaded events\r
4433                                 if (n.onLoaded)\r
4434                                         nns.push(n);\r
4435                                 for (var j = 0; j < nns.length; j++) {\r
4436                                         var onLoaded = nns[j].onLoaded;\r
4437                                         if (onLoaded) {\r
4438                                                 nns[j].onLoaded = null;\r
4439                                                 onLoaded();\r
4440                                         }\r
4441                                 }\r
4442                         } else {\r
4443                                 (n.status == Node.STATUS_CONTENT_LOADED) && updateNode(n); // musts may be changed\r
4444                                 if (n.status < Node.STATUS_DECLARED)\r
4445                                         ready = false;\r
4446                         }\r
4447                         if (node.musts.length != mustLength) {\r
4448                                 // length changed -- restart!\r
4449                                 i = mustLength = node.musts.length;\r
4450                                 ready = true;\r
4451                         }\r
4452                 }\r
4453         }\r
4454         if (!ready)\r
4455                 return;\r
4456         if (node.status < Node.STATUS_DECLARED) {\r
4457                 var decl = node.declaration;\r
4458                 if (decl)\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
4466             }\r
4467     }\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
4477                                                 && nn !== node) {\r
4478                                         nn.status = Node.STATUS_DECLARED;\r
4479                                         if (definedClasses)\r
4480                                                 definedClasses[nn.name] = true;\r
4481                                         _Loader.onScriptInitialized(nn.path);\r
4482                                 }\r
4483                         }\r
4484                 }\r
4485         }\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
4493                         return false;\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
4501                                                 return false;\r
4502                                 }\r
4503                         }\r
4504                 }\r
4505         }\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
4512         }\r
4513         if (level == Node.STATUS_LOAD_COMPLETE)\r
4514                 node.parents = [];\r
4515   }\r
4516 };\r
4517 \r
4518 /* private */\r
4519 var checkStatusIs = function(arr, status){\r
4520         for (var i = arr.length; --i >= 0;)\r
4521                 if (arr[i].status < status)\r
4522                         return false;\r
4523         return true;\r
4524 }\r
4525 /* private */\r
4526 var doneLoading = function(node, level, _doneLoading) {\r
4527         node.status = level;\r
4528         _Loader.onScriptCompleted(node.path);\r
4529   \r
4530         var onLoaded = node.onLoaded;\r
4531         if (onLoaded) {\r
4532                 node.onLoaded = null;\r
4533                 onLoaded();\r
4534                 if (!_Loader.keepOnLoading)\r
4535                         return false;\r
4536         }\r
4537   \r
4538         destroyClassNode(node);\r
4539         return true;\r
4540 }\r
4541 \r
4542 /*\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
4545  */\r
4546 /* private */\r
4547 var usedRandoms = {\r
4548   "r0.13412" : 1\r
4549 };\r
4550 \r
4551 /* private */\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
4558         }\r
4559 }\r
4560 \r
4561 /* protected */\r
4562 var findNode = function(clazzName) {\r
4563         getRnd();\r
4564         return findNodeUnderNode(clazzName, clazzTreeRoot);\r
4565 };\r
4566 \r
4567 /* private */\r
4568 var findNextRequiredClass = function(status) {\r
4569         getRnd();\r
4570         return findNextRequiredNode(clazzTreeRoot, status);\r
4571 };\r
4572 \r
4573 /* private */\r
4574 var findNextMustClass = function(status) {\r
4575         return findNextMustNode(clazzTreeRoot, status);\r
4576 };\r
4577 \r
4578 /* private */\r
4579 var findNodeUnderNode = function(clazzName, node) {\r
4580         var n;\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
4585                 ? n : null);\r
4586 };\r
4587 \r
4588 /* private */\r
4589 var findNodeWithin = function(name, arr) {\r
4590         var rnd = clazzTreeRoot.random;\r
4591         for (var i = arr.length; --i >= 0;) {\r
4592                 var n = arr[i];\r
4593                 if (n.name == name)\r
4594                         return n;\r
4595                 if (n.random != rnd) {\r
4596                         n.random = rnd;\r
4597                         if ((n = findNodeUnderNode(name, n)))\r
4598                                 return n;\r
4599                 }\r
4600         }\r
4601         return null;\r
4602 }\r
4603 \r
4604 /* private */\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
4609 }\r
4610 \r
4611 /* private */\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
4616                         return n;       \r
4617         }\r
4618         return (checkStatus(node, status) ? node : null); \r
4619 };\r
4620 \r
4621 /* private */\r
4622 var findNextRequiredNode = function (node, status) {\r
4623         // search musts first\r
4624         // search optionals second\r
4625         // search itself last\r
4626         var n;\r
4627         return ((n = searchClassArray(node.musts, status))\r
4628                 || (n = searchClassArray(node.optionals, status))\r
4629                 || checkStatus(n = node, status) ? n : null);\r
4630 };\r
4631 \r
4632 /* private */\r
4633 var searchClassArray = function (arr, status) {\r
4634         if (arr) {\r
4635                 var rnd = clazzTreeRoot.random;\r
4636                 for (var i = 0; i < arr.length; i++) {\r
4637                         var n = arr[i];\r
4638                         if (checkStatus(n, status))\r
4639                                 return n;\r
4640                         if (n.random != rnd) {\r
4641                                 n.random = rnd; // mark as visited!\r
4642                                 if ((n = findNextRequiredNode(n, status)))\r
4643                                         return n;\r
4644                         }\r
4645                 }\r
4646         }\r
4647         return null;\r
4648 };\r
4649 \r
4650 /**\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
4654  */\r
4655 /* private */\r
4656 var innerLoadedScripts = {};\r
4657 \r
4658 /**\r
4659  * This method will be called in almost every *.js generated by Java2Script\r
4660  * compiler.\r
4661  */\r
4662 /* public */\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
4669                 return;\r
4670         }       \r
4671 \r
4672   if (_Loader._checkLoad) {\r
4673     if (_Loader._classPending[name]) {\r
4674       //alert("duplicate load for " + name)\r
4675     } else {\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
4680     }\r
4681   }\r
4682 \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
4689                 node.name = name;\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
4694         }\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
4699         }\r
4700         node.declaration = declaration;\r
4701         if (declaration) \r
4702                 node.status = Node.STATUS_CONTENT_LOADED;\r
4703         processRequired(node, optionals, false);\r
4704 };\r
4705 \r
4706 /* private */\r
4707 var processRequired = function(node, arr, isMust) {\r
4708         if (arr && arr.length) {\r
4709                 unwrapArray(arr);\r
4710                 for (var i = 0; i < arr.length; i++) {\r
4711                         var name = arr[i];\r
4712                         if (!name)\r
4713                                 continue;\r
4714                         if (isClassDefined(name)\r
4715                                         || isClassExcluded(name))\r
4716                                 continue;\r
4717                         var n = findNode(name);\r
4718                         if (!n) {\r
4719                                 n = new Node();\r
4720                                 n.name = name;\r
4721                                 n.status = Node.STATUS_KNOWN;\r
4722                         }\r
4723                         n.requiredBy = node;\r
4724                         addChildClassNode(node, n, isMust);\r
4725                 }\r
4726         }\r
4727 }\r
4728 \r
4729 /*\r
4730  * Try to be compatiable of Clazz\r
4731  */\r
4732 if (window["Clazz"]) {\r
4733         Clazz.load = load;\r
4734 } else {\r
4735   _Loader.load = load;\r
4736 }  \r
4737 /**\r
4738  * Map different class to the same path! Many classes may be packed into\r
4739  * a *.z.js already.\r
4740  *\r
4741  * @path *.js path\r
4742  * @name class name\r
4743  * @node Node object\r
4744  */\r
4745 /* private */\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
4750         if (v) {\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
4755                                         existed = true;\r
4756                                         break;\r
4757                                 }\r
4758                         }\r
4759                         if (!existed)\r
4760                                 v.push(node);\r
4761                 } else {\r
4762                         map[keyPath] = [v, node];\r
4763                 }\r
4764         } else {\r
4765                 map[keyPath] = node;\r
4766         }\r
4767         map["#" + name] = node;\r
4768 };\r
4769 \r
4770 /* protected */\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
4776                 node.path = path;\r
4777                 mappingPathNameNode (path, name, node);\r
4778                 if (!loadedScripts[path]) {\r
4779                         loadScript(node, path, node.requiredBy, false);\r
4780                         return true;\r
4781                 }\r
4782         }\r
4783         return false;\r
4784 };\r
4785 \r
4786 \r
4787 /**\r
4788  * Used in package\r
4789 /* public */\r
4790 var runtimeKeyClass = _Loader.runtimeKeyClass = "java.lang.String";\r
4791 \r
4792 /**\r
4793  * Queue used to store classes before key class is loaded.\r
4794  */\r
4795 /* private */\r
4796 var queueBe4KeyClazz = [];\r
4797 \r
4798 /* private */\r
4799 var J2sLibBase;\r
4800 \r
4801 /**\r
4802  * Return J2SLib base path from existed SCRIPT src attribute.\r
4803  */\r
4804 /* public */\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
4808 };\r
4809 \r
4810 /**\r
4811  * Indicate whether _Loader is loading script synchronously or \r
4812  * asynchronously.\r
4813  */\r
4814 /* private */\r
4815 var isAsynchronousLoading = true;\r
4816 \r
4817 /* private */\r
4818 var isUsingXMLHttpRequest = false;\r
4819 \r
4820 /* private */\r
4821 var loadingTimeLag = -1;\r
4822 \r
4823 _Loader.MODE_SCRIPT = 4;\r
4824 _Loader.MODE_XHR = 2;\r
4825 _Loader.MODE_SYNC = 1;\r
4826 \r
4827 /**\r
4828  * String mode:\r
4829  * asynchronous modes:\r
4830  * async(...).script, async(...).xhr, async(...).xmlhttprequest,\r
4831  * script.async(...), xhr.async(...), xmlhttprequest.async(...),\r
4832  * script\r
4833  * \r
4834  * synchronous modes:\r
4835  * sync(...).xhr, sync(...).xmlhttprequest,\r
4836  * xhr.sync(...), xmlhttprequest.sync(...),\r
4837  * xmlhttprequest, xhr\r
4838  *                                                    \r
4839  * Integer mode:\r
4840  * Script 4; XHR 2; SYNC bit 1; \r
4841  */\r
4842 /* public */\r
4843 _Loader.setLoadingMode = function (mode, timeLag) {\r
4844         var async = true;\r
4845         var ajax = true;\r
4846         if (typeof mode == "string") {\r
4847                 mode = mode.toLowerCase();\r
4848                 if (mode.indexOf("script") >= 0)\r
4849                         ajax = false;\r
4850                 else\r
4851                         async = (mode.indexOf("async") >=0);\r
4852                 async = false; // BH\r
4853         } else {\r
4854                 if (mode & _Loader.MODE_SCRIPT)\r
4855                         ajax = false;\r
4856                 else\r
4857                         async = !(mode & _Loader.MODE_SYNC);\r
4858         }\r
4859         isUsingXMLHttpRequest = ajax;\r
4860         isAsynchronousLoading = async;\r
4861         loadingTimeLag = (async && timeLag >= 0 ? timeLag: -1);\r
4862         return async;\r
4863 };\r
4864 \r
4865 /* private */\r
4866 var runtimeLoaded = function () {\r
4867         if (pkgRefCount || !isClassDefined(runtimeKeyClass))\r
4868                 return;\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
4873 };\r
4874 \r
4875 /*\r
4876  * Load those key *.z.js. This *.z.js will be surely loaded before other \r
4877  * queued *.js.\r
4878  */\r
4879 /* public */\r
4880 _Loader.loadZJar = function (zjarPath, keyClass) {\r
4881 // used only by package.js for core.z.js\r
4882         var f = null;\r
4883         var isArr = (keyClass instanceof Array);\r
4884         if (isArr)\r
4885                 keyClass = keyClass[keyClass.length - 1];\r
4886         else\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
4891 };\r
4892 \r
4893 var NodeMap = {};\r
4894 var _allNodes = [];\r
4895 \r
4896 /**\r
4897  * The method help constructing the multiple-binary class dependency tree.\r
4898  */\r
4899 /* private */\r
4900 var addChildClassNode = function (parent, child, isMust) {\r
4901         var existed = false;\r
4902         var arr;\r
4903         if (isMust) {\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
4910 //              }\r
4911 //              if (!parent.requiresMap[child.name]) {\r
4912 //                      parent.requiresMap[child.name] = 1;\r
4913 //                      parent.requires.push[child];\r
4914 //              }\r
4915         } else {\r
4916                 arr = parent.optionals;\r
4917         }\r
4918         if (!NodeMap[child.name]) {\r
4919                 _allNodes.push(child)\r
4920                 NodeMap[child.name]=child\r
4921         }\r
4922         for (var i = 0; i < arr.length; i++) {\r
4923                 if (arr[i].name == child.name) {\r
4924                         existed = true;\r
4925                         break;\r
4926                 }\r
4927         }\r
4928         if (!existed) {\r
4929                 arr.push(child);\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
4941                 }\r
4942         }\r
4943         addParentClassNode(child, parent);\r
4944 };\r
4945 \r
4946 /* private */\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
4951                                 return;\r
4952         child.parents.push(parent);\r
4953 }\r
4954 \r
4955 /* private */\r
4956 var destroyClassNode = function (node) {\r
4957         var parents = node.parents;\r
4958         if (parents)\r
4959                 for (var k = parents.length; --k >= 0;)\r
4960                         removeArrayItem(parents[k].musts, node) || removeArrayItem(parents[k].optionals, node);\r
4961 };\r
4962 \r
4963 /* public */\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
4972         }\r
4973         var n = findNode(qClazzName);\r
4974         if (n) {\r
4975                 n.status = Node.STATUS_KNOWN;\r
4976                 loadedScripts[n.path] = false;\r
4977         }\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
4982 };\r
4983 \r
4984 /* private */\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
4989                         return;\r
4990                 var list = [];\r
4991                 var key = clzz + "$";\r
4992                 for (var s in Clazz.unloadedClasses)\r
4993                         if (Clazz.unloadedClasses[s] && s.indexOf(key) == 0)\r
4994                                 list.push(s);\r
4995                 if (!list.length) \r
4996                         return;\r
4997                 fun = "" + fun;\r
4998                 var idx1, idx2;\r
4999                 if ((idx1 = fun.indexOf(key)) < 0 || (idx2 = fun.indexOf("\"", idx1 + key.length)) < 0) \r
5000                         return;\r
5001                 clzz = fun.substring(idx1, idx2);\r
5002                 if (!Clazz.unloadedClasses[clzz] || (idx1 = fun.indexOf("{", idx2) + 1) == 0)\r
5003                         return;\r
5004                 if ((idx2 = fun.indexOf("(" + clzz + ",", idx1 + 3)) < 0\r
5005                         || (idx2 = fun.lastIndexOf("}", idx2 - 1)) < 0)\r
5006                                 return;\r
5007                 eval(fun.substring(idx1, idx2));\r
5008                 Clazz.unloadedClasses[clzz] = null;\r
5009         }\r
5010 };\r
5011 \r
5012 Clazz.binaryFolders =  _Loader.binaryFolders = [ _Loader.getJ2SLibBase() ];\r
5013 \r
5014 })(Clazz, Clazz._Loader);\r
5015 \r
5016 //}\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
5023  *\r
5024  * Contributors:\r
5025  *     Zhou Renjian - initial API and implementation\r
5026  *****************************************************************************/\r
5027 /*******\r
5028  * @author zhou renjian\r
5029  * @create Jan 11, 2007\r
5030  *******/\r
5031 \r
5032 Clazz._LoaderProgressMonitor = {};\r
5033 \r
5034 ;(function(CLPM, Jmol) {\r
5035 \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
5041 \r
5042 CLPM.DEFAULT_OPACITY = (Jmol && Jmol._j2sLoadMonitorOpacity ? Jmol._j2sLoadMonitorOpacity : 55);\r
5043 \r
5044 /* public */\r
5045 /*CLPM.initialize = function (parent) {\r
5046         bindingParent = parent;\r
5047         if (parent && !attached) {\r
5048                 attached = true;\r
5049                 //Clazz.addEvent (window, "unload", cleanup);\r
5050                 // window.attachEvent ("onunload", cleanup);\r
5051         }\r
5052 };\r
5053 */\r
5054 \r
5055 /* public */\r
5056 CLPM.hideMonitor = function () {\r
5057         monitorEl.style.display = "none";\r
5058 }\r
5059 \r
5060 /* public */\r
5061 CLPM.showStatus = function (msg, fading) {\r
5062         if (!monitorEl) {\r
5063                 createHandle ();\r
5064                 if (!attached) {\r
5065                         attached = true;\r
5066                         //Clazz.addEvent (window, "unload", cleanup);\r
5067                         // window.attachEvent ("onunload", cleanup);\r
5068                 }\r
5069         }\r
5070         clearChildren(monitorEl);\r
5071   if (msg == null) {\r
5072     if (fading) {\r
5073       fadeOut();\r
5074     } else {\r
5075         CLPM.hideMonitor();\r
5076     }\r
5077     return;\r
5078   }\r
5079   \r
5080         monitorEl.appendChild(document.createTextNode ("" + msg));\r
5081         if (monitorEl.style.display == "none") {\r
5082                 monitorEl.style.display = "";\r
5083         }\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
5089         }\r
5090         if (fading) {\r
5091                 fadeOut();\r
5092         }\r
5093 };\r
5094 \r
5095 /* private static */ \r
5096 var clearChildren = function (el) {\r
5097         if (!el)\r
5098                 return;\r
5099         for (var i = el.childNodes.length; --i >= 0;) {\r
5100                 var child = el.childNodes[i];\r
5101                 if (!child)\r
5102                         continue;\r
5103                 if (child.childNodes && child.childNodes.length)\r
5104                         clearChildren (child);\r
5105                 try {\r
5106                         el.removeChild (child);\r
5107                 } catch (e) {};\r
5108         }\r
5109 };\r
5110 /* private */ \r
5111 var setAlpha = function (alpha) {\r
5112         if (fadeOutTimer && alpha == CLPM.DEFAULT_OPACITY) {\r
5113                 window.clearTimeout (fadeOutTimer);\r
5114                 fadeOutTimer = null;\r
5115         }\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
5120 };\r
5121 /* private */ \r
5122 var hidingOnMouseOver = function () {\r
5123   CLPM.hideMonitor();\r
5124 };\r
5125 \r
5126 /* private */ \r
5127 var attached = false;\r
5128 /* private */ \r
5129 var cleanup = function () {\r
5130         //if (monitorEl) {\r
5131         //      monitorEl.onmouseover = null;\r
5132         //}\r
5133         monitorEl = null;\r
5134         bindingParent = null;\r
5135         //Clazz.removeEvent (window, "unload", cleanup);\r
5136         //window.detachEvent ("onunload", cleanup);\r
5137         attached = false;\r
5138 };\r
5139 /* private */ \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
5147         monitorEl = div;\r
5148         if (bindingParent) {\r
5149                 bindingParent.appendChild(div);\r
5150         } else {\r
5151                 document.body.appendChild(div);\r
5152         }\r
5153         return div;\r
5154 };\r
5155 /* private */ \r
5156 \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
5161                                         fadeOut();\r
5162                                 }, 750);\r
5163                 fadeAlpha -= 5;\r
5164         } else if (fadeAlpha - 10 >= 0) {\r
5165                 setAlpha(fadeAlpha - 10);\r
5166                 fadeOutTimer = window.setTimeout(function () {\r
5167                                         fadeOut();\r
5168                                 }, 40);\r
5169         } else {\r
5170                 monitorEl.style.display = "none";\r
5171         }\r
5172 };\r
5173 /* private */\r
5174 var getFixedOffsetTop = function (){\r
5175         if (bindingParent) {\r
5176                 var b = bindingParent;\r
5177                 return b.scrollTop;\r
5178         }\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
5188 };\r
5189 \r
5190 /* not used in Jmol\r
5191 if (window["ClazzLoader"]) {\r
5192         _Loader.onScriptLoading = function(file) {\r
5193                 CLPM.showStatus("Loading " + file + "...");\r
5194         };\r
5195         _Loader.onScriptLoaded = function(file, isError) {\r
5196                 CLPM.showStatus(file + (isError ? " loading failed." : " loaded."), true);\r
5197         };\r
5198         _Loader.onGlobalLoaded = function(file) {\r
5199                 CLPM.showStatus("Application loaded.", true);\r
5200         };\r
5201         _Loader.onClassUnloaded = function(clazz) {\r
5202                 CLPM.showStatus("Class " + clazz + " is unloaded.", true);\r
5203   };\r
5204 }\r
5205 */\r
5206 \r
5207 })(Clazz._LoaderProgressMonitor, Jmol);\r
5208 \r
5209 //}\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
5216  *\r
5217  * Contributors:\r
5218  *     Zhou Renjian - initial API and implementation\r
5219  *****************************************************************************/\r
5220 /*******\r
5221  * @author zhou renjian\r
5222  * @create Nov 5, 2005\r
5223  *******/\r
5224 \r
5225 ;(function(Con, Sys) {\r
5226 /**\r
5227  * Setting maxTotalLines to -1 will not limit the console result\r
5228  */\r
5229 /* protected */\r
5230 Con.maxTotalLines =     10000;\r
5231 \r
5232 /* protected */\r
5233 Con.setMaxTotalLines = function (lines) {\r
5234         Con.maxTotalLines = (lines > 0 ? lines : 999999);\r
5235 }\r
5236 \r
5237 /* protected */\r
5238 Con.maxLatency = 40;\r
5239 \r
5240 /* protected */\r
5241 Con.setMaxLatency = function (latency) {\r
5242         Con.maxLatency = (latency > 0 ? latency : 40);\r
5243 };\r
5244 \r
5245 /* protected */\r
5246 Con.pinning  = false;\r
5247 \r
5248 /* protected */\r
5249 Con.enablePinning = function (enabled) {\r
5250         Con.pinning = enabled;\r
5251 };\r
5252 \r
5253 /* private */\r
5254 Con.linesCount = 0;\r
5255 \r
5256 /* private */\r
5257 Con.metLineBreak = false;\r
5258 \r
5259 \r
5260 /*\r
5261  * Give an extension point so external script can create and bind the console\r
5262  * themself.\r
5263  *\r
5264  * TODO: provide more template of binding console window to browser.\r
5265  */\r
5266 /* protected */\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
5271         return console;\r
5272 };\r
5273 \r
5274 var c160 = String.fromCharCode(160); //nbsp;\r
5275 c160 += c160+c160+c160;\r
5276 \r
5277 /* protected */\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
5283         if (!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
5289                         }\r
5290                 }\r
5291                 Con.linesCount = Con.maxTotalLines;\r
5292         }\r
5293 \r
5294         var willMeetLineBreak = false;\r
5295         s = (typeof s == "undefined" ? "" : s == null ? "null" : "" + s);\r
5296         s = s.replace (/\t/g, c160);\r
5297         if (s.length > 0)\r
5298                 switch (s.charAt(s.length - 1)) {\r
5299                 case '\n':\r
5300                 case '\r':\r
5301                         s = (s.length > 1 ? s.substring (0, s.length - (s.charAt (s.length - 2) == '\r' ? 2 : 1)) : "");\r
5302                         willMeetLineBreak = true;\r
5303                         break;\r
5304                 }\r
5305 \r
5306         var lines = null;\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
5316                         Con.linesCount++;\r
5317                 } else {\r
5318                         try {\r
5319                                 lastLineEl = console.childNodes[console.childNodes.length - 1];\r
5320                         } catch (e) {\r
5321                                 lastLineEl = document.createElement ("DIV");\r
5322                                 console.appendChild (lastLineEl);\r
5323                                 lastLineEl.style.whiteSpace = "nowrap";\r
5324                                 Con.linesCount++;\r
5325                         }\r
5326                 }\r
5327                 var el = document.createElement ("SPAN");\r
5328                 lastLineEl.appendChild (el);\r
5329                 el.style.whiteSpace = "nowrap";\r
5330                 if (color)\r
5331                         el.style.color = color;\r
5332                 var l = lines[i]\r
5333                 if (l.length == 0)\r
5334                         l = c160;\r
5335                 el.appendChild(document.createTextNode(l));\r
5336                 if (!Con.pinning)\r
5337                         console.scrollTop += 100;\r
5338                 Con.metLineBreak = (i != last || willMeetLineBreak);\r
5339         }\r
5340 \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
5345         }\r
5346         Con.lastOutputTime = new Date ().getTime ();\r
5347 };\r
5348 \r
5349 /*\r
5350  * Clear all contents inside the console.\r
5351  */\r
5352 /* public */\r
5353 Con.clear = function () {\r
5354         try {\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
5359                         return;\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
5364         } catch(e){};\r
5365 };\r
5366 \r
5367 /* public */\r
5368 Clazz.alert = function (s) {\r
5369         Con.consoleOutput (s + "\r\n");\r
5370 };\r
5371 \r
5372 \r
5373 /* public */\r
5374 Sys.out.print = function (s) { \r
5375         Con.consoleOutput (s);\r
5376 };\r
5377 /* public */\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
5380 };\r
5381 \r
5382 Sys.out.write = function (buf, offset, len) {\r
5383         Sys.out.print(String.instantialize(buf).substring(offset, offset+len));\r
5384 };\r
5385 \r
5386 /* public */\r
5387 Sys.err.__CLASS_NAME__ = "java.io.PrintStream";\r
5388 \r
5389 /* public */\r
5390 Sys.err.print = function (s) { \r
5391         Con.consoleOutput (s, "red");\r
5392 };\r
5393 \r
5394 /* public */\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
5397 };\r
5398 \r
5399 Sys.err.write = function (buf, offset, len) {\r
5400         Sys.err.print(String.instantialize(buf).substring(offset, offset+len));\r
5401 };\r
5402 \r
5403 })(Clazz.Console, System);\r
5404 \r
5405 })(Clazz, Jmol); // requires JSmolCore.js\r
5406 \r
5407 }; // called by external application \r