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