自:

  http://blog.csdn.net/javaman_chen/article/details/6057033

  http://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-emfvldt/

  http://blog.csdn.net/james999/article/details/1624747

EMF Validation Framework 提供了对 EMF eObjects 的校验框架,和 EMF EValidator API 相比它能提供更复杂全面的验证并且易用易扩展。EMF Validation Framework 提供了灵活的验证定义方式,支持两种验证触发机制:Batch 和 Live。它支持用 JAVA 和 OCL 语言来实现约束,此外它还支持自定义验证时的模型扫描算法,并提供了一个 Validation Client Context 来规避不必要的验证。

EMF模型的验证主要通过ModeValidationService类的调用来完成,该类还声明了一个工厂方法newValidator()用于获取IValidator的实现类。IValidator执行器会从Validation Service模块中获取所匹配的Constraint进行验证。IValidator的子接口有两个,分别是ILiveValidator和IBatchValidator,对应模型的验证方式是Live模式还是Batch模式;而模式的区分通过EvaluationMode来指定。

验证整体需要以下几步:

1.构建约束。

2.注入验证环境

3.将约束与Application进行绑定

4.书写验证主体

1.  构建约束

目前支持三种方式:Java Code,EMF Model,以及OCL。所有的约束必须实现 IModelConstraint 接口,定义了验证执行的逻辑(validate()),并拥有一个约束描述符(一个实现 IConstraintDescriptor 接口的类),该描述符包含了这个约束的源信息,例如,验证模式是 live 还是 batch,验证的目标对象等。不同的Constraint Model类型下会有不同的实现。因为Validation Framework这套构架依赖于在plugin.xml中描述和申明来注册相应的constrain实现,所以需要不同的Parser负责解析和管理。

1.1 java方式。约束的构建主要通过继承AbstractModelConstraint抽象类来完成。AbstractModelConstraint使用了IValidationContext接口作为validate()的方法参数,并且返回Istatus对象用来封装验证结果。//validate(IValidationContext ctx)

IValidationContext对象

(1)提供了当前验证环境的相关信息,包括:
  target:所验证的目标对象;
  eventType:表示Live模式下触发验证操作的事件;
  currentConstraintId:当前所执行的约束Id,等等...

(2) 提供了一些提高验证效率的方法,例如可以用来指定一些的目标对象是“合格的”可以不执行某些验证方法,缓存验证对象。

在validate方法中,如果约束得评估没有通过,可调用IValidationContext接口定义的createFailureStatus(Object... args)方法返回错误状态类型相反,如果评估成功,可调用createSuccessStatus()方法返回成功状态类型。

1.2 OCL

使用EMF OCL非常简单,使用QueryFactory构造一个Query对象,设置表达式(Express),以及表达式所依赖的Context(在EMF OCL中,一般是Classifier)。然后对给定eObject对象进行检查和计算。——就这么简单。
 
Query query = QueryFactory.eINSTANCE.createQuery(
    "Book.allInstances()->select(b : Book | b <> self and b.title = self.title)",
    LibraryPackage.eINSTANCE.getBook());
query.setExtentMap(extents);
Collection result = query.evaluate(myBook);

2. 注入验证环境

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

3.与Application进行绑定

通过org.eclipse.emf.validation.constraintBindings扩展点来实现该功能。

只能在EclipseRCP环境下运行,而且编写扩展点的实现也非常的繁琐。

4.书写验证主题,参照验证逻辑变下

Batch的验证逻辑为:

  1. 指定验证对象,可以使一个EObject或其集合  List objects = myResource.getContents();
  2. 通过验证服务ModelValidationService构建IBatchValidator
  3. 通过EvaluationMode.BATCH指明为Batch模式                                                                                                                                                        IValidator validator = ModelValidationService.getInstance().newValidator(EvaluationMode.BATCH);
  4. validator.setIncludeLiveConstraints(true);//包含Live模式的约束  验证约束这里不需要指定,因为后面的验证是需要注册如application的,而不是添加,而约束可以通过过滤器设置,这里使得验证很难灵活的在使用中添加新的约束。
  5. //可以添加约束的过滤设置   validate.addConstraintFilter(new IConstraintFilter() {...
  6. 模型的验证返回IStatus对象 IStatus results = validator.validate(objects);
  7. 判断验证状态  if (!results.isOK()) {ErrorDialog.openError(null, "Validation", "Validation Failed", results); }

另一种方式//只是替换现成的Validator的实现

用户还可自己编写EValidator的实现,然后将该实现类注入到EValidator注册表中去,一样可完成模型验证操作,
且这种方式无需编写扩展点的实现,因此只需要OSGI环境就可以了。

1. 编写EValidator的实现

(1)若直接在模型中指明了约束,可以通过*.genmodel文件,是可以直接生成对应的EValidator实现类的。

2. 添加到EValdator注册表中

对应代码

3. 编写模型的验证代码

  1. 设置验证目标对象 Object target=getTartget();
  2. Diagnostician diagnostician=new Diagnostician();
  3. BasicDiagnostic diagnostic=diagnostician.createDefaultDiagnostic(target);
  4. Map<Object, Object> context = diagnostician.createDefaultContext();
  5. 执行验证操作 diagnostician.validate(library, diagnostic, context);

评估:

有两点可能阻碍实现可扩展、可自定义的验证:

1. 不仅仅需要验证逻辑的实现,而且需要注册,设置扩展点能操作来具体的配置约束,可不能随意添加自定义的约束

2. 每条约束对应一段代码,如何添加自定义的验证需要思考,这里可以参考OCL验证引擎的实现,北大硕士论文

EMF学习,为了实现可扩展可自定义的模型验证 - 各种实现方法学习的更多相关文章

  1. EMF学习,为了实现可扩展可自定义的模型验证 - emf quary 与 OCL

    http://blog.csdn.net/javaman_chen/article/details/6020050 //这里的验证强调的是condition的构造,基于查找来判断验证结果.支持OCL也 ...

  2. ASP.NET Core - 实现自定义WebApi模型验证

    Framework时代 在Framework时代,我们一般进行参数验证的时候,以下代码是非常常见的 [HttpPost] public async Task<JsonResult> Sav ...

  3. [ExtJS5学习笔记]第七节 Extjs5的组件components及其模板事件方法学习

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/38487519 本文作者:sushengmiyan ------------------ ...

  4. ExtJS学习--------Ext.Element中的经常使用事件和其它重要的方法学习(实例)

    经常使用事件: 其它重要方法: 详细实例:(实例结果能够将相应的代码取消凝视进行測试) Ext.onReady(function(){ Ext.create('Ext.panel.Panel',{ t ...

  5. VSTO 学习笔记(十二)自定义公式与Ribbon

    原文:VSTO 学习笔记(十二)自定义公式与Ribbon 这几天工作中在开发一个Excel插件,包含自定义公式,根据条件从数据库中查询结果.这次我们来做一个简单的测试,达到类似的目的. 即在Excel ...

  6. Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析

    这是关于RecyclerView的第二篇,说的是如何自定义Item动画,但是请注意,本文不包含动画的具体实现方法,只是告诉大家如何去自定义动画,如何去参考源代码. 我们知道,RecyclerView默 ...

  7. 【转发】NPAPI学习(Firefox和Chrome扩展开发 )

    NPAPI学习(Firefox和Chrome扩展开发 ) 2011-11-08 14:41:02 by [6yang], 1172 visits, 收藏 | 返回 Firefox和Chrome扩展开发 ...

  8. Dynamic CRM 2013学习笔记(二十一)自定义审批流2 - 配置按钮

    上次介绍了 Dynamic CRM 2013学习笔记(十九)自定义审批流1 - 效果演示 现在开始介绍如何配置审批流,首先在form上添加三个按钮,Submit, Agree, Reject: 1. ...

  9. Dynamic CRM 2013学习笔记(三十七)自定义审批流7 - 初始化(整套审批流下载、安装)

    前面介绍了自定义审批流的配置.使用,这篇介绍下如何进行初始化. 一. 下载 从下面的地址下载整个审批流: http://yunpan.cn/cZ5Rdx5HCt3VF 下载完后,一共有三块内容: 二. ...

随机推荐

  1. 第3月第9天 循环引用 block

    一.一个对象没有被引用,那么在函数块完成时就会被dealloc,这种情况因为对象销毁了,block块也永远不会执行. MyNetworkOperation *op = [[MyNetworkOpera ...

  2. 如何有效地描述软件缺陷(Defect)?

    最近一个月偷懒了,刚看到一篇博文很不错.最近也是碰到一样的问题,由于我记录bug的描述不够清晰.导致开发看不懂我描述的bug,还有一些配置信息没记录好.出现一问三不知的情况,还被领导训.下面的博文是来 ...

  3. .NET 程序集与命名空间

    程序集 程序集(assembly)是一个或多个托管模块,以及一些资源文件的逻辑组合. 组成部分 Windows文件首部 CLR文件首部 程序集清单 类型元数据 MSIL(CIL)代码 嵌入资源集 作用 ...

  4. 数据库DBA(3年以内需求)

    1.DBA工作:日常维护,备份及恢复,系统安装,补丁应用,健康检查及优化,故障处理; 2.精通sql语句.视图存储过程.函数的编写.触发器; 3.精通data guard/RAC,能顺利配置和管理da ...

  5. python之OS模块详解

    python之OS模块详解 ^_^,步入第二个模块世界----->OS 常见函数列表 os.sep:取代操作系统特定的路径分隔符 os.name:指示你正在使用的工作平台.比如对于Windows ...

  6. 大公司的PHP面试题

    1. 禁用COOKIE 后 SEESION 还能用吗? 2. 抓取远程图片到本地,你会用什么函数? 4. 你觉得在pV10W的时候, 同等配置下,LUNIX 比WIN快多少? 5. 简述pOST 和G ...

  7. unity3d编辑器——检视面板部分(一)

    最近在学习unity编辑器,so,记录总结一下. 以下介绍了一些简单的unity3d检视面板部分的使用技巧. using UnityEngine; using System.Collections; ...

  8. Yii2 用户登录

    在Yii2的basic版本中默认是从一个数组验证用户名和密码,如何改为从数据表中查询验证呢?且数据库的密码要为哈希加密密码验证? 下面我们就一步一步解析Yii2的登录过程. 一. 创建user表模型 ...

  9. 使用FTP FtpWebRequest UsePassive 属性实现主动上传

    类型:System::Boolean如果客户端应用程序的数据传输过程侦听数据端口上的连接,则为 false:如果客户端应在数据端口上启动连接,则为 true. 默认值为 true. UsePassiv ...

  10. Java集合---Array类源码解析

    Java集合---Array类源码解析              ---转自:牛奶.不加糖 一.Arrays.sort()数组排序 Java Arrays中提供了对所有类型的排序.其中主要分为Prim ...