我处理一组使用Xtext和Graphiti开发的插件。它与DSL和图形编辑器有关,可满足研究需求。我们在一些用户项目中有许多文件,它们之间有链接和引用。我需要实现一个Move Participant,当我们将某个东西从一个包移动到另一个时,如果该文件是其他文件中的引用,则自动更新所有文件。
例如:
ProjectA
|- src
| |-org.comp.A
| | |-networkA
| | |-networkB
| |-org.comp.B
| | |-fileC
| | |-fileD
org.comp.A.networkA
引用org.comp.B.fileC
和org.comp.B.fileD
。如果我将fileC和fileD移动到另一个包或另一个项目,我需要正确更新networkA。在networkA的内容中至少有2个不同的替换。
我已经写了一个类,简化了这里:
public class NetworkMoveParticipant extends MoveParticipant {
private IFile originalNetworkFile;
private IFolder destination;
private IPath newNetworkPath;
@Override
protected boolean initialize(Object element) {
if (element instanceof IFile) {
originalNetworkFile = (IFile) element;
destination = (IFolder) getArguments().getDestination();
newNetworkPath = destination.getFile(
originalNetworkFile.getName()
).getFullPath();
return true;
}
return false;
}
@Override
public String getName() {
return "The move participant";
}
@Override
public RefactoringStatus checkConditions(IProgressMonitor pm,
CheckConditionsContext context) throws OperationCanceledException {
return new RefactoringStatus();
}
@Override
public Change createChange(IProgressMonitor pm) throws CoreException,
OperationCanceledException {
return getOtherNetworksContentChanges();
}
private Change getOtherNetworksContentChanges() {
final CompositeChange changes = new CompositeChange();
for(IFile file : getAffectedFiles()) {
final TextFileChange textFileChange =
new TextFileChange(file.getName(), file);
textFileChange.setEdit(new ReplaceEdit(0,
content.length(), getNewFileContent(file)));
changes.add(textFileChange);
}
return changes;
}
private Iterable<IFile> getAffectedFiles() {
// Returns the list of projects' IFile which reference the moved file
}
private String getNewFileContent(IFile file) {
// Perform the replacement in the content of the project's file
}
}
当我移动1个文件时,这非常有效:所有引用此文件的网络都按预期更新。该窗口显示应用替换前的更改预览。
但是如果我尝试移动2个或更多文件并且网络引用它们,即使显示的预览正常,也不会正确应用替换。在某些情况下,有一个例外(因为文件大小小于第二个ReplaceEdit实例中指定的),在其他情况下,执行第二次替换,但文件的第一个版本的最后一个字符仍然在结尾,并且第一次更换不可见。
这是由于
new ReplaceEdit(0, content.length(), "the new file content")
当我初始化替换编辑实例时,我还尝试了更好(和真实)的索引,但没有更多运气。这里的问题是Eclipse,当它在多个文件上使用MoveParticipant类时,不会处理每个替换的结果以适应其他(更新索引等)。
Eclipse API中是否有某些内容可以确保在同一文件上有很多替换当移动2个或更多文件时会正确执行?
答案 0 :(得分:2)
我终于找到了解决问题的方法。我的移动参与者应该实现ISharableParticipant接口。通过这个技巧,RefactoringProcess自动重用参与者实例,并使用addElement()
方法注册所有文件(第一个对象仍然传递initialize()
。然后具体参与者必须照顾整个正确创建更改实例的文件列表。