--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.sal.binding.generator.impl;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.computeDefaultSUID;
+import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.moduleNamespaceToPackageName;
+import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.packageNameForGeneratedType;
+import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.parseToValidParamName;
+import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.DATA_OBJECT;
+import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.DATA_ROOT;
+import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.IDENTIFIABLE;
+import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.IDENTIFIER;
+import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.NOTIFICATION;
+import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.augmentable;
+import static org.opendaylight.yangtools.binding.generator.util.Types.BOOLEAN;
+import static org.opendaylight.yangtools.binding.generator.util.Types.FUTURE;
+import static org.opendaylight.yangtools.binding.generator.util.Types.VOID;
+import static org.opendaylight.yangtools.binding.generator.util.Types.typeForClass;
+import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode;
+import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findNodeInSchemaContext;
+import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findOriginal;
+import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil;
+import org.opendaylight.yangtools.binding.generator.util.BindingTypes;
+import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl;
+import org.opendaylight.yangtools.binding.generator.util.Types;
+import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl;
+import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
+import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTypeBuilderImpl;
+import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
+import org.opendaylight.yangtools.sal.binding.generator.spi.TypeProvider;
+import org.opendaylight.yangtools.sal.binding.model.api.AccessModifier;
+import org.opendaylight.yangtools.sal.binding.model.api.Constant;
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject;
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType;
+import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType;
+import org.opendaylight.yangtools.sal.binding.model.api.Restrictions;
+import org.opendaylight.yangtools.sal.binding.model.api.Type;
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.AnnotationTypeBuilder;
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.EnumBuilder;
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedPropertyBuilder;
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTOBuilder;
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder;
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilderBase;
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.MethodSignatureBuilder;
+import org.opendaylight.yangtools.sal.binding.yang.types.GroupingDefinitionDependencySort;
+import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl;
+import org.opendaylight.yangtools.yang.binding.BaseIdentity;
+import org.opendaylight.yangtools.yang.binding.BindingMapping;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+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.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.UsesNode;
+import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.DataNodeIterator;
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
+import org.opendaylight.yangtools.yang.model.util.UnionType;
+import org.opendaylight.yangtools.yang.parser.builder.util.Comparators;
+import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BindingGeneratorImpl implements BindingGenerator {
+ private static final Logger LOG = LoggerFactory.getLogger(BindingGeneratorImpl.class);
+
+ private final Map<Module, ModuleContext> genCtx = new HashMap<>();
+
+ /**
+ * Outer key represents the package name. Outer value represents map of all
+ * builders in the same package. Inner key represents the schema node name
+ * (in JAVA class/interface name format). Inner value represents instance of
+ * builder for schema node specified in key part.
+ */
+ private Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders;
+
+ /**
+ * Provide methods for converting YANG types to JAVA types.
+ */
+ private TypeProvider typeProvider;
+
+ /**
+ * Holds reference to schema context to resolve data of augmented element
+ * when creating augmentation builder
+ */
+ private SchemaContext schemaContext;
+
+ /**
+ * Constant with the concrete name of namespace.
+ */
+ private final static String YANG_EXT_NAMESPACE = "urn:opendaylight:yang:extension:yang-ext";
+
+ /**
+ * Constant with the concrete name of identifier.
+ */
+ private final static String AUGMENT_IDENTIFIER_NAME = "augment-identifier";
+
+ /**
+ * Resolves generated types from <code>context</code> schema nodes of all
+ * modules.
+ *
+ * Generated types are created for modules, groupings, types, containers,
+ * lists, choices, augments, rpcs, notification, identities.
+ *
+ * @param context
+ * schema context which contains data about all schema nodes
+ * saved in modules
+ * @return list of types (usually <code>GeneratedType</code>
+ * <code>GeneratedTransferObject</code>which are generated from
+ * <code>context</code> data.
+ * @throws IllegalArgumentException
+ * if arg <code>context</code> is null
+ * @throws IllegalStateException
+ * if <code>context</code> contain no modules
+ */
+ @Override
+ public List<Type> generateTypes(SchemaContext context) {
+ checkArgument(context != null, "Schema Context reference cannot be NULL.");
+ checkState(context.getModules() != null, "Schema Context does not contain defined modules.");
+ schemaContext = context;
+ typeProvider = new TypeProviderImpl(context);
+ final Set<Module> modules = context.getModules();
+ return generateTypes(context, modules);
+ }
+
+ /**
+ * Resolves generated types from <code>context</code> schema nodes only for
+ * modules specified in <code>modules</code>
+ *
+ * Generated types are created for modules, groupings, types, containers,
+ * lists, choices, augments, rpcs, notification, identities.
+ *
+ * @param context
+ * schema context which contains data about all schema nodes
+ * saved in modules
+ * @param modules
+ * set of modules for which schema nodes should be generated
+ * types
+ * @return list of types (usually <code>GeneratedType</code> or
+ * <code>GeneratedTransferObject</code>) which:
+ * <ul>
+ * <li>are generated from <code>context</code> schema nodes and</li>
+ * <li>are also part of some of the module in <code>modules</code>
+ * set</li>.
+ * </ul>
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if arg <code>context</code> is null or</li>
+ * <li>if arg <code>modules</code> is null</li>
+ * </ul>
+ * @throws IllegalStateException
+ * if <code>context</code> contain no modules
+ */
+ @Override
+ public List<Type> generateTypes(SchemaContext context, Set<Module> modules) {
+ checkArgument(context != null, "Schema Context reference cannot be NULL.");
+ checkState(context.getModules() != null, "Schema Context does not contain defined modules.");
+ checkArgument(modules != null, "Set of Modules cannot be NULL.");
+
+ schemaContext = context;
+ typeProvider = new TypeProviderImpl(context);
+ Module[] modulesArray = new Module[context.getModules().size()];
+ context.getModules().toArray(modulesArray);
+ final List<Module> contextModules = ModuleDependencySort.sort(modulesArray);
+ genTypeBuilders = new HashMap<>();
+
+ for (Module contextModule : contextModules) {
+ moduleToGenTypes(contextModule, context);
+ }
+ for (Module contextModule : contextModules) {
+ allAugmentsToGenTypes(contextModule);
+ }
+
+ final List<Type> filteredGenTypes = new ArrayList<>();
+ for (Module m : modules) {
+ final ModuleContext ctx = checkNotNull(genCtx.get(m), "Module context not found for module %s", m);
+ filteredGenTypes.addAll(ctx.getGeneratedTypes());
+ final Set<Type> additionalTypes = ((TypeProviderImpl) typeProvider).getAdditionalTypes().get(m);
+ if (additionalTypes != null) {
+ filteredGenTypes.addAll(additionalTypes);
+ }
+ }
+
+ return filteredGenTypes;
+ }
+
+ private void moduleToGenTypes(Module m, SchemaContext context) {
+ genCtx.put(m, new ModuleContext());
+ allTypeDefinitionsToGenTypes(m);
+ groupingsToGenTypes(m, m.getGroupings());
+ rpcMethodsToGenType(m);
+ allIdentitiesToGenTypes(m, context);
+ notificationsToGenType(m);
+
+ if (!m.getChildNodes().isEmpty()) {
+ final GeneratedTypeBuilder moduleType = moduleToDataType(m);
+ genCtx.get(m).addModuleNode(moduleType);
+ final String basePackageName = moduleNamespaceToPackageName(m);
+ resolveDataSchemaNodes(m, basePackageName, moduleType, moduleType, m.getChildNodes());
+ }
+ }
+
+ /**
+ * Converts all extended type definitions of module to the list of
+ * <code>Type</code> objects.
+ *
+ * @param module
+ * module from which is obtained set of type definitions
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if module is null</li>
+ * <li>if name of module is null</li>
+ * </ul>
+ * @throws IllegalStateException
+ * if set of type definitions from module is null
+ */
+ private void allTypeDefinitionsToGenTypes(Module module) {
+ checkArgument(module != null, "Module reference cannot be NULL.");
+ checkArgument(module.getName() != null, "Module name cannot be NULL.");
+ final DataNodeIterator it = new DataNodeIterator(module);
+ final List<TypeDefinition<?>> typeDefinitions = it.allTypedefs();
+ checkState(typeDefinitions != null, "Type Definitions for module «module.name» cannot be NULL.");
+
+ for (TypeDefinition<?> typedef : typeDefinitions) {
+ if (typedef != null) {
+ final Type type = ((TypeProviderImpl) typeProvider).generatedTypeForExtendedDefinitionType(typedef,
+ typedef);
+ if (type != null) {
+ genCtx.get(module).addTypedefType(typedef.getPath(), type);
+ }
+ }
+ }
+ }
+
+ private GeneratedTypeBuilder processDataSchemaNode(Module module, String basePackageName,
+ GeneratedTypeBuilder childOf, DataSchemaNode node) {
+ if (node.isAugmenting() || node.isAddedByUses()) {
+ return null;
+ }
+ final String packageName = packageNameForGeneratedType(basePackageName, node.getPath());
+ final GeneratedTypeBuilder genType = addDefaultInterfaceDefinition(packageName, node, childOf);
+ genType.addComment(node.getDescription());
+ if (node instanceof DataNodeContainer) {
+ genCtx.get(module).addChildNodeType(node.getPath(), genType);
+ groupingsToGenTypes(module, ((DataNodeContainer) node).getGroupings());
+ processUsesAugments((DataNodeContainer) node, module);
+ }
+ return genType;
+ }
+
+ private void containerToGenType(Module module, String basePackageName, GeneratedTypeBuilder parent,
+ GeneratedTypeBuilder childOf, ContainerSchemaNode node) {
+ final GeneratedTypeBuilder genType = processDataSchemaNode(module, basePackageName, childOf, node);
+ if (genType != null) {
+ constructGetter(parent, node.getQName().getLocalName(), node.getDescription(), genType);
+ resolveDataSchemaNodes(module, basePackageName, genType, genType, node.getChildNodes());
+ }
+ }
+
+ private void listToGenType(Module module, String basePackageName, GeneratedTypeBuilder parent,
+ GeneratedTypeBuilder childOf, ListSchemaNode node) {
+ final GeneratedTypeBuilder genType = processDataSchemaNode(module, basePackageName, childOf, node);
+ if (genType != null) {
+ constructGetter(parent, node.getQName().getLocalName(), node.getDescription(), Types.listTypeFor(genType));
+
+ final List<String> listKeys = listKeys(node);
+ final String packageName = packageNameForGeneratedType(basePackageName, node.getPath());
+ final GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, node);
+ if (genTOBuilder != null) {
+ final Type identifierMarker = Types.parameterizedTypeFor(IDENTIFIER, genType);
+ final Type identifiableMarker = Types.parameterizedTypeFor(IDENTIFIABLE, genTOBuilder);
+ genTOBuilder.addImplementsType(identifierMarker);
+ genType.addImplementsType(identifiableMarker);
+ }
+
+ for (DataSchemaNode schemaNode : node.getChildNodes()) {
+ if (!schemaNode.isAugmenting()) {
+ addSchemaNodeToListBuilders(basePackageName, schemaNode, genType, genTOBuilder, listKeys, module);
+ }
+ }
+
+ // serialVersionUID
+ if (genTOBuilder != null) {
+ final GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("serialVersionUID");
+ prop.setValue(Long.toString(computeDefaultSUID(genTOBuilder)));
+ genTOBuilder.setSUID(prop);
+ }
+
+ typeBuildersToGenTypes(module, genType, genTOBuilder);
+ }
+ }
+
+ private void processUsesAugments(DataNodeContainer node, Module module) {
+ final String basePackageName = moduleNamespaceToPackageName(module);
+ for (UsesNode usesNode : node.getUses()) {
+ for (AugmentationSchema augment : usesNode.getAugmentations()) {
+ usesAugmentationToGenTypes(basePackageName, augment, module, usesNode, node);
+ processUsesAugments(augment, module);
+ }
+ }
+ }
+
+ /**
+ * Converts all <b>augmentation</b> of the module to the list
+ * <code>Type</code> objects.
+ *
+ * @param module
+ * module from which is obtained list of all augmentation objects
+ * to iterate over them
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if the module is null</li>
+ * <li>if the name of module is null</li>
+ * </ul>
+ * @throws IllegalStateException
+ * if set of augmentations from module is null
+ */
+ private void allAugmentsToGenTypes(Module module) {
+ checkArgument(module != null, "Module reference cannot be NULL.");
+ checkArgument(module.getName() != null, "Module name cannot be NULL.");
+ checkState(module.getAugmentations() != null, "Augmentations Set cannot be NULL.");
+
+ final String basePackageName = moduleNamespaceToPackageName(module);
+ final List<AugmentationSchema> augmentations = resolveAugmentations(module);
+ for (AugmentationSchema augment : augmentations) {
+ augmentationToGenTypes(basePackageName, augment, module);
+ }
+ }
+
+ /**
+ * Returns list of <code>AugmentationSchema</code> objects. The objects are
+ * sorted according to the length of their target path from the shortest to
+ * the longest.
+ *
+ * @param module
+ * module from which is obtained list of all augmentation objects
+ * @return list of sorted <code>AugmentationSchema</code> objects obtained
+ * from <code>module</code>
+ * @throws IllegalArgumentException
+ * if module is null
+ * @throws IllegalStateException
+ * if set of module augmentations is null
+ */
+ private List<AugmentationSchema> resolveAugmentations(Module module) {
+ checkArgument(module != null, "Module reference cannot be NULL.");
+ checkState(module.getAugmentations() != null, "Augmentations Set cannot be NULL.");
+
+ final Set<AugmentationSchema> augmentations = module.getAugmentations();
+ List<AugmentationSchema> sortedAugmentations = new ArrayList<>(augmentations);
+ Collections.sort(sortedAugmentations, Comparators.AUGMENT_COMP);
+
+ return sortedAugmentations;
+ }
+
+ /**
+ * Create GeneratedTypeBuilder object from module argument.
+ *
+ * @param module
+ * Module object from which builder will be created
+ * @return <code>GeneratedTypeBuilder</code> which is internal
+ * representation of the module
+ * @throws IllegalArgumentException
+ * if module is null
+ */
+ private GeneratedTypeBuilder moduleToDataType(Module module) {
+ checkArgument(module != null, "Module reference cannot be NULL.");
+
+ final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(module, "Data");
+ addImplementedInterfaceFromUses(module, moduleDataTypeBuilder);
+ moduleDataTypeBuilder.addImplementsType(DATA_ROOT);
+ moduleDataTypeBuilder.addComment(module.getDescription());
+ return moduleDataTypeBuilder;
+ }
+
+ /**
+ * Converts all <b>rpcs</b> inputs and outputs substatements of the module
+ * to the list of <code>Type</code> objects. In addition are to containers
+ * and lists which belong to input or output also part of returning list.
+ *
+ * @param module
+ * module from which is obtained set of all rpc objects to
+ * iterate over them
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if the module is null</li>
+ * <li>if the name of module is null</li>
+ * </ul>
+ * @throws IllegalStateException
+ * if set of rpcs from module is null
+ */
+ private void rpcMethodsToGenType(Module module) {
+ checkArgument(module != null, "Module reference cannot be NULL.");
+ checkArgument(module.getName() != null, "Module name cannot be NULL.");
+ final Set<RpcDefinition> rpcDefinitions = module.getRpcs();
+ checkState(rpcDefinitions != null, "Set of rpcs from module " + module.getName() + " cannot be NULL.");
+ if (rpcDefinitions.isEmpty()) {
+ return;
+ }
+
+ final String basePackageName = moduleNamespaceToPackageName(module);
+ final GeneratedTypeBuilder interfaceBuilder = moduleTypeBuilder(module, "Service");
+ interfaceBuilder.addImplementsType(Types.typeForClass(RpcService.class));
+ for (RpcDefinition rpc : rpcDefinitions) {
+ if (rpc != null) {
+ final String rpcName = BindingMapping.getClassName(rpc.getQName());
+ final String rpcMethodName = parseToValidParamName(rpcName);
+ final String rpcComment = rpc.getDescription();
+ final MethodSignatureBuilder method = interfaceBuilder.addMethod(rpcMethodName);
+ final ContainerSchemaNode input = rpc.getInput();
+ final ContainerSchemaNode output = rpc.getOutput();
+
+ if (input != null) {
+ final GeneratedTypeBuilder inType = addRawInterfaceDefinition(basePackageName, input, rpcName);
+ addImplementedInterfaceFromUses(input, inType);
+ inType.addImplementsType(DATA_OBJECT);
+ inType.addImplementsType(augmentable(inType));
+ resolveDataSchemaNodes(module, basePackageName, inType, inType, input.getChildNodes());
+ genCtx.get(module).addChildNodeType(input.getPath(), inType);
+ final GeneratedType inTypeInstance = inType.toInstance();
+ method.addParameter(inTypeInstance, "input");
+ }
+
+ Type outTypeInstance = VOID;
+ if (output != null) {
+ final GeneratedTypeBuilder outType = addRawInterfaceDefinition(basePackageName, output, rpcName);
+ addImplementedInterfaceFromUses(output, outType);
+ outType.addImplementsType(DATA_OBJECT);
+ outType.addImplementsType(augmentable(outType));
+ resolveDataSchemaNodes(module, basePackageName, outType, outType, output.getChildNodes());
+ genCtx.get(module).addChildNodeType(output.getPath(), outType);
+ outTypeInstance = outType.toInstance();
+ }
+
+ final Type rpcRes = Types.parameterizedTypeFor(Types.typeForClass(RpcResult.class), outTypeInstance);
+ method.setComment(rpcComment);
+ method.setReturnType(Types.parameterizedTypeFor(FUTURE, rpcRes));
+ }
+ }
+
+ genCtx.get(module).addTopLevelNodeType(interfaceBuilder);
+ }
+
+ /**
+ * 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 void notificationsToGenType(Module module) {
+ checkArgument(module != null, "Module reference cannot be NULL.");
+ checkArgument(module.getName() != null, "Module name cannot be NULL.");
+ final Set<NotificationDefinition> notifications = module.getNotifications();
+ checkState(notifications != null, "Set of notification from module " + module.getName() + " cannot be NULL.");
+ if (notifications.isEmpty()) {
+ return;
+ }
+
+ final GeneratedTypeBuilder listenerInterface = moduleTypeBuilder(module, "Listener");
+ listenerInterface.addImplementsType(BindingTypes.NOTIFICATION_LISTENER);
+ final String basePackageName = moduleNamespaceToPackageName(module);
+
+ for (NotificationDefinition notification : notifications) {
+ if (notification != null) {
+ processUsesAugments(notification, module);
+
+ final GeneratedTypeBuilder notificationInterface = addDefaultInterfaceDefinition(basePackageName,
+ notification, BindingTypes.DATA_OBJECT);
+ notificationInterface.addImplementsType(NOTIFICATION);
+ genCtx.get(module).addChildNodeType(notification.getPath(), notificationInterface);
+
+ // Notification object
+ resolveDataSchemaNodes(module, basePackageName, notificationInterface, notificationInterface,
+ notification.getChildNodes());
+
+ listenerInterface.addMethod("on" + notificationInterface.getName())
+ .setAccessModifier(AccessModifier.PUBLIC).addParameter(notificationInterface, "notification")
+ .setComment(notification.getDescription()).setReturnType(Types.VOID);
+ }
+ }
+
+ genCtx.get(module).addTopLevelNodeType(listenerInterface);
+ }
+
+ /**
+ * Converts all <b>identities</b> of the module to the list of
+ * <code>Type</code> objects.
+ *
+ * @param module
+ * module from which is obtained set of all identity objects to
+ * iterate over them
+ * @param context
+ * schema context only used as input parameter for method
+ * {@link identityToGenType}
+ *
+ */
+ private void allIdentitiesToGenTypes(Module module, SchemaContext context) {
+ final Set<IdentitySchemaNode> schemaIdentities = module.getIdentities();
+ final String basePackageName = moduleNamespaceToPackageName(module);
+
+ if (schemaIdentities != null && !schemaIdentities.isEmpty()) {
+ for (IdentitySchemaNode identity : schemaIdentities) {
+ identityToGenType(module, basePackageName, identity, context);
+ }
+ }
+ }
+
+ /**
+ * Converts the <b>identity</b> object to GeneratedType. Firstly it is
+ * created transport object builder. If identity contains base identity then
+ * reference to base identity is added to superior identity as its extend.
+ * If identity doesn't contain base identity then only reference to abstract
+ * class {@link org.opendaylight.yangtools.yang.model.api.BaseIdentity
+ * BaseIdentity} is added
+ *
+ * @param module
+ * current module
+ * @param basePackageName
+ * string contains the module package name
+ * @param identity
+ * IdentitySchemaNode which contains data about identity
+ * @param context
+ * SchemaContext which is used to get package and name
+ * information about base of identity
+ *
+ */
+ private void identityToGenType(Module module, String basePackageName, IdentitySchemaNode identity,
+ SchemaContext context) {
+ if (identity == null) {
+ return;
+ }
+ final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath());
+ final String genTypeName = BindingMapping.getClassName(identity.getQName());
+ final GeneratedTOBuilder newType = new GeneratedTOBuilderImpl(packageName, genTypeName);
+ final IdentitySchemaNode baseIdentity = identity.getBaseIdentity();
+ if (baseIdentity == null) {
+ final GeneratedTOBuilderImpl gto = new GeneratedTOBuilderImpl(BaseIdentity.class.getPackage().getName(),
+ BaseIdentity.class.getSimpleName());
+ newType.setExtendsType(gto.toInstance());
+ } else {
+ final Module baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity);
+ final String returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule);
+ final String returnTypeName = BindingMapping.getClassName(baseIdentity.getQName());
+ final GeneratedTransferObject gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName)
+ .toInstance();
+ newType.setExtendsType(gto);
+ }
+ newType.setAbstract(true);
+ newType.addComment(identity.getDescription());
+ final QName qname = identity.getQName();
+ qnameConstant(newType, BindingMapping.QNAME_STATIC_FIELD_NAME, qname);
+
+ genCtx.get(module).addIdentityType(identity.getQName(), newType);
+ }
+
+ private static Constant qnameConstant(GeneratedTypeBuilderBase<?> toBuilder, String constantName, QName name) {
+ StringBuilder sb = new StringBuilder("org.opendaylight.yangtools.yang.common.QName");
+ sb.append(".create(");
+ sb.append('"');
+ sb.append(name.getNamespace());
+ sb.append("\",\"");
+ sb.append(name.getFormattedRevision());
+ sb.append("\",\"");
+ sb.append(name.getLocalName());
+ sb.append("\");");
+
+ return toBuilder.addConstant(typeForClass(QName.class), constantName, sb.toString());
+ }
+
+ /**
+ * Converts all <b>groupings</b> of the module to the list of
+ * <code>Type</code> objects. Firstly are groupings sorted according mutual
+ * dependencies. At least dependent (independent) groupings are in the list
+ * saved at first positions. For every grouping the record is added to map
+ * {@link BindingGeneratorImpl#allGroupings allGroupings}
+ *
+ * @param module
+ * current module
+ * @param collection
+ * of groupings from which types will be generated
+ *
+ */
+ private void groupingsToGenTypes(Module module, Collection<GroupingDefinition> groupings) {
+ final String basePackageName = moduleNamespaceToPackageName(module);
+ final List<GroupingDefinition> groupingsSortedByDependencies = new GroupingDefinitionDependencySort()
+ .sort(groupings);
+ for (GroupingDefinition grouping : groupingsSortedByDependencies) {
+ groupingToGenType(basePackageName, grouping, module);
+ }
+ }
+
+ /**
+ * Converts individual grouping to GeneratedType. Firstly generated type
+ * builder is created and every child node of grouping is resolved to the
+ * method.
+ *
+ * @param basePackageName
+ * string contains the module package name
+ * @param grouping
+ * GroupingDefinition which contains data about grouping
+ * @param module
+ * current module
+ * @return GeneratedType which is generated from grouping (object of type
+ * <code>GroupingDefinition</code>)
+ */
+ private void groupingToGenType(String basePackageName, GroupingDefinition grouping, Module module) {
+ final String packageName = packageNameForGeneratedType(basePackageName, grouping.getPath());
+ final GeneratedTypeBuilder genType = addDefaultInterfaceDefinition(packageName, grouping);
+ genCtx.get(module).addGroupingType(grouping.getPath(), genType);
+ resolveDataSchemaNodes(module, basePackageName, genType, genType, grouping.getChildNodes());
+ groupingsToGenTypes(module, grouping.getGroupings());
+ processUsesAugments(grouping, module);
+ }
+
+ /**
+ * Adds enumeration builder created from <code>enumTypeDef</code> to
+ * <code>typeBuilder</code>.
+ *
+ * Each <code>enumTypeDef</code> item is added to builder with its name and
+ * value.
+ *
+ * @param enumTypeDef
+ * EnumTypeDefinition contains enum data
+ * @param enumName
+ * string contains name which will be assigned to enumeration
+ * builder
+ * @param typeBuilder
+ * GeneratedTypeBuilder to which will be enum builder assigned
+ * @return enumeration builder which contains data from
+ * <code>enumTypeDef</code>
+ */
+ private EnumBuilder resolveInnerEnumFromTypeDefinition(EnumTypeDefinition enumTypeDef, QName enumName,
+ GeneratedTypeBuilder typeBuilder) {
+ if ((enumTypeDef != null) && (typeBuilder != null) && (enumTypeDef.getQName() != null)
+ && (enumTypeDef.getQName().getLocalName() != null)) {
+ final String enumerationName = BindingMapping.getClassName(enumName);
+ final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName);
+ enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef);
+ return enumBuilder;
+ }
+ return null;
+ }
+
+ /**
+ * Generates type builder for <code>module</code>.
+ *
+ * @param module
+ * Module which is source of package name for generated type
+ * builder
+ * @param postfix
+ * string which is added to the module class name representation
+ * as suffix
+ * @return instance of GeneratedTypeBuilder which represents
+ * <code>module</code>.
+ * @throws IllegalArgumentException
+ * if <code>module</code> is null
+ */
+ private GeneratedTypeBuilder moduleTypeBuilder(Module module, String postfix) {
+ checkArgument(module != null, "Module reference cannot be NULL.");
+ final String packageName = moduleNamespaceToPackageName(module);
+ final String moduleName = BindingMapping.getClassName(module.getName()) + postfix;
+ return new GeneratedTypeBuilderImpl(packageName, moduleName);
+ }
+
+ /**
+ * Converts <code>augSchema</code> to list of <code>Type</code> which
+ * contains generated type for augmentation. In addition there are also
+ * generated types for all containers, list and choices which are child of
+ * <code>augSchema</code> node or a generated types for cases are added if
+ * augmented node is choice.
+ *
+ * @param augmentPackageName
+ * string with the name of the package to which the augmentation
+ * belongs
+ * @param augSchema
+ * AugmentationSchema which is contains data about augmentation
+ * (target path, childs...)
+ * @param module
+ * current module
+ * @param parentUsesNode
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if <code>augmentPackageName</code> equals null</li>
+ * <li>if <code>augSchema</code> equals null</li>
+ * </ul>
+ * @throws IllegalStateException
+ * if augment target path is null
+ */
+ private void augmentationToGenTypes(String augmentPackageName, AugmentationSchema augSchema, Module module) {
+ checkArgument(augmentPackageName != null, "Package Name cannot be NULL.");
+ checkArgument(augSchema != null, "Augmentation Schema cannot be NULL.");
+ checkState(augSchema.getTargetPath() != null,
+ "Augmentation Schema does not contain Target Path (Target Path is NULL).");
+
+ processUsesAugments(augSchema, module);
+ final SchemaPath targetPath = augSchema.getTargetPath();
+ SchemaNode targetSchemaNode = null;
+
+ targetSchemaNode = findDataSchemaNode(schemaContext, targetPath);
+ if (targetSchemaNode instanceof DataSchemaNode && ((DataSchemaNode) targetSchemaNode).isAddedByUses()) {
+ targetSchemaNode = findOriginal((DataSchemaNode) targetSchemaNode, schemaContext);
+ if (targetSchemaNode == null) {
+ throw new NullPointerException("Failed to find target node from grouping in augmentation " + augSchema
+ + " in module " + module.getName());
+ }
+ }
+ if (targetSchemaNode == null) {
+ throw new IllegalArgumentException("augment target not found: " + targetPath);
+ }
+
+ GeneratedTypeBuilder targetTypeBuilder = findChildNodeByPath(targetSchemaNode.getPath());
+ if (targetTypeBuilder == null) {
+ targetTypeBuilder = findCaseByPath(targetSchemaNode.getPath());
+ }
+ if (targetTypeBuilder == null) {
+ throw new NullPointerException("Target type not yet generated: " + targetSchemaNode);
+ }
+
+ if (!(targetSchemaNode instanceof ChoiceNode)) {
+ String packageName = augmentPackageName;
+ final Type targetType = new ReferencedTypeImpl(targetTypeBuilder.getPackageName(),
+ targetTypeBuilder.getName());
+ addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName, targetType, augSchema);
+
+ } else {
+ generateTypesFromAugmentedChoiceCases(module, augmentPackageName, targetTypeBuilder.toInstance(),
+ (ChoiceNode) targetSchemaNode, augSchema.getChildNodes());
+ }
+ }
+
+ private void usesAugmentationToGenTypes(String augmentPackageName, AugmentationSchema augSchema, Module module,
+ UsesNode usesNode, DataNodeContainer usesNodeParent) {
+ checkArgument(augmentPackageName != null, "Package Name cannot be NULL.");
+ checkArgument(augSchema != null, "Augmentation Schema cannot be NULL.");
+ checkState(augSchema.getTargetPath() != null,
+ "Augmentation Schema does not contain Target Path (Target Path is NULL).");
+
+ processUsesAugments(augSchema, module);
+ final SchemaPath targetPath = augSchema.getTargetPath();
+ SchemaNode targetSchemaNode = findOriginalTargetFromGrouping(targetPath, usesNode);
+ if (targetSchemaNode == null) {
+ throw new IllegalArgumentException("augment target not found: " + targetPath);
+ }
+
+ GeneratedTypeBuilder targetTypeBuilder = findChildNodeByPath(targetSchemaNode.getPath());
+ if (targetTypeBuilder == null) {
+ targetTypeBuilder = findCaseByPath(targetSchemaNode.getPath());
+ }
+ if (targetTypeBuilder == null) {
+ throw new NullPointerException("Target type not yet generated: " + targetSchemaNode);
+ }
+
+ if (!(targetSchemaNode instanceof ChoiceNode)) {
+ String packageName = augmentPackageName;
+ if (usesNodeParent instanceof SchemaNode) {
+ packageName = packageNameForGeneratedType(augmentPackageName, ((SchemaNode) usesNodeParent).getPath(),
+ true);
+ }
+ addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName, targetTypeBuilder.toInstance(),
+ augSchema);
+ } else {
+ generateTypesFromAugmentedChoiceCases(module, augmentPackageName, targetTypeBuilder.toInstance(),
+ (ChoiceNode) targetSchemaNode, augSchema.getChildNodes());
+ }
+ }
+
+ /**
+ * Convenient method to find node added by uses statement.
+ *
+ * @param targetPath
+ * node path
+ * @param parentUsesNode
+ * parent of uses node
+ * @return node from its original location in grouping
+ */
+ private DataSchemaNode findOriginalTargetFromGrouping(SchemaPath targetPath, UsesNode parentUsesNode) {
+ SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, parentUsesNode.getGroupingPath()
+ .getPathFromRoot());
+ if (!(targetGrouping instanceof GroupingDefinition)) {
+ throw new IllegalArgumentException("Failed to generate code for augment in " + parentUsesNode);
+ }
+
+ GroupingDefinition grouping = (GroupingDefinition) targetGrouping;
+ SchemaNode result = grouping;
+ for (QName node : targetPath.getPathFromRoot()) {
+ // finding by local name is valid, grouping cannot contain nodes
+ // with same name and different namespace
+ if (result instanceof DataNodeContainer) {
+ result = ((DataNodeContainer) result).getDataChildByName(node.getLocalName());
+ } else if (result instanceof ChoiceNode) {
+ result = ((ChoiceNode) result).getCaseNodeByName(node.getLocalName());
+ }
+ }
+ if (result == null) {
+ return null;
+ }
+
+ boolean fromUses = ((DataSchemaNode) result).isAddedByUses();
+ Iterator<UsesNode> groupingUses = grouping.getUses().iterator();
+ while (groupingUses.hasNext() && fromUses) {
+ result = findOriginalTargetFromGrouping(targetPath, groupingUses.next());
+ if (result != null) {
+ fromUses = ((DataSchemaNode) result).isAddedByUses();
+ }
+ }
+ if (fromUses) {
+ // this indicates invalid yang and thus possible bug in code because
+ // invalid yang should be already spotted by parser
+ throw new IllegalStateException("Failed to generate code for augment in " + parentUsesNode);
+ }
+
+ return (DataSchemaNode) result;
+ }
+
+ /**
+ * Returns a generated type builder for an augmentation.
+ *
+ * The name of the type builder is equal to the name of augmented node with
+ * serial number as suffix.
+ *
+ * @param module
+ * current module
+ * @param augmentPackageName
+ * string with contains the package name to which the augment
+ * belongs
+ * @param basePackageName
+ * string with the package name to which the augmented node
+ * belongs
+ * @param targetTypeRef
+ * target type
+ * @param augSchema
+ * augmentation schema which contains data about the child nodes
+ * and uses of augment
+ * @return generated type builder for augment
+ */
+ private GeneratedTypeBuilder addRawAugmentGenTypeDefinition(Module module, String augmentPackageName,
+ String basePackageName, Type targetTypeRef, AugmentationSchema augSchema) {
+ Map<String, GeneratedTypeBuilder> augmentBuilders = genTypeBuilders.get(augmentPackageName);
+ if (augmentBuilders == null) {
+ augmentBuilders = new HashMap<>();
+ genTypeBuilders.put(augmentPackageName, augmentBuilders);
+ }
+ final String augIdentifier = getAugmentIdentifier(augSchema.getUnknownSchemaNodes());
+
+ String augTypeName;
+ if (augIdentifier != null) {
+ augTypeName = BindingMapping.getClassName(augIdentifier);
+ } else {
+ augTypeName = augGenTypeName(augmentBuilders, targetTypeRef.getName());
+ }
+
+ final GeneratedTypeBuilder augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augTypeName);
+
+ augTypeBuilder.addImplementsType(DATA_OBJECT);
+ augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef));
+ addImplementedInterfaceFromUses(augSchema, augTypeBuilder);
+
+ augSchemaNodeToMethods(module, basePackageName, augTypeBuilder, augTypeBuilder, augSchema.getChildNodes());
+ augmentBuilders.put(augTypeName, augTypeBuilder);
+
+ genCtx.get(module).addTargetToAugmentation(targetTypeRef, augTypeBuilder);
+ genCtx.get(module).addAugmentType(augTypeBuilder);
+ genCtx.get(module).addTypeToAugmentation(augTypeBuilder, augSchema);
+ return augTypeBuilder;
+ }
+
+ /**
+ *
+ * @param unknownSchemaNodes
+ * @return nodeParameter of UnknownSchemaNode
+ */
+ private String getAugmentIdentifier(List<UnknownSchemaNode> unknownSchemaNodes) {
+ for (UnknownSchemaNode unknownSchemaNode : unknownSchemaNodes) {
+ final QName nodeType = unknownSchemaNode.getNodeType();
+ if (AUGMENT_IDENTIFIER_NAME.equals(nodeType.getLocalName())
+ && YANG_EXT_NAMESPACE.equals(nodeType.getNamespace().toString())) {
+ return unknownSchemaNode.getNodeParameter();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns first unique name for the augment generated type builder. The
+ * generated type builder name for augment consists from name of augmented
+ * node and serial number of its augmentation.
+ *
+ * @param builders
+ * map of builders which were created in the package to which the
+ * augmentation belongs
+ * @param genTypeName
+ * string with name of augmented node
+ * @return string with unique name for augmentation builder
+ */
+ private String augGenTypeName(Map<String, GeneratedTypeBuilder> builders, String genTypeName) {
+ int index = 1;
+ if (builders != null) {
+ while (builders.containsKey(genTypeName + index)) {
+ index = index + 1;
+ }
+ }
+ return genTypeName + index;
+ }
+
+ /**
+ * Adds the methods to <code>typeBuilder</code> which represent subnodes of
+ * node for which <code>typeBuilder</code> was created.
+ *
+ * The subnodes aren't mapped to the methods if they are part of grouping or
+ * augment (in this case are already part of them).
+ *
+ * @param module
+ * current module
+ * @param basePackageName
+ * string contains the module package name
+ * @param parent
+ * generated type builder which represents any node. The subnodes
+ * of this node are added to the <code>typeBuilder</code> as
+ * methods. The subnode can be of type leaf, leaf-list, list,
+ * container, choice.
+ * @param childOf
+ * parent type
+ * @param schemaNodes
+ * set of data schema nodes which are the children of the node
+ * for which <code>typeBuilder</code> was created
+ * @return generated type builder which is the same builder as input
+ * parameter. The getter methods (representing child nodes) could be
+ * added to it.
+ */
+ private GeneratedTypeBuilder resolveDataSchemaNodes(Module module, String basePackageName,
+ GeneratedTypeBuilder parent, GeneratedTypeBuilder childOf, Set<DataSchemaNode> schemaNodes) {
+ if ((schemaNodes != null) && (parent != null)) {
+ for (DataSchemaNode schemaNode : schemaNodes) {
+ if (!schemaNode.isAugmenting() && !schemaNode.isAddedByUses()) {
+ addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, parent, childOf, module);
+ }
+ }
+ }
+ return parent;
+ }
+
+ /**
+ * Adds the methods to <code>typeBuilder</code> what represents subnodes of
+ * node for which <code>typeBuilder</code> was created.
+ *
+ * @param module
+ * current module
+ * @param basePackageName
+ * string contains the module package name
+ * @param typeBuilder
+ * generated type builder which represents any node. The subnodes
+ * of this node are added to the <code>typeBuilder</code> as
+ * methods. The subnode can be of type leaf, leaf-list, list,
+ * container, choice.
+ * @param childOf
+ * parent type
+ * @param schemaNodes
+ * set of data schema nodes which are the children of the node
+ * for which <code>typeBuilder</code> was created
+ * @return generated type builder which is the same object as the input
+ * parameter <code>typeBuilder</code>. The getter method could be
+ * added to it.
+ */
+ private GeneratedTypeBuilder augSchemaNodeToMethods(Module module, String basePackageName,
+ GeneratedTypeBuilder typeBuilder, GeneratedTypeBuilder childOf, Set<DataSchemaNode> schemaNodes) {
+ if ((schemaNodes != null) && (typeBuilder != null)) {
+ for (DataSchemaNode schemaNode : schemaNodes) {
+ if (!schemaNode.isAugmenting()) {
+ addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder, childOf, module);
+ }
+ }
+ }
+ return typeBuilder;
+ }
+
+ /**
+ * Adds to <code>typeBuilder</code> a method which is derived from
+ * <code>schemaNode</code>.
+ *
+ * @param basePackageName
+ * string with the module package name
+ * @param node
+ * data schema node which is added to <code>typeBuilder</code> as
+ * a method
+ * @param typeBuilder
+ * generated type builder to which is <code>schemaNode</code>
+ * added as a method.
+ * @param childOf
+ * parent type
+ * @param module
+ * current module
+ */
+ private void addSchemaNodeToBuilderAsMethod(String basePackageName, DataSchemaNode node,
+ GeneratedTypeBuilder typeBuilder, GeneratedTypeBuilder childOf, Module module) {
+ if (node != null && typeBuilder != null) {
+ if (node instanceof LeafSchemaNode) {
+ resolveLeafSchemaNodeAsMethod(typeBuilder, (LeafSchemaNode) node);
+ } else if (node instanceof LeafListSchemaNode) {
+ resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) node);
+ } else if (node instanceof ContainerSchemaNode) {
+ containerToGenType(module, basePackageName, typeBuilder, childOf, (ContainerSchemaNode) node);
+ } else if (node instanceof ListSchemaNode) {
+ listToGenType(module, basePackageName, typeBuilder, childOf, (ListSchemaNode) node);
+ } else if (node instanceof ChoiceNode) {
+ choiceToGeneratedType(module, basePackageName, typeBuilder, (ChoiceNode) node);
+ } else {
+ // TODO: anyxml not yet supported
+ LOG.warn("Unable to add schema node {} as method in {}: unsupported type of node.", node.getClass(),
+ typeBuilder.getFullyQualifiedName());
+ }
+ }
+ }
+
+ /**
+ * Converts <code>choiceNode</code> to the list of generated types for
+ * choice and its cases.
+ *
+ * The package names for choice and for its cases are created as
+ * concatenation of the module package (<code>basePackageName</code>) and
+ * names of all parents node.
+ *
+ * @param module
+ * current module
+ * @param basePackageName
+ * string with the module package name
+ * @param parent
+ * parent type
+ * @param choiceNode
+ * choice node which is mapped to generated type. Also child
+ * nodes - cases are mapped to generated types.
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if <code>basePackageName</code> is null</li>
+ * <li>if <code>choiceNode</code> is null</li>
+ * </ul>
+ */
+ private void choiceToGeneratedType(Module module, String basePackageName, GeneratedTypeBuilder parent,
+ ChoiceNode choiceNode) {
+ checkArgument(basePackageName != null, "Base Package Name cannot be NULL.");
+ checkArgument(choiceNode != null, "Choice Schema Node cannot be NULL.");
+
+ if (!choiceNode.isAddedByUses()) {
+ final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath());
+ final GeneratedTypeBuilder choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode);
+ constructGetter(parent, choiceNode.getQName().getLocalName(), choiceNode.getDescription(),
+ choiceTypeBuilder);
+ choiceTypeBuilder.addImplementsType(typeForClass(DataContainer.class));
+ genCtx.get(module).addChildNodeType(choiceNode.getPath(), choiceTypeBuilder);
+ generateTypesFromChoiceCases(module, basePackageName, choiceTypeBuilder.toInstance(), choiceNode);
+ }
+ }
+
+ /**
+ * Converts <code>caseNodes</code> set to list of corresponding generated
+ * types.
+ *
+ * For every <i>case</i> which isn't added through augment or <i>uses</i> is
+ * created generated type builder. The package names for the builder is
+ * created as concatenation of the module package (
+ * <code>basePackageName</code>) and names of all parents nodes of the
+ * concrete <i>case</i>. There is also relation "<i>implements type</i>"
+ * between every case builder and <i>choice</i> type
+ *
+ * @param module
+ * current module
+ * @param basePackageName
+ * string with the module package name
+ * @param refChoiceType
+ * type which represents superior <i>case</i>
+ * @param choiceNode
+ * choice case node which is mapped to generated type
+ * @return list of generated types for <code>caseNodes</code>.
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if <code>basePackageName</code> equals null</li>
+ * <li>if <code>refChoiceType</code> equals null</li>
+ * <li>if <code>caseNodes</code> equals null</li>
+ * </ul>
+ */
+ private void generateTypesFromChoiceCases(Module module, String basePackageName, Type refChoiceType,
+ ChoiceNode choiceNode) {
+ checkArgument(basePackageName != null, "Base Package Name cannot be NULL.");
+ checkArgument(refChoiceType != null, "Referenced Choice Type cannot be NULL.");
+ checkArgument(choiceNode != null, "ChoiceNode cannot be NULL.");
+
+ final Set<ChoiceCaseNode> caseNodes = choiceNode.getCases();
+ if (caseNodes == null) {
+ return;
+ }
+
+ for (ChoiceCaseNode caseNode : caseNodes) {
+ if (caseNode != null && !caseNode.isAddedByUses() && !caseNode.isAugmenting()) {
+ final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath());
+ final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);
+ caseTypeBuilder.addImplementsType(refChoiceType);
+ genCtx.get(module).addCaseType(caseNode.getPath(), caseTypeBuilder);
+ genCtx.get(module).addChoiceToCaseMapping(refChoiceType, caseTypeBuilder, caseNode);
+ final Set<DataSchemaNode> caseChildNodes = caseNode.getChildNodes();
+ if (caseChildNodes != null) {
+ Object parentNode = null;
+ final SchemaPath nodeSp = choiceNode.getPath();
+ parentNode = findDataSchemaNode(schemaContext, nodeSp.getParent());
+
+ SchemaNode parent;
+ if (parentNode instanceof AugmentationSchema) {
+ final AugmentationSchema augSchema = (AugmentationSchema) parentNode;
+ final SchemaPath targetPath = augSchema.getTargetPath();
+ SchemaNode targetSchemaNode = findDataSchemaNode(schemaContext, targetPath);
+ if (targetSchemaNode instanceof DataSchemaNode
+ && ((DataSchemaNode) targetSchemaNode).isAddedByUses()) {
+ targetSchemaNode = findOriginal((DataSchemaNode) targetSchemaNode, schemaContext);
+ if (targetSchemaNode == null) {
+ throw new NullPointerException(
+ "Failed to find target node from grouping for augmentation " + augSchema
+ + " in module " + module.getName());
+ }
+ }
+ parent = targetSchemaNode;
+ } else {
+ final SchemaPath sp = choiceNode.getPath();
+ parent = findDataSchemaNode(schemaContext, sp.getParent());
+ }
+ GeneratedTypeBuilder childOfType = findChildNodeByPath(parent.getPath());
+ resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, childOfType, caseChildNodes);
+ }
+ }
+
+ processUsesAugments(caseNode, module);
+ }
+ }
+
+ /**
+ * Generates list of generated types for all the cases of a choice which are
+ * added to the choice through the augment.
+ *
+ * @param module
+ * current module
+ * @param basePackageName
+ * string contains name of package to which augment belongs. If
+ * an augmented choice is from an other package (pcg1) than an
+ * augmenting choice (pcg2) then case's of the augmenting choice
+ * will belong to pcg2.
+ * @param targetType
+ * Type which represents target choice
+ * @param targetNode
+ * node which represents target choice
+ * @param augmentedNodes
+ * set of choice case nodes for which is checked if are/aren't
+ * added to choice through augmentation
+ * @return list of generated types which represents augmented cases of
+ * choice <code>refChoiceType</code>
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if <code>basePackageName</code> is null</li>
+ * <li>if <code>targetType</code> is null</li>
+ * <li>if <code>augmentedNodes</code> is null</li>
+ * </ul>
+ */
+ private void generateTypesFromAugmentedChoiceCases(Module module, String basePackageName, Type targetType,
+ ChoiceNode targetNode, Set<DataSchemaNode> augmentedNodes) {
+ checkArgument(basePackageName != null, "Base Package Name cannot be NULL.");
+ checkArgument(targetType != null, "Referenced Choice Type cannot be NULL.");
+ checkArgument(augmentedNodes != null, "Set of Choice Case Nodes cannot be NULL.");
+
+ for (DataSchemaNode caseNode : augmentedNodes) {
+ if (caseNode != null) {
+ final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath());
+ final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);
+ caseTypeBuilder.addImplementsType(targetType);
+
+ SchemaNode parent = null;
+ final SchemaPath nodeSp = targetNode.getPath();
+ parent = findDataSchemaNode(schemaContext, nodeSp.getParent());
+
+ GeneratedTypeBuilder childOfType = null;
+ if (parent instanceof Module) {
+ childOfType = genCtx.get((Module) parent).getModuleNode();
+ } else if (parent instanceof ChoiceCaseNode) {
+ childOfType = findCaseByPath(parent.getPath());
+ } else if (parent instanceof DataSchemaNode || parent instanceof NotificationDefinition) {
+ childOfType = findChildNodeByPath(parent.getPath());
+ } else if (parent instanceof GroupingDefinition) {
+ childOfType = findGroupingByPath(parent.getPath());
+ }
+
+ if (childOfType == null) {
+ throw new IllegalArgumentException("Failed to find parent type of choice " + targetNode);
+ }
+
+ ChoiceCaseNode node = null;
+ if (caseNode instanceof ChoiceCaseNode) {
+ node = (ChoiceCaseNode) caseNode;
+ } else {
+ node = targetNode.getCaseNodeByName(caseNode.getQName().getLocalName());
+ }
+ final Set<DataSchemaNode> childNodes = node.getChildNodes();
+ if (childNodes != null) {
+ resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, childOfType, childNodes);
+ }
+ genCtx.get(module).addCaseType(caseNode.getPath(), caseTypeBuilder);
+ genCtx.get(module).addChoiceToCaseMapping(targetType, caseTypeBuilder, node);
+ }
+ }
+ }
+
+ /**
+ * Converts <code>leaf</code> to the getter method which is added to
+ * <code>typeBuilder</code>.
+ *
+ * @param typeBuilder
+ * generated type builder to which is added getter method as
+ * <code>leaf</code> mapping
+ * @param leaf
+ * leaf schema node which is mapped as getter method which is
+ * added to <code>typeBuilder</code>
+ * @return boolean value
+ * <ul>
+ * <li>false - if <code>leaf</code> or <code>typeBuilder</code> are
+ * null</li>
+ * <li>true - in other cases</li>
+ * </ul>
+ */
+ private Type resolveLeafSchemaNodeAsMethod(GeneratedTypeBuilder typeBuilder, LeafSchemaNode leaf) {
+ Type returnType = null;
+ if ((leaf != null) && (typeBuilder != null)) {
+ final String leafName = leaf.getQName().getLocalName();
+ String leafDesc = leaf.getDescription();
+ if (leafDesc == null) {
+ leafDesc = "";
+ }
+
+ final Module parentModule = findParentModule(schemaContext, leaf);
+ if (leafName != null && !leaf.isAddedByUses()) {
+ final TypeDefinition<?> typeDef = leaf.getType();
+
+ GeneratedTOBuilder genTOBuilder;
+ if (typeDef instanceof EnumTypeDefinition) {
+ returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);
+ final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) typeDef;
+ final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leaf.getQName(),
+ typeBuilder);
+
+ if (enumBuilder != null) {
+ returnType = enumBuilder.toInstance(typeBuilder);
+ }
+ ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType);
+ } else if (typeDef instanceof UnionType) {
+ genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf);
+ if (genTOBuilder != null) {
+ returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule);
+ }
+ } else if (typeDef instanceof BitsTypeDefinition) {
+ genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf);
+ if (genTOBuilder != null) {
+ returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName());
+ }
+ } else {
+ final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);
+ returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf, restrictions);
+ }
+ if (returnType != null) {
+ final MethodSignatureBuilder getter = constructGetter(typeBuilder, leafName, leafDesc, returnType);
+ processContextRefExtension(leaf, getter, parentModule);
+ }
+ }
+ }
+ return returnType;
+ }
+
+ private void processContextRefExtension(LeafSchemaNode leaf, MethodSignatureBuilder getter, Module module) {
+ for (UnknownSchemaNode node : leaf.getUnknownSchemaNodes()) {
+ final QName nodeType = node.getNodeType();
+ if ("context-reference".equals(nodeType.getLocalName())) {
+ final String nodeParam = node.getNodeParameter();
+ IdentitySchemaNode identity = null;
+ String basePackageName = null;
+ final Iterable<String> splittedElement = Splitter.on(':').split(nodeParam);
+ final Iterator<String> iterator = splittedElement.iterator();
+ final int length = Iterables.size(splittedElement);
+ if (length == 1) {
+ identity = findIdentityByName(module.getIdentities(), iterator.next());
+ basePackageName = moduleNamespaceToPackageName(module);
+ } else if (length == 2) {
+ String prefix = iterator.next();
+ final Module dependentModule = findModuleFromImports(module.getImports(), prefix);
+ if (dependentModule == null) {
+ throw new IllegalArgumentException("Failed to process context-reference: unknown prefix "
+ + prefix);
+ }
+ identity = findIdentityByName(dependentModule.getIdentities(), iterator.next());
+ basePackageName = moduleNamespaceToPackageName(dependentModule);
+ } else {
+ throw new IllegalArgumentException("Failed to process context-reference: unknown identity "
+ + nodeParam);
+ }
+ if (identity == null) {
+ throw new IllegalArgumentException("Failed to process context-reference: unknown identity "
+ + nodeParam);
+ }
+
+ final Class<RoutingContext> clazz = RoutingContext.class;
+ final AnnotationTypeBuilder rc = getter.addAnnotation(clazz.getPackage().getName(),
+ clazz.getSimpleName());
+ final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath());
+ final String genTypeName = BindingMapping.getClassName(identity.getQName().getLocalName());
+ rc.addParameter("value", packageName + "." + genTypeName + ".class");
+ }
+ }
+ }
+
+ private IdentitySchemaNode findIdentityByName(Set<IdentitySchemaNode> identities, String name) {
+ for (IdentitySchemaNode id : identities) {
+ if (id.getQName().getLocalName().equals(name)) {
+ return id;
+ }
+ }
+ return null;
+ }
+
+ private Module findModuleFromImports(Set<ModuleImport> imports, String prefix) {
+ for (ModuleImport imp : imports) {
+ if (imp.getPrefix().equals(prefix)) {
+ return schemaContext.findModuleByName(imp.getModuleName(), imp.getRevision());
+ }
+ }
+ return null;
+ }
+
+ private boolean resolveLeafSchemaNodeAsProperty(GeneratedTOBuilder toBuilder, LeafSchemaNode leaf,
+ boolean isReadOnly, Module module) {
+ if ((leaf != null) && (toBuilder != null)) {
+ final String leafName = leaf.getQName().getLocalName();
+ String leafDesc = leaf.getDescription();
+ if (leafDesc == null) {
+ leafDesc = "";
+ }
+
+ if (leafName != null) {
+ Type returnType = null;
+ final TypeDefinition<?> typeDef = leaf.getType();
+ if (typeDef instanceof UnionTypeDefinition) {
+ // GeneratedType for this type definition should be already
+ // created
+ QName qname = typeDef.getQName();
+ Module unionModule = null;
+ String prefix = qname.getPrefix();
+ if (prefix == null || prefix.isEmpty() || prefix.equals(module.getPrefix())) {
+ unionModule = module;
+ } else {
+ unionModule = findModuleFromImports(module.getImports(), qname.getPrefix());
+ }
+ final ModuleContext mc = genCtx.get(unionModule);
+ returnType = mc.getTypedefs().get(typeDef.getPath());
+ } else {
+ returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);
+ }
+ return resolveLeafSchemaNodeAsProperty(toBuilder, leaf, returnType, isReadOnly);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Converts <code>leaf</code> schema node to property of generated TO
+ * builder.
+ *
+ * @param toBuilder
+ * generated TO builder to which is <code>leaf</code> added as
+ * property
+ * @param leaf
+ * leaf schema node which is added to <code>toBuilder</code> as
+ * property
+ * @param returnType
+ * property type
+ * @param isReadOnly
+ * boolean value which says if leaf property is|isn't read only
+ * @return boolean value
+ * <ul>
+ * <li>false - if <code>leaf</code>, <code>toBuilder</code> or leaf
+ * name equals null or if leaf is added by <i>uses</i>.</li>
+ * <li>true - other cases</li>
+ * </ul>
+ */
+ private boolean resolveLeafSchemaNodeAsProperty(GeneratedTOBuilder toBuilder, LeafSchemaNode leaf, Type returnType,
+ boolean isReadOnly) {
+ if (returnType == null) {
+ return false;
+ }
+ final String leafName = leaf.getQName().getLocalName();
+ final String leafDesc = leaf.getDescription();
+ final GeneratedPropertyBuilder propBuilder = toBuilder.addProperty(parseToValidParamName(leafName));
+ propBuilder.setReadOnly(isReadOnly);
+ propBuilder.setReturnType(returnType);
+ propBuilder.setComment(leafDesc);
+ toBuilder.addEqualsIdentity(propBuilder);
+ toBuilder.addHashIdentity(propBuilder);
+ toBuilder.addToStringProperty(propBuilder);
+ return true;
+ }
+
+ /**
+ * Converts <code>node</code> leaf list schema node to getter method of
+ * <code>typeBuilder</code>.
+ *
+ * @param typeBuilder
+ * generated type builder to which is <code>node</code> added as
+ * getter method
+ * @param node
+ * leaf list schema node which is added to
+ * <code>typeBuilder</code> as getter method
+ * @return boolean value
+ * <ul>
+ * <li>true - if <code>node</code>, <code>typeBuilder</code>,
+ * nodeName equal null or <code>node</code> is added by <i>uses</i></li>
+ * <li>false - other cases</li>
+ * </ul>
+ */
+ private boolean resolveLeafListSchemaNode(GeneratedTypeBuilder typeBuilder, LeafListSchemaNode node) {
+ if ((node != null) && (typeBuilder != null)) {
+ final QName nodeName = node.getQName();
+
+ if (nodeName != null && !node.isAddedByUses()) {
+ final TypeDefinition<?> typeDef = node.getType();
+ final Module parentModule = findParentModule(schemaContext, node);
+
+ Type returnType = null;
+ if (typeDef instanceof EnumTypeDefinition) {
+ returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node);
+ final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) typeDef;
+ final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, nodeName,
+ typeBuilder);
+ returnType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName());
+ ((TypeProviderImpl) typeProvider).putReferencedType(node.getPath(), returnType);
+ } else if (typeDef instanceof UnionType) {
+ final GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node);
+ if (genTOBuilder != null) {
+ returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule);
+ }
+ } else if (typeDef instanceof BitsTypeDefinition) {
+ final GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node);
+ returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName());
+ } else {
+ final Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);
+ returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node, restrictions);
+ }
+
+ final ParameterizedType listType = Types.listTypeFor(returnType);
+ constructGetter(typeBuilder, nodeName.getLocalName(), node.getDescription(), listType);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private Type createReturnTypeForUnion(GeneratedTOBuilder genTOBuilder, TypeDefinition<?> typeDef,
+ GeneratedTypeBuilder typeBuilder, Module parentModule) {
+ final GeneratedTOBuilderImpl returnType = new GeneratedTOBuilderImpl(genTOBuilder.getPackageName(),
+ genTOBuilder.getName());
+ genTOBuilder.setTypedef(true);
+ genTOBuilder.setIsUnion(true);
+ ((TypeProviderImpl) typeProvider).addUnitsToGenTO(genTOBuilder, typeDef.getUnits());
+
+ // union builder
+ final GeneratedTOBuilder unionBuilder = new GeneratedTOBuilderImpl(typeBuilder.getPackageName(),
+ genTOBuilder.getName() + "Builder");
+ unionBuilder.setIsUnionBuilder(true);
+ final MethodSignatureBuilder method = unionBuilder.addMethod("getDefaultInstance");
+ method.setReturnType(returnType);
+ method.addParameter(Types.STRING, "defaultValue");
+ method.setAccessModifier(AccessModifier.PUBLIC);
+ method.setStatic(true);
+
+ final Set<Type> types = ((TypeProviderImpl) typeProvider).getAdditionalTypes().get(parentModule);
+ if (types == null) {
+ ((TypeProviderImpl) typeProvider).getAdditionalTypes().put(parentModule,
+ Sets.<Type> newHashSet(unionBuilder.toInstance()));
+ } else {
+ types.add(unionBuilder.toInstance());
+ }
+ return returnType.toInstance();
+ }
+
+ private GeneratedTypeBuilder addDefaultInterfaceDefinition(String packageName, SchemaNode schemaNode) {
+ return addDefaultInterfaceDefinition(packageName, schemaNode, null);
+ }
+
+ /**
+ * Instantiates generated type builder with <code>packageName</code> and
+ * <code>schemaNode</code>.
+ *
+ * The new builder always implements
+ * {@link org.opendaylight.yangtools.yang.binding.DataObject DataObject}.<br />
+ * If <code>schemaNode</code> is instance of GroupingDefinition it also
+ * implements {@link org.opendaylight.yangtools.yang.binding.Augmentable
+ * Augmentable}.<br />
+ * If <code>schemaNode</code> is instance of
+ * {@link org.opendaylight.yangtools.yang.model.api.DataNodeContainer
+ * DataNodeContainer} it can also implement nodes which are specified in
+ * <i>uses</i>.
+ *
+ * @param packageName
+ * string with the name of the package to which
+ * <code>schemaNode</code> belongs.
+ * @param schemaNode
+ * schema node for which is created generated type builder
+ * @param parent
+ * parent type (can be null)
+ * @return generated type builder <code>schemaNode</code>
+ */
+ private GeneratedTypeBuilder addDefaultInterfaceDefinition(String packageName, SchemaNode schemaNode, Type parent) {
+ final GeneratedTypeBuilder it = addRawInterfaceDefinition(packageName, schemaNode, "");
+ if (parent == null) {
+ it.addImplementsType(DATA_OBJECT);
+ } else {
+ it.addImplementsType(BindingTypes.childOf(parent));
+ }
+ if (!(schemaNode instanceof GroupingDefinition)) {
+ it.addImplementsType(augmentable(it));
+ }
+
+ if (schemaNode instanceof DataNodeContainer) {
+ addImplementedInterfaceFromUses((DataNodeContainer) schemaNode, it);
+ }
+
+ return it;
+ }
+
+ /**
+ * Wraps the calling of the same overloaded method.
+ *
+ * @param packageName
+ * string with the package name to which returning generated type
+ * builder belongs
+ * @param schemaNode
+ * schema node which provide data about the schema node name
+ * @return generated type builder for <code>schemaNode</code>
+ */
+ private GeneratedTypeBuilder addRawInterfaceDefinition(String packageName, SchemaNode schemaNode) {
+ return addRawInterfaceDefinition(packageName, schemaNode, "");
+ }
+
+ /**
+ * Returns reference to generated type builder for specified
+ * <code>schemaNode</code> with <code>packageName</code>.
+ *
+ * Firstly the generated type builder is searched in
+ * {@link BindingGeneratorImpl#genTypeBuilders genTypeBuilders}. If it isn't
+ * found it is created and added to <code>genTypeBuilders</code>.
+ *
+ * @param packageName
+ * string with the package name to which returning generated type
+ * builder belongs
+ * @param schemaNode
+ * schema node which provide data about the schema node name
+ * @param prefix
+ * return type name prefix
+ * @return generated type builder for <code>schemaNode</code>
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if <code>schemaNode</code> is null</li>
+ * <li>if <code>packageName</code> is null</li>
+ * <li>if QName of schema node is null</li>
+ * <li>if schemaNode name is null</li>
+ * </ul>
+ *
+ */
+ private GeneratedTypeBuilder addRawInterfaceDefinition(String packageName, SchemaNode schemaNode, String prefix) {
+ checkArgument(schemaNode != null, "Data Schema Node cannot be NULL.");
+ checkArgument(packageName != null, "Package Name for Generated Type cannot be NULL.");
+ checkArgument(schemaNode.getQName() != null, "QName for Data Schema Node cannot be NULL.");
+ final String schemaNodeName = schemaNode.getQName().getLocalName();
+ checkArgument(schemaNodeName != null, "Local Name of QName for Data Schema Node cannot be NULL.");
+
+ String genTypeName;
+ if (prefix == null) {
+ genTypeName = BindingMapping.getClassName(schemaNodeName);
+ } else {
+ genTypeName = prefix + BindingMapping.getClassName(schemaNodeName);
+ }
+
+ // FIXME: Validation of name conflict
+ final GeneratedTypeBuilderImpl newType = new GeneratedTypeBuilderImpl(packageName, genTypeName);
+ qnameConstant(newType, BindingMapping.QNAME_STATIC_FIELD_NAME, schemaNode.getQName());
+ newType.addComment(schemaNode.getDescription());
+ if (!genTypeBuilders.containsKey(packageName)) {
+ final Map<String, GeneratedTypeBuilder> builders = new HashMap<>();
+ builders.put(genTypeName, newType);
+ genTypeBuilders.put(packageName, builders);
+ } else {
+ final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders.get(packageName);
+ if (!builders.containsKey(genTypeName)) {
+ builders.put(genTypeName, newType);
+ }
+ }
+ return newType;
+ }
+
+ /**
+ * Creates the name of the getter method name from <code>localName</code>.
+ *
+ * @param localName
+ * string with the name of the getter method
+ * @param returnType
+ * return type
+ * @return string with the name of the getter method for
+ * <code>methodName</code> in JAVA method format
+ */
+ public static String getterMethodName(String localName, Type returnType) {
+ final StringBuilder method = new StringBuilder();
+ if (BOOLEAN.equals(returnType)) {
+ method.append("is");
+ } else {
+ method.append("get");
+ }
+ String name = BindingMapping.toFirstUpper(BindingMapping.getPropertyName(localName));
+ method.append(name);
+ return method.toString();
+ }
+
+ /**
+ * Created a method signature builder as part of
+ * <code>interfaceBuilder</code>.
+ *
+ * The method signature builder is created for the getter method of
+ * <code>schemaNodeName</code>. Also <code>comment</code> and
+ * <code>returnType</code> information are added to the builder.
+ *
+ * @param interfaceBuilder
+ * generated type builder for which the getter method should be
+ * created
+ * @param schemaNodeName
+ * string with schema node name. The name will be the part of the
+ * getter method name.
+ * @param comment
+ * string with comment for the getter method
+ * @param returnType
+ * type which represents the return type of the getter method
+ * @return method signature builder which represents the getter method of
+ * <code>interfaceBuilder</code>
+ */
+ private MethodSignatureBuilder constructGetter(GeneratedTypeBuilder interfaceBuilder, String schemaNodeName,
+ String comment, Type returnType) {
+ final MethodSignatureBuilder getMethod = interfaceBuilder
+ .addMethod(getterMethodName(schemaNodeName, returnType));
+ getMethod.setComment(comment);
+ getMethod.setReturnType(returnType);
+ return getMethod;
+ }
+
+ /**
+ * Adds <code>schemaNode</code> to <code>typeBuilder</code> as getter method
+ * or to <code>genTOBuilder</code> as property.
+ *
+ * @param basePackageName
+ * string contains the module package name
+ * @param schemaNode
+ * data schema node which should be added as getter method to
+ * <code>typeBuilder</code> or as a property to
+ * <code>genTOBuilder</code> if is part of the list key
+ * @param typeBuilder
+ * generated type builder for the list schema node
+ * @param genTOBuilder
+ * generated TO builder for the list keys
+ * @param listKeys
+ * list of string which contains names of the list keys
+ * @param module
+ * current module
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li>if <code>schemaNode</code> equals null</li>
+ * <li>if <code>typeBuilder</code> equals null</li>
+ * </ul>
+ */
+ private void addSchemaNodeToListBuilders(String basePackageName, DataSchemaNode schemaNode,
+ GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder, List<String> listKeys, Module module) {
+ checkArgument(schemaNode != null, "Data Schema Node cannot be NULL.");
+ checkArgument(typeBuilder != null, "Generated Type Builder cannot be NULL.");
+
+ if (schemaNode instanceof LeafSchemaNode) {
+ final LeafSchemaNode leaf = (LeafSchemaNode) schemaNode;
+ final String leafName = leaf.getQName().getLocalName();
+ final Type type = resolveLeafSchemaNodeAsMethod(typeBuilder, leaf);
+ if (listKeys.contains(leafName)) {
+ if (type == null) {
+ resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true, module);
+ } else {
+ resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, type, true);
+ }
+ }
+ } else if (!schemaNode.isAddedByUses()) {
+ if (schemaNode instanceof LeafListSchemaNode) {
+ resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode);
+ } else if (schemaNode instanceof ContainerSchemaNode) {
+ containerToGenType(module, basePackageName, typeBuilder, typeBuilder, (ContainerSchemaNode) schemaNode);
+ } else if (schemaNode instanceof ChoiceNode) {
+ choiceToGeneratedType(module, basePackageName, typeBuilder, (ChoiceNode) schemaNode);
+ } else if (schemaNode instanceof ListSchemaNode) {
+ listToGenType(module, basePackageName, typeBuilder, typeBuilder, (ListSchemaNode) schemaNode);
+ }
+ }
+ }
+
+ private void typeBuildersToGenTypes(Module module, GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder) {
+ checkArgument(typeBuilder != null, "Generated Type Builder cannot be NULL.");
+
+ if (genTOBuilder != null) {
+ GeneratedTransferObject genTO = genTOBuilder.toInstance();
+ constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", genTO);
+ genCtx.get(module).addGeneratedTOBuilder(genTOBuilder);
+ }
+ }
+
+ /**
+ * Selects the names of the list keys from <code>list</code> and returns
+ * them as the list of the strings
+ *
+ * @param list
+ * of string with names of the list keys
+ * @return list of string which represents names of the list keys. If the
+ * <code>list</code> contains no keys then the empty list is
+ * returned.
+ */
+ private List<String> listKeys(final ListSchemaNode list) {
+ final List<String> listKeys = new ArrayList<>();
+
+ List<QName> keyDefinition = list.getKeyDefinition();
+ if (keyDefinition != null) {
+ for (QName keyDef : keyDefinition) {
+ listKeys.add(keyDef.getLocalName());
+ }
+ }
+ return listKeys;
+ }
+
+ /**
+ * Generates for the <code>list</code> which contains any list keys special
+ * generated TO builder.
+ *
+ * @param packageName
+ * string with package name to which the list belongs
+ * @param list
+ * list schema node which is source of data about the list name
+ * @return generated TO builder which represents the keys of the
+ * <code>list</code> or null if <code>list</code> is null or list of
+ * key definitions is null or empty.
+ */
+ private GeneratedTOBuilder resolveListKeyTOBuilder(String packageName, ListSchemaNode list) {
+ GeneratedTOBuilder genTOBuilder = null;
+ if ((list.getKeyDefinition() != null) && (!list.getKeyDefinition().isEmpty())) {
+ final String listName = list.getQName().getLocalName() + "Key";
+ final String genTOName = BindingMapping.getClassName(listName);
+ genTOBuilder = new GeneratedTOBuilderImpl(packageName, genTOName);
+ }
+ return genTOBuilder;
+ }
+
+ /**
+ * Builds generated TO builders for <code>typeDef</code> of type
+ * {@link org.opendaylight.yangtools.yang.model.util.UnionType UnionType} or
+ * {@link org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition
+ * BitsTypeDefinition} which are also added to <code>typeBuilder</code> as
+ * enclosing transfer object.
+ *
+ * If more then one generated TO builder is created for enclosing then all
+ * of the generated TO builders are added to <code>typeBuilder</code> as
+ * enclosing transfer objects.
+ *
+ * @param typeDef
+ * type definition which can be of type <code>UnionType</code> or
+ * <code>BitsTypeDefinition</code>
+ * @param typeBuilder
+ * generated type builder to which is added generated TO created
+ * from <code>typeDef</code>
+ * @param leafName
+ * string with name for generated TO builder
+ * @param leaf
+ * @return generated TO builder for <code>typeDef</code>
+ */
+ private GeneratedTOBuilder addTOToTypeBuilder(TypeDefinition<?> typeDef, GeneratedTypeBuilder typeBuilder,
+ DataSchemaNode leaf) {
+ final String classNameFromLeaf = BindingMapping.getClassName(leaf.getQName());
+ final List<GeneratedTOBuilder> genTOBuilders = new ArrayList<>();
+ final String packageName = typeBuilder.getFullyQualifiedName();
+ if (typeDef instanceof UnionTypeDefinition) {
+ final List<GeneratedTOBuilder> types = ((TypeProviderImpl) typeProvider)
+ .provideGeneratedTOBuildersForUnionTypeDef(packageName, ((UnionTypeDefinition) typeDef),
+ classNameFromLeaf, leaf);
+ genTOBuilders.addAll(types);
+
+ GeneratedTOBuilder resultTOBuilder = null;
+ if (!types.isEmpty()) {
+ resultTOBuilder = types.remove(0);
+ for (GeneratedTOBuilder genTOBuilder : types) {
+ resultTOBuilder.addEnclosingTransferObject(genTOBuilder);
+ }
+ }
+
+ final GeneratedPropertyBuilder genPropBuilder = resultTOBuilder.addProperty("value");
+ genPropBuilder.setReturnType(Types.primitiveType("char[]", null));
+ resultTOBuilder.addEqualsIdentity(genPropBuilder);
+ resultTOBuilder.addHashIdentity(genPropBuilder);
+ resultTOBuilder.addToStringProperty(genPropBuilder);
+
+ } else if (typeDef instanceof BitsTypeDefinition) {
+ genTOBuilders.add((((TypeProviderImpl) typeProvider)).provideGeneratedTOBuilderForBitsTypeDefinition(
+ packageName, typeDef, classNameFromLeaf));
+ }
+ if (genTOBuilders != null && !genTOBuilders.isEmpty()) {
+ for (GeneratedTOBuilder genTOBuilder : genTOBuilders) {
+ typeBuilder.addEnclosingTransferObject(genTOBuilder);
+ }
+ return genTOBuilders.get(0);
+ }
+ return null;
+
+ }
+
+ /**
+ * Adds the implemented types to type builder.
+ *
+ * The method passes through the list of <i>uses</i> in
+ * {@code dataNodeContainer}. For every <i>use</i> is obtained corresponding
+ * generated type from {@link BindingGeneratorImpl#allGroupings
+ * allGroupings} which is added as <i>implements type</i> to
+ * <code>builder</code>
+ *
+ * @param dataNodeContainer
+ * element which contains the list of used YANG groupings
+ * @param builder
+ * builder to which are added implemented types according to
+ * <code>dataNodeContainer</code>
+ * @return generated type builder with all implemented types
+ */
+ private GeneratedTypeBuilder addImplementedInterfaceFromUses(DataNodeContainer dataNodeContainer,
+ GeneratedTypeBuilder builder) {
+ for (UsesNode usesNode : dataNodeContainer.getUses()) {
+ if (usesNode.getGroupingPath() != null) {
+ final GeneratedType genType = findGroupingByPath(usesNode.getGroupingPath()).toInstance();
+ if (genType == null) {
+ throw new IllegalStateException("Grouping " + usesNode.getGroupingPath() + "is not resolved for "
+ + builder.getName());
+ }
+ builder.addImplementsType(genType);
+ builder.addComment(genType.getComment());
+ }
+ }
+ return builder;
+ }
+
+ private GeneratedTypeBuilder findChildNodeByPath(SchemaPath path) {
+ for (ModuleContext ctx : genCtx.values()) {
+ GeneratedTypeBuilder result = ctx.getChildNode(path);
+ if (result != null) {
+ return result;
+ }
+ }
+ return null;
+ }
+
+ private GeneratedTypeBuilder findGroupingByPath(SchemaPath path) {
+ for (ModuleContext ctx : genCtx.values()) {
+ GeneratedTypeBuilder result = ctx.getGrouping(path);
+ if (result != null) {
+ return result;
+ }
+ }
+ return null;
+ }
+
+ private GeneratedTypeBuilder findCaseByPath(SchemaPath path) {
+ for (ModuleContext ctx : genCtx.values()) {
+ GeneratedTypeBuilder result = ctx.getCase(path);
+ if (result != null) {
+ return result;
+ }
+ }
+ return null;
+ }
+
+ public Map<Module, ModuleContext> getModuleContexts() {
+ return genCtx;
+ }
+
+}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.sal.binding.generator.impl;
-
-import static com.google.common.base.Preconditions.*;
-import static extension org.opendaylight.yangtools.binding.generator.util.Types.*;
-import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.*;
-import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.*;
-import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.*;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Iterator
-import java.util.Collection
-import org.opendaylight.yangtools.binding.generator.util.BindingTypes;
-import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl;
-import org.opendaylight.yangtools.binding.generator.util.Types;
-import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
-import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTypeBuilderImpl;
-import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
-import org.opendaylight.yangtools.sal.binding.generator.spi.TypeProvider;
-import org.opendaylight.yangtools.sal.binding.model.api.AccessModifier;
-import org.opendaylight.yangtools.sal.binding.model.api.Type;
-import org.opendaylight.yangtools.sal.binding.model.api.type.builder.EnumBuilder;
-import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTOBuilder;
-import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder;
-import org.opendaylight.yangtools.sal.binding.model.api.type.builder.MethodSignatureBuilder;
-import org.opendaylight.yangtools.sal.binding.yang.types.GroupingDefinitionDependencySort;
-import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl;
-import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
-import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
-import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-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.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
-import org.opendaylight.yangtools.yang.model.util.DataNodeIterator;
-import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
-import org.opendaylight.yangtools.yang.model.util.UnionType;
-import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort
-import org.opendaylight.yangtools.yang.model.util.ExtendedType;
-import org.opendaylight.yangtools.yang.model.api.UsesNode
-import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext
-import org.opendaylight.yangtools.sal.binding.model.api.type.builder.AnnotationTypeBuilder
-import org.opendaylight.yangtools.yang.model.api.ModuleImport
-import org.opendaylight.yangtools.yang.binding.DataContainer
-import org.opendaylight.yangtools.yang.model.api.NotificationDefinition
-import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
-import org.opendaylight.yangtools.sal.binding.model.api.Restrictions
-import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedPropertyBuilder
-import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl
-import org.opendaylight.yangtools.yang.common.QName
-import org.opendaylight.yangtools.yang.binding.BindingMapping
-import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilderBase
-
-import com.google.common.collect.Sets
-import java.util.TreeSet
-import org.opendaylight.yangtools.yang.binding.BaseIdentity
-
-public class BindingGeneratorImpl implements BindingGenerator {
-
- private final Map<Module, ModuleContext> genCtx = new HashMap()
-
- /**
- * Outer key represents the package name. Outer value represents map of
- * all builders in the same package. Inner key represents the schema node
- * name (in JAVA class/interface name format). Inner value represents
- * instance of builder for schema node specified in key part.
- */
- private Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders;
-
- /**
- * Provide methods for converting YANG types to JAVA types.
- */
- private var TypeProvider typeProvider;
-
- /**
- * Holds reference to schema context to resolve data of augmented element
- * when creating augmentation builder
- */
- private var SchemaContext schemaContext;
-
- /**
- * Constant with the concrete name of namespace.
- */
- private val static String YANG_EXT_NAMESPACE = "urn:opendaylight:yang:extension:yang-ext";
-
- /**
- * Constant with the concrete name of identifier.
- */
- private val static String AUGMENT_IDENTIFIER_NAME = "augment-identifier";
-
- /**
- * Resolves generated types from <code>context</code> schema nodes of all
- * modules.
- *
- * Generated types are created for modules, groupings, types, containers,
- * lists, choices, augments, rpcs, notification, identities.
- *
- * @param context
- * schema context which contains data about all schema nodes
- * saved in modules
- * @return list of types (usually <code>GeneratedType</code>
- * <code>GeneratedTransferObject</code>which are generated from
- * <code>context</code> data.
- * @throws IllegalArgumentException
- * if param <code>context</code> is null
- * @throws IllegalStateException
- * if <code>context</code> contain no modules
- */
- override generateTypes(SchemaContext context) {
- checkArgument(context !== null, "Schema Context reference cannot be NULL.");
- checkState(context.modules !== null, "Schema Context does not contain defined modules.");
- schemaContext = context;
- typeProvider = new TypeProviderImpl(context);
- val Set<Module> modules = context.modules;
- return generateTypes(context, modules);
- }
-
- /**
- * Resolves generated types from <code>context</code> schema nodes only for
- * modules specified in <code>modules</code>
- *
- * Generated types are created for modules, groupings, types, containers,
- * lists, choices, augments, rpcs, notification, identities.
- *
- * @param context
- * schema context which contains data about all schema nodes
- * saved in modules
- * @param modules
- * set of modules for which schema nodes should be generated
- * types
- * @return list of types (usually <code>GeneratedType</code> or
- * <code>GeneratedTransferObject</code>) which:
- * <ul>
- * <li>are generated from <code>context</code> schema nodes and</li>
- * <li>are also part of some of the module in <code>modules</code>
- * set</li>.
- * </ul>
- * @throws IllegalArgumentException
- * <ul>
- * <li>if param <code>context</code> is null or</li>
- * <li>if param <code>modules</code> is null</li>
- * </ul>
- * @throws IllegalStateException
- * if <code>context</code> contain no modules
- */
- override generateTypes(SchemaContext context, Set<Module> modules) {
- checkArgument(context !== null, "Schema Context reference cannot be NULL.");
- checkState(context.modules !== null, "Schema Context does not contain defined modules.");
- checkArgument(modules !== null, "Set of Modules cannot be NULL.");
-
- schemaContext = context;
- typeProvider = new TypeProviderImpl(context);
- val contextModules = ModuleDependencySort.sort(context.modules);
- genTypeBuilders = new HashMap();
-
- for (contextModule : contextModules) {
- moduleToGenTypes(contextModule, context);
- }
- for (contextModule : contextModules) {
- allAugmentsToGenTypes(contextModule);
- }
-
- val List<Type> filteredGenTypes = new ArrayList();
- for (Module m : modules) {
- val ctx = checkNotNull(genCtx.get(m), "Module context not found for module %s", m)
- filteredGenTypes.addAll(ctx.generatedTypes);
- val Set<Type> additionalTypes = (typeProvider as TypeProviderImpl).additionalTypes.get(m)
- if (additionalTypes != null) {
- filteredGenTypes.addAll(additionalTypes)
- }
- }
-
- return filteredGenTypes;
- }
-
- private def void moduleToGenTypes(Module m, SchemaContext context) {
- genCtx.put(m, new ModuleContext)
- allTypeDefinitionsToGenTypes(m)
- groupingsToGenTypes(m, m.groupings)
- rpcMethodsToGenType(m)
- allIdentitiesToGenTypes(m, context)
- notificationsToGenType(m)
-
- if (!m.childNodes.isEmpty()) {
- val moduleType = moduleToDataType(m)
- genCtx.get(m).addModuleNode(moduleType)
- val basePackageName = moduleNamespaceToPackageName(m);
- resolveDataSchemaNodes(m, basePackageName, moduleType, moduleType, m.childNodes)
- }
- }
-
- /**
- * Converts all extended type definitions of module to the list of
- * <code>Type</code> objects.
- *
- * @param module
- * module from which is obtained set of type definitions
- * @throws IllegalArgumentException
- * <ul>
- * <li>if module equals null</li>
- * <li>if name of module equals null</li>
- * <li>if type definitions of module equal null</li>
- * </ul>
- *
- */
- private def void allTypeDefinitionsToGenTypes(Module module) {
- checkArgument(module !== null, "Module reference cannot be NULL.");
- checkArgument(module.name !== null, "Module name cannot be NULL.");
- val it = new DataNodeIterator(module);
- val List<TypeDefinition<?>> typeDefinitions = it.allTypedefs;
- checkState(typeDefinitions !== null, '''Type Definitions for module «module.name» cannot be NULL.''');
-
- for (TypeDefinition<?> typedef : typeDefinitions) {
- if (typedef !== null) {
- val type = (typeProvider as TypeProviderImpl).generatedTypeForExtendedDefinitionType(typedef, typedef);
- if (type !== null) {
- genCtx.get(module).addTypedefType(typedef.path, type)
- }
- }
- }
- }
-
- private def GeneratedTypeBuilder processDataSchemaNode(Module module, String basePackageName,
- GeneratedTypeBuilder parent, GeneratedTypeBuilder childOf, DataSchemaNode node) {
- if (node.augmenting || node.addedByUses) {
- return null
- }
- val packageName = packageNameForGeneratedType(basePackageName, node.path)
- val genType = addDefaultInterfaceDefinition(packageName, node, childOf)
- genType.addComment(node.getDescription());
- if (node instanceof DataNodeContainer) {
- genCtx.get(module).addChildNodeType(node.path, genType)
- groupingsToGenTypes(module, (node as DataNodeContainer).groupings)
- processUsesAugments(node as DataNodeContainer, module)
- }
- return genType
- }
-
- private def void containerToGenType(Module module, String basePackageName, GeneratedTypeBuilder parent,
- GeneratedTypeBuilder childOf, ContainerSchemaNode node) {
- val genType = processDataSchemaNode(module, basePackageName, parent, childOf, node)
- if (genType != null) {
- constructGetter(parent, node.QName.localName, node.description, genType)
- resolveDataSchemaNodes(module, basePackageName, genType, genType, node.childNodes)
- }
- }
-
- private def void listToGenType(Module module, String basePackageName, GeneratedTypeBuilder parent,
- GeneratedTypeBuilder childOf, ListSchemaNode node) {
- val genType = processDataSchemaNode(module, basePackageName, parent, childOf, node)
- if (genType != null) {
- constructGetter(parent, node.QName.localName, node.description, Types.listTypeFor(genType))
-
- val List<String> listKeys = listKeys(node);
- val packageName = packageNameForGeneratedType(basePackageName, (node).path)
- val genTOBuilder = resolveListKeyTOBuilder(packageName, node);
- if (genTOBuilder !== null) {
- val identifierMarker = IDENTIFIER.parameterizedTypeFor(genType);
- val identifiableMarker = IDENTIFIABLE.parameterizedTypeFor(genTOBuilder);
- genTOBuilder.addImplementsType(identifierMarker);
- genType.addImplementsType(identifiableMarker);
- }
-
- for (schemaNode : node.childNodes) {
- if (!schemaNode.augmenting) {
- addSchemaNodeToListBuilders(basePackageName, schemaNode, genType, genTOBuilder, listKeys, module);
- }
- }
-
- // serialVersionUID
- if (genTOBuilder !== null) {
- val GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("serialVersionUID");
- prop.setValue(Long.toString(computeDefaultSUID(genTOBuilder)));
- genTOBuilder.setSUID(prop);
- }
-
- typeBuildersToGenTypes(module, genType, genTOBuilder);
- }
- }
-
- private def void processUsesAugments(DataNodeContainer node, Module module) {
- val basePackageName = moduleNamespaceToPackageName(module);
- for (usesNode : node.uses) {
- for (augment : usesNode.augmentations) {
- usesAugmentationToGenTypes(basePackageName, augment, module, usesNode, node);
- processUsesAugments(augment, module);
- }
- }
- }
-
- /**
- * Converts all <b>augmentation</b> of the module to the list
- * <code>Type</code> objects.
- *
- * @param module
- * module from which is obtained list of all augmentation objects
- * to iterate over them
- * @throws IllegalArgumentException
- * <ul>
- * <li>if the module equals null</li>
- * <li>if the name of module equals null</li>
- * <li>if the set of child nodes equals null</li>
- * </ul>
- *
- */
- private def void allAugmentsToGenTypes(Module module) {
- checkArgument(module !== null, "Module reference cannot be NULL.");
- checkArgument(module.name !== null, "Module name cannot be NULL.");
- if (module.childNodes === null) {
- throw new IllegalArgumentException(
- "Reference to Set of Augmentation Definitions in module " + module.name + " cannot be NULL.");
- }
-
- val basePackageName = moduleNamespaceToPackageName(module);
- val List<AugmentationSchema> augmentations = resolveAugmentations(module);
- for (augment : augmentations) {
- augmentationToGenTypes(basePackageName, augment, module);
- }
- }
-
- /**
- * Returns list of <code>AugmentationSchema</code> objects. The objects are
- * sorted according to the length of their target path from the shortest to
- * the longest.
- *
- * @param module
- * module from which is obtained list of all augmentation objects
- * @return list of sorted <code>AugmentationSchema</code> objects obtained
- * from <code>module</code>
- * @throws IllegalArgumentException
- * <ul>
- * <li>if the module equals null</li>
- * <li>if the set of augmentation equals null</li>
- * </ul>
- *
- */
- private def List<AugmentationSchema> resolveAugmentations(Module module) {
- checkArgument(module !== null, "Module reference cannot be NULL.");
- checkState(module.augmentations !== null, "Augmentations Set cannot be NULL.");
-
- val Set<AugmentationSchema> augmentations = module.augmentations;
- var List<AugmentationSchema> sortedAugmentations = getSortedOrNull(augmentations)
- if (sortedAugmentations != null) {
- return sortedAugmentations
- }
- sortedAugmentations = new ArrayList(augmentations);
- Collections.sort(sortedAugmentations,
- [ augSchema1, augSchema2 |
- val Iterator<QName> thisIt = augSchema1.targetPath.getPath().iterator();
- val Iterator<QName> otherIt = augSchema2.getTargetPath().getPath().iterator();
- while (thisIt.hasNext()) {
- if (otherIt.hasNext()) {
- val int comp = thisIt.next().compareTo(otherIt.next());
- if (comp != 0) {
- return comp
- }
- } else {
- return 1
- }
- }
- if (otherIt.hasNext()) {
- return -1
- }
- return 0
- ]);
- return sortedAugmentations;
- }
-
- private def List<AugmentationSchema> getSortedOrNull(Collection<AugmentationSchema> collection) {
- val TreeSet<AugmentationSchema> set = new TreeSet()
- for (e : collection) {
- if (e instanceof Comparable<?>) {
- set.add(e)
- } else {
- return null
- }
- }
- return new ArrayList(set.toArray)
- }
-
- /**
- * Converts whole <b>module</b> to <code>GeneratedType</code> object.
- * Firstly is created the module builder object from which is vally
- * obtained reference to <code>GeneratedType</code> object.
- *
- * @param module
- * module from which are obtained the module name, child nodes,
- * uses and is derived package name
- * @return <code>GeneratedType</code> which is internal representation of
- * the module
- * @throws IllegalArgumentException
- * if the module equals null
- *
- */
- private def GeneratedTypeBuilder moduleToDataType(Module module) {
- checkArgument(module !== null, "Module reference cannot be NULL.");
-
- val moduleDataTypeBuilder = moduleTypeBuilder(module, "Data");
- addImplementedInterfaceFromUses(module, moduleDataTypeBuilder);
- moduleDataTypeBuilder.addImplementsType(DATA_ROOT);
- moduleDataTypeBuilder.addComment(module.getDescription());
- return moduleDataTypeBuilder;
- }
-
- /**
- * Converts all <b>rpcs</b> inputs and outputs substatements of the module
- * to the list of <code>Type</code> objects. In addition are to containers
- * and lists which belong to input or output also part of returning list.
- *
- * @param module
- * module from which is obtained set of all rpc objects to
- * iterate over them
- * @throws IllegalArgumentException
- * <ul>
- * <li>if the module equals null</li>
- * <li>if the name of module equals null</li>
- * <li>if the set of child nodes equals null</li>
- * </ul>
- *
- */
- private def void rpcMethodsToGenType(Module module) {
- checkArgument(module !== null, "Module reference cannot be NULL.");
- checkArgument(module.name !== null, "Module name cannot be NULL.");
- checkArgument(module.childNodes !== null,
- "Reference to Set of RPC Method Definitions in module " + module.name + " cannot be NULL.");
-
- val basePackageName = moduleNamespaceToPackageName(module);
- val Set<RpcDefinition> rpcDefinitions = module.rpcs;
- if (rpcDefinitions.isEmpty()) {
- return;
- }
-
- val interfaceBuilder = moduleTypeBuilder(module, "Service");
- interfaceBuilder.addImplementsType(Types.typeForClass(RpcService));
- for (rpc : rpcDefinitions) {
- if (rpc !== null) {
- val rpcName = BindingMapping.getClassName(rpc.QName);
- val rpcMethodName = parseToValidParamName(rpcName);
- val rpcComment = rpc.getDescription();
- val method = interfaceBuilder.addMethod(rpcMethodName);
-
- val input = rpc.input;
- val output = rpc.output;
-
- if (input !== null) {
- val inType = addRawInterfaceDefinition(basePackageName, input, rpcName);
- addImplementedInterfaceFromUses(input, inType);
- inType.addImplementsType(DATA_OBJECT);
- inType.addImplementsType(augmentable(inType));
- resolveDataSchemaNodes(module, basePackageName, inType, inType, input.childNodes);
- genCtx.get(module).addChildNodeType(input.path, inType)
- val inTypeInstance = inType.toInstance();
- method.addParameter(inTypeInstance, "input");
- }
-
- var Type outTypeInstance = VOID;
- if (output !== null) {
- val outType = addRawInterfaceDefinition(basePackageName, output, rpcName);
- addImplementedInterfaceFromUses(output, outType);
- outType.addImplementsType(DATA_OBJECT);
- outType.addImplementsType(augmentable(outType));
- resolveDataSchemaNodes(module, basePackageName, outType, outType, output.childNodes);
- genCtx.get(module).addChildNodeType(output.path, outType)
- outTypeInstance = outType.toInstance();
- }
-
- val rpcRes = Types.parameterizedTypeFor(Types.typeForClass(RpcResult), outTypeInstance);
- method.setComment(rpcComment);
- method.setReturnType(Types.parameterizedTypeFor(FUTURE, rpcRes));
-
- }
- }
-
- genCtx.get(module).addTopLevelNodeType(interfaceBuilder)
- }
-
- /**
- * 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>
- * <li>if the set of child nodes equals null</li>
- * </ul>
- *
- */
- private def void notificationsToGenType(Module module) {
- checkArgument(module !== null, "Module reference cannot be NULL.");
- checkArgument(module.name !== null, "Module name cannot be NULL.");
-
- if (module.childNodes === null) {
- throw new IllegalArgumentException(
- "Reference to Set of Notification Definitions in module " + module.name + " cannot be NULL.");
- }
- val notifications = module.notifications;
- if(notifications.empty) return;
-
- val listenerInterface = moduleTypeBuilder(module, "Listener");
- listenerInterface.addImplementsType(BindingTypes.NOTIFICATION_LISTENER);
- val basePackageName = moduleNamespaceToPackageName(module);
-
- for (notification : notifications) {
- if (notification !== null) {
- processUsesAugments(notification, module);
-
- val notificationInterface = addDefaultInterfaceDefinition(basePackageName, notification,
- BindingTypes.DATA_OBJECT);
- notificationInterface.addImplementsType(NOTIFICATION);
- genCtx.get(module).addChildNodeType(notification.path, notificationInterface)
-
- // Notification object
- resolveDataSchemaNodes(module, basePackageName, notificationInterface, notificationInterface,
- notification.childNodes);
-
- listenerInterface.addMethod("on" + notificationInterface.name) //
- .setAccessModifier(AccessModifier.PUBLIC).addParameter(notificationInterface, "notification").
- setComment(notification.getDescription()).setReturnType(Types.VOID);
- }
- }
-
- genCtx.get(module).addTopLevelNodeType(listenerInterface)
- }
-
- /**
- * Converts all <b>identities</b> of the module to the list of
- * <code>Type</code> objects.
- *
- * @param module
- * module from which is obtained set of all identity objects to
- * iterate over them
- * @param context
- * schema context only used as input parameter for method
- * {@link identityToGenType}
- *
- */
- private def void allIdentitiesToGenTypes(Module module, SchemaContext context) {
- val Set<IdentitySchemaNode> schemaIdentities = module.identities;
- val basePackageName = moduleNamespaceToPackageName(module);
-
- if (schemaIdentities !== null && !schemaIdentities.isEmpty()) {
- for (identity : schemaIdentities) {
- identityToGenType(module, basePackageName, identity, context);
- }
- }
- }
-
- /**
- * Converts the <b>identity</b> object to GeneratedType. Firstly it is
- * created transport object builder. If identity contains base identity then
- * reference to base identity is added to superior identity as its extend.
- * If identity doesn't contain base identity then only reference to abstract
- * class {@link org.opendaylight.yangtools.yang.model.api.BaseIdentity
- * BaseIdentity} is added
- *
- * @param module current module
- * @param basePackageName
- * string contains the module package name
- * @param identity
- * IdentitySchemaNode which contains data about identity
- * @param context
- * SchemaContext which is used to get package and name
- * information about base of identity
- *
- */
- private def void identityToGenType(Module module, String basePackageName, IdentitySchemaNode identity,
- SchemaContext context) {
- if (identity === null) {
- return;
- }
- val packageName = packageNameForGeneratedType(basePackageName, identity.path);
- val genTypeName = BindingMapping.getClassName(identity.QName);
- val newType = new GeneratedTOBuilderImpl(packageName, genTypeName);
- val baseIdentity = identity.baseIdentity;
- if (baseIdentity === null) {
- val GeneratedTOBuilderImpl gto = new GeneratedTOBuilderImpl(BaseIdentity.package.name,
- BaseIdentity.simpleName);
- newType.setExtendsType(gto.toInstance);
- } else {
- val baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity);
- val returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule);
- val returnTypeName = BindingMapping.getClassName(baseIdentity.QName);
- val gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName).toInstance();
- newType.setExtendsType(gto);
- }
- newType.setAbstract(true);
- newType.addComment(identity.getDescription());
- val qname = identity.QName;
-
- newType.qnameConstant(BindingMapping.QNAME_STATIC_FIELD_NAME,qname);
-
- genCtx.get(module).addIdentityType(identity.QName,newType)
- }
-
- private static def qnameConstant(GeneratedTypeBuilderBase<?> toBuilder, String constantName, QName name) {
- toBuilder.addConstant(QName.typeForClass,constantName,'''
- org.opendaylight.yangtools.yang.common.QName.create("«name.namespace»","«name.formattedRevision»","«name.localName»")
- ''');
- }
-
- /**
- * Converts all <b>groupings</b> of the module to the list of
- * <code>Type</code> objects. Firstly are groupings sorted according mutual
- * dependencies. At least dependent (independent) groupings are in the list
- * saved at first positions. For every grouping the record is added to map
- * {@link BindingGeneratorImpl#allGroupings allGroupings}
- *
- * @param module
- * current module
- * @param collection of groupings from which types will be generated
- *
- */
- private def void groupingsToGenTypes(Module module, Collection<GroupingDefinition> groupings) {
- val basePackageName = moduleNamespaceToPackageName(module);
- val List<GroupingDefinition> groupingsSortedByDependencies = new GroupingDefinitionDependencySort().sort(
- groupings);
- for (grouping : groupingsSortedByDependencies) {
- groupingToGenType(basePackageName, grouping, module);
- }
- }
-
- /**
- * Converts individual grouping to GeneratedType. Firstly generated type
- * builder is created and every child node of grouping is resolved to the
- * method.
- *
- * @param basePackageName
- * string contains the module package name
- * @param grouping
- * GroupingDefinition which contains data about grouping
- * @param module current module
- * @return GeneratedType which is generated from grouping (object of type
- * <code>GroupingDefinition</code>)
- */
- private def void groupingToGenType(String basePackageName, GroupingDefinition grouping, Module module) {
- val packageName = packageNameForGeneratedType(basePackageName, grouping.path);
- val genType = addDefaultInterfaceDefinition(packageName, grouping);
- genCtx.get(module).addGroupingType(grouping.path, genType)
- resolveDataSchemaNodes(module, basePackageName, genType, genType, grouping.childNodes);
- groupingsToGenTypes(module, grouping.groupings);
- processUsesAugments(grouping, module);
- }
-
- /**
- * Tries to find EnumTypeDefinition in <code>typeDefinition</code>. If base
- * type of <code>typeDefinition</code> is of the type ExtendedType then this
- * method is recursively called with this base type.
- *
- * @param typeDefinition
- * TypeDefinition in which should be EnumTypeDefinition found as
- * base type
- * @return EnumTypeDefinition if it is found inside
- * <code>typeDefinition</code> or <code>null</code> in other case
- */
- private def EnumTypeDefinition enumTypeDefFromExtendedType(TypeDefinition<?> typeDefinition) {
- if (typeDefinition !== null) {
- if (typeDefinition.baseType instanceof EnumTypeDefinition) {
- return typeDefinition.baseType as EnumTypeDefinition;
- } else if (typeDefinition.baseType instanceof ExtendedType) {
- return enumTypeDefFromExtendedType(typeDefinition.baseType);
- }
- }
- return null;
- }
-
- /**
- * Adds enumeration builder created from <code>enumTypeDef</code> to
- * <code>typeBuilder</code>.
- *
- * Each <code>enumTypeDef</code> item is added to builder with its name and
- * value.
- *
- * @param enumTypeDef
- * EnumTypeDefinition contains enum data
- * @param enumName
- * string contains name which will be assigned to enumeration
- * builder
- * @param typeBuilder
- * GeneratedTypeBuilder to which will be enum builder assigned
- * @return enumeration builder which contains data from
- * <code>enumTypeDef</code>
- */
- private def EnumBuilder resolveInnerEnumFromTypeDefinition(EnumTypeDefinition enumTypeDef, QName enumName,
- GeneratedTypeBuilder typeBuilder) {
- if ((enumTypeDef !== null) && (typeBuilder !== null) && (enumTypeDef.QName !== null) &&
- (enumTypeDef.QName.localName !== null)) {
- val enumerationName = BindingMapping.getClassName(enumName);
- val enumBuilder = typeBuilder.addEnumeration(enumerationName);
- enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef);
- return enumBuilder;
- }
- return null;
- }
-
- /**
- * Generates type builder for <code>module</code>.
- *
- * @param module
- * Module which is source of package name for generated type
- * builder
- * @param postfix
- * string which is added to the module class name representation
- * as suffix
- * @return instance of GeneratedTypeBuilder which represents
- * <code>module</code>.
- * @throws IllegalArgumentException
- * if <code>module</code> equals null
- */
- private def GeneratedTypeBuilder moduleTypeBuilder(Module module, String postfix) {
- checkArgument(module !== null, "Module reference cannot be NULL.");
- val packageName = moduleNamespaceToPackageName(module);
- val moduleName = BindingMapping.getClassName(module.name) + postfix;
- return new GeneratedTypeBuilderImpl(packageName, moduleName);
- }
-
- /**
- * Converts <code>augSchema</code> to list of <code>Type</code> which
- * contains generated type for augmentation. In addition there are also
- * generated types for all containers, list and choices which are child of
- * <code>augSchema</code> node or a generated types for cases are added if
- * augmented node is choice.
- *
- * @param augmentPackageName
- * string with the name of the package to which the augmentation
- * belongs
- * @param augSchema
- * AugmentationSchema which is contains data about augmentation
- * (target path, childs...)
- * @param module current module
- * @param parentUsesNode parent uses node of this augment (can be null if this augment is not defined under uses statement)
- * @throws IllegalArgumentException
- * <ul>
- * <li>if <code>augmentPackageName</code> equals null</li>
- * <li>if <code>augSchema</code> equals null</li>
- * <li>if target path of <code>augSchema</code> equals null</li>
- * </ul>
- */
- private def void augmentationToGenTypes(String augmentPackageName, AugmentationSchema augSchema, Module module) {
- checkArgument(augmentPackageName !== null, "Package Name cannot be NULL.");
- checkArgument(augSchema !== null, "Augmentation Schema cannot be NULL.");
- checkState(augSchema.targetPath !== null,
- "Augmentation Schema does not contain Target Path (Target Path is NULL).");
-
- processUsesAugments(augSchema, module);
- val targetPath = augSchema.targetPath;
- var SchemaNode targetSchemaNode = null
-
- targetSchemaNode = findDataSchemaNode(schemaContext, targetPath);
- if (targetSchemaNode instanceof DataSchemaNode && (targetSchemaNode as DataSchemaNode).isAddedByUses()) {
- targetSchemaNode = findOriginal(targetSchemaNode as DataSchemaNode, schemaContext);
- if (targetSchemaNode == null) {
- throw new NullPointerException(
- "Failed to find target node from grouping in augmentation " + augSchema + " in module " +
- module.name);
- }
- }
- if (targetSchemaNode == null) {
- throw new IllegalArgumentException("augment target not found: " + targetPath)
- }
-
- var targetTypeBuilder = findChildNodeByPath(targetSchemaNode.path)
- if (targetTypeBuilder === null) {
- targetTypeBuilder = findCaseByPath(targetSchemaNode.path)
- }
- if (targetTypeBuilder === null) {
- throw new NullPointerException("Target type not yet generated: " + targetSchemaNode);
- }
-
- if (!(targetSchemaNode instanceof ChoiceNode)) {
- var packageName = augmentPackageName;
- val targetType = new ReferencedTypeImpl(targetTypeBuilder.packageName,targetTypeBuilder.name);
- addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName,targetType, augSchema);
-
- } else {
- generateTypesFromAugmentedChoiceCases(module, augmentPackageName, targetTypeBuilder.toInstance,
- targetSchemaNode as ChoiceNode, augSchema.childNodes);
- }
- }
-
- private def void usesAugmentationToGenTypes(String augmentPackageName, AugmentationSchema augSchema, Module module,
- UsesNode usesNode, DataNodeContainer usesNodeParent) {
- checkArgument(augmentPackageName !== null, "Package Name cannot be NULL.");
- checkArgument(augSchema !== null, "Augmentation Schema cannot be NULL.");
- checkState(augSchema.targetPath !== null,
- "Augmentation Schema does not contain Target Path (Target Path is NULL).");
-
- processUsesAugments(augSchema, module);
- val targetPath = augSchema.targetPath;
- var SchemaNode targetSchemaNode = null
- targetSchemaNode = findOriginalTargetFromGrouping(targetPath, usesNode);
- if (targetSchemaNode == null) {
- throw new IllegalArgumentException("augment target not found: " + targetPath)
- }
-
- var targetTypeBuilder = findChildNodeByPath(targetSchemaNode.path)
- if (targetTypeBuilder === null) {
- targetTypeBuilder = findCaseByPath(targetSchemaNode.path)
- }
- if (targetTypeBuilder === null) {
- throw new NullPointerException("Target type not yet generated: " + targetSchemaNode);
- }
-
- if (!(targetSchemaNode instanceof ChoiceNode)) {
- var packageName = augmentPackageName;
- if (usesNodeParent instanceof SchemaNode) {
- packageName = packageNameForGeneratedType(augmentPackageName, (usesNodeParent as SchemaNode).path, true)
- }
- addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName,
- targetTypeBuilder.toInstance, augSchema);
- } else {
- generateTypesFromAugmentedChoiceCases(module, augmentPackageName, targetTypeBuilder.toInstance,
- targetSchemaNode as ChoiceNode, augSchema.childNodes);
- }
- }
-
- /**
- * Convenient method to find node added by uses statement.
- */
- private def DataSchemaNode findOriginalTargetFromGrouping(SchemaPath targetPath, UsesNode parentUsesNode) {
- var SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, parentUsesNode.groupingPath.path);
- if (!(targetGrouping instanceof GroupingDefinition)) {
- throw new IllegalArgumentException("Failed to generate code for augment in " + parentUsesNode);
- }
-
- var grouping = targetGrouping as GroupingDefinition;
- var SchemaNode result = grouping;
- val List<QName> path = targetPath.path
- for (node : path) {
- // finding by local name is valid, grouping cannot contain nodes with same name and different namespace
- if (result instanceof DataNodeContainer) {
- result = (result as DataNodeContainer).getDataChildByName(node.localName)
- } else if (result instanceof ChoiceNode) {
- result = (result as ChoiceNode).getCaseNodeByName(node.localName)
- }
- }
- if (result == null) {
- return null;
- }
-
- var boolean fromUses = (result as DataSchemaNode).addedByUses
- var Iterator<UsesNode> groupingUses = grouping.uses.iterator;
- while (groupingUses.hasNext && fromUses) {
- result = findOriginalTargetFromGrouping(targetPath, groupingUses.next);
- if (result != null) {
- fromUses = (result as DataSchemaNode).addedByUses
- }
- }
- if (fromUses) {
- throw new NullPointerException("Failed to generate code for augment in " + parentUsesNode);
- }
-
- return result as DataSchemaNode
- }
-
- /**
- * Returns a generated type builder for an augmentation.
- *
- * The name of the type builder is equal to the name of augmented node with
- * serial number as suffix.
- *
- * @param module current module
- * @param augmentPackageName
- * string with contains the package name to which the augment
- * belongs
- * @param basePackageName
- * string with the package name to which the augmented node
- * belongs
- * @param targetTypeRef
- * target type
- * @param augSchema
- * augmentation schema which contains data about the child nodes
- * and uses of augment
- * @return generated type builder for augment
- */
- private def GeneratedTypeBuilder addRawAugmentGenTypeDefinition(Module module, String augmentPackageName,
- String basePackageName, Type targetTypeRef, AugmentationSchema augSchema) {
- var Map<String, GeneratedTypeBuilder> augmentBuilders = genTypeBuilders.get(augmentPackageName);
- if (augmentBuilders === null) {
- augmentBuilders = new HashMap();
- genTypeBuilders.put(augmentPackageName, augmentBuilders);
- }
- val augIdentifier = getAugmentIdentifier(augSchema.unknownSchemaNodes);
-
- val augTypeName = if (augIdentifier !== null) {
- BindingMapping.getClassName(augIdentifier)
- } else {
- augGenTypeName(augmentBuilders, targetTypeRef.name);
- }
-
- val augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augTypeName);
-
- augTypeBuilder.addImplementsType(DATA_OBJECT);
- augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef));
- addImplementedInterfaceFromUses(augSchema, augTypeBuilder);
-
- augSchemaNodeToMethods(module, basePackageName, augTypeBuilder, augTypeBuilder, augSchema.childNodes);
- augmentBuilders.put(augTypeName, augTypeBuilder);
-
- genCtx.get(module).addTargetToAugmentation(targetTypeRef,augTypeBuilder);
- genCtx.get(module).addAugmentType(augTypeBuilder);
- genCtx.get(module).addTypeToAugmentation(augTypeBuilder, augSchema);
- return augTypeBuilder;
- }
-
- /**
- *
- * @param unknownSchemaNodes
- * @return nodeParameter of UnknownSchemaNode
- */
- private def String getAugmentIdentifier(List<UnknownSchemaNode> unknownSchemaNodes) {
- for (unknownSchemaNode : unknownSchemaNodes) {
- val nodeType = unknownSchemaNode.nodeType;
- if (AUGMENT_IDENTIFIER_NAME.equals(nodeType.localName) &&
- YANG_EXT_NAMESPACE.equals(nodeType.namespace.toString())) {
- return unknownSchemaNode.nodeParameter;
- }
- }
- return null;
- }
-
- /**
- * Returns first unique name for the augment generated type builder. The
- * generated type builder name for augment consists from name of augmented
- * node and serial number of its augmentation.
- *
- * @param builders
- * map of builders which were created in the package to which the
- * augmentation belongs
- * @param genTypeName
- * string with name of augmented node
- * @return string with unique name for augmentation builder
- */
- private def String augGenTypeName(Map<String, GeneratedTypeBuilder> builders, String genTypeName) {
- var index = 1;
- while ((builders !== null) && builders.containsKey(genTypeName + index)) {
- index = index + 1;
- }
- return genTypeName + index;
- }
-
- /**
- * Adds the methods to <code>typeBuilder</code> which represent subnodes of
- * node for which <code>typeBuilder</code> was created.
- *
- * The subnodes aren't mapped to the methods if they are part of grouping or
- * augment (in this case are already part of them).
- *
- * @param module current module
- * @param basePackageName
- * string contains the module package name
- * @param parent
- * generated type builder which represents any node. The subnodes
- * of this node are added to the <code>typeBuilder</code> as
- * methods. The subnode can be of type leaf, leaf-list, list,
- * container, choice.
- * @param childOf parent type
- * @param schemaNodes
- * set of data schema nodes which are the children of the node
- * for which <code>typeBuilder</code> was created
- * @return generated type builder which is the same builder as input
- * parameter. The getter methods (representing child nodes) could be
- * added to it.
- */
- private def GeneratedTypeBuilder resolveDataSchemaNodes(Module module, String basePackageName,
- GeneratedTypeBuilder parent, GeneratedTypeBuilder childOf, Set<DataSchemaNode> schemaNodes) {
- if ((schemaNodes !== null) && (parent !== null)) {
- for (schemaNode : schemaNodes) {
- if (!schemaNode.augmenting && !schemaNode.addedByUses) {
- addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, parent, childOf, module);
- }
- }
- }
- return parent;
- }
-
- /**
- * Adds the methods to <code>typeBuilder</code> what represents subnodes of
- * node for which <code>typeBuilder</code> was created.
- *
- * @param module current module
- * @param basePackageName
- * string contains the module package name
- * @param typeBuilder
- * generated type builder which represents any node. The subnodes
- * of this node are added to the <code>typeBuilder</code> as
- * methods. The subnode can be of type leaf, leaf-list, list,
- * container, choice.
- * @param childOf parent type
- * @param schemaNodes
- * set of data schema nodes which are the children of the node
- * for which <code>typeBuilder</code> was created
- * @return generated type builder which is the same object as the input
- * parameter <code>typeBuilder</code>. The getter method could be
- * added to it.
- */
- private def GeneratedTypeBuilder augSchemaNodeToMethods(Module module, String basePackageName,
- GeneratedTypeBuilder typeBuilder, GeneratedTypeBuilder childOf, Set<DataSchemaNode> schemaNodes) {
- if ((schemaNodes !== null) && (typeBuilder !== null)) {
- for (schemaNode : schemaNodes) {
- if (!schemaNode.isAugmenting()) {
- addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder, childOf, module);
- }
- }
- }
- return typeBuilder;
- }
-
- /**
- * Adds to <code>typeBuilder</code> a method which is derived from
- * <code>schemaNode</code>.
- *
- * @param basePackageName
- * string with the module package name
- * @param node
- * data schema node which is added to <code>typeBuilder</code> as
- * a method
- * @param typeBuilder
- * generated type builder to which is <code>schemaNode</code>
- * added as a method.
- * @param childOf parent type
- * @param module current module
- */
- private def void addSchemaNodeToBuilderAsMethod(String basePackageName, DataSchemaNode node,
- GeneratedTypeBuilder typeBuilder, GeneratedTypeBuilder childOf, Module module) {
- if (node !== null && typeBuilder !== null) {
- switch (node) {
- case node instanceof LeafSchemaNode:
- resolveLeafSchemaNodeAsMethod(typeBuilder, node as LeafSchemaNode)
- case node instanceof LeafListSchemaNode:
- resolveLeafListSchemaNode(typeBuilder, node as LeafListSchemaNode)
- case node instanceof ContainerSchemaNode:
- containerToGenType(module, basePackageName, typeBuilder, childOf, node as ContainerSchemaNode)
- case node instanceof ListSchemaNode:
- listToGenType(module, basePackageName, typeBuilder, childOf, node as ListSchemaNode)
- case node instanceof ChoiceNode:
- choiceToGeneratedType(module, basePackageName, typeBuilder, node as ChoiceNode)
- }
- }
- }
-
- /**
- * Converts <code>choiceNode</code> to the list of generated types for
- * choice and its cases.
- *
- * The package names for choice and for its cases are created as
- * concatenation of the module package (<code>basePackageName</code>) and
- * names of all parents node.
- *
- * @param module current module
- * @param basePackageName
- * string with the module package name
- * @param parent parent type
- * @param childOf concrete parent for case child nodes
- * @param choiceNode
- * choice node which is mapped to generated type. Also child
- * nodes - cases are mapped to generated types.
- * @throws IllegalArgumentException
- * <ul>
- * <li>if <code>basePackageName</code> equals null</li>
- * <li>if <code>choiceNode</code> equals null</li>
- * </ul>
- *
- */
- private def void choiceToGeneratedType(Module module, String basePackageName, GeneratedTypeBuilder parent,
- ChoiceNode choiceNode) {
- checkArgument(basePackageName !== null, "Base Package Name cannot be NULL.");
- checkArgument(choiceNode !== null, "Choice Schema Node cannot be NULL.");
-
- if (!choiceNode.addedByUses) {
- val packageName = packageNameForGeneratedType(basePackageName, choiceNode.path);
- val choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode);
- constructGetter(parent, choiceNode.QName.localName, choiceNode.description, choiceTypeBuilder);
- choiceTypeBuilder.addImplementsType(DataContainer.typeForClass);
- genCtx.get(module).addChildNodeType(choiceNode.path, choiceTypeBuilder)
- generateTypesFromChoiceCases(module, basePackageName, parent, choiceTypeBuilder.toInstance, choiceNode);
- }
- }
-
- /**
- * Converts <code>caseNodes</code> set to list of corresponding generated
- * types.
- *
- * For every <i>case</i> which isn't added through augment or <i>uses</i> is
- * created generated type builder. The package names for the builder is
- * created as concatenation of the module package (
- * <code>basePackageName</code>) and names of all parents nodes of the
- * concrete <i>case</i>. There is also relation "<i>implements type</i>"
- * between every case builder and <i>choice</i> type
- *
- * @param basePackageName
- * string with the module package name
- * @param refChoiceType
- * type which represents superior <i>case</i>
- * @param caseNodes
- * set of choice case nodes which are mapped to generated types
- * @return list of generated types for <code>caseNodes</code>.
- * @throws IllegalArgumentException
- * <ul>
- * <li>if <code>basePackageName</code> equals null</li>
- * <li>if <code>refChoiceType</code> equals null</li>
- * <li>if <code>caseNodes</code> equals null</li>
- * </ul>
- * *
- */
- private def void generateTypesFromChoiceCases(Module module, String basePackageName,
- GeneratedTypeBuilder choiceParent, Type refChoiceType, ChoiceNode choiceNode) {
- checkArgument(basePackageName !== null, "Base Package Name cannot be NULL.");
- checkArgument(refChoiceType !== null, "Referenced Choice Type cannot be NULL.");
- checkArgument(choiceNode !== null, "ChoiceNode cannot be NULL.");
-
- val Set<ChoiceCaseNode> caseNodes = choiceNode.cases;
- if (caseNodes == null) {
- return
- }
-
- for (caseNode : caseNodes) {
- if (caseNode !== null && !caseNode.isAddedByUses() && !caseNode.isAugmenting()) {
- val packageName = packageNameForGeneratedType(basePackageName, caseNode.path)
- val caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode)
- caseTypeBuilder.addImplementsType(refChoiceType)
- genCtx.get(module).addCaseType(caseNode.path, caseTypeBuilder)
- genCtx.get(module).addChoiceToCaseMapping(refChoiceType, caseTypeBuilder,caseNode)
- val Set<DataSchemaNode> caseChildNodes = caseNode.childNodes
- if (caseChildNodes !== null) {
- var Object parentNode = null
- val SchemaPath nodeSp = choiceNode.path
- val List<QName> nodeNames = nodeSp.path
- val List<QName> nodeNewNames = new ArrayList(nodeNames)
- nodeNewNames.remove(nodeNewNames.size - 1)
- val SchemaPath nodeNewSp = SchemaPath.create(nodeNewNames, nodeSp.absolute)
- parentNode = findDataSchemaNode(schemaContext, nodeNewSp)
-
- var SchemaNode parent
- if (parentNode instanceof AugmentationSchema) {
- val augSchema = parentNode as AugmentationSchema;
- val targetPath = augSchema.targetPath;
- var targetSchemaNode = findDataSchemaNode(schemaContext, targetPath)
- if (targetSchemaNode instanceof DataSchemaNode &&
- (targetSchemaNode as DataSchemaNode).isAddedByUses()) {
- targetSchemaNode = findOriginal(targetSchemaNode as DataSchemaNode, schemaContext);
- if (targetSchemaNode == null) {
- throw new NullPointerException(
- "Failed to find target node from grouping for augmentation " + augSchema +
- " in module " + module.name);
- }
- }
- parent = targetSchemaNode
- } else {
- val SchemaPath sp = choiceNode.path
- val List<QName> names = sp.path
- val List<QName> newNames = new ArrayList(names)
- newNames.remove(newNames.size - 1)
- val SchemaPath newSp = SchemaPath.create(newNames, sp.absolute)
- parent = findDataSchemaNode(schemaContext, newSp)
- }
- var GeneratedTypeBuilder childOfType = findChildNodeByPath(parent.path)
- resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, childOfType, caseChildNodes)
- }
- }
-
- processUsesAugments(caseNode, module);
- }
- }
-
- /**
- * Generates list of generated types for all the cases of a choice which are
- * added to the choice through the augment.
- *
- *
- * @param basePackageName
- * string contains name of package to which augment belongs. If
- * an augmented choice is from an other package (pcg1) than an
- * augmenting choice (pcg2) then case's of the augmenting choice
- * will belong to pcg2.
- * @param refChoiceType
- * Type which represents the choice to which case belongs. Every
- * case has to contain its choice in extend part.
- * @param caseNodes
- * set of choice case nodes for which is checked if are/aren't
- * added to choice through augmentation
- * @return list of generated types which represents augmented cases of
- * choice <code>refChoiceType</code>
- * @throws IllegalArgumentException
- * <ul>
- * <li>if <code>basePackageName</code> equals null</li>
- * <li>if <code>refChoiceType</code> equals null</li>
- * <li>if <code>caseNodes</code> equals null</li>
- * </ul>
- */
- private def void generateTypesFromAugmentedChoiceCases(Module module, String basePackageName, Type targetType,
- ChoiceNode targetNode, Set<DataSchemaNode> augmentedNodes) {
- checkArgument(basePackageName !== null, "Base Package Name cannot be NULL.");
- checkArgument(targetType !== null, "Referenced Choice Type cannot be NULL.");
- checkArgument(augmentedNodes !== null, "Set of Choice Case Nodes cannot be NULL.");
-
- for (caseNode : augmentedNodes) {
- if (caseNode !== null) {
- val packageName = packageNameForGeneratedType(basePackageName, caseNode.path);
- val caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);
- caseTypeBuilder.addImplementsType(targetType);
-
- var SchemaNode parent = null
- val SchemaPath nodeSp = targetNode.path
- val List<QName> nodeNames = nodeSp.path
- val List<QName> nodeNewNames = new ArrayList(nodeNames)
- nodeNewNames.remove(nodeNewNames.size - 1)
- val SchemaPath nodeNewSp = SchemaPath.create(nodeNewNames, nodeSp.absolute)
- parent = findDataSchemaNode(schemaContext, nodeNewSp)
-
- var GeneratedTypeBuilder childOfType = null;
- if (parent instanceof Module) {
- childOfType = genCtx.get(parent as Module).moduleNode
- } else if (parent instanceof ChoiceCaseNode) {
- childOfType = findCaseByPath(parent.path)
- } else if (parent instanceof DataSchemaNode || parent instanceof NotificationDefinition) {
- childOfType = findChildNodeByPath(parent.path)
- } else if (parent instanceof GroupingDefinition) {
- childOfType = findGroupingByPath(parent.path);
- }
-
- if (childOfType == null) {
- throw new IllegalArgumentException("Failed to find parent type of choice " + targetNode);
- }
-
- var ChoiceCaseNode node = null;
- if (caseNode instanceof ChoiceCaseNode) {
- node = caseNode as ChoiceCaseNode;
- } else {
- node = targetNode.getCaseNodeByName(caseNode.getQName().getLocalName());
- }
- val Set<DataSchemaNode> childNodes = node.childNodes;
- if (childNodes !== null) {
- resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, childOfType, childNodes);
- }
- genCtx.get(module).addCaseType(caseNode.path, caseTypeBuilder)
- genCtx.get(module).addChoiceToCaseMapping(targetType, caseTypeBuilder,node);
- }
- }
-
- }
-
- /**
- * Converts <code>leaf</code> to the getter method which is added to
- * <code>typeBuilder</code>.
- *
- * @param typeBuilder
- * generated type builder to which is added getter method as
- * <code>leaf</code> mapping
- * @param leaf
- * leaf schema node which is mapped as getter method which is
- * added to <code>typeBuilder</code>
- * @return boolean value
- * <ul>
- * <li>false - if <code>leaf</code> or <code>typeBuilder</code> are
- * null</li>
- * <li>true - in other cases</li>
- * </ul>
- */
- private def Type resolveLeafSchemaNodeAsMethod(GeneratedTypeBuilder typeBuilder, LeafSchemaNode leaf) {
- var Type returnType = null;
- if ((leaf !== null) && (typeBuilder !== null)) {
- val leafName = leaf.QName.localName;
- var String leafDesc = leaf.description;
- if (leafDesc === null) {
- leafDesc = "";
- }
-
- val parentModule = findParentModule(schemaContext, leaf);
- if (leafName !== null && !leaf.isAddedByUses()) {
- val TypeDefinition<?> typeDef = leaf.type;
-
- var GeneratedTOBuilder genTOBuilder;
- if (typeDef instanceof EnumTypeDefinition) {
- returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);
- val enumTypeDef = typeDef as EnumTypeDefinition;
- val enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leaf.QName, typeBuilder);
-
- if (enumBuilder !== null) {
- returnType = enumBuilder.toInstance(typeBuilder)
- }
- (typeProvider as TypeProviderImpl).putReferencedType(leaf.path, returnType);
- } else if (typeDef instanceof UnionType) {
- genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule);
- if (genTOBuilder !== null) {
- returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule)
- }
- } else if (typeDef instanceof BitsTypeDefinition) {
- genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule);
- if (genTOBuilder !== null) {
- returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);
- }
- } else {
- val Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);
- returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf, restrictions);
- }
- if (returnType !== null) {
- val MethodSignatureBuilder getter = constructGetter(typeBuilder, leafName, leafDesc, returnType);
- processContextRefExtension(leaf, getter, parentModule);
- }
- }
- }
- return returnType;
- }
-
- private def void processContextRefExtension(LeafSchemaNode leaf, MethodSignatureBuilder getter, Module module) {
- for (node : leaf.unknownSchemaNodes) {
- val nodeType = node.nodeType;
- if ("context-reference".equals(nodeType.localName)) {
- val nodeParam = node.nodeParameter;
- var IdentitySchemaNode identity = null;
- var String basePackageName = null;
- val String[] splittedElement = nodeParam.split(":");
- if (splittedElement.length == 1) {
- identity = findIdentityByName(module.identities, splittedElement.get(0));
- basePackageName = moduleNamespaceToPackageName(module);
- } else if (splittedElement.length == 2) {
- var prefix = splittedElement.get(0);
- val Module dependentModule = findModuleFromImports(module.imports, prefix)
- if (dependentModule == null) {
- throw new IllegalArgumentException(
- "Failed to process context-reference: unknown prefix " + prefix);
- }
- identity = findIdentityByName(dependentModule.identities, splittedElement.get(1));
- basePackageName = moduleNamespaceToPackageName(dependentModule);
- } else {
- throw new IllegalArgumentException(
- "Failed to process context-reference: unknown identity " + nodeParam);
- }
- if (identity == null) {
- throw new IllegalArgumentException(
- "Failed to process context-reference: unknown identity " + nodeParam);
- }
-
- val Class<RoutingContext> clazz = typeof(RoutingContext);
- val AnnotationTypeBuilder rc = getter.addAnnotation(clazz.package.name, clazz.simpleName);
- val packageName = packageNameForGeneratedType(basePackageName, identity.path);
- val genTypeName = BindingMapping.getClassName(identity.QName.localName);
- rc.addParameter("value", packageName + "." + genTypeName + ".class");
- }
- }
- }
-
- private def IdentitySchemaNode findIdentityByName(Set<IdentitySchemaNode> identities, String name) {
- for (id : identities) {
- if (id.QName.localName.equals(name)) {
- return id;
- }
- }
- return null;
- }
-
- private def Module findModuleFromImports(Set<ModuleImport> imports, String prefix) {
- for (imp : imports) {
- if (imp.prefix.equals(prefix)) {
- return schemaContext.findModuleByName(imp.moduleName, imp.revision);
- }
- }
- return null;
- }
-
- private def boolean resolveLeafSchemaNodeAsProperty(GeneratedTOBuilder toBuilder, LeafSchemaNode leaf,
- boolean isReadOnly, Module module) {
- if ((leaf !== null) && (toBuilder !== null)) {
- val leafName = leaf.QName.localName;
- var String leafDesc = leaf.description;
- if (leafDesc === null) {
- leafDesc = "";
- }
-
- if (leafName !== null) {
- var Type returnType = null;
- val TypeDefinition<?> typeDef = leaf.type;
- if (typeDef instanceof UnionTypeDefinition) {
- // GeneratedType for this type definition should be already created
- var qname = typeDef.QName
- var Module unionModule = null
- if (qname.prefix == null || qname.prefix.empty) {
- unionModule = module
- } else {
- unionModule = findModuleFromImports(module.imports, qname.prefix)
- }
- val ModuleContext mc = genCtx.get(unionModule)
- returnType = mc.typedefs.get(typeDef.path)
- } else {
- returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);
- }
- return resolveLeafSchemaNodeAsProperty(toBuilder, leaf, returnType, isReadOnly)
- }
- }
- return false;
- }
-
- /**
- * Converts <code>leaf</code> schema node to property of generated TO
- * builder.
- *
- * @param toBuilder
- * generated TO builder to which is <code>leaf</code> added as
- * property
- * @param leaf
- * leaf schema node which is added to <code>toBuilder</code> as
- * property
- * @param returnType property type
- * @param isReadOnly
- * boolean value which says if leaf property is|isn't read only
- * @return boolean value
- * <ul>
- * <li>false - if <code>leaf</code>, <code>toBuilder</code> or leaf
- * name equals null or if leaf is added by <i>uses</i>.</li>
- * <li>true - other cases</li>
- * </ul>
- */
- private def resolveLeafSchemaNodeAsProperty(GeneratedTOBuilder toBuilder, LeafSchemaNode leaf, Type returnType,
- boolean isReadOnly) {
- if (returnType == null) {
- return false;
- }
- val leafName = leaf.QName.localName
- val leafDesc = leaf.description
- val propBuilder = toBuilder.addProperty(parseToValidParamName(leafName));
- propBuilder.setReadOnly(isReadOnly);
- propBuilder.setReturnType(returnType);
- propBuilder.setComment(leafDesc);
- toBuilder.addEqualsIdentity(propBuilder);
- toBuilder.addHashIdentity(propBuilder);
- toBuilder.addToStringProperty(propBuilder);
- return true;
- }
-
- /**
- * Converts <code>node</code> leaf list schema node to getter method of
- * <code>typeBuilder</code>.
- *
- * @param typeBuilder
- * generated type builder to which is <code>node</code> added as
- * getter method
- * @param node
- * leaf list schema node which is added to
- * <code>typeBuilder</code> as getter method
- * @return boolean value
- * <ul>
- * <li>true - if <code>node</code>, <code>typeBuilder</code>,
- * nodeName equal null or <code>node</code> is added by <i>uses</i></li>
- * <li>false - other cases</li>
- * </ul>
- */
- private def boolean resolveLeafListSchemaNode(GeneratedTypeBuilder typeBuilder, LeafListSchemaNode node) {
- if ((node !== null) && (typeBuilder !== null)) {
- val nodeName = node.QName;
- var String nodeDesc = node.description;
- if (nodeDesc === null) {
- nodeDesc = "";
- }
- if (nodeName !== null && !node.isAddedByUses()) {
- val TypeDefinition<?> typeDef = node.type;
- val parentModule = findParentModule(schemaContext, node);
-
- var Type returnType = null;
- if (typeDef instanceof EnumTypeDefinition) {
- returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node);
- val enumTypeDef = typeDef as EnumTypeDefinition;
- val enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, nodeName, typeBuilder);
- returnType = new ReferencedTypeImpl(enumBuilder.packageName, enumBuilder.name);
- (typeProvider as TypeProviderImpl).putReferencedType(node.path, returnType);
- } else if (typeDef instanceof UnionType) {
- val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule);
- if (genTOBuilder !== null) {
- returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule)
- }
- } else if (typeDef instanceof BitsTypeDefinition) {
- val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule);
- returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);
- } else {
- val Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);
- returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node, restrictions);
- }
-
- val listType = Types.listTypeFor(returnType);
- constructGetter(typeBuilder, nodeName.localName, nodeDesc, listType);
- return true;
- }
- }
- return false;
- }
-
- private def Type createReturnTypeForUnion(GeneratedTOBuilder genTOBuilder, TypeDefinition<?> typeDef,
- GeneratedTypeBuilder typeBuilder, Module parentModule) {
- val GeneratedTOBuilderImpl returnType = new GeneratedTOBuilderImpl(genTOBuilder.packageName, genTOBuilder.name)
- genTOBuilder.setTypedef(true);
- genTOBuilder.setIsUnion(true);
- (typeProvider as TypeProviderImpl).addUnitsToGenTO(genTOBuilder, typeDef.getUnits());
-
- // union builder
- val GeneratedTOBuilder unionBuilder = new GeneratedTOBuilderImpl(typeBuilder.getPackageName(),
- genTOBuilder.getName() + "Builder");
- unionBuilder.setIsUnionBuilder(true);
- val MethodSignatureBuilder method = unionBuilder.addMethod("getDefaultInstance");
- method.setReturnType(returnType);
- method.addParameter(Types.STRING, "defaultValue");
- method.setAccessModifier(AccessModifier.PUBLIC);
- method.setStatic(true);
-
- val Set<Type> types = (typeProvider as TypeProviderImpl).additionalTypes.get(parentModule);
- if (types == null) {
- (typeProvider as TypeProviderImpl).additionalTypes.put(parentModule,
- Sets.newHashSet(unionBuilder.toInstance))
- } else {
- types.add(unionBuilder.toInstance)
- }
- return returnType.toInstance
- }
-
- private def GeneratedTypeBuilder addDefaultInterfaceDefinition(String packageName, SchemaNode schemaNode) {
- return addDefaultInterfaceDefinition(packageName, schemaNode, null);
- }
-
- /**
- * Instantiates generated type builder with <code>packageName</code> and
- * <code>schemaNode</code>.
- *
- * The new builder always implements
- * {@link org.opendaylight.yangtools.yang.binding.DataObject DataObject}.<br />
- * If <code>schemaNode</code> is instance of GroupingDefinition it also
- * implements {@link org.opendaylight.yangtools.yang.binding.Augmentable
- * Augmentable}.<br />
- * If <code>schemaNode</code> is instance of
- * {@link org.opendaylight.yangtools.yang.model.api.DataNodeContainer
- * DataNodeContainer} it can also implement nodes which are specified in
- * <i>uses</i>.
- *
- * @param packageName
- * string with the name of the package to which
- * <code>schemaNode</code> belongs.
- * @param schemaNode
- * schema node for which is created generated type builder
- * @param parent parent type (can be null)
- * @return generated type builder <code>schemaNode</code>
- */
- private def GeneratedTypeBuilder addDefaultInterfaceDefinition(String packageName, SchemaNode schemaNode,
- Type parent) {
- val it = addRawInterfaceDefinition(packageName, schemaNode, "");
- if (parent === null) {
- addImplementsType(DATA_OBJECT);
- } else {
- addImplementsType(BindingTypes.childOf(parent));
- }
- if (!(schemaNode instanceof GroupingDefinition)) {
- addImplementsType(augmentable(it));
- }
-
- if (schemaNode instanceof DataNodeContainer) {
- addImplementedInterfaceFromUses(schemaNode as DataNodeContainer, it);
- }
-
- return it;
- }
-
- /**
- * Wraps the calling of the same overloaded method.
- *
- * @param packageName
- * string with the package name to which returning generated type
- * builder belongs
- * @param schemaNode
- * schema node which provide data about the schema node name
- * @return generated type builder for <code>schemaNode</code>
- */
- private def GeneratedTypeBuilder addRawInterfaceDefinition(String packageName, SchemaNode schemaNode) {
- return addRawInterfaceDefinition(packageName, schemaNode, "");
- }
-
- /**
- * Returns reference to generated type builder for specified
- * <code>schemaNode</code> with <code>packageName</code>.
- *
- * Firstly the generated type builder is searched in
- * {@link BindingGeneratorImpl#genTypeBuilders genTypeBuilders}. If it isn't
- * found it is created and added to <code>genTypeBuilders</code>.
- *
- * @param packageName
- * string with the package name to which returning generated type
- * builder belongs
- * @param schemaNode
- * schema node which provide data about the schema node name
- * @param prefix return type name prefix
- * @return generated type builder for <code>schemaNode</code>
- * @throws IllegalArgumentException
- * <ul>
- * <li>if <code>schemaNode</code> equals null</li>
- * <li>if <code>packageName</code> equals null</li>
- * <li>if Q name of schema node is null</li>
- * <li>if schema node name is null</li>
- * </ul>
- *
- */
- private def GeneratedTypeBuilder addRawInterfaceDefinition(String packageName, SchemaNode schemaNode,
- String prefix) {
- checkArgument(schemaNode !== null, "Data Schema Node cannot be NULL.");
- checkArgument(packageName !== null, "Package Name for Generated Type cannot be NULL.");
- checkArgument(schemaNode.QName !== null, "QName for Data Schema Node cannot be NULL.");
- val schemaNodeName = schemaNode.QName.localName;
- checkArgument(schemaNodeName !== null, "Local Name of QName for Data Schema Node cannot be NULL.");
-
- var String genTypeName;
- if (prefix === null) {
- genTypeName = BindingMapping.getClassName(schemaNodeName);
- } else {
- genTypeName = prefix + BindingMapping.getClassName(schemaNodeName);
- }
-
- //FIXME: Validation of name conflict
- val newType = new GeneratedTypeBuilderImpl(packageName, genTypeName);
- qnameConstant(newType,BindingMapping.QNAME_STATIC_FIELD_NAME,schemaNode.QName);
- newType.addComment(schemaNode.getDescription());
- if (!genTypeBuilders.containsKey(packageName)) {
- val Map<String, GeneratedTypeBuilder> builders = new HashMap();
- builders.put(genTypeName, newType);
- genTypeBuilders.put(packageName, builders);
- } else {
- val Map<String, GeneratedTypeBuilder> builders = genTypeBuilders.get(packageName);
- if (!builders.containsKey(genTypeName)) {
- builders.put(genTypeName, newType);
- }
- }
- return newType;
- }
-
- /**
- * Creates the name of the getter method name from <code>localName</code>.
- *
- * @param localName
- * string with the name of the getter method
- * @param returnType return type
- * @return string with the name of the getter method for
- * <code>methodName</code> in JAVA method format
- */
- public static def String getterMethodName(String localName, Type returnType) {
- val method = new StringBuilder();
- if (BOOLEAN.equals(returnType)) {
- method.append("is");
- } else {
- method.append("get");
- }
- method.append(BindingMapping.getPropertyName(localName).toFirstUpper);
- return method.toString();
- }
-
- /**
- * Created a method signature builder as part of
- * <code>interfaceBuilder</code>.
- *
- * The method signature builder is created for the getter method of
- * <code>schemaNodeName</code>. Also <code>comment</code> and
- * <code>returnType</code> information are added to the builder.
- *
- * @param interfaceBuilder
- * generated type builder for which the getter method should be
- * created
- * @param schemaNodeName
- * string with schema node name. The name will be the part of the
- * getter method name.
- * @param comment
- * string with comment for the getter method
- * @param returnType
- * type which represents the return type of the getter method
- * @return method signature builder which represents the getter method of
- * <code>interfaceBuilder</code>
- */
- private def MethodSignatureBuilder constructGetter(GeneratedTypeBuilder interfaceBuilder, String schemaNodeName,
- String comment, Type returnType) {
- val getMethod = interfaceBuilder.addMethod(getterMethodName(schemaNodeName, returnType));
- getMethod.setComment(comment);
- getMethod.setReturnType(returnType);
- return getMethod;
- }
-
- /**
- * Adds <code>schemaNode</code> to <code>typeBuilder</code> as getter method
- * or to <code>genTOBuilder</code> as property.
- *
- * @param basePackageName
- * string contains the module package name
- * @param schemaNode
- * data schema node which should be added as getter method to
- * <code>typeBuilder</code> or as a property to
- * <code>genTOBuilder</code> if is part of the list key
- * @param typeBuilder
- * generated type builder for the list schema node
- * @param genTOBuilder
- * generated TO builder for the list keys
- * @param listKeys
- * list of string which contains names of the list keys
- * @param module current module
- * @throws IllegalArgumentException
- * <ul>
- * <li>if <code>schemaNode</code> equals null</li>
- * <li>if <code>typeBuilder</code> equals null</li>
- * </ul>
- */
- private def void addSchemaNodeToListBuilders(String basePackageName, DataSchemaNode schemaNode,
- GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder, List<String> listKeys, Module module) {
- checkArgument(schemaNode !== null, "Data Schema Node cannot be NULL.");
- checkArgument(typeBuilder !== null, "Generated Type Builder cannot be NULL.");
-
- if (schemaNode instanceof LeafSchemaNode) {
- val leaf = schemaNode as LeafSchemaNode;
- val leafName = leaf.QName.localName;
- val Type type = resolveLeafSchemaNodeAsMethod(typeBuilder, leaf);
- if (listKeys.contains(leafName)) {
- if (type == null) {
- resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true, module)
- } else {
- resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, type, true)
- }
- }
- } else if (!schemaNode.addedByUses) {
- if (schemaNode instanceof LeafListSchemaNode) {
- resolveLeafListSchemaNode(typeBuilder, schemaNode as LeafListSchemaNode);
- } else if (schemaNode instanceof ContainerSchemaNode) {
- containerToGenType(module, basePackageName, typeBuilder, typeBuilder, schemaNode as ContainerSchemaNode);
- } else if (schemaNode instanceof ChoiceNode) {
- choiceToGeneratedType(module, basePackageName, typeBuilder, schemaNode as ChoiceNode);
- } else if (schemaNode instanceof ListSchemaNode) {
- listToGenType(module, basePackageName, typeBuilder, typeBuilder, schemaNode as ListSchemaNode);
- }
- }
- }
-
- private def typeBuildersToGenTypes(Module module, GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder) {
- checkArgument(typeBuilder !== null, "Generated Type Builder cannot be NULL.");
-
- if (genTOBuilder !== null) {
- val genTO = genTOBuilder.toInstance();
- constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", genTO);
- genCtx.get(module).addGeneratedTOBuilder(genTOBuilder)
- }
- }
-
- /**
- * Selects the names of the list keys from <code>list</code> and returns
- * them as the list of the strings
- *
- * @param list
- * of string with names of the list keys
- * @return list of string which represents names of the list keys. If the
- * <code>list</code> contains no keys then the empty list is
- * returned.
- */
- private def listKeys(ListSchemaNode list) {
- val List<String> listKeys = new ArrayList();
-
- if (list.keyDefinition !== null) {
- val keyDefinitions = list.keyDefinition;
- for (keyDefinition : keyDefinitions) {
- listKeys.add(keyDefinition.localName);
- }
- }
- return listKeys;
- }
-
- /**
- * Generates for the <code>list</code> which contains any list keys special
- * generated TO builder.
- *
- * @param packageName
- * string with package name to which the list belongs
- * @param list
- * list schema node which is source of data about the list name
- * @return generated TO builder which represents the keys of the
- * <code>list</code> or null if <code>list</code> is null or list of
- * key definitions is null or empty.
- */
- private def GeneratedTOBuilder resolveListKeyTOBuilder(String packageName, ListSchemaNode list) {
- var GeneratedTOBuilder genTOBuilder = null;
- if ((list.keyDefinition !== null) && (!list.keyDefinition.isEmpty())) {
- val listName = list.QName.localName + "Key";
- val String genTOName = BindingMapping.getClassName(listName);
- genTOBuilder = new GeneratedTOBuilderImpl(packageName, genTOName);
- }
- return genTOBuilder;
- }
-
- /**
- * Builds generated TO builders for <code>typeDef</code> of type
- * {@link org.opendaylight.yangtools.yang.model.util.UnionType UnionType} or
- * {@link org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition
- * BitsTypeDefinition} which are also added to <code>typeBuilder</code> as
- * enclosing transfer object.
- *
- * If more then one generated TO builder is created for enclosing then all
- * of the generated TO builders are added to <code>typeBuilder</code> as
- * enclosing transfer objects.
- *
- * @param typeDef
- * type definition which can be of type <code>UnionType</code> or
- * <code>BitsTypeDefinition</code>
- * @param typeBuilder
- * generated type builder to which is added generated TO created
- * from <code>typeDef</code>
- * @param leafName
- * string with name for generated TO builder
- * @param leaf
- * @param parentModule
- * @return generated TO builder for <code>typeDef</code>
- */
- private def GeneratedTOBuilder addTOToTypeBuilder(TypeDefinition<?> typeDef, GeneratedTypeBuilder typeBuilder,
- DataSchemaNode leaf, Module parentModule) {
- val classNameFromLeaf = BindingMapping.getClassName(leaf.QName);
- val List<GeneratedTOBuilder> genTOBuilders = new ArrayList();
- val packageName = typeBuilder.fullyQualifiedName;
- if (typeDef instanceof UnionTypeDefinition) {
- val List<GeneratedTOBuilder> types = (typeProvider as TypeProviderImpl).
- provideGeneratedTOBuildersForUnionTypeDef(packageName, (typeDef as UnionTypeDefinition),
- classNameFromLeaf, leaf);
- genTOBuilders.addAll(types);
-
-
- var GeneratedTOBuilder resultTOBuilder = null;
- if (!types.isEmpty()) {
- resultTOBuilder = types.remove(0);
- for (GeneratedTOBuilder genTOBuilder : types) {
- resultTOBuilder.addEnclosingTransferObject(genTOBuilder);
- }
- }
-
- val GeneratedPropertyBuilder genPropBuilder = resultTOBuilder.addProperty("value");
- genPropBuilder.setReturnType(Types.primitiveType("char[]", null));
- resultTOBuilder.addEqualsIdentity(genPropBuilder);
- resultTOBuilder.addHashIdentity(genPropBuilder);
- resultTOBuilder.addToStringProperty(genPropBuilder);
-
- } else if (typeDef instanceof BitsTypeDefinition) {
- genTOBuilders.add(
- ((typeProvider as TypeProviderImpl) ).
- provideGeneratedTOBuilderForBitsTypeDefinition(packageName, typeDef, classNameFromLeaf));
- }
- if (genTOBuilders !== null && !genTOBuilders.isEmpty()) {
- for (genTOBuilder : genTOBuilders) {
- typeBuilder.addEnclosingTransferObject(genTOBuilder);
- }
- return genTOBuilders.get(0);
- }
- return null;
-
- }
-
- /**
- * Adds the implemented types to type builder.
- *
- * The method passes through the list of <i>uses</i> in
- * {@code dataNodeContainer}. For every <i>use</i> is obtained corresponding
- * generated type from {@link BindingGeneratorImpl#allGroupings
- * allGroupings} which is added as <i>implements type</i> to
- * <code>builder</code>
- *
- * @param dataNodeContainer
- * element which contains the list of used YANG groupings
- * @param builder
- * builder to which are added implemented types according to
- * <code>dataNodeContainer</code>
- * @return generated type builder with all implemented types
- */
- private def addImplementedInterfaceFromUses(DataNodeContainer dataNodeContainer, GeneratedTypeBuilder builder) {
- for (usesNode : dataNodeContainer.uses) {
- if (usesNode.groupingPath !== null) {
- val genType = findGroupingByPath(usesNode.groupingPath).toInstance
- if (genType === null) {
- throw new IllegalStateException(
- "Grouping " + usesNode.groupingPath + "is not resolved for " + builder.name);
- }
- builder.addImplementsType(genType);
- builder.addComment(genType.getComment());
- }
- }
- return builder;
- }
-
- private def GeneratedTypeBuilder findChildNodeByPath(SchemaPath path) {
- for (ctx : genCtx.values) {
- var result = ctx.getChildNode(path)
- if (result !== null) {
- return result
- }
- }
- return null
- }
-
- private def GeneratedTypeBuilder findGroupingByPath(SchemaPath path) {
- for (ctx : genCtx.values) {
- var result = ctx.getGrouping(path)
- if (result !== null) {
- return result
- }
- }
- return null
- }
-
- private def GeneratedTypeBuilder findCaseByPath(SchemaPath path) {
- for (ctx : genCtx.values) {
- var result = ctx.getCase(path)
- if (result !== null) {
- return result
- }
- }
- return null
- }
-
- public def getModuleContexts() {
- genCtx;
- }
-
-}
import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
-
import java.util.Set;
-
import org.opendaylight.yangtools.yang.common.QName;
public final class BindingMapping {
* or <code>null</code> if the input {@link String} {@code s} was
* <code>null</code>.
*/
- private static String toFirstUpper(final String s) {
+ public static String toFirstUpper(final String s) {
if (s == null || s.length() == 0) {
return s;
}
*/
package org.opendaylight.yangtools.yang.data.impl;
+import java.util.ArrayDeque;
import java.util.ArrayList;
+import java.util.Deque;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
-import java.util.Stack;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode;
* @param originalNode
*/
private void addPathMembers(final Node<?> originalNode) {
- Stack<Node<?>> jobQueue = new Stack<>();
+ final Deque<Node<?>> jobQueue = new ArrayDeque<>();
jobQueue.push(originalNode);
while (!jobQueue.isEmpty()) {
Node<?> node2add = jobQueue.pop();
} else {
CompositeNode node2addComposite = (CompositeNode) node2add;
nodeMutant = NodeFactory.createMutableCompositeNode(node2add.getNodeType(),
- null, null,
- ((NodeModification) node2add).getModificationAction(), node2addComposite);
+ null, null,
+ ((NodeModification) node2add).getModificationAction(), node2addComposite);
}
mutableEquivalent = nodeMutant;
} else {
if (!originalRoot.equals(node2add)) {
throw new IllegalStateException("Different tree root node obtained - " +
- "perhaps nodes of different trees are getting mixed up.");
+ "perhaps nodes of different trees are getting mixed up.");
}
}
}
package org.opendaylight.yangtools.yang.data.impl;
import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Deque;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Stack;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
public static <T> MutableSimpleNode<T> createMutableSimpleNode(final QName qName,
final CompositeNode parent, final Object value, final ModifyAction modifyAction, final SimpleNode<T> original) {
@SuppressWarnings("unchecked")
- MutableSimpleNodeTOImpl<T> simpleNodeTOImpl =
- new MutableSimpleNodeTOImpl<T>(qName, parent, (T) value, modifyAction);
+ MutableSimpleNodeTOImpl<T> simpleNodeTOImpl = new MutableSimpleNodeTOImpl<>(qName, parent, (T) value, modifyAction);
simpleNodeTOImpl.setOriginal(original);
return simpleNodeTOImpl;
}
*/
public static CompositeNode createImmutableCompositeNode(final QName qName,
final CompositeNode parent, final List<Node<?>> value, final ModifyAction modifyAction) {
- CompositeNodeTOImpl compositeNodeModTOImpl =
- new CompositeNodeTOImpl(qName, parent, value, modifyAction);
- return compositeNodeModTOImpl;
+ return new CompositeNodeTOImpl(qName, parent, value, modifyAction);
}
/**
* has no reference to this copy
*/
public static <T> SimpleNode<T> copyNode(final SimpleNode<T> node) {
- SimpleNode<T> twinNode = createImmutableSimpleNode(
- node.getNodeType(), node.getParent(), node.getValue());
- return twinNode;
+ return createImmutableSimpleNode(node.getNodeType(), node.getParent(), node.getValue());
}
/**
* has no reference to this copy
*/
public static <T> MutableSimpleNode<T> copyNodeAsMutable(final SimpleNode<T> node) {
- MutableSimpleNode<T> twinNode = createMutableSimpleNode(
- node.getNodeType(), node.getParent(), node.getValue(),
- node.getModificationAction(), null);
- return twinNode;
+ return createMutableSimpleNode(
+ node.getNodeType(), node.getParent(), node.getValue(),
+ node.getModificationAction(), null);
}
/**
* have no reference to this copy
*/
public static CompositeNode copyNode(final CompositeNode node) {
- return copyNode(node, node.getValue().toArray(new Node<?>[0]));
+ return copyNode(node, node.getValue().toArray(new Node<?>[0]));
}
/**
MutableCompositeNode mutableRoot = createMutableCompositeNode(node.getNodeType(), null, null,
node.getModificationAction(), null);
- Stack<SimpleEntry<CompositeNode, MutableCompositeNode>> jobQueue = new Stack<>();
+ final Deque<SimpleEntry<CompositeNode, MutableCompositeNode>> jobQueue = new ArrayDeque<>();
jobQueue.push(new SimpleEntry<CompositeNode, MutableCompositeNode>(node, mutableRoot));
originalToCopy.put(node, mutableRoot);
*/
public static CompositeNode copyDeepAsImmutable(final CompositeNode node,
final Map<Node<?>, Node<?>> originalToCopyArg) {
- Stack<CompositeNode> jobQueue = new Stack<>();
+ final Deque<CompositeNode> jobQueue = new ArrayDeque<>();
jobQueue.push(node);
Map<Node<?>, Node<?>> originalToCopy = originalToCopyArg;
import com.google.common.collect.Maps;
import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayDeque;
import java.util.ArrayList;
+import java.util.Deque;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Stack;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
return null;
}
- Stack<SimpleEntry<org.w3c.dom.Node, Node<?>>> jobQueue = new Stack<>();
+ final Deque<SimpleEntry<org.w3c.dom.Node, Node<?>>> jobQueue = new ArrayDeque<>();
jobQueue.push(new SimpleEntry<org.w3c.dom.Node, Node<?>>(doc, treeRootNode));
while (!jobQueue.isEmpty()) {
public static Map<String, ListSchemaNode> buildMapOfListNodes(final SchemaContext context) {
Map<String, ListSchemaNode> mapOfLists = new HashMap<>();
- Stack<DataSchemaNode> jobQueue = new Stack<>();
+ final Deque<DataSchemaNode> jobQueue = new ArrayDeque<>();
jobQueue.addAll(context.getDataDefinitions());
while (!jobQueue.isEmpty()) {
import java.io.InputStream;
import java.net.URI;
+import java.util.ArrayDeque;
import java.util.ArrayList;
-import java.util.Stack;
+import java.util.Deque;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
* @see Node
*/
public final class XmlTreeBuilder {
-
- private final static XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
- private static XMLEventReader eventReader;
+ private final static XMLInputFactory XML_INPUT_FACTORY = XMLInputFactory.newInstance();
private XmlTreeBuilder() {
}
* @throws XMLStreamException
*/
public static Node<?> buildDataTree(final InputStream inputStream) throws XMLStreamException {
- eventReader = xmlInputFactory.createXMLEventReader(inputStream);
+ final XMLEventReader eventReader = XML_INPUT_FACTORY.createXMLEventReader(inputStream);
- final Stack<Node<?>> processingQueue = new Stack<>();
+ final Deque<Node<?>> processingQueue = new ArrayDeque<>();
Node<?> parentNode = null;
Node<?> root = null;
while (eventReader.hasNext()) {
compParentNode = (MutableCompositeNode) parentNode;
}
Node<?> newNode = null;
- if (isCompositeNodeEvent(event)) {
+ if (isCompositeNodeEvent(eventReader, event)) {
newNode = resolveCompositeNodeFromStartElement(startElement, compParentNode);
- } else if (isSimpleNodeEvent(event)) {
- newNode = resolveSimpleNodeFromStartElement(startElement, compParentNode);
+ } else if (isSimpleNodeEvent(eventReader, event)) {
+ newNode = resolveSimpleNodeFromStartElement(eventReader, startElement, compParentNode);
}
if (newNode != null) {
*
* @see SimpleNode
*/
- private static boolean isSimpleNodeEvent(final XMLEvent event) throws XMLStreamException {
+ private static boolean isSimpleNodeEvent(final XMLEventReader eventReader, final XMLEvent event) throws XMLStreamException {
checkArgument(event != null, "XML Event cannot be NULL!");
if (event.isStartElement()) {
if (eventReader.hasNext()) {
*
* @see CompositeNode
*/
- private static boolean isCompositeNodeEvent(final XMLEvent event) throws XMLStreamException {
+ private static boolean isCompositeNodeEvent(final XMLEventReader eventReader, final XMLEvent event) throws XMLStreamException {
checkArgument(event != null, "XML Event cannot be NULL!");
if (event.isStartElement()) {
if (eventReader.hasNext()) {
*
* @see SimpleNode
*/
- private static SimpleNode<String> resolveSimpleNodeFromStartElement(final StartElement startElement,
- final CompositeNode parent) throws XMLStreamException {
+ private static SimpleNode<String> resolveSimpleNodeFromStartElement(final XMLEventReader eventReader,
+ final StartElement startElement, final CompositeNode parent) throws XMLStreamException {
checkArgument(startElement != null, "Start Element cannot be NULL!");
String data = null;
import java.io.File;
import java.io.FileInputStream;
-import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;
import java.util.Properties;
-
import org.apache.maven.it.VerificationException;
import org.apache.maven.it.Verifier;
-import org.junit.BeforeClass;
import org.junit.Test;
public class YangToSourcesPluginTestIT {
- private static final String SRC_PROPERTIES = "target/it-project.properties";
- private static final String VERSION_PROP = "it-project.version";
- private static Properties props;
// TODO Test yang files in transitive dependencies
@Test
public void testYangRootNotExist() throws URISyntaxException {
try {
- setUp("YangRootNotExist/", false);
+ setUp("test-parent/YangRootNotExist/", false);
} catch (VerificationException e) {
assertVerificationException(e,
"[ERROR] yang-to-sources: Unable to parse yang files from ");
@Test
public void testCorrect() throws Exception {
- Verifier v = setUp("Correct/", false);
+ Verifier v = setUp("test-parent/Correct/", false);
verifyCorrectLog(v);
}
@Test
public void testAdditionalConfiguration() throws Exception {
- Verifier v = setUp("AdditionalConfig/", false);
+ Verifier v = setUp("test-parent/AdditionalConfig/", false);
v.verifyTextInLog("[DEBUG] yang-to-sources: Additional configuration picked up for : org.opendaylight.yangtools.yang2sources.spi.CodeGeneratorTestImpl: {nm1=abcd=a.b.c.d, nm2=abcd2=a.b.c.d.2}");
v.verifyTextInLog("[DEBUG] yang-to-sources: Additional configuration picked up for : org.opendaylight.yangtools.yang2sources.spi.CodeGeneratorTestImpl: {c1=config}");
v.verifyTextInLog(File.separator
@Test
public void testMissingYangInDep() throws Exception {
try {
- setUp("MissingYangInDep/", false);
+ setUp("test-parent/MissingYangInDep/", false);
} catch (VerificationException e) {
assertVerificationException(
e,
@Test
public void testNamingConflict() throws Exception {
- Verifier v = setUp("NamingConflict/", false);
+ Verifier v = setUp("test-parent/NamingConflict/", false);
v.verifyErrorFreeLog();
String baseDir = v.getBasedir();
String fileName = v.getLogFileName();
@Test
public void testNoGenerators() throws Exception {
- Verifier v = setUp("NoGenerators/", false);
+ Verifier v = setUp("test-parent/NoGenerators/", false);
v.verifyErrorFreeLog();
v.verifyTextInLog("[WARNING] yang-to-sources: No code generators provided");
}
@Test
public void testInvalidVersion() throws Exception {
- Verifier v = setUp("InvalidVersion/", false);
+ Verifier v = setUp("test-parent/InvalidVersion/", false);
v.verifyErrorFreeLog();
v.verifyTextInLog("[WARNING] yang-to-sources: Dependency resolution conflict:");
}
@Test
public void testUnknownGenerator() throws Exception {
- Verifier v = setUp("UnknownGenerator/", true);
+ Verifier v = setUp("test-parent/UnknownGenerator/", true);
v.verifyTextInLog("[ERROR] yang-to-sources: Unable to generate sources with unknown generator");
v.verifyTextInLog("java.lang.ClassNotFoundException: unknown");
v.verifyTextInLog("[INFO] yang-to-sources: Code generator instantiated from org.opendaylight.yangtools.yang2sources.spi.CodeGeneratorTestImpl");
@Test
public void testNoYangFiles() throws Exception {
- Verifier v = setUp("NoYangFiles/", false);
+ Verifier v = setUp("test-parent/NoYangFiles/", false);
v.verifyTextInLog("[INFO] yang-to-sources: No input files found");
}
assertThat(e.getMessage(), containsString(string));
}
- @BeforeClass
- public static void generateProps() throws IOException {
- final Properties sp = new Properties();
- try (InputStream is = new FileInputStream(new File(SRC_PROPERTIES))) {
- sp.load(is);
- }
-
- props = new Properties(System.getProperties());
- props.put(VERSION_PROP, sp.getProperty(VERSION_PROP));
- }
-
static Verifier setUp(String project, boolean ignoreF)
throws VerificationException, URISyntaxException {
final URL path = YangToSourcesPluginTestIT.class.getResource("/"
if (ignoreF)
verifier.addCliOption("-fn");
verifier.setMavenDebug(true);
- verifier.setSystemProperties(props);
verifier.executeGoal("generate-sources");
return verifier;
}
@Test
public void testNoOutputDir() throws Exception {
- Verifier v = YangToSourcesPluginTestIT.setUp("NoOutputDir/", false);
+ Verifier v = YangToSourcesPluginTestIT.setUp("test-parent/NoOutputDir/", false);
verifyCorrectLog(v);
}
@Test
public void testFindResourceOnCp() throws Exception {
Verifier v1 = new Verifier(new File(getClass().getResource(
- "/GenerateTest1/pom.xml").toURI()).getParent());
- v1.setSystemProperties(props);
+ "/test-parent/GenerateTest1/pom.xml").toURI()).getParent());
v1.executeGoal("clean");
v1.executeGoal("package");
- v1.assertFilePresent("target/classes/META-INF/yang/testfile1.yang");
- v1.assertFilePresent("target/classes/META-INF/yang/testfile2.yang");
- v1.assertFilePresent("target/classes/META-INF/yang/testfile3.yang");
- Verifier v2 = YangToSourcesPluginTestIT.setUp("GenerateTest2/", false);
+ Properties sp = new Properties();
+ try (InputStream is = new FileInputStream(v1.getBasedir() + "/it-project.properties")) {
+ sp.load(is);
+ }
+ String buildDir = sp.getProperty("target.dir");
+
+ v1.assertFilePresent(buildDir + "/classes/META-INF/yang/testfile1.yang");
+ v1.assertFilePresent(buildDir + "/classes/META-INF/yang/testfile2.yang");
+ v1.assertFilePresent(buildDir + "/classes/META-INF/yang/testfile3.yang");
+
+ Verifier v2 = new Verifier(new File(getClass().getResource(
+ "/test-parent/GenerateTest2/pom.xml").toURI()).getParent());
v2.executeGoal("clean");
v2.executeGoal("package");
- v2.assertFilePresent("target/classes/META-INF/yang/private.yang");
- v2.assertFileNotPresent("target/classes/META-INF/yang/testfile1.yang");
- v2.assertFileNotPresent("target/classes/META-INF/yang/testfile2.yang");
- v2.assertFileNotPresent("target/classes/META-INF/yang/testfile3.yang");
+
+ sp = new Properties();
+ try (InputStream is = new FileInputStream(v2.getBasedir() + "/it-project.properties")) {
+ sp.load(is);
+ }
+ buildDir = sp.getProperty("target.dir");
+
+ v2.assertFilePresent(buildDir + "/classes/META-INF/yang/private.yang");
+ v2.assertFileNotPresent(buildDir + "/classes/META-INF/yang/testfile1.yang");
+ v2.assertFileNotPresent(buildDir + "/classes/META-INF/yang/testfile2.yang");
+ v2.assertFileNotPresent(buildDir + "/classes/META-INF/yang/testfile3.yang");
}
+
}
<?xml version="1.0" encoding="UTF-8"?>
<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
+<!-- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. This
+ program and the accompanying materials are made available under the terms of the
+ Eclipse Public License v1.0 which accompanies this distribution, and is available
+ at http://www.eclipse.org/legal/epl-v10.html -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <groupId>org.opendaylight.yangtools</groupId>
- <version>0.5-SNAPSHOT</version>
- <artifactId>test</artifactId>
+ <parent>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>test-parent</artifactId>
+ <version>1.0</version>
+ </parent>
+
+ <artifactId>additional-config</artifactId>
<dependencies>
<dependency>
<nm2>abcd2=a.b.c.d.2</nm2>
</additionalConfiguration>
<resourceBaseDir>/target/resourcesGenerated</resourceBaseDir>
- <outputBaseDir>
- target/AdditionalConfig
+ <outputBaseDir>
+ target/AdditionalConfig
</outputBaseDir>
</generator>
<generator>
<additionalConfiguration>
<c1>config</c1>
</additionalConfiguration>
- <outputBaseDir>
- target/AdditionalConfig
+ <outputBaseDir>
+ target/AdditionalConfig
</outputBaseDir>
</generator>
</codeGenerators>
</configuration>
</execution>
</executions>
-
<dependencies>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
</dependency>
</dependencies>
</plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>properties-maven-plugin</artifactId>
+ </plugin>
</plugins>
</build>
+
</project>
<?xml version="1.0" encoding="UTF-8"?>
<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
+<!-- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. This
+ program and the accompanying materials are made available under the terms of the
+ Eclipse Public License v1.0 which accompanies this distribution, and is available
+ at http://www.eclipse.org/legal/epl-v10.html -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <groupId>org.opendaylight.yangtools</groupId>
- <version>0.5-SNAPSHOT</version>
- <artifactId>test</artifactId>
+ <parent>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>test-parent</artifactId>
+ <version>1.0</version>
+ </parent>
+
+ <artifactId>correct</artifactId>
<dependencies>
<dependency>
<codeGeneratorClass>
org.opendaylight.yangtools.yang2sources.spi.CodeGeneratorTestImpl
</codeGeneratorClass>
- <outputBaseDir>
- target/correct
+ <outputBaseDir>
+ target/correct
</outputBaseDir>
</generator>
</codeGenerators>
<?xml version="1.0" encoding="UTF-8"?>
<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
+<!-- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. This
+ program and the accompanying materials are made available under the terms of the
+ Eclipse Public License v1.0 which accompanies this distribution, and is available
+ at http://www.eclipse.org/legal/epl-v10.html -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <groupId>org.opendaylight.yangtools</groupId>
+ <parent>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>test-parent</artifactId>
+ <version>1.0</version>
+ </parent>
+
<artifactId>generator-test1</artifactId>
- <version>0.5-SNAPSHOT</version>
+
+ <properties>
+ <target.dir>${project.build.directory}</target.dir>
+ </properties>
<build>
<plugins>
<codeGeneratorClass>
org.opendaylight.yangtools.yang2sources.spi.CodeGeneratorTestImpl
</codeGeneratorClass>
- <outputBaseDir>
- target/GenerateTest1
+ <outputBaseDir>
+ target/GenerateTest1
</outputBaseDir>
</generator>
</codeGenerators>
</configuration>
</execution>
</executions>
-
<dependencies>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
</dependency>
</dependencies>
</plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>properties-maven-plugin</artifactId>
+ </plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
+<!-- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. This
+ program and the accompanying materials are made available under the terms of the
+ Eclipse Public License v1.0 which accompanies this distribution, and is available
+ at http://www.eclipse.org/legal/epl-v10.html -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <groupId>org.opendaylight.yangtools</groupId>
- <version>0.5-SNAPSHOT</version>
+ <parent>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>test-parent</artifactId>
+ <version>1.0</version>
+ </parent>
+
<artifactId>generator-test2</artifactId>
+ <properties>
+ <target.dir>${project.build.directory}</target.dir>
+ </properties>
<dependencies>
<dependency>
<artifactId>generator-test1</artifactId>
<version>${it-project.version}</version>
<scope>system</scope>
- <systemPath>${project.basedir}/../GenerateTest1/target/generator-test1-0.5-SNAPSHOT.jar</systemPath>
+ <systemPath>${project.basedir}/../GenerateTest1/target/generator-test1-1.0.jar</systemPath>
</dependency>
</dependencies>
</configuration>
</execution>
</executions>
-
<dependencies>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
</dependency>
</dependencies>
</plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>properties-maven-plugin</artifactId>
+ </plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
+<!-- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. This
+ program and the accompanying materials are made available under the terms of the
+ Eclipse Public License v1.0 which accompanies this distribution, and is available
+ at http://www.eclipse.org/legal/epl-v10.html -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
+
<parent>
- <artifactId>binding-generator</artifactId>
<groupId>org.opendaylight.yangtools</groupId>
- <version>${it-project.version}</version>
+ <artifactId>test-parent</artifactId>
+ <version>1.0</version>
</parent>
- <artifactId>test</artifactId>
+
+ <artifactId>generator</artifactId>
<build>
<plugins>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <groupId>org.opendaylight.yangtools</groupId>
- <version>0.5-SNAPSHOT</version>
- <artifactId>test</artifactId>
+ <parent>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>test-parent</artifactId>
+ <version>1.0</version>
+ </parent>
+
+ <artifactId>invalid-version</artifactId>
<!-- Testing dependency -->
- <!-- yang-common dependency added here only for purpose of 'artifact version
- check' test: version of yang-common artifact has to be different than one defined
+ <!-- yang-common dependency added here only for purpose of 'artifact version
+ check' test: version of yang-common artifact has to be different than one defined
in yang-maven-plugin to make test pass -->
<repositories>
<repository>
<?xml version="1.0" encoding="UTF-8"?>
<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
+<!-- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. This
+ program and the accompanying materials are made available under the terms of the
+ Eclipse Public License v1.0 which accompanies this distribution, and is available
+ at http://www.eclipse.org/legal/epl-v10.html -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <groupId>org.opendaylight.yangtools</groupId>
- <version>0.5-SNAPSHOT</version>
- <artifactId>generator-test2</artifactId>
+ <parent>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>test-parent</artifactId>
+ <version>1.0</version>
+ </parent>
+
+ <artifactId>missing-yang-in-dep</artifactId>
<build>
<plugins>
<?xml version="1.0" encoding="UTF-8"?>
<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!-- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. This
- program and the accompanying materials are made available under the terms of the
- Eclipse Public License v1.0 which accompanies this distribution, and is available
+<!-- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. This
+ program and the accompanying materials are made available under the terms of the
+ Eclipse Public License v1.0 which accompanies this distribution, and is available
at http://www.eclipse.org/legal/epl-v10.html -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <groupId>org.opendaylight.yangtools</groupId>
- <version>0.5-SNAPSHOT</version>
- <artifactId>test</artifactId>
+ <parent>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>test-parent</artifactId>
+ <version>1.0</version>
+ </parent>
+
+ <artifactId>naming-conflict</artifactId>
<build>
<plugins>
<?xml version="1.0" encoding="UTF-8"?>
<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
+<!-- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. This
+ program and the accompanying materials are made available under the terms of the
+ Eclipse Public License v1.0 which accompanies this distribution, and is available
+ at http://www.eclipse.org/legal/epl-v10.html -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
+ <parent>
<groupId>org.opendaylight.yangtools</groupId>
- <version>0.5-SNAPSHOT</version>
- <artifactId>test</artifactId>
+ <artifactId>test-parent</artifactId>
+ <version>1.0</version>
+ </parent>
+
+ <artifactId>no-generators</artifactId>
<build>
<plugins>
</configuration>
</execution>
</executions>
- <dependencies>
+ <dependencies>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-maven-plugin-spi</artifactId>
<?xml version="1.0" encoding="UTF-8"?>
<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
+<!-- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. This
+ program and the accompanying materials are made available under the terms of the
+ Eclipse Public License v1.0 which accompanies this distribution, and is available
+ at http://www.eclipse.org/legal/epl-v10.html -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>test</artifactId>
- <version>0.5-SNAPSHOT</version>
+ <parent>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>test-parent</artifactId>
+ <version>1.0</version>
+ </parent>
+
+ <artifactId>no-output-dir</artifactId>
<build>
<plugins>
<codeGeneratorClass>
org.opendaylight.yangtools.yang2sources.spi.CodeGeneratorTestImpl
</codeGeneratorClass>
- <outputBaseDir>
- target/NoOutputDir
+ <outputBaseDir>
+ target/NoOutputDir
</outputBaseDir>
</generator>
</codeGenerators>
<?xml version="1.0" encoding="UTF-8"?>
<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
+<!-- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. This
+ program and the accompanying materials are made available under the terms of the
+ Eclipse Public License v1.0 which accompanies this distribution, and is available
+ at http://www.eclipse.org/legal/epl-v10.html -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <groupId>org.opendaylight.yangtools</groupId>
- <version>0.5-SNAPSHOT</version>
- <artifactId>test</artifactId>
+ <parent>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>test-parent</artifactId>
+ <version>1.0</version>
+ </parent>
+
+ <artifactId>no-yang-files</artifactId>
<build>
<plugins>
<?xml version="1.0" encoding="UTF-8"?>
<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
+<!-- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. This
+ program and the accompanying materials are made available under the terms of the
+ Eclipse Public License v1.0 which accompanies this distribution, and is available
+ at http://www.eclipse.org/legal/epl-v10.html -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <groupId>org.opendaylight.yangtools</groupId>
- <version>0.5-SNAPSHOT</version>
+ <parent>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>test-parent</artifactId>
+ <version>1.0</version>
+ </parent>
- <artifactId>test</artifactId>
+ <artifactId>unknown-generator</artifactId>
<build>
<plugins>
<?xml version="1.0" encoding="UTF-8"?>
<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
+<!-- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. This
+ program and the accompanying materials are made available under the terms of the
+ Eclipse Public License v1.0 which accompanies this distribution, and is available
+ at http://www.eclipse.org/legal/epl-v10.html -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <groupId>org.opendaylight.yangtools</groupId>
- <version>0.5-SNAPSHOT</version>
+ <parent>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>test-parent</artifactId>
+ <version>1.0</version>
+ </parent>
- <artifactId>test</artifactId>
+ <artifactId>yang-root-not-exist</artifactId>
<build>
<plugins>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!-- Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. This
+ program and the accompanying materials are made available under the terms of the
+ Eclipse Public License v1.0 which accompanies this distribution, and is available
+ at http://www.eclipse.org/legal/epl-v10.html -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>test-parent</artifactId>
+ <version>1.0</version>
+ <packaging>pom</packaging>
+
+ <properties>
+ <it-project.version>0.6.2-SNAPSHOT</it-project.version>
+ </properties>
+
+ <modules>
+ <module>additional-config</module>
+ <module>correct</module>
+ <module>generate-test1</module>
+ <module>generate-test2</module>
+ <module>generator</module>
+ <module>invalid-version</module>
+ <module>missing-yang-in-dep</module>
+ <module>naming-conflict</module>
+ <module>no-generators</module>
+ <module>no-output-dir</module>
+ <module>no-yang-files</module>
+ <module>unknown-generator</module>
+ <module>yang-root-not-exist</module>
+ </modules>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>properties-maven-plugin</artifactId>
+ <version>1.0-alpha-2</version>
+ <executions>
+ <execution>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>write-project-properties</goal>
+ </goals>
+ <configuration>
+ <outputFile>it-project.properties</outputFile>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+</project>
import com.google.common.base.Splitter;
import com.google.common.collect.Collections2;
import com.google.common.io.ByteSource;
-
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
return schemaPath.createChild(qname);
}
- /**
- * Get module import referenced by given prefix.
- *
- * @param builder
- * module to search
- * @param prefix
- * prefix associated with import
- * @return ModuleImport based on given prefix
- */
- private static ModuleImport getModuleImport(final ModuleBuilder builder, final String prefix) {
- for (ModuleImport mi : builder.getModuleImports()) {
- if (mi.getPrefix().equals(prefix)) {
- return mi;
-
- }
- }
- return null;
- }
-
/**
* Find dependent module based on given prefix
*
} else if (prefix.equals(module.getPrefix())) {
dependentModule = module;
} else {
- ModuleImport dependentModuleImport = getModuleImport(module, prefix);
+ ModuleImport dependentModuleImport = module.getImport(prefix);
if (dependentModuleImport == null) {
throw new YangParseException(module.getName(), line, "No import found with prefix '" + prefix + "'.");
}
* @param currentModule
* current module
* @param prefix
- * current prefix used to reference dependent module
+ * prefix used to reference dependent module
* @param line
* current line in yang model
- * @return module based on given prefix if found in context, null otherwise
+ * @return module based on import with given prefix if found in context,
+ * null otherwise
+ * @throws YangParseException
+ * if no import found with given prefix
*/
public static Module findModuleFromContext(final SchemaContext context, final ModuleBuilder currentModule,
final String prefix, final int line) {
- if (context == null) {
- throw new YangParseException(currentModule.getName(), line, "Cannot find module with prefix '" + prefix
- + "'.");
- }
TreeMap<Date, Module> modulesByRevision = new TreeMap<>();
- ModuleImport dependentModuleImport = BuilderUtils.getModuleImport(currentModule, prefix);
+ ModuleImport dependentModuleImport = currentModule.getImport(prefix);
if (dependentModuleImport == null) {
throw new YangParseException(currentModule.getName(), line, "No import found with prefix '" + prefix + "'.");
}
} else {
result = modulesByRevision.get(dependentModuleRevision);
}
+ if (result == null) {
+ throw new YangParseException(currentModule.getName(), line, "Module not found for prefix " + prefix);
+ }
+
return result;
}
}
}
- /**
- * Set config flag to new value.
- *
- * @param node
- * node to update
- * @param config
- * new config value
- */
- private static void setNodeConfig(final DataSchemaNodeBuilder node, final Boolean config) {
- if (node instanceof ContainerSchemaNodeBuilder || node instanceof LeafSchemaNodeBuilder
- || node instanceof LeafListSchemaNodeBuilder || node instanceof ListSchemaNodeBuilder
- || node instanceof ChoiceBuilder || node instanceof AnyXmlBuilder) {
- node.setConfiguration(config);
- }
- if (node instanceof DataNodeContainerBuilder) {
- DataNodeContainerBuilder dataNodeChild = (DataNodeContainerBuilder) node;
- for (DataSchemaNodeBuilder inner : dataNodeChild.getChildNodeBuilders()) {
- setNodeConfig(inner, config);
- }
- } else if (node instanceof ChoiceBuilder) {
- ChoiceBuilder choiceChild = (ChoiceBuilder) node;
- for (ChoiceCaseBuilder inner : choiceChild.getCases()) {
- setNodeConfig(inner, config);
- }
- }
- }
-
public static DataSchemaNodeBuilder findSchemaNode(final List<QName> path, final SchemaNodeBuilder parentNode) {
DataSchemaNodeBuilder node = null;
SchemaNodeBuilder parent = parentNode;
throw new YangParseException(module.getName(), line, "Failed to parse identityref base: " + baseString);
}
- ModuleBuilder dependentModule = findModuleFromBuilders(modules, module, prefix, line);
+ ModuleBuilder dependentModule = getModuleByPrefix(module, prefix);
if (dependentModule == null) {
return null;
}
}
}
+ public static ModuleBuilder getModuleByPrefix(ModuleBuilder module, String prefix) {
+ if (prefix == null || prefix.isEmpty() || prefix.equals(module.getPrefix())) {
+ return module;
+ } else {
+ return module.getImportedModule(prefix);
+ }
+ }
+
}
package org.opendaylight.yangtools.yang.parser.builder.impl;
import com.google.common.base.Splitter;
-
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
-
-import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
import org.opendaylight.yangtools.yang.parser.builder.api.DataNodeContainerBuilder;
import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
}
/**
- * Common string splitter. Given a string representation of a grouping's name, it creates a prefix/name
- * pair and returns it.
+ * Common string splitter. Given a string representation of a grouping's
+ * name, it creates a prefix/name pair and returns it.
*
- * @param groupingString Grouping string reference
- * @param module Module which we are processing
- * @param line Module line which we are processing
- * @return An array of two strings, first one is the module prefix, the second is the grouping name.
+ * @param groupingString
+ * Grouping string reference
+ * @param module
+ * Module which we are processing
+ * @param line
+ * Module line which we are processing
+ * @return An array of two strings, first one is the module prefix, the
+ * second is the grouping name.
*/
private static String[] getPrefixAndName(final String groupingString, final ModuleBuilder module, final int line) {
final String[] ret = new String[2];
return null;
}
- GroupingBuilder result;
Set<GroupingBuilder> groupings = dependentModule.getGroupingBuilders();
- result = findGroupingBuilder(groupings, groupingName);
+ GroupingBuilder result = findGroupingBuilder(groupings, groupingName);
if (result != null) {
return result;
}
Builder parent = usesBuilder.getParent();
-
while (parent != null) {
if (parent instanceof DataNodeContainerBuilder) {
groupings = ((DataNodeContainerBuilder) parent).getGroupingBuilders();
}
if (result == null) {
- throw new YangParseException(module.getName(), line, "Referenced grouping '" + groupingName
- + "' not found.");
+ throw new YangParseException(module.getName(), line, "Grouping '" + groupingName + "' not found.");
}
return result;
}
- /**
- * Search context for grouping by name defined in uses node.
- *
- * @param usesBuilder
- * builder of uses statement
- * @param module
- * current module
- * @param context
- * SchemaContext containing already resolved modules
- * @return grouping with given name if found, null otherwise
- */
- public static GroupingDefinition getTargetGroupingFromContext(final UsesNodeBuilder usesBuilder,
- final ModuleBuilder module, final SchemaContext context) {
- final int line = usesBuilder.getLine();
- final String[] split = getPrefixAndName(usesBuilder.getGroupingPathAsString(), module, line);
- Module dependentModule = BuilderUtils.findModuleFromContext(context, module, split[0], line);
- return findGroupingDefinition(dependentModule.getGroupings(), split[1]);
- }
-
/**
* Find grouping by name.
*
return null;
}
- /**
- * Find grouping by name.
- *
- * @param groupings
- * collection of grouping definitions to search
- * @param name
- * name of grouping
- * @return grouping with given name if present in collection, null otherwise
- */
- private static GroupingDefinition findGroupingDefinition(final Set<GroupingDefinition> groupings, final String name) {
- for (GroupingDefinition grouping : groupings) {
- if (grouping.getQName().getLocalName().equals(name)) {
- return grouping;
- }
- }
- return null;
- }
-
/**
* Perform refinement of uses target grouping nodes. Uses process has to be
* already performed.
import java.util.Collections;
import java.util.Date;
import java.util.Deque;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
private final Deque<Builder> actualPath = new LinkedList<>();
private final Set<TypeAwareBuilder> dirtyNodes = new HashSet<>();
- final Set<ModuleImport> imports = new HashSet<>();
+ final Map<String, ModuleImport> imports = new HashMap<>();
+ final Map<String, ModuleBuilder> importedModules = new HashMap<>();
private final Set<AugmentationSchema> augments = new LinkedHashSet<>();
private final List<AugmentationSchemaBuilder> augmentBuilders = new ArrayList<>();
return qnameModule.getRevision();
}
- protected Set<ModuleImport> getImports() {
+ public ModuleImport getImport(final String prefix) {
+ return imports.get(prefix);
+ }
+
+ public Map<String, ModuleImport> getImports() {
return imports;
}
+ public ModuleBuilder getImportedModule(final String prefix) {
+ return importedModules.get(prefix);
+ }
+
+ public void addImportedModule(final String prefix, final ModuleBuilder module) {
+ checkPrefix(prefix);
+ importedModules.put(prefix, module);
+ }
+
protected String getSource() {
return source;
}
this.contact = contact;
}
- public boolean addModuleImport(final String moduleName, final Date revision, final String prefix) {
+ public void addModuleImport(final String moduleName, final Date revision, final String prefix) {
+ checkPrefix(prefix);
checkNotSealed();
final ModuleImport moduleImport = createModuleImport(moduleName, revision, prefix);
- return imports.add(moduleImport);
+ imports.put(prefix, moduleImport);
}
- public Set<ModuleImport> getModuleImports() {
- return imports;
+ private void checkPrefix(final String prefix) {
+ if (prefix == null || prefix.isEmpty()) {
+ throw new IllegalArgumentException("Cannot add imported module with undefined prefix");
+ }
+ if (prefix.equals(this.prefix)) {
+ throw new IllegalArgumentException("Cannot add imported module with prefix equals to module prefix");
+ }
}
public ExtensionBuilder addExtension(final QName qname, final int line, final SchemaPath path) {
((TypeAwareBuilder) parent).setType(type);
}
- public UnionTypeBuilder addUnionType(final int line, final URI namespace, final Date revision) {
+ public UnionTypeBuilder addUnionType(final int line, final QNameModule module) {
final Builder parent = getActualNode();
if (parent == null) {
throw new YangParseException(name, line, "Unresolved parent of union type");
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
-
import java.net.URI;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
-
import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.yang.common.QNameModule;
import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
super(builder);
this.name = checkNotNull(name, "Missing name");
this.sourcePath = sourcePath; //TODO: can this be nullable?
- this.imports = ImmutableSet.copyOf(builder.imports);
+ this.imports = ImmutableSet.<ModuleImport> copyOf(builder.imports.values());
this.prefix = builder.getPrefix();
this.qnameModule = QNameModule.create(builder.getNamespace(),
*/
package org.opendaylight.yangtools.yang.parser.builder.impl;
-import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findModuleFromBuilders;
-import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findModuleFromContext;
-
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TreeMap;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
*/
public static void resolveType(final TypeAwareBuilder nodeToResolve,
final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
- final int line = nodeToResolve.getLine();
final TypeDefinition<?> nodeToResolveType = nodeToResolve.getType();
final QName unknownTypeQName = nodeToResolveType.getBaseType().getQName();
- final ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module,
- unknownTypeQName.getPrefix(), line);
-
+ final ModuleBuilder dependentModuleBuilder = BuilderUtils.getModuleByPrefix(module, unknownTypeQName.getPrefix());
+ if (dependentModuleBuilder == null) {
+ throw new YangParseException(module.getName(), nodeToResolve.getLine(), "No module found for import "
+ + unknownTypeQName.getPrefix());
+ }
TypeDefinitionBuilder resolvedType = findUnknownTypeDefinition(nodeToResolve, dependentModuleBuilder, modules,
module);
nodeToResolve.setTypedef(resolvedType);
}
- /**
- * Resolve unknown type of node. It is assumed that type of node is either
- * UnknownType or ExtendedType with UnknownType as base type.
- *
- * @param nodeToResolve
- * node with type to resolve
- * @param modules
- * all loaded modules
- * @param module
- * current module
- * @param context
- * SchemaContext containing already resolved modules
- */
- public static void resolveTypeWithContext(final TypeAwareBuilder nodeToResolve,
- final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module,
- final SchemaContext context) {
- final int line = nodeToResolve.getLine();
- final TypeDefinition<?> nodeToResolveType = nodeToResolve.getType();
- final QName unknownTypeQName = nodeToResolveType.getBaseType().getQName();
- final ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module,
- unknownTypeQName.getPrefix(), line);
-
- if (dependentModuleBuilder == null) {
- final Module dependentModule = findModuleFromContext(context, module, unknownTypeQName.getPrefix(), line);
- final Set<TypeDefinition<?>> types = dependentModule.getTypeDefinitions();
- final TypeDefinition<?> type = findTypeByName(types, unknownTypeQName.getLocalName());
-
- if (nodeToResolveType instanceof ExtendedType) {
- final ExtendedType extType = (ExtendedType) nodeToResolveType;
- final TypeDefinitionBuilder newType = extendedTypeWithNewBase(null, type, extType, modules, module,
- nodeToResolve.getLine());
-
- nodeToResolve.setTypedef(newType);
- } else {
- if (nodeToResolve instanceof TypeDefinitionBuilder) {
- TypeDefinitionBuilder tdb = (TypeDefinitionBuilder) nodeToResolve;
- TypeConstraints tc = findConstraintsFromTypeBuilder(nodeToResolve,
- new TypeConstraints(module.getName(), nodeToResolve.getLine()), modules, module, context);
- tdb.setLengths(tc.getLength());
- tdb.setPatterns(tc.getPatterns());
- tdb.setRanges(tc.getRange());
- tdb.setFractionDigits(tc.getFractionDigits());
- }
- nodeToResolve.setType(type);
- }
-
- } else {
- TypeDefinitionBuilder resolvedType = findUnknownTypeDefinition(nodeToResolve, dependentModuleBuilder,
- modules, module);
- nodeToResolve.setTypedef(resolvedType);
- }
- }
-
- public static void resolveTypeUnion(final UnionTypeBuilder union,
- final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder builder) {
- final List<TypeDefinition<?>> unionTypes = union.getTypes();
- final List<TypeDefinition<?>> toRemove = new ArrayList<>();
- for (TypeDefinition<?> unionType : unionTypes) {
- if (unionType instanceof UnknownType) {
- final ModuleBuilder dependentModule = findModuleFromBuilders(modules, builder, unionType.getQName()
- .getPrefix(), union.getLine());
- final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(union, dependentModule, unionType
- .getQName().getLocalName(), builder.getName(), union.getLine());
- union.setTypedef(resolvedType);
- toRemove.add(unionType);
- } else if (unionType instanceof ExtendedType && unionType.getBaseType() instanceof UnknownType) {
- final UnknownType ut = (UnknownType) unionType.getBaseType();
- final ModuleBuilder dependentModule = findModuleFromBuilders(modules, builder, ut.getQName()
- .getPrefix(), union.getLine());
- final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(union, dependentModule, ut
- .getQName().getLocalName(), builder.getName(), union.getLine());
- final TypeDefinitionBuilder newType = extendedTypeWithNewBase(targetTypeBuilder, null,
- (ExtendedType) unionType, modules, builder, union.getLine());
- union.setTypedef(newType);
- toRemove.add(unionType);
- }
- }
- unionTypes.removeAll(toRemove);
- }
-
/**
* Resolve union type which contains one or more unresolved types.
*
* all loaded modules
* @param module
* current module
- * @param context
- * SchemaContext containing already resolved modules
*/
- public static void resolveTypeUnionWithContext(final UnionTypeBuilder union,
- final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module,
- final SchemaContext context) {
+ public static void resolveTypeUnion(final UnionTypeBuilder union,
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
final List<TypeDefinition<?>> unionTypes = union.getTypes();
final List<TypeDefinition<?>> toRemove = new ArrayList<>();
for (TypeDefinition<?> unionType : unionTypes) {
if (unionType instanceof UnknownType) {
- resolveUnionUnknownType(union, (UnknownType) unionType, modules, module, context);
+ resolveUnionUnknownType(union, (UnknownType) unionType, modules, module);
toRemove.add(unionType);
} else if (unionType instanceof ExtendedType && unionType.getBaseType() instanceof UnknownType) {
- resolveUnionUnknownType(union, (ExtendedType) unionType, modules, module, context);
+ resolveUnionUnknownType(union, (ExtendedType) unionType, modules, module);
toRemove.add(unionType);
}
}
}
private static void resolveUnionUnknownType(final UnionTypeBuilder union, final UnknownType ut,
- final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module,
- final SchemaContext context) {
- final int line = union.getLine();
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
final QName utQName = ut.getQName();
- final ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module, utQName.getPrefix(), line);
-
- if (dependentModuleBuilder == null) {
- Module dependentModule = findModuleFromContext(context, module, utQName.getPrefix(), line);
- Set<TypeDefinition<?>> types = dependentModule.getTypeDefinitions();
- TypeDefinition<?> type = findTypeByName(types, utQName.getLocalName());
- union.setType(type);
- } else {
- final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(union, dependentModuleBuilder,
- utQName.getLocalName(), module.getName(), union.getLine());
- union.setTypedef(resolvedType);
- }
+ final ModuleBuilder dependentModuleBuilder = BuilderUtils.getModuleByPrefix(module, utQName.getPrefix());
+ final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(union, dependentModuleBuilder,
+ utQName.getLocalName(), module.getName(), union.getLine());
+ union.setTypedef(resolvedType);
}
private static void resolveUnionUnknownType(final UnionTypeBuilder union, final ExtendedType extType,
- final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module,
- final SchemaContext context) {
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
final int line = union.getLine();
final TypeDefinition<?> extTypeBase = extType.getBaseType();
final UnknownType ut = (UnknownType) extTypeBase;
final QName utQName = ut.getQName();
- final ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module, utQName.getPrefix(), line);
-
- if (dependentModuleBuilder == null) {
- final Module dependentModule = findModuleFromContext(context, module, utQName.getPrefix(), line);
- Set<TypeDefinition<?>> types = dependentModule.getTypeDefinitions();
- TypeDefinition<?> type = findTypeByName(types, utQName.getLocalName());
- final TypeDefinitionBuilder newType = extendedTypeWithNewBase(null, type, extType, modules, module, 0);
- union.setTypedef(newType);
- } else {
- final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(union, dependentModuleBuilder,
- utQName.getLocalName(), module.getName(), line);
- final TypeDefinitionBuilder newType = extendedTypeWithNewBase(targetTypeBuilder, null, extType, modules,
- module, line);
- union.setTypedef(newType);
- }
+ final ModuleBuilder dependentModuleBuilder = BuilderUtils.getModuleByPrefix(module, utQName.getPrefix());
+ final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(union, dependentModuleBuilder,
+ utQName.getLocalName(), module.getName(), line);
+ final TypeDefinitionBuilder newType = extendedTypeWithNewBase(targetTypeBuilder, null, extType, modules,
+ module, line);
+ union.setTypedef(newType);
}
/**
// validate constraints
final TypeConstraints constraints = findConstraintsFromTypeBuilder(nodeToResolve,
- new TypeConstraints(module.getName(), nodeToResolve.getLine()), modules, module, null);
+ new TypeConstraints(module.getName(), nodeToResolve.getLine()), modules, module);
constraints.validateConstraints();
return resolvedType;
return null;
}
- /**
- * Find type by name.
- *
- * @param types
- * collection of types
- * @param typeName
- * type name
- * @return type with given name if it is present in collection, null
- * otherwise
- */
- private static TypeDefinition<?> findTypeByName(Set<TypeDefinition<?>> types, String typeName) {
- for (TypeDefinition<?> type : types) {
- if (type.getQName().getLocalName().equals(typeName)) {
- return type;
- }
- }
- return null;
- }
-
/**
* Pull restriction from type and add them to constraints.
*
tc.addLengths(oldExtendedType.getLengthConstraints());
tc.addPatterns(oldExtendedType.getPatternConstraints());
tc.addRanges(oldExtendedType.getRangeConstraints());
- constraints = findConstraintsFromTypeBuilder(newBaseTypeBuilder, tc, modules, module, null);
+ constraints = findConstraintsFromTypeBuilder(newBaseTypeBuilder, tc, modules, module);
newType.setTypedef(newBaseTypeBuilder);
} else {
constraints = findConstraintsFromTypeDefinition(newBaseType, tc);
private static TypeConstraints findConstraintsFromTypeBuilder(final TypeAwareBuilder nodeToResolve,
final TypeConstraints constraints, final Map<String, TreeMap<Date, ModuleBuilder>> modules,
- final ModuleBuilder builder, final SchemaContext context) {
+ final ModuleBuilder builder) {
// union and identityref types cannot be restricted
if (nodeToResolve instanceof UnionTypeBuilder || nodeToResolve instanceof IdentityrefTypeBuilder) {
TypeDefinition<?> type = nodeToResolve.getType();
if (type == null) {
- return findConstraintsFromTypeBuilder(nodeToResolve.getTypedef(), constraints, modules, builder, context);
+ return findConstraintsFromTypeBuilder(nodeToResolve.getTypedef(), constraints, modules, builder);
} else {
QName qname = type.getQName();
if (type instanceof UnknownType) {
- ModuleBuilder dependentModuleBuilder = BuilderUtils.findModuleFromBuilders(modules, builder,
- qname.getPrefix(), nodeToResolve.getLine());
- if (dependentModuleBuilder == null) {
- if (context == null) {
- throw new YangParseException(builder.getName(), nodeToResolve.getLine(),
- "Failed to resolved type constraints.");
- }
- Module dm = BuilderUtils.findModuleFromContext(context, builder, qname.getPrefix(),
- nodeToResolve.getLine());
- TypeDefinition<?> t = findTypeByName(dm.getTypeDefinitions(), qname.getLocalName());
- return mergeConstraints(t, constraints);
-
- } else {
- TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve, dependentModuleBuilder,
- qname.getLocalName(), builder.getName(), nodeToResolve.getLine());
- return findConstraintsFromTypeBuilder(tdb, constraints, modules, dependentModuleBuilder, context);
- }
+ ModuleBuilder dependentModuleBuilder = BuilderUtils.getModuleByPrefix(builder, qname.getPrefix());
+ TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve, dependentModuleBuilder,
+ qname.getLocalName(), builder.getName(), nodeToResolve.getLine());
+ return findConstraintsFromTypeBuilder(tdb, constraints, modules, dependentModuleBuilder);
} else if (type instanceof ExtendedType) {
mergeConstraints(type, constraints);
TypeDefinition<?> base = ((ExtendedType) type).getBaseType();
if (base instanceof UnknownType) {
- ModuleBuilder dependentModule = BuilderUtils.findModuleFromBuilders(modules, builder, base
- .getQName().getPrefix(), nodeToResolve.getLine());
+ ModuleBuilder dependentModule = BuilderUtils.getModuleByPrefix(builder, base.getQName().getPrefix());
TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve, dependentModule, base
.getQName().getLocalName(), builder.getName(), nodeToResolve.getLine());
- return findConstraintsFromTypeBuilder(tdb, constraints, modules, dependentModule, context);
+ return findConstraintsFromTypeBuilder(tdb, constraints, modules, dependentModule);
} else {
// it has to be base yang type
return mergeConstraints(type, constraints);
*/
package org.opendaylight.yangtools.yang.parser.builder.util;
+import com.google.common.collect.Iterables;
import java.util.Comparator;
+import java.util.Iterator;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
public final class Comparators {
/**
- * Comparator based on alphabetical order of local name of SchemaNode's qname.
+ * Comparator based on alphabetical order of local name of SchemaNode's
+ * qname.
*/
public static final SchemaNodeComparator SCHEMA_NODE_COMP = new SchemaNodeComparator();
/**
- * Comparator based on augment target path length.
+ * Comparator based on augment target path.
*/
- @Deprecated
public static final AugmentComparator AUGMENT_COMP = new AugmentComparator();
+ public static final AugmentBuilderComparator AUGMENT_BUILDER_COMP = new AugmentBuilderComparator();
+
private Comparators() {
}
}
}
- private static final class AugmentComparator implements Comparator<AugmentationSchemaBuilder> {
+ private static final class AugmentBuilderComparator implements Comparator<AugmentationSchemaBuilder> {
+ @Override
+ public int compare(AugmentationSchemaBuilder o1, AugmentationSchemaBuilder o2) {
+ int length1 = Iterables.size(o1.getTargetPath().getPathFromRoot());
+ int length2 = Iterables.size(o2.getTargetPath().getPathFromRoot());
+ return length1 - length2;
+ }
+ }
+
+ private static final class AugmentComparator implements Comparator<AugmentationSchema> {
@Override
- public int compare(final AugmentationSchemaBuilder o1, final AugmentationSchemaBuilder o2) {
- return o1.getTargetPath().getPath().size() - o2.getTargetPath().getPath().size();
+ public int compare(AugmentationSchema augSchema1, AugmentationSchema augSchema2) {
+ final Iterator<QName> thisIt = augSchema1.getTargetPath().getPathFromRoot().iterator();
+ final Iterator<QName> otherIt = augSchema2.getTargetPath().getPathFromRoot().iterator();
+
+ while (thisIt.hasNext()) {
+ if (otherIt.hasNext()) {
+ final int comp = thisIt.next().compareTo(otherIt.next());
+ if (comp != 0) {
+ return comp;
+ }
+ } else {
+ return 1;
+ }
+ }
+ if (otherIt.hasNext()) {
+ return -1;
+ }
+ return 0;
}
}
import java.math.BigDecimal;
import java.math.BigInteger;
-import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Date;
import java.util.Iterator;
import java.util.List;
-import java.util.Stack;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ParseTree;
return null;
}
- /**
- * Create SchemaPath from actualPath and new node name.
- *
- * @param actualPath
- * current position in model
- * @return SchemaPath object
- */
- public static SchemaPath createActualSchemaPath(final Stack<QName> actualPath) {
- return SchemaPath.create(actualPath, true);
- }
-
/**
* Create java.util.List of key node names.
*
* @return List of EnumPair object parsed from given context
*/
private static List<EnumTypeDefinition.EnumPair> getEnumConstants(final Type_body_stmtsContext ctx,
- final Stack<QName> path, final String moduleName) {
+ final SchemaPath path, final String moduleName) {
List<EnumTypeDefinition.EnumPair> enumConstants = new ArrayList<>();
for (int i = 0; i < ctx.getChildCount(); i++) {
* @return EnumPair object parsed from given context
*/
private static EnumTypeDefinition.EnumPair createEnumPair(final Enum_stmtContext ctx, final int highestValue,
- final Stack<QName> actualPath, final String moduleName) {
+ final SchemaPath actualPath, final String moduleName) {
final String name = stringFromNode(ctx);
SchemaPath path = createTypePath(actualPath, name);
Integer value = null;
* @return PatternConstraint object
*/
private static PatternConstraint parsePatternConstraint(final Pattern_stmtContext ctx) {
- String description = null;
- String reference = null;
+ Optional<String> description = Optional.absent();
+ Optional<String> reference = Optional.absent();
for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree child = ctx.getChild(i);
if (child instanceof Description_stmtContext) {
- description = stringFromNode(child);
+ description = Optional.of(stringFromNode(child));
} else if (child instanceof Reference_stmtContext) {
- reference = stringFromNode(child);
+ reference = Optional.of(stringFromNode(child));
}
}
String pattern = parsePatternString(ctx);
- return BaseConstraints.patternConstraint(pattern, description, reference);
+ return BaseConstraints.newPatternConstraint(pattern, description, reference);
}
/**
* current module name
* @return List of Bit objects created from this context
*/
- private static List<BitsTypeDefinition.Bit> getBits(final Type_body_stmtsContext ctx, final Stack<QName> actualPath,
+ private static List<BitsTypeDefinition.Bit> getBits(final Type_body_stmtsContext ctx, final SchemaPath actualPath,
final String moduleName) {
final List<BitsTypeDefinition.Bit> bits = new ArrayList<>();
for (int j = 0; j < ctx.getChildCount(); j++) {
* @return Bit object parsed from this context
*/
private static BitsTypeDefinition.Bit parseBit(final Bit_stmtContext ctx, final long highestPosition,
- final Stack<QName> actualPath, final String moduleName) {
+ final SchemaPath actualPath, final String moduleName) {
String name = stringFromNode(ctx);
Long position = null;
* @return UnknownType object with constraints from parsed type body
*/
public static TypeDefinition<?> parseUnknownTypeWithBody(final QName typedefQName,
- final Type_body_stmtsContext ctx, final Stack<QName> actualPath, final URI namespace, final Date revision,
- final String prefix, final Builder parent) {
+ final Type_body_stmtsContext ctx, final SchemaPath actualPath, final QName moduleQName, final Builder parent) {
String moduleName = parent.getModuleName();
String typeName = typedefQName.getLocalName();
return unknownType.build();
} else {
TypeDefinition<?> baseType = unknownType.build();
- QName qname = new QName(namespace, revision, prefix, typeName);
+ QName qname = QName.create(moduleQName, typeName);
SchemaPath schemaPath = createTypePath(actualPath, typeName);
- ExtendedType.Builder typeBuilder = new ExtendedType.Builder(qname, baseType, null, null, schemaPath);
+ ExtendedType.Builder typeBuilder = ExtendedType.builder(qname, baseType, Optional.<String>absent(), Optional.<String>absent(), schemaPath);
typeBuilder.ranges(rangeStatements);
typeBuilder.lengths(lengthStatements);
typeBuilder.patterns(patternStatements);
* @return TypeDefinition object based on parsed values.
*/
public static TypeDefinition<?> parseTypeWithBody(final String typeName, final Type_body_stmtsContext typeBody,
- final Stack<QName> actualPath, final URI namespace, final Date revision, final String prefix,
- final Builder parent) {
+ final SchemaPath actualPath, final QName moduleQName, final Builder parent) {
final String moduleName = parent.getModuleName();
final int line = typeBody.getStart().getLine();
constraints.addRanges(rangeStatements);
SchemaPath baseTypePath = createBaseTypePath(actualPath, typeName);
- SchemaPath extBaseTypePath = createExtendedBaseTypePath(actualPath, namespace, revision, prefix, typeName);
+ SchemaPath extBaseTypePath = createExtendedBaseTypePath(actualPath, moduleQName, typeName);
if (parent instanceof TypeDefinitionBuilder && !(parent instanceof UnionTypeBuilder)) {
extBaseTypePath = baseTypePath;
if ("decimal64".equals(typeName)) {
if (rangeStatements.isEmpty()) {
try {
- return new Decimal64(baseTypePath, fractionDigits);
+ return Decimal64.create(baseTypePath, fractionDigits);
} catch(Exception e) {
throw new YangParseException(moduleName, line, e.getMessage());
}
}
- Decimal64 decimalType = new Decimal64(extBaseTypePath, fractionDigits);
+ Decimal64 decimalType = Decimal64.create(extBaseTypePath, fractionDigits);
constraints.addRanges(decimalType.getRangeConstraints());
baseType = decimalType;
} else if (typeName.startsWith("int")) {
return baseType;
}
- List<QName> path = new ArrayList<>(actualPath);
- path.add(new QName(namespace, revision, prefix, typeName));
- SchemaPath schemaPath = SchemaPath.create(path, true);
-
- QName qname = schemaPath.getPath().get(schemaPath.getPath().size() - 1);
- ExtendedType.Builder typeBuilder = new ExtendedType.Builder(qname, baseType, "", "", schemaPath);
+ QName qname = QName.create(moduleQName, typeName);
+ SchemaPath schemaPath = actualPath.createChild(qname);
+ final Optional<String> opt = Optional.of("");
+ ExtendedType.Builder typeBuilder = ExtendedType.builder(qname, baseType, opt, opt, schemaPath);
typeBuilder.ranges(constraints.getRange());
typeBuilder.lengths(constraints.getLength());
return typeBuilder.build();
}
- private static SchemaPath createTypePath(final Stack<QName> actual, final String typeName) {
- QName last = actual.peek();
- QName typeQName = QName.create(last, typeName);
- List<QName> path = new ArrayList<>(actual);
- path.add(typeQName);
- return SchemaPath.create(path, true);
+ private static SchemaPath createTypePath(final SchemaPath actual, final String typeName) {
+ QName last = actual.getLastComponent();
+ return actual.createChild(QName.create(last, typeName));
}
- private static SchemaPath createBaseTypePath(final Stack<QName> actual, final String typeName) {
- List<QName> path = new ArrayList<>(actual);
- path.add(BaseTypes.constructQName(typeName));
- return SchemaPath.create(path, true);
+ private static SchemaPath createBaseTypePath(final SchemaPath actual, final String typeName) {
+ return actual.createChild(BaseTypes.constructQName(typeName));
}
- private static SchemaPath createExtendedBaseTypePath(final Stack<QName> actual, final URI namespace, final Date revision,
- final String prefix, final String typeName) {
- QName extTypeName = new QName(namespace, revision, prefix, typeName);
- QName baseTypeName = BaseTypes.constructQName(typeName);
- List<QName> path = new ArrayList<>(actual);
- path.add(extTypeName);
- path.add(baseTypeName);
- return SchemaPath.create(path, true);
+ private static SchemaPath createExtendedBaseTypePath(final SchemaPath actual, final QName moduleQName, final String typeName) {
+ return actual.createChild(
+ QName.create(moduleQName, typeName),
+ BaseTypes.constructQName(typeName));
}
/**
*/
private static MustDefinition parseMust(final YangParser.Must_stmtContext ctx) {
StringBuilder mustText = new StringBuilder();
- String description = null;
- String reference = null;
- String errorAppTag = null;
- String errorMessage = null;
+ Optional<String> description = Optional.absent();
+ Optional<String> reference = Optional.absent();
+ Optional<String> errorAppTag = Optional.absent();
+ Optional<String> errorMessage = Optional.absent();
for (int i = 0; i < ctx.getChildCount(); ++i) {
ParseTree child = ctx.getChild(i);
if (child instanceof StringContext) {
}
}
} else if (child instanceof Description_stmtContext) {
- description = stringFromNode(child);
+ description = Optional.of(stringFromNode(child));
} else if (child instanceof Reference_stmtContext) {
- reference = stringFromNode(child);
+ reference = Optional.of(stringFromNode(child));
} else if (child instanceof Error_app_tag_stmtContext) {
- errorAppTag = stringFromNode(child);
+ errorAppTag = Optional.of(stringFromNode(child));
} else if (child instanceof Error_message_stmtContext) {
- errorMessage = stringFromNode(child);
+ errorMessage = Optional.of(stringFromNode(child));
}
}
- return new MustDefinitionImpl(mustText.toString(), description, reference, errorAppTag, errorMessage);
+ return MustDefinitionImpl.create(mustText.toString(), description, reference, errorAppTag, errorMessage);
}
/**
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.impl;
+
+import com.google.common.base.Preconditions;
+
+import java.util.Deque;
+import java.util.LinkedList;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+final class SchemaPathStack {
+ private final Deque<SchemaPath> paths = new LinkedList<>();
+
+ SchemaPath addNodeToPath(final QName name) {
+ SchemaPath sp = paths.pop();
+ sp = sp.createChild(name);
+ paths.push(sp);
+ return sp;
+ }
+
+ QName removeNodeFromPath() {
+ SchemaPath sp = paths.pop();
+ QName ret = sp.getLastComponent();
+ paths.push(Preconditions.checkNotNull(sp.getParent(), "Attempted to remove too many nodes from schemapath at stack {}", paths));
+ return ret;
+ }
+
+ SchemaPath currentSchemaPath() {
+ return paths.peek();
+ }
+
+ void pop() {
+ paths.pop();
+ }
+
+ void push() {
+ paths.push(SchemaPath.ROOT);
+ }
+}
import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findSchemaNodeInModule;
import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.processAugmentation;
import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.setNodeAddedByUses;
-import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.wrapChildNode;
import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.wrapChildNodes;
import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.wrapGroupings;
import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.wrapTypedefs;
import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.wrapUnknownNodes;
import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.resolveType;
import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.resolveTypeUnion;
-import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.resolveTypeUnionWithContext;
-import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.resolveTypeWithContext;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.HashBiMap;
import com.google.common.io.ByteSource;
-
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
-
import javax.annotation.concurrent.Immutable;
-
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.YangContext;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
import org.opendaylight.yangtools.yang.model.api.ModuleImport;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser;
import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
@Override
public SchemaContext parseFile(final File yangFile, final File directory) throws IOException,
- YangSyntaxErrorException {
+ YangSyntaxErrorException {
Preconditions.checkState(yangFile.exists(), yangFile + " does not exists");
Preconditions.checkState(directory.exists(), directory + " does not exists");
Preconditions.checkState(directory.isDirectory(), directory + " is not a directory");
// module builders sorted by dependencies
List<ModuleBuilder> sortedBuilders = ModuleDependencySort.sort(resolved);
- LinkedHashMap<String, TreeMap<Date, ModuleBuilder>> modules = orderModules(sortedBuilders);
+ LinkedHashMap<String, TreeMap<Date, ModuleBuilder>> modules = resolveModulesWithImports(sortedBuilders, null);
Collection<Module> unsorted = build(modules).values();
Set<Module> result = new LinkedHashSet<>(
ModuleDependencySort.sort(unsorted.toArray(new Module[unsorted.size()])));
@Override
public SchemaContext parseFiles(final Collection<File> yangFiles, final SchemaContext context) throws IOException,
- YangSyntaxErrorException {
+ YangSyntaxErrorException {
if (yangFiles == null) {
return resolveSchemaContext(Collections.<Module> emptySet());
}
@Override
public SchemaContext parseSources(final Collection<ByteSource> sources) throws IOException,
- YangSyntaxErrorException {
+ YangSyntaxErrorException {
Collection<Module> unsorted = parseYangModelSources(sources).values();
Set<Module> sorted = new LinkedHashSet<>(
ModuleDependencySort.sort(unsorted.toArray(new Module[unsorted.size()])));
return resolveSchemaContext(Collections.<Module> emptySet());
}
- final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuilders(sources, context);
- final Set<Module> unsorted = new LinkedHashSet<>(buildWithContext(modules, context).values());
+ final List<ModuleBuilder> sorted = resolveModuleBuilders(sources, context);
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModulesWithImports(sorted, context);
+
+ final Set<Module> unsorted = new LinkedHashSet<>(build(modules).values());
if (context != null) {
for (Module m : context.getModules()) {
if (!unsorted.contains(m)) {
return resolveSchemaContext(result);
}
+ private LinkedHashMap<String, TreeMap<Date, ModuleBuilder>> resolveModulesWithImports(List<ModuleBuilder> sorted,
+ SchemaContext context) {
+ final LinkedHashMap<String, TreeMap<Date, ModuleBuilder>> modules = orderModules(sorted);
+ for (ModuleBuilder module : sorted) {
+ if (module != null) {
+ for (ModuleImport imp : module.getImports().values()) {
+ String prefix = imp.getPrefix();
+ ModuleBuilder targetModule = findModuleFromBuilders(modules, module, prefix, 0);
+ if (targetModule == null) {
+ Module result = findModuleFromContext(context, module, prefix, 0);
+ targetModule = new ModuleBuilder(result);
+ TreeMap<Date, ModuleBuilder> map = modules.get(prefix);
+ if (map == null) {
+ map = new TreeMap<>();
+ map.put(targetModule.getRevision(), targetModule);
+ modules.put(targetModule.getName(), map);
+ } else {
+ map.put(targetModule.getRevision(), targetModule);
+ }
+ }
+ module.addImportedModule(prefix, targetModule);
+ }
+ }
+ }
+ return modules;
+ }
+
@Override
public Map<File, Module> parseYangModelsMapped(final Collection<File> yangFiles) {
if (yangFiles == null || yangFiles.isEmpty()) {
}
private Map<ByteSource, Module> parseYangModelSources(final Collection<ByteSource> sources) throws IOException,
- YangSyntaxErrorException {
+ YangSyntaxErrorException {
if (sources == null || sources.isEmpty()) {
return Collections.emptyMap();
}
Map<ByteSource, ModuleBuilder> sourceToBuilder = resolveSources(sources);
// sort and check for duplicates
List<ModuleBuilder> sorted = ModuleDependencySort.sort(sourceToBuilder.values());
- Map<String, TreeMap<Date, ModuleBuilder>> modules = orderModules(sorted);
+ Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModulesWithImports(sorted, null);
Map<ModuleBuilder, Module> builderToModule = build(modules);
Map<ModuleBuilder, ByteSource> builderToSource = HashBiMap.create(sourceToBuilder).inverse();
sorted = ModuleDependencySort.sort(builderToModule.keySet());
* @throws YangSyntaxErrorException
*/
// TODO: remove ByteSource result after removing YangModelParser
- private Map<ByteSource, ModuleBuilder> resolveSources(final Collection<ByteSource> streams)
- throws IOException, YangSyntaxErrorException {
+ private Map<ByteSource, ModuleBuilder> resolveSources(final Collection<ByteSource> streams) throws IOException,
+ YangSyntaxErrorException {
Map<ByteSource, ModuleBuilder> builders = parseSourcesToBuilders(streams);
return resolveSubmodules(builders);
}
for (Map.Entry<ByteSource, ParseTree> entry : sourceToTree.entrySet()) {
ByteSource source = entry.getKey();
String path = null; // TODO refactor to Optional
- //TODO refactor so that path can be retrieved without opening stream: NamedInputStream -> NamedByteSource ?
- try(InputStream stream = source.openStream()) {
+ // TODO refactor so that path can be retrieved without opening
+ // stream: NamedInputStream -> NamedByteSource ?
+ try (InputStream stream = source.openStream()) {
if (stream instanceof NamedInputStream) {
path = stream.toString();
}
private void addSubmoduleToModule(final ModuleBuilder submodule, final ModuleBuilder module) {
submodule.setParent(module);
module.getDirtyNodes().addAll(submodule.getDirtyNodes());
- module.getModuleImports().addAll(submodule.getModuleImports());
+ module.getImports().putAll(submodule.getImports());
module.getAugments().addAll(submodule.getAugments());
module.getAugmentBuilders().addAll(submodule.getAugmentBuilders());
module.getAllAugments().addAll(submodule.getAllAugments());
module.getAllUnknownNodes().addAll(submodule.getAllUnknownNodes());
}
- private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuilders(
- final Collection<ByteSource> yangFileStreams, final SchemaContext context) throws IOException,
- YangSyntaxErrorException {
+ private List<ModuleBuilder> resolveModuleBuilders(final Collection<ByteSource> yangFileStreams,
+ final SchemaContext context) throws IOException, YangSyntaxErrorException {
Map<ByteSource, ModuleBuilder> parsedBuilders = resolveSources(yangFileStreams);
ModuleBuilder[] builders = new ModuleBuilder[parsedBuilders.size()];
parsedBuilders.values().toArray(builders);
} else {
sorted = ModuleDependencySort.sortWithContext(context, builders);
}
- return orderModules(sorted);
+ return sorted;
}
/**
* Order modules by name and revision.
*
* @param modules
- * modules to order
+ * topologically sorted modules
* @return modules ordered by name and revision
*/
private LinkedHashMap<String, TreeMap<Date, ModuleBuilder>> orderModules(final List<ModuleBuilder> modules) {
TreeMap<Date, ModuleBuilder> builderByRevision = result.get(builderName);
if (builderByRevision == null) {
builderByRevision = new TreeMap<>();
+ builderByRevision.put(builderRevision, builder);
+ result.put(builderName, builderByRevision);
+ } else {
+ builderByRevision.put(builderRevision, builder);
}
- builderByRevision.put(builderRevision, builder);
- result.put(builderName, builderByRevision);
}
return result;
}
*/
private void filterImports(final ModuleBuilder main, final Collection<ModuleBuilder> other,
final Collection<ModuleBuilder> filtered) {
- Set<ModuleImport> imports = main.getModuleImports();
+ Map<String, ModuleImport> imports = main.getImports();
// if this is submodule, add parent to filtered and pick its imports
if (main.isSubmodule()) {
}
ModuleBuilder parent = dependencies.get(dependencies.firstKey());
filtered.add(parent);
- imports.addAll(parent.getModuleImports());
+ imports.putAll(parent.getImports());
}
- for (ModuleImport mi : imports) {
+ for (ModuleImport mi : imports.values()) {
for (ModuleBuilder builder : other) {
if (mi.getModuleName().equals(builder.getModuleName())) {
if (mi.getRevision() == null) {
}
private Map<ByteSource, ParseTree> parseYangSources(final Collection<ByteSource> sources) throws IOException,
- YangSyntaxErrorException {
+ YangSyntaxErrorException {
final Map<ByteSource, ParseTree> trees = new HashMap<>();
for (ByteSource source : sources) {
trees.put(source, parseYangSource(source));
}
/**
- * Mini parser: This parsing context does not validate full YANG module, only
- * parses header up to the revisions and imports.
+ * Mini parser: This parsing context does not validate full YANG module,
+ * only parses header up to the revisions and imports.
+ *
* @see org.opendaylight.yangtools.yang.parser.impl.util.YangModelDependencyInfo
*/
public static YangContext parseStreamWithoutErrorListeners(final InputStream yangStream) {
*/
private Map<ModuleBuilder, Module> build(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
resolveDirtyNodes(modules);
- resolveAugmentsTargetPath(modules, null);
- resolveUsesTargetGrouping(modules, null);
- resolveUsesForGroupings(modules, null);
- resolveUsesForNodes(modules, null);
- resolveAugments(modules, null);
+ resolveAugmentsTargetPath(modules);
+ resolveUsesTargetGrouping(modules);
+ resolveUsesForGroupings(modules);
+ resolveUsesForNodes(modules);
+ resolveAugments(modules);
resolveIdentities(modules);
resolveDeviations(modules);
return result;
}
- /**
- * Creates builder-to-module map based on given modules. Method first
- * resolve unresolved type references, instantiate groupings through uses
- * statements and perform augmentation.
- *
- * Node resolving must be performed in following order:
- * <ol>
- * <li>
- * unresolved type references</li>
- * <li>
- * uses in groupings</li>
- * <li>
- * uses in other nodes</li>
- * <li>
- * augments</li>
- * </ol>
- *
- * @param modules
- * all loaded modules
- * @param context
- * SchemaContext containing already resolved modules
- * @return modules mapped on their builders
- */
- private Map<ModuleBuilder, Module> buildWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
- final SchemaContext context) {
- resolvedDirtyNodesWithContext(modules, context);
- resolveAugmentsTargetPath(modules, context);
- resolveUsesTargetGrouping(modules, context);
- resolveUsesForGroupings(modules, context);
- resolveUsesForNodes(modules, context);
- resolveAugments(modules, context);
- resolveIdentitiesWithContext(modules, context);
- resolveDeviationsWithContext(modules, context);
-
- // build
- final Map<ModuleBuilder, Module> result = new LinkedHashMap<>();
- for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
- for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
- final ModuleBuilder moduleBuilder = childEntry.getValue();
- final Module module = moduleBuilder.build();
- result.put(moduleBuilder, module);
- }
- }
- return result;
- }
-
/**
* Resolve all unresolved type references.
*
}
}
- /**
- * Resolve all unresolved type references.
- *
- * @param modules
- * all loaded modules
- * @param context
- * SchemaContext containing already resolved modules
- */
- private void resolvedDirtyNodesWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
- final SchemaContext context) {
- for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
- for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue().entrySet()) {
- final ModuleBuilder module = childEntry.getValue();
- resolveUnknownNodesWithContext(modules, module, context);
- resolveDirtyNodesWithContext(modules, module, context);
- }
- }
- }
-
/**
* Search for dirty nodes (node which contains UnknownType) and resolve
* unknown types.
}
}
- private void resolveDirtyNodesWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
- final ModuleBuilder module, final SchemaContext context) {
- final Set<TypeAwareBuilder> dirtyNodes = module.getDirtyNodes();
- if (!dirtyNodes.isEmpty()) {
- for (TypeAwareBuilder nodeToResolve : dirtyNodes) {
- if (nodeToResolve instanceof UnionTypeBuilder) {
- // special handling for union types
- resolveTypeUnionWithContext((UnionTypeBuilder) nodeToResolve, modules, module, context);
- } else if (nodeToResolve.getTypedef() instanceof IdentityrefTypeBuilder) {
- // special handling for identityref types
- IdentityrefTypeBuilder idref = (IdentityrefTypeBuilder) nodeToResolve.getTypedef();
- IdentitySchemaNodeBuilder identity = findBaseIdentity(modules, module, idref.getBaseString(),
- idref.getLine());
- idref.setBaseIdentity(identity);
- nodeToResolve.setType(idref.build());
- } else {
- resolveTypeWithContext(nodeToResolve, modules, module, context);
- }
- }
- }
- }
-
/**
* Traverse through augmentations of modules and fix their child nodes
* schema path.
*
* @param modules
* all loaded modules
- * @param context
- * SchemaContext containing already resolved modules
*/
- private void resolveAugmentsTargetPath(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
- final SchemaContext context) {
+ private void resolveAugmentsTargetPath(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
// collect augments from all loaded modules
final List<AugmentationSchemaBuilder> allAugments = new ArrayList<>();
for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
}
for (AugmentationSchemaBuilder augment : allAugments) {
- setCorrectAugmentTargetPath(modules, augment, context);
+ setCorrectAugmentTargetPath(modules, augment);
}
}
* all loaded modules
* @param augment
* augment to resolve
- * @param context
- * SchemaContext containing already resolved modules
*/
private void setCorrectAugmentTargetPath(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
- final AugmentationSchemaBuilder augment, final SchemaContext context) {
+ final AugmentationSchemaBuilder augment) {
ModuleBuilder module = BuilderUtils.getParentModule(augment);
- SchemaPath oldSchemaPath = augment.getTargetPath();
+ Iterable<QName> oldPath = augment.getTargetPath().getPathFromRoot();
List<QName> newPath = new ArrayList<>();
Builder parent = augment.getParent();
DataNodeContainerBuilder usesParent = ((UsesNodeBuilder) parent).getParent();
newPath.addAll(usesParent.getPath().getPath());
- final QName baseQName = usesParent.getQName();
+ QName baseQName = usesParent.getQName();
final QNameModule qnm;
- final String prefix;
+ String prefix;
if (baseQName == null) {
ModuleBuilder m = BuilderUtils.getParentModule(usesParent);
qnm = m.getQNameModule();
prefix = baseQName.getPrefix();
}
- for (QName qn : oldSchemaPath.getPathFromRoot()) {
+ for (QName qn : oldPath) {
newPath.add(QName.create(qnm, prefix, qn.getLocalName()));
}
} else {
- Iterable<QName> oldPath = oldSchemaPath.getPathFromRoot();
for (QName qn : oldPath) {
QNameModule qnm = module.getQNameModule();
String localPrefix = qn.getPrefix();
if (localPrefix != null && !localPrefix.isEmpty()) {
- ModuleBuilder currentModule = BuilderUtils.findModuleFromBuilders(modules, module, localPrefix,
- augment.getLine());
+ ModuleBuilder currentModule = BuilderUtils.getModuleByPrefix(module, localPrefix);
if (currentModule == null) {
- Module m = BuilderUtils.findModuleFromContext(context, module, localPrefix, augment.getLine());
- if (m == null) {
- throw new YangParseException(module.getName(), augment.getLine(), "Module with prefix "
- + localPrefix + " not found.");
- }
- qnm = m.getQNameModule();
- } else {
- qnm = currentModule.getQNameModule();
+ throw new YangParseException(module.getName(), augment.getLine(), "Module with prefix "
+ + localPrefix + " not found.");
}
+ qnm = currentModule.getQNameModule();
}
newPath.add(new QName(qnm.getNamespace(), qnm.getRevision(), localPrefix, qn.getLocalName()));
}
* Go through all augment definitions and resolve them.
*
* @param modules
- * all loaded modules
- * @param context
- * SchemaContext containing already resolved modules
+ * all loaded modules topologically sorted (based on dependencies
+ * between each other)
*/
- private void resolveAugments(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final SchemaContext context) {
+ private void resolveAugments(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
List<ModuleBuilder> all = new ArrayList<>();
for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
}
}
- List<ModuleBuilder> sorted;
- if (context == null) {
- sorted = ModuleDependencySort.sort(all.toArray(new ModuleBuilder[all.size()]));
- } else {
- sorted = ModuleDependencySort.sortWithContext(context, all.toArray(new ModuleBuilder[all.size()]));
- }
-
- for (ModuleBuilder mb : sorted) {
+ for (ModuleBuilder mb : all) {
if (mb != null) {
List<AugmentationSchemaBuilder> augments = mb.getAllAugments();
checkAugmentMandatoryNodes(augments);
- Collections.sort(augments, Comparators.AUGMENT_COMP);
+ Collections.sort(augments, Comparators.AUGMENT_BUILDER_COMP);
for (AugmentationSchemaBuilder augment : augments) {
if (!(augment.isResolved())) {
- boolean resolved = resolveAugment(augment, mb, modules, context);
+ boolean resolved = resolveAugment(augment, mb, modules);
if (!resolved) {
throw new YangParseException(augment.getModuleName(), augment.getLine(),
"Error in augment parsing: failed to find augment target: " + augment);
* current module
* @param modules
* all loaded modules
- * @param context
- * SchemaContext containing already resolved modules
* @return true if augment process succeed
*/
private boolean resolveUsesAugment(final AugmentationSchemaBuilder augment, final ModuleBuilder module,
- final Map<String, TreeMap<Date, ModuleBuilder>> modules, final SchemaContext context) {
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
if (augment.isResolved()) {
return true;
}
// We lookup in data namespace to find correct augmentation target
potentialTargetNode = findSchemaNodeInModule(resolvedTargetPath, (ModuleBuilder) parentNode);
} else {
- // Uses is used in local context (be it data namespace or grouping namespace,
+ // Uses is used in local context (be it data namespace or grouping
+ // namespace,
// since all nodes via uses are imported to localName, it is safe to
// to proceed only with local names.
//
// Conflicting elements in other namespaces are still not present
- // since resolveUsesAugment occurs before augmenting from external modules.
+ // since resolveUsesAugment occurs before augmenting from external
+ // modules.
potentialTargetNode = Optional.<SchemaNodeBuilder> fromNullable(findSchemaNode(augment.getTargetPath()
.getPath(), (SchemaNodeBuilder) parentNode));
}
* current module
* @param modules
* all loaded modules
- * @param context
- * SchemaContext containing already resolved modules
* @return true if augment process succeed
*/
private boolean resolveAugment(final AugmentationSchemaBuilder augment, final ModuleBuilder module,
- final Map<String, TreeMap<Date, ModuleBuilder>> modules, final SchemaContext context) {
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
if (augment.isResolved()) {
return true;
}
- QName targetPath = augment.getTargetPath().getPathFromRoot().iterator().next();
- ModuleBuilder targetModule = findTargetModule(targetPath, module, modules, context, augment.getLine());
+ QName targetModuleName = augment.getTargetPath().getPathFromRoot().iterator().next();
+ ModuleBuilder targetModule = BuilderUtils.getModuleByPrefix(module, targetModuleName.getPrefix());
if (targetModule == null) {
throw new YangParseException(module.getModuleName(), augment.getLine(), "Failed to resolve augment "
+ augment);
return processAugmentation(augment, targetModule);
}
- /**
- * Find module from loaded modules or from context based on given qname. If
- * module is found in context, create wrapper over this module and add it to
- * collection of loaded modules.
- *
- * @param qname
- * @param module
- * current module
- * @param modules
- * all loaded modules
- * @param context
- * schema context
- * @param line
- * current line
- * @return
- */
- private ModuleBuilder findTargetModule(final QName qname, final ModuleBuilder module,
- final Map<String, TreeMap<Date, ModuleBuilder>> modules, final SchemaContext context, final int line) {
- ModuleBuilder targetModule;
-
- String prefix = qname.getPrefix();
- if (prefix == null || prefix.isEmpty()) {
- targetModule = module;
- } else {
- targetModule = findModuleFromBuilders(modules, module, qname.getPrefix(), line);
- }
-
- if (targetModule == null && context != null) {
- Module m = findModuleFromContext(context, module, prefix, line);
- targetModule = new ModuleBuilder(m);
- DataSchemaNode firstNode = m.getDataChildByName(qname.getLocalName());
- DataSchemaNodeBuilder firstNodeWrapped = wrapChildNode(targetModule.getModuleName(), line, firstNode,
- targetModule.getPath(), firstNode.getQName());
- targetModule.addChildNode(firstNodeWrapped);
-
- TreeMap<Date, ModuleBuilder> map = new TreeMap<>();
- map.put(targetModule.getRevision(), targetModule);
- modules.put(targetModule.getModuleName(), map);
- }
-
- return targetModule;
- }
-
- private ModuleBuilder findTargetModule(final String prefix, final ModuleBuilder module,
- final Map<String, TreeMap<Date, ModuleBuilder>> modules, final SchemaContext context, final int line) {
- ModuleBuilder targetModule;
-
- if (prefix == null || prefix.equals("")) {
- targetModule = module;
- } else {
- targetModule = findModuleFromBuilders(modules, module, prefix, line);
- }
-
- if (targetModule == null && context != null) {
- Module m = findModuleFromContext(context, module, prefix, line);
- if (m != null) {
- targetModule = new ModuleBuilder(m);
- TreeMap<Date, ModuleBuilder> map = new TreeMap<>();
- map.put(targetModule.getRevision(), targetModule);
- modules.put(targetModule.getModuleName(), map);
- }
- }
-
- return targetModule;
- }
-
/**
* Go through identity statements defined in current module and resolve
- * their 'base' statement if present.
+ * their 'base' statement.
*
* @param modules
- * all modules
- * @param module
- * module being resolved
+ * all loaded modules
*/
private void resolveIdentities(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
ModuleBuilder module = inner.getValue();
final Set<IdentitySchemaNodeBuilder> identities = module.getAddedIdentities();
for (IdentitySchemaNodeBuilder identity : identities) {
- final String baseIdentityName = identity.getBaseIdentityName();
- final int line = identity.getLine();
- if (baseIdentityName != null) {
- IdentitySchemaNodeBuilder baseIdentity = findBaseIdentity(modules, module, baseIdentityName,
- line);
- if (baseIdentity == null) {
- throw new YangParseException(module.getName(), identity.getLine(),
- "Failed to find base identity");
- } else {
- identity.setBaseIdentity(baseIdentity);
- }
- }
+ resolveIdentity(modules, module, identity);
}
-
}
}
}
- /**
- * Go through identity statements defined in current module and resolve
- * their 'base' statement. Method tries to find base identity in given
- * modules. If base identity is not found, method will search it in context.
- *
- * @param modules
- * all loaded modules
- * @param module
- * current module
- * @param context
- * SchemaContext containing already resolved modules
- */
- private void resolveIdentitiesWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
- final SchemaContext context) {
- for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
- for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
- ModuleBuilder module = inner.getValue();
- final Set<IdentitySchemaNodeBuilder> identities = module.getAddedIdentities();
- for (IdentitySchemaNodeBuilder identity : identities) {
- final String baseIdentityName = identity.getBaseIdentityName();
- final int line = identity.getLine();
- if (baseIdentityName != null) {
-
- IdentitySchemaNodeBuilder result = null;
- if (baseIdentityName.indexOf(':') != -1) {
- final Iterator<String> split = COLON_SPLITTER.split(baseIdentityName).iterator();
- final String prefix = split.next();
- final String name = split.next();
- if (split.hasNext()) {
- throw new YangParseException(module.getName(), line,
- "Failed to parse identityref base: " + baseIdentityName);
- }
-
- ModuleBuilder dependentModule = findTargetModule(prefix, module, modules, context, line);
- if (dependentModule != null) {
- result = BuilderUtils.findIdentity(dependentModule.getAddedIdentities(), name);
- }
- } else {
- result = BuilderUtils.findIdentity(module.getAddedIdentities(), baseIdentityName);
- }
- identity.setBaseIdentity(result);
- }
+ private void resolveIdentity(final Map<String, TreeMap<Date, ModuleBuilder>> modules, ModuleBuilder module,
+ final IdentitySchemaNodeBuilder identity) {
+ final String baseIdentityName = identity.getBaseIdentityName();
+ if (baseIdentityName != null) {
+ IdentitySchemaNodeBuilder result = null;
+ if (baseIdentityName.contains(":")) {
+ final int line = identity.getLine();
+ String[] splittedBase = baseIdentityName.split(":");
+ if (splittedBase.length > 2) {
+ throw new YangParseException(module.getName(), line, "Failed to parse identityref base: "
+ + baseIdentityName);
}
+ String prefix = splittedBase[0];
+ String name = splittedBase[1];
+ ModuleBuilder dependentModule = BuilderUtils.getModuleByPrefix(module, prefix);
+ result = BuilderUtils.findIdentity(dependentModule.getAddedIdentities(), name);
+ } else {
+ result = BuilderUtils.findIdentity(module.getAddedIdentities(), baseIdentityName);
}
+ identity.setBaseIdentity(result);
}
}
*
* @param modules
* all loaded modules
- * @param context
- * SchemaContext containing already resolved modules or null if
- * context is not available
*/
- private void resolveUsesTargetGrouping(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
- final SchemaContext context) {
+ private void resolveUsesTargetGrouping(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
final List<UsesNodeBuilder> allUses = new ArrayList<>();
for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
final GroupingBuilder targetGroupingBuilder = GroupingUtils.getTargetGroupingFromModules(usesNode, modules,
module);
if (targetGroupingBuilder == null) {
- if (context == null) {
- throw new YangParseException(module.getName(), usesNode.getLine(), "Referenced grouping '"
- + usesNode.getGroupingPathAsString() + "' not found.");
- } else {
- GroupingDefinition targetGroupingDefinition = GroupingUtils.getTargetGroupingFromContext(usesNode,
- module, context);
- usesNode.setGroupingDefinition(targetGroupingDefinition);
- }
- } else {
- usesNode.setGrouping(targetGroupingBuilder);
+ throw new YangParseException(module.getName(), usesNode.getLine(), "Referenced grouping '"
+ + usesNode.getGroupingPathAsString() + "' not found.");
}
+ usesNode.setGrouping(targetGroupingBuilder);
}
}
*
* @param modules
* all loaded modules
- * @param context
- * SchemaContext containing already resolved modules
*/
- private void resolveUsesForGroupings(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
- final SchemaContext context) {
+ private void resolveUsesForGroupings(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
final Set<GroupingBuilder> allGroupings = new HashSet<>();
for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
List<UsesNodeBuilder> usesNodes = new ArrayList<>(GroupingSort.getAllUsesNodes(gb));
Collections.sort(usesNodes, new GroupingUtils.UsesComparator());
for (UsesNodeBuilder usesNode : usesNodes) {
- resolveUses(usesNode, modules, context);
+ resolveUses(usesNode, modules);
}
}
}
*
* @param modules
* all loaded modules
- * @param context
- * SchemaContext containing already resolved modules
*/
- private void resolveUsesForNodes(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
- final SchemaContext context) {
+ private void resolveUsesForNodes(final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
ModuleBuilder module = inner.getValue();
List<UsesNodeBuilder> usesNodes = module.getAllUsesNodes();
Collections.sort(usesNodes, new GroupingUtils.UsesComparator());
for (UsesNodeBuilder usesNode : usesNodes) {
- resolveUses(usesNode, modules, context);
+ resolveUses(usesNode, modules);
}
}
}
* uses node to resolve
* @param modules
* all loaded modules
- * @param context
- * SchemaContext containing already resolved modules
*/
- private void resolveUses(final UsesNodeBuilder usesNode, final Map<String, TreeMap<Date, ModuleBuilder>> modules,
- final SchemaContext context) {
+ private void resolveUses(final UsesNodeBuilder usesNode, final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
if (!usesNode.isResolved()) {
DataNodeContainerBuilder parent = usesNode.getParent();
ModuleBuilder module = BuilderUtils.getParentModule(parent);
resolveUsesWithContext(usesNode);
usesNode.setResolved(true);
for (AugmentationSchemaBuilder augment : usesNode.getAugmentations()) {
- resolveUsesAugment(augment, module, modules, context);
+ resolveUsesAugment(augment, module, modules);
}
} else {
parent.getChildNodeBuilders().addAll(target.instantiateChildNodes(parent));
parent.getUnknownNodes().addAll(target.instantiateUnknownNodes(parent));
usesNode.setResolved(true);
for (AugmentationSchemaBuilder augment : usesNode.getAugmentations()) {
- resolveUsesAugment(augment, module, modules, context);
+ resolveUsesAugment(augment, module, modules);
}
}
GroupingUtils.performRefine(usesNode);
*
* @param usesNode
* uses node to resolve
- * @param modules
- * all loaded modules
- * @param context
- * SchemaContext containing already resolved modules
*/
private void resolveUsesWithContext(final UsesNodeBuilder usesNode) {
final int line = usesNode.getLine();
}
/**
- * Try to find extension builder describing this unknown node and assign it
- * to unknown node builder.
+ * Try to find extension describing this unknown node and assign it to
+ * unknown node builder.
*
* @param modules
* all loaded modules
private void resolveUnknownNodes(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
for (UnknownSchemaNodeBuilder usnb : module.getAllUnknownNodes()) {
QName nodeType = usnb.getNodeType();
- try {
- ModuleBuilder dependentModule = findModuleFromBuilders(modules, module, nodeType.getPrefix(),
- usnb.getLine());
- for (ExtensionBuilder extension : dependentModule.getAddedExtensions()) {
- if (extension.getQName().getLocalName().equals(nodeType.getLocalName())) {
- usnb.setNodeType(extension.getQName());
- usnb.setExtensionBuilder(extension);
- break;
- }
+ ModuleBuilder dependentModuleBuilder = BuilderUtils.getModuleByPrefix(module, nodeType.getPrefix());
+ ExtensionBuilder extBuilder = findExtBuilder(nodeType.getLocalName(),
+ dependentModuleBuilder.getAddedExtensions());
+ if (extBuilder == null) {
+ ExtensionDefinition extDef = findExtDef(nodeType.getLocalName(), dependentModuleBuilder.getExtensions());
+ if (extDef == null) {
+ LOG.warn(
+ "Error in module {} at line {}: Failed to resolve node {}: no such extension definition found.",
+ module.getName(), usnb.getLine(), usnb);
+ } else {
+ usnb.setNodeType(new QName(extDef.getQName().getNamespace(), extDef.getQName().getRevision(),
+ nodeType.getPrefix(), extDef.getQName().getLocalName()));
+ usnb.setExtensionDefinition(extDef);
}
- } catch (YangParseException e) {
- throw new YangParseException(module.getName(), usnb.getLine(), "Failed to resolve node " + usnb
- + ": no such extension definition found.", e);
+ } else {
+ usnb.setNodeType(new QName(extBuilder.getQName().getNamespace(), extBuilder.getQName().getRevision(),
+ nodeType.getPrefix(), extBuilder.getQName().getLocalName()));
+ usnb.setExtensionBuilder(extBuilder);
}
}
}
- /**
- * Try to find extension builder describing this unknown node and assign it
- * to unknown node builder. If extension is not found in loaded modules, try
- * to find it in context.
- *
- * @param modules
- * all loaded modules
- * @param module
- * current module
- * @param context
- * SchemaContext containing already resolved modules
- */
- private void resolveUnknownNodesWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
- final ModuleBuilder module, final SchemaContext context) {
- for (UnknownSchemaNodeBuilder usnb : module.getAllUnknownNodes()) {
- QName nodeType = usnb.getNodeType();
- try {
- ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module, nodeType.getPrefix(),
- usnb.getLine());
-
- if (dependentModuleBuilder == null) {
- Module dependentModule = findModuleFromContext(context, module, nodeType.getPrefix(),
- usnb.getLine());
- for (ExtensionDefinition e : dependentModule.getExtensionSchemaNodes()) {
- if (e.getQName().getLocalName().equals(nodeType.getLocalName())) {
- usnb.setNodeType(new QName(e.getQName().getNamespace(), e.getQName().getRevision(),
- nodeType.getPrefix(), e.getQName().getLocalName()));
- usnb.setExtensionDefinition(e);
- break;
- }
- }
- } else {
- for (ExtensionBuilder extension : dependentModuleBuilder.getAddedExtensions()) {
- if (extension.getQName().getLocalName().equals(nodeType.getLocalName())) {
- usnb.setExtensionBuilder(extension);
- break;
- }
- }
- }
-
- } catch (YangParseException e) {
- throw new YangParseException(module.getName(), usnb.getLine(), "Failed to resolve node " + usnb
- + ": no such extension definition found.", e);
+ private ExtensionBuilder findExtBuilder(final String name, final Collection<ExtensionBuilder> extensions) {
+ for (ExtensionBuilder extension : extensions) {
+ if (extension.getQName().getLocalName().equals(name)) {
+ return extension;
}
+ }
+ return null;
+ }
+ private ExtensionDefinition findExtDef(final String name, final Collection<ExtensionDefinition> extensions) {
+ for (ExtensionDefinition extension : extensions) {
+ if (extension.getQName().getLocalName().equals(name)) {
+ return extension;
+ }
}
+ return null;
}
/**
*/
private void resolveDeviation(final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
for (DeviationBuilder dev : module.getDeviationBuilders()) {
- int line = dev.getLine();
SchemaPath targetPath = dev.getTargetPath();
Iterable<QName> path = targetPath.getPathFromRoot();
QName q0 = path.iterator().next();
prefix = module.getPrefix();
}
- ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module, prefix, line);
+ ModuleBuilder dependentModuleBuilder = BuilderUtils.getModuleByPrefix(module, prefix);
processDeviation(dev, dependentModuleBuilder, path, module);
}
}
- /**
- * Traverse through modules and resolve their deviation statements with
- * given context.
- *
- * @param modules
- * all loaded modules
- * @param context
- * already resolved context
- */
- private void resolveDeviationsWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
- final SchemaContext context) {
- for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules.entrySet()) {
- for (Map.Entry<Date, ModuleBuilder> inner : entry.getValue().entrySet()) {
- ModuleBuilder b = inner.getValue();
- resolveDeviationWithContext(modules, b, context);
- }
- }
- }
-
- /**
- * Traverse through module and resolve its deviation statements with given
- * context.
- *
- * @param modules
- * all loaded modules
- * @param module
- * module in which resolve deviations
- * @param context
- * already resolved context
- */
- private void resolveDeviationWithContext(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
- final ModuleBuilder module, final SchemaContext context) {
- for (DeviationBuilder dev : module.getDeviationBuilders()) {
- int line = dev.getLine();
- SchemaPath targetPath = dev.getTargetPath();
- Iterable<QName> path = targetPath.getPathFromRoot();
- QName q0 = path.iterator().next();
- String prefix = q0.getPrefix();
- if (prefix == null) {
- prefix = module.getPrefix();
- }
-
- ModuleBuilder dependentModuleBuilder = findModuleFromBuilders(modules, module, prefix, line);
- if (dependentModuleBuilder == null) {
- Object currentParent = findModuleFromContext(context, module, prefix, line);
-
- for (QName q : path) {
- if (currentParent == null) {
- throw new YangParseException(module.getName(), line, FAIL_DEVIATION_TARGET);
- }
- String name = q.getLocalName();
- if (currentParent instanceof DataNodeContainer) {
- currentParent = ((DataNodeContainer) currentParent).getDataChildByName(name);
- }
- }
-
- if (currentParent == null) {
- throw new YangParseException(module.getName(), line, FAIL_DEVIATION_TARGET);
- }
- if (currentParent instanceof SchemaNode) {
- dev.setTargetPath(((SchemaNode) currentParent).getPath());
- }
-
- } else {
- processDeviation(dev, dependentModuleBuilder, path, module);
- }
- }
- }
-
/**
* Correct deviation target path in deviation builder.
*
package org.opendaylight.yangtools.yang.parser.impl;
import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.checkMissingBody;
-import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.createActualSchemaPath;
import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.createListKey;
import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.getConfig;
import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.getIdentityrefBase;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
-import java.util.Stack;
import org.antlr.v4.runtime.tree.ParseTree;
import org.opendaylight.yangtools.antlrv4.code.gen.YangParser;
import org.slf4j.LoggerFactory;
public final class YangParserListenerImpl extends YangParserBaseListener {
- private static final Logger LOGGER = LoggerFactory.getLogger(YangParserListenerImpl.class);
+ private static final Logger LOG = LoggerFactory.getLogger(YangParserListenerImpl.class);
private static final Splitter COLON_SPLITTER = Splitter.on(':');
private static final String AUGMENT_STR = "augment";
private final DateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
- private final Stack<Stack<QName>> actualPath = new Stack<>();
+ private final SchemaPathStack stack = new SchemaPathStack();
private final String sourcePath;
+ private QName moduleQName = new QName(null, new Date(0L), null, "dummy");
private ModuleBuilder moduleBuilder;
private String moduleName;
- private URI namespace;
- private String yangModelPrefix;
- private Date revision = new Date(0L);
private int augmentOrder;
- private void addNodeToPath(final QName name) {
- actualPath.peek().push(name);
- }
-
- private QName removeNodeFromPath() {
- return actualPath.peek().pop();
- }
-
public YangParserListenerImpl(final String sourcePath) {
this.sourcePath = sourcePath;
}
@Override
public void enterModule_stmt(final YangParser.Module_stmtContext ctx) {
moduleName = stringFromNode(ctx);
- LOGGER.trace("entering module {}", moduleName);
+ LOG.trace("entering module {}", moduleName);
enterLog("module", moduleName, 0);
- actualPath.push(new Stack<QName>());
+ stack.push();
moduleBuilder = new ModuleBuilder(moduleName, sourcePath);
@Override
public void exitModule_stmt(final YangParser.Module_stmtContext ctx) {
exitLog("module");
- actualPath.pop();
+ stack.pop();
}
- @Override public void enterSubmodule_stmt(final YangParser.Submodule_stmtContext ctx) {
+ @Override
+ public void enterSubmodule_stmt(final YangParser.Submodule_stmtContext ctx) {
moduleName = stringFromNode(ctx);
- LOGGER.trace("entering submodule {}", moduleName);
+ LOG.trace("entering submodule {}", moduleName);
enterLog("submodule", moduleName, 0);
- actualPath.push(new Stack<QName>());
+ stack.push();
moduleBuilder = new ModuleBuilder(moduleName, true, sourcePath);
@Override
public void exitSubmodule_stmt(final YangParser.Submodule_stmtContext ctx) {
exitLog("submodule");
- actualPath.pop();
+ stack.pop();
}
@Override
final ParseTree treeNode = ctx.getChild(i);
if (treeNode instanceof Namespace_stmtContext) {
final String namespaceStr = stringFromNode(treeNode);
- namespace = URI.create(namespaceStr);
- moduleBuilder.setNamespace(namespace);
+ final URI namespace = URI.create(namespaceStr);
+ this.moduleQName = new QName(namespace, moduleQName.getRevision(), moduleQName.getPrefix(), moduleQName.getLocalName());
+ moduleBuilder.setQNameModule(moduleQName.getModule());
setLog("namespace", namespaceStr);
} else if (treeNode instanceof Prefix_stmtContext) {
- yangModelPrefix = stringFromNode(treeNode);
+ final String yangModelPrefix = stringFromNode(treeNode);
+ this.moduleQName = new QName(moduleQName.getNamespace(), moduleQName.getRevision(), yangModelPrefix, moduleQName.getLocalName());
moduleBuilder.setPrefix(yangModelPrefix);
setLog("prefix", yangModelPrefix);
} else if (treeNode instanceof Yang_version_stmtContext) {
final String revisionDateStr = stringFromNode(treeNode);
try {
final Date revisionDate = SIMPLE_DATE_FORMAT.parse(revisionDateStr);
- if ((revisionDate != null) && (this.revision.compareTo(revisionDate) < 0)) {
- this.revision = revisionDate;
- moduleBuilder.setRevision(this.revision);
- setLog("revision", this.revision.toString());
+ if ((revisionDate != null) && (this.moduleQName.getRevision().compareTo(revisionDate) < 0)) {
+ this.moduleQName = new QName(moduleQName.getNamespace(), revisionDate, moduleQName.getPrefix(), moduleQName.getLocalName());
+ moduleBuilder.setQNameModule(moduleQName.getModule());
+ setLog("revision", revisionDate.toString());
for (int i = 0; i < treeNode.getChildCount(); ++i) {
ParseTree child = treeNode.getChild(i);
if (child instanceof Reference_stmtContext) {
}
}
} catch (ParseException e) {
- final String message = "Failed to parse revision string: " + revisionDateStr;
- LOGGER.warn(message);
+ LOG.warn("Failed to parse revision string: {}", revisionDateStr, e);
}
}
try {
importRevision = SIMPLE_DATE_FORMAT.parse(importRevisionStr);
} catch (ParseException e) {
- LOGGER.warn("Failed to parse import revision-date at line " + line + ": " + importRevisionStr);
+ LOG.warn("Failed to parse import revision-date at line {}: {}", line, importRevisionStr, e);
}
}
}
moduleBuilder.addModuleImport(importName, importRevision, importPrefix);
- setLog("import", "(" + importName + "; " + importRevision + "; " + importPrefix + ")");
+ LOG.trace("setting import ({}; {}; {})", importName, importRevision, importPrefix);
}
@Override
final int line = ctx.getStart().getLine();
final String augmentPath = stringFromNode(ctx);
enterLog(AUGMENT_STR, augmentPath, line);
- actualPath.push(new Stack<QName>());
+ stack.push();
AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, augmentOrder++);
public void exitAugment_stmt(final YangParser.Augment_stmtContext ctx) {
moduleBuilder.exitNode();
exitLog(AUGMENT_STR);
- actualPath.pop();
+ stack.pop();
}
@Override
final int line = ctx.getStart().getLine();
final String extName = stringFromNode(ctx);
enterLog("extension", extName, line);
- QName qname = new QName(namespace, revision, yangModelPrefix, extName);
- addNodeToPath(qname);
- SchemaPath path = createActualSchemaPath(actualPath.peek());
+ QName qname = QName.create(moduleQName, extName);
+ SchemaPath path = stack.addNodeToPath(qname);
ExtensionBuilder builder = moduleBuilder.addExtension(qname, line, path);
parseSchemaNodeArgs(ctx, builder);
@Override
public void exitExtension_stmt(final YangParser.Extension_stmtContext ctx) {
moduleBuilder.exitNode();
- exitLog("extension", removeNodeFromPath());
+ exitLog("extension", stack.removeNodeFromPath());
}
@Override
final int line = ctx.getStart().getLine();
final String typedefName = stringFromNode(ctx);
enterLog("typedef", typedefName, line);
- QName typedefQName = new QName(namespace, revision, yangModelPrefix, typedefName);
- addNodeToPath(typedefQName);
- SchemaPath path = createActualSchemaPath(actualPath.peek());
+ QName typedefQName = QName.create(moduleQName, typedefName);
+ SchemaPath path = stack.addNodeToPath(typedefQName);
TypeDefinitionBuilder builder = moduleBuilder.addTypedef(line, typedefQName, path);
parseSchemaNodeArgs(ctx, builder);
@Override
public void exitTypedef_stmt(final YangParser.Typedef_stmtContext ctx) {
moduleBuilder.exitNode();
- exitLog("typedef", removeNodeFromPath());
+ exitLog("typedef", stack.removeNodeFromPath());
}
@Override
checkMissingBody(typeName, moduleName, line);
// if there are no constraints, just grab default base yang type
type = BaseTypes.defaultBaseTypeFor(typeName).orNull();
- addNodeToPath(type.getQName());
+ stack.addNodeToPath(type.getQName());
moduleBuilder.setType(type);
} else {
QName qname;
switch (typeName) {
case "union":
qname = BaseTypes.UNION_QNAME;
- addNodeToPath(qname);
- UnionTypeBuilder unionBuilder = moduleBuilder.addUnionType(line, namespace, revision);
+ stack.addNodeToPath(qname);
+ UnionTypeBuilder unionBuilder = moduleBuilder.addUnionType(line, moduleQName.getModule());
Builder parent = moduleBuilder.getActualNode();
unionBuilder.setParent(parent);
moduleBuilder.enterNode(unionBuilder);
break;
case "identityref":
qname = BaseTypes.IDENTITYREF_QNAME;
- addNodeToPath(qname);
- SchemaPath path = createActualSchemaPath(actualPath.peek());
+ SchemaPath path = stack.addNodeToPath(qname);
moduleBuilder.addIdentityrefType(line, path, getIdentityrefBase(typeBody));
break;
default:
- type = parseTypeWithBody(typeName, typeBody, actualPath.peek(), namespace, revision,
- yangModelPrefix, moduleBuilder.getActualNode());
+ type = parseTypeWithBody(typeName, typeBody, stack.currentSchemaPath(), moduleQName, moduleBuilder.getActualNode());
moduleBuilder.setType(type);
- addNodeToPath(type.getQName());
+ stack.addNodeToPath(type.getQName());
}
}
} else {
- type = parseUnknownTypeWithBody(typeQName, typeBody, actualPath.peek(), namespace, revision,
- yangModelPrefix, moduleBuilder.getActualNode());
+ type = parseUnknownTypeWithBody(typeQName, typeBody, stack.currentSchemaPath(), moduleQName, moduleBuilder.getActualNode());
// add parent node of this type statement to dirty nodes
moduleBuilder.markActualNodeDirty();
moduleBuilder.setType(type);
- addNodeToPath(type.getQName());
+ stack.addNodeToPath(type.getQName());
}
}
final Iterator<String> split = COLON_SPLITTER.split(typeName).iterator();
final String prefix = split.next();
final String name = split.next();
- if (prefix.equals(yangModelPrefix)) {
- typeQName = new QName(namespace, revision, prefix, name);
+ if (prefix.equals(moduleQName.getPrefix())) {
+ typeQName = QName.create(moduleQName, name);
} else {
typeQName = new QName(null, null, prefix, name);
}
} else {
- typeQName = new QName(namespace, revision, yangModelPrefix, typeName);
+ typeQName = QName.create(moduleQName, typeName);
}
return typeQName;
}
if ("union".equals(typeName)) {
moduleBuilder.exitNode();
}
- exitLog("type", removeNodeFromPath());
+ exitLog("type", stack.removeNodeFromPath());
}
@Override
final int line = ctx.getStart().getLine();
final String groupName = stringFromNode(ctx);
enterLog("grouping", groupName, line);
- QName groupQName = new QName(namespace, revision, yangModelPrefix, groupName);
- addNodeToPath(groupQName);
- SchemaPath path = createActualSchemaPath(actualPath.peek());
+ QName groupQName = QName.create(moduleQName, groupName);
+ SchemaPath path = stack.addNodeToPath(groupQName);
GroupingBuilder builder = moduleBuilder.addGrouping(ctx.getStart().getLine(), groupQName, path);
parseSchemaNodeArgs(ctx, builder);
@Override
public void exitGrouping_stmt(final YangParser.Grouping_stmtContext ctx) {
moduleBuilder.exitNode();
- exitLog("grouping", removeNodeFromPath());
+ exitLog("grouping", stack.removeNodeFromPath());
}
@Override
final String containerName = stringFromNode(ctx);
enterLog("container", containerName, line);
- QName containerQName = new QName(namespace, revision, yangModelPrefix, containerName);
- addNodeToPath(containerQName);
- SchemaPath path = createActualSchemaPath(actualPath.peek());
+ QName containerQName = QName.create(moduleQName, containerName);
+ SchemaPath path = stack.addNodeToPath(containerQName);
ContainerSchemaNodeBuilder builder = moduleBuilder.addContainerNode(line, containerQName, path);
parseSchemaNodeArgs(ctx, builder);
@Override
public void exitContainer_stmt(final Container_stmtContext ctx) {
moduleBuilder.exitNode();
- exitLog("container", removeNodeFromPath());
+ exitLog("container", stack.removeNodeFromPath());
}
@Override
final String leafName = stringFromNode(ctx);
enterLog("leaf", leafName, line);
- QName leafQName = new QName(namespace, revision, yangModelPrefix, leafName);
- addNodeToPath(leafQName);
- SchemaPath path = createActualSchemaPath(actualPath.peek());
+ QName leafQName = QName.create(moduleQName, leafName);
+ SchemaPath path = stack.addNodeToPath(leafQName);
LeafSchemaNodeBuilder builder = moduleBuilder.addLeafNode(line, leafQName, path);
parseSchemaNodeArgs(ctx, builder);
@Override
public void exitLeaf_stmt(final YangParser.Leaf_stmtContext ctx) {
moduleBuilder.exitNode();
- exitLog("leaf", removeNodeFromPath());
+ exitLog("leaf", stack.removeNodeFromPath());
}
@Override
@Override
public void enterUses_augment_stmt(final YangParser.Uses_augment_stmtContext ctx) {
- actualPath.push(new Stack<QName>());
final int line = ctx.getStart().getLine();
final String augmentPath = stringFromNode(ctx);
enterLog(AUGMENT_STR, augmentPath, line);
+ stack.push();
AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, augmentOrder++);
public void exitUses_augment_stmt(final YangParser.Uses_augment_stmtContext ctx) {
moduleBuilder.exitNode();
exitLog(AUGMENT_STR);
- actualPath.pop();
+ stack.pop();
}
@Override
final int line = ctx.getStart().getLine();
final String leafListName = stringFromNode(ctx);
enterLog("leaf-list", leafListName, line);
- QName leafListQName = new QName(namespace, revision, yangModelPrefix, leafListName);
- addNodeToPath(leafListQName);
- SchemaPath path = createActualSchemaPath(actualPath.peek());
+ QName leafListQName = QName.create(moduleQName, leafListName);
+ SchemaPath path = stack.addNodeToPath(leafListQName);
LeafListSchemaNodeBuilder builder = moduleBuilder.addLeafListNode(line, leafListQName, path);
moduleBuilder.enterNode(builder);
@Override
public void exitLeaf_list_stmt(final YangParser.Leaf_list_stmtContext ctx) {
moduleBuilder.exitNode();
- exitLog("leaf-list", removeNodeFromPath());
+ exitLog("leaf-list", stack.removeNodeFromPath());
}
@Override
final String listName = stringFromNode(ctx);
enterLog("list", listName, line);
- QName listQName = new QName(namespace, revision, yangModelPrefix, listName);
- addNodeToPath(listQName);
- SchemaPath path = createActualSchemaPath(actualPath.peek());
+ QName listQName = QName.create(moduleQName, listName);
+ SchemaPath path = stack.addNodeToPath(listQName);
ListSchemaNodeBuilder builder = moduleBuilder.addListNode(line, listQName, path);
moduleBuilder.enterNode(builder);
@Override
public void exitList_stmt(final List_stmtContext ctx) {
moduleBuilder.exitNode();
- exitLog("list", removeNodeFromPath());
+ exitLog("list", stack.removeNodeFromPath());
}
@Override
final String anyXmlName = stringFromNode(ctx);
enterLog("anyxml", anyXmlName, line);
- QName anyXmlQName = new QName(namespace, revision, yangModelPrefix, anyXmlName);
- addNodeToPath(anyXmlQName);
- SchemaPath path = createActualSchemaPath(actualPath.peek());
+ QName anyXmlQName = QName.create(moduleQName, anyXmlName);
+ SchemaPath path = stack.addNodeToPath(anyXmlQName);
AnyXmlBuilder builder = moduleBuilder.addAnyXml(line, anyXmlQName, path);
moduleBuilder.enterNode(builder);
@Override
public void exitAnyxml_stmt(final YangParser.Anyxml_stmtContext ctx) {
moduleBuilder.exitNode();
- exitLog("anyxml", removeNodeFromPath());
+ exitLog("anyxml", stack.removeNodeFromPath());
}
@Override
final String choiceName = stringFromNode(ctx);
enterLog("choice", choiceName, line);
- QName choiceQName = new QName(namespace, revision, yangModelPrefix, choiceName);
- addNodeToPath(choiceQName);
- SchemaPath path = createActualSchemaPath(actualPath.peek());
+ QName choiceQName = QName.create(moduleQName, choiceName);
+ SchemaPath path = stack.addNodeToPath(choiceQName);
ChoiceBuilder builder = moduleBuilder.addChoice(line, choiceQName, path);
moduleBuilder.enterNode(builder);
@Override
public void exitChoice_stmt(final YangParser.Choice_stmtContext ctx) {
moduleBuilder.exitNode();
- exitLog("choice", removeNodeFromPath());
+ exitLog("choice", stack.removeNodeFromPath());
}
@Override
final String caseName = stringFromNode(ctx);
enterLog("case", caseName, line);
- QName caseQName = new QName(namespace, revision, yangModelPrefix, caseName);
- addNodeToPath(caseQName);
- SchemaPath path = createActualSchemaPath(actualPath.peek());
+ QName caseQName = QName.create(moduleQName, caseName);
+ SchemaPath path = stack.addNodeToPath(caseQName);
ChoiceCaseBuilder builder = moduleBuilder.addCase(line, caseQName, path);
moduleBuilder.enterNode(builder);
@Override
public void exitCase_stmt(final YangParser.Case_stmtContext ctx) {
moduleBuilder.exitNode();
- exitLog("case", removeNodeFromPath());
+ exitLog("case", stack.removeNodeFromPath());
}
@Override
final String notificationName = stringFromNode(ctx);
enterLog("notification", notificationName, line);
- QName notificationQName = new QName(namespace, revision, yangModelPrefix, notificationName);
- addNodeToPath(notificationQName);
- SchemaPath path = createActualSchemaPath(actualPath.peek());
+ QName notificationQName = QName.create(moduleQName, notificationName);
+ SchemaPath path = stack.addNodeToPath(notificationQName);
NotificationBuilder builder = moduleBuilder.addNotification(line, notificationQName, path);
moduleBuilder.enterNode(builder);
@Override
public void exitNotification_stmt(final YangParser.Notification_stmtContext ctx) {
moduleBuilder.exitNode();
- exitLog("notification", removeNodeFromPath());
+ exitLog("notification", stack.removeNodeFromPath());
}
// Unknown nodes
@Override
public void exitIdentifier_stmt(final YangParser.Identifier_stmtContext ctx) {
moduleBuilder.exitNode();
- exitLog("unknown-node", removeNodeFromPath());
+ exitLog("unknown-node", stack.removeNodeFromPath());
}
@Override public void enterUnknown_statement(final YangParser.Unknown_statementContext ctx) {
@Override public void exitUnknown_statement(final YangParser.Unknown_statementContext ctx) {
moduleBuilder.exitNode();
- exitLog("unknown-node", removeNodeFromPath());
+ exitLog("unknown-node", stack.removeNodeFromPath());
}
@Override public void enterUnknown_statement2(final YangParser.Unknown_statement2Context ctx) {
@Override public void exitUnknown_statement2(final YangParser.Unknown_statement2Context ctx) {
moduleBuilder.exitNode();
- exitLog("unknown-node", removeNodeFromPath());
+ exitLog("unknown-node", stack.removeNodeFromPath());
}
@Override public void enterUnknown_statement3(final YangParser.Unknown_statement3Context ctx) {
@Override public void exitUnknown_statement3(final YangParser.Unknown_statement3Context ctx) {
moduleBuilder.exitNode();
- exitLog("unknown-node", removeNodeFromPath());
+ exitLog("unknown-node", stack.removeNodeFromPath());
}
@Override
final String rpcName = stringFromNode(ctx);
enterLog("rpc", rpcName, line);
- QName rpcQName = new QName(namespace, revision, yangModelPrefix, rpcName);
- addNodeToPath(rpcQName);
- SchemaPath path = createActualSchemaPath(actualPath.peek());
+ QName rpcQName = QName.create(moduleQName, rpcName);
+ SchemaPath path = stack.addNodeToPath(rpcQName);
RpcDefinitionBuilder rpcBuilder = moduleBuilder.addRpc(line, rpcQName, path);
moduleBuilder.enterNode(rpcBuilder);
@Override
public void exitRpc_stmt(final YangParser.Rpc_stmtContext ctx) {
moduleBuilder.exitNode();
- exitLog("rpc", removeNodeFromPath());
+ exitLog("rpc", stack.removeNodeFromPath());
}
@Override
final String input = "input";
enterLog(input, input, line);
- QName rpcQName = new QName(namespace, revision, yangModelPrefix, input);
- addNodeToPath(rpcQName);
- SchemaPath path = createActualSchemaPath(actualPath.peek());
+ QName rpcQName = QName.create(moduleQName, input);
+ SchemaPath path = stack.addNodeToPath(rpcQName);
ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcInput(line, rpcQName, path);
moduleBuilder.enterNode(builder);
@Override
public void exitInput_stmt(final YangParser.Input_stmtContext ctx) {
moduleBuilder.exitNode();
- exitLog("input", removeNodeFromPath());
+ exitLog("input", stack.removeNodeFromPath());
}
@Override
final String output = "output";
enterLog(output, output, line);
- QName rpcQName = new QName(namespace, revision, yangModelPrefix, output);
- addNodeToPath(rpcQName);
- SchemaPath path = createActualSchemaPath(actualPath.peek());
+ QName rpcQName = QName.create(moduleQName, output);
+ SchemaPath path = stack.addNodeToPath(rpcQName);
ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcOutput(path, rpcQName, line);
moduleBuilder.enterNode(builder);
@Override
public void exitOutput_stmt(final YangParser.Output_stmtContext ctx) {
moduleBuilder.exitNode();
- exitLog("output", removeNodeFromPath());
+ exitLog("output", stack.removeNodeFromPath());
}
@Override
final String featureName = stringFromNode(ctx);
enterLog("feature", featureName, line);
- QName featureQName = new QName(namespace, revision, yangModelPrefix, featureName);
- addNodeToPath(featureQName);
- SchemaPath path = createActualSchemaPath(actualPath.peek());
+ QName featureQName = QName.create(moduleQName, featureName);
+ SchemaPath path = stack.addNodeToPath(featureQName);
FeatureBuilder featureBuilder = moduleBuilder.addFeature(line, featureQName, path);
moduleBuilder.enterNode(featureBuilder);
@Override
public void exitFeature_stmt(final YangParser.Feature_stmtContext ctx) {
moduleBuilder.exitNode();
- exitLog("feature", removeNodeFromPath());
+ exitLog("feature", stack.removeNodeFromPath());
}
@Override
final String identityName = stringFromNode(ctx);
enterLog("identity", identityName, line);
- final QName identityQName = new QName(namespace, revision, yangModelPrefix, identityName);
- addNodeToPath(identityQName);
- SchemaPath path = createActualSchemaPath(actualPath.peek());
+ final QName identityQName = QName.create(moduleQName, identityName);
+ SchemaPath path = stack.addNodeToPath(identityQName);
IdentitySchemaNodeBuilder builder = moduleBuilder.addIdentity(identityQName, line, path);
moduleBuilder.enterNode(builder);
-
parseSchemaNodeArgs(ctx, builder);
for (int i = 0; i < ctx.getChildCount(); i++) {
@Override
public void exitIdentity_stmt(final YangParser.Identity_stmtContext ctx) {
moduleBuilder.exitNode();
- exitLog("identity", removeNodeFromPath());
+ exitLog("identity", stack.removeNodeFromPath());
}
public ModuleBuilder getModuleBuilder() {
return moduleBuilder;
}
- private void enterLog(final String p1, final String p2, final int line) {
- LOGGER.trace("entering {} {} ({})", p1, p2, line);
+ private static void enterLog(final String p1, final String p2, final int line) {
+ LOG.trace("entering {} {} ({})", p1, p2, line);
}
- private void exitLog(final String p1) {
- LOGGER.trace("exiting {}", p1);
+ private static void exitLog(final String p1) {
+ LOG.trace("exiting {}", p1);
}
- private void exitLog(final String p1, final QName p2) {
- LOGGER.trace("exiting {} {}", p1, p2.getLocalName());
+ private static void exitLog(final String p1, final QName p2) {
+ LOG.trace("exiting {} {}", p1, p2.getLocalName());
}
- private void setLog(final String p1, final String p2) {
- LOGGER.trace("setting {} {}", p1, p2);
+ private static void setLog(final String p1, final String p2) {
+ LOG.trace("setting {} {}", p1, p2);
}
private void handleUnknownNode(final int line, final ParseTree ctx) {
final String e0 = splittedElement.next();
final QName nodeType;
if (splittedElement.hasNext()) {
- nodeType = new QName(namespace, revision, e0, splittedElement.next());
+ nodeType = new QName(moduleQName.getNamespace(), moduleQName.getRevision(), e0, splittedElement.next());
} else {
- nodeType = new QName(namespace, revision, yangModelPrefix, e0);
+ nodeType = QName.create(moduleQName, e0);
}
QName qname;
if (Iterables.size(splittedName) == 2) {
qname = new QName(null, null, it.next(), it.next());
} else {
- qname = new QName(namespace, revision, yangModelPrefix, it.next());
+ qname = QName.create(moduleQName, it.next());
}
} else {
qname = nodeType;
} catch (IllegalArgumentException e) {
qname = nodeType;
}
- addNodeToPath(qname);
- SchemaPath path = createActualSchemaPath(actualPath.peek());
+ SchemaPath path = stack.addNodeToPath(qname);
UnknownSchemaNodeBuilderImpl builder = moduleBuilder.addUnknownSchemaNode(line, qname, path);
builder.setNodeType(nodeType);
String fromName;
Date fromRevision;
- Set<ModuleImport> imports;
+ Collection<ModuleImport> imports;
URI ns;
if (mmb.isModule()) {
ModuleBuilder moduleBuilder = mmb.getModuleBuilder();
fromName = moduleBuilder.getName();
fromRevision = moduleBuilder.getRevision();
- imports = moduleBuilder.getModuleImports();
+ imports = moduleBuilder.getImports().values();
ns = moduleBuilder.getNamespace();
}
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.junit.Ignore;
import org.junit.Test;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
assertNotNull(un.getExtensionDefinition());
}
- @Ignore
@Test
public void testAugment() throws Exception {
// load first module
- SchemaContext context;
String resource = "/context-augment-test/test4.yang";
-
- try (InputStream stream = new FileInputStream(new File(getClass().getResource(resource).toURI()))) {
- context = parser.resolveSchemaContext(TestUtils.loadModules(Lists.newArrayList(stream)));
- }
+ SchemaContext context = parser.parseFiles(Collections.singleton(new File(getClass().getResource(resource)
+ .toURI())));
// load another modules and parse them against already existing context
- Set<Module> modules;
- try (InputStream stream1 = new FileInputStream(new File(getClass().getResource(
- "/context-augment-test/test1.yang").toURI()));
- InputStream stream2 = new FileInputStream(new File(getClass().getResource(
- "/context-augment-test/test2.yang").toURI()));
- InputStream stream3 = new FileInputStream(new File(getClass().getResource(
- "/context-augment-test/test3.yang").toURI()))) {
- List<InputStream> input = Lists.newArrayList(stream1, stream2, stream3);
- modules = TestUtils.loadModulesWithContext(input, context);
- }
+ File test1 = new File(getClass().getResource("/context-augment-test/test1.yang").toURI());
+ File test2 = new File(getClass().getResource("/context-augment-test/test2.yang").toURI());
+ File test3 = new File(getClass().getResource("/context-augment-test/test3.yang").toURI());
+ Set<Module> modules = parser.parseFiles(Arrays.asList(test1, test2, test3), context).getModules();
assertNotNull(modules);
- Module t3 = TestUtils.findModule(modules, "test4");
- ContainerSchemaNode interfaces = (ContainerSchemaNode) t3.getDataChildByName("interfaces");
+ Module t4 = TestUtils.findModule(modules, "test4");
+ ContainerSchemaNode interfaces = (ContainerSchemaNode) t4.getDataChildByName("interfaces");
ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName("ifEntry");
// test augmentation process
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
private void mockDependency(final ModuleBuilder a, final ModuleBuilder b) {
ModuleImport imprt = mock(ModuleImport.class);
doReturn(b.getName()).when(imprt).getModuleName();
+ doReturn(b.getName()).when(imprt).getPrefix();
doReturn(b.getRevision()).when(imprt).getRevision();
- a.getModuleImports().add(imprt);
+ a.getImports().put(b.getName(), imprt);
}
private void mockDependency(final Module a, final Module b) {
private ModuleBuilder mockModuleBuilder(final String name, final Date rev) {
ModuleBuilder a = mock(ModuleBuilder.class);
doReturn(name).when(a).getName();
- Set<ModuleImport> set = Sets.newHashSet();
- doReturn(set).when(a).getModuleImports();
+ Map<String, ModuleImport> map = new HashMap<>();
+ doReturn(map).when(a).getImports();
if (rev != null) {
doReturn(rev).when(a).getRevision();
}
reference " WILL BE DEFINED LATER";
}
+ extension opendaylight {
+ argument "name" {
+ yin-element "true";
+ }
+ }
+
container interfaces {
grouping ifEntry {
container augment-holder;
revision 2013-06-18 {
}
- augment "/t4:interfaces/t4:ifEntry/t2:augment-holder/t3:schemas" {
+ augment "/t4:interfaces/t4:ifEntry/t3:augment-holder/t2:schemas" {
when "if:ifType='ds0'";
leaf id {
type string;
leaf id {
type inet:port-number {
- range "0..65536";
+ range "0..65535";
}
}
}
}
+ extension opendaylight {
+ argument "name" {
+ yin-element "true";
+ }
+ }
+
}