You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by il...@apache.org on 2014/03/24 10:42:08 UTC
[19/50] [abbrv] git commit: [OLINGO-214] Using Timestamp consistently
for both V4 and V3 datetime types
[OLINGO-214] Using Timestamp consistently for both V4 and V3 datetime types
Project: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/commit/130a49fe
Tree: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/tree/130a49fe
Diff: http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/diff/130a49fe
Branch: refs/heads/master
Commit: 130a49fed20c32a4f4d8272919e9bae4c9427d55
Parents: 5a15155
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Sat Mar 22 16:11:36 2014 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Sat Mar 22 16:11:36 2014 +0100
----------------------------------------------------------------------
.../core/edm/primitivetype/EdmDateTime.java | 89 +++++++++++---------
.../edm/primitivetype/EdmDateTimeOffset.java | 68 +++++++++++++--
.../core/edm/primitivetype/EdmTimeOfDay.java | 45 ++++++++--
3 files changed, 147 insertions(+), 55 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/130a49fe/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTime.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTime.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTime.java
index e061388..af2793b 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTime.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTime.java
@@ -54,37 +54,43 @@ public final class EdmDateTime extends SingletonPrimitiveType {
final Boolean isNullable, final Integer maxLength, final Integer precision,
final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
- Calendar calendar = null;
- Timestamp timestamp = null;
-
final String[] dateParts = value.split("\\.");
+
+ final Date date;
try {
- final Date date = DATE_FORMAT.get().parse(dateParts[0]);
- if (dateParts.length > 1) {
- int idx = dateParts[1].indexOf('+');
- if (idx == -1) {
- idx = dateParts[1].indexOf('-');
- }
- if (idx == -1) {
- calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
- calendar.setTime(date);
-
- timestamp = new Timestamp(calendar.getTimeInMillis());
- timestamp.setNanos(Integer.parseInt(dateParts[1]));
- } else {
- calendar = Calendar.getInstance(TimeZone.getTimeZone(dateParts[1].substring(idx)));
- calendar.setTime(date);
-
- timestamp = new Timestamp(calendar.getTimeInMillis());
- timestamp.setNanos(Integer.parseInt(dateParts[1].substring(0, idx)));
- }
- } else {
- timestamp = new Timestamp(date.getTime());
- }
+ date = DATE_FORMAT.get().parse(dateParts[0]);
} catch (Exception e) {
throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)", e);
}
+ TimeZone timezone = null;
+ Integer fractionalSecs = null;
+ if (dateParts.length > 1) {
+ int idx = dateParts[1].indexOf('+');
+ if (idx == -1) {
+ idx = dateParts[1].indexOf('-');
+ }
+ if (idx == -1) {
+ fractionalSecs = Integer.parseInt(dateParts[1]);
+ } else {
+ timezone = TimeZone.getTimeZone(dateParts[1].substring(idx));
+ fractionalSecs = Integer.parseInt(dateParts[1].substring(0, idx));
+ }
+ }
+
+ if (fractionalSecs != null && String.valueOf(fractionalSecs).length() > (precision == null ? 0 : precision)) {
+ throw new EdmPrimitiveTypeException(
+ "EdmPrimitiveTypeException.LITERAL_FACETS_NOT_MATCHED.addContent(value, facets)");
+ }
+
+ final Calendar calendar = timezone == null ? Calendar.getInstance() : Calendar.getInstance(timezone);
+ calendar.setTime(date);
+ final Timestamp timestamp = new Timestamp(date.getTime());
+ if (fractionalSecs != null) {
+ calendar.set(Calendar.MILLISECOND, fractionalSecs);
+ timestamp.setNanos(fractionalSecs);
+ }
+
if (returnType.isAssignableFrom(Calendar.class)) {
return returnType.cast(calendar);
} else if (returnType.isAssignableFrom(Timestamp.class)) {
@@ -100,25 +106,32 @@ public final class EdmDateTime extends SingletonPrimitiveType {
final Boolean isNullable, final Integer maxLength, final Integer precision,
final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
+ Date date = null;
+ Integer fractionalSecs = null;
if (value instanceof Calendar) {
final Calendar calendar = (Calendar) value;
-
- final StringBuilder formatted = new StringBuilder().append(DATE_FORMAT.get().format(calendar.getTime()));
- formatted.append(calendar.getTimeZone());
-
- return formatted.toString();
- } else if (value instanceof Timestamp) {
+ date = calendar.getTime();
+ fractionalSecs = calendar.get(Calendar.MILLISECOND);
+ }
+ if (value instanceof Timestamp) {
final Timestamp timestamp = (Timestamp) value;
+ date = new Date(timestamp.getTime());
+ fractionalSecs = timestamp.getNanos();
+ }
- final StringBuilder formatted = new StringBuilder().append(DATE_FORMAT.get().format(timestamp));
- if (timestamp.getNanos() > 0) {
- formatted.append('.').append(String.valueOf(timestamp.getNanos()));
- }
+ final StringBuilder result = new StringBuilder().append(DATE_FORMAT.get().format(date));
- return formatted.toString();
- } else {
+ try {
+ if (value instanceof Timestamp) {
+ EdmDateTimeOffset.appendFractionalSeconds(result, fractionalSecs, precision);
+ } else {
+ EdmDateTimeOffset.appendMilliseconds(result, fractionalSecs, precision);
+ }
+ } catch (final IllegalArgumentException e) {
throw new EdmPrimitiveTypeException(
- "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass())");
+ "EdmPrimitiveTypeException.VALUE_FACETS_NOT_MATCHED.addContent(value, facets)", e);
}
+
+ return result.toString();
}
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/130a49fe/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java
index 7a511d6..f1b707f 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffset.java
@@ -18,6 +18,7 @@
*/
package org.apache.olingo.commons.core.edm.primitivetype;
+import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
@@ -33,7 +34,7 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
private static final Pattern PATTERN = Pattern.compile(
"(-?\\p{Digit}{4,})-(\\p{Digit}{2})-(\\p{Digit}{2})"
- + "T(\\p{Digit}{2}):(\\p{Digit}{2})(?::(\\p{Digit}{2})(\\.(\\p{Digit}{0,3}?)0*)?)?"
+ + "T(\\p{Digit}{2}):(\\p{Digit}{2})(?::(\\p{Digit}{2})(\\.(\\p{Digit}{0,12}?)0*)?)?"
+ "(Z|([-+]\\p{Digit}{2}:\\p{Digit}{2}))?");
private static final EdmDateTimeOffset INSTANCE = new EdmDateTimeOffset();
@@ -74,6 +75,10 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
Byte.parseByte(matcher.group(5)),
matcher.group(6) == null ? 0 : Byte.parseByte(matcher.group(6)));
+ // cloning the original Calendar instance to avoid vanishing the Calendar value check - triggered by any
+ // get method - empowered by the convertDateTime() method below
+ final Timestamp timestamp = new Timestamp(((Calendar) dateTimeValue.clone()).getTimeInMillis());
+
if (matcher.group(7) != null) {
if (matcher.group(7).length() == 1 || matcher.group(7).length() > 13) {
throw new EdmPrimitiveTypeException(
@@ -84,18 +89,28 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
throw new EdmPrimitiveTypeException(
"EdmPrimitiveTypeException.LITERAL_FACETS_NOT_MATCHED.addContent(value, facets)");
}
- final String milliSeconds = decimals + "000".substring(decimals.length());
+ final String milliSeconds = decimals.length() > 3
+ ? decimals.substring(0, 3)
+ : decimals + "000".substring(decimals.length());
dateTimeValue.set(Calendar.MILLISECOND, Short.parseShort(milliSeconds));
+
+ if (!decimals.isEmpty()) {
+ timestamp.setNanos(Integer.parseInt(decimals));
+ }
+ }
+
+ if (returnType.isAssignableFrom(Timestamp.class)) {
+ return returnType.cast(timestamp);
}
try {
return convertDateTime(dateTimeValue, returnType);
} catch (final IllegalArgumentException e) {
throw new EdmPrimitiveTypeException(
- "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value), e");
+ "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)", e);
} catch (final ClassCastException e) {
throw new EdmPrimitiveTypeException(
- "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType), e");
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType)", e);
}
}
@@ -138,9 +153,19 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
final Boolean isNullable, final Integer maxLength, final Integer precision,
final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
- final Calendar dateTimeValue = createDateTime(value);
+ final Calendar dateTimeValue;
+ final int fractionalSecs;
+ if (value instanceof Timestamp) {
+ final Calendar tmp = Calendar.getInstance();
+ tmp.setTimeInMillis(((Timestamp) value).getTime());
+ dateTimeValue = createDateTime(tmp);
+ fractionalSecs = ((Timestamp) value).getNanos();
+ } else {
+ dateTimeValue = createDateTime(value);
+ fractionalSecs = dateTimeValue.get(Calendar.MILLISECOND);
+ }
- final StringBuilder result = new StringBuilder(23); // 23 characters are enough for millisecond precision.
+ final StringBuilder result = new StringBuilder();
final int year = dateTimeValue.get(Calendar.YEAR);
appendTwoDigits(result, year / 100);
appendTwoDigits(result, year % 100);
@@ -156,10 +181,14 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
appendTwoDigits(result, dateTimeValue.get(Calendar.SECOND));
try {
- appendMilliseconds(result, dateTimeValue.get(Calendar.MILLISECOND), precision);
+ if (value instanceof Timestamp) {
+ appendFractionalSeconds(result, fractionalSecs, precision);
+ } else {
+ appendMilliseconds(result, fractionalSecs, precision);
+ }
} catch (final IllegalArgumentException e) {
throw new EdmPrimitiveTypeException(
- "EdmPrimitiveTypeException.VALUE_FACETS_NOT_MATCHED.addContent(value, facets), e");
+ "EdmPrimitiveTypeException.VALUE_FACETS_NOT_MATCHED.addContent(value, facets)", e);
}
final int offsetInMinutes = (dateTimeValue.get(Calendar.ZONE_OFFSET)
@@ -218,8 +247,9 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
* @param result a {@link StringBuilder}
* @param milliseconds an integer that must satisfy <code>0 <= milliseconds <= 999</code>
* @param precision the upper limit for decimal digits (optional, defaults to zero)
+ * @throws IllegalArgumentException if precision is not met
*/
- protected static void appendMilliseconds(final StringBuilder result, final long milliseconds,
+ protected static void appendMilliseconds(final StringBuilder result, final int milliseconds,
final Integer precision) throws IllegalArgumentException {
final int digits = milliseconds % 1000 == 0 ? 0 : milliseconds % 100 == 0 ? 1 : milliseconds % 10 == 0 ? 2 : 3;
if (digits > 0) {
@@ -236,4 +266,24 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
}
}
}
+
+ /**
+ * Appends the given fractional seconds to the given string builder.
+ *
+ * @param result a {@link StringBuilder}
+ * @param fractionalSeconds fractional seconds
+ * @param precision the upper limit for decimal digits (optional, defaults to zero)
+ * @throws IllegalArgumentException if precision is not met
+ */
+ protected static void appendFractionalSeconds(final StringBuilder result, final int fractionalSeconds,
+ final Integer precision) throws IllegalArgumentException {
+
+ if (fractionalSeconds > 0) {
+ if (precision == null || precision < String.valueOf(fractionalSeconds).length()) {
+ throw new IllegalArgumentException();
+ }
+
+ result.append('.').append(fractionalSeconds);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata4/blob/130a49fe/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java
index 7d8cf9e..2003b09 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/primitivetype/EdmTimeOfDay.java
@@ -18,6 +18,7 @@
*/
package org.apache.olingo.commons.core.edm.primitivetype;
+import java.sql.Timestamp;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.regex.Matcher;
@@ -28,7 +29,7 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
public final class EdmTimeOfDay extends SingletonPrimitiveType {
private static final Pattern PATTERN = Pattern.compile(
- "(\\p{Digit}{2}):(\\p{Digit}{2})(?::(\\p{Digit}{2})(\\.(\\p{Digit}{0,3}?)0*)?)?");
+ "(\\p{Digit}{2}):(\\p{Digit}{2})(?::(\\p{Digit}{2})(\\.(\\p{Digit}{0,}?)0*)?)?");
private static final EdmTimeOfDay INSTANCE = new EdmTimeOfDay();
@@ -57,6 +58,10 @@ public final class EdmTimeOfDay extends SingletonPrimitiveType {
dateTimeValue.set(Calendar.MINUTE, Byte.parseByte(matcher.group(2)));
dateTimeValue.set(Calendar.SECOND, matcher.group(3) == null ? 0 : Byte.parseByte(matcher.group(3)));
+ // cloning the original Calendar instance to avoid vanishing the Calendar value check - triggered by any
+ // get method - empowered by the convertDateTime() method below
+ final Timestamp timestamp = new Timestamp(((Calendar) dateTimeValue.clone()).getTimeInMillis());
+
if (matcher.group(4) != null) {
if (matcher.group(4).length() == 1 || matcher.group(4).length() > 13) {
throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)");
@@ -66,18 +71,28 @@ public final class EdmTimeOfDay extends SingletonPrimitiveType {
throw new EdmPrimitiveTypeException(
"EdmPrimitiveTypeException.LITERAL_FACETS_NOT_MATCHED.addContent(value, facets)");
}
- final String milliSeconds = decimals + "000".substring(decimals.length());
+ final String milliSeconds = decimals.length() > 3
+ ? decimals.substring(0, 3)
+ : decimals + "000".substring(decimals.length());
dateTimeValue.set(Calendar.MILLISECOND, Short.parseShort(milliSeconds));
+
+ if (!decimals.isEmpty()) {
+ timestamp.setNanos(Integer.parseInt(decimals));
+ }
+ }
+
+ if (returnType.isAssignableFrom(Timestamp.class)) {
+ return returnType.cast(timestamp);
}
try {
return EdmDateTimeOffset.convertDateTime(dateTimeValue, returnType);
} catch (final IllegalArgumentException e) {
throw new EdmPrimitiveTypeException(
- "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value), e");
+ "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)", e);
} catch (final ClassCastException e) {
throw new EdmPrimitiveTypeException(
- "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType), e");
+ "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType)", e);
}
}
@@ -86,9 +101,19 @@ public final class EdmTimeOfDay extends SingletonPrimitiveType {
final Boolean isNullable, final Integer maxLength, final Integer precision,
final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
- final Calendar dateTimeValue = EdmDateTimeOffset.createDateTime(value);
+ final Calendar dateTimeValue;
+ final int fractionalSecs;
+ if (value instanceof Timestamp) {
+ final Calendar tmp = Calendar.getInstance();
+ tmp.setTimeInMillis(((Timestamp) value).getTime());
+ dateTimeValue = EdmDateTimeOffset.createDateTime(tmp);
+ fractionalSecs = ((Timestamp) value).getNanos();
+ } else {
+ dateTimeValue = EdmDateTimeOffset.createDateTime(value);
+ fractionalSecs = dateTimeValue.get(Calendar.MILLISECOND);
+ }
- final StringBuilder result = new StringBuilder(8); // Eight characters are enough for "normal" times.
+ final StringBuilder result = new StringBuilder();
EdmDateTimeOffset.appendTwoDigits(result, dateTimeValue.get(Calendar.HOUR_OF_DAY));
result.append(':');
EdmDateTimeOffset.appendTwoDigits(result, dateTimeValue.get(Calendar.MINUTE));
@@ -96,10 +121,14 @@ public final class EdmTimeOfDay extends SingletonPrimitiveType {
EdmDateTimeOffset.appendTwoDigits(result, dateTimeValue.get(Calendar.SECOND));
try {
- EdmDateTimeOffset.appendMilliseconds(result, dateTimeValue.get(Calendar.MILLISECOND), precision);
+ if (value instanceof Timestamp) {
+ EdmDateTimeOffset.appendFractionalSeconds(result, fractionalSecs, precision);
+ } else {
+ EdmDateTimeOffset.appendMilliseconds(result, fractionalSecs, precision);
+ }
} catch (final IllegalArgumentException e) {
throw new EdmPrimitiveTypeException(
- "EdmPrimitiveTypeException.VALUE_FACETS_NOT_MATCHED.addContent(value, facets), e");
+ "EdmPrimitiveTypeException.VALUE_FACETS_NOT_MATCHED.addContent(value, facets)", e);
}
return result.toString();