| /******************************************************************************* |
| * Copyright (c) 2004, 2012 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.Date; |
| import java.util.LinkedHashMap; |
| import java.util.List; |
| 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.TaskAttachmentMapper; |
| import org.eclipse.mylyn.tasks.core.data.TaskAttribute; |
| import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper; |
| |
| /** |
| * @author Rob Elves |
| * @author Frank Becker |
| */ |
| public class BugzillaAttributeMapper extends TaskAttributeMapper { |
| |
| private static final String dateFormat_1 = "yyyy-MM-dd HH:mm:ss"; //$NON-NLS-1$ |
| |
| private static final String dateFormat_2 = "yyyy-MM-dd HH:mm"; //$NON-NLS-1$ |
| |
| private static final String dateFormat_3 = "yyyy-MM-dd"; //$NON-NLS-1$ |
| |
| private static final String dateFormat_1_TimeZone = "yyyy-MM-dd HH:mm:ss Z"; //$NON-NLS-1$ |
| |
| private static final String dateFormat_2_TimeZone = "yyyy-MM-dd HH:mm z"; //$NON-NLS-1$ |
| |
| private static final String dateFormat_3_TimeZone = "yyyy-MM-dd z"; //$NON-NLS-1$ |
| |
| // Order is significant |
| private static final String[] dateFormats = { dateFormat_1_TimeZone, dateFormat_1, dateFormat_2_TimeZone, |
| dateFormat_2, dateFormat_3_TimeZone, dateFormat_3 }; |
| |
| private final BugzillaRepositoryConnector connector; |
| |
| public BugzillaAttributeMapper(TaskRepository taskRepository, BugzillaRepositoryConnector connector) { |
| super(taskRepository); |
| this.connector = connector; |
| } |
| |
| @Override |
| public Date getDateValue(TaskAttribute attribute) { |
| if (attribute == null) { |
| return null; |
| } |
| Date parsedDate = parseDate(attribute.getValue()); |
| if (parsedDate != null) { |
| return parsedDate; |
| } |
| return super.getDateValue(attribute); |
| } |
| |
| @Override |
| public boolean getBooleanValue(TaskAttribute attribute) { |
| if (attribute.getValue().equals("1")) { //$NON-NLS-1$ |
| return true; |
| } else { |
| return false; |
| } |
| } |
| |
| @Override |
| public void setBooleanValue(TaskAttribute attribute, Boolean value) { |
| if (value == null) { |
| attribute.setValue("0"); //$NON-NLS-1$ |
| } else if (value) { |
| attribute.setValue("1"); //$NON-NLS-1$ |
| } else { |
| attribute.setValue("0"); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Note: Date formatter constructed within method for thread safety |
| */ |
| public static final Date parseDate(String dateString) { |
| for (String format : dateFormats) { |
| try { |
| SimpleDateFormat simpleFormatter = new SimpleDateFormat(format); |
| return simpleFormatter.parse(dateString); |
| } catch (ParseException e) { |
| } catch (NumberFormatException e) { |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public void setDateValue(TaskAttribute attribute, Date date) { |
| if (date != null) { |
| |
| RepositoryConfiguration repositoryConfiguration; |
| BugzillaVersion bugzillaVersion = null; |
| repositoryConfiguration = connector.getRepositoryConfiguration(getTaskRepository().getUrl()); |
| if (repositoryConfiguration != null) { |
| bugzillaVersion = repositoryConfiguration.getInstallVersion(); |
| } else { |
| bugzillaVersion = BugzillaVersion.MIN_VERSION; |
| } |
| |
| SimpleDateFormat comment_creation_ts_Format; |
| SimpleDateFormat attachment_creation_ts_Format; |
| |
| String dateString = null; |
| String attributeId = attribute.getId(); |
| |
| if (attributeId.equals(BugzillaAttribute.DELTA_TS.getKey())) { |
| dateString = new SimpleDateFormat(dateFormat_1).format(date); |
| } else if (attributeId.equals(BugzillaAttribute.CREATION_TS.getKey())) { |
| dateString = new SimpleDateFormat(dateFormat_2).format(date); |
| } else if (attributeId.equals(BugzillaAttribute.BUG_WHEN.getKey())) { |
| if (bugzillaVersion.compareMajorMinorOnly(BugzillaVersion.BUGZILLA_2_22) < 0) { |
| comment_creation_ts_Format = new SimpleDateFormat(dateFormat_2); |
| } else { |
| comment_creation_ts_Format = new SimpleDateFormat(dateFormat_1); |
| } |
| dateString = comment_creation_ts_Format.format(date); |
| } else if (attributeId.equals(BugzillaAttribute.DATE.getKey())) { |
| if (bugzillaVersion.compareMajorMinorOnly(BugzillaVersion.BUGZILLA_2_22) < 0) { |
| attachment_creation_ts_Format = new SimpleDateFormat(dateFormat_2); |
| } else { |
| attachment_creation_ts_Format = new SimpleDateFormat(dateFormat_1); |
| } |
| dateString = attachment_creation_ts_Format.format(date); |
| } else if (attributeId.equals(BugzillaAttribute.DEADLINE.getKey())) { |
| dateString = new SimpleDateFormat(dateFormat_3).format(date); |
| } else if (attributeId.startsWith(BugzillaCustomField.CUSTOM_FIELD_PREFIX)) { |
| dateString = new SimpleDateFormat(dateFormat_1).format(date); |
| } |
| |
| if (dateString == null) { |
| super.setDateValue(attribute, date); |
| } else { |
| attribute.setValue(dateString); |
| } |
| |
| } else { |
| attribute.clearValues(); |
| } |
| } |
| |
| @SuppressWarnings("deprecation") |
| @Override |
| public String mapToRepositoryKey(TaskAttribute parent, String key) { |
| /*if (key.equals(TaskAttribute.NEW_CC)) { |
| return BugzillaReportElement.NEWCC.getKey(); |
| } else*/if (key.equals(TaskAttribute.COMMENT_DATE)) { |
| return BugzillaAttribute.BUG_WHEN.getKey(); |
| } else if (key.equals(TaskAttribute.COMMENT_AUTHOR)) { |
| return BugzillaAttribute.WHO.getKey(); |
| } else if (key.equals(TaskAttribute.COMMENT_AUTHOR_NAME)) { |
| return BugzillaAttribute.WHO_NAME.getKey(); |
| } else if (key.equals(TaskAttribute.USER_CC)) { |
| return BugzillaAttribute.CC.getKey(); |
| } else if (key.equals(TaskAttribute.COMMENT_TEXT)) { |
| return BugzillaAttribute.THETEXT.getKey(); |
| } else if (key.equals(TaskAttribute.COMMENT_ISPRIVATE)) { |
| return BugzillaAttribute.IS_PRIVATE.getKey(); |
| } else if (key.equals(TaskAttribute.DATE_CREATION)) { |
| return BugzillaAttribute.CREATION_TS.getKey(); |
| } else if (key.equals(TaskAttribute.DESCRIPTION)) { |
| return BugzillaAttribute.LONG_DESC.getKey(); |
| } else if (key.equals(TaskAttribute.ATTACHMENT_ID)) { |
| return BugzillaAttribute.ATTACHID.getKey(); |
| } else if (key.equals(TaskAttribute.ATTACHMENT_DESCRIPTION)) { |
| return BugzillaAttribute.DESC.getKey(); |
| } else if (key.equals(TaskAttribute.ATTACHMENT_CONTENT_TYPE)) { |
| return BugzillaAttribute.CTYPE.getKey(); |
| //return BugzillaReportElement.TYPE.getKey();*/ |
| } else if (key.equals(TaskAttribute.USER_ASSIGNED)) { |
| return BugzillaAttribute.ASSIGNED_TO.getKey(); |
| } else if (key.equals(TaskAttribute.USER_ASSIGNED_NAME)) { |
| return BugzillaAttribute.ASSIGNED_TO_NAME.getKey(); |
| } else if (key.equals(TaskAttribute.RESOLUTION)) { |
| return BugzillaAttribute.RESOLUTION.getKey(); |
| } else if (key.equals(TaskAttribute.STATUS)) { |
| return BugzillaAttribute.BUG_STATUS.getKey(); |
| } else if (key.equals(TaskAttribute.DATE_MODIFICATION)) { |
| return BugzillaAttribute.DELTA_TS.getKey(); |
| } else if (key.equals(TaskAttribute.USER_REPORTER)) { |
| return BugzillaAttribute.REPORTER.getKey(); |
| } else if (key.equals(TaskAttribute.USER_REPORTER_NAME)) { |
| return BugzillaAttribute.REPORTER_NAME.getKey(); |
| } else if (key.equals(TaskAttribute.SUMMARY)) { |
| return BugzillaAttribute.SHORT_DESC.getKey(); |
| } else if (key.equals(TaskAttribute.PRODUCT)) { |
| return BugzillaAttribute.PRODUCT.getKey(); |
| } else if (key.equals(TaskAttribute.KEYWORDS)) { |
| return BugzillaAttribute.KEYWORDS.getKey(); |
| } else if (key.equals(TaskAttribute.ATTACHMENT_DATE)) { |
| return BugzillaAttribute.DATE.getKey(); |
| } else if (key.equals(TaskAttribute.ATTACHMENT_SIZE)) { |
| return BugzillaAttribute.SIZE.getKey(); |
| } else if (key.equals(TaskAttribute.ADD_SELF_CC)) { |
| return BugzillaAttribute.ADDSELFCC.getKey(); |
| } else if (key.equals(TaskAttribute.PRIORITY)) { |
| return BugzillaAttribute.PRIORITY.getKey(); |
| } else if (key.equals(TaskAttribute.COMMENT_NEW)) { |
| return BugzillaAttribute.NEW_COMMENT.getKey(); |
| } else if (key.equals(TaskAttribute.COMPONENT)) { |
| return BugzillaAttribute.COMPONENT.getKey(); |
| } else if (key.equals(TaskAttribute.TASK_KEY)) { |
| return BugzillaAttribute.BUG_ID.getKey(); |
| } else if (key.equals(TaskAttribute.DATE_DUE)) { |
| return BugzillaAttribute.DEADLINE.getKey(); |
| } else if (key.equals(TaskAttribute.SEVERITY)) { |
| return BugzillaAttribute.BUG_SEVERITY.getKey(); |
| } else if (key.equals(TaskAttribute.VERSION)) { |
| return BugzillaAttribute.VERSION.getKey(); |
| } |
| return super.mapToRepositoryKey(parent, key); |
| } |
| |
| @Override |
| public TaskAttribute getAssoctiatedAttribute(TaskAttribute taskAttribute) { |
| String id = taskAttribute.getMetaData().getValue(TaskAttribute.META_ASSOCIATED_ATTRIBUTE_ID); |
| if (id != null) { |
| // operation associated input attributes are stored on the root attribute |
| if (TaskAttribute.TYPE_OPERATION.equals(taskAttribute.getMetaData().getType())) { |
| return taskAttribute.getTaskData().getRoot().getMappedAttribute(id); |
| } |
| return taskAttribute.getMappedAttribute(id); |
| } |
| return null; |
| } |
| |
| @Override |
| public IRepositoryPerson getRepositoryPerson(TaskAttribute taskAttribute) { |
| |
| IRepositoryPerson person = super.getRepositoryPerson(taskAttribute); |
| if (person.getName() == null) { |
| if (taskAttribute.getId().equals(BugzillaAttribute.ASSIGNED_TO.getKey())) { |
| TaskAttribute attrAssigned = taskAttribute.getTaskData() |
| .getRoot() |
| .getAttribute(BugzillaAttribute.ASSIGNED_TO_NAME.getKey()); |
| if (attrAssigned != null) { |
| person.setName(attrAssigned.getValue()); |
| } |
| } else if (taskAttribute.getId().equals(BugzillaAttribute.REPORTER.getKey())) { |
| TaskAttribute attrReporter = taskAttribute.getTaskData() |
| .getRoot() |
| .getAttribute(BugzillaAttribute.REPORTER_NAME.getKey()); |
| if (attrReporter != null) { |
| person.setName(attrReporter.getValue()); |
| } |
| } else if (taskAttribute.getId().equals(BugzillaAttribute.QA_CONTACT.getKey())) { |
| TaskAttribute attrReporter = taskAttribute.getTaskData() |
| .getRoot() |
| .getAttribute(BugzillaAttribute.QA_CONTACT_NAME.getKey()); |
| if (attrReporter != null) { |
| person.setName(attrReporter.getValue()); |
| } |
| } |
| } |
| return person; |
| } |
| |
| @Override |
| public Map<String, String> getOptions(TaskAttribute attribute) { |
| RepositoryConfiguration configuration = connector.getRepositoryConfiguration(getTaskRepository().getRepositoryUrl()); |
| if (configuration != null) { |
| TaskAttribute attributeProduct = attribute.getTaskData() |
| .getRoot() |
| .getMappedAttribute(BugzillaAttribute.PRODUCT.getKey()); |
| if (attributeProduct != null && attributeProduct.getValue().length() > 0) { |
| List<String> options = configuration.getAttributeOptions(attributeProduct.getValue(), attribute); |
| if (options.size() == 0 && attribute.getId().equals("resolutionInput")) { //$NON-NLS-1$ |
| options = configuration.getOptionValues(BugzillaAttribute.RESOLUTION); |
| // DUPLICATE and MOVED have special meanings so do not show as resolution |
| // TODO: COPIED FUNCTIONALITY from RepositoryConfiguration.addOperation() refactor. |
| options.remove("DUPLICATE"); //$NON-NLS-1$ |
| options.remove("MOVED"); //$NON-NLS-1$ |
| } |
| Map<String, String> newOptions = new LinkedHashMap<String, String>(); |
| for (String option : options) { |
| newOptions.put(option, option); |
| } |
| if (newOptions != null && !newOptions.isEmpty()) { |
| List<String> values = attribute.getValues(); |
| for (String value : values) { |
| if (!newOptions.containsKey(value)) { |
| // the RepositoryConfiguration is not up to date a new option was add |
| // but Mylyn has not updated the RepositoryConfiguration. So we can have a value |
| // which is not in the Options of the RepositoryConfiguration and need to add |
| // it to the newOptions. |
| // TODO: change this with bug 338347 |
| newOptions.put(value, value); |
| } |
| } |
| } |
| return newOptions; |
| } |
| } |
| return super.getOptions(attribute); |
| } |
| |
| @Override |
| public boolean equals(TaskAttribute newAttribute, TaskAttribute oldAttribute) { |
| if (TaskAttribute.TYPE_COMMENT.equals(newAttribute.getMetaData().getType())) { |
| // the ID mapping for Bugzilla changed in Mylyn 3.7, always consider existing comments equal |
| return true; |
| } |
| String id = oldAttribute.getId(); |
| if (id.startsWith(TaskAttribute.PREFIX_ATTACHMENT)) { |
| TaskAttachmentMapper oldAttachment; |
| oldAttachment = TaskAttachmentMapper.createFrom(oldAttribute); |
| TaskAttachmentMapper newAttachment; |
| newAttachment = TaskAttachmentMapper.createFrom(newAttribute); |
| return newAttachment.equals(oldAttachment); |
| } |
| boolean result = super.equals(newAttribute, oldAttribute); |
| // bug 367861: avoid showing incomings for fields that were previously not part of the schema when empty |
| if (!result // |
| && (BugzillaAttribute.RESOLUTION.getKey().equals(id) |
| || BugzillaAttribute.BUG_FILE_LOC.getKey().equals(id) |
| || BugzillaAttribute.STATUS_WHITEBOARD.getKey().equals(id) // |
| || BugzillaAttribute.KEYWORDS.getKey().equals(id))) { |
| if (oldAttribute.getValue().length() == 0 && newAttribute.getValue().length() == 0 |
| && oldAttribute.getValues().size() <= 1 && newAttribute.getValues().size() <= 1) { |
| return true; |
| } |
| } |
| return result; |
| } |
| |
| @Override |
| public String getLabel(TaskAttribute taskAttribute) { |
| if (taskAttribute.getId().startsWith(BugzillaCustomField.CUSTOM_FIELD_PREFIX)) { |
| return super.getLabel(taskAttribute) + ":"; //$NON-NLS-1$ |
| } else { |
| return super.getLabel(taskAttribute); |
| } |
| } |
| |
| } |