Report ErrorType.APPLICATION from codecs
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / codec / BinaryStringCodec.java
index 69881ef44fc30e2efcbf465aeb6095884ca72530..920a19897e752f28575b76dfac756a4070fe868e 100644 (file)
@@ -7,14 +7,14 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.codec;
 
-import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.annotations.Beta;
+import com.google.common.collect.RangeSet;
 import java.util.Base64;
-import java.util.Optional;
-import javax.xml.bind.DatatypeConverter;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
 import org.opendaylight.yangtools.yang.data.api.codec.BinaryCodec;
+import org.opendaylight.yangtools.yang.data.api.codec.YangInvalidValueException;
 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
 
@@ -34,9 +34,11 @@ public abstract class BinaryStringCodec extends TypeDefinitionAwareCodec<byte[],
 
         @Override
         void validate(final byte[] value) {
-            // FIXME: throw an exception capturing the constraint violation
-            checkArgument(lengthConstraint.getAllowedRanges().contains(value.length),
-                "Value length %s does not match constraint %s", value.length, lengthConstraint);
+            final RangeSet<Integer> ranges = lengthConstraint.getAllowedRanges();
+            if (!ranges.contains(value.length)) {
+                throw new YangInvalidValueException(ErrorType.APPLICATION, lengthConstraint,
+                        "Value length " + value.length + " is not in required ranges " + ranges);
+            }
         }
     }
 
@@ -52,7 +54,7 @@ public abstract class BinaryStringCodec extends TypeDefinitionAwareCodec<byte[],
     }
 
     BinaryStringCodec(final BinaryTypeDefinition typeDef) {
-        super(Optional.of(typeDef), byte[].class);
+        super(requireNonNull(typeDef), byte[].class);
     }
 
     public static BinaryStringCodec from(final BinaryTypeDefinition type) {
@@ -61,19 +63,17 @@ public abstract class BinaryStringCodec extends TypeDefinitionAwareCodec<byte[],
     }
 
     @Override
-    public String serialize(final byte[] data) {
-        return data == null ? "" : Base64.getEncoder().encodeToString(data);
+    public final byte[] deserializeImpl(final String product) {
+        // https://tools.ietf.org/html/rfc4648#section-4 plus lenient to allow for MIME blocks
+        final byte[] ret = Base64.getMimeDecoder().decode(product);
+        validate(ret);
+        return ret;
     }
 
     @Override
-    public byte[] deserialize(final String stringRepresentation) {
-        if (stringRepresentation == null) {
-            return null;
-        }
-
-        final byte[] ret = DatatypeConverter.parseBase64Binary(stringRepresentation);
-        validate(ret);
-        return ret;
+    protected final String serializeImpl(final byte[] data) {
+        // We do not split data on 76 characters on output
+        return Base64.getEncoder().encodeToString(data);
     }
 
     abstract void validate(byte[] value);