Reputation: 55
I've created a Java provided attribute for a work item that provides a value set by looking at two other attributes (enumerations) from the same/current work item which together form a directory path that the java provided attribute will create a value set using the names of files nested in that directory. It works well if a work item is created for the first time however on modifying the work item, it fails to populate the set so a new value can be selected.
I've found that when it gets to this statement:
IAttribute currentAttribute= (IAttribute) handle;
That an exception is generated. It can't cast to IAttribute handle because the return items from workItem.getCustomAttributes() are different between a new Wotk Item and a modified work item.
The exception message is:
com.ibm.team.workitem.common.internal.model.impl.AttributeHandleImpl incompatible with com.ibm.team.workitem.common.model.IAttribute
I'm not sure why the how to get the com.ibm.team.workitem.common.internal.model.impl.AttributeHandleImpl is used on modifying a workitem and ...AttributeHandle is used on first creation of a work item.
I'm not sure how to tackle this or cast it to IAttribute which I what I need.
public class SpecificArtifactType implements IValueSetProvider<String> {
private List<String> list;
public SpecificArtifactType() {
}
@Override
public List<String> getValueSet(IAttribute attribute, IWorkItem workItem,
IWorkItemCommon workItemCommon, IConfiguration configuration,
IProgressMonitor monitor) throws TeamRepositoryException {
String idValue= "";
String deliverableArtifactTypeValue= "";
List<IAttributeHandle> customAttributeHandles= workItem.getCustomAttributes();
/*
* THE DELIVERABLE ARTIFACT AND ID VALUES ARE BOTH USED TO BUILD
* THE DIRECTORY PATH WHICH THIS ATTRIBUTE WILL USE TO POPULATE
* ITS VALUE SET WITH THE ARTIFACTS LOCATED AT THAT LOCATION.
*/
for (IAttributeHandle handle: customAttributeHandles)
{
IAttribute currentAttribute= (IAttribute) handle;
if (currentAttribute.getDisplayName()
.equals(ICustomAttributeDefinitions.ID))
{
idValue= getValue(currentAttribute, monitor, workItemCommon, workItem);
}
else if (currentAttribute.getDisplayName()
.equals(ICustomAttributeDefinitions.DELIVERABLE_ARTIFACT_TYPE))
{
deliverableArtifactTypeValue= getValue(currentAttribute, monitor, workItemCommon, workItem);
}
}
// BUILD THE DIRECTORY PATH
String directory = ICustomAttributeDefinitions.STREAM_ROOT_DIRECTORY
+deliverableArtifactTypeValue +"\\"+ idValue;
File folderPath = new File(directory);
/*
* NEED A VALID PATH TO CONTINUE AND ALSO PREVENT TRYING TO
* LIST CHILD ITEMS IF IT'S A FILE.
*/
if (folderPath.exists() && folderPath.isDirectory())
{
if (folderPath.list().length == 0)
{
directoryEmpty();
return list;
}
list= new ArrayList<String>();
for (String name: folderPath.list())
list.add(name);
}
else invalidDirectoryPath();
return list;
}
/*
* CONVERT VALUE FROM MODEL IDENTIFIER (EG ID.literal.l01) TO ACTUAL VALUE
*/
private String getValue(IAttribute attribute,
IProgressMonitor monitor,
IWorkItemCommon workItemCommon,
IWorkItem workItem) throws TeamRepositoryException
{
IEnumeration<? extends ILiteral> enumeration= workItemCommon
.resolveEnumeration(attribute, monitor);
String value= "";
List<? extends ILiteral> literals= enumeration.getEnumerationLiterals();
for (Iterator<? extends ILiteral> iterator= literals.iterator(); iterator.hasNext(); )
{
ILiteral iLiteral= (ILiteral) iterator.next();
if (iLiteral.getIdentifier2().equals(workItem.getValue(attribute)))
{
value= iLiteral.getName().toString();
break;
}
}
return value;
}
private void directoryEmpty(){
list= new ArrayList<String>(1);
list.add(ICustomAttributeDefinitions.DIRECTORY_EMPTY);
}
private void invalidDirectoryPath()
{
list= new ArrayList<String>(1);
list.add(ICustomAttributeDefinitions.INVALID_DIRECTORY_PATH);
}
}
Upvotes: 1
Views: 480
Reputation: 1809
There could be three solutions of this issue:
1) When you create workItem and save the workItem instance then its state changed, So now when you call workItem.getCustomAttributes(), It will not return the desired result So you need to add this line before:
IWorkItem workItem = (IWorkItem) getWorkItemServer()
.getAuditableCommon()
.resolveAuditable(savedWorkItem, IWorkItem.FULL_PROFILE, null);
you can get the client code easily against this server code, this will get the saved state of workItem
2) You can prevent this exception to occur by checking instanceof
before casting it to IAttribute
3) Get the IAttribute
by its identifier and then get the IAttribute
by:
WorkItemUIWorkingCopy uiWorkingCopy = (WorkItemUIWorkingCopy)
workingCopy.getAdapter(IWorkItemUIWorkingCopy.class);
IAttribute attribute =
uiWorkingCopy.getResolvedWorkItem().findAttribute(fAttribute.getIdentifier());
Hope it will help you
Upvotes: 1