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