Source Code Cross Referenced for ClassInfo.java in  » IDE-Netbeans » cvsclient » org » netbeans » lib » profiler » classfile » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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


001:        /*
002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003:         *
004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005:         *
006:         * The contents of this file are subject to the terms of either the GNU
007:         * General Public License Version 2 only ("GPL") or the Common
008:         * Development and Distribution License("CDDL") (collectively, the
009:         * "License"). You may not use this file except in compliance with the
010:         * License. You can obtain a copy of the License at
011:         * http://www.netbeans.org/cddl-gplv2.html
012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013:         * specific language governing permissions and limitations under the
014:         * License.  When distributing the software, include this License Header
015:         * Notice in each file and include the License file at
016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
017:         * particular file as subject to the "Classpath" exception as provided
018:         * by Sun in the GPL Version 2 section of the License file that
019:         * accompanied this code. If applicable, add the following below the
020:         * License Header, with the fields enclosed by brackets [] replaced by
021:         * your own identifying information:
022:         * "Portions Copyrighted [year] [name of copyright owner]"
023:         *
024:         * Contributor(s):
025:         * The Original Software is NetBeans. The Initial Developer of the Original
026:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
027:         * Microsystems, Inc. All Rights Reserved.
028:         *
029:         * If you wish your version of this file to be governed by only the CDDL
030:         * or only the GPL Version 2, indicate your decision by adding
031:         * "[Contributor] elects to include this software in this distribution
032:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
033:         * single choice of license, a recipient has the option to distribute
034:         * your version of this file under either the CDDL, the GPL Version 2 or
035:         * to extend the choice of license to its licensees as provided above.
036:         * However, if you add GPL Version 2 code and therefore, elected the GPL
037:         * Version 2 license, then the option applies only if the new code is
038:         * made subject to such option by the copyright holder.
039:         */
040:
041:        package org.netbeans.lib.profiler.classfile;
042:
043:        import org.netbeans.lib.profiler.global.CommonConstants;
044:        import org.netbeans.lib.profiler.instrumentation.JavaClassConstants;
045:        import java.io.IOException;
046:        import java.lang.reflect.Modifier;
047:
048:        /**
049:         * A representation of a binary Java class, that is relatively compact - it does not contain method bodies,
050:         * and contains only a subset of information from the constant pool. Method bodies (or, more precisely, byte
051:         * arrays representing either full MethodInfos as defined in JVM Specification, or just method bodies), can
052:         * be obtained individually on demand.
053:         *
054:         * This class is abstract, since it contains a single abstract method that actually returns the class file bytes
055:         * for the whole class. Concrete subclasses of this class may choose to simply store this byte array, or retrieve
056:         * it e.g. from disk on demand.
057:         *
058:         * @author Misha Dmitirev
059:         */
060:        public abstract class ClassInfo extends BaseClassInfo implements 
061:                JavaClassConstants, CommonConstants {
062:            //~ Inner Classes ------------------------------------------------------------------------------------------------------------
063:
064:            public static class LineNumberTables {
065:                //~ Instance fields ------------------------------------------------------------------------------------------------------
066:
067:                char[][] lineNumbers;
068:                char[][] startPCs;
069:
070:                //~ Methods --------------------------------------------------------------------------------------------------------------
071:
072:                public char[][] getStartPCs() {
073:                    return startPCs;
074:                }
075:
076:                int[] getMinAndMaxLinesForMethod(int methodIdx) {
077:                    int[] lines = new int[2];
078:
079:                    if (startPCs[methodIdx] == null) { // No line number table for this method - return special value
080:                        lines[0] = lines[1] = -1;
081:
082:                        return lines;
083:                    }
084:
085:                    lines[0] = 10000000;
086:                    lines[1] = -10000000;
087:
088:                    char[] lns = lineNumbers[methodIdx];
089:
090:                    for (int i = 0; i < lns.length; i++) {
091:                        if (lns[i] < lines[0]) {
092:                            lines[0] = lns[i];
093:                        }
094:
095:                        if (lns[i] > lines[1]) {
096:                            lines[1] = lns[i];
097:                        }
098:                    }
099:
100:                    return lines;
101:                }
102:
103:                int bciForLineNo(int methodIdx, int lineNo) {
104:                    char[] spcs = startPCs[methodIdx];
105:
106:                    if (spcs == null) {
107:                        return -1;
108:                    }
109:
110:                    int tableLen = spcs.length;
111:                    char[] lns = lineNumbers[methodIdx];
112:
113:                    int minLine = 100000000;
114:                    int bestLine = 100000000;
115:                    int maxLine = 0;
116:
117:                    int curLine = -1;
118:                    int bestBCI = 100000000;
119:
120:                    for (int i = 0; i < tableLen; i++) {
121:                        curLine = lns[i];
122:
123:                        if (curLine > maxLine) {
124:                            maxLine = curLine;
125:                        }
126:
127:                        if (curLine < minLine) {
128:                            minLine = curLine;
129:                        }
130:
131:                        if (curLine == lineNo) { // Perfect match
132:                            bestBCI = spcs[i];
133:
134:                            break;
135:                        } else if ((curLine > lineNo) && (curLine <= bestLine)) { // Update bci/line
136:
137:                            if (spcs[i] < bestBCI) { // ..but check first if it's the smallest bci for this line.
138:                                // The whole issue is due to 'while() { }' effectively compiled as 'do { } while()', where for the actual
139:                                // line of the 'while' statementwe get two different bci's in the line number table:
140:                                // 1. the one for the initial 'goto' that transfers us to the condition check block in the end of the loop body
141:                                // 2. the first bci of that condition check block.
142:                                // Whether we hit this line as the first or the last line of our code fragment, the smallest bci is a correct answer.
143:                                bestBCI = spcs[i];
144:                                bestLine = curLine;
145:                            }
146:                        }
147:                    }
148:
149:                    // Found a valid matching line if there is a perfect match or at least the specified
150:                    // line is within this method's line number table.
151:                    if ((curLine == lineNo)
152:                            || ((lineNo >= minLine) && (lineNo <= maxLine))) {
153:                        return bestBCI;
154:                    } else {
155:                        return -1;
156:                    }
157:                }
158:
159:                int lineNoForBci(int methodIdx, int bci) {
160:                    char[] spcs = startPCs[methodIdx];
161:
162:                    if (spcs == null) {
163:                        return -1;
164:                    }
165:
166:                    int tableLen = spcs.length;
167:                    char[] lns = lineNumbers[methodIdx];
168:
169:                    int bestLine = -1;
170:
171:                    for (int i = 0; i < tableLen; i++) {
172:                        if (spcs[i] > bci) {
173:                            break; // reached in last cycle
174:                        }
175:
176:                        bestLine = lns[i];
177:                    }
178:
179:                    return bestLine;
180:                }
181:            }
182:
183:            //~ Instance fields ----------------------------------------------------------------------------------------------------------
184:
185:            String packageName;
186:            String super Name;
187:            char[] cpoolRefsToClassIdx; // Cpool indices of ClassEntry entires for referenced classes
188:            String[] cpoolRefsToClassName; // Names of classes referenced from cpool, including array classes.
189:            String[][] cpoolRefsToMethodClassNameAndSig;
190:
191:            // In all signatures we replace the 'L' and ';' symbols that enclose non-primitive type names with '@' and '#' respectively,
192:            // so that class names inside signatures can be located fast and unambiguously.  
193:            char[] cpoolRefsToMethodIdx; // Cpool indices of MethodEntry entries for referenced methods
194:            // The following array consists of "referenced method's class name, name, signature" triplets.
195:            // Defining classes names are trimmed of enclosing 'L' and ';' symbols
196:            int[] exceptionTableStartOffsets; // Relative offsets within a MethodInfo
197:            String[] interfaces;
198:            char[] lineNumberTablesLengths;
199:            int[] lineNumberTablesOffsets; // Relative offsets within a MethodInfo
200:            char[] methodAccessFlags;
201:            char[] methodBytecodesLengths;
202:            int[] methodBytecodesOffsets; // Relative offsets within a MethodInfo
203:            int[] methodInfoLengths;
204:            int[] methodInfoOffsets;
205:            String[] methodNames;
206:            String[] methodSignatures;
207:            String[] nestedClassNames;
208:            char accessFlags; // isInterface flag included
209:            int attrsStartOfs; // Ditto for class attributes
210:            int cpoolStartOfs; // Starting offset, in bytes, of the original cpool (cpool length char included)
211:            int fieldsStartOfs; // Ditto for fields
212:            int intermediateDataStartOfs; // Ditto for intermediate data (class flags, name, super, etc.)
213:            int methodsStartOfs; // Ditto for methods
214:            int origCPoolCount; // The number of entries in the original cpool of this class
215:            short lineNumberTablesInitStatus; // 0 : not yet initialized, 1 : OK, -1 : no tables exist
216:            private LineNumberTables lineNumberTables;
217:
218:            //~ Constructors -------------------------------------------------------------------------------------------------------------
219:
220:            protected ClassInfo(String className, int loaderId) {
221:                super (className, loaderId);
222:                packageName = getPackageName(name);
223:            }
224:
225:            /**
226:             * This constructor is used for creation of temporary instances of ClassInfo, typically to just find out something about
227:             * class contained in a given .class file.
228:             */
229:            ClassInfo(byte[] buf) throws ClassFormatError {
230:                super ("", 0); // NOI18N
231:
232:                try {
233:                    (new ClassFileParser()).parseClassFile(buf, this );
234:                } catch (ClassFileParser.ClassFileReadException ex) {
235:                    throw new ClassFormatError(ex.getMessage());
236:                }
237:
238:                packageName = getPackageName(name);
239:            }
240:
241:            //~ Methods ------------------------------------------------------------------------------------------------------------------
242:
243:            public boolean isAbstract() {
244:                return Modifier.isAbstract(accessFlags);
245:            }
246:
247:            public int getExceptionTableStartOffsetInMethodInfo(int i) {
248:                return exceptionTableStartOffsets[i];
249:            }
250:
251:            public boolean isInterface() {
252:                return Modifier.isInterface(accessFlags);
253:            }
254:
255:            public String[] getInterfaceNames() {
256:                return interfaces;
257:            }
258:
259:            public LineNumberTables getLineNumberTables() {
260:                if (lineNumberTables == null) {
261:                    initLineNumberTables();
262:                }
263:
264:                return lineNumberTables;
265:            }
266:
267:            public boolean isMethodAbstract(int i) {
268:                return Modifier.isAbstract(methodAccessFlags[i]);
269:            }
270:
271:            public byte[] getMethodBytecode(int i) {
272:                try {
273:                    byte[] classFile = getClassFileBytes();
274:                    byte[] res = new byte[methodBytecodesLengths[i]];
275:                    System.arraycopy(classFile, methodInfoOffsets[i]
276:                            + methodBytecodesOffsets[i], res, 0,
277:                            methodBytecodesLengths[i]);
278:
279:                    return res;
280:                } catch (IOException ex1) {
281:                    return null; // Should not happen - class file already loaded once by this time
282:                } catch (ClassNotFoundException ex2) {
283:                    return null;
284:                } // Ditto
285:            }
286:
287:            public int getMethodBytecodeOffsetInMethodInfo(int i) {
288:                return methodBytecodesOffsets[i];
289:            }
290:
291:            public int getMethodBytecodesLength(int i) {
292:                return methodBytecodesLengths[i];
293:            }
294:
295:            public boolean isMethodFinal(int i) {
296:                return Modifier.isFinal(methodAccessFlags[i]);
297:            }
298:
299:            public int getMethodIndex(String name, String sig) {
300:                for (int i = 0; i < methodNames.length; i++) {
301:                    if ((methodNames[i] == name)
302:                            && (methodSignatures[i] == sig)) {
303:                        return i;
304:                    }
305:                }
306:
307:                return -1;
308:            }
309:
310:            public byte[] getMethodInfo(int i) {
311:                try {
312:                    byte[] classFile = getClassFileBytes();
313:                    byte[] res = new byte[methodInfoLengths[i]];
314:                    System.arraycopy(classFile, methodInfoOffsets[i], res, 0,
315:                            methodInfoLengths[i]);
316:
317:                    return res;
318:                } catch (IOException ex1) {
319:                    return null; // Should not happen - class file already loaded once by this time
320:                } catch (ClassNotFoundException ex2) {
321:                    return null;
322:                } // Ditto
323:            }
324:
325:            public int getMethodInfoLength(int i) {
326:                return methodInfoLengths[i];
327:            }
328:
329:            public String getMethodName(int i) {
330:                return methodNames[i];
331:            }
332:
333:            public String[] getMethodNames() {
334:                return methodNames;
335:            }
336:
337:            public boolean isMethodNative(int i) {
338:                return Modifier.isNative(methodAccessFlags[i]);
339:            }
340:
341:            public boolean isMethodPrivate(int i) {
342:                return Modifier.isPrivate(methodAccessFlags[i]);
343:            }
344:
345:            public boolean isMethodProtected(int i) {
346:                return Modifier.isProtected(methodAccessFlags[i]);
347:            }
348:
349:            public boolean isMethodPublic(int i) {
350:                return Modifier.isPublic(methodAccessFlags[i]);
351:            }
352:
353:            public String getMethodSignature(int i) {
354:                return methodSignatures[i];
355:            }
356:
357:            public String[] getMethodSignatures() {
358:                return methodSignatures;
359:            }
360:
361:            public boolean isMethodStatic(int i) {
362:                return Modifier.isStatic(methodAccessFlags[i]);
363:            }
364:
365:            public int[] getMinAndMaxLinesForMethod(int methodIdx) {
366:                if (lineNumberTables == null) {
367:                    initLineNumberTables();
368:                }
369:
370:                return lineNumberTables.getMinAndMaxLinesForMethod(methodIdx);
371:            }
372:
373:            public String[] getNestedClassNames() {
374:                return nestedClassNames;
375:            }
376:
377:            public int getOrigAttrsStartOfs() {
378:                return attrsStartOfs;
379:            }
380:
381:            public int getOrigCPoolCount() {
382:                return origCPoolCount;
383:            }
384:
385:            public int getOrigCPoolStartOfs() {
386:                return cpoolStartOfs;
387:            }
388:
389:            public int getOrigFieldsStartOfs() {
390:                return fieldsStartOfs;
391:            }
392:
393:            public int getOrigIntermediateDataStartOfs() {
394:                return intermediateDataStartOfs;
395:            }
396:
397:            public int getOrigMethodsStartOfs() {
398:                return methodsStartOfs;
399:            }
400:
401:            public String getRefClassName(int refClassIdx) {
402:                for (int i = 0; i < cpoolRefsToClassIdx.length; i++) {
403:                    if (cpoolRefsToClassIdx[i] == refClassIdx) {
404:                        return cpoolRefsToClassName[i];
405:                    }
406:                }
407:
408:                return null;
409:            }
410:
411:            public String[] getRefMethodsClassNameAndSig(int refMethodIdx) {
412:                for (int i = 0; i < cpoolRefsToMethodIdx.length; i++) {
413:                    if (cpoolRefsToMethodIdx[i] == refMethodIdx) {
414:                        return cpoolRefsToMethodClassNameAndSig[i];
415:                    }
416:                }
417:
418:                return null;
419:            }
420:
421:            public String getSuperclassName() {
422:                return super Name;
423:            }
424:
425:            public int bciForMethodAndLineNo(int methodIdx, int lineNo) {
426:                if (lineNumberTables == null) {
427:                    initLineNumberTables();
428:                }
429:
430:                return lineNumberTables.bciForLineNo(methodIdx, lineNo);
431:            }
432:
433:            /** Check if the given method's opcode at bci is goto. or goto_w. If so, find and return the bci of the previous opcode */
434:            public int checkIfAtGoTo(int methodIdx, int bci) { // TODO CHECK: unused method
435:
436:                byte[] codeBytes = getMethodBytecode(methodIdx);
437:                int codeAtBCI = codeBytes[bci] & 0xFF;
438:
439:                if ((codeAtBCI != opc_goto) && (codeAtBCI != opc_goto_w)) {
440:                    return bci;
441:                }
442:
443:                return findPreviousBCI(codeBytes, bci);
444:            }
445:
446:            public boolean containsMethod(String name, String sig) { // TODO CHECK: unused method
447:
448:                return (getMethodIndex(name, sig) != -1);
449:            }
450:
451:            /** For given bytecode offset bci, return the offset of the bytecode before the one at bci */
452:            public static int findPreviousBCI(byte[] codeBytes, int bci) {
453:                int prev_offset = 0;
454:
455:                for (int offset = 0; offset < bci;) {
456:                    prev_offset = offset;
457:
458:                    int opcode = codeBytes[offset] & 0xFF;
459:
460:                    if (opcode == opc_wide) {
461:                        opcode = codeBytes[offset + 1] & 0xFF;
462:
463:                        if (((opcode >= opc_iload) && (opcode <= opc_aload))
464:                                || ((opcode >= opc_istore) && (opcode <= opc_astore))
465:                                || (opcode == opc_ret)) {
466:                            offset += 4;
467:                        } else if (opcode == opc_iinc) {
468:                            offset += 6;
469:                        } else {
470:                            offset++;
471:                        }
472:                    } else {
473:                        switch (opcode) {
474:                        case opc_tableswitch: {
475:                            int tbl = (offset + 1 + 3) & (~3); // four byte boundry
476:                            long default_skip = intAt(codeBytes, tbl, 0);
477:                            long low = intAt(codeBytes, tbl, 1);
478:                            long high = intAt(codeBytes, tbl, 2);
479:                            tbl += (3 << 2); // three int header
480:                            offset = tbl + (int) ((high - low + 1) << 2);
481:
482:                            break;
483:                        }
484:                        case opc_lookupswitch: {
485:                            int tbl = (offset + 1 + 3) & (~3); // four byte boundry
486:                            long default_skip = intAt(codeBytes, tbl, 0);
487:                            int npairs = (int) intAt(codeBytes, tbl, 1);
488:                            int nints = npairs * 2;
489:                            tbl += (2 << 2); // two int header
490:                            offset = tbl + (nints << 2);
491:
492:                            break;
493:                        }
494:                        default:
495:                            offset += opc_length[opcode];
496:
497:                            break;
498:                        }
499:                    }
500:                }
501:
502:                return prev_offset;
503:            }
504:
505:            public int lineNoForMethodAndBci(int methodIdx, int bci) { // TODO CHECK: unused method
506:
507:                if (lineNumberTables == null) {
508:                    initLineNumberTables();
509:                }
510:
511:                return lineNumberTables.lineNoForBci(methodIdx, bci);
512:            }
513:
514:            /**
515:             * Returns a {method idx, best BCI} pair for the given source line number in this class. If no suitable method is
516:             * found, returns {-1, -1}. If this class doesn't have any line number tables (because it's abstract or because
517:             * it was compiled without tables), returns {-2, -2}.
518:             */
519:            public int[] methodIdxAndBestBCIForLineNo(int lineNo) {
520:                if (lineNumberTablesInitStatus == 0) {
521:                    initLineNumberTables();
522:                }
523:
524:                if (lineNumberTablesInitStatus == -1) {
525:                    return new int[] { -2, -2 };
526:                }
527:
528:                int nMethods = methodNames.length;
529:
530:                // We need to take into account the fact that for a constructor/class initializer the line numbers may span
531:                // a much larger range than the constructor body. That's due to instance/static initialization statements
532:                // that can be scattered about the whole class. If we put the cursor into a method that is between two
533:                // initializers, we may well get a constructor as the "best match" for the given line. Thus, we first
534:                // search normal methods, and only if this fails - constructors and class initializer.
535:                for (int i = 0; i < nMethods; i++) {
536:                    if ((methodNames[i] == "<init>")
537:                            || (methodNames[i] == "<clinit>")) {
538:                        continue; // NOI18N
539:                    }
540:
541:                    int bestBCI = lineNumberTables.bciForLineNo(i, lineNo);
542:
543:                    if (bestBCI != -1) {
544:                        return new int[] { i, bestBCI };
545:                    }
546:                }
547:
548:                // No success with ordinary methods - try constructors now
549:                for (int i = 0; i < nMethods; i++) {
550:                    if ((methodNames[i] != "<init>")
551:                            && (methodNames[i] != "<clinit>")) {
552:                        continue; // NOI18N
553:                    }
554:
555:                    int bestBCI = lineNumberTables.bciForLineNo(i, lineNo);
556:
557:                    if (bestBCI != -1) {
558:                        return new int[] { i, bestBCI };
559:                    }
560:                }
561:
562:                return new int[] { -1, -1 };
563:            }
564:
565:            // WARNING: this call doesn't check if the method in superClass is not private, final, static or constructor. This is done for
566:            // speedup, since we call it only in the context when it is already known that the above is true.
567:            public int overridesVirtualMethod(ClassInfo super Class,
568:                    int super MethodIdx) { // TODO CHECK: unused method
569:
570:                int idx = getMethodIndex(
571:                        super Class.methodNames[super MethodIdx],
572:                        super Class.methodSignatures[super MethodIdx]);
573:
574:                if (idx == -1) {
575:                    return -1;
576:                }
577:
578:                if (super Class.isMethodPublic(super MethodIdx)
579:                        || super Class.isMethodProtected(super MethodIdx)) {
580:                    return idx;
581:                } else if (super Class.packageName == this .packageName) {
582:                    return idx;
583:                } else {
584:                    return -1;
585:                }
586:            }
587:
588:            //-------------------------------------- Protected methods -------------------------------------------
589:
590:            /** Returns the class file bytes for this class. */
591:            protected abstract byte[] getClassFileBytes() throws IOException,
592:                    ClassNotFoundException;
593:
594:            /**
595:             * Returns package name for the given class. In case of no package, returns an
596:             * empty, but non-null string. Returned string is interned.
597:             */
598:            protected static String getPackageName(String clazzName) {
599:                int ldi = clazzName.lastIndexOf('/'); // For convenience, we use system-internal slashes, not dots
600:
601:                if (ldi == -1) {
602:                    return ""; // NOI18N
603:                } else {
604:                    return clazzName.substring(0, ldi).intern();
605:                }
606:            }
607:
608:            //----------------------------------------- Private implementation -----------------------------------
609:
610:            /** Given the table at the specified index, return the specified entry */
611:            private static final long intAt(byte[] codeBytes, int tbl, int entry) { // TODO CHECK: unused method
612:
613:                int base = tbl + (entry << 2);
614:
615:                return (codeBytes[base] << 24)
616:                        | ((codeBytes[base + 1] & 0xFF) << 16)
617:                        | ((codeBytes[base + 2] & 0xFF) << 8)
618:                        | (codeBytes[base + 3] & 0xFF);
619:            }
620:
621:            private void initLineNumberTables() {
622:                byte[] classBuf = null;
623:
624:                try {
625:                    classBuf = getClassFileBytes();
626:                } catch (IOException ex1) { // Should not happen - class file already loaded once by this time
627:                } catch (ClassNotFoundException ex2) {
628:                } // Ditto
629:
630:                int nMethods = methodNames.length;
631:                char[][] startPCs = new char[nMethods][];
632:                char[][] lineNumbers = new char[nMethods][];
633:                boolean lineNumberTablesExist = false;
634:
635:                for (int i = 0; i < nMethods; i++) {
636:                    int ofs = methodInfoOffsets[i] + lineNumberTablesOffsets[i];
637:
638:                    if (ofs == -1) {
639:                        continue; // Abstract or native method, or no line number tables in this class
640:                    }
641:
642:                    lineNumberTablesExist = true;
643:
644:                    int tableLen = lineNumberTablesLengths[i];
645:                    char[] startPC = startPCs[i] = new char[tableLen];
646:                    char[] lineNumber = lineNumbers[i] = new char[tableLen];
647:
648:                    for (int j = 0; j < tableLen; j++) {
649:                        startPC[j] = (char) (((classBuf[ofs++] & 255) << 8) + (classBuf[ofs++] & 255));
650:                        lineNumber[j] = (char) (((classBuf[ofs++] & 255) << 8) + (classBuf[ofs++] & 255));
651:                    }
652:                }
653:
654:                // Let's init this data anyway, to avoid NullPointerExceptions etc.
655:                lineNumberTables = new LineNumberTables();
656:                lineNumberTables.startPCs = startPCs;
657:                lineNumberTables.lineNumbers = lineNumbers;
658:
659:                if (lineNumberTablesExist) {
660:                    lineNumberTablesInitStatus = 1;
661:                } else {
662:                    lineNumberTablesInitStatus = -1;
663:                }
664:            }
665:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.