From c6f05b10e72d0c7310e78e59e33f480fb6426bc5 Mon Sep 17 00:00:00 2001 From: Jakub Toth Date: Tue, 13 Jun 2017 14:08:00 +0200 Subject: [PATCH] Binding2 runtime - Codecs - serialized Change-Id: I45eef52b91b0a493d7352a7ea46479cb9fff709e Signed-off-by: Jakub Toth --- .../LazySerializedContainerNode.java | 153 ++++++++++++++++++ .../LazySerializedDOMNotification.java | 80 +++++++++ 2 files changed, 233 insertions(+) create mode 100644 binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/serialized/LazySerializedContainerNode.java create mode 100644 binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/serialized/LazySerializedDOMNotification.java diff --git a/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/serialized/LazySerializedContainerNode.java b/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/serialized/LazySerializedContainerNode.java new file mode 100644 index 0000000000..6b543ccf60 --- /dev/null +++ b/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/serialized/LazySerializedContainerNode.java @@ -0,0 +1,153 @@ +/* + * 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 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> getValue() { + return delegate().getValue(); + } + + @Nonnull + @Override + public final NodeIdentifier getIdentifier() { + return identifier; + } + + @Override + public Optional> 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> 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); + } + } + +} diff --git a/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/serialized/LazySerializedDOMNotification.java b/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/serialized/LazySerializedDOMNotification.java new file mode 100644 index 0000000000..ace09cffc4 --- /dev/null +++ b/binding2/mdsal-binding2-dom-codec/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/codec/serialized/LazySerializedDOMNotification.java @@ -0,0 +1,80 @@ +/* + * 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. + * + *

+ * 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; + } +} -- 2.36.6