Repository: olingo-odata4
Updated Branches:
  refs/heads/master 3bb39defd -> b157e26ca


Fixing incorrect millis <-> nanos conversion (with Timestamp) in 
EdmDateTimeOffset


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/b157e26c
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/b157e26c
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/b157e26c

Branch: refs/heads/master
Commit: b157e26caf34f8953b1c7f65b4aca124e7a49c9c
Parents: 3bb39de
Author: Francesco Chicchiriccò <[email protected]>
Authored: Thu Apr 17 15:57:56 2014 +0200
Committer: Francesco Chicchiriccò <[email protected]>
Committed: Thu Apr 17 15:57:56 2014 +0200

----------------------------------------------------------------------
 .../core/it/v3/PropertyRetrieveTestITCase.java  | 142 +++++++++----------
 .../client/core/v3/PrimitiveValueTest.java      |   8 +-
 .../edm/primitivetype/EdmDateTimeOffset.java    |  28 +++-
 3 files changed, 99 insertions(+), 79 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b157e26c/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/PropertyRetrieveTestITCase.java
----------------------------------------------------------------------
diff --git 
a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/PropertyRetrieveTestITCase.java
 
b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/PropertyRetrieveTestITCase.java
index 2e495dc..a38b403 100644
--- 
a/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/PropertyRetrieveTestITCase.java
+++ 
b/lib/client-core/src/test/java/org/apache/olingo/client/core/it/v3/PropertyRetrieveTestITCase.java
@@ -18,14 +18,19 @@
  */
 package org.apache.olingo.client.core.it.v3;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import java.util.List;
 import org.apache.olingo.client.api.communication.ODataClientErrorException;
 import 
org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
 import 
org.apache.olingo.client.api.communication.request.retrieve.ODataPropertyRequest;
 import 
org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
-import org.apache.olingo.client.api.uri.CommonURIBuilder;
+import org.apache.olingo.client.api.uri.v3.URIBuilder;
 import org.apache.olingo.commons.api.domain.CommonODataEntity;
-import org.apache.olingo.commons.api.domain.CommonODataEntitySet;
 import org.apache.olingo.commons.api.domain.ODataCollectionValue;
 import org.apache.olingo.commons.api.domain.ODataComplexValue;
 import org.apache.olingo.commons.api.domain.ODataPrimitiveValue;
@@ -33,17 +38,12 @@ import org.apache.olingo.commons.api.domain.v3.ODataEntity;
 import org.apache.olingo.commons.api.domain.v3.ODataEntitySet;
 import org.apache.olingo.commons.api.domain.v3.ODataProperty;
 import org.apache.olingo.commons.api.format.ODataFormat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
 import org.junit.Test;
 
 public class PropertyRetrieveTestITCase extends AbstractTestITCase {
 
-  private void retreivePropertyTest(final ODataFormat format, String 
entitySegment, String structuralSegment) {
-    final CommonURIBuilder<?> uriBuilder = 
client.getURIBuilder(testStaticServiceRootURL).
+  private void retrievePropertyTest(final ODataFormat format, String 
entitySegment, String structuralSegment) {
+    final URIBuilder uriBuilder = 
client.getURIBuilder(testStaticServiceRootURL).
             
appendEntitySetSegment(entitySegment).appendPropertySegment(structuralSegment);
     final ODataPropertyRequest<ODataProperty> req = 
client.getRetrieveRequestFactory().
             getPropertyRequest(uriBuilder.build());
@@ -75,48 +75,48 @@ public class PropertyRetrieveTestITCase extends 
AbstractTestITCase {
   @Test
   public void jsonRetrieveProperty() {
     //Primitive types
-    retreivePropertyTest(ODataFormat.JSON, "Customer(-10)", "Name");
-    retreivePropertyTest(ODataFormat.JSON, "Customer(-10)", "CustomerId");
-    retreivePropertyTest(ODataFormat.JSON, 
"Message(FromUsername='1',MessageId=-10)", "Sent");
-    retreivePropertyTest(ODataFormat.JSON, 
"Message(FromUsername='1',MessageId=-10)", "IsRead");
+    retrievePropertyTest(ODataFormat.JSON, "Customer(-10)", "Name");
+    retrievePropertyTest(ODataFormat.JSON, "Customer(-10)", "CustomerId");
+    retrievePropertyTest(ODataFormat.JSON, 
"Message(FromUsername='1',MessageId=-10)", "Sent");
+    retrievePropertyTest(ODataFormat.JSON, 
"Message(FromUsername='1',MessageId=-10)", "IsRead");
     //Collection of Complex types
-    retreivePropertyTest(ODataFormat.JSON, "Customer(-10)", 
"BackupContactInfo");
+    retrievePropertyTest(ODataFormat.JSON, "Customer(-10)", 
"BackupContactInfo");
     //Collection of primitives
-    retreivePropertyTest(ODataFormat.JSON, "Customer(-10)/PrimaryContactInfo", 
"EmailBag");
+    retrievePropertyTest(ODataFormat.JSON, "Customer(-10)/PrimaryContactInfo", 
"EmailBag");
     //complex types
-    retreivePropertyTest(ODataFormat.JSON, "Order(-9)", "Concurrency");
+    retrievePropertyTest(ODataFormat.JSON, "Order(-9)", "Concurrency");
   }
   //test with json full metadata
 
   @Test
   public void jsonFullMetadataRetrieveProperty() {
     //primitive types
-    retreivePropertyTest(ODataFormat.JSON_FULL_METADATA, "Customer(-10)", 
"Name");
-    retreivePropertyTest(ODataFormat.JSON_FULL_METADATA, "Customer(-10)", 
"CustomerId");
-    retreivePropertyTest(ODataFormat.JSON_FULL_METADATA, 
"Message(FromUsername='1',MessageId=-10)", "Sent");
-    retreivePropertyTest(ODataFormat.JSON_FULL_METADATA, 
"Message(FromUsername='1',MessageId=-10)", "IsRead");
+    retrievePropertyTest(ODataFormat.JSON_FULL_METADATA, "Customer(-10)", 
"Name");
+    retrievePropertyTest(ODataFormat.JSON_FULL_METADATA, "Customer(-10)", 
"CustomerId");
+    retrievePropertyTest(ODataFormat.JSON_FULL_METADATA, 
"Message(FromUsername='1',MessageId=-10)", "Sent");
+    retrievePropertyTest(ODataFormat.JSON_FULL_METADATA, 
"Message(FromUsername='1',MessageId=-10)", "IsRead");
     //Collection of Complex types
-    retreivePropertyTest(ODataFormat.JSON_FULL_METADATA, "Customer(-10)", 
"BackupContactInfo");
+    retrievePropertyTest(ODataFormat.JSON_FULL_METADATA, "Customer(-10)", 
"BackupContactInfo");
     //Collection of primitives         
-    retreivePropertyTest(ODataFormat.JSON_FULL_METADATA, 
"Customer(-10)/PrimaryContactInfo", "EmailBag");
+    retrievePropertyTest(ODataFormat.JSON_FULL_METADATA, 
"Customer(-10)/PrimaryContactInfo", "EmailBag");
     //Complex types
-    retreivePropertyTest(ODataFormat.JSON_FULL_METADATA, "Order(-9)", 
"Concurrency");
+    retrievePropertyTest(ODataFormat.JSON_FULL_METADATA, "Order(-9)", 
"Concurrency");
   }
   // json with no metadata
 
   @Test
   public void jsonNoMetadataRetrieveProperty() {
     //primitive types
-    retreivePropertyTest(ODataFormat.JSON_NO_METADATA, "Customer(-10)", 
"Name");
-    retreivePropertyTest(ODataFormat.JSON_NO_METADATA, "Customer(-10)", 
"CustomerId");
-    retreivePropertyTest(ODataFormat.JSON_NO_METADATA, 
"Message(FromUsername='1',MessageId=-10)", "Sent");
-    retreivePropertyTest(ODataFormat.JSON_NO_METADATA, 
"Message(FromUsername='1',MessageId=-10)", "IsRead");
+    retrievePropertyTest(ODataFormat.JSON_NO_METADATA, "Customer(-10)", 
"Name");
+    retrievePropertyTest(ODataFormat.JSON_NO_METADATA, "Customer(-10)", 
"CustomerId");
+    retrievePropertyTest(ODataFormat.JSON_NO_METADATA, 
"Message(FromUsername='1',MessageId=-10)", "Sent");
+    retrievePropertyTest(ODataFormat.JSON_NO_METADATA, 
"Message(FromUsername='1',MessageId=-10)", "IsRead");
     //Collection of Complex types
-    retreivePropertyTest(ODataFormat.JSON_NO_METADATA, "Customer(-10)", 
"BackupContactInfo");
+    retrievePropertyTest(ODataFormat.JSON_NO_METADATA, "Customer(-10)", 
"BackupContactInfo");
     //Collection of Primitives
-    retreivePropertyTest(ODataFormat.JSON_NO_METADATA, 
"Customer(-10)/PrimaryContactInfo", "EmailBag");
+    retrievePropertyTest(ODataFormat.JSON_NO_METADATA, 
"Customer(-10)/PrimaryContactInfo", "EmailBag");
     //Complex types
-    retreivePropertyTest(ODataFormat.JSON_NO_METADATA, "Order(-9)", 
"Concurrency");
+    retrievePropertyTest(ODataFormat.JSON_NO_METADATA, "Order(-9)", 
"Concurrency");
 
   }
   // json with minimla metadata
@@ -124,55 +124,55 @@ public class PropertyRetrieveTestITCase extends 
AbstractTestITCase {
   @Test
   public void jsonmininalRetrieveProperty() {
     //primitive types
-    retreivePropertyTest(ODataFormat.JSON_NO_METADATA, "Customer(-10)", 
"Name");
-    retreivePropertyTest(ODataFormat.JSON_NO_METADATA, "Customer(-10)", 
"CustomerId");
-    retreivePropertyTest(ODataFormat.JSON_NO_METADATA, 
"Message(FromUsername='1',MessageId=-10)", "Sent");
-    retreivePropertyTest(ODataFormat.JSON_NO_METADATA, 
"Message(FromUsername='1',MessageId=-10)", "IsRead");
+    retrievePropertyTest(ODataFormat.JSON_NO_METADATA, "Customer(-10)", 
"Name");
+    retrievePropertyTest(ODataFormat.JSON_NO_METADATA, "Customer(-10)", 
"CustomerId");
+    retrievePropertyTest(ODataFormat.JSON_NO_METADATA, 
"Message(FromUsername='1',MessageId=-10)", "Sent");
+    retrievePropertyTest(ODataFormat.JSON_NO_METADATA, 
"Message(FromUsername='1',MessageId=-10)", "IsRead");
     //Collection of complex types
-    retreivePropertyTest(ODataFormat.JSON_NO_METADATA, "Customer(-10)", 
"BackupContactInfo");
+    retrievePropertyTest(ODataFormat.JSON_NO_METADATA, "Customer(-10)", 
"BackupContactInfo");
     //Collection of primitives
-    retreivePropertyTest(ODataFormat.JSON_NO_METADATA, 
"Customer(-10)/PrimaryContactInfo", "EmailBag");
+    retrievePropertyTest(ODataFormat.JSON_NO_METADATA, 
"Customer(-10)/PrimaryContactInfo", "EmailBag");
     //Complex types
-    retreivePropertyTest(ODataFormat.JSON_NO_METADATA, "Order(-9)", 
"Concurrency");
+    retrievePropertyTest(ODataFormat.JSON_NO_METADATA, "Order(-9)", 
"Concurrency");
   }
   // with xml header
 
   @Test
   public void xmlRetrieveProperty() {
     //primitive types
-    retreivePropertyTest(ODataFormat.XML, "Customer(-10)", "Name");
-    retreivePropertyTest(ODataFormat.XML, "Customer(-10)", "CustomerId");
-    retreivePropertyTest(ODataFormat.XML, 
"Message(FromUsername='1',MessageId=-10)", "Sent");
-    retreivePropertyTest(ODataFormat.XML, 
"Message(FromUsername='1',MessageId=-10)", "IsRead");
+    retrievePropertyTest(ODataFormat.XML, "Customer(-10)", "Name");
+    retrievePropertyTest(ODataFormat.XML, "Customer(-10)", "CustomerId");
+    retrievePropertyTest(ODataFormat.XML, 
"Message(FromUsername='1',MessageId=-10)", "Sent");
+    retrievePropertyTest(ODataFormat.XML, 
"Message(FromUsername='1',MessageId=-10)", "IsRead");
     //Collection of Complex types
-    retreivePropertyTest(ODataFormat.XML, "Customer(-10)", 
"BackupContactInfo");
+    retrievePropertyTest(ODataFormat.XML, "Customer(-10)", 
"BackupContactInfo");
     //Collection of primitives
-    retreivePropertyTest(ODataFormat.XML, "Customer(-10)/PrimaryContactInfo", 
"EmailBag");
+    retrievePropertyTest(ODataFormat.XML, "Customer(-10)/PrimaryContactInfo", 
"EmailBag");
     //Complex types
-    retreivePropertyTest(ODataFormat.XML, "Order(-9)", "Concurrency");
+    retrievePropertyTest(ODataFormat.XML, "Order(-9)", "Concurrency");
   }
   // with atom header
 
   @Test
   public void atomRetrieveProperty() {
     //primitive types
-    retreivePropertyTest(ODataFormat.XML, "Customer(-10)", "Name");
-    retreivePropertyTest(ODataFormat.XML, "Customer(-10)", "CustomerId");
-    retreivePropertyTest(ODataFormat.XML, 
"Message(FromUsername='1',MessageId=-10)", "Sent");
-    retreivePropertyTest(ODataFormat.XML, 
"Message(FromUsername='1',MessageId=-10)", "IsRead");
+    retrievePropertyTest(ODataFormat.XML, "Customer(-10)", "Name");
+    retrievePropertyTest(ODataFormat.XML, "Customer(-10)", "CustomerId");
+    retrievePropertyTest(ODataFormat.XML, 
"Message(FromUsername='1',MessageId=-10)", "Sent");
+    retrievePropertyTest(ODataFormat.XML, 
"Message(FromUsername='1',MessageId=-10)", "IsRead");
     //Collection of Complex types 
-    retreivePropertyTest(ODataFormat.XML, "Customer(-10)", 
"BackupContactInfo");
+    retrievePropertyTest(ODataFormat.XML, "Customer(-10)", 
"BackupContactInfo");
     //Collection of primitives
-    retreivePropertyTest(ODataFormat.XML, "Customer(-10)/PrimaryContactInfo", 
"EmailBag");
+    retrievePropertyTest(ODataFormat.XML, "Customer(-10)/PrimaryContactInfo", 
"EmailBag");
     //complex types
-    retreivePropertyTest(ODataFormat.XML, "Order(-9)", "Concurrency");
+    retrievePropertyTest(ODataFormat.XML, "Order(-9)", "Concurrency");
   }
   // with invalid structural segment
 
   @Test
   public void invalidSegmentRetrieveProperty() {
     //primitive types
-    retreivePropertyTest(ODataFormat.XML, "Customers(-10)", "Name");
+    retrievePropertyTest(ODataFormat.XML, "Customers(-10)", "Name");
 
   }
   // with null pub format
@@ -180,7 +180,7 @@ public class PropertyRetrieveTestITCase extends 
AbstractTestITCase {
   @Test
   public void nullSegmentRetrieveProperty() {
     //primitive types
-    retreivePropertyTest(null, "Customers(-10)", "Name");
+    retrievePropertyTest(null, "Customers(-10)", "Name");
 
   }
   // with null accept header format
@@ -188,7 +188,7 @@ public class PropertyRetrieveTestITCase extends 
AbstractTestITCase {
   @Test
   public void nullAcceptRetrieveProperty() {
     //primitive types
-    retreivePropertyTest(ODataFormat.XML, "Customers(-10)", "Name");
+    retrievePropertyTest(ODataFormat.XML, "Customers(-10)", "Name");
 
   }
   // with json pub format and atom accept format
@@ -196,7 +196,7 @@ public class PropertyRetrieveTestITCase extends 
AbstractTestITCase {
   @Test
   public void differentFormatAndAcceptRetrieveProperty() {
     //
-    retreivePropertyTest(ODataFormat.JSON_FULL_METADATA, "Customers(-10)", 
"Name");
+    retrievePropertyTest(ODataFormat.JSON_FULL_METADATA, "Customers(-10)", 
"Name");
 
   }
   //bad request 400 error. Message takes two keys
@@ -204,22 +204,22 @@ public class PropertyRetrieveTestITCase extends 
AbstractTestITCase {
   @Test
   public void badRequestTest() {
     //primitive types
-    retreivePropertyTest(ODataFormat.JSON_FULL_METADATA, 
"Message(FromUsername='1')", "Sent");
+    retrievePropertyTest(ODataFormat.JSON_FULL_METADATA, 
"Message(FromUsername='1')", "Sent");
   }
   //navigation link of stream
 
   @Test
   public void navigationMediaLink() {
-    CommonURIBuilder<?> uriBuilder = 
client.getURIBuilder(testStaticServiceRootURL).
+    final URIBuilder uriBuilder = 
client.getURIBuilder(testStaticServiceRootURL).
             
appendNavigationSegment("Product").appendKeySegment(-7).appendLinksSegment("Photos");
-    ODataEntitySetRequest<ODataEntitySet> req = 
client.getRetrieveRequestFactory().
+    final ODataEntitySetRequest<ODataEntitySet> req = 
client.getRetrieveRequestFactory().
             getEntitySetRequest(uriBuilder.build());
     req.setAccept("application/json");
-    ODataRetrieveResponse<ODataEntitySet> res = req.execute();
+    final ODataRetrieveResponse<ODataEntitySet> res = req.execute();
     assertEquals(200, res.getStatusCode());
-    CommonODataEntitySet entitySet = res.getBody();
+    final ODataEntitySet entitySet = res.getBody();
     assertNotNull(entitySet);
-    List<? extends CommonODataEntity> entity = entitySet.getEntities();
+    final List<? extends CommonODataEntity> entity = entitySet.getEntities();
     assertNotNull(entity);
     assertEquals(entity.size(), 2);
     assertEquals(testStaticServiceRootURL + 
"/ProductPhoto(PhotoId=-3,ProductId=-3)",
@@ -234,17 +234,17 @@ public class PropertyRetrieveTestITCase extends 
AbstractTestITCase {
 
   @Test
   public void navigationMediaLinkInvalidQuery() {
-    CommonURIBuilder<?> uriBuilder = 
client.getURIBuilder(testStaticServiceRootURL).
+    final URIBuilder uriBuilder = 
client.getURIBuilder(testStaticServiceRootURL).
             
appendNavigationSegment("Product").appendKeySegment(-7).appendLinksSegment("Photo");
-    ODataEntitySetRequest<ODataEntitySet> req = 
client.getRetrieveRequestFactory().
+    final ODataEntitySetRequest<ODataEntitySet> req = 
client.getRetrieveRequestFactory().
             getEntitySetRequest(uriBuilder.build());
     req.setAccept("application/json");
     try {
-      ODataRetrieveResponse<ODataEntitySet> res = req.execute();
+      final ODataRetrieveResponse<ODataEntitySet> res = req.execute();
       assertEquals(200, res.getStatusCode());
-      CommonODataEntitySet entitySet = res.getBody();
+      ODataEntitySet entitySet = res.getBody();
       assertNotNull(entitySet);
-      List<? extends CommonODataEntity> entity = entitySet.getEntities();
+      final List<? extends CommonODataEntity> entity = entitySet.getEntities();
       assertNotNull(entity);
       assertEquals(entity.size(), 2);
       assertEquals(testStaticServiceRootURL + 
"/ProductPhoto(PhotoId=-3,ProductId=-3)", entity.get(0).
@@ -258,17 +258,17 @@ public class PropertyRetrieveTestITCase extends 
AbstractTestITCase {
 
   @Test
   public void navigationMediaLinkInvalidFormat() {
-    CommonURIBuilder<?> uriBuilder = 
client.getURIBuilder(testStaticServiceRootURL).
+    final URIBuilder uriBuilder = 
client.getURIBuilder(testStaticServiceRootURL).
             
appendNavigationSegment("Product").appendKeySegment(-7).appendLinksSegment("Photos");
-    ODataEntitySetRequest<ODataEntitySet> req = 
client.getRetrieveRequestFactory().
+    final ODataEntitySetRequest<ODataEntitySet> req = 
client.getRetrieveRequestFactory().
             getEntitySetRequest(uriBuilder.build());
     req.setAccept("application/atom+xml");
     try {
-      ODataRetrieveResponse<ODataEntitySet> res = req.execute();
+      final ODataRetrieveResponse<ODataEntitySet> res = req.execute();
       assertEquals(200, res.getStatusCode());
-      ODataEntitySet entitySet = res.getBody();
+      final ODataEntitySet entitySet = res.getBody();
       assertNotNull(entitySet);
-      List<ODataEntity> entity = entitySet.getEntities();
+      final List<ODataEntity> entity = entitySet.getEntities();
       assertNotNull(entity);
       assertEquals(entity.size(), 2);
       assertEquals(testStaticServiceRootURL + 
"/ProductPhoto(PhotoId=-3,ProductId=-3)", entity.get(0).

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b157e26c/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/PrimitiveValueTest.java
----------------------------------------------------------------------
diff --git 
a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/PrimitiveValueTest.java
 
b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/PrimitiveValueTest.java
index 24c13da..260f9a4 100644
--- 
a/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/PrimitiveValueTest.java
+++ 
b/lib/client-core/src/test/java/org/apache/olingo/client/core/v3/PrimitiveValueTest.java
@@ -152,9 +152,13 @@ public class PrimitiveValueTest extends AbstractTest {
     assertEquals(expected.get(Calendar.MILLISECOND), 
asCalendar.get(Calendar.MILLISECOND));
 
     final Timestamp asTimestamp = 
value.asPrimitive().toCastValue(Timestamp.class);
-    assertEquals(expected.get(Calendar.MILLISECOND), asTimestamp.getNanos());
-    
+    assertEquals(expected.get(Calendar.MILLISECOND), asTimestamp.getNanos() / 
1000000);
+
     assertEquals("2013-01-10T02:00:00.022Z", value.asPrimitive().toString());
+
+    final ODataValue parsed = 
getClient().getObjectFactory().newPrimitiveValueBuilder().
+            
setType(EdmPrimitiveTypeKind.DateTimeOffset).setText(value.asPrimitive().toString()).build();
+    assertEquals("2013-01-10T03:00:00.022+01:00", 
parsed.asPrimitive().toString());
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b157e26c/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 c2b88c0..2e7ab98 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,6 +19,7 @@
 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;
@@ -32,6 +33,13 @@ 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*)?)?"
@@ -95,7 +103,9 @@ public final class EdmDateTimeOffset extends 
SingletonPrimitiveType {
       dateTimeValue.set(Calendar.MILLISECOND, Short.parseShort(milliSeconds));
 
       if (!decimals.isEmpty()) {
-        timestamp.setNanos(Integer.parseInt(decimals));
+        final int fractionalSecs = Integer.parseInt(decimals);
+        // if fractional are just milliseconds, convert to nanoseconds
+        timestamp.setNanos(fractionalSecs < 1000 ? fractionalSecs * 1000000 : 
fractionalSecs);
       }
     }
 
@@ -253,8 +263,13 @@ public final class EdmDateTimeOffset extends 
SingletonPrimitiveType {
    */
   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) {
+      if (precision == null || precision < digits) {
+        throw new IllegalArgumentException();
+      }
+
       result.append('.');
       for (int d = 100; d > 0; d /= 10) {
         final byte digit = (byte) (milliseconds % (d * 10) / d);
@@ -262,10 +277,6 @@ public final class EdmDateTimeOffset extends 
SingletonPrimitiveType {
           result.append((char) ('0' + digit));
         }
       }
-
-      if (precision == null || precision < digits) {
-        throw new IllegalArgumentException();
-      }
     }
   }
 
@@ -285,7 +296,12 @@ public final class EdmDateTimeOffset extends 
SingletonPrimitiveType {
         throw new IllegalArgumentException();
       }
 
-      result.append('.').append(fractionalSeconds);
+      String fractionals = NANO_FORMAT.get().format(fractionalSeconds);
+      // Keep output similar to Calendar's, if possible
+      if ("000000".equals(fractionals.substring(3))) {
+        fractionals = fractionals.substring(0, 3);
+      }
+      result.append('.').append(fractionals);
     }
   }
 }

Reply via email to