2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.netconf.nettyutil.handler.exi;
10 import static java.util.Objects.requireNonNull;
12 import com.google.common.annotations.VisibleForTesting;
13 import com.siemens.ct.exi.core.CodingMode;
14 import com.siemens.ct.exi.core.EXIFactory;
15 import com.siemens.ct.exi.core.EncodingOptions;
16 import com.siemens.ct.exi.core.FidelityOptions;
17 import com.siemens.ct.exi.core.exceptions.UnsupportedOption;
18 import com.siemens.ct.exi.core.helpers.DefaultEXIFactory;
19 import java.util.Objects;
20 import org.opendaylight.controller.config.util.xml.XmlElement;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23 import org.w3c.dom.Element;
24 import org.w3c.dom.NodeList;
26 public final class EXIParameters {
27 private static final Logger LOG = LoggerFactory.getLogger(EXIParameters.class);
29 static final String EXI_PARAMETER_ALIGNMENT = "alignment";
30 private static final String EXI_PARAMETER_BYTE_ALIGNED = "byte-aligned";
31 private static final String EXI_PARAMETER_BIT_PACKED = "bit-packed";
32 private static final String EXI_PARAMETER_COMPRESSED = "compressed";
33 private static final String EXI_PARAMETER_PRE_COMPRESSION = "pre-compression";
35 static final String EXI_PARAMETER_FIDELITY = "fidelity";
36 private static final String EXI_FIDELITY_DTD = "dtd";
37 private static final String EXI_FIDELITY_LEXICAL_VALUES = "lexical-values";
38 private static final String EXI_FIDELITY_COMMENTS = "comments";
39 private static final String EXI_FIDELITY_PIS = "pis";
40 private static final String EXI_FIDELITY_PREFIXES = "prefixes";
42 private static final EncodingOptions ENCODING_OPTIONS;
45 final EncodingOptions opts = EncodingOptions.createDefault();
47 opts.setOption(EncodingOptions.RETAIN_ENTITY_REFERENCE);
48 opts.setOption(EncodingOptions.INCLUDE_OPTIONS);
51 * NETCONF is XML environment, so the use of EXI cookie is not really needed. Adding it
52 * decreases efficiency of encoding by adding human-readable 4 bytes "EXI$" to the head
53 * of the stream. This is really useful, so let's output it now.
55 opts.setOption(EncodingOptions.INCLUDE_COOKIE);
56 } catch (final UnsupportedOption e) {
57 throw new ExceptionInInitializerError(e);
60 ENCODING_OPTIONS = opts;
63 private final FidelityOptions fidelityOptions;
64 private final CodingMode codingMode;
66 public EXIParameters(final CodingMode codingMode, final FidelityOptions fidelityOptions) {
67 this.fidelityOptions = requireNonNull(fidelityOptions);
68 this.codingMode = requireNonNull(codingMode);
72 public static EXIParameters empty() {
73 return new EXIParameters(CodingMode.BIT_PACKED, FidelityOptions.createDefault());
76 public static EXIParameters fromXmlElement(final XmlElement root) throws UnsupportedOption {
77 final CodingMode coding;
78 final NodeList alignmentElements = root.getElementsByTagName(EXI_PARAMETER_ALIGNMENT);
79 if (alignmentElements.getLength() > 0) {
80 final Element alignmentElement = (Element) alignmentElements.item(0);
81 final String alignmentTextContent = alignmentElement.getTextContent().trim();
83 switch (alignmentTextContent) {
84 case EXI_PARAMETER_BYTE_ALIGNED:
85 coding = CodingMode.BYTE_PACKED;
87 case EXI_PARAMETER_COMPRESSED:
88 coding = CodingMode.COMPRESSION;
90 case EXI_PARAMETER_PRE_COMPRESSION:
91 coding = CodingMode.PRE_COMPRESSION;
93 case EXI_PARAMETER_BIT_PACKED:
94 coding = CodingMode.BIT_PACKED;
97 LOG.warn("Unexpected value in alignmentTextContent: {} , using default value",
98 alignmentTextContent);
99 coding = CodingMode.BIT_PACKED;
103 coding = CodingMode.BIT_PACKED;
106 final FidelityOptions fidelity = FidelityOptions.createDefault();
107 final NodeList fidelityElements = root.getElementsByTagName(EXI_PARAMETER_FIDELITY);
108 if (fidelityElements.getLength() > 0) {
109 final Element fidelityElement = (Element) fidelityElements.item(0);
111 fidelity.setFidelity(FidelityOptions.FEATURE_DTD,
112 fidelityElement.getElementsByTagName(EXI_FIDELITY_DTD).getLength() > 0);
113 fidelity.setFidelity(FidelityOptions.FEATURE_LEXICAL_VALUE,
114 fidelityElement.getElementsByTagName(EXI_FIDELITY_LEXICAL_VALUES).getLength() > 0);
115 fidelity.setFidelity(FidelityOptions.FEATURE_COMMENT,
116 fidelityElement.getElementsByTagName(EXI_FIDELITY_COMMENTS).getLength() > 0);
117 fidelity.setFidelity(FidelityOptions.FEATURE_PI,
118 fidelityElement.getElementsByTagName(EXI_FIDELITY_PIS).getLength() > 0);
119 fidelity.setFidelity(FidelityOptions.FEATURE_PREFIX,
120 fidelityElement.getElementsByTagName(EXI_FIDELITY_PREFIXES).getLength() > 0);
123 return new EXIParameters(coding, fidelity);
126 public EXIFactory getFactory() {
127 final EXIFactory factory = DefaultEXIFactory.newInstance();
128 factory.setCodingMode(codingMode);
129 factory.setEncodingOptions(ENCODING_OPTIONS);
130 factory.setFidelityOptions(fidelityOptions);
135 public int hashCode() {
136 return Objects.hash(fidelityOptions, codingMode);
140 public boolean equals(final Object obj) {
144 if (!(obj instanceof EXIParameters)) {
147 final EXIParameters other = (EXIParameters) obj;
148 return (codingMode == other.codingMode) && fidelityOptions.equals(other.fidelityOptions);
151 String getAlignment() {
152 switch (codingMode) {
154 return EXI_PARAMETER_BIT_PACKED;
156 return EXI_PARAMETER_BYTE_ALIGNED;
158 return EXI_PARAMETER_COMPRESSED;
159 case PRE_COMPRESSION:
160 return EXI_PARAMETER_PRE_COMPRESSION;
162 throw new IllegalStateException("Unhandled coding mode " + codingMode);
166 private String fidelityString(final String feature, final String string) {
167 return fidelityOptions.isFidelityEnabled(feature) ? string : null;
170 String getPreserveComments() {
171 return fidelityString(FidelityOptions.FEATURE_COMMENT, EXI_FIDELITY_COMMENTS);
174 String getPreserveDTD() {
175 return fidelityString(FidelityOptions.FEATURE_DTD, EXI_FIDELITY_DTD);
178 String getPreserveLexicalValues() {
179 return fidelityString(FidelityOptions.FEATURE_LEXICAL_VALUE, EXI_FIDELITY_LEXICAL_VALUES);
182 String getPreservePIs() {
183 return fidelityString(FidelityOptions.FEATURE_PI, EXI_FIDELITY_PIS);
186 String getPreservePrefixes() {
187 return fidelityString(FidelityOptions.FEATURE_PREFIX, EXI_FIDELITY_PREFIXES);