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 net.sourceforge.jrefactory.ast.ASTMethodDeclaration;
012: import net.sourceforge.jrefactory.ast.SimpleNode;
013: import org.acm.seguin.refactor.ComplexTransform;
014: import org.acm.seguin.refactor.Refactoring;
015: import org.acm.seguin.refactor.RefactoringException;
016: import org.acm.seguin.refactor.TransformAST;
017: import org.acm.seguin.summary.FileSummary;
018: import org.acm.seguin.summary.MethodSummary;
019: import org.acm.seguin.summary.TypeDeclSummary;
020: import org.acm.seguin.summary.TypeSummary;
021: import org.acm.seguin.summary.query.GetTypeSummary;
022: import org.acm.seguin.summary.query.SameMethod;
023:
024: /**
025: * Pushes up a method into a parent class
026: *
027: *@author Chris Seguin
028: *@created April 5, 2000
029: */
030: public class PushUpMethodRefactoring extends
031: InheretenceMethodRefactoring {
032: private TypeSummary typeSummary;
033: private TypeSummary parentType;
034:
035: /**
036: * Constructor for the PushUpMethodRefactoring object
037: */
038: protected PushUpMethodRefactoring() {
039: }
040:
041: /**
042: * Gets the description of the refactoring
043: *
044: *@return the description
045: */
046: public String getDescription() {
047: return "Moves a method " + methodSummary.getName()
048: + " down into the parent class " + parentType.getName();
049: }
050:
051: /**
052: * Gets the ID attribute of the PushUpMethodRefactoring object
053: *
054: *@return The ID value
055: */
056: public int getID() {
057: return PUSH_UP_METHOD;
058: }
059:
060: /**
061: * This specifies the preconditions for applying the refactoring
062: *
063: *@exception RefactoringException Description of Exception
064: */
065: protected void preconditions() throws RefactoringException {
066: if (methodSummary == null) {
067: throw new RefactoringException("No method specified");
068: }
069:
070: typeSummary = (TypeSummary) methodSummary.getParent();
071: TypeDeclSummary parent = typeSummary.getParentClass();
072: parentType = GetTypeSummary.query(parent);
073:
074: checkDestination(parentType);
075: checkDestinationFile(parentType,
076: "Can't push up a method into source code that you don't have");
077:
078: NearMissVisitor nmv = new NearMissVisitor(parentType,
079: methodSummary, typeSummary);
080: nmv.visit(null);
081:
082: if (nmv.getProblem() != null) {
083: throw new RefactoringException(
084: "Method with a signature of "
085: + nmv.getProblem().toString()
086: + " found in child of "
087: + parentType.getName());
088: }
089: }
090:
091: /**
092: * Moves the method to the parent class
093: */
094: protected void transform() {
095: RemoveMethodTransform rft = new RemoveMethodTransform(
096: methodSummary);
097: ComplexTransform transform = getComplexTransform();
098: removeMethod(typeSummary, transform, rft);
099:
100: // Update the method declaration to have the proper permissions
101: SimpleNode methodDecl = rft.getMethodDeclaration();
102: if (methodDecl == null) {
103: return;
104: }
105:
106: ASTMethodDeclaration decl = updateMethod(methodDecl);
107:
108: addMethodToDest(transform, rft, methodDecl, parentType);
109:
110: // Remove the method from all child classes
111: (new RemoveMethodFromSubclassVisitor(parentType, methodSummary,
112: typeSummary, transform)).visit(null);
113: }
114: }
|