001: package org.acm.seguin.refactor.type;
002:
003: import java.io.File;
004: import java.util.Iterator;
005: import java.util.LinkedList;
006: import java.util.StringTokenizer;
007: import net.sourceforge.jrefactory.ast.ASTName;
008: import org.acm.seguin.summary.*;
009: import org.acm.seguin.summary.query.FileSummaryGetter;
010: import org.acm.seguin.summary.query.MovingTypeList;
011: import org.acm.seguin.summary.query.StayingTypeList;
012: import org.acm.seguin.refactor.AddImportTransform;
013: import org.acm.seguin.refactor.TransformAST;
014: import org.acm.seguin.refactor.RemoveImportTransform;
015: import org.acm.seguin.refactor.ComplexTransform;
016:
017: /**
018: * Scans through the summary objects to create a list of files that reference
019: * a particular class.
020: *
021: *@author Chris Seguin
022: */
023: public class MoveClassVisitor extends TypeChangeVisitor {
024: // Instance Variables
025: private String oldPackageName;
026: private String newPackageName;
027: private File base;
028:
029: /**
030: * Determine if anything in this tree references these classes.
031: *
032: *@param oldPackage the name of the old package
033: *@param newPackage the name of the new package
034: *@param base the base directory
035: *@param complex Description of Parameter
036: */
037: public MoveClassVisitor(String oldPackage, String newPackage,
038: File base, ComplexTransform complex) {
039: super (complex);
040: oldPackageName = oldPackage;
041: newPackageName = newPackage;
042: this .base = base;
043: }
044:
045: /**
046: * Gets the File Specific Transform
047: *
048: *@param summary Gets a file specific transform
049: *@return The FileSpecificTransform value
050: */
051: protected TransformAST getFileSpecificTransform(FileSummary summary) {
052: if (summary.isMoving()) {
053: return new ChangePackageTransform(newPackageName);
054: }
055:
056: return null;
057: }
058:
059: /**
060: * Gets the New Imports transform
061: *
062: *@param node the file summary
063: *@param className the name of the class that is changing
064: *@return The NewImports value
065: */
066: protected AddImportTransform getNewImports(FileSummary node,
067: String className) {
068: String currentPackage = "";
069: String otherPackage = "";
070:
071: if (node.isMoving()) {
072: currentPackage = oldPackageName;
073: otherPackage = newPackageName;
074: } else {
075: currentPackage = newPackageName;
076: otherPackage = oldPackageName;
077: }
078:
079: return new AddImportTransform(currentPackage, className);
080: }
081:
082: /**
083: * Gets the Remove Imports transform
084: *
085: *@param node the import summary
086: *@return The transform
087: */
088: protected RemoveImportTransform getRemoveImportTransform(
089: ImportSummary node) {
090: if (node.getType() == null) {
091: return null;
092: } else {
093: return new RemoveImportTransform(oldPackageName, node
094: .getType());
095: }
096: }
097:
098: /**
099: * Gets the AppropriateClasses attribute of the TypeChangeVisitor object
100: *
101: *@param node Description of Parameter
102: *@return The AppropriateClasses value
103: */
104: protected LinkedList getAppropriateClasses(FileSummary node) {
105: if (!node.isMoving()) {
106: MovingTypeList mtl = new MovingTypeList();
107: return mtl.query(oldPackageName);
108: } else {
109: StayingTypeList stl = new StayingTypeList();
110: return stl.query(oldPackageName);
111: }
112: }
113:
114: /**
115: * Gets the reference to the file where the refactored output should be sent
116: *
117: *@param node the files summary
118: *@return The NewFile value
119: */
120: protected File getNewFile(FileSummary node) {
121: if (!node.isMoving()) {
122: return node.getFile();
123: }
124:
125: File current = base;
126:
127: StringTokenizer tok = new StringTokenizer(newPackageName, ".");
128: while (tok.hasMoreTokens()) {
129: current = new File(current, tok.nextToken());
130: }
131:
132: return new File(current, node.getName());
133: }
134:
135: /**
136: * Return the current package
137: *
138: *@return the current package of the class
139: */
140: protected String getCurrentPackage() {
141: return oldPackageName;
142: }
143:
144: /**
145: * Gets the RenamingTransform
146: *
147: *@param refactoring the refactoring
148: *@param node the file summary to reference
149: *@param className the name of the class that is changing
150: */
151: protected void addRenamingTransforms(ComplexTransform refactoring,
152: FileSummary node, String className) {
153: String currentPackage = "";
154: String otherPackage = "";
155: if (node.isMoving()) {
156: currentPackage = oldPackageName;
157: otherPackage = newPackageName;
158: } else {
159: currentPackage = newPackageName;
160: otherPackage = oldPackageName;
161: }
162:
163: if (otherPackage.length() > 0) {
164: refactoring.add(new RenameTypeTransform(otherPackage,
165: currentPackage, className));
166: }
167: }
168:
169: /**
170: * Set the class name. Allows sub classes of this to reuse themselves for
171: * different classes in the same package.
172: *
173: *@param newClassName the new class name
174: */
175: protected void add(String newClassName) {
176: FileSummary summary = (new FileSummaryGetter()).query(
177: oldPackageName, newClassName);
178: if (summary != null) {
179: summary.setMoving(true);
180: } else {
181: System.out.println("WARNING: Unable to find the class "
182: + newClassName + " in the package "
183: + oldPackageName);
184: }
185: }
186: }
|