Source Code Cross Referenced for OptimizedMBeanDispatcher.java in  » EJB-Server-JBoss-4.2.1 » jmx » org » jboss » mx » capability » 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 » jmx » org.jboss.mx.capability 
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.mx.capability;
023:
024:        import org.apache.bcel.Constants;
025:        import org.apache.bcel.classfile.JavaClass;
026:        import org.apache.bcel.generic.*;
027:        import org.jboss.mx.metadata.AttributeOperationResolver;
028:        import org.jboss.mx.server.ServerConstants;
029:
030:        import javax.management.MBeanException;
031:        import javax.management.MBeanInfo;
032:        import javax.management.MBeanOperationInfo;
033:        import javax.management.MBeanParameterInfo;
034:        import javax.management.ReflectionException;
035:        import java.io.BufferedOutputStream;
036:        import java.io.ByteArrayOutputStream;
037:        import java.lang.reflect.Constructor;
038:        import java.util.ArrayList;
039:        import java.util.HashMap;
040:        import java.util.Iterator;
041:
042:        /**
043:         * Byte code optimized dispatcher for Standard MBeans. This dispatcher generates
044:         * an invoke implementation that handles the operation dispatching without
045:         * Java reflection.<p>
046:         *
047:         * The use of this dispatcher may be controlled by setting a
048:         * {@link org.jboss.mx.server.ServerConstants#OPTIMIZE_REFLECTED_DISPATCHER OPTIMIZE_REFLECTED_DISPATCHER}
049:         * property to either <tt>"true"</tt> or <tt>"false"</tt> string value.
050:         *
051:         * @see org.jboss.mx.capability.ReflectedMBeanDispatcher
052:         * @see org.jboss.mx.capability.DispatchClassLoader
053:         *
054:         * @author  <a href="mailto:juha@jboss.org">Juha Lindfors</a>.
055:         * @version $Revision: 57200 $
056:         *
057:         */
058:        public class OptimizedMBeanDispatcher implements  ServerConstants {
059:            // Constants -----------------------------------------------------
060:            final static Class SUPER_CLASS = ReflectedMBeanDispatcher.class;
061:
062:            // Static --------------------------------------------------------
063:            public static ReflectedMBeanDispatcher create(MBeanInfo info,
064:                    Object resource) {
065:                try {
066:                    // construct class template
067:                    String className = resource.getClass().getName().replace(
068:                            '.', '_')
069:                            + "_Dispatcher";
070:                    String super Class = SUPER_CLASS.getName();
071:                    String fileName = className + ".class";
072:                    int modifiers = Constants.ACC_PUBLIC;
073:                    String[] interfaces = new String[0];
074:
075:                    ClassGen clazz = new ClassGen(className, super Class,
076:                            fileName, modifiers, interfaces);
077:                    ConstantPoolGen cp = clazz.getConstantPool();
078:
079:                    clazz.addMethod(createConstructor(cp, className)
080:                            .getMethod());
081:                    clazz.addMethod(createInvoke(cp, info, className,
082:                            resource.getClass().getName()).getMethod());
083:                    clazz.update();
084:
085:                    JavaClass c = clazz.getJavaClass();
086:
087:                    ByteArrayOutputStream baos = new ByteArrayOutputStream(2000);
088:                    BufferedOutputStream bos = new BufferedOutputStream(baos);
089:                    c.dump(bos);
090:
091:                    // FIXME: what about ctx cl?
092:                    // FIXME: also I dont know if the parent is right here, have to check later
093:                    ClassLoader ocl = new DispatchClassLoader(resource
094:                            .getClass().getClassLoader(), className, baos
095:                            .toByteArray());
096:
097:                    Class dispatcherClass = ocl.loadClass(className);
098:                    Constructor constr = dispatcherClass
099:                            .getConstructor(new Class[] { MBeanInfo.class,
100:                                    AttributeOperationResolver.class,
101:                                    Object.class });
102:
103:                    Object o = constr.newInstance(new Object[] { info,
104:                            new AttributeOperationResolver(info), resource });
105:
106:                    return (ReflectedMBeanDispatcher) o;
107:                } catch (Exception e) {
108:                    e.printStackTrace();
109:                    throw new Error();
110:                }
111:            }
112:
113:            /**
114:             * Returns the signature of a MBean operation using the grammar required by
115:             * the class file format, excluding the method name. <p>
116:             *
117:             * <h4>The Java Virtual Machine Specification: 4.3.3 Method Descriptors</h4>
118:             *
119:             * A method descriptor represents the parameters that the method takes and the value that it returns:   <br><i><pre>
120:             *
121:             * MethodDescriptor:
122:             *    ( ParameterDescriptor* ) ReturnDescriptor
123:             * </pre></i>
124:             *
125:             * A parameter descriptor represents a parameter passed to a method:   <br><i><pre>
126:             *
127:             * ParameterDescriptor:
128:             *    FieldType
129:             * </pre></i>
130:             *
131:             * A return descriptor represents the type of the value returned from a method. It is a series of characters generated by the grammar:  <br><i><pre>
132:             *
133:             * ReturnDescriptor:
134:             *    FieldType
135:             *    V
136:             * </pre></i>
137:             *
138:             * The character V indicates that the method returns no value (its return type is void).  <p>
139:             *
140:             * For example, the method descriptor for the method <br>
141:             *
142:             * <pre>  Object mymethod(int i, double d, Thread t)  </pre>
143:             *
144:             * is <br>
145:             *
146:             * <b><pre>  (IDLjava/lang/Thread;)Ljava/lang/Object;  </pre></b>
147:             *
148:             * Note that internal forms of the fully qualified names of Thread and Object are used in the method descriptor.
149:             */
150:            public static String getMethodDescriptor(
151:                    MBeanParameterInfo[] signature, String returnType) {
152:
153:                StringBuffer sign = new StringBuffer(256);
154:                sign.append("(");
155:
156:                for (int i = 0; i < signature.length; ++i)
157:                    sign.append(getDescriptorForType(signature[i].getName()));
158:
159:                sign.append(")" + getDescriptorForType(returnType));
160:
161:                return sign.toString();
162:            }
163:
164:            /**
165:             * Returns a descriptor for a given Java type. See {@link java.lang.Class#getName() Class.getName()}
166:             * for details on the grammar for arrays and primitive types. Note that the internal form of the fully
167:             * qualified name for class Object is used, so for example, the returned descriptor for
168:             * <tt>java.lang.Object</tt> is
169:             *
170:             * <b><pre>Ljava/lang/Object;</pre></b>
171:             *
172:             * See JVM spec �4.2 and �4.3 for detailed description of the internal class name format and grammar notation.
173:             *
174:             * @param name  fully qualified name of the Java type
175:             * @return descriptor string using the JVM grammar
176:             */
177:            public static String getDescriptorForType(String name) {
178:                if (name.equals(Byte.TYPE.getName()))
179:                    return "B";
180:                else if (name.equals(Character.TYPE.getName()))
181:                    return "C";
182:                else if (name.equals(Double.TYPE.getName()))
183:                    return "D";
184:                else if (name.equals(Float.TYPE.getName()))
185:                    return "F";
186:                else if (name.equals(Integer.TYPE.getName()))
187:                    return "I";
188:                else if (name.equals(Long.TYPE.getName()))
189:                    return "J";
190:                else if (name.equals(Short.TYPE.getName()))
191:                    return "S";
192:                else if (name.equals(Boolean.TYPE.getName()))
193:                    return "Z";
194:                else if (name.equals(Void.TYPE.getName()))
195:                    return "V";
196:                else if (name.startsWith("["))
197:                    return name.replace('.', '/');
198:                else
199:                    return "L" + name.replace('.', '/') + ";";
200:            }
201:
202:            /**
203:             * Checks if a given name matches the <tt>TYPE</tt> name of a primitive wrapper class.
204:             *
205:             * @see  java.lang.Integer#TYPE
206:             *
207:             * @param   name  TYPE.getName()
208:             * @return  true if is a primitive type name; false otherwise
209:             */
210:            public static boolean isPrimitive(String name) {
211:                if (name.equals(Byte.TYPE.getName())
212:                        || name.equals(Character.TYPE.getName())
213:                        || name.equals(Double.TYPE.getName())
214:                        || name.equals(Float.TYPE.getName())
215:                        || name.equals(Integer.TYPE.getName())
216:                        || name.equals(Long.TYPE.getName())
217:                        || name.equals(Short.TYPE.getName())
218:                        || name.equals(Boolean.TYPE.getName()))
219:
220:                    return true;
221:
222:                return false;
223:            }
224:
225:            // Protected -----------------------------------------------------
226:
227:            /**
228:             * creates constructor <tt>&lt;init&gt;(MBeanInfo info, AttributeOperationResolver resolver, Object resource)</tt>
229:             * that calls <tt>super(info, resolver, resource)</tt> in its implementation
230:             *
231:             * @param   cp          constant pool
232:             * @param   className   name of the class being generated
233:             */
234:            protected static MethodGen createConstructor(ConstantPoolGen cp,
235:                    String className) {
236:                InstructionList constrInstructions = new InstructionList();
237:
238:                int constrRefIndex = cp
239:                        .addMethodref(
240:                                SUPER_CLASS.getName(),
241:                                "<init>",
242:                                "("
243:                                        + getDescriptorForType(MBeanInfo.class
244:                                                .getName())
245:                                        + getDescriptorForType(AttributeOperationResolver.class
246:                                                .getName())
247:                                        + getDescriptorForType(Object.class
248:                                                .getName()) + ")V");
249:
250:                constrInstructions.append(new ALOAD(0)); // Stack:  => ..., this
251:                constrInstructions.append(new ALOAD(1)); // Stack:  => ..., this, arg1 [MBeanInfo]
252:                constrInstructions.append(new ALOAD(2)); // Stack:  => ..., this, arg1 [MBeanInfo], arg2 [AttributeOperationResolver]
253:                constrInstructions.append(new ALOAD(3)); // Stack:  => ..., this, arg1 [MBeanInfo], arg2 [AttributeOperationResolver], arg3 [Object]
254:                constrInstructions.append(new INVOKESPECIAL(constrRefIndex)); // Stack:  => ...
255:                constrInstructions.append(new RETURN()); // Stack:  => <empty>
256:
257:                MethodGen constrMethod = new MethodGen(Constants.ACC_PUBLIC,
258:                        Type.VOID, new Type[] {
259:                                new ObjectType(MBeanInfo.class.getName()),
260:                                new ObjectType(AttributeOperationResolver.class
261:                                        .getName()),
262:                                new ObjectType(Object.class.getName()) },
263:                        new String[] { "info", "resolver", "resource" },
264:                        "<init>", className, constrInstructions, cp);
265:                constrMethod.setMaxStack(4);
266:
267:                return constrMethod;
268:            }
269:
270:            /**
271:             * Creates the implementation of the <tt>invoke(String actionName, Object[] args, String[] signature)</tt>
272:             * method. This implementation currently handles all non overloaded MBean operation invocations.
273:             * Overloaded operations still fall back to the default reflected invocations. <p>
274:             *
275:             * The Java equivalent of the implementation looks roughly as follows:<br><pre>
276:             *
277:             * public void invoke(String actionName, Object[] args, String[] signature)
278:             * {
279:             *    if (actionName != null)
280:             *    {
281:             *       try
282:             *       {
283:             *          if (actionName.equals(&lt;operName1&gt;))
284:             *             return ((&lt;resource type&gt;)super.getResourceObject()).&lt;operName1&gt;((&lt;arg1 type&gt;)arg1, (&lt;arg2 type&gt;)arg2, ...);
285:             *          else if (actionName.equals(&lt;operName2&gt;))
286:             *             return ((&lt;resource type&gt;)super.getResourceObject()).&lt;operName2&gt;((&lt;arg1 type&gt;)arg1, (&lt;arg2 type&gt;)arg2, ...);
287:             *
288:             *          ...
289:             *
290:             *          else
291:             *             super.invoke(actionName, args, signature);
292:             *      }
293:             *      catch (Throwable t)
294:             *      {
295:             *          super.invoke(actionName, args, signature);
296:             *      }
297:             *    }
298:             * }
299:             * </pre>
300:             *
301:             * @param   cp                   constant pool of the class being generated
302:             * @param   info                 metadata of the MBean
303:             * @param   className            name of the class being generated
304:             * @param   resourceClassName    name of the resource class being invoked
305:             */
306:            protected static MethodGen createInvoke(ConstantPoolGen cp,
307:                    MBeanInfo info, String className, String resourceClassName) {
308:                InstructionList invokeInstructions = new InstructionList();
309:                MethodEntry[] operations = getOperations(info);
310:
311:                // load operation name strings and methods to constant pool
312:                for (int i = 0; i < operations.length; ++i) {
313:                    operations[i].nameIndexInCP = cp.addString(operations[i]
314:                            .getName());
315:                    operations[i].methodIndexInCP = cp.addMethodref(
316:                            resourceClassName, operations[i].getName(),
317:                            operations[i].methodDescriptor);
318:                }
319:
320:                int invokeIndex = cp
321:                        .addMethodref(SUPER_CLASS.getName(), "invoke",
322:                                "("
323:                                        + getDescriptorForType(String.class
324:                                                .getName())
325:                                        + getDescriptorForType(Object[].class
326:                                                .getName())
327:                                        + getDescriptorForType(String[].class
328:                                                .getName())
329:                                        + ")"
330:                                        + getDescriptorForType(Object.class
331:                                                .getName()));
332:
333:                int getResourceObjectIndex = cp
334:                        .addMethodref(SUPER_CLASS.getName(),
335:                                "getResourceObject", "()Ljava/lang/Object;");
336:
337:                int strEqualsIndex = cp.addMethodref(String.class.getName(),
338:                        "equals", "(Ljava/lang/Object;)Z");
339:
340:                InstructionHandle beginTryBlock = null;
341:                InstructionHandle endTryBlock = null;
342:
343:                IFNULL ifOperationEqualsNull = new IFNULL(null);
344:                IFEQ operationElseIfBranch = null;
345:
346:                if (operations.length > 0) {
347:                    //
348:                    //    if (actionName != null)
349:                    //
350:                    invokeInstructions.append(new ALOAD(1)); // Stack:  => ..., arg1 [String]
351:
352:                    beginTryBlock = invokeInstructions
353:                            .append(ifOperationEqualsNull); // Stack:  => ...
354:
355:                    for (int i = 0; i < operations.length; ++i) {
356:                        //
357:                        //  if (actionName.equals(operations[i].getName());
358:                        //
359:                        InstructionHandle jumpToNextElse = invokeInstructions
360:                                .append(new ALOAD(1)); // Stack:  => ..., arg1 [String]
361:                        invokeInstructions.append(new LDC(
362:                                operations[i].nameIndexInCP)); // Stack:  => ..., opName [String]
363:                        invokeInstructions.append(new INVOKEVIRTUAL(
364:                                strEqualsIndex)); // Stack:  => ..., 0 | 1 [boolean]
365:
366:                        // set the jump target for previous else if branch
367:                        if (operationElseIfBranch != null)
368:                            operationElseIfBranch.setTarget(jumpToNextElse);
369:
370:                        operationElseIfBranch = new IFEQ(null);
371:                        invokeInstructions.append(operationElseIfBranch); // Stack:  => ...
372:
373:                        invokeInstructions.append(new ALOAD(0)); // Stack:  => ..., this
374:                        invokeInstructions.append(new INVOKEVIRTUAL(
375:                                getResourceObjectIndex)); // Stack:  => ..., resource [Object]
376:
377:                        int x = cp.addClass(resourceClassName);
378:                        invokeInstructions.append(new CHECKCAST(x)); // Stack:  => ..., resource [<resource object type>]
379:
380:                        // if invocation has args, we need to push them into stack
381:                        if (operations[i].getSignature().length > 0) {
382:
383:                            for (int arrayIndex = 0; arrayIndex < operations[i]
384:                                    .getSignature().length; ++arrayIndex) {
385:                                invokeInstructions.append(new ALOAD(2)); // Stack:  => ..., resource [<type>], arg2 [Object[]]
386:                                invokeInstructions.append(new PUSH(cp,
387:                                        arrayIndex)); // Stack:  => ..., resource [<type>], arg2 [Object[]], array index [int]
388:                                invokeInstructions.append(new AALOAD()); // Stack:  => ..., resource [<type>], array[index] [Object]
389:
390:                                // Args come in as objects. If signature has a primitive type
391:                                // we need to convert the arg before we can invoke the operation
392:                                String type = operations[i].getSignature()[arrayIndex]
393:                                        .getName();
394:
395:                                if (isPrimitive(type))
396:                                    invokeInstructions
397:                                            .append(convertObjectToPrimitive(
398:                                                    cp, type)); // Stack:  => ..., resource[<type>], value [<primitive>]
399:
400:                                else {
401:                                    x = cp.addClass(type);
402:                                    invokeInstructions.append(new CHECKCAST(x)); // Stack:  => ..., resource[<type>], value [<reference>]
403:                                }
404:                            }
405:                        }
406:
407:                        //
408:                        //    resource.<operation>(<arg 1, ... arg n>)
409:                        //
410:                        x = operations[i].methodIndexInCP;
411:                        invokeInstructions.append(new INVOKEVIRTUAL(x)); // Stack:  => ..., returnvalue
412:
413:                        // Wrap primitive return values into their corresponding wrapper objects
414:                        String type = operations[i].getReturnType();
415:
416:                        if (isPrimitive(type)) {
417:                            invokeInstructions.append(convertPrimitiveToObject(
418:                                    cp, type)); // Stack:  => ..., objectref [wrapper]
419:                            invokeInstructions.append(new ARETURN()); // Stack:  => <empty>
420:                        } else if (type.equals(Void.TYPE.getName())) {
421:                            invokeInstructions.append(new ACONST_NULL()); // Stack:  => ..., null
422:                            invokeInstructions.append(new ARETURN()); // Stack:  => <empty>
423:                        } else {
424:                            invokeInstructions.append(new ARETURN()); // Stack:  => <empty>
425:                        }
426:                    }
427:                }
428:
429:                //
430:                //  super.invoke(actionName, args, signature)  if no match was found
431:                //
432:                InstructionHandle jumpToSuperInvoke = invokeInstructions
433:                        .append(new ALOAD(0)); // Stack:  => ..., this
434:                invokeInstructions.append(new ALOAD(1)); // Stack:  => ..., this, arg1 [String]
435:                invokeInstructions.append(new ALOAD(2)); // Stack:  => ..., this, arg1 [String], arg2 [Object[]]
436:                invokeInstructions.append(new ALOAD(3)); // Stack:  => ..., this, arg1 [String], arg2 [Object[]], arg3 [String[]]
437:                invokeInstructions.append(new INVOKESPECIAL(invokeIndex)); // Stack:  => ..., reference [Object]
438:                invokeInstructions.append(new ARETURN()); // Stack:  => <empty>
439:
440:                // set the jump targets
441:                ifOperationEqualsNull.setTarget(jumpToSuperInvoke);
442:
443:                if (operations.length > 0) {
444:                    // set the last else branch to call super.invoke
445:                    if (operationElseIfBranch != null)
446:                        operationElseIfBranch.setTarget(jumpToSuperInvoke);
447:
448:                    // set the try catch block limits
449:                    beginTryBlock = beginTryBlock.getNext();
450:                    endTryBlock = jumpToSuperInvoke.getPrev();
451:                }
452:
453:                // exception handler (it's a cheap shot -- if there is any exception, re-invoke
454:                // on super class and let it handle all exceptions)
455:                InstructionHandle exceptionHandlerCode = invokeInstructions
456:                        .append(new ALOAD(0));
457:                invokeInstructions.append(new ALOAD(1));
458:                invokeInstructions.append(new ALOAD(2));
459:                invokeInstructions.append(new ALOAD(3));
460:                invokeInstructions.append(new INVOKESPECIAL(invokeIndex));
461:                invokeInstructions.append(new ARETURN());
462:
463:                MethodGen invokeMethod = new MethodGen(Constants.ACC_PUBLIC,
464:                        Type.OBJECT, new Type[] { Type.STRING,
465:                                new ArrayType(Object.class.getName(), 1),
466:                                new ArrayType(String.class.getName(), 1) },
467:                        new String[] { "operationName", "args", "signature" },
468:                        "invoke", className, invokeInstructions, cp);
469:                invokeMethod.setMaxLocals(7);
470:                invokeMethod.setMaxStack(calculateMaxStackSize(info));
471:
472:                invokeMethod.addException(ReflectionException.class.getName());
473:                invokeMethod.addException(MBeanException.class.getName());
474:
475:                if (operations.length > 0) {
476:                    invokeMethod.addExceptionHandler(beginTryBlock,
477:                            endTryBlock, exceptionHandlerCode, new ObjectType(
478:                                    "java.lang.Throwable"));
479:                }
480:
481:                return invokeMethod;
482:            }
483:
484:            private static int calculateMaxStackSize(MBeanInfo info) {
485:                MBeanOperationInfo[] operations = info.getOperations();
486:                int maxSize = 7;
487:
488:                for (int i = 0; i < operations.length; ++i) {
489:                    if (operations[i].getSignature().length > maxSize + 2)
490:                        maxSize = operations[i].getSignature().length + 2;
491:                }
492:
493:                return maxSize;
494:            }
495:
496:            /**
497:             * Converts a reference of a primitve wrapper object into a primite value type.
498:             * This method assumes that the wrapper object reference is already loaded at the
499:             * top of the operand stack. The stack is modified so that the object reference
500:             * to a primitive wrapper is replaced by the corresponding value in the stack.
501:             *
502:             * @param   cp    constant pool
503:             * @param   type  class name of the primitive wrapper object to convert
504:             * @return  an instruction list that replaces an object reference of a primitive
505:             *          wrapper object to its corresponding value in the operand stack
506:             */
507:            protected static InstructionList convertObjectToPrimitive(
508:                    ConstantPoolGen cp, String type) {
509:                InstructionList il = new InstructionList();
510:
511:                int intValueIndex = cp.addMethodref(Integer.class.getName(),
512:                        "intValue", "()I");
513:                int byteValueIndex = cp.addMethodref(Byte.class.getName(),
514:                        "byteValue", "()B");
515:                int charValueIndex = cp.addMethodref(Character.class.getName(),
516:                        "charValue", "()C");
517:                int doubleValueIndex = cp.addMethodref(Double.class.getName(),
518:                        "doubleValue", "()D");
519:                int floatValueIndex = cp.addMethodref(Float.class.getName(),
520:                        "floatValue", "()F");
521:                int longValueIndex = cp.addMethodref(Long.class.getName(),
522:                        "longValue", "()J");
523:                int shortValueIndex = cp.addMethodref(Short.class.getName(),
524:                        "shortValue", "()S");
525:                int booleanValueIndex = cp.addMethodref(
526:                        Boolean.class.getName(), "booleanValue", "()Z");
527:
528:                //
529:                // Assumes the wrapper object reference is on top of the stack
530:                //
531:
532:                if (type.equals(Integer.TYPE.getName())) {
533:                    int x = cp.addClass("java.lang.Integer");
534:                    il.append(new CHECKCAST(x)); // Stack:  => ..., type [Integer]
535:                    il.append(new INVOKEVIRTUAL(intValueIndex)); // Stack:  => ..., value [int]
536:                }
537:
538:                else if (type.equals(Byte.TYPE.getName())) {
539:                    int x = cp.addClass("java.lang.Byte");
540:                    il.append(new CHECKCAST(x)); // Stack:  => ..., type [Boolean]
541:                    il.append(new INVOKEVIRTUAL(byteValueIndex)); // Stack:  => ..., 0 | 1 [boolean]
542:                }
543:
544:                else if (type.equals(Character.TYPE.getName())) {
545:                    int x = cp.addClass("java.lang.Character");
546:                    il.append(new CHECKCAST(x)); // Stack:  => ..., type [Character]
547:                    il.append(new INVOKEVIRTUAL(charValueIndex)); // Stack:  => ..., value [char]
548:                }
549:
550:                else if (type.equals(Double.TYPE.getName())) {
551:                    int x = cp.addClass("java.lang.Double");
552:                    il.append(new CHECKCAST(x)); // Stack:  => ..., type [Double]
553:                    il.append(new INVOKEVIRTUAL(doubleValueIndex)); // Stack:  => ..., value [double]
554:                }
555:
556:                else if (type.equals(Float.TYPE.getName())) {
557:                    int x = cp.addClass("java.lang.Float");
558:                    il.append(new CHECKCAST(x)); // Stack:  => ..., type [Float]
559:                    il.append(new INVOKEVIRTUAL(floatValueIndex)); // Stack:  => ..., value [float]
560:                }
561:
562:                else if (type.equals(Long.TYPE.getName())) {
563:                    int x = cp.addClass("java.lang.Long");
564:                    il.append(new CHECKCAST(x)); // Stack:  => ..., type [Long]
565:                    il.append(new INVOKEVIRTUAL(longValueIndex)); // Stack:  => ..., value [long]
566:                }
567:
568:                else if (type.equals(Short.TYPE.getName())) {
569:                    int x = cp.addClass("java.lang.Short");
570:                    il.append(new CHECKCAST(x)); // Stack:  => ..., type [Short]
571:                    il.append(new INVOKEVIRTUAL(shortValueIndex)); // Stack:  => ..., value [short]
572:                }
573:
574:                else if (type.equals(Boolean.TYPE.getName())) {
575:                    int x = cp.addClass("java.lang.Boolean");
576:                    il.append(new CHECKCAST(x)); // Stack:  => ..., type [Boolean]
577:                    il.append(new INVOKEVIRTUAL(booleanValueIndex)); // Stack:  => ..., value [boolean]
578:                }
579:
580:                return il;
581:            }
582:
583:            /**
584:             * Converts a primitive into its corresponding object wrapper reference.
585:             * This method assumes the primitve is already pushed to the top of the operand
586:             * stack. The stack is modified so that the primitive value is replaced
587:             * by a reference to its corresponding wrapper object that has been
588:             * initialized to contain the same value.
589:             *
590:             * @param   cp    constant pool
591:             * @param   type  type string of the primitive, for example {@link java.lang.Integer#TYPE Integer.TYPE.getName()}
592:             * @return  an instruction list that replaces the primitive type at the top of
593:             *          the operand stack with its corresponding, initialized, wrapper object
594:             */
595:            protected static InstructionList convertPrimitiveToObject(
596:                    ConstantPoolGen cp, String type) {
597:                InstructionList il = new InstructionList();
598:
599:                if (type.equals(Boolean.TYPE.getName())) {
600:                    int x = cp.addClass("java.lang.Boolean");
601:                    int constrIndex = cp.addMethodref("java.lang.Boolean",
602:                            "<init>", "(B)V");
603:
604:                    il.append(new ISTORE(4));
605:                    il.append(new NEW(x));
606:                    il.append(new ASTORE(5));
607:                    il.append(new ALOAD(5));
608:                    il.append(new ILOAD(4));
609:                    il.append(new INVOKESPECIAL(constrIndex));
610:                    il.append(new ALOAD(5));
611:                }
612:
613:                else if (type.equals(Short.TYPE.getName())) {
614:                    int x = cp.addClass("java.lang.Short");
615:                    int constrIndex = cp.addMethodref("java.lang.Short",
616:                            "<init>", "(S)V");
617:
618:                    il.append(new ISTORE(4));
619:                    il.append(new NEW(x));
620:                    il.append(new ASTORE(5));
621:                    il.append(new ALOAD(5));
622:                    il.append(new ILOAD(4));
623:                    il.append(new INVOKESPECIAL(constrIndex));
624:                    il.append(new ALOAD(5));
625:                }
626:
627:                else if (type.equals(Long.TYPE.getName())) {
628:                    int x = cp.addClass("java.lang.Long");
629:                    int constrIndex = cp.addMethodref("java.lang.Long",
630:                            "<init>", "(J)V");
631:
632:                    il.append(new LSTORE(4));
633:                    il.append(new NEW(x));
634:                    il.append(new ASTORE(6));
635:                    il.append(new ALOAD(6));
636:                    il.append(new LLOAD(4));
637:                    il.append(new INVOKESPECIAL(constrIndex));
638:                    il.append(new ALOAD(6));
639:                }
640:
641:                else if (type.equals(Integer.TYPE.getName())) {
642:                    int x = cp.addClass("java.lang.Integer");
643:                    int constrIndex = cp.addMethodref("java.lang.Integer",
644:                            "<init>", "(I)V");
645:
646:                    il.append(new ISTORE(4));
647:                    il.append(new NEW(x));
648:                    il.append(new ASTORE(5));
649:                    il.append(new ALOAD(5));
650:                    il.append(new ILOAD(4));
651:                    il.append(new INVOKESPECIAL(constrIndex));
652:                    il.append(new ALOAD(5));
653:                }
654:
655:                else if (type.equals(Float.TYPE.getName())) {
656:                    int x = cp.addClass("java.lang.Float");
657:                    int constrIndex = cp.addMethodref("java.lang.Float",
658:                            "<init>", "(F)V");
659:
660:                    il.append(new FSTORE(4));
661:                    il.append(new NEW(x));
662:                    il.append(new ASTORE(5));
663:                    il.append(new ALOAD(5));
664:                    il.append(new FLOAD(4));
665:                    il.append(new INVOKESPECIAL(constrIndex));
666:                    il.append(new ALOAD(5));
667:                }
668:
669:                else if (type.equals(Double.TYPE.getName())) {
670:                    int x = cp.addClass("java.lang.Double");
671:                    int constrIndex = cp.addMethodref("java.lang.Double",
672:                            "<init>", "(D)V");
673:
674:                    il.append(new DSTORE(4));
675:                    il.append(new NEW(x));
676:                    il.append(new ASTORE(6));
677:                    il.append(new ALOAD(6));
678:                    il.append(new DLOAD(4));
679:                    il.append(new INVOKESPECIAL(constrIndex));
680:                    il.append(new ALOAD(6));
681:                }
682:
683:                else if (type.equals(Character.TYPE.getName())) {
684:                    int x = cp.addClass("java.lang.Character");
685:                    int constrIndex = cp.addMethodref("java.lang.Character",
686:                            "<init>", "(C)V");
687:
688:                    il.append(new ISTORE(4));
689:                    il.append(new NEW(x));
690:                    il.append(new ASTORE(5));
691:                    il.append(new ALOAD(5));
692:                    il.append(new ILOAD(4));
693:                    il.append(new INVOKESPECIAL(constrIndex));
694:                    il.append(new ALOAD(5));
695:                }
696:
697:                else if (type.equals(Byte.TYPE.getName())) {
698:                    int x = cp.addClass("java.lang.Byte");
699:                    int constrIndex = cp.addMethodref("java.lang.Byte",
700:                            "<init>", "(B)V");
701:
702:                    il.append(new ISTORE(4));
703:                    il.append(new NEW(x));
704:                    il.append(new ASTORE(5));
705:                    il.append(new ALOAD(5));
706:                    il.append(new ILOAD(4));
707:                    il.append(new INVOKESPECIAL(constrIndex));
708:                    il.append(new ALOAD(5));
709:                }
710:
711:                return il;
712:            }
713:
714:            /**
715:             * Returns a subset of MBean's operations. Overloaded operations are not supported yet,
716:             * so they're left out of the list and their invocations are delegated to the reflection
717:             * based super class. <p>
718:             *
719:             * Overloaded operations that differ in their arg list length may be able to gain in
720:             * performance if implemented directly with byte code. Overloaded operations with
721:             * equal arg list length may not show much difference compared to ternary search tree
722:             * based resolver.
723:             */
724:            protected static MethodEntry[] getOperations(MBeanInfo info) {
725:                HashMap operationMap = new HashMap();
726:                ArrayList overloadList = new ArrayList();
727:                MBeanOperationInfo[] operations = info.getOperations();
728:
729:                for (int i = 0; i < operations.length; ++i) {
730:                    String methodName = operations[i].getName();
731:
732:                    if (operationMap.containsKey(methodName))
733:                        overloadList.add(methodName);
734:                    else
735:                        operationMap.put(methodName, new MethodEntry(
736:                                operations[i]));
737:                }
738:
739:                // method overloading not supported yet
740:                Iterator it = overloadList.iterator();
741:                while (it.hasNext())
742:                    operationMap.remove(it.next());
743:
744:                return (MethodEntry[]) operationMap.values().toArray(
745:                        new MethodEntry[0]);
746:            }
747:
748:            // Inner classes -------------------------------------------------
749:            private static class MethodEntry extends MBeanOperationInfo {
750:
751:                /** Not really serialized */
752:                private static final long serialVersionUID = 1792631947840418314L;
753:
754:                String methodDescriptor = null;
755:                int nameIndexInCP = -1;
756:                int methodIndexInCP = -1;
757:
758:                public MethodEntry(MBeanOperationInfo info) {
759:                    super(info.getName(), info.getDescription(), info
760:                            .getSignature(), info.getReturnType(), info
761:                            .getImpact());
762:
763:                    this.methodDescriptor = getMethodDescriptor(info
764:                            .getSignature(), info.getReturnType());
765:                }
766:            }
767:
768:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.