您的位置:首页 > 其它

EMF学习笔记6——模型验证

2010-12-05 22:47 393 查看
EMF模型的验证主要通过ModeValidationService类的调用来完成



由类图可以看到,ModelValidationService其实是一个单例模式,声明了getInstance()方法用于获取类的实例;

同时,该类还声明了一个工厂方法newValidator()用于获取IValidator的实现类。

IValidator的子接口有两个,分别是ILiveValidator和IBatchValidator,对应模型的验证方式是Live模式还是Batch模式;而模式的区分通过EvaluationMode来指定。

注:EMF Validation Framework提供了两种模型验证方式,Batch和Live

Batch模式:静态的模型验证方式,触发方式通常通过点击某个按钮,或在固定的业务逻辑处编写验证代码;

Live模式:验证的触发通过Notification,即模型改变通知。

Batch模式的验证逻辑如下:

List notifications = transaction.getChanges(); //input值是Notification的集合
//构建ILiveValidator,通过EvaluationMode.LIVE指明为Live模式
ILiveValidator validator = (ILiveValidator) ModelValidationService.getInstance().newValidator(EvaluationMode.LIVE);
IStatus results = validator.validate(notifications);//对通知进行验证
if (!results.isOK()) {//判断验证结果
    ErrorDialog.openError(null, "Validation", "Validation Failed", results);
}


除此之外,无论是Batch模式还是Live模式,可以为模型的验证指定过滤器来过滤掉不需要的约束和目标对象。

public class LibraryNameIsUnique extends AbstractModelConstraint {//首先继承AbstractModelConstraint超类
    public IStatus validate(IValidationContext ctx) {
        Library target = (Library) ctx.getTarget(); //通过IValidationContext获取所验证的目标对象

        //判断library的名称是否唯一
        Set<Library> libs = findLibrariesWithName(target.getName());
        if (libs.size() > 1) {//如果不唯一
            ctx.addResults(libs);
            libs.remove(target);
            ctx.skipCurrentConstraintFor(libs);//省略其他实体类的验证
     //返回错误状态类型
            return ctx.createFailureStatus(new Object[] {target, libs});
        }
    }
    //返回成功状态类型
    return ctx.createSuccessStatus();
  }    
}


有了约束对象以后,还需要将此约束对象注入到验证环境中去,这样在执行验证操作时,Eclipse才会找到该约束进行评估。

可通过实现org.eclipse.emf.validation.constraintProviders扩展点完成约束的注入。

<extension
 point="org.eclipse.emf.validation.constraintBindings"> 
 <clientContext
  default="false"
  id="org.emf.demo.validate.libraryContext">
  <!--selector所声明的class实现了IClientSelector接口,其selects(Object object)方法相当于一个门闩,
   来控制是否对约束进行评估-->
  <selector class="org.emf.demo.validate.ValidationDelegateClientSelector"/>
 </clientContext>
 <binding
  context="org.emf.demo.validate.libraryContext"
  category="org.emf.demo.validate.library"/>  //将此类型的约束绑定到所声明的clientContext中
</extension>


EMF的这种验证方式,由于使用了扩展点技术,所以只能在EclipseRCP环境下运行,而且编写扩展点的实现也非常的繁琐。

除了这种方式外,用户还可自己编写EValidator的实现,然后将该实现类注入到EValidator注册表中去,一样可完成模型验证操作,

且这种方式无需编写扩展点的实现,因此只需要OSGI环境就可以了。

首先编写EValidator的实现:

如果在*.ecore模型文件中,为模型实体指明了相关的约束,那么通过*.genmodel文件,是可以直接生成对应的EValidator实现类的。

该类会放在模型实体bundle中的util包下面,主要继承了EObjectValidator超类,且类中定义了相关的验证方法来对应模型描述文件中声明的约束。



有了该Evalidator的实现类以后,需要将其添加到EValdator注册表中去,可通过如下代码完成操作:

Object target=getTartget();//target为需要验证的目标对象。
Diagnostician diagnostician=new Diagnostician();
BasicDiagnostic diagnostic=diagnostician.createDefaultDiagnostic(target);
Map<Object, Object> context = diagnostician.createDefaultContext();
diagnostician.validate(library, diagnostic, context);//执行验证操作
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: