5

我正在尝试在 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

4

1 回答 1

5

感叹该文件已经过时了。您应该使用 org.eclipse.wst.validation.validatorV2 扩展点,扩展较新的 org.eclipse.wst.validation.AbstractValidator 类。

于 2013-09-24T20:31:13.803 回答