1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.itracker.web.util;
20
21 import org.apache.log4j.Logger;
22 import org.itracker.core.resources.ITrackerResources;
23 import org.itracker.model.*;
24 import org.itracker.model.util.IssueUtilities;
25 import org.itracker.model.util.UserUtilities;
26 import org.xml.sax.Attributes;
27 import org.xml.sax.SAXException;
28 import org.xml.sax.helpers.DefaultHandler;
29
30 import java.util.*;
31
32
33
34
35
36
37 public class ImportHandler extends DefaultHandler implements ImportExportTags {
38
39 private final Logger logger;
40 private List<AbstractEntity> items;
41 private StringBuffer tagBuffer;
42 private SAXException endException;
43
44 private AbstractEntity parentModel;
45 private AbstractEntity childModel;
46 private List<Object> itemList;
47 private String tempStorage;
48
49 public ImportHandler() {
50 this.logger = Logger.getLogger(getClass());
51 this.items = new ArrayList<>();
52 this.endException = null;
53 }
54
55 public AbstractEntity[] getModels() {
56 return items.toArray(new AbstractEntity[items.size()]);
57 }
58
59 @Override
60 public void startDocument() {
61 logger.debug("Started import xml parsing.");
62 }
63
64 @Override
65 public void endDocument() {
66 logger.debug("Completed import xml parsing.");
67 }
68
69 @Override
70 public void startElement(String uri, String name, String qName, Attributes atts) throws SAXException {
71 logger.debug("Parsing import tag " + qName);
72
73 if (endException != null) {
74 throw endException;
75 }
76
77
78 tempStorage = "";
79 try {
80 if (TAG_COMPONENT.equals(qName)) {
81 String id = atts.getValue(ATTR_SYSTEMID);
82 if (id == null) {
83 throw new SAXException("Attribute " + ATTR_SYSTEMID + " was null for component.");
84 }
85
86
87 childModel = new Component((Project) parentModel, atts.getValue(ATTR_ID));
88 childModel.setId(new Integer(id));
89 } else if (TAG_COMPONENTS.equals(qName)) {
90 itemList = new ArrayList<>();
91 } else if (TAG_CONFIGURATION.equals(qName)) {
92 parentModel = new SystemConfiguration();
93 } else if (TAG_CUSTOM_FIELD.equals(qName)) {
94 String id = atts.getValue(ATTR_SYSTEMID);
95 if (id == null) {
96 throw new SAXException("Attribute " + ATTR_SYSTEMID + " was null for issue.");
97 }
98
99 childModel = new CustomField();
100 childModel.setId(new Integer(id));
101 } else if (TAG_CUSTOM_FIELD_OPTION.equals(qName)) {
102 tempStorage = ITrackerResources.unescapeUnicodeString(atts.getValue(ATTR_VALUE));
103 } else if (TAG_CUSTOM_FIELDS.equals(qName)) {
104 itemList = new ArrayList<>();
105 } else if (TAG_HISTORY_ENTRY.equals(qName)) {
106 String creatorId = atts.getValue(ATTR_CREATOR_ID);
107 String date = atts.getValue(ATTR_DATE);
108 String status = atts.getValue(ATTR_STATUS);
109 if (creatorId == null) {
110 throw new SAXException("Attribute " + ATTR_CREATOR_ID + " was null for issue history.");
111 } else if (date == null) {
112 throw new SAXException("Attribute date was null for issue history.");
113 }
114
115 childModel = new IssueHistory();
116 ((IssueHistory) childModel).setUser((User) findModel(creatorId));
117 ((IssueHistory) childModel).setStatus(status != null && !status.equals("") ? Integer.parseInt(status) : IssueUtilities.HISTORY_STATUS_AVAILABLE);
118 childModel.setCreateDate(getDateValue(date, qName));
119 tagBuffer = new StringBuffer();
120 } else if (TAG_ISSUE.equals(qName)) {
121 String id = atts.getValue(ATTR_SYSTEMID);
122 if (id == null) {
123 throw new SAXException("Attribute " + ATTR_SYSTEMID + " was null for issue.");
124 }
125
126 parentModel = new Issue();
127 parentModel.setId(new Integer(id));
128 } else if (TAG_ISSUE_ATTACHMENT.equals(qName)) {
129 childModel = new IssueAttachment();
130 } else if (TAG_ISSUE_ATTACHMENTS.equals(qName)) {
131 itemList = new ArrayList<Object>();
132 } else if (TAG_ISSUE_COMPONENTS.equals(qName)) {
133 itemList = new ArrayList<Object>();
134 } else if (TAG_ISSUE_FIELD.equals(qName)) {
135 String id = atts.getValue(ATTR_ID);
136 if (id == null) {
137 throw new SAXException("Attribute " + ATTR_SYSTEMID + " was null for issue field.");
138 }
139 childModel = new IssueField((Issue) parentModel, (CustomField) findModel(id));
140 } else if (TAG_ISSUE_FIELDS.equals(qName)) {
141 itemList = new ArrayList<>();
142 } else if (TAG_ISSUE_HISTORY.equals(qName)) {
143 itemList = new ArrayList<>();
144 } else if (TAG_ISSUE_VERSIONS.equals(qName)) {
145 itemList = new ArrayList<>();
146 } else if (TAG_PROJECT.equals(qName)) {
147 String id = atts.getValue(ATTR_SYSTEMID);
148 if (id == null) {
149 throw new SAXException("Attribute " + ATTR_SYSTEMID + " was null for project.");
150 }
151
152 parentModel = new Project();
153 parentModel.setId(new Integer(id));
154 } else if (TAG_PROJECT_FIELDS.equals(qName)) {
155 itemList = new ArrayList<>();
156 } else if (TAG_PROJECT_OWNERS.equals(qName)) {
157 itemList = new ArrayList<>();
158 } else if (TAG_RESOLUTION.equals(qName)) {
159 String value = atts.getValue(ATTR_VALUE);
160 String order = atts.getValue(ATTR_ORDER);
161
162 childModel = new Configuration(Configuration.Type.resolution, value, Integer.parseInt(order));
163 tagBuffer = new StringBuffer();
164 } else if (TAG_SEVERITY.equals(qName)) {
165 String value = atts.getValue(ATTR_VALUE);
166 String order = atts.getValue(ATTR_ORDER);
167
168 childModel = new Configuration(Configuration.Type.severity, value, Integer.parseInt(order));
169 tagBuffer = new StringBuffer();
170 } else if (TAG_STATUS.equals(qName)) {
171 String value = atts.getValue(ATTR_VALUE);
172 String order = atts.getValue(ATTR_ORDER);
173
174 childModel = new Configuration(Configuration.Type.status, value, Integer.parseInt(order));
175 tagBuffer = new StringBuffer();
176 } else if (TAG_USER.equals(qName)) {
177 String id = atts.getValue(ATTR_SYSTEMID);
178 if (id == null) {
179 throw new SAXException("Attribute " + ATTR_SYSTEMID + " was null for user.");
180 }
181
182 parentModel = new User();
183 parentModel.setId(new Integer(id));
184 } else if (TAG_VERSION.equals(qName)) {
185 String id = atts.getValue(ATTR_SYSTEMID);
186 if (id == null) {
187 throw new SAXException("Attribute " + ATTR_SYSTEMID + " was null for version.");
188 }
189
190
191 childModel = new Version((Project) parentModel, atts.getValue(ATTR_ID));
192 childModel.setId(new Integer(id));
193 } else if (TAG_VERSIONS.equals(qName)) {
194 itemList = new ArrayList<>();
195 } else {
196 tagBuffer = new StringBuffer();
197 }
198 } catch (NumberFormatException nfe) {
199 throw new SAXException("Attribute in " + qName + " did not contain a numeric value.");
200 }
201 }
202
203 @Override
204 public void endElement(String uri, String name, String qName) throws SAXException {
205 logger.debug("Completing import tag " + qName);
206
207 try {
208 if (TAG_ISSUE.equals(qName) || TAG_PROJECT.equals(qName) || TAG_USER.equals(qName) || TAG_CONFIGURATION.equals(qName)) {
209 items.add((AbstractEntity) parentModel.clone());
210 parentModel = null;
211 childModel = null;
212 itemList = null;
213 } else if (TAG_RESOLUTION.equals(qName) || TAG_SEVERITY.equals(qName) || TAG_STATUS.equals(qName)) {
214 ((Configuration) childModel).setName(getBuffer());
215 items.add((AbstractEntity) childModel.clone());
216 ((SystemConfiguration) parentModel).addConfiguration((Configuration) childModel);
217 childModel = null;
218 } else if (TAG_COMPONENT.equals(qName) || TAG_VERSION.equals(qName) || TAG_CUSTOM_FIELD.equals(qName)) {
219
220
221 items.add((AbstractEntity) childModel.clone());
222 itemList.add(childModel.clone());
223 childModel = null;
224 } else if (TAG_HISTORY_ENTRY.equals(qName)) {
225 ((IssueHistory) childModel).setDescription(getBuffer());
226 itemList.add(childModel.clone());
227 childModel = null;
228 } else if (TAG_ISSUE_ATTACHMENT.equals(qName)) {
229 itemList.add(childModel.clone());
230 childModel = null;
231 } else if (TAG_ISSUE_FIELD.equals(qName)) {
232 itemList.add(childModel.clone());
233 childModel = null;
234 } else if (TAG_COMPONENTS.equals(qName)) {
235 List<Component> itemListArray = new ArrayList<>();
236 for (Object anItemList : itemList) {
237 itemListArray.add((Component) anItemList);
238 }
239 ((Project) parentModel).setComponents(itemListArray);
240 } else if (TAG_COMPONENT_DESCRIPTION.equals(qName)) {
241 ((Component) childModel).setDescription(getBuffer());
242 } else if (TAG_COMPONENT_ID.equals(qName)) {
243 if (itemList == null) {
244 itemList = new ArrayList<>();
245 }
246 itemList.add(findModel(getBuffer()));
247 } else if (TAG_COMPONENT_NAME.equals(qName)) {
248 ((Component) childModel).setName(getBuffer());
249 } else if (TAG_CONFIGURATION_VERSION.equals(qName)) {
250 ((SystemConfiguration) parentModel).setVersion(getBuffer());
251 } else if (TAG_CREATE_DATE.equals(qName)) {
252 parentModel.setCreateDate(getDateValue(getBuffer(), qName));
253 } else if (TAG_CREATOR.equals(qName)) {
254 ((Issue) parentModel).setCreator((User) findModel(getBuffer()));
255 } else if (TAG_CUSTOM_FIELDS.equals(qName)) {
256 List<CustomField> itemListArray = new ArrayList<>();
257 for (Object anItemList : itemList) {
258 itemListArray.add((CustomField) anItemList);
259 }
260 ((SystemConfiguration) parentModel).setCustomFields(itemListArray);
261 } else if (TAG_CUSTOM_FIELD_DATEFORMAT.equals(qName)) {
262 ((CustomField) childModel).setDateFormat(getBuffer());
263 } else if (TAG_CUSTOM_FIELD_LABEL.equals(qName)) {
264
265
266 } else if (TAG_CUSTOM_FIELD_OPTION.equals(qName)) {
267 ((CustomField) childModel).addOption(tempStorage, getBuffer());
268 } else if (TAG_CUSTOM_FIELD_REQUIRED.equals(qName)) {
269 ((CustomField) childModel).setRequired(("true".equalsIgnoreCase(getBuffer())));
270 } else if (TAG_CUSTOM_FIELD_SORTOPTIONS.equals(qName)) {
271 ((CustomField) childModel).setSortOptionsByName(("true".equalsIgnoreCase(getBuffer())));
272 } else if (TAG_CUSTOM_FIELD_TYPE.equals(qName)) {
273 final String s = getBuffer();
274 try {
275
276 int i = Integer.valueOf(s);
277 ((CustomField) childModel).setFieldType(CustomField.Type.valueOf(i));
278 } catch (RuntimeException e) {
279 try {
280 ((CustomField) childModel).setFieldType(CustomField.Type.valueOf(s));
281 } catch (RuntimeException re) {
282 throw new SAXException("Could not convert string buffer to type value.");
283 }
284 }
285 } else if (TAG_EMAIL.equals(qName)) {
286 ((User) parentModel).setEmail(getBuffer());
287 } else if (TAG_FIRST_NAME.equals(qName)) {
288 ((User) parentModel).setFirstName(getBuffer());
289 } else if (TAG_ISSUE_ATTACHMENTS.equals(qName)) {
290 List<IssueAttachment> itemListArray = new ArrayList<>();
291 for (Object anItemList : itemList) {
292 itemListArray.add((IssueAttachment) anItemList);
293 }
294 ((Issue) parentModel).setAttachments(itemListArray);
295 } else if (TAG_ISSUE_ATTACHMENT_CREATOR.equals(qName)) {
296 ((IssueAttachment) childModel).setUser((User) findModel(getBuffer()));
297 } else if (TAG_ISSUE_ATTACHMENT_DESCRIPTION.equals(qName)) {
298 ((IssueAttachment) childModel).setDescription(getBuffer());
299 } else if (TAG_ISSUE_ATTACHMENT_FILENAME.equals(qName)) {
300 ((IssueAttachment) childModel).setFileName(getBuffer());
301 } else if (TAG_ISSUE_ATTACHMENT_ORIGFILE.equals(qName)) {
302 ((IssueAttachment) childModel).setOriginalFileName(getBuffer());
303 } else if (TAG_ISSUE_ATTACHMENT_SIZE.equals(qName)) {
304 ((IssueAttachment) childModel).setSize(getBufferAsLong());
305 } else if (TAG_ISSUE_ATTACHMENT_TYPE.equals(qName)) {
306 ((IssueAttachment) childModel).setType(getBuffer());
307 } else if (TAG_ISSUE_COMPONENTS.equals(qName)) {
308 List<Component> itemListArray = new ArrayList<>();
309 for (Object anItemList : itemList) {
310 itemListArray.add((Component) anItemList);
311 }
312 ((Issue) parentModel).setComponents(itemListArray);
313 } else if (TAG_ISSUE_DESCRIPTION.equals(qName)) {
314 ((Issue) parentModel).setDescription(getBuffer());
315 } else if (TAG_ISSUE_FIELDS.equals(qName)) {
316 List<IssueField> itemListArray = new ArrayList<>();
317 for (int i = 0; i < itemList.size(); i++) {
318 itemListArray.add(i, (IssueField) itemList.get(i));
319 }
320 ((Issue) parentModel).setFields(itemListArray);
321 } else if (TAG_ISSUE_HISTORY.equals(qName)) {
322 List<IssueHistory> itemListArray = new ArrayList<>();
323 for (int i = 0; i < itemList.size(); i++) {
324 itemListArray.add(i, (IssueHistory) itemList.get(i));
325 }
326 ((Issue) parentModel).setHistory(itemListArray);
327 } else if (TAG_ISSUE_PROJECT.equals(qName)) {
328 ((Issue) parentModel).setProject((Project) findModel(getBuffer()));
329 } else if (TAG_ISSUE_RESOLUTION.equals(qName)) {
330 ((Issue) parentModel).setResolution(getBuffer());
331 } else if (TAG_ISSUE_SEVERITY.equals(qName)) {
332 ((Issue) parentModel).setSeverity(getBufferAsInt());
333 } else if (TAG_ISSUE_STATUS.equals(qName)) {
334 ((Issue) parentModel).setStatus(getBufferAsInt());
335 } else if (TAG_ISSUE_VERSIONS.equals(qName)) {
336 List<Version> itemListArray = new ArrayList<>();
337 for (int i = 0; i < itemList.size(); i++) {
338 itemListArray.add(i, (Version) itemList.get(i));
339 }
340 ((Issue) parentModel).setVersions(itemListArray);
341 } else if (TAG_LAST_MODIFIED.equals(qName)) {
342 parentModel.setLastModifiedDate(getDateValue(getBuffer(), qName));
343 } else if (TAG_LAST_NAME.equals(qName)) {
344 ((User) parentModel).setLastName(getBuffer());
345 } else if (TAG_LOGIN.equals(qName)) {
346 ((User) parentModel).setLogin(getBuffer());
347 } else if (TAG_OWNER.equals(qName)) {
348 ((Issue) parentModel).setOwner((User) findModel(getBuffer()));
349 } else if (TAG_PROJECT_NAME.equals(qName)) {
350 ((Project) parentModel).setName(getBuffer());
351 } else if (TAG_PROJECT_DESCRIPTION.equals(qName)) {
352 ((Project) parentModel).setDescription(getBuffer());
353 } else if (TAG_PROJECT_FIELDS.equals(qName)) {
354 List<CustomField> itemListArray = new ArrayList<>();
355 for (int i = 0; i < itemList.size(); i++) {
356 itemListArray.add(i, (CustomField) itemList.get(i));
357 }
358 ((Project) parentModel).setCustomFields(itemListArray);
359 } else if (TAG_PROJECT_FIELD_ID.equals(qName)) {
360 itemList.add(findModel(getBuffer()));
361 } else if (TAG_PROJECT_OPTIONS.equals(qName)) {
362 ((Project) parentModel).setOptions(getBufferAsInt());
363 } else if (TAG_PROJECT_OWNERS.equals(qName)) {
364 List<User> itemListArray = new ArrayList<>();
365 for (int i = 0; i < itemList.size(); i++) {
366 itemListArray.add(i, (User) itemList.get(i));
367 }
368 ((Project) parentModel).setOwners(itemListArray);
369 } else if (TAG_PROJECT_OWNER_ID.equals(qName)) {
370 itemList.add(findModel(getBuffer()));
371 } else if (TAG_PROJECT_STATUS.equals(qName)) {
372
373 ((Project) parentModel).setStatus(Status.ACTIVE);
374 try {
375 ((Project) parentModel).setStatus(Status.valueOf(getBuffer().toUpperCase()));
376 } catch (RuntimeException re) {
377
378 }
379 } else if (TAG_SUPER_USER.equals(qName)) {
380 ((User) parentModel).setSuperUser(("true".equalsIgnoreCase(getBuffer())));
381 } else if (TAG_TARGET_VERSION_ID.equals(qName)) {
382 ((Issue) parentModel).setTargetVersion((Version) findModel(getBuffer()));
383 } else if (TAG_USER_STATUS.equals(qName)) {
384
385 ((User) parentModel).setStatus(UserUtilities.STATUS_LOCKED);
386
387 String currBuffer = getBuffer();
388 try {
389 ((User)parentModel).setStatus(Integer.parseInt(currBuffer));
390 } catch (RuntimeException re) {
391 HashMap<String, String> userStatuses = UserUtilities.getStatusNames(EXPORT_LOCALE);
392 for (String key : userStatuses.keySet()) {
393 String keyValue = userStatuses.get(key);
394 if (keyValue != null && keyValue.equalsIgnoreCase(currBuffer)) {
395 ((User) parentModel).setStatus(Integer.parseInt(key));
396 break;
397 }
398 }
399 }
400 } else if (TAG_VERSIONS.equals(qName)) {
401 List<Version> itemListArray = new ArrayList<>();
402 for (int i = 0; i < itemList.size(); i++) {
403 itemListArray.add(i, (Version) itemList.get(i));
404 }
405 ((Project) parentModel).setVersions(itemListArray);
406 } else if (TAG_VERSION_DESCRIPTION.equals(qName)) {
407 ((Version) childModel).setDescription(getBuffer());
408 } else if (TAG_VERSION_ID.equals(qName)) {
409 if (itemList == null) {
410 itemList = new ArrayList<>();
411 }
412 itemList.add(findModel(getBuffer()));
413 } else if (TAG_VERSION_NUMBER.equals(qName)) {
414 ((Version) childModel).setVersionInfo(getBuffer());
415 }
416 } catch (RuntimeException e) {
417 logger.debug("endElement: RuntimeException importing data.", e);
418 endException = new SAXException("Error processing tag " + qName + ": " + e.getMessage());
419 throw endException;
420 } catch (SAXException e) {
421 logger.debug("endElement: SAXException importing data.", e);
422 throw e;
423 } catch (CloneNotSupportedException e) {
424 logger.debug("endElement: CloneNotSupportedException importing data.", e);
425 endException = new SAXException("Error processing tag " + qName + ": " + e.getMessage());
426 throw endException;
427 }
428 tagBuffer = null;
429 }
430
431 @Override
432 public void characters(char[] ch, int start, int length) {
433 logger.debug("Read " + ch.length + " Start: " + start + " Length: " + length);
434 logger.debug("String: " + new String(ch, start, length));
435 if (tagBuffer != null) {
436 tagBuffer.append(ITrackerResources.unescapeUnicodeString(new String(ch, start, length)));
437 }
438 }
439
440 private String getBuffer() {
441 if (tagBuffer == null) {
442 return "";
443 } else {
444 return tagBuffer.toString();
445 }
446 }
447
448 private int getBufferAsInt() throws SAXException {
449 if (tagBuffer == null) {
450 return -1;
451 } else {
452 try {
453 return Integer.parseInt(tagBuffer.toString());
454 } catch (NumberFormatException nfe) {
455 throw new SAXException("Could not convert string buffer to int value.");
456 }
457 }
458 }
459
460 private long getBufferAsLong() throws SAXException {
461 if (tagBuffer == null) {
462 return -1;
463 } else {
464 try {
465 return Long.parseLong(tagBuffer.toString());
466 } catch (NumberFormatException nfe) {
467 throw new SAXException("Could not convert string buffer to long value.");
468 }
469 }
470 }
471
472 private AbstractEntity findModel(String itemTypeId) {
473 if (itemTypeId != null && !itemTypeId.equals("")) {
474 for (AbstractEntity model : items) {
475 if (getModelTypeIdString(model).equalsIgnoreCase(itemTypeId)) {
476 return model;
477 }
478 }
479 }
480 logger.debug("Unable to find model id " + itemTypeId + " during import.");
481 return null;
482 }
483
484 private String getModelTypeIdString(AbstractEntity model) {
485 String idString = "UNKNOWN";
486
487 if (model != null && model.getId() != null) {
488 String type = "";
489 if (model instanceof Component) {
490 type = TAG_COMPONENT;
491 } else if (model instanceof CustomField) {
492 type = TAG_CUSTOM_FIELD;
493 } else if (model instanceof Issue) {
494 type = TAG_ISSUE;
495 } else if (model instanceof Project) {
496 type = TAG_PROJECT;
497 } else if (model instanceof User) {
498 type = TAG_USER;
499 } else if (model instanceof Version) {
500 type = TAG_VERSION;
501 }
502
503 idString = type + model.getId();
504 }
505
506 return idString;
507 }
508
509 private Date getDateValue(String dateString, String qName) throws SAXException {
510 if (dateString == null || "".equals(dateString)) {
511 return new Date();
512 }
513
514 try {
515 return DATE_FORMATTER.parse(dateString);
516 } catch (Exception e) {
517 throw new SAXException("Value in " + qName + " did not contain a valid date value.");
518 }
519 }
520 }