package org.opendaylight.yangtools.binding.data.codec.impl;
import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableCollection;
+import com.google.common.collect.ImmutableSet;
+import java.io.IOException;
import java.util.List;
import javax.annotation.Nullable;
+import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeCachingCodec;
import org.opendaylight.yangtools.yang.binding.BindingStreamEventWriter;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.DataObjectSerializer;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.common.QNameModule;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+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.impl.schema.ImmutableNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
-abstract class DataContainerCodecContext<T> extends NodeCodecContext {
+abstract class DataContainerCodecContext<D extends DataObject,T> extends NodeCodecContext<D> {
private final DataContainerCodecPrototype<T> prototype;
+ private volatile DataObjectSerializer eventStreamSerializer;
protected DataContainerCodecContext(final DataContainerCodecPrototype<T> prototype) {
this.prototype = prototype;
* @return Context of child
* @throws IllegalArgumentException If supplied argument does not represent valid child.
*/
- protected abstract NodeCodecContext getYangIdentifierChild(final YangInstanceIdentifier.PathArgument arg);
+ @Override
+ public abstract NodeCodecContext<?> yangPathArgumentChild(final YangInstanceIdentifier.PathArgument arg);
/**
* Returns nested node context using supplied Binding Instance Identifier
* @return Context of child or null if supplied {@code arg} does not represent valid child.
* @throws IllegalArgumentException If supplied argument does not represent valid child.
*/
- protected @Nullable DataContainerCodecContext<?> getIdentifierChild(final InstanceIdentifier.PathArgument arg,
+ @Override
+ public @Nullable DataContainerCodecContext<?,?> bindingPathArgumentChild(final InstanceIdentifier.PathArgument arg,
final List<YangInstanceIdentifier.PathArgument> builder) {
- final DataContainerCodecContext<?> child = getStreamChild(arg.getType());
+ final DataContainerCodecContext<?,?> child = streamChild(arg.getType());
if(child != null) {
if (builder != null) {
child.addYangPathArgument(arg,builder);
}
return child;
}
- return null;
+ throw new IllegalArgumentException("SUpplied argument is not valid child");
}
/**
return prototype.getBindingArg();
}
- protected final Class<?> bindingClass() {
- return prototype.getBindingClass();
+ @SuppressWarnings("unchecked")
+ @Override
+ public final Class<D> getBindingClass() {
+ return Class.class.cast(prototype.getBindingClass());
}
/**
* @return Context of child node or null, if supplied class is not subtree child
* @throws IllegalArgumentException If supplied child class is not valid in specified context.
*/
- protected abstract @Nullable DataContainerCodecContext<?> getStreamChild(final Class<?> childClass) throws IllegalArgumentException;
+ @Override
+ public abstract @Nullable <DV extends DataObject> DataContainerCodecContext<DV,?> streamChild(final Class<DV> childClass) throws IllegalArgumentException;
/**
*
* @param childClass
* @return Context of child or Optional absent is supplied class is not applicable in context.
*/
- protected abstract Optional<DataContainerCodecContext<?>> getPossibleStreamChild(final Class<?> childClass);
+ @Override
+ public abstract <DV extends DataObject> Optional<DataContainerCodecContext<DV,?>> possibleStreamChild(final Class<DV> childClass);
@Override
public String toString() {
return getClass().getSimpleName() + " [" + prototype.getBindingClass() + "]";
}
+ @Override
+ public BindingNormalizedNodeCachingCodec<D> createCachingCodec(
+ final ImmutableCollection<Class<? extends DataObject>> cacheSpecifier) {
+ if(cacheSpecifier.isEmpty()) {
+ return new NonCachingCodec<>(this);
+ }
+ return new CachingNormalizedNodeCodec<D>(this,ImmutableSet.copyOf(cacheSpecifier));
+ }
+
+ BindingStreamEventWriter createWriter(final NormalizedNodeStreamWriter domWriter) {
+ return new BindingToNormalizedStreamWriter(this, domWriter);
+ }
+
+ DataObjectSerializer eventStreamSerializer() {
+ if(eventStreamSerializer == null) {
+ eventStreamSerializer = factory().getEventStreamSerializer(getBindingClass());
+ }
+ return eventStreamSerializer;
+ }
+
+ @Override
+ public NormalizedNode<?, ?> serialize(final D data) {
+ final NormalizedNodeResult result = new NormalizedNodeResult();
+ // We create DOM stream writer which produces normalized nodes
+ final NormalizedNodeStreamWriter domWriter = ImmutableNormalizedNodeStreamWriter.from(result);
+ writeAsNormalizedNode(data, domWriter);
+ return result.getResult();
+ }
+
+ @Override
+ public void writeAsNormalizedNode(final D data, final NormalizedNodeStreamWriter writer) {
+ try {
+ eventStreamSerializer().serialize(data, createWriter(writer));
+ } catch (final IOException e) {
+ throw new IllegalStateException("Failed to serialize Binding DTO",e);
+ }
+ }
+
}
\ No newline at end of file