com.thoughtworks.gauge.refactor.JavaRefactoring Maven / Gradle / Ivy
/*----------------------------------------------------------------
* Copyright (c) ThoughtWorks, Inc.
* Licensed under the Apache License, Version 2.0
* See LICENSE.txt in the project root for license information.
*----------------------------------------------------------------*/
package com.thoughtworks.gauge.refactor;
import com.github.javaparser.Position;
import com.github.javaparser.Range;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.Parameter;
import com.thoughtworks.gauge.StepValue;
import com.thoughtworks.gauge.Util;
import com.thoughtworks.gauge.registry.StepRegistry;
import gauge.messages.Messages;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class JavaRefactoring {
private final StepValue oldStepValue;
private final StepValue newStepValue;
private final List paramPositions;
private StepRegistry registry;
private String parameterizedStepValue;
private boolean saveChanges;
public JavaRefactoring(StepValue oldStepValue, StepValue newStepValue, List paramPositionsList, StepRegistry registry, String parameterizedStepValue, boolean saveChanges) {
this.oldStepValue = oldStepValue;
this.newStepValue = newStepValue;
this.paramPositions = paramPositionsList;
this.registry = registry;
this.parameterizedStepValue = parameterizedStepValue;
this.saveChanges = saveChanges;
}
public RefactoringResult performRefactoring() {
String oldStepText = oldStepValue.getStepText();
String fileName = registry.get(oldStepText).getFileName();
Boolean hasAlias = registry.get(oldStepText).getHasAlias();
if (fileName == null || fileName.isEmpty()) {
return new RefactoringResult(false, "Step Implementation Not Found: Unable to find a file Name to refactor");
}
if (hasAlias) {
return new RefactoringResult(false, "Refactoring for steps having aliases are not supported.");
}
if (registry.hasMultipleImplementations(oldStepText)) {
return new RefactoringResult(false, "Duplicate step implementation found.");
}
JavaRefactoringElement element;
try {
element = createJavaRefactoringElement(fileName);
if (saveChanges) {
new FileModifier(element).refactor();
}
} catch (IOException e) {
return new RefactoringResult(false, "Unable to read/write file while refactoring. " + e.getMessage());
} catch (RefactoringException e) {
return new RefactoringResult(false, "Step Implementation Not Found: " + e.getMessage());
} catch (Exception e) {
return new RefactoringResult(false, "Refactoring failed: " + e.getMessage());
}
return new RefactoringResult(true, element);
}
private Range getStepRange(Range range) {
return new Range(new Position(range.begin.line, range.begin.column - 1), new Position(range.end.line, range.end.column));
}
private String updatedParameters(List parameters) {
return new StringBuilder(StringUtils.join(parameters, ", ")).toString();
}
private Range getParamsRange() {
List parameters = registry.get(oldStepValue.getStepText()).getParameters();
if (parameters.isEmpty()) {
int line = registry.get(oldStepValue.getStepText()).getSpan().begin.line + 1;
int column = registry.get(oldStepValue.getStepText()).getName().length();
return new Range(new Position(line, column), new Position(line, column));
}
Range firstParam = parameters.get(0).getRange().get();
Range lastParam = parameters.get(parameters.size() - 1).getRange().get();
return new Range(new Position(firstParam.begin.line, firstParam.begin.column - 1), new Position(lastParam.end.line, lastParam.end.column));
}
JavaRefactoringElement createJavaRefactoringElement(String fileName) throws RefactoringException {
List javaParseWorkers = parseJavaFiles(Util.workingDir(), fileName);
if (javaParseWorkers.isEmpty()) {
throw new RefactoringException("Unable to find file: " + fileName);
}
try {
for (JavaParseWorker javaFile : javaParseWorkers) {
CompilationUnit compilationUnit = javaFile.getCompilationUnit();
RefactoringMethodVisitor methodVisitor = new RefactoringMethodVisitor(oldStepValue, newStepValue, paramPositions);
methodVisitor.visit(compilationUnit, null);
if (methodVisitor.refactored()) {
JavaRefactoringElement javaElement = methodVisitor.getRefactoredJavaElement();
javaElement.setFile(javaFile.getJavaFile());
if (!saveChanges) {
javaElement = addJavaDiffElements(methodVisitor, javaElement);
}
return javaElement;
}
}
} catch (Exception e) {
throw new RefactoringException("Failed creating java element: " + e.getMessage());
}
throw new RefactoringException("Unable to find implementation");
}
private JavaRefactoringElement addJavaDiffElements(RefactoringMethodVisitor methodVisitor, JavaRefactoringElement javaElement) {
List newParameters = methodVisitor.getNewParameters();
Range stepLineSpan = methodVisitor.getStepLineSpan();
javaElement.addDiffs(new Diff("\"" + parameterizedStepValue + "\"", getStepRange(stepLineSpan)));
javaElement.addDiffs(new Diff(updatedParameters(newParameters), getParamsRange()));
return javaElement;
}
private List parseJavaFiles(File workingDir, String fileName) {
ArrayList javaFiles = new ArrayList<>();
File[] allFiles = workingDir.listFiles();
for (File file : allFiles) {
if (file.isDirectory()) {
javaFiles.addAll(parseJavaFiles(file, fileName));
} else {
if (file.getAbsolutePath().endsWith(fileName)) {
JavaParseWorker worker = new JavaParseWorker(file);
worker.start();
javaFiles.add(worker);
}
}
}
return javaFiles;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy