public IssueLink getIssueLink(Long sourceId, Long destinationId, Long issueLinkTypeId) { List<IssueLink> links = getIssueLinks(FieldMap.build("source", sourceId)); for (IssueLink link : links) { if (link.getDestinationId().equals(destinationId) && link.getLinkTypeId().equals(issueLinkTypeId)) { return link; } } return null; }
/** * Retrieves ids of all sub-task issues in the system. */ @Override public Collection<Long> getAllSubTaskIssueIds() { // Get the sub-task issue link type final IssueLinkType subTaskIssueLinkType = getSubTaskIssueLinkType(); // Find all sub-task links final Collection<IssueLink> issueLinks = issueLinkManager.getIssueLinks(subTaskIssueLinkType.getId()); // Theorietically we should be able to return the count of issue links (as a sub-task should cannot be a sub-task of // more than one issue). However if this ever changes, this will likely cause a bug. Hence, this code is in place. // As it is not expected to be executed often, the safe approach is taken. Set<Long> subTaskIssueIds = new HashSet<Long>(); for (final IssueLink issueLink : issueLinks) { subTaskIssueIds.add(issueLink.getDestinationId()); } return subTaskIssueIds; }
public void addIndex(Document doc, Issue issue) { // This accesses the link manager directly (instead of issue.getSubtasks()) so that we only pull out the ids. // This has a performance improvement final List<IssueLink> outwardLinks = issueLinkManager.getOutwardLinks(issue.getId()); for (final IssueLink outwardLink : outwardLinks) { if (outwardLink.getIssueLinkType().isSubTaskLinkType()) { doc.add(new Field(getDocumentFieldId(), outwardLink.getDestinationId().toString(), Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)); } } } }
private void addFieldsToDoc(Document doc, Collection<IssueLink> issueLinks, Direction direction) { for (IssueLink issueLink : issueLinks) { Long linkTypeId = issueLink.getLinkTypeId(); doc.add(new Field(getDocumentFieldId(), createValue(linkTypeId), NO, NOT_ANALYZED)); doc.add(new Field(getDocumentFieldId(), createValue(linkTypeId, direction), NO, NOT_ANALYZED)); Long otherIssue = direction == Direction.OUT ? issueLink.getDestinationId() : issueLink.getSourceId(); // IN links have OTHER issue at SOURCE, OUT links have OTHER issue at DEST doc.add(new Field(getDocumentFieldId(), createValue(linkTypeId, direction, otherIssue), NO, NOT_ANALYZED)); } } }
private void removeLinkFromParent(final MutableIssue issue, final ApplicationUser applicationUser) { if (issue.getParentId() != null) { List<IssueLink> parentLinks = issueLinkManager.getOutwardLinks(issue.getParentId()); parentLinks.stream().filter(link -> link.getIssueLinkType().isSubTaskLinkType() && link.getDestinationId().equals(issue.getId())).forEach( link -> issueLinkManager.removeIssueLink(link, applicationUser) ); } }
inwardLinkCache.remove(issueLink.getDestinationId());
public void changeIssueLinkType(IssueLink issueLink, IssueLinkType swapLinkType, ApplicationUser remoteUser) { final IssueLinkType oldIssueLinkType = issueLink.getIssueLinkType(); if (!oldIssueLinkType.isSystemLinkType() && swapLinkType.isSystemLinkType()) { log.warn("Changing non-system link type to a system link type."); } else if (oldIssueLinkType.isSystemLinkType() && !swapLinkType.isSystemLinkType()) { log.warn("Changing system link type to a non-system link type."); } updateIssueLinkType(issueLink, swapLinkType); outwardLinkCache.remove(issueLink.getSourceId()); inwardLinkCache.remove(issueLink.getDestinationId()); // If the link we are swapping from is not a system link type, it means its creation should have // been recorded in 'change history', so we should update change history here. if (!oldIssueLinkType.isSystemLinkType()) { createRemoveIssueLinkChangeItems(issueLink, oldIssueLinkType, remoteUser); createCreateIssueLinkChangeItems(issueLink, swapLinkType, remoteUser); } }
@Override public FieldMap fieldMapFrom(final IssueLink value) { return new FieldMap("id", value.getId()) .add("linktype", value.getLinkTypeId()) .add("source", value.getSourceId()) .add("destination", value.getDestinationId()) .add("sequence", value.getSequence()); } }
Long workingIssueId = isCopyingInwardLinks ? issueLink.getSourceId() : issueLink.getDestinationId();
inwardLinkCache.remove(issueLink.getDestinationId());
@Override public SingleIssueLinkResult getIssueLink(Long issueLinkId, ApplicationUser user) { Assertions.notNull("issueLinkId", issueLinkId); IssueLink issueLink = issueLinkManager.getIssueLink(issueLinkId); if (issueLink == null) { SimpleErrorCollection simpleErrorCollection = new SimpleErrorCollection(); simpleErrorCollection.addErrorMessage(beanFactory.getInstance(user).getText("rest.issue.link.not.found", issueLinkId.toString())); return new SingleIssueLinkResult(simpleErrorCollection, null); } MutableIssue sourceIssue = issueManager.getIssueObject(issueLink.getSourceId()); ErrorCollection sourceIssueErrors = validateIssuePermission(user, sourceIssue, Permissions.BROWSE); MutableIssue destinationIssue = issueManager.getIssueObject(issueLink.getDestinationId()); ErrorCollection destinationIssueErrors = validateIssuePermission(user, destinationIssue, Permissions.BROWSE); if (sourceIssueErrors.hasAnyErrors() || destinationIssueErrors.hasAnyErrors()) { sourceIssueErrors.getErrors().putAll(destinationIssueErrors.getErrors()); sourceIssueErrors.getErrorMessages().addAll(destinationIssueErrors.getErrorMessages()); return new SingleIssueLinkResult(sourceIssueErrors, null); } return new SingleIssueLinkResult(new SimpleErrorCollection(), issueLink); }
IssueService.IssueResult destinationIssueResult = issueService.getIssue(authContext.getUser(), issueLink.getDestinationId()); if (!sourceIssueResult.isValid() || !destinationIssueResult.isValid())
IssueService.IssueResult destinationIssueResult = issueService.getIssue(authContext.getUser(), issueLink.getDestinationId()); if (!sourceIssueResult.isValid() || !destinationIssueResult.isValid())
public void resetSequences(final List<IssueLink> issueLinks) { dbConnectionManager.execute(dbConnection -> { dbConnection.setAutoCommit(false); long i = 0; for (final IssueLink issueLink : issueLinks) { dbConnection.update(QIssueLink.ISSUE_LINK) .set(QIssueLink.ISSUE_LINK.sequence, i) .where(QIssueLink.ISSUE_LINK.id.eq(issueLink.getId())) .execute(); i++; } dbConnection.commit(); // Make sure we don't clear the cache until after the DB is committed, else we get a race condition // whereby another thread can put stale values back into the cache. for (IssueLink issueLink : issueLinks) { outwardLinkCache.remove(issueLink.getSourceId()); inwardLinkCache.remove(issueLink.getDestinationId()); } }); }