list of files that are connected to workitem
2 answers
I wrote a plugin that writes the names of the files that contained in a chagesets related to the workitem.
the list of files is written in Description attributes.
The problem is that I get the file list on associate CS to WI, but the developer can associate a new file after the association action (so the file will not be written in my list). So I need a different action to trigger (maybe checkin)
/*******************************************************************************
* Licensed Materials - Property of IBM (c) Copyright IBM Corporation 2005-2006.
* All Rights Reserved.
*
* Note to U.S. Government Users Restricted Rights: Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
******************************************************************************/
package advisor.example;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import com.ibm.team.foundation.common.text.XMLString;
import com.ibm.team.process.common.IProcessConfigurationElement;
import com.ibm.team.process.common.advice.AdvisableOperation;
import com.ibm.team.process.common.advice.IAdvisorInfo;
import com.ibm.team.process.common.advice.IAdvisorInfoCollector;
import com.ibm.team.process.common.advice.runtime.IOperationAdvisor;
import com.ibm.team.repository.common.IAuditableHandle;
import com.ibm.team.repository.common.IItemHandle;
import com.ibm.team.repository.common.TeamRepositoryException;
import com.ibm.team.repository.service.AbstractService;
import com.ibm.team.repository.service.IItemServiceIterator;
import com.ibm.team.repository.service.IRepositoryItemService;
import com.ibm.team.repository.service.ItemServiceIteratorFactory;
import com.ibm.team.repository.service.internal.util.StringUtils;
import com.ibm.team.scm.common.IChange;
import com.ibm.team.scm.common.IChangeSet;
import com.ibm.team.scm.common.IChangeSetHandle;
import com.ibm.team.scm.common.IScmService;
import com.ibm.team.scm.common.IVersionable;
import com.ibm.team.scm.common.IVersionableHandle;
import com.ibm.team.scm.common.dto.IAncestorReport;
import com.ibm.team.scm.common.dto.INameItemPair;
import com.ibm.team.scm.common.internal.dto.ServiceConfigurationProvider;
import com.ibm.team.scm.common.process.DeliverOperationData;
import com.ibm.team.scm.common.process.SaveClosedChangeSetOperationData;
import com.ibm.team.workitem.common.IAuditableCommon;
import com.ibm.team.workitem.common.model.IApproval;
import com.ibm.team.workitem.common.model.IApprovals;
import com.ibm.team.workitem.common.model.IAttribute;
import com.ibm.team.workitem.common.model.IWorkItem;
import com.ibm.team.workitem.common.model.IWorkItemHandle;
import com.ibm.team.workitem.common.model.ItemProfile;
import com.ibm.team.workitem.service.IWorkItemServer;
@SuppressWarnings("unchecked")
public class RestrictDeliverOfDeletionsAdvisor extends AbstractService implements IOperationAdvisor {
private static final String fileSeperator = "˜";
private static final String endOfLine = "<br/>";
private static final String fileHasBeenChangeMessage = " <b> שים לב הקובץ השתנה !!! </b>";
private String lastKey;
public void run(AdvisableOperation operation, IProcessConfigurationElement advisorConfiguration, IAdvisorInfoCollector collector, IProgressMonitor monitor) throws TeamRepositoryException {
Object operationData = operation.getOperationData();
if (!(operationData instanceof SaveClosedChangeSetOperationData)) {
return;
}
SaveClosedChangeSetOperationData data = (SaveClosedChangeSetOperationData) operationData;
//General
//IAuditableCommon common = (IAuditableCommon) this.getService(IAuditableCommon.class);
//IRepositoryItemService itemService = getService(IRepositoryItemService.class);
IScmService scmService = getService(IScmService.class);
IWorkItemServer itemServer= getService(IWorkItemServer.class);
IRepositoryItemService repositoryItemService = getService(IRepositoryItemService.class);
//Get Change-set and put it in HashMap
Set<String> fileNameSet = new HashSet<String>(); //set to put new filenames
IChangeSet changeSet = data.getChangeSet();
List<IChange> mychanges = changeSet.changes();
for ( IChange change : mychanges ) {
//case: new> change.afterState(); change or old> change.beforeState(); deleted> change.beforeState()+ delete the filename from the list.
IVersionableHandle versionableHandle = change.beforeState();
if (versionableHandle == null){
versionableHandle = change.afterState();
}
IVersionable item = (IVersionable) scmService.fetchState(versionableHandle, null, null);
fileNameSet.add(item.getName());
//map.put(item.getName(),"");
}
//Get Work-item and build a new HashMap from the existing data of the work-item.
Map<String,String> fileDescriptionMap;// = getFileDescriptionMap();//new HashMap<String,String>();
String allFileNamesString = ""; //the final string value to set to the WI
List<? extends IAuditableHandle> mylinks = data.getLinks();
IAttribute attribute;
String attrName = "description";
IWorkItem relatedWorkItem;
IWorkItem itemCopy;
for (IAuditableHandle mylink : mylinks) { //need to think if I want the code reviewer to check this file in all workitems..
//* ItemProfile<IAuditable> profile = ItemProfile.createFullProfile(IProjectArea.ITEM_TYPE);
//** ItemProfile<IWorkItem> profile = IWorkItem.SMALL_PROFILE;
if (mylink instanceof IWorkItemHandle){
IWorkItemHandle handle = (IWorkItemHandle) mylink;
relatedWorkItem = (IWorkItem) repositoryItemService.fetchItem(handle, null);
itemCopy = (IWorkItem)relatedWorkItem.getWorkingCopy();
attribute = itemServer.findAttribute(itemCopy.getProjectArea(), attrName, null);
XMLString lastData = relatedWorkItem.getHTMLDescription();
String lastDataString = lastData.toString();
//need to make parsing on the old data and enter the values to the map.
fileDescriptionMap = getFileDescriptionMap(lastDataString);
//add new files to the HashMap. If value exist than add a comment. after, write the complete HashMap to the Work-item.
allFileNamesString = getAttributeContent(fileDescriptionMap, fileNameSet);
//Object myString = fileNameSet.toString();
//itemCopy.setValue(attribute, myString);
itemCopy.setValue(attribute, allFileNamesString);
itemServer.saveWorkItem2(itemCopy, null, null);
}
}
}
private Map<String, String> getFileDescriptionMap(String lastDataString) {
Map<String, String> fileDescriptionMap = new HashMap<String, String>();
if (StringUtils.isEmpty(lastDataString)){
return fileDescriptionMap;
}
String[] linesArray = lastDataString.split(endOfLine);
for (String line : linesArray){
if (line.contains(fileSeperator)){
int fileSeperatorIndex = line.indexOf(fileSeperator);
String fileName = line.substring(0, fileSeperatorIndex);
//remove any <b> or </b>
while (fileName.startsWith("<b>")){
//fileName = fileName.substring(5);
fileName = fileName.substring(3, fileName.length()-4);
}
/*while (fileName.endsWith("</b>")){
fileName = fileName.substring(5, fileName.length()-6);
}*/
String fileDescription = line.substring(fileSeperatorIndex + fileSeperator.length());
fileDescriptionMap.put(fileName, fileDescription);
lastKey = fileName;
}
else{
//the line is continue for the last description
String value = fileDescriptionMap.get(lastKey);
fileDescriptionMap.put(lastKey, value + endOfLine + line );
}
}
return fileDescriptionMap;
}
private String getAttributeContent(Map<String, String> existingFileDescriptionMap, Set<String>newFileSet){
String attributeContent = "";
for (String existingFile : existingFileDescriptionMap.keySet()){
if (newFileSet.contains(existingFile)){
attributeContent += newLineContent(existingFile, existingFileDescriptionMap.get(existingFile), true);
newFileSet.remove(existingFile);
}
else {
attributeContent += newLineContent(existingFile, existingFileDescriptionMap.get(existingFile), false);
}
}
for (String newFile : newFileSet){
attributeContent += newLineContent(newFile, "", false);
}
return attributeContent;
}
private String newLineContent(String fileName, String fileDescription, boolean hasBeenChange){
String newLineContent = "<b>" + fileName + "</b>" + fileSeperator + fileDescription;
if (hasBeenChange && !fileDescription.endsWith(fileHasBeenChangeMessage)){
newLineContent += fileHasBeenChangeMessage;
}
newLineContent += endOfLine;
return newLineContent;
}
private String toFullPath(IVersionable versionable/*, List<INameItemPair> segments*/) {
return versionable.getName();
/*StringBuffer path = new StringBuffer();
if(segments.isEmpty()) {
return versionable.getName();
}
for (INameItemPair nameItemPair : segments) {
if(path.length() != 0) {
path.append(Path.SEPARATOR);
}
// ignore the root folder which doesn't have a name
if(nameItemPair.getName() != null)
path.append(nameItemPair.getName());
}
return path.toString();*/
}
}
the list of files is written in Description attributes.
The problem is that I get the file list on associate CS to WI, but the developer can associate a new file after the association action (so the file will not be written in my list). So I need a different action to trigger (maybe checkin)
/*******************************************************************************
* Licensed Materials - Property of IBM (c) Copyright IBM Corporation 2005-2006.
* All Rights Reserved.
*
* Note to U.S. Government Users Restricted Rights: Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
******************************************************************************/
package advisor.example;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import com.ibm.team.foundation.common.text.XMLString;
import com.ibm.team.process.common.IProcessConfigurationElement;
import com.ibm.team.process.common.advice.AdvisableOperation;
import com.ibm.team.process.common.advice.IAdvisorInfo;
import com.ibm.team.process.common.advice.IAdvisorInfoCollector;
import com.ibm.team.process.common.advice.runtime.IOperationAdvisor;
import com.ibm.team.repository.common.IAuditableHandle;
import com.ibm.team.repository.common.IItemHandle;
import com.ibm.team.repository.common.TeamRepositoryException;
import com.ibm.team.repository.service.AbstractService;
import com.ibm.team.repository.service.IItemServiceIterator;
import com.ibm.team.repository.service.IRepositoryItemService;
import com.ibm.team.repository.service.ItemServiceIteratorFactory;
import com.ibm.team.repository.service.internal.util.StringUtils;
import com.ibm.team.scm.common.IChange;
import com.ibm.team.scm.common.IChangeSet;
import com.ibm.team.scm.common.IChangeSetHandle;
import com.ibm.team.scm.common.IScmService;
import com.ibm.team.scm.common.IVersionable;
import com.ibm.team.scm.common.IVersionableHandle;
import com.ibm.team.scm.common.dto.IAncestorReport;
import com.ibm.team.scm.common.dto.INameItemPair;
import com.ibm.team.scm.common.internal.dto.ServiceConfigurationProvider;
import com.ibm.team.scm.common.process.DeliverOperationData;
import com.ibm.team.scm.common.process.SaveClosedChangeSetOperationData;
import com.ibm.team.workitem.common.IAuditableCommon;
import com.ibm.team.workitem.common.model.IApproval;
import com.ibm.team.workitem.common.model.IApprovals;
import com.ibm.team.workitem.common.model.IAttribute;
import com.ibm.team.workitem.common.model.IWorkItem;
import com.ibm.team.workitem.common.model.IWorkItemHandle;
import com.ibm.team.workitem.common.model.ItemProfile;
import com.ibm.team.workitem.service.IWorkItemServer;
@SuppressWarnings("unchecked")
public class RestrictDeliverOfDeletionsAdvisor extends AbstractService implements IOperationAdvisor {
private static final String fileSeperator = "˜";
private static final String endOfLine = "<br/>";
private static final String fileHasBeenChangeMessage = " <b> שים לב הקובץ השתנה !!! </b>";
private String lastKey;
public void run(AdvisableOperation operation, IProcessConfigurationElement advisorConfiguration, IAdvisorInfoCollector collector, IProgressMonitor monitor) throws TeamRepositoryException {
Object operationData = operation.getOperationData();
if (!(operationData instanceof SaveClosedChangeSetOperationData)) {
return;
}
SaveClosedChangeSetOperationData data = (SaveClosedChangeSetOperationData) operationData;
//General
//IAuditableCommon common = (IAuditableCommon) this.getService(IAuditableCommon.class);
//IRepositoryItemService itemService = getService(IRepositoryItemService.class);
IScmService scmService = getService(IScmService.class);
IWorkItemServer itemServer= getService(IWorkItemServer.class);
IRepositoryItemService repositoryItemService = getService(IRepositoryItemService.class);
//Get Change-set and put it in HashMap
Set<String> fileNameSet = new HashSet<String>(); //set to put new filenames
IChangeSet changeSet = data.getChangeSet();
List<IChange> mychanges = changeSet.changes();
for ( IChange change : mychanges ) {
//case: new> change.afterState(); change or old> change.beforeState(); deleted> change.beforeState()+ delete the filename from the list.
IVersionableHandle versionableHandle = change.beforeState();
if (versionableHandle == null){
versionableHandle = change.afterState();
}
IVersionable item = (IVersionable) scmService.fetchState(versionableHandle, null, null);
fileNameSet.add(item.getName());
//map.put(item.getName(),"");
}
//Get Work-item and build a new HashMap from the existing data of the work-item.
Map<String,String> fileDescriptionMap;// = getFileDescriptionMap();//new HashMap<String,String>();
String allFileNamesString = ""; //the final string value to set to the WI
List<? extends IAuditableHandle> mylinks = data.getLinks();
IAttribute attribute;
String attrName = "description";
IWorkItem relatedWorkItem;
IWorkItem itemCopy;
for (IAuditableHandle mylink : mylinks) { //need to think if I want the code reviewer to check this file in all workitems..
//* ItemProfile<IAuditable> profile = ItemProfile.createFullProfile(IProjectArea.ITEM_TYPE);
//** ItemProfile<IWorkItem> profile = IWorkItem.SMALL_PROFILE;
if (mylink instanceof IWorkItemHandle){
IWorkItemHandle handle = (IWorkItemHandle) mylink;
relatedWorkItem = (IWorkItem) repositoryItemService.fetchItem(handle, null);
itemCopy = (IWorkItem)relatedWorkItem.getWorkingCopy();
attribute = itemServer.findAttribute(itemCopy.getProjectArea(), attrName, null);
XMLString lastData = relatedWorkItem.getHTMLDescription();
String lastDataString = lastData.toString();
//need to make parsing on the old data and enter the values to the map.
fileDescriptionMap = getFileDescriptionMap(lastDataString);
//add new files to the HashMap. If value exist than add a comment. after, write the complete HashMap to the Work-item.
allFileNamesString = getAttributeContent(fileDescriptionMap, fileNameSet);
//Object myString = fileNameSet.toString();
//itemCopy.setValue(attribute, myString);
itemCopy.setValue(attribute, allFileNamesString);
itemServer.saveWorkItem2(itemCopy, null, null);
}
}
}
private Map<String, String> getFileDescriptionMap(String lastDataString) {
Map<String, String> fileDescriptionMap = new HashMap<String, String>();
if (StringUtils.isEmpty(lastDataString)){
return fileDescriptionMap;
}
String[] linesArray = lastDataString.split(endOfLine);
for (String line : linesArray){
if (line.contains(fileSeperator)){
int fileSeperatorIndex = line.indexOf(fileSeperator);
String fileName = line.substring(0, fileSeperatorIndex);
//remove any <b> or </b>
while (fileName.startsWith("<b>")){
//fileName = fileName.substring(5);
fileName = fileName.substring(3, fileName.length()-4);
}
/*while (fileName.endsWith("</b>")){
fileName = fileName.substring(5, fileName.length()-6);
}*/
String fileDescription = line.substring(fileSeperatorIndex + fileSeperator.length());
fileDescriptionMap.put(fileName, fileDescription);
lastKey = fileName;
}
else{
//the line is continue for the last description
String value = fileDescriptionMap.get(lastKey);
fileDescriptionMap.put(lastKey, value + endOfLine + line );
}
}
return fileDescriptionMap;
}
private String getAttributeContent(Map<String, String> existingFileDescriptionMap, Set<String>newFileSet){
String attributeContent = "";
for (String existingFile : existingFileDescriptionMap.keySet()){
if (newFileSet.contains(existingFile)){
attributeContent += newLineContent(existingFile, existingFileDescriptionMap.get(existingFile), true);
newFileSet.remove(existingFile);
}
else {
attributeContent += newLineContent(existingFile, existingFileDescriptionMap.get(existingFile), false);
}
}
for (String newFile : newFileSet){
attributeContent += newLineContent(newFile, "", false);
}
return attributeContent;
}
private String newLineContent(String fileName, String fileDescription, boolean hasBeenChange){
String newLineContent = "<b>" + fileName + "</b>" + fileSeperator + fileDescription;
if (hasBeenChange && !fileDescription.endsWith(fileHasBeenChangeMessage)){
newLineContent += fileHasBeenChangeMessage;
}
newLineContent += endOfLine;
return newLineContent;
}
private String toFullPath(IVersionable versionable/*, List<INameItemPair> segments*/) {
return versionable.getName();
/*StringBuffer path = new StringBuffer();
if(segments.isEmpty()) {
return versionable.getName();
}
for (INameItemPair nameItemPair : segments) {
if(path.length() != 0) {
path.append(Path.SEPARATOR);
}
// ignore the root folder which doesn't have a name
if(nameItemPair.getName() != null)
path.append(nameItemPair.getName());
}
return path.toString();*/
}
}