Source Code Cross Referenced for Proxies.java in  » EJB-Server-JBoss-4.2.1 » server » org » jboss » proxy » compiler » 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 » EJB Server JBoss 4.2.1 » server » org.jboss.proxy.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * JBoss, Home of Professional Open Source.
003:         * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004:         * as indicated by the @author tags. See the copyright.txt file in the
005:         * distribution for a full listing of individual contributors.
006:         *
007:         * This is free software; you can redistribute it and/or modify it
008:         * under the terms of the GNU Lesser General Public License as
009:         * published by the Free Software Foundation; either version 2.1 of
010:         * the License, or (at your option) any later version.
011:         *
012:         * This software is distributed in the hope that it will be useful,
013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015:         * Lesser General Public License for more details.
016:         *
017:         * You should have received a copy of the GNU Lesser General Public
018:         * License along with this software; if not, write to the Free
019:         * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021:         */
022:        package org.jboss.proxy.compiler;
023:
024:        import java.lang.reflect.Method;
025:        import java.lang.reflect.Constructor;
026:        import java.lang.reflect.InvocationTargetException;
027:        import java.lang.reflect.Modifier;
028:        import java.lang.reflect.Member;
029:
030:        import java.io.Serializable;
031:
032:        import java.util.ArrayList;
033:        import java.util.Hashtable;
034:
035:        /**
036:         * Routines for converting between strongly-typed interfaces and
037:         * generic InvocationHandler objects.
038:         *
039:         * @version <tt>$Revision: 57209 $</tt>
040:         * @author Unknown
041:         * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
042:         */
043:        public final class Proxies {
044:            /**
045:             * Disallow creation of Proxyies instances.
046:             */
047:            private Proxies() {
048:                super ();
049:            }
050:
051:            /**
052:             * Create a new target object <em>x</em> which is a proxy for
053:             * the given InvocationHandler <tt>disp</tt>.  The new object will be
054:             * equivalent to <tt>disp</tt>, except that it will support normal Java
055:             * method invocation, in place of the <tt>InvocationHandler.invoke</tt>
056:             * protocol, for each method supported by the InvocationHandler.
057:             *
058:             * <p>
059:             * The new object will implement each of the given target types.
060:             * (The target types default to those declared by the InvocationHandler
061:             * itself.) The new object will also implement the "administrative"
062:             * interface <tt>Proxies.ProxyTarget</tt>.
063:             *
064:             * <p>
065:             * For each "overrideable" (public, non-static, non-final)
066:             * method <tt>T.m</tt> of <tt>T</tt>, calling <tt>x.m(...)</tt>
067:             * will immediately cause a corresponding reflective call of the
068:             * form <tt>disp.invoke(RM, new Object[]{ ... })</tt>, where <tt>RM</tt>
069:             * is the reflective object for <tt>m</tt>.
070:             *
071:             * <p>
072:             * The concrete class of this target object will be
073:             * something mysterious and indefinite.  Many callers will
074:             * immediately cast the resulting proxy object to the target type
075:             * of the InvocationHandler.  For example:
076:             * <code>
077:             * MyInterface x1 = ...;
078:             * InvocationHandler i = Proxies.newInvocationHandler(x1, MyInterface.class);
079:             * MyInterface x2 = (MyInterface) ((Proxies.ProxyInvocationHandler)i).getTarget();
080:             *   // x1 == x2
081:             * MyInterface x3 = (MyInterface) Proxies.newTarget(i);
082:             *   // x1 != x3, but calls to x3 are forwarded via i to x1
083:             * </code>    
084:             */
085:            public static ProxyTarget newTarget(ClassLoader parent,
086:                    InvocationHandler invocationHandler, Class targetTypes[])
087:                    throws Exception {
088:                return Impl.getImpl(targetTypes).newTarget(invocationHandler,
089:                        parent);
090:            }
091:
092:            /**
093:             * A common interface shared by all objects created
094:             * by <tt>Proxies.newTarget</tt>.
095:             */
096:            public interface ProxyTarget extends Serializable {
097:                /**
098:                 * Recover the original InvocationHandler object around which this
099:                 * proxy is wrapped.
100:                 */
101:                InvocationHandler getInvocationHandler();
102:
103:                /**
104:                 * Recover the original target types for which this proxy was wrapped.
105:                 */
106:                Class[] getTargetTypes();
107:            }
108:
109:            /**
110:             * Create a new reflective InvocationHandler object
111:             * <tt>InvocationHandler</tt> wrapped around the given target object, for
112:             * the given target type(s).
113:             *
114:             * <p>
115:             * The new object will be operationally equivalent to <tt>target</tt>,
116:             * except that it will support a reflective method invocation sequence
117:             * (<tt>InvocationHandler.invoke</tt>) instead of the normal Java method
118:             * invocation mechanism.
119:             *
120:             * <p>
121:             * The target type must be specified, since the complete implementation
122:             * type of the target object is usually irrelevant to the application.
123:             * The target object must match the specified target type.
124:             * For example:
125:             * <code>
126:             * MyInterface x1 = ...;
127:             * InvocationHandler i = Proxies.newInvocationHandler(x1, MyInterface.class);
128:             * </code>
129:             */
130:            public static ProxyInvocationHandler newInvocationHandler(
131:                    Object target, Class targetType) {
132:                return Impl.getImpl(targetType).newInvocationHandler(target);
133:            }
134:
135:            public static ProxyInvocationHandler newInvocationHandler(
136:                    Object target, Class targetTypes[]) {
137:                return Impl.getImpl(targetTypes).newInvocationHandler(target);
138:            }
139:
140:            /**
141:             * A common interface shared by all objects created
142:             * by <tt>Proxies.newInvocationHandler</tt>.
143:             */
144:            public interface ProxyInvocationHandler extends InvocationHandler,
145:                    Serializable {
146:                /**
147:                 * Recover the original target object around which this
148:                 * InvocationHandler proxy is wrapped.
149:                 */
150:                Object getTarget();
151:            }
152:
153:            /**
154:             * Utility built on top of <tt>newTarget</tt> to find
155:             * or create a proxy for the given InvocationHandler.
156:             * It is the inverse of <tt>getInvocationHandler</tt>.
157:             *
158:             * <p>
159:             * If the InvocationHandler implements <tt>ProxyInvocationHandler</tt>,
160:             * it is a proxy for some original target object; extract and return
161:             * that object.  Otherwise, just call <tt>newTarget</tt>.
162:             */
163:            public static Object getTarget(InvocationHandler invocationHandler) {
164:                if (invocationHandler instanceof  ProxyInvocationHandler) {
165:                    Object target = ((ProxyInvocationHandler) invocationHandler)
166:                            .getTarget();
167:                    if (target != null) {
168:                        return target;
169:                    }
170:                    // and fall through...
171:                }
172:
173:                return null;
174:            }
175:
176:            /**
177:             * Utility built on top of <tt>newInvocationHandler</tt> to find
178:             * or create a proxy for the given target object.
179:             * It is the inverse of <tt>getTarget</tt>.
180:             *
181:             * <p>
182:             * If the target implements <tt>ProxyTarget</tt>, it is a proxy
183:             * for some original InvocationHandler; extract and return that
184:             * InvocationHandler.  Otherwise, just call <tt>newInvocationHandler</tt>.
185:             *
186:             * @see #newInvocationHandler
187:             */
188:            public static InvocationHandler getInvocationHandler(Object target,
189:                    Class targetTypes[]) {
190:                if (target instanceof  ProxyTarget) {
191:                    ProxyTarget tproxy = (ProxyTarget) target;
192:                    InvocationHandler invocationHandler = tproxy
193:                            .getInvocationHandler();
194:                    if (targetTypes == null
195:                            || Impl.sameTypes(tproxy.getTargetTypes(),
196:                                    targetTypes)) {
197:                        return invocationHandler;
198:                    }
199:                    // and fall through...
200:                }
201:                return newInvocationHandler(target, targetTypes);
202:            }
203:
204:            public static InvocationHandler getInvocationHandler(Object target,
205:                    Class targetType) {
206:                // (should this be optimized?)
207:                if (targetType == null) {
208:                    return getInvocationHandler(target, (Class[]) null);
209:                }
210:
211:                return getInvocationHandler(target, new Class[] { targetType });
212:            }
213:
214:            /**
215:             * Utility which reports the set of valid methods for a target type.
216:             * It is exactly the set of <tt>public</tt>, <tt>abstract</tt> methods
217:             * returned by <tt>targetType.getMethods()</tt>, which are neither
218:             * <tt>static</tt> nor <tt>final</tt>.
219:             * <p>
220:             * Also, if the targetType is not a suitable type, an empty array
221:             * will be returned.  The target type must not contain <tt>protected</tt>
222:             * <tt>abstract</tt> methods, must have a nullary constructor,
223:             * and must not be something silly like
224:             * an array or primitive type, or a <tt>final</tt> class.
225:             */
226:            public static Method[] getMethods(Class targetType) {
227:                return Impl.getImpl(targetType).copyMethods();
228:            }
229:
230:            public static Method[] getMethods(Class targetTypes[]) {
231:                return Impl.getImpl(targetTypes).copyMethods();
232:            }
233:
234:            public static void forgetProxyForClass(Class clazz) {
235:                Impl.forgetProxyForClass(clazz);
236:            }
237:
238:            /**
239:             * ???
240:             */
241:            static class Impl implements  Serializable {
242:                static final long serialVersionUID = 2911933124627738645L;
243:                static Hashtable impls = new Hashtable();
244:
245:                /** the types that this impl processes */
246:                Class targetTypes[];
247:
248:                Method methods[];
249:
250:                /** hashtable link to Impls sharing a target type */
251:                Impl more;
252:
253:                Class super class = Object.class;
254:
255:                /** used in print names of proxies */
256:                String proxyString;
257:
258:                Constructor proxyConstructor;
259:
260:                Impl(Class targetTypes[]) {
261:                    this .targetTypes = targetTypes;
262:
263:                    Method methodLists[][] = new Method[targetTypes.length][];
264:                    for (int i = 0; i < targetTypes.length; i++) {
265:                        methodLists[i] = checkTargetType(targetTypes[i]);
266:                    }
267:
268:                    checkSuperclass();
269:                    this .methods = combineMethodLists(methodLists);
270:                }
271:
272:                static synchronized Impl getImpl(Class targetType) {
273:                    Impl impl = (Impl) impls.get(targetType);
274:                    if (impl == null) {
275:                        impl = new Impl(new Class[] { targetType });
276:                        impls.put(targetType, impl);
277:                    }
278:                    return impl;
279:                }
280:
281:                static synchronized Impl getImpl(Class targetTypes[]) {
282:                    int n = targetTypes.length;
283:                    if (n == 1) {
284:                        return getImpl(targetTypes[0]);
285:                    }
286:                    // note that the desired Impl could be in any one of n places
287:                    // this requires extra searching, which is not a big deal
288:                    for (int i = 0; i < n; ++i) {
289:                        for (Impl impl = (Impl) impls.get(targetTypes[i]); impl != null; impl = impl.more) {
290:                            if (sameTypes(targetTypes, impl.targetTypes))
291:                                return impl;
292:                        }
293:                    }
294:
295:                    // now link it into the table
296:                    targetTypes = copyAndUniquify(targetTypes);
297:                    Impl impl1 = getImpl(new Class[] { targetTypes[0] });
298:                    Impl impl = new Impl(targetTypes);
299:                    impl.more = impl1.more;
300:                    impl1.more = impl;
301:                    return impl;
302:                }
303:
304:                /**
305:                 * The <code>forgetProxyForClass</code> method removes the impl from the 
306:                 * class-impl map.  This releases the UnifiedClassloader used to load the 
307:                 * class we are constructing the proxy for.
308:                 *
309:                 * This may not work if the original class[] contained many classes, but
310:                 * seems OK with one class + Serializable, which is what is used by the cmp2
311:                 * engine.  At present the cmp2 engine is the only caller of this method 
312:                 * (through Proxy).
313:                 *
314:                 * @param clazz a <code>Class</code> value
315:                 */
316:                static synchronized void forgetProxyForClass(Class clazz) {
317:                    impls.remove(clazz);
318:                }
319:
320:                // do the arrays have the same elements?
321:                // (duplication and reordering are ignored)
322:                static boolean sameTypes(Class tt1[], Class tt2[]) {
323:                    if (tt1.length == 1 && tt2.length == 1) {
324:                        return tt1[0] == tt2[0];
325:                    }
326:
327:                    int totalSeen2 = 0;
328:                    each_type: for (int i = tt1.length; --i >= 0;) {
329:                        Class c = tt1[i];
330:                        for (int j = i; --j >= 0;) {
331:                            if (c == tt1[j]) {
332:                                continue each_type;
333:                            }
334:                        }
335:                        // now c is a uniquified element of tt1
336:                        // count its occurrences in tt2
337:                        int seen2 = 0;
338:                        for (int j = tt2.length; --j >= 0;) {
339:                            if (c == tt2[j]) {
340:                                ++seen2;
341:                            }
342:                        }
343:
344:                        if (seen2 == 0) {
345:                            // c does not occur in tt2
346:                            return false;
347:                        }
348:                        totalSeen2 += seen2;
349:                    }
350:                    // now, each element of tt2 must have been visited
351:                    return totalSeen2 == tt2.length;
352:                }
353:
354:                static Class[] copyAndUniquify(Class targetTypes[]) {
355:                    int n = targetTypes.length;
356:                    Class tt[] = new Class[n];
357:                    int k = 0;
358:                    each_type: for (int i = 0; i < n; i++) {
359:                        Class c = targetTypes[i];
360:                        for (int j = i; --j >= 0;) {
361:                            if (c == targetTypes[j]) {
362:                                continue each_type;
363:                            }
364:                        }
365:                        tt[k++] = c;
366:                    }
367:                    if (k < n) {
368:                        // oops; caller passed in duplicate
369:                        Class tt0[] = new Class[k];
370:                        for (int i = 0; i < k; i++) {
371:                            tt0[i] = tt[i];
372:                        }
373:                        tt = tt0;
374:                    }
375:                    return tt;
376:                }
377:
378:                // make sure a give target type is acceptable
379:                // return a list of eligible methods (may also include nulls)
380:                Method[] checkTargetType(Class targetType) {
381:                    if (targetType.isArray()) {
382:                        throw new IllegalArgumentException(
383:                                "cannot subclass an array type: "
384:                                        + targetType.getName());
385:                    }
386:
387:                    if (targetType.isPrimitive()) {
388:                        throw new IllegalArgumentException(
389:                                "cannot subclass a primitive type: "
390:                                        + targetType);
391:                    }
392:
393:                    int tmod = targetType.getModifiers();
394:                    if (Modifier.isFinal(tmod)) {
395:                        throw new IllegalArgumentException(
396:                                "cannot subclass a final type: " + targetType);
397:                    }
398:
399:                    if (!Modifier.isPublic(tmod)) {
400:                        throw new IllegalArgumentException(
401:                                "cannot subclass a non-public type: "
402:                                        + targetType);
403:                    }
404:
405:                    // Make sure the subclass will not need a "super" statement.
406:                    if (!targetType.isInterface()) {
407:                        if (!targetType.isAssignableFrom(super class)) {
408:                            if (super class.isAssignableFrom(targetType)) {
409:                                super class = targetType;
410:                            } else {
411:                                throw new IllegalArgumentException(
412:                                        "inconsistent superclass: "
413:                                                + targetType);
414:                            }
415:                        }
416:                    }
417:
418:                    // Decide what overrideable methods this type supports.
419:                    Method methodList[] = targetType.getMethods();
420:                    int nm = 0;
421:                    for (int i = 0; i < methodList.length; i++) {
422:                        Method m = methodList[i];
423:                        if (eligibleForInvocationHandler(m)) {
424:                            methodList[nm++] = m; // (reuse the method array)
425:                        }
426:                    }
427:
428:                    while (nm < methodList.length) {
429:                        methodList[nm++] = null; // (pad the reused method array)
430:                    }
431:
432:                    return methodList;
433:                }
434:
435:                void checkSuperclass() {
436:                    Constructor constructors[] = super class.getConstructors();
437:                    for (int i = 0; i < constructors.length; i++) {
438:                        Constructor c = constructors[i];
439:                        int mod = c.getModifiers();
440:                        if (Modifier.isPublic(mod)
441:                                && c.getParameterTypes().length == 0) {
442:                            return; // OK
443:                        }
444:                    }
445:
446:                    throw new IllegalArgumentException(
447:                            "cannot subclass without nullary constructor: "
448:                                    + super class.getName());
449:                }
450:
451:                /**
452:                 * Tell if a given method will be passed by a proxy to its
453:                 * InvocationHandler
454:                 */
455:                static boolean eligibleForInvocationHandler(Method m) {
456:                    int mod = m.getModifiers();
457:
458:                    if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
459:                        // can't override these
460:                        return false;
461:                    }
462:
463:                    if (!Modifier.isAbstract(mod)) {
464:                        // do not support methods with "super"
465:                        return false;
466:                    }
467:
468:                    return true;
469:                }
470:
471:                /**
472:                 * Are the 2 methods equal in terms of conflicting with each other.
473:                 * i.e. String toString() and Map toString() are equal since only one
474:                 * toString() can be defined in a class.
475:                 * Also fixes problems with complex inheritance graphs and j2se1.4
476:                 */
477:                static boolean areEqual(Method m1, Method m2) {
478:                    // Check method names.
479:                    if (!m1.getName().equals(m2.getName()))
480:                        return false;
481:
482:                    // Check parameters
483:                    Class a1[] = m1.getParameterTypes();
484:                    Class a2[] = m2.getParameterTypes();
485:                    if (a1.length != a2.length)
486:                        return false;
487:                    for (int i = 0; i < a1.length; i++)
488:                        if (!a1[i].equals(a2[i]))
489:                            return false;
490:
491:                    return true;
492:                }
493:
494:                /**
495:                 * Combine the given list of method[]'s into one method[],
496:                 * removing any methods duplicates.
497:                 */
498:                static Method[] combineMethodLists(Method methodLists[][]) {
499:                    int nm = 0;
500:                    for (int i = 0; i < methodLists.length; i++) {
501:                        nm += methodLists[i].length;
502:                    }
503:                    Method methods[] = new Method[nm];
504:
505:                    // Merge the methods into a single array.
506:                    nm = 0;
507:                    for (int i = 0; i < methodLists.length; i++)
508:                        for (int j = 0; j < methodLists[i].length; j++)
509:                            methods[nm++] = methodLists[i][j];
510:
511:                    // Remove duplicate methods. (set them to null)
512:                    for (int i = 0; i < methods.length; i++) {
513:                        if (methods[i] == null)
514:                            continue;
515:                        for (int j = i + 1; j < methods.length; j++) {
516:                            if (methods[j] == null)
517:                                continue;
518:                            if (areEqual(methods[i], methods[j])) {
519:                                methods[j] = null;
520:                                nm--;
521:                            }
522:                        }
523:                    }
524:
525:                    // shorten and copy the array
526:                    ArrayList tmp = new ArrayList();
527:                    for (int i = 0; i < methods.length; i++) {
528:                        if (methods[i] != null)
529:                            tmp.add(methods[i]);
530:                    }
531:                    Method methodsCopy[] = new Method[tmp.size()];
532:                    tmp.toArray(methodsCopy);
533:                    return methodsCopy;
534:                }
535:
536:                Method[] copyMethods() {
537:                    return (Method[]) methods.clone();
538:                }
539:
540:                Class[] copyTargetTypes() {
541:                    return (Class[]) targetTypes.clone();
542:                }
543:
544:                ProxyTarget newTarget(InvocationHandler invocationHandler,
545:                        ClassLoader parent) throws Exception {
546:                    if (proxyConstructor == null) {
547:                        // make the proxy constructor
548:                        ProxyCompiler pc = new ProxyCompiler(parent,
549:                                super class, targetTypes, methods);
550:
551:                        Class type[] = { InvocationHandler.class };
552:                        proxyConstructor = pc.getProxyType().getConstructor(
553:                                type);
554:                    }
555:
556:                    Object args[] = { invocationHandler };
557:                    return (ProxyTarget) proxyConstructor.newInstance(args);
558:                }
559:
560:                ProxyInvocationHandler newInvocationHandler(final Object target) {
561:                    if (proxyString == null) {
562:                        String s = "InvocationHandler@"
563:                                + targetTypes[0].getName();
564:                        for (int i = 1; i < targetTypes.length; i++) {
565:                            s += "," + targetTypes[i].getName();
566:                        }
567:                        proxyString = s;
568:                    }
569:
570:                    return new ProxyInvocationHandler() {
571:                        // (ISSUE: Should this be made subclassable?)
572:                        public Object getTarget() {
573:                            return target;
574:                        }
575:
576:                        public Class[] getTargetTypes() {
577:                            return copyTargetTypes();
578:                        }
579:
580:                        public String toString() {
581:                            return proxyString + "[" + target + "]";
582:                        }
583:
584:                        public Object invoke(Object dummy, Method method,
585:                                Object values[]) throws Throwable {
586:                            return Impl.this .invoke(target, method, values);
587:                        }
588:                    };
589:                }
590:
591:                /** 
592:                 * The heart of a ProxyInvocationHandler.
593:                 */
594:                Object invoke(Object target, Member method, Object values[])
595:                        throws Throwable {
596:                    // Note:  
597:                    //
598:                    // We will not invoke the method unless we are expecting it.
599:                    // Thus, we cannot blindly call Method.invoke, but must first
600:                    // check our list of allowed methods.
601:
602:                    try {
603:                        Method methods[] = this .methods; // cache
604:
605:                        // use fast pointer equality (it usually succeeds)
606:                        for (int i = methods.length; --i >= 0;) {
607:                            if (methods[i] == method) {
608:                                return methods[i].invoke(target, values);
609:                            }
610:                        }
611:
612:                        // special case:  allow a null method to select the unique one
613:                        if (method == null) {
614:                            if (methods.length == 1) {
615:                                return methods[0].invoke(target, values);
616:                            }
617:                            throw new IllegalArgumentException(
618:                                    "non-unique method");
619:                        }
620:
621:                        // try the slower form of equality
622:                        for (int i = methods.length; --i >= 0;) {
623:                            if (methods[i].equals(method)) {
624:                                return methods[i].invoke(target, values);
625:                            }
626:                        }
627:
628:                    } catch (InvocationTargetException e) {
629:                        throw e.getTargetException();
630:                    }
631:
632:                    throw new IllegalArgumentException("method unexpected "
633:                            + method);
634:                }
635:            }
636:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.