运行模型到模型变换将生成一个 in-memory 模型。缺省情况下,作为变换后处理的一部分,变换框架会将已生成的 in-memory 模型的内容写入工作空间中的一个文件。当用户为模型到模型变换创建变换配置时,可以将此文件指定为变换的目标容器,也可以创建新的目标容器。在变换配置中,名为“目标容器”的配置属性包含目标模型的文件名。工作空间中必须存在此文件才能运行变换。
此样本变换项目说明了如何提供另一种方法,以使用户可以通过定制已生成的变换源代码来配置目标容器。您作为变换的编写者,在生成模型到模型变换的源代码之后,可以定制代码,以使变换用户可以将 URI 而不是模型文件指定为变换目标容器。在运行变换之前,不需要 URI 所标识的文件;如果此文件不存在,变换时会创建它。
生成变换源代码之后,在 plugin.xml 文件包含的变换扩展点中,名为 targetModelType 的属性将列示变换用户可以指定为目标容器的模型的类型。缺省情况下,此属性设置为 resource,这意味着在变换配置中,用户必须指定工作空间中已存在的文件。在定制的 plugin.xml 文件中,targetModelType 属性被设置为 none。
在 plugin.xml 文件中,已生成的变换扩展元素包含一个名为“目标模型 URI”的新变换属性。在此样本中,在“变换配置”向导和编辑器的属性选项卡上的目标模型 URI 字段中,用户将为此属性指定字符串值。
变换配置向导和编辑器使用已生成的名为 Uri4targetTransformationValidator 的定制变换验证器类来验证变换配置中的设置。缺省情况下,仅当已配置的目标容器是一个文件时,isTargetElementValid 方法的实现才将返回 true。在此样本中,缺省实现已被覆盖,并且无论是否将一个值指定为目标容器,它都将返回 true。更强大的实现可能会对用户指定的 URI 执行特定于变换或特定于项目的验证。
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see com.ibm.xtools.transform.authoring.TransformationValidator#isTargetElementValid(java.lang.Object)
* @generated
*/
protected boolean isTargetElementValid(Object target) {
//Remove @generated tag to add more target validation checks
return super.isTargetElementValid(target);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @see com.ibm.xtools.transform.authoring.TransformationValidator#isTargetElementValid(java.lang.Object)
* @generated NOT
*/
protected boolean isTargetElementValid(Object target) {
return true;
}
在已生成的名为 Uri4targetTransformationProvider 的定制类中,createRootTransformation 方法的缺省实现将实例化 RootTransformation 类,而此类会依次实例化 ResourceTransform 类。ResourceTransform 类的缺省实现使用名为 ResourceTargetRule 的实现,此实现将打开用于表示已配置的目标容器的文件。在此样本中,以配置的目标容器是一个 URI 而不是一个文件;因此,已将一个名为 ResourceFromUriTransform 的定制 ResourceTransform 实现和一项名为 ResourceFromUriTargetRule 的定制 ResourceTargetRule 规则添加至 Uri4targetTransformationProvider 类。
/**
* Creates a root transformation. You may add more rules to the transformation here
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @param transform The root transformation
* @generated
*/
protected RootTransformation createRootTransformation(ITransformationDescriptor descriptor) {
return new RootTransformation(descriptor, new MainTransform());
}
/**
* Creates a root transformation. You may add more rules to the transformation here
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @param transform The root transformation
* @generated NOT
*/
protected RootTransformation createRootTransformation(ITransformationDescriptor descriptor) {
return new RootTransformation(descriptor, new MainTransform()) {
@Override
protected void addInitialExtractor(Transform mainTransform) {
add(new ResourceListExtractor(new ResourceFromUriTransform(mainTransform)));
}};
}
protected class ResourceFromUriTransform extends ResourceTransform {
public ResourceFromUriTransform(Transform mainTransform) {
super(Uri4targetMessages.ResourceFromUriTransform_id);
setName(Uri4targetMessages.ResourceFromUriTransform_name);
add(new ResourceFromUriTargetRule());
add(new ResourceContentsExtractor(mainTransform));
}
}
protected class ResourceFromUriTargetRule extends ResourceTargetRule {
@Override
protected Object createTarget(ITransformContext context) {
ResourceSet resourceSet = ((EditingDomain) context
.getPropertyValue(TransformAuthoringConstants.TARGET_EDITING_DOMAIN))
.getResourceSet();
Resource resource = null;
Object targetModelURIString = context.getPropertyValue("TargetModelURI"); //$NON-NLS-1$
if (targetModelURIString instanceof String) {
URI targetModelURI = URI.createURI((String)targetModelURIString);
IPath targetModelPath = new Path(targetModelURI.path());
IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
IFile targetModelFile = wsRoot.getFile(targetModelPath);
ValidateEditRule.addAffectedFile(context, targetModelFile);
resource = resourceSet.createResource(getPlatformURI(targetModelFile));
ITransformContext rootContext = context;
while (rootContext.getParentContext() != null)
rootContext = rootContext.getParentContext();
rootContext.setPropertyValue(ITransformContext.TARGET_CONTAINER, targetModelFile);
}
return resource;
}
}