/** * Change the MsProject and 'Close depends on' linkType's link direction to right to left For item * links of those types change the predecessor with successor and vice versa and change the link * direction */ public static void inverseLinkDirections(boolean linkPredSuccAlso) { // change the direction to inward for MsProjectLinkType and // CloseDependsOnLinkType List<Integer> linkTypeIDs = new LinkedList<Integer>(); List<TLinkTypeBean> msProjectlinkTypeBeans = LinkTypeBL.loadByLinkType(MsProjectLinkType.getInstance().getPluginID(), null); if (msProjectlinkTypeBeans != null) { for (TLinkTypeBean linkTypeBean : msProjectlinkTypeBeans) { linkTypeIDs.add(linkTypeBean.getObjectID()); Integer direction = linkTypeBean.getLinkDirection(); if (direction == null || direction.intValue() != LINK_DIRECTION.RIGHT_TO_LEFT) { linkTypeBean.setLinkDirection(LINK_DIRECTION.RIGHT_TO_LEFT); LinkTypeBL.save(linkTypeBean); LOGGER.info( "'MsProject' link type " + linkTypeBean.getName() + " set to unidirectional inward"); } } } List<TLinkTypeBean> closeDependsOnLinkBeans = LinkTypeBL.loadByLinkType(CloseDependsOnLinkType.getInstance().getPluginID(), null); if (closeDependsOnLinkBeans != null) { for (TLinkTypeBean linkTypeBean : closeDependsOnLinkBeans) { linkTypeIDs.add(linkTypeBean.getObjectID()); Integer direction = linkTypeBean.getLinkDirection(); if (direction == null || direction.intValue() != LINK_DIRECTION.RIGHT_TO_LEFT) { linkTypeBean.setLinkDirection(LINK_DIRECTION.RIGHT_TO_LEFT); LinkTypeBL.save(linkTypeBean); LOGGER.info( "'Closed depends on' link type " + linkTypeBean.getName() + "set to unidirectional inward"); } } } List<TWorkItemLinkBean> workItemLinks = ItemLinkBL.loadByLinkTypeAndDirection(linkTypeIDs, LINK_DIRECTION.LEFT_TO_RIGHT); if (workItemLinks != null) { LOGGER.info("Number of item links to reverse " + workItemLinks.size()); for (TWorkItemLinkBean workItemLinkBean : workItemLinks) { if (linkPredSuccAlso) { Integer predecessor = workItemLinkBean.getLinkPred(); Integer successor = workItemLinkBean.getLinkSucc(); workItemLinkBean.setLinkPred(successor); workItemLinkBean.setLinkSucc(predecessor); } workItemLinkBean.setLinkDirection(LINK_DIRECTION.RIGHT_TO_LEFT); ItemLinkBL.saveLink(workItemLinkBean); } } LOGGER.info("'MsProject' and 'Closed depends on' item links reversed"); }
/** * Validates the workItemLink before save * * @param workItemLinkBean * @param workItemLinkOriginal * @param workItemsLinksMap * @param predWorkItem * @param succWorkItem * @param personBean * @param locale * @return */ @Override public List<ErrorData> validateBeforeSave( TWorkItemLinkBean workItemLinkBean, TWorkItemLinkBean workItemLinkOriginal, SortedMap<Integer, TWorkItemLinkBean> workItemsLinksMap, TWorkItemBean predWorkItem, TWorkItemBean succWorkItem, TPersonBean personBean, Locale locale) { List<ErrorData> errorDataList = new LinkedList<ErrorData>(); Integer linkPred = workItemLinkBean.getLinkPred(); Integer linkSucc = workItemLinkBean.getLinkSucc(); if (linkPred == null || linkSucc == null) { // add link to a new item boolean linkedIsSuccessor = false; if (linkSucc != null) { linkedIsSuccessor = true; } else { if (linkPred != null) { linkedIsSuccessor = false; } } Integer newLinkedItemID = getLinkedItem(workItemLinkBean, linkedIsSuccessor); Integer newlinkType = workItemLinkBean.getLinkType(); Integer newLinkDirection = workItemLinkBean.getLinkDirection(); if (newLinkedItemID != null) { if (workItemsLinksMap != null) { for (TWorkItemLinkBean addedWorkItemLinkBean : workItemsLinksMap.values()) { Integer addedLinkedItemID = getLinkedItem(addedWorkItemLinkBean, linkedIsSuccessor); if (EqualUtils.equal(newLinkedItemID, addedLinkedItemID) && EqualUtils.equal(newlinkType, addedWorkItemLinkBean.getLinkType())) { // duplicate link for new item if (EqualUtils.equal(newLinkDirection, addedWorkItemLinkBean.getLinkDirection())) { errorDataList.add(new ErrorData("item.tabs.itemLink.err.linkExists")); } else { errorDataList.add(new ErrorData("item.tabs.itemLink.err.circularDependency")); } return errorDataList; } } } } // no duplicate link for new item return errorDataList; } Integer linkTypeID = workItemLinkBean.getLinkType(); Integer newLinkDirection = workItemLinkBean.getLinkDirection(); List<Integer> linkTypeIDs = new LinkedList<Integer>(); linkTypeIDs.add(linkTypeID); // link with the same linkTypeID can't be duplicated List<TWorkItemLinkBean> existingLinks = ItemLinkBL.loadLinksOfWorkItems( workItemLinkBean.getObjectID(), linkPred, linkSucc, linkTypeIDs); boolean linkExists = existingLinks != null && !existingLinks.isEmpty(); if (linkExists) { TWorkItemLinkBean existingLinkBean = existingLinks.get(0); if (EqualUtils.equal(newLinkDirection, existingLinkBean.getLinkDirection())) { errorDataList.add(new ErrorData("item.tabs.itemLink.err.linkExists")); } else { errorDataList.add(new ErrorData("item.tabs.itemLink.err.circularDependency")); } } List<TWorkItemLinkBean> reverseLinks = ItemLinkBL.loadLinksOfWorkItems( workItemLinkBean.getObjectID(), linkSucc, linkPred, linkTypeIDs); boolean reverseLinkExists = reverseLinks != null && !reverseLinks.isEmpty(); if (reverseLinkExists) { TWorkItemLinkBean existingLinkBean = reverseLinks.get(0); if (EqualUtils.equal(newLinkDirection, existingLinkBean.getLinkDirection())) { errorDataList.add(new ErrorData("item.tabs.itemLink.err.circularDependency")); } else { errorDataList.add(new ErrorData("item.tabs.itemLink.err.linkExists")); } } return errorDataList; }