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.AuxiliaryGenUtils.createDescription;
13 import static org.opendaylight.mdsal.binding.javav2.generator.impl.GenHelperUtil.moduleTypeBuilder;
14 import static org.opendaylight.mdsal.binding.javav2.generator.impl.GenHelperUtil.resolveNotification;
15 import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes.NOTIFICATION_LISTENER;
17 import com.google.common.annotations.Beta;
18 import com.google.common.base.Preconditions;
19 import java.util.Collection;
20 import java.util.List;
23 import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider;
24 import org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeProviderImpl;
25 import org.opendaylight.mdsal.binding.javav2.model.api.Type;
26 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilder;
27 import org.opendaylight.mdsal.binding.javav2.util.BindingMapping;
28 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
29 import org.opendaylight.yangtools.yang.model.api.Module;
30 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
31 import org.opendaylight.yangtools.yang.model.api.NotificationNodeContainer;
32 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
33 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
34 import org.opendaylight.yangtools.yang.model.util.DataNodeIterator;
37 final class ModuleToGenType {
39 private ModuleToGenType() {
40 throw new UnsupportedOperationException("Utility class");
43 static Map<Module, ModuleContext> generate(final Module module, Map<String, Map<String, GeneratedTypeBuilder>>
44 genTypeBuilders, final SchemaContext schemaContext, TypeProvider typeProvider, Map<Module,
45 ModuleContext> genCtx, final boolean verboseClassComments) {
47 genCtx.put(module, new ModuleContext());
48 genCtx = allTypeDefinitionsToGenTypes(module, genCtx, typeProvider);
49 genCtx = actionsAndRPCMethodsToGenType(module, genCtx, schemaContext, verboseClassComments,
50 genTypeBuilders, typeProvider);
51 genCtx = notificationsToGenType(module, genCtx, schemaContext, genTypeBuilders, verboseClassComments, typeProvider);
53 //TODO: call generate for other entities (groupings, identities)
55 if (!module.getChildNodes().isEmpty()) {
56 final GeneratedTypeBuilder moduleType = GenHelperUtil.moduleToDataType(module, genCtx, verboseClassComments);
57 genCtx.get(module).addModuleNode(moduleType);
58 final String basePackageName = BindingMapping.getRootPackageName(module);
59 GenHelperUtil.resolveDataSchemaNodes(module, basePackageName, moduleType, moduleType, module
60 .getChildNodes(), genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider);
67 * Converts all extended type definitions of module to the list of
68 * <code>Type</code> objects.
71 * module from which is obtained set of type definitions
72 * @throws IllegalArgumentException
74 * <li>if module is null</li>
75 * <li>if name of module is null</li>
77 * @throws IllegalStateException
78 * if set of type definitions from module is null
80 private static Map<Module, ModuleContext> allTypeDefinitionsToGenTypes(final Module module, Map<Module, ModuleContext> genCtx,
81 TypeProvider typeProvider) {
82 Preconditions.checkArgument(module != null, "Module reference cannot be NULL.");
83 Preconditions.checkArgument(module.getName() != null, "Module name cannot be NULL.");
84 final DataNodeIterator it = new DataNodeIterator(module);
85 final List<TypeDefinition<?>> typeDefinitions = it.allTypedefs();
86 Preconditions.checkState(typeDefinitions != null, "Type Definitions for module «module.name» cannot be NULL.");
88 typeDefinitions.stream().filter(typedef -> typedef != null).forEach(typedef -> {
89 final Type type = ((TypeProviderImpl) typeProvider).generatedTypeForExtendedDefinitionType(typedef,
92 final ModuleContext ctx = genCtx.get(module);
93 ctx.addTypedefType(typedef.getPath(), type);
94 ctx.addTypeToSchema(type, typedef);
100 private static Map<Module, ModuleContext> actionsAndRPCMethodsToGenType(final Module module, Map<Module,
101 ModuleContext> genCtx, final SchemaContext schemaContext, final boolean verboseClassComments,
102 Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, TypeProvider typeProvider) {
104 genCtx = RpcActionGenHelper.rpcMethodsToGenType(module, genCtx, schemaContext, verboseClassComments,
105 genTypeBuilders, typeProvider);
106 genCtx = RpcActionGenHelper.actionMethodsToGenType(module, genCtx, schemaContext, verboseClassComments,
107 genTypeBuilders, typeProvider);
113 * Converts all <b>notifications</b> of the module to the list of
114 * <code>Type</code> objects. In addition are to this list added containers
115 * and lists which are part of this notification.
118 * module from which is obtained set of all notification objects
119 * to iterate over them
120 * @throws IllegalArgumentException
122 * <li>if the module equals null</li>
123 * <li>if the name of module equals null</li>
125 * @throws IllegalStateException
126 * if set of notifications from module is null
128 private static Map<Module, ModuleContext> notificationsToGenType(final Module module, Map<Module, ModuleContext> genCtx,
129 final SchemaContext schemaContext, Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders,
130 final boolean verboseClassComments, TypeProvider typeProvider) {
131 checkArgument(module != null, "Module reference cannot be NULL.");
132 checkArgument(module.getName() != null, "Module name cannot be NULL.");
133 final Set<NotificationDefinition> notifications = module.getNotifications();
134 if (notifications.isEmpty()) {
138 final GeneratedTypeBuilder listenerInterface = moduleTypeBuilder(module, "Listener", verboseClassComments);
139 listenerInterface.addImplementsType(NOTIFICATION_LISTENER);
140 final String basePackageName = BindingMapping.getRootPackageName(module);
142 for (final NotificationDefinition notification : notifications) {
143 if (notification != null) {
144 resolveNotification(listenerInterface, null, basePackageName, notification, module, schemaContext,
145 verboseClassComments, genTypeBuilders, typeProvider, genCtx);
149 //YANG 1.1 allows notifications be tied to containers and lists
150 final Collection<DataSchemaNode> potentials = module.getChildNodes();
152 for (final DataSchemaNode potential : potentials) {
153 if (potential instanceof NotificationNodeContainer) {
154 final Set<NotificationDefinition> tiedNotifications = ((NotificationNodeContainer) potential)
156 for (final NotificationDefinition tiedNotification: tiedNotifications) {
157 if (tiedNotification != null) {
158 resolveNotification(listenerInterface, potential.getQName().getLocalName(), basePackageName,
159 tiedNotification, module, schemaContext, verboseClassComments, genTypeBuilders,
160 typeProvider, genCtx);
161 notifications.add(tiedNotification);
167 listenerInterface.setDescription(createDescription(notifications, module.getName(), verboseClassComments));
169 genCtx.get(module).addTopLevelNodeType(listenerInterface);