Source Code Cross Referenced for ExtractMethodRefactoring.java in  » UML » jrefactory » org » acm » seguin » refactor » method » 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 » UML » jrefactory » org.acm.seguin.refactor.method 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *  Author:  Chris Seguin
003:         *
004:         *  This software has been developed under the copyleft
005:         *  rules of the GNU General Public License.  Please
006:         *  consult the GNU General Public License for more
007:         *  details about use and distribution of this software.
008:         */
009:        package org.acm.seguin.refactor.method;
010:
011:        import java.io.StringWriter;
012:        import java.util.Iterator;
013:        import java.util.LinkedList;
014:        import net.sourceforge.jrefactory.ast.Node;
015:        import net.sourceforge.jrefactory.ast.ASTBlockStatement;
016:        import net.sourceforge.jrefactory.ast.ASTClassBody;
017:        import net.sourceforge.jrefactory.ast.ASTClassBodyDeclaration;
018:        import net.sourceforge.jrefactory.ast.ASTClassDeclaration;
019:        import net.sourceforge.jrefactory.ast.ASTCompilationUnit;
020:        import net.sourceforge.jrefactory.ast.ASTMethodDeclaration;
021:        import net.sourceforge.jrefactory.ast.ASTReturnStatement;
022:        import net.sourceforge.jrefactory.ast.ASTStatement;
023:        import net.sourceforge.jrefactory.ast.ASTTypeDeclaration;
024:        import net.sourceforge.jrefactory.ast.ASTUnmodifiedClassDeclaration;
025:        import net.sourceforge.jrefactory.ast.SimpleNode;
026:        import net.sourceforge.jrefactory.build.BuildExpression;
027:        import net.sourceforge.jrefactory.factory.BufferParserFactory;
028:        import net.sourceforge.jrefactory.query.Found;
029:        import net.sourceforge.jrefactory.query.Search;
030:        import org.acm.seguin.pretty.JavadocTags;
031:        import net.sourceforge.jrefactory.ast.ModifierHolder;
032:        import org.acm.seguin.awt.ExceptionPrinter;
033:        import org.acm.seguin.pretty.PrettyPrintVisitor;
034:        import org.acm.seguin.pretty.PrintData;
035:        import org.acm.seguin.refactor.Refactoring;
036:        import org.acm.seguin.refactor.RefactoringException;
037:        import org.acm.seguin.summary.FileSummary;
038:        import org.acm.seguin.summary.SummaryLoadVisitor;
039:        import org.acm.seguin.summary.SummaryLoaderState;
040:        import org.acm.seguin.summary.VariableSummary;
041:        import net.sourceforge.jrefactory.parser.JavaParserTreeConstants;
042:
043:        /**
044:         *  Refactoring class that extracts a portion of the method and creates a new
045:         *  method with what the user has selected.
046:         *
047:         *@author    Chris Seguin
048:         *@author     <a href="JRefactory@ladyshot.demon.co.uk">Mike Atkinson</a>
049:         *@version    $Id: ExtractMethodRefactoring.java,v 1.7 2003/10/30 15:24:23 mikeatkinson Exp $ 
050:         */
051:        public class ExtractMethodRefactoring extends Refactoring {
052:            private StringBuffer fullFile = null;
053:            private String selection = null;
054:            private String methodName = null;
055:            private SimpleNode root;
056:            private FileSummary mainFileSummary;
057:            private FileSummary extractedMethodFileSummary;
058:            private Node key;
059:            private EMParameterFinder empf = null;
060:            private StringBuffer signature;
061:            /**
062:             *  Stores the return type for the extracted method
063:             */
064:            private Object returnType = null;
065:            private int prot = PRIVATE;
066:            private Object[] arguments = new Object[0];
067:
068:            /**
069:             *  The extracted method should be private
070:             */
071:            public final static int PRIVATE = 0;
072:            /**
073:             *  The extracted method should have package scope
074:             */
075:            public final static int PACKAGE = 1;
076:            /**
077:             *  The extracted method should have protected scope
078:             */
079:            public final static int PROTECTED = 2;
080:            /**
081:             *  The extracted method should have public scope
082:             */
083:            public final static int PUBLIC = 3;
084:
085:            /**
086:             *  Constructor for the ExtractMethodRefactoring object
087:             */
088:            protected ExtractMethodRefactoring() {
089:                super ();
090:
091:                signature = new StringBuffer();
092:            }
093:
094:            /**
095:             *  Sets the FullFile attribute of the ExtractMethodRefactoring object
096:             *
097:             *@param  value  The new FullFile value
098:             */
099:            public void setFullFile(String value) {
100:                fullFile = new StringBuffer(value);
101:            }
102:
103:            /**
104:             *  Sets the FullFile attribute of the ExtractMethodRefactoring object
105:             *
106:             *@param  value  The new FullFile value
107:             */
108:            public void setFullFile(StringBuffer value) {
109:                fullFile = value;
110:            }
111:
112:            /**
113:             *  Sets the Selection attribute of the ExtractMethodRefactoring object
114:             *
115:             *@param  value  The new Selection value
116:             */
117:            public void setSelection(String value) throws RefactoringException {
118:                if (value == null) {
119:                    throw new RefactoringException(
120:                            "Nothing has been selected, so nothing can be extracted");
121:                }
122:
123:                selection = value.trim();
124:
125:                if (isStatement()) {
126:                    setReturnType(null);
127:                } else {
128:                    setReturnType("boolean");
129:                }
130:            }
131:
132:            /**
133:             *  Sets the MethodName attribute of the ExtractMethodRefactoring object
134:             *
135:             *@param  value  The new MethodName value
136:             */
137:            public void setMethodName(String value) {
138:                methodName = value;
139:                if ((methodName == null) || (methodName.length() == 0)) {
140:                    methodName = "extractedMethod";
141:                }
142:            }
143:
144:            /**
145:             *  Sets the order of the parameters
146:             *
147:             *@param  data  The new ParameterOrder value
148:             */
149:            public void setParameterOrder(Object[] data) {
150:                empf.setParameterOrder(data);
151:                arguments = data;
152:            }
153:
154:            /**
155:             *  Sets the Protection attribute of the ExtractMethodRefactoring object
156:             *
157:             *@param  value  The new Protection value
158:             */
159:            public void setProtection(int value) {
160:                prot = value;
161:            }
162:
163:            /**
164:             *  Sets the return type for the extracted method
165:             *
166:             *@param  obj  The new ReturnType value
167:             */
168:            public void setReturnType(Object obj) {
169:                returnType = obj;
170:            }
171:
172:            /**
173:             *  Gets the Description attribute of the ExtractMethodRefactoring object
174:             *
175:             *@return    The Description value
176:             */
177:            public String getDescription() {
178:                return "Extract a method named " + methodName;
179:            }
180:
181:            /**
182:             *  Gets the FullFile attribute of the ExtractMethodRefactoring object
183:             *
184:             *@return    The FullFile value
185:             */
186:            public String getFullFile() {
187:                return fullFile.toString();
188:            }
189:
190:            /**
191:             *  Gets the Parameters attribute of the ExtractMethodRefactoring object
192:             *
193:             *@return                           The Parameters value
194:             *@exception  RefactoringException  Description of Exception
195:             */
196:            public VariableSummary[] getParameters()
197:                    throws RefactoringException {
198:                preconditions();
199:                Search srch = new Search();
200:                empf = prescan(srch);
201:
202:                LinkedList list = empf.getList();
203:                VariableSummary[] result = new VariableSummary[list.size()];
204:                Iterator iter = list.iterator();
205:                int count = 0;
206:                while (iter.hasNext()) {
207:                    result[count] = (VariableSummary) iter.next();
208:                    count++;
209:                }
210:
211:                arguments = result;
212:
213:                return result;
214:            }
215:
216:            /**
217:             *  Gets the possible return types
218:             *
219:             *@return                           The return types
220:             *@exception  RefactoringException  problem in loading these
221:             */
222:            public Object[] getReturnTypes() throws RefactoringException {
223:                if (empf == null) {
224:                    return null;
225:                }
226:                return empf.getReturnTypes();
227:            }
228:
229:            /**
230:             *  Gets the Statement attribute of the ExtractMethodRefactoring object
231:             *
232:             *@return    The Statement value
233:             */
234:            public boolean isStatement() {
235:                return (selection.indexOf(";") > 0)
236:                        || (selection.indexOf("}") > 0);
237:            }
238:
239:            /**
240:             *  Gets the Signature attribute of the ExtractMethodRefactoring object
241:             *
242:             *@return    The Signature value
243:             */
244:            public String getSignature() {
245:                signature.setLength(0);
246:                signature.append(getProtection());
247:                signature.append(" ");
248:                signature.append(getReturnTypeString());
249:                signature.append(" ");
250:                signature.append(methodName);
251:                signature.append("(");
252:                for (int ndx = 0; ndx < arguments.length; ndx++) {
253:                    signature.append(((VariableSummary) arguments[ndx])
254:                            .getDeclaration());
255:                    if (ndx != arguments.length - 1) {
256:                        signature.append(", ");
257:                    }
258:                }
259:                signature.append(")");
260:
261:                return signature.toString();
262:            }
263:
264:            /**
265:             *  Gets the return type for the extracted method
266:             *
267:             *@return    The return type
268:             */
269:            public Object getReturnType() {
270:                return returnType;
271:            }
272:
273:            /**
274:             *  Gets the ID attribute of the ExtractMethodRefactoring object
275:             *
276:             *@return    The ID value
277:             */
278:            public int getID() {
279:                return EXTRACT_METHOD;
280:            }
281:
282:            /**
283:             *  These items must be true before the refactoring will work
284:             *
285:             *@exception  RefactoringException  the problem that arose
286:             */
287:            protected void preconditions() throws RefactoringException {
288:                if (fullFile == null) {
289:                    throw new RefactoringException("No file specified");
290:                }
291:
292:                if (selection == null) {
293:                    throw new RefactoringException("No selection specified");
294:                }
295:
296:                if (methodName == null) {
297:                    throw new RefactoringException("No method specified");
298:                }
299:
300:                root = getFileRoot();
301:                if (root == null) {
302:                    throw new RefactoringException(
303:                            "Unable to parse the current file.\n"
304:                                    + "Please make sure you can compile this file before\n"
305:                                    + "trying to extract a method from it.");
306:                }
307:
308:                mainFileSummary = findVariablesUsed(root);
309:
310:                SimpleNode newMethod = getMethodTree();
311:                if (newMethod == null) {
312:                    throw new RefactoringException(
313:                            "Unable to parse the current selection.\n"
314:                                    + "Please make sure you have highlighted the entire expression\n"
315:                                    + "or set of statements.");
316:                }
317:            }
318:
319:            /**
320:             *  Actually make the transformation
321:             */
322:            protected void transform() {
323:                replaceAllInstances(root);
324:                printFile(root);
325:            }
326:
327:            /**
328:             *  Gets the MethodTree attribute of the ExtractMethodRefactoring object
329:             *
330:             *@return    The MethodTree value
331:             */
332:            private SimpleNode getMethodTree() {
333:                String tempClass = "public class TempClass { " + makeMethod()
334:                        + "}";
335:                BufferParserFactory bpf = new BufferParserFactory(tempClass);
336:                SimpleNode root = bpf.getAbstractSyntaxTree(false,
337:                        ExceptionPrinter.getInstance());
338:
339:                extractedMethodFileSummary = findVariablesUsed(root);
340:
341:                ASTTypeDeclaration top = (ASTTypeDeclaration) root
342:                        .jjtGetFirstChild();
343:                ASTClassDeclaration classDecl = (ASTClassDeclaration) top
344:                        .jjtGetFirstChild();
345:                ASTUnmodifiedClassDeclaration unmodifiedClassDecl = (ASTUnmodifiedClassDeclaration) classDecl
346:                        .jjtGetFirstChild();
347:                ASTClassBody classBody = (ASTClassBody) unmodifiedClassDecl
348:                        .jjtGetFirstChild();
349:                ASTClassBodyDeclaration bodyDecl = (ASTClassBodyDeclaration) classBody
350:                        .jjtGetFirstChild();
351:
352:                return (SimpleNode) bodyDecl.jjtGetFirstChild();
353:            }
354:
355:            /**
356:             *  Gets the FileRoot attribute of the ExtractMethodRefactoring object
357:             *
358:             *@return    The FileRoot value
359:             */
360:            private SimpleNode getFileRoot() {
361:                BufferParserFactory bpf = new BufferParserFactory(fullFile
362:                        .toString());
363:                SimpleNode root = bpf.getAbstractSyntaxTree(true,
364:                        ExceptionPrinter.getInstance());
365:                return root;
366:            }
367:
368:            /**
369:             *  Returns the protection
370:             *
371:             *@return    The Protection value
372:             */
373:            private String getProtection() {
374:                switch (prot) {
375:                case PRIVATE:
376:                    return "private";
377:                case PACKAGE:
378:                    return "";
379:                case PROTECTED:
380:                    return "protected";
381:                case PUBLIC:
382:                    return "public";
383:                }
384:                return "private";
385:            }
386:
387:            /**
388:             *  Returns the return type
389:             *
390:             *@return    The ReturnType value
391:             */
392:            private String getReturnTypeString() {
393:                if (returnType == null) {
394:                    return "void";
395:                } else if (returnType instanceof  String) {
396:                    return (String) returnType;
397:                } else if (returnType instanceof  VariableSummary) {
398:                    return ((VariableSummary) returnType).getTypeDecl()
399:                            .getName();
400:                } else {
401:                    return returnType.toString();
402:                }
403:            }
404:
405:            /**
406:             *  Replace all instances of code with a selected value
407:             *
408:             *@param  root  Description of Parameter
409:             */
410:            private void replaceAllInstances(SimpleNode root) {
411:                EMBuilder builder = new EMBuilder();
412:                builder.setMethodName(methodName);
413:                builder.setStatement(isStatement());
414:
415:                Search srch = new Search();
416:                if (empf == null) {
417:                    empf = prescan(srch);
418:                }
419:                builder.setParameters(empf.getList());
420:
421:                SimpleNode methodTree = addReturn(getMethodTree());
422:
423:                Found result = srch.search(root, key);
424:                updateModifiers((SimpleNode) result.getRoot(), methodTree);
425:
426:                if (returnType instanceof  VariableSummary) {
427:                    builder.setReturnSummary((VariableSummary) returnType);
428:                    FindLocalVariableDeclVisitor flvdv = new FindLocalVariableDeclVisitor();
429:                    methodTree.jjtAccept(flvdv, returnType);
430:                    builder.setLocalVariableNeeded(flvdv.isFound());
431:                }
432:
433:                SimpleNode firstResult = (SimpleNode) result.getRoot();
434:                while (result != null) {
435:                    replaceExtractedMethod(result, builder);
436:                    result = srch.search(root, key);
437:                }
438:
439:                insertAtNextClass(firstResult, methodTree);
440:            }
441:
442:            /**
443:             *  Prints the file using the pretty printer option
444:             *
445:             *@param  root  Description of Parameter
446:             */
447:            private void printFile(SimpleNode root) {
448:                StringWriter writer = new StringWriter();
449:                JavadocTags.get().reload();
450:                PrintData pd = new PrintData(writer);
451:                PrettyPrintVisitor ppv = new PrettyPrintVisitor();
452:                ppv.visit((ASTCompilationUnit) root, pd);
453:                pd.close();
454:
455:                String file = writer.toString();
456:                if (file.length() > 0) {
457:                    fullFile = new StringBuffer(file);
458:                }
459:            }
460:
461:            /**
462:             *  Creates a string with the new method in it
463:             *
464:             *@return    the new method
465:             */
466:            private String makeMethod() {
467:                if (isStatement()) {
468:                    return getSignature() + "{" + selection + "}";
469:                } else {
470:                    return getSignature() + "{ return " + selection + "; }";
471:                }
472:            }
473:
474:            /**
475:             *  Description of the Method
476:             *
477:             *@param  node  Description of Parameter
478:             *@return       Description of the Returned Value
479:             */
480:            private FileSummary findVariablesUsed(Node node) {
481:                if (node == null) {
482:                    return null;
483:                }
484:                SummaryLoaderState state = new SummaryLoaderState();
485:                node.jjtAccept(new SummaryLoadVisitor(), state);
486:                return (FileSummary) state.getCurrentSummary();
487:            }
488:
489:            /**
490:             *  Finds the parameters
491:             *
492:             *@param  result  the location where the section was found
493:             *@return         Description of the Returned Value
494:             */
495:            private EMParameterFinder findParameters(Found result) {
496:                EMParameterFinder empf = new EMParameterFinder();
497:                empf.setMainFileSummary(mainFileSummary);
498:                empf.setExtractFileSummary(extractedMethodFileSummary);
499:                empf.setLocation(result.getRoot());
500:                empf.run();
501:                return empf;
502:            }
503:
504:            /**
505:             *  This allows us to scan for the parameters first
506:             *
507:             *@param  srch  Description of Parameter
508:             *@return       Description of the Returned Value
509:             */
510:            private EMParameterFinder prescan(Search srch) {
511:                EMDigger digger = new EMDigger();
512:                if (isStatement()) {
513:                    key = digger.last((ASTMethodDeclaration) getMethodTree());
514:                } else {
515:                    key = digger.dig((ASTMethodDeclaration) getMethodTree());
516:                }
517:
518:                Found result = srch.search(root, key);
519:
520:                EMParameterFinder parameterFinder = findParameters(result);
521:
522:                LinkedList list = parameterFinder.getList();
523:                arguments = new Object[list.size()];
524:                Iterator iter = list.iterator();
525:                int count = 0;
526:                while (iter.hasNext()) {
527:                    arguments[count] = iter.next();
528:                    count++;
529:                }
530:
531:                return parameterFinder;
532:            }
533:
534:            /**
535:             *  Replaces the extracted method
536:             *
537:             *@param  result   where we found the portion to replace
538:             *@param  builder  build a method invocation
539:             */
540:            private void replaceExtractedMethod(Found result, EMBuilder builder) {
541:                int index = result.getIndex();
542:                int length = key.jjtGetNumChildren();
543:                Node location = result.getRoot();
544:
545:                for (int ndx = 0; ndx < length; ndx++) {
546:                    location.jjtDeleteChild(index);
547:                }
548:                location.jjtInsertChild(builder.build(), index);
549:            }
550:
551:            /**
552:             *  Adds the return at the end of the method if one is necessary
553:             *
554:             *@param  methodDecl  The feature to be added to the Return attribute
555:             *@return             Description of the Returned Value
556:             */
557:            private SimpleNode addReturn(SimpleNode methodDecl) {
558:                if (returnType instanceof  VariableSummary) {
559:                    Node block = methodDecl.jjtGetChild(methodDecl
560:                            .jjtGetNumChildren() - 1);
561:
562:                    ASTBlockStatement blockStatement = new ASTBlockStatement(
563:                            JavaParserTreeConstants.JJTBLOCKSTATEMENT);
564:
565:                    ASTStatement statement = new ASTStatement(
566:                            JavaParserTreeConstants.JJTSTATEMENT);
567:                    blockStatement.jjtAddChild(statement, 0);
568:
569:                    ASTReturnStatement returnStatement = new ASTReturnStatement(
570:                            JavaParserTreeConstants.JJTRETURNSTATEMENT);
571:                    statement.jjtAddChild(returnStatement, 0);
572:
573:                    BuildExpression be = new BuildExpression();
574:                    String name = ((VariableSummary) returnType).getName();
575:                    returnStatement.jjtAddChild(be.buildName(name), 0);
576:
577:                    block
578:                            .jjtAddChild(blockStatement, block
579:                                    .jjtGetNumChildren());
580:                }
581:
582:                return methodDecl;
583:            }
584:
585:            /**
586:             *  Adds the static and synchronized attributes to the extracted method
587:             *
588:             *@param  currentNode  where the body of the extracted method was found
589:             *@param  methodTree   the method we are extracting
590:             */
591:            private void updateModifiers(SimpleNode currentNode,
592:                    SimpleNode methodTree) {
593:                while (!(currentNode instanceof  ASTMethodDeclaration)) {
594:                    currentNode = (SimpleNode) currentNode.jjtGetParent();
595:                    if (currentNode instanceof  ASTClassBody) {
596:                        return;
597:                    }
598:                }
599:
600:                ASTMethodDeclaration extractedFrom = (ASTMethodDeclaration) currentNode;
601:                ASTMethodDeclaration newMethod = (ASTMethodDeclaration) methodTree;
602:
603:                //ModifierHolder efmh = extractedFrom.getModifiers();
604:                //ModifierHolder nmmh = newMethod.getModifiers();
605:                //nmmh.setStatic(efmh.isStatic());
606:                //nmmh.setSynchronized(nmmh.isSynchronized());
607:                newMethod.setStatic(extractedFrom.isStatic());
608:                newMethod.setSynchronized(extractedFrom.isSynchronized());
609:            }
610:
611:            /**
612:             *  Inserts the method at the next class found when heading up from the first
613:             *  place where we replaced this value
614:             *
615:             *@param  currentNode  where this was found
616:             *@param  methodTree   the method to be inserted
617:             */
618:            private void insertAtNextClass(SimpleNode currentNode,
619:                    SimpleNode methodTree) {
620:                while (!(currentNode instanceof  ASTClassBody)) {
621:                    currentNode = (SimpleNode) currentNode.jjtGetParent();
622:                    if (currentNode == null) {
623:                        return;
624:                    }
625:                }
626:
627:                currentNode.jjtInsertChild(methodTree, currentNode
628:                        .jjtGetNumChildren());
629:            }
630:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.