001: /*
002: * Copyright (c) 2001-2007, Jean Tessier
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions
007: * are met:
008: *
009: * * Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: *
012: * * Redistributions in binary form must reproduce the above copyright
013: * notice, this list of conditions and the following disclaimer in the
014: * documentation and/or other materials provided with the distribution.
015: *
016: * * Neither the name of Jean Tessier nor the names of his contributors
017: * may be used to endorse or promote products derived from this software
018: * without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
023: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
024: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031: */
032:
033: package com.jeantessier.dependency;
034:
035: import java.util.*;
036:
037: import org.apache.log4j.*;
038:
039: import com.jeantessier.classreader.*;
040:
041: public class DeletingVisitor implements Visitor, RemoveVisitor {
042: private NodeFactory factory;
043:
044: public DeletingVisitor(NodeFactory factory) {
045: this .factory = factory;
046: }
047:
048: public NodeFactory getFactory() {
049: return factory;
050: }
051:
052: public void traverseNodes(Collection<? extends Node> nodes) {
053: // Iterator i = nodes.iterator();
054: // while (i.hasNext()) {
055: // ((Node) i.next()).accept(this);
056: // }
057: }
058:
059: /*
060: * Regular visits are used to completely delete sections
061: */
062:
063: public void visitPackageNode(PackageNode node) {
064: Logger.getLogger(getClass()).debug(
065: "visitPackageNode(" + node + ")");
066:
067: for (ClassNode classNode : new ArrayList<ClassNode>(node
068: .getClasses())) {
069: classNode.accept(this );
070: }
071:
072: visitNode(node);
073: }
074:
075: public void visitClassNode(ClassNode node) {
076: Logger.getLogger(getClass()).debug(
077: "visitClassNode(" + node + ")");
078:
079: for (FeatureNode featureNode : new ArrayList<FeatureNode>(node
080: .getFeatures())) {
081: featureNode.accept(this );
082: }
083:
084: visitNode(node);
085: }
086:
087: public void visitFeatureNode(FeatureNode node) {
088: Logger.getLogger(getClass()).debug(
089: "visitFeatureNode(" + node + ")");
090:
091: visitNode(node);
092: }
093:
094: private void visitNode(Node node) {
095: node.setConfirmed(false);
096:
097: for (Node outbound : new ArrayList<Node>(node
098: .getOutboundDependencies())) {
099: node.removeDependency(outbound);
100: outbound.acceptOutbound(this );
101: }
102:
103: node.acceptOutbound(this );
104: }
105:
106: /*
107: * Outbound visits are used to clean up sections
108: */
109:
110: public void visitOutboundPackageNode(PackageNode node) {
111: Logger.getLogger(getClass()).debug(
112: "visitOutboundPackageNode(" + node + ")");
113:
114: if (canDeletePackage(node)) {
115: factory.deletePackage(node);
116: }
117: }
118:
119: public void visitOutboundClassNode(ClassNode node) {
120: Logger.getLogger(getClass()).debug(
121: "visitOutboundClassNode(" + node + ")");
122:
123: if (canDeleteClass(node)) {
124: factory.deleteClass(node);
125: }
126:
127: node.getPackageNode().acceptOutbound(this );
128: }
129:
130: public void visitOutboundFeatureNode(FeatureNode node) {
131: Logger.getLogger(getClass()).debug(
132: "visitOutboundFeatureNode(" + node + ")");
133:
134: if (canDeleteFeature(node)) {
135: factory.deleteFeature(node);
136: }
137:
138: node.getClassNode().acceptOutbound(this );
139: }
140:
141: private boolean canDelete(Node node) {
142: return !node.isConfirmed()
143: && node.getInboundDependencies().isEmpty();
144: }
145:
146: private boolean canDeletePackage(PackageNode node) {
147: return canDelete(node) && node.getClasses().isEmpty();
148: }
149:
150: private boolean canDeleteClass(ClassNode node) {
151: return canDelete(node) && node.getFeatures().isEmpty();
152: }
153:
154: private boolean canDeleteFeature(FeatureNode node) {
155: return canDelete(node);
156: }
157:
158: /*
159: * Inbound visits are not used
160: */
161:
162: public void visitInboundPackageNode(PackageNode node) {
163: // Do nothing
164: }
165:
166: public void visitInboundClassNode(ClassNode node) {
167: // Do nothing
168: }
169:
170: public void visitInboundFeatureNode(FeatureNode node) {
171: // Do nothing
172: }
173:
174: /*
175: * RemoveVisitor methods
176: */
177:
178: public void removeClass(String classname) {
179: Node node = factory.getClasses().get(classname);
180: if (node != null) {
181: node.accept(this);
182: }
183: }
184: }
|