Remove unused arguments from UnionTypeCodec.loader()
[yangtools.git] / code-generator / binding-data-codec / src / main / java / org / opendaylight / yangtools / binding / data / codec / impl / DataContainerCodecPrototype.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.collect.Iterables;
11
12 import javax.annotation.concurrent.GuardedBy;
13
14 import org.opendaylight.yangtools.binding.data.codec.impl.NodeCodecContext.CodecContextFactory;
15 import org.opendaylight.yangtools.yang.binding.DataRoot;
16 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
17 import org.opendaylight.yangtools.yang.common.QNameModule;
18 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
21 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
22 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
23 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
24 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
25 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
26 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
27 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
28
29 class DataContainerCodecPrototype<T> implements NodeContextSupplier {
30
31     private final T schema;
32     private final QNameModule namespace;
33     private final CodecContextFactory factory;
34     private final Class<?> bindingClass;
35     private final InstanceIdentifier.Item<?> bindingArg;
36     private final YangInstanceIdentifier.PathArgument yangArg;
37     private volatile DataContainerCodecContext<T> instance = null;
38
39     private DataContainerCodecPrototype(final Class<?> cls, final YangInstanceIdentifier.PathArgument arg, final T nodeSchema,
40             final CodecContextFactory factory) {
41         super();
42         this.bindingClass = cls;
43         this.yangArg = arg;
44         this.schema = nodeSchema;
45         this.factory = factory;
46         this.bindingArg = new InstanceIdentifier.Item(bindingClass);
47
48         if (arg instanceof AugmentationIdentifier) {
49             this.namespace = Iterables.getFirst(((AugmentationIdentifier) arg).getPossibleChildNames(), null).getModule();
50         } else {
51             this.namespace = arg.getNodeType().getModule();
52         }
53     }
54
55     private DataContainerCodecPrototype(final Class<?> cls, final YangInstanceIdentifier.PathArgument arg, final T nodeSchema,
56             final CodecContextFactory factory,final DataContainerCodecContext<T> instance) {
57         super();
58         this.yangArg = arg;
59         this.schema = nodeSchema;
60         this.factory = factory;
61         this.namespace = arg.getNodeType().getModule();
62         this.bindingClass = cls;
63         this.bindingArg = new InstanceIdentifier.Item(bindingClass);
64         this.instance = instance;
65     }
66
67     @SuppressWarnings({ "unchecked", "rawtypes" })
68     static <T extends DataSchemaNode> DataContainerCodecPrototype<T> from(final Class<?> cls, final T schema,
69             final CodecContextFactory factory) {
70         NodeIdentifier arg = new NodeIdentifier(schema.getQName());
71         return new DataContainerCodecPrototype(cls, arg, schema, factory);
72     }
73
74     static DataContainerCodecPrototype<SchemaContext> rootPrototype(final CodecContextFactory factory) {
75         SchemaContext schema = factory.getRuntimeContext().getSchemaContext();
76         NodeIdentifier arg = new NodeIdentifier(schema.getQName());
77         return new DataContainerCodecPrototype<SchemaContext>(DataRoot.class, arg, schema, factory);
78     }
79
80
81     @SuppressWarnings({ "rawtypes", "unchecked" })
82     public static DataContainerCodecPrototype<?> from(final Class<?> augClass, final AugmentationIdentifier arg,
83             final AugmentationSchema schema, final CodecContextFactory factory) {
84         return new DataContainerCodecPrototype(augClass, arg, schema, factory);
85     }
86
87     protected final T getSchema() {
88         return schema;
89     }
90
91     protected final QNameModule getNamespace() {
92         return namespace;
93     }
94
95     protected final CodecContextFactory getFactory() {
96         return factory;
97     }
98
99     protected final Class<?> getBindingClass() {
100         return bindingClass;
101     }
102
103     protected final InstanceIdentifier.Item<?> getBindingArg() {
104         return bindingArg;
105     }
106
107     protected final YangInstanceIdentifier.PathArgument getYangArg() {
108         return yangArg;
109     }
110
111     @Override
112     public DataContainerCodecContext<T> get() {
113         DataContainerCodecContext<T> tmp = instance;
114         if (tmp == null) {
115             synchronized (this) {
116                 tmp = instance;
117                 if (tmp == null) {
118                     tmp = createInstance();
119                     instance = tmp;
120                 }
121             }
122         }
123
124         return tmp;
125     }
126
127     @GuardedBy("this")
128     private DataContainerCodecContext createInstance() {
129         // FIXME: make protected abstract
130         if (schema instanceof ContainerSchemaNode) {
131             return new ContainerNodeCodecContext((DataContainerCodecPrototype) this);
132         } else if (schema instanceof ListSchemaNode) {
133             return new ListNodeCodecContext((DataContainerCodecPrototype) this);
134         } else if (schema instanceof ChoiceNode) {
135             return new ChoiceNodeCodecContext((DataContainerCodecPrototype) this);
136         } else if (schema instanceof AugmentationSchema) {
137             return new AugmentationNodeContext((DataContainerCodecPrototype) this);
138         } else if (schema instanceof ChoiceCaseNode) {
139             return new CaseNodeCodecContext((DataContainerCodecPrototype) this);
140         }
141         throw new IllegalArgumentException("Unsupported type " + bindingClass + " " + schema);
142     }
143
144     boolean isChoice() {
145         return schema instanceof ChoiceNode;
146     }
147 }