private MappingResult validateAndAutoMapFields( final JiraServiceContext jiraServiceContext, final ProjectImportOptions projectImportOptions, final ProjectImportData projectImportData, final BackupProject backupProject, final BackupSystemInformation backupSystemInformation, final TaskProgressInterval taskProgressInterval) { log.info( "Project Import: Mapping the backed up data to data in the current system, and validating the mappings..."); final MappingResult mappingResult = buildMappingResult(); final I18nHelper i18n = jiraServiceContext.getI18nBean(); // Step 2 Map and validate the Issue Types projectImportManager.autoMapAndValidateIssueTypes( projectImportData, mappingResult, backupProject, jiraServiceContext.getI18nBean()); // If there is a problem processing the issue types then we don't want to do any further // mappings or validation if ((mappingResult.getIssueTypeMessageSet() != null) && !mappingResult.getIssueTypeMessageSet().hasAnyErrors()) { // Try to map the custom fields projectImportManager.autoMapAndValidateCustomFields( projectImportData, mappingResult, backupProject, i18n); if (!mappingResult.getCustomFieldMessageSet().hasAnyErrors()) { // Only map the system fields if we can move forward with the custom fields projectImportManager.autoMapSystemFields(projectImportData, backupProject); // Only map the project roles if we can move forward with the custom fields projectImportManager.autoMapProjectRoles(projectImportData); // Only map the custom field values once we know that the custom fields are good projectImportManager.autoMapCustomFieldOptions(projectImportData, backupProject); final boolean importAttachments = !StringUtils.isEmpty(projectImportOptions.getAttachmentPath()); final int customFieldValuePercentage = (importAttachments) ? 60 : 90; // if we can successfully map the custom fields then lets validate the custom field values try { // Create a TaskProgressProcessor for validateCustomFieldValues final TaskProgressInterval subInterval = getSubInterval(taskProgressInterval, 0, customFieldValuePercentage); EntityCountTaskProgressProcessor taskProgressProcessor = null; if (taskProgressInterval != null) { taskProgressProcessor = new EntityCountTaskProgressProcessor( subInterval, i18n.getText( "admin.message.project.import.manager.do.mapping.validate.custom.field.values"), projectImportData.getCustomFieldValuesEntityCount(), i18n); } projectImportManager.validateCustomFieldValues( projectImportData, mappingResult, backupProject, taskProgressProcessor, i18n); } catch (final IOException e) { log.error( "There was a problem accessing the file '" + projectImportData.getPathToCustomFieldValuesXml() + "' when performing a project import.", e); jiraServiceContext .getErrorCollection() .addErrorMessage( getText( i18n, "admin.errors.project.import.problem.reading.custom.field.xml", projectImportData.getPathToCustomFieldValuesXml())); return null; } catch (final SAXException e) { log.error( "There was a problem accessing the file '" + projectImportData.getPathToCustomFieldValuesXml() + "' when performing a project import.", e); jiraServiceContext .getErrorCollection() .addErrorMessage( getText( i18n, "admin.errors.project.import.custom.field.sax.problem", projectImportData.getPathToCustomFieldValuesXml(), e.getMessage())); return null; } // Only validate the system field mappings after we have done all the rest // Create a sub interval of the taskProgressInterval we were given. TaskProgressInterval sysFieldSubInterval = null; if (taskProgressInterval != null) { sysFieldSubInterval = taskProgressInterval.getSubInterval( customFieldValuePercentage, customFieldValuePercentage + 10); } projectImportManager.validateSystemFields( projectImportData, mappingResult, projectImportOptions, backupProject, sysFieldSubInterval, i18n); // Validate the attachments if we are importing attachments if (!importAttachments) { final MessageSet messageSet = new MessageSetImpl(); messageSet.addWarningMessage( getText(i18n, "admin.warning.project.import.mapping.no.backup.atttachment.path")); log.warn( "File attachments will not be imported because you have not provided a backup attachment path."); mappingResult.setFileAttachmentMessageSet(messageSet); } else { try { // Create a TaskProgressProcessor for validateFileAttachments final TaskProgressInterval attachmentSubInterval = getSubInterval(taskProgressInterval, 70, 100); EntityCountTaskProgressProcessor taskProgressProcessor = null; if (taskProgressInterval != null) { taskProgressProcessor = new EntityCountTaskProgressProcessor( attachmentSubInterval, i18n.getText( "admin.message.project.import.manager.do.mapping.validate.file.attachment.values"), projectImportData.getFileAttachmentEntityCount(), i18n); } projectImportManager.validateFileAttachments( projectImportOptions, projectImportData, mappingResult, backupProject, backupSystemInformation, taskProgressProcessor, i18n); } catch (final IOException e) { log.error( "There was a problem accessing the file '" + projectImportData.getPathToFileAttachmentXml() + "' when performing a project import.", e); jiraServiceContext .getErrorCollection() .addErrorMessage( getText( i18n, "admin.errors.project.import.problem.reading.attachment.xml", projectImportData.getPathToFileAttachmentXml())); return null; } catch (final SAXException e) { log.error( "There was a problem accessing the file '" + projectImportData.getPathToFileAttachmentXml() + "' when performing a project import.", e); jiraServiceContext .getErrorCollection() .addErrorMessage( getText( i18n, "admin.errors.project.import.custom.field.sax.problem", projectImportData.getPathToFileAttachmentXml(), e.getMessage())); return null; } } } else { // When the required custom fields have not passed validation we still want to show that // validation has // not happened for each of the custom field values. addCustomFieldValuesNotCheckedMessageSets(projectImportData, mappingResult); } } else { // When the required issue types have not passed validation we still want to show that // validation has // not happened for each of the custom field values. addCustomFieldValuesNotCheckedMessageSets(projectImportData, mappingResult); } // We want to populate the message list of the results. This puts the message results into order // and gives // them i18n header labels createValidationMessageList(mappingResult, projectImportData, i18n); if (mappingResult.canImport()) { log.info("Project Import: No validation errors were found and the import can continue."); } else { log.info("Project Import: Validation errors were found. The import cannot continue."); } return mappingResult; }
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")); } } }