From ff319144e7d78418205f186ae571b94048d08c46 Mon Sep 17 00:00:00 2001 From: Sam Davis Date: Thu, 26 Nov 2015 13:09:18 -0800 Subject: 483327: [api] provide API to specify the precision of date/time fields Change-Id: I01bf0cf5d8437785a69103427dfaeaedef9cbca0 Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=483327--- .../mylyn/tasks/core/data/TaskAttribute.java | 20 ++++++++++ .../mylyn/tasks/core/data/TaskAttributeMapper.java | 12 ++++++ .../tasks/core/data/TaskAttributeMetaData.java | 46 +++++++++++++++++++++- .../tests/core/TaskAttributeMetaDataTest.java | 24 +++++++++++ 4 files changed, 101 insertions(+), 1 deletion(-) diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttribute.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttribute.java index 1a3519dc7..b32d46934 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttribute.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttribute.java @@ -16,6 +16,7 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.TimeUnit; import org.eclipse.core.runtime.Assert; import org.eclipse.mylyn.internal.tasks.core.RepositoryPerson; @@ -127,6 +128,24 @@ public final class TaskAttribute { public static final String META_ATTRIBUTE_TYPE = "task.meta.type"; //$NON-NLS-1$ + /** + * A key for {@link TaskAttributeMetaData} that is used to specify the precision of a date or time attribute, which + * must be parseable by {@link TimeUnit#valueOf(String)}. This specifies the precision with which values are + * represented on the server. This is separate from the attribute {@link #META_ATTRIBUTE_TYPE type}, which + * may specify that an attribute should be displayed as a {@link #TYPE_DATE date} or a {@link #TYPE_DATETIME + * date with time}. + *

+ * Connectors should ensure that {@link TaskAttributeMapper#getDateValue(TaskAttribute)} and + * {@link TaskAttributeMapper#setDateValue(TaskAttribute, java.util.Date) setDateValue(TaskAttribute, Date)} + * respectively return and accept dates at midnight in the local time zone when the precision is + * {@link TimeUnit#DAYS} or coarser. + * + * @since 3.18 + * @see TaskAttributeMetaData#getPrecision() + * @see TaskAttributeMetaData#setPrecision() + */ + public static final String META_ATTRIBUTE_PRECISION = "task.meta.precision"; //$NON-NLS-1$ + /** * A key for {@link TaskAttributeMetaData} that is used for specifying the ID of the parent {@link TaskAttribute} * for attributes that have a dependency. When the parent is changed we look for all attributes with have a @@ -683,4 +702,5 @@ public final class TaskAttribute { Assert.isNotNull(mappedAttributeId); return new TaskAttribute(this, mappedAttributeId); } + } diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttributeMapper.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttributeMapper.java index 8922609a3..f3daee40f 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttributeMapper.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttributeMapper.java @@ -15,6 +15,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.concurrent.TimeUnit; import org.eclipse.core.runtime.Assert; import org.eclipse.jdt.annotation.NonNull; @@ -117,6 +118,13 @@ public class TaskAttributeMapper { return false; } + /** + * Connectors should ensure that this method returns dates at midnight in the local time zone when the + * {@link TaskAttribute#META_ATTRIBUTE_PRECISION precision} is {@link TimeUnit#DAYS} or coarser. This is because + * {@link Date Dates} are automatically displayed in the local time zone. This is not a concern when the precision + * is finer than {@link TimeUnit#DAYS}, because in that case the value has a time component which can meaningfully + * be converted to local time. + */ @Nullable public Date getDateValue(@NonNull TaskAttribute attribute) { String dateString = attribute.getValue(); @@ -283,6 +291,10 @@ public class TaskAttributeMapper { attribute.setValue(Boolean.toString(value)); } + /** + * Connectors should ensure that this method accepts dates at midnight in the local time zone when the + * {@link TaskAttribute#META_ATTRIBUTE_PRECISION precision} is {@link TimeUnit#DAYS} or coarser. + */ public void setDateValue(@NonNull TaskAttribute attribute, @Nullable Date date) { if (date != null) { attribute.setValue(Long.toString(date.getTime())); diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttributeMetaData.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttributeMetaData.java index af012c3a4..6f680b2bb 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttributeMetaData.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/data/TaskAttributeMetaData.java @@ -12,6 +12,16 @@ package org.eclipse.mylyn.tasks.core.data; import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.mylyn.commons.core.StatusHandler; +import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants; +import org.eclipse.osgi.util.NLS; + +import com.google.common.base.Strings; /** * @author Steffen Pingel @@ -132,7 +142,7 @@ public class TaskAttributeMetaData { * The default option property is not used. Connectors are expected to set default values in * {@link AbstractTaskDataHandler#initializeTaskData(org.eclipse.mylyn.tasks.core.TaskRepository, TaskData, org.eclipse.mylyn.tasks.core.ITaskMapping, org.eclipse.core.runtime.IProgressMonitor)} * . - * + * * @deprecated Not used, set default value in * {@link AbstractTaskDataHandler#initializeTaskData(org.eclipse.mylyn.tasks.core.TaskRepository, TaskData, org.eclipse.mylyn.tasks.core.ITaskMapping, org.eclipse.core.runtime.IProgressMonitor)} * instead. @@ -232,4 +242,38 @@ public class TaskAttributeMetaData { return this; } + /** + * Get the precision of a date or time attribute. Returns null if there is no precision specified. + * + * @since 3.18 + * @see TaskAttribute#META_ATTRIBUTE_PRECISION + */ + @Nullable + public TimeUnit getPrecision() { + String precision = taskAttribute.getMetaDatum(TaskAttribute.META_ATTRIBUTE_PRECISION); + if (!Strings.isNullOrEmpty(precision)) { + try { + return TimeUnit.valueOf(precision); + } catch (IllegalArgumentException e) { + StatusHandler.log(new Status(IStatus.ERROR, ITasksCoreConstants.ID_PLUGIN, NLS.bind( + "Could not parse precision '{0}'", precision), e)); //$NON-NLS-1$ + } + } + return null; + } + + /** + * Set the precision of a date or time attribute. + * + * @since 3.18 + * @see TaskAttribute#META_ATTRIBUTE_PRECISION + */ + public void setPrecision(TimeUnit precision) { + if (precision == null) { + taskAttribute.removeMetaDatum(TaskAttribute.META_ATTRIBUTE_PRECISION); + } else { + taskAttribute.putMetaDatum(TaskAttribute.META_ATTRIBUTE_PRECISION, precision.name()); + } + } + } diff --git a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/TaskAttributeMetaDataTest.java b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/TaskAttributeMetaDataTest.java index 5c674d64e..623202950 100644 --- a/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/TaskAttributeMetaDataTest.java +++ b/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/core/TaskAttributeMetaDataTest.java @@ -11,11 +11,16 @@ package org.eclipse.mylyn.tasks.tests.core; +import static java.util.concurrent.TimeUnit.HOURS; + +import java.util.concurrent.TimeUnit; + import junit.framework.TestCase; 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.TaskAttributeMetaData; import org.eclipse.mylyn.tasks.core.data.TaskData; import org.eclipse.mylyn.tasks.tests.connector.MockRepositoryConnector; @@ -47,4 +52,23 @@ public class TaskAttributeMetaDataTest extends TestCase { assertFalse(attribute.getMetaData().isRequired()); } + public void testPrecision() throws Exception { + TaskAttribute attribute = new TaskAttribute(data.getRoot(), "attributeId"); + TaskAttributeMetaData metaData = attribute.getMetaData(); + + for (TimeUnit unit : TimeUnit.values()) { + metaData.setPrecision(unit); + assertEquals(unit, metaData.getPrecision()); + } + + metaData.setPrecision(null); + assertNull(metaData.getPrecision()); + + metaData.putValue(TaskAttribute.META_ATTRIBUTE_PRECISION, "blah"); + assertNull(metaData.getPrecision()); + + metaData.putValue(TaskAttribute.META_ATTRIBUTE_PRECISION, HOURS.name()); + assertEquals(HOURS, metaData.getPrecision()); + } + } -- cgit v1.2.3