import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import org.opendaylight.mdsal.binding.javav2.generator.impl.txt.yangTemplateForModule;
import org.opendaylight.mdsal.binding.javav2.generator.impl.txt.yangTemplateForNode;
+import org.opendaylight.mdsal.binding.javav2.generator.impl.txt.yangTemplateForNodes;
import org.opendaylight.mdsal.binding.javav2.generator.impl.util.YangTextTemplate;
import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider;
import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifier;
return replaceAllIllegalChars(sb);
}
+ static String createDescription(final Set<? extends SchemaNode> schemaNodes, final String moduleName, final
+ boolean verboseClassComments) {
+ final StringBuilder sb = new StringBuilder();
+
+ if (!isNullOrEmpty(schemaNodes)) {
+ final SchemaNode node = schemaNodes.iterator().next();
+
+ if (node instanceof RpcDefinition) {
+ sb.append("Interface for implementing the following YANG RPCs defined in module <b>" + moduleName + "</b>");
+ } else if (node instanceof NotificationDefinition) {
+ sb.append("Interface for receiving the following YANG notifications defined in module <b>" + moduleName + "</b>");
+ }
+ }
+ sb.append(NEW_LINE);
+
+ if (verboseClassComments) {
+ sb.append("<pre>");
+ sb.append(NEW_LINE);
+ sb.append(encodeAngleBrackets(yangTemplateForNodes.render(schemaNodes).body()));
+ sb.append("</pre>");
+ sb.append(NEW_LINE);
+ }
+
+ return replaceAllIllegalChars(sb);
+ }
+
+ private static boolean isNullOrEmpty(final Collection<?> list) {
+ return list == null || list.isEmpty();
+ }
+
/**
* Returns first unique name for the augment generated type builder. The
* generated type builder name for augment consists from name of augmented
import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.resolveInnerEnumFromTypeDefinition;
import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.resolveListKeyTOBuilder;
import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.computeDefaultSUID;
+import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.encodeAngleBrackets;
import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil.packageNameForGeneratedType;
+import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes.NOTIFICATION;
import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
import com.google.common.annotations.Beta;
import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider;
import org.opendaylight.mdsal.binding.javav2.generator.util.BindingGeneratorUtil;
import org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes;
+import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifier;
+import org.opendaylight.mdsal.binding.javav2.generator.util.NonJavaCharsConverter;
import org.opendaylight.mdsal.binding.javav2.generator.util.Types;
import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl;
import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedTypeBuilderImpl;
import org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeProviderImpl;
+import org.opendaylight.mdsal.binding.javav2.model.api.AccessModifier;
import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedTransferObject;
import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedType;
import org.opendaylight.mdsal.binding.javav2.model.api.Restrictions;
import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
* @throws IllegalArgumentException
* if <code>module</code> is null
*/
- private static GeneratedTypeBuilder moduleTypeBuilder(final Module module, final String postfix, final boolean
+ static GeneratedTypeBuilder moduleTypeBuilder(final Module module, final String postfix, final boolean
verboseClassComments) {
Preconditions.checkArgument(module != null, "Module reference cannot be NULL.");
final String packageName = BindingMapping.getRootPackageName(module);
* @param schemaContext schema context
* @return generated type builder <code>schemaNode</code>
*/
- private static GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode
+ static GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode
schemaNode, final Type parent, final Module module, final Map<Module, ModuleContext> genCtx,
final SchemaContext schemaContext, final boolean verboseClassComments, final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders) {
return it;
}
+ static GeneratedTypeBuilder resolveNotification(final GeneratedTypeBuilder listenerInterface, String
+ parentName, final String basePackageName, final NotificationDefinition notification, final Module module,
+ final SchemaContext schemaContext, final boolean verboseClassComments, Map<String, Map<String, GeneratedTypeBuilder>>
+ genTypeBuilders, TypeProvider typeProvider, Map<Module, ModuleContext> genCtx) {
+
+ processUsesAugments(schemaContext, notification, module, genCtx, genTypeBuilders,
+ verboseClassComments, typeProvider);
+
+ final GeneratedTypeBuilder notificationInterface = addDefaultInterfaceDefinition
+ (basePackageName, notification, null, module, genCtx, schemaContext,
+ verboseClassComments, genTypeBuilders);
+ annotateDeprecatedIfNecessary(notification.getStatus(), notificationInterface);
+ notificationInterface.addImplementsType(NOTIFICATION);
+ genCtx.get(module).addChildNodeType(notification, notificationInterface);
+
+ // Notification object
+ resolveDataSchemaNodes(module, basePackageName, notificationInterface,
+ notificationInterface, notification.getChildNodes(), genCtx, schemaContext,
+ verboseClassComments, genTypeBuilders, typeProvider);
+
+ //in case of tied notification, incorporate parent's localName
+ final StringBuilder sb = new StringBuilder("on_");
+ if (parentName != null) {
+ sb.append(parentName).append('_');
+ }
+ sb.append(notificationInterface.getName());
+
+ listenerInterface.addMethod(NonJavaCharsConverter.convertIdentifier(sb.toString(), JavaIdentifier.METHOD))
+ .setAccessModifier(AccessModifier.PUBLIC).addParameter(notificationInterface, "notification")
+ .setComment(encodeAngleBrackets(notification.getDescription())).setReturnType(Types.VOID);
+ return listenerInterface;
+ }
+
/**
* Returns reference to generated type builder for specified
* <code>schemaNode</code> with <code>packageName</code>.
}
return genType;
}
-
}
package org.opendaylight.mdsal.binding.javav2.generator.impl;
+import static com.google.common.base.Preconditions.checkArgument;
+import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.createDescription;
+import static org.opendaylight.mdsal.binding.javav2.generator.impl.GenHelperUtil.moduleTypeBuilder;
+import static org.opendaylight.mdsal.binding.javav2.generator.impl.GenHelperUtil.resolveNotification;
+import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes.NOTIFICATION_LISTENER;
+
import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.opendaylight.mdsal.binding.javav2.generator.spi.TypeProvider;
import org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeProviderImpl;
import org.opendaylight.mdsal.binding.javav2.model.api.Type;
import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilder;
import org.opendaylight.mdsal.binding.javav2.util.BindingMapping;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
+import org.opendaylight.yangtools.yang.model.api.NotificationNodeContainer;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
import org.opendaylight.yangtools.yang.model.util.DataNodeIterator;
genCtx.put(module, new ModuleContext());
genCtx = allTypeDefinitionsToGenTypes(module, genCtx, typeProvider);
+ genCtx = notificationsToGenType(module, genCtx, schemaContext, genTypeBuilders, verboseClassComments, typeProvider);
- //TODO: call generate for other entities (groupings, rpcs, identities, notifications)
+ //TODO: call generate for other entities (groupings, rpcs, actions, identities)
if (!module.getChildNodes().isEmpty()) {
final GeneratedTypeBuilder moduleType = GenHelperUtil.moduleToDataType(module, genCtx, verboseClassComments);
* if set of type definitions from module is null
*/
private static Map<Module, ModuleContext> allTypeDefinitionsToGenTypes(final Module module, Map<Module, ModuleContext> genCtx,
- TypeProvider typeProvider) {
+ TypeProvider typeProvider) {
Preconditions.checkArgument(module != null, "Module reference cannot be NULL.");
Preconditions.checkArgument(module.getName() != null, "Module name cannot be NULL.");
final DataNodeIterator it = new DataNodeIterator(module);
});
return genCtx;
}
+
+ /**
+ * Converts all <b>notifications</b> of the module to the list of
+ * <code>Type</code> objects. In addition are to this list added containers
+ * and lists which are part of this notification.
+ *
+ * @param module
+ * module from which is obtained set of all notification objects
+ * to iterate over them
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if the module equals null</li>
+ * <li>if the name of module equals null</li>
+ * </ul>
+ * @throws IllegalStateException
+ * if set of notifications from module is null
+ */
+ private static Map<Module, ModuleContext> notificationsToGenType(final Module module, Map<Module, ModuleContext> genCtx,
+ final SchemaContext schemaContext, Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders,
+ final boolean verboseClassComments, TypeProvider typeProvider) {
+ checkArgument(module != null, "Module reference cannot be NULL.");
+ checkArgument(module.getName() != null, "Module name cannot be NULL.");
+ final Set<NotificationDefinition> notifications = module.getNotifications();
+ if (notifications.isEmpty()) {
+ return genCtx;
+ }
+
+ final GeneratedTypeBuilder listenerInterface = moduleTypeBuilder(module, "Listener", verboseClassComments);
+ listenerInterface.addImplementsType(NOTIFICATION_LISTENER);
+ final String basePackageName = BindingMapping.getRootPackageName(module);
+
+ for (final NotificationDefinition notification : notifications) {
+ if (notification != null) {
+ resolveNotification(listenerInterface, null, basePackageName, notification, module, schemaContext,
+ verboseClassComments, genTypeBuilders, typeProvider, genCtx);
+ }
+ }
+
+ //YANG 1.1 allows notifications be tied to containers and lists
+ final Collection<DataSchemaNode> potentials = module.getChildNodes();
+
+ for (final DataSchemaNode potential : potentials) {
+ if (potential instanceof NotificationNodeContainer) {
+ final Set<NotificationDefinition> tiedNotifications = ((NotificationNodeContainer) potential)
+ .getNotifications();
+ for (final NotificationDefinition tiedNotification: tiedNotifications) {
+ if (tiedNotification != null) {
+ resolveNotification(listenerInterface, potential.getQName().getLocalName(), basePackageName,
+ tiedNotification, module, schemaContext, verboseClassComments, genTypeBuilders,
+ typeProvider, genCtx);
+ notifications.add(tiedNotification);
+ }
+ }
+ }
+ }
+
+ listenerInterface.setDescription(createDescription(notifications, module.getName(), verboseClassComments));
+
+ genCtx.get(module).addTopLevelNodeType(listenerInterface);
+
+ return genCtx;
+ }
}