Merge "Bug 1372 - toString methods in generated classes"
[yangtools.git] / code-generator / binding-data-codec / src / main / java / org / opendaylight / yangtools / binding / data / codec / impl / DataContainerCodecContext.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.binding.data.codec.impl;
9
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;
23
24 abstract class DataContainerCodecContext<T> extends NodeCodecContext {
25
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;
31
32     protected final LoadingCache<Class<?>, DataContainerCodecContext<?>> containerChild;
33
34     @SuppressWarnings({ "rawtypes", "unchecked" })
35     protected DataContainerCodecContext(final Class<?> cls, final QNameModule namespace, final T nodeSchema,
36             final CodecContextFactory factory) {
37         super();
38         this.schema = nodeSchema;
39         this.factory = factory;
40         this.namespace = namespace;
41         this.bindingClass = cls;
42         this.bindingArg = new InstanceIdentifier.Item(bindingClass);
43
44         this.containerChild = CacheBuilder.newBuilder().build(new CacheLoader<Class<?>, DataContainerCodecContext<?>>() {
45             @Override
46             public DataContainerCodecContext<?> load(final Class<?> key) throws Exception {
47                 return loadChild(key);
48             }
49         });
50     }
51
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);
60         }
61         throw new IllegalArgumentException("Not supported type " + cls + " " + schema);
62     }
63
64     protected  T getSchema() {
65         return schema;
66     }
67
68     /**
69      * Returns nested node context using supplied YANG Instance Identifier
70      *
71      * @param arg Yang Instance Identifier Argument
72      * @return Context of child
73      * @throws IllegalArgumentException If supplied argument does not represent valid child.
74      */
75     protected abstract NodeCodecContext getYangIdentifierChild(final YangInstanceIdentifier.PathArgument arg);
76
77     /**
78      * Returns nested node context using supplied Binding Instance Identifier
79      * and adds YANG instance identifiers to supplied list.
80      *
81      * @param arg Binding Instance Identifier Argument
82      * @return Context of child
83      * @throws IllegalArgumentException If supplied argument does not represent valid child.
84      */
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);
90         }
91         return child;
92     }
93
94     /**
95      *
96      * Returns deserialized Binding Path Argument from YANG instance identifier.
97      *
98      * @param domArg
99      * @return
100      */
101     protected  PathArgument getBindingPathArgument(final YangInstanceIdentifier.PathArgument domArg) {
102         return bindingArg;
103     }
104
105     /**
106      *
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).
110      *
111      * @param childClass
112      * @return Context of child
113      */
114     protected  DataContainerCodecContext<?> getStreamChild(final Class<?> childClass) {
115         return containerChild.getUnchecked(childClass);
116     }
117
118     /**
119      * Loads children identified by supplied class. If children is not
120      * valid, throws {@link IllegalArgumentException}.
121      *
122      * @param childClass
123      * @return Context of child
124      */
125     protected abstract DataContainerCodecContext<?> loadChild(final Class<?> childClass);
126
127     @Override
128     public String toString() {
129         return getClass().getSimpleName() + " [" + bindingClass + "]";
130     }
131
132 }