Java tutorial
/* * This software was designed and created by Jason Carroll. * Copyright (c) 2002, 2003, 2004 Jason Carroll. * The author can be reached at jcarroll@cowsultants.com * ITracker website: http://www.cowsultants.com * ITracker forums: http://www.cowsultants.com/phpBB/index.php * * This program is free software; you can redistribute it and/or modify * it only under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ package org.itracker.web.actions.admin.configuration; import org.apache.commons.beanutils.PropertyUtils; import org.apache.log4j.Logger; import org.apache.struts.action.*; import org.apache.struts.upload.FormFile; import org.itracker.ImportExportException; import org.itracker.core.resources.ITrackerResources; import org.itracker.model.*; import org.itracker.model.util.SystemConfigurationUtilities; import org.itracker.model.util.UserUtilities; import org.itracker.persistence.dao.NoSuchEntityException; import org.itracker.services.ConfigurationService; import org.itracker.services.ProjectService; import org.itracker.services.UserService; import org.itracker.web.actions.base.ItrackerBaseAction; import org.itracker.web.util.Constants; import org.itracker.web.util.ImportExportUtilities; import org.itracker.web.util.LoginUtilities; import org.itracker.web.util.ServletContextUtils; import javax.naming.InitialContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.io.InputStreamReader; import java.util.List; /** * Performs a verification on the import data to ensure that it contains no errors, * applies any import options, and also updates the data to reuse any current system * data if needed. It also collects statistics on the import data to display to the user * before the import is actually processed. * <br><br> * When reusing existing system data. The following criteria is used to determine if * a piece of data matches an existing system resource:<br> * User - the login<br> * Project - the project name<br> * Status, Severity, Resolution - the name of the item as defined in the language root/base locale<br> * Custom Fields - the label name of the custom field as defined in the language root/base locale<br> */ public class ImportDataVerifyAction extends ItrackerBaseAction { private static final Logger log = Logger.getLogger(ImportDataVerifyAction.class); private static final int UPDATE_STATUS = 1; private static final int UPDATE_SEVERITY = 2; private static final int UPDATE_RESOLUTION = 3; public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ActionMessages errors = new ActionMessages(); if (!LoginUtilities.hasPermission(PermissionType.USER_ADMIN, request, response)) { return mapping.findForward("unauthorized"); } try { FormFile file = (FormFile) PropertyUtils.getSimpleProperty(form, "importFile"); ImportDataModel model = new ImportDataModel(); AbstractEntity[] importData = ImportExportUtilities .importIssues(new InputStreamReader(file.getInputStream())); AbstractEntity[] existingModel = new AbstractEntity[importData.length]; model.setReuseUsers((Boolean) PropertyUtils.getSimpleProperty(form, "optionreuseusers")); model.setReuseProjects((Boolean) PropertyUtils.getSimpleProperty(form, "optionreuseprojects")); model.setReuseConfig((Boolean) PropertyUtils.getSimpleProperty(form, "optionreuseconfig")); model.setCreatePasswords((Boolean) PropertyUtils.getSimpleProperty(form, "optioncreatepasswords")); model.setData(importData, existingModel); InitialContext ic = new InitialContext(); checkConfig(model, ic); log.debug(model.toString()); checkUsers(model, ic); log.debug(model.toString()); checkProjects(model, ic); log.debug(model.toString()); checkIssues(model, ic); log.debug(model.toString()); HttpSession session = request.getSession(true); session.setAttribute(Constants.IMPORT_DATA_KEY, model); } catch (ImportExportException iee) { if (iee.getType() == ImportExportException.TYPE_INVALID_LOGINS) { log.error("Invalid logins found while verifying import data."); errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.importexport.invalidlogins", iee.getMessage())); } else if (iee.getType() == ImportExportException.TYPE_INVALID_STATUS) { log.error("Invalid status found while verifying import data."); errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.importexport.invalidstatus", iee.getMessage())); } else { log.error("Exception while verifying import data.", iee); errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.system")); } } catch (Exception e) { log.error("Exception while verifying import data.", e); errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.system")); } if (!errors.isEmpty()) { saveErrors(request, errors); return mapping.getInputForward(); } return mapping.findForward("importdataverify"); } private void checkConfig(ImportDataModel model, InitialContext ic) throws ImportExportException { try { int maxSeverityValue = 1; int maxResolutionValue = 1; ConfigurationService configurationService = getITrackerServices().getConfigurationService(); List<Configuration> statuses = configurationService .getConfigurationItemsByType(Configuration.Type.status, ImportExportUtilities.EXPORT_LOCALE); List<Configuration> severities = configurationService .getConfigurationItemsByType(Configuration.Type.severity, ImportExportUtilities.EXPORT_LOCALE); List<Configuration> resolutions = configurationService.getConfigurationItemsByType( Configuration.Type.resolution, ImportExportUtilities.EXPORT_LOCALE); List<CustomField> fields = configurationService.getCustomFields(); for (int i = 0; i < severities.size(); i++) { maxSeverityValue = Math.max(maxSeverityValue, Integer.parseInt(severities.get(i).getValue())); } for (int i = 0; i < resolutions.size(); i++) { maxResolutionValue = Math.max(maxResolutionValue, Integer.parseInt(resolutions.get(i).getValue())); } AbstractEntity[] importData = model.getData(); for (int i = 0; i < importData.length; i++) { if (importData[i] instanceof Configuration) { // Need to check to see if it finds a matching name. If so change value. // For status, if it finds a matching value but not name, this is an error. // Otherwise, just change the value for the resolution and severity. Then iterate // through the issues and update the old value to the new one since they are all stored // as strings/ints, not the id to the config item. Configuration configItem = (Configuration) importData[i]; if (configItem.getType() == Configuration.Type.status) { boolean found = false; for (int j = 0; j < statuses.size(); j++) { if (model.getReuseConfig() && statuses.get(j).getName().equalsIgnoreCase(configItem.getName())) { // Matching status, update issues updateIssues(importData, UPDATE_STATUS, configItem.getValue(), statuses.get(j).getValue()); model.setExistingModel(i, configItem); model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_STATUSES, ImportExportUtilities.IMPORT_STAT_REUSED); found = true; break; } else if (statuses.get(j).getValue().equalsIgnoreCase(configItem.getValue())) { // Found a matching status value, and the name didn't match throw new ImportExportException(configItem.getValue(), ImportExportException.TYPE_INVALID_STATUS); } } if (!found) { model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_STATUSES, ImportExportUtilities.IMPORT_STAT_NEW); } } else if (configItem.getType() == Configuration.Type.severity) { boolean found = false; if (model.getReuseConfig()) { for (int j = 0; j < severities.size(); j++) { if (severities.get(j).getName().equalsIgnoreCase(configItem.getName())) { // Matching severity, update issues updateIssues(importData, UPDATE_SEVERITY, configItem.getValue(), severities.get(j).getValue()); model.setExistingModel(i, configItem); model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_SEVERITIES, ImportExportUtilities.IMPORT_STAT_REUSED); found = true; break; } } } if (!found) { updateIssues(importData, UPDATE_SEVERITY, configItem.getValue(), Integer.toString(++maxSeverityValue)); configItem.setValue(Integer.toString(maxSeverityValue)); model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_SEVERITIES, ImportExportUtilities.IMPORT_STAT_NEW); } } else if (configItem.getType() == Configuration.Type.resolution) { boolean found = false; if (model.getReuseConfig()) { for (int j = 0; j < resolutions.size(); j++) { if (resolutions.get(j).getName().equalsIgnoreCase(configItem.getName())) { // Matching resolution, update issues updateIssues(importData, UPDATE_RESOLUTION, configItem.getValue(), resolutions.get(j).getValue()); model.setExistingModel(i, configItem); model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_RESOLUTIONS, ImportExportUtilities.IMPORT_STAT_REUSED); found = true; break; } } } if (!found) { updateIssues(importData, UPDATE_RESOLUTION, configItem.getValue(), Integer.toString(++maxResolutionValue)); configItem.setValue(Integer.toString(maxResolutionValue)); model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_RESOLUTIONS, ImportExportUtilities.IMPORT_STAT_NEW); } } } else if (importData[i] instanceof CustomField) { boolean found = false; CustomField field = (CustomField) importData[i]; if (model.getReuseFields()) { for (int j = 0; j < fields.size(); j++) { if (fields.get(j).getFieldType() == field .getFieldType() /*&& fields.get(j).getName().equalsIgnoreCase(field.getName())*/) { // Matching custom field. Set id, but don't need to update issues // since it contains the customfield model field.setId(fields.get(j).getId()); model.setExistingModel(i, field); model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_FIELDS, ImportExportUtilities.IMPORT_STAT_REUSED); found = true; break; } } } if (!found) { model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_FIELDS, ImportExportUtilities.IMPORT_STAT_NEW); } } } } catch (ImportExportException iee) { throw iee; } catch (Exception e) { log.error("Error verifiying import data.", e); throw new ImportExportException(e.getMessage()); } } private void checkUsers(ImportDataModel model, InitialContext ic) throws ImportExportException { String invalidLogins = null; try { UserService userService = getITrackerServices().getUserService(); AbstractEntity[] importData = model.getData(); for (int i = 0; i < importData.length; i++) { if (importData[i] instanceof User) { User user = (User) importData[i]; User existingUser; try { existingUser = userService.getUserByLogin(user.getLogin()); } catch (NoSuchEntityException e) { existingUser = null; } if (existingUser != null) { if (model.getReuseUsers()) { user.setId(existingUser.getId()); model.setExistingModel(i, existingUser); model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_USERS, ImportExportUtilities.IMPORT_STAT_REUSED); log.debug("Reusing existing user " + user.getLogin() + "(" + user.getId() + ") during import."); } else { log.debug("Existing user " + existingUser.getLogin() + "(" + existingUser.getId() + ") during import. Adding to invalid login list."); invalidLogins = (invalidLogins == null ? existingUser.getLogin() : new StringBuffer(invalidLogins).append(", ").append(existingUser.getLogin()) .toString()); } } else { model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_USERS, ImportExportUtilities.IMPORT_STAT_NEW); } } } } catch (Exception e) { log.error("Error verifying import data.", e); throw new ImportExportException(e.getMessage()); } if (invalidLogins != null) { throw new ImportExportException(invalidLogins, ImportExportException.TYPE_INVALID_LOGINS); } } private void checkProjects(ImportDataModel model, InitialContext ic) throws ImportExportException { try { ProjectService projectService = ServletContextUtils.getItrackerServices().getProjectService(); List<Project> existingProjects = projectService.getAllProjects(); AbstractEntity[] importData = model.getData(); for (int i = 0; i < importData.length; i++) { if (importData[i] instanceof Project) { if (!model.getReuseProjects()) { model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_PROJECTS, ImportExportUtilities.IMPORT_STAT_NEW); continue; } Project project = (Project) importData[i]; for (int j = 0; j < existingProjects.size(); j++) { log.debug("Project Name: " + project.getName() + " Existing Project: " + existingProjects.get(j).getName()); log.debug("Project Name: " + ITrackerResources.escapeUnicodeString(project.getName(), false) + " Existing Project: " + ITrackerResources.escapeUnicodeString(existingProjects.get(j).getName(), false)); if (project.getName() != null && project.getName().equalsIgnoreCase(existingProjects.get(j).getName())) { project.setId(existingProjects.get(j).getId()); model.setExistingModel(i, project); model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_PROJECTS, ImportExportUtilities.IMPORT_STAT_REUSED); log.debug("Reusing existing project " + project.getName() + "(" + project.getId() + ") during import."); break; } } model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_PROJECTS, ImportExportUtilities.IMPORT_STAT_NEW); } } } catch (Exception e) { log.error("Error verifiying import data.", e); throw new ImportExportException(e.getMessage()); } } private void checkIssues(ImportDataModel model, InitialContext ic) throws ImportExportException { AbstractEntity[] importData = model.getData(); for (int i = 0; i < importData.length; i++) { if (importData[i] instanceof Issue) { model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_ISSUES, ImportExportUtilities.IMPORT_STAT_NEW); } } } private void updateIssues(AbstractEntity[] models, int updateType, String currentValue, String newValue) throws ImportExportException { if (models == null || currentValue == null || newValue == null) { return; } try { for (int i = 0; i < models.length; i++) { if (models[i] instanceof Issue) { Issue issue = (Issue) models[i]; if (updateType == UPDATE_STATUS && issue.getStatus() == Integer.parseInt(currentValue)) { issue.setStatus(Integer.parseInt(newValue)); } else if (updateType == UPDATE_SEVERITY && issue.getSeverity() == Integer.parseInt(currentValue)) { issue.setSeverity(Integer.parseInt(newValue)); } else if (updateType == UPDATE_RESOLUTION && currentValue.equalsIgnoreCase(issue.getResolution())) { issue.setResolution(newValue); } } } } catch (Exception e) { log.debug("Unable to update configuration data in issues.", e); throw new ImportExportException("Unable to update configuration data in issues: " + e.getMessage()); } } }