48e59f28512697f9e8dc04bea9942b02edf26dc2
[jalviewjs.git] / site / j2s / java / lang / ClassExt.js
1 /******************************************************************************\r
2  * Copyright (c) 2007 java2script.org and others.\r
3  * All rights reserved. This program and the accompanying materials\r
4  * are made available under the terms of the Eclipse Public License v1.0\r
5  * which accompanies this distribution, and is available at\r
6  * http://www.eclipse.org/legal/epl-v10.html\r
7  *\r
8  * Contributors:\r
9  *     Zhou Renjian - initial API and implementation\r
10  *****************************************************************************/\r
11 /*******\r
12  * @author zhou renjian\r
13  * @create March 10, 2006\r
14  *******/\r
15 \r
16 if (window["Clazz"] == null || window["Clazz"].unloadClass == null) {\r
17 /**\r
18  * Once ClassExt.js is part of Class.js.\r
19  * In order to make the Class.js as small as possible, part of its content\r
20  * is moved into this ClassExt.js.\r
21  *\r
22  * See also http://j2s.sourceforge.net/j2sclazz/\r
23  */\r
24  \r
25 /**\r
26  * Clazz.MethodNotFoundException is used to notify the developer about calling\r
27  * methods with incorrect parameters.\r
28  */\r
29 /* protected */\r
30 // Override the Clazz.MethodNotFoundException in Class.js to give details\r
31 Clazz.MethodNotFoundException = function (obj, clazz, method, params) {\r
32         var paramStr = "";\r
33         if (params != null) {\r
34                 paramStr = params.substring (1).replace (/\\/g, ",");\r
35         }\r
36         var leadingStr = "";\r
37         if (method != null && method != "construct") {\r
38                 leadingStr = "Method";\r
39         } else {\r
40                 leadingStr = "Constructor";\r
41         }\r
42         this.message = leadingStr + " " + Clazz.getClassName (clazz, true) + "." \r
43                                         + method + "(" + paramStr + ") is not found!";\r
44         this.toString = function () {\r
45                 return "MethodNotFoundException:" + this.message;\r
46         }\r
47 };\r
48 \r
49 /**\r
50  * Prepare callback for instance of anonymous Class.\r
51  * For example for the callback:\r
52  *     this.callbacks.MyEditor.sayHello();\r
53  *\r
54  * @param objThis the host object for callback\r
55  * @param args arguments object. args[0] will be classThisObj -- the "this"\r
56  * object to be hooked\r
57  * \r
58  * Attention: parameters should not be null!\r
59  */\r
60 /* protected */\r
61 Clazz.prepareCallback = function (objThis, args) {\r
62         var classThisObj = args[0];\r
63         var cbName = "b$"; // "callbacks";\r
64         if (objThis != null && classThisObj != null && classThisObj !== window) {\r
65                 var obs = new Array ();\r
66                 if (objThis[cbName] == null) {\r
67                         objThis[cbName] = obs;\r
68                 } else { // must make a copy!\r
69                         for (var s in objThis[cbName]) {\r
70                                 if (s != "length") {\r
71                                         obs[s] = objThis[cbName][s];\r
72                                 }\r
73                         }\r
74                         objThis[cbName] = obs;\r
75                 }\r
76                 var className = Clazz.getClassName (classThisObj, true);\r
77                 //if (obs[className] == null) { /* == null make no sense! */\r
78                         //obs[className] = classThisObj;\r
79                         /*\r
80                          * TODO: the following line is SWT-specific! Try to move it out!\r
81                          */\r
82                         obs[className.replace (/org\.eclipse\.swt\./, "$wt.")] = classThisObj;\r
83                         var clazz = Clazz.getClass (classThisObj);\r
84                         while (clazz.superClazz != null) {\r
85                                 clazz = clazz.superClazz;\r
86                                 //obs[Clazz.getClassName (clazz)] = classThisObj;\r
87                                 /*\r
88                                  * TODO: the following line is SWT-specific! Try to move it out!\r
89                                  */\r
90                                 obs[Clazz.getClassName (clazz, true)\r
91                                                 .replace (/org\.eclipse\.swt\./, "$wt.")] = classThisObj;\r
92                         }\r
93                 //}\r
94                 var cbs = classThisObj[cbName];\r
95                 if (cbs != null && cbs instanceof Array) {\r
96                         for (var s in cbs) {\r
97                                 if (s != "length") {\r
98                                         obs[s] = cbs[s];\r
99                                 }\r
100                         }\r
101                 }\r
102         }\r
103         // Shift the arguments\r
104         for (var i = 0; i < args.length - 1; i++) {\r
105                 args[i] = args[i + 1];\r
106         }\r
107         args.length--;\r
108         // arguments will be returned!\r
109 };\r
110 \r
111 /**\r
112  * Construct instance of the given inner class.\r
113  *\r
114  * @param classInner given inner class, alway with name like "*$*"\r
115  * @param objThis this instance which can be used to call back.\r
116  * @param finalVars final variables which the inner class may use\r
117  * @return the constructed object\r
118  *\r
119  * @see Clazz#cloneFinals\r
120  */\r
121 /* public */\r
122 Clazz.innerTypeInstance = function (clazzInner, objThis, finalVars) {\r
123         if (clazzInner == null) {\r
124                 clazzInner = arguments.callee.caller;\r
125         }\r
126         var obj = null;\r
127         /*if (arguments.length == 2) {\r
128                 obj = new clazzInner (objThis);\r
129         } else */if (arguments.length == 3) {\r
130                 obj = new clazzInner (objThis);\r
131         } else if (arguments.length == 4) {\r
132                 if (objThis.__CLASS_NAME__ == clazzInner.__CLASS_NAME__\r
133                                 && arguments[3] === Clazz.inheritArgs) {\r
134                         obj = objThis;\r
135                 } else {\r
136                         obj = new clazzInner (objThis, arguments[3]);\r
137                 }\r
138         } else if (arguments.length == 5) {\r
139                 obj = new clazzInner (objThis, arguments[3], arguments[4]);\r
140         } else if (arguments.length == 6) {\r
141                 obj = new clazzInner (objThis, arguments[3], arguments[4], \r
142                                 arguments[5]);\r
143         } else if (arguments.length == 7) {\r
144                 obj = new clazzInner (objThis, arguments[3], arguments[4], \r
145                                 arguments[5], arguments[6]);\r
146         } else if (arguments.length == 8) {\r
147                 obj = new clazzInner (objThis, arguments[3], arguments[4], \r
148                                 arguments[5], arguments[6], arguments[7]);\r
149         } else if (arguments.length == 9) {\r
150                 obj = new clazzInner (objThis, arguments[3], arguments[4], \r
151                                 arguments[5], arguments[6], arguments[7], arguments[8]);\r
152         } else if (arguments.length == 10) {\r
153                 obj = new clazzInner (objThis, arguments[3], arguments[4], \r
154                                 arguments[5], arguments[6], arguments[7], arguments[8],\r
155                                 arguments[9]);\r
156         } else {\r
157                 /*\r
158                  * Should construct instance manually.\r
159                  */\r
160                 obj = new clazzInner ();\r
161                 if (obj.construct == null) {\r
162                         throw new String ("No support anonymous class constructor with " \r
163                                         + "more than 7 parameters.");\r
164                 }\r
165                 var args = new Array ();\r
166                 for (var i = 3; i < arguments.length; i++) {\r
167                         args[i - 3] = arguments[i];\r
168                 }\r
169                 obj.construct.apply (obj, args);\r
170         }\r
171         // f$ is short for the once choosen "$finals"\r
172         if (finalVars != null && objThis.f$ == null) {\r
173                 obj.f$ = finalVars;\r
174         } else if (finalVars == null && objThis.f$ != null) {\r
175                 obj.f$ = objThis.f$;\r
176         } else if (finalVars != null && objThis.f$ != null) {\r
177                 var o = new Object ();\r
178                 for (var attr in objThis.f$) {\r
179                         o[attr] = objThis.f$[attr];\r
180                 }\r
181                 for (var attr in finalVars) {\r
182                         o[attr] = finalVars[attr];\r
183                 }\r
184                 obj.f$ = o;\r
185         }\r
186         /*\r
187         if (finalVars != null && objThis.$finals == null) {\r
188                 obj.$finals = finalVars;\r
189         } else if (finalVars == null && objThis.$finals != null) {\r
190                 obj.$finals = objThis.$finals;\r
191         } else if (finalVars != null && objThis.$finals != null) {\r
192                 var o = new Object ();\r
193                 for (var attr in objThis.$finals) {\r
194                         o[attr] = objThis.$finals[attr];\r
195                 }\r
196                 for (var attr in finalVars) {\r
197                         o[attr] = finalVars[attr];\r
198                 }\r
199                 obj.$finals = o;\r
200         }\r
201         */\r
202         //Clazz.prepareCallback (obj, objThis);\r
203         return obj;\r
204 };\r
205 \r
206 /**\r
207  * Clone variables whose modifier is "final".\r
208  * Usage: var o = Clazz.cloneFinals ("name", name, "age", age);\r
209  *\r
210  * @return Object with all final variables\r
211  */\r
212 /* protected */\r
213 Clazz.cloneFinals = function () {\r
214         var o = new Object ();\r
215         var length = arguments.length / 2;\r
216         for (var i = 0; i < length; i++) {\r
217                 o[arguments[i + i]] = arguments[i + i + 1];\r
218         }\r
219         return o;\r
220 };\r
221 \r
222 /* public */\r
223 Clazz.isClassDefined = Clazz.isDefinedClass = function (clazzName) {\r
224         if (clazzName != null && clazzName.length != 0) {\r
225                 if (Clazz.allClasses[clazzName]) {\r
226                         return true;\r
227                 }\r
228                 var pkgFrags = clazzName.split (/\./);\r
229                 var pkg = null;\r
230                 for (var i = 0; i < pkgFrags.length; i++) {\r
231                         if (pkg == null) {\r
232                                 if (Clazz.allPackage[pkgFrags[0]] == null) {\r
233                                         //error (clazzName + " / " + false);\r
234                                         return false;\r
235                                 }\r
236                                 pkg = Clazz.allPackage[pkgFrags[0]];\r
237                         } else {\r
238                                 if (pkg[pkgFrags[i]] == null) {\r
239                                         //error (clazzName + " / " + false);\r
240                                         return false;\r
241                                 }\r
242                                 pkg = pkg[pkgFrags[i]]\r
243                         }\r
244                 }\r
245                 //error (clazzName + " / " + (pkg != null));\r
246                 //return pkg != null;\r
247                 if (pkg != null) {\r
248                         Clazz.allClasses[clazzName] = true;\r
249                         return true;\r
250                 } else {\r
251                         return false;\r
252                 }\r
253         } else {\r
254                 /* consider null or empty name as non-defined class */\r
255                 return false;\r
256         }\r
257 };\r
258 /**\r
259  * Define the enum constant.\r
260  * @param classEnum enum type\r
261  * @param enumName enum constant\r
262  * @param enumOrdinal enum ordinal\r
263  * @param initialParams enum constant constructor parameters\r
264  * @return return defined enum constant\r
265  */\r
266 /* public */\r
267 Clazz.defineEnumConstant = function (clazzEnum, enumName, enumOrdinal, initialParams, clazzEnumExt) {\r
268         var o = null;\r
269         if (clazzEnumExt != null) {\r
270                 o = new clazzEnumExt ();\r
271         } else {\r
272                 o = new clazzEnum ();\r
273         }\r
274         Clazz.superConstructor (o, clazzEnum, [enumName, enumOrdinal]);\r
275         if (initialParams != null && initialParams.length != 0) {\r
276                 o.construct.apply (o, initialParams);\r
277         }\r
278         clazzEnum[enumName] = o;\r
279         clazzEnum.prototype[enumName] = o;\r
280         return o;\r
281 };\r
282 \r
283 /**\r
284  * Make arrays.\r
285  *\r
286  * @return the created Array object\r
287  */\r
288 /* public */\r
289 Clazz.newArray  = function () {\r
290         var args = arguments;\r
291         if (arguments.length == 1) {\r
292                 if (arguments[0] instanceof Array) {\r
293                         args = arguments[0];\r
294                 }\r
295         }\r
296         if (args.length <= 1) {\r
297                 return new Array ();\r
298         } else if (args.length == 2) {\r
299                 var dim = args[0];\r
300                 if (typeof dim == "string") {\r
301                         dim = dim.charCodeAt (0); // char\r
302                 }\r
303                 var val = args[1];\r
304                 var arr = new Array (dim);\r
305                 for (var i = 0; i < dim; i++) {\r
306                         arr[i] = val;\r
307                 }\r
308                 return arr;\r
309         } else {\r
310                 var dim = args[0];\r
311                 if (typeof dim == "string") {\r
312                         dim = dim.charCodeAt (0); // char\r
313                 }\r
314                 var len = args.length - 1;\r
315                 var xargs = new Array (len);\r
316                 for (var i = 0; i < len; i++) {\r
317                         xargs[i] = args[i + 1];\r
318                 }\r
319                 var arr = new Array (dim);\r
320                 for (var i = 0; i < dim; i++) {\r
321                         // Call recursively!\r
322                         arr[i] = Clazz.newArray (xargs);\r
323                 }\r
324                 return arr;\r
325         }\r
326 };\r
327 \r
328 /**\r
329  * Make the RunnableCompatiability instance as a JavaScript function.\r
330  *\r
331  * @param jsr Instance of RunnableCompatiability\r
332  * @return JavaScript function instance represents the method run of jsr.\r
333  */\r
334 /* public */\r
335 Clazz.makeFunction = function (jsr) {\r
336         return function (e) {\r
337                 if (e == null) {\r
338                         e = window.event;\r
339                 }\r
340                 if (jsr.setEvent != null) {\r
341                         jsr.setEvent (e);\r
342                 }\r
343                 jsr.run ();\r
344                 /*\r
345                 if (e != null && jsr.isReturned != null && jsr.isReturned()) {\r
346                         // Is it correct to stopPropagation here? --Feb 19, 2006\r
347                         e.cancelBubble = true;\r
348                         if (e.stopPropagation) {\r
349                                 e.stopPropagation();\r
350                         }\r
351                 }\r
352                 */\r
353                 if (jsr.returnSet == 1) {\r
354                         return jsr.returnNumber;\r
355                 } else if (jsr.returnSet == 2) {\r
356                         return jsr.returnBoolean;\r
357                 } else if (jsr.returnSet == 3) {\r
358                         return jsr.returnObject;\r
359                 }\r
360         };\r
361 };\r
362 \r
363 /* protected */\r
364 Clazz.defineStatics = function (clazz) {\r
365         for (var i = 0; i < (arguments.length - 1) / 2; i++) {\r
366                 var name = arguments[i + i + 1];\r
367                 clazz[name] = clazz.prototype[name] = arguments[i + i + 2];\r
368         }\r
369 };\r
370 \r
371 /* protected */\r
372 Clazz.prepareFields = function (clazz, fieldsFun) {\r
373         var stacks = new Array ();\r
374         if (clazz.con$truct != null) {\r
375                 var ss = clazz.con$truct.stacks;\r
376                 var idx = clazz.con$truct.index;\r
377                 for (var i = idx; i < ss.length; i++) {\r
378                         stacks[i] = ss[i];\r
379                 }\r
380         }\r
381         clazz.con$truct = clazz.prototype.con$truct = function () {\r
382                 var stacks = arguments.callee.stacks;\r
383                 if (stacks != null) {\r
384                         for (var i = 0; i < stacks.length; i++) {\r
385                                 stacks[i].apply (this, []);\r
386                         }\r
387                 }\r
388         };\r
389         stacks[stacks.length] = fieldsFun;\r
390         clazz.con$truct.stacks = stacks;\r
391         clazz.con$truct.index = 0;\r
392 };\r
393 \r
394 /*\r
395  * Serialize those public or protected fields in class \r
396  * net.sf.j2s.ajax.SimpleSerializable.\r
397  */\r
398 /* protected */\r
399 Clazz.registerSerializableFields = function (clazz) {\r
400         var args = arguments;\r
401         var length = args.length;\r
402         var newArr = new Array ();\r
403         if (clazz.declared$Fields != null) {\r
404                 for (var i = 0; i < clazz.declared$Fields.length; i++) {\r
405                         newArr[i] = clazz.declared$Fields[i];\r
406                 }\r
407         }\r
408         clazz.declared$Fields = newArr;\r
409         \r
410         if (length > 0 && length % 2 == 1) {\r
411                 var fs = clazz.declared$Fields;\r
412                 for (var i = 1; i <= (length - 1) / 2; i++) {\r
413                         var o = { name : args[i + i - 1], type : args[i + i] };\r
414                         var existed = false;\r
415                         for (var j = 0; j < fs.length; j++) {\r
416                                 if (fs[j].name == o.name) { // reloaded classes\r
417                                         fs[j].type = o.type; // update type\r
418                                         existed = true;\r
419                                         break;\r
420                                 }\r
421                         }\r
422                         if (!existed) {\r
423                                 fs[fs.length] = o;\r
424                         }\r
425                 }\r
426         }\r
427 };\r
428 \r
429 /*\r
430  * Get the caller method for those methods that are wrapped by \r
431  * Clazz.searchAndExecuteMethod.\r
432  *\r
433  * @param args caller method's arguments\r
434  * @return caller method, null if there is not wrapped by \r
435  * Clazz.searchAndExecuteMethod or is called directly.\r
436  */\r
437 /* protected */\r
438 /*-# getMixedCallerMethod -> gMCM  #-*/\r
439 Clazz.getMixedCallerMethod = function (args) {\r
440         var o = new Object ();\r
441         var argc = args.callee.caller; // Clazz.tryToSearchAndExecute\r
442         if (argc == null) return null;\r
443         if (argc !== Clazz.tryToSearchAndExecute) { // inherited method's apply\r
444                 argc = argc.arguments.callee.caller;\r
445                 if (argc == null) return null;\r
446         }\r
447         if (argc !== Clazz.tryToSearchAndExecute) return null;\r
448         argc = argc.arguments.callee.caller; // Clazz.searchAndExecuteMethod\r
449         if (argc == null || argc !== Clazz.searchAndExecuteMethod) return null;\r
450         o.claxxRef = argc.arguments[1];\r
451         o.fxName = argc.arguments[2];\r
452         o.paramTypes = Clazz.getParamsType (argc.arguments[3]);\r
453         argc = argc.arguments.callee.caller; // Clazz.generateDelegatingMethod\r
454         if (argc == null) return null;\r
455         argc = argc.arguments.callee.caller; // the private method's caller\r
456         if (argc == null) return null;\r
457         o.caller = argc;\r
458         return o;\r
459 };\r
460 \r
461 /*\r
462  * Check and return super private method.\r
463  * In order make private methods be executed correctly, some extra javascript\r
464  * must be inserted into the beggining of the method body of the non-private \r
465  * methods that with the same method signature as following:\r
466  * <code>\r
467  *                      var $private = Clazz.checkPrivateMethod (arguments);\r
468  *                      if ($private != null) {\r
469  *                              return $private.apply (this, arguments);\r
470  *                      }\r
471  * </code>\r
472  * Be cautious about this. The above codes should be insert by Java2Script\r
473  * compiler or with double checks to make sure things work correctly.\r
474  *\r
475  * @param args caller method's arguments\r
476  * @return private method if there are private method fitted for the current \r
477  * calling environment\r
478  */\r
479 /* public */\r
480 Clazz.checkPrivateMethod = function (args) {\r
481         var m = Clazz.getMixedCallerMethod (args);\r
482         if (m == null) return null;\r
483         var callerFx = m.claxxRef.prototype[m.caller.exName];\r
484         if (callerFx == null) return null; // may not be in the class hierarchies\r
485         var ppFun = null;\r
486         if (callerFx.claxxOwner != null) {\r
487                 ppFun = callerFx.claxxOwner.prototype[m.fxName];\r
488         } else {\r
489                 var stacks = callerFx.stacks;\r
490                 for (var i = stacks.length - 1; i >= 0; i--) {\r
491                         var fx = stacks[i].prototype[m.caller.exName];\r
492                         if (fx === m.caller) {\r
493                                 ppFun = stacks[i].prototype[m.fxName];\r
494                         } else if (fx != null) {\r
495                                 for (var fn in fx) {\r
496                                         if (fn.indexOf ('\\') == 0 && fx[fn] === m.caller) {\r
497                                                 ppFun = stacks[i].prototype[m.fxName];\r
498                                                 break;\r
499                                         }\r
500                                 }\r
501                         }\r
502                         if (ppFun != null) {\r
503                                 break;\r
504                         }\r
505                 }\r
506         }\r
507         if (ppFun != null && ppFun.claxxOwner == null) {\r
508                 ppFun = ppFun["\\" + m.paramTypes];\r
509         }\r
510         if (ppFun != null && ppFun.isPrivate && ppFun !== args.callee) {\r
511                 return ppFun;\r
512         }\r
513         return null;\r
514 };\r
515 var $fz = null; // for private method declaration\r
516 //var cla$$ = null;\r
517 var c$ = null;\r
518 /*-# cla$$$tack -> cst  #-*/\r
519 Clazz.cla$$$tack = new Array ();\r
520 Clazz.pu$h = function () {\r
521         if (c$ != null) { // if (cla$$ != null) {\r
522                 Clazz.cla$$$tack[Clazz.cla$$$tack.length] = c$; // cla$$;\r
523         }\r
524 };\r
525 Clazz.p0p = function () {\r
526         if (Clazz.cla$$$tack.length > 0) {\r
527                 var clazz = Clazz.cla$$$tack[Clazz.cla$$$tack.length - 1];\r
528                 Clazz.cla$$$tack.length--;\r
529                 return clazz;\r
530         } else {\r
531                 return null;\r
532         }\r
533 };\r
534 \r
535 /*# {$no.debug.support} >>x #*/\r
536 /*\r
537  * Option to switch on/off of stack traces.\r
538  */\r
539 /* protect */\r
540 Clazz.tracingCalling = false;\r
541 \r
542 /*\r
543  * Use to mark that the Throwable instance is created or not.\r
544  */\r
545 /* private */\r
546 Clazz.initializingException = false;\r
547 \r
548 /* private */\r
549 Clazz.callingStack = function (caller, owner) {\r
550         this.caller = caller;\r
551         this.owner = owner;\r
552 };\r
553 Clazz.callingStackTraces = new Array ();\r
554 Clazz.pu$hCalling = function (stack) {\r
555         Clazz.callingStackTraces[Clazz.callingStackTraces.length] = stack;\r
556 };\r
557 Clazz.p0pCalling = function () {\r
558         var length = Clazz.callingStackTraces.length;\r
559         if (length > 0) {\r
560                 var stack = Clazz.callingStackTraces[length - 1];\r
561                 Clazz.callingStackTraces.length--;\r
562                 return stack;\r
563         } else {\r
564                 return null;\r
565         }\r
566 };\r
567 /*# x<< #*/\r
568 \r
569 /**\r
570  * The first folder is considered as the primary folder.\r
571  * And try to be compatiable with ClazzLoader system.\r
572  */\r
573 /* private */\r
574 if (window["ClazzLoader"] != null && ClazzLoader.binaryFolders != null) {\r
575         Clazz.binaryFolders = ClazzLoader.binaryFolders;\r
576 } else {\r
577         Clazz.binaryFolders = ["bin/", "", "j2slib/"];\r
578 }\r
579 \r
580 Clazz.addBinaryFolder = function (bin) {\r
581         if (bin != null) {\r
582                 var bins = Clazz.binaryFolders;\r
583                 for (var i = 0; i < bins.length; i++) {\r
584                         if (bins[i] == bin) {\r
585                                 return ;\r
586                         }\r
587                 }\r
588                 bins[bins.length] = bin;\r
589         }\r
590 };\r
591 Clazz.removeBinaryFolder = function (bin) {\r
592         if (bin != null) {\r
593                 var bins = Clazz.binaryFolders;\r
594                 for (var i = 0; i < bins.length; i++) {\r
595                         if (bins[i] == bin) {\r
596                                 for (var j = i; j < bins.length - 1; j++) {\r
597                                         bins[j] = bins[j + 1];\r
598                                 }\r
599                                 bins.length--;\r
600                                 return bin;\r
601                         }\r
602                 }\r
603         }\r
604         return null;\r
605 };\r
606 Clazz.setPrimaryFolder = function (bin) {\r
607         if (bin != null) {\r
608                 Clazz.removeBinaryFolder (bin);\r
609                 var bins = Clazz.binaryFolders;\r
610                 for (var i = bins.length - 1; i >= 0; i--) {\r
611                         bins[i + 1] = bins[i];\r
612                 }\r
613                 bins[0] = bin;\r
614         }\r
615 };\r
616 \r
617 /**\r
618  * This is a simple implementation for Clazz#load. It just ignore dependencies\r
619  * of the class. This will be fine for jar *.z.js file.\r
620  * It will be overriden by ClazzLoader#load.\r
621  * For more details, see ClazzLoader.js\r
622  */\r
623 /* protected */\r
624 Clazz.load = function (musts, clazz, optionals, declaration) {\r
625         if (declaration != null) {\r
626                 declaration ();\r
627         }\r
628 };\r
629 \r
630 /*\r
631  * Invade the Object prototype!\r
632  * TODO: make sure that invading Object prototype does not affect other\r
633  * existed library, such as Dojo, YUI, Prototype, ...\r
634  */\r
635 java.lang.Object = Clazz._O;\r
636 \r
637 JavaObject.getName = Clazz.innerFunctions.getName;\r
638 \r
639 w$ = window; // Short for browser's window object\r
640 d$ = document; // Short for browser's document object\r
641 System = {\r
642         currentTimeMillis : function () {\r
643                 return new Date ().getTime ();\r
644         },\r
645         props : null, //new java.util.Properties (),\r
646         getProperties : function () {\r
647                 return System.props;\r
648         },\r
649         setProperties : function (props) {\r
650                 System.props = props;\r
651         },\r
652         getProperty : function (key, def) {\r
653                 if (System.props != null) {\r
654                         return System.props.getProperty (key, def);\r
655                 }\r
656                 if (def != null) {\r
657                         return def;\r
658                 }\r
659                 return key;\r
660         },\r
661         setProperty : function (key, val) {\r
662                 if (System.props == null) {\r
663                         return ;\r
664                 }\r
665                 System.props.setProperty (key, val);\r
666         },\r
667         currentTimeMillis : function () {\r
668                 return new Date ().getTime ();\r
669         },\r
670         arraycopy : function (src, srcPos, dest, destPos, length) {\r
671                 if (src !== dest) {\r
672                         for (var i = 0; i < length; i++) {\r
673                                 dest[destPos + i] = src[srcPos + i];\r
674                         }\r
675                 } else {\r
676                         var swap = [];\r
677                         for (var i = 0; i < length; i++) {\r
678                                 swap[i] = src[srcPos + i];\r
679                         }\r
680                         for (var i = 0; i < length; i++) {\r
681                                 dest[destPos + i] = swap[i];\r
682                         }\r
683                 }\r
684         }\r
685 };\r
686 System.out = new Clazz._O ();\r
687 System.out.__CLASS_NAME__ = "java.io.PrintStream";\r
688 System.out.print = function () {};\r
689 System.out.printf = function () {};\r
690 System.out.println = function () {};\r
691 \r
692 System.err = new Clazz._O ();\r
693 System.err.__CLASS_NAME__ = "java.io.PrintStream";\r
694 System.err.print = function () {};\r
695 System.err.printf = function () {};\r
696 System.err.println = function () {};\r
697 \r
698 popup = assert = log = error = window.alert;\r
699 \r
700 Thread = function () {};\r
701 Thread.J2S_THREAD = Thread.prototype.J2S_THREAD = new Thread ();\r
702 Thread.currentThread = Thread.prototype.currentThread = function () {\r
703         return this.J2S_THREAD;\r
704 };\r
705 \r
706 /* public */\r
707 Clazz.intCast = function (n) { // 32bit\r
708         var b1 = (n & 0xff000000) >> 24;\r
709         var b2 = (n & 0xff0000) >> 16;\r
710         var b3 = (n & 0xff00) >> 8;\r
711         var b4 = n & 0xff;\r
712         if ((b1 & 0x80) != 0) {\r
713                 return -(((b1 & 0x7f) << 24) + (b2 << 16) + (b3 << 8) + b4 + 1);\r
714         } else {\r
715                 return (b1 << 24) + (b2 << 16) + (b3 << 8) + b4;\r
716         }\r
717 };\r
718 \r
719 /* public */\r
720 Clazz.shortCast = function (s) { // 16bit\r
721         var b1 = (n & 0xff00) >> 8;\r
722         var b2 = n & 0xff;\r
723         if ((b1 & 0x80) != 0) {\r
724                 return -(((b1 & 0x7f) << 8) + b2 + 1);\r
725         } else {\r
726                 return (b1 << 8) + b4;\r
727         }\r
728 };\r
729 \r
730 /* public */\r
731 Clazz.byteCast = function (b) { // 8bit\r
732         if ((b & 0x80) != 0) {\r
733                 return -((b & 0x7f) + 1);\r
734         } else {\r
735                 return b & 0xff;\r
736         }\r
737 };\r
738 \r
739 /* public */\r
740 Clazz.charCast = function (c) { // 8bit\r
741         return String.fromCharCode (c & 0xff).charAt (0);\r
742 };\r
743 \r
744 /**\r
745  * Warning: Unsafe conversion!\r
746  */\r
747 /* public */\r
748 Clazz.floatCast = function (f) { // 32bit\r
749         return f;\r
750 };\r
751 \r
752 /*\r
753  * Try to fix JavaScript's shift operator defects on long type numbers.\r
754  */\r
755 \r
756 Clazz.longMasks = [];\r
757 \r
758 Clazz.longReverseMasks = [];\r
759 \r
760 Clazz.longBits = [];\r
761 \r
762 (function () {\r
763         var arr = [1];\r
764         for (var i = 1; i < 53; i++) {\r
765                 arr[i] = arr[i - 1] + arr[i - 1]; // * 2 or << 1\r
766         }\r
767         Clazz.longBits = arr;\r
768         Clazz.longMasks[52] = arr[52];\r
769         for (var i = 51; i >= 0; i--) {\r
770                 Clazz.longMasks[i] = Clazz.longMasks[i + 1] + arr[i];\r
771         }\r
772         Clazz.longReverseMasks[0] = arr[0];\r
773         for (var i = 1; i < 52; i++) {\r
774                 Clazz.longReverseMasks[i] = Clazz.longReverseMasks[i - 1] + arr[i];\r
775         }\r
776 }) ();\r
777 \r
778 /* public */\r
779 Clazz.longLeftShift = function (l, o) { // 64bit\r
780         if (o == 0) return l;\r
781         if (o >= 64) return 0;\r
782         if (o > 52) {\r
783                 error ("[Java2Script] Error : JavaScript does not support long shift!");\r
784                 return l;\r
785         }\r
786         if ((l & Clazz.longMasks[o - 1]) != 0) {\r
787                 error ("[Java2Script] Error : Such shift operator results in wrong calculation!");\r
788                 return l;\r
789         }\r
790         var high = l & Clazz.longMasks[52 - 32 + o];\r
791         if (high != 0) {\r
792                 return high * Clazz.longBits[o] + (l & Clazz.longReverseMasks[32 - o]) << 0;\r
793         } else {\r
794                 return l << o;\r
795         }\r
796 };\r
797 \r
798 /* public */\r
799 Clazz.intLeftShift = function (n, o) { // 32bit\r
800         return (n << o) & 0xffffffff;\r
801 };\r
802 \r
803 /* public */\r
804 Clazz.longRightShift = function (l, o) { // 64bit\r
805         if ((l & Clazz.longMasks[52 - 32]) != 0) {\r
806                 return Math.round((l & Clazz.longMasks[52 - 32]) / Clazz.longBits[32 - o]) + (l & Clazz.longReverseMasks[o]) >> o;\r
807         } else {\r
808                 return l >> o;\r
809         }\r
810 };\r
811 \r
812 /* public */\r
813 Clazz.intRightShift = function (n, o) { // 32bit\r
814         return n >> o; // no needs for this shifting wrapper\r
815 };\r
816 \r
817 /* public */\r
818 Clazz.long0RightShift = function (l, o) { // 64bit\r
819         return l >>> o;\r
820 };\r
821 \r
822 /* public */\r
823 Clazz.int0RightShift = function (n, o) { // 64bit\r
824         return n >>> o; // no needs for this shifting wrapper\r
825 };\r
826 \r
827 // Compress the common public API method in shorter name\r
828 $_L=Clazz.load;$_W=Clazz.declareAnonymous;$_T=Clazz.declareType;$_J=Clazz.declarePackage;$_C=Clazz.decorateAsClass;$_Z=Clazz.instantialize;$_I=Clazz.declareInterface;$_D=Clazz.isClassDefined;$_H=Clazz.pu$h;$_P=Clazz.p0p;$_B=Clazz.prepareCallback;$_N=Clazz.innerTypeInstance;$_K=Clazz.makeConstructor;$_U=Clazz.superCall;$_R=Clazz.superConstructor;$_M=Clazz.defineMethod;$_V=Clazz.overrideMethod;$_S=Clazz.defineStatics;$_E=Clazz.defineEnumConstant;$_F=Clazz.cloneFinals;$_Y=Clazz.prepareFields;$_A=Clazz.newArray;$_O=Clazz.instanceOf;$_G=Clazz.inheritArgs;$_X=Clazz.checkPrivateMethod;$_Q=Clazz.makeFunction;$_s=Clazz.registerSerializableFields;\r
829 \r
830 \r
831 var reflect = Clazz.declarePackage ("java.lang.reflect");\r
832 Clazz.declarePackage ("java.security");\r
833 \r
834 Clazz.innerFunctionNames = Clazz.innerFunctionNames.concat (["getSuperclass",\r
835                 "isAssignableFrom", "getMethods", "getMethod", "getDeclaredMethods", \r
836                 "getDeclaredMethod", "getConstructor", "getModifiers", "isArray", "newInstance"]);\r
837 \r
838 Clazz.innerFunctions.getSuperclass = function () {\r
839         return this.superClazz; \r
840 };\r
841 Clazz.innerFunctions.isAssignableFrom = function (clazz) {\r
842         return Clazz.getInheritedLevel (clazz, this) >= 0;      \r
843 };\r
844 Clazz.innerFunctions.getConstructor = function () {\r
845         return new java.lang.reflect.Constructor (this, [], [], \r
846                         java.lang.reflect.Modifier.PUBLIC);\r
847 };\r
848 /**\r
849  * TODO: fix bug for polymorphic methods!\r
850  */\r
851 Clazz.innerFunctions.getDeclaredMethods = Clazz.innerFunctions.getMethods = function () {\r
852         var ms = new Array ();\r
853         var p = this.prototype;\r
854         for (var attr in p) {\r
855                 if (typeof p[attr] == "function" && p[attr].__CLASS_NAME__ == null) {\r
856                         /* there are polynormical methods. */\r
857                         ms[ms.length] = new java.lang.reflect.Method (this, attr,\r
858                                         [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC);\r
859                 }\r
860         }\r
861         p = this;\r
862         for (var attr in p) {\r
863                 if (typeof p[attr] == "function" && p[attr].__CLASS_NAME__ == null) {\r
864                         ms[ms.length] = new java.lang.reflect.Method (this, attr,\r
865                                         [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC\r
866                                         | java.lang.reflect.Modifier.STATIC);\r
867                 }\r
868         }\r
869         return ms;\r
870 };\r
871 Clazz.innerFunctions.getDeclaredMethod = Clazz.innerFunctions.getMethod = function (name, clazzes) {\r
872         var p = this.prototype;\r
873         for (var attr in p) {\r
874                 if (name == attr && typeof p[attr] == "function" \r
875                                 && p[attr].__CLASS_NAME__ == null) {\r
876                         /* there are polynormical methods. */\r
877                         return new java.lang.reflect.Method (this, attr,\r
878                                         [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC);\r
879                 }\r
880         }\r
881         p = this;\r
882         for (var attr in p) {\r
883                 if (name == attr && typeof p[attr] == "function" \r
884                                 && p[attr].__CLASS_NAME__ == null) {\r
885                         return new java.lang.reflect.Method (this, attr,\r
886                                         [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC\r
887                                         | java.lang.reflect.Modifier.STATIC);\r
888                 }\r
889         }\r
890         return null;\r
891 };\r
892 Clazz.innerFunctions.getModifiers = function () {\r
893         return java.lang.reflect.Modifier.PUBLIC;\r
894 };\r
895 Clazz.innerFunctions.isArray = function () {\r
896         return false;\r
897 };\r
898 Clazz.innerFunctions.newInstance = function () {\r
899         var clz = this;\r
900         return new clz ();\r
901 };\r
902 \r
903 //Object.newInstance = Clazz.innerFunctions.newInstance;\r
904 {\r
905         var inF = Clazz.innerFunctionNames;\r
906         for (var i = 0; i < inF.length; i++) {\r
907                 JavaObject[inF[i]] = Clazz.innerFunctions[inF[i]];\r
908                 Array[inF[i]] = Clazz.innerFunctions[inF[i]];\r
909         }\r
910         Array["isArray"] = function () {\r
911                 return true;\r
912         };\r
913 }\r
914 \r
915 /* public */\r
916 Clazz.forName = function (clazzName) {\r
917         if (Clazz.isClassDefined (clazzName)) {\r
918                 return Clazz.evalType (clazzName);\r
919         }\r
920         if (window["ClazzLoader"] != null) {\r
921                 ClazzLoader.setLoadingMode ("xhr.sync");\r
922                 ClazzLoader.loadClass (clazzName);\r
923                 return Clazz.evalType (clazzName);\r
924         } else {\r
925                 alert ("[Java2Script] Error: No ClassLoader!");\r
926         }\r
927 };\r
928 \r
929 /* For hotspot and unloading */\r
930 \r
931 /* private */\r
932 Clazz.cleanDelegateMethod = function (m) {\r
933         if (m == null) return;\r
934         if (typeof m == "function" && m.lastMethod != null\r
935                         && m.lastParams != null && m.lastClaxxRef != null) {\r
936                 m.lastMethod = null;\r
937                 m.lastParams = null;\r
938                 m.lastClaxxRef = null;\r
939         }\r
940 };\r
941 \r
942 /* public */\r
943 Clazz.unloadClass = function (qClazzName) {\r
944         var cc = Clazz.evalType (qClazzName);\r
945         if (cc != null) {\r
946                 Clazz.unloadedClasses[qClazzName] = cc;\r
947                 var clazzName = qClazzName;\r
948                 var pkgFrags = clazzName.split (/\./);\r
949                 var pkg = null;\r
950                 for (var i = 0; i < pkgFrags.length - 1; i++) {\r
951                         if (pkg == null) {\r
952                                 pkg = Clazz.allPackage[pkgFrags[0]];\r
953                         } else {\r
954                                 pkg = pkg[pkgFrags[i]]\r
955                         }\r
956                 }\r
957                 if (pkg == null) {\r
958                         Clazz.allPackage[pkgFrags[0]] = null;\r
959                         window[pkgFrags[0]] = null;\r
960                         // also try to unload inner or anonymous classes\r
961                         for (var c in window) {\r
962                                 if (c.indexOf (qClazzName + "$") == 0) {\r
963                                         Clazz.unloadClass (c);\r
964                                         window[c] = null;\r
965                                 }\r
966                         }\r
967                 } else {\r
968                         pkg[pkgFrags[pkgFrags.length - 1]] = null;\r
969                         // also try to unload inner or anonymous classes\r
970                         for (var c in pkg) {\r
971                                 if (c.indexOf (pkgFrags[pkgFrags.length - 1] + "$") == 0) {\r
972                                         Clazz.unloadClass (pkg.__PKG_NAME__ + "." + c);\r
973                                         pkg[c] = null;\r
974                                 }\r
975                         }\r
976                 }\r
977 \r
978                 if (Clazz.allClasses[qClazzName] == true) {\r
979                         Clazz.allClasses[qClazzName] = false;\r
980                         // also try to unload inner or anonymous classes\r
981                         for (var c in Clazz.allClasses) {\r
982                                 if (c.indexOf (qClazzName + "$") == 0) {\r
983                                         Clazz.allClasses[c] = false;\r
984                                 }\r
985                         }\r
986                 }\r
987                 \r
988                 for (var m in cc) {\r
989                         Clazz.cleanDelegateMethod (cc[m]);\r
990                 }\r
991                 for (var m in cc.prototype) {\r
992                         Clazz.cleanDelegateMethod (cc.prototype[m]);\r
993                 }\r
994 \r
995                 if (window["ClazzLoader"] != null) {\r
996                         ClazzLoader.unloadClassExt (qClazzName);\r
997                 }\r
998                 \r
999                 return true;\r
1000         }\r
1001         return false;\r
1002 };\r
1003 \r
1004 //written by Dean Edwards, 2005\r
1005 //with input from Tino Zijdel, Matthias Miller, Diego Perini\r
1006 \r
1007 //http://dean.edwards.name/weblog/2005/10/add-event/\r
1008 \r
1009 // Merge Dean Edwards' addEvent for Java2Script\r
1010 /* public */\r
1011 Clazz.addEvent = function (element, type, handler) {\r
1012         if (element.addEventListener) {\r
1013                 element.addEventListener(type, handler, false);\r
1014         } else {\r
1015                 // assign each event handler a unique ID\r
1016                 if (!handler.$$guid) handler.$$guid = Clazz.addEvent.guid++;\r
1017                 // create a hash table of event types for the element\r
1018                 if (!element.events) element.events = {};\r
1019                 // create a hash table of event handlers for each element/event pair\r
1020                 var handlers = element.events[type];\r
1021                 if (!handlers) {\r
1022                         handlers = element.events[type] = {};\r
1023                         // store the existing event handler (if there is one)\r
1024                         if (element["on" + type]) {\r
1025                                 handlers[0] = element["on" + type];\r
1026                         }\r
1027                 }\r
1028                 // store the event handler in the hash table\r
1029                 handlers[handler.$$guid] = handler;\r
1030                 // assign a global event handler to do all the work\r
1031                 element["on" + type] = Clazz.handleEvent;\r
1032         }\r
1033 };\r
1034 /* private */\r
1035 //a counter used to create unique IDs\r
1036 Clazz.addEvent.guid = 1;\r
1037 \r
1038 /* public */\r
1039 Clazz.removeEvent = function (element, type, handler) {\r
1040         if (element.removeEventListener) {\r
1041                 element.removeEventListener(type, handler, false);\r
1042         } else {\r
1043                 // delete the event handler from the hash table\r
1044                 if (element.events && element.events[type]) {\r
1045                         delete element.events[type][handler.$$guid];\r
1046                 }\r
1047         }\r
1048 };\r
1049 \r
1050 /* private */\r
1051 Clazz.isVeryOldIE = navigator.userAgent.indexOf("MSIE 6.0") != -1 || navigator.userAgent.indexOf("MSIE 5.5") != -1 || navigator.userAgent.indexOf("MSIE 5.0") != -1;\r
1052 \r
1053 /* protected */\r
1054 Clazz.handleEvent = function (event) {\r
1055         var returnValue = true;\r
1056         // grab the event object (IE uses a global event object)\r
1057         if (!Clazz.isVeryOldIE) {\r
1058                 event = event || Clazz.fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event);\r
1059         } else { // The above line is buggy in IE 6.0\r
1060                 if (event == null) {\r
1061                         var evt = null;\r
1062                         try {\r
1063                                 var pWindow = (this.ownerDocument || this.document || this).parentWindow;\r
1064                                 if (pWindow != null) {\r
1065                                         evt = pWindow.event;\r
1066                                 }\r
1067                         } catch (e) {\r
1068                                 evt = window.event;\r
1069                         }\r
1070                         event = Clazz.fixEvent(evt);\r
1071                 }\r
1072         }\r
1073         // get a reference to the hash table of event handlers\r
1074         var handlers = this.events[event.type];\r
1075         // execute each event handler\r
1076         for (var i in handlers) {\r
1077                 if (isNaN (i)) {\r
1078                         continue;\r
1079                 }\r
1080                 this.$$handleEvent = handlers[i];\r
1081                 if (typeof this.$$handleEvent != "function") {\r
1082                         continue;\r
1083                 }\r
1084                 if (this.$$handleEvent(event) === false) {\r
1085                         returnValue = false;\r
1086                 }\r
1087         }\r
1088         return returnValue;\r
1089 };\r
1090 \r
1091 /* private */\r
1092 Clazz.fixEvent = function (event) {\r
1093         // add W3C standard event methods\r
1094         event.preventDefault = Clazz.fixEvent.preventDefault;\r
1095         event.stopPropagation = Clazz.fixEvent.stopPropagation;\r
1096         return event;\r
1097 };\r
1098 Clazz.fixEvent.preventDefault = function() {\r
1099         this.returnValue = false;\r
1100 };\r
1101 Clazz.fixEvent.stopPropagation = function() {\r
1102         this.cancelBubble = true;\r
1103 };\r
1104 \r
1105 }\r