--- /dev/null
+/*
+ * Copyright (c) 2019 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.rfc7952.data.api;
+
+import com.google.common.annotations.Beta;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedAnydata;
+
+/**
+ * A piece of {@link NormalizedAnydata} with a corresponding piece of {@link NormalizedMetadata}.
+ */
+@Beta
+@NonNullByDefault
+public interface MetadataNormalizedAnydata extends NormalizedAnydata {
+
+ NormalizedMetadata getMetadata();
+}
import com.google.common.annotations.Beta;
import java.io.IOException;
import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.yangtools.rfc7952.data.api.MetadataNormalizedAnydata;
import org.opendaylight.yangtools.rfc7952.data.api.NormalizedMetadata;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.util.NormalizedAnydata;
+import org.opendaylight.yangtools.yang.data.util.ImmutableNormalizedAnydata;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@Beta
@NonNullByDefault
-public final class MetadataNormalizedAnydata extends NormalizedAnydata {
+public final class ImmutableMetadataNormalizedAnydata extends ImmutableNormalizedAnydata
+ implements MetadataNormalizedAnydata {
private final NormalizedMetadata metadata;
- public MetadataNormalizedAnydata(final SchemaContext schemaContext, final DataSchemaNode contextNode,
+ public ImmutableMetadataNormalizedAnydata(final SchemaContext schemaContext, final DataSchemaNode contextNode,
final NormalizedNode<?, ?> data, final NormalizedMetadata metadata) {
super(schemaContext, contextNode, data);
this.metadata = requireNonNull(metadata);
}
+ @Override
public NormalizedMetadata getMetadata() {
return metadata;
}
@Override
public void writeTo(final NormalizedNodeStreamWriter writer, final boolean orderKeyLeaves) throws IOException {
- NormalizedMetadataWriter.forStreamWriter(writer, orderKeyLeaves).write(getData(), metadata).flush();
+ NormalizedMetadataWriter.forStreamWriter(writer, orderKeyLeaves).write(getData(), getMetadata()).flush();
}
}
* @author Robert Varga
*/
@Beta
+// FIXME: 5.0.0: consider moving this class to api to keep related stuff together
public final class NormalizedMetadataWriter implements Closeable, Flushable {
private final NormalizedNodeStreamWriter writer;
private final boolean orderKeyLeaves;
@Override
public void close() throws IOException {
- writer.flush();
- writer.close();
+ try {
+ writer.flush();
+ } finally {
+ writer.close();
+ }
}
@Override
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
/**
- * A NormalizedNode holding the contents of an {@code anydata} node in some object model.
+ * A NormalizedNode holding the contents of an {@code anydata} node in some object model. While no guarantees are placed
+ * on object models, there are related interfaces available for data interchange:
+ *
+ * <ul>
+ * <li>{@link NormalizedAnydata}, which exposes the contents as a {@link NormalizedNode} with attached schema
+ * information</li>
+ * <li>{@link NormalizableAnydata}, which is trait optionally implemented by object models and allows the opaque,
+ * implementation-specific representation to be interpreted in a the context of provided schema information,
+ * potentially forming a NormalizedAnydata node.
+ * </ul>
*
* @param <V> Value type, uniquely identifying the object model used for values
*/
* 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.util;
+package org.opendaylight.yangtools.yang.data.api.schema;
import static java.util.Objects.requireNonNull;
* 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.util;
+package org.opendaylight.yangtools.yang.data.api.schema;
import com.google.common.annotations.Beta;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+/**
+ * An {@link AnydataNode#getValueObjectModel() anydata value object model} which can be normalized to
+ * {@link NormalizedAnydata} when provided with proper context.
+ */
@Beta
@NonNullByDefault
public interface NormalizableAnydata {
--- /dev/null
+/*
+ * Copyright (c) 2019 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.api.schema;
+
+import com.google.common.annotations.Beta;
+import java.io.IOException;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
+
+/**
+ * The contents of an {@code anydata} node in a normalized format. This representation acts as a schema-bound bridge
+ * between the various (mostly parser-based) representations. Implementations of this interface are usually created
+ * from an instance of {@link NormalizableAnydata}.
+ *
+ * <p>
+ * Note this interface does not have an equality contract and implementations are expected to default to identity
+ * equality (or in Valhalla-speak: be plain data).
+ */
+@Beta
+@NonNullByDefault
+public interface NormalizedAnydata extends Immutable, SchemaContextProvider {
+
+ @Override
+ // FIXME: remove this override when SchemaContextProvider's method has sane semantics.
+ @NonNull SchemaContext getSchemaContext();
+
+ DataSchemaNode getContextNode();
+
+ NormalizedNode<?, ?> getData();
+
+ default void writeTo(final NormalizedNodeStreamWriter writer) throws IOException {
+ writeTo(writer, true);
+ }
+
+ default void writeTo(final NormalizedNodeStreamWriter writer, final boolean orderKeyLeaves) throws IOException {
+ NormalizedNodeWriter.forStreamWriter(writer, orderKeyLeaves).write(getData()).flush();
+ }
+}
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedAnydata;
import org.opendaylight.yangtools.yang.data.api.schema.stream.AnydataExtension;
import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriterExtension;
import org.opendaylight.yangtools.yang.data.impl.codec.SchemaTracker;
-import org.opendaylight.yangtools.yang.data.util.NormalizedAnydata;
import org.opendaylight.yangtools.yang.data.util.SingleChildDataNodeContainer;
import org.opendaylight.yangtools.yang.model.api.AnyDataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
import java.io.IOException;
import java.net.URISyntaxException;
import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.dom.DOMSource;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.xml.sax.SAXException;
+/**
+ * Internal parser representation of a parsed-out chunk of XML. This format is completely internal to the parser
+ * and can be changed at any time. Current implementation uses W3C DOM tree as the backing implementations, but others
+ * are possible as well.
+ *
+ * @author Robert Varga
+ */
@NonNullByDefault
final class DOMSourceAnydata extends AbstractNormalizableAnydata {
private final DOMSource source;
this.source = requireNonNull(source);
}
- DOMSource getSource() {
- return source;
+ XMLStreamReader toStreamReader() throws XMLStreamException {
+ return new DOMSourceXMLStreamReader(source);
}
@Override
}
try {
- xmlParser.traverse(source).close();
+ xmlParser.parse(toStreamReader()).close();
} catch (XMLStreamException | URISyntaxException | SAXException e) {
throw new IOException("Failed to parse payload", e);
}
import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.util.NormalizedAnydata;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedAnydata;
import org.opendaylight.yangtools.yang.data.util.SingleChildDataNodeContainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
writer.flush();
}
- void anydataWriteStreamReader(final DOMSourceXMLStreamReader reader) throws XMLStreamException {
+ void anydataWriteStreamReader(final XMLStreamReader reader) throws XMLStreamException {
flushElement();
while (reader.hasNext()) {
}
}
- private void forwardAttributes(final DOMSourceXMLStreamReader reader) throws XMLStreamException {
+ private void forwardAttributes(final XMLStreamReader reader) throws XMLStreamException {
for (int i = 0, count = reader.getAttributeCount(); i < count; ++i) {
final String localName = reader.getAttributeLocalName(i);
final String value = reader.getAttributeValue(i);
}
}
- private void forwardNamespaces(final DOMSourceXMLStreamReader reader) throws XMLStreamException {
+ private void forwardNamespaces(final XMLStreamReader reader) throws XMLStreamException {
for (int i = 0; i < reader.getNamespaceCount(); ++i) {
writer.writeNamespace(reader.getNamespacePrefix(i), reader.getNamespaceURI(i));
}
}
- private void forwardProcessingInstruction(final DOMSourceXMLStreamReader reader) throws XMLStreamException {
+ private void forwardProcessingInstruction(final XMLStreamReader reader) throws XMLStreamException {
final String target = reader.getPITarget();
final String data = reader.getPIData();
if (data != null) {
}
}
- private void forwardStartElement(final DOMSourceXMLStreamReader reader) throws XMLStreamException {
+ private void forwardStartElement(final XMLStreamReader reader) throws XMLStreamException {
final String localName = reader.getLocalName();
final String prefix = reader.getPrefix();
if (prefix != null) {
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedAnydata;
import org.opendaylight.yangtools.yang.data.api.schema.stream.AnydataExtension;
import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriterExtension;
import org.opendaylight.yangtools.yang.data.impl.codec.SchemaTracker;
-import org.opendaylight.yangtools.yang.data.util.NormalizedAnydata;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
final void anydataValue(final Object value) throws IOException {
if (value instanceof DOMSourceAnydata) {
- anydataValue(((DOMSourceAnydata) value).getSource());
+ try {
+ facade.anydataWriteStreamReader(((DOMSourceAnydata) value).toStreamReader());
+ } catch (XMLStreamException e) {
+ throw new IOException("Unable to transform anydata value: " + value, e);
+ }
} else if (value instanceof NormalizedAnydata) {
- anydataValue((NormalizedAnydata) value);
+ try {
+ facade.emitNormalizedAnydata((NormalizedAnydata) value);
+ } catch (XMLStreamException e) {
+ throw new IOException("Unable to emit anydata value: " + value, e);
+ }
} else {
throw new IllegalStateException("Unexpected anydata value " + value);
}
}
- private void anydataValue(final DOMSource domSource) throws IOException {
- final Node domNode = requireNonNull(domSource.getNode());
- try {
- facade.anydataWriteStreamReader(new DOMSourceXMLStreamReader(domSource));
- } catch (XMLStreamException e) {
- throw new IOException("Unable to transform anyXml value: " + domNode, e);
- }
- }
-
- private void anydataValue(final NormalizedAnydata anydata) throws IOException {
- try {
- facade.emitNormalizedAnydata(anydata);
- } catch (XMLStreamException e) {
- throw new IOException("Unable to emit anydata value: " + anydata, e);
- }
- }
-
final void anyxmlValue(final DOMSource domSource) throws IOException {
if (domSource != null) {
final Node domNode = requireNonNull(domSource.getNode());
import java.util.Optional;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.opendaylight.yangtools.rfc7952.data.api.NormalizedMetadata;
-import org.opendaylight.yangtools.rfc7952.data.util.MetadataNormalizedAnydata;
+import org.opendaylight.yangtools.rfc7952.data.util.ImmutableMetadataNormalizedAnydata;
+import org.opendaylight.yangtools.yang.data.api.schema.AnydataNormalizationException;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizableAnydata;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedAnydata;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.util.AnydataNormalizationException;
-import org.opendaylight.yangtools.yang.data.util.NormalizableAnydata;
-import org.opendaylight.yangtools.yang.data.util.NormalizedAnydata;
+import org.opendaylight.yangtools.yang.data.util.ImmutableNormalizedAnydata;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
final NormalizedNode<?, ?> data = result.getResult();
final Optional<NormalizedMetadata> optMeta = result.getMetadata();
- return optMeta.isPresent() ? new MetadataNormalizedAnydata(schemaContext, contextNode, data, optMeta.get())
- : new NormalizedAnydata(schemaContext, contextNode, result.getResult());
+ return optMeta.isPresent()
+ ? new ImmutableMetadataNormalizedAnydata(schemaContext, contextNode, data, optMeta.get())
+ : new ImmutableNormalizedAnydata(schemaContext, contextNode, result.getResult());
}
@Override
import com.google.common.annotations.Beta;
import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
-import java.io.IOException;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedAnydata;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
-/**
- * The contents of an {@code anydata} node in a normalized format. This representation acts as a schema-bound bridge
- * between the various (mostly parser-based) representations.
- *
- * <p>
- * Note this class (and all of its subclasses) rely on identity for their equality contract.
- */
@Beta
@NonNullByDefault
-public class NormalizedAnydata implements Immutable, SchemaContextProvider {
+public class ImmutableNormalizedAnydata implements NormalizedAnydata {
private final SchemaContext schemaContext;
private final DataSchemaNode contextNode;
private final NormalizedNode<?, ?> data;
- public NormalizedAnydata(final SchemaContext schemaContext, final DataSchemaNode contextNode,
+ public ImmutableNormalizedAnydata(final SchemaContext schemaContext, final DataSchemaNode contextNode,
final NormalizedNode<?, ?> data) {
this.schemaContext = requireNonNull(schemaContext);
this.contextNode = requireNonNull(contextNode);
return schemaContext;
}
+ @Override
public final DataSchemaNode getContextNode() {
return contextNode;
}
+ @Override
public final NormalizedNode<?, ?> getData() {
return data;
}
- public final void writeTo(final NormalizedNodeStreamWriter writer) throws IOException {
- writeTo(writer, true);
- }
-
- public void writeTo(final NormalizedNodeStreamWriter writer, final boolean orderKeyLeaves) throws IOException {
- NormalizedNodeWriter.forStreamWriter(writer, orderKeyLeaves).write(data).flush();
- }
-
@Override
public final int hashCode() {
return super.hashCode();