blob: 77a5d6e0182d2737752806546960d6361ba9d3be [file] [log] [blame]
/*
* 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.refactoring.java.plugins;
import com.sun.source.util.TreePath;
import java.io.IOException;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.Name;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.util.ElementFilter;
import org.netbeans.api.java.source.CodeStyle;
import org.netbeans.api.java.source.CodeStyleUtils;
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.Task;
import org.netbeans.api.java.source.TreePathHandle;
import org.netbeans.modules.refactoring.api.AbstractRefactoring;
import org.netbeans.modules.refactoring.api.Problem;
import org.netbeans.modules.refactoring.api.RenameRefactoring;
import org.netbeans.modules.refactoring.java.RefactoringUtils;
import org.netbeans.modules.refactoring.java.spi.JavaRefactoringPlugin;
import org.netbeans.modules.refactoring.java.ui.JavaRenameProperties;
import org.netbeans.modules.refactoring.spi.RefactoringElementsBag;
import org.openide.util.Exceptions;
import org.openide.util.lookup.Lookups;
/**
*
* @author Jan Becicka
*/
public class RenamePropertyRefactoringPlugin extends JavaRefactoringPlugin {
private RenameRefactoring refactoring;
private TreePathHandle property;
private CodeStyle codeStyle;
private boolean isStatic;
private boolean isBoolean;
private RenameRefactoring getterDelegate;
private RenameRefactoring setterDelegate;
private RenameRefactoring parameterDelegate;
/** Creates a new instance of RenamePropertyRefactoringPlugin */
public RenamePropertyRefactoringPlugin(RenameRefactoring rename) {
this.refactoring = rename;
property = rename.getRefactoringSource().lookup(TreePathHandle.class);
}
@Override
protected JavaSource getJavaSource(Phase phase) {
return JavaSource.forFileObject(property.getFileObject());
}
@Override
public Problem checkParameters() {
if (!isRenameProperty()) {
return null;
}
initDelegates();
Problem p = null;
if (getterDelegate != null) {
p = JavaPluginUtils.chainProblems(p, getterDelegate.checkParameters());
if (p != null && p.isFatal()) {
return p;
}
}
if (setterDelegate != null) {
p = JavaPluginUtils.chainProblems(p, setterDelegate.checkParameters());
if (p != null && p.isFatal()) {
return p;
}
}
if (parameterDelegate != null) {
p = JavaPluginUtils.chainProblems(p, parameterDelegate.checkParameters());
if (p != null && p.isFatal()) {
return p;
}
}
return p = JavaPluginUtils.chainProblems(p, super.checkParameters());
}
@Override
protected Problem fastCheckParameters(CompilationController info) throws IOException {
if (!isRenameProperty()) {
return null;
}
initDelegates();
info.toPhase(JavaSource.Phase.RESOLVED);
Element el = property.resolveElement(info);
if (el == null || el.getKind() != ElementKind.FIELD) {
return null;
}
String oldName = el.getSimpleName().toString();
String bareName = RefactoringUtils.removeFieldPrefixSuffix(el, codeStyle);
boolean isStatic = el.getModifiers().contains(Modifier.STATIC);
String bareNewName = CodeStyleUtils.removePrefixSuffix(refactoring.getNewName(),
isStatic ? codeStyle.getStaticFieldNamePrefix() : codeStyle.getFieldNamePrefix(),
isStatic ? codeStyle.getStaticFieldNameSuffix() : codeStyle.getFieldNameSuffix());
if (bareName.equals(bareNewName)) {
return null;
}
Problem p = null;
JavaRenameProperties renameProps = refactoring.getContext().lookup(JavaRenameProperties.class);
boolean saveNoChange = false;
if (renameProps != null) {
saveNoChange = renameProps.isNoChangeOK();
renameProps.setNoChangeOK(true);
}
try {
if (getterDelegate != null) {
String gettername = CodeStyleUtils.computeGetterName(
refactoring.getNewName(), isBoolean, isStatic, codeStyle);
getterDelegate.setNewName(gettername);
p = JavaPluginUtils.chainProblems(p, getterDelegate.fastCheckParameters());
if (p != null && p.isFatal()) {
return p;
}
}
if (setterDelegate != null) {
String settername = CodeStyleUtils.computeSetterName(
refactoring.getNewName(), isStatic, codeStyle);
setterDelegate.setNewName(settername);
p = JavaPluginUtils.chainProblems(p, setterDelegate.fastCheckParameters());
if (p != null && p.isFatal()) {
return p;
}
}
if (parameterDelegate != null) {
String newParam = RefactoringUtils.addParamPrefixSuffix(
CodeStyleUtils.removePrefixSuffix(
refactoring.getNewName(),
isStatic ? codeStyle.getStaticFieldNamePrefix() : codeStyle.getFieldNamePrefix(),
isStatic ? codeStyle.getStaticFieldNameSuffix() : codeStyle.getFieldNameSuffix()), codeStyle);
parameterDelegate.setNewName(newParam);
p = JavaPluginUtils.chainProblems(p, parameterDelegate.fastCheckParameters());
if (p != null && p.isFatal()) {
return p;
}
}
} finally {
if (renameProps != null) {
renameProps.setNoChangeOK(saveNoChange);
}
}
return p = JavaPluginUtils.chainProblems(p, super.fastCheckParameters(info));
}
@Override
protected Problem preCheck(CompilationController javac) throws IOException {
if (!isRenameProperty()) {
return null;
}
initDelegates();
Problem p = null;
if (getterDelegate != null) {
p = JavaPluginUtils.chainProblems(p, getterDelegate.preCheck());
if (p != null && p.isFatal()) {
return p;
}
}
if (setterDelegate != null) {
p = JavaPluginUtils.chainProblems(p, setterDelegate.preCheck());
if (p != null && p.isFatal()) {
return p;
}
}
if (parameterDelegate != null) {
p = JavaPluginUtils.chainProblems(p, parameterDelegate.preCheck());
if (p != null && p.isFatal()) {
return p;
}
}
return p = JavaPluginUtils.chainProblems(p, super.preCheck(javac));
}
@Override
public Problem prepare(RefactoringElementsBag reb) {
if (!isRenameProperty()) {
return null;
}
initDelegates();
fireProgressListenerStart(AbstractRefactoring.PREPARE, 3);
Problem p = null;
if (getterDelegate != null) {
p = JavaPluginUtils.chainProblems(p, getterDelegate.prepare(reb.getSession()));
if (p != null && p.isFatal()) {
return p;
}
}
fireProgressListenerStep();
if (setterDelegate != null) {
p = JavaPluginUtils.chainProblems(p, setterDelegate.prepare(reb.getSession()));
if (p != null && p.isFatal()) {
return p;
}
}
fireProgressListenerStep();
if (parameterDelegate != null) {
p = JavaPluginUtils.chainProblems(p, parameterDelegate.prepare(reb.getSession()));
if (p != null && p.isFatal()) {
return p;
}
}
fireProgressListenerStep();
fireProgressListenerStop();
return p;
}
private boolean isRenameProperty() {
JavaRenameProperties renameProps = refactoring.getContext().lookup(JavaRenameProperties.class);
if (renameProps != null && renameProps.isIsRenameGettersSetters()) {
return true;
}
return false;
}
private boolean inited = false;
private void initDelegates() {
if (inited) {
return;
}
try {
getJavaSource(Phase.PREPARE).runUserActionTask(new Task<CompilationController>() {
@Override
public void run(CompilationController p) throws Exception {
JavaRenameProperties renameProps = refactoring.getContext().lookup(JavaRenameProperties.class);
p.toPhase(JavaSource.Phase.RESOLVED);
codeStyle = RefactoringUtils.getCodeStyle(p);
Element propertyElement = property.resolveElement(p);
isStatic = propertyElement.getModifiers().contains(Modifier.STATIC);
isBoolean = propertyElement.asType().getKind() == TypeKind.BOOLEAN;
String propName = RefactoringUtils.removeFieldPrefixSuffix(propertyElement, codeStyle);
String paramName = RefactoringUtils.addParamPrefixSuffix(propName, codeStyle);
String newParam = RefactoringUtils.addParamPrefixSuffix(
CodeStyleUtils.removePrefixSuffix(
refactoring.getNewName(),
isStatic ? codeStyle.getStaticFieldNamePrefix() : codeStyle.getFieldNamePrefix(),
isStatic ? codeStyle.getStaticFieldNameSuffix() : codeStyle.getFieldNameSuffix()), codeStyle);
for (ExecutableElement el : ElementFilter.methodsIn(propertyElement.getEnclosingElement().getEnclosedElements())) {
TreePath elPath = p.getTrees().getPath(el);
if(elPath == null || p.getTreeUtilities().isSynthetic(elPath)) {
continue;
} else if (RefactoringUtils.isGetter(p, el, propertyElement)) {
getterDelegate = new RenameRefactoring(Lookups.singleton(TreePathHandle.create(el, p)));
getterDelegate.getContext().add(renameProps);
String gettername = CodeStyleUtils.computeGetterName(
refactoring.getNewName(), isBoolean, isStatic, codeStyle);
getterDelegate.setNewName(gettername);
getterDelegate.setSearchInComments(refactoring.isSearchInComments());
} else if (RefactoringUtils.isSetter(p, el, propertyElement)) {
setterDelegate = new RenameRefactoring(Lookups.singleton(TreePathHandle.create(el, p)));
setterDelegate.getContext().add(renameProps);
String settername = CodeStyleUtils.computeSetterName(
refactoring.getNewName(), isStatic, codeStyle);
setterDelegate.setNewName(settername);
setterDelegate.setSearchInComments(refactoring.isSearchInComments());
VariableElement par = el.getParameters().iterator().next();
if (par.getSimpleName().contentEquals(paramName)) {
parameterDelegate = new RenameRefactoring(Lookups.singleton(TreePathHandle.create(p.getTrees().getPath(par), p)));
parameterDelegate.getContext().add(RenamePropertyRefactoringPlugin.this);
parameterDelegate.setNewName(newParam);
parameterDelegate.setSearchInComments(refactoring.isSearchInComments());
parameterDelegate.getContext().add(renameProps);
}
}
}
}
}, true);
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
inited = true;
}
}