public MessageSet validate( final User searcher, final FunctionOperand functionOperand, final TerminalClause terminalClause) { final MessageSet messageSet; I18nHelper i18n = getI18n(); if (functionOperand.getArgs().size() == 0 && searcher == null) { messageSet = new MessageSetImpl(); messageSet.addErrorMessage( i18n.getText("jira.jql.function.anonymous.disallowed", getFunctionName())); } else { MessageSet messages = validateNumberOfArgs(functionOperand, i18n); if (!messages.hasAnyErrors()) { if (functionOperand.getArgs().size() == 1) { final String username = functionOperand.getArgs().get(0); if (userUtil.getUserObject(username) == null) { messages.addErrorMessage( i18n.getText(getUserNotFoundMessageKey(), functionOperand.getName(), username)); } } } return messages; } return messageSet; }
private void validateExistingProjectHasValidStateForImport( final BackupProject backupProject, final BackupSystemInformation backupSystemInformation, final Project existingProject, final I18nHelper i18n, final MessageSet messageSet) { final String projectKey = backupProject.getProject().getKey(); // Verify that the project has no existing issues final long issueCount = issueManager.getIssueCountForProject(existingProject.getId()); if (issueCount != 0) { messageSet.addErrorMessage( getText( i18n, "admin.error.project.import.project.contains.issues", projectKey, String.valueOf(issueCount))); } // Verify that the project has no existing versions final long versionCount = versionManager.getVersions(existingProject.getId()).size(); if (versionCount != 0) { messageSet.addErrorMessage( getText( i18n, "admin.error.project.import.project.contains.versions", projectKey, String.valueOf(versionCount))); } // Verify that the project has no existing components final long componentCount = projectComponentManager.findAllForProject(existingProject.getId()).size(); if (componentCount != 0) { messageSet.addErrorMessage( getText( i18n, "admin.error.project.import.project.contains.components", projectKey, String.valueOf(componentCount))); } // Verify that if the project has a default assignee of Unassigned that the current instance of // JIRA supports unassigned issues if (projectHasDefaultAssigneeUnassigned(backupProject, backupSystemInformation)) { // We want this instance of JIRA to allow unassigned issues. final boolean allowUnassigned = applicationProperties.getOption(APKeys.JIRA_OPTION_ALLOWUNASSIGNED); if (!allowUnassigned) { messageSet.addErrorMessage( getText( i18n, "admin.error.project.import.project.default.assignee.not.allowed", backupProject.getProject().getName())); } } }
void validateCustomFieldPluginVersions( final BackupProject backupProject, final Collection backupPluginVersions, final MessageSet messageSet, final I18nHelper i18n) { for (final Iterator iterator = backupProject.getCustomFields().iterator(); iterator.hasNext(); ) { final ExternalCustomFieldConfiguration customFieldConfiguration = (ExternalCustomFieldConfiguration) iterator.next(); String key = customFieldConfiguration.getCustomField().getTypeKey(); // The key is the plugin container key, a colon, then the module key (e.g. // com.atlassian.jira.plugin.system.customfieldtypes:textarea) // We just get the plugin container key, as this is where the version exists. final int index = key.indexOf(":"); // This should never happen unless there was a bad plugin module installed in the backup data, // if this is // the case then we just want to use the key as specified and let the error propagate to the // user screen if (index != -1) { key = key.substring(0, index); } // Does this plugin exist in the current JIRA instance final Plugin plugin = pluginAccessor.getPlugin(key); if (plugin != null) { final String currentPluginVersion = plugin.getPluginInformation().getVersion(); String backupVersion = null; for (final Iterator iterator1 = backupPluginVersions.iterator(); iterator1.hasNext(); ) { final PluginVersion pluginVersion = (PluginVersion) iterator1.next(); if (pluginVersion.getKey().equals(key)) { backupVersion = pluginVersion.getVersion(); break; } } if (!currentPluginVersion.equals(backupVersion)) { final String customFieldName = customFieldConfiguration.getCustomField().getName(); if (backupVersion == null) { messageSet.addErrorMessage( i18n.getText( "admin.error.project.import.plugin.wrong.version.null.backup", backupProject.getProject().getName(), customFieldName, customFieldConfiguration.getCustomField().getTypeKey(), currentPluginVersion)); } else { messageSet.addErrorMessage( i18n.getText( "admin.error.project.import.plugin.wrong.version", backupProject.getProject().getName(), customFieldName, customFieldConfiguration.getCustomField().getTypeKey(), currentPluginVersion, backupVersion)); } } } } }
private void writeLogMessages(final MessageSet messageSet) { if (messageSet == null) { return; } // Log the errors for (final Iterator iterator = messageSet.getErrorMessagesInEnglish().iterator(); iterator.hasNext(); ) { log.error(iterator.next()); } // Log the warnings for (final Iterator iterator = messageSet.getWarningMessagesInEnglish().iterator(); iterator.hasNext(); ) { log.warn(iterator.next()); } }
public MessageSet validateBackupProjectImportableSystemLevel( final JiraServiceContext jiraServiceContext, final BackupProject backupProject, final BackupSystemInformation backupSystemInformation) { validateJiraServiceContext(jiraServiceContext); // No need to check if backupProject has null members, we will never create backup project like // that. Null.not("backupSystemInformation", backupSystemInformation); final MessageSet messageSet = new MessageSetImpl(); final I18nHelper i18n = jiraServiceContext.getI18nBean(); // Need to provide a backupProject if (backupProject == null) { messageSet.addErrorMessage(getText(i18n, "admin.error.project.import.null.project")); jiraServiceContext .getErrorCollection() .addErrorMessage(getText(i18n, "admin.error.project.import.null.project")); return messageSet; } // The user must have the system administrator permission to perform a project import if (!userHasSysAdminPermission(jiraServiceContext.getUser())) { messageSet.addErrorMessage(getText(i18n, "admin.errors.project.import.must.be.admin")); } else { // Verify that if the backup projects custom field plugins exist that they are of the right // version in this JIRA instance // NOTE: warnings, such as the plugin not existing or the custom field being not importable or // out of context // are not checked here, that is handled by the next phase of the import. validateCustomFieldPluginVersions( backupProject, backupSystemInformation.getPluginVersions(), messageSet, i18n); final String projectKey = backupProject.getProject().getKey(); final Project existingProject = projectManager.getProjectObjByKey(projectKey); if (existingProject == null) { // It does not really make sense to warn that we will create a project for them if there are // already errors. if (!messageSet.hasAnyErrors()) { messageSet.addWarningMessage( getText(i18n, "admin.warning.project.import.no.existing.project", projectKey)); } } else { // We need to make sure that the project does not contain issues, versions, components, // etc... validateExistingProjectHasValidStateForImport( backupProject, backupSystemInformation, existingProject, i18n, messageSet); } } // Copy the errors into the service context error collection jiraServiceContext.getErrorCollection().addErrorMessages(messageSet.getErrorMessages()); return messageSet; }
public MessageSet validateValues(User searcher, String fieldName, List<QueryLiteral> rawValues) { final PossibleValuesHolder possibleValuesHolder = new PossibleValuesHolder(); final MessageSet messages = new MessageSetImpl(); for (QueryLiteral rawValue : rawValues) { if (rawValue.getStringValue() != null) { if (!stringValueExists( possibleValuesHolder, searcher, fieldName, rawValue.getStringValue())) { if (operandResolver.isFunctionOperand(rawValue.getSourceOperand())) { messages.addErrorMessage( getI18n(searcher) .getText( "jira.jql.clause.no.value.for.name.from.function", rawValue.getSourceOperand().getName(), fieldName)); } else { messages.addErrorMessage( getI18n(searcher) .getText( "jira.jql.clause.no.value.for.name", fieldName, rawValue.getStringValue())); } } } else if (rawValue.getLongValue() != null) { if (stringValueExists( possibleValuesHolder, searcher, fieldName, rawValue.getLongValue().toString())) { return messages; } if (!configurationManager.supportsIdSearching(fieldName.toLowerCase())) { if (operandResolver.isFunctionOperand(rawValue.getSourceOperand())) { messages.addErrorMessage( getI18n(searcher) .getText( "jira.jql.clause.no.value.for.name.from.function", rawValue.getSourceOperand().getName(), fieldName)); } else { messages.addErrorMessage( getI18n(searcher) .getText( "jira.jql.history.clause.not.string", rawValue.getSourceOperand().getName(), fieldName)); } } else { if (!longValueExists(searcher, fieldName, rawValue.getLongValue())) { if (operandResolver.isFunctionOperand(rawValue.getSourceOperand())) { messages.addErrorMessage( getI18n(searcher) .getText( "jira.jql.clause.no.value.for.name.from.function", rawValue.getSourceOperand().getName(), fieldName)); } else { messages.addErrorMessage( getI18n(searcher) .getText( "jira.jql.clause.no.value.for.id", fieldName, rawValue.getLongValue().toString())); } } } } } return messages; }
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; }