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