基本自定义 > Windchill 自定义基础 > Windchill 自定义入门 > 创建类
  
创建类
1. 首先启动 Eclipse (请参阅上一节)。cust_Windchill_src 项目应在 Eclipse 中打开,其显示应与如下所示类似:
2. 创建 Pet 类。
a. 导航到“文件” > “新建” > “类”
b. “包”设置为 com.acme
c. “名称”设置为 Pet
d. 单击“完成”
结果将为空类,如下所示:
3. 将 Pet 设置为持续类。
a. 使用 @GenAsPersistable 注释类声明 (注:完成快捷键为 Ctrl + 空格键,由于 Eclipse 完成支持混合大小写,因此可在按 Ctrl + 空格键后键入 "@GAP" 完成此操作;通常,使用 Eclipse 完成的优点是,如果无法完成,则表示存在一些较大的语法错误需要纠正)
b. 保存 Pet (Ctrl-s)。Pet 将立即显示两个编译错误,如下所示:
此为预期结果。
c. 解决方法:
a. 使 Pet 扩展 _Pet
b. 在 Pet 正文中添加必需的声明
d. 再次保存 Pet。现在,Pet 扩展了实现 wt.fc.Persistable_Pet,并因此导致两个新错误。
通过将 superClass=WTObject.class 添加到上面的注释,以将 WTObject 设置为 _Pet 的超类,而不是直接实现这些操作 (superClassWTObject 将完成,Eclipse 将在完成过程中自动导入 WTObject)。
e. 再次保存 Pet。结果 (将完全编译) 如下所示:
f. 为 Pet 创建无参数工厂方法,组成如下:
public static Pet newPet() throws WTException {
final Pet instance = new Pet();
instance.initialize();
return instance;
}
Windchill 持续对象要求使用与基于构造函数的 newPet() 工厂方法类似的工厂方法。它们与接受相同参数的初始化方法配对,以便子类可以继承父类方法中存在的逻辑。在这种情况下,不需要显式初始化方法,因为 Pet 不会提供功能;此时,从 WTObject 继承的实现足以满足要求。
4. ContentHolderOwnable 添加到 Pet。Windchill 利用 Java 接口向持续业务类提供域功能。ContentHolder 可提供存储文件 (内容) 的能力,Ownable 可提供获取业务对象所有权的能力。
a. superClass 注释成员后添加 ", interfaces={ContentHolder.class, Ownable.class}"。确保使用 Eclipse“Ctrl + 空格键”完成自动导入接口
b. 保存 Pet
5. namedateOfBirthfixed 作为特性添加到 Pet。
a. 声明特性注释成员,方法如下:在接口的右 "}" 后添加一个逗号,添加一个换行符,然后插入以下内容 (即会显示注释的右括号):properties={ })
b. 所有特性将包含在特性的 "{}" 之间,每个特性一行。首先,按如下方式添加名称:
@GeneratedProperty(name="name", type=String.class,
columnProperties=@ColumnProperties(index=true),
constraints=@PropertyConstraints(required=true, upperLimit=60))
此特性声明 name 的类型为 String。名称为必填项,长度必须小于等于 60 个字符,并且将在数据库中索引。此工作的大部分过程可在 IDE 中通过代码完成,从而显著减少所需的输入工作量
c. 接下来,紧接着名称之后添加 dateOfBirth。为了分隔两个声明,需要在前一行末尾添加一个逗号:
@GeneratedProperty(name="dateOfBirth", type=Timestamp.class)
此处,dateOfBirthjava.sql.Timestamp
d. 最后,添加 fixed (布尔型):@GeneratedProperty(name="fixed", type=boolean.class)
6. 创建由常见宠物种类组成的枚举类型 PetKind
a. 导航到“文件” > “新建” > “类”
b. “包”设置为 com.acme
c. “名称”设置为 PetKind
d. 单击“完成”
GenAsEnumeratedType 注释添加到类声明中并使类扩展 _PetKind (忽略警告)。结果将如下所示:
7. 创建 PetKindRB.rbInfo 资源束,用于存储各种类型的宠物。
a. 选择 PetKind.java 并按 Ctrl + N。
b. 选择“常规” > “文件”,然后单击“下一步”
c. 提供 PetKindRB.rbInfo 作为文件名。
d. 单击 Finish。
e. 按如下所示创建 PetKindRB.rbInfo 内容 (并保存):
ResourceInfo.class=wt.tools.resource.EnumResourceInfo
dog.value=Dog
dog.order=10
cat.value=Cat
cat.order=20
gerbil.value=Gerbil
gerbil.order=30
8. 向 Pet 添加种类。
a. kind 置于 namedateOfBirth 之间: @GeneratedProperty(name="kind", type=PetKind.class, constraints=@PropertyConstraints(upperLimit=40))
枚举类型的存储值是键值 (dog、cat、gerbil),而不是显示值 (Dog、Cat、Gerbil)。指定的上限为 40,因为该值用来存储键已足够大。
9. 验证结果。请注意,稍微清理后,所有单独的注释导入已缩减为单一 "*" 导入:
10. 编译 PetKindRB.rbInfo
a. 查找或启动 Windchill shell (命令假定 shell 位于 Windchill 目录中)。
b. 运行以下命令:ant -f bin/tools.xml bundle -Dbundle.input=com.acme.*
11. 确保 PetPetKind 使用 Ant 进行编译。
a. 从先前命令重用 Windchill shell
b. ant -f bin/tools.xml class -Dclass.includes=com/acme/** -Dclass.force=true
12. 生成 SQL 脚本。
a. 再次重用 Windchill shell
b. ant -f bin/tools.xml sql_script -Dgen.input=com.acme.*
13. 加载 Pet 的架构。
a. 在以下路径中找到相应文件:load point/db, Make_pkg_acme_Table.sql
a. Oracle (单字节):db/sql/com/acme/Make_pkg_acme_Table.sql
b. Oracle (多字节):db/sql3/com/acme/Make_pkg_acme_Table.sql
c. SQLServer:db/sqlServer/com/acme/Make_pkg_acme_Table.sql
b. cd 从上面的内容 (db/sql、db/sql3 或 db/sqlServer) 更改为 db/<xxx>
c. 运行脚本
a. Oracle: sqlplus <database credentials> @com/acme/Make_pkg_acme_Table.sql
b. SQLServer:...
d. 重复 @com/acme/Make_pkg_acme_Index.sql
验证自定义
自定义不完整:不存在用于管理 Pet 对象的用户界面 (UI)。但是,已完成的自定义足以 验证对 Pet 对象执行的 CRUD 操作是否可行,如以下 Jython 代码演示。要调用示例:
1. http://www.jython.org 下载 (并安装) 最新版本的 Jython。
2. 启动 (或重新启动) MethodServer
3. 启动 Windchill shell
4. 运行 Jython,这将在无参数的情况下启动 Jython 解释器。
Jython 是采用 Python 编程语言的 Java 实现,而 Jython 使用 Python 语法,这样 Java 程序员容易上手。Jython 为主方法引入了 Java 类的两个重要优势:
Jython 是动态的:方法可在解释器中键入,由解释器立即调用,并且调用的结果将立即可用。这 (有时称为 "REPL") 将提供静态类文件不可比拟的代码交互级别,即使在调试器中进行调试时也是如此。此外,Jython 的动态特性还会阻止键入变量,转换、写入 try/catch 程序块 (除非这是所需的) 等,因此,与 Java 等效代码段相比,其代码明显更短。
Jython 可与 Java 无缝交互:Jython 可将 Python 引入 Java 而不降低 Java 性能。Jython 是“纯 Java”,可实例化任何 Java 类并调用任何 Java 方法或访问任何 Java 字段 (在 Java 安全模型的限制范围内)。除了能够与 Java 进行交互外,另外值得注意的是,Jython (作为 Python 实现) 和 Java 之间的“阻抗失谐”非常小,使得与 Java 的交互简单、轻松且可预测,并且可轻松转换为标准 Java。
Jython 并非基于 Java 虚拟机的唯一语言。除此之外还有 Groovy、JRuby、BeanShell 以及 JavaScript。所有语言都值得研究并且都具有值得发现的不同方法和原理,但是,Jython 胜在简单、可交互且解释器质量高。
应在 Jython 解释器中执行以下代码片段。分段后,这些片段应在同一解释会话中进行调用。也可以将这些段合并到单个脚本中,以由 Jython 执行;请注意,完成后,Jython 不会像在解释器中那样自动输出。
1. 导入对 Pet 对象执行 CRUD 所需的 Java 类:
from java.sql import Timestamp
from java.text import SimpleDateFormat
from com.acme import Pet, PetKind
from wt.fc import PersistenceHelper
from wt.ownership import OwnershipHelper
from wt.query import QuerySpec, SearchCondition
2. 创建两个宠物:
dog = Pet.newPet()
dog.setName('Fergus')
dog.setKind(PetKind.toPetKind('dog'))
dog.setDateOfBirth(Timestamp(SimpleDateFormat('yyyy-MM-dd').
parse('1999-02-11').getTime()))
dog.setFixed(False)
dog = PersistenceHelper.manager.store(dog)
cat = Pet.newPet()
cat.setName('Stimpy')
cat.setKind(PetKind.toPetKind('cat'))
cat.setDateOfBirth(Timestamp(SimpleDateFormat('yyyy-MM-dd').
parse('1996-08-24').getTime()))
cat.setFixed(False)
cat = PersistenceHelper.manager.store(cat)
3. 更新猫 (请注意,备注以 "#" 开头,它相当于 Java 的 "//";不需要输入备注字符串,该字符串旨在强调调用将输出当前承担者):
cat.setFixed(True)
cat = PersistenceHelper.manager.modify(cat)
cat = OwnershipHelper.service.takeOwnership(cat)
OwnershipHelper.getOwner(cat) #Should print/return the current principal
4. 查询 (读取) 名为 Fergus 的 Pet:
qs = QuerySpec(Pet)
qs.appendWhere(SearchCondition(Pet, Pet.NAME, SearchCondition.EQUAL,
'Fergus'))
qr = PersistenceHelper.manager.find(qs)
qr.size() #Should print/return 1
fergus = qr.nextElement()
fergus.getName() #Should print/return “Fergus”
5. 最后,删除狗:
PersistenceHelper.manager.delete(dog)
Pet 自定义注解
如前所述,本示例与其说是实际 Windchill 业务对象的示例,不如说是关于 Windchill 持久化和模型化的 "Hello, World!" 介绍。因此,会对各种类型 (字符串、枚举、时间戳和基元) 的特性进行建模以演示可能的情况,但很显然,Pet 类不足以存储有关宠物的信息。
类似地,在 Pet 实现 Windchill 接口时,从 Windchill 的角度来说,它是一个特别轻量化的对象。首先,它未设置为 AccessControlled (在 wt.access 中),因此满足身份验证最低要求的任何人都可以创建、读取、更新或删除宠物。其次,大多数 Windchill 业务类都是 WTContained (在 wt.inf.container 中),因为 ContainerShip 是 Windchill 的主要组织原则。
对自定义进行的最终急需更正是类似于已在验证中使用的帮助程序/服务 (PersistenceHelper.manager 中的 PersistenceManagerOwnershipHelper.service 中的 OwnershipService)。
可通过服务提供内嵌逻辑操作 (如采用) 的 API。这些 API 可利用事务处理,与离散 API 配合解决主要缺陷,从而在客户端上实现采用:可修改 Pet,无法 takeOwnership,产生可能被视为已损坏的状态。服务 API (例如 "public Pet adopt(Pet pet, WTPrincipalReference owner) throws WTException") 可利用事务处理,以确保整个采用过程顺利进行,或无法进行。
本指南中的后续章节将涵盖建模和服务器端自定义的这些及更多方面。
有关使用主数据类对 WTObject 进行建模的详细信息,请参阅对新文档子类进行建模