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