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 org.acm.seguin.summary.TraversalVisitor;
013: import org.acm.seguin.summary.FieldSummary;
014: import org.acm.seguin.summary.FileSummary;
015: import org.acm.seguin.summary.TypeSummary;
016: import org.acm.seguin.summary.TypeDeclSummary;
017: import org.acm.seguin.refactor.ComplexTransform;
018: import org.acm.seguin.summary.query.Ancestor;
019: import org.acm.seguin.summary.query.GetTypeSummary;
020:
021: /**
022: * Removes the field from all subclasses of a particular class.
023: *
024: *@author Chris Seguin
025: */
026: public class RemoveFieldFromSubclassVisitor extends TraversalVisitor {
027: private FieldSummary target;
028: private TypeSummary ancestor;
029: private ComplexTransform complex;
030: private TypeSummary notHere;
031:
032: /**
033: * Constructor for the RemoveFieldFromSubclassVisitor object
034: *
035: *@param type the ancestor type
036: *@param init the field
037: *@param notThisOne a type to skip
038: *@param transform Description of Parameter
039: */
040: public RemoveFieldFromSubclassVisitor(TypeSummary type,
041: FieldSummary init, TypeSummary notThisOne,
042: ComplexTransform transform) {
043: target = init;
044: ancestor = type;
045: notHere = notThisOne;
046: complex = transform;
047: }
048:
049: /**
050: * Visits a file summary node and updates it if necessary
051: *
052: *@param fileSummary Description of Parameter
053: *@param data Description of Parameter
054: *@return Description of the Returned Value
055: */
056: public Object visit(FileSummary fileSummary, Object data) {
057: complex.clear();
058: super .visit(fileSummary, data);
059: if (complex.hasAnyChanges()) {
060: complex.apply(fileSummary.getFile(), fileSummary.getFile());
061: }
062: return data;
063: }
064:
065: /**
066: * Visits a type summary and updates it
067: *
068: *@param typeSummary Description of Parameter
069: *@param data Description of Parameter
070: *@return Description of the Returned Value
071: */
072: public Object visit(TypeSummary typeSummary, Object data) {
073: if ((typeSummary != notHere)
074: && Ancestor.query(typeSummary, ancestor)) {
075: Iterator iter = typeSummary.getFields();
076: if (iter != null) {
077: while (iter.hasNext()) {
078: visit((FieldSummary) iter.next(), data);
079: }
080: }
081: }
082: return data;
083: }
084:
085: /**
086: * Visits the field summary and determines if it should be removed.
087: *
088: *@param fieldSummary Description of Parameter
089: *@param data Description of Parameter
090: *@return Description of the Returned Value
091: */
092: public Object visit(FieldSummary fieldSummary, Object data) {
093: if (fieldSummary.getName().equals(target.getName())) {
094: TypeDeclSummary current = fieldSummary.getTypeDecl();
095: TypeDeclSummary targetDecl = target.getTypeDecl();
096: if (GetTypeSummary.query(current) == GetTypeSummary
097: .query(targetDecl)) {
098: complex.add(new RemoveFieldTransform(target.getName()));
099: }
100: }
101:
102: return data;
103: }
104: }
|