@Override public void update( Comment comment, Map<String, JSONObject> commentProperties, boolean dispatchEvent) { if (comment == null) { throw new IllegalArgumentException("Comment must not be null"); } if (comment.getId() == null) { throw new IllegalArgumentException("Comment ID must not be null"); } // create persistable generic value GenericValue commentGV; // We need an in-memory copy of the old comment so we can pass it through in the fired event and // to make sure // that some fields have changed. Comment originalComment = getCommentById(comment.getId()); if (originalComment == null) { throw new IllegalArgumentException( "Can not find a comment in the datastore with id: " + comment.getId()); } // Make sure that either the comment body or visibility data has changed, otherwise do not // update the datastore if (!areCommentsEquivalent(originalComment, comment)) { try { commentGV = delegator.findById(COMMENT_ENTITY, comment.getId()); populateGenericValueFromComment(comment, commentGV); commentGV.store(); } catch (GenericEntityException e) { throw new DataAccessException(e); } // Update the issue object IssueFactory issueFactory = ComponentAccessor.getComponentOfType(IssueFactory.class); GenericValue issueGV = comment.getIssue().getGenericValue(); MutableIssue mutableIssue = issueFactory.getIssue(issueGV); mutableIssue.setUpdated(UtilDateTime.nowTimestamp()); mutableIssue.store(); } // Update comment properties if (commentProperties != null) { setProperties(comment.getAuthorApplicationUser(), comment, commentProperties); } // Dispatch an event if required if (dispatchEvent) { dispatchIssueCommentEditedEvent( comment, MapBuilder.build( "eventsource", IssueEventSource.ACTION, EVENT_ORIGINAL_COMMENT_PARAMETER, originalComment)); } }
// JRA-19763 public void testDoTagNotLoggedInUser() throws Exception { final String scriptFilename = "transition-workflow.test.valid.action.name-action-differentuser.jelly"; runScript(scriptFilename); MutableIssue issue1 = ComponentAccessor.getIssueManager().getIssueObject("ABC-2"); assertEquals(user, issue1.getAssignee()); assertAuthor(secondaryUser, issue1); }
private void setDefaultSecurityLevel(MutableIssue issue) throws Exception { GenericValue project = issue.getProject(); if (project != null) { final Long levelId = getIssueSecurityLevelManager().getSchemeDefaultSecurityLevel(project); if (levelId != null) { issue.setSecurityLevel(getIssueSecurityLevelManager().getIssueSecurity(levelId)); } } }
// JRA-14164: ensure that when processing multiple issues with the one tag, that the assignee is // not overwritten accidentally public void testDoTagValidFilterId() throws Exception { final String scriptFilename = "transition-workflow.test.valid.filter.id-action.jelly"; runScript(scriptFilename); MutableIssue issue1 = ComponentAccessor.getIssueManager().getIssueObject("ABC-2"); MutableIssue issue2 = ComponentAccessor.getIssueManager().getIssueObject("ABC-3"); assertEquals(user, issue1.getAssignee()); assertEquals(secondaryUser, issue2.getAssignee()); }
// This is the positive test that shows the tag actually works public void testDoTagValidActionName() throws Exception { final String scriptFilename = "transition-workflow.test.valid.action.name-action.jelly"; try { runScript(scriptFilename); } catch (JellyServiceException e) { fail("JellyTagException should not have been thrown."); } MutableIssue issue1 = ComponentAccessor.getIssueManager().getIssueObject("ABC-2"); assertEquals(user, issue1.getAssignee()); assertAuthor(user, issue1); }
public GenericValue getProject() { if (project == null) { project = issue.getProject(); } return project; }
/** * Sets the value as a modified external field in the issue so that this field will be updated * along with all the other modified issue values. */ @Override public void updateIssue( FieldLayoutItem fieldLayoutItem, MutableIssue issue, Map fieldValueHolder) { if (fieldValueHolder.containsKey(getId())) { Map commentParams = (Map) fieldValueHolder.get(getId()); if (StringUtils.isNotBlank((String) commentParams.get(getId()))) { issue.setExternalFieldValue(getId(), fieldValueHolder.get(getId())); } } }
@Test public void shouldDeleteSubTaskWithLinks() throws Exception { setUpEmptyCustomFields(); IssueDeleteHelper tested = getIssueDeleteHelper(); setUpEmptyWatchers(); MutableIssue parentIssue = createNiceMock(MutableIssue.class); expect(parentIssue.getId()).andReturn(PARENT_ISSUE_ID); replay(parentIssue); expect(mockSubTaskManager.isSubTask(issueGenericValue)).andReturn(true); expect(mockSubTaskManager.getParentIssueId(issueGenericValue)).andReturn(PARENT_ISSUE_ID); mockSubTaskManager.resetSequences(parentIssue); expectLastCall(); expect(mockIssueManager.getIssueObject(PARENT_ISSUE_ID)).andReturn(parentIssue); replayMocks(); tested.deleteIssue((User) null, issue, EventDispatchOption.ISSUE_DELETED, true); makeAssertions(); assertTrue(capturedSendMailFlag); }
/** * This is called to back update the MutableIssue with the value object we previously stuffed into * the field values holder. * * <p> * * <p>This is called prior to the issue being stored on disk. * * @param fieldLayoutItem FieldLayoutItem in play. * @param issue MutableIssue in play. * @param fieldValueHolder Field Value Holder Map. */ public void updateIssue( FieldLayoutItem fieldLayoutItem, MutableIssue issue, Map fieldValueHolder) { IssueLinkingValue newValue = (IssueLinkingValue) getValueFromParams(fieldValueHolder); if (newValue == null) { return; // belts and braces. We don't ever expect this } if (isIssueLinkingEnabled()) { issue.setExternalFieldValue(getId(), null, newValue); } }
@Test public void testRemoveSubTasks() throws Exception { setUpIssue(); final AtomicInteger deleteIssueCalled = new AtomicInteger(0); DefaultIssueDeleteHelper tested = newMockDeleteIssueHelper(deleteIssueCalled); final MockGenericValue subTask1 = createIssueGV(2L, PROJECT_ID, "sub task 1", "TST-10", null, null); final MutableIssue subTaskIssue1 = createNiceMock(MutableIssue.class); expect(subTaskIssue1.getId()).andReturn(2L).anyTimes(); expect(subTaskIssue1.getGenericValue()).andReturn(subTask1).anyTimes(); final MockGenericValue subTask2 = createIssueGV(3L, PROJECT_ID, "sub task 2", "TST-11", null, null); final MutableIssue subTaskIssue2 = createNiceMock(MutableIssue.class); expect(subTaskIssue2.getId()).andReturn(3L).anyTimes(); expect(subTaskIssue2.getGenericValue()).andReturn(subTask2).anyTimes(); replay(subTaskIssue1, subTaskIssue2); expect(mockIssueManager.getIssueObject(2L)).andReturn(subTaskIssue1); expect(mockIssueManager.getIssueObject(3L)).andReturn(subTaskIssue2); final MockGenericValue mockLinkGV1 = new DbIndependentMockGenericValue( "IssueLink", ImmutableMap.<String, Object>of("destination", 2L)); final IssueLink issueLink1 = new IssueLink(mockLinkGV1, null, mockIssueManager); final MockGenericValue mockLinkGV2 = new DbIndependentMockGenericValue( "IssueLink", ImmutableMap.<String, Object>of("destination", 3L)); final IssueLink issueLink2 = new IssueLink(mockLinkGV2, null, mockIssueManager); expect(mockSubTaskManager.getSubTaskIssueLinks(ISSUE_ID)) .andReturn(ImmutableList.of(issueLink1, issueLink2)); replayMocks(); tested.removeSubTasks(null, issue, EventDispatchOption.ISSUE_DELETED, true); assertEquals(2, deleteIssueCalled.get()); verifyMocks(); }
@EventListener public void onIssueEvent(IssueEvent issueEvent) { if (!issueEvent.getEventTypeId().equals(EventType.ISSUE_CREATED_ID)) { return; } Issue issue = issueEvent.getIssue(); Collection<ProjectComponent> comps = issue.getComponentObjects(); if (comps == null || comps.size() < 2) { return; } Project project = issue.getProjectObject(); if (project == null || !isApplyPlugin(project.getId())) { return; } List<Issue> newIssues = new ArrayList<Issue>(); ProjectComponent gv = null; Iterator<ProjectComponent> iter = comps.iterator(); while (iter.hasNext()) { gv = iter.next(); MutableIssue nissue = ComponentManager.getInstance().getIssueFactory().getIssue(); // --> summary nissue.setSummary(String.format("[%s] %s", gv.getName(), issue.getSummary())); // --> project if (issue.getProjectObject() != null) { nissue.setProjectId(issue.getProjectObject().getId()); } // --> issue type if (issue.getIssueTypeObject() != null) { nissue.setIssueTypeId(issue.getIssueTypeObject().getId()); } // --> components Collection<ProjectComponent> nComps = new LinkedList<ProjectComponent>(); nComps.add(gv); nissue.setComponentObjects(nComps); // --> assignee String compLead = gv.getLead(); nissue.setAssigneeId(compLead); // --> reporter nissue.setReporter(issueEvent.getUser()); // --> priority nissue.setPriorityObject(issue.getPriorityObject()); // --> description nissue.setDescription(issue.getDescription()); // --> env nissue.setEnvironment(issue.getEnvironment()); // --> due date nissue.setDueDate(issue.getDueDate()); // --> estimate nissue.setEstimate(issue.getEstimate()); // --> labels nissue.setLabels(issue.getLabels()); nissue.setAffectedVersions(issue.getAffectedVersions()); nissue.setWorkflowId(issue.getWorkflowId()); nissue.setParentId(issue.getParentId()); // --> status if (issue.getStatusObject() != null) { nissue.setStatusId(issue.getStatusObject().getId()); } // --> resolution if (issue.getResolutionObject() != null) { nissue.setResolutionId(issue.getResolutionObject().getId()); } nissue.setFixVersions(issue.getFixVersions()); nissue.setResolutionDate(issue.getResolutionDate()); nissue.setTimeSpent(issue.getTimeSpent()); nissue.setVotes(issue.getVotes()); nissue.setCreated(issue.getCreated()); nissue.setSecurityLevelId(issue.getSecurityLevelId()); nissue.setOriginalEstimate(issue.getOriginalEstimate()); List<CustomField> cfs = ComponentManager.getInstance().getCustomFieldManager().getCustomFieldObjects(issue); if (cfs != null) { for (CustomField cf : cfs) { Object cfVal = issue.getCustomFieldValue(cf); if (cfVal != null) { nissue.setCustomFieldValue(cf, cfVal); } } } // --> create issue try { Issue newIssueObj = ComponentManager.getInstance() .getIssueManager() .createIssueObject(issueEvent.getUser(), nissue); newIssues.add(newIssueObj); } catch (CreateException crex) { log.error("IssueClonerByComponents::onIssueEvent - Cannot create dependent issues", crex); } } Collection<Attachment> atts = issue.getAttachments(); if (atts != null) { AttachmentManager am = ComponentManager.getInstance().getAttachmentManager(); for (Attachment att : atts) { File attFile = AttachmentUtils.getAttachmentFile(att); String filename = att.getFilename(); String contentType = att.getMimetype(); for (Issue nissue : newIssues) { File newFile = new File(attFile.getAbsolutePath() + nissue.getKey()); try { FileUtils.copyFile(attFile, newFile); am.createAttachment(newFile, filename, contentType, issueEvent.getUser(), nissue); } catch (Exception ex) { log.error("IssueClonerByComponents::onIssueEvent - Cannot copy attachment", ex); } } } } IssueLinkTypeManager issueLinkTypeManager = ComponentManager.getComponentInstanceOfType(IssueLinkTypeManager.class); Collection<IssueLinkType> types = issueLinkTypeManager.getIssueLinkTypesByName(LINK_TYPE); if (types == null || types.isEmpty()) { return; } IssueLinkType ilt = types.iterator().next(); if (ilt != null) { IssueLinkManager ilm = ComponentManager.getInstance().getIssueLinkManager(); for (Issue nissue : newIssues) { try { ilm.createIssueLink( issue.getId(), nissue.getId(), ilt.getId(), null, issueEvent.getUser()); } catch (CreateException crex) { log.error("IssueClonerByComponents::onIssueEvent - Cannot create link", crex); } } } }
@Override public boolean handleMessage(Message message, MessageHandlerContext context) throws MessagingException { log.debug("CreateIssueHandler.handleMessage"); if (!canHandleMessage(message, context.getMonitor())) { return deleteEmail; } try { // get either the sender of the message, or the default reporter User reporter = getReporter(message, context); // no reporter - so reject the message if (reporter == null) { final String error = getI18nBean().getText("admin.mail.no.default.reporter"); context.getMonitor().warning(error); context.getMonitor().messageRejected(message, error); return false; } final Project project = getProject(message); log.debug("Project = " + project); if (project == null) { final String text = getI18nBean().getText("admin.mail.no.project.configured"); context.getMonitor().warning(text); context.getMonitor().messageRejected(message, text); return false; } // Check that the license is valid before allowing issues to be created // This checks for: evaluation licenses expired, user limit licenses where limit has been // exceeded ErrorCollection errorCollection = new SimpleErrorCollection(); // Note: want English locale here for logging purposes I18nHelper i18nHelper = new I18nBean(Locale.ENGLISH); getIssueCreationHelperBean().validateLicense(errorCollection, i18nHelper); if (errorCollection.hasAnyErrors()) { context .getMonitor() .warning( getI18nBean() .getText( "admin.mail.bad.license", errorCollection.getErrorMessages().toString())); return false; } // If user does not have create permissions, there's no point proceeding. Error out here to // avoid a stack // trace blow up from the WorkflowManager later on. if (!getPermissionManager().hasPermission(Permissions.CREATE_ISSUE, project, reporter, true) && reporter.getDirectoryId() != -1) { final String error = getI18nBean().getText("admin.mail.no.create.permission", reporter.getName()); context.getMonitor().warning(error); context.getMonitor().messageRejected(message, error); return false; } log.debug("Issue Type Key = = " + issueType); if (!hasValidIssueType()) { context.getMonitor().warning(getI18nBean().getText("admin.mail.invalid.issue.type")); return false; } String summary = message.getSubject(); if (!TextUtils.stringSet(summary)) { context.getMonitor().error(getI18nBean().getText("admin.mail.no.subject")); return false; } if (summary.length() > SummarySystemField.MAX_LEN.intValue()) { context.getMonitor().info("Truncating summary field because it is too long: " + summary); summary = summary.substring(0, SummarySystemField.MAX_LEN.intValue() - 3) + "..."; } // JRA-7646 - check if priority/description is hidden - if so, do not set String priority = null; String description = null; if (!getFieldVisibilityManager() .isFieldHiddenInAllSchemes( project.getId(), IssueFieldConstants.PRIORITY, Collections.singletonList(issueType))) { priority = getPriority(message); } if (!getFieldVisibilityManager() .isFieldHiddenInAllSchemes( project.getId(), IssueFieldConstants.DESCRIPTION, Collections.singletonList(issueType))) { description = getDescription(reporter, message); } MutableIssue issueObject = getIssueFactory().getIssue(); issueObject.setProjectObject(project); issueObject.setSummary(summary); issueObject.setDescription(description); issueObject.setIssueTypeId(issueType); issueObject.setReporter(reporter); // if no valid assignee found, attempt to assign to default assignee User assignee = null; if (ccAssignee) { assignee = getFirstValidAssignee(message.getAllRecipients(), project); } if (assignee == null) { assignee = getAssigneeResolver().getDefaultAssignee(issueObject, Collections.EMPTY_MAP); } if (assignee != null) { issueObject.setAssignee(assignee); } issueObject.setPriorityId(priority); // Ensure issue level security is correct setDefaultSecurityLevel(issueObject); /* * + FIXME -- set cf defaults @todo + */ // set default custom field values // CustomFieldValuesHolder cfvh = new CustomFieldValuesHolder(issueType, project.getId()); // fields.put("customFields", CustomFieldUtils.getCustomFieldValues(cfvh.getCustomFields())); Map<String, Object> fields = new HashMap<String, Object>(); fields.put("issue", issueObject); // TODO: How is this supposed to work? There is no issue created yet; ID = null. // wseliga note: Ineed I think that such call does not make sense - it will be always null MutableIssue originalIssue = getIssueManager().getIssueObject(issueObject.getId()); // Give the CustomFields a chance to set their default values JRA-11762 List<CustomField> customFieldObjects = ComponentAccessor.getCustomFieldManager().getCustomFieldObjects(issueObject); for (CustomField customField : customFieldObjects) { issueObject.setCustomFieldValue(customField, customField.getDefaultValue(issueObject)); } fields.put(WorkflowFunctionUtils.ORIGINAL_ISSUE_KEY, originalIssue); final Issue issue = context.createIssue(reporter, issueObject); if (issue != null) { // Add Cc'ed users as watchers if params set - JRA-9983 if (ccWatcher) { addCcWatchersToIssue(message, issue, reporter, context, context.getMonitor()); } // Record the message id of this e-mail message so we can track replies to this message // and associate them with this issue recordMessageId( MailThreadManager.ISSUE_CREATED_FROM_EMAIL, message, issue.getId(), context); } // TODO: if this throws an error, then the issue is already created, but the email not deleted // - we will keep "handling" this email over and over :( createAttachmentsForMessage(message, issue, context); return true; } catch (Exception e) { context.getMonitor().warning(getI18nBean().getText("admin.mail.unable.to.create.issue"), e); } // something went wrong - don't delete the message return false; }
private void setUpIssue() { expect(issue.getId()).andReturn(ISSUE_ID).anyTimes(); expect(issue.getGenericValue()).andReturn(issueGenericValue).anyTimes(); }
@Override public Map<String, Object> getVelocityParameters( Issue issue, CustomField field, FieldLayoutItem fieldLayoutItem) { Map<String, Object> params = super.getVelocityParameters(issue, field, fieldLayoutItem); params.put("i18n", getI18nBean()); params.put("baseUrl", applicationProperties.getBaseUrl()); Long prId; if (field.isAllProjects()) { prId = Consts.PROJECT_ID_FOR_GLOBAL_CF; } else { if (issue == null) { return params; } prId = issue.getProjectObject().getId(); } String jqlData = qfMgr.getQueryFieldData(field.getIdAsLong(), prId); boolean addNull = qfMgr.getAddNull(field.getIdAsLong(), prId); boolean isAutocompleteView = qfMgr.isAutocompleteView(field.getIdAsLong(), prId); List<String> options = qfMgr.getLinkeFieldsOptions(field.getIdAsLong(), prId); params.put("isAutocompleteView", isAutocompleteView); params.put("prId", prId.toString()); String cfValue = field.getValueFromIssue(issue); if (Utils.isValidStr(cfValue)) { MutableIssue mi = issueMgr.getIssueObject(cfValue); if (mi != null && Utils.isValidStr(mi.getSummary())) { StringBuilder sb = new StringBuilder(); if (options.contains("status")) { sb.append(getI18nBean().getText("queryfields.opt.status")) .append(": ") .append(mi.getStatusObject().getName()); } if (options.contains("assignee") && mi.getAssigneeUser() != null) { if (sb.length() > 0) { sb.append(", "); } User aUser = mi.getAssigneeUser(); String encodedUser; try { encodedUser = URLEncoder.encode(aUser.getName(), "UTF-8"); } catch (UnsupportedEncodingException e) { // --> impossible encodedUser = aUser.getName(); } sb.append(getI18nBean().getText("queryfields.opt.assignee")) .append(": ") .append("<a class='user-hover' rel='") .append(aUser.getName()) .append("' id='issue_summary_assignee_'") .append(aUser.getName()) .append("' href='/secure/ViewProfile.jspa?name='") .append(encodedUser) .append("'>") .append(aUser.getDisplayName()) .append("</a>"); } if (options.contains("priority") && mi.getPriorityObject() != null) { if (sb.length() > 0) { sb.append(", "); } sb.append(getI18nBean().getText("queryfields.opt.priority")) .append(": ") .append(mi.getPriorityObject().getName()); } if (options.contains("due") && mi.getDueDate() != null) { if (sb.length() > 0) { sb.append(", "); } sb.append(getI18nBean().getText("queryfields.opt.due")) .append(": ") .append( ComponentAccessor.getJiraAuthenticationContext() .getOutlookDate() .format(mi.getDueDate())); } if (sb.length() > 0) { sb.insert(0, " ("); sb.append(")"); } IssueData issueData; if (options.contains("justDesc")) { String descr = mi.getDescription(); if (Utils.isValidStr(descr)) { issueData = new IssueData(descr, sb.toString()); } else { issueData = new IssueData(mi.getSummary(), sb.toString()); } } else if (options.contains("key")) { issueData = new IssueData(mi.getKey().concat(":").concat(mi.getSummary()), sb.toString()); } else { issueData = new IssueData(mi.getSummary(), sb.toString()); } params.put("fullValue", issueData); } } if (!Utils.isValidStr(jqlData)) { params.put("jqlNotSet", Boolean.TRUE); return params; } params.put("jqlNotSet", Boolean.FALSE); params.put("options", options); if (options.contains("editKey")) { params.put("hasKey", Boolean.TRUE); } User user = ComponentManager.getInstance().getJiraAuthenticationContext().getLoggedInUser(); SearchService.ParseResult parseResult = searchService.parseQuery(user, jqlData); if (parseResult.isValid()) { params.put("jqlNotValid", Boolean.FALSE); Query query = parseResult.getQuery(); try { Map<String, String> cfVals = new LinkedHashMap<String, String>(); SearchResults results = searchService.search(user, query, PagerFilter.getUnlimitedFilter()); List<Issue> issues = results.getIssues(); for (Issue i : issues) { String summary; if (options.contains("justDesc")) { String descr = i.getDescription(); if (Utils.isValidStr(descr)) { summary = descr; } else { summary = i.getSummary(); } } else if (options.contains("editKey")) { summary = i.getKey().concat(":").concat(i.getSummary()); } else { summary = i.getSummary(); } cfVals.put(i.getKey(), summary); } if (addNull) { cfVals.put("Empty", Consts.EMPTY_VALUE); } String selected = Consts.EMPTY_VALUE; String value = (String) issue.getCustomFieldValue(field); for (Map.Entry<String, String> cf : cfVals.entrySet()) { if (value != null && cf.getKey().equals(value)) { selected = value; break; } } if (isAutocompleteView) { Issue selectedIssue = issueMgr.getIssueObject(selected); if (selectedIssue != null) { params.put("selIssue", selectedIssue); } } else { if (selected.equals("")) { String defaultValue = (String) field.getDefaultValue(issue); if (defaultValue != null && defaultValue.length() > 0 && cfVals.keySet().contains(defaultValue)) { selected = defaultValue; } } if (cfVals != null && !cfVals.isEmpty() && selected.equals("")) { selected = cfVals.keySet().iterator().next(); } } params.put("selected", selected); params.put("isError", Boolean.FALSE); params.put("cfVals", cfVals); } catch (SearchException e) { params.put("isError", Boolean.TRUE); } } else { params.put("jqlNotValid", Boolean.TRUE); return params; } return params; }
public Comment create( Issue issue, ApplicationUser author, ApplicationUser updateAuthor, String body, String groupLevel, Long roleLevelId, Date created, Date updated, Map<String, JSONObject> commentProperties, boolean dispatchEvent, boolean modifyIssueUpdateDate) { if (textFieldCharacterLengthValidator.isTextTooLong(body)) { final long maximumNumberOfCharacters = textFieldCharacterLengthValidator.getMaximumNumberOfCharacters(); String errorMessage = getText("field.error.text.toolong", String.valueOf(maximumNumberOfCharacters)); throw new IllegalArgumentException(errorMessage); } // create new instance of comment CommentImpl comment = new CommentImpl( projectRoleManager, author, updateAuthor, body, groupLevel, roleLevelId, created, updated, issue); // create persistable generic value Map<String, Object> fields = new HashMap<String, Object>(); fields.put("issue", issue.getId()); fields.put("type", ActionConstants.TYPE_COMMENT); ApplicationUser commentAuthor = comment.getAuthorApplicationUser(); ApplicationUser commentUpdateAuthor = comment.getUpdateAuthorApplicationUser(); fields.put("author", commentAuthor == null ? null : commentAuthor.getKey()); fields.put("updateauthor", commentUpdateAuthor == null ? null : commentUpdateAuthor.getKey()); fields.put("body", comment.getBody()); fields.put("level", comment.getGroupLevel()); fields.put("rolelevel", comment.getRoleLevelId()); fields.put("created", new Timestamp(comment.getCreated().getTime())); fields.put("updated", new Timestamp(comment.getUpdated().getTime())); GenericValue commentGV = EntityUtils.createValue(COMMENT_ENTITY, fields); // set the ID on comment object comment.setId(commentGV.getLong(COMMENT_ID)); // Update the issue object if required if (modifyIssueUpdateDate) { // JRA-36334: Only modify the Issue updated date if it would move forward - we don't want it // to go back in time if (comment.getUpdated().getTime() > issue.getUpdated().getTime()) { IssueFactory issueFactory = ComponentAccessor.getComponentOfType(IssueFactory.class); MutableIssue mutableIssue = issueFactory.getIssue(issue.getGenericValue()); // JRA-15723: Use the comments updated time for the updated time of the issue. This allows // users to // import old comments without setting the updated time on the issue to now, but to the date // of the old comments. mutableIssue.setUpdated(new Timestamp(comment.getUpdated().getTime())); issue.store(); } } if (commentProperties != null) { setProperties(author, comment, commentProperties); } // Dispatch an event if required if (dispatchEvent) { Map<String, Object> params = new HashMap<String, Object>(); params.put("eventsource", IssueEventSource.ACTION); dispatchIssueCommentAddedEvent(comment, params); } return comment; }
protected void setUp() throws Exception { super.setUp(); user = createMockUser("logged-in-user"); secondaryUser = createMockUser("testuser"); g = createMockGroup("jira-user"); addUserToGroup(user, g); addUserToGroup(secondaryUser, g); JiraTestUtil.loginUser(user); ComponentAccessor.getApplicationProperties() .setOption(APKeys.JIRA_OPTION_ALLOWUNASSIGNED, true); ManagerFactory.getGlobalPermissionManager().addPermission(Permissions.ADMINISTER, null); SchemeManager permManager = ManagerFactory.getPermissionSchemeManager(); GenericValue scheme = permManager.createDefaultScheme(); PermissionManager pm = ManagerFactory.getPermissionManager(); pm.addPermission(Permissions.CREATE_ISSUE, scheme, "jira-user", "group"); pm.addPermission(Permissions.BROWSE, scheme, "jira-user", "group"); pm.addPermission(Permissions.RESOLVE_ISSUE, scheme, "jira-user", "group"); pm.addPermission(Permissions.ASSIGN_ISSUE, scheme, "jira-user", "group"); pm.addPermission(Permissions.CLOSE_ISSUE, scheme, "jira-user", "group"); pm.addPermission(Permissions.WORK_ISSUE, scheme, "jira-user", "group"); pm.addPermission(Permissions.ASSIGNABLE_USER, scheme, "jira-user", "group"); // Build IssueConstants UpgradeTask_Build11 upgradeTask_build11 = new UpgradeTask_Build11(ComponentAccessor.getConstantsManager()); upgradeTask_build11.doUpgrade(false); // Build the default statuses UpgradeTask_Build27 upgradeTask_build27 = new UpgradeTask_Build27(); upgradeTask_build27.doUpgrade(false); // Create field screens UpgradeTask upgradeTask = (UpgradeTask) JiraUtils.loadComponent(UpgradeTask_Build83.class); upgradeTask.doUpgrade(false); // Build default IssueTypeScheme UpgradeTask upgradeTask101 = (UpgradeTask) JiraUtils.loadComponent(UpgradeTask_Build101.class); upgradeTask101.doUpgrade(false); JiraAuthenticationContext authenticationContext = ComponentAccessor.getJiraAuthenticationContext(); // Log in user authenticationContext.setLoggedInUser(user); GenericValue project = UtilsForTests.getTestEntity( "Project", EasyMap.build( "key", "ABC", "name", "A Project", "lead", user.getName(), "counter", new Long(1))); ComponentAccessor.getIssueTypeScreenSchemeManager().associateWithDefaultScheme(project); ManagerFactory.getProjectManager().refresh(); final PermissionSchemeManager permissionSchemeManager = ManagerFactory.getPermissionSchemeManager(); permissionSchemeManager.addSchemeToProject(project, scheme); // Create a REAL issue (with valid transitions and everything) with key ABC-2 final MutableIssue issue1 = ComponentAccessor.getIssueFactory().getIssue(); issue1.setProject(project); issue1.setAssignee(user); GenericValue issueTypeGV = ComponentAccessor.getConstantsManager().getIssueType("1"); issue1.setIssueType(issueTypeGV); ComponentAccessor.getIssueManager().createIssue(user, issue1); // Create a second REAL issue with key ABC-3 final MutableIssue issue2 = ComponentAccessor.getIssueFactory().getIssue(); issue2.setProject(project); issue2.setAssignee(secondaryUser); issue2.setIssueType(issueTypeGV); ComponentAccessor.getIssueManager().createIssue(secondaryUser, issue2); // Create a SearchRequest to return the two issues sr = UtilsForTests.getTestEntity( "SearchRequest", EasyMap.build( "id", new Long(10241), "name", "test", "author", "logged-in-user", "user", "logged-in-user", "group", "jira-user", "project", project.get("id"), "request", "project = " + project.get("id"))); }
public void updateIssue( FieldLayoutItem fieldLayoutItem, MutableIssue issue, Map fieldValueHolder) { issue.setSummary((String) getValueFromParams(fieldValueHolder)); }
/** * Initialises this MultiBulkMoveBean given a list of issues. * * <p>If this MultiBulkMoveBean links a BulkEditBean with parent issues to BulkEditBeans with * subtasks, then include the parent BulkEditBean in the parentBulkEditBean parameter. Otherwise * you can pass null. * * @param issues Issues for this MultiBulkMoveBean. * @param parentBulkEditBean If this MultiBulkMoveBean represents subtasks, then this is the * BulkEditBean that contains the parents of the subtasks, otherwise null. */ public void initFromIssues(List issues, BulkEditBean parentBulkEditBean) { // Ensure that the order is kept issuesInContext = (ListOrderedMap) ListOrderedMap.decorate(new MultiHashMap()); regularIssues = new ListOrderedMap(); subTaskIssues = new ArrayList<Issue>(); // First pass stores att the for (final Object issue2 : issues) { MutableIssue issue = (MutableIssue) issue2; if (!issue.isSubTask()) { regularIssues.put(issue.getId(), issue); } else { subTaskIssues.add(issue); } } // Split it up by context, also check special rule that you can't move sub tasks & its parent // all in the same go for (final Object issue1 : issues) { MutableIssue issue = (MutableIssue) issue1; // NOTE: we only do this for the bulk move operation, this is likely the correct behavior for // the // bulk move operation but I am certain that it is not correct for the bulk migrate operation // JRA-10244. // In bulk move the wizard will prompt the user with subtask information once it has collected // the project // information about the parent issues, this is not need in the the issue type scheme // migration since you // will never be changing the project // TODO: Why test for operation name? if (BulkMigrateOperation.OPERATION_NAME.equals(operationName) && issue.isSubTask() && regularIssues.containsKey(issue.getParentId())) { log.info( "Sub issue: " + issue.getKey() + " : discarded since parent was also present in the bulk move"); subTasksDiscarded++; } else { issuesInContext.put( new IssueContextImpl(issue.getProjectObject(), issue.getIssueTypeObject()), issue); } } // Set the bulk edit bean.. sort the keys by project bulkEditBeans = new ListOrderedMap(); List keys = new ArrayList(issuesInContext.keySet()); Collections.sort(keys); for (final Object key : keys) { IssueContext context = (IssueContext) key; Collection issuesForContext = (Collection) issuesInContext.get(context); BulkEditBean bulkEditBean = new BulkEditBeanImpl(issueManager); bulkEditBean.initSelectedIssues(issuesForContext); bulkEditBean.setOperationName(operationName); bulkEditBean.setTargetProject(context.getProjectObject()); bulkEditBean.setTargetIssueTypeId( context.getIssueTypeObject() != null ? context.getIssueTypeObject().getId() : null); // Set the Parent BulkEditBean - used by subtask BulkEditBean's to get to the new version of // the subtask's parents. bulkEditBean.setParentBulkEditBean(parentBulkEditBean); bulkEditBeans.put(context, bulkEditBean); } }
public void removeValueFromIssueObject(MutableIssue issue) { issue.setSummary(null); }