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.cache.CacheBuilder;
11 import com.google.common.cache.CacheLoader;
12 import com.google.common.cache.LoadingCache;
13 import java.util.List;
14 import org.opendaylight.yangtools.yang.binding.BindingStreamEventWriter;
15 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
16 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
17 import org.opendaylight.yangtools.yang.common.QNameModule;
18 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
19 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
20 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
21 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
22 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
24 abstract class DataContainerCodecContext<T> extends NodeCodecContext {
26 protected final T schema;
27 protected final QNameModule namespace;
28 protected final CodecContextFactory factory;
29 protected final Class<?> bindingClass;
30 protected final InstanceIdentifier.Item<?> bindingArg;
32 protected final LoadingCache<Class<?>, DataContainerCodecContext<?>> containerChild;
34 @SuppressWarnings({ "rawtypes", "unchecked" })
35 protected DataContainerCodecContext(final Class<?> cls, final QNameModule namespace, final T nodeSchema,
36 final CodecContextFactory factory) {
38 this.schema = nodeSchema;
39 this.factory = factory;
40 this.namespace = namespace;
41 this.bindingClass = cls;
42 this.bindingArg = new InstanceIdentifier.Item(bindingClass);
44 this.containerChild = CacheBuilder.newBuilder().build(new CacheLoader<Class<?>, DataContainerCodecContext<?>>() {
46 public DataContainerCodecContext<?> load(final Class<?> key) throws Exception {
47 return loadChild(key);
52 static DataContainerCodecContext<?> from(final Class<?> cls, final DataSchemaNode schema,
53 final CodecContextFactory loader) {
54 if (schema instanceof ContainerSchemaNode) {
55 return new ContainerNodeCodecContext(cls, (ContainerSchemaNode) schema, loader);
56 } else if (schema instanceof ListSchemaNode) {
57 return new ListNodeCodecContext(cls, (ListSchemaNode) schema, loader);
58 } else if (schema instanceof ChoiceNode) {
59 return new ChoiceNodeCodecContext(cls, (ChoiceNode) schema, loader);
61 throw new IllegalArgumentException("Not supported type " + cls + " " + schema);
64 protected T getSchema() {
69 * Returns nested node context using supplied YANG Instance Identifier
71 * @param arg Yang Instance Identifier Argument
72 * @return Context of child
73 * @throws IllegalArgumentException If supplied argument does not represent valid child.
75 protected abstract NodeCodecContext getYangIdentifierChild(final YangInstanceIdentifier.PathArgument arg);
78 * Returns nested node context using supplied Binding Instance Identifier
79 * and adds YANG instance identifiers to supplied list.
81 * @param arg Binding Instance Identifier Argument
82 * @return Context of child
83 * @throws IllegalArgumentException If supplied argument does not represent valid child.
85 protected DataContainerCodecContext<?> getIdentifierChild(final InstanceIdentifier.PathArgument arg,
86 final List<YangInstanceIdentifier.PathArgument> builder) {
87 final DataContainerCodecContext<?> child = getStreamChild(arg.getType());
88 if (builder != null) {
89 child.addYangPathArgument(arg,builder);
96 * Returns deserialized Binding Path Argument from YANG instance identifier.
101 protected PathArgument getBindingPathArgument(final YangInstanceIdentifier.PathArgument domArg) {
107 * Returns child context as if it was walked by
108 * {@link BindingStreamEventWriter}. This means that to enter case, one
109 * must issue getChild(ChoiceClass).getChild(CaseClass).
112 * @return Context of child
114 protected DataContainerCodecContext<?> getStreamChild(final Class<?> childClass) {
115 return containerChild.getUnchecked(childClass);
119 * Loads children identified by supplied class. If children is not
120 * valid, throws {@link IllegalArgumentException}.
123 * @return Context of child
125 protected abstract DataContainerCodecContext<?> loadChild(final Class<?> childClass);
128 public String toString() {
129 return getClass().getSimpleName() + " [" + bindingClass + "]";