2.Work Item的应用和扩展
在团队协同工作中,常常需要记录、追踪和管理团队成员的各种工作和任务。这些工作和任务总是具有一些共同的属性,同时又相互有所区别;它们还具有若干种状态信息,进而和流程绑定。Jazz为管理这些工作和任务提供了工作项(Work Item)的概念:
· 每个Work Item都有一个类型属性,它将Work Item按照使用的目的不同分为若干类,如Defect,Task等。如果Jazz中存在的几种Work Item类型不能满足需要,开发者可以通过扩展来加入新的Work Item类型。具有相同类型的Work Item将具有相同的属性集以及相同的状态转换策略。
· Work Item有一组内建的属性,这些属性与它们的类型无关。也就是说每种Work Item都具有这些属性,如ID、摘要、描述、类型、状态、严重程度、优先级、创建时间、创建人等。除了内建属性外,每个Work Item类型都可以自定义新的属性,这些新的属性被称为定制属性。
· 为了记录Work Item与其它Work Item之间,或与其它实体之间的关系,Jazz使用了Link的概念。已有的Link类型有“Parent”,“Child”,“Duplicate”等,分别表示一个Work Item是另一个的父任务、子任务,及重复项。Link信息并不是存储在Work Item之中,而是通过Link service提供的API进行操作。Link允许扩展,开发者可以自己的需要来定义所需的Link类型。
Jazz支持对WorkItem的扩展以满足特定的需求,接下来我们结合在开发EasyInspection的过程中的实践,来具体介绍如何对Work Item进行扩展。
在EasyInspection中,我们需要为用户创建一种特殊的、与Code Inspection相关的Work Item。Jazz中已有的类型,如Defect、Task等类型都不是很合适,而且我们希望通过该类型可以将这种Work Item与其它的Work Item区分开来,于是我们决定建立一种称之为Inspection的新的Work Item类型。
Jazz为扩展Work Item类型提供的扩展点是“com.ibm.team.workitem.common.workItemType”。我们新建了一个Jazz/Eclipse插件项目,在plugin.xml中声明对它进行扩展,并指定新类型的ID、名称和分类,如下所示。
<extension
point="com.ibm.team.workitem.common.workItemType">
<workItemType
id="com.ibm.team.rtc.inspection.common.workItemType.inspection"
name="Inspection"
category="com.ibm.team.workitem.workItemType"
>
<alias name="inspection" />
</workItemType>
</extension>
(注意,在运行EasyInspection之前,需要将该插件部署到RTC的Server中。)
在运行时,通过所声明的类型ID“com.ibm.team.rtc.inspection.common.workItemType.inspection”找到WorkItem类型实例后,就可以动态的创建属于该类型的Work Item了:
public static final String CodeInspectionWorkItemTypeID =
"com.ibm.team.rtc.inspection.common.workItemType.inspection";
/**
* Create a "Inspection" work item instance, and then use the "workItemOperation" to initialize * it.
* @param projectArea the handle of the project area;
* @param workItemOperation a WorkItemOperation implementation that would initialize and
* save the new work item;
* @param monitor
* @return the handle of the new created work item.
* @throws TeamRepositoryException
*/
public IWorkItemHandle createCodeInspectionWorkItem(IProjectAreaHandle projectArea,
WorkItemOperation workItemOperation, IProgressMonitor monitor) throws TeamRepositoryException {
// find the definition of the work item type
IWorkItemType workItemType = findWorkItemType(projectArea,
CodeInspectionWorkItemTypeID, monitor);
// call workItemOperation to create, initialize and save the work item.
return workItemOperation.run(workItemType, monitor);
}
private IWorkItemType findWorkItemType(IProjectAreaHandle prjArea, String itemTypeId,
IProgressMonitor mon) throws TeamRepositoryException {
// get the repository
ITeamRepository repos = context.teamRepository();
// get the instance of the work item client
IWorkItemClient workItemClient = (IWorkItemClient) repos.getClientLibrary(IWorkItemClient.class);
// find the work item type definition through the type ID.
return workItemClient.findWorkItemType(prjArea, itemTypeId, mon);
}
当用户创建一个Inspection类型的Work Item时,往往需要指定与此Work Item相关联的代码片段或者文件名。例如,用户A发现在文件abc.java的50行处有一个编程错误,需要通知用户B修改。于是他创建一个类型为Inspection的Work Item给B,加入描述,并在Work Item中标注出此位置。为了记录该位置信息并帮助用户快速定位,我们决定扩展并使用Link,以满足此需求。
与扩展Work Item类型一样,需要首先在plugin.xml中声明此扩展。Jazz提供的扩展点是“com.ibm.team.repository.common.linkTypes”,我们指定新的Link类型的ID为“com.ibm.team.rtc.inspection.common.linkType.sourceCode”,它是从一个Work Item指向一个或多个源代码文件。
<extension
point="com.ibm.team.repository.common.linkTypes">
<linkType constrained="false"
id="com.ibm.team.rtc.inspection.common.linkType.sourceCode"
internal="false">
<source>
<endpoint displayName="Work Item" id="workItem" multiplicity="0..1">
<itemReferenceType itemTypeName="WorkItem"
packageURI="com.ibm.team.workitem">
</itemReferenceType>
</endpoint>
</source>
<target>
<endpoint displayName="Source Code"
id="sourceCode" icon="/icons/obj16/resolutn_wontdo.gif"
multiplicity="0..n">
</endpoint>
</target>
</linkType>
</extension>
有了此声明后,在程序中可以通过此ID来获取到对该Link的描述符,然后通过Link service的API创建Link。
// get the work item
IWorkItem workItem = workingCopy.getWorkItem();
.... ...
// SourceCodeLocator contains the location information of the selected source files.
SourceCodeLocator[] resources;
... ...
// get the definition of the link type, and then get the descriptor
// for it's endpoint
IEndPointDescriptor endPoint = ILinkTypeRegistry.INSTANCE.getLinkType(
“com.ibm.team.rtc.inspection.common.linkType.sourceCode “) .getTargetEndPointDescriptor();
// save the location information one by one
for (int i = 0, n = resources.length; i < n; i++) {
// create a reference to the source code entity
IURIReference uri = IReferenceFactory.INSTANCE.createReferenceFromURI(resources[i].toUri());
// add this reference to the work item;
workingCopy.getReferences().add(endPoint, uri);
}
下图为我们在EasyInspect中创建的LINK的具体实现效果:
