Merge "BUG-1433: augmentation field visibility changed to default"
[yangtools.git] / code-generator / binding-data-codec / src / main / java / org / opendaylight / yangtools / binding / data / codec / impl / SchemaRootCodecContext.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.base.Optional;
11 import com.google.common.base.Preconditions;
12 import com.google.common.cache.CacheBuilder;
13 import com.google.common.cache.CacheLoader;
14 import com.google.common.cache.LoadingCache;
15 import org.opendaylight.yangtools.util.ClassLoaderUtils;
16 import org.opendaylight.yangtools.yang.binding.ChildOf;
17 import org.opendaylight.yangtools.yang.binding.DataRoot;
18 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
19 import org.opendaylight.yangtools.yang.common.QName;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
21 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
22 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
23 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
24 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
25 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
26
27 class SchemaRootCodecContext extends DataContainerCodecContext<SchemaContext> {
28
29     private final LoadingCache<Class<?>, DataContainerCodecContext<?>> children = CacheBuilder.newBuilder().build(
30             new CacheLoader<Class<?>, DataContainerCodecContext<?>>() {
31                 @Override
32                 public DataContainerCodecContext<?> load(final Class<?> key) {
33                     Class<Object> parent = ClassLoaderUtils.findFirstGenericArgument(key, ChildOf.class);
34                     Preconditions.checkArgument(DataRoot.class.isAssignableFrom(parent));
35                     QName qname = BindingReflections.findQName(key);
36                     DataSchemaNode childSchema = schema().getDataChildByName(qname);
37                     return DataContainerCodecPrototype.from(key, childSchema, factory()).get();
38                 }
39             });
40
41     private SchemaRootCodecContext(final DataContainerCodecPrototype<SchemaContext> dataPrototype) {
42         super(dataPrototype);
43     }
44
45     /**
46      * Creates RootNode from supplied CodecContextFactory.
47      *
48      * @param factory
49      *            CodecContextFactory
50      * @return
51      */
52     static SchemaRootCodecContext create(final CodecContextFactory factory) {
53         DataContainerCodecPrototype<SchemaContext> prototype = DataContainerCodecPrototype.rootPrototype(factory);
54         return new SchemaRootCodecContext(prototype);
55     }
56
57     @Override
58     protected DataContainerCodecContext<?> getStreamChild(final Class<?> childClass) {
59         return children.getUnchecked(childClass);
60     }
61
62     @Override
63     protected Optional<DataContainerCodecContext<?>> getPossibleStreamChild(final Class<?> childClass) {
64         throw new UnsupportedOperationException("Not supported");
65     }
66
67     @Override
68     protected YangInstanceIdentifier.PathArgument getDomPathArgument() {
69         throw new UnsupportedOperationException();
70     }
71
72     @Override
73     protected NodeCodecContext getYangIdentifierChild(final YangInstanceIdentifier.PathArgument arg) {
74         // FIXME: Optimize this
75         QName childQName = arg.getNodeType();
76         DataSchemaNode childSchema = schema().getDataChildByName(childQName);
77         Preconditions.checkArgument(childSchema != null, "Argument %s is not valid child of %s", arg, schema());
78         if (childSchema instanceof DataNodeContainer || childSchema instanceof ChoiceNode) {
79             Class<?> childCls = factory().getRuntimeContext().getClassForSchema(childSchema);
80             DataContainerCodecContext<?> childNode = getStreamChild(childCls);
81             return childNode;
82         } else {
83             throw new UnsupportedOperationException();
84         }
85     }
86
87     @Override
88     protected Object dataFromNormalizedNode(final NormalizedNode<?, ?> normalizedNode) {
89         throw new UnsupportedOperationException("Could not create Binding data representation for root");
90     }
91 }