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.collect.Iterables;
12 import javax.annotation.concurrent.GuardedBy;
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;
29 class DataContainerCodecPrototype<T> implements NodeContextSupplier {
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;
39 private DataContainerCodecPrototype(final Class<?> cls, final YangInstanceIdentifier.PathArgument arg, final T nodeSchema,
40 final CodecContextFactory factory) {
42 this.bindingClass = cls;
44 this.schema = nodeSchema;
45 this.factory = factory;
46 this.bindingArg = new InstanceIdentifier.Item(bindingClass);
48 if (arg instanceof AugmentationIdentifier) {
49 this.namespace = Iterables.getFirst(((AugmentationIdentifier) arg).getPossibleChildNames(), null).getModule();
51 this.namespace = arg.getNodeType().getModule();
55 private DataContainerCodecPrototype(final Class<?> cls, final YangInstanceIdentifier.PathArgument arg, final T nodeSchema,
56 final CodecContextFactory factory,final DataContainerCodecContext<T> instance) {
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;
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);
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);
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);
87 protected final T getSchema() {
91 protected final QNameModule getNamespace() {
95 protected final CodecContextFactory getFactory() {
99 protected final Class<?> getBindingClass() {
103 protected final InstanceIdentifier.Item<?> getBindingArg() {
107 protected final YangInstanceIdentifier.PathArgument getYangArg() {
112 public DataContainerCodecContext<T> get() {
113 DataContainerCodecContext<T> tmp = instance;
115 synchronized (this) {
118 tmp = createInstance();
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);
141 throw new IllegalArgumentException("Unsupported type " + bindingClass + " " + schema);
145 return schema instanceof ChoiceNode;