* 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.codec.xml;
import static java.util.Objects.requireNonNull;
import javax.xml.namespace.NamespaceContext;
+import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.data.impl.codec.DataStringCodec;
import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
* @param <T> Deserialized object type
*/
abstract class AbstractXmlCodec<T> implements XmlCodec<T> {
-
private final DataStringCodec<T> codec;
- protected AbstractXmlCodec(final DataStringCodec<T> codec) {
+ AbstractXmlCodec(final DataStringCodec<T> codec) {
this.codec = requireNonNull(codec);
}
@Override
public final T parseValue(final NamespaceContext namespaceContext, final String str) {
- return codec.deserialize(str);
+ return codec.deserialize(trimValue(str));
+ }
+
+ // FIXME: YANGTOOLS-1523: remove this method
+ @Deprecated
+ @NonNull String trimValue(final @NonNull String str) {
+ return str.trim();
}
final String serialize(final T input) {
import static java.util.Objects.requireNonNull;
import com.google.common.base.MoreObjects;
-import java.util.Iterator;
-import java.util.Map.Entry;
import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
+import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.QNameModule;
import org.opendaylight.yangtools.yang.common.XMLNamespace;
import org.opendaylight.yangtools.yang.data.util.codec.IdentityCodecUtil;
import org.opendaylight.yangtools.yang.data.util.codec.QNameCodecUtil;
import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
-import org.opendaylight.yangtools.yang.model.api.Module;
final class IdentityrefXmlCodec implements XmlCodec<QName> {
- private final EffectiveModelContext schemaContext;
- private final QNameModule parentModule;
+ private final @NonNull EffectiveModelContext context;
+ private final @NonNull QNameModule parentModule;
IdentityrefXmlCodec(final EffectiveModelContext context, final QNameModule parentModule) {
- schemaContext = requireNonNull(context);
+ this.context = requireNonNull(context);
this.parentModule = requireNonNull(parentModule);
}
@Override
public QName parseValue(final NamespaceContext ctx, final String str) {
- return IdentityCodecUtil.parseIdentity(str, schemaContext, prefix -> {
+ // FIXME: YANGTOOLS-1523: do not trim()
+ return IdentityCodecUtil.parseIdentity(str.trim(), context, prefix -> {
if (prefix.isEmpty()) {
return parentModule;
}
- final String prefixedNS = ctx.getNamespaceURI(prefix);
+ final var prefixedNS = ctx.getNamespaceURI(prefix);
checkArgument(prefixedNS != null, "Failed to resolve prefix %s", prefix);
- final Iterator<? extends Module> modules =
- schemaContext.findModules(XMLNamespace.of(prefixedNS)).iterator();
+ final var modules = context.findModules(XMLNamespace.of(prefixedNS)).iterator();
checkArgument(modules.hasNext(), "Could not find module for namespace %s", prefixedNS);
return modules.next().getQNameModule();
}).getQName();
@Override
public void writeValue(final XMLStreamWriter ctx, final QName value) throws XMLStreamException {
- final RandomPrefix prefixes = new RandomPrefix(ctx.getNamespaceContext());
- final String str = QNameCodecUtil.encodeQName(value, uri -> prefixes.encodePrefix(uri.getNamespace()));
+ final var prefixes = new RandomPrefix(ctx.getNamespaceContext());
+ final var str = QNameCodecUtil.encodeQName(value, uri -> prefixes.encodePrefix(uri.getNamespace()));
- for (Entry<XMLNamespace, String> e : prefixes.getPrefixes()) {
+ for (var e : prefixes.getPrefixes()) {
ctx.writeNamespace(e.getValue(), e.getKey().toString());
}
ctx.writeCharacters(str);
* 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.codec.xml;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.opendaylight.yangtools.yang.data.impl.codec.DataStringCodec;
-final class QuotedXmlCodec<T> extends AbstractXmlCodec<T> {
+// FIXME: YANGTOOLS-1523: make this class final
+class QuotedXmlCodec<T> extends AbstractXmlCodec<T> {
QuotedXmlCodec(final DataStringCodec<T> codec) {
super(codec);
}
@Override
- public void writeValue(final XMLStreamWriter ctx, final T value) throws XMLStreamException {
+ public final void writeValue(final XMLStreamWriter ctx, final T value) throws XMLStreamException {
ctx.writeCharacters(serialize(value));
}
}
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. 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.codec.xml;
+
+import org.opendaylight.yangtools.yang.data.impl.codec.StringStringCodec;
+
+// FIXME: YANGTOOLS-1523: remove this class
+@Deprecated
+final class StringXmlCodec extends QuotedXmlCodec<String> {
+ StringXmlCodec(final StringStringCodec codec) {
+ super(codec);
+ }
+
+ @Override
+ @Deprecated
+ String trimValue(final String str) {
+ return str;
+ }
+}
@Override
protected XmlCodec<?> stringCodec(final StringTypeDefinition type) {
- return new QuotedXmlCodec<>(StringStringCodec.from(type));
+ // FIXME: YANGTOOLS-1523: use QuotedXmlCodec
+ return new StringXmlCodec(StringStringCodec.from(type));
}
@Override
if (parent instanceof LeafNodeDataWithSchema || parent instanceof LeafListEntryNodeDataWithSchema) {
parent.setAttributes(getElementAttributes(in));
- setValue((SimpleNodeDataWithSchema<?>) parent, in.getElementText().trim(), in.getNamespaceContext());
+ setValue((SimpleNodeDataWithSchema<?>) parent, in.getElementText(), in.getNamespaceContext());
if (isNextEndDocument(in)) {
return;
}
import java.util.ArrayDeque;
import java.util.Deque;
-import java.util.Iterator;
import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
private final @NonNull XmlCodecFactory codecFactory;
private final @NonNull EffectiveModelContext context;
- XmlStringInstanceIdentifierCodec(final EffectiveModelContext context, final XmlCodecFactory xmlCodecFactory) {
+ XmlStringInstanceIdentifierCodec(final EffectiveModelContext context, final XmlCodecFactory codecFactory) {
this.context = requireNonNull(context);
- this.dataContextTree = DataSchemaContextTree.from(context);
- this.codecFactory = requireNonNull(xmlCodecFactory);
+ this.codecFactory = requireNonNull(codecFactory);
+ dataContextTree = DataSchemaContextTree.from(context);
}
@Override
protected Module moduleForPrefix(final String prefix) {
- final String prefixedNS = getNamespaceContext().getNamespaceURI(prefix);
- final Iterator<? extends Module> modules = context.findModules(XMLNamespace.of(prefixedNS)).iterator();
+ final var prefixedNS = getNamespaceContext().getNamespaceURI(prefix);
+ final var modules = context.findModules(XMLNamespace.of(prefixedNS)).iterator();
return modules.hasNext() ? modules.next() : null;
}
@Override
protected String prefixForNamespace(final XMLNamespace namespace) {
- final Iterator<? extends Module> modules = context.findModules(namespace).iterator();
+ final var modules = context.findModules(namespace).iterator();
return modules.hasNext() ? modules.next().getName() : null;
}
public YangInstanceIdentifier parseValue(final NamespaceContext ctx, final String str) {
pushNamespaceContext(ctx);
try {
- return deserialize(str);
+ // FIXME: YANGTOOLS-1523: do not trim()
+ return deserialize(str.trim());
} finally {
popNamespaceContext();
}
}
@Override
- public void writeValue(final XMLStreamWriter ctx, final YangInstanceIdentifier value)
- throws XMLStreamException {
+ public void writeValue(final XMLStreamWriter ctx, final YangInstanceIdentifier value) throws XMLStreamException {
ctx.writeCharacters(serialize(value));
}
}
private static void popNamespaceContext() {
- final Deque<NamespaceContext> stack = TL_CONTEXT.get();
+ final var stack = TL_CONTEXT.get();
stack.pop();
if (stack.isEmpty()) {
TL_CONTEXT.set(null);
}
private static void pushNamespaceContext(final NamespaceContext context) {
- Deque<NamespaceContext> stack = TL_CONTEXT.get();
+ var stack = TL_CONTEXT.get();
if (stack == null) {
stack = new ArrayDeque<>(1);
TL_CONTEXT.set(stack);
--- /dev/null
+/*
+ * Copyright (c) 2023 PANTHEON.tech, s.r.o. 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.codec.xml;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.StringReader;
+import org.junit.jupiter.api.Test;
+import org.opendaylight.yangtools.util.xml.UntrustedXML;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.NormalizationResultHolder;
+import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
+import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
+
+class YT1522Test {
+ @Test
+ void testWhitespaceLeaf() throws Exception {
+ final var context = YangParserTestUtils.parseYang("""
+ module foo {
+ namespace foo;
+ prefix foo;
+
+ leaf foo {
+ type string {
+ length 1..4;
+ }
+ }
+ }""");
+ final var result = new NormalizationResultHolder();
+ final var streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
+ final var xmlParser = XmlParserStream.create(streamWriter,
+ Inference.ofDataTreePath(context, QName.create("foo", "foo")));
+ xmlParser.parse(UntrustedXML.createXMLStreamReader(new StringReader("""
+ <foo xmlns="foo"> </foo>""")));
+ assertEquals(ImmutableNodes.leafNode(QName.create("foo", "foo"), " "), result.getResult().data());
+ }
+}