Source Code Cross Referenced for JavaMembers.java in  » IDE-Netbeans » library » org » mozilla » javascript » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » library » org.mozilla.javascript 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
002:         *
003:         * ***** BEGIN LICENSE BLOCK *****
004:         * Version: MPL 1.1/GPL 2.0
005:         *
006:         * The contents of this file are subject to the Mozilla Public License Version
007:         * 1.1 (the "License"); you may not use this file except in compliance with
008:         * the License. You may obtain a copy of the License at
009:         * http://www.mozilla.org/MPL/
010:         *
011:         * Software distributed under the License is distributed on an "AS IS" basis,
012:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
013:         * for the specific language governing rights and limitations under the
014:         * License.
015:         *
016:         * The Original Code is Rhino code, released
017:         * May 6, 1999.
018:         *
019:         * The Initial Developer of the Original Code is
020:         * Netscape Communications Corporation.
021:         * Portions created by the Initial Developer are Copyright (C) 1997-2000
022:         * the Initial Developer. All Rights Reserved.
023:         *
024:         * Contributor(s):
025:         *   Norris Boyd
026:         *   Cameron McCormack
027:         *   Frank Mitchell
028:         *   Mike Shaver
029:         *   Kurt Westerfeld
030:         *
031:         * Alternatively, the contents of this file may be used under the terms of
032:         * the GNU General Public License Version 2 or later (the "GPL"), in which
033:         * case the provisions of the GPL are applicable instead of those above. If
034:         * you wish to allow use of your version of this file only under the terms of
035:         * the GPL and not to allow others to use your version of this file under the
036:         * MPL, indicate your decision by deleting the provisions above and replacing
037:         * them with the notice and other provisions required by the GPL. If you do
038:         * not delete the provisions above, a recipient may use your version of this
039:         * file under either the MPL or the GPL.
040:         *
041:         * ***** END LICENSE BLOCK ***** */
042:
043:        package org.mozilla.javascript;
044:
045:        import java.lang.reflect.*;
046:        import java.util.Arrays;
047:        import java.util.HashMap;
048:        import java.util.Hashtable;
049:        import java.util.Enumeration;
050:        import java.util.Map;
051:
052:        /**
053:         *
054:         * @author Mike Shaver
055:         * @author Norris Boyd
056:         * @see NativeJavaObject
057:         * @see NativeJavaClass
058:         */
059:        class JavaMembers {
060:            JavaMembers(Scriptable scope, Class cl) {
061:                this (scope, cl, false);
062:            }
063:
064:            JavaMembers(Scriptable scope, Class cl, boolean includeProtected) {
065:                Context cx = Context.getContext();
066:                ClassShutter shutter = cx.getClassShutter();
067:                if (shutter != null && !shutter.visibleToScripts(cl.getName())) {
068:                    throw Context.reportRuntimeError1("msg.access.prohibited",
069:                            cl.getName());
070:                }
071:                this .members = new Hashtable(23);
072:                this .staticMembers = new Hashtable(7);
073:                this .cl = cl;
074:                reflect(scope, includeProtected);
075:            }
076:
077:            boolean has(String name, boolean isStatic) {
078:                Hashtable ht = isStatic ? staticMembers : members;
079:                Object obj = ht.get(name);
080:                if (obj != null) {
081:                    return true;
082:                } else {
083:                    return null != findExplicitFunction(name, isStatic);
084:                }
085:            }
086:
087:            Object get(Scriptable scope, String name, Object javaObject,
088:                    boolean isStatic) {
089:                Hashtable ht = isStatic ? staticMembers : members;
090:                Object member = ht.get(name);
091:                if (!isStatic && member == null) {
092:                    // Try to get static member from instance (LC3)
093:                    member = staticMembers.get(name);
094:                }
095:                if (member == null) {
096:                    member = this .getExplicitFunction(scope, name, javaObject,
097:                            isStatic);
098:                    if (member == null)
099:                        return Scriptable.NOT_FOUND;
100:                }
101:                if (member instanceof  Scriptable) {
102:                    return member;
103:                }
104:                Context cx = Context.getContext();
105:                Object rval;
106:                Class type;
107:                try {
108:                    if (member instanceof  BeanProperty) {
109:                        BeanProperty bp = (BeanProperty) member;
110:                        if (bp.getter == null)
111:                            return Scriptable.NOT_FOUND;
112:                        rval = bp.getter.invoke(javaObject, Context.emptyArgs);
113:                        type = bp.getter.method().getReturnType();
114:                    } else {
115:                        Field field = (Field) member;
116:                        rval = field.get(isStatic ? null : javaObject);
117:                        type = field.getType();
118:                    }
119:                } catch (Exception ex) {
120:                    throw Context.throwAsScriptRuntimeEx(ex);
121:                }
122:                // Need to wrap the object before we return it.
123:                scope = ScriptableObject.getTopLevelScope(scope);
124:                return cx.getWrapFactory().wrap(cx, scope, rval, type);
125:            }
126:
127:            void put(Scriptable scope, String name, Object javaObject,
128:                    Object value, boolean isStatic) {
129:                Hashtable ht = isStatic ? staticMembers : members;
130:                Object member = ht.get(name);
131:                if (!isStatic && member == null) {
132:                    // Try to get static member from instance (LC3)
133:                    member = staticMembers.get(name);
134:                }
135:                if (member == null)
136:                    throw reportMemberNotFound(name);
137:                if (member instanceof  FieldAndMethods) {
138:                    FieldAndMethods fam = (FieldAndMethods) ht.get(name);
139:                    member = fam.field;
140:                }
141:
142:                // Is this a bean property "set"?
143:                if (member instanceof  BeanProperty) {
144:                    BeanProperty bp = (BeanProperty) member;
145:                    if (bp.setter == null) {
146:                        throw reportMemberNotFound(name);
147:                    }
148:                    // If there's only one setter or if the value is null, use the
149:                    // main setter. Otherwise, let the NativeJavaMethod decide which
150:                    // setter to use:
151:                    if (bp.setters == null || value == null) {
152:                        Class setType = bp.setter.argTypes[0];
153:                        Object[] args = { Context.jsToJava(value, setType) };
154:                        try {
155:                            bp.setter.invoke(javaObject, args);
156:                        } catch (Exception ex) {
157:                            throw Context.throwAsScriptRuntimeEx(ex);
158:                        }
159:                    } else {
160:                        Object[] args = { value };
161:                        bp.setters.call(Context.getContext(), ScriptableObject
162:                                .getTopLevelScope(scope), scope, args);
163:                    }
164:                } else {
165:                    if (!(member instanceof  Field)) {
166:                        String str = (member == null) ? "msg.java.internal.private"
167:                                : "msg.java.method.assign";
168:                        throw Context.reportRuntimeError1(str, name);
169:                    }
170:                    Field field = (Field) member;
171:                    Object javaValue = Context.jsToJava(value, field.getType());
172:                    try {
173:                        field.set(javaObject, javaValue);
174:                    } catch (IllegalAccessException accessEx) {
175:                        throw new RuntimeException(
176:                                "unexpected IllegalAccessException "
177:                                        + "accessing Java field");
178:                    } catch (IllegalArgumentException argEx) {
179:                        throw Context.reportRuntimeError3(
180:                                "msg.java.internal.field.type", value
181:                                        .getClass().getName(), field,
182:                                javaObject.getClass().getName());
183:                    }
184:                }
185:            }
186:
187:            Object[] getIds(boolean isStatic) {
188:                Hashtable ht = isStatic ? staticMembers : members;
189:                int len = ht.size();
190:                Object[] result = new Object[len];
191:                Enumeration keys = ht.keys();
192:                for (int i = 0; i < len; i++)
193:                    result[i] = keys.nextElement();
194:                return result;
195:            }
196:
197:            static String javaSignature(Class type) {
198:                if (!type.isArray()) {
199:                    return type.getName();
200:                } else {
201:                    int arrayDimension = 0;
202:                    do {
203:                        ++arrayDimension;
204:                        type = type.getComponentType();
205:                    } while (type.isArray());
206:                    String name = type.getName();
207:                    String suffix = "[]";
208:                    if (arrayDimension == 1) {
209:                        return name.concat(suffix);
210:                    } else {
211:                        int length = name.length() + arrayDimension
212:                                * suffix.length();
213:                        StringBuffer sb = new StringBuffer(length);
214:                        sb.append(name);
215:                        while (arrayDimension != 0) {
216:                            --arrayDimension;
217:                            sb.append(suffix);
218:                        }
219:                        return sb.toString();
220:                    }
221:                }
222:            }
223:
224:            static String liveConnectSignature(Class[] argTypes) {
225:                int N = argTypes.length;
226:                if (N == 0) {
227:                    return "()";
228:                }
229:                StringBuffer sb = new StringBuffer();
230:                sb.append('(');
231:                for (int i = 0; i != N; ++i) {
232:                    if (i != 0) {
233:                        sb.append(',');
234:                    }
235:                    sb.append(javaSignature(argTypes[i]));
236:                }
237:                sb.append(')');
238:                return sb.toString();
239:            }
240:
241:            private MemberBox findExplicitFunction(String name, boolean isStatic) {
242:                int sigStart = name.indexOf('(');
243:                if (sigStart < 0) {
244:                    return null;
245:                }
246:
247:                Hashtable ht = isStatic ? staticMembers : members;
248:                MemberBox[] methodsOrCtors = null;
249:                boolean isCtor = (isStatic && sigStart == 0);
250:
251:                if (isCtor) {
252:                    // Explicit request for an overloaded constructor
253:                    methodsOrCtors = ctors;
254:                } else {
255:                    // Explicit request for an overloaded method
256:                    String trueName = name.substring(0, sigStart);
257:                    Object obj = ht.get(trueName);
258:                    if (!isStatic && obj == null) {
259:                        // Try to get static member from instance (LC3)
260:                        obj = staticMembers.get(trueName);
261:                    }
262:                    if (obj instanceof  NativeJavaMethod) {
263:                        NativeJavaMethod njm = (NativeJavaMethod) obj;
264:                        methodsOrCtors = njm.methods;
265:                    }
266:                }
267:
268:                if (methodsOrCtors != null) {
269:                    for (int i = 0; i < methodsOrCtors.length; i++) {
270:                        Class[] type = methodsOrCtors[i].argTypes;
271:                        String sig = liveConnectSignature(type);
272:                        if (sigStart + sig.length() == name.length()
273:                                && name.regionMatches(sigStart, sig, 0, sig
274:                                        .length())) {
275:                            return methodsOrCtors[i];
276:                        }
277:                    }
278:                }
279:
280:                return null;
281:            }
282:
283:            private Object getExplicitFunction(Scriptable scope, String name,
284:                    Object javaObject, boolean isStatic) {
285:                Hashtable ht = isStatic ? staticMembers : members;
286:                Object member = null;
287:                MemberBox methodOrCtor = findExplicitFunction(name, isStatic);
288:
289:                if (methodOrCtor != null) {
290:                    Scriptable prototype = ScriptableObject
291:                            .getFunctionPrototype(scope);
292:
293:                    if (methodOrCtor.isCtor()) {
294:                        NativeJavaConstructor fun = new NativeJavaConstructor(
295:                                methodOrCtor);
296:                        fun.setPrototype(prototype);
297:                        member = fun;
298:                        ht.put(name, fun);
299:                    } else {
300:                        String trueName = methodOrCtor.getName();
301:                        member = ht.get(trueName);
302:
303:                        if (member instanceof  NativeJavaMethod
304:                                && ((NativeJavaMethod) member).methods.length > 1) {
305:                            NativeJavaMethod fun = new NativeJavaMethod(
306:                                    methodOrCtor, name);
307:                            fun.setPrototype(prototype);
308:                            ht.put(name, fun);
309:                            member = fun;
310:                        }
311:                    }
312:                }
313:
314:                return member;
315:            }
316:
317:            /**
318:             * Retrieves mapping of methods to accessible methods for a class.
319:             * In case the class is not public, retrieves methods with same 
320:             * signature as its public methods from public superclasses and 
321:             * interfaces (if they exist). Basically upcasts every method to the 
322:             * nearest accessible method.
323:             */
324:            private static Method[] discoverAccessibleMethods(Class clazz,
325:                    boolean includeProtected) {
326:                Map map = new HashMap();
327:                discoverAccessibleMethods(clazz, map, includeProtected);
328:                return (Method[]) map.values().toArray(new Method[map.size()]);
329:            }
330:
331:            private static void discoverAccessibleMethods(Class clazz, Map map,
332:                    boolean includeProtected) {
333:                if (Modifier.isPublic(clazz.getModifiers())) {
334:                    try {
335:                        if (includeProtected) {
336:                            while (clazz != null) {
337:                                Method[] methods = clazz.getDeclaredMethods();
338:                                for (int i = 0; i < methods.length; i++) {
339:                                    Method method = methods[i];
340:                                    int mods = method.getModifiers();
341:                                    if (Modifier.isPublic(mods)
342:                                            || Modifier.isProtected(mods)) {
343:                                        MethodSignature sig = new MethodSignature(
344:                                                method);
345:                                        map.put(sig, method);
346:                                    }
347:                                }
348:                                clazz = clazz.getSuperclass();
349:                            }
350:                        } else {
351:                            Method[] methods = clazz.getMethods();
352:                            for (int i = 0; i < methods.length; i++) {
353:                                Method method = methods[i];
354:                                MethodSignature sig = new MethodSignature(
355:                                        method);
356:                                map.put(sig, method);
357:                            }
358:                        }
359:                        return;
360:                    } catch (SecurityException e) {
361:                        Context.reportWarning(
362:                                "Could not discover accessible methods of class "
363:                                        + clazz.getName()
364:                                        + " due to lack of privileges, "
365:                                        + "attemping superclasses/interfaces."
366:                                // <netbeans>
367:                                , "discoverAccessibleMethods",
368:                                new Object[] { clazz }
369:                        // </netbeans>
370:                                );
371:                        // Fall through and attempt to discover superclass/interface 
372:                        // methods
373:                    }
374:                }
375:
376:                Class[] interfaces = clazz.getInterfaces();
377:                for (int i = 0; i < interfaces.length; i++) {
378:                    discoverAccessibleMethods(interfaces[i], map,
379:                            includeProtected);
380:                }
381:                Class super class = clazz.getSuperclass();
382:                if (super class != null) {
383:                    discoverAccessibleMethods(super class, map, includeProtected);
384:                }
385:            }
386:
387:            private static final class MethodSignature {
388:                private final String name;
389:                private final Class[] args;
390:
391:                private MethodSignature(String name, Class[] args) {
392:                    this .name = name;
393:                    this .args = args;
394:                }
395:
396:                MethodSignature(Method method) {
397:                    this (method.getName(), method.getParameterTypes());
398:                }
399:
400:                public boolean equals(Object o) {
401:                    if (o instanceof  MethodSignature) {
402:                        MethodSignature ms = (MethodSignature) o;
403:                        return ms.name.equals(name)
404:                                && Arrays.equals(args, ms.args);
405:                    }
406:                    return false;
407:                }
408:
409:                public int hashCode() {
410:                    return name.hashCode() ^ args.length;
411:                }
412:            }
413:
414:            private void reflect(Scriptable scope, boolean includeProtected) {
415:                // We reflect methods first, because we want overloaded field/method
416:                // names to be allocated to the NativeJavaMethod before the field
417:                // gets in the way.
418:
419:                Method[] methods = discoverAccessibleMethods(cl,
420:                        includeProtected);
421:                for (int i = 0; i < methods.length; i++) {
422:                    Method method = methods[i];
423:                    int mods = method.getModifiers();
424:                    boolean isStatic = Modifier.isStatic(mods);
425:                    Hashtable ht = isStatic ? staticMembers : members;
426:                    String name = method.getName();
427:                    Object value = ht.get(name);
428:                    if (value == null) {
429:                        ht.put(name, method);
430:                    } else {
431:                        ObjArray overloadedMethods;
432:                        if (value instanceof  ObjArray) {
433:                            overloadedMethods = (ObjArray) value;
434:                        } else {
435:                            if (!(value instanceof  Method))
436:                                Kit.codeBug();
437:                            // value should be instance of Method as at this stage
438:                            // staticMembers and members can only contain methods
439:                            overloadedMethods = new ObjArray();
440:                            overloadedMethods.add(value);
441:                            ht.put(name, overloadedMethods);
442:                        }
443:                        overloadedMethods.add(method);
444:                    }
445:                }
446:
447:                // replace Method instances by wrapped NativeJavaMethod objects
448:                // first in staticMembers and then in members
449:                for (int tableCursor = 0; tableCursor != 2; ++tableCursor) {
450:                    boolean isStatic = (tableCursor == 0);
451:                    Hashtable ht = (isStatic) ? staticMembers : members;
452:                    Enumeration e = ht.keys();
453:                    while (e.hasMoreElements()) {
454:                        String name = (String) e.nextElement();
455:                        MemberBox[] methodBoxes;
456:                        Object value = ht.get(name);
457:                        if (value instanceof  Method) {
458:                            methodBoxes = new MemberBox[1];
459:                            methodBoxes[0] = new MemberBox((Method) value);
460:                        } else {
461:                            ObjArray overloadedMethods = (ObjArray) value;
462:                            int N = overloadedMethods.size();
463:                            if (N < 2)
464:                                Kit.codeBug();
465:                            methodBoxes = new MemberBox[N];
466:                            for (int i = 0; i != N; ++i) {
467:                                Method method = (Method) overloadedMethods
468:                                        .get(i);
469:                                methodBoxes[i] = new MemberBox(method);
470:                            }
471:                        }
472:                        NativeJavaMethod fun = new NativeJavaMethod(methodBoxes);
473:                        if (scope != null) {
474:                            ScriptRuntime.setFunctionProtoAndParent(fun, scope);
475:                        }
476:                        ht.put(name, fun);
477:                    }
478:                }
479:
480:                // Reflect fields.
481:                Field[] fields = cl.getFields();
482:                for (int i = 0; i < fields.length; i++) {
483:                    Field field = fields[i];
484:                    int mods = field.getModifiers();
485:                    if (!Modifier.isPublic(mods)) {
486:                        continue;
487:                    }
488:                    boolean isStatic = Modifier.isStatic(mods);
489:                    Hashtable ht = isStatic ? staticMembers : members;
490:                    String name = field.getName();
491:                    Object member = ht.get(name);
492:                    if (member == null) {
493:                        ht.put(name, field);
494:                    } else if (member instanceof  NativeJavaMethod) {
495:                        NativeJavaMethod method = (NativeJavaMethod) member;
496:                        FieldAndMethods fam = new FieldAndMethods(scope,
497:                                method.methods, field);
498:                        Hashtable fmht = isStatic ? staticFieldAndMethods
499:                                : fieldAndMethods;
500:                        if (fmht == null) {
501:                            fmht = new Hashtable(4);
502:                            if (isStatic) {
503:                                staticFieldAndMethods = fmht;
504:                            } else {
505:                                fieldAndMethods = fmht;
506:                            }
507:                        }
508:                        fmht.put(name, fam);
509:                        ht.put(name, fam);
510:                    } else if (member instanceof  Field) {
511:                        Field oldField = (Field) member;
512:                        // If this newly reflected field shadows an inherited field,
513:                        // then replace it. Otherwise, since access to the field
514:                        // would be ambiguous from Java, no field should be reflected.
515:                        // For now, the first field found wins, unless another field
516:                        // explicitly shadows it.
517:                        if (oldField.getDeclaringClass().isAssignableFrom(
518:                                field.getDeclaringClass())) {
519:                            ht.put(name, field);
520:                        }
521:                    } else {
522:                        // "unknown member type"
523:                        Kit.codeBug();
524:                    }
525:                }
526:
527:                // Create bean propeties from corresponding get/set methods first for
528:                // static members and then for instance members
529:                for (int tableCursor = 0; tableCursor != 2; ++tableCursor) {
530:                    boolean isStatic = (tableCursor == 0);
531:                    Hashtable ht = (isStatic) ? staticMembers : members;
532:
533:                    Hashtable toAdd = new Hashtable();
534:
535:                    // Now, For each member, make "bean" properties.
536:                    for (Enumeration e = ht.keys(); e.hasMoreElements();) {
537:
538:                        // Is this a getter?
539:                        String name = (String) e.nextElement();
540:                        boolean memberIsGetMethod = name.startsWith("get");
541:                        boolean memberIsSetMethod = name.startsWith("set");
542:                        boolean memberIsIsMethod = name.startsWith("is");
543:                        if (memberIsGetMethod || memberIsIsMethod
544:                                || memberIsSetMethod) {
545:                            // Double check name component.
546:                            String nameComponent = name
547:                                    .substring(memberIsIsMethod ? 2 : 3);
548:                            if (nameComponent.length() == 0)
549:                                continue;
550:
551:                            // Make the bean property name.
552:                            String beanPropertyName = nameComponent;
553:                            char ch0 = nameComponent.charAt(0);
554:                            if (Character.isUpperCase(ch0)) {
555:                                if (nameComponent.length() == 1) {
556:                                    beanPropertyName = nameComponent
557:                                            .toLowerCase();
558:                                } else {
559:                                    char ch1 = nameComponent.charAt(1);
560:                                    if (!Character.isUpperCase(ch1)) {
561:                                        beanPropertyName = Character
562:                                                .toLowerCase(ch0)
563:                                                + nameComponent.substring(1);
564:                                    }
565:                                }
566:                            }
567:
568:                            // If we already have a member by this name, don't do this
569:                            // property.
570:                            if (ht.containsKey(beanPropertyName)
571:                                    || toAdd.containsKey(beanPropertyName)) {
572:                                continue;
573:                            }
574:
575:                            // Find the getter method, or if there is none, the is-
576:                            // method.
577:                            MemberBox getter = null;
578:                            getter = findGetter(isStatic, ht, "get",
579:                                    nameComponent);
580:                            // If there was no valid getter, check for an is- method.
581:                            if (getter == null) {
582:                                getter = findGetter(isStatic, ht, "is",
583:                                        nameComponent);
584:                            }
585:
586:                            // setter
587:                            MemberBox setter = null;
588:                            NativeJavaMethod setters = null;
589:                            String setterName = "set".concat(nameComponent);
590:
591:                            if (ht.containsKey(setterName)) {
592:                                // Is this value a method?
593:                                Object member = ht.get(setterName);
594:                                if (member instanceof  NativeJavaMethod) {
595:                                    NativeJavaMethod njmSet = (NativeJavaMethod) member;
596:                                    if (getter != null) {
597:                                        // We have a getter. Now, do we have a matching 
598:                                        // setter?
599:                                        Class type = getter.method()
600:                                                .getReturnType();
601:                                        setter = extractSetMethod(type,
602:                                                njmSet.methods, isStatic);
603:                                    } else {
604:                                        // No getter, find any set method
605:                                        setter = extractSetMethod(
606:                                                njmSet.methods, isStatic);
607:                                    }
608:                                    if (njmSet.methods.length > 1) {
609:                                        setters = njmSet;
610:                                    }
611:                                }
612:                            }
613:                            // Make the property.
614:                            BeanProperty bp = new BeanProperty(getter, setter,
615:                                    setters);
616:                            toAdd.put(beanPropertyName, bp);
617:                        }
618:                    }
619:
620:                    // Add the new bean properties.
621:                    for (Enumeration e = toAdd.keys(); e.hasMoreElements();) {
622:                        Object key = e.nextElement();
623:                        Object value = toAdd.get(key);
624:                        ht.put(key, value);
625:                    }
626:                }
627:
628:                // Reflect constructors
629:                Constructor[] constructors = cl.getConstructors();
630:                ctors = new MemberBox[constructors.length];
631:                for (int i = 0; i != constructors.length; ++i) {
632:                    ctors[i] = new MemberBox(constructors[i]);
633:                }
634:            }
635:
636:            private MemberBox findGetter(boolean isStatic, Hashtable ht,
637:                    String prefix, String propertyName) {
638:                String getterName = prefix.concat(propertyName);
639:                if (ht.containsKey(getterName)) {
640:                    // Check that the getter is a method.
641:                    Object member = ht.get(getterName);
642:                    if (member instanceof  NativeJavaMethod) {
643:                        NativeJavaMethod njmGet = (NativeJavaMethod) member;
644:                        return extractGetMethod(njmGet.methods, isStatic);
645:                    }
646:                }
647:                return null;
648:            }
649:
650:            private static MemberBox extractGetMethod(MemberBox[] methods,
651:                    boolean isStatic) {
652:                // Inspect the list of all MemberBox for the only one having no
653:                // parameters
654:                for (int methodIdx = 0; methodIdx < methods.length; methodIdx++) {
655:                    MemberBox method = methods[methodIdx];
656:                    // Does getter method have an empty parameter list with a return
657:                    // value (eg. a getSomething() or isSomething())?
658:                    if (method.argTypes.length == 0
659:                            && (!isStatic || method.isStatic())) {
660:                        Class type = method.method().getReturnType();
661:                        if (type != Void.TYPE) {
662:                            return method;
663:                        }
664:                        break;
665:                    }
666:                }
667:                return null;
668:            }
669:
670:            private static MemberBox extractSetMethod(Class type,
671:                    MemberBox[] methods, boolean isStatic) {
672:                //
673:                // Note: it may be preferable to allow NativeJavaMethod.findFunction()
674:                //       to find the appropriate setter; unfortunately, it requires an
675:                //       instance of the target arg to determine that.
676:                //
677:
678:                // Make two passes: one to find a method with direct type assignment,
679:                // and one to find a widening conversion.
680:                for (int pass = 1; pass <= 2; ++pass) {
681:                    for (int i = 0; i < methods.length; ++i) {
682:                        MemberBox method = methods[i];
683:                        if (!isStatic || method.isStatic()) {
684:                            if (method.method().getReturnType() == Void.TYPE) {
685:                                Class[] params = method.argTypes;
686:                                if (params.length == 1) {
687:                                    if (pass == 1) {
688:                                        if (params[0] == type) {
689:                                            return method;
690:                                        }
691:                                    } else {
692:                                        if (pass != 2)
693:                                            Kit.codeBug();
694:                                        if (params[0].isAssignableFrom(type)) {
695:                                            return method;
696:                                        }
697:                                    }
698:                                }
699:                            }
700:                        }
701:                    }
702:                }
703:                return null;
704:            }
705:
706:            private static MemberBox extractSetMethod(MemberBox[] methods,
707:                    boolean isStatic) {
708:
709:                for (int i = 0; i < methods.length; ++i) {
710:                    MemberBox method = methods[i];
711:                    if (!isStatic || method.isStatic()) {
712:                        if (method.method().getReturnType() == Void.TYPE) {
713:                            if (method.argTypes.length == 1) {
714:                                return method;
715:                            }
716:                        }
717:                    }
718:                }
719:                return null;
720:            }
721:
722:            Hashtable getFieldAndMethodsObjects(Scriptable scope,
723:                    Object javaObject, boolean isStatic) {
724:                Hashtable ht = isStatic ? staticFieldAndMethods
725:                        : fieldAndMethods;
726:                if (ht == null)
727:                    return null;
728:                int len = ht.size();
729:                Hashtable result = new Hashtable(len);
730:                Enumeration e = ht.elements();
731:                while (len-- > 0) {
732:                    FieldAndMethods fam = (FieldAndMethods) e.nextElement();
733:                    FieldAndMethods famNew = new FieldAndMethods(scope,
734:                            fam.methods, fam.field);
735:                    famNew.javaObject = javaObject;
736:                    result.put(fam.field.getName(), famNew);
737:                }
738:                return result;
739:            }
740:
741:            static JavaMembers lookupClass(Scriptable scope, Class dynamicType,
742:                    Class staticType, boolean includeProtected) {
743:                JavaMembers members;
744:                ClassCache cache = ClassCache.get(scope);
745:                Hashtable ct = cache.classTable;
746:
747:                Class cl = dynamicType;
748:                for (;;) {
749:                    members = (JavaMembers) ct.get(cl);
750:                    if (members != null) {
751:                        return members;
752:                    }
753:                    try {
754:                        members = new JavaMembers(cache.scope, cl,
755:                                includeProtected);
756:                        break;
757:                    } catch (SecurityException e) {
758:                        // Reflection may fail for objects that are in a restricted
759:                        // access package (e.g. sun.*).  If we get a security
760:                        // exception, try again with the static type if it is interface.
761:                        // Otherwise, try superclass
762:                        if (staticType != null && staticType.isInterface()) {
763:                            cl = staticType;
764:                            staticType = null; // try staticType only once
765:                        } else {
766:                            Class parent = cl.getSuperclass();
767:                            if (parent == null) {
768:                                if (cl.isInterface()) {
769:                                    // last resort after failed staticType interface
770:                                    parent = ScriptRuntime.ObjectClass;
771:                                } else {
772:                                    throw e;
773:                                }
774:                            }
775:                            cl = parent;
776:                        }
777:                    }
778:                }
779:
780:                if (cache.isCachingEnabled())
781:                    ct.put(cl, members);
782:                return members;
783:            }
784:
785:            RuntimeException reportMemberNotFound(String memberName) {
786:                return Context.reportRuntimeError2("msg.java.member.not.found",
787:                        cl.getName(), memberName);
788:            }
789:
790:            private Class cl;
791:            private Hashtable members;
792:            private Hashtable fieldAndMethods;
793:            private Hashtable staticMembers;
794:            private Hashtable staticFieldAndMethods;
795:            MemberBox[] ctors;
796:        }
797:
798:        class BeanProperty {
799:            BeanProperty(MemberBox getter, MemberBox setter,
800:                    NativeJavaMethod setters) {
801:                this .getter = getter;
802:                this .setter = setter;
803:                this .setters = setters;
804:            }
805:
806:            MemberBox getter;
807:            MemberBox setter;
808:            NativeJavaMethod setters;
809:        }
810:
811:        class FieldAndMethods extends NativeJavaMethod {
812:            static final long serialVersionUID = -9222428244284796755L;
813:
814:            FieldAndMethods(Scriptable scope, MemberBox[] methods, Field field) {
815:                super (methods);
816:                this .field = field;
817:                setParentScope(scope);
818:                setPrototype(ScriptableObject.getFunctionPrototype(scope));
819:            }
820:
821:            public Object getDefaultValue(Class hint) {
822:                if (hint == ScriptRuntime.FunctionClass)
823:                    return this ;
824:                Object rval;
825:                Class type;
826:                try {
827:                    rval = field.get(javaObject);
828:                    type = field.getType();
829:                } catch (IllegalAccessException accEx) {
830:                    throw Context.reportRuntimeError1(
831:                            "msg.java.internal.private", field.getName());
832:                }
833:                Context cx = Context.getContext();
834:                rval = cx.getWrapFactory().wrap(cx, this , rval, type);
835:                if (rval instanceof  Scriptable) {
836:                    rval = ((Scriptable) rval).getDefaultValue(hint);
837:                }
838:                return rval;
839:            }
840:
841:            Field field;
842:            Object javaObject;
843:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.