我正在尝试在 Eclipse 中实现验证。我的工作有许多小项目,用于为各种客户定制我们的产品。由于有大量的开发人员,我们正试图找到一种方法来执行各种标准和最佳实践。
例如,我们有许多要验证的 XML 配置。内置验证器确保文件格式正确并遵循模式,但我们希望添加验证,例如检查 XML 中引用的 Java 类是否确实存在于类路径中。另一个例子是验证实现某个接口的Java 类没有任何对象变量(即代码只需要对参数进行操作而不需要维护状态)。
似乎有两种方法可以添加验证。第一种是通过添加标记的构建器。第二种是通过独立验证。但是,我们实际上并没有构建任何东西,而且我还没有找到任何有用的教程或验证示例(无助于 help.eclipse.org 当前正在移动并且不可用)。
当我右键单击一个测试项目并选择“验证”时,我收到一条消息,指出验证期间出现错误,并且我的测试消息未显示在问题视图中。但是,Eclipse 日志中没有错误。主机 Eclipse 在控制台中不显示任何内容。任何地方都没有记录异常,也没有消息。该项目确实具有所需的自定义性质。
我按照这些说明进行操作,但没有代码或功能完整的示例,而且 Google 也没有善意地填补空白。再加上 Eclipse 帮助站点现在正在关闭,我不知道如何继续。
插件.xml:
<plugin>
<extension name="My Validator" point="org.eclipse.wst.validation.validator"
id="com.mycompany.pluginname.validator.MyValidator">
<validator>
<projectNature id="com.mycompany.pluginname.nature.MyNature"/>
<helper class="org.eclipse.wst.validation.internal.operations.WorkbenchContext"/>
<markerId markerIdValue="com.mycompany.pluginname.validator.DefaultMarker"/>
<run class="com.mycompany.pluginname.validation.validator.MyValidator"/>
<runStrategy project="true"/>
</validator>
</extension>
<extension point="org.eclipse.core.resources.markers" name="My Validator"
id="com.mycompany.pluginname.validator.DefaultMarker">
<super type="org.eclipse.core.resources.problemmarker"/>
<persistent value="true"/>
<attribute name="owner"/>
<attribute name="validationSeverity"/>
<attribute name="targetObject"/>
<attribute name="groupName"/>
<attribute name="messageId"/>
</extension>
</plugin>
验证码:
package com.mycompany.pluginname.validation.validator;
import org.eclipse.core.resources.IProject;
import org.eclipse.wst.validation.internal.core.Message;
import org.eclipse.wst.validation.internal.core.ValidationException;
import org.eclipse.wst.validation.internal.operations.IWorkbenchContext;
import org.eclipse.wst.validation.internal.provisional.core.*;
import com.mycompany.pluginname.validation.plugin.ValidationPlugin;
@SuppressWarnings("restriction")
public class MyValidator
implements IValidator {
@Override
public void cleanup(IReporter argReporter) {
argReporter.removeAllMessages(this);
}
@Override
public void validate(IValidationContext argContext, IReporter argReporter)
throws ValidationException {
String bundle = ValidationPlugin.getDefault().getTranslationsBundleName();
IProject prj = ((IWorkbenchContext) argContext).getProject();
String[] attributes =
new String[] {"owner", "validationSeverity", "targetObject", "groupName", "messageId"};
IMessage msg = new Message(bundle, IMessage.HIGH_SEVERITY, "test", attributes, prj);
argReporter.addMessage(this, msg);
}
}
我还觉得奇怪的是,添加验证需要使用受限的包和接口。它想要一个IMessage
而不是一个似乎也很奇怪IMarker
。
我确实查看了带有自定义验证的 Eclipse 插件,它似乎是围绕创建一个新的编辑器而设计的,无论使用什么编辑器,我都想验证文件(实际上我不想创建一个编辑器)。
编辑:我更新为使用 V2 框架,但问题视图中没有出现任何内容。我究竟做错了什么?是否有教程可以解释这是如何工作的?我能够弄清楚以下内容,但显然它是不正确的:
public ValidationResult validate(ValidationEvent argEvent, ValidationState argState,
IProgressMonitor argMonitor) {
final IResource resource = argEvent.getResource();
final ValidationResult result = new ValidationResult();
try {
List<String> contents = Resources.readFile((IFile) resource);
for (int i = 0; i < contents.size(); ++i) {
int offset = contents.get(i).indexOf("bad_string");
if (offset >= 0) {
result.add(ValidatorMessage.create("Found bad string", resource));
result.incrementError(1);
}
}
}
catch (Exception ex) {
result.add(ValidatorMessage.create(ex.getMessage(), resource));
}
return result;
}
我承认这是在黑暗中刺伤:文档描述性不是很好,我还没有找到关于这个 V2 验证器的任何教程。哦,我在这个验证器上有一个过滤器,所以它只接收特定的 XML 文件,这就是没有输入验证的原因。
另外,由于我自己是一个书呆子,我在那里使用旧式的 for 循环,因为我希望向用户显示带有错误的行号。但显然我还没有完全到那里。
另一个编辑:这是工作代码。唯一的问题是波浪线不在正确的行上,因为偏移量来自文件的开头,而不是行。但它确实有效:
public ValidationResult validate(ValidationEvent argEvent, ValidationState argState,
IProgressMonitor argMonitor) {
final IResource resource = argEvent.getResource();
final ValidationResult result = new ValidationResult();
try {
List<String> contents = Resources.readFile((IFile) resource);
int location = 0;
for (int i = 0; i < contents.size(); ++i) {
int offset = contents.get(i).indexOf(CONSTANT);
if (offset >= 0) {
ValidatorMessage vm = ValidatorMessage.create("Message", resource);
vm.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
vm.setAttribute(IMarker.SOURCE_ID, IMarker.PROBLEM);
vm.setAttribute(IMarker.LINE_NUMBER, i + 1);
vm.setAttribute(IMarker.CHAR_START, location + offset);
vm.setAttribute(IMarker.CHAR_END, location + offset + CONSTANT.length());
result.add(vm);
}
// TODO: account for different line endings.
location += (line.length() + 2);
}
}
catch (Exception ex) {
ValidationPlugin.getDefault().warn(ex);
result.add(ValidatorMessage.create(ex.toString(), resource));
}
return result;
}
插件.xml:
<extension name="My Validator" point="org.eclipse.wst.validation.validatorV2"
id="com.company.plugin.validation.validator.MyValidator">
<validator class="com.company.plugin.validation.validator.MyValidator">
<include>
<rules>
<file type="file" name="FileName.xml"/>
</rules>
</include>
</validator>
</extension>
我实际上发现了另一个 SO 问题,这些问题证实了我的发现:Setting IMarker.CHAR_START and IMarker.CHAR_END attributes for IMarkers Annotations