* @return A list of changed files or a map containing a list of errors.
*/
private Object apply(ICompilationUnit src, ChangeCorrectionProposal proposal)
throws Exception
{
Change change = null;
try {
NullProgressMonitor monitor = new NullProgressMonitor();
change = proposal.getChange();
change.initializeValidationData(monitor);
RefactoringStatus status = change.isValid(monitor);
if (status.hasFatalError()){
List<String> errors = new ArrayList<String>();
for (RefactoringStatusEntry entry : status.getEntries()){
String message = entry.getMessage();
if (!errors.contains(message) &&
!message.startsWith("Found potential matches"))
{
errors.add(message);
}
}
HashMap<String,List<String>> result = new HashMap<String,List<String>>();
result.put("errors", errors);
return result;
}
ResourceChangeListener rcl = new ResourceChangeListener();
IWorkspace workspace = ResourcesPlugin.getWorkspace();
workspace.addResourceChangeListener(rcl);
try{
TextEdit[] edits = new TextEdit[0];
if (change instanceof TextFileChange){
TextFileChange fileChange = (TextFileChange)change;
fileChange.setSaveMode(TextFileChange.FORCE_SAVE);
TextEdit edit = fileChange.getEdit();
if (edit instanceof MultiTextEdit){
edits = ((MultiTextEdit)edit).getChildren();
}else{
edits = new TextEdit[]{edit};
}
}
PerformChangeOperation changeOperation = new PerformChangeOperation(change);
changeOperation.setUndoManager(
RefactoringCore.getUndoManager(), proposal.getName());
changeOperation.run(monitor);
if (edits.length > 0 &&
change instanceof CompilationUnitChange &&
src.equals(((CompilationUnitChange)change).getCompilationUnit()))
{
for (TextEdit edit : edits){
int offset = edit.getOffset();
int length = edit.getLength();
// for "Create field" and "Create local" the edit length includes
// additional existing code that we don't want to reformat.
if (proposal instanceof NewVariableCorrectionProposal) {
String text = src.getBuffer()
.getText(edit.getOffset(), edit.getLength());
int index = text.indexOf('\n');
if (index != -1){
length = index;
// include the white space up to the next bit of code
while(length < text.length()){
char next = text.charAt(length);
if (next == '\t' || next == '\n' || next == ' '){
length += 1;
continue;
}
break;
}
}
}
JavaUtils.format(
src, CodeFormatter.K_COMPILATION_UNIT, offset, length);
}
}
// if the proposal change touched the imports, then run our import
// grouping edit after it.
if (proposal instanceof ASTRewriteCorrectionProposal){
ASTRewriteCorrectionProposal astProposal =
(ASTRewriteCorrectionProposal)proposal;
if (astProposal.getImportRewrite() != null){
TextEdit groupingEdit =
ImportUtils.importGroupingEdit(src, getPreferences());
if (groupingEdit != null){
JavaModelUtil.applyEdit(src, groupingEdit, true, null);
if (src.isWorkingCopy()) {
src.commitWorkingCopy(false, null);
}
}
}
}
return rcl.getChangedFiles();
}finally{
workspace.removeResourceChangeListener(rcl);
}
}finally{
if (change != null) {
change.dispose();
}
}
}