You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2015/09/07 08:18:59 UTC
[7/8] olingo-odata4 git commit: [OLINGO-659] small improvement in
DateTime serialization
[OLINGO-659] small improvement in DateTime serialization
Change-Id: Ieb0f00b5314be88bc0e38b74564538d1f4751c5b
Signed-off-by: Michael Bolz <mi...@sap.com>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/72ad9b37
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/72ad9b37
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/72ad9b37
Branch: refs/heads/master
Commit: 72ad9b376bff518b5c28fe23eff6a8904b2b0c3f
Parents: 1277086
Author: Klaus Straubinger <kl...@sap.com>
Authored: Fri Sep 4 16:51:59 2015 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Mon Sep 7 08:06:03 2015 +0200
----------------------------------------------------------------------
.../edm/primitivetype/EdmDateTimeOffset.java | 97 ++++++--------------
.../core/edm/primitivetype/EdmTimeOfDay.java | 6 +-
.../primitivetype/EdmDateTimeOffsetTest.java | 7 +-
3 files changed, 37 insertions(+), 73 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/72ad9b37/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 ab295bf..61344fb 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
@@ -19,7 +19,6 @@
package org.apache.olingo.commons.core.edm.primitivetype;
import java.sql.Timestamp;
-import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
@@ -33,13 +32,6 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
*/
public final class EdmDateTimeOffset extends SingletonPrimitiveType {
- public static final ThreadLocal<DecimalFormat> NANO_FORMAT = new ThreadLocal<DecimalFormat>() {
- @Override
- protected DecimalFormat initialValue() {
- return new DecimalFormat("000000000");
- }
- };
-
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,12}?)0*)?)?"
@@ -93,14 +85,15 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
}
if (returnType.isAssignableFrom(Timestamp.class)) {
if (!decimals.isEmpty()) {
- nanoSeconds = Integer.parseInt(decimals.length() > 9 ? decimals.substring(0, 9)
- : decimals + "000000000".substring(decimals.length()));
+ nanoSeconds = Integer.parseInt(decimals.length() > 9 ?
+ decimals.substring(0, 9) :
+ decimals + "000000000".substring(decimals.length()));
}
} else {
- final String milliSeconds = decimals.length() > 3
- ? decimals.substring(0, 3)
- : decimals + "000".substring(decimals.length());
- dateTimeValue.set(Calendar.MILLISECOND, Short.parseShort(milliSeconds));
+ final String milliSeconds = decimals.length() > 3 ?
+ decimals.substring(0, 3) :
+ decimals + "000".substring(decimals.length());
+ dateTimeValue.set(Calendar.MILLISECOND, Short.parseShort(milliSeconds));
}
}
@@ -157,19 +150,16 @@ 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;
- final int fractionalSecs;
+ Calendar dateTimeValue;
if (value instanceof Timestamp) {
final Calendar tmp = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
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();
+ StringBuilder result = new StringBuilder();
final int year = dateTimeValue.get(Calendar.YEAR);
appendTwoDigits(result, year / 100);
appendTwoDigits(result, year % 100);
@@ -184,12 +174,11 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
result.append(':');
appendTwoDigits(result, dateTimeValue.get(Calendar.SECOND));
+ final int fractionalSecs = value instanceof Timestamp ?
+ ((Timestamp) value).getNanos() :
+ dateTimeValue.get(Calendar.MILLISECOND);
try {
- if (value instanceof Timestamp) {
- appendFractionalSeconds(result, fractionalSecs, precision);
- } else {
- appendMilliseconds(result, fractionalSecs, precision);
- }
+ appendFractionalSeconds(result, fractionalSecs, value instanceof Timestamp, precision);
} catch (final IllegalArgumentException e) {
throw new EdmPrimitiveTypeException("The value '" + value + "' does not match the facets' constraints.", e);
}
@@ -243,61 +232,35 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
}
/**
- * Appends the given number of milliseconds to the given string builder, assuming that the number has at most three
- * digits, performance-optimized.
- *
+ * Appends the given milli- or nanoseconds to the given string builder, performance-optimized.
* @param result a {@link StringBuilder}
- * @param milliseconds an integer that must satisfy <code>0 <= milliseconds <= 999</code>
+ * @param fractionalSeconds fractional seconds (nonnegative and assumed to be in the valid range)
+ * @param isNano whether the value is to be interpreted as nanoseconds (milliseconds if false)
* @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 int milliseconds,
- final Integer precision) throws IllegalArgumentException {
+ protected static void appendFractionalSeconds(StringBuilder result, final int fractionalSeconds,
+ final boolean isNano, final Integer precision) throws IllegalArgumentException {
+ if (fractionalSeconds > 0) {
+ // Determine the number of trailing zeroes.
+ int nonSignificant = 0;
+ int output = fractionalSeconds;
+ while (output % 10 == 0) {
+ output /= 10;
+ nonSignificant++;
+ }
- final int digits = milliseconds % 1000 == 0 ? 0 : milliseconds % 100 == 0 ? 1 : milliseconds % 10 == 0 ? 2 : 3;
- if (digits > 0) {
- if (precision == null || precision < digits) {
+ if (precision == null || precision < (isNano ? 9 : 3) - nonSignificant) {
throw new IllegalArgumentException();
}
result.append('.');
- for (int d = 100; d > 0; d /= 10) {
- final byte digit = (byte) (milliseconds % (d * 10) / d);
- if (digit > 0 || milliseconds % d > 0) {
+ for (int d = 100 * (isNano ? 1000 * 1000 : 1); d > 0; d /= 10) {
+ final byte digit = (byte) (fractionalSeconds % (d * 10) / d);
+ if (digit > 0 || fractionalSeconds % d > 0) {
result.append((char) ('0' + digit));
}
}
}
}
-
- /**
- * 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) {
- String formatted = NANO_FORMAT.get().format(fractionalSeconds);
- int actualLength = formatted.length();
- boolean nonZeroFound = false;
- for (int i = formatted.length() - 1; i >= 0 && !nonZeroFound; i--) {
- if ('0' == formatted.charAt(i)) {
- actualLength--;
- } else {
- nonZeroFound = true;
- }
- }
-
- if (precision == null || precision < actualLength) {
- throw new IllegalArgumentException();
- }
-
- result.append('.').append(formatted.substring(0, actualLength));
- }
- }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/72ad9b37/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 7330fac..7595e51 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
@@ -112,11 +112,7 @@ public final class EdmTimeOfDay extends SingletonPrimitiveType {
EdmDateTimeOffset.appendTwoDigits(result, dateTimeValue.get(Calendar.SECOND));
try {
- if (value instanceof Timestamp) {
- EdmDateTimeOffset.appendFractionalSeconds(result, fractionalSecs, precision);
- } else {
- EdmDateTimeOffset.appendMilliseconds(result, fractionalSecs, precision);
- }
+ EdmDateTimeOffset.appendFractionalSeconds(result, fractionalSecs, value instanceof Timestamp, precision);
} catch (final IllegalArgumentException e) {
throw new EdmPrimitiveTypeException("The value '" + value + "' does not match the facets' constraints.", e);
}
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/72ad9b37/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java
index d8ea7c9..17ea5ce 100644
--- a/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java
+++ b/lib/commons-core/src/test/java/org/apache/olingo/commons/core/edm/primitivetype/EdmDateTimeOffsetTest.java
@@ -80,8 +80,13 @@ public class EdmDateTimeOffsetTest extends PrimitiveTypeBaseTest {
final String time = date.toString().substring(11, 19);
assertTrue(instance.valueToString(date, null, null, 3, null, null).contains(time));
+ Timestamp timestamp = new Timestamp(0);
+ timestamp.setNanos(120);
+ assertEquals("1970-01-01T00:00:00.00000012Z", instance.valueToString(timestamp, null, null, 8, null, null));
+
expectFacetsErrorInValueToString(instance, millis, null, null, null, null, null);
expectFacetsErrorInValueToString(instance, 3L, null, null, 2, null, null);
+ expectFacetsErrorInValueToString(instance, timestamp, null, null, 7, null, null);
expectTypeErrorInValueToString(instance, 0);
}
@@ -114,7 +119,7 @@ public class EdmDateTimeOffsetTest extends PrimitiveTypeBaseTest {
dateTime.add(Calendar.MILLISECOND, 7);
assertEquals(dateTime, instance.valueOfString("2012-02-29T01:02:03.007+11:00", null, null, 3, null, null,
Calendar.class));
- assertEquals(530000000, instance.valueOfString("2012-02-29T01:02:03.53+11:00", null, null, 9, null, null,
+ assertEquals(530000001, instance.valueOfString("2012-02-29T01:02:03.530000001+11:00", null, null, 9, null, null,
Timestamp.class).getNanos());
assertEquals(Long.valueOf(120000L), instance.valueOfString("1970-01-01T00:02", null, null, null, null, null,