Eclipse中实现Copy Participant:同目录复制无法获取新文件名的问题
我之前折腾Eclipse CopyParticipant的时候也碰到过一模一样的问题,给你分享下我当时的解决思路和具体步骤:
一、为什么拿不到同目录复制的新文件名?
你提到的org.eclipse.jdt.internal.corext.refactoring.changes.CopyResourceChange.getNewResourceName()确实是在CopyParticipant执行完成后才会被调用,时机完全不对。正确的做法是从CopyParticipant的参数上下文里直接获取新文件名,而不是等后续的Change生成。
具体来说,在你的CopyParticipant实现中,可以通过getArguments()方法拿到CopyArguments对象,里面已经包含了用户输入的新文件完整路径:
@Override public void initialize(RefactoringArguments arguments) { super.initialize(arguments); if (arguments instanceof CopyArguments) { CopyArguments copyArgs = (CopyArguments) arguments; IPath destPath = copyArgs.getDestination(); // 同目录复制时,destPath是新文件的完整路径,直接取最后一段就是新文件名 String newFileName = destPath.lastSegment(); // 这里可以把newFileName存为成员变量,后续createChange时用 } }
需要注意区分两种复制场景:
- 跨目录复制:destPath是目标目录的路径,新文件名和原文件名一致
- 同目录复制:destPath是新文件的完整路径,此时
destPath.lastSegment()就是用户输入的新名称
二、实现同目录复制时生成关联文件
要复制同名关联文件(比如原文件X.java对应X.xml,复制后要生成Y.java和Y.xml),可以在createChange方法中添加自定义的复制逻辑,步骤如下:
获取原资源与新文件名
先从之前保存的成员变量或重新从CopyArguments中拿到新文件名,同时定位原资源的关联文件。创建关联文件的复制Change
针对每个关联文件,生成对应的目标路径,然后创建CopyFileChange并添加到CompositeChange中。
示例代码如下:
@Override public Change createChange(IProgressMonitor monitor) throws CoreException, OperationCanceledException { CompositeChange compositeChange = new CompositeChange("Copy Associated Files"); IResource originalResource = getResource(); CopyArguments copyArgs = (CopyArguments) getArguments(); IPath destPath = copyArgs.getDestination(); String newFileName = destPath.lastSegment(); String originalName = originalResource.getName(); // 示例:复制对应的XML关联文件 String originalAssociatedSuffix = ".xml"; String originalAssociatedName = originalName.substring(0, originalName.lastIndexOf(".")) + originalAssociatedSuffix; IPath originalAssociatedPath = originalResource.getParent().getFullPath().append(originalAssociatedName); IResource originalAssociated = ResourcesPlugin.getWorkspace().getRoot().findMember(originalAssociatedPath); if (originalAssociated != null && originalAssociated.exists()) { String newAssociatedName = newFileName.substring(0, newFileName.lastIndexOf(".")) + originalAssociatedSuffix; IPath destAssociatedPath = destPath.removeLastSegments(1).append(newAssociatedName); // 创建复制关联文件的Change CopyFileChange copyChange = new CopyFileChange(originalAssociated.getFullPath(), destAssociatedPath); compositeChange.add(copyChange); } // 可添加其他关联文件的处理逻辑(比如.properties、.vm等) return compositeChange; }
- 确保CopyParticipant正确注册
别忘了在plugin.xml中注册你的CopyParticipant,指定对应的资源类型(比如针对Java文件,设置objectClass="org.eclipse.jdt.core.ICompilationUnit"),示例扩展点配置:
<extension point="org.eclipse.ltk.core.refactoring.copyParticipants"> <copyParticipant class="com.yourpackage.YourCopyParticipant" id="com.yourpackage.yourCopyParticipant" name="Your Copy Participant"> <enablement> <objectClass name="org.eclipse.jdt.core.ICompilationUnit"/> </enablement> </copyParticipant> </extension>
三、额外调试技巧
如果不确定参数内容,可以在initialize或createChange方法中加断点,查看CopyArguments里的destination、getNewName()(有些版本的CopyArguments可能直接提供getNewName()方法)等字段,确认新文件名的来源。
内容的提问来源于stack exchange,提问作者SSK

