Source Code Cross Referenced for ByteCodeCallsSnippetFactory.java in  » Test-Coverage » NoUnit » net » firstpartners » nounit » reader » bytecode » 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 » Test Coverage » NoUnit » net.firstpartners.nounit.reader.bytecode 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package net.firstpartners.nounit.reader.bytecode;
002:
003:        /*
004:         This Class Modified from JClassLib , Free software under the terms of the
005:         Gnu Public Library (below). You can redistribute it and/or
006:         modify it under the terms of the GNU General Public
007:         License as published by the Free Software Foundation; either
008:         version 2 of the license, or (at your option) any later version.
009:         */
010:
011:        import java.io.IOException;
012:        import java.util.HashMap;
013:        import java.util.HashSet;
014:        import java.util.Iterator;
015:
016:        import net.firstpartners.nounit.reader.ISnippetFactory;
017:        import net.firstpartners.nounit.snippet.SnippetCalls;
018:        import net.firstpartners.nounit.snippet.Snippets;
019:        import net.firstpartners.nounit.utility.NoUnitException;
020:
021:        import org.apache.log4j.Logger;
022:
023:        import org.gjt.jclasslib.bytecode.AbstractInstruction;
024:        import org.gjt.jclasslib.bytecode.BranchInstruction;
025:        import org.gjt.jclasslib.bytecode.ImmediateByteInstruction;
026:        import org.gjt.jclasslib.bytecode.ImmediateIntInstruction;
027:        import org.gjt.jclasslib.bytecode.ImmediateShortInstruction;
028:        import org.gjt.jclasslib.bytecode.IncrementInstruction;
029:        import org.gjt.jclasslib.bytecode.InvokeInterfaceInstruction;
030:        import org.gjt.jclasslib.bytecode.LookupSwitchInstruction;
031:        import org.gjt.jclasslib.bytecode.MultianewarrayInstruction;
032:        import org.gjt.jclasslib.bytecode.Opcodes;
033:        import org.gjt.jclasslib.bytecode.OpcodesUtil;
034:        import org.gjt.jclasslib.bytecode.TableSwitchInstruction;
035:        import org.gjt.jclasslib.bytecode.MatchOffsetPair;
036:        import org.gjt.jclasslib.io.ByteCodeReader;
037:        import org.gjt.jclasslib.structures.AttributeInfo;
038:        import org.gjt.jclasslib.structures.ClassFile;
039:        import org.gjt.jclasslib.structures.InvalidByteCodeException;
040:        import org.gjt.jclasslib.structures.MethodInfo;
041:        import org.gjt.jclasslib.structures.attributes.CodeAttribute;
042:
043:        /**
044:         * Get the Other Methods Called by this one
045:         * @author modified by Paul Browne
046:         * @version 20/11/01
047:         */
048:        public class ByteCodeCallsSnippetFactory extends
049:                AbstractByteCodeSnippetFactory implements  ISnippetFactory,
050:                Opcodes {
051:
052:            /*
053:             * Attribute that we are interested in within the file
054:             */
055:            private CodeAttribute attribute;
056:
057:            /*
058:             *Source Class file
059:             */
060:            private ClassFile classFile;
061:
062:            private HashMap offsetToPosition = new HashMap();
063:            private int opcodeCounterWidth;
064:            private int offsetWidth;
065:
066:            //handle to logger
067:            static Logger log = Logger
068:                    .getLogger(ByteCodeCallsSnippetFactory.class);
069:
070:            /**
071:             * Holds Process ByteCode -> Instructions
072:             */
073:            private HashMap internalInstructions = new HashMap();
074:
075:            /*
076:             * Position in internalInstruction
077:             */
078:            private int currentInstructionPosition = 0;
079:
080:            /**
081:             * Makes note of important positons in the Internal Instructions Table
082:             */
083:            private HashSet methodCalls = new HashSet();
084:
085:            /** 
086:             * Constant - marks normal instruction
087:             */
088:            private static final int I_NORMAL = 0;
089:
090:            /** 
091:             * Constant - marks method call instruction
092:             */
093:            private static final int I_CALL = 1;
094:
095:            /**
096:             * Construct a bytecode document with an associated <tt>Code</tt>
097:             * attribute and a parent class file.
098:             * Only use the first Attribute from the method , which for methods should be OK!!
099:             * @param styles the style cache
100:             * @param attribute the <tt>Code</tt> attribute
101:             * @param classFile the class file
102:             */
103:            public ByteCodeCallsSnippetFactory(MethodInfo this Method,
104:                    ClassFile classFile) throws IOException,
105:                    InvalidByteCodeException, NoUnitException {
106:
107:                //Local Variables
108:                CodeAttribute attribute;
109:                int counter = 0;
110:                boolean foundFlag = false;
111:
112:                //Convert to handle to code attribute
113:                //Following presumes only one (CodeAttribute) - throws NoUnitException if not
114:                AttributeInfo[] genAttributes = this Method.getAttributes();
115:
116:                while ((counter < genAttributes.length) && (!foundFlag)) {
117:
118:                    //Check and convert if possible   
119:                    if (genAttributes[counter] instanceof  CodeAttribute) {
120:
121:                        //Set flag to skip loop
122:                        foundFlag = true;
123:
124:                        //Do conversion and doc preparation
125:
126:                        log.debug(genAttributes[counter].getClass().toString());
127:
128:                        attribute = (CodeAttribute) genAttributes[counter];
129:
130:                        // Once Converted , Same as other constructor
131:                        this .attribute = attribute;
132:                        this .classFile = classFile;
133:
134:                        setupDocument();
135:
136:                    } else {
137:                        counter++;
138:                    }
139:                }
140:
141:            }
142:
143:            /**
144:             * Construct a bytecode document with an associated <tt>Code</tt>
145:             * attribute and a parent class file.
146:             * @param styles the style cache
147:             * @param attribute the <tt>Code</tt> attribute
148:             * @param classFile the class file
149:             */
150:            public ByteCodeCallsSnippetFactory(CodeAttribute attribute,
151:                    ClassFile classFile) throws IOException,
152:                    InvalidByteCodeException {
153:
154:                this .attribute = attribute;
155:                this .classFile = classFile;
156:
157:                setupDocument();
158:            }
159:
160:            /**
161:             * Get the document containing the opcode counters.
162:             * @return internalByteCodes - String describing the internal calls
163:             */
164:            public String toString() {
165:
166:                StringBuffer internalByteCodes = new StringBuffer();
167:
168:                //Loop through , adding internal Instructions
169:                for (int a = 0; a < this .currentInstructionPosition; a++) {
170:
171:                    internalByteCodes.append(this .internalInstructions
172:                            .get(String.valueOf(a)));
173:
174:                }
175:
176:                return internalByteCodes.toString();
177:            }
178:
179:            /**
180:             * See what methods are called by the implementation of this code
181:             * <BR> Called Methods are the one <I>after</I> the stored instruction
182:             * <BR> How they are called , is the instruction <I>before</I> the stored instruction
183:             * <BR> Constant pool reference is the <I>actual</I> stored instruction
184:             * @return Snippets Collection of Called Methods (String , Names)
185:             * Get the Collection of Snippets (as read from the source)
186:             * @return Snippets
187:             */
188:            public Snippets getSnippets() throws NoUnitException {
189:
190:                //Internal Variables
191:                int this Instruction;
192:                String tmpString;
193:                String tmpClass;
194:                String tmpMethod;
195:                Snippets calls = new Snippets();
196:                SnippetCalls tmpSnippet;
197:                Iterator myLoop = methodCalls.iterator();
198:
199:                //Loop and add relevant calls 
200:                while (myLoop.hasNext()) {
201:
202:                    //Get the Param Info via the Class Pool
203:
204:                    //Get the Class & Method Info
205:                    this Instruction = ((Integer) myLoop.next()).intValue();
206:                    this Instruction++; // we want the one after - see note above
207:                    tmpString = (String) this .internalInstructions.get(String
208:                            .valueOf(this Instruction));
209:
210:                    // Put this into Snippet Form and save
211:                    tmpClass = getClassFromCalledString(tmpString);
212:                    tmpMethod = getMethodFromCalledString(tmpString);
213:                    tmpSnippet = new SnippetCalls(tmpClass, tmpMethod, null);
214:                    calls.add(tmpSnippet);
215:
216:                }
217:
218:                return calls;
219:            }
220:
221:            /**
222:             * Store the String as Part of the Internal Instruction Set (nomral type)
223:             * @param string to Add
224:             */
225:            protected void appendString(String string) {
226:
227:                appendString(I_NORMAL, string);
228:
229:            }
230:
231:            /**
232:             * Store the String as Part of the Internal Instruction Set
233:             * @param type of Instruction Being added (as per constants)
234:             * @param string to Add
235:             */
236:            protected void appendString(int type, String string) {
237:
238:                //Add only if the incoming String is not null
239:                if (string != null) {
240:
241:                    //Check to see if it should be noted in the method calls table
242:                    if ((type == I_CALL)
243:                            && (this 
244:                                    .doubleCheckCalledMethod(currentInstructionPosition))) {
245:                        this .methodCalls.add(new Integer(
246:                                currentInstructionPosition));
247:
248:                    }
249:
250:                    //Add everything to the internal instruction table
251:                    internalInstructions.put(String
252:                            .valueOf(this .currentInstructionPosition), string);
253:                    currentInstructionPosition++;
254:
255:                }
256:            }
257:
258:            /**
259:             * Setup the Internal Document
260:             */
261:            private void setupDocument() throws IOException,
262:                    InvalidByteCodeException {
263:
264:                byte[] code = attribute.getCode();
265:
266:                java.util.List instructions = ByteCodeReader.readByteCode(code);
267:
268:                // calculateOffsetWidth(instructions);
269:
270:                int[] linesPerOpcode = new int[instructions.size()];
271:
272:                Iterator it = instructions.iterator();
273:                AbstractInstruction currentInstruction;
274:                int instructionCount = 0;
275:                while (it.hasNext()) {
276:                    currentInstruction = (AbstractInstruction) it.next();
277:                    linesPerOpcode[instructionCount++] = addInstructionToDocument(currentInstruction);
278:                }
279:
280:                createOpcodeCounterDocument(linesPerOpcode);
281:
282:            }
283:
284:            /**
285:             * Add More Information to internal store
286:             */
287:            private int addInstructionToDocument(AbstractInstruction instruction)
288:                    throws InvalidByteCodeException {
289:
290:                int offset = instruction.getOffset();
291:
292:                appendString(getPaddedValue(offset, offsetWidth));
293:
294:                appendString(" " + instruction.getOpcodeVerbose());
295:
296:                int additionalLines = addOpcodeSpecificInfo(instruction);
297:
298:                appendString("\n");
299:
300:                return additionalLines + 1;
301:            }
302:
303:            /**
304:             * Add More Information to internal store
305:             */
306:            private int addOpcodeSpecificInfo(AbstractInstruction instruction)
307:                    throws InvalidByteCodeException {
308:
309:                int additionalLines = 0;
310:
311:                if (instruction instanceof  ImmediateByteInstruction) {
312:                    additionalLines += addImmediateByteSpecificInfo((ImmediateByteInstruction) instruction);
313:                } else if (instruction instanceof  ImmediateShortInstruction) {
314:                    additionalLines += addImmediateShortSpecificInfo((ImmediateShortInstruction) instruction);
315:                } else if (instruction instanceof  ImmediateIntInstruction) {
316:                    additionalLines += addImmediateIntSpecificInfo((ImmediateIntInstruction) instruction);
317:                } else if (instruction instanceof  BranchInstruction) {
318:                    additionalLines += addBranchSpecificInfo((BranchInstruction) instruction);
319:                } else if (instruction instanceof  TableSwitchInstruction) {
320:                    additionalLines += addTableSwitchSpecificInfo((TableSwitchInstruction) instruction);
321:                } else if (instruction instanceof  LookupSwitchInstruction) {
322:                    additionalLines += addLookupSwitchSpecificInfo((LookupSwitchInstruction) instruction);
323:                }
324:
325:                return additionalLines;
326:            }
327:
328:            /**
329:             * Add More Information to internal store
330:             */
331:            private int addImmediateByteSpecificInfo(
332:                    ImmediateByteInstruction instruction)
333:                    throws InvalidByteCodeException {
334:
335:                int opcode = instruction.getOpcode();
336:                int sourceOffset = instruction.getOffset();
337:                int immediateByte = instruction.getImmediateByte();
338:
339:                if (opcode == OPCODE_LDC) {
340:                    addConstantPoolLink(immediateByte, sourceOffset);
341:                } else if (opcode == OPCODE_NEWARRAY) {
342:                    String verbose = OpcodesUtil
343:                            .getArrayTypeVerbose(immediateByte);
344:                    appendString(" " + immediateByte + " (" + verbose + ")");
345:
346:                } else {
347:                    appendString(" " + immediateByte);
348:
349:                    if (instruction instanceof  IncrementInstruction) {
350:                        appendString(" by");
351:                        appendString(" "
352:                                + ((IncrementInstruction) instruction)
353:                                        .getIncrementConst());
354:                    }
355:                }
356:                return 0;
357:            }
358:
359:            /**
360:             * Add More Information to internal store
361:             */
362:            private int addImmediateShortSpecificInfo(
363:                    ImmediateShortInstruction instruction)
364:                    throws InvalidByteCodeException {
365:
366:                int opcode = instruction.getOpcode();
367:                int sourceOffset = instruction.getOffset();
368:                int immediateShort = instruction.getImmediateShort();
369:
370:                if (opcode == OPCODE_SIPUSH) {
371:                    appendString(" " + immediateShort);
372:                } else {
373:                    addConstantPoolLink(immediateShort, sourceOffset);
374:
375:                    if (instruction instanceof  InvokeInterfaceInstruction) {
376:                        appendString(" count "
377:                                + ((InvokeInterfaceInstruction) instruction)
378:                                        .getCount());
379:
380:                    } else if (instruction instanceof  MultianewarrayInstruction) {
381:                        appendString(" dim "
382:                                + ((MultianewarrayInstruction) instruction)
383:                                        .getDimensions());
384:
385:                    }
386:                }
387:
388:                return 0;
389:            }
390:
391:            /**
392:             * Add More Information to internal store
393:             */
394:            private int addImmediateIntSpecificInfo(
395:                    ImmediateIntInstruction instruction)
396:                    throws InvalidByteCodeException {
397:
398:                int immediateInt = instruction.getImmediateInt();
399:                int sourceOffset = instruction.getOffset();
400:
401:                addConstantPoolLink(immediateInt, sourceOffset);
402:
403:                return 0;
404:            }
405:
406:            /**
407:             * Add More Information to internal store
408:             */
409:            private int addBranchSpecificInfo(BranchInstruction instruction) {
410:
411:                int branchOffset = instruction.getBranchOffset();
412:                int instructionOffset = instruction.getOffset();
413:
414:                addOffsetLink(branchOffset, instructionOffset);
415:
416:                return 0;
417:            }
418:
419:            /**
420:             * Add More Information to internal store
421:             */
422:            private int addTableSwitchSpecificInfo(
423:                    TableSwitchInstruction instruction) {
424:
425:                int instructionOffset = instruction.getOffset();
426:                int lowByte = instruction.getLowByte();
427:                int highByte = instruction.getHighByte();
428:                int[] jumpOffsets = instruction.getJumpOffsets();
429:
430:                appendString(" " + lowByte + " to " + highByte + "\n");
431:
432:                for (int i = 0; i <= highByte - lowByte; i++) {
433:                    appendString("\u0009" + (i + lowByte) + ": ");
434:                    addOffsetLink(jumpOffsets[i], instructionOffset);
435:                    appendString("\n");
436:
437:                }
438:                appendString("\u0009default: ");
439:                addOffsetLink(instruction.getDefaultOffset(), instructionOffset);
440:
441:                return highByte - lowByte + 2;
442:            }
443:
444:            /**
445:             * Add More Information to internal store
446:             */
447:            private int addLookupSwitchSpecificInfo(
448:                    LookupSwitchInstruction instruction) {
449:
450:                int instructionOffset = instruction.getOffset();
451:                java.util.List matchOffsetPairs = instruction
452:                        .getMatchOffsetPairs();
453:                int matchOffsetPairsCount = matchOffsetPairs.size();
454:
455:                appendString(" " + matchOffsetPairsCount + "\n");
456:
457:                MatchOffsetPair matchOffsetPairEntry;
458:
459:                for (int i = 0; i < matchOffsetPairsCount; i++) {
460:                    matchOffsetPairEntry = (MatchOffsetPair) matchOffsetPairs
461:                            .get(i);
462:                    appendString("\u0009" + matchOffsetPairEntry.getMatch()
463:                            + ": ");
464:                    addOffsetLink(matchOffsetPairEntry.getOffset(),
465:                            instructionOffset);
466:                    appendString("\n");
467:
468:                }
469:                appendString("\u0009default: ");
470:                addOffsetLink(instruction.getDefaultOffset(), instructionOffset);
471:
472:                return matchOffsetPairsCount + 1;
473:            }
474:
475:            /**
476:             * Add More Information to internal store
477:             */
478:            private void addConstantPoolLink(int constantPoolIndex,
479:                    int sourceOffset) throws InvalidByteCodeException {
480:
481:                appendString(I_CALL, "#" + constantPoolIndex);
482:
483:                String name = classFile
484:                        .getConstantPoolEntryName(constantPoolIndex);
485:                if (name.length() > 0) {
486:                    appendString(" <" + name + ">");
487:                }
488:
489:            }
490:
491:            /**
492:             * Add More Information to internal store
493:             */
494:            private void addOffsetLink(int branchOffset, int instructionOffset) {
495:
496:                int totalOffset = branchOffset + instructionOffset;
497:
498:                appendString(String.valueOf(totalOffset));
499:
500:                appendString(" (" + (branchOffset > 0 ? "+" : "")
501:                        + String.valueOf(branchOffset) + ")");
502:            }
503:
504:            /**
505:             *Called during inital setup
506:             */
507:            private void createOpcodeCounterDocument(int[] linesPerOpcode) {
508:
509:                int numberOfOpcodes = linesPerOpcode.length;
510:
511:                opcodeCounterWidth = String.valueOf(numberOfOpcodes - 1)
512:                        .length();
513:
514:                for (int i = 0; i < numberOfOpcodes; i++) {
515:                    appendString(getPaddedValue(i, opcodeCounterWidth));
516:
517:                    for (int j = 0; j < linesPerOpcode[i]; j++) {
518:                        appendString("\n");
519:                    }
520:                }
521:
522:            }
523:
524:            /**
525:             * Pads out a number to a certain width
526:             * @param number to pad out
527:             * @param width required
528:             * @return String of required length , containing spaces and number
529:             */
530:            private static String getPaddedValue(int number, int width) {
531:
532:                StringBuffer buffer = new StringBuffer();
533:                String value = String.valueOf(number);
534:                int valueLength = value.length();
535:                for (int i = valueLength; i < width; i++) {
536:                    buffer.append(' ');
537:                }
538:                buffer.append(value);
539:                return buffer.toString();
540:            }
541:
542:            /**
543:             * Double Checks to see if this is really an instruction to call another method
544:             * @see getCalledMethods() javadoc for info on how the internal instruction store
545:             *      is currently implemented
546:             * @param instructionReference to check
547:             * @return true if is call to another method , false if not
548:             */
549:            private boolean doubleCheckCalledMethod(int instructionReference) {
550:
551:                //Internal Variables
552:                String previousInstruction = (String) internalInstructions
553:                        .get(String.valueOf(instructionReference - 1));
554:
555:                //Check for nothing found
556:                if (previousInstruction == null) {
557:                    return false;
558:                }
559:
560:                //Check to see what this string says
561:                if (previousInstruction.indexOf("invoke") > -1) {
562:                    return true;
563:                } else {
564:                    return false;
565:                }
566:
567:            }
568:
569:            /**
570:             * Extracts the class portion from the called string
571:             * @param inString to split
572:             * @return String , the class portion only
573:             */
574:            private String getClassFromCalledString(String inString) {
575:
576:                String returnString = "";
577:
578:                //Find Place to break
579:                int breakplace = inString.lastIndexOf(".");
580:
581:                //Break, clean and retrun
582:                returnString = inString.substring(0, breakplace);
583:
584:                returnString = tidyNames(returnString);
585:
586:                return returnString;
587:            }
588:
589:            /**
590:             * Extracts the class portion from the called string
591:             * @param inString to split
592:             * @return String , the class portion only
593:             */
594:            private String getMethodFromCalledString(String inString) {
595:
596:                String returnString = "";
597:
598:                //Find Place to break
599:                int breakplace = inString.lastIndexOf(".");
600:
601:                //Break , clean and retrun
602:                returnString = inString
603:                        .substring(breakplace, inString.length());
604:
605:                returnString = tidyNames(returnString);
606:
607:                return returnString;
608:            }
609:
610:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.