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;
21 import java.util.Collection;
22 import java.util.List;
25 import org.opendaylight.mdsal.binding.javav2.generator.context.ModuleContext;
26 import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider;
27 import org.opendaylight.mdsal.binding.javav2.generator.util.TypeComments;
28 import org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeProviderImpl;
29 import org.opendaylight.mdsal.binding.javav2.model.api.Type;
30 import org.opendaylight.mdsal.binding.javav2.model.api.YangSourceDefinition;
31 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilder;
32 import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingNamespaceType;
33 import org.opendaylight.mdsal.binding.javav2.util.BindingMapping;
34 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
35 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
36 import org.opendaylight.yangtools.yang.model.api.Module;
37 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
38 import org.opendaylight.yangtools.yang.model.api.NotificationNodeContainer;
39 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
40 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
41 import org.opendaylight.yangtools.yang.model.util.DataNodeIterator;
44 final class ModuleToGenType {
46 private ModuleToGenType() {
47 throw new UnsupportedOperationException("Utility class");
50 static Map<Module, ModuleContext> generate(final Module module, final Map<String, Map<String, GeneratedTypeBuilder>>
51 genTypeBuilders, final SchemaContext schemaContext, final TypeProvider typeProvider, Map<Module,
52 ModuleContext> genCtx, final boolean verboseClassComments) {
54 genCtx.put(module, new ModuleContext());
55 genCtx = allTypeDefinitionsToGenTypes(module, genCtx, typeProvider);
56 genCtx = groupingsToGenTypes(module, module.getGroupings(), genCtx, schemaContext, verboseClassComments,
57 genTypeBuilders, typeProvider);
58 genCtx = allIdentitiesToGenTypes(module, schemaContext, genCtx, verboseClassComments, genTypeBuilders, typeProvider);
60 if (!module.getChildNodes().isEmpty()) {
61 final GeneratedTypeBuilder moduleType = GenHelperUtil.moduleToDataType(module, genCtx, verboseClassComments);
62 genCtx.get(module).addModuleNode(moduleType);
63 final String basePackageName = BindingMapping.getRootPackageName(module);
64 GenHelperUtil.resolveDataSchemaNodes(module, basePackageName, moduleType, moduleType, module
65 .getChildNodes(), genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider,
66 BindingNamespaceType.Data);
67 processUsesImplements(module, module, schemaContext, genCtx, BindingNamespaceType.Data);
70 genCtx = notificationsToGenType(module, genCtx, schemaContext, genTypeBuilders, verboseClassComments, typeProvider);
72 //after potential parent data schema nodes
73 genCtx = actionsAndRPCMethodsToGenType(module, genCtx, schemaContext, verboseClassComments,
74 genTypeBuilders, typeProvider);
80 * Converts all extended type definitions of module to the list of
81 * <code>Type</code> objects.
84 * module from which is obtained set of type definitions
85 * @throws IllegalArgumentException
87 * <li>if module is null</li>
88 * <li>if name of module is null</li>
90 * @throws IllegalStateException
91 * if set of type definitions from module is null
93 private static Map<Module, ModuleContext> allTypeDefinitionsToGenTypes(final Module module, final Map<Module, ModuleContext> genCtx,
94 final TypeProvider typeProvider) {
95 Preconditions.checkArgument(module != null, "Module reference cannot be NULL.");
96 Preconditions.checkArgument(module.getName() != null, "Module name cannot be NULL.");
97 final DataNodeIterator it = new DataNodeIterator(module);
98 final List<TypeDefinition<?>> typeDefinitions = it.allTypedefs();
99 Preconditions.checkState(typeDefinitions != null, "Type Definitions for module «module.name» cannot be NULL.");
101 typeDefinitions.stream().filter(typedef -> typedef != null).forEach(typedef -> {
102 final Type type = ((TypeProviderImpl) typeProvider).generatedTypeForExtendedDefinitionType(typedef,
105 final ModuleContext ctx = genCtx.get(module);
106 ctx.addTypedefType(typedef.getPath(), type);
107 ctx.addTypeToSchema(type, typedef);
113 private static Map<Module, ModuleContext> actionsAndRPCMethodsToGenType(final Module module, Map<Module,
114 ModuleContext> genCtx, final SchemaContext schemaContext, final boolean verboseClassComments,
115 final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final TypeProvider typeProvider) {
117 genCtx = RpcActionGenHelper.rpcMethodsToGenType(module, genCtx, schemaContext, verboseClassComments,
118 genTypeBuilders, typeProvider);
119 genCtx = RpcActionGenHelper.actionMethodsToGenType(module, genCtx, schemaContext, verboseClassComments,
120 genTypeBuilders, typeProvider);
126 * Converts all <b>identities</b> of the module to the list of
127 * <code>Type</code> objects.
130 * module from which is obtained set of all identity objects to
132 * @param schemaContext
133 * schema context only used as input parameter for method
134 * {@link GenHelperUtil#identityToGenType(Module, String, IdentitySchemaNode, SchemaContext, Map, boolean)}
135 * @param genCtx generated context
136 * @return returns generated context
139 private static Map<Module, ModuleContext> allIdentitiesToGenTypes(final Module module,
140 final SchemaContext schemaContext, Map<Module, ModuleContext> genCtx, boolean verboseClassComments,
141 final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final TypeProvider typeProvider) {
143 final Set<IdentitySchemaNode> schemaIdentities = module.getIdentities();
144 final String basePackageName = BindingMapping.getRootPackageName(module);
146 if (schemaIdentities != null && !schemaIdentities.isEmpty()) {
147 for (final IdentitySchemaNode identity : schemaIdentities) {
148 GenHelperUtil.identityToGenType(module, basePackageName, identity, schemaContext, genCtx,
149 verboseClassComments);
157 * Converts all <b>notifications</b> of the module to the list of
158 * <code>Type</code> objects. In addition are to this list added containers
159 * and lists which are part of this notification.
162 * module from which is obtained set of all notification objects
163 * to iterate over them
164 * @throws IllegalArgumentException
166 * <li>if the module equals null</li>
167 * <li>if the name of module equals null</li>
169 * @throws IllegalStateException
170 * if set of notifications from module is null
172 private static Map<Module, ModuleContext> notificationsToGenType(final Module module, final Map<Module, ModuleContext> genCtx,
173 final SchemaContext schemaContext, final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders,
174 final boolean verboseClassComments, final TypeProvider typeProvider) {
175 checkArgument(module != null, "Module reference cannot be NULL.");
176 checkArgument(module.getName() != null, "Module name cannot be NULL.");
177 final Set<NotificationDefinition> notifications = module.getNotifications();
178 if (notifications.isEmpty()) {
182 final GeneratedTypeBuilder listenerInterface = moduleTypeBuilder(module, "Listener", verboseClassComments,
184 listenerInterface.addImplementsType(NOTIFICATION_LISTENER);
185 final String basePackageName = BindingMapping.getRootPackageName(module);
187 for (final NotificationDefinition notification : notifications) {
188 if (notification != null) {
189 resolveNotification(listenerInterface, null, basePackageName, notification, module, schemaContext,
190 verboseClassComments, genTypeBuilders, typeProvider, genCtx);
191 processUsesImplements(notification, module, schemaContext, genCtx, BindingNamespaceType.Data);
195 //YANG 1.1 allows notifications be tied to containers and lists
196 final Collection<DataSchemaNode> potentials = module.getChildNodes();
197 Set<NotificationDefinition> tiedNotifications = null;
199 for (final DataSchemaNode potential : potentials) {
200 if (potential instanceof NotificationNodeContainer) {
201 tiedNotifications = ((NotificationNodeContainer) potential)
203 for (final NotificationDefinition tiedNotification: tiedNotifications) {
204 if (tiedNotification != null) {
205 resolveNotification(listenerInterface, potential.getQName().getLocalName(), basePackageName,
206 tiedNotification, module, schemaContext, verboseClassComments, genTypeBuilders,
207 typeProvider, genCtx);
208 processUsesImplements(tiedNotification, module, schemaContext, genCtx, BindingNamespaceType.Data);
214 if (verboseClassComments) {
215 if (tiedNotifications != null) {
216 YangSourceDefinition.of(module,
217 ImmutableSet.<NotificationDefinition>builder().addAll(notifications).addAll(tiedNotifications)
218 .build()).ifPresent(listenerInterface::setYangSourceDefinition);
220 YangSourceDefinition.of(module, notifications).ifPresent(listenerInterface::setYangSourceDefinition);
222 listenerInterface.addComment(TypeComments.javadoc(
223 "Interface for receiving the following YANG notifications defined in module <b>" + module.getName()
227 genCtx.get(module).addTopLevelNodeType(listenerInterface);