001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.refactoring.java.plugins;
043:
044: import org.netbeans.modules.refactoring.java.spi.RefactoringVisitor;
045: import com.sun.source.tree.*;
046: import com.sun.source.util.TreePath;
047: import java.util.HashSet;
048: import java.util.Set;
049: import javax.lang.model.element.*;
050: import org.netbeans.api.java.source.ElementHandle;
051: import org.netbeans.api.java.source.GeneratorUtilities;
052: import org.netbeans.api.java.source.WorkingCopy;
053: import org.netbeans.modules.refactoring.java.RetoucheUtils;
054: import org.netbeans.modules.refactoring.java.api.MemberInfo;
055: import org.netbeans.modules.refactoring.java.api.PullUpRefactoring;
056: import org.netbeans.modules.refactoring.java.spi.ToPhaseException;
057:
058: /**
059: *
060: * @author Jan Becicka
061: */
062: public class PullUpTransformer extends RefactoringVisitor {
063:
064: private MemberInfo<ElementHandle<? extends Element>>[] members;
065: private Element targetType;
066: private PullUpRefactoring refactoring;
067:
068: public PullUpTransformer(PullUpRefactoring refactoring) {
069: this .refactoring = refactoring;
070: this .members = refactoring.getMembers();
071: }
072:
073: public void setWorkingCopy(WorkingCopy copy)
074: throws ToPhaseException {
075: super .setWorkingCopy(copy);
076: this .targetType = refactoring.getTargetType().resolve(copy);
077: }
078:
079: @Override
080: public Tree visitClass(ClassTree tree, Element p) {
081: Element el = workingCopy.getTrees()
082: .getElement(getCurrentPath());
083: GeneratorUtilities genUtils = GeneratorUtilities
084: .get(workingCopy); // helper
085: boolean classIsAbstract = el.getKind().isInterface();
086: ClassTree njuClass = tree;
087: if (el.equals(targetType)) {
088: //target type
089: //add members
090: for (int i = 0; i < members.length; i++) {
091: if (members[i].getGroup() == MemberInfo.Group.IMPLEMENTS) {
092: njuClass = make.addClassImplementsClause(njuClass,
093: make.Identifier(members[i]
094: .getElementHandle().resolve(
095: workingCopy)));
096: rewrite(tree, njuClass);
097: } else {
098: if (members[i].isMakeAbstract()) {
099:
100: if (!classIsAbstract) {
101: classIsAbstract = true;
102: Set<Modifier> mod = new HashSet<Modifier>(
103: njuClass.getModifiers().getFlags());
104: mod.add(Modifier.ABSTRACT);
105: mod.remove(Modifier.FINAL);
106: ModifiersTree modifiers = make
107: .Modifiers(mod);
108: rewrite(njuClass.getModifiers(), modifiers);
109: }
110:
111: Element methodElm = members[i]
112: .getElementHandle()
113: .resolve(workingCopy);
114: MethodTree method = (MethodTree) workingCopy
115: .getTrees().getTree(methodElm);
116: Set<Modifier> mod = new HashSet<Modifier>(
117: method.getModifiers().getFlags());
118: mod.add(Modifier.ABSTRACT);
119: mod.remove(Modifier.FINAL);
120: if (el.getKind().isInterface()) {
121: mod.remove(Modifier.PUBLIC);
122: mod.remove(Modifier.PROTECTED);
123: mod.remove(Modifier.PRIVATE);
124: mod.remove(Modifier.ABSTRACT);
125: }
126: MethodTree nju = make.Method(make
127: .Modifiers(mod), method.getName(),
128: method.getReturnType(), method
129: .getTypeParameters(), method
130: .getParameters(), method
131: .getThrows(), (BlockTree) null,
132: (ExpressionTree) method
133: .getDefaultValue());
134: nju = genUtils.importFQNs(nju);
135: RetoucheUtils.copyJavadoc(methodElm, nju,
136: workingCopy);
137: njuClass = genUtils.insertClassMember(njuClass,
138: nju);
139: rewrite(tree, njuClass);
140: } else {
141: Element methodElm = members[i]
142: .getElementHandle()
143: .resolve(workingCopy);
144: TreePath mpath = workingCopy.getTrees()
145: .getPath(
146: members[i].getElementHandle()
147: .resolve(workingCopy));
148: Tree newMethodTree = genUtils.importComments(
149: mpath.getLeaf(), mpath
150: .getCompilationUnit());
151: newMethodTree = genUtils
152: .importFQNs(newMethodTree);
153: if (methodElm != null)
154: RetoucheUtils.copyJavadoc(methodElm,
155: newMethodTree, workingCopy);
156: njuClass = genUtils.insertClassMember(njuClass,
157: newMethodTree);
158: rewrite(tree, njuClass);
159: }
160: }
161: }
162: } else {
163: for (int i = 0; i < members.length; i++) {
164: if (members[i].getGroup() == MemberInfo.Group.IMPLEMENTS) {
165: for (Tree t : njuClass.getImplementsClause()) {
166: Element currentInterface = workingCopy
167: .getTrees().getElement(
168: TreePath.getPath(
169: getCurrentPath(), t));
170: if (currentInterface.equals(members[i]
171: .getElementHandle()
172: .resolve(workingCopy))) {
173: njuClass = make
174: .removeClassImplementsClause(
175: njuClass, t);
176: rewrite(tree, njuClass);
177: }
178: }
179: } else {
180: Element current = workingCopy.getTrees()
181: .getElement(getCurrentPath());
182: Element currentMember = members[i]
183: .getElementHandle().resolve(workingCopy);
184: if (currentMember.getEnclosingElement().equals(
185: current)) {
186: if (!members[i].isMakeAbstract()) {
187: njuClass = make.removeClassMember(njuClass,
188: workingCopy.getTrees().getTree(
189: currentMember));
190: rewrite(tree, njuClass);
191: }
192: }
193: }
194: }
195: }
196: return super.visitClass(tree, p);
197: }
198:
199: }
|