1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.itracker.web.actions.admin.configuration;
20
21 import java.io.IOException;
22 import java.util.List;
23
24 import javax.naming.InitialContext;
25 import javax.servlet.ServletException;
26 import javax.servlet.http.HttpServletRequest;
27 import javax.servlet.http.HttpServletResponse;
28 import javax.servlet.http.HttpSession;
29
30 import org.apache.commons.beanutils.PropertyUtils;
31 import org.apache.log4j.Logger;
32 import org.apache.struts.action.ActionForm;
33 import org.apache.struts.action.ActionForward;
34 import org.apache.struts.action.ActionMapping;
35 import org.apache.struts.action.ActionMessage;
36 import org.apache.struts.action.ActionMessages;
37 import org.apache.struts.upload.FormFile;
38 import org.itracker.core.resources.ITrackerResources;
39 import org.itracker.model.AbstractEntity;
40 import org.itracker.model.Configuration;
41 import org.itracker.model.CustomField;
42 import org.itracker.model.ImportDataModel;
43 import org.itracker.model.Issue;
44 import org.itracker.model.Project;
45 import org.itracker.model.User;
46 import org.itracker.services.ConfigurationService;
47 import org.itracker.services.ProjectService;
48 import org.itracker.services.UserService;
49 import org.itracker.services.exceptions.ImportExportException;
50 import org.itracker.services.util.ImportExportUtilities;
51 import org.itracker.services.util.SystemConfigurationUtilities;
52 import org.itracker.services.util.UserUtilities;
53 import org.itracker.web.actions.base.ItrackerBaseAction;
54 import org.itracker.web.util.Constants;
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 public class ImportDataVerifyAction extends ItrackerBaseAction {
72 private static final Logger log = Logger.getLogger(ImportDataVerifyAction.class);
73
74 private static final int UPDATE_STATUS = 1;
75 private static final int UPDATE_SEVERITY = 2;
76 private static final int UPDATE_RESOLUTION = 3;
77
78 public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
79 ActionMessages errors = new ActionMessages();
80
81
82 if(! hasPermission(UserUtilities.PERMISSION_USER_ADMIN, request, response)) {
83 return mapping.findForward("unauthorized");
84 }
85
86 try {
87 FormFile file = (FormFile) PropertyUtils.getSimpleProperty(form, "importFile");
88 String xmlData = new String(file.getFileData());
89
90 ImportDataModel model = new ImportDataModel();
91 AbstractEntity[] importData = ImportExportUtilities.importIssues(xmlData);
92 boolean[] existingModel = new boolean[importData.length];
93
94 model.setReuseUsers((Boolean) PropertyUtils.getSimpleProperty(form, "optionreuseusers"));
95 model.setReuseProjects((Boolean) PropertyUtils.getSimpleProperty(form, "optionreuseprojects"));
96 model.setReuseConfig((Boolean) PropertyUtils.getSimpleProperty(form, "optionreuseconfig"));
97 model.setCreatePasswords((Boolean) PropertyUtils.getSimpleProperty(form, "optioncreatepasswords"));
98 model.setData(importData, existingModel);
99
100 InitialContext ic = new InitialContext();
101 checkConfig(model, ic);
102 log.debug(model.toString());
103 checkUsers(model, ic);
104 log.debug(model.toString());
105 checkProjects(model, ic);
106 log.debug(model.toString());
107 checkIssues(model, ic);
108 log.debug(model.toString());
109
110 HttpSession session = request.getSession(true);
111 session.setAttribute(Constants.IMPORT_DATA_KEY, model);
112 } catch(ImportExportException iee) {
113 if(iee.getType() == ImportExportException.TYPE_INVALID_LOGINS) {
114 log.error("Invalid logins found while verifying import data.");
115 errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.importexport.invalidlogins", iee.getMessage()));
116 } else if(iee.getType() == ImportExportException.TYPE_INVALID_STATUS) {
117 log.error("Invalid status found while verifying import data.");
118 errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.importexport.invalidstatus", iee.getMessage()));
119 } else {
120 log.error("Exception while verifying import data.", iee);
121 errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.system"));
122 }
123 } catch(Exception e) {
124 log.error("Exception while verifying import data.", e);
125 errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.system"));
126 }
127
128 if(! errors.isEmpty()) {
129 saveErrors(request, errors);
130 return mapping.getInputForward();
131 }
132
133 return mapping.findForward("importdataverify");
134 }
135
136 private void checkConfig(ImportDataModel model, InitialContext ic) throws ImportExportException {
137 try {
138 int maxSeverityValue = 1;
139 int maxResolutionValue = 1;
140
141 ConfigurationService configurationService = getITrackerServices().getConfigurationService();
142
143 List<Configuration> statuses = configurationService.getConfigurationItemsByType(SystemConfigurationUtilities.TYPE_STATUS, ImportExportUtilities.EXPORT_LOCALE);
144 List<Configuration> severities = configurationService.getConfigurationItemsByType(SystemConfigurationUtilities.TYPE_SEVERITY, ImportExportUtilities.EXPORT_LOCALE);
145 List<Configuration> resolutions = configurationService.getConfigurationItemsByType(SystemConfigurationUtilities.TYPE_RESOLUTION, ImportExportUtilities.EXPORT_LOCALE);
146 List<CustomField> fields = configurationService.getCustomFields(ImportExportUtilities.EXPORT_LOCALE);
147
148 for(int i = 0; i < severities.size(); i++) {
149 maxSeverityValue = Math.max(maxSeverityValue, Integer.parseInt(severities.get(i).getValue()));
150 }
151 for(int i = 0; i < resolutions.size(); i++) {
152 maxResolutionValue = Math.max(maxResolutionValue, Integer.parseInt(resolutions.get(i).getValue()));
153 }
154
155 AbstractEntity[] importData = model.getData();
156 for(int i = 0; i < importData.length; i++) {
157 if(importData[i] instanceof Configuration) {
158
159
160
161
162
163 Configuration configItem = (Configuration) importData[i];
164 if(configItem.getType() == SystemConfigurationUtilities.TYPE_STATUS) {
165 boolean found = false;
166 for(int j = 0; j < statuses.size(); j++) {
167 if(model.getReuseConfig() && statuses.get(j).getName().equalsIgnoreCase(configItem.getName())) {
168
169 updateIssues(importData, UPDATE_STATUS, configItem.getValue(), statuses.get(j).getValue());
170 model.setExistingModel(i, true);
171 model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_STATUSES, ImportExportUtilities.IMPORT_STAT_REUSED);
172 found = true;
173 break;
174 } else if(statuses.get(j).getValue().equalsIgnoreCase(configItem.getValue())) {
175
176 throw new ImportExportException(configItem.getValue(), ImportExportException.TYPE_INVALID_STATUS);
177 }
178 }
179 if(! found) {
180 model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_STATUSES, ImportExportUtilities.IMPORT_STAT_NEW);
181 }
182 } else if(configItem.getType() == SystemConfigurationUtilities.TYPE_SEVERITY) {
183 boolean found = false;
184 if(model.getReuseConfig()) {
185 for(int j = 0; j < severities.size(); j++) {
186 if(severities.get(j).getName().equalsIgnoreCase(configItem.getName())) {
187
188 updateIssues(importData, UPDATE_SEVERITY, configItem.getValue(), severities.get(j).getValue());
189 model.setExistingModel(i, true);
190 model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_SEVERITIES, ImportExportUtilities.IMPORT_STAT_REUSED);
191 found = true;
192 break;
193 }
194 }
195 }
196 if(! found) {
197 updateIssues(importData, UPDATE_SEVERITY, configItem.getValue(), Integer.toString(++maxSeverityValue));
198 configItem.setValue(Integer.toString(maxSeverityValue));
199 model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_SEVERITIES, ImportExportUtilities.IMPORT_STAT_NEW);
200 }
201 } else if(configItem.getType() == SystemConfigurationUtilities.TYPE_RESOLUTION) {
202 boolean found = false;
203 if(model.getReuseConfig()) {
204 for(int j = 0; j < resolutions.size(); j++) {
205 if(resolutions.get(j).getName().equalsIgnoreCase(configItem.getName())) {
206
207 updateIssues(importData, UPDATE_RESOLUTION, configItem.getValue(), resolutions.get(j).getValue());
208 model.setExistingModel(i, true);
209 model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_RESOLUTIONS, ImportExportUtilities.IMPORT_STAT_REUSED);
210 found = true;
211 break;
212 }
213 }
214 }
215 if(! found) {
216 updateIssues(importData, UPDATE_RESOLUTION, configItem.getValue(), Integer.toString(++maxResolutionValue));
217 configItem.setValue(Integer.toString(maxResolutionValue));
218 model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_RESOLUTIONS, ImportExportUtilities.IMPORT_STAT_NEW);
219 }
220 }
221 } else if(importData[i] instanceof CustomField) {
222 boolean found = false;
223 CustomField field = (CustomField) importData[i];
224 if(model.getReuseFields()) {
225 for(int j = 0; j < fields.size(); j++) {
226 if(fields.get(j).getFieldType() == field.getFieldType()
227
228
229 field.setId(fields.get(j).getId());
230 model.setExistingModel(i, true);
231 model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_FIELDS, ImportExportUtilities.IMPORT_STAT_REUSED);
232 found = true;
233 break;
234 }
235 }
236 }
237 if(! found) {
238 model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_FIELDS, ImportExportUtilities.IMPORT_STAT_NEW);
239 }
240 }
241 }
242 } catch(ImportExportException iee) {
243 throw iee;
244 } catch(Exception e) {
245 log.error("Error verifiying import data.", e);
246 throw new ImportExportException(e.getMessage());
247 }
248 }
249
250 private void checkUsers(ImportDataModel model, InitialContext ic) throws ImportExportException {
251 String invalidLogins = null;
252
253 try {
254 UserService userService = getITrackerServices().getUserService();
255
256 AbstractEntity[] importData = model.getData();
257
258 for(int i = 0; i < importData.length; i++) {
259 if(importData[i] instanceof User) {
260 User user = (User) importData[i];
261 User existingUser = userService.getUserByLogin(user.getLogin());
262 if(existingUser != null) {
263 if(model.getReuseUsers()) {
264 user.setId(existingUser.getId());
265 model.setExistingModel(i, true);
266 model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_USERS, ImportExportUtilities.IMPORT_STAT_REUSED);
267 log.debug("Reusing existing user " + user.getLogin() + "(" + user.getId() + ") during import.");
268 } else {
269 log.debug("Existing user " + existingUser.getLogin() + "(" + existingUser.getId() + ") during import. Adding to invalid login list.");
270 invalidLogins = (invalidLogins == null ?
271 existingUser.getLogin() :
272 new StringBuffer(invalidLogins).append(", ").append(existingUser.getLogin()).toString());
273 }
274 } else {
275 model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_USERS, ImportExportUtilities.IMPORT_STAT_NEW);
276 }
277 }
278 }
279 } catch(Exception e) {
280 log.error("Error verifiying import data.", e);
281 throw new ImportExportException(e.getMessage());
282 }
283
284 if(invalidLogins != null) {
285 throw new ImportExportException(invalidLogins, ImportExportException.TYPE_INVALID_LOGINS);
286 }
287 }
288
289 private void checkProjects(ImportDataModel model, InitialContext ic) throws ImportExportException {
290 try {
291 ProjectService projectService = getITrackerServices().getProjectService();
292
293 List<Project> existingProjects = projectService.getAllProjects();
294 if(existingProjects.size() == 0) {
295 return;
296 }
297
298 AbstractEntity[] importData = model.getData();
299
300 for(int i = 0; i < importData.length; i++) {
301 if(importData[i] instanceof Project) {
302 if(! model.getReuseProjects()) {
303 model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_PROJECTS, ImportExportUtilities.IMPORT_STAT_NEW);
304 continue;
305 }
306
307 Project project = (Project) importData[i];
308 boolean found = false;
309 for(int j = 0; j < existingProjects.size(); j++) {
310 log.debug("Project Name: " + project.getName() + " Existing Project: " + existingProjects.get(j).getName());
311 log.debug("Project Name: " + ITrackerResources.escapeUnicodeString(project.getName(), false) + " Existing Project: " + ITrackerResources.escapeUnicodeString(existingProjects.get(j).getName(), false));
312 if(project.getName() != null && project.getName().equalsIgnoreCase(existingProjects.get(j).getName())) {
313 project.setId(existingProjects.get(j).getId());
314 model.setExistingModel(i, true);
315 model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_PROJECTS, ImportExportUtilities.IMPORT_STAT_REUSED);
316 found = true;
317 log.debug("Reusing existing project " + project.getName() + "(" + project.getId() + ") during import.");
318 break;
319 }
320 }
321 if(! found) {
322 model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_PROJECTS, ImportExportUtilities.IMPORT_STAT_NEW);
323 }
324 }
325 }
326 } catch(Exception e) {
327 log.error("Error verifiying import data.", e);
328 throw new ImportExportException(e.getMessage());
329 }
330 }
331
332 private void checkIssues(ImportDataModel model, InitialContext ic) throws ImportExportException {
333 AbstractEntity[] importData = model.getData();
334
335 for(int i = 0; i < importData.length; i++) {
336 if(importData[i] instanceof Issue) {
337 model.addVerifyStatistic(ImportExportUtilities.IMPORT_STAT_ISSUES, ImportExportUtilities.IMPORT_STAT_NEW);
338 }
339 }
340 }
341
342 private void updateIssues(AbstractEntity[] models, int updateType, String currentValue, String newValue) throws ImportExportException {
343 if(models == null || currentValue == null || newValue == null) {
344 return;
345 }
346
347 try {
348 for(int i = 0; i < models.length; i++) {
349 if(models[i] instanceof Issue) {
350 Issue issue = (Issue) models[i];
351 if(updateType == UPDATE_STATUS && issue.getStatus() == Integer.parseInt(currentValue)) {
352 issue.setStatus(Integer.parseInt(newValue));
353 } else if(updateType == UPDATE_SEVERITY && issue.getSeverity() == Integer.parseInt(currentValue)) {
354 issue.setSeverity(Integer.parseInt(newValue));
355 } else if(updateType == UPDATE_RESOLUTION && currentValue.equalsIgnoreCase(issue.getResolution())) {
356 issue.setResolution(newValue);
357 }
358 }
359 }
360 } catch(Exception e) {
361 log.debug("Unable to update configuration data in issues.", e);
362 throw new ImportExportException("Unable to update configuration data in issues: " + e.getMessage());
363 }
364 }
365 }
366