Bug 1411-4: MDSAL Binding2 Generator Impl
[mdsal.git] / binding2 / mdsal-binding2-generator-impl / src / main / java / org / opendaylight / mdsal / binding2 / generator / yang / types / TypeProviderImpl.java
1 /*
2  * Copyright (c) 2016 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
9 package org.opendaylight.mdsal.binding2.generator.yang.types;
10
11 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
12
13 import com.google.common.annotations.Beta;
14 import com.google.common.base.Preconditions;
15 import java.util.Date;
16 import java.util.HashMap;
17 import java.util.Map;
18 import java.util.Set;
19 import org.opendaylight.mdsal.binding2.generator.spi.TypeProvider;
20 import org.opendaylight.mdsal.binding2.model.api.Restrictions;
21 import org.opendaylight.mdsal.binding2.model.api.Type;
22 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
23 import org.opendaylight.yangtools.yang.model.api.Module;
24 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
25 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
26 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
27 import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
28 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 @Beta
33 public final class TypeProviderImpl implements TypeProvider {
34
35     private static final Logger LOG = LoggerFactory.getLogger(TypeProviderImpl.class);
36
37     /**
38      * Contains the schema data red from YANG files.
39      */
40     private final SchemaContext schemaContext;
41
42     /**
43      * Map<moduleName, Map<moduleDate, Map<typeName, type>>>
44      */
45     private final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap;
46
47     private final Map<Module, Set<Type>> additionalTypes;
48     /**
49      * Creates new instance of class <code>TypeProviderImpl</code>.
50      *
51      * @param schemaContext
52      *            contains the schema data red from YANG files
53      * @throws IllegalArgumentException
54      *             if <code>schemaContext</code> equal null.
55      */
56     public TypeProviderImpl(final SchemaContext schemaContext) {
57         this.schemaContext = schemaContext;
58         this.genTypeDefsContextMap = new HashMap<>();
59         this.additionalTypes = new HashMap<>();
60     }
61
62     @Override
63     public Type javaTypeForSchemaDefinitionType(TypeDefinition<?> type, SchemaNode parentNode) {
64         return null;
65     }
66
67     @Override
68     public Type javaTypeForSchemaDefinitionType(TypeDefinition<?> type, SchemaNode parentNode, Restrictions restrictions) {
69         return null;
70     }
71
72     @Override
73     public String getTypeDefaultConstruction(LeafSchemaNode node) {
74         return null;
75     }
76
77     @Override
78     public String getConstructorPropertyName(SchemaNode node) {
79         return null;
80     }
81
82     @Override
83     public String getParamNameFromType(TypeDefinition<?> type) {
84         return null;
85     }
86
87     /**
88      * Converts <code>typeDefinition</code> to concrete JAVA <code>Type</code>.
89      *
90      * @param typeDefinition
91      *            type definition which should be converted to JAVA
92      *            <code>Type</code>
93      * @return JAVA <code>Type</code> which represents
94      *         <code>typeDefinition</code>
95      * @throws IllegalArgumentException
96      *             <ul>
97      *             <li>if <code>typeDefinition</code> equal null</li>
98      *             <li>if Q name of <code>typeDefinition</code></li>
99      *             <li>if name of <code>typeDefinition</code></li>
100      *             </ul>
101      */
102     public Type generatedTypeForExtendedDefinitionType(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode) {
103         Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!");
104         if (typeDefinition.getQName() == null) {
105             throw new IllegalArgumentException(
106                     "Type Definition cannot have non specified QName (QName cannot be NULL!)");
107         }
108         Preconditions.checkArgument(typeDefinition.getQName().getLocalName() != null,
109                 "Type Definitions Local Name cannot be NULL!");
110
111         final TypeDefinition<?> baseTypeDef = baseTypeDefForExtendedType(typeDefinition);
112         if (!(baseTypeDef instanceof LeafrefTypeDefinition) && !(baseTypeDef instanceof IdentityrefTypeDefinition)) {
113             final Module module = findParentModule(schemaContext, parentNode);
114
115             if (module != null) {
116                 final Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(module.getName());
117                 final Map<String, Type> genTOs = modulesByDate.get(module.getRevision());
118                 if (genTOs != null) {
119                     return genTOs.get(typeDefinition.getQName().getLocalName());
120                 }
121             }
122         }
123         return null;
124     }
125
126     /**
127      * Gets base type definition for <code>extendTypeDef</code>. The method is
128      * recursively called until non <code>ExtendedType</code> type is found.
129      *
130      * @param extendTypeDef
131      *            type definition for which is the base type definition sought
132      * @return type definition which is base type for <code>extendTypeDef</code>
133      * @throws IllegalArgumentException
134      *             if <code>extendTypeDef</code> equal null
135      */
136     private static TypeDefinition<?> baseTypeDefForExtendedType(final TypeDefinition<?> extendTypeDef) {
137         Preconditions.checkArgument(extendTypeDef != null, "Type Definition reference cannot be NULL!");
138
139         TypeDefinition<?> ret = extendTypeDef;
140         while (ret.getBaseType() != null) {
141             ret = ret.getBaseType();
142         }
143
144         return ret;
145     }
146
147     public Map<Module, Set<Type>> getAdditionalTypes() {
148         return additionalTypes;
149     }
150
151 }