c4e47ed1b0987ce6326668008bae1726406eccda
[jalviewjs.git] / site / js / j2sSwingJS.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/24/2015 6:48:50 AM adding optional ?j2sdebug flag on page URL\r
47  //                      -- switches to using j2s/core/corexxx.js, not j2s/core/corexxx.z.js \r
48  //                      -- adds ";//# sourceURL="+file  in eval(js)\r
49  //                      -- enables DebugJS.$(msg) call to debugger;\r
50  //  see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger\r
51  //  see https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Debug_eval_sources\r
52  // BH 7/23/2015 6:45:55 PM added sourceURL in each js class eval(), allowing full \r
53  //                         breakpoint debugging and code checking in Firefox and Chrome\r
54  // BH 7/19/2015 6:18:17 PM added os.name, line.separator, etc. to System.getProperty()\r
55  // BH 7/19/2015 5:39:10 PM added java.lang.System = System\r
56  // BH 7/19/2015 10:33:10 AM fix for SAEM equating "null" with number or boolean\r
57  // BH 7/18/2015 6:08:05 PM for Jmol I was able to remove the $private/$fx business, but now\r
58  //    I see that in general that cannot be done. Thinking about a strategy...\r
59  // BH 7/18/2015 4:43:38 PM better handling of TypeError and InternalError for e.getMessage() and e.getStackTrace()\r
60  // BH 7/17/2015 11:51:15 AM adds class.getResource(name) and class.getResourceAsStream(name) \r
61  // BH 7/16/2015 7:56:49 PM general instantiation using any constructor (in Java here):\r
62  // BH  x = class.forName("my.class.name").newInstance()\r
63  // BH or\r
64  // BH  x = class.forName("my.class.name").getConstructor(String.class,String.class).newInstance(new Object[] {"test", "now"})\r
65  // BH 7/15/2015 11:34:58 PM adding System.lineSeparator()\r
66  // BH 7/15/2015 7:32:41 AM adding class.getCanonicalName == getName\r
67  // BH 5/31/2015 5:38:14 PM  NPEExceptionPredicate fix\r
68  // BH 4/25/2015 9:16:12 AM SAEM misrepresnting Number as Object in parameters and Integer as Number \r
69  // BH 4/24/2015 7:32:54 AM Object.hashCode() and System.getIdentityHashCode() fail. changed to:     return this._$hashcode || (this._$hashcode = ++Clazz._hashCode)\r
70  // BH 4/23/2015 9:08:59 AM Clazz.instanceOf(a, b) needs to check for a == b.   \r
71  // BH 4/23/2015 9:08:59 AM xx.getContentType() is nonfunctional. Array.newInstance now defines a wrapper for .getClass().getComponentType() that works  \r
72  // BH 4/12/2015 11:48:03 AM added Clazz.getStackTrace(-n) -- reports actual parameter values for n levels\r
73  // BH 4/10/2015 8:23:05 AM adding Int32Array.prototype.clone and Float64.prototype.clone\r
74  // BH 4/5/2015 8:12:57 AM refactoring j2slib (this file) to make private functions really private using var\r
75  // BH 4/3/2015 6:14:34 AM adding anonymous local "ClazzLoader" (Clazz._Loader) --> "_Loader"\r
76  // BH 4/3/2015 6:14:34 AM adding Clazz._Loader._classPending, Clazz._Loader._classCount\r
77  // BH 4/3/2015 6:14:34 AM adding Clazz._Loader._checkLoad \r
78  //  -- forces asynchronous class loading\r
79  //  -- builds Clazz._Loader._classPending and Clazz._classCount\r
80  //  -- allows reporting \r
81  \r
82  // BH 3/24/2015 4:11:26 AM better file load failure message in _Loader.evaluate \r
83  // BH 2/28/2015 7:30:25 AM corrects newIntArray32() and newArray() for pre-defined arrays \r
84  //             int[] a =  new int[] {1,2,3,343};\r
85  //             int[][] b = new int[][] {new int[]{4,5},new int[]{5,6}}; \r
86 \r
87  // BH 9/29/2014 11:34:19 PM removing support for getClass().isArray() \r
88  // BH 8/29/2014 9:15:57 AM total reworking of Java2Script in preparation for all-asynchronous loading\r
89  //                         (currently sync loading is only for \r
90  //                                                                                                LOAD command and load() function without ASYNC\r
91  //                            getInterface() \r
92  //                         see JSmol.js and Jmol._isAsync flag\r
93  // BH 5/11/2015 5:58:42 AM adding __signatures for debugging SAEM issues \r
94  // BH 3/29/2015 8:12:44 PM System.getProperty(x, "") does not return ""\r
95  // BH 8/23/2014 10:04:19 AM cleaning up a few general methods; Clazz.removeArrayItem\r
96  // BH 6/1/2014 10:58:46 AM fix for Clazz.isAP() not working\r
97  // BH 5/26/2014 5:19:29 PM removing superConstructor call in creating Enum constants\r
98  // BH 4/1/2014 7:55:54 PM removing all $fz references and instances where sub/super classes have same private function names\r
99  // BH 4/1/2014 4:47:30 PM all $_X removed; this is taken care of by Google Closure Compiler\r
100  // BH 4/1/2014 6:40:08 AM removing ClassLoader -- equals Clazz._Loader\r
101  // BH 4/1/2014 6:40:08 AM removing ClassLoaderProgressMonitor -- equals _LoaderProgressMonitor\r
102  // BH 4/1/2014 6:17:21 AM removing Class  -- only used for "Class.forName" in Jmol, which ANT will now change to "Clazz._4Name"\r
103  // BH 3/7/2014 9:05:06 AM Array.prototype.toString should not be aliased. -- http://sourceforge.net/p/jmol/bugs/560/ with Google Visualization\r
104 \r
105  // BH 1/30/2014 12:54:22 PM gave all field variables prefix underscore. This allows Google Closure Compiler to skip them.  \r
106  // BH 12/3/2013 3:39:57 PM window["j2s.lib"].base implemented\r
107  // BH 12/1/2013 5:34:21 AM removed _LoaderProgressMonitor.initialize and all Clazz.event business; handled by Jmol.clearVars()\r
108  // BH 11/30/2013 12:43:58 PM adding Clazz.arrayIs() -- avoids Number.constructor.toString() infinite recursion\r
109  // BH 11/29/2013 6:33:51 AM adding Clazz._profiler -- reports use of SAEM\r
110  // BH 11/10/2013 9:02:20 AM fixing fading in MSIE  \r
111  // BH 11/3/2013 7:21:39 AM additional wrapping functions for better compressibility\r
112  // BH 10/30/2013 8:10:58 AM added getClass().getResource() -- returning a relative string, not a URL\r
113  // BH 10/30/2013 6:43:00 AM removed second System def and added System.$props and default System.property "line.separator" \r
114  // BH 6/15/2013 8:02:07 AM corrections to Class.isAS to return true if first element is null\r
115  // BH 6/14/2013 4:41:09 PM corrections to Clazz.isAI and related methods to include check for null object\r
116  // BH 3/17/2013 11:54:28 AM adds stackTrace for ERROR \r
117 \r
118  // BH 3/13/2013 6:58:26 PM adds Clazz.clone(me) for BS clone \r
119  // BH 3/12/2013 6:30:53 AM fixes Clazz.exceptionOf for ERROR condition trapping\r
120  // BH 3/2/2013 9:09:53 AM delete globals c$ and $fz\r
121  // BH 3/2/2013 9:10:45 AM optimizing defineMethod using "look no further" "@" parameter designation (see "\\@" below -- removed 3/23/13)\r
122  // BH 2/27/2013 optimizing Clazz.getParamsType for common cases () and (Number)\r
123  // BH 2/27/2013 optimizing SAEM delegation for hashCode and equals -- disallows overloading of equals(Object)\r
124  \r
125  // BH 2/23/2013 found String.replaceAll does not work -- solution was to never call it.\r
126  // BH 2/9/2013 9:18:03 PM Int32Array/Float64Array fixed for MSIE9\r
127  // BH 1/25/2013 1:55:31 AM moved package.js from j2s/java to j2s/core \r
128  // BH 1/17/2013 4:37:17 PM String.compareTo() added\r
129  // BH 1/17/2013 4:52:22 PM Int32Array and Float64Array may not have .prototype.sort method\r
130  // BH 1/16/2013 6:20:34 PM Float64Array not available in Safari 5.1\r
131  // BH 1/14/2013 11:28:58 PM  Going to all doubles in JavaScript (Float64Array, not Float32Array)\r
132  //   so that (new float[] {13.48f})[0] == 13.48f, effectively\r
133 \r
134  // BH 1/14/2013 12:53:41 AM  Fix for Opera 10 not loading any files\r
135  // BH 1/13/2013 11:50:11 PM  Fix for MSIE not loading (nonbinary) files locally\r
136  \r
137  // BH 12/1/2012 9:52:26 AM Compiler note: Thread.start() cannot be executed within the constructor;\r
138  \r
139  // BH 11/24/2012 11:08:39 AM removed unneeded sections\r
140  // BH 11/24/2012 10:23:22 AM  all XHR uses sync loading (_Loader.setLoadingMode)\r
141  // BH 11/21/2012 7:30:06 PM    if (base)       map["@" + pkg] = base;  critical for multiple applets\r
142 \r
143  // BH 10/8/2012 3:27:41 PM         if (clazzName.indexOf("Array") >= 0) return "Array"; in Clazz.getClassName for function\r
144  // BH removed Clazz.ie$plit = "\\2".split (/\\/).length == 1; unnecessary; using RegEx slows process significantly in all browsers\r
145  // BH 10/6/12 added Int32Array, Float32Array, newArrayBH, upgraded java.lang and java.io\r
146  // BH added Integer.bitCount in core.z.js\r
147  // BH changed alert to Clazz.alert in java.lang.Class.js *.ClassLoader.js, java.lang.thread.js\r
148  // BH removed toString from innerFunctionNames due to infinite recursion\r
149  // BH note: Logger.error(null, e) does not work -- get no constructor for (String) (TypeError)\r
150  // BH added j2s.lib.console\r
151  // BH allowed for alias="."\r
152  // BH removed alert def --> Clazz.alert\r
153  // BH added wrapper at line 2856 \r
154  // BH newArray fix at line 2205\r
155  // BH System.getProperty fix at line 6693\r
156  // BH added Enum .value() method at line 2183\r
157  // BH added System.getSecurityManager() at end\r
158  // BH added String.contains() at end\r
159  // BH added System.gc() at end\r
160  // BH added Clazz.exceptionOf = updated\r
161  // BH added String.getBytes() at end\r
162  \r
163 \r
164 LoadClazz = function() {\r
165 \r
166 // BH This is the ONLY global used in J2S now. I do not think it is necessary,\r
167 // but it is created by the compiler, and I have not found a work-around.\r
168 // it is used as a local variable in class definitions to point to the \r
169 // current method. See Clazz.p0p and Clazz.pu$h\r
170 \r
171 c$ = null;\r
172 \r
173 if (!window["j2s.clazzloaded"])\r
174         window["j2s.clazzloaded"] = false;\r
175 \r
176 if (window["j2s.clazzloaded"])return;\r
177 \r
178 window["j2s.clazzloaded"] = true;\r
179 \r
180 window["j2s.object.native"] = true;\r
181 \r
182  // Clazz changes:\r
183 \r
184  /* http://j2s.sf.net/ *//******************************************************************************\r
185  * Copyright (c) 2007 java2script.org and others.\r
186  * All rights reserved. This program and the accompanying materials\r
187  * are made available under the terms of the Eclipse Public License v1.0\r
188  * which accompanies this distribution, and is available at\r
189  * http://www.eclipse.org/legal/epl-v10.html\r
190  *\r
191  * Contributors:\r
192  *     Zhou Renjian - initial API and implementation\r
193  *****************************************************************************/\r
194 /*******\r
195  * @author zhou renjian\r
196  * @create Nov 5, 2005\r
197  *******/\r
198  \r
199 \r
200 /**\r
201  * Class Clazz. All the methods are static in this class.\r
202  */\r
203 /* static */\r
204 /*Class = */ Clazz = {\r
205   _isQuiet: false,\r
206   _debugging: false\r
207 };\r
208 \r
209 ;(function(Clazz, Jmol) {\r
210 \r
211 \r
212 try {\r
213 Clazz._debugging = (document.location.href.indexOf("j2sdebug") >= 0);\r
214 } catch (e) {\r
215 }\r
216 var __debuggingBH = false;\r
217 var _globals = ["j2s.clazzloaded", "j2s.object.native"];\r
218 Clazz.setGlobal = function(a, v) {\r
219         _globals.push(a);\r
220         window[a] = v;\r
221 }\r
222 \r
223 Clazz.getGlobals = function() {\r
224         return _globals.sort().join("\n");\r
225 }\r
226 \r
227 Clazz.setConsoleDiv = function(d) {\r
228         window["j2s.lib"] && (window["j2s.lib"].console = d);\r
229 };\r
230 \r
231 // BH Clazz.getProfile monitors exactly what is being delegated with SAEM,\r
232 // which could be a bottle-neck for function calling.\r
233 // This is critical for performance optimization.\r
234 \r
235 // Jmol.getProfile()\r
236 \r
237 var _profile = (window["j2s.doProfile"]  && self.JSON ? {} : null);\r
238 \r
239 NullObject = function () {};\r
240 \r
241 /* protected */\r
242 Clazz._supportsNativeObject = window["j2s.object.native"];\r
243 \r
244 if (Clazz._supportsNativeObject) {\r
245         Clazz._O = function () {};\r
246         Clazz._O.__CLASS_NAME__ = "Object";\r
247         Clazz._O["getClass"] = function () { return Clazz._O; }; \r
248 } else {\r
249         Clazz._O = Object;\r
250 }\r
251 \r
252 Clazz.Console = {};\r
253 Clazz.dateToString = Date.prototype.toString;\r
254 Clazz._hashCode = 0;\r
255 \r
256 var addProto = function(proto, name, func) {\r
257         return proto[name] = func;\r
258 };\r
259 \r
260 ;(function(proto) {\r
261         addProto(proto, "equals", function (obj) {\r
262                 return this == obj;\r
263         });\r
264 \r
265         addProto(proto, "hashCode", function () {\r
266   \r
267     return this._$hashcode || (this._$hashcode = ++Clazz._hashCode)\r
268 \r
269   \r
270                 try {\r
271                         return this.toString ().hashCode ();\r
272                 } catch (e) {\r
273                         var str = ":";\r
274                         for (var s in this) {\r
275                                 str += s + ":"\r
276                         }\r
277                         return str.hashCode ();\r
278                 }\r
279         });\r
280 \r
281         addProto(proto, "getClass", function () { return Clazz.getClass (this); });\r
282 \r
283         addProto(proto, "clone", function () { return Clazz.clone(this); });\r
284 \r
285         Clazz.clone = function(me) {\r
286                 // BH allows @j2sNative access without super constructor\r
287                 var o = new me.constructor();\r
288                 for (var i in me) {\r
289                         o[i] = me[i];\r
290       }\r
291                 return o;\r
292         }\r
293 /*\r
294  * Methods for thread in Object\r
295  */\r
296         addProto(proto, "finalize", function () {});\r
297         addProto(proto, "notify", function () {});\r
298         addProto(proto, "notifyAll", function () {});\r
299         addProto(proto, "wait", function () {});\r
300         addProto(proto, "to$tring", Object.prototype.toString);\r
301         addProto(proto, "toString", function () { return (this.__CLASS_NAME__ ? "[" + this.__CLASS_NAME__ + " object]" : this.to$tring.apply(this, arguments)); });\r
302         Clazz._extendedObjectMethods = [ "equals", "hashCode", "getClass", "clone", "finalize", "notify", "notifyAll", "wait", "to$tring", "toString" ];\r
303 \r
304 })(Clazz._O.prototype);\r
305 \r
306 Clazz.extendJO = function(c, name) {  \r
307         if (name)\r
308                 c.__CLASS_NAME__ = c.prototype.__CLASS_NAME__ = name;\r
309         if (Clazz._supportsNativeObject) {\r
310                 for (var i = 0; i < Clazz._extendedObjectMethods.length; i++) {\r
311                         var p = Clazz._extendedObjectMethods[i];\r
312                         addProto(c.prototype, p, Clazz._O.prototype[p]);\r
313                 }\r
314         }\r
315 };\r
316 \r
317 /**\r
318  * Try to fix bug on Safari\r
319  */\r
320 //InternalFunction = Object;\r
321 \r
322 Clazz.extractClassName = function(clazzStr) {\r
323         // [object Int32Array]\r
324         var clazzName = clazzStr.substring (1, clazzStr.length - 1);\r
325         return (clazzName.indexOf("Array") >= 0 ? "Array" // BH -- for Float64Array and Int32Array\r
326                 : clazzName.indexOf ("object ") >= 0 ? clazzName.substring (7) // IE\r
327                 : clazzName);\r
328 }\r
329 /**\r
330  * Return the class name of the given class or object.\r
331  *\r
332  * @param clazzHost given class or object\r
333  * @return class name\r
334  */\r
335 /* public */\r
336 Clazz.getClassName = function (obj) {\r
337         if (obj == null)\r
338                 return "NullObject";\r
339         if (obj instanceof Clazz.CastedNull)\r
340                 return obj.clazzName;\r
341         switch(typeof obj) {\r
342         case "number":\r
343                 return "n";\r
344         case "boolean":\r
345                 return "b";\r
346         case "string":\r
347                 // Always treat the constant string as String object.\r
348                 // This will be compatiable with Java String instance.\r
349                 return "String";\r
350         case "function":\r
351                 if (obj.__CLASS_NAME__)\r
352                         return (arguments[1] ? obj.__CLASS_NAME__ : "Class"); /* user defined class name */\r
353                 var s = obj.toString();\r
354                 var idx0 = s.indexOf("function");\r
355                 if (idx0 < 0)\r
356                         return (s.charAt(0) == '[' ? Clazz.extractClassName(s) : s.replace(/[^a-zA-Z0-9]/g, ''));\r
357                 var idx1 = idx0 + 8;\r
358                 var idx2 = s.indexOf ("(", idx1);\r
359                 if (idx2 < 0)\r
360                         return "Object";\r
361                 s = s.substring (idx1, idx2);\r
362                 if (s.indexOf("Array") >= 0)\r
363                         return "Array"; \r
364                 s = s.replace (/^\s+/, "").replace (/\s+$/, "");\r
365                 return (s == "anonymous" || s == "" ? "Function" : s);\r
366         case "object":\r
367                 if (obj.__CLASS_NAME__) // user defined class name\r
368                         return obj.__CLASS_NAME__;\r
369                 if (!obj.constructor)\r
370                         return "Object"; // For HTML Element in IE\r
371                 if (!obj.constructor.__CLASS_NAME__) {\r
372                         if (obj instanceof Number)\r
373                                 return "Number";\r
374                         if (obj instanceof Boolean)\r
375                                 return "Boolean";\r
376                         if (obj instanceof Array)\r
377                                 return "Array";\r
378                         var s = obj.toString();\r
379       // "[object Int32Array]"\r
380                         if (s.charAt(0) == '[')\r
381                                 return Clazz.extractClassName(s);\r
382                 }\r
383         return Clazz.getClassName (obj.constructor, true);\r
384         }\r
385   // some new, unidentified class\r
386   return "Object";\r
387 };\r
388 /**\r
389  * Return the class of the given class or object.\r
390  *\r
391  * @param clazzHost given class or object\r
392  * @return class name\r
393  */\r
394 /* public */\r
395 Clazz.getClass = function (clazzHost) {\r
396         if (!clazzHost)\r
397                 return Clazz._O;        // null/undefined is always treated as Object\r
398         if (typeof clazzHost == "function")\r
399                 return clazzHost;\r
400         var clazzName;\r
401         if (clazzHost instanceof Clazz.CastedNull) {\r
402                 clazzName = clazzHost.clazzName;\r
403         } else {\r
404                 switch (typeof clazzHost) {\r
405                 case "string":\r
406                         return String;\r
407           case "object":\r
408                         if (!clazzHost.__CLASS_NAME__)\r
409                                 return (clazzHost.constructor || Clazz._O);\r
410                         clazzName = clazzHost.__CLASS_NAME__;\r
411                 break;\r
412                 default:\r
413                         return clazzHost.constructor;\r
414                 }\r
415         }\r
416         return Clazz.evalType(clazzName, true);\r
417 };\r
418 \r
419 \r
420 /* private */\r
421 var checkInnerFunction = function (hostSuper, funName) {\r
422         for (var k = 0; k < Clazz.innerFunctionNames.length; k++)\r
423                 if (funName == Clazz.innerFunctionNames[k] && \r
424                                 Clazz._innerFunctions[funName] === hostSuper[funName])\r
425                         return true;\r
426         return false;\r
427 };\r
428 \r
429 var args4InheritClass = function () {};\r
430 \r
431 Clazz.inheritArgs = new args4InheritClass ();\r
432 \r
433 /**\r
434  * Inherit class with "extends" keyword and also copy those static members. \r
435  * Example, as in Java, if NAME is a static member of ClassA, and ClassB \r
436  * extends ClassA then ClassB.NAME can be accessed in some ways.\r
437  *\r
438  * @param clazzThis child class to be extended\r
439  * @param clazzSuper super class which is inherited from\r
440  * @param objSuper super class instance\r
441  */\r
442 /* protected */\r
443 Clazz.inheritClass = function (clazzThis, clazzSuper, objSuper) {\r
444         //var thisClassName = Clazz.getClassName (clazzThis);\r
445         for (var o in clazzSuper) {\r
446                 if (o != "b$" && o != "prototype" && o != "superClazz"\r
447                                 && o != "__CLASS_NAME__" && o != "implementz"\r
448                                 && !checkInnerFunction (clazzSuper, o)) {\r
449                         clazzThis[o] = clazzSuper[o];\r
450                 }\r
451         }\r
452         if (Clazz.unloadedClasses[Clazz.getClassName(clazzThis, true)]) {\r
453                 // Don't change clazzThis.protoype! Keep it!\r
454         } else if (objSuper) {\r
455                 // ! Unsafe reference prototype to an instance!\r
456                 // Feb 19, 2006 --josson\r
457                 // OK for this reference to an instance, as this is anonymous instance,\r
458                 // which is not referenced elsewhere.\r
459                 // March 13, 2006\r
460                 clazzThis.prototype = objSuper; \r
461         } else if (clazzSuper !== Number) {\r
462                 clazzThis.prototype = new clazzSuper (Clazz.inheritArgs);\r
463         } else { // Number\r
464                 clazzThis.prototype = new Number ();\r
465         }\r
466         clazzThis.superClazz = clazzSuper;\r
467         /*\r
468          * Is it necessary to reassign the class name?\r
469          * Mar 10, 2006 --josson\r
470          */\r
471         //clazzThis.__CLASS_NAME__ = thisClassName;\r
472         clazzThis.prototype.__CLASS_NAME__ = clazzThis.__CLASS_NAME__;\r
473 };\r
474 \r
475 /**\r
476  * Implementation of Java's keyword "implements".\r
477  * As in JavaScript there are on "implements" keyword implemented, a property\r
478  * of "implementz" is added to the class to record the interfaces the class\r
479  * is implemented.\r
480  * \r
481  * @param clazzThis the class to implement\r
482  * @param interfacez Array of interfaces\r
483  */\r
484 /* public */\r
485 Clazz.implementOf = function (clazzThis, interfacez) {\r
486         if (arguments.length >= 2) {\r
487                 if (!clazzThis.implementz)\r
488                         clazzThis.implementz = [];\r
489                 var impls = clazzThis.implementz;\r
490                 if (arguments.length == 2) {\r
491                         if (typeof interfacez == "function") {\r
492                                 impls.push(interfacez);\r
493                                 copyProperties(clazzThis, interfacez);\r
494                         } else if (interfacez instanceof Array) {\r
495                                 for (var i = 0; i < interfacez.length; i++) {\r
496                                         impls.push(interfacez[i]);\r
497                                         copyProperties(clazzThis, interfacez[i]);\r
498                                 }\r
499                         }\r
500                 } else {\r
501                         for (var i = 1; i < arguments.length; i++) {\r
502                                 impls.push(arguments[i]);\r
503                                 copyProperties(clazzThis, arguments[i]);\r
504                         }\r
505                 }\r
506         }\r
507 };\r
508 \r
509 /*\r
510  * Copy members of interface\r
511  */\r
512 /* private */\r
513 var copyProperties = function(clazzThis, clazzSuper) {\r
514         for (var o in clazzSuper)\r
515                 if (o != "b$" \r
516                                 && o != "prototype" && o != "superClazz"\r
517                                 && o != "__CLASS_NAME__" && o != "implementz"\r
518                                 && (typeof clazzSuper[o] != "function" || !checkInnerFunction(clazzSuper, o)))\r
519                         clazzThis[o] = clazzThis.prototype[o] = clazzSuper[o];\r
520 };\r
521 \r
522 /**\r
523  * TODO: More should be done for interface's inheritance\r
524  */\r
525 /* public */\r
526 Clazz.extendInterface = Clazz.implementOf;\r
527 \r
528 /* protected */\r
529 Clazz.equalsOrExtendsLevel = function (clazzThis, clazzAncestor) {\r
530         if (clazzThis === clazzAncestor)\r
531                 return 0;\r
532         if (clazzThis.implementz) {\r
533                 var impls = clazzThis.implementz;\r
534                 for (var i = 0; i < impls.length; i++) {\r
535                         var level = Clazz.equalsOrExtendsLevel (impls[i], clazzAncestor);\r
536                         if (level >= 0)\r
537                                 return level + 1;\r
538                 }\r
539         }\r
540         return -1;\r
541 };\r
542 \r
543 /* protected */\r
544 Clazz.getInheritedLevel = function (clazzTarget, clazzBase) {\r
545         if (clazzTarget === clazzBase)\r
546                 return 0;\r
547         var isTgtStr = (typeof clazzTarget == "string");\r
548         if (isTgtStr && ("void" == clazzTarget || "unknown" == clazzTarget))\r
549                 return -1;\r
550         var isBaseStr = (typeof clazzBase == "string");\r
551         if (isBaseStr && ("void" == clazzBase || "unknown" == clazzBase))\r
552                 return -1;\r
553         if (clazzTarget === (isTgtStr ? "NullObject" : NullObject)) {\r
554                 switch (clazzBase) {\r
555     case "n":\r
556     case "b":\r
557       return -1;\r
558                 case Number:\r
559                 case Boolean:\r
560                 case NullObject:\r
561                         break;\r
562                 default:\r
563                         return 0;\r
564                 }\r
565         }\r
566         if (isTgtStr)\r
567                 clazzTarget = Clazz.evalType(clazzTarget);\r
568         if (isBaseStr)\r
569                 clazzBase = Clazz.evalType(clazzBase);\r
570         if (!clazzBase || !clazzTarget)\r
571                 return -1;\r
572         var level = 0;\r
573         var zzalc = clazzTarget; // zzalc <--> clazz\r
574         while (zzalc !== clazzBase && level < 10) {\r
575                 /* maybe clazzBase is interface */\r
576                 if (zzalc.implementz) {\r
577                         var impls = zzalc.implementz;\r
578                         for (var i = 0; i < impls.length; i++) {\r
579                                 var implsLevel = Clazz.equalsOrExtendsLevel (impls[i], clazzBase);\r
580                                 if (implsLevel >= 0)\r
581                                         return level + implsLevel + 1;\r
582                         }\r
583                 }\r
584                 zzalc = zzalc.superClazz;\r
585                 if (!zzalc)\r
586                         return (clazzBase === Object || clazzBase === Clazz._O ? \r
587                                 // getInheritedLevel(String, CharSequence) == 1\r
588                                 // getInheritedLevel(String, Object) == 1.5\r
589                                 // So if both #test(CharSequence) and #test(Object) existed,\r
590                                 // #test("hello") will correctly call #test(CharSequence)\r
591                                 // instead of #test(Object).\r
592                                 level + 1.5 // 1.5! Special!\r
593                         : -1);\r
594                 level++;\r
595         }\r
596         return level;\r
597 };\r
598 \r
599 \r
600 /**\r
601  * Implements Java's keyword "instanceof" in JavaScript's way.\r
602  * As in JavaScript part of the object inheritance is implemented in only-\r
603  * JavaScript way.\r
604  *\r
605  * @param obj the object to be tested\r
606  * @param clazz the class to be checked\r
607  * @return whether the object is an instance of the class\r
608  */\r
609 /* public */\r
610 Clazz.instanceOf = function (obj, clazz) {\r
611   // allows obj to be a class already, from arrayX.getClass().isInstance(y)\r
612         return (obj != null && clazz && (obj == clazz || obj instanceof clazz || Clazz.getInheritedLevel(Clazz.getClassName(obj), clazz) >= 0));\r
613 };\r
614 \r
615 /**\r
616  * Call super method of the class. \r
617  * The same effect as Java's expression:\r
618  * <code> super.* () </code>\r
619  * \r
620  * @param objThis host object\r
621  * @param clazzThis class of declaring method scope. It's hard to determine \r
622  * which super class is right class for "super.*()" call when it's in runtime\r
623  * environment. For example,\r
624  * 1. ClasssA has method #run()\r
625  * 2. ClassB extends ClassA overriding method #run() with "super.run()" call\r
626  * 3. ClassC extends ClassB\r
627  * 4. objC is an instance of ClassC\r
628  * Now we have to decide which super #run() method is to be invoked. Without\r
629  * explicit clazzThis parameter, we only know that objC.getClass() is ClassC \r
630  * and current method scope is #run(). We do not known we are in scope \r
631  * ClassA#run() or scope of ClassB#run(). if ClassB is given, Clazz can search\r
632  * all super methods that are before ClassB and get the correct super method.\r
633  * This is the reason why there must be an extra clazzThis parameter.\r
634  * @param funName method name to be called\r
635  * @param funParams Array of method parameters\r
636  */\r
637 /* public */\r
638 Clazz.superCall = function (objThis, clazzThis, funName, funParams) {\r
639         var fx = null;\r
640         var i = -1;\r
641         var clazzFun = objThis[funName];\r
642         if (clazzFun) {\r
643                 if (clazzFun.claxxOwner) { \r
644                         // claxxOwner is a mark for methods that is single.\r
645                         if (clazzFun.claxxOwner !== clazzThis) {\r
646                                 // This is a single method, call directly!\r
647                                 fx = clazzFun;\r
648         \r
649                         }\r
650                 } else if (!clazzFun.stacks && !(clazzFun.lastClaxxRef\r
651                                         && clazzFun.lastClaxxRef.prototype[funName]\r
652                                         && clazzFun.lastClaxxRef.prototype[funName].stacks)) { // super.toString\r
653                         fx = clazzFun;\r
654                 } else { // normal wrapped method\r
655                         var stacks = clazzFun.stacks;\r
656                         if (!stacks)\r
657                                 stacks = clazzFun.lastClaxxRef.prototype[funName].stacks;\r
658                         for (i = stacks.length; --i >= 0;) {\r
659                                 /*\r
660                                  * Once super call is computed precisely, there are no need \r
661                                  * to calculate the inherited level but just an equals\r
662                                  * comparision\r
663                                  */\r
664                                 //var level = Clazz.getInheritedLevel (clazzThis, stacks[i]);\r
665                                 if (clazzThis === stacks[i]) { // level == 0\r
666                                         if (i > 0) {\r
667                                                 fx = stacks[--i].prototype[funName];\r
668                                         } else {\r
669                                                 /*\r
670                                                  * Will this case be reachable?\r
671                                                  * March 4, 2006\r
672                                                  * Should never reach here if all things are converted\r
673                                                  * by Java2Script\r
674                                                  */\r
675                                                 fx = stacks[0].prototype[funName]["\\unknown"];\r
676                                         }\r
677                                         break;\r
678                                 } else if (Clazz.getInheritedLevel (clazzThis, stacks[i]) > 0) {\r
679                                         fx = stacks[i].prototype[funName];\r
680                                         break;\r
681                                 }\r
682                         } // end of for loop\r
683                 } // end of normal wrapped method\r
684         } // end of clazzFun\r
685         if (!fx) {\r
686                 if (funName != "construct") {\r
687                         Clazz.alert (["j2slib","no class found",(funParams).typeString])\r
688                         newMethodNotFoundException(objThis, clazzThis, funName, \r
689                                         Clazz.getParamsType(funParams).typeString);     \r
690                 }\r
691                 /* there are members which are initialized out of the constructor */\r
692                 /* No super constructor! */\r
693                 return;\r
694         }\r
695         /* there are members which are initialized out of the constructor */\r
696         if (i == 0 && funName == "construct") {\r
697                 var ss = clazzFun.stacks;\r
698                 if (ss && !ss[0].superClazz && ss[0].con$truct)\r
699                         ss[0].con$truct.apply (objThis, []);\r
700         }\r
701         /*# {$no.debug.support} >>x #*/\r
702         /* not used in Jmol\r
703         if (Clazz.tracingCalling) {\r
704                 var caller = arguments.callee.caller;\r
705                 if (caller === Clazz.superConstructor) {\r
706                         caller = caller.arguments.callee.caller;\r
707                 }\r
708                 Clazz._callingStackTraces.push(new Clazz.callingStack (caller, clazzThis));\r
709                 var ret = fx.apply (objThis, (funParams == null) ? [] : funParams);\r
710                 Clazz._callingStackTraces.pop();\r
711                 return ret;\r
712         }\r
713         */\r
714         /*# x<< #*/\r
715         return fx.apply (objThis, funParams || []);\r
716 };\r
717 \r
718 /**\r
719  * Call super constructor of the class. \r
720  * The same effect as Java's expression: \r
721  * <code> super () </code>\r
722  */\r
723 /* public */\r
724 Clazz.superConstructor = function (objThis, clazzThis, funParams) {\r
725         Clazz.superCall (objThis, clazzThis, "construct", funParams);\r
726         /* If there are members which are initialized out of the constructor */\r
727         if (clazzThis.con$truct) {\r
728                 clazzThis.con$truct.apply (objThis, []);\r
729         }\r
730 };\r
731 \r
732 /**\r
733  * Class for null with a given class as to be casted.\r
734  * This class will be used as an implementation of Java's casting way.\r
735  * For example,\r
736  * <code> this.call ((String) null); </code>\r
737  */\r
738 /* public */\r
739 Clazz.CastedNull = function (asClazz) {\r
740         if (asClazz) {\r
741                 if (asClazz instanceof String) {\r
742                         this.clazzName = asClazz;\r
743                 } else if (asClazz instanceof Function) {\r
744                         this.clazzName = Clazz.getClassName (asClazz, true);\r
745                 } else {\r
746                         this.clazzName = "" + asClazz;\r
747                 }\r
748         } else {\r
749                 this.clazzName = "Object";\r
750         }\r
751         this.toString = function () {\r
752                 return null;\r
753         };\r
754         this.valueOf = function () {\r
755                 return null;\r
756         };\r
757 };\r
758 \r
759 /**\r
760  * API for Java's casting null.\r
761  * @see Clazz.CastedNull\r
762  *\r
763  * @param asClazz given class\r
764  * @return an instance of class Clazz.CastedNull\r
765  */\r
766 /* public */\r
767 Clazz.castNullAs = function (asClazz) {\r
768         return new Clazz.CastedNull (asClazz);\r
769 };\r
770 \r
771 /////////////////////////// Exception handling ////////////////////////////\r
772 \r
773 /*\r
774  * Use to mark that the Throwable instance is created or not.\r
775  * \r
776  * Called from java.lang.Throwable, as defined in JSmolJavaExt.js\r
777  * \r
778  * The underscore is important - it tells the JSmol ANT task to NOT \r
779  * turn this into Clazz_initializingException, because coreBottom2.js does \r
780  * not include that call, and so Google Closure Compiler does not minify it.\r
781  *        \r
782  */\r
783 /* public */\r
784 Clazz._initializingException = false;\r
785 \r
786 /**\r
787  * BH: used in Throwable\r
788  *  \r
789  */  \r
790 /* public */\r
791 Clazz._callingStackTraces = [];\r
792 \r
793 /** \r
794  * MethodException will be used as a signal to notify that the method is\r
795  * not found in the current clazz hierarchy.\r
796  */\r
797 /* private */\r
798 var MethodException = function () {\r
799         this.toString = function () {\r
800                 return "J2S MethodException";\r
801         };\r
802 };\r
803 /* private */\r
804 //var MethodNotFoundException = function () {\r
805 //      this.toString = function () {\r
806 //              return "J2S MethodNotFoundException";\r
807 //      };\r
808 //};\r
809 \r
810   var _isNPEExceptionPredicate;\r
811 \r
812 /* super private */\r
813 ;(function() { \r
814   /* sgurin: native exception detection mechanism. Only NullPointerException detected and wrapped to java excepions */\r
815   /** private utility method for creating a general regexp that can be used later  \r
816    * for detecting a certain kind of native exceptions. use with error messages like "blabla IDENTIFIER blabla"\r
817    * @param msg String - the error message\r
818    * @param spliterName String, must be contained once in msg\r
819    * spliterRegex String, a string with the regexp literal for identifying the spitter in exception further error messages.\r
820    */\r
821   // reproduce NullPointerException for knowing how to detect them, and create detector function Clazz._isNPEExceptionPredicate\r
822   var $$o$$ = null;\r
823   \r
824   try {\r
825         $$o$$.hello();\r
826   } catch (e) {\r
827     var _ex_reg = function(msg, spliterName, spliterRegex) {\r
828         if(!spliterRegex) \r
829                 spliterRegex="[^\\s]+"; \r
830         var idx = msg.indexOf (spliterName), \r
831                 str = msg.substring (0, idx) + spliterRegex + msg.substring(idx + spliterName.length), \r
832                 regexp = new RegExp("^"+str+"$");\r
833         return regexp;\r
834     };\r
835         if(/Opera[\/\s](\d+\.\d+)/.test(navigator.userAgent)) {// opera throws an exception with fixed messages like "Statement on line 23: Cannot convert undefined or null to Object Backtrace: Line....long text... " \r
836                 var idx1 = e.message.indexOf(":"), idx2 = e.message.indexOf(":", idx1+2);\r
837                 var _NPEMsgFragment = e.message.substr(idx1+1, idx2-idx1-20);\r
838                 _isNPEExceptionPredicate = function(e) { return e.message.indexOf(_NPEMsgFragment)!=-1; };\r
839         }       else if(navigator.userAgent.toLowerCase().indexOf("webkit")!=-1) { //webkit, google chrome prints the property name accessed. \r
840                 var _exceptionNPERegExp = _ex_reg(e.message, "hello");\r
841                 _isNPEExceptionPredicate = function(e) { return _exceptionNPERegExp.test(e.message); };\r
842         }       else {// ie, firefox and others print the name of the object accessed: \r
843                 var _exceptionNPERegExp = _ex_reg(e.message, "$$o$$");\r
844                 _isNPEExceptionPredicate = function(e) { return _exceptionNPERegExp.test(e.message); };\r
845         }               \r
846   };\r
847 })();\r
848 \r
849 /**sgurin\r
850  * Implements Java's keyword "instanceof" in JavaScript's way **for exception objects**.\r
851  * \r
852  * calls Clazz.instanceOf if e is a Java exception. If not, try to detect known native \r
853  * exceptions, like native NullPointerExceptions and wrap it into a Java exception and \r
854  * call Clazz.instanceOf again. if the native exception can't be wrapped, false is returned.\r
855  * \r
856  * @param obj the object to be tested\r
857  * @param clazz the class to be checked\r
858  * @return whether the object is an instance of the class\r
859  * @author: sgurin\r
860  */\r
861 Clazz.exceptionOf = function(e, clazz) {\r
862         if(e.__CLASS_NAME__)\r
863                 return Clazz.instanceOf(e, clazz);\r
864   if (!e.getMessage) {\r
865     e.getMessage = function() {return "" + this};\r
866   }\r
867   if (!e.printStackTrace) {\r
868     e.printStackTrace = function(){};\r
869     alert(e + " try/catch path:" + Clazz.getStackTrace(-10));\r
870   }\r
871         if(clazz == Error) {\r
872                 if (("" + e).indexOf("Error") < 0)\r
873       return false;\r
874                 System.out.println (Clazz.getStackTrace());\r
875     return true;\r
876                 // everything here is a Java Exception, not a Java Error\r
877         }\r
878         return (clazz == Exception || clazz == Throwable\r
879                 || clazz == NullPointerException && _isNPEExceptionPredicate(e));\r
880 };\r
881 \r
882 /**\r
883  * BH need to limit this, as JavaScript call stack may be recursive\r
884  */ \r
885 Clazz.getStackTrace = function(n) {\r
886         n || (n = 25);\r
887   // updateNode and updateParents cause infinite loop here\r
888         var s = "\n";\r
889         var c = arguments.callee;\r
890   var showParams = (n < 0);\r
891   if (showParams)\r
892     n = -n;\r
893         for (var i = 0; i < n; i++) {\r
894                 if (!(c = c.caller))\r
895       break;\r
896     var sig = (c.toString ? c.toString().substring(0, c.toString().indexOf("{")) : "<native method>");\r
897                 s += i + " " + (c.exName ? (c.claxxOwner ? c.claxxOwner.__CLASS_NAME__ + "."  : "") + c.exName  + sig.replace(/function /,""): sig) + "\n";\r
898                 if (c == c.caller) {\r
899       s += "<recursing>\n";\r
900       break;\r
901     }\r
902     if (showParams) {\r
903       var args = c.arguments;\r
904       for (var j = 0; j < args.length; j++) {\r
905         var sa = "" + args[j];\r
906         if (sa.length > 60)\r
907           sa = sa.substring(0, 60) + "...";\r
908         s += " args[" + j + "]=" + sa.replace(/\s+/g," ") + "\n";\r
909       }\r
910     }\r
911         }\r
912         return s;\r
913 }\r
914 \r
915 ///////////////////// method creation ////////////////////////////////\r
916 \r
917 /**\r
918  * Make constructor for the class with the given function body and parameters\r
919  * signature.\r
920  * \r
921  * @param clazzThis host class\r
922  * @param funBody constructor body\r
923  * @param funParams constructor parameters signature\r
924  */\r
925 /* public */\r
926 Clazz.makeConstructor = function (clazzThis, funBody, funParams) {\r
927         Clazz.defineMethod (clazzThis, "construct", funBody, funParams);\r
928         if (clazzThis.con$truct) {\r
929                 clazzThis.con$truct.index = clazzThis.con$truct.stacks.length;\r
930         }\r
931         //clazzThis.con$truct = clazzThis.prototype.con$truct = null;\r
932 };\r
933 \r
934 /**\r
935  * Override constructor for the class with the given function body and\r
936  * parameters signature.\r
937  * \r
938  * @param clazzThis host class\r
939  * @param funBody constructor body\r
940  * @param funParams constructor parameters signature\r
941  */\r
942 /* public */\r
943 Clazz.overrideConstructor = function (clazzThis, funBody, funParams) {\r
944         Clazz.overrideMethod (clazzThis, "construct", funBody, funParams);\r
945         if (clazzThis.con$truct) {\r
946                 clazzThis.con$truct.index = clazzThis.con$truct.stacks.length;\r
947         }\r
948         //clazzThis.con$truct = clazzThis.prototype.con$truct = null;\r
949 };\r
950 \r
951 \r
952 /*\r
953  * Define method for the class with the given method name and method\r
954  * body and method parameter signature.\r
955  *\r
956  * @param clazzThis host class in which the method to be defined\r
957  * @param funName method name\r
958  * @param funBody function object, e.g function () { ... }\r
959  * @param funParams paramether signature, e.g ["string", "number"]\r
960  * @return method of the given name. The method may be funBody or a wrapper\r
961  * of the given funBody.\r
962  */\r
963 /* public */\r
964 Clazz.defineMethod = function (clazzThis, funName, funBody, funParams) {\r
965         if (Clazz.assureInnerClass) \r
966     Clazz.assureInnerClass(clazzThis, funBody);\r
967         funBody.exName = funName;\r
968         var fpName = formatParameters(funParams);\r
969         var proto = clazzThis.prototype;\r
970         var f$ = proto[funName];\r
971   if (Clazz._Loader._checkLoad)\r
972     checkDuplicate(clazzThis, funName, fpName);\r
973         if (!f$ || (f$.claxxOwner === clazzThis && f$.funParams == fpName)) {\r
974                 // property "funParams" will be used as a mark of only-one method\r
975                 funBody.funParams = fpName; \r
976                 funBody.claxxOwner = clazzThis;\r
977                 funBody.exClazz = clazzThis; // make it traceable\r
978                 return addProto(proto, funName, funBody);\r
979         }\r
980   // we have found a duplicate\r
981         var oldFun = null;\r
982         var oldStacks = f$.stacks;\r
983                 if (!oldStacks) {\r
984                         /* method is not defined by Clazz.defineMethod () */\r
985       oldStacks = [];\r
986                         oldFun = f$;\r
987                         if (f$.claxxOwner) {\r
988                                 oldStacks[0] = oldFun.claxxOwner;\r
989                         }\r
990                 }\r
991                 /*\r
992          * Method that is already defined in super class will be overridden\r
993          * with a new proxy method with class hierarchy stored in a stack.\r
994          * That is to say, the super methods are lost in this class' proxy\r
995          * method. \r
996          * When method are being called, methods defined in the new proxy \r
997          * method will be searched through first. And if no method fitted,\r
998          * it will then try to search method in the super class stacks.\r
999          */\r
1000         if (!f$.stacks || f$.claxxReference !== clazzThis) {\r
1001                 //Generate a new delegating method for the class                \r
1002     var id = ++SAEMid;\r
1003         var delegate = function () {\r
1004                 return searchAndExecuteMethod(id, this, arguments.callee.claxxReference, arguments.callee.methodName, arguments);\r
1005         };\r
1006         delegate.methodName = funName;\r
1007         delegate.claxxReference = clazzThis;\r
1008                 f$ = addProto(proto, funName, delegate);                                \r
1009                 // Keep the class inheritance stacks\r
1010                 var arr = [];\r
1011                 for (var i = 0; i < oldStacks.length; i++)\r
1012                         arr[i] = oldStacks[i];\r
1013                 f$.stacks = arr;\r
1014         }\r
1015         var ss = f$.stacks;\r
1016         if (findArrayItem(ss, clazzThis) < 0) ss.push(clazzThis);\r
1017 \r
1018         if (oldFun) {\r
1019                 if (oldFun.claxxOwner === clazzThis) {\r
1020                         f$[oldFun.funParams] = oldFun;\r
1021                         oldFun.claxxOwner = null;\r
1022                         // property "funParams" will be used as a mark of only-one method\r
1023                         oldFun.funParams = null; // null ? safe ? // safe for != null\r
1024                 } else if (!oldFun.claxxOwner) {\r
1025                         /*\r
1026                          * The function is not defined Clazz.defineMethod ().\r
1027                          * Try to fixup the method ...\r
1028                          * As a matter of lost method information, I just suppose\r
1029                          * the method to be fixed is with void parameter!\r
1030                          */\r
1031                         f$["\\unknown"] = oldFun;\r
1032                 }\r
1033         }\r
1034         funBody.exClazz = clazzThis; // make it traceable\r
1035         f$[fpName] = funBody;\r
1036         return f$;\r
1037 };                                                \r
1038 \r
1039 duplicatedMethods = {};\r
1040 \r
1041 var checkDuplicate = function(clazzThis, funName, fpName) {\r
1042         var proto = clazzThis.prototype;\r
1043         var f$ = proto[funName];\r
1044   if (f$ && (f$.claxxOwner || f$.claxxReference) === clazzThis) {\r
1045     key = clazzThis.__CLASS_NAME__ + "." + funName + fpName;\r
1046     var m = duplicatedMethods[key];\r
1047     if (m) {\r
1048       var s = "Warning! Duplicate method found for " + key;\r
1049       System.out.println(s);\r
1050       Clazz.alert(s);\r
1051       duplicatedMethods[key] = m + 1; \r
1052     } else {\r
1053       duplicatedMethods[key] = 1;\r
1054     }\r
1055   }\r
1056 }\r
1057 \r
1058 Clazz.showDuplicates = function(quiet) {\r
1059   var s = "";\r
1060   var a = duplicatedMethods;\r
1061   var n = 0;\r
1062   for (var key in a)\r
1063     if (a[key] > 1) {\r
1064       s += a[key] + "\t" + key + "\n";\r
1065       n++;\r
1066     }\r
1067   s = "Duplicates: " + n + "\n\n" + s;\r
1068   System.out.println(s);\r
1069   if (!quiet)\r
1070     alert(s);\r
1071 }\r
1072 \r
1073 var findArrayItem = function(arr, item) {\r
1074         if (arr && item)\r
1075                 for (var i = arr.length; --i >= 0;)\r
1076                         if (arr[i] === item)\r
1077                                 return i;\r
1078         return -1;\r
1079 }\r
1080 \r
1081 var removeArrayItem = function(arr, item) {\r
1082         var i = findArrayItem(arr, item);\r
1083         if (i >= 0) {\r
1084                 var n = arr.length - 1;\r
1085                 for (; i < n; i++)\r
1086                         arr[i] = arr[i + 1];\r
1087                 arr.length--;\r
1088                 return true;\r
1089         }\r
1090 }\r
1091 \r
1092 /*\r
1093  * Other developers may need to extend this formatParameters method\r
1094  * to deal complicated situation.\r
1095  */\r
1096 /* protected */\r
1097 var formatParameters = function (funParams) {\r
1098         return (funParams ? funParams.replace (/~([NABSO])/g, \r
1099       function ($0, $1) {\r
1100         switch ($1) {\r
1101         case 'N':\r
1102                 return "n";\r
1103         case 'B':\r
1104                 return "b";\r
1105         case 'S':\r
1106                 return "String";\r
1107         case 'O':\r
1108                 return "Object";\r
1109         case 'A':\r
1110                 return "Array";\r
1111         }\r
1112         return "Unknown";\r
1113       }).replace (/\s+/g, "").replace (/^|,/g, "\\").replace (/\$/g, "org.eclipse.s") : "\\void");\r
1114 };\r
1115 \r
1116 /*\r
1117  * Override the existed methods which are in the same name.\r
1118  * Overriding methods is provided for the purpose that the JavaScript\r
1119  * does not need to search the whole hierarchied methods to find the\r
1120  * correct method to execute.\r
1121  * Be cautious about this method. Incorrectly using this method may\r
1122  * break the inheritance system.\r
1123  *\r
1124  * @param clazzThis host class in which the method to be defined\r
1125  * @param funName method name\r
1126  * @param funBody function object, e.g function () { ... }\r
1127  * @param funParams paramether signature, e.g ["string", "number"]\r
1128  */\r
1129 /* public */\r
1130 Clazz.overrideMethod = function(clazzThis, funName, funBody, funParams) {\r
1131         if (Clazz.assureInnerClass) Clazz.assureInnerClass (clazzThis, funBody);\r
1132         funBody.exName = funName;\r
1133         var fpName = formatParameters(funParams);\r
1134   if (Clazz._Loader._checkLoad)\r
1135     checkDuplicate(clazzThis, funName, fpName);\r
1136         /*\r
1137          * Replace old methods with new method. No super methods are kept.\r
1138          */\r
1139         funBody.funParams = fpName; \r
1140         funBody.claxxOwner = clazzThis;\r
1141         return addProto(clazzThis.prototype, funName, funBody);\r
1142 };\r
1143 \r
1144 //////////////  Overridden and Overloaded Java Method Handling //////////////////\r
1145 //                       SAEM (SearchAndExecuteMethod)\r
1146 // adapted by BH\r
1147 //\r
1148 \r
1149 /*\r
1150  * BH Clazz.getProfile monitors exactly what is being delegated with SAEM,\r
1151  * which could be a bottle-neck for function calling.\r
1152  * This is critical for performance optimization.\r
1153  */ \r
1154 \r
1155   var __signatures = ""; \r
1156 \r
1157 Clazz.getProfile = function() {\r
1158         var s = "";\r
1159         if (_profile) {\r
1160                 var l = [];\r
1161                 for (var i in _profile) {\r
1162                         var n = "" + _profile[i];\r
1163                         l.push("        ".substring(n.length) + n + "\t" + i);\r
1164                 }\r
1165                 s = l.sort().reverse().join("\r\n");\r
1166                 _profile = {};\r
1167         }\r
1168         return s + __signatures;\r
1169 }\r
1170 \r
1171 var addProfile = function(c, f, p, id) {\r
1172         var s = id + " " + c.__CLASS_NAME__ + " " + f + " ";// + JSON.stringify(p);\r
1173   if (__signatures.indexOf(s) < 0)\r
1174     __signatures += s + "\n";    \r
1175         _profile[s] || (_profile[s] = 0);\r
1176         _profile[s]++;\r
1177 }\r
1178 \r
1179 /**\r
1180  * Called also by Throwable\r
1181  *  \r
1182 /* public */\r
1183 Clazz.getParamsType = function (funParams) {\r
1184         // bh: optimization here for very common cases\r
1185         var n = funParams.length;\r
1186         switch (n) {\r
1187         case 0:\r
1188                 var params = ["void"];\r
1189                 params.typeString = "\\void";\r
1190                 return params;\r
1191         case 1:\r
1192           // BH just so common\r
1193     switch (typeof obj) {\r
1194     case "number":\r
1195                         var params = ["n"];\r
1196                         params.typeString = "\\n";\r
1197                         return params;\r
1198     case "boolean":\r
1199                         var params = ["b"];\r
1200                         params.typeString = "\\b";\r
1201                         return params;\r
1202                 }\r
1203         }\r
1204 \r
1205         var params = [];\r
1206         params.hasCastedNull = false;\r
1207         if (funParams) {\r
1208                 for (var i = 0; i < n; i++) {\r
1209                         params[i] = Clazz.getClassName (funParams[i]);\r
1210                         if (funParams[i] instanceof Clazz.CastedNull) {\r
1211                                 params.hasCastedNull = true;\r
1212                         }\r
1213                 }\r
1214         }\r
1215         params.typeString = "\\" + params.join ('\\');\r
1216         return params;\r
1217 };\r
1218 \r
1219 var SAEMid = 0;\r
1220 xxxSAEMlist = "";\r
1221 \r
1222 //var SAEMarray = [];\r
1223 /**\r
1224  * BH: OK, this was an idea that doesn't work. The idea was to tag SAEM calls\r
1225  * and then refer back to an array. But the id number cannot be put in the right place.\r
1226  * \r
1227  * Say we have this:\r
1228  * \r
1229  * StringBuffer sb = new StringBuffer(); \r
1230  * sb.append("").append(1);\r
1231  * \r
1232  * Here we have two different append methods to call. They are saved under two\r
1233  * names:  StringBuffer.prototype.append["\\String"] \r
1234  *     and StringBuffer.prototype.append["\\Number"]\r
1235  * \r
1236  * The job of generateDelegatingMethod is to discriminate between those two. We can do\r
1237  * that, but the real issue is that we have to do that EVERY time a call is made.\r
1238  * This is a problem that must be handled at compile time. There is no way to \r
1239  * make .append("") to go one way the first time and another way the second time. \r
1240  * What we need at run time is something like this:\r
1241  * \r
1242  * Clazz.delegate(sb.append,1,[""]) and Clazz.delegate(sb.append,2,[1])\r
1243  * The we would be able to log those numbers at run time and refer to them.\r
1244  *                     \r
1245  * The only real way to avoid SAEM is: \r
1246  * \r
1247  * 1) to never call super() -- always call a differently named function in a superclass.\r
1248  * 2) don't overload functions \r
1249  *  \r
1250  */   \r
1251 \r
1252 \r
1253 /**\r
1254  * Search the given class prototype, find the method with the same\r
1255  * method name and the same parameter signatures by the given \r
1256  * parameters, and then run the method with the given parameters.\r
1257  *\r
1258  * @param objThis the current host object\r
1259  * @param claxxRef the current host object's class\r
1260  * @param fxName the method name\r
1261  * @param funParams the given arguments\r
1262  * @return the result of the specified method of the host object,\r
1263  * the return maybe void.\r
1264  * @throws MethodNotFoundException if no matched method is found\r
1265  */\r
1266 /* protected */\r
1267 var searchAndExecuteMethod = function (id, objThis, claxxRef, fxName, args, _saem) {\r
1268 \r
1269 //  var fx = SAEMarray[id];\r
1270 //  if (fx) {\r
1271 //    return fx.apply(objThis, args);\r
1272 //  }\r
1273 \r
1274 \r
1275         fx = objThis[fxName];\r
1276         var params = Clazz.getParamsType(args);\r
1277 \r
1278 \r
1279 var s = "SAEM " + claxxRef.__CLASS_NAME__ + "." + fxName + "(" + params+ ")\n";\r
1280 if (xxxSAEMlist.length > 300)xxxSAEMlist = "";\r
1281 xxxSAEMlist += s;\r
1282  \r
1283 \r
1284   if (!fx)    \r
1285     try {System.out.println(Clazz.getStackTrace(5))} catch (e){}\r
1286         _profile && addProfile(claxxRef, fxName, params, id);\r
1287         // Cache last matched method\r
1288         if (fx.lastParams == params.typeString && fx.lastClaxxRef === claxxRef) {\r
1289                 var methodParams;\r
1290                 if (params.hasCastedNull) {\r
1291                         methodParams = [];\r
1292                         // For Clazz.CastedNull instances, the type name is\r
1293                         // already used to indentified the method in searchMethod.\r
1294                         for (var k = 0; k < args.length; k++)\r
1295                                 methodParams[k] = (args[k] instanceof Clazz.CastedNull ? null : args[k]);\r
1296                 } else {\r
1297 //      if (fx.lastMethod) SAEMarray[id] = fx.lastMethod;\r
1298                         methodParams = args;\r
1299                 }\r
1300                 return (fx.lastMethod ? fx.lastMethod.apply(objThis, methodParams) : null);\r
1301         }\r
1302         fx.lastParams = params.typeString;\r
1303         fx.lastClaxxRef = claxxRef;\r
1304 \r
1305         var stacks = fx.stacks;\r
1306         if (!stacks)\r
1307                 stacks = claxxRef.prototype[fxName].stacks;\r
1308         var length = stacks.length;\r
1309 \r
1310         /*\r
1311          * Search the inheritance stacks to get the given class' function\r
1312          */\r
1313         var began = false; // began to search its super classes\r
1314         for (var i = length; --i >= 0;) {\r
1315                 if (began || stacks[i] === claxxRef) {\r
1316                         /*\r
1317                          * First try to search method within the same class scope\r
1318                          * with stacks[i] === claxxRef\r
1319                          */\r
1320                         var clazzFun = stacks[i].prototype[fxName];\r
1321                         var ret = tryToSearchAndExecute(id, fxName, objThis, clazzFun, params,\r
1322                                         args, fx);\r
1323                         if (!(ret instanceof MethodException)) {\r
1324                                 return ret;\r
1325                         }\r
1326                         /*\r
1327                          * As there are no such methods in current class, Clazz will try \r
1328                          * to search its super class stacks. Here variable began indicates\r
1329                          * that super searchi is began, and there is no need checking\r
1330                          * <code>stacks[i] === claxxRef</code>\r
1331                          */\r
1332                         began = true; \r
1333                 } // end of if\r
1334         } // end of for\r
1335         if ("construct" == fxName) {\r
1336                 /*\r
1337                  * For non existed constructors, just return without throwing\r
1338                  * exceptions. In Java codes, extending Object can call super\r
1339                  * default Object#constructor, which is not defined in JS.\r
1340                  */\r
1341                 return;\r
1342         }\r
1343         newMethodNotFoundException(objThis, claxxRef, \r
1344                         fxName, params.typeString);\r
1345 };\r
1346 \r
1347 \r
1348 /* private */\r
1349 var tryToSearchAndExecute = function(id, fxName, objThis, clazzFun, params, args, fx, _ttsaem) {\r
1350         var method = [];\r
1351         var generic = true;\r
1352         for (var fn in clazzFun) {\r
1353                 if (fn.charCodeAt(0) == 92) { // 92 == '\\'.charCodeAt (0)\r
1354                         var ps = fn.substring(1).split("\\");\r
1355                         (ps.length == params.length) && method.push(ps);\r
1356                 generic = false;\r
1357                         continue;\r
1358                 }\r
1359                 /*\r
1360                  * When there is only one method in the class, use the args\r
1361                  * to identify the parameter type.\r
1362                  *\r
1363                  * AbstractCollection.remove (Object)\r
1364                  * AbstractList.remove (int)\r
1365                  * ArrayList.remove (int)\r
1366                  *\r
1367                  * Then calling #remove (Object) method on ArrayList instance will \r
1368                  * need to search up to the AbstractCollection.remove (Object),\r
1369                  * which contains only one method.\r
1370                  */\r
1371                 /*\r
1372                  * See Clazz#defineMethod --Mar 10, 2006, josson\r
1373                  */\r
1374                 if (generic && fn == "funParams" && clazzFun.funParams) {\r
1375                         fn = clazzFun.funParams;\r
1376                         var ps = fn.substring(1).split ("\\");\r
1377                         (ps.length == params.length) && (method[0] = ps);\r
1378                         break;\r
1379                 }\r
1380         }\r
1381   var debug = false;//(method.length > 1 && method.join().indexOf("Listen")< 0 && params.join().indexOf("Null") >= 0)\r
1382   if (debug)alert(fxName + " -- " + method.join("|") + " -- searching for method with " + params)\r
1383   if (method.length == 0 || !(method = searchMethod(method, params, debug)))\r
1384           return new MethodException();\r
1385   if (debug) alert("OK: \\" + method)\r
1386         var f = (generic ? clazzFun : clazzFun["\\" + method]);\r
1387         //if (generic) \r
1388   //{ /* Use the generic method */\r
1389                 /*\r
1390                  * Will this case be reachable?\r
1391                  * March 4, 2006 josson\r
1392                  * \r
1393                  * Reachable for calling #remove (Object) method on \r
1394                  * ArrayList instance\r
1395                  * May 5, 2006 josson\r
1396                  */\r
1397         var methodParams = null;\r
1398         if (params.hasCastedNull) {\r
1399                 methodParams = [];\r
1400                 for (var k = 0; k < args.length; k++) {\r
1401                         if (args[k] instanceof Clazz.CastedNull) {\r
1402                                 /*\r
1403                                  * For Clazz.CastedNull instances, the type name is\r
1404                                  * already used to indentify the method in searchMethod.\r
1405                                  */\r
1406                                 methodParams[k] = null;\r
1407                         } else {\r
1408                                 methodParams[k] = args[k];\r
1409                         }\r
1410                 }\r
1411         } else {\r
1412                 methodParams = args;\r
1413         }\r
1414         fx.lastMethod = f;\r
1415   //if (!params.hasCastedNull) SAEMarray[id] = f;\r
1416         return f.apply(objThis, methodParams);\r
1417 };\r
1418 \r
1419 /**\r
1420  * Search the existed polymorphic methods to get the matched method with\r
1421  * the given parameter types.\r
1422  *\r
1423  * @param existedMethods Array of string which contains method parameters\r
1424  * @param paramTypes Array of string that is parameter type.\r
1425  * @return string of method parameters seperated by "\\"\r
1426  */\r
1427 /* private */\r
1428 var searchMethod = function(roundOne, paramTypes, debug) {\r
1429 \r
1430 // Filter out all the fitted methods for the given parameters\r
1431         var roundTwo = [];\r
1432         var len = roundOne.length;\r
1433         for (var i = 0; i < len; i++) {\r
1434                 var fittedLevel = [];\r
1435                 var isFitted = true;\r
1436                 var len2 = roundOne[i].length;\r
1437                 for (var j = 0; j < len2; j++) {\r
1438     \r
1439                         fittedLevel[j] = Clazz.getInheritedLevel (paramTypes[j], \r
1440                                         roundOne[i][j]);\r
1441       //if (debug)alert([paramTypes[j],fittedLevel[j],roundOne[i][j]])    \r
1442                         if (fittedLevel[j] < 0) {\r
1443                                 isFitted = false;\r
1444                                 break;\r
1445                         }\r
1446                 }\r
1447                 if (isFitted) {\r
1448                         fittedLevel[paramTypes.length] = i; // Keep index for later use\r
1449                         roundTwo.push(fittedLevel);\r
1450                 }\r
1451         }\r
1452         if (roundTwo.length == 0)\r
1453                 return null;\r
1454         // Find out the best method according to the inheritance.\r
1455         var resultTwo = roundTwo;\r
1456         var min = resultTwo[0];\r
1457         for (var i = 1; i < resultTwo.length; i++) {\r
1458                 var isVectorLesser = true;\r
1459                 for (var j = 0; j < paramTypes.length; j++) {\r
1460                         if (min[j] < resultTwo[i][j]) {\r
1461                                 isVectorLesser = false;;\r
1462                                 break;\r
1463                         }\r
1464                 }\r
1465                 if (isVectorLesser)\r
1466                         min = resultTwo[i];\r
1467         }\r
1468         var index = min[paramTypes.length]; // Get the previously stored index\r
1469         /*\r
1470          * Return the method parameters' type string as indentifier of the\r
1471          * choosen method.\r
1472          */\r
1473         return roundOne[index].join ('\\');\r
1474 };\r
1475 \r
1476 ////////////////////////////////// package loading ///////////////////////\r
1477 \r
1478 /*\r
1479  * all root packages. e.g. java.*, org.*, com.*\r
1480  */\r
1481 /* protected */\r
1482 Clazz.allPackage = {};\r
1483 \r
1484 /**\r
1485  * Will be used to keep value of whether the class is defined or not.\r
1486  */\r
1487 /* protected */\r
1488 Clazz.allClasses = {};\r
1489 \r
1490 Clazz.lastPackageName = null;\r
1491 Clazz.lastPackage = null;\r
1492 \r
1493 /* protected */\r
1494 Clazz.unloadedClasses = [];\r
1495 \r
1496 /* public */\r
1497 Clazz.declarePackage = function (pkgName) {\r
1498         if (Clazz.lastPackageName == pkgName)\r
1499                 return Clazz.lastPackage;\r
1500         if (pkgName && pkgName.length) {\r
1501                 var pkgFrags = pkgName.split (/\./);\r
1502                 var pkg = Clazz.allPackage;\r
1503                 for (var i = 0; i < pkgFrags.length; i++) {\r
1504                         if (!pkg[pkgFrags[i]]) {\r
1505                                 pkg[pkgFrags[i]] = { \r
1506                                         __PKG_NAME__ : (pkg.__PKG_NAME__ ? \r
1507                                                 pkg.__PKG_NAME__ + "." + pkgFrags[i] : pkgFrags[i])\r
1508                                 }; \r
1509                                 // pkg[pkgFrags[i]] = {};\r
1510                                 if (i == 0) {\r
1511                                         // eval ...\r
1512                                         Clazz.setGlobal(pkgFrags[i], pkg[pkgFrags[i]]);\r
1513                                 }\r
1514                         }\r
1515                         pkg = pkg[pkgFrags[i]]\r
1516                 }\r
1517                 Clazz.lastPackageName = pkgName;\r
1518                 Clazz.lastPackage = pkg;\r
1519                 return pkg;\r
1520         }\r
1521 };\r
1522 \r
1523 /* protected */\r
1524 Clazz.evalType = function (typeStr, isQualified) {\r
1525         var idx = typeStr.lastIndexOf(".");\r
1526         if (idx != -1) {\r
1527                 var pkgName = typeStr.substring (0, idx);\r
1528                 var pkg = Clazz.declarePackage (pkgName);\r
1529                 var clazzName = typeStr.substring (idx + 1);\r
1530                 return pkg[clazzName];\r
1531         } \r
1532         if (isQualified)\r
1533                 return window[typeStr];\r
1534         switch (typeStr) {\r
1535         case "string":\r
1536                 return String;\r
1537         case "number":\r
1538                 return Number;\r
1539   case "object":\r
1540                 return Clazz._O;\r
1541         case "boolean":\r
1542                 return Boolean;\r
1543         case "function":\r
1544                 return Function;\r
1545   case "void":\r
1546   case "undefined":\r
1547   case "unknown":\r
1548                 return typeStr;\r
1549         case "NullObject":\r
1550                 return NullObject;\r
1551         default:\r
1552                 return window[typeStr];\r
1553         }\r
1554 };\r
1555 \r
1556 /**\r
1557  * Define a class or interface.\r
1558  *\r
1559  * @param qClazzName String presents the qualified name of the class\r
1560  * @param clazzFun Function of the body\r
1561  * @param clazzParent Clazz to inherit from, may be null\r
1562  * @param interfacez Clazz may implement one or many interfaces\r
1563  *   interfacez can be Clazz object or Array of Clazz objects.\r
1564  * @return Ruturn the modified Clazz object\r
1565  */\r
1566 /* public */\r
1567 Clazz.defineType = function (qClazzName, clazzFun, clazzParent, interfacez) {\r
1568         var cf = Clazz.unloadedClasses[qClazzName];\r
1569         if (cf) {\r
1570                 clazzFun = cf;\r
1571         }\r
1572         var idx = qClazzName.lastIndexOf (".");\r
1573         if (idx != -1) {\r
1574                 var pkgName = qClazzName.substring (0, idx);\r
1575                 var pkg = Clazz.declarePackage (pkgName);\r
1576                 var clazzName = qClazzName.substring (idx + 1);\r
1577                 if (pkg[clazzName]) {\r
1578                         // already defined! Should throw exception!\r
1579                         return pkg[clazzName];\r
1580                 }\r
1581                 pkg[clazzName] = clazzFun;\r
1582         } else {\r
1583                 if (window[qClazzName]) {\r
1584                         // already defined! Should throw exception!\r
1585                         return window[qClazzName];\r
1586                 }\r
1587                 Clazz.setGlobal(qClazzName, clazzFun);\r
1588         }\r
1589         Clazz.decorateAsType(clazzFun, qClazzName, clazzParent, interfacez);\r
1590         /*# {$no.javascript.support} >>x #*/\r
1591         var iFun = Clazz._innerFunctions;\r
1592         clazzFun.defineMethod = iFun.defineMethod;\r
1593         clazzFun.defineStaticMethod = iFun.defineStaticMethod;\r
1594         clazzFun.makeConstructor = iFun.makeConstructor;\r
1595         /*# x<< #*/\r
1596         return clazzFun;\r
1597 };\r
1598 \r
1599 var isSafari = (navigator.userAgent.indexOf ("Safari") != -1);\r
1600 var isSafari4Plus = false;\r
1601 if (isSafari) {\r
1602         var ua = navigator.userAgent;\r
1603         var verIdx = ua.indexOf("Version/");\r
1604         if (verIdx  != -1) {\r
1605                 var verStr = ua.substring(verIdx + 8);\r
1606                 var verNumber = parseFloat(verStr);\r
1607                 isSafari4Plus = verNumber >= 4.0;\r
1608         }\r
1609 }\r
1610 \r
1611 /* public */\r
1612 Clazz.instantialize = function (objThis, args) {\r
1613 \r
1614 \r
1615         if (args && args.length == 1 && args[0] \r
1616                         && args[0] instanceof args4InheritClass) {\r
1617                 return;\r
1618         }\r
1619         if (objThis instanceof Number) {\r
1620                 objThis.valueOf = function () {\r
1621                         return this;\r
1622                 };\r
1623         }\r
1624         if (isSafari4Plus) { // Fix bug of Safari 4.0+'s over-optimization\r
1625                 var argsClone = [];\r
1626                 for (var k = 0; k < args.length; k++) {\r
1627                         argsClone[k] = args[k];\r
1628                 }\r
1629                 args = argsClone;\r
1630         }\r
1631 \r
1632         var c = objThis.construct;\r
1633         if (c) {\r
1634                 if (!objThis.con$truct) { // no need to init fields\r
1635                         c.apply (objThis, args);\r
1636                 } else if (!objThis.getClass ().superClazz) { // the base class\r
1637                         objThis.con$truct.apply (objThis, []);\r
1638                         c.apply (objThis, args);\r
1639                 } else if ((c.claxxOwner \r
1640                                 && c.claxxOwner === objThis.getClass ())\r
1641                                 || (c.stacks \r
1642                                 && c.stacks[c.stacks.length - 1] == objThis.getClass ())) {\r
1643                         /*\r
1644                          * This #construct is defined by this class itself.\r
1645                          * #construct will call Clazz.superConstructor, which will\r
1646                          * call #con$truct back\r
1647                          */\r
1648                         c.apply (objThis, args);\r
1649                 } else { // constructor is a super constructor\r
1650                         if (c.claxxOwner && !c.claxxOwner.superClazz \r
1651                                                 && c.claxxOwner.con$truct) {\r
1652                                 c.claxxOwner.con$truct.apply (objThis, []);\r
1653                         } else if (c.stacks && c.stacks.length == 1\r
1654                                         && !c.stacks[0].superClazz) {\r
1655                                 c.stacks[0].con$truct.apply (objThis, []);\r
1656                         }\r
1657                         c.apply (objThis, args);\r
1658                         objThis.con$truct.apply (objThis, []);\r
1659                 }\r
1660         } else if (objThis.con$truct) {\r
1661                 objThis.con$truct.apply (objThis, []);\r
1662         }\r
1663 };\r
1664 \r
1665 /**\r
1666  * Once there are other methods registered to the Function.prototype, \r
1667  * those method names should be add to the following Array.\r
1668  */\r
1669 /*\r
1670  * static final member of interface may be a class, which may\r
1671  * be function.\r
1672  */\r
1673 /* protected */\r
1674 Clazz.innerFunctionNames = [\r
1675         "isInstance", "equals", "hashCode", /*"toString",*/ "getName", "getCanonicalName", "getClassLoader", "getResource", "getResourceAsStream" /*# {$no.javascript.support} >>x #*/, "defineMethod", "defineStaticMethod",\r
1676         "makeConstructor" /*# x<< #*/\r
1677 ];\r
1678 \r
1679 /*\r
1680  * Static methods\r
1681  */\r
1682 Clazz._innerFunctions = {\r
1683         /*\r
1684          * Similar to Object#equals\r
1685          */\r
1686    \r
1687   isInstance: function(c) {\r
1688     return Clazz.instanceOf(c, this);\r
1689   },\r
1690   \r
1691         equals : function (aFun) {\r
1692                 return this === aFun;\r
1693         },\r
1694 \r
1695         hashCode : function () {\r
1696                 return this.getName ().hashCode ();\r
1697         },\r
1698 \r
1699         toString : function () {\r
1700                 return "class " + this.getName ();\r
1701         },\r
1702 \r
1703         /*\r
1704          * Similar to Class#getName\r
1705          */\r
1706         getName : function () {\r
1707                 return Clazz.getClassName (this, true);\r
1708         },\r
1709         getCanonicalName : function () {\r
1710                 return this.__CLASS_NAME__;\r
1711         },\r
1712         getClassLoader : function () {\r
1713                 var clazzName = this.__CLASS_NAME__;\r
1714                 var baseFolder = Clazz._Loader.getClasspathFor(clazzName);\r
1715                 var x = baseFolder.lastIndexOf (clazzName.replace (/\./g, "/"));\r
1716                 if (x != -1) {\r
1717                         baseFolder = baseFolder.substring (0, x);\r
1718                 } else {\r
1719                         baseFolder = Clazz._Loader.getClasspathFor(clazzName, true);\r
1720                 }\r
1721                 var loader = Clazz._Loader.requireLoaderByBase(baseFolder);\r
1722                 loader.getResourceAsStream = Clazz._innerFunctions.getResourceAsStream;\r
1723                 loader.getResource = Clazz._innerFunctions.getResource; // BH\r
1724                 return loader;\r
1725         },\r
1726 \r
1727         getResource : function(name) {\r
1728                 var stream = this.getResourceAsStream(name);\r
1729     return (stream ? stream.url : null);\r
1730         },\r
1731 \r
1732         getResourceAsStream : function (name) {\r
1733                 if (!name)\r
1734                         return null;\r
1735                 name = name.replace (/\\/g, '/');\r
1736                 var baseFolder = null;\r
1737     var fname = name;\r
1738                 var clazzName = this.__CLASS_NAME__;\r
1739                 if (arguments.length == 2 && name.indexOf ('/') != 0) { // additional argument\r
1740                         name = "/" + name;\r
1741                 }\r
1742                 if (name.indexOf ('/') == 0) {\r
1743                         //is.url = name.substring (1);\r
1744                         if (arguments.length == 2) { // additional argument\r
1745                                 baseFolder = arguments[1];\r
1746                                 if (!baseFolder)\r
1747                                         baseFolder = Clazz.binaryFolders[0];\r
1748                         } else if (Clazz._Loader) {\r
1749                                 baseFolder = Clazz._Loader.getClasspathFor(clazzName, true);\r
1750                         }\r
1751                         if (!baseFolder) {\r
1752                                 fname = name.substring (1);\r
1753                         } else {\r
1754                                 baseFolder = baseFolder.replace (/\\/g, '/');\r
1755                                 var length = baseFolder.length;\r
1756                                 var lastChar = baseFolder.charAt (length - 1);\r
1757                                 if (lastChar != '/') {\r
1758                                         baseFolder += "/";\r
1759                                 }\r
1760                                 fname = baseFolder + name.substring (1);\r
1761                         }\r
1762                 } else {\r
1763                         if (this.base) {\r
1764                                 baseFolder = this.base;\r
1765                         } else if (Clazz._Loader) {\r
1766                                 baseFolder = Clazz._Loader.getClasspathFor(clazzName);\r
1767                                 var x = baseFolder.lastIndexOf (clazzName.replace (/\./g, "/"));\r
1768                                 if (x != -1) {\r
1769                                         baseFolder = baseFolder.substring (0, x);\r
1770                                 } else {\r
1771                                         //baseFolder = null;\r
1772                                         var y = -1;\r
1773                                         if (baseFolder.indexOf (".z.js") == baseFolder.length - 5\r
1774                                                         && (y = baseFolder.lastIndexOf ("/")) != -1) {\r
1775                                                 baseFolder = baseFolder.substring (0, y + 1);\r
1776                                                 var pkgs = clazzName.split (/\./);\r
1777                                                 for (var k = 1; k < pkgs.length; k++) {\r
1778                                                         var pkgURL = "/";\r
1779                                                         for (var j = 0; j < k; j++) {\r
1780                                                                 pkgURL += pkgs[j] + "/";\r
1781                                                         }\r
1782                                                         if (pkgURL.length > baseFolder.length) {\r
1783                                                                 break;\r
1784                                                         }\r
1785                                                         if (baseFolder.indexOf (pkgURL) == baseFolder.length - pkgURL.length) {\r
1786                                                                 baseFolder = baseFolder.substring (0, baseFolder.length - pkgURL.length + 1);\r
1787                                                                 break;\r
1788                                                         }\r
1789                                                 }\r
1790                                         } else {\r
1791                                                 baseFolder = Clazz._Loader.getClasspathFor(clazzName, true);\r
1792                                         }\r
1793                                 }\r
1794                         } else {\r
1795                                 var bins = Clazz.binaryFolders;\r
1796                                 if (bins && bins.length) {\r
1797                                         baseFolder = bins[0];\r
1798                                 }\r
1799                         }\r
1800                         if (!baseFolder)\r
1801                                 baseFolder = "j2s/";\r
1802                         baseFolder = baseFolder.replace (/\\/g, '/');\r
1803                         var length = baseFolder.length;\r
1804                         var lastChar = baseFolder.charAt (length - 1);\r
1805                         if (lastChar != '/') {\r
1806                                 baseFolder += "/";\r
1807                         }\r
1808                         if (this.base) {\r
1809                                 fname = baseFolder + name;\r
1810                         } else {\r
1811                                 var idx = clazzName.lastIndexOf ('.');\r
1812                                 if (idx == -1 || this.base) {\r
1813                                         fname = baseFolder + name;\r
1814                                 } else {\r
1815                                         fname = baseFolder + clazzName.substring (0, idx)\r
1816                                                         .replace (/\./g, '/') +  "/" + name;\r
1817                                 }\r
1818                         }            \r
1819                 }\r
1820     var url = null;\r
1821     try {\r
1822       if (fname.indexOf(":/") < 0) {\r
1823         var d = document.location.href.split("?")[0].split("/");\r
1824         d[d.length - 1] = fname;\r
1825         fname = d.join("/");\r
1826       }\r
1827       url = new java.net.URL(fname);\r
1828     } catch (e) {\r
1829     }\r
1830                 var data = (url == null ? null : Jmol._getFileData(fname.toString()));\r
1831     if (!data || data == "error" || data.indexOf("[Exception") == 0)\r
1832       return null;\r
1833     var bytes = new java.lang.String(data).getBytes();      \r
1834     var is = new java.io.BufferedInputStream ( new java.io.ByteArrayInputStream (bytes)); \r
1835     is.url = url;\r
1836                 return is;\r
1837         }/*# {$no.javascript.support} >>x #*/,\r
1838 \r
1839         /*\r
1840          * For JavaScript programmers\r
1841          */\r
1842         defineMethod : function (methodName, funBody, paramTypes) {\r
1843                 Clazz.defineMethod (this, methodName, funBody, paramTypes);\r
1844         },\r
1845 \r
1846         /*\r
1847          * For JavaScript programmers\r
1848          */\r
1849         defineStaticMethod : function (methodName, funBody, paramTypes) {\r
1850                 Clazz.defineMethod (this, methodName, funBody, paramTypes);\r
1851                 this[methodName] = this.prototype[methodName];\r
1852         },\r
1853 \r
1854         /*\r
1855          * For JavaScript programmers\r
1856          */\r
1857         makeConstructor : function (funBody, paramTypes) {\r
1858                 Clazz.makeConstructor (this, funBody, paramTypes);\r
1859         }\r
1860         /*# x<< #*/\r
1861 };\r
1862 \r
1863 \r
1864 var cStack = [];\r
1865 \r
1866 /**\r
1867  * BH: I would like to be able to remove "self.c$" here, but that is tricky.\r
1868  */\r
1869   \r
1870 Clazz.pu$h = function (c) {\r
1871   c || (c = self.c$); // old style\r
1872         c && cStack.push(c);\r
1873 };\r
1874 \r
1875 Clazz.p0p = function () {\r
1876         return cStack.pop();\r
1877 };\r
1878 \r
1879 /* protected */\r
1880 Clazz.decorateAsClass = function (clazzFun, prefix, name, clazzParent, \r
1881                 interfacez, parentClazzInstance, _decorateAsClass) {\r
1882     \r
1883         var prefixName = null;\r
1884         if (prefix) {\r
1885                 prefixName = prefix.__PKG_NAME__;\r
1886                 if (!prefixName)\r
1887                         prefixName = prefix.__CLASS_NAME__;      \r
1888         }\r
1889         var qName = (prefixName ? prefixName + "." : "") + name;\r
1890   \r
1891     if (Clazz._Loader._classPending[qName]) {\r
1892       delete Clazz._Loader._classPending[qName];\r
1893       Clazz._Loader._classCountOK++;\r
1894       Clazz._Loader._classCountPending--;\r
1895     }\r
1896   if (Clazz._Loader && Clazz._Loader._checkLoad) {\r
1897     System.out.println("decorating class " + prefixName + "." + name);\r
1898   }\r
1899         var cf = Clazz.unloadedClasses[qName];\r
1900         if (cf) {\r
1901                 clazzFun = cf;\r
1902         }\r
1903         var qName = null;\r
1904         decorateFunction(clazzFun, prefix, name);\r
1905         if (parentClazzInstance) {\r
1906                 Clazz.inheritClass (clazzFun, clazzParent, parentClazzInstance);\r
1907         } else if (clazzParent) {\r
1908                 Clazz.inheritClass (clazzFun, clazzParent);\r
1909         }\r
1910         if (interfacez) {\r
1911                 Clazz.implementOf (clazzFun, interfacez);\r
1912         }\r
1913         return clazzFun;\r
1914 };\r
1915 \r
1916 /* private */\r
1917 var decorateFunction = function (clazzFun, prefix, name, _decorateFunction) {\r
1918         var qName;\r
1919         if (!prefix) {\r
1920                 // e.g. Clazz.declareInterface (null, "ICorePlugin", org.eclipse.ui.IPlugin);\r
1921                 qName = name;\r
1922                 Clazz.setGlobal(name, clazzFun);\r
1923         } else if (prefix.__PKG_NAME__) {\r
1924                 // e.g. Clazz.declareInterface (org.eclipse.ui, "ICorePlugin", org.eclipse.ui.IPlugin);\r
1925                 qName = prefix.__PKG_NAME__ + "." + name;\r
1926                 prefix[name] = clazzFun;\r
1927                 if (prefix === java.lang)\r
1928                         Clazz.setGlobal(name, clazzFun);\r
1929         } else {\r
1930                 // e.g. Clazz.declareInterface (org.eclipse.ui.Plugin, "ICorePlugin", org.eclipse.ui.IPlugin);\r
1931                 qName = prefix.__CLASS_NAME__ + "." + name;\r
1932                 prefix[name] = clazzFun;\r
1933         }\r
1934         Clazz.extendJO(clazzFun, qName);\r
1935         var inF = Clazz.innerFunctionNames;\r
1936         for (var i = 0; i < inF.length; i++) {\r
1937                 clazzFun[inF[i]] = Clazz._innerFunctions[inF[i]];\r
1938         }\r
1939 \r
1940         if (Clazz._Loader) \r
1941     Clazz._Loader.updateNodeForFunctionDecoration(qName);\r
1942 };\r
1943 \r
1944 /* protected */\r
1945 Clazz.declareInterface = function (prefix, name, interfacez, _declareInterface) {\r
1946         var clazzFun = function () {};\r
1947         decorateFunction(clazzFun, prefix, name);\r
1948         if (interfacez) {\r
1949                 Clazz.implementOf (clazzFun, interfacez);\r
1950         }\r
1951         return clazzFun;\r
1952 };\r
1953 \r
1954 /* public */\r
1955 Clazz.declareType = function (prefix, name, clazzParent, interfacez, \r
1956                 parentClazzInstance, _declareType) {\r
1957         var f = function () {\r
1958                 Clazz.instantialize (this, arguments);\r
1959         };\r
1960         return Clazz.decorateAsClass (f, prefix, name, clazzParent, interfacez, \r
1961                         parentClazzInstance);\r
1962 };\r
1963 \r
1964 /* public */\r
1965 Clazz.declareAnonymous = function (prefix, name, clazzParent, interfacez, \r
1966                 parentClazzInstance, _declareAnonymous) {\r
1967         var f = function () {\r
1968                 Clazz.prepareCallback(this, arguments);\r
1969                 Clazz.instantialize (this, arguments);\r
1970         };\r
1971         return Clazz.decorateAsClass (f, prefix, name, clazzParent, interfacez, \r
1972                         parentClazzInstance);\r
1973 };\r
1974 \r
1975 /* public */\r
1976 Clazz.decorateAsType = function (clazzFun, qClazzName, clazzParent, \r
1977                 interfacez, parentClazzInstance, inheritClazzFuns, _decorateAsType) {\r
1978         Clazz.extendJO(clazzFun, qClazzName);\r
1979         clazzFun.equals = Clazz._innerFunctions.equals;\r
1980         clazzFun.getName = Clazz._innerFunctions.getName;\r
1981         if (inheritClazzFuns) {\r
1982                 for (var i = 0; i < Clazz.innerFunctionNames.length; i++) {\r
1983                         var methodName = Clazz.innerFunctionNames[i];\r
1984                         clazzFun[methodName] = Clazz._innerFunctions[methodName];\r
1985                 }\r
1986         }\r
1987         if (parentClazzInstance) {\r
1988                 Clazz.inheritClass (clazzFun, clazzParent, parentClazzInstance);\r
1989         } else if (clazzParent) {\r
1990                 Clazz.inheritClass (clazzFun, clazzParent);\r
1991         }\r
1992         if (interfacez) {\r
1993                 Clazz.implementOf (clazzFun, interfacez);\r
1994         }\r
1995         return clazzFun;\r
1996 };\r
1997 \r
1998 \r
1999 ////////////////////////// default package declarations ////////////////////////\r
2000 \r
2001 /* sgurin: preserve Number.prototype.toString */\r
2002 Number.prototype._numberToString=Number.prototype.toString;\r
2003 \r
2004 \r
2005 Clazz.declarePackage ("java.io");\r
2006 //Clazz.declarePackage ("java.lang");\r
2007 Clazz.declarePackage ("java.lang.annotation"); // java.lang\r
2008 Clazz.declarePackage ("java.lang.instrument"); // java.lang\r
2009 Clazz.declarePackage ("java.lang.management"); // java.lang\r
2010 Clazz.declarePackage ("java.lang.reflect"); // java.lang\r
2011 Clazz.declarePackage ("java.lang.ref");  // java.lang.ref\r
2012 java.lang.ref.reflect = java.lang.reflect;\r
2013 Clazz.declarePackage ("java.util");\r
2014 //var reflect = Clazz.declarePackage ("java.lang.reflect");\r
2015 Clazz.declarePackage ("java.security");\r
2016 \r
2017 \r
2018 /*\r
2019  * Consider these interfaces are basic!\r
2020  */\r
2021 Clazz.declareInterface (java.io,"Closeable");\r
2022 Clazz.declareInterface (java.io,"DataInput");\r
2023 Clazz.declareInterface (java.io,"DataOutput");\r
2024 Clazz.declareInterface (java.io,"Externalizable");\r
2025 Clazz.declareInterface (java.io,"Flushable");\r
2026 Clazz.declareInterface (java.io,"Serializable");\r
2027 Clazz.declareInterface (java.lang,"Iterable");\r
2028 Clazz.declareInterface (java.lang,"CharSequence");\r
2029 Clazz.declareInterface (java.lang,"Cloneable");\r
2030 Clazz.declareInterface (java.lang,"Appendable");\r
2031 Clazz.declareInterface (java.lang,"Comparable");\r
2032 Clazz.declareInterface (java.lang,"Runnable");\r
2033 Clazz.declareInterface (java.util,"Comparator");\r
2034 \r
2035 java.lang.ClassLoader = {\r
2036         __CLASS_NAME__ : "ClassLoader"\r
2037 };\r
2038 \r
2039 /******************************************************************************\r
2040  * Copyright (c) 2007 java2script.org and others.\r
2041  * All rights reserved. This program and the accompanying materials\r
2042  * are made available under the terms of the Eclipse Public License v1.0\r
2043  * which accompanies this distribution, and is available at\r
2044  * http://www.eclipse.org/legal/epl-v10.html\r
2045  *\r
2046  * Contributors:\r
2047  *     Zhou Renjian - initial API and implementation\r
2048  *****************************************************************************/\r
2049 /*******\r
2050  * @author zhou renjian\r
2051  * @create March 10, 2006\r
2052  *******/\r
2053 \r
2054 /**\r
2055  * Once ClassExt.js is part of Class.js.\r
2056  * In order to make the Class.js as small as possible, part of its content\r
2057  * is moved into this ClassExt.js.\r
2058  *\r
2059  * See also http://j2s.sourceforge.net/j2sclazz/\r
2060  */\r
2061  \r
2062 /**\r
2063  * Clazz.MethodNotFoundException is used to notify the developer about calling\r
2064  * methods with incorrect parameters.\r
2065  */\r
2066 /* protected */\r
2067 // Override the Clazz.MethodNotFoundException in Class.js to give details\r
2068 var newMethodNotFoundException = function (obj, clazz, method, params) {\r
2069         var paramStr = "";\r
2070         if (params) {\r
2071                 paramStr = params.substring (1).replace (/\\/g, ",");\r
2072         }\r
2073         var leadingStr = "";\r
2074         if (method && method != "construct") {\r
2075                 leadingStr = "Method";\r
2076         } else {\r
2077                 leadingStr = "Constructor";\r
2078         }\r
2079         var message = leadingStr + " " + Clazz.getClassName (clazz, true) + "." \r
2080                                         + method + "(" + paramStr + ") is not found!";\r
2081   throw new java.lang.NoSuchMethodException(message);        \r
2082 };\r
2083 \r
2084 /**\r
2085  * Prepare "callback" for instance of anonymous Class.\r
2086  * For example for the callback:\r
2087  *     this.callbacks.MyEditor.sayHello();\r
2088  *     \r
2089  * This is specifically for inner classes that are referring to \r
2090  * outer class methods and fields.   \r
2091  *\r
2092  * @param objThis the host object for callback\r
2093  * @param args arguments object. args[0] will be classThisObj -- the "this"\r
2094  * object to be hooked\r
2095  * \r
2096  * Attention: parameters should not be null!\r
2097  */\r
2098 /* protected */\r
2099 Clazz.prepareCallback = function (innerObj, args) {\r
2100         var outerObj = args[0];\r
2101         var cbName = "b$"; // "callbacks";\r
2102         if (innerObj && outerObj && outerObj !== window) {\r
2103                 var className = Clazz.getClassName(outerObj, true);             \r
2104                 var obs = {};\r
2105                 if (innerObj[cbName]) // must make a copy!\r
2106                         for (var s in innerObj[cbName])\r
2107                                 obs[s] = innerObj[cbName][s];\r
2108                 innerObj[cbName] = obs;\r
2109                 \r
2110                 /*\r
2111                  * TODO: the following line is SWT-specific! Try to move it out!\r
2112                  */\r
2113                 //                      obs[className.replace (/org\.eclipse\.swt\./, "$wt.")] = outerObj;\r
2114 \r
2115         // all references to outer class and its superclass objects must be here as well\r
2116                 obs[className] = outerObj;\r
2117                 var clazz = Clazz.getClass(outerObj);\r
2118                 while (clazz.superClazz) {\r
2119                         clazz = clazz.superClazz;\r
2120                         /*\r
2121                          * TODO: the following line is SWT-specific! Try to move it out!\r
2122                          */\r
2123                         //                              obs[Clazz.getClassName (clazz, true)\r
2124                         //                                              .replace (/org\.eclipse\.swt\./, "$wt.")] = outerObj;\r
2125                         obs[Clazz.getClassName(clazz, true)] = outerObj;\r
2126                 }\r
2127                 var cbs = outerObj[cbName];\r
2128                 if (cbs)\r
2129                         for (var s in cbs)\r
2130                                 obs[s] = cbs[s];\r
2131         }\r
2132         // remove "this" argument\r
2133         // note that args is an instance of arguments -- NOT an array; does not have the .shift() method!\r
2134         for (var i = 0; i < args.length - 1; i++)\r
2135                 args[i] = args[i + 1];\r
2136         args.length--;\r
2137 };\r
2138 \r
2139 /**\r
2140  * Construct instance of the given inner class.\r
2141  *\r
2142  * @param classInner given inner class, alway with name like "*$*"\r
2143  * @param innerObj this instance which can be used to call back.\r
2144  * @param finalVars final variables which the inner class may use\r
2145  * @return the constructed object\r
2146  *\r
2147  * @see Clazz#cloneFinals\r
2148  */\r
2149 /* public */\r
2150 Clazz.innerTypeInstance = function (clazzInner, innerObj, finalVars) {\r
2151         if (!clazzInner)\r
2152                 clazzInner = arguments.callee.caller;\r
2153         var obj;\r
2154         if (finalVars || innerObj.$finals) {\r
2155                         obj = new clazzInner(innerObj, Clazz.inheritArgs);\r
2156                 // f$ is short for the once choosen "$finals"\r
2157                 if (finalVars) {\r
2158                         if (innerObj.f$) {\r
2159                                 var o = {};\r
2160                                 for (var attr in innerObj.f$)\r
2161                                         o[attr] = innerObj.f$[attr];\r
2162                                 for (var attr in finalVars)\r
2163                                         o[attr] = finalVars[attr];\r
2164                                 obj.f$ = o;\r
2165                         } else {\r
2166                                 obj.f$ = finalVars;\r
2167                         }\r
2168                 } else if (innerObj.f$) {\r
2169                         obj.f$ = innerObj.f$;\r
2170                 }\r
2171         } else {\r
2172                 switch (arguments.length) {\r
2173                 case 3:\r
2174                         return new clazzInner(innerObj);\r
2175                 case 4:\r
2176                         return (innerObj.__CLASS_NAME__ == clazzInner.__CLASS_NAME__\r
2177                                         && arguments[3] === Clazz.inheritArgs ? innerObj : new clazzInner(innerObj, arguments[3]));\r
2178                 case 5:\r
2179                         return new clazzInner(innerObj, arguments[3], arguments[4]);\r
2180                 case 6:\r
2181                         return new clazzInner(innerObj, arguments[3], arguments[4], \r
2182                                         arguments[5]);\r
2183                 case 7:\r
2184                         return new clazzInner(innerObj, arguments[3], arguments[4], \r
2185                                         arguments[5], arguments[6]);\r
2186                 case 8:\r
2187                         return new clazzInner(innerObj, arguments[3], arguments[4], \r
2188                                         arguments[5], arguments[6], arguments[7]);\r
2189                 case 9:\r
2190                         return new clazzInner(innerObj, arguments[3], arguments[4], \r
2191                                         arguments[5], arguments[6], arguments[7], arguments[8]);\r
2192                 case 10:\r
2193                         return new clazzInner(innerObj, arguments[3], arguments[4], \r
2194                                         arguments[5], arguments[6], arguments[7], arguments[8],\r
2195                                         arguments[9]);\r
2196                 default:\r
2197                         //Should construct instance manually.\r
2198                         obj = new clazzInner(innerObj, Clazz.inheritArgs);\r
2199                         break;\r
2200                 }\r
2201         }\r
2202         var n = arguments.length - 3;\r
2203         var args = new Array(n);\r
2204         for (var i = n; --i >= 0;)\r
2205                 args[i] = arguments[i + 3];\r
2206         Clazz.instantialize(obj, args);\r
2207         return obj;\r
2208 };\r
2209 \r
2210 /**\r
2211  * Clone variables whose modifier is "final".\r
2212  * Usage: var o = Clazz.cloneFinals ("name", name, "age", age);\r
2213  *\r
2214  * @return Object with all final variables\r
2215  */\r
2216 /* public */\r
2217 Clazz.cloneFinals = function () {\r
2218         var o = {};\r
2219         var len = arguments.length / 2;\r
2220         for (var i = len; --i >= 0;)\r
2221                 o[arguments[i + i]] = arguments[i + i + 1];\r
2222         return o;\r
2223 };\r
2224 \r
2225 /* public */\r
2226 Clazz.isClassDefined = Clazz.isDefinedClass = function(clazzName) {\r
2227         if (!clazzName) \r
2228                 return false;           /* consider null or empty name as non-defined class */\r
2229         if (Clazz.allClasses[clazzName])\r
2230                 return true;\r
2231         var pkgFrags = clazzName.split (/\./);\r
2232         var pkg = null;\r
2233         for (var i = 0; i < pkgFrags.length; i++)\r
2234                 if (!(pkg = (pkg ? pkg[pkgFrags[i]] : Clazz.allPackage[pkgFrags[0]]))) {\r
2235                         return false;\r
2236     }\r
2237   return (pkg && (Clazz.allClasses[clazzName] = true));\r
2238 };\r
2239 /**\r
2240  * Define the enum constant.\r
2241  * @param classEnum enum type\r
2242  * @param enumName enum constant\r
2243  * @param enumOrdinal enum ordinal\r
2244  * @param initialParams enum constant constructor parameters\r
2245  * @return return defined enum constant\r
2246  */\r
2247 /* public */\r
2248 Clazz.defineEnumConstant = function (clazzEnum, enumName, enumOrdinal, initialParams, clazzEnumExt) {\r
2249         var o = (clazzEnumExt ? new clazzEnumExt() : new clazzEnum());\r
2250         // BH avoids unnecessary calls to SAEM\r
2251         o.$name = enumName;\r
2252         o.$ordinal = enumOrdinal;\r
2253         //Clazz.superConstructor (o, clazzEnum, [enumName, enumOrdinal]);\r
2254         if (initialParams && initialParams.length)\r
2255                 o.construct.apply (o, initialParams);\r
2256         clazzEnum[enumName] = o;\r
2257         clazzEnum.prototype[enumName] = o;\r
2258         if (!clazzEnum["$ values"]) {         // BH added\r
2259                 clazzEnum["$ values"] = []          // BH added\r
2260                 clazzEnum.values = function() {     // BH added\r
2261                         return this["$ values"];          // BH added\r
2262                 };                                  // BH added\r
2263         }\r
2264         clazzEnum["$ values"].push(o);\r
2265         return o;\r
2266 };\r
2267 \r
2268 //////// (int) conversions //////////\r
2269 \r
2270 Clazz.floatToInt = function (x) {\r
2271         return x < 0 ? Math.ceil(x) : Math.floor(x);\r
2272 };\r
2273 \r
2274 Clazz.floatToByte = Clazz.floatToShort = Clazz.floatToLong = Clazz.floatToInt;\r
2275 Clazz.doubleToByte = Clazz.doubleToShort = Clazz.doubleToLong = Clazz.doubleToInt = Clazz.floatToInt;\r
2276 \r
2277 Clazz.floatToChar = function (x) {\r
2278         return String.fromCharCode (x < 0 ? Math.ceil(x) : Math.floor(x));\r
2279 };\r
2280 \r
2281 Clazz.doubleToChar = Clazz.floatToChar;\r
2282 \r
2283 \r
2284 \r
2285 ///////////////////////////////// Array additions //////////////////////////////\r
2286 //\r
2287 // BH: these are necessary for integer processing, especially\r
2288 //\r
2289 //\r
2290 \r
2291 var getArrayClone = function(nbits) {\r
2292   return function() {\r
2293     var me = this;\r
2294     var n = me.length;\r
2295     var a = (nbits == 32 ? new Int32Array(n) : new Float64Array(n));\r
2296     for (var i = n; --i >= 0;)\r
2297       a[i] = me[i];\r
2298     return a; \r
2299   }\r
2300 }\r
2301 \r
2302 if (self.Int32Array && self.Int32Array != Array) {\r
2303         Clazz.haveInt32 = true;\r
2304         if (!Int32Array.prototype.sort)\r
2305                 Int32Array.prototype.sort = Array.prototype.sort\r
2306         if (!Int32Array.prototype.clone)\r
2307                 Int32Array.prototype.clone = getArrayClone(32);\r
2308 } else {\r
2309         Int32Array = function(n) {\r
2310                 if (!n) n = 0;\r
2311                 var b = new Array(n);\r
2312                 b.toString = function(){return "[object Int32Array]"}\r
2313                 for (var i = 0; i < n; i++)b[i] = 0\r
2314                 return b;\r
2315         }\r
2316         Clazz.haveInt32 = false;\r
2317         Int32Array.prototype.sort = Array.prototype.sort\r
2318         Int32Array.prototype.clone = getArrayClone(32);\r
2319         Int32Array.prototype.int32Fake = function(){};\r
2320 }\r
2321 \r
2322 if (self.Float64Array && self.Float64Array != Array) {\r
2323         Clazz.haveFloat64 = true;\r
2324         if (!Float64Array.prototype.sort)\r
2325                 Float64Array.prototype.sort = Array.prototype.sort\r
2326         if (!Float64Array.prototype.clone)\r
2327                 Float64Array.prototype.clone = getArrayClone(64);\r
2328 } else {\r
2329         Clazz.haveFloat64 = false;\r
2330         Float64Array = function(n) {\r
2331                 if (!n) n = 0;\r
2332                 var b = new Array(n);\r
2333                 for (var i = 0; i < n; i++)b[i] = 0.0\r
2334                 return b;\r
2335         };\r
2336         Float64Array.prototype.sort = Array.prototype.sort\r
2337         Float64Array.prototype.clone = getArrayClone(64);\r
2338         Float64Array.prototype.float64Fake = function() {}; // "present"\r
2339         Float64Array.prototype.toString = function() {return "[object Float64Array]"};\r
2340 // Darn! Mozilla makes this a double, not a float. It's 64-bit.\r
2341 // and Safari 5.1 doesn't have Float64Array \r
2342 }\r
2343 \r
2344 /**\r
2345  * Make arrays.\r
2346  *\r
2347  * @return the created Array object\r
2348  */\r
2349 /* public */\r
2350 Clazz.newArray  = function () {\r
2351         if (arguments[0] instanceof Array) {\r
2352                 // recursive, from newArray(n,m,value)\r
2353                 // as newArray([m, value], newInt32Array)\r
2354                 var args = arguments[0];\r
2355                 var f = arguments[1];\r
2356         } else {\r
2357                 var args = arguments;\r
2358                 var f = Array;\r
2359         }\r
2360         var dim = args[0];\r
2361         if (typeof dim == "string") {\r
2362                 dim = dim.charCodeAt (0); // char\r
2363         }\r
2364         var len = args.length - 1;\r
2365         var val = args[len];\r
2366   switch (args.length) {\r
2367   case 0: // never\r
2368   case 1:\r
2369                 return []; // maybe never?\r
2370   case 2:\r
2371                 if (val == null)\r
2372                 return new Array(dim);\r
2373           if (f === true && Clazz.haveInt32) return new Int32Array(dim);\r
2374           if (f === false && Clazz.haveFloat64) return new Float64Array(dim);\r
2375                 var arr = (f === true ? new Int32Array() : f === false ? new Float64Array() : dim < 0 ? val : new Array(dim));\r
2376                 for (var i = dim; --i >= 0;)\r
2377                 arr[i] = val;\r
2378           return arr;\r
2379   default:\r
2380         var xargs = new Array (len);\r
2381         for (var i = 0; i < len; i++) {\r
2382                 xargs[i] = args[i + 1];\r
2383         }\r
2384         var arr = new Array (dim);\r
2385         if (val == null || val >= 0 || len > 2)\r
2386                 for (var i = 0; i < dim; i++) {\r
2387                 // Call recursively!\r
2388                         arr[i] = Clazz.newArray (xargs, f);\r
2389                 }\r
2390         return arr;\r
2391         }\r
2392 };\r
2393 \r
2394 Clazz.newArray32 = function(args, isInt32) {\r
2395         var dim = args[0];\r
2396         if (typeof dim == "string")\r
2397                 dim = dim.charCodeAt (0); // char\r
2398         var len = args.length - 1;\r
2399         var val = args[len];\r
2400         switch (args.length) {\r
2401         case 0:\r
2402         case 1:  \r
2403                 alert ("ERROR IN newArray32 -- args.length < 2");\r
2404                 return new Array(0);\r
2405         case 2:\r
2406     var isDefined = (dim < 0);\r
2407     if (isDefined)\r
2408       dim = val.length;\r
2409     var a = (val < 0 ? new Array(dim) : isInt32 ? new Int32Array(dim) : new Float64Array(dim));\r
2410     if (isDefined)\r
2411       for (var i = dim; --i >= 0;)\r
2412         a[i] = val[i];\r
2413     return a;\r
2414         }\r
2415         var xargs = new Array(len);\r
2416         for (var i = len; --i >= 0;) {\r
2417                 xargs[i] = args[i + 1];\r
2418         }\r
2419         var arr = new Array (dim);\r
2420         for (var i = 0; i < dim; i++) {\r
2421                 // Call newArray referencing this array type\r
2422                 // only for the final iteration, and only if val === 0\r
2423                 arr[i] = Clazz.newArray (xargs, isInt32);\r
2424         }\r
2425         return arr;\r
2426 };\r
2427 \r
2428 \r
2429 /**\r
2430  * Make arrays.\r
2431  *\r
2432  * @return the created Array object\r
2433  */\r
2434 /* public */\r
2435 Clazz.newInt32Array  = function () {\r
2436         return Clazz.newArray32(arguments, true);\r
2437 }\r
2438 \r
2439 /**\r
2440  * Make arrays.\r
2441  *\r
2442  * @return the created Array object\r
2443  */\r
2444 /* public */\r
2445 Clazz.newFloat64Array  = function () {\r
2446         return Clazz.newArray32(arguments, false);\r
2447 }\r
2448 \r
2449 Clazz.newFloatArray = Clazz.newDoubleArray = Clazz.newFloat64Array;\r
2450 Clazz.newIntArray = Clazz.newLongArray = Clazz.newShortArray = Clazz.newByteArray = Clazz.newInt32Array;\r
2451 Clazz.newCharArray = Clazz.newBooleanArray = Clazz.newArray;\r
2452 \r
2453 //$_AI=Clazz.newIntArray;\r
2454 //$_AF=Clazz.newFloatArray;\r
2455 //$_AD=Clazz.newDoubleArray;\r
2456 //$_AL=Clazz.newLongArray;\r
2457 //$_AS=Clazz.newShortArray;\r
2458 //$_AB=Clazz.newByteArray;\r
2459 //$_AC=Clazz.newCharArray;\r
2460 //$_Ab=Clazz.newBooleanArray;\r
2461 \r
2462 \r
2463 var arrayIs = function(a, what) {\r
2464         // for some reason, Number.constructor.toString() now gives "too much recursion"\r
2465         return a.constructor && a.constructor != Number && a.constructor.toString().indexOf(what) >= 0\r
2466 }\r
2467 \r
2468 Clazz.isAS = function(a) { // just checking first parameter\r
2469         return (a && typeof a == "object" && arrayIs(a, " Array") && (typeof a[0] == "string" || typeof a[0] == "undefined"));\r
2470 }\r
2471 \r
2472 Clazz.isASS = function(a) {\r
2473         return (a && typeof a == "object" && Clazz.isAS(a[0]));\r
2474 }\r
2475 \r
2476 Clazz.isAP = function(a) {\r
2477         return (a && Clazz.getClassName(a[0]) == "JU.P3");\r
2478 }\r
2479 \r
2480 Clazz.isAI = function(a) {\r
2481         return (a && typeof a == "object" && (Clazz.haveInt32 ? arrayIs(a, "Int32Array") : a.int32Fake ? true : false));\r
2482 }\r
2483 \r
2484 Clazz.isAII = function(a) { // assumes non-null a[0]\r
2485         return (a && typeof a == "object" && Clazz.isAI(a[0]));\r
2486 }\r
2487 \r
2488 Clazz.isAF = function(a) {\r
2489         return (a && typeof a == "object" && (Clazz.haveFloat64 ? arrayIs(a, "Float64Array") : a.float64Fake ? true : false));\r
2490 }\r
2491 \r
2492 Clazz.isAFF = function(a) { // assumes non-null a[0]\r
2493         return (a && typeof a == "object" && Clazz.isAF(a[0]));\r
2494 }\r
2495 \r
2496 Clazz.isAFFF = function(a) { // assumes non-null a[0]\r
2497         return (a && typeof a == "object" && Clazz.isAFF(a[0]));\r
2498 }\r
2499 \r
2500 Clazz.isAFloat = function(a) { // just checking first parameter\r
2501         return (a && typeof a == "object" && arrayIs(a, " Array") && Clazz.instanceOf(a[0], Float));\r
2502 }\r
2503 \r
2504 \r
2505 /**\r
2506  * Make the RunnableCompatiability instance as a JavaScript function.\r
2507  *\r
2508  * @param jsr Instance of RunnableCompatiability\r
2509  * @return JavaScript function instance represents the method run of jsr.\r
2510  */\r
2511 /* public */\r
2512 /*\r
2513 Clazz.makeFunction = function (jsr) {\r
2514 // never used in Jmol -- called by Enum, but not accessible to it -- part of SWT\r
2515         return function(e) {\r
2516                 if (!e)\r
2517                         e = window.event;\r
2518                 if (jsr.setEvent)\r
2519                         jsr.setEvent(e);\r
2520                 jsr.run();\r
2521                 switch (jsr.returnSet) {\r
2522                 case 1: \r
2523                         return jsr.returnNumber;\r
2524                 case 2:\r
2525                         return jsr.returnBoolean;\r
2526                 case 3:\r
2527                         return jsr.returnObject;\r
2528                 }\r
2529         };\r
2530 };\r
2531 */\r
2532 \r
2533 /* protected */\r
2534 Clazz.defineStatics = function (clazz) {\r
2535         for (var j = arguments.length, i = (j - 1) / 2; --i >= 0;) {\r
2536                 var val = arguments[--j]\r
2537                 var name = arguments[--j];\r
2538                 clazz[name] = clazz.prototype[name] = val;\r
2539         }\r
2540 };\r
2541 \r
2542 /* public */\r
2543 Clazz.prepareFields = function (clazz, fieldsFun) {\r
2544         var stacks = [];\r
2545         if (clazz.con$truct) {\r
2546                 var ss = clazz.con$truct.stacks;\r
2547                 var idx = 0;//clazz.con$truct.index;\r
2548                 for (var i = idx; i < ss.length; i++) {\r
2549                         stacks[i] = ss[i];\r
2550                 }\r
2551         }\r
2552         addProto(clazz.prototype, "con$truct", clazz.con$truct = function () {\r
2553                 var stacks = arguments.callee.stacks;\r
2554                 if (stacks) {\r
2555                         for (var i = 0; i < stacks.length; i++) {\r
2556                                 stacks[i].apply (this, []);\r
2557                         }\r
2558                 }\r
2559         });\r
2560         stacks.push(fieldsFun);\r
2561         clazz.con$truct.stacks = stacks;\r
2562         clazz.con$truct.index = 0;\r
2563 };\r
2564 \r
2565 /*\r
2566  * Serialize those public or protected fields in class \r
2567  * net.sf.j2s.ajax.SimpleSerializable.\r
2568  */\r
2569 /* protected */\r
2570 /*\r
2571 Clazz.registerSerializableFields = function (clazz) {\r
2572         var args = arguments;\r
2573         var length = args.length;\r
2574         var newArr = [];\r
2575         if (clazz.declared$Fields) {\r
2576                 for (var i = 0; i < clazz.declared$Fields.length; i++) {\r
2577                         newArr[i] = clazz.declared$Fields[i];\r
2578                 }\r
2579         }\r
2580         clazz.declared$Fields = newArr;\r
2581 \r
2582         if (length > 0 && length % 2 == 1) {\r
2583                 var fs = clazz.declared$Fields;\r
2584                 var n = (length - 1) / 2;\r
2585                 for (var i = 1; i <= n; i++) {\r
2586                         var o = { name : args[i + i - 1], type : args[i + i] };\r
2587                         var existed = false;\r
2588                         for (var j = 0; j < fs.length; j++) {\r
2589                                 if (fs[j].name == o.name) { // reloaded classes\r
2590                                         fs[j].type = o.type; // update type\r
2591                                         existed = true;\r
2592                                         break;\r
2593                                 }\r
2594                         }\r
2595                         if (!existed)\r
2596                                 fs.push(o);\r
2597                 }\r
2598         }\r
2599 };\r
2600 */\r
2601 /*\r
2602  * Get the caller method for those methods that are wrapped by \r
2603  * Clazz.searchAndExecuteMethod.\r
2604  *\r
2605  * @param args caller method's arguments\r
2606  * @return caller method, null if there is not wrapped by \r
2607  * Clazz.searchAndExecuteMethod or is called directly.\r
2608  */\r
2609 /* protected */\r
2610 /*\r
2611 Clazz.getMixedCallerMethod = function (args) {\r
2612         var o = {};\r
2613         var argc = args.callee.caller; // tryToSearchAndExecute\r
2614         if (argc && argc !== tryToSearchAndExecute) // inherited method's apply\r
2615                 argc = argc.arguments.callee.caller;\r
2616         if (argc !== tryToSearchAndExecute\r
2617                 || (argc = argc.arguments.callee.caller) !== Clazz.searchAndExecuteMethod)\r
2618                 return null;\r
2619         o.claxxRef = argc.arguments[1];\r
2620         o.fxName = argc.arguments[2];\r
2621         o.paramTypes = Clazz.getParamsType(argc.arguments[3]);  \r
2622         argc = argc.arguments.callee.caller // Clazz.generateDelegatingMethod \r
2623                                         && argc.arguments.callee.caller; // the private method's caller\r
2624         if (!argc)\r
2625                 return null;\r
2626         o.caller = argc;\r
2627         return o;\r
2628 };\r
2629 */\r
2630 /* BH -- The issue here is a subclass calling its private method FOO when\r
2631  *       there is also a private method of the same name in its super class.\r
2632  *       This can ALWAYS be avoided and, one could argue, is bad \r
2633  *       program design anyway. In Jmol, the presence of this possibility\r
2634  *       creates over 8000 references to the global $fx, which was only\r
2635  *       checked in a few rare cases. We can then also remove $fz references.\r
2636  *         \r
2637  */\r
2638 \r
2639 /*\r
2640  * Check and return super private method.\r
2641  * In order make private methods be executed correctly, some extra javascript\r
2642  * must be inserted into the beggining of the method body of the non-private \r
2643  * methods that with the same method signature as following:\r
2644  * <code>\r
2645  *                      var $private = Clazz.checkPrivateMethod (arguments);\r
2646  *                      if ($private) {\r
2647  *                              return $private.apply (this, arguments);\r
2648  *                      }\r
2649  * </code>\r
2650  * Be cautious about this. The above codes should be insert by Java2Script\r
2651  * compiler or with double checks to make sure things work correctly.\r
2652  *\r
2653  * @param args caller method's arguments\r
2654  * @return private method if there are private method fitted for the current \r
2655  * calling environment\r
2656  */\r
2657 /* public */\r
2658 \r
2659 Clazz.checkPrivateMethod = function () {\r
2660   // get both this one and the one calling it\r
2661   me = arguments.callee.caller;\r
2662   caller = arguments.callee.caller.caller;\r
2663   var stack = me.stacks;\r
2664   // if their classes are the same, no issue\r
2665   var mySig = "\\" + Clazz.getParamsType(arguments[0]).join("\\")\r
2666   if (!me.privateNote) {\r
2667     me.privateNote = "You are seeing this note because the method " \r
2668     + me.exName + mySig + " in class " \r
2669     + me.exClazz.__CLASS_NAME__\r
2670     + " has a superclass method by the same name (possibly with the same parameters) that is private and "\r
2671     + " therefore might be called improperly from this class. If your "\r
2672     + " code does not run properly, or you want to make it run faster, change the name of this method to something else."\r
2673     System.out.println(me.privateNote);\r
2674     alert(me.privateNote);\r
2675   }\r
2676   /*\r
2677   alert([me.exClazz.__CLASS_NAME__, me.exName,\r
2678     caller.exClazz.__CLASS_NAME__, caller.exName,stack,mySig])\r
2679   if (stack == null || caller.exClazz == me.exClazz)\r
2680     return null;\r
2681   // I am being called by a different class...\r
2682   \r
2683   for (var i = stack.length; --i >= 0;) {\r
2684     if (stacks[i] != caller.claxxRef)\r
2685       continue;\r
2686     // and it is on MY class stack\r
2687 //    if (\r
2688      \r
2689   }\r
2690   */\r
2691   \r
2692 /*      var m = Clazz.getMixedCallerMethod (args);\r
2693         if (m == null) return null;\r
2694         var callerFx = m.claxxRef.prototype[m.caller.exName];\r
2695         if (callerFx == null) return null; // may not be in the class hierarchies\r
2696         var ppFun = null;\r
2697         if (callerFx.claxxOwner ) {\r
2698                 ppFun = callerFx.claxxOwner.prototype[m.fxName];\r
2699         } else {\r
2700                 var stacks = callerFx.stacks;\r
2701                 for (var i = stacks.length - 1; i >= 0; i--) {\r
2702                         var fx = stacks[i].prototype[m.caller.exName];\r
2703                         if (fx === m.caller) {\r
2704                                 ppFun = stacks[i].prototype[m.fxName];\r
2705                         } else if (fx ) {\r
2706                                 for (var fn in fx) {\r
2707                                         if (fn.indexOf ('\\') == 0 && fx[fn] === m.caller) {\r
2708                                                 ppFun = stacks[i].prototype[m.fxName];\r
2709                                                 break;\r
2710                                         }\r
2711                                 }\r
2712                         }\r
2713                         if (ppFun) {\r
2714                                 break;\r
2715                         }\r
2716                 }\r
2717         }\r
2718         if (ppFun && ppFun.claxxOwner == null) {\r
2719                 ppFun = ppFun["\\" + m.paramTypes];\r
2720         }\r
2721         if (ppFun && ppFun.isPrivate && ppFun !== args.callee) {\r
2722                 return ppFun;\r
2723         }\r
2724 */  \r
2725         return null;\r
2726 };\r
2727 \r
2728 \r
2729 //$fz = null; // for private method declaration\r
2730 \r
2731 \r
2732 // /*# {$no.debug.support} >>x #*/\r
2733 // /*\r
2734 //  * Option to switch on/off of stack traces.\r
2735 //  */\r
2736 // /* protect */\r
2737 //Clazz.tracingCalling = false;\r
2738 \r
2739 // /* private */\r
2740 // Clazz.callingStack = function (caller, owner) {\r
2741 //      this.caller = caller;\r
2742 //      this.owner = owner;\r
2743 // };\r
2744 \r
2745 /*# x<< #*/\r
2746 \r
2747 /**\r
2748  * The first folder is considered as the primary folder.\r
2749  * And try to be compatiable with _Loader system.\r
2750  */\r
2751 /* private */\r
2752 \r
2753 \r
2754 /*** not used in Jmol\r
2755  * *\r
2756 if (window["_Loader"] && _Loader.binaryFolders) {\r
2757         Clazz.binaryFolders = _Loader.binaryFolders;\r
2758 } else {\r
2759         Clazz.binaryFolders = ["j2s/", "", "j2slib/"];\r
2760 }\r
2761 \r
2762 Clazz.addBinaryFolder = function (bin) {\r
2763         if (bin) {\r
2764                 var bins = Clazz.binaryFolders;\r
2765                 for (var i = 0; i < bins.length; i++) {\r
2766                         if (bins[i] == bin) {\r
2767                                 return ;\r
2768                         }\r
2769                 }\r
2770                 bins[bins.length] = bin;\r
2771         }\r
2772 };\r
2773 Clazz.removeBinaryFolder = function (bin) {\r
2774         if (bin) {\r
2775                 var bins = Clazz.binaryFolders;\r
2776                 for (var i = 0; i < bins.length; i++) {\r
2777                         if (bins[i] == bin) {\r
2778                                 for (var j = i; j < bins.length - 1; j++) {\r
2779                                         bins[j] = bins[j + 1];\r
2780                                 }\r
2781                                 bins.length--;\r
2782                                 return bin;\r
2783                         }\r
2784                 }\r
2785         }\r
2786         return null;\r
2787 };\r
2788 Clazz.setPrimaryFolder = function (bin) {\r
2789         if (bin) {\r
2790                 Clazz.removeBinaryFolder (bin);\r
2791                 var bins = Clazz.binaryFolders;\r
2792                 for (var i = bins.length - 1; i >= 0; i--) {\r
2793                         bins[i + 1] = bins[i];\r
2794                 }\r
2795                 bins[0] = bin;\r
2796         }\r
2797 };\r
2798 \r
2799 ***/\r
2800 \r
2801 \r
2802 ///////////////// special definitions of standard Java class methods ///////////\r
2803 \r
2804 /**\r
2805  * This is a simple implementation for Clazz#load. It just ignore dependencies\r
2806  * of the class. This will be fine for jar *.z.js file.\r
2807  * It will be overriden by _Loader#load.\r
2808  * For more details, see _Loader.js\r
2809  */\r
2810 /* protected */\r
2811 /*\r
2812 Clazz.load = function (musts, clazz, optionals, declaration) {\r
2813         // not used in Jmol\r
2814         if (declaration)\r
2815                 declaration ();\r
2816 };\r
2817 */\r
2818 \r
2819 /*\r
2820  * Invade the Object prototype!\r
2821  * TODO: make sure that invading Object prototype does not affect other\r
2822  * existed library, such as Dojo, YUI, Prototype, ...\r
2823  */\r
2824 java.lang.Object = Clazz._O;\r
2825 \r
2826 Clazz._O.getName = Clazz._innerFunctions.getName;\r
2827 \r
2828 \r
2829 java.lang.System = System = {\r
2830         props : null, //new java.util.Properties (),\r
2831         $props : {},\r
2832         arraycopy : function (src, srcPos, dest, destPos, length) {\r
2833                 if (src !== dest) {\r
2834                         for (var i = 0; i < length; i++) {\r
2835                                 dest[destPos + i] = src[srcPos + i];\r
2836                         }\r
2837                 } else {\r
2838                         var swap = [];\r
2839                         for (var i = 0; i < length; i++) {\r
2840                                 swap[i] = src[srcPos + i];\r
2841                         }\r
2842                         for (var i = 0; i < length; i++) {\r
2843                                 dest[destPos + i] = swap[i];\r
2844                         }\r
2845                 }\r
2846         },\r
2847         currentTimeMillis : function () {\r
2848                 return new Date ().getTime ();\r
2849         },\r
2850         gc : function() {}, // bh\r
2851         getProperties : function () {\r
2852                 return System.props;\r
2853         },\r
2854         getProperty : function (key, def) {\r
2855                 if (System.props)\r
2856                         return System.props.getProperty (key, def);\r
2857                 var v = System.$props[key];\r
2858     if (typeof v != "undefined")\r
2859       return v;\r
2860     if (key.indexOf(".") > 0) {\r
2861       v = null;    \r
2862       switch (key) {\r
2863       case "java.version":\r
2864         v = "1.6";\r
2865       case "file.separator":\r
2866       case "path.separator":\r
2867         v = "/";\r
2868         break;        \r
2869       case "line.separator":\r
2870         v = (navigator.userAgent.indexOf("Windows") >= 0 ? "\r\n" : "\n");\r
2871         break;\r
2872       case "os.name":\r
2873       case "os.version":\r
2874         v = navigator.userAgent;\r
2875         break;\r
2876       }\r
2877       if (v)\r
2878         return System.$props[key] = v;\r
2879     }\r
2880     return (arguments.length == 1 ? null : def == null ? key : def); // BH\r
2881         },\r
2882         getSecurityManager : function() { return null },  // bh\r
2883         setProperties : function (props) {\r
2884                 System.props = props;\r
2885         },\r
2886   lineSeparator : function() { return '\n' }, // bh\r
2887         setProperty : function (key, val) {\r
2888                 if (!System.props)\r
2889                         return System.$props[key] = val; // BH\r
2890                 System.props.setProperty (key, val);\r
2891         }\r
2892 };\r
2893 \r
2894 System.identityHashCode=function(obj){\r
2895   if(obj==null)\r
2896     return 0;\r
2897     \r
2898         return obj._$hashcode || (obj._$hashcode = ++Clazz._hashCode)\r
2899 \r
2900 /*    \r
2901   try{\r
2902     return obj.toString().hashCode();\r
2903   }catch(e){\r
2904     var str=":";\r
2905     for(var s in obj){\r
2906      str+=s+":"\r
2907     }\r
2908     return str.hashCode();\r
2909   }\r
2910 */  \r
2911 }\r
2912 \r
2913 System.out = new Clazz._O ();\r
2914 System.out.__CLASS_NAME__ = "java.io.PrintStream";\r
2915 System.out.print = function () {};\r
2916 System.out.printf = function () {};\r
2917 System.out.println = function () {};\r
2918 System.out.write = function () {};\r
2919 \r
2920 System.err = new Clazz._O ();\r
2921 System.err.__CLASS_NAME__ = "java.io.PrintStream";\r
2922 System.err.print = function () {};\r
2923 System.err.printf = function () {};\r
2924 System.err.println = function () {};\r
2925 System.err.write = function () {};\r
2926 \r
2927 Clazz.popup = Clazz.assert = Clazz.log = Clazz.error = window.alert;\r
2928 \r
2929 Thread = function () {};\r
2930 Thread.J2S_THREAD = Thread.prototype.J2S_THREAD = new Thread ();\r
2931 Thread.currentThread = Thread.prototype.currentThread = function () {\r
2932         return this.J2S_THREAD;\r
2933 };\r
2934 \r
2935 /* not used in Jmol\r
2936 Clazz.intCast = function (n) { // 32bit\r
2937         var b1 = (n & 0xff000000) >> 24;\r
2938         var b2 = (n & 0xff0000) >> 16;\r
2939         var b3 = (n & 0xff00) >> 8;\r
2940         var b4 = n & 0xff;\r
2941         if ((b1 & 0x80) != 0) {\r
2942                 return -(((b1 & 0x7f) << 24) + (b2 << 16) + (b3 << 8) + b4 + 1);\r
2943         } else {\r
2944                 return (b1 << 24) + (b2 << 16) + (b3 << 8) + b4;\r
2945         }\r
2946 };\r
2947 Clazz.shortCast = function (s) { // 16bit\r
2948         var b1 = (n & 0xff00) >> 8;\r
2949         var b2 = n & 0xff;\r
2950         if ((b1 & 0x80) != 0) {\r
2951                 return -(((b1 & 0x7f) << 8) + b2 + 1);\r
2952         } else {\r
2953                 return (b1 << 8) + b4;\r
2954         }\r
2955 };\r
2956 \r
2957 Clazz.byteCast = function (b) { // 8bit\r
2958         if ((b & 0x80) != 0) {\r
2959                 return -((b & 0x7f) + 1);\r
2960         } else {\r
2961                 return b & 0xff;\r
2962         }\r
2963 };\r
2964 \r
2965 Clazz.charCast = function (c) { // 8bit\r
2966         return String.fromCharCode (c & 0xff).charAt (0);\r
2967 };\r
2968 \r
2969 Clazz.floatCast = function (f) { // 32bit\r
2970         return f;\r
2971 };\r
2972 \r
2973 */\r
2974 \r
2975 \r
2976 /*\r
2977  * Try to fix JavaScript's shift operator defects on long type numbers.\r
2978  */\r
2979 \r
2980 /* not used in Jmol\r
2981 \r
2982 Clazz.longMasks = [];\r
2983 \r
2984 Clazz.longReverseMasks = [];\r
2985 \r
2986 Clazz.longBits = [];\r
2987 \r
2988 ;(function () {\r
2989         var arr = [1];\r
2990         for (var i = 1; i < 53; i++) {\r
2991                 arr[i] = arr[i - 1] + arr[i - 1]; // * 2 or << 1\r
2992         }\r
2993         Clazz.longBits = arr;\r
2994         Clazz.longMasks[52] = arr[52];\r
2995         for (var i = 51; i >= 0; i--) {\r
2996                 Clazz.longMasks[i] = Clazz.longMasks[i + 1] + arr[i];\r
2997         }\r
2998         Clazz.longReverseMasks[0] = arr[0];\r
2999         for (var i = 1; i < 52; i++) {\r
3000                 Clazz.longReverseMasks[i] = Clazz.longReverseMasks[i - 1] + arr[i];\r
3001         }\r
3002 }) ();\r
3003 \r
3004 \r
3005 Clazz.longLeftShift = function (l, o) { // 64bit\r
3006         if (o == 0) return l;\r
3007         if (o >= 64) return 0;\r
3008         if (o > 52) {\r
3009                 error ("[Java2Script] Error : JavaScript does not support long shift!");\r
3010                 return l;\r
3011         }\r
3012         if ((l & Clazz.longMasks[o - 1]) != 0) {\r
3013                 error ("[Java2Script] Error : Such shift operator results in wrong calculation!");\r
3014                 return l;\r
3015         }\r
3016         var high = l & Clazz.longMasks[52 - 32 + o];\r
3017         if (high != 0) {\r
3018                 return high * Clazz.longBits[o] + (l & Clazz.longReverseMasks[32 - o]) << 0;\r
3019         } else {\r
3020                 return l << o;\r
3021         }\r
3022 };\r
3023 \r
3024 Clazz.intLeftShift = function (n, o) { // 32bit\r
3025         return (n << o) & 0xffffffff;\r
3026 };\r
3027 \r
3028 Clazz.longRightShift = function (l, o) { // 64bit\r
3029         if ((l & Clazz.longMasks[52 - 32]) != 0) {\r
3030                 return Math.round((l & Clazz.longMasks[52 - 32]) / Clazz.longBits[32 - o]) + (l & Clazz.longReverseMasks[o]) >> o;\r
3031         } else {\r
3032                 return l >> o;\r
3033         }\r
3034 };\r
3035 \r
3036 Clazz.intRightShift = function (n, o) { // 32bit\r
3037         return n >> o; // no needs for this shifting wrapper\r
3038 };\r
3039 \r
3040 Clazz.long0RightShift = function (l, o) { // 64bit\r
3041         return l >>> o;\r
3042 };\r
3043 \r
3044 Clazz.int0RightShift = function (n, o) { // 64bit\r
3045         return n >>> o; // no needs for this shifting wrapper\r
3046 };\r
3047 \r
3048 */\r
3049 // Compress the common public API method in shorter name\r
3050 //$_L=Clazz.load;\r
3051 //$_W=Clazz.declareAnonymous;$_T=Clazz.declareType;\r
3052 //$_J=Clazz.declarePackage;$_C=Clazz.decorateAsClass;\r
3053 //$_Z=Clazz.instantialize;$_I=Clazz.declareInterface;$_D=Clazz.isClassDefined;\r
3054 //$_H=Clazz.pu$h;$_P=Clazz.p0p;$_B=Clazz.prepareCallback;\r
3055 //$_N=Clazz.innerTypeInstance;$_K=Clazz.makeConstructor;$_U=Clazz.superCall;$_R=Clazz.superConstructor;\r
3056 //$_M=Clazz.defineMethod;$_V=Clazz.overrideMethod;$_S=Clazz.defineStatics;\r
3057 //$_E=Clazz.defineEnumConstant;\r
3058 //$_F=Clazz.cloneFinals;\r
3059 //$_Y=Clazz.prepareFields;$_A=Clazz.newArray;$_O=Clazz.instanceOf;\r
3060 //$_G=Clazz.inheritArgs;$_X=Clazz.checkPrivateMethod;$_Q=Clazz.makeFunction;\r
3061 //$_s=Clazz.registerSerializableFields;\r
3062 //$_k=Clazz.overrideConstructor;\r
3063 \r
3064 \r
3065 /////////////////////// inner function support /////////////////////////////////\r
3066 \r
3067 /* public */\r
3068 Clazz.innerFunctionNames = Clazz.innerFunctionNames.concat ([\r
3069     "getSuperclass", "isAssignableFrom", \r
3070     "getConstructor", \r
3071     "getDeclaredMethod", "getDeclaredMethods",\r
3072     "getMethod", "getMethods",   \r
3073                 "getModifiers", /*"isArray",*/ "newInstance"]);\r
3074 \r
3075 /* public */\r
3076 Clazz._innerFunctions.getSuperclass = function () {\r
3077         return this.superClazz; \r
3078 };\r
3079 \r
3080 /* public */\r
3081 Clazz._innerFunctions.isAssignableFrom = function (clazz) {\r
3082         return Clazz.getInheritedLevel (clazz, this) >= 0;      \r
3083 };\r
3084 \r
3085 /* public */\r
3086 Clazz._innerFunctions.getConstructor = function () {\r
3087         return new java.lang.reflect.Constructor (this, [], [], \r
3088                         java.lang.reflect.Modifier.PUBLIC);\r
3089 };\r
3090 /**\r
3091  * TODO: fix bug for polymorphic methods!\r
3092  */\r
3093 /* public */\r
3094 Clazz._innerFunctions.getDeclaredMethods = Clazz._innerFunctions.getMethods = function () {\r
3095         var ms = [];\r
3096         var p = this.prototype;\r
3097         for (var attr in p) {\r
3098                 if (typeof p[attr] == "function" && !p[attr].__CLASS_NAME__) {\r
3099                         /* there are polynormical methods. */\r
3100                         ms.push(new java.lang.reflect.Method (this, attr,\r
3101                                         [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC));\r
3102                 }\r
3103         }\r
3104         p = this;\r
3105         for (var attr in p) {\r
3106                 if (typeof p[attr] == "function" && !p[attr].__CLASS_NAME__) {\r
3107                         ms.push(new java.lang.reflect.Method (this, attr,\r
3108                                         [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC\r
3109                                         | java.lang.reflect.Modifier.STATIC));\r
3110                 }\r
3111         }\r
3112         return ms;\r
3113 };\r
3114 /* public */\r
3115 Clazz._innerFunctions.getDeclaredMethod = Clazz._innerFunctions.getMethod = function (name, clazzes) {\r
3116         var p = this.prototype;\r
3117         for (var attr in p) {\r
3118                 if (name == attr && typeof p[attr] == "function" \r
3119                                 && !p[attr].__CLASS_NAME__) {\r
3120                         /* there are polynormical methods. */\r
3121                         return new java.lang.reflect.Method (this, attr,\r
3122                                         [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC);\r
3123                 }\r
3124         }\r
3125         p = this;\r
3126         for (var attr in p) {\r
3127                 if (name == attr && typeof p[attr] == "function" \r
3128                                 && !p[attr].__CLASS_NAME__) {\r
3129                         return new java.lang.reflect.Method (this, attr,\r
3130                                         [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC\r
3131                                         | java.lang.reflect.Modifier.STATIC);\r
3132                 }\r
3133         }\r
3134         return null;\r
3135 };\r
3136 /* public */\r
3137 Clazz._innerFunctions.getModifiers = function () {\r
3138         return java.lang.reflect.Modifier.PUBLIC;\r
3139 };\r
3140 \r
3141 Clazz._innerFunctions.newInstance = function (a) {\r
3142         var clz = this;\r
3143   switch(a == null ? 0 : a.length) {\r
3144   case 0:\r
3145     return new clz();\r
3146   case 1:\r
3147         return new clz(a[0]);\r
3148   case 2:\r
3149         return new clz(a[0], a[1]);\r
3150   case 3:\r
3151         return new clz(a[0], a[1], a[2]);\r
3152   case 4:\r
3153         return new clz(a[0], a[1], a[2], a[3]);\r
3154   default:\r
3155     var x = "new " + clz.__CLASS_NAME__ + "(";\r
3156     for (var i = 0; i < a.length; i++)\r
3157      x += (i == 0 ? "" : ",") + "a[" + i + "]";\r
3158     x += ")";\r
3159     return eval(x);\r
3160   }\r
3161 };\r
3162 \r
3163 //Object.newInstance = Clazz._innerFunctions.newInstance;\r
3164 ;(function(){  // BH added wrapper here\r
3165         var inF = Clazz.innerFunctionNames;\r
3166         for (var i = 0; i < inF.length; i++) {\r
3167                 Clazz._O[inF[i]] = Clazz._innerFunctions[inF[i]];\r
3168                 Array[inF[i]] = Clazz._innerFunctions[inF[i]];\r
3169         }\r
3170         //Array["isArray"] = function () {\r
3171         //      return true;\r
3172         //};\r
3173 })();\r
3174 \r
3175 //////////////////////////// hotspot and unloading /////////////////////////////\r
3176 /* For hotspot and unloading */\r
3177 \r
3178 if (window["Clazz"] && !window["Clazz"].unloadClass) {\r
3179 \r
3180 /* public */\r
3181 Clazz.unloadClass = function (qClazzName) {\r
3182         var cc = Clazz.evalType (qClazzName);\r
3183         if (cc) {\r
3184                 Clazz.unloadedClasses[qClazzName] = cc;\r
3185                 var clazzName = qClazzName;\r
3186                 var pkgFrags = clazzName.split (/\./);\r
3187                 var pkg = null;\r
3188                 for (var i = 0; i < pkgFrags.length - 1; i++)\r
3189                         pkg = (pkg ? pkg[pkgFrags[i]] : Clazz.allPackage[pkgFrags[0]]);\r
3190                 if (!pkg) {\r
3191                         Clazz.allPackage[pkgFrags[0]] = null;\r
3192                         window[pkgFrags[0]] = null;\r
3193                         // also try to unload inner or anonymous classes\r
3194                         for (var c in window) {\r
3195                                 if (c.indexOf (qClazzName + "$") == 0) {\r
3196                                         Clazz.unloadClass (c);\r
3197                                         window[c] = null;\r
3198                                 }\r
3199                         }\r
3200                 } else {\r
3201                         pkg[pkgFrags[pkgFrags.length - 1]] = null;\r
3202                         // also try to unload inner or anonymous classes\r
3203                         for (var c in pkg) {\r
3204                                 if (c.indexOf (pkgFrags[pkgFrags.length - 1] + "$") == 0) {\r
3205                                         Clazz.unloadClass (pkg.__PKG_NAME__ + "." + c);\r
3206                                         pkg[c] = null;\r
3207                                 }\r
3208                         }\r
3209                 }\r
3210 \r
3211                 if (Clazz.allClasses[qClazzName]) {\r
3212                         Clazz.allClasses[qClazzName] = false;\r
3213                         // also try to unload inner or anonymous classes\r
3214                         for (var c in Clazz.allClasses) {\r
3215                                 if (c.indexOf (qClazzName + "$") == 0) {\r
3216                                         Clazz.allClasses[c] = false;\r
3217                                 }\r
3218                         }\r
3219                 }\r
3220 \r
3221                 for (var m in cc) {\r
3222                         cleanDelegateMethod (cc[m]);\r
3223                 }\r
3224                 for (var m in cc.prototype) {\r
3225                         cleanDelegateMethod (cc.prototype[m]);\r
3226                 }\r
3227 \r
3228                 if (Clazz._Loader) {\r
3229                         Clazz._Loader.unloadClassExt(qClazzName);\r
3230                 }\r
3231 \r
3232                 return true;\r
3233         }\r
3234         return false;\r
3235 };\r
3236 \r
3237 /* private */\r
3238 var cleanDelegateMethod = function (m) {\r
3239         if (!m) \r
3240                 return;\r
3241         if (typeof m == "function" && m.lastMethod\r
3242                         && m.lastParams && m.lastClaxxRef) {\r
3243                 m.lastMethod = null;\r
3244                 m.lastParams = null;\r
3245                 m.lastClaxxRef = null;\r
3246         }\r
3247 };\r
3248 \r
3249 } // if (window["Clazz"] && !window["Clazz"].unloadClass)\r
3250 \r
3251 /******************************************************************************\r
3252  * Copyright (c) 2007 java2script.org and others.\r
3253  * All rights reserved. This program and the accompanying materials\r
3254  * are made available under the terms of the Eclipse Public License v1.0\r
3255  * which accompanies this distribution, and is available at\r
3256  * http://www.eclipse.org/legal/epl-v10.html\r
3257  *\r
3258  * Contributors:\r
3259  *     Zhou Renjian - initial API and implementation\r
3260  *****************************************************************************/\r
3261 /*******\r
3262  * @author zhou renjian\r
3263  * @create July 10, 2006\r
3264  *******/\r
3265 \r
3266 //if (window["ClazzNode"] == null) {\r
3267 /**\r
3268  * TODO:\r
3269  * Make optimization over class dependency tree.\r
3270  */\r
3271 \r
3272 /*\r
3273  * ClassLoader Summary\r
3274  * \r
3275  * ClassLoader creates SCRIPT elements and setup class path and onload \r
3276  * callback to continue class loading.\r
3277  *\r
3278  * In the onload callbacks, _Loader will try to calculate the next-to-be-\r
3279  * load *.js and load it. In *.js, it will contains some codes like\r
3280  * Clazz.load (..., "$wt.widgets.Control", ...);\r
3281  * to provide information to build up the class dependency tree.\r
3282  *\r
3283  * Some known problems of different browsers:\r
3284  * 1. In IE, loading *.js through SCRIPT will first triggers onreadstatechange \r
3285  * event, and then executes inner *.js source.\r
3286  * 2. In Firefox, loading *.js will first executes *.js source and then \r
3287  * triggers onload event.\r
3288  * 3. In Opera, similar to IE, but trigger onload event. (TODO: More details \r
3289  * should be studied. Currently, Opera supports no multiple-thread-loading)\r
3290  * \r
3291  * For class dependency tree, actually, it is not a tree. It is a reference\r
3292  * net with nodes have n parents and n children. There is a root, which \r
3293  * ClassLoader knows where to start searching and loading classes, for such\r
3294  * a net. Each node is a class. Each class may require a set of must-classes, \r
3295  * which must be loaded before itself getting initialized, and also need a set\r
3296  * of optional classes, which also be loaded before being called.\r
3297  *\r
3298  * The class loading status will be in 6 stages.\r
3299  * 1. Unknown, the class is newly introduced by other class.\r
3300  * 2. Known, the class is already mentioned by other class.\r
3301  * 3. Loaded, *.js source is in memory, but may not be initialized yet. It \r
3302  * requires all its must-classes be intiailized, which is in the next stage.\r
3303  * 4. Musts loaded, all must classes is already loaded and declared.\r
3304  * 5. Delcared, the class is already declared (_Loader#isClassDefined).\r
3305  * 6. Optionals loaded, all optional classes is loaded and declared.\r
3306  *\r
3307  * The ClassLoader tries to load all necessary classes in order, and intialize\r
3308  * them in order. For such job, it will traverse the dependency tree, and try \r
3309  * to next class to-be-loaded. Sometime, the class dependencies may be in one\r
3310  * or more cycles, which must be broken down so classes is loaded in correct\r
3311  * order.\r
3312  *\r
3313  * Loading order and intializing order is very important for the ClassLoader.\r
3314  * The following technical options are considered:\r
3315  * 1. SCRIPT is loading asynchronously, which means controling order must use\r
3316  * callback methods to continue.\r
3317  * 2. Multiple loading threads are later introduced, which requires the \r
3318  * ClassLoader should use variables to record the class status.\r
3319  * 3. Different browsers have different loading orders, which means extra tests\r
3320  * should be tested to make sure loading order won't be broken.\r
3321  * 4. Java2Script simulator itself have some loading orders that must be \r
3322  * honored, which means it should be integrated seamlessly to Clazz system.\r
3323  * 5. Packed *.z.js is introduced to avoid lots of small *.js which requires \r
3324  * lots of HTTP connections, which means that packed *.z.js should be treated\r
3325  * specially (There will be mappings for such packed classes).\r
3326  * 6. *.js or *.css loading may fail according to network status, which means\r
3327  * another loading try should be performed, so _Loader is more robust.\r
3328  * 7. SWT lazy loading is later introduced, which means that class loading\r
3329  * process may be paused and should be resumed later.\r
3330  *\r
3331  * Some known bugs:\r
3332  * <code>$_L(["$wt.graphics.Drawable","$wt.widgets.Widget"],\r
3333  *  "$wt.widgets.Control", ...</code>\r
3334  * has errors while must classes in different order such as\r
3335  * <code>$_L(["$wt.widgets.Widget", "$wt.graphics.Drawable"],\r
3336  *  "$wt.widgets.Control", ...</code>\r
3337  * has no error.\r
3338  * \r
3339  * Other maybe bug scenarios:\r
3340  * 1. In <code>_Loader.maxLoadingThreads = 1;</code> single loading thread \r
3341  * mode, there are no errors, but in default multiple thread loading mode, \r
3342  * there are errors.\r
3343  * 2. No errors in one browser, but has errors on other browsers (Browser \r
3344  * script loading order differences).\r
3345  * 3. First time loading has errors, but reloading it gets no errors (Maybe \r
3346  * HTTP connections timeout, but should not accur in local file system, or it\r
3347  * is a loading bug by using JavaScript timeout thread).\r
3348  */\r
3349 \r
3350 /*\r
3351  * The following comments with "#" are special configurations for a much\r
3352  * smaller *.js file size.\r
3353  *\r
3354  * @see net.sf.j2s.lib/src/net/sf/j2s/lib/build/SmartJSCompressor.java\r
3355  */\r
3356 /**\r
3357  * Static class loader class\r
3358  */\r
3359 Clazz._Loader = Clazz.ClazzLoader = function () {};\r
3360 \r
3361 /**\r
3362  * Class dependency tree node\r
3363  */\r
3364 /* private */\r
3365 var Node = function () {\r
3366         this.parents = [];\r
3367         this.musts = [];\r
3368         this.optionals = [];\r
3369         this.declaration = null;\r
3370         this.name = null; // id\r
3371         this.path = null;\r
3372 //      this.requires = null;\r
3373 //      this.requiresMap = null;\r
3374         this.onLoaded = null;\r
3375         this.status = 0;\r
3376         this.random = 0.13412;\r
3377 };\r
3378 \r
3379 \r
3380 ;(function(Clazz, _Loader) {\r
3381 \r
3382 _Loader._checkLoad = Jmol._checkLoad;\r
3383  \r
3384 _Loader.updateNodeForFunctionDecoration = function(qName) {\r
3385         var node = findNode(qName);\r
3386         if (node && node.status == Node.STATUS_KNOWN) {\r
3387                 window.setTimeout((function(nnn) {\r
3388                         return function() {\r
3389                                 updateNode(nnn);\r
3390                         };\r
3391                 })(node), 1);\r
3392         }\r
3393 }\r
3394 \r
3395 Node.prototype.toString = function() {\r
3396         return this.name || this.path || "ClazzNode";\r
3397 }\r
3398 \r
3399 Node.STATUS_UNKNOWN = 0;\r
3400 Node.STATUS_KNOWN = 1;\r
3401 Node.STATUS_CONTENT_LOADED = 2;\r
3402 Node.STATUS_MUSTS_LOADED = 3;\r
3403 Node.STATUS_DECLARED = 4;\r
3404 Node.STATUS_LOAD_COMPLETE = 5;\r
3405 \r
3406                                                  \r
3407 var loaders = [];\r
3408 \r
3409 /* public */\r
3410 _Loader.requireLoaderByBase = function (base) {\r
3411         for (var i = 0; i < loaders.length; i++) {\r
3412                 if (loaders[i].base == base) {\r
3413                         return loaders[i];\r
3414                 }\r
3415         }\r
3416         var loader = new _Loader ();\r
3417         loader.base = base; \r
3418         loaders.push(loader);\r
3419         return loader;\r
3420 };\r
3421 \r
3422 /**\r
3423  * Class dependency tree\r
3424  */\r
3425 var clazzTreeRoot = new Node();\r
3426 \r
3427 /**\r
3428  * Used to keep the status whether a given *.js path is loaded or not.\r
3429  */\r
3430 /* private */\r
3431 var loadedScripts = {};\r
3432 \r
3433 /**\r
3434  * Multiple threads are used to speed up *.js loading.\r
3435  */\r
3436 /* private */\r
3437 var inLoadingThreads = 0;\r
3438 \r
3439 /**\r
3440  * Maximum of loading threads\r
3441  */\r
3442 /* private */\r
3443 var maxLoadingThreads = 6;\r
3444 \r
3445 var userAgent = navigator.userAgent.toLowerCase ();\r
3446 var isOpera = (userAgent.indexOf ("opera") != -1);\r
3447 var isIE = (userAgent.indexOf ("msie") != -1) && !isOpera;\r
3448 var isGecko = (userAgent.indexOf ("gecko") != -1);\r
3449 \r
3450 /*\r
3451  * Opera has different loading order which will result in performance degrade!\r
3452  * So just return to single thread loading in Opera!\r
3453  *\r
3454  * FIXME: This different loading order also causes bugs in single thread!\r
3455  */\r
3456 if (isOpera) {\r
3457         maxLoadingThreads = 1;\r
3458         var index = userAgent.indexOf ("opera/");\r
3459         if (index != -1) {\r
3460                 var verNumber = 9.0;\r
3461                 try {\r
3462                         verNumber = parseFloat(userAgent.subString (index + 6));\r
3463                 } catch (e) {}\r
3464                 if (verNumber >= 9.6) {\r
3465                         maxLoadingThreads = 6;\r
3466                 }\r
3467         } \r
3468 }\r
3469 \r
3470 /**\r
3471  * Try to be compatiable with Clazz system.\r
3472  * In original design _Loader and Clazz are independent!\r
3473  *  -- zhourenjian @ December 23, 2006\r
3474  */\r
3475 var isClassdefined;\r
3476 var definedClasses;\r
3477 \r
3478 if (self.Clazz && Clazz.isClassDefined) {\r
3479         isClassDefined = Clazz.isClassDefined;\r
3480 } else {\r
3481         definedClasses = {};\r
3482         isClassDefined = function (clazzName) {\r
3483                 return definedClasses[clazzName] == true;\r
3484         };\r
3485 }\r
3486 \r
3487 /**\r
3488  * Expand the shortened list of class names.\r
3489  * For example:\r
3490  * JU.Log, $.Display, $.Decorations\r
3491  * will be expanded to \r
3492  * JU.Log, JU.Display, JU.Decorations\r
3493  * where "$." stands for the previous class name's package.\r
3494  *\r
3495  * This method will be used to unwrap the required/optional classes list and \r
3496  * the ignored classes list.\r
3497  */\r
3498 /* private */\r
3499 var unwrapArray = function (arr) {\r
3500         if (!arr || arr.length == 0)\r
3501                 return [];\r
3502         var last = null;\r
3503         for (var i = 0; i < arr.length; i++) {\r
3504                 if (!arr[i])\r
3505                         continue;\r
3506                 if (arr[i].charAt (0) == '$') {\r
3507                         if (arr[i].charAt (1) == '.') {\r
3508                                 if (!last)\r
3509                                         continue;\r
3510                                 var idx = last.lastIndexOf (".");\r
3511                                 if (idx != -1) {\r
3512                                         var prefix = last.substring (0, idx);\r
3513                                         arr[i] = prefix + arr[i].substring (1);\r
3514                                 }\r
3515                         } else {\r
3516                                 arr[i] = "org.eclipse.s" + arr[i].substring (1);\r
3517                         }\r
3518                 }\r
3519                 last = arr[i];\r
3520         }\r
3521         return arr;\r
3522 };\r
3523 \r
3524 /**\r
3525  * Used to keep to-be-loaded classes.\r
3526  */\r
3527 /* private */\r
3528 var classQueue = [];\r
3529 \r
3530 /* private */\r
3531 var classpathMap = {};\r
3532 \r
3533 /* private */\r
3534 var pkgRefCount = 0;\r
3535 \r
3536 /* public */\r
3537 _Loader.loadPackageClasspath = function (pkg, base, isIndex, fSuccess, mode, pt) {\r
3538         var map = classpathMap;\r
3539         mode || (mode = 0);\r
3540         fSuccess || (fSuccess = null);\r
3541         pt || (pt = 0);\r
3542 \r
3543         /*\r
3544          * In some situation, maybe,\r
3545          * _Loader.packageClasspath ("java", ..., true);\r
3546          * is called after other _Loader#packageClasspath, e.g.\r
3547          * <code>\r
3548          * _Loader.packageClasspath ("org.eclipse.swt", "...", true);\r
3549          * _Loader.packageClasspath ("java", "...", true);\r
3550          * </code>\r
3551          * which is not recommended. But _Loader should try to adjust orders\r
3552          * which requires "java" to be declared before normal _Loader\r
3553          * #packageClasspath call before that line! And later that line\r
3554          * should never initialize "java/package.js" again!\r
3555          */\r
3556         var isPkgDeclared = (isIndex && map["@" + pkg]);\r
3557         if (mode == 0 && isIndex && !map["@java"] && pkg.indexOf ("java") != 0 && needPackage("java")) {\r
3558                 _Loader.loadPackage("java", fSuccess ? function(_package){_Loader.loadPackageClasspath(pkg, base, isIndex, fSuccess, 1)} : null);\r
3559                 if (fSuccess)\r
3560                         return;\r
3561         }\r
3562         if (pkg instanceof Array) {\r
3563                 unwrapArray(pkg);\r
3564                 if (fSuccess) {\r
3565                         if (pt < pkg.length)\r
3566                                 _Loader.loadPackageClasspath(pkg[pt], base, isIndex, function(_loadPackageClassPath){_Loader.loadPackageClasspath(pkg, base, isIndex, fSuccess, 1, pt + 1)}, 1);\r
3567                         else\r
3568                                 fSuccess();\r
3569                 } else {\r
3570                         for (var i = 0; i < pkg.length; i++)\r
3571                                 _Loader.loadPackageClasspath(pkg[i], base, isIndex, null);\r
3572                 }\r
3573                 return;\r
3574         }\r
3575         switch (pkg) {\r
3576         case "java.*":\r
3577                 pkg = "java";\r
3578                 // fall through\r
3579         case "java":\r
3580                 if (base) {\r
3581                         // support ajax for default\r
3582                         var key = "@net.sf.j2s.ajax";\r
3583                         if (!map[key])\r
3584                                 map[key] = base;\r
3585                         key = "@net.sf.j2s";\r
3586                         if (!map[key])\r
3587                                 map[key] = base;\r
3588                 }               \r
3589                 break;\r
3590         case "swt":\r
3591                 pkg = "org.eclipse.swt";\r
3592                 break;\r
3593         case "ajax":\r
3594                 pkg = "net.sf.j2s.ajax";\r
3595                 break;\r
3596         case "j2s":\r
3597                 pkg = "net.sf.j2s";\r
3598                 break;\r
3599         default:\r
3600                 if (pkg.lastIndexOf(".*") == pkg.length - 2)\r
3601                         pkg = pkg.substring(0, pkg.length - 2);\r
3602                 break;\r
3603         }\r
3604         if (base) // critical for multiple applets\r
3605                 map["@" + pkg] = base;\r
3606         if (isIndex && !isPkgDeclared && !window[pkg + ".registered"]) {\r
3607                 pkgRefCount++;\r
3608                 if (pkg == "java")\r
3609                         pkg = "core" // JSmol -- moves java/package.js to core/package.js\r
3610                 _Loader.loadClass(pkg + ".package", function () {\r
3611                                         if (--pkgRefCount == 0)\r
3612                                                 runtimeLoaded();\r
3613                                         //fSuccess && fSuccess();\r
3614                                 }, true, true, 1);\r
3615                 return;\r
3616         }\r
3617         fSuccess && fSuccess();\r
3618 };\r
3619 \r
3620 /**\r
3621  * BH: allows user/developer to load classes even though wrapping and Google\r
3622  * Closure Compiler has not been run on the class.\r
3623  *   \r
3624  */\r
3625 Clazz.loadClass = function (name, onLoaded, async) {\r
3626   if (!self.Class) {\r
3627     Class = Clazz;\r
3628     Class.forName = Clazz._4Name;\r
3629     JavaObject = Clazz._O;\r
3630     // maybe more here\r
3631   }\r
3632   return (name && _Loader.loadClass(name, onLoaded, true, async, 1));\r
3633 }\r
3634 \r
3635 /**\r
3636  * Load the given class ant its related classes.\r
3637  */\r
3638 /* public */\r
3639 _Loader.loadClass = function (name, onLoaded, forced, async, mode) {\r
3640 \r
3641   mode || (mode = 0); // BH: not implemented\r
3642   (async == null) && (async = false);\r
3643   \r
3644         if (typeof onLoaded == "boolean")\r
3645                 return Clazz.evalType(name);\r
3646 \r
3647   System.out.println("loadClass " + name)\r
3648 \r
3649         // Make sure that packageClasspath ("java", base, true); \r
3650         // is called before any _Loader#loadClass is called.\r
3651 \r
3652         if (needPackage("java"))\r
3653                 _Loader.loadPackage("java");\r
3654         if (needPackage("core"))\r
3655                 _Loader.loadPackage("core");    \r
3656 \r
3657 //      var swtPkg = "org.eclipse.swt";\r
3658 //      if (name.indexOf (swtPkg) == 0 || name.indexOf ("$wt") == 0) {\r
3659 //              _Loader.assurePackageClasspath (swtPkg);\r
3660 //      }\r
3661 //      if (name.indexOf ("junit") == 0) {\r
3662 //              _Loader.assurePackageClasspath ("junit");\r
3663 //      }\r
3664 \r
3665         // Any _Loader#loadClass calls will be queued until java.* core classes are loaded.\r
3666 \r
3667         _Loader.keepOnLoading = true;\r
3668         \r
3669         if (!forced && (pkgRefCount && name.lastIndexOf(".package") != name.length - 8\r
3670                         || name.indexOf("java.") != 0 && !isClassDefined(runtimeKeyClass)\r
3671                  )) {   \r
3672                 queueBe4KeyClazz.push([name, onLoaded]);\r
3673     \r
3674     \r
3675   System.out.println("loadclass-queuing" + name+ runtimeKeyClass + " "+ isClassDefined(runtimeKeyClass))\r
3676 \r
3677                 return;    \r
3678         }\r
3679         var b;\r
3680         if ((b = isClassDefined(name)) || isClassExcluded(name)) {\r
3681                 if (b && onLoaded) {\r
3682                         var nn = findNode(name);\r
3683                         if (!nn || nn.status >= Node.STATUS_LOAD_COMPLETE) {\r
3684                                 if (async) {\r
3685                                         window.setTimeout(onLoaded, 25);\r
3686                                 } else {\r
3687                                         onLoaded();\r
3688                                 }\r
3689                         }\r
3690                 }\r
3691                 return;\r
3692         }\r
3693         var path = _Loader.getClasspathFor(name);\r
3694   var existed = loadedScripts[path];\r
3695         var qq = classQueue;\r
3696         if (!existed)\r
3697                 for (var i = qq.length; --i >= 0;)\r
3698                         if (qq[i].path == path || qq[i].name == name) {\r
3699                                 existed = true;\r
3700                                 break;\r
3701                         }\r
3702         if (existed) {\r
3703                 if (onLoaded) {\r
3704                         var n = findNode(name);\r
3705                         if (n) {\r
3706                                 if (!n.onLoaded) {\r
3707                                         n.onLoaded = onLoaded;\r
3708                                 } else if (onLoaded != n.onLoaded) {\r
3709                                         n.onLoaded = (function (nF, oF) { return function () { nF(); oF() };    }) (n.onLoaded, onLoaded);\r
3710                                 }\r
3711                         }\r
3712                 }\r
3713                 return;\r
3714         }\r
3715 \r
3716         var n = (Clazz.unloadedClasses[name] && findNode(name) || new Node());\r
3717         n.name = name;\r
3718         n.path = path;\r
3719         n.isPackage = (path.lastIndexOf("package.js") == path.length - 10);\r
3720         mappingPathNameNode(path, name, n);\r
3721         n.onLoaded = onLoaded;\r
3722         n.status = Node.STATUS_KNOWN;\r
3723         var needBeingQueued = false;\r
3724         for (var i = qq.length; --i >= 0;) {\r
3725                 if (qq[i].status != Node.STATUS_LOAD_COMPLETE) {\r
3726                         needBeingQueued = true;\r
3727                         break;\r
3728                 }\r
3729         }\r
3730         \r
3731         if (n.isPackage) {//forced\r
3732                 // push class to queue\r
3733                 var pt = qq.length;\r
3734                 for (; --pt >= 0;) {\r
3735                         if (qq[pt].isPackage) \r
3736                                 break;\r
3737                         qq[pt + 1] = qq[pt];\r
3738                 }\r
3739                 qq[++pt] = n;\r
3740         } else if (needBeingQueued) {\r
3741                 qq.push(n);\r
3742         }\r
3743         if (!needBeingQueued) { // can be loaded directly\r
3744                 var bSave = false;\r
3745                 if (onLoaded) { \r
3746                         bSave = isLoadingEntryClass;\r
3747                         isLoadingEntryClass = true;\r
3748                 }\r
3749     if (forced)onLoaded = null;\r
3750                 addChildClassNode(clazzTreeRoot, n, true);\r
3751                 loadScript(n, n.path, n.requiredBy, false, onLoaded ? function(_loadClass){ isLoadingEntryClass = bSave; onLoaded()}: null);\r
3752         }\r
3753 };\r
3754 \r
3755 /*\r
3756  * Check whether given package's classpath is setup or not.\r
3757  * Only "java" and "org.eclipse.swt" are accepted in argument.\r
3758  */\r
3759 /* private */\r
3760 var needPackage = function(pkg) {\r
3761   // note that false != null and true != null\r
3762         return (window[pkg + ".registered"] != null && !classpathMap["@" + pkg]);\r
3763 }\r
3764 \r
3765 /* private */\r
3766 _Loader.loadPackage = function(pkg, fSuccess) {\r
3767         fSuccess || (fSuccess = null);\r
3768         window[pkg + ".registered"] = false;\r
3769         _Loader.loadPackageClasspath(pkg, \r
3770                 (_Loader.J2SLibBase || (_Loader.J2SLibBase = (_Loader.getJ2SLibBase() || "j2s/"))), \r
3771                 true, fSuccess);\r
3772 };\r
3773 \r
3774 /**\r
3775  * Register classes to a given *.z.js path, so only a single *.z.js is loaded\r
3776  * for all those classes.\r
3777  */\r
3778 /* public */\r
3779 _Loader.jarClasspath = function (jar, clazzes) {\r
3780         if (!(clazzes instanceof Array))\r
3781                 clazzes = [classes];\r
3782         unwrapArray(clazzes);\r
3783         for (var i = clazzes.length; --i >= 0;)\r
3784                 classpathMap["#" + clazzes[i]] = jar;\r
3785         classpathMap["$" + jar] = clazzes;\r
3786 };\r
3787 \r
3788 /**\r
3789  * Usually be used in .../package.js. All given packages will be registered\r
3790  * to the same classpath of given prefix package.\r
3791  */\r
3792 /* public */\r
3793 _Loader.registerPackages = function (prefix, pkgs) {\r
3794         //_Loader.checkInteractive ();\r
3795         var base = _Loader.getClasspathFor (prefix + ".*", true);\r
3796         for (var i = 0; i < pkgs.length; i++) {\r
3797                 if (window["Clazz"]) {\r
3798                         Clazz.declarePackage (prefix + "." + pkgs[i]);\r
3799                 }\r
3800                 _Loader.loadPackageClasspath (prefix + "." + pkgs[i], base);\r
3801         }\r
3802 };\r
3803 \r
3804 /**\r
3805  * Using multiple sites to load *.js in multiple threads. Using multiple\r
3806  * sites may avoid 2 HTTP 1.1 connections recommendation limit.\r
3807  * Here is a default implementation for http://archive.java2script.org.\r
3808  * In site archive.java2script.org, there are 6 sites:\r
3809  * 1. http://archive.java2script.org or http://a.java2script.org\r
3810  * 2. http://erchive.java2script.org or http://e.java2script.org\r
3811  * 3. http://irchive.java2script.org or http://i.java2script.org\r
3812  * 4. http://orchive.java2script.org or http://o.java2script.org\r
3813  * 5. http://urchive.java2script.org or http://u.java2script.org\r
3814  * 6. http://yrchive.java2script.org or http://y.java2script.org\r
3815  */\r
3816 /* protected */\r
3817         /*\r
3818 _Loader.multipleSites = function (path) {\r
3819         var deltas = window["j2s.update.delta"];\r
3820         if (deltas && deltas instanceof Array && deltas.length >= 3) {\r
3821                 var lastOldVersion = null;\r
3822                 var lastNewVersion = null;\r
3823                 for (var i = 0; i < deltas.length / 3; i++) {\r
3824                         var oldVersion = deltas[i + i + i];\r
3825                         if (oldVersion != "$") {\r
3826                                 lastOldVersion = oldVersion;\r
3827                         }\r
3828                         var newVersion = deltas[i + i + i + 1];\r
3829                         if (newVersion != "$") {\r
3830                                 lastNewVersion = newVersion;\r
3831                         }\r
3832                         var relativePath = deltas[i + i + i + 2];\r
3833                         var key = lastOldVersion + "/" + relativePath;\r
3834                         var idx = path.indexOf (key);\r
3835                         if (idx != -1 && idx == path.length - key.length) {\r
3836                                 path = path.substring (0, idx) + lastNewVersion + "/" + relativePath;\r
3837                                 break;\r
3838                         }\r
3839                 }\r
3840         }\r
3841         var length = path.length;\r
3842         if (maxLoadingThreads > 1 \r
3843                         && ((length > 15 && path.substring (0, 15) == "http://archive.")\r
3844                         || (length > 9 && path.substring (0, 9) == "http://a."))) {\r
3845                 var index = path.lastIndexOf("/");\r
3846                 if (index < length - 3) {\r
3847                         var arr = ['a', 'e', 'i', 'o', 'u', 'y'];\r
3848                         var c1 = path.charCodeAt (index + 1);\r
3849                         var c2 = path.charCodeAt (index + 2);\r
3850                         var idx = (length - index) * 3 + c1 * 5 + c2 * 7; // Hash\r
3851                         return path.substring (0, 7) + arr[idx % 6] + path.substring (8);\r
3852                 }\r
3853         }\r
3854         return path;\r
3855 };\r
3856         */\r
3857 \r
3858 /**\r
3859  * Return the *.js path of the given class. Maybe the class is contained\r
3860  * in a *.z.js jar file.\r
3861  * @param clazz Given class that the path is to be calculated for. May\r
3862  * be java.package, or java.lang.String\r
3863  * @param forRoot Optional argument, if true, the return path will be root\r
3864  * of the given classs' package root path.\r
3865  * @param ext Optional argument, if given, it will replace the default ".js"\r
3866  * extension.\r
3867  */\r
3868 /* public */\r
3869 _Loader.getClasspathFor = function (clazz, forRoot, ext) {\r
3870         var path = classpathMap["#" + clazz];\r
3871         if (!path || forRoot || ext) {\r
3872                 var base;\r
3873                 var idx;\r
3874                 if (path) {\r
3875                         clazz = clazz.replace(/\./g, "/");      \r
3876                         if ((idx = path.lastIndexOf(clazz)) >= 0 \r
3877                                 || (idx = clazz.lastIndexOf("/")) >= 0 \r
3878                                         && (idx = path.lastIndexOf(clazz.substring(0, idx))) >= 0)\r
3879                                 base = path.substring(0, idx);\r
3880                 } else {\r
3881                         idx = clazz.length + 2;\r
3882                         while ((idx = clazz.lastIndexOf(".", idx - 2)) >= 0)\r
3883                                 if ((base = classpathMap["@" + clazz.substring(0, idx)]))\r
3884                                         break;\r
3885                         if (!forRoot)\r
3886                                 clazz = clazz.replace (/\./g, "/");     \r
3887                 }\r
3888                 if (base == null) {\r
3889                         var bins = "binaryFolders";\r
3890                         base = (window["Clazz"] && Clazz[bins] && Clazz[bins].length ? Clazz[bins][0] \r
3891                                 : _Loader[bins] && _Loader[bins].length ? _Loader[bins][0]\r
3892                                 : "j2s");\r
3893                 }\r
3894                 path = (base.lastIndexOf("/") == base.length - 1 ? base : base + "/") + (forRoot ? ""\r
3895                         : clazz.lastIndexOf("/*") == clazz.length - 2 ? clazz.substring(0, idx + 1)\r
3896                         : clazz + (!ext ? ".js" : ext.charAt(0) != '.' ? "." + ext : ext));\r
3897         }               \r
3898         return path;//_Loader.multipleSites(path);\r
3899 };\r
3900 \r
3901 /**\r
3902  * To ignore some classes.\r
3903  */\r
3904 /* public */\r
3905 _Loader.ignore = function () {\r
3906         var clazzes = (arguments.length == 1 && arguments[0] instanceof Array ?\r
3907                         clazzes = arguments[0] : null);\r
3908         var n = (clazzes ? clazzes.length : arguments.length);\r
3909         if (!clazzes) {\r
3910                 clazzes = new Array(n);\r
3911                 for (var i = 0; i < n; i++)\r
3912                         clazzes[i] = arguments[i];\r
3913         }\r
3914         unwrapArray(clazzes);\r
3915         for (var i = 0; i < n; i++)\r
3916                 excludeClassMap["@" + clazzes[i]] = 1;\r
3917 };\r
3918 \r
3919 /**\r
3920  * The following *.script* can be overriden to indicate the \r
3921  * status of classes loading.\r
3922  *\r
3923  * TODO: There should be a Java interface with name like INativeLoaderStatus\r
3924  */\r
3925 /* public */\r
3926 _Loader.onScriptLoading = function (file){};\r
3927 \r
3928 /* public */\r
3929 _Loader.onScriptLoaded = function (file, isError){};\r
3930 \r
3931 /* public */\r
3932 _Loader.onScriptInitialized = function (file){};\r
3933 \r
3934 /* public */\r
3935 _Loader.onScriptCompleted = function (file){};\r
3936 \r
3937 /* public */\r
3938 _Loader.onClassUnloaded = function (clazz){};\r
3939 \r
3940 /**\r
3941  * After all the classes are loaded, this method will be called.\r
3942  * Should be overriden to run *.main([]).\r
3943  */\r
3944 /* public */\r
3945 _Loader.onGlobalLoaded = function () {};\r
3946 \r
3947 /* public */\r
3948 _Loader.keepOnLoading = true; // never set false in this code\r
3949 \r
3950 \r
3951 /* private */\r
3952 var mapPath2ClassNode = {};\r
3953 \r
3954 /* private */\r
3955 var isClassExcluded = function (clazz) {\r
3956         return excludeClassMap["@" + clazz];\r
3957 };\r
3958 \r
3959 /* Used to keep ignored classes */\r
3960 /* private */\r
3961 var excludeClassMap = {};\r
3962 \r
3963 /* private */\r
3964 var evaluate = function(file, file0, js) {\r
3965                 try {\r
3966                         eval(js + ";//# sourceURL="+file);\r
3967                 } catch (e) {      \r
3968       if (Clazz._isQuiet) \r
3969         return;\r
3970                         var s = "[Java2Script] The required class file \n\n" + file + (js.indexOf("[Exception") == 0 && js.indexOf("data: no") ? \r
3971          "\nwas not found.\n"\r
3972         : "\ncould not be loaded. Script error: " + e.message + " \n\ndata:\n\n" + js) + "\n\n" + Clazz.getStackTrace();\r
3973                 alert(s)\r
3974                         Clazz.alert(s);\r
3975                         throw e;\r
3976                 }\r
3977                 _Loader.onScriptLoaded(file, false);\r
3978                 tryToLoadNext(file0);\r
3979 }\r
3980 \r
3981 /* private */\r
3982 var failedHandles = {};\r
3983 \r
3984 /* private */\r
3985 var generateRemovingFunction = function (node) {\r
3986         return function () {\r
3987                 if (node.readyState != "interactive") {\r
3988                         try {\r
3989                                 if (node.parentNode)\r
3990                                         node.parentNode.removeChild (node);\r
3991                         } catch (e) { }\r
3992                         node = null;\r
3993                 }\r
3994         };\r
3995 };\r
3996 \r
3997 /* private */\r
3998 var removeScriptNode = function (n) {\r
3999         if (window["j2s.script.debugging"]) {\r
4000                 return;\r
4001         }\r
4002         // lazily remove script nodes.\r
4003         window.setTimeout (generateRemovingFunction (n), 1);\r
4004 };\r
4005 \r
4006 /* public */\r
4007 Clazz._4Name = function(clazzName, applet, state) {\r
4008         if (Clazz.isClassDefined(clazzName))\r
4009                 return Clazz.evalType(clazzName);\r
4010         var f = (Jmol._isAsync && applet ? applet._restoreState(clazzName, state) : null);\r
4011         if (f == 1)\r
4012                 return null; // must be already being created\r
4013         if (_Loader.setLoadingMode(f ? _Loader.MODE_SCRIPT : "xhr.sync")) {\r
4014                 _Loader.loadClass(clazzName, f, false, true, 1);\r
4015                 return null; // this will surely throw an error, but that is OK\r
4016         }\r
4017         //alert ("Using Java reflection: " + clazzName + " for " + applet._id + " \n"+ Clazz.getStackTrace());\r
4018         _Loader.loadClass(clazzName);\r
4019         return Clazz.evalType(clazzName);\r
4020 };\r
4021 \r
4022 /**\r
4023  * BH: possibly useful for debugging\r
4024  */ \r
4025 Clazz.currentPath= "";\r
4026 \r
4027 /**\r
4028  * Load *.js by adding script elements into head. Hook the onload event to\r
4029  * load the next class in dependency tree.\r
4030  */\r
4031 /* private */\r
4032 var loadScript = function (node, file, why, ignoreOnload, fSuccess, _loadScript) {\r
4033 \r
4034         Clazz.currentPath = file;\r
4035         if (ignoreOnload)alert("WHY>>")\r
4036 //BH removed    // maybe some scripts are to be loaded without needs to know onload event.\r
4037 //      if (!ignoreOnload && loadedScripts[file]) {\r
4038 //              _Loader.tryToLoadNext(file);\r
4039 //              return;\r
4040 //      }\r
4041         loadedScripts[file] = true;\r
4042         // also remove from queue\r
4043         removeArrayItem(classQueue, file);\r
4044 \r
4045     // forces not-found message\r
4046     isUsingXMLHttpRequest = true;\r
4047     isAsynchronousLoading = false;\r
4048   if (_Loader._checkLoad) {\r
4049     System.out.println("\t" + file + (why ? "\n -- required by " + why : "") + "  ajax=" + isUsingXMLHttpRequest + " async=" + isAsynchronousLoading)\r
4050   }\r
4051 \r
4052   var file0 = file;\r
4053   if (Clazz._debugging) {\r
4054     file = file.replace(/\.z\.js/,".js");\r
4055   }\r
4056 \r
4057         _Loader.onScriptLoading(file);\r
4058         if (isUsingXMLHttpRequest && !isAsynchronousLoading) {\r
4059                 // alert("\t" + file + (why ? "\n -- required by " + why : "") + "  ajax=" + isUsingXMLHttpRequest + " async=" + isAsynchronousLoading + " " + Clazz.getStackTrace())\r
4060                 // synchronous loading\r
4061                 // works in MSIE locally unless a binary file :)\r
4062                 // from Jmol.api.Interface only\r
4063                 var data = Jmol._getFileData(file);\r
4064     try{\r
4065                   evaluate(file, file0, data);\r
4066     }catch(e) {\r
4067       alert(e + " loading file " + file + " " + node.name + " " + Clazz.getStackTrace());\r
4068     }\r
4069     if (fSuccess) {\r
4070 //      System.out.println("firing in loadScript " + file + " " + (fSuccess && fSuccess.toString()))\r
4071       fSuccess(); \r
4072     }\r
4073                 return;\r
4074         }\r
4075   \r
4076   \r
4077 System.out.println("for file " + file +" fSuccess = " + (fSuccess ? fSuccess.toString() : ""))\r
4078         var info = {\r
4079                 dataType:"script",\r
4080                 async:true, \r
4081                 type:"GET", \r
4082                 url:file,\r
4083                 success:W3CScriptOnCallback(file, false, fSuccess),\r
4084                 error:W3CScriptOnCallback(file, true, fSuccess)\r
4085         };\r
4086         inLoadingThreads++;\r
4087         Jmol.$ajax(info);\r
4088 };\r
4089 \r
4090 /* private */\r
4091 var W3CScriptOnCallback = function (path, forError, fSuccess) {\r
4092   var s = Clazz.getStackTrace();\r
4093   // if (!fSuccess)alert("why no fSuccess?" + s)\r
4094         return function () {\r
4095   //System.out.println("returning " + (fSuccess ? fSuccess.toString() : "no function ") + s) \r
4096                 if (forError && __debuggingBH)Clazz.alert ("############ forError=" + forError + " path=" + path + " ####" + (forError ? "NOT" : "") + "LOADED###");\r
4097                 if (isGecko && this.timeoutHandle)\r
4098                         window.clearTimeout(this.timeoutHandle), this.timeoutHandle = null;\r
4099                 if (inLoadingThreads > 0)\r
4100                         inLoadingThreads--;\r
4101                 //System.out.println("w3ccalback for " + path + " " + inLoadingThreads + " threads")\r
4102                 this.onload = null;\r
4103                 this.onerror = null;\r
4104                 if (forError) \r
4105                         alert ("There was a problem loading " + path);\r
4106                 _Loader.onScriptLoaded(path, true);\r
4107                 var node = this;                        \r
4108                 var f;\r
4109     if (fSuccess)\r
4110       f = function(_W3scriptFS){removeScriptNode(node);tryToLoadNext(path, fSuccess); };\r
4111     else\r
4112       f = function(_W3script){removeScriptNode(node);tryToLoadNext(path)};\r
4113                 if (loadingTimeLag >= 0)\r
4114                         window.setTimeout(function() { tryToLoadNext(path, f); }, loadingTimeLag);\r
4115                 else\r
4116                         tryToLoadNext(path, f);\r
4117         };\r
4118 };\r
4119 \r
4120 /* private */\r
4121 var isLoadingEntryClass = true;\r
4122 \r
4123 /* private */\r
4124 var besidesJavaPackage = false;\r
4125 \r
4126 /**\r
4127  * After class is loaded, this method will be executed to check whether there\r
4128  * are classes in the dependency tree that need to be loaded.\r
4129  */\r
4130 /* private */\r
4131 var tryToLoadNext = function (file, fSuccess) {\r
4132         var node = mapPath2ClassNode["@" + file];\r
4133         if (!node) // maybe class tree root\r
4134                 return;\r
4135         var n;\r
4136   // check for content loaded\r
4137         var clazzes = classpathMap["$" + file];\r
4138         if (clazzes) {\r
4139                 for (var i = 0; i < clazzes.length; i++) {\r
4140                         var name = clazzes[i];\r
4141                         if (name != node.name && (n = findNode(name))) {\r
4142                                 if (n.status < Node.STATUS_CONTENT_LOADED) {\r
4143                                         n.status = Node.STATUS_CONTENT_LOADED;\r
4144                                         updateNode(n);\r
4145                                 }\r
4146                         } else {\r
4147                                 n = new Node();\r
4148                                 n.name = name;\r
4149                                 var pp = classpathMap["#" + name];\r
4150                                 if (!pp) {\r
4151                                         alert (name + " J2S error in tryToLoadNext");\r
4152                                         error("Java2Script implementation error! Please report this bug!");\r
4153                                 }\r
4154                                 n.path = pp;\r
4155                                 mappingPathNameNode (n.path, name, n);\r
4156                                 n.status = Node.STATUS_CONTENT_LOADED;\r
4157                                 addChildClassNode(clazzTreeRoot, n, false);\r
4158                                 updateNode(n);\r
4159                         }\r
4160                 }\r
4161         }\r
4162         if (node instanceof Array) {\r
4163                 for (var i = 0; i < node.length; i++) {\r
4164                         if (node[i].status < Node.STATUS_CONTENT_LOADED) {\r
4165                                 node[i].status = Node.STATUS_CONTENT_LOADED;\r
4166                                 updateNode(node[i]);\r
4167                         }\r
4168                 }\r
4169         } else if (node.status < Node.STATUS_CONTENT_LOADED) {\r
4170                 var stillLoading = false;\r
4171                 var ss = document.getElementsByTagName ("SCRIPT");\r
4172                 for (var i = 0; i < ss.length; i++) {\r
4173                         if (isIE) {\r
4174                                 if (ss[i].onreadystatechange && ss[i].onreadystatechange.path == node.path\r
4175                                                 && ss[i].readyState == "interactive") {\r
4176                                         stillLoading = true;\r
4177                                         break;\r
4178                                 }\r
4179                         } else if (ss[i].onload && ss[i].onload.path == node.path) {\r
4180                                 stillLoading = true;\r
4181                                 break;\r
4182                         }\r
4183                 }\r
4184                 if (!stillLoading) {\r
4185                         node.status = Node.STATUS_CONTENT_LOADED;\r
4186                         updateNode(node);\r
4187                 }\r
4188         }\r
4189         /*\r
4190          * Maybe in #optinalLoaded inside above _Loader#updateNode calls, \r
4191          * _Loader.keepOnLoading is set false (Already loaded the wanted\r
4192          * classes), so here check to stop.\r
4193          */\r
4194          \r
4195         if (!_Loader.keepOnLoading) // set externally\r
4196                 return;\r
4197 \r
4198  // check for a "must" class that has content and load it\r
4199         var cq;\r
4200         var working = true;\r
4201         if ((n = findNextMustClass(Node.STATUS_KNOWN))) {\r
4202                 loadClassNode(n);\r
4203                 while (inLoadingThreads < maxLoadingThreads) {\r
4204                         if (!(n = findNextMustClass(Node.STATUS_KNOWN)))\r
4205                                 break;\r
4206                         loadClassNode(n); // will increase inLoadingThreads!\r
4207                 }\r
4208         } else if ((cq = classQueue).length != 0) { \r
4209                 /* queue must be loaded in order! */\r
4210                 n = cq.shift();\r
4211                 if (!loadedScripts[n.path] \r
4212                                 || cq.length != 0 \r
4213                                 || !isLoadingEntryClass\r
4214                                 || n.musts.length\r
4215                                 || n.optionals.length) {\r
4216                         addChildClassNode(clazzTreeRoot, n, true);\r
4217                         loadScript(n, n.path, n.requiredBy, false);\r
4218                 } else if (isLoadingEntryClass) {\r
4219                         /*\r
4220                          * The first time reaching here is the time when ClassLoader\r
4221                          * is trying to load entry class. Class with #main method and\r
4222                          * is to be executed is called Entry Class.\r
4223                          *\r
4224                          * Here when loading entry class, ClassLoader should not call\r
4225                          * the next following loading script. This is because, those\r
4226                          * scripts will try to mark the class as loaded directly and\r
4227                          * then continue to call #onLoaded callback method,\r
4228                          * which results in an script error!\r
4229                          */\r
4230                         isLoadingEntryClass = false;\r
4231                 }\r
4232         } else if ((n = findNextRequiredClass(Node.STATUS_KNOWN))) {\r
4233                 loadClassNode(n);\r
4234                 while (inLoadingThreads < maxLoadingThreads) {\r
4235                         if (!(n = findNextRequiredClass(Node.STATUS_KNOWN)))\r
4236                                 break;\r
4237                         loadClassNode(n); // will increase inLoadingThreads!\r
4238                 }\r
4239         } else {\r
4240                 working = false;\r
4241         }\r
4242         if (working || inLoadingThreads > 0)\r
4243                 return;\r
4244   // \r
4245   // now check all classes that MUST be loaded prior to initialization \r
4246   // of some other class (static calls, extends, implements)\r
4247   // and all classes REQUIRED somewhere in that class, possibly by the constructor\r
4248   // (that is, "new xxxx()" called somewhere in code) and update them\r
4249   // that have content but are not declared already \r
4250         var f = [findNextMustClass,findNextRequiredClass];\r
4251         var lastNode = null;\r
4252         for (var i = 0; i < 2; i++)\r
4253                 while ((n = f[i](Node.STATUS_CONTENT_LOADED))) {\r
4254                         if (i == 1 && lastNode === n) // Already existed cycle ?\r
4255                                 n.status = Node.STATUS_LOAD_COMPLETE;\r
4256                         updateNode(n);\r
4257                         lastNode = n;\r
4258                 }\r
4259     \r
4260   // check for load cycles\r
4261   \r
4262         while (true) {\r
4263                 tracks = [];\r
4264                 if (!checkCycle(clazzTreeRoot, file))\r
4265                         break;\r
4266         }\r
4267   \r
4268   // and update all MUST and REQUIRED classes that are declared already \r
4269   \r
4270         for (var i = 0; i < 2; i++) {\r
4271                 lastNode = null;\r
4272                 while ((n = f[i](Node.STATUS_DECLARED))) {\r
4273                         if (lastNode === n) \r
4274                                 break;\r
4275                         updateNode(lastNode = n);\r
4276                 }\r
4277         }\r
4278         var done = [];\r
4279         for (var i = 0; i < 2; i++) \r
4280                 while ((n = f[i](Node.STATUS_DECLARED)))\r
4281                         done.push(n), n.status = Node.STATUS_LOAD_COMPLETE;\r
4282         if (done.length) {\r
4283                 for (var i = 0; i < done.length; i++)\r
4284                         destroyClassNode(done[i]);\r
4285                 for (var i = 0; i < done.length; i++)\r
4286                         if ((f = done[i].onLoaded))\r
4287                                 done[i].onLoaded = null, f();\r
4288         }\r
4289   \r
4290   \r
4291   \r
4292   \r
4293   \r
4294   \r
4295   \r
4296         //System.out.println(node.name + " loaded completely" + _Loader.onGlobalLoaded + "\n\n")\r
4297   if (fSuccess) {\r
4298     //System.out.println("tryToLoadNext firing " + _Loader._classCountOK + "/" + _Loader._classCountPending + " "   + fSuccess.toString() + " " + Clazz.getStackTrace())\r
4299           fSuccess();\r
4300   } else if (_Loader._classCountPending) {\r
4301     for (var name in _Loader._classPending) {\r
4302       var n = findNode(name);\r
4303       System.out.println("class left pending " + name + " " + n);\r
4304       if (n) {\r
4305         updateNode(n);\r
4306         break;\r
4307       }\r
4308     }\r
4309   } else {\r
4310     \r
4311  // System.out.println("I think I'm done " \r
4312   // + _Loader._classCountOK + "/" + _Loader._classCountPending + " " \r
4313    //+ _Loader.onGlobalLoaded.toString() + " " + Clazz.getStackTrace()\r
4314  //  )\r
4315     if (_Loader._checkLoad) {\r
4316       System.out.println("I think I'm done: SAEM call count: " + SAEMid);\r
4317       Clazz.showDuplicates(true);\r
4318     }\r
4319   }\r
4320         _Loader.onGlobalLoaded();\r
4321 };\r
4322 \r
4323 \r
4324 var tracks = [];\r
4325 \r
4326 /*\r
4327  * There are classes reference cycles. Try to detect and break those cycles.\r
4328  */\r
4329 /* private */\r
4330 var checkCycle = function (node, file) {\r
4331         var ts = tracks;\r
4332         var len = ts.length;\r
4333   // add this node to tracks\r
4334         ts.push(node);\r
4335         var i = len;\r
4336         for (; --i >= 0;)\r
4337                 if (ts[i] === node && ts[i].status >= Node.STATUS_DECLARED) \r
4338                         break;\r
4339         if (i >= 0) {\r
4340     // this node is already in tracks, and it has been declared already\r
4341     // for each node in tracks, set its status to "LOAD_COMPLETE"\r
4342     // update all parents, remove all parents, and fire its onLoaded function\r
4343     // then clear tracks and return true (keep checking)  \r
4344     if (_Loader._checkLoad) {\r
4345       var msg = "cycle found loading " + file + " for " + node;\r
4346       System.out.println(msg)\r
4347     } \r
4348                 for (; i < len; i++) {\r
4349       var n = ts[i];\r
4350                         n.status = Node.STATUS_LOAD_COMPLETE;\r
4351                         destroyClassNode(n); // Same as above\r
4352                         for (var k = 0; k < n.parents.length; k++)\r
4353                                 updateNode(n.parents[k]);\r
4354                         n.parents = [];\r
4355       var f = n.onLoaded;\r
4356       if (_Loader._checkLoad) {\r
4357         var msg = "cycle setting status to LOAD_COMPLETE for " + n.name + (f ? " firing " + f.toString() : "");\r
4358         System.out.println(msg)\r
4359       } \r
4360                         if (f)\r
4361                                 n.onLoaded = null, f();\r
4362                 }\r
4363                 ts.length = 0;\r
4364                 return true;\r
4365         }\r
4366         var a = [node.musts, node.optionals];\r
4367         for (var j = 0; j < 2; j++)\r
4368                 for (var r = a[j], i = r.length; --i >= 0;)\r
4369                         if (r[i].status == Node.STATUS_DECLARED && checkCycle(r[i], file)) \r
4370                                 return true;\r
4371   // reset _tracks to its original length      \r
4372         ts.length = len;\r
4373         return false; // done \r
4374 };\r
4375 \r
4376 \r
4377 _Loader._classCountPending = 0;\r
4378 _Loader._classCountOK = 0;\r
4379 _Loader._classPending = {};\r
4380 \r
4381 _Loader.showPending = function() {\r
4382   var a = [];\r
4383   for (var name in _Loader._classPending) {\r
4384     var n = findNode(name);\r
4385     if (!n) {\r
4386       alert("No node for " + name);\r
4387       continue;\r
4388     }\r
4389     a.push(n);\r
4390     System.out.println(showNode("", "", n, "", 0));     \r
4391   }  \r
4392   return a;\r
4393 }\r
4394 \r
4395 var showNode = function(s, names, node, inset, level) {\r
4396   names += "--" + node.name;\r
4397   s += names + "\n";\r
4398   if (level > 5) {\r
4399     s += inset + " ...\n";\r
4400     return s;\r
4401   }\r
4402   inset += "\t";\r
4403   s += inset + "status: " + node.status + "\n";\r
4404   if (node.parents && node.parents.length && node.parents[0] && node.parents[0].name) {\r
4405     s += inset + "parents: " + node.parents.length + "\n";\r
4406     for (var i = 0; i < node.parents.length; i++) {\r
4407       s = showNode(s, names, node.parents[i], inset + "\t", level+1);\r
4408     }\r
4409     s += "\n";\r
4410   }\r
4411 //  if (node.requiredBy) {\r
4412 //    s += inset + "requiredBy:\n";\r
4413 //    s = showNode(s, names, node.requiredBy, inset + "\t", level+1);\r
4414 //    s += "\n";\r
4415 //  }\r
4416   return s;    \r
4417 }     \r
4418 \r
4419 /**\r
4420  * Update the dependency tree nodes recursively.\r
4421  */\r
4422 /* private */\r
4423 updateNode = function(node, _updateNode) {\r
4424         if (!node.name || node.status >= Node.STATUS_LOAD_COMPLETE) {\r
4425                 destroyClassNode(node);\r
4426                 return;\r
4427         }\r
4428         var ready = true;\r
4429   // check for declared and also having MUSTS\r
4430         if (node.musts.length && node.declaration) {\r
4431                 for (var mustLength = node.musts.length, i = mustLength; --i >= 0;) {\r
4432                         var n = node.musts[i];\r
4433                         n.requiredBy = node;\r
4434                         if (n.status < Node.STATUS_DECLARED && isClassDefined (n.name)) {\r
4435                                 var nns = []; // a stack for onLoaded events\r
4436                                 n.status = Node.STATUS_LOAD_COMPLETE;\r
4437                                 destroyClassNode(n); // Same as above\r
4438                                 if (n.declaration       && n.declaration.clazzList) {\r
4439                                         // For those classes within one *.js file, update them synchronously.\r
4440                                         for (var j = 0, list = n.declaration.clazzList, l = list.length; j < l; j++) {\r
4441                                                 var nn = findNode (list[j]);\r
4442                                                 if (nn && nn.status != Node.STATUS_LOAD_COMPLETE\r
4443                                                                 && nn !== n) {\r
4444                                                         nn.status = n.status;\r
4445                                                         nn.declaration = null;\r
4446                                                         destroyClassNode(nn);\r
4447                                                         nn.onLoaded && nns.push(nn);\r
4448                                                 }\r
4449                                         }\r
4450                                         n.declaration = null;\r
4451                                 }\r
4452         // fire all onLoaded events\r
4453                                 if (n.onLoaded)\r
4454                                         nns.push(n);\r
4455                                 for (var j = 0; j < nns.length; j++) {\r
4456                                         var onLoaded = nns[j].onLoaded;\r
4457                                         if (onLoaded) {\r
4458                                                 nns[j].onLoaded = null;\r
4459                                                 onLoaded();\r
4460                                         }\r
4461                                 }\r
4462                         } else {\r
4463                                 (n.status == Node.STATUS_CONTENT_LOADED) && updateNode(n); // musts may be changed\r
4464                                 if (n.status < Node.STATUS_DECLARED)\r
4465                                         ready = false;\r
4466                         }\r
4467                         if (node.musts.length != mustLength) {\r
4468                                 // length changed -- restart!\r
4469                                 i = mustLength = node.musts.length;\r
4470                                 ready = true;\r
4471                         }\r
4472                 }\r
4473         }\r
4474         if (!ready)\r
4475                 return;\r
4476         if (node.status < Node.STATUS_DECLARED) {\r
4477                 var decl = node.declaration;\r
4478                 if (decl)\r
4479                         decl(), decl.executed = true;\r
4480     if(_Loader._checkLoad) {\r
4481             if (_Loader._classPending[node.name]) {\r
4482               delete _Loader._classPending[node.name];\r
4483               _Loader._classCountOK;\r
4484               _Loader._classCountPending--;\r
4485 //              System.out.println("OK " + (_Loader._classCountOK) + " FOR " + node.name)\r
4486             }\r
4487     }\r
4488                 node.status = Node.STATUS_DECLARED;\r
4489                 if (definedClasses)\r
4490                         definedClasses[node.name] = true;\r
4491                 _Loader.onScriptInitialized(node.path);\r
4492                 if (node.declaration && node.declaration.clazzList) {\r
4493                         // For those classes within one *.js file, update them synchronously.\r
4494                         for (var j = 0, list = node.declaration.clazzList, l = list.length; j < l; j++) {\r
4495                                 var nn = findNode(list[j]);\r
4496                                 if (nn && nn.status != Node.STATUS_DECLARED\r
4497                                                 && nn !== node) {\r
4498                                         nn.status = Node.STATUS_DECLARED;\r
4499                                         if (definedClasses)\r
4500                                                 definedClasses[nn.name] = true;\r
4501                                         _Loader.onScriptInitialized(nn.path);\r
4502                                 }\r
4503                         }\r
4504                 }\r
4505         }\r
4506         var level = Node.STATUS_DECLARED;\r
4507         if (node.optionals.length == 0 && node.musts.length == 0\r
4508                         || node.status > Node.STATUS_KNOWN && !node.declaration\r
4509                         || checkStatusIs(node.musts, Node.STATUS_LOAD_COMPLETE)\r
4510                                         && checkStatusIs(node.optionals, Node.STATUS_LOAD_COMPLETE)) { \r
4511                 level = Node.STATUS_LOAD_COMPLETE;\r
4512                 if (!doneLoading(node, level))\r
4513                         return false;\r
4514                         // For those classes within one *.js file, update them synchronously.\r
4515                 if (node.declaration && node.declaration.clazzList) {\r
4516                         for (var j = 0, list = node.declaration.clazzList, l = list.length; j < l; j++) {\r
4517                                 var nn = findNode(list[j]);\r
4518                                 if (nn && nn.status != level && nn !== node) {\r
4519                                         nn.declaration = null;\r
4520                                         if (!doneLoading(nn, level))\r
4521                                                 return false;\r
4522                                 }\r
4523                         }\r
4524                 }\r
4525         }\r
4526   // _Loader.updateParents = function (node, level, _updateParents)\r
4527         if (node.parents && node.parents.length) {\r
4528         for (var i = 0; i < node.parents.length; i++) {\r
4529                 var p = node.parents[i];\r
4530                 if (p.status < level) \r
4531                         updateNode(p, p.name);\r
4532         }\r
4533         if (level == Node.STATUS_LOAD_COMPLETE)\r
4534                 node.parents = [];\r
4535   }\r
4536 };\r
4537 \r
4538 /* private */\r
4539 var checkStatusIs = function(arr, status){\r
4540         for (var i = arr.length; --i >= 0;)\r
4541                 if (arr[i].status < status)\r
4542                         return false;\r
4543         return true;\r
4544 }\r
4545 /* private */\r
4546 var doneLoading = function(node, level, _doneLoading) {\r
4547         node.status = level;\r
4548         _Loader.onScriptCompleted(node.path);\r
4549   \r
4550         var onLoaded = node.onLoaded;\r
4551         if (onLoaded) {\r
4552                 node.onLoaded = null;\r
4553                 onLoaded();\r
4554                 if (!_Loader.keepOnLoading)\r
4555                         return false;\r
4556         }\r
4557   \r
4558         destroyClassNode(node);\r
4559         return true;\r
4560 }\r
4561 \r
4562 /*\r
4563  * Be used to record already used random numbers. And next new random\r
4564  * number should not be in the property set.\r
4565  */\r
4566 /* private */\r
4567 var usedRandoms = {\r
4568   "r0.13412" : 1\r
4569 };\r
4570 \r
4571 /* private */\r
4572 var getRnd = function() {\r
4573         while (true) { // get a unique random number\r
4574                 var rnd = Math.random();\r
4575                 var s = "r" + rnd;\r
4576                 if (!usedRandoms[s])\r
4577                         return (usedRandoms[s] = 1, clazzTreeRoot.random = rnd);\r
4578         }\r
4579 }\r
4580 \r
4581 /* protected */\r
4582 var findNode = function(clazzName) {\r
4583         getRnd();\r
4584         return findNodeUnderNode(clazzName, clazzTreeRoot);\r
4585 };\r
4586 \r
4587 /* private */\r
4588 var findNextRequiredClass = function(status) {\r
4589         getRnd();\r
4590         return findNextRequiredNode(clazzTreeRoot, status);\r
4591 };\r
4592 \r
4593 /* private */\r
4594 var findNextMustClass = function(status) {\r
4595         return findNextMustNode(clazzTreeRoot, status);\r
4596 };\r
4597 \r
4598 /* private */\r
4599 var findNodeUnderNode = function(clazzName, node) {\r
4600         var n;\r
4601         // node, then musts then optionals\r
4602         return (node.name == clazzName ? node \r
4603                 : (n = findNodeWithin(clazzName, node.musts))\r
4604                 || (n = findNodeWithin(clazzName, node.optionals)) \r
4605                 ? n : null);\r
4606 };\r
4607 \r
4608 /* private */\r
4609 var findNodeWithin = function(name, arr) {\r
4610         var rnd = clazzTreeRoot.random;\r
4611         for (var i = arr.length; --i >= 0;) {\r
4612                 var n = arr[i];\r
4613                 if (n.name == name)\r
4614                         return n;\r
4615                 if (n.random != rnd) {\r
4616                         n.random = rnd;\r
4617                         if ((n = findNodeUnderNode(name, n)))\r
4618                                 return n;\r
4619                 }\r
4620         }\r
4621         return null;\r
4622 }\r
4623 \r
4624 /* private */\r
4625 var checkStatus = function(n, status) {\r
4626         return (n.status == status \r
4627                         && (status != Node.STATUS_KNOWN || !loadedScripts[n.path])\r
4628                         && (status == Node.STATUS_DECLARED      || !isClassDefined (n.name)));\r
4629 }\r
4630 \r
4631 /* private */\r
4632 var findNextMustNode = function(node, status) {\r
4633         for (var i = node.musts.length; --i >= 0;) {\r
4634                 var n = node.musts[i];\r
4635                 if (checkStatus(n, status) || (n = findNextMustNode(n, status)))\r
4636                         return n;       \r
4637         }\r
4638         return (checkStatus(node, status) ? node : null); \r
4639 };\r
4640 \r
4641 /* private */\r
4642 var findNextRequiredNode = function (node, status) {\r
4643         // search musts first\r
4644         // search optionals second\r
4645         // search itself last\r
4646         var n;\r
4647         return ((n = searchClassArray(node.musts, status))\r
4648                 || (n = searchClassArray(node.optionals, status))\r
4649                 || checkStatus(n = node, status) ? n : null);\r
4650 };\r
4651 \r
4652 /* private */\r
4653 var searchClassArray = function (arr, status) {\r
4654         if (arr) {\r
4655                 var rnd = clazzTreeRoot.random;\r
4656                 for (var i = 0; i < arr.length; i++) {\r
4657                         var n = arr[i];\r
4658                         if (checkStatus(n, status))\r
4659                                 return n;\r
4660                         if (n.random != rnd) {\r
4661                                 n.random = rnd; // mark as visited!\r
4662                                 if ((n = findNextRequiredNode(n, status)))\r
4663                                         return n;\r
4664                         }\r
4665                 }\r
4666         }\r
4667         return null;\r
4668 };\r
4669 \r
4670 /**\r
4671  * This map variable is used to mark that *.js is correctly loaded.\r
4672  * In IE, _Loader has defects to detect whether a *.js is correctly\r
4673  * loaded or not, so inner loading mark is used for detecting.\r
4674  */\r
4675 /* private */\r
4676 var innerLoadedScripts = {};\r
4677 \r
4678 /**\r
4679  * This method will be called in almost every *.js generated by Java2Script\r
4680  * compiler.\r
4681  */\r
4682 /* public */\r
4683 var load = function (musts, name, optionals, declaration) {\r
4684   // called as name.load in Jmol\r
4685         if (name instanceof Array) {\r
4686                 unwrapArray(name);\r
4687                 for (var i = 0; i < name.length; i++)\r
4688                         load(musts, name[i], optionals, declaration, name);\r
4689                 return;\r
4690         }       \r
4691 \r
4692   if (_Loader._checkLoad) {\r
4693     if (_Loader._classPending[name]) {\r
4694       //alert("duplicate load for " + name)\r
4695     } else {\r
4696       _Loader._classPending[name] = 1;\r
4697       if (_Loader._classCountPending++ == 0)\r
4698         _Loader._classCountOK = 0;\r
4699       System.out.println("Loading class " + name);\r
4700     }\r
4701   }\r
4702 \r
4703 //      if (clazz.charAt (0) == '$')\r
4704 //              clazz = "org.eclipse.s" + clazz.substring (1);\r
4705         var node = mapPath2ClassNode["#" + name];\r
4706         if (!node) { // load called inside *.z.js?\r
4707                 var n = findNode(name);\r
4708                 node = (n ? n : new Node());\r
4709                 node.name = name;\r
4710                 node.path = classpathMap["#" + name] || "unknown";\r
4711                 mappingPathNameNode(node.path, name, node);\r
4712                 node.status = Node.STATUS_KNOWN;\r
4713                 addChildClassNode(clazzTreeRoot, node, false);\r
4714         }\r
4715         processRequired(node, musts, true);\r
4716         if (arguments.length == 5 && declaration) {\r
4717                 declaration.status = node.status;\r
4718                 declaration.clazzList = arguments[4];\r
4719         }\r
4720         node.declaration = declaration;\r
4721         if (declaration) \r
4722                 node.status = Node.STATUS_CONTENT_LOADED;\r
4723         processRequired(node, optionals, false);\r
4724 };\r
4725 \r
4726 /* private */\r
4727 var processRequired = function(node, arr, isMust) {\r
4728         if (arr && arr.length) {\r
4729                 unwrapArray(arr);\r
4730                 for (var i = 0; i < arr.length; i++) {\r
4731                         var name = arr[i];\r
4732                         if (!name)\r
4733                                 continue;\r
4734                         if (isClassDefined(name)\r
4735                                         || isClassExcluded(name))\r
4736                                 continue;\r
4737                         var n = findNode(name);\r
4738                         if (!n) {\r
4739                                 n = new Node();\r
4740                                 n.name = name;\r
4741                                 n.status = Node.STATUS_KNOWN;\r
4742                         }\r
4743                         n.requiredBy = node;\r
4744                         addChildClassNode(node, n, isMust);\r
4745                 }\r
4746         }\r
4747 }\r
4748 \r
4749 /*\r
4750  * Try to be compatiable of Clazz\r
4751  */\r
4752 if (window["Clazz"]) {\r
4753         Clazz.load = load;\r
4754 } else {\r
4755   _Loader.load = load;\r
4756 }  \r
4757 /**\r
4758  * Map different class to the same path! Many classes may be packed into\r
4759  * a *.z.js already.\r
4760  *\r
4761  * @path *.js path\r
4762  * @name class name\r
4763  * @node Node object\r
4764  */\r
4765 /* private */\r
4766 var mappingPathNameNode = function (path, name, node) {\r
4767         var map = mapPath2ClassNode;\r
4768         var keyPath = "@" + path;\r
4769         var v = map[keyPath];\r
4770         if (v) {\r
4771                 if (v instanceof Array) {\r
4772                         var existed = false;\r
4773                         for (var i = 0; i < v.length; i++) {\r
4774                                 if (v[i].name == name) {\r
4775                                         existed = true;\r
4776                                         break;\r
4777                                 }\r
4778                         }\r
4779                         if (!existed)\r
4780                                 v.push(node);\r
4781                 } else {\r
4782                         map[keyPath] = [v, node];\r
4783                 }\r
4784         } else {\r
4785                 map[keyPath] = node;\r
4786         }\r
4787         map["#" + name] = node;\r
4788 };\r
4789 \r
4790 /* protected */\r
4791 var loadClassNode = function (node) {\r
4792         var name = node.name;\r
4793         if (!isClassDefined (name) \r
4794                         && !isClassExcluded (name)) {\r
4795                 var path = _Loader.getClasspathFor (name/*, true*/);\r
4796                 node.path = path;\r
4797                 mappingPathNameNode (path, name, node);\r
4798                 if (!loadedScripts[path]) {\r
4799                         loadScript(node, path, node.requiredBy, false);\r
4800                         return true;\r
4801                 }\r
4802         }\r
4803         return false;\r
4804 };\r
4805 \r
4806 \r
4807 /**\r
4808  * Used in package\r
4809 /* public */\r
4810 var runtimeKeyClass = _Loader.runtimeKeyClass = "java.lang.String";\r
4811 \r
4812 /**\r
4813  * Queue used to store classes before key class is loaded.\r
4814  */\r
4815 /* private */\r
4816 var queueBe4KeyClazz = [];\r
4817 \r
4818 /* private */\r
4819 var J2sLibBase;\r
4820 \r
4821 /**\r
4822  * Return J2SLib base path from existed SCRIPT src attribute.\r
4823  */\r
4824 /* public */\r
4825 _Loader.getJ2SLibBase = function () {\r
4826         var o = window["j2s.lib"];\r
4827         return (o ? o.base + (o.alias == "." ? "" : (o.alias ? o.alias : (o.version ? o.version : "1.0.0")) + "/") : null);\r
4828 };\r
4829 \r
4830 /**\r
4831  * Indicate whether _Loader is loading script synchronously or \r
4832  * asynchronously.\r
4833  */\r
4834 /* private */\r
4835 var isAsynchronousLoading = true;\r
4836 \r
4837 /* private */\r
4838 var isUsingXMLHttpRequest = false;\r
4839 \r
4840 /* private */\r
4841 var loadingTimeLag = -1;\r
4842 \r
4843 _Loader.MODE_SCRIPT = 4;\r
4844 _Loader.MODE_XHR = 2;\r
4845 _Loader.MODE_SYNC = 1;\r
4846 \r
4847 /**\r
4848  * String mode:\r
4849  * asynchronous modes:\r
4850  * async(...).script, async(...).xhr, async(...).xmlhttprequest,\r
4851  * script.async(...), xhr.async(...), xmlhttprequest.async(...),\r
4852  * script\r
4853  * \r
4854  * synchronous modes:\r
4855  * sync(...).xhr, sync(...).xmlhttprequest,\r
4856  * xhr.sync(...), xmlhttprequest.sync(...),\r
4857  * xmlhttprequest, xhr\r
4858  *                                                    \r
4859  * Integer mode:\r
4860  * Script 4; XHR 2; SYNC bit 1; \r
4861  */\r
4862 /* public */\r
4863 _Loader.setLoadingMode = function (mode, timeLag) {\r
4864         var async = true;\r
4865         var ajax = true;\r
4866         if (typeof mode == "string") {\r
4867                 mode = mode.toLowerCase();\r
4868                 if (mode.indexOf("script") >= 0)\r
4869                         ajax = false;\r
4870                 else\r
4871                         async = (mode.indexOf("async") >=0);\r
4872                 async = false; // BH\r
4873         } else {\r
4874                 if (mode & _Loader.MODE_SCRIPT)\r
4875                         ajax = false;\r
4876                 else\r
4877                         async = !(mode & _Loader.MODE_SYNC);\r
4878         }\r
4879         isUsingXMLHttpRequest = ajax;\r
4880         isAsynchronousLoading = async;\r
4881         loadingTimeLag = (async && timeLag >= 0 ? timeLag: -1);\r
4882         return async;\r
4883 };\r
4884 \r
4885 /* private */\r
4886 var runtimeLoaded = function () {\r
4887         if (pkgRefCount || !isClassDefined(runtimeKeyClass))\r
4888                 return;\r
4889         var qbs = queueBe4KeyClazz;\r
4890         for (var i = 0; i < qbs.length; i++)\r
4891                 _Loader.loadClass(qbs[i][0], qbs[i][1]);\r
4892         queueBe4KeyClazz = [];\r
4893 };\r
4894 \r
4895 /*\r
4896  * Load those key *.z.js. This *.z.js will be surely loaded before other \r
4897  * queued *.js.\r
4898  */\r
4899 /* public */\r
4900 _Loader.loadZJar = function (zjarPath, keyClass) {\r
4901 // used only by package.js for core.z.js\r
4902         var f = null;\r
4903         var isArr = (keyClass instanceof Array);\r
4904         if (isArr)\r
4905                 keyClass = keyClass[keyClass.length - 1];\r
4906         else\r
4907                 f = (keyClass == runtimeKeyClass ? runtimeLoaded : null);                       \r
4908         _Loader.jarClasspath(zjarPath, isArr ? keyClass : [keyClass]);\r
4909         // BH note: runtimeKeyClass is java.lang.String \r
4910         _Loader.loadClass(keyClass, f, true);\r
4911 };\r
4912 \r
4913 var NodeMap = {};\r
4914 var _allNodes = [];\r
4915 \r
4916 /**\r
4917  * The method help constructing the multiple-binary class dependency tree.\r
4918  */\r
4919 /* private */\r
4920 var addChildClassNode = function (parent, child, isMust) {\r
4921         var existed = false;\r
4922         var arr;\r
4923         if (isMust) {\r
4924                 arr = parent.musts;\r
4925                 if (!child.requiredBy)\r
4926                         child.requiredBy = parent;\r
4927 //              if (!parent.requiresMap){\r
4928 //                      parent.requires = [];\r
4929 //                      parent.requiresMap = {};\r
4930 //              }\r
4931 //              if (!parent.requiresMap[child.name]) {\r
4932 //                      parent.requiresMap[child.name] = 1;\r
4933 //                      parent.requires.push[child];\r
4934 //              }\r
4935         } else {\r
4936                 arr = parent.optionals;\r
4937         }\r
4938         if (!NodeMap[child.name]) {\r
4939                 _allNodes.push(child)\r
4940                 NodeMap[child.name]=child\r
4941         }\r
4942         for (var i = 0; i < arr.length; i++) {\r
4943                 if (arr[i].name == child.name) {\r
4944                         existed = true;\r
4945                         break;\r
4946                 }\r
4947         }\r
4948         if (!existed) {\r
4949                 arr.push(child);\r
4950                 if (isLoadingEntryClass \r
4951                                 && child.name.indexOf("java") != 0 \r
4952                                 && child.name.indexOf("net.sf.j2s.ajax") != 0) {\r
4953                         if (besidesJavaPackage)\r
4954                                 isLoadingEntryClass = false;\r
4955                         besidesJavaPackage = true;\r
4956 //              } else if (child.name.indexOf("org.eclipse.swt") == 0 \r
4957 //                              || child.name.indexOf("$wt") == 0) {\r
4958 //                      window["swt.lazy.loading.callback"] = swtLazyLoading;\r
4959 //                      if (needPackage("org.eclipse.swt"))\r
4960 //                              return _Loader.loadPackage("org.eclipse.swt", function() {addParentClassNode(child, parent)});\r
4961                 }\r
4962         }\r
4963         addParentClassNode(child, parent);\r
4964 };\r
4965 \r
4966 /* private */\r
4967 var addParentClassNode = function(child, parent) {\r
4968         if (parent.name && parent != clazzTreeRoot && parent != child)\r
4969                 for (var i = 0; i < child.parents.length; i++)\r
4970                         if (child.parents[i].name == parent.name)\r
4971                                 return;\r
4972         child.parents.push(parent);\r
4973 }\r
4974 \r
4975 /* private */\r
4976 var destroyClassNode = function (node) {\r
4977         var parents = node.parents;\r
4978         if (parents)\r
4979                 for (var k = parents.length; --k >= 0;)\r
4980                         removeArrayItem(parents[k].musts, node) || removeArrayItem(parents[k].optionals, node);\r
4981 };\r
4982 \r
4983 /* public */\r
4984 _Loader.unloadClassExt = function (qClazzName) {\r
4985         if (definedClasses)\r
4986                 definedClasses[qClazzName] = false;\r
4987         if (classpathMap["#" + qClazzName]) {\r
4988                 var pp = classpathMap["#" + qClazzName];\r
4989                 classpathMap["#" + qClazzName] = null;\r
4990                 var arr = classpathMap["$" + pp];\r
4991                 removeArrayItem(arr, qClazzName) && (classpathMap["$" + pp] = arr);\r
4992         }\r
4993         var n = findNode(qClazzName);\r
4994         if (n) {\r
4995                 n.status = Node.STATUS_KNOWN;\r
4996                 loadedScripts[n.path] = false;\r
4997         }\r
4998         var path = _Loader.getClasspathFor (qClazzName);\r
4999         loadedScripts[path] = false;\r
5000         innerLoadedScripts[path] && (innerLoadedScripts[path] = false);\r
5001         _Loader.onClassUnloaded(qClazzName);\r
5002 };\r
5003 \r
5004 /* private */\r
5005 var assureInnerClass = function (clzz, fun) {\r
5006         clzz = clzz.__CLASS_NAME__;\r
5007         if (Clazz.unloadedClasses[clzz]) {\r
5008                 if (clzz.indexOf("$") >= 0)\r
5009                         return;\r
5010                 var list = [];\r
5011                 var key = clzz + "$";\r
5012                 for (var s in Clazz.unloadedClasses)\r
5013                         if (Clazz.unloadedClasses[s] && s.indexOf(key) == 0)\r
5014                                 list.push(s);\r
5015                 if (!list.length) \r
5016                         return;\r
5017                 fun = "" + fun;\r
5018                 var idx1, idx2;\r
5019                 if ((idx1 = fun.indexOf(key)) < 0 || (idx2 = fun.indexOf("\"", idx1 + key.length)) < 0) \r
5020                         return;\r
5021                 clzz = fun.substring(idx1, idx2);\r
5022                 if (!Clazz.unloadedClasses[clzz] || (idx1 = fun.indexOf("{", idx2) + 1) == 0)\r
5023                         return;\r
5024                 if ((idx2 = fun.indexOf("(" + clzz + ",", idx1 + 3)) < 0\r
5025                         || (idx2 = fun.lastIndexOf("}", idx2 - 1)) < 0)\r
5026                                 return;\r
5027                 eval(fun.substring(idx1, idx2));\r
5028                 Clazz.unloadedClasses[clzz] = null;\r
5029         }\r
5030 };\r
5031 \r
5032 Clazz.binaryFolders =  _Loader.binaryFolders = [ _Loader.getJ2SLibBase() ];\r
5033 \r
5034 })(Clazz, Clazz._Loader);\r
5035 \r
5036 //}\r
5037 /******************************************************************************\r
5038  * Copyright (c) 2007 java2script.org and others.\r
5039  * All rights reserved. This program and the accompanying materials\r
5040  * are made available under the terms of the Eclipse Public License v1.0\r
5041  * which accompanies this distribution, and is available at\r
5042  * http://www.eclipse.org/legal/epl-v10.html\r
5043  *\r
5044  * Contributors:\r
5045  *     Zhou Renjian - initial API and implementation\r
5046  *****************************************************************************/\r
5047 /*******\r
5048  * @author zhou renjian\r
5049  * @create Jan 11, 2007\r
5050  *******/\r
5051 \r
5052 Clazz._LoaderProgressMonitor = {};\r
5053 \r
5054 ;(function(CLPM, Jmol) {\r
5055 \r
5056 var fadeOutTimer = null;\r
5057 var fadeAlpha = 0;\r
5058 var monitorEl = null;\r
5059 var lastScrollTop = 0;\r
5060 var bindingParent = null;\r
5061 \r
5062 CLPM.DEFAULT_OPACITY = (Jmol && Jmol._j2sLoadMonitorOpacity ? Jmol._j2sLoadMonitorOpacity : 55);\r
5063 \r
5064 /* public */\r
5065 /*CLPM.initialize = function (parent) {\r
5066         bindingParent = parent;\r
5067         if (parent && !attached) {\r
5068                 attached = true;\r
5069                 //Clazz.addEvent (window, "unload", cleanup);\r
5070                 // window.attachEvent ("onunload", cleanup);\r
5071         }\r
5072 };\r
5073 */\r
5074 \r
5075 /* public */\r
5076 CLPM.hideMonitor = function () {\r
5077         monitorEl.style.display = "none";\r
5078 }\r
5079 \r
5080 /* public */\r
5081 CLPM.showStatus = function (msg, fading) {\r
5082         if (!monitorEl) {\r
5083                 createHandle ();\r
5084                 if (!attached) {\r
5085                         attached = true;\r
5086                         //Clazz.addEvent (window, "unload", cleanup);\r
5087                         // window.attachEvent ("onunload", cleanup);\r
5088                 }\r
5089         }\r
5090         clearChildren(monitorEl);\r
5091   if (msg == null) {\r
5092     if (fading) {\r
5093       fadeOut();\r
5094     } else {\r
5095         CLPM.hideMonitor();\r
5096     }\r
5097     return;\r
5098   }\r
5099   \r
5100         monitorEl.appendChild(document.createTextNode ("" + msg));\r
5101         if (monitorEl.style.display == "none") {\r
5102                 monitorEl.style.display = "";\r
5103         }\r
5104         setAlpha(CLPM.DEFAULT_OPACITY);\r
5105         var offTop = getFixedOffsetTop();\r
5106         if (lastScrollTop != offTop) {\r
5107                 lastScrollTop = offTop;\r
5108                 monitorEl.style.bottom = (lastScrollTop + 4) + "px";\r
5109         }\r
5110         if (fading) {\r
5111                 fadeOut();\r
5112         }\r
5113 };\r
5114 \r
5115 /* private static */ \r
5116 var clearChildren = function (el) {\r
5117         if (!el)\r
5118                 return;\r
5119         for (var i = el.childNodes.length; --i >= 0;) {\r
5120                 var child = el.childNodes[i];\r
5121                 if (!child)\r
5122                         continue;\r
5123                 if (child.childNodes && child.childNodes.length)\r
5124                         clearChildren (child);\r
5125                 try {\r
5126                         el.removeChild (child);\r
5127                 } catch (e) {};\r
5128         }\r
5129 };\r
5130 /* private */ \r
5131 var setAlpha = function (alpha) {\r
5132         if (fadeOutTimer && alpha == CLPM.DEFAULT_OPACITY) {\r
5133                 window.clearTimeout (fadeOutTimer);\r
5134                 fadeOutTimer = null;\r
5135         }\r
5136         fadeAlpha = alpha;\r
5137         var ua = navigator.userAgent.toLowerCase();\r
5138         monitorEl.style.filter = "Alpha(Opacity=" + alpha + ")";\r
5139         monitorEl.style.opacity = alpha / 100.0;\r
5140 };\r
5141 /* private */ \r
5142 var hidingOnMouseOver = function () {\r
5143   CLPM.hideMonitor();\r
5144 };\r
5145 \r
5146 /* private */ \r
5147 var attached = false;\r
5148 /* private */ \r
5149 var cleanup = function () {\r
5150         //if (monitorEl) {\r
5151         //      monitorEl.onmouseover = null;\r
5152         //}\r
5153         monitorEl = null;\r
5154         bindingParent = null;\r
5155         //Clazz.removeEvent (window, "unload", cleanup);\r
5156         //window.detachEvent ("onunload", cleanup);\r
5157         attached = false;\r
5158 };\r
5159 /* private */ \r
5160 var createHandle = function () {\r
5161         var div = document.createElement ("DIV");\r
5162         div.id = "_Loader-status";\r
5163         div.style.cssText = "position:absolute;bottom:4px;left:4px;padding:2px 8px;"\r
5164                         + "z-index:" + (window["j2s.lib"].monitorZIndex || 10000) + ";background-color:#8e0000;color:yellow;" \r
5165                         + "font-family:Arial, sans-serif;font-size:10pt;white-space:nowrap;";\r
5166         div.onmouseover = hidingOnMouseOver;\r
5167         monitorEl = div;\r
5168         if (bindingParent) {\r
5169                 bindingParent.appendChild(div);\r
5170         } else {\r
5171                 document.body.appendChild(div);\r
5172         }\r
5173         return div;\r
5174 };\r
5175 /* private */ \r
5176 \r
5177 var fadeOut = function () {\r
5178         if (monitorEl.style.display == "none") return;\r
5179         if (fadeAlpha == CLPM.DEFAULT_OPACITY) {\r
5180                 fadeOutTimer = window.setTimeout(function () {\r
5181                                         fadeOut();\r
5182                                 }, 750);\r
5183                 fadeAlpha -= 5;\r
5184         } else if (fadeAlpha - 10 >= 0) {\r
5185                 setAlpha(fadeAlpha - 10);\r
5186                 fadeOutTimer = window.setTimeout(function () {\r
5187                                         fadeOut();\r
5188                                 }, 40);\r
5189         } else {\r
5190                 monitorEl.style.display = "none";\r
5191         }\r
5192 };\r
5193 /* private */\r
5194 var getFixedOffsetTop = function (){\r
5195         if (bindingParent) {\r
5196                 var b = bindingParent;\r
5197                 return b.scrollTop;\r
5198         }\r
5199         var dua = navigator.userAgent;\r
5200         var b = document.body;\r
5201         var p = b.parentNode;\r
5202         var pcHeight = p.clientHeight;\r
5203         var bcScrollTop = b.scrollTop + b.offsetTop;\r
5204         var pcScrollTop = p.scrollTop + p.offsetTop;\r
5205         return (dua.indexOf("Opera") < 0 && document.all ? (pcHeight == 0 ? bcScrollTop : pcScrollTop)\r
5206                 : dua.indexOf("Gecko") < 0 ? (pcHeight == p.offsetHeight \r
5207                                 && pcHeight == p.scrollHeight ? bcScrollTop : pcScrollTop) : bcScrollTop);\r
5208 };\r
5209 \r
5210 /* not used in Jmol\r
5211 if (window["ClazzLoader"]) {\r
5212         _Loader.onScriptLoading = function(file) {\r
5213                 CLPM.showStatus("Loading " + file + "...");\r
5214         };\r
5215         _Loader.onScriptLoaded = function(file, isError) {\r
5216                 CLPM.showStatus(file + (isError ? " loading failed." : " loaded."), true);\r
5217         };\r
5218         _Loader.onGlobalLoaded = function(file) {\r
5219                 CLPM.showStatus("Application loaded.", true);\r
5220         };\r
5221         _Loader.onClassUnloaded = function(clazz) {\r
5222                 CLPM.showStatus("Class " + clazz + " is unloaded.", true);\r
5223   };\r
5224 }\r
5225 */\r
5226 \r
5227 })(Clazz._LoaderProgressMonitor, Jmol);\r
5228 \r
5229 //}\r
5230 /******************************************************************************\r
5231  * Copyright (c) 2007 java2script.org and others.\r
5232  * All rights reserved. This program and the accompanying materials\r
5233  * are made available under the terms of the Eclipse Public License v1.0\r
5234  * which accompanies this distribution, and is available at\r
5235  * http://www.eclipse.org/legal/epl-v10.html\r
5236  *\r
5237  * Contributors:\r
5238  *     Zhou Renjian - initial API and implementation\r
5239  *****************************************************************************/\r
5240 /*******\r
5241  * @author zhou renjian\r
5242  * @create Nov 5, 2005\r
5243  *******/\r
5244 \r
5245 ;(function(Con, Sys) {\r
5246 /**\r
5247  * Setting maxTotalLines to -1 will not limit the console result\r
5248  */\r
5249 /* protected */\r
5250 Con.maxTotalLines =     10000;\r
5251 \r
5252 /* protected */\r
5253 Con.setMaxTotalLines = function (lines) {\r
5254         Con.maxTotalLines = (lines > 0 ? lines : 999999);\r
5255 }\r
5256 \r
5257 /* protected */\r
5258 Con.maxLatency = 40;\r
5259 \r
5260 /* protected */\r
5261 Con.setMaxLatency = function (latency) {\r
5262         Con.maxLatency = (latency > 0 ? latency : 40);\r
5263 };\r
5264 \r
5265 /* protected */\r
5266 Con.pinning  = false;\r
5267 \r
5268 /* protected */\r
5269 Con.enablePinning = function (enabled) {\r
5270         Con.pinning = enabled;\r
5271 };\r
5272 \r
5273 /* private */\r
5274 Con.linesCount = 0;\r
5275 \r
5276 /* private */\r
5277 Con.metLineBreak = false;\r
5278 \r
5279 \r
5280 /*\r
5281  * Give an extension point so external script can create and bind the console\r
5282  * themself.\r
5283  *\r
5284  * TODO: provide more template of binding console window to browser.\r
5285  */\r
5286 /* protected */\r
5287 Con.createConsoleWindow = function (parentEl) {\r
5288         var console = document.createElement ("DIV");\r
5289         console.style.cssText = "font-family:monospace, Arial, sans-serif;";\r
5290         document.body.appendChild (console);\r
5291         return console;\r
5292 };\r
5293 \r
5294 var c160 = String.fromCharCode(160); //nbsp;\r
5295 c160 += c160+c160+c160;\r
5296 \r
5297 /* protected */\r
5298 Con.consoleOutput = function (s, color) {\r
5299         var o = window["j2s.lib"];\r
5300         var console = (o && o.console);\r
5301         if (console && typeof console == "string")\r
5302                 console = document.getElementById(console)\r
5303         if (!console)\r
5304                 return false; // BH this just means we have turned off all console action\r
5305         if (Con.linesCount > Con.maxTotalLines) {\r
5306                 for (var i = 0; i < Con.linesCount - Con.maxTotalLines; i++) {\r
5307                         if (console && console.childNodes.length > 0) {\r
5308                                 console.removeChild (console.childNodes[0]);\r
5309                         }\r
5310                 }\r
5311                 Con.linesCount = Con.maxTotalLines;\r
5312         }\r
5313 \r
5314         var willMeetLineBreak = false;\r
5315         s = (typeof s == "undefined" ? "" : s == null ? "null" : "" + s);\r
5316         s = s.replace (/\t/g, c160);\r
5317         if (s.length > 0)\r
5318                 switch (s.charAt(s.length - 1)) {\r
5319                 case '\n':\r
5320                 case '\r':\r
5321                         s = (s.length > 1 ? s.substring (0, s.length - (s.charAt (s.length - 2) == '\r' ? 2 : 1)) : "");\r
5322                         willMeetLineBreak = true;\r
5323                         break;\r
5324                 }\r
5325 \r
5326         var lines = null;\r
5327         s = s.replace (/\t/g, c160);\r
5328         lines = s.split(/\r\n|\r|\n/g);\r
5329         for (var i = 0, last = lines.length - 1; i <= last; i++) {\r
5330                 var lastLineEl = null;\r
5331                 if (Con.metLineBreak || Con.linesCount == 0 \r
5332                                 || console.childNodes.length < 1) {\r
5333                         lastLineEl = document.createElement ("DIV");\r
5334                         console.appendChild (lastLineEl);\r
5335                         lastLineEl.style.whiteSpace = "nowrap";\r
5336                         Con.linesCount++;\r
5337                 } else {\r
5338                         try {\r
5339                                 lastLineEl = console.childNodes[console.childNodes.length - 1];\r
5340                         } catch (e) {\r
5341                                 lastLineEl = document.createElement ("DIV");\r
5342                                 console.appendChild (lastLineEl);\r
5343                                 lastLineEl.style.whiteSpace = "nowrap";\r
5344                                 Con.linesCount++;\r
5345                         }\r
5346                 }\r
5347                 var el = document.createElement ("SPAN");\r
5348                 lastLineEl.appendChild (el);\r
5349                 el.style.whiteSpace = "nowrap";\r
5350                 if (color)\r
5351                         el.style.color = color;\r
5352                 var l = lines[i]\r
5353                 if (l.length == 0)\r
5354                         l = c160;\r
5355                 el.appendChild(document.createTextNode(l));\r
5356                 if (!Con.pinning)\r
5357                         console.scrollTop += 100;\r
5358                 Con.metLineBreak = (i != last || willMeetLineBreak);\r
5359         }\r
5360 \r
5361         var cssClazzName = console.parentNode.className;\r
5362         if (!Con.pinning && cssClazzName\r
5363                         && cssClazzName.indexOf ("composite") != -1) {\r
5364                 console.parentNode.scrollTop = console.parentNode.scrollHeight;\r
5365         }\r
5366         Con.lastOutputTime = new Date ().getTime ();\r
5367 };\r
5368 \r
5369 /*\r
5370  * Clear all contents inside the console.\r
5371  */\r
5372 /* public */\r
5373 Con.clear = function () {\r
5374         try {\r
5375                 Con.metLineBreak = true;\r
5376                 var o = window["j2s.lib"];\r
5377                 var console = o && o.console;\r
5378                 if (!console || !(console = document.getElementById (console)))\r
5379                         return;\r
5380                 var childNodes = console.childNodes;\r
5381                 for (var i = childNodes.length; --i >= 0;)\r
5382                         console.removeChild (childNodes[i]);\r
5383                 Con.linesCount = 0;\r
5384         } catch(e){};\r
5385 };\r
5386 \r
5387 /* public */\r
5388 Clazz.alert = function (s) {\r
5389         Con.consoleOutput (s + "\r\n");\r
5390 };\r
5391 \r
5392 \r
5393 /* public */\r
5394 Sys.out.print = function (s) { \r
5395         Con.consoleOutput (s);\r
5396 };\r
5397 /* public */\r
5398 Sys.out.println = function(s) { \r
5399         Con.consoleOutput(typeof s == "undefined" ? "\r\n" : s == null ?  s = "null\r\n" : s + "\r\n");\r
5400 };\r
5401 \r
5402 Sys.out.write = function (buf, offset, len) {\r
5403         Sys.out.print(String.instantialize(buf).substring(offset, offset+len));\r
5404 };\r
5405 \r
5406 /* public */\r
5407 Sys.err.__CLASS_NAME__ = "java.io.PrintStream";\r
5408 \r
5409 /* public */\r
5410 Sys.err.print = function (s) { \r
5411         Con.consoleOutput (s, "red");\r
5412 };\r
5413 \r
5414 /* public */\r
5415 Sys.err.println = function (s) {\r
5416         Con.consoleOutput (typeof s == "undefined" ? "\r\n" : s == null ?  s = "null\r\n" : s + "\r\n", "red");\r
5417 };\r
5418 \r
5419 Sys.err.write = function (buf, offset, len) {\r
5420         Sys.err.print(String.instantialize(buf).substring(offset, offset+len));\r
5421 };\r
5422 \r
5423 })(Clazz.Console, System);\r
5424 \r
5425 })(Clazz, Jmol); // requires JSmolCore.js\r
5426 \r
5427 }; // called by external application \r