| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.netbeans.modules.form.refactoring; |
| |
| import com.sun.source.tree.ClassTree; |
| import com.sun.source.tree.IdentifierTree; |
| import com.sun.source.tree.Tree; |
| import com.sun.source.util.TreePath; |
| import org.netbeans.api.java.source.support.ErrorAwareTreePathScanner; |
| import com.sun.source.util.Trees; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import javax.lang.model.element.Element; |
| import org.netbeans.api.java.source.CancellableTask; |
| import org.netbeans.api.java.source.CompilationController; |
| import org.netbeans.api.java.source.CompilationInfo; |
| import org.netbeans.api.java.source.JavaSource; |
| import org.netbeans.api.java.source.JavaSource.Phase; |
| import org.netbeans.api.java.source.TreePathHandle; |
| import org.netbeans.modules.form.FormDataObject; |
| import org.netbeans.modules.form.FormEditor; |
| import org.netbeans.modules.nbform.FormEditorSupport; |
| import org.netbeans.modules.form.FormModel; |
| import org.netbeans.modules.form.RenameSupport; |
| import org.netbeans.modules.refactoring.api.Problem; |
| import org.netbeans.modules.refactoring.api.RefactoringSession; |
| import org.netbeans.modules.refactoring.api.RenameRefactoring; |
| import org.openide.util.Lookup; |
| import org.openide.util.lookup.Lookups; |
| import org.openide.util.lookup.ServiceProvider; |
| |
| /** |
| * Class used to hook form component/variables renaming into refactoring. |
| * @author Wade Chandler |
| * @version 1.0 |
| */ |
| @ServiceProvider(service=RenameSupport.Refactoring.class) |
| public class RADComponentRenameRefactoringSupport implements RenameSupport.Refactoring { |
| |
| @Override |
| public void renameComponent(FormModel formModel, String currentName, String newName) { |
| FormDataObject formDO = FormEditor.getFormDataObject(formModel); |
| JavaSource js = JavaSource.forFileObject(formDO.getPrimaryFile()); |
| MemberVisitor scanner = new MemberVisitor(currentName, true); //privateField); |
| try { |
| js.runUserActionTask(scanner, true); |
| doRenameRefactoring(formDO, newName, scanner.getHandle()); |
| } catch (IOException e) { |
| Logger.getLogger(RADComponentRenameRefactoringSupport.class.getName()).log(Level.SEVERE, e.getMessage(), e); |
| } |
| } |
| |
| private static void doRenameRefactoring(FormDataObject dao, String newName, TreePathHandle handle) throws IOException { |
| if(handle==null){ |
| //this would only happen if setName were called without the correct component being |
| //selected some how... |
| return; |
| } |
| FormEditorSupport fes = (FormEditorSupport)dao.getFormEditorSupport(); |
| if (fes.isModified()) { |
| fes.saveDocument(); |
| } |
| //ok, so we are now ready to actually setup our RenameRefactoring...we need the element TreePathHandle |
| Lookup rnl = Lookups.singleton(handle); |
| RefactoringSession renameSession = RefactoringSession.create("Change variable name");//NOI18N |
| RenameRefactoring refactoring = new RenameRefactoring(rnl); |
| Problem pre = refactoring.preCheck(); |
| if(pre!=null&&pre.isFatal()){ |
| Logger.getLogger("global").log(Level.WARNING, "There were problems trying to perform the refactoring."); |
| } |
| |
| Problem p = null; |
| |
| if( (!(pre!=null&&pre.isFatal())) && !emptyOrWhite(newName) ){ |
| refactoring.setNewName(newName); |
| p = refactoring.prepare(renameSession); |
| } |
| |
| if( (!(p!=null&&p.isFatal())) && !emptyOrWhite(newName) ){ |
| renameSession.doRefactoring(true); |
| } |
| } |
| |
| private static boolean emptyOrWhite(String s){ |
| return s == null || s.trim().length() == 0; |
| } |
| |
| private static class MemberVisitor |
| extends ErrorAwareTreePathScanner<Void, Void> |
| implements CancellableTask<CompilationController>{ |
| |
| private CompilationInfo info; |
| private String member = null; |
| private TreePathHandle handle = null; |
| |
| boolean findUsages; |
| private Element variableElement; |
| private List<Integer> usagesPositions; |
| |
| public TreePathHandle getHandle() { |
| return handle; |
| } |
| |
| public void setHandle(TreePathHandle handle) { |
| this.handle = handle; |
| } |
| |
| public MemberVisitor(String member, boolean findUsages) { |
| this.member = member; |
| this.findUsages = findUsages; |
| } |
| |
| @Override |
| public Void visitClass(ClassTree t, Void v) { |
| if (variableElement == null) { |
| // try to find the component's field variable in the class |
| List<? extends Tree> members = (List<? extends Tree>) t.getMembers(); |
| Iterator<? extends Tree> it = members.iterator(); |
| while(it.hasNext()){ |
| Tree tr = it.next(); |
| if (tr.getKind() == Tree.Kind.VARIABLE) { |
| Trees trees = info.getTrees(); |
| TreePath path = new TreePath(getCurrentPath(), tr); |
| Element el = trees.getElement(path); |
| if (el != null) { // Issue 185420 |
| String sname = el.getSimpleName().toString(); |
| if(sname.equals(this.member)){ |
| this.handle = TreePathHandle.create(path, info); |
| variableElement = el; |
| if (findUsages) { |
| usagesPositions = new ArrayList<Integer>(); |
| } |
| } |
| } |
| } |
| } |
| } |
| if (findUsages) { |
| super.visitClass(t, v); |
| } |
| return null; |
| } |
| |
| @Override |
| public Void visitIdentifier(IdentifierTree tree, Void v) { |
| if (findUsages) { |
| Element el = info.getTrees().getElement(getCurrentPath()); |
| if (variableElement != null && variableElement.equals(el)) { |
| int pos = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), tree); |
| usagesPositions.add(pos); |
| } |
| } |
| return super.visitIdentifier(tree, v); |
| } |
| |
| @Override |
| public void cancel() { |
| } |
| |
| @Override |
| public void run(CompilationController parameter) throws IOException { |
| this.info = parameter; |
| parameter.toPhase(Phase.RESOLVED); |
| this.scan(parameter.getCompilationUnit(), null); |
| } |
| } |
| } |