public ErrorCollection validate() {
    validateComment();

    if (errorCollection.hasAnyErrors()) return errorCollection;

    for (FieldScreenRenderTab fieldScreenRenderTab :
        getFieldScreenRenderer().getFieldScreenRenderTabs()) {
      for (FieldScreenRenderLayoutItem fieldScreenRenderLayoutItem :
          fieldScreenRenderTab.getFieldScreenRenderLayoutItemsForProcessing()) {
        if (fieldScreenRenderLayoutItem.isShow(getIssue())) {
          OrderableField orderableField = fieldScreenRenderLayoutItem.getOrderableField();

          // JRA-16112 - This is a hack that is here because the resolution field is "special". You
          // can not
          // make the resolution field required and therefore by default the FieldLayoutItem for
          // resolution
          // returns false for the isRequired method. This is so that you can not make the
          // resolution field
          // required for issue creation. HOWEVER, whenever the resolution system field is shown it
          // is
          // required because the edit template does not provide a none option and indicates that it
          // is
          // required. THEREFORE, when the field is included on a transition screen we will do a
          // special
          // check to make the FieldLayoutItem claim it is required IF we run into the resolution
          // field.
          if (IssueFieldConstants.RESOLUTION.equals(orderableField.getId())) {
            fieldScreenRenderLayoutItem =
                new FieldScreenRenderLayoutItemImpl(
                    fieldScreenRenderLayoutItem.getFieldScreenLayoutItem(),
                    fieldScreenRenderLayoutItem.getFieldLayoutItem()) {
                  public boolean isRequired() {
                    return true;
                  }
                };
          }
          orderableField.validateParams(
              getOperationContext(),
              errorCollection,
              authenticationContext.getI18nHelper(),
              getIssue(),
              fieldScreenRenderLayoutItem);
        }
      }
    }

    return errorCollection;
  }
Esempio n. 2
0
 private void removeComment(IssueChangeHolder issueChangeHolder, Map commentParams) {
   final ApplicationUser user = authenticationContext.getUser();
   final ErrorCollection errorCollection = new SimpleErrorCollection();
   final long commentId = Long.valueOf((String) commentParams.get(PARAM_COMMENT_ID));
   Comment comment = commentService.getCommentById(user, commentId, errorCollection);
   commentService.delete(new JiraServiceContextImpl(user, errorCollection), comment, true);
   if (errorCollection.hasAnyErrors()) {
     log.error(
         "Error updating comment id '"
             + commentId
             + "' Error(s): '"
             + errorCollection.toString()
             + "'");
   } else {
     issueChangeHolder.setComment(comment);
   }
 }
  @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;
  }
  public BackupOverview getBackupOverview(
      final JiraServiceContext jiraServiceContext,
      final ProjectImportOptions projectImportOptions,
      final TaskProgressSink taskProgressSink) {
    Null.not("projectImportOptions", projectImportOptions);
    validateJiraServiceContext(jiraServiceContext);
    final ErrorCollection errorCollection = jiraServiceContext.getErrorCollection();
    final I18nHelper i18n = jiraServiceContext.getI18nBean();

    // The user must have the system administrator permission to perform a project import
    if (!userHasSysAdminPermission(jiraServiceContext.getUser())) {
      errorCollection.addErrorMessage(getText(i18n, "admin.errors.project.import.must.be.admin"));
      return null;
    }

    try {
      final String backupPath = projectImportOptions.getPathToBackupXml();
      log.info(
          "Project Import: Parsing the backup file '"
              + backupPath
              + "' to obtain a Backup Overview.");
      final BackupOverview backupOverview =
          projectImportManager.getBackupOverview(backupPath, taskProgressSink, i18n);
      log.debug("Project count for backup file = " + backupOverview.getProjects().size());
      log.debug(
          "Entity count for backup file = "
              + backupOverview.getBackupSystemInformation().getEntityCount());

      // Now do some further validation
      // BuildNumbers must be exactly the same.
      if (!getBuildNumber()
          .equalsIgnoreCase(backupOverview.getBackupSystemInformation().getBuildNumber())) {
        final String errorMessage =
            getText(
                i18n,
                "admin.errors.project.import.wrong.build.number",
                getBuildNumber(),
                backupOverview.getBackupSystemInformation().getBuildNumber());
        errorCollection.addErrorMessage(errorMessage);
        log.error(
            "This data appears to be from an older version of JIRA. Please upgrade the data and try again. The current version of JIRA is at build number '"
                + getBuildNumber()
                + "', but the supplied backup file was for build number '"
                + backupOverview.getBackupSystemInformation().getBuildNumber()
                + "'.");
      }

      // Only return the backupOverview if we do not have any errors, otherwise we want to fall
      // through and return null
      if (!errorCollection.hasAnyErrors()) {
        log.info(
            "Project Import: Backup Overview was successfully extracted from '"
                + backupPath
                + "'.");

        return backupOverview;
      }
    } catch (final IOException e) {
      log.error(
          "There was a problem accessing the file '"
              + projectImportOptions.getPathToBackupXml()
              + "' when performing a project import.",
          e);
      errorCollection.addErrorMessage(
          getText(
              i18n,
              "admin.errors.project.import.problem.reading.backup",
              projectImportOptions.getPathToBackupXml()));
    } catch (final SAXException e) {
      log.error(
          "There was a problem with the SAX parsing of the file '"
              + projectImportOptions.getPathToBackupXml()
              + "' when performing a project import.");
      errorCollection.addErrorMessage(
          getText(
              i18n,
              "admin.errors.project.import.sax.problem",
              projectImportOptions.getPathToBackupXml(),
              e.getMessage()));
    }
    return null;
  }