博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
EMF介绍系列(八、模型的验证)
阅读量:7189 次
发布时间:2019-06-29

本文共 2772 字,大约阅读时间需要 9 分钟。

在ecore模型里可以详细的定义各种类型、属性和方法,但对于像“每个类别里至少有两种产品”这样的限制就无能为力了。为此,EMF提供了一套验证框架(Validator Framework)用于解决这个问题,在ecore文件里特定的方法可以被识别为验证方法并生成用于验证的代码。

还是以shop模型为例,假设要求“每个类别里至少有两种产品”,我们需要在shop.ecore里添加一个名为“validateProductsCount”的验证方法,如图1所示。验证方法的返回类型是要具有两个参数:第一个是EDiagnosticChain类型,第二个是EMap类型,参数的名称没有特别要求,但这两个参数的顺序不能交换。

图1 新增的验证方法

接下来,通过shop.genmodel重新生成一遍代码(如果还没有shop.genmodel文件,通过“New -> EMF Model”创建一个),注意没有必要reload这个genmodel文件。通过比较添加验证方法前后的代码,可以发现EMF在util包里多生成了一个名为ShopValidator.java的文件;同时,在CategoryImpl的validateProductsCount()方法里的代码如下所示:

/**
 * <!-- begin-user-doc -->
 * <!-- end-user-doc -->
 * @generated
 
*/
public
 
boolean
 validateProductsCount(DiagnosticChain diagnostics, Map contex) {
    
//
 TODO: implement this method
    
//
 -> specify the condition that violates the invariant
    
//
 -> verify the details of the diagnostic, including severity and message
    
//
 Ensure that you remove @generated or mark it @generated NOT
    
if
 (
false
) {
        
if
 (diagnostics 
!=
 
null
) {
            diagnostics.add
                (
new
 BasicDiagnostic
                    (Diagnostic.ERROR,
                     ShopValidator.DIAGNOSTIC_SOURCE,
                     ShopValidator.CATEGORY__VALIDATE_PRODUCTS_COUNT,
                     EcorePlugin.INSTANCE.getString(
"
_UI_GenericInvariant_diagnostic
"
new
 Object[] { 
"
validateProductsCount
"
, EObjectValidator.getObjectLabel(
this
, contex) }),
                     
new
 Object [] { 
this
 }));
        }
        
return
 
false
;
    }
    
return
 
true
;
}

有别于普通方法的实现(简单的抛出一个UnsupportedOperationException异常)。由于这段代码是被“if(false){...}”包围的,所以如果不进行定制,则里面的内容永远不会被执行,被包围代码的功能是将验证错误记录下来以便统一报告。现在,我们要做的就是修改这个条件,来告诉EMF什么时候运行里面的代码,如下所示:

/**
 * <!-- begin-user-doc -->
 * <!-- end-user-doc -->
 * @generated NOT
 
*/
public
 
boolean
 validateProductsCount(DiagnosticChain diagnostics, Map contex) {
    
//
 我们修改了验证条件
    
if
 (getProducts().size() 
<
 
2
) {
        
if
 (diagnostics 
!=
 
null
) {
            diagnostics.add
                (
new
 BasicDiagnostic
                    (Diagnostic.ERROR,
                     ShopValidator.DIAGNOSTIC_SOURCE,
                     ShopValidator.CATEGORY__VALIDATE_PRODUCTS_COUNT,
                     EcorePlugin.INSTANCE.getString(
"
_UI_GenericInvariant_diagnostic
"
new
 Object[] { 
"
validateProductsCount
"
, EObjectValidator.getObjectLabel(
this
, contex) }),
                     
new
 Object [] { 
this
 }));
        }
        
return
 
false
;
    }
    
return
 
true
;
}

因为我们要实现的验证条件很简单,所以代码的改动也很少,还是注意不要忘记修改注释中的@generated标记。现在可以运行我们的shop编辑器了,在一个只包含一种产品(Product)的类别(Category)上按右键,选择弹出菜单里的“Validate”命令,就会得到如图2所示的提示信息。

图2 模型未通过验证

通过修改代码的方式表达模型的限制条件是很直观,不过当条件又多又不确定的时候,直接在ecore文件里集中的表达这些条件也许更方便管理,而且Java代码甚至不需要重新生成和编译。Eclipse网站上的这篇文章“”通过自定义JET模板实现了这个功能,有兴趣的朋友不妨试试。

补充另一种让EMF生成Validate代码的方法:在ecore模型里需要验证的EClass下建立一个EAnnotation,其source属性为“http://www.eclipse.org/emf/2002/Ecore”;然后在这个EAnnotation下建立key为“constraints”的Details Entry,value属性指定为想要的constraint名字,如果要定义多个constraint,则每个名字之间用空格分隔(格式见EcoreUtil#setConstraints()),如图3所示。这样,EMF就会在util包里生成XXXValidator.java文件,以及相应的验证方法,这些方法的代码和上面第一段嗲吗是类似的,同样需要自己修改if语句里的条件。

图3 在ecore模型里添加EAnnotation以生成验证代码

本文转自博客园八进制的博客,原文链接:,如需转载请自行联系原博主。

你可能感兴趣的文章
Roundabout不规则列表效果展示,类似旋转木马效果
查看>>
天龙八部服务器端---共享内存的设计
查看>>
透明的ico
查看>>
XSS攻击简单了解
查看>>
高性能的I/O设计中 著名的模式Reactor和Proactor模式
查看>>
XDOC合同填报解决方案
查看>>
git迁移
查看>>
Ubuntu 安装JDK6
查看>>
C++前置声明
查看>>
dbcp基本配置和重连配置
查看>>
用fgetc()函数读取磁盘文件并打印到屏幕
查看>>
Golang、python中统计字母,数字、汉字其他的个数。
查看>>
greenRobot的EventBus
查看>>
select2的基本应用
查看>>
PHP面试时经常出现的小算法题
查看>>
使用strace+pstack利器分析程序性能
查看>>
关于Cadence中电源及地的处理
查看>>
cordova 环境搭建
查看>>
json所需包
查看>>
Android中ContentProvider和Uri用法
查看>>