Bug 2362: Added pattern validation for string types. 99/17899/4
authorTony Tkacik <ttkacik@cisco.com>
Wed, 8 Apr 2015 09:01:31 +0000 (11:01 +0200)
committerTony Tkacik <ttkacik@cisco.com>
Thu, 9 Apr 2015 11:33:55 +0000 (13:33 +0200)
Change-Id: Icea2e7cfa87bd746e6da99e6908ab959d6356fd3
Signed-off-by: Tony Tkacik <ttkacik@cisco.com>
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/CompiledPatternContext.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/StringPatternCheckingCodec.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/StringStringCodec.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/TypeDefinitionAwareCodec.java

diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/CompiledPatternContext.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/CompiledPatternContext.java
new file mode 100644 (file)
index 0000000..6e90122
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.impl.codec;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import java.util.regex.Pattern;
+import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
+
+class CompiledPatternContext {
+
+    private final Pattern pattern;
+    private final String errorMessage;
+
+    CompiledPatternContext(final PatternConstraint yangConstraint) {
+        pattern = Pattern.compile("^" + yangConstraint.getRegularExpression() + "$");
+        final String yangMessage = yangConstraint.getErrorMessage();
+        if (Strings.isNullOrEmpty(yangMessage)) {
+            errorMessage = "Value %s does not match regular expression <" + pattern.pattern() + ">";
+        } else {
+            errorMessage = yangMessage;
+        }
+    }
+
+    public void validate(final String s) {
+        Preconditions.checkArgument(pattern.matcher(s).matches(), errorMessage, s);
+    }
+
+}
\ No newline at end of file
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/StringPatternCheckingCodec.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/StringPatternCheckingCodec.java
new file mode 100644 (file)
index 0000000..6ada9e3
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.impl.codec;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.regex.PatternSyntaxException;
+import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
+import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class StringPatternCheckingCodec extends StringStringCodec {
+
+    private static final Logger LOG = LoggerFactory.getLogger(StringPatternCheckingCodec.class);
+    private final Collection<CompiledPatternContext> patterns;
+
+    protected StringPatternCheckingCodec(final StringTypeDefinition typeDef) {
+        super(typeDef);
+        patterns = new ArrayList<>(typeDef.getPatternConstraints().size());
+        for (final PatternConstraint yangPattern : typeDef.getPatternConstraints()) {
+            try {
+                patterns.add(new CompiledPatternContext(yangPattern));
+            } catch (final PatternSyntaxException e) {
+                LOG.debug("Unable to compile {} pattern, excluding it from validation.", yangPattern, e);
+            }
+        }
+    }
+
+    @Override
+    protected void validate(final String s) {
+        super.validate(s);
+        for (final CompiledPatternContext pattern : patterns) {
+            pattern.validate(s);
+        }
+    }
+
+}
\ No newline at end of file
index d7bbb6971913aac06087cbe87af03fa8ddfb1be6..91cf6761c4f2c0685c00ada09a87c2dd5933aad2 100644 (file)
@@ -14,21 +14,35 @@ import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
 class StringStringCodec extends TypeDefinitionAwareCodec<String, StringTypeDefinition> implements
         StringCodec<String> {
 
-    protected StringStringCodec(final Optional<StringTypeDefinition> typeDef) {
-        super(typeDef, String.class);
+    protected StringStringCodec(final StringTypeDefinition typeDef) {
+        super(Optional.of(typeDef), String.class);
+        typeDef.getLengthConstraints();
     }
 
-    static TypeDefinitionAwareCodec<?,StringTypeDefinition> from(final StringTypeDefinition normalizedType) {
-        return new StringStringCodec(Optional.fromNullable(normalizedType));
+    static TypeDefinitionAwareCodec<?, StringTypeDefinition> from(final StringTypeDefinition normalizedType) {
+        if (normalizedType.getPatternConstraints().isEmpty()) {
+            return new StringStringCodec(normalizedType);
+        }
+
+        return new StringPatternCheckingCodec(normalizedType);
     }
 
     @Override
     public final String deserialize(final String stringRepresentation) {
-        return stringRepresentation == null ? "" : stringRepresentation;
+        if (stringRepresentation == null) {
+            // FIXME: These seems buggy, but someone may be using this behaviour
+            return "";
+        }
+        validate(stringRepresentation);
+        return stringRepresentation;
     }
 
     @Override
     public final String serialize(final String data) {
         return data == null ? "" : data;
     }
+
+    protected void validate(final String s) {
+
+    }
 }
\ No newline at end of file
index 76f64377c37e80a641737d9573fb98c1aa76b2aa..24981326d7ab49c18cf34e1442c03197224b9510 100644 (file)
@@ -119,7 +119,7 @@ public abstract class TypeDefinitionAwareCodec<J, T extends TypeDefinition<T>> i
     @Deprecated
     public static class StringCodecStringImpl extends StringStringCodec {
         protected StringCodecStringImpl(final Optional<StringTypeDefinition> typeDef) {
-            super(typeDef);
+            super(typeDef.get());
         }
     }