blob: c53b64a124ec1f1a14252c3b68e56e1a5288bb3a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2015 Tasktop Technologies and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Tasktop Technologies - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.tasks.core.data;
import java.util.Date;
import java.util.List;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.tasks.core.ITask.PriorityLevel;
import org.eclipse.mylyn.tasks.core.ITaskMapping;
import org.eclipse.mylyn.tasks.core.data.AbstractTaskSchema.Field;
/**
* @author Steffen Pingel
* @since 3.0
*/
public class TaskMapper implements ITaskMapping {
private final boolean createNonExistingAttributes;
private final TaskData taskData;
public TaskMapper(@NonNull TaskData taskData) {
this(taskData, false);
}
public TaskMapper(@NonNull TaskData taskData, boolean createNonExistingAttributes) {
this.createNonExistingAttributes = createNonExistingAttributes;
Assert.isNotNull(taskData);
this.taskData = taskData;
}
public boolean applyTo(@NonNull ITask task) {
boolean changed = false;
if (hasChanges(task.getCompletionDate(), getCompletionDate(), TaskAttribute.DATE_COMPLETION)) {
task.setCompletionDate(getCompletionDate());
changed = true;
}
if (hasChanges(task.getCreationDate(), getCreationDate(), TaskAttribute.DATE_CREATION)) {
task.setCreationDate(getCreationDate());
changed = true;
}
if (hasChanges(task.getModificationDate(), getModificationDate(), TaskAttribute.DATE_MODIFICATION)) {
task.setModificationDate(getModificationDate());
changed = true;
}
if (hasChanges(task.getDueDate(), getDueDate(), TaskAttribute.DATE_DUE)) {
task.setDueDate(getDueDate());
changed = true;
}
if (hasChanges(task.getOwner(), getOwner(), TaskAttribute.USER_ASSIGNED)) {
task.setOwner(getOwner());
changed = true;
}
if (hasChanges(task.getOwnerId(), getOwnerId(), TaskAttribute.USER_ASSIGNED)) {
task.setOwnerId(getOwnerId());
changed = true;
}
if (hasChanges(task.getPriority(), getPriorityLevelString(), TaskAttribute.PRIORITY)) {
task.setPriority(getPriorityLevelString());
changed = true;
}
String priorityLabel = getPriority();
if (hasChanges(task.getAttribute(ITasksCoreConstants.ATTRIBUTE_PRIORITY_LABEL), priorityLabel,
TaskAttribute.PRIORITY)) {
task.setAttribute(ITasksCoreConstants.ATTRIBUTE_PRIORITY_LABEL, priorityLabel);
changed = true;
}
if (hasChanges(task.getSummary(), getSummary(), TaskAttribute.SUMMARY)) {
task.setSummary(getSummary());
changed = true;
}
if (hasChanges(task.getTaskKey(), getTaskKey(), TaskAttribute.TASK_KEY)) {
task.setTaskKey(getTaskKey());
changed = true;
}
if (hasChanges(task.getTaskKind(), getTaskKind(), TaskAttribute.TASK_KIND)) {
task.setTaskKind(getTaskKind());
changed = true;
}
if (hasChanges(task.getUrl(), getTaskUrl(), TaskAttribute.TASK_URL)) {
task.setUrl(getTaskUrl());
changed = true;
}
return changed;
}
@Nullable
private String getPriorityLevelString() {
PriorityLevel priorityLevel = getPriorityLevel();
return (priorityLevel != null) ? priorityLevel.toString() : PriorityLevel.getDefault().toString();
}
private boolean hasChanges(@Nullable Object existingValue, @Nullable Object newValue, @NonNull String attributeId) {
TaskAttribute attribute = taskData.getRoot().getMappedAttribute(attributeId);
if (attribute != null) {
return areNotEquals(existingValue, newValue);
}
return false;
}
private boolean areNotEquals(@Nullable Object existingProperty, @Nullable Object newProperty) {
return (existingProperty != null) ? !existingProperty.equals(newProperty) : newProperty != null;
}
private void copyAttributeValue(@NonNull TaskAttribute sourceAttribute, @Nullable TaskAttribute targetAttribute) {
if (targetAttribute == null) {
return;
}
if (!targetAttribute.getMetaData().isReadOnly()) {
targetAttribute.clearValues();
if (targetAttribute.getOptions().size() > 0) {
List<String> values = sourceAttribute.getValues();
for (String value : values) {
if (targetAttribute.getOptions().containsKey(value)) {
targetAttribute.addValue(value);
}
}
} else {
List<String> values = sourceAttribute.getValues();
for (String value : values) {
targetAttribute.addValue(value);
}
}
}
}
/**
* TODO update comment Sets attribute values from <code>sourceTaskData</code> on <code>targetTaskData</code>. Sets
* the following attributes:
* <ul>
* <li>summary
* <li>description
* </ul>
* Other attribute values are only set if they exist on <code>sourceTaskData</code> and <code>targetTaskData</code>.
*
* @param sourceTaskData
* the source task data values are copied from, the connector kind of repository of
* <code>sourceTaskData</code> can be different from <code>targetTaskData</code>
* @param targetTaskData
* the target task data values are copied to, the connector kind matches the one of this task data
* handler
* @since 2.2
*/
public void merge(@NonNull ITaskMapping source) {
if (source.getTaskData() != null && this.getTaskData() != null
&& source.getTaskData().getConnectorKind().equals(this.getTaskData().getConnectorKind())) {
// task data objects are from the same connector, copy all attributes
for (TaskAttribute sourceAttribute : source.getTaskData().getRoot().getAttributes().values()) {
copyAttributeValue(sourceAttribute, this.getTaskData().getRoot().getAttribute(sourceAttribute.getId()));
}
} else {
if (source.getCc() != null) {
setCc(source.getCc());
}
if (source.getDescription() != null) {
setDescription(source.getDescription());
}
if (source.getComponent() != null) {
setComponent(source.getComponent());
}
if (source.getKeywords() != null) {
setKeywords(source.getKeywords());
}
if (source.getOwner() != null) {
setOwner(source.getOwner());
}
if (source.getPriorityLevel() != null) {
setPriorityLevel(source.getPriorityLevel());
}
if (source.getProduct() != null) {
setProduct(source.getProduct());
}
if (source.getSeverity() != null) {
setSeverity(source.getSeverity());
}
if (source.getSummary() != null) {
setSummary(source.getSummary());
}
if (source.getVersion() != null) {
setVersion(source.getVersion());
}
}
}
@NonNull
private TaskAttribute createAttribute(@NonNull String attributeKey, @Nullable String type) {
TaskAttribute attribute;
Field field = DefaultTaskSchema.getField(attributeKey);
if (field != null) {
attribute = field.createAttribute(taskData.getRoot());
} else {
attribute = taskData.getRoot().createMappedAttribute(attributeKey);
attribute.getMetaData().defaults().setType(type);
}
return attribute;
}
@Nullable
public List<String> getCc() {
return getValues(TaskAttribute.USER_CC);
}
@Nullable
public Date getCompletionDate() {
return getDateValue(TaskAttribute.DATE_COMPLETION);
}
@Nullable
public String getComponent() {
return getValue(TaskAttribute.COMPONENT);
}
@Nullable
public Date getCreationDate() {
return getDateValue(TaskAttribute.DATE_CREATION);
}
@Nullable
private Date getDateValue(@NonNull String attributeKey) {
TaskAttribute attribute = taskData.getRoot().getMappedAttribute(attributeKey);
if (attribute != null) {
return taskData.getAttributeMapper().getDateValue(attribute);
}
return null;
}
@Nullable
public String getDescription() {
return getValue(TaskAttribute.DESCRIPTION);
}
@Nullable
public Date getDueDate() {
return getDateValue(TaskAttribute.DATE_DUE);
}
@Nullable
public List<String> getKeywords() {
return getValues(TaskAttribute.KEYWORDS);
}
@Nullable
private TaskAttribute getWriteableAttribute(@NonNull String attributeKey, String type) {
TaskAttribute attribute = taskData.getRoot().getMappedAttribute(attributeKey);
if (createNonExistingAttributes) {
if (attribute == null) {
attribute = createAttribute(attributeKey, type);
}
} else if (attribute != null && attribute.getMetaData().isReadOnly()) {
return null;
}
return attribute;
}
@Nullable
public Date getModificationDate() {
return getDateValue(TaskAttribute.DATE_MODIFICATION);
}
@Nullable
public String getOwner() {
return getValue(TaskAttribute.USER_ASSIGNED);
}
/**
* @since 3.15
*/
@Nullable
public String getOwnerId() {
return getValueId(TaskAttribute.USER_ASSIGNED);
}
@Nullable
public String getPriority() {
return getValue(TaskAttribute.PRIORITY);
}
/**
* Connectors should override {@link TaskAttributeMapper#getPriorityLevel(TaskAttribute, String)} to customize how
* priority options are mapped to {@link PriorityLevel}
*/
@Nullable
public PriorityLevel getPriorityLevel() {
String valueLabel = getPriority();
if (valueLabel != null && PriorityLevel.isValidPriority(valueLabel)) {
return PriorityLevel.fromString(valueLabel);
}
TaskAttribute attribute = taskData.getRoot().getMappedAttribute(TaskAttribute.PRIORITY);
if (attribute != null) {
return getTaskData().getAttributeMapper().getPriorityLevel(attribute, attribute.getValue());
}
return null;
}
@Nullable
public String getProduct() {
return getValue(TaskAttribute.PRODUCT);
}
@Nullable
public String getReporter() {
return getValue(TaskAttribute.USER_REPORTER);
}
@Nullable
public String getResolution() {
return getValue(TaskAttribute.RESOLUTION);
}
/**
* @since 3.2
*/
@Nullable
public String getSeverity() {
return getValue(TaskAttribute.SEVERITY);
}
@Nullable
public String getSummary() {
return getValue(TaskAttribute.SUMMARY);
}
@Nullable
public String getStatus() {
return getValue(TaskAttribute.STATUS);
}
@NonNull
public TaskData getTaskData() {
return taskData;
}
@Nullable
public String getTaskKey() {
return getValue(TaskAttribute.TASK_KEY);
}
@Nullable
public String getTaskKind() {
return getValue(TaskAttribute.TASK_KIND);
}
@Nullable
public String getTaskStatus() {
return getValue(TaskAttribute.STATUS);
}
@Nullable
public String getTaskUrl() {
return getValue(TaskAttribute.TASK_URL);
}
/**
* Returns the label of the attribute value.
*/
@Nullable
public String getValue(@NonNull String attributeKey) {
TaskAttribute attribute = taskData.getRoot().getMappedAttribute(attributeKey);
if (attribute != null) {
return taskData.getAttributeMapper().getValueLabel(attribute);
}
return null;
}
/**
* Returns the id of the attribute value.
*/
@Nullable
private String getValueId(@NonNull String attributeKey) {
TaskAttribute attribute = taskData.getRoot().getMappedAttribute(attributeKey);
if (attribute != null) {
return taskData.getAttributeMapper().getValue(attribute);
}
return null;
}
@Nullable
private List<String> getValues(@NonNull String attributeKey) {
TaskAttribute attribute = taskData.getRoot().getMappedAttribute(attributeKey);
if (attribute != null) {
return taskData.getAttributeMapper().getValueLabels(attribute);
}
return null;
}
/**
* @since 3.2
*/
@Nullable
public String getVersion() {
return getValue(TaskAttribute.VERSION);
}
public boolean hasChanges(@NonNull ITask task) {
boolean changed = false;
changed |= hasChanges(task.getCompletionDate(), getCompletionDate(), TaskAttribute.DATE_COMPLETION);
changed |= hasChanges(task.getCreationDate(), getCreationDate(), TaskAttribute.DATE_CREATION);
changed |= hasChanges(task.getModificationDate(), getModificationDate(), TaskAttribute.DATE_MODIFICATION);
changed |= hasChanges(task.getDueDate(), getDueDate(), TaskAttribute.DATE_DUE);
changed |= hasChanges(task.getOwner(), getOwner(), TaskAttribute.USER_ASSIGNED);
changed |= hasChanges(task.getOwnerId(), getOwnerId(), TaskAttribute.USER_ASSIGNED);
changed |= hasChanges(task.getPriority(), getPriorityLevelString(), TaskAttribute.PRIORITY);
changed |= hasChanges(task.getSummary(), getSummary(), TaskAttribute.SUMMARY);
changed |= hasChanges(task.getTaskKey(), getTaskKey(), TaskAttribute.TASK_KEY);
changed |= hasChanges(task.getTaskKind(), getTaskKind(), TaskAttribute.TASK_KIND);
changed |= hasChanges(task.getUrl(), getTaskUrl(), TaskAttribute.TASK_URL);
changed |= hasChanges(task.getAttribute(ITasksCoreConstants.ATTRIBUTE_PRIORITY_LABEL), getPriority(),
TaskAttribute.PRIORITY);
return changed;
}
// private boolean hasChanges(Object value, String attributeKey) {
// TaskAttribute attribute = taskData.getRoot().getMappedAttribute(attributeKey);
// if (attribute != null) {
// if (TaskAttribute.TYPE_BOOLEAN.equals(attribute.getMetaData().getType())) {
// return areNotEquals(value, taskData.getAttributeMapper().getBooleanValue(attribute));
// } else if (TaskAttribute.TYPE_DATE.equals(attribute.getMetaData().getType())) {
// return areNotEquals(value, taskData.getAttributeMapper().getDateValue(attribute));
// } else if (TaskAttribute.TYPE_INTEGER.equals(attribute.getMetaData().getType())) {
// return areNotEquals(value, taskData.getAttributeMapper().getIntegerValue(attribute));
// } else {
// return areNotEquals(value, taskData.getAttributeMapper().getValue(attribute));
// }
// }
// return false;
// }
public void setCc(@NonNull List<String> cc) {
setValues(TaskAttribute.USER_CC, cc);
}
public void setCompletionDate(@Nullable Date dateCompleted) {
setDateValue(TaskAttribute.DATE_COMPLETION, dateCompleted);
}
public void setComponent(@NonNull String component) {
setValue(TaskAttribute.COMPONENT, component);
}
public void setCreationDate(@Nullable Date dateCreated) {
setDateValue(TaskAttribute.DATE_CREATION, dateCreated);
}
@Nullable
private TaskAttribute setDateValue(@NonNull String attributeKey, @Nullable Date value) {
TaskAttribute attribute = getWriteableAttribute(attributeKey, TaskAttribute.TYPE_DATE);
if (attribute != null) {
taskData.getAttributeMapper().setDateValue(attribute, value);
}
return attribute;
}
public void setDescription(@NonNull String description) {
setValue(TaskAttribute.DESCRIPTION, description);
}
public void setDueDate(Date value) {
setDateValue(TaskAttribute.DATE_DUE, value);
}
public void setKeywords(@NonNull List<String> keywords) {
setValues(TaskAttribute.KEYWORDS, keywords);
}
public void setModificationDate(@Nullable Date dateModified) {
setDateValue(TaskAttribute.DATE_MODIFICATION, dateModified);
}
// TODO use Person class?
public void setOwner(@NonNull String owner) {
setValue(TaskAttribute.USER_ASSIGNED, owner);
}
public void setPriority(@NonNull String priority) {
setValue(TaskAttribute.PRIORITY, priority);
}
public void setPriorityLevel(@NonNull PriorityLevel priority) {
setPriority(priority.toString());
}
public void setProduct(@NonNull String product) {
setValue(TaskAttribute.PRODUCT, product);
}
// TODO use Person class?
public void setReporter(@NonNull String reporter) {
setValue(TaskAttribute.USER_REPORTER, reporter);
}
/**
* @since 3.2
*/
public void setSeverity(@NonNull String severity) {
setValue(TaskAttribute.SEVERITY, severity);
}
public void setSummary(@NonNull String summary) {
setValue(TaskAttribute.SUMMARY, summary);
}
public void setStatus(@NonNull String status) {
setValue(TaskAttribute.STATUS, status);
}
public void setTaskKind(@NonNull String taskKind) {
setValue(TaskAttribute.TASK_KIND, taskKind);
}
/**
* @since 3.3
*/
public void setTaskKey(@NonNull String taskKey) {
setValue(TaskAttribute.TASK_KEY, taskKey);
}
public void setTaskUrl(@NonNull String taskUrl) {
setValue(TaskAttribute.TASK_URL, taskUrl);
}
/**
* @since 3.2
*/
public void setVersion(@NonNull String version) {
setValue(TaskAttribute.VERSION, version);
}
@Nullable
public TaskAttribute setValue(@NonNull String attributeKey, @NonNull String value) {
TaskAttribute attribute = getWriteableAttribute(attributeKey, TaskAttribute.TYPE_SHORT_TEXT);
if (attribute != null) {
taskData.getAttributeMapper().setValue(attribute, value);
}
return attribute;
}
@Nullable
private TaskAttribute setValues(@NonNull String attributeKey, @NonNull List<String> values) {
TaskAttribute attribute = getWriteableAttribute(attributeKey, TaskAttribute.TYPE_SHORT_TEXT);
if (attribute != null) {
taskData.getAttributeMapper().setValues(attribute, values);
}
return attribute;
}
}