ProjectImportResults getInitialImportResults( final ProjectImportData projectImportData, final I18nHelper i18n, final int usersToCreate) { return new ProjectImportResultsImpl( System.currentTimeMillis(), projectImportData.getIssueEntityCount(), usersToCreate, projectImportData.getValidAttachmentsCount(), i18n); }
void addCustomFieldValuesNotCheckedMessageSets( final ProjectImportData projectImportData, final MappingResult mappingResult) { final Map customFieldMessageSets = new HashMap(); final CustomFieldMapper customFieldMapper = projectImportData.getProjectImportMapper().getCustomFieldMapper(); for (final Iterator iterator = customFieldMapper.getRequiredOldIds().iterator(); iterator.hasNext(); ) { final String oldCustomFieldId = (String) iterator.next(); if (!customFieldMapper.isIgnoredCustomField(oldCustomFieldId)) { customFieldMessageSets.put(oldCustomFieldId, null); } } mappingResult.setCustomFieldValueMessageSets(customFieldMessageSets); }
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; }
void createValidationMessageList( final MappingResult mappingResult, final ProjectImportData projectImportData, final I18nHelper i18nHelper) { // create an ordered list of Validation Messages with translated Context names. final List systemFieldsMessageList = new ArrayList(); // Issue Type systemFieldsMessageList.add( new MappingResult.ValidationMessage( i18nHelper.getText("issue.field.issuetype"), mappingResult.getIssueTypeMessageSet())); // Custom Field systemFieldsMessageList.add( new MappingResult.ValidationMessage( i18nHelper.getText("admin.project.import.custom.field.configuration"), mappingResult.getCustomFieldMessageSet())); // Status systemFieldsMessageList.add( new MappingResult.ValidationMessage( i18nHelper.getText("issue.field.status"), mappingResult.getStatusMessageSet())); // Priority systemFieldsMessageList.add( new MappingResult.ValidationMessage( i18nHelper.getText("issue.field.priority"), mappingResult.getPriorityMessageSet())); // Resolution systemFieldsMessageList.add( new MappingResult.ValidationMessage( i18nHelper.getText("issue.field.resolution"), mappingResult.getResolutionMessageSet())); // Users systemFieldsMessageList.add( new MappingResult.ValidationMessage( i18nHelper.getText("admin.common.words.users"), mappingResult.getUserMessageSet())); // ProjectRole systemFieldsMessageList.add( new MappingResult.ValidationMessage( i18nHelper.getText("admin.common.words.projectrole"), mappingResult.getProjectRoleMessageSet())); // ProjectRoleActors systemFieldsMessageList.add( new MappingResult.ValidationMessage( i18nHelper.getText("admin.common.words.projectrole.membership"), mappingResult.getProjectRoleActorMessageSet())); // Group systemFieldsMessageList.add( new MappingResult.ValidationMessage( i18nHelper.getText("admin.common.words.group"), mappingResult.getGroupMessageSet())); // IssueLinkType systemFieldsMessageList.add( new MappingResult.ValidationMessage( i18nHelper.getText("common.concepts.issuelinktype"), mappingResult.getIssueLinkTypeMessageSet())); // IssueSecurityLevel systemFieldsMessageList.add( new MappingResult.ValidationMessage( i18nHelper.getText("admin.common.words.issue.security.level"), mappingResult.getIssueSecurityLevelMessageSet())); // File Attachments systemFieldsMessageList.add( new MappingResult.ValidationMessage( i18nHelper.getText("common.concepts.attachments.files"), mappingResult.getFileAttachmentMessageSet())); mappingResult.setSystemFieldsMessageList(systemFieldsMessageList); // Now find Custom Field Value messages final List customFieldsMessageList = new ArrayList(); final CustomFieldMapper customFieldMapper = projectImportData.getProjectImportMapper().getCustomFieldMapper(); for (final Iterator iterator = mappingResult.getCustomFieldValueMessageSets().keySet().iterator(); iterator.hasNext(); ) { final String oldCustomFieldId = (String) iterator.next(); final MessageSet messageSet = (MessageSet) mappingResult.getCustomFieldValueMessageSets().get(oldCustomFieldId); customFieldsMessageList.add( new MappingResult.ValidationMessage( customFieldMapper.getDisplayName(oldCustomFieldId), messageSet)); } mappingResult.setCustomFieldsMessageList(customFieldsMessageList); }
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; }