--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies 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.mdsal.binding.javav2.dom.codec.serialized;
+
+import com.google.common.base.Optional;
+import java.util.Collection;
+import java.util.Map;
+import javax.annotation.Nonnull;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Instantiable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+/**
+ * Serialize operation from binding to DOM.
+ */
+public class LazySerializedContainerNode implements ContainerNode {
+
+ private final NodeIdentifier identifier;
+ private final Instantiable<?> bindingData;
+
+ private BindingNormalizedNodeCodecRegistry registry;
+ private ContainerNode domData;
+
+ private LazySerializedContainerNode(final QName identifier, final Instantiable<?> binding,
+ final BindingNormalizedNodeCodecRegistry registry) {
+ this.identifier = NodeIdentifier.create(identifier);
+ this.bindingData = binding;
+ this.registry = registry;
+ this.domData = null;
+ }
+
+ /**
+ * Prepare serializer of binding data with specific codec.
+ *
+ * @param operationName
+ * - qname of operation
+ * @param data
+ * - binding operation
+ * @param codec
+ * - specifc codec for operation
+ * @return instance of lazy serialized container node
+ */
+ public static NormalizedNode<?, ?> create(final SchemaPath operationName, final Instantiable<?> data,
+ final BindingNormalizedNodeCodecRegistry codec) {
+ return new LazySerializedContainerNode(operationName.getLastComponent(), data, codec);
+ }
+
+ /**
+ * Prepare serializer of binding data with specific codec and pre-cached serialized leaf holding routing
+ * information.
+ *
+ * @param operationName
+ * - operation name
+ * @param data
+ * - Binding data
+ * @param contextRef
+ * - leaf context reference
+ * @param codec
+ * - specific codec
+ * @return insntance of lazy serialized container node with pre-cached serialized leaf
+ */
+ public static NormalizedNode<?, ?> withContextRef(final SchemaPath operationName, final Instantiable<?> data,
+ final LeafNode<?> contextRef, final BindingNormalizedNodeCodecRegistry codec) {
+ return new WithContextRef(operationName.getLastComponent(), data, contextRef, codec);
+ }
+
+ @Override
+ public Map<QName, String> getAttributes() {
+ return delegate().getAttributes();
+ }
+
+ private ContainerNode delegate() {
+ if (domData == null) {
+ domData = registry.toNormalizedNodeOperationData(bindingData);
+ registry = null;
+ }
+ return domData;
+ }
+
+ @Override
+ public final QName getNodeType() {
+ return identifier.getNodeType();
+ }
+
+ @Override
+ public final Collection<DataContainerChild<? extends PathArgument, ?>> getValue() {
+ return delegate().getValue();
+ }
+
+ @Nonnull
+ @Override
+ public final NodeIdentifier getIdentifier() {
+ return identifier;
+ }
+
+ @Override
+ public Optional<DataContainerChild<? extends PathArgument, ?>> getChild(final PathArgument child) {
+ return delegate().getChild(child);
+ }
+
+ @Override
+ public final Object getAttributeValue(final QName name) {
+ return delegate().getAttributeValue(name);
+ }
+
+ /**
+ * Get binding data.
+ *
+ * @return binding data.
+ */
+ public final Instantiable<?> bindingData() {
+ return bindingData;
+ }
+
+ /**
+ * Lazy Serialized Node with pre-cached serialized leaf holding routing information.
+ *
+ */
+ private static final class WithContextRef extends LazySerializedContainerNode {
+
+ private final LeafNode<?> contextRef;
+
+ private WithContextRef(final QName identifier, final Instantiable<?> binding, final LeafNode<?> contextRef,
+ final BindingNormalizedNodeCodecRegistry registry) {
+ super(identifier, binding, registry);
+ this.contextRef = contextRef;
+ }
+
+ @Override
+ public Optional<DataContainerChild<? extends PathArgument, ?>> getChild(final PathArgument child) {
+ /*
+ * Use precached value of routing field and do not run full serialization if we are accessing it.
+ */
+ if (contextRef.getIdentifier().equals(child)) {
+ return Optional.of(contextRef);
+ }
+ return super.getChild(child);
+ }
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies 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.mdsal.binding.javav2.dom.codec.serialized;
+
+import com.google.common.annotations.Beta;
+import javax.annotation.Nonnull;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.api.serializer.BindingNormalizedNodeSerializer;
+import org.opendaylight.mdsal.binding.javav2.runtime.reflection.BindingReflections;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Notification;
+import org.opendaylight.mdsal.dom.api.DOMNotification;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+/**
+ * Lazy serialized implementation of DOM Notification.
+ *
+ * <p>
+ * This implementation performs serialization of data, only if receiver of notification actually accessed data
+ * from notification.
+ *
+ */
+@Beta
+public final class LazySerializedDOMNotification implements DOMNotification {
+
+ private final BindingNormalizedNodeSerializer codec;
+ private final Notification<?> data;
+ private final SchemaPath type;
+
+ private ContainerNode domBody;
+
+ private LazySerializedDOMNotification(final BindingNormalizedNodeSerializer codec, final Notification<?> data,
+ final SchemaPath type) {
+ this.codec = codec;
+ this.data = data;
+ this.type = type;
+ }
+
+ /**
+ * Create serializer of Binding notification data to DOM notification with specific codec.
+ *
+ * @param codec
+ * - specific codec
+ * @param data
+ * - binding notification data
+ * @return DOM notification serializer
+ */
+ public static DOMNotification create(final BindingNormalizedNodeSerializer codec, final Notification<?> data) {
+ final SchemaPath type = SchemaPath.create(true, BindingReflections.findQName(data.getClass()));
+ return new LazySerializedDOMNotification(codec, data, type);
+ }
+
+ @Nonnull
+ @Override
+ public SchemaPath getType() {
+ return type;
+ }
+
+ @Nonnull
+ @Override
+ public ContainerNode getBody() {
+ if (domBody == null) {
+ domBody = codec.toNormalizedNodeNotification(data);
+ }
+ return domBody;
+ }
+
+ /**
+ * Get binding notification data.
+ *
+ * @return binding notification data
+ */
+ public Notification<?> getBindingData() {
+ return data;
+ }
+}