在Eclipse中实现验证器

5 eclipse validation eclipse-plugin

我正在尝试在Eclipse中实现验证.我的工作有很多小项目,可以为各种客户定制我们的产品.由于有大量的开发人员,我们正在努力寻找一种方法来执行各种标准和最佳实践.

例如,我们有许多我们想要验证的XML配置.内置验证器可确保文件格式正确并遵循模式,但我们希望添加验证,例如检查XML中引用的Java类实际存在于类路径中.另一个例子是验证实现某个接口的Java类没有任何对象变量(即代码只需要对参数进行操作而不是维护状态).

似乎有两种方法可以添加验证.第一种是通过添加标记的构建器.第二种是通过独立验证.但是,我们实际上并没有构建任何东西,并且我没有找到任何有用的教程或验证示例(没有帮助帮助..eclipse.org目前正被移动并且不可用).

当我右键单击一个测试项目并选择"验证"时,我收到一条消息,说明验证期间出现错误,并且我的测试消息未显示在问题视图中.但是,Eclipse日志中没有错误.主机Eclipse在控制台中没有显示任何内容.没有异常记录在任何地方,也没有消息.该项目确实具有所需的自定义性质.

我遵循了这些说明,但没有代码或功能齐全的示例,Google也不足以填补空白.结合Eclipse帮助网站现在,我不知道如何继续.

plugin.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>
Run Code Online (Sandbox Code Playgroud)

验证码:

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);
  }

}
Run Code Online (Sandbox Code Playgroud)

我还发现添加验证需要使用受限制的包和接口,这很奇怪.它似乎很奇怪,它想要一个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;
  }
Run Code Online (Sandbox Code Playgroud)

我承认这是在黑暗中刺伤:文档不是很具描述性,我没有在这个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;
  }
Run Code Online (Sandbox Code Playgroud)

plugin.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>
Run Code Online (Sandbox Code Playgroud)

我实际上在这些方面找到了另一个SO问题,证实了我发现的内容:为IMarkers注释设置IMarker.CHAR_START和IMarker.CHAR_END属性

nit*_*ind 5

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