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