2 * Copyright (c) 2017 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
9 package org.opendaylight.mdsal.binding.javav2.generator.impl;
11 import static com.google.common.base.Preconditions.checkArgument;
12 import static org.opendaylight.mdsal.binding.javav2.generator.impl.GenHelperUtil.groupingsToGenTypes;
13 import static org.opendaylight.mdsal.binding.javav2.generator.impl.GenHelperUtil.moduleTypeBuilder;
14 import static org.opendaylight.mdsal.binding.javav2.generator.impl.GenHelperUtil.processUsesImplements;
15 import static org.opendaylight.mdsal.binding.javav2.generator.impl.GenHelperUtil.resolveNotification;
16 import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes.NOTIFICATION_LISTENER;
18 import com.google.common.annotations.Beta;
19 import com.google.common.base.Preconditions;
20 import com.google.common.collect.ImmutableSet;
22 import java.util.Collection;
23 import java.util.List;
25 import java.util.Objects;
28 import org.opendaylight.mdsal.binding.javav2.generator.context.ModuleContext;
29 import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider;
30 import org.opendaylight.mdsal.binding.javav2.generator.util.TypeComments;
31 import org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeProviderImpl;
32 import org.opendaylight.mdsal.binding.javav2.model.api.Type;
33 import org.opendaylight.mdsal.binding.javav2.model.api.YangSourceDefinition;
34 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilder;
35 import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingNamespaceType;
36 import org.opendaylight.mdsal.binding.javav2.util.BindingMapping;
37 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
38 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
39 import org.opendaylight.yangtools.yang.model.api.Module;
40 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
41 import org.opendaylight.yangtools.yang.model.api.NotificationNodeContainer;
42 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
43 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
44 import org.opendaylight.yangtools.yang.model.util.DataNodeIterator;
47 final class ModuleToGenType {
49 private ModuleToGenType() {
50 throw new UnsupportedOperationException("Utility class");
53 static Map<Module, ModuleContext> generate(final Module module, final Map<String, Map<String, GeneratedTypeBuilder>>
54 genTypeBuilders, final SchemaContext schemaContext, final TypeProvider typeProvider, Map<Module,
55 ModuleContext> genCtx, final boolean verboseClassComments) {
57 genCtx.put(module, new ModuleContext());
58 genCtx = allTypeDefinitionsToGenTypes(module, genCtx, typeProvider);
59 genCtx = groupingsToGenTypes(module, module.getGroupings(), genCtx, schemaContext, verboseClassComments,
60 genTypeBuilders, typeProvider);
61 genCtx = allIdentitiesToGenTypes(module, schemaContext, genCtx, verboseClassComments, genTypeBuilders,
64 if (!module.getChildNodes().isEmpty()) {
65 final GeneratedTypeBuilder moduleType = GenHelperUtil.moduleToDataType(module, genCtx,
66 verboseClassComments);
67 genCtx.get(module).addModuleNode(moduleType);
68 final String basePackageName = BindingMapping.getRootPackageName(module);
69 GenHelperUtil.resolveDataSchemaNodes(module, basePackageName, moduleType, moduleType, module
70 .getChildNodes(), genCtx, schemaContext, verboseClassComments, genTypeBuilders,
72 BindingNamespaceType.Data);
73 processUsesImplements(module, module, schemaContext, genCtx, BindingNamespaceType.Data);
76 genCtx = notificationsToGenType(module, genCtx, schemaContext, genTypeBuilders, verboseClassComments,
79 //after potential parent data schema nodes
80 genCtx = actionsAndRPCMethodsToGenType(module, genCtx, schemaContext, verboseClassComments,
81 genTypeBuilders, typeProvider);
87 * Converts all extended type definitions of module to the list of
88 * <code>Type</code> objects.
90 * @param module module from which is obtained set of type definitions
91 * @throws IllegalArgumentException <ul>
92 * <li>if module is null</li>
93 * <li>if name of module is null</li>
95 * @throws IllegalStateException if set of type definitions from module is null
97 private static Map<Module, ModuleContext> allTypeDefinitionsToGenTypes(final Module module, final Map<Module,
98 ModuleContext> genCtx,
99 final TypeProvider typeProvider) {
100 Preconditions.checkArgument(module != null, "Module reference cannot be NULL.");
101 Preconditions.checkArgument(module.getName() != null, "Module name cannot be NULL.");
102 final DataNodeIterator it = new DataNodeIterator(module);
103 final List<TypeDefinition<?>> typeDefinitions = it.allTypedefs();
104 Preconditions.checkState(typeDefinitions != null, "Type Definitions for module «module.name» cannot be NULL.");
106 typeDefinitions.stream().filter(Objects::nonNull).forEach(typedef -> {
107 final Type type = ((TypeProviderImpl) typeProvider).generatedTypeForExtendedDefinitionType(typedef,
110 final ModuleContext ctx = genCtx.get(module);
111 ctx.addTypedefType(typedef.getPath(), type);
112 ctx.addTypeToSchema(type, typedef);
118 private static Map<Module, ModuleContext> actionsAndRPCMethodsToGenType(final Module module, Map<Module,
119 ModuleContext> genCtx, final SchemaContext schemaContext, final boolean verboseClassComments,
120 final Map<String, Map<String,
121 GeneratedTypeBuilder>>
122 genTypeBuilders, final
123 TypeProvider typeProvider) {
125 genCtx = RpcActionGenHelper.rpcMethodsToGenType(module, genCtx, schemaContext, verboseClassComments,
126 genTypeBuilders, typeProvider);
127 genCtx = RpcActionGenHelper.actionMethodsToGenType(module, genCtx, schemaContext, verboseClassComments,
128 genTypeBuilders, typeProvider);
134 * Converts all <b>identities</b> of the module to the list of
135 * <code>Type</code> objects.
137 * @param module module from which is obtained set of all identity objects to
139 * @param schemaContext schema context only used as input parameter for method
140 * {@link GenHelperUtil#identityToGenType(Module, String, IdentitySchemaNode, SchemaContext,Map, boolean)}
141 * @param genCtx generated context
142 * @return returns generated context
144 private static Map<Module, ModuleContext> allIdentitiesToGenTypes(final Module module,
145 final SchemaContext schemaContext, Map<Module,
146 ModuleContext> genCtx, boolean verboseClassComments,
147 final Map<String, Map<String,
148 GeneratedTypeBuilder>> genTypeBuilders,
149 final TypeProvider typeProvider) {
151 final Set<IdentitySchemaNode> schemaIdentities = module.getIdentities();
152 final String basePackageName = BindingMapping.getRootPackageName(module);
154 if (schemaIdentities != null && !schemaIdentities.isEmpty()) {
155 for (final IdentitySchemaNode identity : schemaIdentities) {
156 GenHelperUtil.identityToGenType(module, basePackageName, identity, schemaContext, genCtx,
157 verboseClassComments);
165 * Converts all <b>notifications</b> of the module to the list of
166 * <code>Type</code> objects. In addition are to this list added containers
167 * and lists which are part of this notification.
169 * @param module module from which is obtained set of all notification objects
170 * to iterate over them
171 * @throws IllegalArgumentException <ul>
172 * <li>if the module equals null</li>
173 * <li>if the name of module equals null</li>
175 * @throws IllegalStateException if set of notifications from module is null
177 private static Map<Module, ModuleContext> notificationsToGenType(final Module module, final Map<Module,
178 ModuleContext> genCtx,
179 final SchemaContext schemaContext, final
180 Map<String, Map<String, GeneratedTypeBuilder>>
182 final boolean verboseClassComments, final
183 TypeProvider typeProvider) {
184 checkArgument(module != null, "Module reference cannot be NULL.");
185 checkArgument(module.getName() != null, "Module name cannot be NULL.");
186 final Set<NotificationDefinition> notifications = module.getNotifications();
187 if (notifications.isEmpty()) {
191 final GeneratedTypeBuilder listenerInterface = moduleTypeBuilder(module, "Listener", verboseClassComments,
193 listenerInterface.addImplementsType(NOTIFICATION_LISTENER);
194 final String basePackageName = BindingMapping.getRootPackageName(module);
196 for (final NotificationDefinition notification : notifications) {
197 if (notification != null) {
198 resolveNotification(listenerInterface, null, basePackageName, notification, module, schemaContext,
199 verboseClassComments, genTypeBuilders, typeProvider, genCtx);
200 processUsesImplements(notification, module, schemaContext, genCtx, BindingNamespaceType.Notification);
204 //YANG 1.1 allows notifications be tied to containers and lists
205 final Collection<DataSchemaNode> potentials = module.getChildNodes();
206 Set<NotificationDefinition> tiedNotifications = null;
208 for (final DataSchemaNode potential : potentials) {
209 if (potential instanceof NotificationNodeContainer) {
210 tiedNotifications = ((NotificationNodeContainer) potential)
212 for (final NotificationDefinition tiedNotification : tiedNotifications) {
213 if (tiedNotification != null) {
214 resolveNotification(listenerInterface, potential.getQName().getLocalName(), basePackageName,
215 tiedNotification, module, schemaContext, verboseClassComments, genTypeBuilders,
216 typeProvider, genCtx);
217 processUsesImplements(tiedNotification, module, schemaContext, genCtx, BindingNamespaceType
224 if (verboseClassComments) {
225 if (tiedNotifications != null) {
226 YangSourceDefinition.of(module,
227 ImmutableSet.<NotificationDefinition>builder().addAll(notifications).addAll(tiedNotifications)
228 .build()).ifPresent(listenerInterface::setYangSourceDefinition);
230 YangSourceDefinition.of(module, notifications).ifPresent(listenerInterface::setYangSourceDefinition);
232 listenerInterface.addComment(TypeComments.javadoc(
233 "Interface for receiving the following YANG notifications defined in module <b>" + module.getName()
237 genCtx.get(module).addTopLevelNodeType(listenerInterface);