2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.binding.data.codec.impl;
10 import com.google.common.base.Optional;
11 import com.google.common.collect.ImmutableCollection;
12 import com.google.common.collect.ImmutableSet;
13 import java.io.IOException;
14 import java.util.List;
15 import javax.annotation.Nullable;
16 import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeCachingCodec;
17 import org.opendaylight.yangtools.yang.binding.BindingStreamEventWriter;
18 import org.opendaylight.yangtools.yang.binding.DataObject;
19 import org.opendaylight.yangtools.yang.binding.DataObjectSerializer;
20 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
21 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
22 import org.opendaylight.yangtools.yang.common.QNameModule;
23 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
24 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
25 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
26 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
27 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
29 abstract class DataContainerCodecContext<D extends DataObject,T> extends NodeCodecContext<D> {
31 private final DataContainerCodecPrototype<T> prototype;
32 private volatile DataObjectSerializer eventStreamSerializer;
34 protected DataContainerCodecContext(final DataContainerCodecPrototype<T> prototype) {
35 this.prototype = prototype;
38 protected final T schema() {
39 return prototype.getSchema();
42 protected final QNameModule namespace() {
43 return prototype.getNamespace();
46 protected final CodecContextFactory factory() {
47 return prototype.getFactory();
51 protected YangInstanceIdentifier.PathArgument getDomPathArgument() {
52 return prototype.getYangArg();
56 * Returns nested node context using supplied YANG Instance Identifier
58 * @param arg Yang Instance Identifier Argument
59 * @return Context of child
60 * @throws IllegalArgumentException If supplied argument does not represent valid child.
63 public abstract NodeCodecContext<?> yangPathArgumentChild(final YangInstanceIdentifier.PathArgument arg);
66 * Returns nested node context using supplied Binding Instance Identifier
67 * and adds YANG instance identifiers to supplied list.
69 * @param arg Binding Instance Identifier Argument
70 * @return Context of child or null if supplied {@code arg} does not represent valid child.
71 * @throws IllegalArgumentException If supplied argument does not represent valid child.
74 public @Nullable DataContainerCodecContext<?,?> bindingPathArgumentChild(final InstanceIdentifier.PathArgument arg,
75 final List<YangInstanceIdentifier.PathArgument> builder) {
76 final DataContainerCodecContext<?,?> child = streamChild(arg.getType());
78 if (builder != null) {
79 child.addYangPathArgument(arg,builder);
83 throw new IllegalArgumentException("SUpplied argument is not valid child");
87 * Returns deserialized Binding Path Argument from YANG instance identifier.
92 protected PathArgument getBindingPathArgument(final YangInstanceIdentifier.PathArgument domArg) {
96 protected final PathArgument bindingArg() {
97 return prototype.getBindingArg();
100 @SuppressWarnings("unchecked")
102 public final Class<D> getBindingClass() {
103 return Class.class.cast(prototype.getBindingClass());
108 * Returns child context as if it was walked by
109 * {@link BindingStreamEventWriter}. This means that to enter case, one
110 * must issue getChild(ChoiceClass).getChild(CaseClass).
113 * @return Context of child node or null, if supplied class is not subtree child
114 * @throws IllegalArgumentException If supplied child class is not valid in specified context.
117 public abstract @Nullable <DV extends DataObject> DataContainerCodecContext<DV,?> streamChild(final Class<DV> childClass) throws IllegalArgumentException;
121 * Returns child context as if it was walked by
122 * {@link BindingStreamEventWriter}. This means that to enter case, one
123 * must issue getChild(ChoiceClass).getChild(CaseClass).
126 * @return Context of child or Optional absent is supplied class is not applicable in context.
129 public abstract <DV extends DataObject> Optional<DataContainerCodecContext<DV,?>> possibleStreamChild(final Class<DV> childClass);
132 public String toString() {
133 return getClass().getSimpleName() + " [" + prototype.getBindingClass() + "]";
137 public BindingNormalizedNodeCachingCodec<D> createCachingCodec(
138 ImmutableCollection<Class<? extends DataObject>> cacheSpecifier) {
139 return new CachingNormalizedNodeCodecImpl<D>(this,ImmutableSet.copyOf(cacheSpecifier));
142 BindingStreamEventWriter createWriter(NormalizedNodeStreamWriter domWriter) {
143 return new BindingToNormalizedStreamWriter(this, domWriter);
146 DataObjectSerializer eventStreamSerializer() {
147 if(eventStreamSerializer == null) {
148 eventStreamSerializer = factory().getEventStreamSerializer(getBindingClass());
150 return eventStreamSerializer;
154 public NormalizedNode<?, ?> serialize(D data) {
155 final NormalizedNodeResult result = new NormalizedNodeResult();
156 // We create DOM stream writer which produces normalized nodes
157 final NormalizedNodeStreamWriter domWriter = ImmutableNormalizedNodeStreamWriter.from(result);
158 writeAsNormalizedNode(data, domWriter);
159 return result.getResult();
163 public void writeAsNormalizedNode(D data, NormalizedNodeStreamWriter writer) {
165 eventStreamSerializer().serialize(data, createWriter(writer));
166 } catch (IOException e) {
167 throw new IllegalStateException("Failed to serialize Binding DTO",e);