/**
  * validate the field value
  *
  * @param operationContext OperationContext
  * @param errorCollectionToAddTo ErrorCollection
  * @param i18n I18nHelper
  * @param issue Issue
  * @param fieldScreenRenderLayoutItem FieldScreenRenderLayoutItem
  */
 public void validateParams(
     OperationContext operationContext,
     ErrorCollection errorCollectionToAddTo,
     I18nHelper i18n,
     Issue issue,
     FieldScreenRenderLayoutItem fieldScreenRenderLayoutItem) {
   Map fieldValuesHolder = operationContext.getFieldValuesHolder();
   String summary = (String) getValueFromParams(fieldValuesHolder);
   if (summary == null) {
     errorCollectionToAddTo.addError(getId(), i18n.getText("createissue.error.specify.a.summary"));
     return;
   }
   // JRADEV-1867 User can create summary with "  "
   summary = summary.trim();
   if (!TextUtils.stringSet(summary)) {
     errorCollectionToAddTo.addError(getId(), i18n.getText("createissue.error.specify.a.summary"));
   }
   if (summary.contains("\n") || summary.contains("\r")) {
     errorCollectionToAddTo.addError(getId(), i18n.getText("createissue.invalidsummary.newlines"));
   }
   if (summary.length() > MAX_LEN) {
     errorCollectionToAddTo.addError(
         getId(), i18n.getText("createissue.error.summary.less.than", MAX_LEN.toString()));
   }
 }
  public void validateDoMapping(
      final JiraServiceContext jiraServiceContext,
      final ProjectImportOptions projectImportOptions,
      final BackupProject backupProject,
      final BackupSystemInformation backupSystemInformation) {
    Null.not("projectImportOptions", projectImportOptions);
    Null.not("backupSystemInformation", backupSystemInformation);
    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"));
    }

    // Check the pathToBackupXml is valid
    if (StringUtils.isEmpty(projectImportOptions.getPathToBackupXml())) {
      errorCollection.addErrorMessage(
          getText(i18n, "admin.errors.project.import.provide.backup.path"));
    } else if (!pathExists(projectImportOptions.getPathToBackupXml(), true)) {
      errorCollection.addErrorMessage(
          getText(i18n, "admin.errors.project.import.invalid.backup.path"));
    }

    // Check that we are being provided a backup project
    if (backupProject == null) {
      errorCollection.addErrorMessage(
          getText(i18n, "admin.errors.project.import.no.backup.project"));
    }
  }
  private void editComment(
      IssueChangeHolder issueChangeHolder, Map<String, Object> commentParams, String body) {
    final ApplicationUser user = authenticationContext.getUser();
    final long commentId = Long.valueOf((String) commentParams.get(PARAM_COMMENT_ID));
    final ErrorCollection errorCollection = new SimpleErrorCollection();

    MutableComment mutableComment =
        commentService.getMutableComment(user, commentId, errorCollection);
    CommentParametersBuilder builder = CommentParameters.builder(mutableComment);

    if (StringUtils.isNotBlank(body)) {
      builder.body(body);
    }
    String groupLevel = (String) commentParams.get(PARAM_GROUP_LEVEL);
    String roleLevelIdStr = (String) commentParams.get(PARAM_ROLE_LEVEL);
    builder.visibility(Visibilities.fromGroupAndStrRoleId(groupLevel, roleLevelIdStr));
    builder.commentProperties(getCommentPropertiesQuietly(commentParams));

    final CommentService.CommentUpdateValidationResult validationResult =
        commentService.validateCommentUpdate(user, commentId, builder.build());
    if (validationResult.isValid()) {
      commentService.update(user, validationResult, true);
      issueChangeHolder.setComment(mutableComment);
    } else {
      log.error(
          "Error updating comment id '"
              + commentId
              + "' Error(s): '"
              + errorCollection.toString()
              + "'");
    }
  }
 private void mapErrors(final ErrorCollection errorCollection) {
   // Convert field errors to error messages so that they will appear on the page
   // Hide the field name (key), as this will mean nothing to users
   for (final Map.Entry<String, String> entry : errorCollection.getErrors().entrySet()) {
     if ("globalId".equals(entry.getKey())) {
       // Give a more meaningful message when a duplicate link exists
       errorCollection.addErrorMessage(getText("addconfluencelink.error.duplicate"));
     } else {
       errorCollection.addErrorMessage(entry.getValue());
     }
   }
 }
  @Override
  public void validateFromParams(
      CustomFieldParams cfParams, ErrorCollection errorCollection, FieldConfig fieldConfig) {
    @SuppressWarnings("unchecked")
    final Collection<String> params = cfParams.getAllValues();
    CustomField cf = fieldConfig.getCustomField();
    JiraAuthenticationContext authCtx =
        ComponentManager.getInstance().getJiraAuthenticationContext();
    I18nHelper i18n = authCtx.getI18nHelper();
    UserProjectHistoryManager userProjectHistoryManager =
        ComponentManager.getComponentInstanceOfType(UserProjectHistoryManager.class);
    Project currentProject =
        userProjectHistoryManager.getCurrentProject(Permissions.BROWSE, authCtx.getLoggedInUser());

    boolean isAutocompleteView;
    if (cf.isAllProjects()) {
      isAutocompleteView =
          qfMgr.isAutocompleteView(cf.getIdAsLong(), Consts.PROJECT_ID_FOR_GLOBAL_CF);
    } else {
      isAutocompleteView = qfMgr.isAutocompleteView(cf.getIdAsLong(), currentProject.getId());
    }

    if (isAutocompleteView) {
      if ((params == null) || params.isEmpty()) {
        boolean addNull;
        if (cf.isAllProjects()) {
          addNull = qfMgr.getAddNull(cf.getIdAsLong(), Consts.PROJECT_ID_FOR_GLOBAL_CF);
        } else {
          addNull = qfMgr.getAddNull(cf.getIdAsLong(), currentProject.getId());
        }

        if (!addNull) {
          errorCollection.addError(
              fieldConfig.getFieldId(), i18n.getText("queryfields.error.isnotnull"));
        }
      } else {
        if (params.size() > 1) {
          errorCollection.addError(
              fieldConfig.getFieldId(), i18n.getText("queryfields.error.invalid.params"));
        } else {
          for (String param : params) {
            Issue issue = issueMgr.getIssueObject(param);
            if (issue == null) {
              errorCollection.addError(
                  fieldConfig.getFieldId(), i18n.getText("queryfields.error.notissue", param));
            }
          }
        }
      }
    }
  }
 private void validateComment() {
   // Check if we have a comment
   if (fieldUpdated(FIELD_COMMENT)) {
     // If so if the user can comment on the issue
     if (permissionManager.hasPermission(
         Permissions.COMMENT_ISSUE, getProject(), getRemoteUser())) {
       commentService.isValidCommentData(
           getRemoteUser(), getIssue(), getCommentLevel(), getCommentRoleLevel(), errorCollection);
       if (!fieldUpdated(FIELD_COMMENT_LEVEL) && !fieldUpdated(FIELD_COMMENT_ROLE_LEVEL)) {
         setCommentLevel(null);
       }
     } else {
       errorCollection.addErrorMessage(
           authenticationContext
               .getI18nHelper()
               .getText(
                   "admin.errors.user.does.not.have.permission",
                   (getRemoteUser() != null
                       ? authenticationContext
                           .getI18nHelper()
                           .getText("admin.errors.user", "'" + getRemoteUser().getName() + "'")
                       : authenticationContext
                           .getI18nHelper()
                           .getText("admin.errors.anonymous.user"))));
     }
   }
 }
 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);
   }
 }
 private void validateRemoveComment(
     ErrorCollection errorCollectionToAddTo,
     Map<String, Object> commentParams,
     ApplicationUser user) {
   Object commentIdObj = commentParams.get(PARAM_COMMENT_ID);
   if (commentIdObj != null) {
     try {
       Long commentId = Long.valueOf((String) commentIdObj);
       commentService.hasPermissionToDelete(
           new JiraServiceContextImpl(user, errorCollectionToAddTo), commentId);
     } catch (NumberFormatException ex) {
       errorCollectionToAddTo.addError(
           IssueFieldConstants.COMMENT, "invalid comment id specified.");
     }
   } else {
     errorCollectionToAddTo.addError(IssueFieldConstants.COMMENT, "no comment id specified.");
   }
 }
 public void validateCommentProperties(
     Map<String, Object> properties, ErrorCollection errorCollection) {
   try {
     final ImmutableMap<String, JSONObject> commentProperties =
         getCommentPropertiesFromParameters(properties);
     for (Map.Entry<String, JSONObject> property : commentProperties.entrySet()) {
       EntityPropertyService.PropertyInput propertyInput =
           new EntityPropertyService.PropertyInput(
               property.getValue().toString(), property.getKey());
       errorCollection.addErrorCollection(
           commentPropertyService.validatePropertyInput(propertyInput));
     }
   } catch (JSONException e) {
     errorCollection.addErrorMessage(
         i18nFactory
             .getInstance(authenticationContext.getUser())
             .getText(
                 "jira.properties.service.invalid.json", properties.get(PARAM_COMMENT_PROPERTY)));
   }
 }
 private void validateEditComment(
     ErrorCollection errorCollection,
     Issue issue,
     Map<String, Object> commentParams,
     String body,
     Visibility visibility,
     ApplicationUser user) {
   if (commentParams.get(PARAM_COMMENT_ID) != null) {
     try {
       commentService.isValidCommentBody(body, errorCollection);
       final Long commentIdAsLong = Long.valueOf((String) commentParams.get(PARAM_COMMENT_ID));
       commentService.hasPermissionToEdit(
           new JiraServiceContextImpl(user, errorCollection), commentIdAsLong);
       commentService.isValidCommentVisibility(user, issue, visibility, errorCollection);
       validateCommentProperties(commentParams, errorCollection);
     } catch (NumberFormatException ex) {
       errorCollection.addError(IssueFieldConstants.COMMENT, "invalid comment id specified.");
     }
   } else {
     errorCollection.addError(IssueFieldConstants.COMMENT, "no comment id specified.");
   }
 }
  @Test
  public void testInvalidLicenseProvided() throws Exception {
    expect(mockBeanFactory.getInstance(currentUser)).andReturn(mockI18nHelper).anyTimes();
    expect(mockPermissionManager.hasPermission(Permissions.SYSTEM_ADMIN, currentUser))
        .andReturn(true);
    expect(mockJiraLicenseService.validate(mockI18nHelper, "thisisnotavalidlicensestring"))
        .andReturn(mockValidationResult);
    final ErrorCollection errors = new SimpleErrorCollection();
    errors.addErrorMessage("Not a valid license");
    expect(mockValidationResult.getErrorCollection()).andReturn(errors);

    try {
      final String filePath = getDataFilePath("jira-export-test.xml");
      final DataImportParams params =
          new DataImportParams.Builder(filePath)
              .setLicenseString("thisisnotavalidlicensestring")
              .build();
      executeTest(params, false, DataImportService.ImportError.NONE);
      fail("Calling doImport with invalid validation result should have thrown an exception!");
    } catch (IllegalStateException e) {
      // yay
    }
  }
  @Override
  public void validate(
      final ErrorCollection errors,
      final BulkMoveOperation bulkMoveOperation,
      final ApplicationUser applicationUser) {
    if (!regularIssues.isEmpty() && regularOptions.isEmpty()) {
      errors.addErrorMessage(
          authenticationContext
              .getI18nHelper()
              .getText("admin.errors.bean.issues.affected", "" + regularIssues.size()));
    }

    if (!subTaskIssues.isEmpty() && subTaskOptions.isEmpty()) {
      errors.addErrorMessage(
          authenticationContext
              .getI18nHelper()
              .getText("admin.errors.bean.subtasks.affected", "" + subTaskIssues.size()));
    }

    // Validate permission
    Set entries = bulkEditBeans.entrySet();
    for (final Object entry1 : entries) {
      Map.Entry entry = (Map.Entry) entry1;
      IssueContext issueContext = (IssueContext) entry.getKey();
      BulkEditBean bulkEditBean = (BulkEditBean) entry.getValue();
      if (!bulkMoveOperation.canPerform(bulkEditBean, applicationUser)) {
        errors.addErrorMessage(
            authenticationContext
                .getI18nHelper()
                .getText(
                    "admin.errors.bean.no.permission",
                    issueContext.getProject().getString("name"),
                    issueContext.getIssueTypeObject().getName()));
      }
    }
  }
  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;
  }
 private void transferErrorMessages(
     ErrorCollection errorCollection, Collection<String> errorMessages) {
   for (String errMsg : errorMessages) {
     errorCollection.addError(getId(), errMsg);
   }
 }
  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;
  }
  public void validateGetBackupOverview(
      final JiraServiceContext jiraServiceContext,
      final ProjectImportOptions projectImportOptions) {
    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"));
      // Don't care to check any more validity
      return;
    }

    if (StringUtils.isEmpty(projectImportOptions.getPathToBackupXml())) {
      errorCollection.addError(
          "backupXmlPath", getText(i18n, "admin.errors.project.import.provide.backup.path"));
    } else if (!pathExists(projectImportOptions.getPathToBackupXml(), true)) {
      errorCollection.addError(
          "backupXmlPath", getText(i18n, "admin.errors.project.import.invalid.backup.path"));
    }

    // Check if the user has supplied an attachment path
    if (!StringUtils.isEmpty(projectImportOptions.getAttachmentPath())) {
      // Check that attachments are enabled for the current JIRA
      if (!attachmentManager.attachmentsEnabled()) {
        errorCollection.addError(
            "backupAttachmentPath",
            getText(i18n, "admin.errors.project.import.attachments.not.enabled"));
      }
      // Now check if the path exists
      else if (pathExists(projectImportOptions.getAttachmentPath(), false)) {
        // Path Exists, but it is not allowed to be the current system's Attachment Path.
        // Get the configured attachment path for this JIRA instance.
        final String attachmentPathString = attachmentPathManager.getAttachmentPath();
        // Create a File object with it.
        final File attachmentPathFile = new File(attachmentPathString);
        // Create a File object with the attachment path
        final File backupAttachmentPathFile = new File(projectImportOptions.getAttachmentPath());
        // Compare the canonical paths to see if the directories are the same.
        try {
          if (attachmentPathFile
              .getCanonicalPath()
              .equals(backupAttachmentPathFile.getCanonicalPath())) {
            errorCollection.addError(
                "backupAttachmentPath",
                getText(i18n, "admin.errors.project.import.attachment.backup.path.same.as.system"));
          }
        } catch (final IOException e) {
          // This would be rather strange, but see the javadoc for getCanonicalFile():
          // "If an I/O error occurs, which is possible because the construction of the canonical
          // pathname may require filesystem queries"
          errorCollection.addErrorMessage(
              getText(i18n, "admin.errors.project.import.attachment.ioexception", e.getMessage()));
        }
      } else {
        // Path doesn't exist
        errorCollection.addError(
            "backupAttachmentPath",
            getText(i18n, "admin.errors.project.import.invalid.attachment.backup.path"));
      }
    }
  }
  public ProjectImportResults doImport(
      final JiraServiceContext jiraServiceContext,
      final ProjectImportOptions projectImportOptions,
      final BackupProject backupProject,
      final BackupSystemInformation backupSystemInformation,
      final ProjectImportData projectImportData,
      final TaskProgressInterval taskProgressInterval) {
    Null.not("projectImportOptions", projectImportOptions);
    Null.not("backupSystemInformation", backupSystemInformation);
    Null.not("projectImportData", projectImportData);
    Null.not("backupProject", backupProject);
    validateJiraServiceContext(jiraServiceContext);
    final ErrorCollection errorCollection = jiraServiceContext.getErrorCollection();
    final I18nHelper i18n = jiraServiceContext.getI18nBean();

    // Get the expected number of users that we will create
    final int usersToCreate =
        (isExternalUserManagementEnabled())
            ? 0
            : projectImportData
                .getProjectImportMapper()
                .getUserMapper()
                .getUsersToAutoCreate()
                .size();

    final ProjectImportResults projectImportResults =
        getInitialImportResults(projectImportData, i18n, usersToCreate);

    // 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 projectImportResults;
    }

    try {
      log.info(
          "Starting project import for project '" + backupProject.getProject().getKey() + "'.");
      if (isExternalUserManagementEnabled()) {
        log.info("External user management is enabled. No users will be imported.");
      } else {
        log.info(
            "Creating missing users. Attempting to create "
                + projectImportResults.getExpectedUsersCreatedCount()
                + " users.");
        // External User Management is OFF - create missing users that we can.
        // This will fill in subtask progress from 0% - 10% of the doImport task
        final TaskProgressInterval subInterval = getSubInterval(taskProgressInterval, 0, 10);
        projectImportManager.createMissingUsers(
            projectImportData.getProjectImportMapper().getUserMapper(),
            projectImportResults,
            subInterval);
        log.info(
            "Finished creating missing users. "
                + projectImportResults.getUsersCreatedCount()
                + " users created.");
      }

      // Create/Update the project, its details, components, versions, role membership
      try {
        // This will fill in subtask progress from 10% - 20% of the doImport task (Allow for
        // creating lots of Project Role members)
        final TaskProgressInterval subInterval = getSubInterval(taskProgressInterval, 10, 20);
        projectImportManager.importProject(
            projectImportOptions,
            projectImportData.getProjectImportMapper(),
            backupProject,
            projectImportResults,
            subInterval);
      } catch (final AbortImportException e) {
        // Add an error message
        errorCollection.addErrorMessage(
            i18n.getText("admin.error.project.import.project.update.error"));
        throw e;
      }

      // Import the issues and all their related values and reIndex the project once it is done
      try {
        // This will fill in subtask progress from 20% - 100% of the doImport task (Allow for
        // creating lots of Project Role members)
        final TaskProgressInterval subInterval = getSubInterval(taskProgressInterval, 20, 100);
        projectImportManager.doImport(
            projectImportOptions,
            projectImportData,
            backupProject,
            backupSystemInformation,
            projectImportResults,
            subInterval,
            i18n,
            jiraServiceContext.getUser());
        // Only set the completed flag once everything has finished
        projectImportResults.setImportCompleted(true);
      } catch (final IOException e) {
        log.error(
            "There was a problem accessing the partitioned XML files when performing a project import.",
            e);
        errorCollection.addErrorMessage(
            getText(
                i18n,
                "admin.errors.project.import.problem.reading.partitioned.xml",
                e.getMessage()));
      } catch (final AbortImportException aie) {
        // Note that AbortImportException extends SAXException, so we need to catch and handle
        // AbortImportException first.
        log.error("The import was aborted because there were too many errors.");
        errorCollection.addErrorMessage(i18n.getText("admin.errors.project.import.import.error"));
      } catch (final SAXException e) {
        log.error(
            "There was a problem accessing the partitioned XML files when performing a project import.",
            e);
        errorCollection.addErrorMessage(
            getText(
                i18n, "admin.errors.project.import.sax.problem.partitioned.xml", e.getMessage()));
      } catch (final IndexException e) {
        log.error("There was a problem reIndexing the newly imported project.", e);
        errorCollection.addErrorMessage(
            i18n.getText("admin.errors.project.import.reindex.problem", e.getMessage()));
      }
      log.info(
          "Finished project import for project '" + backupProject.getProject().getKey() + "'.");

    } catch (final AbortImportException aie) {
      log.error("The import was aborted because there were too many errors.");
      errorCollection.addErrorMessage(i18n.getText("admin.errors.project.import.import.error"));
    }

    // Clean up the temporary "partitioned" XML files.
    projectImportData.getTemporaryFiles().deleteTempFiles();

    // Always record the end of the import.
    projectImportResults.setEndTime(System.currentTimeMillis());
    logImportResults(projectImportResults);
    return projectImportResults;
  }
  public ProjectImportData getProjectImportData(
      final JiraServiceContext jiraServiceContext,
      final ProjectImportOptions projectImportOptions,
      final BackupProject backupProject,
      final BackupSystemInformation backupSystemInformation,
      final TaskProgressInterval taskProgressInterval) {
    Null.not("backupProject", backupProject);
    Null.not("projectImportOptions", projectImportOptions);
    Null.not("backupSystemInformation", backupSystemInformation);
    validateJiraServiceContext(jiraServiceContext);

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

    final ErrorCollection errorCollection = jiraServiceContext.getErrorCollection();
    final I18nHelper i18n = jiraServiceContext.getI18nBean();
    final ProjectImportData projectImportData;
    try {
      // First step is to go through the import file again, populating our mappers and creating
      // partitioned XML files.
      // Create the Task Progress Processor for this subtask.
      EntityCountTaskProgressProcessor taskProgressProcessor = null;
      if (taskProgressInterval != null) {
        taskProgressProcessor =
            new EntityCountTaskProgressProcessor(
                taskProgressInterval,
                i18n.getText(
                    "admin.message.project.import.manager.do.mapping.extracting.project.data"),
                backupSystemInformation.getEntityCount(),
                i18n);
      }
      projectImportData =
          projectImportManager.getProjectImportData(
              projectImportOptions, backupProject, backupSystemInformation, taskProgressProcessor);
    } 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()));
      return null;
    } 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;
    }
    return projectImportData;
  }
 public void addErrorMessage(String error) {
   errorCollection.addErrorMessage(error);
 }
  @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 void addError(String name, String error) {
   errorCollection.addError(name, error);
 }