blob: 473325a888fef86e6b2a5dfe45abdc4ac8342143 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2015 Tasktop Technologies and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Tasktop Technologies - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.internal.bugzilla.core;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.eclipse.mylyn.tasks.core.IRepositoryPerson;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper;
import org.eclipse.mylyn.tasks.core.data.TaskCommentMapper;
import org.eclipse.mylyn.tasks.core.data.TaskData;
import org.eclipse.mylyn.tasks.core.data.TaskDataCollector;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* Parser for xml bugzilla reports.
*
* @author Rob Elves
* @author Hiroyuki Inaba (internationalization)
*/
public class SaxMultiBugReportContentHandler extends DefaultHandler {
private static final String ATTRIBUTE_NAME = "name"; //$NON-NLS-1$
private static final String ID_STRING_BEGIN = " (id="; //$NON-NLS-1$
private static final String ID_STRING_END = ")"; //$NON-NLS-1$
private StringBuffer characters;
private TaskComment taskComment;
private Map<String, TaskCommentMapper> attachIdToComment = new HashMap<String, TaskCommentMapper>();
private int commentNum = 0;
private BugzillaAttachmentMapper attachment;
private final Map<String, TaskData> taskDataMap;
private TaskData repositoryTaskData;
private List<TaskComment> longDescs;
private String errorMessage = null;
private final List<BugzillaCustomField> customFields;
private final TaskDataCollector collector;
private boolean isDeprecated = false;
private boolean isPatch = false;
private String token;
private String exporter;
private TaskAttribute attachmentAttribute;
private boolean bugParseErrorOccurred;
private final BugzillaRepositoryConnector connector;
private boolean useIsPrivate;
private final TaskAttributeMapper mapper;
private final SimpleDateFormat simpleFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm"); //$NON-NLS-1$
private final SimpleDateFormat simpleFormatter_deltaTS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //$NON-NLS-1$
private String bugIDValue;
public SaxMultiBugReportContentHandler(TaskAttributeMapper mapper, TaskDataCollector collector,
Map<String, TaskData> taskDataMap, List<BugzillaCustomField> customFields,
BugzillaRepositoryConnector connector) {
this.mapper = mapper;
this.taskDataMap = taskDataMap;
this.customFields = customFields;
this.collector = collector;
this.connector = connector;
TaskRepository taskRepository = mapper.getTaskRepository();
String useParam = taskRepository.getProperty(IBugzillaConstants.BUGZILLA_INSIDER_GROUP);
useIsPrivate = (useParam == null || (useParam != null && useParam.equals("true"))); //$NON-NLS-1$
}
public boolean errorOccurred() {
return errorMessage != null;
}
public String getErrorMessage() {
return errorMessage;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
characters.append(ch, start, length);
//System.err.println(String.copyValueOf(ch, start, length));
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
characters = new StringBuffer();
BugzillaAttribute tag = BugzillaAttribute.UNKNOWN;
if (localName.startsWith(BugzillaCustomField.CUSTOM_FIELD_PREFIX)) {
return;
}
try {
tag = BugzillaAttribute.valueOf(localName.trim().toUpperCase(Locale.ENGLISH));
} catch (RuntimeException e) {
if (e instanceof IllegalArgumentException) {
// ignore unrecognized tags
return;
}
throw e;
}
switch (tag) {
case BUGZILLA:
// Note: here we can get the bugzilla version if necessary
// String version = attributes.getValue("version");
// urlbase = attributes.getValue("urlbase"); //$NON-NLS-1$
// String maintainer = attributes.getValue("maintainer");
exporter = attributes.getValue("exporter"); //$NON-NLS-1$
break;
case BUG:
if (attributes != null && (attributes.getValue("error") != null)) { //$NON-NLS-1$
errorMessage = attributes.getValue("error"); //$NON-NLS-1$
bugParseErrorOccurred = true;
repositoryTaskData = null;
}
attachIdToComment = new HashMap<String, TaskCommentMapper>();
commentNum = 0;
taskComment = null;
longDescs = new ArrayList<TaskComment>();
token = null;
bugIDValue = null;
break;
case LONG_DESC:
String is_private = attributes.getValue("isprivate"); //$NON-NLS-1$
taskComment = new TaskComment(is_private);
break;
case WHO:
if (taskComment != null) {
if (attributes != null && attributes.getLength() > 0) {
String name = attributes.getValue(ATTRIBUTE_NAME);
if (name != null && name.length() > 0) {
taskComment.authorName = name;
}
}
}
break;
case REPORTER:
if (attributes != null && attributes.getLength() > 0) {
String name = attributes.getValue(ATTRIBUTE_NAME);
if (name != null) {
BugzillaTaskDataHandler.createAttribute(repositoryTaskData, BugzillaAttribute.REPORTER_NAME)
.setValue(name);
}
}
break;
case QA_CONTACT:
if (attributes != null && attributes.getLength() > 0) {
String name = attributes.getValue(ATTRIBUTE_NAME);
if (name != null) {
BugzillaTaskDataHandler.createAttribute(repositoryTaskData, BugzillaAttribute.QA_CONTACT_NAME)
.setValue(name);
}
}
break;
case ASSIGNED_TO:
if (attributes != null && attributes.getLength() > 0) {
String name = attributes.getValue(ATTRIBUTE_NAME);
if (name != null) {
BugzillaTaskDataHandler.createAttribute(repositoryTaskData, BugzillaAttribute.ASSIGNED_TO_NAME)
.setValue(name);
}
}
break;
case ATTACHMENT:
if (attributes != null) {
isDeprecated = "1".equals(attributes.getValue(BugzillaAttribute.IS_OBSOLETE.getKey())); //$NON-NLS-1$
isPatch = "1".equals(attributes.getValue(BugzillaAttribute.IS_PATCH.getKey())); //$NON-NLS-1$
}
break;
case FLAG:
if (attributes != null && attributes.getLength() > 0) {
String name = attributes.getValue(ATTRIBUTE_NAME);
if (name != null) {
BugzillaFlagMapper mapper = new BugzillaFlagMapper(connector);
String requestee = attributes.getValue("requestee"); //$NON-NLS-1$
mapper.setRequestee(requestee);
String setter = attributes.getValue("setter"); //$NON-NLS-1$
mapper.setSetter(setter);
String status = attributes.getValue("status"); //$NON-NLS-1$
mapper.setState(status);
mapper.setFlagId(name);
String id = attributes.getValue("id"); //$NON-NLS-1$
if (id != null && !id.equals("")) { //$NON-NLS-1$
/*
* for version 3.2rc1 and 3.2.rc2 the id was not defined so we ignore
* the definition
*/
try {
mapper.setNumber(Integer.valueOf(id));
TaskAttribute attribute;
if (attachmentAttribute != null) {
attribute = attachmentAttribute.createAttribute(BugzillaAttribute.KIND_FLAG + id);
} else {
attribute = repositoryTaskData.getRoot().createAttribute(
BugzillaAttribute.KIND_FLAG + id);
}
mapper.applyTo(attribute);
} catch (NumberFormatException e) {
// ignore
}
}
}
}
break;
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
//remove whitespaces from the end of the parsed Text
while (characters.length() > 0 && Character.isWhitespace(characters.charAt(characters.length() - 1))) {
characters.setLength(characters.length() - 1);
}
String parsedText = characters.toString();
if (localName.startsWith(BugzillaCustomField.CUSTOM_FIELD_PREFIX)) {
TaskAttribute endAttribute = repositoryTaskData.getRoot().getAttribute(localName);
if (endAttribute == null) {
String desc = "???"; //$NON-NLS-1$
BugzillaCustomField customField = null;
for (BugzillaCustomField bugzillaCustomField : customFields) {
if (localName.equals(bugzillaCustomField.getName())) {
customField = bugzillaCustomField;
break;
}
}
if (customField != null) {
TaskAttribute atr = repositoryTaskData.getRoot().createAttribute(localName);
desc = customField.getDescription();
atr.getMetaData().defaults().setLabel(desc).setReadOnly(false);
atr.getMetaData().setKind(TaskAttribute.KIND_DEFAULT);
atr.getMetaData().setType(TaskAttribute.TYPE_SHORT_TEXT);
switch (customField.getFieldType()) {
case FreeText:
atr.getMetaData().setType(TaskAttribute.TYPE_SHORT_TEXT);
break;
case DropDown:
atr.getMetaData().setType(TaskAttribute.TYPE_SINGLE_SELECT);
break;
case MultipleSelection:
atr.getMetaData().setType(TaskAttribute.TYPE_MULTI_SELECT);
break;
case LargeText:
atr.getMetaData().setType(TaskAttribute.TYPE_LONG_TEXT);
break;
case DateTime:
atr.getMetaData().setType(TaskAttribute.TYPE_DATETIME);
break;
default:
List<String> options = customField.getOptions();
if (options.size() > 0) {
atr.getMetaData().setType(TaskAttribute.TYPE_SINGLE_SELECT);
} else {
atr.getMetaData().setType(TaskAttribute.TYPE_SHORT_TEXT);
}
}
atr.getMetaData().setReadOnly(false);
atr.setValue(parsedText);
}
} else {
endAttribute.addValue(parsedText);
}
}
BugzillaAttribute tag = BugzillaAttribute.UNKNOWN;
try {
tag = BugzillaAttribute.valueOf(localName.trim().toUpperCase(Locale.ENGLISH));
} catch (RuntimeException e) {
if (e instanceof IllegalArgumentException) {
// ignore unrecognized tags
return;
}
throw e;
}
switch (tag) {
case BUG_ID: {
bugIDValue = parsedText.trim();
repositoryTaskData = taskDataMap.get(parsedText.trim());
if (repositoryTaskData == null) {
errorMessage = parsedText + Messages.SaxMultiBugReportContentHandler_id_not_found;
bugParseErrorOccurred = true;
break;
}
TaskAttribute attr = repositoryTaskData.getRoot().getMappedAttribute(tag.getKey());
if (attr == null) {
attr = BugzillaTaskDataHandler.createAttribute(repositoryTaskData, tag);
}
attr.setValue(parsedText);
if (exporter != null) {
createAttrribute(exporter, BugzillaAttribute.EXPORTER_NAME);
} else {
createAttrribute("", BugzillaAttribute.EXPORTER_NAME); //$NON-NLS-1$
}
break;
}
// Comment attributes
case WHO:
if (taskComment != null) {
taskComment.author = parsedText;
}
break;
case BUG_WHEN:
if (taskComment != null) {
taskComment.createdTimeStamp = parsedText;
}
break;
case WORK_TIME:
if (taskComment != null) {
taskComment.timeWorked = parsedText;
}
break;
case THETEXT:
if (taskComment != null) {
taskComment.commentText = parsedText;
}
break;
case LONG_DESC:
if (taskComment != null) {
longDescs.add(taskComment);
}
break;
// Attachment attributes
case ATTACHID:
attachmentAttribute = repositoryTaskData.getRoot().createAttribute(
TaskAttribute.PREFIX_ATTACHMENT + parsedText);
attachment = BugzillaAttachmentMapper.createFrom(attachmentAttribute);
attachment.setLength(new Long(-1));
attachment.setAttachmentId(parsedText);
attachment.setPatch(isPatch);
attachment.setDeprecated(isDeprecated);
attachment.setToken(null);
break;
case DATE:
if (attachment != null) {
try {
attachment.setCreationDate(simpleFormatter.parse(parsedText));
break;
} catch (ParseException e) {
} catch (NumberFormatException e) {
}
}
break;
case DESC:
if (attachment != null) {
attachment.setDescription(parsedText);
}
break;
case FILENAME:
if (attachment != null) {
attachment.setFileName(parsedText);
}
break;
case CTYPE:
case TYPE:
if (attachment != null) {
attachment.setContentType(parsedText);
}
break;
case DELTA_TS:
if (attachment != null) {
try {
if (parsedText != null) {
try {
attachment.setDeltaDate(simpleFormatter_deltaTS.parse(parsedText));
} catch (ParseException e) {
}
}
} catch (NumberFormatException e) {
// ignore
}
} else {
createAttrribute(parsedText, tag);
}
break;
case SIZE:
if (attachment != null) {
try {
if (parsedText != null) {
attachment.setLength(Long.parseLong(parsedText));
}
} catch (NumberFormatException e) {
// ignore
}
}
break;
case ATTACHMENT:
if (attachment != null) {
attachment.applyTo(attachmentAttribute);
}
isPatch = false;
isDeprecated = false;
attachment = null;
attachmentAttribute = null;
break;
case DATA:
// ignored
break;
case BUGZILLA:
// ignored
break;
case BUG:
// Reached end of bug.
if (bugParseErrorOccurred) {
bugParseErrorOccurred = false;
break;
}
addDescriptionAndComments();
// Need to set LONGDESCLENGTH to number of comments + 1 for description
TaskAttribute numCommentsAttribute = repositoryTaskData.getRoot().getMappedAttribute(
BugzillaAttribute.LONGDESCLENGTH.getKey());
if (numCommentsAttribute == null) {
numCommentsAttribute = BugzillaTaskDataHandler.createAttribute(repositoryTaskData,
BugzillaAttribute.LONGDESCLENGTH);
}
numCommentsAttribute.setValue("" + commentNum); //$NON-NLS-1$
updateAttachmentMetaData();
TaskAttribute attrCreation = repositoryTaskData.getRoot().getAttribute(
BugzillaAttribute.CREATION_TS.getKey());
updateCustomFields(repositoryTaskData);
if (token != null) {
TaskAttribute tokenAttribute = BugzillaTaskDataHandler.createAttribute(repositoryTaskData,
BugzillaAttribute.TOKEN);
tokenAttribute.setValue(token);
}
// Work around (bug#285796) If planning enabled (ESTIMATE_TIME attr present) create DEADLINE attr since it should be present.
TaskAttribute estimatedTimeAttr = repositoryTaskData.getRoot().getMappedAttribute(
BugzillaAttribute.ESTIMATED_TIME.getKey());
TaskAttribute deadlineAttr = repositoryTaskData.getRoot().getMappedAttribute(
BugzillaAttribute.DEADLINE.getKey());
if (estimatedTimeAttr != null && deadlineAttr == null) {
BugzillaTaskDataHandler.createAttribute(repositoryTaskData, BugzillaAttribute.DEADLINE);
}
// Save/Add to collector. Guard against empty data sets
if (attrCreation != null && !attrCreation.equals("")) { //$NON-NLS-1$
collector.accept(repositoryTaskData);
}
repositoryTaskData = null;
break;
case BLOCKED:
// handled similarly to DEPENDSON
case DEPENDSON:
TaskAttribute blockOrDepends = repositoryTaskData.getRoot().getMappedAttribute(tag.getKey());
if (blockOrDepends == null) {
BugzillaTaskDataHandler.createAttribute(repositoryTaskData, tag).setValue(parsedText);
} else {
if (blockOrDepends.getValue().equals("")) { //$NON-NLS-1$
blockOrDepends.setValue(parsedText);
} else {
blockOrDepends.setValue(blockOrDepends.getValue() + ", " + parsedText); //$NON-NLS-1$
}
}
break;
case DUP_ID:
TaskAttribute duplicateOf = repositoryTaskData.getRoot().getMappedAttribute(tag.getKey());
if (duplicateOf == null) {
BugzillaTaskDataHandler.createAttribute(repositoryTaskData, tag).setValue(parsedText);
} else {
if (duplicateOf.getValue().equals("")) { //$NON-NLS-1$
duplicateOf.setValue(parsedText);
}
}
break;
case UNKNOWN:
//ignore
break;
case FLAG:
//ignore
break;
case TOKEN:
if (attachment != null) {
attachment.setToken(parsedText);
} else {
token = parsedText;
}
break;
case ATTACHER:
if (attachment != null) {
IRepositoryPerson author = repositoryTaskData.getAttributeMapper()
.getTaskRepository()
.createPerson(parsedText);
attachment.setAuthor(author);
}
break;
case TARGET_MILESTONE:
BugzillaUtil.createAttributeWithKindDefaultIfUsed(parsedText, tag, repositoryTaskData,
IBugzillaConstants.BUGZILLA_PARAM_USETARGETMILESTONE, true);
break;
case QA_CONTACT:
BugzillaUtil.createAttributeWithKindDefaultIfUsed(parsedText, tag, repositoryTaskData,
IBugzillaConstants.BUGZILLA_PARAM_USEQACONTACT, true);
break;
case STATUS_WHITEBOARD:
BugzillaUtil.createAttributeWithKindDefaultIfUsed(parsedText, tag, repositoryTaskData,
IBugzillaConstants.BUGZILLA_PARAM_USESTATUSWHITEBOARD, true);
break;
case CLASSIFICATION:
BugzillaUtil.createAttributeWithKindDefaultIfUsed(parsedText, tag, repositoryTaskData,
IBugzillaConstants.BUGZILLA_PARAM_USECLASSIFICATION, false);
break;
case ALIAS:
if (repositoryTaskData == null) {
repositoryTaskData = taskDataMap.get(parsedText.trim());
if (repositoryTaskData == null) {
errorMessage = parsedText + Messages.SaxMultiBugReportContentHandler_id_not_found;
bugParseErrorOccurred = true;
break;
} else {
errorMessage = null;
bugParseErrorOccurred = false;
}
}
BugzillaUtil.createAttributeWithKindDefaultIfUsed(parsedText, tag, repositoryTaskData,
IBugzillaConstants.BUGZILLA_PARAM_USEBUGALIASES, false);
TaskAttribute attr = repositoryTaskData.getRoot().getMappedAttribute(BugzillaAttribute.BUG_ID.getKey());
if (attr == null) {
attr = BugzillaTaskDataHandler.createAttribute(repositoryTaskData, BugzillaAttribute.BUG_ID);
}
attr.setValue(bugIDValue);
if (exporter != null) {
createAttrribute(exporter, BugzillaAttribute.EXPORTER_NAME);
} else {
createAttrribute("", BugzillaAttribute.EXPORTER_NAME); //$NON-NLS-1$
}
break;
case SEE_ALSO:
TaskAttribute seeAlso = repositoryTaskData.getRoot().getMappedAttribute(
BugzillaAttribute.SEE_ALSO_READ.getKey());
if (seeAlso == null) {
BugzillaUtil.createAttributeWithKindDefaultIfUsed("", tag, repositoryTaskData,
IBugzillaConstants.BUGZILLA_PARAM_USE_SEE_ALSO, false);
BugzillaUtil.createAttributeWithKindDefaultIfUsed(parsedText, BugzillaAttribute.SEE_ALSO_READ,
repositoryTaskData, IBugzillaConstants.BUGZILLA_PARAM_USE_SEE_ALSO, false);
} else {
if (seeAlso.getValue().equals("")) { //$NON-NLS-1$
seeAlso.setValue(parsedText);
} else {
seeAlso.addValue(parsedText);
}
}
break;
case COMMENTID:
if (taskComment != null) {
taskComment.id = Integer.parseInt(parsedText);
}
break;
default:
createAttrribute(parsedText, tag);
break;
}
}
private TaskAttribute createAttrribute(String parsedText, BugzillaAttribute tag) {
TaskAttribute attribute = repositoryTaskData.getRoot().getMappedAttribute(tag.getKey());
if (attribute == null) {
attribute = BugzillaTaskDataHandler.createAttribute(repositoryTaskData, tag);
attribute.setValue(parsedText);
} else {
attribute.addValue(parsedText);
}
return attribute;
}
private void updateCustomFields(TaskData taskData) {
RepositoryConfiguration config = connector.getRepositoryConfiguration(repositoryTaskData.getRepositoryUrl());
if (config != null) {
for (BugzillaCustomField bugzillaCustomField : config.getCustomFields()) {
TaskAttribute atr = taskData.getRoot().getAttribute(bugzillaCustomField.getName());
if (atr == null) {
atr = taskData.getRoot().createAttribute(bugzillaCustomField.getName());
}
if (atr != null) {
atr.getMetaData().defaults().setLabel(bugzillaCustomField.getDescription());
atr.getMetaData().setKind(TaskAttribute.KIND_DEFAULT);
switch (bugzillaCustomField.getFieldType()) {
case FreeText:
atr.getMetaData().setType(TaskAttribute.TYPE_SHORT_TEXT);
break;
case DropDown:
atr.getMetaData().setType(TaskAttribute.TYPE_SINGLE_SELECT);
break;
case MultipleSelection:
atr.getMetaData().setType(TaskAttribute.TYPE_MULTI_SELECT);
break;
case LargeText:
atr.getMetaData().setType(TaskAttribute.TYPE_LONG_TEXT);
break;
case DateTime:
atr.getMetaData().setType(TaskAttribute.TYPE_DATETIME);
break;
case BugId:
atr.getMetaData().setType(TaskAttribute.TYPE_TASK_DEPENDENCY);
break;
default:
List<String> options = bugzillaCustomField.getOptions();
if (options.size() > 0) {
atr.getMetaData().setType(TaskAttribute.TYPE_SINGLE_SELECT);
} else {
atr.getMetaData().setType(TaskAttribute.TYPE_SHORT_TEXT);
}
}
atr.getMetaData().setReadOnly(false);
}
}
}
}
private void updateAttachmentMetaData() {
List<TaskAttribute> taskAttachments = repositoryTaskData.getAttributeMapper().getAttributesByType(
repositoryTaskData, TaskAttribute.TYPE_ATTACHMENT);
for (TaskAttribute attachment : taskAttachments) {
BugzillaAttachmentMapper attachmentMapper = BugzillaAttachmentMapper.createFrom(attachment);
if (attachmentMapper.getAuthor() == null || attachmentMapper.getCreationDate() == null) {
TaskCommentMapper taskComment = attachIdToComment.get(attachmentMapper.getAttachmentId());
if (taskComment != null) {
attachmentMapper.setAuthor(taskComment.getAuthor());
attachmentMapper.setCreationDate(taskComment.getCreationDate());
}
}
attachmentMapper.setUrl(repositoryTaskData.getRepositoryUrl()
+ IBugzillaConstants.URL_GET_ATTACHMENT_SUFFIX + attachmentMapper.getAttachmentId());
attachmentMapper.applyTo(attachment);
}
}
private void addDescriptionAndComments() {
int longDescsSize = longDescs.size() - 1;
commentNum = 1;
if (longDescsSize == 0) {
addDescription(longDescs.get(0));
} else if (longDescsSize == 1) {
if (longDescs.get(0).createdTimeStamp.compareTo(longDescs.get(1).createdTimeStamp) <= 0) {
// if created_0 is equal to created_1 we assume that longDescs at index 0 is the description.
addDescription(longDescs.get(0));
addComment(longDescs.get(1));
} else {
addDescription(longDescs.get(1));
addComment(longDescs.get(0));
}
} else if (longDescsSize > 1) {
String created_0 = longDescs.get(0).createdTimeStamp;
String created_1 = longDescs.get(1).createdTimeStamp;
String created_n = longDescs.get(longDescsSize).createdTimeStamp;
if (created_0.compareTo(created_1) <= 0 && created_0.compareTo(created_n) < 0) {
// if created_0 is equal to created_1 we assume that longDescs at index 0 is the description.
addDescription(longDescs.get(0));
if (created_1.compareTo(created_n) < 0) {
for (int i = 1; i <= longDescsSize; i++) {
addComment(longDescs.get(i));
}
} else {
for (int i = longDescsSize; i > 0; i--) {
addComment(longDescs.get(i));
}
}
} else {
addDescription(longDescs.get(longDescsSize));
if (created_0.compareTo(created_1) < 0) {
for (int i = 0; i < longDescsSize; i++) {
addComment(longDescs.get(i));
}
} else {
for (int i = longDescsSize - 1; i >= 0; i--) {
addComment(longDescs.get(i));
}
}
}
}
}
private void addDescription(TaskComment comment) {
TaskAttribute attrDescription = BugzillaTaskDataHandler.createAttribute(repositoryTaskData,
BugzillaAttribute.LONG_DESC);
TaskAttribute idAttribute = attrDescription.createAttribute(IBugzillaConstants.BUGZILLA_DESCRIPTION_ID);
TaskAttribute isprivateAttribute = attrDescription.createAttribute(IBugzillaConstants.BUGZILLA_DESCRIPTION_IS_PRIVATE);
attrDescription.setValue(comment.commentText);
idAttribute.setValue(Integer.toString(comment.id));
if (comment.isPrivate != null) {
isprivateAttribute.setValue(comment.isPrivate);
}
if (!useIsPrivate) {
if ("1".equals(comment.isPrivate)) { //$NON-NLS-1$
TaskRepository taskRepository = mapper.getTaskRepository();
taskRepository.setProperty(IBugzillaConstants.BUGZILLA_INSIDER_GROUP, "true"); //$NON-NLS-1$
useIsPrivate = true;
}
}
}
private void addComment(TaskComment comment) {
TaskAttribute attribute = repositoryTaskData.getRoot().createAttribute(
TaskAttribute.PREFIX_COMMENT + commentNum);
TaskCommentMapper taskComment = TaskCommentMapper.createFrom(attribute);
taskComment.setCommentId(comment.id + ""); //$NON-NLS-1$
taskComment.setNumber(commentNum);
taskComment.setUrl(repositoryTaskData.getRepositoryUrl() + "/show_bug.cgi?id=" //$NON-NLS-1$
+ repositoryTaskData.getTaskId() + "#c" + commentNum); //$NON-NLS-1$
IRepositoryPerson author = repositoryTaskData.getAttributeMapper()
.getTaskRepository()
.createPerson(comment.author);
author.setName(comment.authorName);
taskComment.setAuthor(author);
if (useIsPrivate) {
taskComment.setIsPrivate("1".equals(comment.isPrivate)); //$NON-NLS-1$
} else {
if ("1".equals(comment.isPrivate)) { //$NON-NLS-1$
TaskRepository taskRepository = mapper.getTaskRepository();
taskRepository.setProperty(IBugzillaConstants.BUGZILLA_INSIDER_GROUP, "true"); //$NON-NLS-1$
useIsPrivate = true;
taskComment.setIsPrivate("1".equals(comment.isPrivate)); //$NON-NLS-1$
} else {
taskComment.setIsPrivate(null);
}
}
TaskAttribute attrTimestamp = attribute.createAttribute(BugzillaAttribute.BUG_WHEN.getKey());
attrTimestamp.setValue(comment.createdTimeStamp);
taskComment.setCreationDate(repositoryTaskData.getAttributeMapper().getDateValue(attrTimestamp));
if (comment.commentText != null) {
String commentText = comment.commentText.trim();
taskComment.setText(commentText);
}
taskComment.applyTo(attribute);
commentNum++;
if (comment.timeWorked != null) {
TaskAttribute workTime = BugzillaTaskDataHandler.createAttribute(attribute, BugzillaAttribute.WORK_TIME);
workTime.setValue(comment.timeWorked);
}
parseAttachment(taskComment);
}
/** determines attachment id from comment */
private void parseAttachment(TaskCommentMapper comment) {
String attachmentID = ""; //$NON-NLS-1$
String commentText = comment.getText();
int firstDelimiter = commentText.indexOf("\n"); //$NON-NLS-1$
if (firstDelimiter < 0) {
firstDelimiter = commentText.length();
}
int startIndex = commentText.indexOf(ID_STRING_BEGIN);
if (startIndex > 0 && startIndex < firstDelimiter) {
int endIndex = commentText.indexOf(ID_STRING_END, startIndex);
if (endIndex > 0 && endIndex < firstDelimiter) {
startIndex += ID_STRING_BEGIN.length();
int p = startIndex;
while (p < endIndex) {
char c = commentText.charAt(p);
if (c < '0' || c > '9') {
break;
}
p++;
}
if (p == endIndex) {
attachmentID = commentText.substring(startIndex, endIndex);
if (!attachmentID.equals("")) { //$NON-NLS-1$
attachIdToComment.put(attachmentID, comment);
}
}
}
}
}
private static class TaskComment {
@SuppressWarnings("unused")
public int number;
public int id;
public String author;
public String authorName;
public String createdTimeStamp;
public String commentText;
public String timeWorked;
public String isPrivate;
public TaskComment(String isprivate) {
this.isPrivate = isprivate;
}
}
}