- @Override
- public void streamNormalizedNode(final NormalizedNodeStreamWriter writer) throws IOException {
- streamNormalizedNode(requireNonNull(writer), input.readByte());
- }
-
- private void streamNormalizedNode(final NormalizedNodeStreamWriter writer, final byte nodeType) throws IOException {
- switch (nodeType) {
- case NodeTypes.ANY_XML_NODE:
- streamAnyxml(writer);
- break;
- case NodeTypes.AUGMENTATION_NODE:
- streamAugmentation(writer);
- break;
- case NodeTypes.CHOICE_NODE:
- streamChoice(writer);
- break;
- case NodeTypes.CONTAINER_NODE:
- streamContainer(writer);
- break;
- case NodeTypes.LEAF_NODE:
- streamLeaf(writer);
- break;
- case NodeTypes.LEAF_SET:
- streamLeafSet(writer);
- break;
- case NodeTypes.ORDERED_LEAF_SET:
- streamOrderedLeafSet(writer);
- break;
- case NodeTypes.LEAF_SET_ENTRY_NODE:
- streamLeafSetEntry(writer);
- break;
- case NodeTypes.MAP_ENTRY_NODE:
- streamMapEntry(writer);
- break;
- case NodeTypes.MAP_NODE:
- streamMap(writer);
- break;
- case NodeTypes.ORDERED_MAP_NODE:
- streamOrderedMap(writer);
- break;
- case NodeTypes.UNKEYED_LIST:
- streamUnkeyedList(writer);
- break;
- case NodeTypes.UNKEYED_LIST_ITEM:
- streamUnkeyedListItem(writer);
- break;
- default:
- throw new InvalidNormalizedNodeStreamException("Unexpected node " + nodeType);
- }
- }
-
- private void streamAnyxml(final NormalizedNodeStreamWriter writer) throws IOException {
- final NodeIdentifier identifier = readNodeIdentifier();
- LOG.trace("Streaming anyxml node {}", identifier);
- writer.startAnyxmlNode(identifier);
- writer.domSourceValue(readDOMSource());
- writer.endNode();
- }
-
- private void streamAugmentation(final NormalizedNodeStreamWriter writer) throws IOException {
- final AugmentationIdentifier augIdentifier = readAugmentationIdentifier();
- LOG.trace("Streaming augmentation node {}", augIdentifier);
- writer.startAugmentationNode(augIdentifier);
- commonStreamContainer(writer);
- }
-
- private void streamChoice(final NormalizedNodeStreamWriter writer) throws IOException {
- final NodeIdentifier identifier = readNodeIdentifier();
- LOG.trace("Streaming choice node {}", identifier);
- writer.startChoiceNode(identifier, NormalizedNodeStreamWriter.UNKNOWN_SIZE);
- commonStreamContainer(writer);
- }
-
- private void streamContainer(final NormalizedNodeStreamWriter writer) throws IOException {
- final NodeIdentifier identifier = readNodeIdentifier();
- LOG.trace("Streaming container node {}", identifier);
- writer.startContainerNode(identifier, NormalizedNodeStreamWriter.UNKNOWN_SIZE);
- commonStreamContainer(writer);
- }
-
- private void streamLeaf(final NormalizedNodeStreamWriter writer) throws IOException {
- startLeaf(writer);
- endLeaf(writer, readObject());
- }
-
- // Leaf inside a MapEntryNode, it can potentially be a key leaf, in which case we want to de-duplicate values.
- private void streamLeaf(final NormalizedNodeStreamWriter writer, final NodeIdentifierWithPredicates entryId)
- throws IOException {
- final NodeIdentifier identifier = startLeaf(writer);
- final Object value = readObject();
- final Object entryValue = entryId.getValue(identifier.getNodeType());
- endLeaf(writer, entryValue == null ? value : entryValue);
- }
-
- private NodeIdentifier startLeaf(final NormalizedNodeStreamWriter writer) throws IOException {
- final NodeIdentifier identifier = readNodeIdentifier();
- LOG.trace("Streaming leaf node {}", identifier);
- writer.startLeafNode(identifier);
- return identifier;
- }
-
- private static void endLeaf(final NormalizedNodeStreamWriter writer, final Object value) throws IOException {
- writer.scalarValue(value);
- writer.endNode();
- }
-
- private void streamLeafSet(final NormalizedNodeStreamWriter writer) throws IOException {
- final NodeIdentifier identifier = readNodeIdentifier();
- LOG.trace("Streaming leaf set node {}", identifier);
- writer.startLeafSet(identifier, NormalizedNodeStreamWriter.UNKNOWN_SIZE);
- commonStreamLeafSet(writer, identifier);
- }
-
- private void streamOrderedLeafSet(final NormalizedNodeStreamWriter writer) throws IOException {
- final NodeIdentifier identifier = readNodeIdentifier();
- LOG.trace("Streaming ordered leaf set node {}", identifier);
- writer.startOrderedLeafSet(identifier, NormalizedNodeStreamWriter.UNKNOWN_SIZE);
- commonStreamLeafSet(writer, identifier);
- }
-
- private void commonStreamLeafSet(final NormalizedNodeStreamWriter writer, final NodeIdentifier identifier)
- throws IOException {
- lastLeafSetQName = identifier.getNodeType();
- try {
- commonStreamContainer(writer);
- } finally {
- // Make sure we never leak this
- lastLeafSetQName = null;
- }
- }
-
- private void streamLeafSetEntry(final NormalizedNodeStreamWriter writer) throws IOException {
- final QName name = lastLeafSetQName != null ? lastLeafSetQName : readQName();
- final Object value = readObject();
- final NodeWithValue<Object> leafIdentifier = new NodeWithValue<>(name, value);
- LOG.trace("Streaming leaf set entry node {}, value {}", leafIdentifier, value);
- writer.startLeafSetEntryNode(leafIdentifier);
- writer.scalarValue(value);
- writer.endNode();
- }
-
- private void streamMap(final NormalizedNodeStreamWriter writer) throws IOException {
- final NodeIdentifier identifier = readNodeIdentifier();
- LOG.trace("Streaming map node {}", identifier);
- writer.startMapNode(identifier, NormalizedNodeStreamWriter.UNKNOWN_SIZE);
- commonStreamContainer(writer);
- }
-
- private void streamOrderedMap(final NormalizedNodeStreamWriter writer) throws IOException {
- final NodeIdentifier identifier = readNodeIdentifier();
- LOG.trace("Streaming ordered map node {}", identifier);
- writer.startOrderedMapNode(identifier, NormalizedNodeStreamWriter.UNKNOWN_SIZE);
- commonStreamContainer(writer);
- }
-
- private void streamMapEntry(final NormalizedNodeStreamWriter writer) throws IOException {
- final NodeIdentifierWithPredicates entryIdentifier = readNormalizedNodeWithPredicates();
- LOG.trace("Streaming map entry node {}", entryIdentifier);
- writer.startMapEntryNode(entryIdentifier, NormalizedNodeStreamWriter.UNKNOWN_SIZE);
-
- // Same loop as commonStreamContainer(), but ...
- for (byte nodeType = input.readByte(); nodeType != NodeTypes.END_NODE; nodeType = input.readByte()) {
- if (nodeType == NodeTypes.LEAF_NODE) {
- // ... leaf nodes may need de-duplication
- streamLeaf(writer, entryIdentifier);
- } else {
- streamNormalizedNode(writer, nodeType);
- }
- }
- writer.endNode();
- }
-
- private void streamUnkeyedList(final NormalizedNodeStreamWriter writer) throws IOException {
- final NodeIdentifier identifier = readNodeIdentifier();
- LOG.trace("Streaming unkeyed list node {}", identifier);
- writer.startUnkeyedList(identifier, NormalizedNodeStreamWriter.UNKNOWN_SIZE);
- commonStreamContainer(writer);
- }
-
- private void streamUnkeyedListItem(final NormalizedNodeStreamWriter writer) throws IOException {
- final NodeIdentifier identifier = readNodeIdentifier();
- LOG.trace("Streaming unkeyed list item node {}", identifier);
- writer.startUnkeyedListItem(identifier, NormalizedNodeStreamWriter.UNKNOWN_SIZE);
- commonStreamContainer(writer);
- }
-
- private void commonStreamContainer(final NormalizedNodeStreamWriter writer) throws IOException {
- for (byte nodeType = input.readByte(); nodeType != NodeTypes.END_NODE; nodeType = input.readByte()) {
- streamNormalizedNode(writer, nodeType);
- }
- writer.endNode();
- }
-
- private DOMSource readDOMSource() throws IOException {
- String xml = readObject().toString();
- try {
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- factory.setNamespaceAware(true);
- Element node = factory.newDocumentBuilder().parse(
- new InputSource(new StringReader(xml))).getDocumentElement();
- return new DOMSource(node);
- } catch (SAXException | ParserConfigurationException e) {
- throw new IOException("Error parsing XML: " + xml, e);
- }
- }
-