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/07/29 09:41:05 UTC

git commit: [OLINGO-365] More robust handling for bound operations via proxy

Repository: olingo-odata4
Updated Branches:
  refs/heads/master 8c68516dc -> d56e0ef45


[OLINGO-365] More robust handling for bound operations via proxy


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

Branch: refs/heads/master
Commit: d56e0ef4571263228afe2d74831a1d7ecb6f2888
Parents: 8c68516
Author: Francesco Chicchiriccò <--global>
Authored: Tue Jul 29 09:40:52 2014 +0200
Committer: Francesco Chicchiriccò <--global>
Committed: Tue Jul 29 09:40:52 2014 +0200

----------------------------------------------------------------------
 .../AbstractStructuredInvocationHandler.java    |  5 +-
 .../commons/OperationInvocationHandler.java     | 42 ++++++------
 .../fit/proxy/v4/APIBasicDesignTestITCase.java  | 16 +++--
 .../request/cud/v4/CUDRequestFactory.java       |  5 +-
 .../edm/primitivetype/EdmDateTimeOffset.java    | 72 ++++++++++----------
 5 files changed, 70 insertions(+), 70 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d56e0ef4/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java
index b1835a3..168bece 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractStructuredInvocationHandler.java
@@ -307,7 +307,6 @@ public abstract class AbstractStructuredInvocationHandler extends AbstractInvoca
 
         return res;
       } else {
-
         if (propertyChanges.containsKey(name)) {
           res = propertyChanges.get(name);
         } else if (propertyCache.containsKey(name)) {
@@ -325,7 +324,6 @@ public abstract class AbstractStructuredInvocationHandler extends AbstractInvoca
                     false);
 
           } else if (ref != null && ComplexCollection.class.isAssignableFrom(ref)) {
-
             final ComplexCollectionInvocationHandler<?> collectionHandler;
             final Class<?> itemRef = ClassUtils.extractTypeArg(ref, ComplexCollection.class);
 
@@ -361,8 +359,7 @@ public abstract class AbstractStructuredInvocationHandler extends AbstractInvoca
                     new Class<?>[] {ref}, collectionHandler);
 
           } else if (ref != null && PrimitiveCollection.class.isAssignableFrom(ref)) {
-            final PrimitiveCollectionInvocationHandler collectionHandler;
-
+            PrimitiveCollectionInvocationHandler collectionHandler;
             if (property == null || property.hasNullValue()) {
               collectionHandler = new PrimitiveCollectionInvocationHandler(
                       service,

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d56e0ef4/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/OperationInvocationHandler.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/OperationInvocationHandler.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/OperationInvocationHandler.java
index 1ff39e1..1e94cc7 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/OperationInvocationHandler.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/OperationInvocationHandler.java
@@ -196,12 +196,12 @@ final class OperationInvocationHandler extends AbstractInvocationHandler impleme
         return Proxy.newProxyInstance(
                 Thread.currentThread().getContextClassLoader(),
                 new Class<?>[] {ClassUtils.getTypeClass(method.getGenericReturnType())}, new InvokerHandler(
-                edmOperation.getKey(),
-                parameterValues,
-                operation,
-                edmOperation.getValue(),
-                ClassUtils.getTypeArguments(method.getGenericReturnType()),
-                service));
+                        edmOperation.getKey(),
+                        parameterValues,
+                        operation,
+                        edmOperation.getValue(),
+                        ClassUtils.getTypeArguments(method.getGenericReturnType()),
+                        service));
       } else {
         throw new NoSuchMethodException(method.getName());
       }
@@ -228,50 +228,50 @@ final class OperationInvocationHandler extends AbstractInvocationHandler impleme
 
   private Map.Entry<URI, EdmOperation> getBoundOperation(final Operation operation, final List<String> parameterNames) {
     final CommonODataEntity entity = EntityInvocationHandler.class.cast(target).getEntity();
+    final URI entityURI = EntityInvocationHandler.class.cast(target).getEntityURI();
 
     ODataOperation boundOp = entity.getOperation(operation.name());
     if (boundOp == null) {
       boundOp = entity.getOperation(new FullQualifiedName(targetFQN.getNamespace(), operation.name()).toString());
     }
 
-    boolean useOperationFQN = this.getClient().getConfiguration().isUseUrlOperationFQN();
+    final boolean useOperationFQN = this.getClient().getConfiguration().isUseUrlOperationFQN();
 
     EdmEntityType entityType = getClient().getCachedEdm().getEntityType(entity.getTypeName());
     EdmEntityType baseType = entityType;
     while (boundOp == null && baseType != null) {
       // json minimal/none metadata doesn't return operations for entity, so here try creating it from Edm: 
-      EdmAction action = this.getClient().getCachedEdm().getBoundAction(
+      final EdmAction action = this.getClient().getCachedEdm().getBoundAction(
               new FullQualifiedName(targetFQN.getNamespace(), operation.name()),
               baseType.getFullQualifiedName(),
               false);
 
-      if (action != null) {
+      if (action == null) {
+        baseType = baseType.getBaseType();
+      } else {
         boundOp = new ODataOperation();
         boundOp.setMetadataAnchor(action.getFullQualifiedName().toString());
         boundOp.setTitle(boundOp.getMetadataAnchor());
-        boundOp.setTarget(URI.create(entity.getEditLink().toString() + "/"
+        boundOp.setTarget(URI.create(entityURI.toASCIIString() + "/"
                 + (useOperationFQN ? action.getFullQualifiedName().toString() : operation.name())));
-      } else {
-        baseType = baseType.getBaseType();
       }
     }
 
     baseType = entityType;
     while (boundOp == null && baseType != null) {
       // json minimal/none metadata doesn't return operations for entity, so here try creating it from Edm: 
-      EdmFunction func = this.getClient().getCachedEdm().getBoundFunction(
+      final EdmFunction func = this.getClient().getCachedEdm().getBoundFunction(
               new FullQualifiedName(targetFQN.getNamespace(), operation.name()), baseType.getFullQualifiedName(),
               false, parameterNames);
 
-      if (func != null) {
+      if (func == null) {
+        baseType = baseType.getBaseType();
+      } else {
         boundOp = new ODataOperation();
         boundOp.setMetadataAnchor(func.getFullQualifiedName().toString());
         boundOp.setTitle(boundOp.getMetadataAnchor());
-        boundOp.setTarget(URI.create((entity.getEditLink() == null
-                ? EntityInvocationHandler.class.cast(target).getEntityURI() : entity.getEditLink()).toString() + "/"
+        boundOp.setTarget(URI.create(entityURI.toASCIIString() + "/"
                 + (useOperationFQN ? func.getFullQualifiedName().toString() : operation.name())));
-      } else {
-        baseType = baseType.getBaseType();
       }
     }
     if (boundOp == null) {
@@ -287,9 +287,9 @@ final class OperationInvocationHandler extends AbstractInvocationHandler impleme
     while (edmOperation == null && entityType != null) {
       edmOperation = operation.type() == OperationType.FUNCTION
               ? getClient().getCachedEdm().getBoundFunction(
-              operationFQN, entityType.getFullQualifiedName(), false, parameterNames)
+                      operationFQN, entityType.getFullQualifiedName(), false, parameterNames)
               : getClient().getCachedEdm().getBoundAction(
-              operationFQN, entityType.getFullQualifiedName(), false);
+                      operationFQN, entityType.getFullQualifiedName(), false);
       if (entityType.getBaseType() != null) {
         entityType = entityType.getBaseType();
       }
@@ -318,6 +318,6 @@ final class OperationInvocationHandler extends AbstractInvocationHandler impleme
 
     return new AbstractMap.SimpleEntry<URI, EdmOperation>(
             URI.create(((EntityCollectionInvocationHandler<?>) target).getURI().toASCIIString()
-            + "/" + edmOperation.getName()), edmOperation);
+                    + "/" + edmOperation.getName()), edmOperation);
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d56e0ef4/fit/src/test/java/org/apache/olingo/fit/proxy/v4/APIBasicDesignTestITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/v4/APIBasicDesignTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/APIBasicDesignTestITCase.java
index e687d41..828068b 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/v4/APIBasicDesignTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/APIBasicDesignTestITCase.java
@@ -361,8 +361,8 @@ public class APIBasicDesignTestITCase extends AbstractTestITCase {
   }
 
   @Test
-  public void getProductDetails() {
-    Product product = getContainer().newEntityInstance(Product.class);
+  public void boundOperationsAfterCreate() {
+    final Product product = getContainer().newEntityInstance(Product.class);
     product.setProductID(1012);
     product.setName("Latte");
     product.setQuantityPerUnit("100g Bag");
@@ -390,9 +390,14 @@ public class APIBasicDesignTestITCase extends AbstractTestITCase {
     product.setDetails(detailCollection);
 
     getContainer().getProducts().add(product);
-    getContainer().flush(); // The first HTTP Request to create product and the linked product detail
+    
+    // The first HTTP Request to create product and the linked product detail
+    getContainer().flush();
+
+    // The second HTTP request to access a bound operation via the local object
+    assertNotNull(product.operations().addAccessRight(AccessLevel.None).execute());
 
-    // the second HTTP Request to execute getProductDetails() operation.
+    // The third HTTP Request to access a bound operation via entity URL
     final StructuredCollectionInvoker<ProductDetailCollection> result =
             container.getProducts().getByKey(1012).operations().getProductDetails(1);
     assertEquals(1, result.execute().size());
@@ -405,7 +410,7 @@ public class APIBasicDesignTestITCase extends AbstractTestITCase {
     // ---------------------------------------
     org.apache.olingo.fit.proxy.v3.staticservice.Service<org.apache.olingo.client.api.v3.EdmEnabledODataClient> v3serv =
             org.apache.olingo.fit.proxy.v3.staticservice.Service.getV3(
-            "http://localhost:9080/stub/StaticService/V30/Static.svc");
+                    "http://localhost:9080/stub/StaticService/V30/Static.svc");
     v3serv.getClient().getConfiguration().setDefaultBatchAcceptFormat(ContentType.APPLICATION_OCTET_STREAM);
     final DefaultContainer v3cont = v3serv.getEntityContainer(DefaultContainer.class);
     assertNotNull(v3cont);
@@ -456,7 +461,6 @@ public class APIBasicDesignTestITCase extends AbstractTestITCase {
     // container.getOrders().getByKey(1).getCustomerForOrder().getEmails().execute().isEmpty());
     // Not supported by the test service BTW generates a single request as expected: 
     // <service root>/Orders(1)/CustomerForOrder/Emails
-
     emails.add("fabio.martelli@tirasa.net");
     container.getPeople().getByKey(1).setEmails(emails);
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d56e0ef4/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v4/CUDRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v4/CUDRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v4/CUDRequestFactory.java
index 6652809..f5753eb 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v4/CUDRequestFactory.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v4/CUDRequestFactory.java
@@ -38,9 +38,8 @@ public interface CUDRequestFactory extends CommonCUDRequestFactory<UpdateType> {
    * appropriate format document for details. On successful completion, the response MUST be 204 No Content and contain
    * an empty body.
    *
-   * @param <E> concrete ODataEntity implementation
-   * @param targetURI entity set URI.
-   * @param entity entity to be created.
+   * @param targetURI entity set URI
+   * @param reference entity reference
    * @return new ODataEntityCreateRequest instance.
    */
   ODataReferenceAddingRequest getReferenceAddingRequest(URI targetURI, URI reference);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/d56e0ef4/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 aea2ebb..c3b4bcc 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
@@ -41,7 +41,7 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
   };
 
   private static final Pattern PATTERN = Pattern.compile(
-      "(-?\\p{Digit}{4,})-(\\p{Digit}{2})-(\\p{Digit}{2})"
+          "(-?\\p{Digit}{4,})-(\\p{Digit}{2})-(\\p{Digit}{2})"
           + "T(\\p{Digit}{2}):(\\p{Digit}{2})(?::(\\p{Digit}{2})(\\.(\\p{Digit}{0,12}?)0*)?)?"
           + "(Z|([-+]\\p{Digit}{2}:\\p{Digit}{2}))?");
 
@@ -58,51 +58,51 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
 
   @Override
   protected <T> T internalValueOfString(final String value,
-      final Boolean isNullable, final Integer maxLength, final Integer precision,
-      final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
+          final Boolean isNullable, final Integer maxLength, final Integer precision,
+          final Integer scale, final Boolean isUnicode, final Class<T> returnType) throws EdmPrimitiveTypeException {
 
     final Matcher matcher = PATTERN.matcher(value);
     if (!matcher.matches()) {
       throw new EdmPrimitiveTypeException("EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)");
     }
 
-    final String timeZoneOffset = matcher.group(9) != null && matcher.group(10) != null
-        && !matcher.group(10).matches("[-+]0+:0+") ? matcher.group(10) : null;
+    final String timeZoneOffset = matcher.group(9) == null || matcher.group(10) == null
+            || matcher.group(10).matches("[-+]0+:0+") ? null : matcher.group(10);
     final Calendar dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT" + timeZoneOffset));
     if (dateTimeValue.get(Calendar.ZONE_OFFSET) == 0 && timeZoneOffset != null) {
       throw new EdmPrimitiveTypeException(
-          "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)");
+              "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)");
     }
     dateTimeValue.clear();
 
     dateTimeValue.set(
-        Short.parseShort(matcher.group(1)),
-        Byte.parseByte(matcher.group(2)) - 1, // month is zero-based
-        Byte.parseByte(matcher.group(3)),
-        Byte.parseByte(matcher.group(4)),
-        Byte.parseByte(matcher.group(5)),
-        matcher.group(6) == null ? 0 : Byte.parseByte(matcher.group(6)));
+            Short.parseShort(matcher.group(1)),
+            Byte.parseByte(matcher.group(2)) - 1, // month is zero-based
+            Byte.parseByte(matcher.group(3)),
+            Byte.parseByte(matcher.group(4)),
+            Byte.parseByte(matcher.group(5)),
+            matcher.group(6) == null ? 0 : Byte.parseByte(matcher.group(6)));
 
     int nanoSeconds = 0;
     if (matcher.group(7) != null) {
       if (matcher.group(7).length() == 1 || matcher.group(7).length() > 13) {
         throw new EdmPrimitiveTypeException(
-            "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)");
+                "EdmPrimitiveTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value)");
       }
       final String decimals = matcher.group(8);
       if (decimals.length() > (precision == null ? 0 : precision)) {
         throw new EdmPrimitiveTypeException(
-            "EdmPrimitiveTypeException.LITERAL_FACETS_NOT_MATCHED.addContent(value, facets)");
+                "EdmPrimitiveTypeException.LITERAL_FACETS_NOT_MATCHED.addContent(value, facets)");
       }
       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());
+        final String milliSeconds = decimals.length() > 3
+                ? decimals.substring(0, 3)
+                : decimals + "000".substring(decimals.length());
         dateTimeValue.set(Calendar.MILLISECOND, Short.parseShort(milliSeconds));
       }
     }
@@ -111,26 +111,26 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
       return convertDateTime(dateTimeValue, nanoSeconds, 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);
     }
   }
 
   /**
    * Converts a {@link Calendar} value into the requested return type if possible.
-   * 
+   *
    * @param dateTimeValue the value
    * @param nanoSeconds nanoseconds part of the value; only used for the {@link Timestamp} return type
-   * @param returnType the class of the returned value;
-   * it must be one of {@link Calendar}, {@link Long}, {@link Date}, or {@link Timestamp}
+   * @param returnType the class of the returned value; it must be one of {@link Calendar}, {@link Long}, {@link Date},
+   * or {@link Timestamp}
    * @return the converted value
    * @throws IllegalArgumentException if the Calendar value is not valid
    * @throws ClassCastException if the return type is not allowed
    */
   protected static <T> T convertDateTime(final Calendar dateTimeValue, final int nanoSeconds,
-      final Class<T> returnType) throws IllegalArgumentException, ClassCastException {
+          final Class<T> returnType) throws IllegalArgumentException, ClassCastException {
 
     // The Calendar class does not check any values until a get method is called,
     // so we do just that to validate the fields that may have been set,
@@ -159,8 +159,8 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
 
   @Override
   protected <T> String internalValueToString(final T value,
-      final Boolean isNullable, final Integer maxLength, final Integer precision,
-      final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
+          final Boolean isNullable, final Integer maxLength, final Integer precision,
+          final Integer scale, final Boolean isUnicode) throws EdmPrimitiveTypeException {
 
     final Calendar dateTimeValue;
     final int fractionalSecs;
@@ -197,11 +197,11 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
       }
     } 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)
-        + dateTimeValue.get(Calendar.DST_OFFSET)) / 60 / 1000;
+            + dateTimeValue.get(Calendar.DST_OFFSET)) / 60 / 1000;
     final int offsetHours = offsetInMinutes / 60;
     final int offsetMinutes = Math.abs(offsetInMinutes % 60);
     final String offsetString = offsetInMinutes == 0 ? "Z" : String.format("%+03d:%02d", offsetHours, offsetMinutes);
@@ -212,7 +212,7 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
 
   /**
    * Creates a date/time value from the given value.
-   * 
+   *
    * @param value the value as {@link Calendar}, {@link Date}, or {@link Long}
    * @return the value as {@link Calendar}
    * @throws EdmPrimitiveTypeException if the type of the value is not supported
@@ -232,7 +232,7 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
       dateTimeValue.setTimeInMillis((Long) value);
     } else {
       throw new EdmPrimitiveTypeException(
-          "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass())");
+              "EdmPrimitiveTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(" + value.getClass().getName() + ")");
     }
     return dateTimeValue;
   }
@@ -240,7 +240,7 @@ public final class EdmDateTimeOffset extends SingletonPrimitiveType {
   /**
    * Appends the given number to the given string builder, assuming that the number has at most two digits,
    * performance-optimized.
-   * 
+   *
    * @param result a {@link StringBuilder}
    * @param number an integer that must satisfy <code>0 <= number <= 99</code>
    */
@@ -252,14 +252,14 @@ 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.
-   * 
+   *
    * @param result a {@link StringBuilder}
    * @param milliseconds an integer that must satisfy <code>0 &lt;= milliseconds &lt;= 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 int milliseconds,
-      final Integer precision) throws IllegalArgumentException {
+          final Integer precision) throws IllegalArgumentException {
 
     final int digits = milliseconds % 1000 == 0 ? 0 : milliseconds % 100 == 0 ? 1 : milliseconds % 10 == 0 ? 2 : 3;
     if (digits > 0) {
@@ -279,14 +279,14 @@ 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 {
+          final Integer precision) throws IllegalArgumentException {
 
     if (fractionalSeconds > 0) {
       String formatted = NANO_FORMAT.get().format(fractionalSeconds);