如何写入 IX 应用程序
导出将以导出应用程序开始。调用导出的应用程序代码的外观应如下所示:
ExportHandler appHandler = new ExportHandler ();
Exporter exporter = IxbHelper.newExporter(handle,
IxbHelper.STANDARD_DTD,
clientSettingsElement,
policyFile==null?(File)null:policyFile.getFile());
Iterator iter = objectSet.iterator();
while (iter.hasNext()) {
Persistable ob = (Persistable)iter.next();
exporter.doExport(ob);
}
exporter.finalizeExport();
appHandler.cleanUp ();
创建应用程序导出处理程序 (appHandler)。这是实现 ApplicationExportHandler 接口或扩展抽象类 ApplicationExportHandlerTemplate 的类的实例。在 StandardIXBService 中的导出应用程序中,appHandler 可扩展 ApplicationExportHandlerForJar,这是 ApplicationExportHandlerTemplate 的子类
appHandler 的作业是:
• 创建一个文件来存储导出的对象 (例如 JAR 文件)。
• 存储要发送回客户端的日志 (可选)。
• 清理临时文件并执行其他清理作业 (建议,但可选)。
要创建内容,必须在 appHandler 中实现以下方法:
• storeLogMessage(...) 方法用于将日志发送回客户端。由开发人员决定如何实现将日志发回的机制。如果您不想发送任何日志消息,请使您的导出处理程序扩展为 ApplicationExportHandlerTemplate。此类具有默认的 storeLogMessage() (空方法)。
• 可以选择在此执行清理和其他结束任务,并且必须在 exporter.finalizeExport() 之后显式调用这些作业。
如果应用程序需要修改导出的 XML,则应用程序导出处理程序可能还包含执行变换输出任务的方法。例如,PDXExportHandler 具有用于 XSL 变换为 PDX 格式的方法。这些方法必须在 exporter.finalizeExport() 之后显式调用。
应用程序导出处理程序的现有实现为:
• PDXExportHandler 可扩展 ApplicationExportHandlerTemplate。此类执行与导出为 PDX 格式相连接的特定任务。这包括创建其他 XML 属性/元素以及将 XSL 变换为 PDX 格式。
创建 Exporter 类的实例,并通过调用 exporter.doExport(obj) 使用该实例来导出对象,其中 obj 会运行收集到的所有要导出的 WT 对象。
完成此操作后,请调用 exporter.finalizeExport(),执行所有其他任务 (例如,变换为其他格式),在导出进程之后调用 appHandler 的方法进行清理,并将日志消息发送给客户端。
方法
doExport(…)、
doExportImpl(…) 和
StandardIXBService 中的内部类
ExportHandler 是一个导出应用程序的示例。请在
使用 ObjectSet 应用程序导航对象的结构中查看示例的详细信息。
先决条件
为了在客户特定的位置创建导出 jar,在调用 StandardIXBService 的 doExport api 之前,需要满足以下先决条件:
• 需要使用完整的客户端文件路径设置上下文键 ISBStreamer.CLIENT_SAVE_AS_FILE:
WTContext.getContext().put(IXBStreamer.CLIENT_SAVE_AS_FILE,CLIENT
JAR);
其中,CLIENT_JAR 是完整的客户端文件路径,例如 .c:\\mydocuments\\impex.jar。
Exporter 类
导出程序类的详细信息如下所示:
定义:
public class Exporter extends ExpImporter{…};
构造函数:
Exporter (ApplicationExportHandler _applicationExportHandler,
WTContainerRef _sourceContainer,
String targetDTD,
File localMappingRuleFile,
File policyRuleFile,
String actionName)
throws WTException {
super ("export", ( localMappingRuleFile==null?null:
localMappingRuleFile.getAbsolutePath() ));
//assign Container
sourceContainer = _sourceContainer;
// -- init expActionTuner --
applicationExportHandler = _applicationExportHandler;
dtd = targetDTD;
this.expImpContextData = new ExportContextData();
expActionTuner = new ExportActionTuner (policyRuleFile, actionName);
}
以下是对参数的说明:
• _applicationExportHandler - 实现接口 ApplicationExportHandler,扩展抽象类 ApplicationExportHandlerTemplate 或扩展抽象类 ApplicationExportHandlerForJar 的任何类的实例。
• 类 ApplicationExportHandlerForJar 可扩展类 ApplicationExportHandlerTemplate。类 ApplicationExportHandlerForJar 可提供用于在导出 jar 文件中存储 XML 和内容文件的方法。该类既处理 ApplicationData 内容,又处理本地文件系统中的内容。
• _applicationExportHandler 具有为生成的 XML 片段集合 (导出的对象) 创建 Jar 文件 (或其他存储方式) 的作业。该项必须实现两种方法:
storeContent (ApplicationData);
storeDocument (IxbElement );
sourceContainer: Reference of container.
• targetDTD:用于指定导出进程必须使用的 DTD 的字符串。IX 框架将基于此 DTD 字符串找到对象的适当处理程序和对象的文档类型定义。Windchill 版本 10.X 的 DTD 字符串为 standard20.dtd。
通常,目的是能够在任何 DTD 中导出对象。正如您将在下面看到的那样,使用 DTD 标识符解析类导出处理程序。string targetDTD 也会写入导出对象的 XML 文件,因此导入进程可以了解应使用何种 DTD 来导入对象。
• localMapppingRules:用于在执行导出进程时覆盖、更改或排除某些属性对象的 XML 文件或 XSL 文件。
以下 XML 规则文件会覆盖团队模板属性,并且无论对象在导出时属于哪个团队,其团队模板属性都将是 "/System" 域中的“更改团队”。
<?xml version="1.0" encoding="UTF-8"?>
<userSettings>
<mappingRules>
<COPY_AS>
<tag>teamIdentity</tag>
<value>*</value>
<newValue>Change Team (/System)</newValue>
</COPY_AS>
</mappingRules>
</userSettings>
XSL 规则文件测试导出对象的名称是否为 "part_c",如果是,其将覆盖团队模板属性和版本信息;并测试导出对象的名称是否为 "PART_B",如果是,其将覆盖团队模板属性。
如果您不想覆盖任何内容,只需为参数 localMapppingRules 传递 "null" 即可。
policyRuleFile:用于在执行导出进程时覆盖、更改或排除某些属性对象的 XSL 文件。
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@* | node()" priority="-9">
</xsl:template>
<xsl:template match="WTPart">
<xsl:choose>
<xsl:when test="name='part_c'">
<newInfo>
<teamIdentity>Default (/System)</teamIdentity>
<folderPath>/Design</folderPath>
<versionInfo>
<versionId>B</versionId>
<iterationId>2</iterationId>
<versionLevel>1</versionLevel>
</versionInfo>
</newInfo>
</xsl:when>
<xsl:when test="number='PART_B'">
<newInfo>
<teamIdentity>Default (/System)</teamIdentity>
<folderPath>/Design</folderPath>
</newInfo>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
例如,策略规则文件指定导出后在数据库中检出已导出的 WTPart 对象。如果导出的 WTDocument 对象的编号为 "TESTDOC-1",请在导出后将其检出。对于所有其他导出的 WTDocuments,请在导出后将其锁定在数据库中。
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl=http://www.w3.org/1999/XSL/Transform
version="2.0">
<xsl:output method="xml" indent="no" encoding="UTF-8"/>
<!--
The syntax of Export Policy is standard XSL syntax. The output of
XSLT using the XSL policy file
must only have at most one element of the form:
<actionInfo>
<action>...</action>
</actionInfo>
-->
The following is a sample of a well-formed xsl. In the cases, where
there are no specific actions to be performed, nothing needs to be
done, which is the default action that would transpire as shown in
the uncommented section below.
-->
<xsl:template match="@* | node()" priority="-9">
</xsl:template>
<xsl:template match="WTPart">
<actionInfo>
<action>Checkout</action>
</actionInfo>
</xsl:template>
<xsl:template match="WTDocument">
<actionInfo>
<xsl:choose>
<xsl:when test="number='TESTDOC-1">
<action>Checkout</action>
</xsl:when>
<xsl:otherwise>
<action>Lock</action>
</xsl:otherwise>
</xsl:choose>
</actionInfo>
</xsl:template>
-->
<!-- Do nothing by default -->
<xsl:template match="@* | node()" priority="-9">
</xsl:template>
</xsl:stylesheet>
如果您不想覆盖任何内容,只需为参数 policyRuleFile 传递 "null" 即可。
actionName : Action name
必须通过类 IxbHelper 的工厂方法 newExporter() 创建 Exporter 的实例。例如:
IxbHelper.newExporter (…..);
使用 Exporter 导出对象
在创建类 Exporter 的实例 (例如 exporter) 之后,可以使用该实例导出顶层对象。导出对象 'obj' 的调用为 exporter.doExport(obj);
实际上,这是在对类 Exporter 中的方法 doExport (Object obj, String targetDTD, String targetElem) 进行调用。
在此方法中,将创建对象 obj 的实际导出处理程序。
|
基于文件夹 <Windchill>\registry\ixb\handlers 中的 XML 文件创建可用导出处理程序的列表。如果在 Exporter 的构造函数中传递了错误的 DTD (系统中不可用的 DTD),则不会获得处理程序,因此无法导出对象。请参阅 如何编写 Exp/Imp 处理程序,以获取有关如何将导出处理程序的条目添加到 XML 文件的信息。
|
如果您有多个对象,则必须将这些对象传递给集合中的导出程序。
exporter.doExport(collection)
导出所有对象后,必须调用 exporter.finalizeExport();
您可以调用 appHandler 的清理方法 (如果有的话)。现在导出完成。
导入的工作原理
要从 jar 文件中的 XML 文件导入对象,导入应用程序必须执行以下操作:
1. 创建工具以读取导入的 jar 文件并提取 jar 文件中包含的 XML 文件列表。有关实现示例,请参阅类 IXBJarReader。
2. 准备将字符串 ruleFileName 传递到类 Importer 的实例中。根据导入应用程序的结构,字符串 ruleFileName 可以从 IxbStreamer 用户处获得 (分配值为空),或从其他位置获得。
3. 处理 policyFile (如果不为空) 以创建包含导入策略的 XSL StreamSource。
4. 创建应用程序导入处理程序 (appHandler)。这是实现接口 ApplicationImportHandler 或扩展抽象类 ApplicationImportHandlerTemplate 的任何类的实例。
5. 创建类 Importer (导入程序) 的实例。
6. 获取 jar 文件中的 XML 文件列表。
7. 从这些 XML 文件创建 IxbDocuments。
8. 对于每个 IxbDocument,请执行以下操作:
◦ 如果将操作名称传递给应用程序,并且 policyFile 为空,则将操作名称应用到 IxbDocument 中。如果 policyFile 不为空,则将 policyFile 中的操作名称和操作信息应用到 IxbDocument 中。
◦ 通过调用导入进程将这些内容逐一送入导入程序:
▪ importer.doImport(IxbDocument Doc);
▪ importer.finalizeImport();
9. 清理 (如果需要)。
10. 向客户端发送日志消息。
方法
doImport(...), doImportImpl(...) 和
StandardIXBService 中的内部类
ImportHandler 为某个导入应用程序的示例。有关详细信息,请参阅
使用 ObjectSet 应用程序导航对象的结构。
可通过操作名称和操作信息确定的十种不同方式中的任何一种来导入版本化对象,这些操作名称和操作信息会写入每个导入对象的 IxbDocument fileXML 中。写入导入应用程序的开发人员必须了解操作名称及其含义,才能正确对其进行应用,但是,对象处理人员不必担心 Actor 类。可在文件 <Windchill>\codebase\registry\ixb\handlers\actor.xml 中找到所有可用操作名称的列表。
以下三种关键方法中的所有操作彼此不同:previewObject、createObject 和 storeObject。在类 ClassExporterImporterTemplate 和 ExpImpForVersionedObject 中,基于传递到 IxbDocument fileXML 中的操作名称和操作信息,将创建适当的操作者,并将调用该操作者的方法以达到预览、创建和存储版本化对象的目的。
以下是按操作者名称列出的信息列表。
1. PickExistingObject:查找是否存在与数据库中的 XML 文件中的对象具有相同 ufid 或相同 (名称、编号、版本、小版本) 的对象。如果存在这样的对象,则框架将更新该对象。如果操作者认为该对象是更新的候选对象,则不执行任何操作。否则,在 XML 文件导入对象。
2. NewIteration:在 XML 文件中导入对象,以将其作为数据库中的下一个可用小版本。
◦ 例如:如果数据库中的 XML 文件中的对象没有版本/小版本,则导入的对象将获得在 XML 文件中指定的版本/小版本。如果数据库中对象的最新版本/小版本是 B.2,则导入的对象将是 B.3。
3. NewVersion:从 XML 文件导入对象,以将其作为数据库中的下一个可用版本。
◦ 例如:如果数据库中的 XML 文件中的对象没有版本/小版本,则导入的对象将获得在 XML 文件中指定的版本/小版本。如果数据库中对象的最新版本/小版本是 B.2,则导入的对象将是 C.1。
4. CheckOut:在 XML 文件中查找对象的任何版本/小版本 (检查数据库中是否存在主对象)。如果 XML 文件中没有该对象的版本,则抛出错误。否则,请在数据库中查找与 XML 文件中的对象具有相同版本 (小版本可以不同) 的对象的实例。如果存在这种对象,请在数据库中检出对象的最新小版本,并使用 XML 文件中的信息对其进行更新。我同意,否则会抛出错误。该项现已检入
5. ImportNonVersionedAttr:查找与 XML 文件中的对象具有相同 ufid 或相同 (名称、编号、版本、小版本) 的对象。如果存在这种对象,请使用 XML 文件中的信息对其进行更新。否则会抛出错误。
6. UpdateInPlace:查找与数据库中存在的 XML 文件中的对象具有相同 ufid 或相同 (名称、编号、版本、小版本) 的对象。如果存在这种对象,且该对象已检出,则使用 XML 文件中的信息对其进行更新。否则会抛出错误。
7. UnlockAndIterate:在数据库中查找与 XML 文件中的对象具有相同 ufid 或相同 (名称、编号、版本、小版本) 的对象。如果存在这种对象,且该对象已锁定,则解锁并升级其小版本,然后使用 XML 文件中的信息对其进行更新。否则会抛出错误。
8. CreateNewObject:使用导入策略文件中提供的新名称、新编号、新版本、新小版本创建全新对象。其他信息将从 XML 文件中提取。此功能不能单独使用。
|
如果没有用于指定新对象标识的策略文件,此选项将不起作用。
|
必须在 ImportPolicy 文件中提供的新信息的格式为:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<!--
The syntax of Import Policy is standard XSL syntax. The output of XSLT using
the XSL policy file must only have at most one element of the form:
<actionInfo>
<action>...</action>
</actionInfo>
以下是标准格式的 xsl 的示例。在没有要执行的特定操作的情况下,无需执行任何操作,该过程可以通过以下操作实现:
<xsl:template match="@* | node()" priority="-9">
</xsl:template>
-->
<xsl:template match="@* | node()" priority="-9">
</xsl:template>
<xsl:template match='WTPart'>
<actionInfo>
<action>PickExistingObject</action>
</actionInfo>
</xsl:template>
<xsl:template match='WTDocument'>
<actionInfo>
<action>PickExistingObject</action>
</actionInfo>
</xsl:template>
<xsl:template match='EPMDocument'>
<actionInfo>
<action>PickExistingObject</action>
</actionInfo>
</xsl:template>
</xsl:stylesheet>
|
• <actionInfo> 必须始终存在。
• Criteria 可以是 XML 文件中对象的任何有效属性。
• 在 <xsl:choose> 之间,可能存在许多包含不同条件和不同操作名称的 <xsl: when test ....>。
• 只有 CreateNewObject 和 SubstituteObject 可以具有操作参数,并且只有四个操作参数 <newName>、<newNumber>、<newVersion>、<newIteration>,必须提供全部四个参数。
• SubstituteObject:使用 XML 文件中的对象代替数据库中的对象,后者具有在 ImportPolicy 文件中提供的名称、编号、版本和小版本。如果不存在这种对象,则会抛出异常。在这种情况下,标记和参数的格式与 CreateNewObject 完全相同,但是 <action> 为 SubstituteObject。
• 忽略:请勿在 XML 文件中导入对象。无需任何操作者。
|
Importer 类
定义:公共类 Importer 可扩展 ExpImporter
构造函数:
Importer ( ApplicationImportHandler _applicationImportHandler,
WTContainerRef _targetContainer,
String _dtd,
String _ruleFileName,
String _xslPolicyFileName,
String _containerMappingFileName,
String _actorName,
Boolean _overrideConflicts,
Boolean _validate
) throws WTException
参数说明:
• applicationImportHandler:实现接口 ApplicationImportHandler 或扩展抽象类 ApplicationImportHandlerTemplate 的类的实例
• applicationImportHandler 具有从存储 XML 的 Jar 文件中提取的作业,并且其类必须实现两种方法:
getContentAsInputStream (String contentId);
getContentAsApplicationData (String contentId);
后面的方法可能总是返回空,以指示该文件在 Windchill 数据库中不存在。
|
有关应用程序导入处理程序的实现示例,请参阅 ApplicationExportHandlerForJar。
|
• targetContainer:必须在其中导入对象的容器
• targetDTD:用于指定导入进程必须使用的 DTD 的字符串。如果导入的文件未指定任何对象,则 IX 框架将基于此 DTD 字符串找到对象的适当处理程序和对象的文档类型定义。Windchill 版本 10.X 中使用的 DTD 字符串为 standardX20.dtd。
• ruleFileName:映射规则文件可以是 XML 文件 (如以前的版本) 或 XSL 文件,因此此参数为字符串。使用 IxbElement _localMappingRules 的构造函数已弃用。如果您没有映射规则文件并希望将其设置为空,请不要将 "null" 值直接放入构造函数中,原因在于这将导致不明确的参考错误。请不要这样做,您应该使用字符串,为其分配空值,然后将其作为 ruleFileName 传递。映射规则文件用于在执行导入进程时更改、覆盖或排除某些属性对象。
例如,规则文件会覆盖团队模板属性,并且无论对象在导出时属于哪个团队,导入时在 "/System" 域中的“团队”模板属性都将被“更改”替换。
<?xml version="1.0" encoding="UTF-8"?>
<userSettings>
<mappingRules>
<COPY_AS>
<tag>teamIdentity</tag>
<value>*</value>
<newValue>Change Team (/System)</newValue>
</COPY_AS>
</mappingRules>
</userSettings>
XSL 映射规则文件的示例:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="WTPart">
<xsl:choose>
<xsl:when test="name='part_c'">
<newInfo>
<teamIdentity>Default (/System)</teamIdentity>
<folderPath>/Design</folderPath>
<versionInfo>
<versionId>B</versionId>
<iterationId>2</iterationId>
<versionLevel>1</versionLevel>
</versionInfo>
</newInfo>
</xsl:when>
<xsl:when test="number='PART_B'">
<newInfo>
<teamIdentity>Default (/System)</teamIdentity>
<folderPath>/Design<folderPath>
</newInfo>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
此 XSL 文件表明,每当导入进程遇到名为 part_c 的 WTPart 时,将其团队标识模板更改为默认 (/System),将其文件夹部件更改为 /Design,并将其版本更改为 B.2;每当导入进程遇到编号为 PART_B 的 WTPart 时,将其团队标识模板更改为 默认 (/System),并将其文件夹部件更改为 /Design
如果您不想覆盖任何内容,只需为参数 localMapppingRules 传递 "null" 即可。
• _xslPolicyFileName:策略文件名称
• _containerMappingFileName:容器映射文件名样本容器映射文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<container-info>
<container>
<source-container>/wt.inf.container.OrgContainer=
Demo Organization/wt.pdmlink.PDMLinkProduct=
DemoSourceProduct</source-container>
<target-container>/wt.inf.container.OrgContainer=
Demo Organization/wt.pdmlink.PDMLinkProduct=
DemoTargetProduct</target-container>
</container>
</container-info>
• _actorName:要使用的操作者的名称
• _overrideConflicts:布尔值指定导入进程是否应覆盖“可覆盖”冲突。
• _validate:布尔值指定导入进程是否应根据 DTD 验证导入对象的 XML 文件。
必须通过类 IxbHelper 的方法 newImporter() 创建类 Importer 的实例。例如:
Importer importer = IxbHelper.newImporter(…);
使用 Importer 从 XML 文件导入对象
创建类 Importer (导入程序) 的实例后,可以使用该实例从 XML 文件导入对象。如果要导入的 XML 文件不止一个,则必须将从 XML 文件创建的 IxbDocument-s 一对一地提供给导入程序。
如上所述,导入应用程序服务器必须调用两种方法来执行导入:
importer.doImport(IxbDocument doc);
importer.finalizeImport();
• doImport (doc):此方法实际上并未导入对象,而是将表示该对象的 XML 文档插入到列表中,以便稍后导入。在将代表所有导入对象的所有 XML 文档插入到导入列表中之后,实际导入进程从对 finalizeImport() 的调用开始。
• finalizeImport():导入进程实际上在此方法中执行。该进程将调用:
doCheckConflicts() - 检查导入对象的冲突。
doRealImport () - 通过对表示列表中每个对象的每个 XML 文档调用 importElement (IxbElement doc) 来实际导入对象列表。
ImportElement(...) calls importElements(...):在方法 importElements(…) 中,通过调用 getImportHandler(tag 创建对象的特定类型的导入处理程序。
方法 getImportHandler(…) 会为导入对象找到合适的处理程序,如下所示。
1. 尝试通过使用导入对象 XML 文件的 <dtd> 标记中的 DTD 字符串来获取导入处理程序。
2. 如果处理程序为空,请使用导入程序中的当前 DTD 重试。使用当前 Windchill 的版本来计算当前的 DTD。对于 Windchill 版本 10.X,该项为 standardX20.dtd。
获取元素的处理程序后,importElements(…) 调用以下方法:
handler.importElements(…) to do the import task.
handler.outputLog(…) to send log to user.
非版本对象的所有处理程序 (例如 ReportTemplate ... )) 可扩展类 ClassExporterImporterTemplate,链接对象的所有处理程序 (例如 PartUsageLink...) 可扩展类 ExpImpForLinkObject,所有版本化对象的处理程序 (例如部件、文档、EPMDocument...) 可扩展类 ExpImpForVersionedObject。
如果实际处理程序未实现方法 importElements(…),则调用将调用类 ClassExporterImporterTemplate 的默认方法 importElements(…)。在此类中,importElement(...) 方法可调用 findAmongExistingObjects (elements, importer);。
如果发现 XML 文件中的对象当前存在于数据库中,则不会导入该对象。否则将调用以下方法:
createObjects ( elements, importer);
importObjectsAttributes (elements, importer);
storeObjects (elements, importer);
importObjectsAttributesAfterStore (elements, importer);
finalizeImprtObjects(isNewObject, elements, importer);
其中一些方法应在处理程序中实现,这是实际处理程序执行作业的方式和时间。
如果实际处理程序未实现方法 importElements(…),则调用将调用类 ExpImpForVersionedObject 的默认方法 importElements(…)。 在此类中,无论 XML 文件中的对象是否存在于数据库中,importElements(…) 方法始终会调用:
createObject (elements, importer);
importObjectsAttributes (elements,
importer);
storeObjects (List<ElementObjectPair> pairs, importer);
importObjectsAttributesAfterStore (List<ElementObjectPair> pairs,
importer);
然后,导入应用程序可以执行清理操作,并将消息发送至客户端。导入进程完成。