Add the ability to use schema-aware coding
[netconf.git] / netconf / netconf-netty-util / src / main / java / org / opendaylight / netconf / nettyutil / handler / exi / EXIParameters.java
index 5340baa6e44b77299f660ed04a54f5a8dd74ce97..adf665c3cc145c093638858977fcb7e2d456dd71 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.netconf.nettyutil.handler.exi;
 
+import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.annotations.VisibleForTesting;
@@ -14,7 +15,10 @@ import com.siemens.ct.exi.core.CodingMode;
 import com.siemens.ct.exi.core.EXIFactory;
 import com.siemens.ct.exi.core.EncodingOptions;
 import com.siemens.ct.exi.core.FidelityOptions;
+import com.siemens.ct.exi.core.SchemaIdResolver;
+import com.siemens.ct.exi.core.exceptions.EXIException;
 import com.siemens.ct.exi.core.exceptions.UnsupportedOption;
+import com.siemens.ct.exi.core.grammars.Grammars;
 import com.siemens.ct.exi.core.helpers.DefaultEXIFactory;
 import java.util.Objects;
 import org.opendaylight.netconf.api.xml.XmlElement;
@@ -39,6 +43,24 @@ public final class EXIParameters {
     private static final String EXI_FIDELITY_PIS = "pis";
     private static final String EXI_FIDELITY_PREFIXES = "prefixes";
 
+    static final String EXI_PARAMETER_SCHEMAS = "schemas";
+
+    private static final SchemaIdResolver SCHEMA_RESOLVER = schemaId -> {
+        if (schemaId == null) {
+            return null;
+        }
+        if (schemaId.isEmpty()) {
+            return EXISchema.BUILTIN.getGrammar();
+        }
+
+        final Grammars g = EXISchema.BASE_1_1.getGrammar();
+        if (g.getSchemaId().equals(schemaId)) {
+            return g;
+        }
+
+        throw new EXIException("Cannot resolve schema " + schemaId);
+    };
+
     private static final EncodingOptions ENCODING_OPTIONS;
 
     static {
@@ -62,10 +84,16 @@ public final class EXIParameters {
 
     private final FidelityOptions fidelityOptions;
     private final CodingMode codingMode;
+    private final EXISchema schema;
 
     public EXIParameters(final CodingMode codingMode, final FidelityOptions fidelityOptions) {
+        this(codingMode, fidelityOptions, EXISchema.NONE);
+    }
+
+    public EXIParameters(final CodingMode codingMode, final FidelityOptions fidelityOptions, final EXISchema schema) {
         this.fidelityOptions = requireNonNull(fidelityOptions);
         this.codingMode = requireNonNull(codingMode);
+        this.schema = requireNonNull(schema);
     }
 
     @VisibleForTesting
@@ -120,7 +148,18 @@ public final class EXIParameters {
                 fidelityElement.getElementsByTagName(EXI_FIDELITY_PREFIXES).getLength() > 0);
         }
 
-        return new EXIParameters(coding, fidelity);
+        final EXISchema schema;
+        final NodeList schemaElements = root.getElementsByTagName(EXI_PARAMETER_SCHEMAS);
+        if (schemaElements.getLength() > 0) {
+            final Element schemaElement = (Element) schemaElements.item(0);
+            final String schemaName = schemaElement.getTextContent().trim();
+            schema = EXISchema.forOption(schemaName);
+            checkArgument(schema != null, "Unsupported schema name %s", schemaName);
+        } else {
+            schema = EXISchema.NONE;
+        }
+
+        return new EXIParameters(coding, fidelity, schema);
     }
 
     public EXIFactory getFactory() {
@@ -128,12 +167,14 @@ public final class EXIParameters {
         factory.setCodingMode(codingMode);
         factory.setEncodingOptions(ENCODING_OPTIONS);
         factory.setFidelityOptions(fidelityOptions);
+        factory.setGrammars(schema.getGrammar());
+        factory.setSchemaIdResolver(SCHEMA_RESOLVER);
         return factory;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(fidelityOptions, codingMode);
+        return Objects.hash(fidelityOptions, codingMode, schema);
     }
 
     @Override
@@ -145,7 +186,8 @@ public final class EXIParameters {
             return false;
         }
         final EXIParameters other = (EXIParameters) obj;
-        return codingMode == other.codingMode && fidelityOptions.equals(other.fidelityOptions);
+        return codingMode == other.codingMode && schema == other.schema
+                && fidelityOptions.equals(other.fidelityOptions);
     }
 
     String getAlignment() {
@@ -186,4 +228,8 @@ public final class EXIParameters {
     String getPreservePrefixes() {
         return fidelityString(FidelityOptions.FEATURE_PREFIX, EXI_FIDELITY_PREFIXES);
     }
+
+    String getSchema() {
+        return schema == EXISchema.NONE ? null : schema.name();
+    }
 }