import java.io.Closeable;
import java.io.Flushable;
import java.io.IOException;
-import java.net.URISyntaxException;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.Deque;
import java.util.HashMap;
import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
import org.opendaylight.yangtools.yang.model.api.OperationDefinition;
import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
/**
* This class provides functionality for parsing an XML source containing YANG-modeled data. It disallows multiple
* annotations.
*/
@Deprecated
- public static final QNameModule LEGACY_ATTRIBUTE_NAMESPACE = QNameModule.create(XMLNamespace.of("")).intern();
+ public static final QNameModule LEGACY_ATTRIBUTE_NAMESPACE = QNameModule.of("").intern();
private static final Logger LOG = LoggerFactory.getLogger(XmlParserStream.class);
private static final String XML_STANDARD_VERSION = "1.0";
this.codecs = requireNonNull(codecs);
this.stack = requireNonNull(stack);
this.strictParsing = strictParsing;
+ parentNode = stack.isEmpty() ? stack.modelContext() : coerceAsParent(stack.currentStatement());
+ }
- if (!stack.isEmpty()) {
- final var stmt = stack.currentStatement();
- if (stmt instanceof DataSchemaNode data) {
- parentNode = data;
- } else if (stmt instanceof OperationDefinition oper) {
- parentNode = oper.toContainerLike();
- } else if (stmt instanceof NotificationDefinition notif) {
- parentNode = notif.toContainerLike();
- } else if (stmt instanceof YangDataSchemaNode yangData) {
- parentNode = yangData.toContainerLike();
- } else {
- throw new IllegalArgumentException("Illegal parent node " + stmt);
- }
- } else {
- parentNode = stack.getEffectiveModelContext();
- }
+ private static DataSchemaNode coerceAsParent(final EffectiveStatement<?, ?> stmt) {
+ return switch (stmt) {
+ case DataSchemaNode data -> data;
+ case OperationDefinition oper -> oper.toContainerLike();
+ case NotificationDefinition notif -> notif.toContainerLike();
+ case YangDataSchemaNode yangData -> yangData.toContainerLike();
+ default -> throw new IllegalArgumentException("Illegal parent node " + stmt);
+ };
}
/**
*/
public static XmlParserStream create(final NormalizedNodeStreamWriter writer,
final EffectiveStatementInference parentNode, final boolean strictParsing) {
- return create(writer, XmlCodecFactory.create(parentNode.getEffectiveModelContext()), parentNode, strictParsing);
+ return create(writer, XmlCodecFactory.create(parentNode.modelContext()), parentNode, strictParsing);
}
/**
* instead and maintain a {@link XmlCodecFactory} to match the current {@link MountPointContext}.
*/
public static XmlParserStream create(final NormalizedNodeStreamWriter writer, final MountPointContext mountCtx) {
- return create(writer, mountCtx, SchemaInferenceStack.of(mountCtx.getEffectiveModelContext()).toInference(),
- true);
+ return create(writer, mountCtx, SchemaInferenceStack.of(mountCtx.modelContext()).toInference(), true);
}
/**
public static XmlParserStream create(final NormalizedNodeStreamWriter writer, final XmlCodecFactory codecs,
final Absolute parentNode, final boolean strictParsing) {
return new XmlParserStream(writer, codecs,
- SchemaInferenceStack.of(codecs.getEffectiveModelContext(), parentNode), strictParsing);
+ SchemaInferenceStack.of(codecs.modelContext(), parentNode), strictParsing);
}
@Beta
@Beta
public static XmlParserStream create(final NormalizedNodeStreamWriter writer, final MountPointContext mountCtx,
final YangInstanceIdentifier parentNode, final boolean strictParsing) {
- final var init = DataSchemaContextTree.from(mountCtx.getEffectiveModelContext())
+ final var init = DataSchemaContextTree.from(mountCtx.modelContext())
.enterPath(parentNode)
.orElseThrow();
return new XmlParserStream(writer, XmlCodecFactory.create(mountCtx), init.stack(), strictParsing);
* instance of XmlParserStream
* @throws XMLStreamException
* if a well-formedness error or an unexpected processing condition occurs while parsing the XML
- * @throws URISyntaxException
- * if the namespace URI of an XML element contains a syntax error
* @throws IOException
* if an error occurs while parsing the value of an anyxml node
- * @throws SAXException
- * if an error occurs while parsing the value of an anyxml node
*/
@Beta
- public XmlParserStream traverse(final DOMSource src) throws XMLStreamException, URISyntaxException, IOException,
- SAXException {
+ public XmlParserStream traverse(final DOMSource src) throws XMLStreamException, IOException {
return parse(new DOMSourceXMLStreamReader(src));
}
final Optional<QNameModule> optModule = resolveXmlNamespace(attributeNS);
if (optModule.isPresent()) {
final QName qname = QName.create(optModule.orElseThrow(), localName);
- final var optAnnotation = AnnotationSchemaNode.find(codecs.getEffectiveModelContext(),
+ final var optAnnotation = AnnotationSchemaNode.find(codecs.modelContext(),
new AnnotationName(qname));
if (optAnnotation.isPresent()) {
final AnnotationSchemaNode schema = optAnnotation.orElseThrow();
final XMLNamespace nsUri;
try {
- nsUri = rawXmlNamespace(elementNS).getNamespace();
+ nsUri = rawXmlNamespace(elementNS).namespace();
} catch (IllegalArgumentException e) {
throw new XMLStreamException("Failed to convert namespace " + xmlElementName, in.getLocation(),
e);
}
- final Deque<DataSchemaNode> childDataSchemaNodes =
- ParserStreamUtils.findSchemaNodeByNameAndNamespace(parentSchema, xmlElementName, nsUri);
+ final var childDataSchemaNodes = ParserStreamUtils.findSchemaNodeByNameAndNamespace(parentSchema,
+ xmlElementName, nsUri);
if (!childDataSchemaNodes.isEmpty()) {
final boolean elementList = isElementList(childDataSchemaNodes);
if (!added && !elementList) {
}
// We have a match, proceed with it
- final QName qname = childDataSchemaNodes.peekLast().getQName();
- final AbstractNodeDataWithSchema<?> child = ((CompositeNodeDataWithSchema<?>) parent).addChild(
- childDataSchemaNodes, elementList ? ChildReusePolicy.REUSE : ChildReusePolicy.NOOP);
+ final var qname = childDataSchemaNodes.peekLast().getQName();
+ final var child = ((CompositeNodeDataWithSchema<?>) parent).addChild(childDataSchemaNodes,
+ elementList ? ChildReusePolicy.REUSE : ChildReusePolicy.NOOP);
stack.enterDataTree(qname);
read(in, child, rootElement);
stack.exit();
// Parent can potentially hold a mount point, let's see if there is a label present. We
// explicitly unmask Optional to null so as to not to lead us on to functional programming,
// because ...
- final MountPointSchemaNode mount;
- if (parentSchema instanceof ContainerSchemaNode container) {
- mount = MountPointSchemaNode.streamAll(container).findFirst().orElse(null);
- } else if (parentSchema instanceof ListSchemaNode list) {
- mount = MountPointSchemaNode.streamAll(list).findFirst().orElse(null);
- } else if (parentSchema instanceof ContainerLike) {
- mount = null;
- } else {
- throw new XMLStreamException("Unhandled mount-aware schema " + parentSchema,
+ final var mount = switch (parentSchema) {
+ case ContainerSchemaNode container ->
+ MountPointSchemaNode.streamAll(container).findFirst().orElse(null);
+ case ListSchemaNode list -> MountPointSchemaNode.streamAll(list).findFirst().orElse(null);
+ case ContainerLike containerLike -> null;
+ default -> throw new XMLStreamException("Unhandled mount-aware schema " + parentSchema,
in.getLocation());
- }
+ };
if (mount != null) {
final var label = mount.asEffectiveStatement().argument();
}
LOG.warn("Encountered unknown element {} from YANG Library namespace", localName);
- } else if (SchemaMountConstants.RFC8528_MODULE.getNamespace().equals(namespace)) {
+ } else if (SchemaMountConstants.MODULE_NAMESPACE.equals(namespace)) {
mount.setSchemaMounts(child);
return;
}
private Object translateValueByType(final Object value, final DataSchemaNode node,
final NamespaceContext namespaceCtx) {
- if (node instanceof AnyxmlSchemaNode) {
- checkArgument(value instanceof Document);
- /*
- * FIXME: Figure out some YANG extension dispatch, which will reuse JSON parsing or XML parsing -
- * anyxml is not well-defined in JSON.
- */
- return new DOMSource(((Document) value).getDocumentElement());
- } else if (node instanceof AnydataSchemaNode) {
- checkArgument(value instanceof Document);
- return new DOMSourceAnydata(new DOMSource(((Document) value).getDocumentElement()));
- } else if (node instanceof TypedDataSchemaNode typedNode) {
- checkArgument(value instanceof String);
- return codecs.codecFor(typedNode, stack).parseValue(namespaceCtx, (String) value);
- } else {
- throw new IllegalStateException("Unhandled schema " + node);
+ return switch (node) {
+ // FIXME: Figure out some YANG extension dispatch, which will reuse JSON parsing or XML parsing -
+ // anyxml is not well-defined in JSON.
+ case AnydataSchemaNode anydata ->
+ new DOMSourceAnydata(new DOMSource(checkDocument(value).getDocumentElement()));
+ case AnyxmlSchemaNode anyxml -> new DOMSource(checkDocument(value).getDocumentElement());
+ case TypedDataSchemaNode typedNode ->
+ codecs.codecFor(typedNode, stack).parseValue(namespaceCtx, checkValue(String.class, value));
+ default -> throw new IllegalStateException("Unhandled schema " + node);
+ };
+ }
+
+ private static Document checkDocument(final Object value) {
+ return checkValue(Document.class, value);
+ }
+
+ private static <T> T checkValue(final Class<T> type, final Object value) {
+ try {
+ return type.cast(requireNonNull(value));
+ } catch (ClassCastException e) {
+ throw new IllegalArgumentException("Unexpected value while expecting a " + type.getName(), e);
}
}
private Optional<QNameModule> resolveXmlNamespace(final String xmlNamespace) {
return resolvedNamespaces.computeIfAbsent(xmlNamespace, nsUri -> {
- final var it = codecs.getEffectiveModelContext().findModuleStatements(XMLNamespace.of(nsUri)).iterator();
+ final var it = codecs.modelContext().findModuleStatements(XMLNamespace.of(nsUri)).iterator();
return it.hasNext() ? Optional.of(it.next().localQNameModule()) : Optional.empty();
});
}
private QNameModule rawXmlNamespace(final String xmlNamespace) {
- return rawNamespaces.computeIfAbsent(xmlNamespace, nsUri -> QNameModule.create(XMLNamespace.of(nsUri)));
+ return rawNamespaces.computeIfAbsent(xmlNamespace, QNameModule::of);
}
}