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.field;
010:
011: import java.util.Iterator;
012: import java.util.LinkedList;
013: import java.util.StringTokenizer;
014: import org.acm.seguin.refactor.ComplexTransform;
015: import org.acm.seguin.summary.FieldAccessSummary;
016: import org.acm.seguin.summary.FieldSummary;
017: import org.acm.seguin.summary.FileSummary;
018: import org.acm.seguin.summary.LocalVariableSummary;
019: import org.acm.seguin.summary.MessageSendSummary;
020: import org.acm.seguin.summary.MethodSummary;
021: import org.acm.seguin.summary.ParameterSummary;
022: import org.acm.seguin.summary.Summary;
023: import org.acm.seguin.summary.TraversalVisitor;
024: import org.acm.seguin.summary.TypeDeclSummary;
025: import org.acm.seguin.summary.TypeSummary;
026: import org.acm.seguin.summary.VariableSummary;
027:
028: /**
029: * All items that want to visit a summary tree should implement this
030: * interface.
031: *
032: *@author Chris Seguin
033: *@created May 15, 1999
034: */
035: public class RenameSystemTraversal extends TraversalVisitor {
036: /**
037: * Visit a file summary.
038: *
039: *@param node the summary that we are visiting
040: *@param data the data that was passed in
041: *@return the result
042: */
043: public Object visit(FileSummary node, Object data) {
044: if (node.getFile() == null) {
045: return data;
046: }
047:
048: // Over the types
049: Boolean result = Boolean.FALSE;
050: Iterator iter = node.getTypes();
051: if (iter != null) {
052: while (iter.hasNext() && result.equals(Boolean.FALSE)) {
053: TypeSummary next = (TypeSummary) iter.next();
054: result = (Boolean) next.accept(this , data);
055: }
056: }
057:
058: if (result.booleanValue()) {
059: // Apply the refactoring to this file
060: System.out
061: .println("Updating: " + node.getFile().getPath());
062: RenameFieldData rfd = (RenameFieldData) data;
063: transform(node, rfd.getOldField(), rfd.getNewName(), rfd
064: .getComplexTransform());
065: }
066:
067: // Return some value
068: return data;
069: }
070:
071: /**
072: * Visit a type summary.
073: *
074: *@param node the summary that we are visiting
075: *@param data the data that was passed in
076: *@return the result
077: */
078: public Object visit(TypeSummary node, Object data) {
079: RenameFieldData rfd = (RenameFieldData) data;
080: if (node.equals(rfd.getTypeSummary())) {
081: return Boolean.FALSE;
082: }
083:
084: // Over the fields
085: Iterator iter = node.getMethods();
086: if (iter != null) {
087: while (iter.hasNext()) {
088: MethodSummary next = (MethodSummary) iter.next();
089: Boolean result = (Boolean) next.accept(this , data);
090: if (result.equals(Boolean.TRUE)) {
091: return result;
092: }
093: }
094: }
095:
096: // Over the types
097: iter = node.getTypes();
098: if (iter != null) {
099: while (iter.hasNext()) {
100: TypeSummary next = (TypeSummary) iter.next();
101: Boolean result = (Boolean) next.accept(this , data);
102: if (result.equals(Boolean.TRUE)) {
103: return result;
104: }
105: }
106: }
107:
108: // Return some value
109: return Boolean.FALSE;
110: }
111:
112: /**
113: * Visit a method summary.
114: *
115: *@param node the summary that we are visiting
116: *@param data the data that was passed in
117: *@return the result
118: */
119: public Object visit(MethodSummary node, Object data) {
120: // Finally visit the dependencies
121: Iterator iter = node.getDependencies();
122: if (iter != null) {
123: while (iter.hasNext()) {
124: Summary next = (Summary) iter.next();
125: Boolean result = (Boolean) next.accept(this , data);
126: if (result.equals(Boolean.TRUE)) {
127: return result;
128: }
129: }
130: }
131:
132: return Boolean.FALSE;
133: }
134:
135: /**
136: * Visit a field summary.
137: *
138: *@param node the summary that we are visiting
139: *@param data the data that was passed in
140: *@return the result
141: */
142: public Object visit(FieldSummary node, Object data) {
143: return Boolean.FALSE;
144: }
145:
146: /**
147: * Visit a parameter summary.
148: *
149: *@param node the summary that we are visiting
150: *@param data the data that was passed in
151: *@return the result
152: */
153: public Object visit(ParameterSummary node, Object data) {
154: return Boolean.FALSE;
155: }
156:
157: /**
158: * Visit a local variable summary.
159: *
160: *@param node the summary that we are visiting
161: *@param data the data that was passed in
162: *@return the result
163: */
164: public Object visit(LocalVariableSummary node, Object data) {
165: return Boolean.FALSE;
166: }
167:
168: /**
169: * Visit a variable summary.
170: *
171: *@param node the summary that we are visiting
172: *@param data the data that was passed in
173: *@return the result
174: */
175: public Object visit(VariableSummary node, Object data) {
176: return Boolean.FALSE;
177: }
178:
179: /**
180: * Visit a type declaration summary.
181: *
182: *@param node the summary that we are visiting
183: *@param data the data that was passed in
184: *@return the result
185: */
186: public Object visit(TypeDeclSummary node, Object data) {
187: return Boolean.FALSE;
188: }
189:
190: /**
191: * Visit a message send summary.
192: *
193: *@param node the summary that we are visiting
194: *@param data the data that was passed in
195: *@return the result
196: */
197: public Object visit(MessageSendSummary node, Object data) {
198: String message = node.toString();
199:
200: RenameFieldData rfd = (RenameFieldData) data;
201: StringTokenizer tok = new StringTokenizer(message, ".");
202:
203: while (tok.hasMoreTokens()) {
204: String next = tok.nextToken();
205: if (next.equals(rfd.getOldName())) {
206: return Boolean.TRUE;
207: }
208: }
209:
210: return Boolean.FALSE;
211: }
212:
213: /**
214: * Visit a field access summary.
215: *
216: *@param node the summary that we are visiting
217: *@param data the data that was passed in
218: *@return the result
219: */
220: public Object visit(FieldAccessSummary node, Object data) {
221: String message = node.getName();
222:
223: RenameFieldData rfd = (RenameFieldData) data;
224: StringTokenizer tok = new StringTokenizer(message, ".");
225:
226: while (tok.hasMoreTokens()) {
227: String next = tok.nextToken();
228: if (next.equals(rfd.getOldName())) {
229: return Boolean.TRUE;
230: }
231: }
232:
233: return Boolean.FALSE;
234: }
235:
236: /**
237: * Perform the rename transformation on this particular file
238: *
239: *@param fileSummary Description of Parameter
240: *@param oldField Description of Parameter
241: *@param newName Description of Parameter
242: *@param transform Description of Parameter
243: */
244: private void transform(FileSummary fileSummary,
245: FieldSummary oldField, String newName,
246: ComplexTransform transform) {
247: transform.clear();
248:
249: RenameFieldTransform rft = new RenameFieldTransform(oldField,
250: newName);
251: transform.add(rft);
252: transform.apply(fileSummary.getFile(), fileSummary.getFile());
253: }
254: }
|