From: Tony Tkacik Date: Tue, 3 Sep 2013 04:23:28 +0000 (-0700) Subject: Converted BindingGenerator and ParserUtils to xtend X-Git-Tag: yangtools-0.1.0~41 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=2da3d7fcfede6cb3f848cee177af0edfddc1096a;p=yangtools.git Converted BindingGenerator and ParserUtils to xtend - Fixed bug in findNode implementation methods, which lead to ignoring rpcs and notifications Change-Id: Ifb16c9911a0d0dfb4a62e2986b8c1d2ae84e4b17 Signed-off-by: Tony Tkacik --- diff --git a/code-generator/binding-generator-impl/pom.xml b/code-generator/binding-generator-impl/pom.xml index 9a1fc491ee..60f6ff5734 100644 --- a/code-generator/binding-generator-impl/pom.xml +++ b/code-generator/binding-generator-impl/pom.xml @@ -10,6 +10,40 @@ 4.0.0 binding-generator-impl + + + + org.eclipse.xtend + xtend-maven-plugin + 2.4.2 + + + + compile + + + ${basedir}/src/main/xtend-gen + + + + + + maven-clean-plugin + 2.4.1 + + + + ${basedir}/src/main/xtend-gen + + ** + + + + + + + + org.opendaylight.yangtools @@ -40,6 +74,11 @@ com.google.guava guava + + + org.eclipse.xtend + org.eclipse.xtend.lib + 2.4.2 diff --git a/code-generator/binding-generator-impl/src/main/.gitignore b/code-generator/binding-generator-impl/src/main/.gitignore new file mode 100644 index 0000000000..04b73cb01e --- /dev/null +++ b/code-generator/binding-generator-impl/src/main/.gitignore @@ -0,0 +1 @@ +/xtend-gen diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.xtend similarity index 58% rename from code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java rename to code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.xtend index f6e96d8301..562f6b425b 100644 --- a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java +++ b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.xtend @@ -9,17 +9,14 @@ package org.opendaylight.yangtools.sal.binding.generator.impl; import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.*; import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.*; -import static org.opendaylight.yangtools.binding.generator.util.Types.BOOLEAN; import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.*; import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.Future; import org.opendaylight.yangtools.binding.generator.util.BindingTypes; import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl; @@ -29,22 +26,15 @@ import org.opendaylight.yangtools.binding.generator.util.generated.type.builder. 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.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.Type; 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.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.DataRoot; -import org.opendaylight.yangtools.yang.binding.Identifiable; -import org.opendaylight.yangtools.yang.binding.Identifier; import org.opendaylight.yangtools.yang.binding.RpcService; -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; @@ -58,14 +48,12 @@ 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.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; @@ -73,10 +61,10 @@ import org.opendaylight.yangtools.yang.model.util.DataNodeIterator; import org.opendaylight.yangtools.yang.model.util.ExtendedType; import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; import org.opendaylight.yangtools.yang.model.util.UnionType; +import static com.google.common.base.Preconditions.*; +import static extension org.opendaylight.yangtools.binding.generator.util.Types.*; -import com.google.common.base.Preconditions; - -public final class BindingGeneratorImpl implements BindingGenerator { +public class BindingGeneratorImpl implements BindingGenerator { /** * Outter key represents the package name. Outter value represents map of @@ -89,13 +77,13 @@ public final class BindingGeneratorImpl implements BindingGenerator { /** * Provide methods for converting YANG types to JAVA types. */ - private TypeProvider typeProvider; + private var TypeProvider typeProvider; /** * Holds reference to schema context to resolve data of augmented elemnt * when creating augmentation builder */ - private SchemaContext schemaContext; + private var SchemaContext schemaContext; /** * Each grouping which is converted from schema node to generated type is @@ -105,25 +93,22 @@ public final class BindingGeneratorImpl implements BindingGenerator { * Schema node the object of type Type is required. So in this * case is used this map. */ - private final Map allGroupings = new HashMap(); + private val allGroupings = new HashMap(); + + + private val yangToJavaMapping = new HashMap(); /** * Constant with the concrete name of namespace. */ - private final static String YANG_EXT_NAMESPACE = "urn:opendaylight:yang:extension:yang-ext"; + private val 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"; - - /** - * Only parent constructor is invoked. - */ - public BindingGeneratorImpl() { - super(); - } + private val static String AUGMENT_IDENTIFIER_NAME = "augment-identifier"; + /** * Resolves generated types from context schema nodes of all * modules. @@ -142,31 +127,32 @@ public final class BindingGeneratorImpl implements BindingGenerator { * @throws IllegalStateException * if context contain no modules */ - @Override - public List generateTypes(final SchemaContext context) { - Preconditions.checkArgument(context != null,"Schema Context reference cannot be NULL."); - Preconditions.checkState(context.getModules() != null,"Schema Context does not contain defined modules."); - final List generatedTypes = new ArrayList<>(); + override generateTypes(SchemaContext context) { + checkArgument(context !== null,"Schema Context reference cannot be NULL."); + checkState(context.modules !== null,"Schema Context does not contain defined modules."); + val List generatedTypes = new ArrayList(); schemaContext = context; typeProvider = new TypeProviderImpl(context); - final Set modules = context.getModules(); - genTypeBuilders = new HashMap<>(); - for (final Module module : modules) { + val Set modules = context.modules; + genTypeBuilders = new HashMap(); + for (module : modules) { generatedTypes.addAll(allGroupingsToGenTypes(module)); - if (false == module.getChildNodes().isEmpty()) { + if (false == module.childNodes.isEmpty()) { generatedTypes.add(moduleToDataType(module)); } generatedTypes.addAll(allTypeDefinitionsToGenTypes(module)); generatedTypes.addAll(allContainersToGenTypes(module)); generatedTypes.addAll(allListsToGenTypes(module)); generatedTypes.addAll(allChoicesToGenTypes(module)); - generatedTypes.addAll(allAugmentsToGenTypes(module)); generatedTypes.addAll(allRPCMethodsToGenType(module)); generatedTypes.addAll(allNotificationsToGenType(module)); generatedTypes.addAll(allIdentitiesToGenTypes(module, context)); - + } + for (module : modules) { + generatedTypes.addAll(allAugmentsToGenTypes(module)); + } return generatedTypes; } @@ -199,37 +185,43 @@ public final class BindingGeneratorImpl implements BindingGenerator { * @throws IllegalStateException * if context contain no modules */ - @Override - public List generateTypes(final SchemaContext context, final Set modules) { - Preconditions.checkArgument(context != null,"Schema Context reference cannot be NULL."); - Preconditions.checkState(context.getModules() != null,"Schema Context does not contain defined modules."); - Preconditions.checkArgument(modules != null,"Sef of Modules cannot be NULL."); + override generateTypes(SchemaContext context, Set 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."); - final List filteredGenTypes = new ArrayList<>(); + val List filteredGenTypes = new ArrayList(); schemaContext = context; typeProvider = new TypeProviderImpl(context); - final Set contextModules = context.getModules(); - genTypeBuilders = new HashMap<>(); - for (final Module contextModule : contextModules) { - final List generatedTypes = new ArrayList<>(); + val Set contextModules = context.modules; + genTypeBuilders = new HashMap(); + + for (contextModule : contextModules) { + val List generatedTypes = new ArrayList(); generatedTypes.addAll(allGroupingsToGenTypes(contextModule)); - if (false == contextModule.getChildNodes().isEmpty()) { + if (false == contextModule.childNodes.isEmpty()) { generatedTypes.add(moduleToDataType(contextModule)); } generatedTypes.addAll(allTypeDefinitionsToGenTypes(contextModule)); generatedTypes.addAll(allContainersToGenTypes(contextModule)); generatedTypes.addAll(allListsToGenTypes(contextModule)); generatedTypes.addAll(allChoicesToGenTypes(contextModule)); - generatedTypes.addAll(allAugmentsToGenTypes(contextModule)); generatedTypes.addAll(allRPCMethodsToGenType(contextModule)); generatedTypes.addAll(allNotificationsToGenType(contextModule)); generatedTypes.addAll(allIdentitiesToGenTypes(contextModule, context)); - + if (modules.contains(contextModule)) { filteredGenTypes.addAll(generatedTypes); } } + for (contextModule : contextModules) { + val generatedTypes = (allAugmentsToGenTypes(contextModule)); + if (modules.contains(contextModule)) { + filteredGenTypes.addAll(generatedTypes); + } + + } return filteredGenTypes; } @@ -249,17 +241,18 @@ public final class BindingGeneratorImpl implements BindingGenerator { * * */ - private List allTypeDefinitionsToGenTypes(final Module module) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - Preconditions.checkArgument(module.getName() != null,"Module name cannot be NULL."); - Preconditions.checkArgument(module.getTypeDefinitions() != null,"Type Definitions for module " + module.getName() + " cannot be NULL."); - - final Set> typeDefinitions = module.getTypeDefinitions(); - final List generatedTypes = new ArrayList<>(); - for (final TypeDefinition typedef : typeDefinitions) { - if (typedef != null) { - final Type type = ((TypeProviderImpl) typeProvider).generatedTypeForExtendedDefinitionType(typedef, typedef); - if ((type != null) && !generatedTypes.contains(type)) { + private def List allTypeDefinitionsToGenTypes( Module module) { + checkArgument(module !== null,"Module reference cannot be NULL."); + checkArgument(module.name !== null,"Module name cannot be NULL."); + val Set> typeDefinitions = module.typeDefinitions; + checkState(typeDefinitions !== null,'''Type Definitions for module «module.name» cannot be NULL.'''); + + + val List generatedTypes = new ArrayList(); + for ( TypeDefinition typedef : typeDefinitions) { + if (typedef !== null) { + val type = (typeProvider as TypeProviderImpl).generatedTypeForExtendedDefinitionType(typedef, typedef); + if ((type !== null) && !generatedTypes.contains(type)) { generatedTypes.add(type); } } @@ -284,21 +277,21 @@ public final class BindingGeneratorImpl implements BindingGenerator { * * */ - private List allContainersToGenTypes(final Module module) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); + private def List allContainersToGenTypes( Module module) { + checkArgument(module !== null,"Module reference cannot be NULL."); - Preconditions.checkArgument(module.getName() != null,"Module name cannot be NULL."); + checkArgument(module.name !== null,"Module name cannot be NULL."); - if (module.getChildNodes() == null) { - throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.getName() + if (module.childNodes === null) { + throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.name + " cannot be NULL."); } - final List generatedTypes = new ArrayList<>(); - final DataNodeIterator it = new DataNodeIterator(module); - final List schemaContainers = it.allContainers(); - final String basePackageName = moduleNamespaceToPackageName(module); - for (final ContainerSchemaNode container : schemaContainers) { + val List generatedTypes = new ArrayList(); + val it = new DataNodeIterator(module); + val List schemaContainers = it.allContainers(); + val basePackageName = moduleNamespaceToPackageName(module); + for (container : schemaContainers) { if (!container.isAddedByUses()) { generatedTypes.add(containerToGenType(basePackageName, container)); } @@ -323,22 +316,21 @@ public final class BindingGeneratorImpl implements BindingGenerator { * * */ - private List allListsToGenTypes(final Module module) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - - Preconditions.checkArgument(module.getName() != null,"Module name cannot be NULL."); + private def List allListsToGenTypes( Module module) { + checkArgument(module !== null,"Module reference cannot be NULL."); + checkArgument(module.name !== null,"Module name cannot be NULL."); - if (module.getChildNodes() == null) { - throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.getName() + if (module.childNodes === null) { + throw new IllegalArgumentException("Reference to Set of Child Nodes in module " + module.name + " cannot be NULL."); } - final List generatedTypes = new ArrayList<>(); - final DataNodeIterator it = new DataNodeIterator(module); - final List schemaLists = it.allLists(); - final String basePackageName = moduleNamespaceToPackageName(module); - if (schemaLists != null) { - for (final ListSchemaNode list : schemaLists) { + val List generatedTypes = new ArrayList(); + val it = new DataNodeIterator(module); + val List schemaLists = it.allLists(); + val basePackageName = moduleNamespaceToPackageName(module); + if (schemaLists !== null) { + for (list : schemaLists) { if (!list.isAddedByUses()) { generatedTypes.addAll(listToGenType(basePackageName, list)); } @@ -363,17 +355,17 @@ public final class BindingGeneratorImpl implements BindingGenerator { * * */ - private List allChoicesToGenTypes(final Module module) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - Preconditions.checkArgument(module.getName() != null,"Module name cannot be NULL."); + private def List allChoicesToGenTypes( Module module) { + checkArgument(module !== null,"Module reference cannot be NULL."); + checkArgument(module.name !== null,"Module name cannot be NULL."); - final DataNodeIterator it = new DataNodeIterator(module); - final List choiceNodes = it.allChoices(); - final String basePackageName = moduleNamespaceToPackageName(module); + val it = new DataNodeIterator(module); + val choiceNodes = it.allChoices(); + val basePackageName = moduleNamespaceToPackageName(module); - final List generatedTypes = new ArrayList<>(); - for (final ChoiceNode choice : choiceNodes) { - if ((choice != null) && !choice.isAddedByUses()) { + val List generatedTypes = new ArrayList(); + for (choice : choiceNodes) { + if ((choice !== null) && !choice.isAddedByUses()) { generatedTypes.addAll(choiceToGeneratedType(basePackageName, choice)); } } @@ -397,18 +389,18 @@ public final class BindingGeneratorImpl implements BindingGenerator { * * */ - private List allAugmentsToGenTypes(final Module module) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - Preconditions.checkArgument(module.getName() != null,"Module name cannot be NULL."); - if (module.getChildNodes() == null) { + private def List 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.getName() + " cannot be NULL."); + + module.name + " cannot be NULL."); } - final List generatedTypes = new ArrayList<>(); - final String basePackageName = moduleNamespaceToPackageName(module); - final List augmentations = resolveAugmentations(module); - for (final AugmentationSchema augment : augmentations) { + val List generatedTypes = new ArrayList(); + val basePackageName = moduleNamespaceToPackageName(module); + val List augmentations = resolveAugmentations(module); + for (augment : augmentations) { generatedTypes.addAll(augmentationToGenTypes(basePackageName, augment)); } return generatedTypes; @@ -430,33 +422,27 @@ public final class BindingGeneratorImpl implements BindingGenerator { * * */ - private List resolveAugmentations(final Module module) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - Preconditions.checkState(module.getAugmentations() != null,"Augmentations Set cannot be NULL."); - - final Set augmentations = module.getAugmentations(); - final List sortedAugmentations = new ArrayList<>(augmentations); - Collections.sort(sortedAugmentations, new Comparator() { + private def List resolveAugmentations( Module module) { + checkArgument(module !== null,"Module reference cannot be NULL."); + checkState(module.augmentations !== null,"Augmentations Set cannot be NULL."); - @Override - public int compare(AugmentationSchema augSchema1, AugmentationSchema augSchema2) { + val Set augmentations = module.augmentations; + val List sortedAugmentations = new ArrayList(augmentations); + Collections.sort(sortedAugmentations, [augSchema1, augSchema2 | - if (augSchema1.getTargetPath().getPath().size() > augSchema2.getTargetPath().getPath().size()) { + if (augSchema1.targetPath.path.size() > augSchema2.targetPath.path.size()) { return 1; - } else if (augSchema1.getTargetPath().getPath().size() < augSchema2.getTargetPath().getPath().size()) { + } else if (augSchema1.targetPath.path.size() < augSchema2.targetPath.path.size()) { return -1; } return 0; - - } - }); - + ]); return sortedAugmentations; } /** * Converts whole module to GeneratedType object. - * Firstly is created the module builder object from which is finally + * Firstly is created the module builder object from which is vally * obtained reference to GeneratedType object. * * @param module @@ -468,16 +454,16 @@ public final class BindingGeneratorImpl implements BindingGenerator { * if the module equals null * */ - private GeneratedType moduleToDataType(final Module module) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); + private def GeneratedType moduleToDataType( Module module) { + checkArgument(module !== null,"Module reference cannot be NULL."); - final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(module, "Data"); + val moduleDataTypeBuilder = moduleTypeBuilder(module, "Data"); addImplementedInterfaceFromUses(module, moduleDataTypeBuilder); - moduleDataTypeBuilder.addImplementsType(Types.typeForClass(DataRoot.class)); + moduleDataTypeBuilder.addImplementsType(DATA_ROOT); - final String basePackageName = moduleNamespaceToPackageName(module); - if (moduleDataTypeBuilder != null) { - final Set dataNodes = module.getChildNodes(); + val basePackageName = moduleNamespaceToPackageName(module); + if (moduleDataTypeBuilder !== null) { + val Set dataNodes = module.childNodes; resolveDataSchemaNodes(basePackageName, moduleDataTypeBuilder, dataNodes); } return moduleDataTypeBuilder.toInstance(); @@ -501,79 +487,78 @@ public final class BindingGeneratorImpl implements BindingGenerator { * * */ - private List allRPCMethodsToGenType(final Module module) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); + private def List allRPCMethodsToGenType( Module module) { + checkArgument(module !== null,"Module reference cannot be NULL."); - Preconditions.checkArgument(module.getName() != null,"Module name cannot be NULL."); + checkArgument(module.name !== null,"Module name cannot be NULL."); - if (module.getChildNodes() == null) { + if (module.childNodes === null) { throw new IllegalArgumentException("Reference to Set of RPC Method Definitions in module " - + module.getName() + " cannot be NULL."); + + module.name + " cannot be NULL."); } - final String basePackageName = moduleNamespaceToPackageName(module); - final Set rpcDefinitions = module.getRpcs(); + val basePackageName = moduleNamespaceToPackageName(module); + val Set rpcDefinitions = module.rpcs; if (rpcDefinitions.isEmpty()) { return Collections.emptyList(); } - final List genRPCTypes = new ArrayList<>(); - final GeneratedTypeBuilder interfaceBuilder = moduleTypeBuilder(module, "Service"); - interfaceBuilder.addImplementsType(Types.typeForClass(RpcService.class)); - final Type future = Types.typeForClass(Future.class); - for (final RpcDefinition rpc : rpcDefinitions) { - if (rpc != null) { + val List genRPCTypes = new ArrayList(); + val interfaceBuilder = moduleTypeBuilder(module, "Service"); + interfaceBuilder.addImplementsType(Types.typeForClass(RpcService)); + for (rpc : rpcDefinitions) { + if (rpc !== null) { - String rpcName = parseToClassName(rpc.getQName().getLocalName()); - String rpcMethodName = parseToValidParamName(rpcName); - MethodSignatureBuilder method = interfaceBuilder.addMethod(rpcMethodName); + val rpcName = parseToClassName(rpc.QName.localName); + val rpcMethodName = parseToValidParamName(rpcName); + val method = interfaceBuilder.addMethod(rpcMethodName); - final List rpcInOut = new ArrayList<>(); + val rpcInOut = new ArrayList(); - ContainerSchemaNode input = rpc.getInput(); - ContainerSchemaNode output = rpc.getOutput(); + val input = rpc.input; + val output = rpc.output; - if (input != null) { + if (input !== null) { rpcInOut.add(new DataNodeIterator(input)); - GeneratedTypeBuilder inType = addRawInterfaceDefinition(basePackageName, input, rpcName); + val inType = addRawInterfaceDefinition(basePackageName, input, rpcName); addImplementedInterfaceFromUses(input, inType); inType.addImplementsType(DATA_OBJECT); inType.addImplementsType(augmentable(inType)); - resolveDataSchemaNodes(basePackageName, inType, input.getChildNodes()); - Type inTypeInstance = inType.toInstance(); + resolveDataSchemaNodes(basePackageName, inType, input.childNodes); + val inTypeInstance = inType.toInstance(); genRPCTypes.add(inTypeInstance); method.addParameter(inTypeInstance, "input"); } - Type outTypeInstance = Types.typeForClass(Void.class); - if (output != null) { + var Type outTypeInstance = VOID; + if (output !== null) { rpcInOut.add(new DataNodeIterator(output)); - GeneratedTypeBuilder outType = addRawInterfaceDefinition(basePackageName, output, rpcName); + val outType = addRawInterfaceDefinition(basePackageName, output, rpcName); addImplementedInterfaceFromUses(output, outType); outType.addImplementsType(DATA_OBJECT); outType.addImplementsType(augmentable(outType)); - resolveDataSchemaNodes(basePackageName, outType, output.getChildNodes()); + resolveDataSchemaNodes(basePackageName, outType, output.childNodes); outTypeInstance = outType.toInstance(); genRPCTypes.add(outTypeInstance); } - final Type rpcRes = Types.parameterizedTypeFor(Types.typeForClass(RpcResult.class), outTypeInstance); - method.setReturnType(Types.parameterizedTypeFor(future, rpcRes)); - for (DataNodeIterator it : rpcInOut) { - List nContainers = it.allContainers(); - if ((nContainers != null) && !nContainers.isEmpty()) { - for (final ContainerSchemaNode container : nContainers) { + val rpcRes = Types.parameterizedTypeFor(Types.typeForClass(RpcResult), outTypeInstance); + method.setReturnType(Types.parameterizedTypeFor(FUTURE, rpcRes)); + for (iter : rpcInOut) { + val List nContainers = iter.allContainers(); + if ((nContainers !== null) && !nContainers.isEmpty()) { + for (container : nContainers) { if (!container.isAddedByUses()) { genRPCTypes.add(containerToGenType(basePackageName, container)); } } } - List nLists = it.allLists(); - if ((nLists != null) && !nLists.isEmpty()) { - for (final ListSchemaNode list : nLists) { + val List nLists = iter.allLists(); + if ((nLists !== null) && !nLists.isEmpty()) { + for (list : nLists) { if (!list.isAddedByUses()) { genRPCTypes.addAll(listToGenType(basePackageName, list)); } @@ -604,51 +589,50 @@ public final class BindingGeneratorImpl implements BindingGenerator { * * */ - private List allNotificationsToGenType(final Module module) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); + private def List allNotificationsToGenType( Module module) { + checkArgument(module !== null,"Module reference cannot be NULL."); - Preconditions.checkArgument(module.getName() != null,"Module name cannot be NULL."); + checkArgument(module.name !== null,"Module name cannot be NULL."); - if (module.getChildNodes() == null) { + if (module.childNodes === null) { throw new IllegalArgumentException("Reference to Set of Notification Definitions in module " - + module.getName() + " cannot be NULL."); + + module.name + " cannot be NULL."); } - final Set notifications = module.getNotifications(); + val notifications = module.notifications; if(notifications.isEmpty()) return Collections.emptyList(); - final GeneratedTypeBuilder listenerInterface = moduleTypeBuilder(module, "Listener"); + val listenerInterface = moduleTypeBuilder(module, "Listener"); listenerInterface.addImplementsType(BindingTypes.NOTIFICATION_LISTENER); - final String basePackageName = moduleNamespaceToPackageName(module); - final List generatedTypes = new ArrayList<>(); + val basePackageName = moduleNamespaceToPackageName(module); + val List generatedTypes = new ArrayList(); - for (final NotificationDefinition notification : notifications) { - if (notification != null) { - DataNodeIterator it = new DataNodeIterator(notification); + for ( notification : notifications) { + if (notification !== null) { + val iter = new DataNodeIterator(notification); // Containers - for (ContainerSchemaNode node : it.allContainers()) { + for (node : iter.allContainers()) { if (!node.isAddedByUses()) { generatedTypes.add(containerToGenType(basePackageName, node)); } } // Lists - for (ListSchemaNode node : it.allLists()) { + for (node : iter.allLists()) { if (!node.isAddedByUses()) { generatedTypes.addAll(listToGenType(basePackageName, node)); } } - final GeneratedTypeBuilder notificationInterface = addDefaultInterfaceDefinition(basePackageName, + val notificationInterface = addDefaultInterfaceDefinition(basePackageName, notification); - notificationInterface.addImplementsType(Types - .typeForClass(org.opendaylight.yangtools.yang.binding.Notification.class)); + notificationInterface.addImplementsType(NOTIFICATION); // Notification object - resolveDataSchemaNodes(basePackageName, notificationInterface, notification.getChildNodes()); + resolveDataSchemaNodes(basePackageName, notificationInterface, notification.childNodes); - listenerInterface.addMethod("on"+notificationInterface.getName()) // + listenerInterface.addMethod("on"+notificationInterface.name) // .setAccessModifier(AccessModifier.PUBLIC) .addParameter(notificationInterface, "notification") .setReturnType(Types.VOID); @@ -674,15 +658,15 @@ public final class BindingGeneratorImpl implements BindingGenerator { * (object of type IdentitySchemaNode * */ - private List allIdentitiesToGenTypes(final Module module, final SchemaContext context) { - List genTypes = new ArrayList<>(); + private def List allIdentitiesToGenTypes( Module module, SchemaContext context) { + val List genTypes = new ArrayList(); - final Set schemaIdentities = module.getIdentities(); + val Set schemaIdentities = module.identities; - final String basePackageName = moduleNamespaceToPackageName(module); + val basePackageName = moduleNamespaceToPackageName(module); - if (schemaIdentities != null && !schemaIdentities.isEmpty()) { - for (final IdentitySchemaNode identity : schemaIdentities) { + if (schemaIdentities !== null && !schemaIdentities.isEmpty()) { + for (identity : schemaIdentities) { genTypes.add(identityToGenType(basePackageName, identity, context)); } } @@ -709,27 +693,27 @@ public final class BindingGeneratorImpl implements BindingGenerator { * IdentitySchemaNode * */ - private GeneratedType identityToGenType(final String basePackageName, final IdentitySchemaNode identity, - final SchemaContext context) { - if (identity == null) { + private def GeneratedType identityToGenType(String basePackageName, IdentitySchemaNode identity, + SchemaContext context) { + if (identity === null) { return null; } - final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath()); - final String genTypeName = parseToClassName(identity.getQName().getLocalName()); - final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(packageName, genTypeName); + val packageName = packageNameForGeneratedType(basePackageName, identity.path); + val genTypeName = parseToClassName(identity.QName.localName); + val newType = new GeneratedTOBuilderImpl(packageName, genTypeName); - IdentitySchemaNode baseIdentity = identity.getBaseIdentity(); - if (baseIdentity != null) { - Module baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity); + val baseIdentity = identity.baseIdentity; + if (baseIdentity !== null) { + val baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity); - final String returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule); - final String returnTypeName = parseToClassName(baseIdentity.getQName().getLocalName()); + val returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule); + val returnTypeName = parseToClassName(baseIdentity.QName.localName); - GeneratedTransferObject gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName).toInstance(); + val gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName).toInstance(); newType.setExtendsType(gto); } else { - newType.setExtendsType(Types.getBaseIdentityTO()); + newType.setExtendsType(Types.baseIdentityTO); } newType.setAbstract(true); return newType.toInstance(); @@ -749,19 +733,17 @@ public final class BindingGeneratorImpl implements BindingGenerator { * (object of type GroupingDefinition) * */ - private List allGroupingsToGenTypes(final Module module) { - Preconditions.checkArgument(module != null,"Module parameter can not be null"); - final List genTypes = new ArrayList<>(); - final String basePackageName = moduleNamespaceToPackageName(module); - final Set groupings = module.getGroupings(); - List groupingsSortedByDependencies; - - groupingsSortedByDependencies = GroupingDefinitionDependencySort.sort(groupings); - - for (final GroupingDefinition grouping : groupingsSortedByDependencies) { - GeneratedType genType = groupingToGenType(basePackageName, grouping); + private def List allGroupingsToGenTypes( Module module) { + checkArgument(module !== null,"Module parameter can not be null"); + val List genTypes = new ArrayList(); + val basePackageName = moduleNamespaceToPackageName(module); + val Set groupings = module.groupings; + val List groupingsSortedByDependencies = GroupingDefinitionDependencySort.sort(groupings); + + for (grouping : groupingsSortedByDependencies) { + val genType = groupingToGenType(basePackageName, grouping); genTypes.add(genType); - SchemaPath schemaPath = grouping.getPath(); + val schemaPath = grouping.path; allGroupings.put(schemaPath, genType); } return genTypes; @@ -779,14 +761,14 @@ public final class BindingGeneratorImpl implements BindingGenerator { * @return GeneratedType which is generated from grouping (object of type * GroupingDefinition) */ - private GeneratedType groupingToGenType(final String basePackageName, GroupingDefinition grouping) { - if (grouping == null) { + private def GeneratedType groupingToGenType( String basePackageName, GroupingDefinition grouping) { + if (grouping === null) { return null; } - final String packageName = packageNameForGeneratedType(basePackageName, grouping.getPath()); - final Set schemaNodes = grouping.getChildNodes(); - final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, grouping); + val packageName = packageNameForGeneratedType(basePackageName, grouping.path); + val Set schemaNodes = grouping.childNodes; + val typeBuilder = addDefaultInterfaceDefinition(packageName, grouping); resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes); return typeBuilder.toInstance(); @@ -803,12 +785,12 @@ public final class BindingGeneratorImpl implements BindingGenerator { * @return EnumTypeDefinition if it is found inside * typeDefinition or null in other case */ - private EnumTypeDefinition enumTypeDefFromExtendedType(final TypeDefinition typeDefinition) { - if (typeDefinition != null) { - if (typeDefinition.getBaseType() instanceof EnumTypeDefinition) { - return (EnumTypeDefinition) typeDefinition.getBaseType(); - } else if (typeDefinition.getBaseType() instanceof ExtendedType) { - return enumTypeDefFromExtendedType(typeDefinition.getBaseType()); + 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; @@ -831,13 +813,13 @@ public final class BindingGeneratorImpl implements BindingGenerator { * @return enumeration builder which contais data from * enumTypeDef */ - private EnumBuilder resolveInnerEnumFromTypeDefinition(final EnumTypeDefinition enumTypeDef, final String enumName, - final GeneratedTypeBuilder typeBuilder) { - if ((enumTypeDef != null) && (typeBuilder != null) && (enumTypeDef.getQName() != null) - && (enumTypeDef.getQName().getLocalName() != null)) { + private def EnumBuilder resolveInnerEnumFromTypeDefinition( EnumTypeDefinition enumTypeDef, String enumName, + GeneratedTypeBuilder typeBuilder) { + if ((enumTypeDef !== null) && (typeBuilder !== null) && (enumTypeDef.QName !== null) + && (enumTypeDef.QName.localName !== null)) { - final String enumerationName = parseToClassName(enumName); - final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName); + val enumerationName = parseToClassName(enumName); + val enumBuilder = typeBuilder.addEnumeration(enumerationName); enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef); return enumBuilder; @@ -859,10 +841,10 @@ public final class BindingGeneratorImpl implements BindingGenerator { * @throws IllegalArgumentException * if module equals null */ - private GeneratedTypeBuilder moduleTypeBuilder(final Module module, final String postfix) { - Preconditions.checkArgument(module != null,"Module reference cannot be NULL."); - String packageName = moduleNamespaceToPackageName(module); - final String moduleName = parseToClassName(module.getName()) + postfix; + private def GeneratedTypeBuilder moduleTypeBuilder( Module module, String postfix) { + checkArgument(module !== null,"Module reference cannot be NULL."); + val packageName = moduleNamespaceToPackageName(module); + val moduleName = parseToClassName(module.name) + postfix; return new GeneratedTypeBuilderImpl(packageName, moduleName); @@ -890,35 +872,37 @@ public final class BindingGeneratorImpl implements BindingGenerator { *
  • if target path of augSchema equals null
  • * */ - private List augmentationToGenTypes(final String augmentPackageName, final AugmentationSchema augSchema) { - Preconditions.checkArgument(augmentPackageName != null,"Package Name cannot be NULL."); - Preconditions.checkArgument(augSchema != null,"Augmentation Schema cannot be NULL."); - Preconditions.checkState(augSchema.getTargetPath() != null,"Augmentation Schema does not contain Target Path (Target Path is NULL)."); + private def List augmentationToGenTypes( String augmentPackageName, AugmentationSchema augSchema) { + 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)."); - final List genTypes = new ArrayList<>(); + val List genTypes = new ArrayList(); // EVERY augmented interface will extends Augmentation interface // and DataObject interface!!! - final SchemaPath targetPath = augSchema.getTargetPath(); - final DataSchemaNode targetSchemaNode = findDataSchemaNode(schemaContext, targetPath); - if ((targetSchemaNode != null) && (targetSchemaNode.getQName() != null) - && (targetSchemaNode.getQName().getLocalName() != null)) { - final Module targetModule = findParentModule(schemaContext, targetSchemaNode); - final String targetBasePackage = moduleNamespaceToPackageName(targetModule); - final String targetPackageName = packageNameForGeneratedType(targetBasePackage, targetSchemaNode.getPath()); - final String targetSchemaNodeName = targetSchemaNode.getQName().getLocalName(); - final Set augChildNodes = augSchema.getChildNodes(); + val targetPath = augSchema.targetPath; + val targetSchemaNode = findDataSchemaNode(schemaContext, targetPath); + val targetType = yangToJavaMapping.get(targetSchemaNode.path); + if ((targetSchemaNode !== null) && (targetSchemaNode.QName !== null) + && (targetSchemaNode.QName.localName !== null)) { + + val targetPackageName = targetType.packageName; + val targetSchemaNodeName = targetType.name; + + + val augChildNodes = augSchema.childNodes; if (!(targetSchemaNode instanceof ChoiceNode)) { - final GeneratedTypeBuilder augTypeBuilder = addRawAugmentGenTypeDefinition(augmentPackageName, - targetPackageName, targetSchemaNodeName, augSchema); - final GeneratedType augType = augTypeBuilder.toInstance(); + val augTypeBuilder = addRawAugmentGenTypeDefinition(augmentPackageName, + targetType, augSchema); + val augType = augTypeBuilder.toInstance(); genTypes.add(augType); } else { - final Type refChoiceType = new ReferencedTypeImpl(targetPackageName, + val refChoiceType = new ReferencedTypeImpl(targetPackageName, parseToClassName(targetSchemaNodeName)); - final ChoiceNode choiceTarget = (ChoiceNode) targetSchemaNode; - final Set choiceCaseNodes = choiceTarget.getCases(); + val choiceTarget = targetSchemaNode as ChoiceNode; + val choiceCaseNodes = choiceTarget.cases; genTypes.addAll(generateTypesFromAugmentedChoiceCases(augmentPackageName, refChoiceType, choiceCaseNodes)); } @@ -946,22 +930,23 @@ public final class BindingGeneratorImpl implements BindingGenerator { * and uses of augment * @return generated type builder for augment */ - private GeneratedTypeBuilder addRawAugmentGenTypeDefinition(final String augmentPackageName, - final String targetPackageName, final String targetSchemaNodeName, final AugmentationSchema augSchema) { - final String targetTypeName = parseToClassName(targetSchemaNodeName); - Map augmentBuilders = genTypeBuilders.get(augmentPackageName); - if (augmentBuilders == null) { - augmentBuilders = new HashMap<>(); + private def GeneratedTypeBuilder addRawAugmentGenTypeDefinition( String augmentPackageName, + Type targetTypeRef, AugmentationSchema augSchema) { + var Map augmentBuilders = genTypeBuilders.get(augmentPackageName); + if (augmentBuilders === null) { + augmentBuilders = new HashMap(); genTypeBuilders.put(augmentPackageName, augmentBuilders); } - final String augIdentifier = getAugmentIdentifier(augSchema.getUnknownSchemaNodes()); + val augIdentifier = getAugmentIdentifier(augSchema.unknownSchemaNodes); - final String augTypeName = augIdentifier != null ? parseToClassName(augIdentifier) : augGenTypeName( - augmentBuilders, targetTypeName); - final Type targetTypeRef = new ReferencedTypeImpl(targetPackageName, targetTypeName); - final Set augChildNodes = augSchema.getChildNodes(); + val augTypeName = if (augIdentifier !== null ) { + parseToClassName(augIdentifier) + } else { + augGenTypeName(augmentBuilders, targetTypeRef.name); + } + val Set augChildNodes = augSchema.childNodes; - final GeneratedTypeBuilder augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augTypeName); + val augTypeBuilder = new GeneratedTypeBuilderImpl(augmentPackageName, augTypeName); augTypeBuilder.addImplementsType(DATA_OBJECT); augTypeBuilder.addImplementsType(Types.augmentationTypeFor(targetTypeRef)); @@ -977,16 +962,15 @@ public final class BindingGeneratorImpl implements BindingGenerator { * @param unknownSchemaNodes * @return */ - private String getAugmentIdentifier(List unknownSchemaNodes) { - String ret = null; - for (UnknownSchemaNode unknownSchemaNode : unknownSchemaNodes) { - QName nodeType = unknownSchemaNode.getNodeType(); - if (AUGMENT_IDENTIFIER_NAME.equals(nodeType.getLocalName()) - && YANG_EXT_NAMESPACE.equals(nodeType.getNamespace().toString())) { - return unknownSchemaNode.getNodeParameter(); + private def String getAugmentIdentifier(List 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 ret; + return null; } /** @@ -1002,45 +986,45 @@ public final class BindingGeneratorImpl implements BindingGenerator { * @return list of Type which represents container, list and * choice subnodes of augment */ - private List augmentationBodyToGenTypes(final String augBasePackageName, - final Set augChildNodes) { - final List genTypes = new ArrayList<>(); - final List augSchemaIts = new ArrayList<>(); - for (final DataSchemaNode childNode : augChildNodes) { + private def List augmentationBodyToGenTypes( String augBasePackageName, + Set augChildNodes) { + val List genTypes = new ArrayList(); + val List augSchemaIts = new ArrayList(); + for (childNode : augChildNodes) { if (childNode instanceof DataNodeContainer) { - augSchemaIts.add(new DataNodeIterator((DataNodeContainer) childNode)); + augSchemaIts.add(new DataNodeIterator(childNode as DataNodeContainer)); if (childNode instanceof ContainerSchemaNode) { - genTypes.add(containerToGenType(augBasePackageName, (ContainerSchemaNode) childNode)); + genTypes.add(containerToGenType(augBasePackageName, childNode as ContainerSchemaNode)); } else if (childNode instanceof ListSchemaNode) { - genTypes.addAll(listToGenType(augBasePackageName, (ListSchemaNode) childNode)); + genTypes.addAll(listToGenType(augBasePackageName, childNode as ListSchemaNode)); } } else if (childNode instanceof ChoiceNode) { - final ChoiceNode choice = (ChoiceNode) childNode; - for (final ChoiceCaseNode caseNode : choice.getCases()) { + val choice = childNode as ChoiceNode; + for (caseNode : choice.cases) { augSchemaIts.add(new DataNodeIterator(caseNode)); } - genTypes.addAll(choiceToGeneratedType(augBasePackageName, (ChoiceNode) childNode)); + genTypes.addAll(choiceToGeneratedType(augBasePackageName, childNode as ChoiceNode)); } } - for (final DataNodeIterator it : augSchemaIts) { - final List augContainers = it.allContainers(); - final List augLists = it.allLists(); - final List augChoices = it.allChoices(); + for (it : augSchemaIts) { + val List augContainers = it.allContainers(); + val List augLists = it.allLists(); + val List augChoices = it.allChoices(); - if (augContainers != null) { - for (final ContainerSchemaNode container : augContainers) { + if (augContainers !== null) { + for (container : augContainers) { genTypes.add(containerToGenType(augBasePackageName, container)); } } - if (augLists != null) { - for (final ListSchemaNode list : augLists) { + if (augLists !== null) { + for (list : augLists) { genTypes.addAll(listToGenType(augBasePackageName, list)); } } - if (augChoices != null) { - for (final ChoiceNode choice : augChoices) { + if (augChoices !== null) { + for (choice : augChoices) { genTypes.addAll(choiceToGeneratedType(augBasePackageName, choice)); } } @@ -1060,15 +1044,12 @@ public final class BindingGeneratorImpl implements BindingGenerator { * string with name of augmented node * @return string with unique name for augmentation builder */ - private String augGenTypeName(final Map builders, final String genTypeName) { - String augTypeName = genTypeName; - - int index = 1; - while ((builders != null) && builders.containsKey(genTypeName + index)) { - index++; + private def String augGenTypeName( Map builders, String genTypeName) { + var index = 1; + while ((builders !== null) && builders.containsKey(genTypeName + index)) { + index = index + 1; } - augTypeName += index; - return augTypeName; + return genTypeName + index; } /** @@ -1084,14 +1065,14 @@ public final class BindingGeneratorImpl implements BindingGenerator { * schema paths * @return generated type for containerNode */ - private GeneratedType containerToGenType(final String basePackageName, ContainerSchemaNode containerNode) { - if (containerNode == null) { + private def GeneratedType containerToGenType( String basePackageName, ContainerSchemaNode containerNode) { + if (containerNode === null) { return null; } - final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath()); - final Set schemaNodes = containerNode.getChildNodes(); - final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, containerNode); + val packageName = packageNameForGeneratedType(basePackageName, containerNode.path); + val schemaNodes = containerNode.childNodes; + val typeBuilder = addDefaultInterfaceDefinition(packageName, containerNode); resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes); return typeBuilder.toInstance(); @@ -1118,14 +1099,14 @@ public final class BindingGeneratorImpl implements BindingGenerator { * parameter. The getter methods (representing child nodes) could be * added to it. */ - private GeneratedTypeBuilder resolveDataSchemaNodes(final String basePackageName, - final GeneratedTypeBuilder typeBuilder, final Set schemaNodes) { - if ((schemaNodes != null) && (typeBuilder != null)) { - for (final DataSchemaNode schemaNode : schemaNodes) { - if (schemaNode.isAugmenting() || schemaNode.isAddedByUses()) { - continue; + private def GeneratedTypeBuilder resolveDataSchemaNodes( String basePackageName, + GeneratedTypeBuilder typeBuilder, Set schemaNodes) { + if ((schemaNodes !== null) && (typeBuilder !== null)) { + for (schemaNode : schemaNodes) { + if (!schemaNode.isAugmenting() && !schemaNode.isAddedByUses()) { + addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder); } - addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder); + } } return typeBuilder; @@ -1149,10 +1130,10 @@ public final class BindingGeneratorImpl implements BindingGenerator { * parameter typeBuilder. The getter method could be * added to it. */ - private GeneratedTypeBuilder augSchemaNodeToMethods(final String basePackageName, - final GeneratedTypeBuilder typeBuilder, final Set schemaNodes) { - if ((schemaNodes != null) && (typeBuilder != null)) { - for (final DataSchemaNode schemaNode : schemaNodes) { + private def GeneratedTypeBuilder augSchemaNodeToMethods( String basePackageName, + GeneratedTypeBuilder typeBuilder, Set schemaNodes) { + if ((schemaNodes !== null) && (typeBuilder !== null)) { + for (schemaNode : schemaNodes) { if (schemaNode.isAugmenting()) { addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder); } @@ -1174,19 +1155,15 @@ public final class BindingGeneratorImpl implements BindingGenerator { * generated type builder to which is schemaNode * added as a method. */ - private void addSchemaNodeToBuilderAsMethod(final String basePackageName, final DataSchemaNode schemaNode, - final GeneratedTypeBuilder typeBuilder) { - if (schemaNode != null && typeBuilder != null) { - if (schemaNode instanceof LeafSchemaNode) { - resolveLeafSchemaNodeAsMethod(typeBuilder, (LeafSchemaNode) schemaNode); - } else if (schemaNode instanceof LeafListSchemaNode) { - resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode); - } else if (schemaNode instanceof ContainerSchemaNode) { - resolveContainerSchemaNode(basePackageName, typeBuilder, (ContainerSchemaNode) schemaNode); - } else if (schemaNode instanceof ListSchemaNode) { - resolveListSchemaNode(basePackageName, typeBuilder, (ListSchemaNode) schemaNode); - } else if (schemaNode instanceof ChoiceNode) { - resolveChoiceSchemaNode(basePackageName, typeBuilder, (ChoiceNode) schemaNode); + private def void addSchemaNodeToBuilderAsMethod( String basePackageName, DataSchemaNode node, + GeneratedTypeBuilder typeBuilder) { + 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: resolveContainerSchemaNode(basePackageName, typeBuilder, node as ContainerSchemaNode) + case node instanceof ListSchemaNode: resolveListSchemaNode(basePackageName, typeBuilder, node as ListSchemaNode) + case node instanceof ChoiceNode: resolveChoiceSchemaNode(basePackageName, typeBuilder, node as ChoiceNode) } } } @@ -1216,17 +1193,17 @@ public final class BindingGeneratorImpl implements BindingGenerator { * * */ - private void resolveChoiceSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder, - final ChoiceNode choiceNode) { - Preconditions.checkArgument(basePackageName != null,"Base Package Name cannot be NULL."); - Preconditions.checkArgument(typeBuilder != null,"Generated Type Builder cannot be NULL."); - Preconditions.checkArgument(choiceNode != null,"Choice Schema Node cannot be NULL."); - - final String choiceName = choiceNode.getQName().getLocalName(); - if (choiceName != null && !choiceNode.isAddedByUses()) { - final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath()); - final GeneratedTypeBuilder choiceType = addDefaultInterfaceDefinition(packageName, choiceNode); - constructGetter(typeBuilder, choiceName, choiceNode.getDescription(), choiceType); + private def void resolveChoiceSchemaNode( String basePackageName, GeneratedTypeBuilder typeBuilder, + ChoiceNode choiceNode) { + checkArgument(basePackageName !== null,"Base Package Name cannot be NULL."); + checkArgument(typeBuilder !== null,"Generated Type Builder cannot be NULL."); + checkArgument(choiceNode !== null,"Choice Schema Node cannot be NULL."); + + val choiceName = choiceNode.QName.localName; + if (choiceName !== null && !choiceNode.isAddedByUses()) { + val packageName = packageNameForGeneratedType(basePackageName, choiceNode.path); + val choiceType = addDefaultInterfaceDefinition(packageName, choiceNode); + constructGetter(typeBuilder, choiceName, choiceNode.description, choiceType); } } @@ -1253,19 +1230,19 @@ public final class BindingGeneratorImpl implements BindingGenerator { * * */ - private List choiceToGeneratedType(final String basePackageName, final ChoiceNode choiceNode) { - Preconditions.checkArgument(basePackageName != null,"Base Package Name cannot be NULL."); - Preconditions.checkArgument(choiceNode != null,"Choice Schema Node cannot be NULL."); + private def List choiceToGeneratedType( String basePackageName, ChoiceNode choiceNode) { + checkArgument(basePackageName !== null,"Base Package Name cannot be NULL."); + checkArgument(choiceNode !== null,"Choice Schema Node cannot be NULL."); - final List generatedTypes = new ArrayList<>(); - final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath()); - final GeneratedTypeBuilder choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode); - choiceTypeBuilder.addImplementsType(DATA_OBJECT); - final GeneratedType choiceType = choiceTypeBuilder.toInstance(); + val List generatedTypes = new ArrayList(); + val packageName = packageNameForGeneratedType(basePackageName, choiceNode.path); + val choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode); + //choiceTypeBuilder.addImplementsType(DATA_OBJECT); + val choiceType = choiceTypeBuilder.toInstance(); generatedTypes.add(choiceType); - final Set caseNodes = choiceNode.getCases(); - if ((caseNodes != null) && !caseNodes.isEmpty()) { + val Set caseNodes = choiceNode.cases; + if ((caseNodes !== null) && !caseNodes.isEmpty()) { generatedTypes.addAll(generateTypesFromChoiceCases(basePackageName, choiceType, caseNodes)); } return generatedTypes; @@ -1297,21 +1274,21 @@ public final class BindingGeneratorImpl implements BindingGenerator { * * * */ - private List generateTypesFromChoiceCases(final String basePackageName, final Type refChoiceType, - final Set caseNodes) { - Preconditions.checkArgument(basePackageName != null,"Base Package Name cannot be NULL."); - Preconditions.checkArgument(refChoiceType != null,"Referenced Choice Type cannot be NULL."); - Preconditions.checkArgument(caseNodes != null,"Set of Choice Case Nodes cannot be NULL."); - - final List generatedTypes = new ArrayList<>(); - for (final ChoiceCaseNode caseNode : caseNodes) { - if (caseNode != null && !caseNode.isAddedByUses() && !caseNode.isAugmenting()) { - final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath()); - final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode); + private def List generateTypesFromChoiceCases( String basePackageName, Type refChoiceType, + Set caseNodes) { + checkArgument(basePackageName !== null,"Base Package Name cannot be NULL."); + checkArgument(refChoiceType !== null,"Referenced Choice Type cannot be NULL."); + checkArgument(caseNodes !== null,"Set of Choice Case Nodes cannot be NULL."); + + val List generatedTypes = new ArrayList(); + for (caseNode : caseNodes) { + if (caseNode !== null && !caseNode.isAddedByUses() && !caseNode.isAugmenting()) { + val packageName = packageNameForGeneratedType(basePackageName, caseNode.path); + val caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode); caseTypeBuilder.addImplementsType(refChoiceType); - final Set childNodes = caseNode.getChildNodes(); - if (childNodes != null) { + val Set childNodes = caseNode.childNodes; + if (childNodes !== null) { resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes); } generatedTypes.add(caseTypeBuilder.toInstance()); @@ -1346,21 +1323,21 @@ public final class BindingGeneratorImpl implements BindingGenerator { *
  • if caseNodes equals null
  • * */ - private List generateTypesFromAugmentedChoiceCases(final String basePackageName, - final Type refChoiceType, final Set caseNodes) { - Preconditions.checkArgument(basePackageName != null,"Base Package Name cannot be NULL."); - Preconditions.checkArgument(refChoiceType != null,"Referenced Choice Type cannot be NULL."); - Preconditions.checkArgument(caseNodes != null,"Set of Choice Case Nodes cannot be NULL."); - - final List generatedTypes = new ArrayList<>(); - for (final ChoiceCaseNode caseNode : caseNodes) { - if (caseNode != null && caseNode.isAugmenting()) { - final String packageName = packageNameForGeneratedType(basePackageName, caseNode.getPath()); - final GeneratedTypeBuilder caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode); + private def List generateTypesFromAugmentedChoiceCases( String basePackageName, + Type refChoiceType, Set caseNodes) { + checkArgument(basePackageName !== null,"Base Package Name cannot be NULL."); + checkArgument(refChoiceType !== null,"Referenced Choice Type cannot be NULL."); + checkArgument(caseNodes !== null,"Set of Choice Case Nodes cannot be NULL."); + + val List generatedTypes = new ArrayList(); + for (caseNode : caseNodes) { + if (caseNode !== null && caseNode.isAugmenting()) { + val packageName = packageNameForGeneratedType(basePackageName, caseNode.path); + val caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode); caseTypeBuilder.addImplementsType(refChoiceType); - final Set childNodes = caseNode.getChildNodes(); - if (childNodes != null) { + val Set childNodes = caseNode.childNodes; + if (childNodes !== null) { resolveDataSchemaNodes(basePackageName, caseTypeBuilder, childNodes); } generatedTypes.add(caseTypeBuilder.toInstance()); @@ -1387,43 +1364,43 @@ public final class BindingGeneratorImpl implements BindingGenerator { *
  • true - in other cases
  • * */ - private boolean resolveLeafSchemaNodeAsMethod(final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf) { - if ((leaf != null) && (typeBuilder != null)) { - final String leafName = leaf.getQName().getLocalName(); - String leafDesc = leaf.getDescription(); - if (leafDesc == null) { + private def boolean resolveLeafSchemaNodeAsMethod( GeneratedTypeBuilder typeBuilder, LeafSchemaNode leaf) { + if ((leaf !== null) && (typeBuilder !== null)) { + val leafName = leaf.QName.localName; + var String leafDesc = leaf.description; + if (leafDesc === null) { leafDesc = ""; } - final Module parentModule = findParentModule(schemaContext, leaf); - if (leafName != null && !leaf.isAddedByUses()) { - final TypeDefinition typeDef = leaf.getType(); + val parentModule = findParentModule(schemaContext, leaf); + if (leafName !== null && !leaf.isAddedByUses()) { + val TypeDefinition typeDef = leaf.type; - Type returnType = null; + var Type returnType = null; if (typeDef instanceof EnumTypeDefinition) { returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf); - final EnumTypeDefinition enumTypeDef = enumTypeDefFromExtendedType(typeDef); - final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leafName, + val enumTypeDef = enumTypeDefFromExtendedType(typeDef); + val enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leafName, typeBuilder); - if (enumBuilder != null) { - returnType = new ReferencedTypeImpl(enumBuilder.getPackageName(), enumBuilder.getName()); + if (enumBuilder !== null) { + returnType = new ReferencedTypeImpl(enumBuilder.packageName, enumBuilder.name); } - ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType); + (typeProvider as TypeProviderImpl).putReferencedType(leaf.path, returnType); } else if (typeDef instanceof UnionType) { - GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, leaf, parentModule); - if (genTOBuilder != null) { - returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName()); + val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, leaf, parentModule); + if (genTOBuilder !== null) { + returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name); } } else if (typeDef instanceof BitsTypeDefinition) { - GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, leaf, parentModule); - if (genTOBuilder != null) { - returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName()); + val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, leaf, parentModule); + if (genTOBuilder !== null) { + returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name); } } else { returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf); } - if (returnType != null) { + if (returnType !== null) { constructGetter(typeBuilder, leafName, leafDesc, returnType); return true; } @@ -1451,23 +1428,23 @@ public final class BindingGeneratorImpl implements BindingGenerator { *
  • true - other cases
  • * */ - private boolean resolveLeafSchemaNodeAsProperty(final GeneratedTOBuilder toBuilder, final LeafSchemaNode leaf, + private def boolean resolveLeafSchemaNodeAsProperty( GeneratedTOBuilder toBuilder, LeafSchemaNode leaf, boolean isReadOnly) { - if ((leaf != null) && (toBuilder != null)) { - final String leafName = leaf.getQName().getLocalName(); - String leafDesc = leaf.getDescription(); - if (leafDesc == null) { + if ((leaf !== null) && (toBuilder !== null)) { + val leafName = leaf.QName.localName; + var String leafDesc = leaf.description; + if (leafDesc === null) { leafDesc = ""; } - if (leafName != null && !leaf.isAddedByUses()) { - final TypeDefinition typeDef = leaf.getType(); + if (leafName !== null && !leaf.isAddedByUses()) { + val TypeDefinition typeDef = leaf.type; // TODO: properly resolve enum types - final Type returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf); + val returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf); - if (returnType != null) { - final GeneratedPropertyBuilder propBuilder = toBuilder.addProperty(parseToClassName(leafName)); + if (returnType !== null) { + val propBuilder = toBuilder.addProperty(parseToClassName(leafName)); propBuilder.setReadOnly(isReadOnly); propBuilder.setReturnType(returnType); @@ -1501,17 +1478,17 @@ public final class BindingGeneratorImpl implements BindingGenerator { *
  • false - other cases
  • * */ - private boolean resolveLeafListSchemaNode(final GeneratedTypeBuilder typeBuilder, final LeafListSchemaNode node) { - if ((node != null) && (typeBuilder != null)) { - final String nodeName = node.getQName().getLocalName(); - String nodeDesc = node.getDescription(); - if (nodeDesc == null) { + private def boolean resolveLeafListSchemaNode( GeneratedTypeBuilder typeBuilder, LeafListSchemaNode node) { + if ((node !== null) && (typeBuilder !== null)) { + val nodeName = node.QName.localName; + var String nodeDesc = node.description; + if (nodeDesc === null) { nodeDesc = ""; } - if (nodeName != null && !node.isAddedByUses()) { - final TypeDefinition type = node.getType(); - final Type listType = Types.listTypeFor(typeProvider.javaTypeForSchemaDefinitionType(type, node)); + if (nodeName !== null && !node.isAddedByUses()) { + val TypeDefinition type = node.type; + val listType = Types.listTypeFor(typeProvider.javaTypeForSchemaDefinitionType(type, node)); constructGetter(typeBuilder, nodeName, nodeDesc, listType); return true; @@ -1546,16 +1523,16 @@ public final class BindingGeneratorImpl implements BindingGenerator { *
  • true - other cases
  • * */ - private boolean resolveContainerSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder, - final ContainerSchemaNode containerNode) { - if ((containerNode != null) && (typeBuilder != null)) { - final String nodeName = containerNode.getQName().getLocalName(); + private def boolean resolveContainerSchemaNode( String basePackageName, GeneratedTypeBuilder typeBuilder, + ContainerSchemaNode containerNode) { + if ((containerNode !== null) && (typeBuilder !== null)) { + val nodeName = containerNode.QName.localName; - if (nodeName != null && !containerNode.isAddedByUses()) { - final String packageName = packageNameForGeneratedType(basePackageName, containerNode.getPath()); + if (nodeName !== null && !containerNode.isAddedByUses()) { + val packageName = packageNameForGeneratedType(basePackageName, containerNode.path); - final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, containerNode); - constructGetter(typeBuilder, nodeName, containerNode.getDescription(), rawGenType); + val rawGenType = addDefaultInterfaceDefinition(packageName, containerNode); + constructGetter(typeBuilder, nodeName, containerNode.description, rawGenType); return true; } @@ -1588,15 +1565,15 @@ public final class BindingGeneratorImpl implements BindingGenerator { *
  • true - other cases
  • * */ - private boolean resolveListSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder, - final ListSchemaNode listNode) { - if ((listNode != null) && (typeBuilder != null)) { - final String listName = listNode.getQName().getLocalName(); - - if (listName != null && !listNode.isAddedByUses()) { - final String packageName = packageNameForGeneratedType(basePackageName, listNode.getPath()); - final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, listNode); - constructGetter(typeBuilder, listName, listNode.getDescription(), Types.listTypeFor(rawGenType)); + private def boolean resolveListSchemaNode( String basePackageName, GeneratedTypeBuilder typeBuilder, + ListSchemaNode listNode) { + if ((listNode !== null) && (typeBuilder !== null)) { + val listName = listNode.QName.localName; + + if (listName !== null && !listNode.isAddedByUses()) { + val packageName = packageNameForGeneratedType(basePackageName, listNode.path); + val rawGenType = addDefaultInterfaceDefinition(packageName, listNode); + constructGetter(typeBuilder, listName, listNode.description, Types.listTypeFor(rawGenType)); return true; } } @@ -1624,15 +1601,15 @@ public final class BindingGeneratorImpl implements BindingGenerator { * schema node for which is created generated type builder * @return generated type builder schemaNode */ - private GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode schemaNode) { - final GeneratedTypeBuilder builder = addRawInterfaceDefinition(packageName, schemaNode, ""); + private def GeneratedTypeBuilder addDefaultInterfaceDefinition( String packageName, SchemaNode schemaNode) { + val builder = addRawInterfaceDefinition(packageName, schemaNode, ""); builder.addImplementsType(DATA_OBJECT); if (!(schemaNode instanceof GroupingDefinition)) { builder.addImplementsType(augmentable(builder)); } if (schemaNode instanceof DataNodeContainer) { - addImplementedInterfaceFromUses((DataNodeContainer) schemaNode, builder); + addImplementedInterfaceFromUses( schemaNode as DataNodeContainer, builder); } return builder; @@ -1648,7 +1625,7 @@ public final class BindingGeneratorImpl implements BindingGenerator { * schema node which provide data about the schema node name * @return generated type builder for schemaNode */ - private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode) { + private def GeneratedTypeBuilder addRawInterfaceDefinition( String packageName, SchemaNode schemaNode) { return addRawInterfaceDefinition(packageName, schemaNode, ""); } @@ -1675,28 +1652,29 @@ public final class BindingGeneratorImpl implements BindingGenerator { * * */ - private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode, - final String prefix) { - Preconditions.checkArgument(schemaNode != null,"Data Schema Node cannot be NULL."); - Preconditions.checkArgument(packageName != null,"Package Name for Generated Type cannot be NULL."); - Preconditions.checkArgument(schemaNode.getQName() != null,"QName for Data Schema Node cannot be NULL."); - final String schemaNodeName = schemaNode.getQName().getLocalName(); - Preconditions.checkArgument(schemaNodeName != null,"Local Name of QName for Data Schema Node cannot be NULL."); - - final String genTypeName; - if (prefix == null) { + 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 = parseToClassName(schemaNodeName); } else { genTypeName = prefix + parseToClassName(schemaNodeName); } - - final GeneratedTypeBuilder newType = new GeneratedTypeBuilderImpl(packageName, genTypeName); + //FIXME: Validation of name conflict + val newType = new GeneratedTypeBuilderImpl(packageName, genTypeName); + yangToJavaMapping.put(schemaNode.path,newType); if (!genTypeBuilders.containsKey(packageName)) { - final Map builders = new HashMap<>(); + val Map builders = new HashMap(); builders.put(genTypeName, newType); genTypeBuilders.put(packageName, builders); } else { - final Map builders = genTypeBuilders.get(packageName); + val Map builders = genTypeBuilders.get(packageName); if (!builders.containsKey(genTypeName)) { builders.put(genTypeName, newType); } @@ -1712,8 +1690,8 @@ public final class BindingGeneratorImpl implements BindingGenerator { * @return string with the name of the getter method for * methodName in JAVA method format */ - private String getterMethodName(final String methodName,Type returnType) { - final StringBuilder method = new StringBuilder(); + private def String getterMethodName( String methodName,Type returnType) { + val method = new StringBuilder(); if(BOOLEAN.equals(returnType)) { method.append("is"); } else { @@ -1723,21 +1701,6 @@ public final class BindingGeneratorImpl implements BindingGenerator { return method.toString(); } - /** - * Creates the name of the setter method from methodName. - * - * @param methodName - * string with the name of the setter method - * @return string with the name of the setter method for - * methodName in JAVA method format - */ - private String setterMethodName(final String methodName) { - final StringBuilder method = new StringBuilder(); - method.append("set"); - method.append(parseToClassName(methodName)); - return method.toString(); - } - /** * Created a method signature builder as part of * interfaceBuilder. @@ -1759,10 +1722,10 @@ public final class BindingGeneratorImpl implements BindingGenerator { * @return method signature builder which represents the getter method of * interfaceBuilder */ - private MethodSignatureBuilder constructGetter(final GeneratedTypeBuilder interfaceBuilder, - final String schemaNodeName, final String comment, final Type returnType) { + private def MethodSignatureBuilder constructGetter( GeneratedTypeBuilder interfaceBuilder, + String schemaNodeName, String comment, Type returnType) { - final MethodSignatureBuilder getMethod = interfaceBuilder.addMethod(getterMethodName(schemaNodeName,returnType)); + val getMethod = interfaceBuilder.addMethod(getterMethodName(schemaNodeName,returnType)); getMethod.setComment(comment); getMethod.setReturnType(returnType); @@ -1770,33 +1733,30 @@ public final class BindingGeneratorImpl implements BindingGenerator { return getMethod; } - private List listToGenType(final String basePackageName, final ListSchemaNode list) { - Preconditions.checkArgument(basePackageName != null,"Package Name for Generated Type cannot be NULL."); - Preconditions.checkArgument(list != null,"List Schema Node cannot be NULL."); + private def listToGenType( String basePackageName, ListSchemaNode list) { + checkArgument(basePackageName !== null,"Package Name for Generated Type cannot be NULL."); + checkArgument(list !== null,"List Schema Node cannot be NULL."); - final String packageName = packageNameForGeneratedType(basePackageName, list.getPath()); - // final GeneratedTypeBuilder typeBuilder = + val packageName = packageNameForGeneratedType(basePackageName, list.path); + // val typeBuilder = // resolveListTypeBuilder(packageName, list); - final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, list); + val typeBuilder = addDefaultInterfaceDefinition(packageName, list); - final List listKeys = listKeys(list); - GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, list); + val List listKeys = listKeys(list); + val genTOBuilder = resolveListKeyTOBuilder(packageName, list); - if (genTOBuilder != null) { - ParameterizedType identifierMarker = Types.parameterizedTypeFor(Types.typeForClass(Identifier.class), - typeBuilder); - ParameterizedType identifiableMarker = Types.parameterizedTypeFor(Types.typeForClass(Identifiable.class), - genTOBuilder); + if (genTOBuilder !== null) { + val identifierMarker = IDENTIFIER.parameterizedTypeFor(typeBuilder); + val identifiableMarker = IDENTIFIABLE.parameterizedTypeFor(genTOBuilder); genTOBuilder.addImplementsType(identifierMarker); typeBuilder.addImplementsType(identifiableMarker); } - final Set schemaNodes = list.getChildNodes(); + val schemaNodes = list.childNodes; - for (final DataSchemaNode schemaNode : schemaNodes) { - if (schemaNode.isAugmenting()) { - continue; + for (schemaNode : schemaNodes) { + if (!schemaNode.isAugmenting()) { + addSchemaNodeToListBuilders(basePackageName, schemaNode, typeBuilder, genTOBuilder, listKeys); } - addSchemaNodeToListBuilders(basePackageName, schemaNode, typeBuilder, genTOBuilder, listKeys); } return typeBuildersToGenTypes(typeBuilder, genTOBuilder); } @@ -1823,35 +1783,35 @@ public final class BindingGeneratorImpl implements BindingGenerator { *
  • if typeBuilder equals null
  • * */ - private void addSchemaNodeToListBuilders(final String basePackageName, final DataSchemaNode schemaNode, - final GeneratedTypeBuilder typeBuilder, final GeneratedTOBuilder genTOBuilder, final List listKeys) { - Preconditions.checkArgument(schemaNode != null,"Data Schema Node cannot be NULL."); + private def void addSchemaNodeToListBuilders( String basePackageName, DataSchemaNode schemaNode, + GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder, List listKeys) { + checkArgument(schemaNode !== null,"Data Schema Node cannot be NULL."); - Preconditions.checkArgument(typeBuilder != null,"Generated Type Builder 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(); + val leaf = schemaNode as LeafSchemaNode; + val leafName = leaf.QName.localName; if (!listKeys.contains(leafName)) { resolveLeafSchemaNodeAsMethod(typeBuilder, leaf); } else { resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true); } } else if (schemaNode instanceof LeafListSchemaNode) { - resolveLeafListSchemaNode(typeBuilder, (LeafListSchemaNode) schemaNode); + resolveLeafListSchemaNode(typeBuilder, schemaNode as LeafListSchemaNode); } else if (schemaNode instanceof ContainerSchemaNode) { - resolveContainerSchemaNode(basePackageName, typeBuilder, (ContainerSchemaNode) schemaNode); + resolveContainerSchemaNode(basePackageName, typeBuilder, schemaNode as ContainerSchemaNode); } else if (schemaNode instanceof ListSchemaNode) { - resolveListSchemaNode(basePackageName, typeBuilder, (ListSchemaNode) schemaNode); + resolveListSchemaNode(basePackageName, typeBuilder, schemaNode as ListSchemaNode); } } - private List typeBuildersToGenTypes(final GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder) { - final List genTypes = new ArrayList<>(); - Preconditions.checkArgument(typeBuilder != null,"Generated Type Builder cannot be NULL."); + private def typeBuildersToGenTypes( GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder) { + val List genTypes = new ArrayList(); + checkArgument(typeBuilder !== null,"Generated Type Builder cannot be NULL."); - if (genTOBuilder != null) { - final GeneratedTransferObject genTO = genTOBuilder.toInstance(); + if (genTOBuilder !== null) { + val genTO = genTOBuilder.toInstance(); constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", genTO); genTypes.add(genTO); } @@ -1869,14 +1829,13 @@ public final class BindingGeneratorImpl implements BindingGenerator { * list contains no keys then the empty list is * returned. */ - private List listKeys(final ListSchemaNode list) { - final List listKeys = new ArrayList<>(); + private def listKeys( ListSchemaNode list) { + val List listKeys = new ArrayList(); - if (list.getKeyDefinition() != null) { - final List keyDefinitions = list.getKeyDefinition(); - - for (final QName keyDefinition : keyDefinitions) { - listKeys.add(keyDefinition.getLocalName()); + if (list.keyDefinition !== null) { + val keyDefinitions = list.keyDefinition; + for (keyDefinition : keyDefinitions) { + listKeys.add(keyDefinition.localName); } } return listKeys; @@ -1894,11 +1853,11 @@ public final class BindingGeneratorImpl implements BindingGenerator { * list or null if list is null or list of * key definitions is null or empty. */ - private GeneratedTOBuilder resolveListKeyTOBuilder(final String packageName, final ListSchemaNode list) { - GeneratedTOBuilder genTOBuilder = null; - if ((list.getKeyDefinition() != null) && (!list.getKeyDefinition().isEmpty())) { - if (list != null) { - final String listName = list.getQName().getLocalName() + "Key"; + private def GeneratedTOBuilder resolveListKeyTOBuilder( String packageName, ListSchemaNode list) { + var GeneratedTOBuilder genTOBuilder = null; + if ((list.keyDefinition !== null) && (!list.keyDefinition.isEmpty())) { + if (list !== null) { + val listName = list.QName.localName + "Key"; genTOBuilder = schemaNodeToTransferObjectBuilder(packageName, listName); } } @@ -1927,20 +1886,20 @@ public final class BindingGeneratorImpl implements BindingGenerator { * string with name for generated TO builder * @return generated TO builder for typeDef */ - private GeneratedTOBuilder addTOToTypeBuilder(TypeDefinition typeDef, GeneratedTypeBuilder typeBuilder, + private def GeneratedTOBuilder addTOToTypeBuilder(TypeDefinition typeDef, GeneratedTypeBuilder typeBuilder, String leafName, LeafSchemaNode leaf, Module parentModule) { - final String classNameFromLeaf = parseToClassName(leafName); - List genTOBuilders = new ArrayList<>(); - final String packageName = typeBuilder.getFullyQualifiedName(); + val classNameFromLeaf = parseToClassName(leafName); + val List genTOBuilders = new ArrayList(); + val packageName = typeBuilder.fullyQualifiedName; if (typeDef instanceof UnionTypeDefinition) { - genTOBuilders.addAll(((TypeProviderImpl) typeProvider).provideGeneratedTOBuildersForUnionTypeDef( + genTOBuilders.addAll((typeProvider as TypeProviderImpl).provideGeneratedTOBuildersForUnionTypeDef( packageName, typeDef, classNameFromLeaf, leaf)); } else if (typeDef instanceof BitsTypeDefinition) { - genTOBuilders.add(((TypeProviderImpl) typeProvider).provideGeneratedTOBuilderForBitsTypeDefinition( + genTOBuilders.add(((typeProvider as TypeProviderImpl) ).provideGeneratedTOBuilderForBitsTypeDefinition( packageName, typeDef, classNameFromLeaf)); } - if (genTOBuilders != null && !genTOBuilders.isEmpty()) { - for (GeneratedTOBuilder genTOBuilder : genTOBuilders) { + if (genTOBuilders !== null && !genTOBuilders.isEmpty()) { + for (genTOBuilder : genTOBuilders) { typeBuilder.addEnclosingTransferObject(genTOBuilder); } return genTOBuilders.get(0); @@ -1955,7 +1914,7 @@ public final class BindingGeneratorImpl implements BindingGenerator { * The method passes through the list of uses in * {@code dataNodeContainer}. For every use is obtained coresponding * generated type from {@link BindingGeneratorImpl#allGroupings - * allGroupings} which is adde as implements type to + * allGroupings} which is added as implements type to * builder * * @param dataNodeContainer @@ -1965,19 +1924,18 @@ public final class BindingGeneratorImpl implements BindingGenerator { * dataNodeContainer * @return generated type builder with all implemented types */ - private GeneratedTypeBuilder addImplementedInterfaceFromUses(final DataNodeContainer dataNodeContainer, - final GeneratedTypeBuilder builder) { - for (UsesNode usesNode : dataNodeContainer.getUses()) { - if (usesNode.getGroupingPath() != null) { - GeneratedType genType = allGroupings.get(usesNode.getGroupingPath()); - if (genType == null) { - throw new IllegalStateException("Grouping " + usesNode.getGroupingPath() + "is not resolved for " - + builder.getName()); + private def addImplementedInterfaceFromUses( DataNodeContainer dataNodeContainer, + GeneratedTypeBuilder builder) { + for (usesNode : dataNodeContainer.uses) { + if (usesNode.groupingPath !== null) { + val genType = allGroupings.get(usesNode.groupingPath); + if (genType === null) { + throw new IllegalStateException("Grouping " + usesNode.groupingPath + "is not resolved for " + + builder.name); } builder.addImplementsType(genType); } } return builder; } - } diff --git a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java index 513390c75e..14e0c67889 100644 --- a/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java +++ b/code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java @@ -365,7 +365,7 @@ public final class TypeProviderImpl implements TypeProvider { } else { final Module module = findParentModule(schemaContext, parentNode); if (module != null) { - final DataSchemaNode dataNode; + final SchemaNode dataNode; if (xpath.isAbsolute()) { dataNode = findDataSchemaNode(schemaContext, module, xpath); } else { @@ -398,7 +398,7 @@ public final class TypeProviderImpl implements TypeProvider { *
  • false - other cases
  • * */ - private boolean leafContainsEnumDefinition(final DataSchemaNode dataNode) { + private boolean leafContainsEnumDefinition(final SchemaNode dataNode) { if (dataNode instanceof LeafSchemaNode) { final LeafSchemaNode leaf = (LeafSchemaNode) dataNode; if (leaf.getType() instanceof EnumTypeDefinition) { @@ -422,7 +422,7 @@ public final class TypeProviderImpl implements TypeProvider { *
  • false - other cases
  • * */ - private boolean leafListContainsEnumDefinition(final DataSchemaNode dataNode) { + private boolean leafListContainsEnumDefinition(final SchemaNode dataNode) { if (dataNode instanceof LeafListSchemaNode) { final LeafListSchemaNode leafList = (LeafListSchemaNode) dataNode; if (leafList.getType() instanceof EnumTypeDefinition) { @@ -516,7 +516,7 @@ public final class TypeProviderImpl implements TypeProvider { * contains information about YANG type * @return JAVA Type representation of dataNode */ - private Type resolveTypeFromDataSchemaNode(final DataSchemaNode dataNode) { + private Type resolveTypeFromDataSchemaNode(final SchemaNode dataNode) { Type returnType = null; if (dataNode != null) { if (dataNode instanceof LeafSchemaNode) { diff --git a/model/enum/src/main/yang/.gitignore b/model/enum/src/main/yang/.gitignore new file mode 100644 index 0000000000..e69de29bb2 diff --git a/yang/yang-model-util/pom.xml b/yang/yang-model-util/pom.xml index 4856c4a350..7b02980732 100644 --- a/yang/yang-model-util/pom.xml +++ b/yang/yang-model-util/pom.xml @@ -12,11 +12,50 @@ ${project.artifactId} ${project.artifactId} + + + + + org.eclipse.xtend + xtend-maven-plugin + 2.4.2 + + + + compile + + + ${basedir}/src/main/xtend-gen + + + + + + maven-clean-plugin + 2.4.1 + + + + ${basedir}/src/main/xtend-gen + + ** + + + + + + + + ${project.groupId} yang-model-api + + org.eclipse.xtend + org.eclipse.xtend.lib + 2.4.2 + - diff --git a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.xtend similarity index 69% rename from yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java rename to yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.xtend index 91ba9364d1..67374b354e 100644 --- a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java +++ b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.xtend @@ -25,6 +25,10 @@ import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath; 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.RpcDefinition +import org.opendaylight.yangtools.yang.model.api.NotificationDefinition +import java.io.ObjectOutputStream.PutField +import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode /** * The Schema Context Util contains support methods for searching through Schema Context modules for specified schema @@ -33,9 +37,9 @@ import org.opendaylight.yangtools.yang.model.api.SchemaPath; * * @author Lukas Sedlak */ -public final class SchemaContextUtil { +public class SchemaContextUtil { - private SchemaContextUtil() { + private new() { } /** @@ -55,19 +59,16 @@ public final class SchemaContextUtil { * @return DataSchemaNode from the end of the Schema Path or * null if the Node is not present. */ - public static DataSchemaNode findDataSchemaNode(final SchemaContext context, final SchemaPath schemaPath) { + public static def SchemaNode findDataSchemaNode( SchemaContext context, SchemaPath schemaPath) { if (context == null) { throw new IllegalArgumentException("Schema Context reference cannot be NULL!"); } if (schemaPath == null) { throw new IllegalArgumentException("Schema Path reference cannot be NULL"); } - - final Module module = resolveModuleFromSchemaPath(context, schemaPath); - final Queue prefixedPath = new LinkedList<>(schemaPath.getPath()); - - if ((module != null) && (prefixedPath != null)) { - return findSchemaNodeForGivenPath(context, module, prefixedPath); + val prefixedPath = (schemaPath.getPath()); + if (prefixedPath != null) { + return findNodeInSchemaContext(context,prefixedPath); } return null; } @@ -96,8 +97,8 @@ public final class SchemaContextUtil { * @return Returns Data Schema Node for specified Schema Context for given Non-conditional Revision Aware XPath, * or null if the DataSchemaNode is not present in Schema Context. */ - public static DataSchemaNode findDataSchemaNode(final SchemaContext context, final Module module, - final RevisionAwareXPath nonCondXPath) { + public static def SchemaNode findDataSchemaNode( SchemaContext context, Module module, + RevisionAwareXPath nonCondXPath) { if (context == null) { throw new IllegalArgumentException("Schema Context reference cannot be NULL!"); } @@ -108,16 +109,15 @@ public final class SchemaContextUtil { throw new IllegalArgumentException("Non Conditional Revision Aware XPath cannot be NULL!"); } - final String strXPath = nonCondXPath.toString(); + val strXPath = nonCondXPath.toString(); if (strXPath != null) { if (strXPath.contains("[")) { throw new IllegalArgumentException("Revision Aware XPath cannot contains condition!"); } if (nonCondXPath.isAbsolute()) { - final Queue qnamedPath = xpathToQNamePath(context, module, strXPath); + val qnamedPath = xpathToQNamePath(context, module, strXPath); if (qnamedPath != null) { - final DataSchemaNode dataNode = findSchemaNodeForGivenPath(context, module, qnamedPath); - return dataNode; + return findNodeInSchemaContext(context,qnamedPath); } } } @@ -157,8 +157,8 @@ public final class SchemaContextUtil { * @return DataSchemaNode if is present in specified Schema Context for given relative Revision Aware XPath, * otherwise will return null. */ - public static DataSchemaNode findDataSchemaNodeForRelativeXPath(final SchemaContext context, final Module module, - final SchemaNode actualSchemaNode, final RevisionAwareXPath relativeXPath) { + public static def SchemaNode findDataSchemaNodeForRelativeXPath( SchemaContext context, Module module, + SchemaNode actualSchemaNode, RevisionAwareXPath relativeXPath) { if (context == null) { throw new IllegalArgumentException("Schema Context reference cannot be NULL!"); } @@ -176,53 +176,17 @@ public final class SchemaContextUtil { + "for non relative Revision Aware XPath use findDataSchemaNode method!"); } - final SchemaPath actualNodePath = actualSchemaNode.getPath(); + val actualNodePath = actualSchemaNode.getPath(); if (actualNodePath != null) { - final Queue qnamePath = resolveRelativeXPath(context, module, relativeXPath, actualSchemaNode); + val qnamePath = resolveRelativeXPath(context, module, relativeXPath, actualSchemaNode); if (qnamePath != null) { - final DataSchemaNode dataNode = findSchemaNodeForGivenPath(context, module, qnamePath); - return dataNode; + return findNodeInSchemaContext(context,qnamePath); } } return null; } - /** - * Retrieve information from Schema Path and returns the module reference to which Schema Node belongs. The - * search for correct Module is based on namespace within the last item in Schema Path. If schema context - * contains module with namespace specified in last item of Schema Path, then operation will returns Module - * reference, otherwise returns null - *
    - * If Schema Context or Schema Node contains null references the method will throw IllegalArgumentException - * - * @throws IllegalArgumentException - * - * @param context Schema Context - * @param schemaPath Schema Path - * @return Module reference for given Schema Path if module is present in Schema Context, - * otherwise returns null - */ - private static Module resolveModuleFromSchemaPath(final SchemaContext context, final SchemaPath schemaPath) { - if (context == null) { - throw new IllegalArgumentException("Schema Context reference cannot be NULL!"); - } - if (schemaPath == null) { - throw new IllegalArgumentException("Schema Path reference cannot be NULL"); - } - - final List path = schemaPath.getPath(); - if (!path.isEmpty()) { - final QName qname = path.get(path.size() - 1); - - if ((qname != null) && (qname.getNamespace() != null)) { - return context.findModuleByNamespace(qname.getNamespace()); - } - } - - return null; - } - /** * Returns parent Yang Module for specified Schema Context in which Schema Node is declared. If the Schema Node * is not present in Schema Context the operation will return null. @@ -236,7 +200,7 @@ public final class SchemaContextUtil { * @return Yang Module for specified Schema Context and Schema Node, if Schema Node is NOT present, * the method will returns null */ - public static Module findParentModule(final SchemaContext context, final SchemaNode schemaNode) { + public static def Module findParentModule( SchemaContext context, SchemaNode schemaNode) { if (context == null) { throw new IllegalArgumentException("Schema Context reference cannot be NULL!"); } @@ -244,18 +208,18 @@ public final class SchemaContextUtil { throw new IllegalArgumentException("Schema Node cannot be NULL!"); } - final SchemaPath schemaPath = schemaNode.getPath(); + val schemaPath = schemaNode.getPath(); if (schemaPath == null) { throw new IllegalStateException("Schema Path for Schema Node is not " + "set properly (Schema Path is NULL)"); } - final List qnamedPath = schemaPath.getPath(); + val qnamedPath = schemaPath.getPath(); if (qnamedPath == null || qnamedPath.isEmpty()) { throw new IllegalStateException("Schema Path contains invalid state of path parts." + "The Schema Path MUST contain at least ONE QName which defines namespace and Local name" + "of path."); } - final QName qname = qnamedPath.get(qnamedPath.size() - 1); + val qname = qnamedPath.get(qnamedPath.size() - 1); return context.findModuleByNamespace(qname.getNamespace()); } @@ -276,8 +240,8 @@ public final class SchemaContextUtil { * @return DataSchemaNode if is present in Module(s) for specified Schema Context and given QNamed Path, * otherwise will return null. */ - private static DataSchemaNode findSchemaNodeForGivenPath(final SchemaContext context, final Module module, - final Queue qnamedPath) { + private static def SchemaNode findSchemaNodeForGivenPath( SchemaContext context, Module module, + Queue qnamedPath) { if (context == null) { throw new IllegalArgumentException("Schema Context reference cannot be NULL!"); } @@ -293,35 +257,41 @@ public final class SchemaContextUtil { + "of path."); } - DataNodeContainer nextNode = module; - final URI moduleNamespace = module.getNamespace(); + var DataNodeContainer nextNode = module; + val moduleNamespace = module.getNamespace(); - QName childNodeQName; - DataSchemaNode schemaNode = null; + var QName childNodeQName; + var SchemaNode schemaNode = null; while ((nextNode != null) && !qnamedPath.isEmpty()) { childNodeQName = qnamedPath.peek(); if (childNodeQName != null) { - final URI childNodeNamespace = childNodeQName.getNamespace(); + val URI childNodeNamespace = childNodeQName.getNamespace(); schemaNode = nextNode.getDataChildByName(childNodeQName.getLocalName()); + if(schemaNode == null && nextNode instanceof Module) { + schemaNode = (nextNode as Module).getNotificationByName(childNodeQName); + } + if(schemaNode == null && nextNode instanceof Module) { + + } if (schemaNode != null) { if (schemaNode instanceof ContainerSchemaNode) { - nextNode = (ContainerSchemaNode) schemaNode; + nextNode = schemaNode as ContainerSchemaNode; } else if (schemaNode instanceof ListSchemaNode) { - nextNode = (ListSchemaNode) schemaNode; + nextNode = schemaNode as ListSchemaNode; } else if (schemaNode instanceof ChoiceNode) { - final ChoiceNode choice = (ChoiceNode) schemaNode; + val choice = schemaNode as ChoiceNode; qnamedPath.poll(); if (!qnamedPath.isEmpty()) { childNodeQName = qnamedPath.peek(); nextNode = choice.getCaseNodeByName(childNodeQName); - schemaNode = (DataSchemaNode) nextNode; + schemaNode = nextNode as DataSchemaNode; } } else { nextNode = null; } } else if (!childNodeNamespace.equals(moduleNamespace)) { - final Module nextModule = context.findModuleByNamespace(childNodeNamespace); + val Module nextModule = context.findModuleByNamespace(childNodeNamespace); schemaNode = findSchemaNodeForGivenPath(context, nextModule, qnamedPath); return schemaNode; } @@ -330,6 +300,107 @@ public final class SchemaContextUtil { } return schemaNode; } + + + private static def SchemaNode findNodeInSchemaContext(SchemaContext context, List path) { + val current = path.get(0); + val module = context.findModuleByNamespace(current.namespace); + if(module == null) return null; + return findNodeInModule(module,path); + } + + private static def SchemaNode findNodeInModule(Module module, List path) { + val current = path.get(0); + var SchemaNode node = module.getDataChildByName(current); + if (node != null) return findNode(node as DataSchemaNode,path.nextLevel); + node = module.getRpcByName(current); + if (node != null) return findNodeInRpc(node as RpcDefinition,path.nextLevel) + node = module.getNotificationByName(current); + if (node != null) return findNodeInNotification(node as NotificationDefinition,path.nextLevel) + return null + } + + private static def SchemaNode findNodeInRpc(RpcDefinition rpc,List path) { + if(path.empty) return rpc; + val current = path.get(0); + switch (current.localName) { + case "input": return findNode(rpc.input,path.nextLevel) + case "output": return findNode(rpc.output,path.nextLevel) + } + return null + } + + private static def SchemaNode findNodeInNotification(NotificationDefinition rpc,List path) { + if(path.empty) return rpc; + val current = path.get(0); + val node = rpc.getDataChildByName(current) + if(node != null) return findNode(node,path.nextLevel) + return null + } + + private static dispatch def SchemaNode findNode(ChoiceNode parent,List path) { + if(path.empty) return parent; + val current = path.get(0); + val node = parent.getCaseNodeByName(current) + if (node != null) return findNodeInCase(node,path.nextLevel) + return null + } + + private static dispatch def SchemaNode findNode(ContainerSchemaNode parent,List path) { + if(path.empty) return parent; + val current = path.get(0); + val node = parent.getDataChildByName(current) + if (node != null) return findNode(node,path.nextLevel) + return null + } + + private static dispatch def SchemaNode findNode(ListSchemaNode parent,List path) { + if(path.empty) return parent; + val current = path.get(0); + val node = parent.getDataChildByName(current) + if (node != null) return findNode(node,path.nextLevel) + return null + } + + private static dispatch def SchemaNode findNode(DataSchemaNode parent,List path){ + if(path.empty) { + return parent + } else { + throw new IllegalArgumentException("Path nesting violation"); + } + } + + public static def SchemaNode findNodeInCase(ChoiceCaseNode parent,List path) { + if(path.empty) return parent; + val current = path.get(0); + val node = parent.getDataChildByName(current) + if (node != null) return findNode(node,path.nextLevel) + return null + } + + + public static def RpcDefinition getRpcByName(Module module, QName name) { + for(notification : module.rpcs) { + if(notification.QName == name) { + return notification; + } + } + return null; + } + + + private static def nextLevel(List path){ + return path.subList(1,path.size) + } + + public static def NotificationDefinition getNotificationByName(Module module, QName name) { + for(notification : module.notifications) { + if(notification.QName == name) { + return notification; + } + } + return null; + } /** * Transforms string representation of XPath to Queue of QNames. The XPath is split by "/" and for each part of @@ -345,8 +416,8 @@ public final class SchemaContextUtil { * @param xpath XPath String * @return */ - private static Queue xpathToQNamePath(final SchemaContext context, final Module parentModule, - final String xpath) { + private static def xpathToQNamePath( SchemaContext context, Module parentModule, + String xpath) { if (context == null) { throw new IllegalArgumentException("Schema Context reference cannot be NULL!"); } @@ -357,11 +428,11 @@ public final class SchemaContextUtil { throw new IllegalArgumentException("XPath string reference cannot be NULL!"); } - final Queue path = new LinkedList<>(); - final String[] prefixedPath = xpath.split("/"); - for (int i = 0; i < prefixedPath.length; ++i) { - if (!prefixedPath[i].isEmpty()) { - path.add(stringPathPartToQName(context, parentModule, prefixedPath[i])); + val path = new LinkedList(); + val String[] prefixedPath = xpath.split("/"); + for (pathComponent : prefixedPath) { + if (!pathComponent.isEmpty()) { + path.add(stringPathPartToQName(context, parentModule, pathComponent)); } } return path; @@ -387,8 +458,8 @@ public final class SchemaContextUtil { * @param prefixedPathPart Prefixed Path Part string * @return QName from prefixed Path Part String. */ - private static QName stringPathPartToQName(final SchemaContext context, final Module parentModule, - final String prefixedPathPart) { + private static def QName stringPathPartToQName( SchemaContext context, Module parentModule, + String prefixedPathPart) { if (context == null) { throw new IllegalArgumentException("Schema Context reference cannot be NULL!"); } @@ -400,10 +471,10 @@ public final class SchemaContextUtil { } if (prefixedPathPart.contains(":")) { - final String[] prefixedName = prefixedPathPart.split(":"); - final Module module = resolveModuleForPrefix(context, parentModule, prefixedName[0]); + val String[] prefixedName = prefixedPathPart.split(":"); + val module = resolveModuleForPrefix(context, parentModule, prefixedName.get(0)); if (module != null) { - return new QName(module.getNamespace(), module.getRevision(), prefixedName[1]); + return new QName(module.getNamespace(), module.getRevision(), prefixedName.get(1)); } } else { return new QName(parentModule.getNamespace(), parentModule.getRevision(), prefixedPathPart); @@ -430,7 +501,7 @@ public final class SchemaContextUtil { * @param prefix Module Prefix * @return Module for given prefix in specified Schema Context if is present, otherwise returns null */ - private static Module resolveModuleForPrefix(final SchemaContext context, final Module module, final String prefix) { + private static def Module resolveModuleForPrefix( SchemaContext context, Module module, String prefix) { if (context == null) { throw new IllegalArgumentException("Schema Context reference cannot be NULL!"); } @@ -445,8 +516,8 @@ public final class SchemaContextUtil { return module; } - final Set imports = module.getImports(); - for (final ModuleImport mi : imports) { + val imports = module.getImports(); + for ( ModuleImport mi : imports) { if (prefix.equals(mi.getPrefix())) { return context.findModuleByName(mi.getModuleName(), mi.getRevision()); } @@ -463,9 +534,9 @@ public final class SchemaContextUtil { * @param leafrefSchemaPath Schema Path for Leafref * @return */ - private static Queue resolveRelativeXPath(final SchemaContext context, final Module module, - final RevisionAwareXPath relativeXPath, final SchemaNode leafrefParentNode) { - final Queue absolutePath = new LinkedList<>(); + private static def resolveRelativeXPath( SchemaContext context, Module module, + RevisionAwareXPath relativeXPath, SchemaNode leafrefParentNode) { + if (context == null) { throw new IllegalArgumentException("Schema Context reference cannot be NULL!"); } @@ -482,24 +553,22 @@ public final class SchemaContextUtil { if (leafrefParentNode.getPath() == null) { throw new IllegalArgumentException("Schema Path reference for Leafref cannot be NULL!"); } - - final String strXPath = relativeXPath.toString(); + val absolutePath = new LinkedList(); + val String strXPath = relativeXPath.toString(); if (strXPath != null) { - final String[] xpaths = strXPath.split("/"); + val String[] xpaths = strXPath.split("/"); if (xpaths != null) { - int colCount = 0; - while (xpaths[colCount].contains("..")) { - ++colCount; + var int colCount = 0; + while (xpaths.get(colCount).contains("..")) { + colCount = colCount+ 1; } - final List path = leafrefParentNode.getPath().getPath(); + val path = leafrefParentNode.getPath().getPath(); if (path != null) { - int lenght = path.size() - colCount; - for (int i = 0; i < lenght; ++i) { - absolutePath.add(path.get(i)); - } - for (int i = colCount; i < xpaths.length; ++i) { - absolutePath.add(stringPathPartToQName(context, module, xpaths[i])); - } + val int lenght = path.size() - colCount; + absolutePath.addAll(path.subList(0,lenght)); + absolutePath.addAll( + xpaths.subList(colCount,xpaths.length).map[stringPathPartToQName(context, module,it)] + ) } } } diff --git a/yang/yang-parser-impl/pom.xml b/yang/yang-parser-impl/pom.xml index 189c7cb7c0..88ef7280f9 100644 --- a/yang/yang-parser-impl/pom.xml +++ b/yang/yang-parser-impl/pom.xml @@ -50,14 +50,34 @@ com.google.guava guava + + org.eclipse.xtend + org.eclipse.xtend.lib + 2.4.2 + junit junit + test + + maven-clean-plugin + 2.4.1 + + + + ${basedir}/src/main/xtend-gen + + ** + + + + + org.antlr antlr4-maven-plugin @@ -77,6 +97,20 @@ + org.eclipse.xtend + xtend-maven-plugin + 2.4.2 + + + + compile + + + ${basedir}/src/main/xtend-gen + + + + org.codehaus.mojo build-helper-maven-plugin 1.7 @@ -94,6 +128,7 @@ + org.apache.maven.plugins maven-javadoc-plugin diff --git a/yang/yang-parser-impl/src/main/.gitignore b/yang/yang-parser-impl/src/main/.gitignore new file mode 100644 index 0000000000..04b73cb01e --- /dev/null +++ b/yang/yang-parser-impl/src/main/.gitignore @@ -0,0 +1 @@ +/xtend-gen diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/api/Builder.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/api/Builder.java index 2ae0ad5531..9f534ad192 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/api/Builder.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/api/Builder.java @@ -77,4 +77,8 @@ public interface Builder { */ Object build(); + + public interface Rebuildable { + T toBuilder(); + } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ModuleBuilder.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ModuleBuilder.java index 01ee714694..cab518c329 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ModuleBuilder.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ModuleBuilder.java @@ -1,1275 +1,1283 @@ -/* - * 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.builder.impl; - -import java.net.URI; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -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.TreeMap; -import java.util.TreeSet; - -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; -import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; -import org.opendaylight.yangtools.yang.model.api.Deviation; -import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition; -import org.opendaylight.yangtools.yang.model.api.FeatureDefinition; -import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; -import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; -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.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.parser.builder.api.AbstractDataNodeContainerBuilder; -import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder; -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; -import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder; -import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder; -import org.opendaylight.yangtools.yang.parser.builder.api.TypeAwareBuilder; -import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder; -import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder; -import org.opendaylight.yangtools.yang.parser.util.Comparators; -import org.opendaylight.yangtools.yang.parser.util.RefineHolder; -import org.opendaylight.yangtools.yang.parser.util.YangParseException; - -/** - * Builder of Module object. If this module is dependent on external - * module/modules, these dependencies must be resolved before module is built, - * otherwise result may not be valid. - */ -public class ModuleBuilder extends AbstractDataNodeContainerBuilder { - private final ModuleImpl instance; - private final String name; - private final SchemaPath schemaPath; - private URI namespace; - private String prefix; - private Date revision; - - private final LinkedList actualPath = new LinkedList(); - private final Set dirtyNodes = new HashSet(); - - private final Set imports = new HashSet(); - private final List addedAugments = new ArrayList(); - private final List allAugments = new ArrayList(); - private final Set addedUsesNodes = new HashSet(); - private final List allUsesNodes = new ArrayList(); - private final Set addedRpcs = new HashSet(); - private final Set addedNotifications = new HashSet(); - private final Set addedIdentities = new HashSet(); - private final Set addedFeatures = new HashSet(); - private final Set addedDeviations = new HashSet(); - private final Set addedTypedefs = new HashSet(); - private final List addedExtensions = new ArrayList(); - private final List allUnknownNodes = new ArrayList(); - - public ModuleBuilder(final String name) { - super(name, 0, null); - this.name = name; - schemaPath = new SchemaPath(Collections.emptyList(), true); - instance = new ModuleImpl(name); - actualPath.push(this); - } - - /** - * Build new Module object based on this builder. - */ - @Override - public Module build() { - instance.setPrefix(prefix); - instance.setRevision(revision); - instance.setImports(imports); - instance.setNamespace(namespace); - - // TYPEDEFS - final Set> typedefs = new TreeSet>(Comparators.SCHEMA_NODE_COMP); - for (TypeDefinitionBuilder tdb : addedTypedefs) { - typedefs.add(tdb.build()); - } - instance.setTypeDefinitions(typedefs); - - // CHILD NODES - final Map children = new TreeMap(Comparators.QNAME_COMP); - for (DataSchemaNodeBuilder child : addedChildNodes) { - children.put(child.getQName(), child.build()); - } - instance.setChildNodes(children); - - // GROUPINGS - final Set groupings = new TreeSet(Comparators.SCHEMA_NODE_COMP); - for (GroupingBuilder gb : addedGroupings) { - groupings.add(gb.build()); - } - instance.setGroupings(groupings); - - // USES - final Set usesDefinitions = new HashSet(); - for (UsesNodeBuilder unb : addedUsesNodes) { - usesDefinitions.add(unb.build()); - } - instance.setUses(usesDefinitions); - - // FEATURES - final Set features = new TreeSet(Comparators.SCHEMA_NODE_COMP); - for (FeatureBuilder fb : addedFeatures) { - features.add(fb.build()); - } - instance.setFeatures(features); - - // NOTIFICATIONS - final Set notifications = new TreeSet( - Comparators.SCHEMA_NODE_COMP); - for (NotificationBuilder entry : addedNotifications) { - notifications.add(entry.build()); - } - instance.setNotifications(notifications); - - // AUGMENTATIONS - final Set augmentations = new HashSet(); - for (AugmentationSchemaBuilder builder : addedAugments) { - augmentations.add(builder.build()); - } - instance.setAugmentations(augmentations); - - // RPCs - final Set rpcs = new TreeSet(Comparators.SCHEMA_NODE_COMP); - for (RpcDefinitionBuilder rpc : addedRpcs) { - rpcs.add(rpc.build()); - } - instance.setRpcs(rpcs); - - // DEVIATIONS - final Set deviations = new HashSet(); - for (DeviationBuilder entry : addedDeviations) { - deviations.add(entry.build()); - } - instance.setDeviations(deviations); - - // EXTENSIONS - final List extensions = new ArrayList(); - for (ExtensionBuilder eb : addedExtensions) { - extensions.add(eb.build()); - } - Collections.sort(extensions, Comparators.SCHEMA_NODE_COMP); - instance.setExtensionSchemaNodes(extensions); - - // IDENTITIES - final Set identities = new TreeSet(Comparators.SCHEMA_NODE_COMP); - for (IdentitySchemaNodeBuilder id : addedIdentities) { - identities.add(id.build()); - } - instance.setIdentities(identities); - - // UNKNOWN NODES - final List unknownNodes = new ArrayList(); - for (UnknownSchemaNodeBuilder unb : addedUnknownNodes) { - unknownNodes.add(unb.build()); - } - instance.setUnknownSchemaNodes(unknownNodes); - - return instance; - } - - public boolean isAllUsesDataCollected() { - for(UsesNodeBuilder usesNode : allUsesNodes) { - if(!usesNode.isDataCollected()) { - return false; - } - } - return true; - } - - @Override - public void setParent(Builder parent) { - throw new YangParseException(name, 0, "Can not set parent to module"); - } - - @Override - public SchemaPath getPath() { - return schemaPath; - } - - @Override - public Set getTypeDefinitionBuilders() { - return addedTypedefs; - } - - public void enterNode(final Builder node) { - actualPath.push(node); - } - - public void exitNode() { - actualPath.pop(); - } - - public Builder getActualNode() { - if (actualPath.isEmpty()) { - return null; - } else { - return actualPath.get(0); - } - } - - public Builder getActualParent() { - if (actualPath.size() < 2) { - return null; - } else { - return actualPath.get(1); - } - } - - public Set getDirtyNodes() { - return dirtyNodes; - } - - public List getAllAugments() { - return allAugments; - } - - public Set getIdentities() { - return addedIdentities; - } - - public List getAllUsesNodes() { - return allUsesNodes; - } - - public Set getDeviations() { - return addedDeviations; - } - - public List getExtensions() { - return addedExtensions; - } - - public List getAllUnknownNodes() { - return allUnknownNodes; - } - - public String getName() { - return name; - } - - public URI getNamespace() { - return namespace; - } - - public void setNamespace(final URI namespace) { - this.namespace = namespace; - } - - public String getPrefix() { - return prefix; - } - - public Date getRevision() { - return revision; - } - - public void markActualNodeDirty() { - final TypeAwareBuilder nodeBuilder = (TypeAwareBuilder) getActualNode(); - dirtyNodes.add(nodeBuilder); - } - - public void setRevision(final Date revision) { - this.revision = revision; - } - - public void setPrefix(final String prefix) { - this.prefix = prefix; - } - - public void setYangVersion(final String yangVersion) { - instance.setYangVersion(yangVersion); - } - - public void setDescription(final String description) { - instance.setDescription(description); - } - - public void setReference(final String reference) { - instance.setReference(reference); - } - - public void setOrganization(final String organization) { - instance.setOrganization(organization); - } - - public void setContact(final String contact) { - instance.setContact(contact); - } - - public boolean addModuleImport(final String moduleName, final Date revision, final String prefix) { - final ModuleImport moduleImport = createModuleImport(moduleName, revision, prefix); - return imports.add(moduleImport); - } - - public Set getModuleImports() { - return imports; - } - - public ExtensionBuilder addExtension(final QName qname, final int line) { - final String extName = qname.getLocalName(); - for (ExtensionBuilder addedExtension : addedExtensions) { - if (addedExtension.getQName().getLocalName().equals(extName)) { - throw new YangParseException(moduleName, line, "Can not add extension '" + extName - + "': extension with same name already declared at line " + addedExtension.getLine()); - } - } - final ExtensionBuilder builder = new ExtensionBuilder(name, line, qname); - addedExtensions.add(builder); - return builder; - } - - public ContainerSchemaNodeBuilder addContainerNode(final int line, final QName qname, final SchemaPath schemaPath) { - final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(name, line, qname, schemaPath); - - Builder parent = getActualNode(); - builder.setParent(parent); - addChildToParent(parent, builder, qname.getLocalName()); - - return builder; - } - - public ListSchemaNodeBuilder addListNode(final int line, final QName qname, final SchemaPath schemaPath) { - final ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(name, line, qname, schemaPath); - - Builder parent = getActualNode(); - builder.setParent(parent); - addChildToParent(parent, builder, qname.getLocalName()); - - return builder; - } - - public LeafSchemaNodeBuilder addLeafNode(final int line, final QName qname, final SchemaPath schemaPath) { - final LeafSchemaNodeBuilder builder = new LeafSchemaNodeBuilder(name, line, qname, schemaPath); - - Builder parent = getActualNode(); - builder.setParent(parent); - addChildToParent(parent, builder, qname.getLocalName()); - - return builder; - } - - public LeafListSchemaNodeBuilder addLeafListNode(final int line, final QName qname, final SchemaPath schemaPath) { - final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(name, line, qname, schemaPath); - - Builder parent = getActualNode(); - builder.setParent(parent); - addChildToParent(parent, builder, qname.getLocalName()); - - return builder; - } - - public GroupingBuilder addGrouping(final int line, final QName qname) { - final GroupingBuilder builder = new GroupingBuilderImpl(name, line, qname); - - Builder parent = getActualNode(); - builder.setParent(parent); - - String groupingName = qname.getLocalName(); - if (parent.equals(this)) { - for (GroupingBuilder addedGrouping : addedGroupings) { - if (addedGrouping.getQName().getLocalName().equals(groupingName)) { - throw new YangParseException(name, line, "grouping with same name '" + groupingName - + "' already declared at line " + addedGrouping.getLine()); - } - } - addedGroupings.add(builder); - } else { - if (parent instanceof DataNodeContainerBuilder) { - DataNodeContainerBuilder parentNode = (DataNodeContainerBuilder) parent; - for (GroupingBuilder addedGrouping : parentNode.getGroupingBuilders()) { - if (addedGrouping.getQName().getLocalName().equals(groupingName)) { - throw new YangParseException(name, line, "grouping with same name '" + groupingName - + "' already declared at line " + addedGrouping.getLine()); - } - } - parentNode.addGrouping(builder); - } else if (parent instanceof RpcDefinitionBuilder) { - RpcDefinitionBuilder parentNode = (RpcDefinitionBuilder) parent; - for (GroupingBuilder child : parentNode.getGroupings()) { - if (child.getQName().getLocalName().equals(groupingName)) { - throw new YangParseException(name, line, "grouping with same name '" + groupingName - + "' already declared at line " + child.getLine()); - } - } - parentNode.addGrouping(builder); - } else { - throw new YangParseException(name, line, "Unresolved parent of grouping " + groupingName); - } - } - - return builder; - } - - public AugmentationSchemaBuilder addAugment(final int line, final String augmentTargetStr) { - final AugmentationSchemaBuilder builder = new AugmentationSchemaBuilderImpl(name, line, augmentTargetStr); - - Builder parent = getActualNode(); - builder.setParent(parent); - - if (parent.equals(this)) { - // augment can be declared only under 'module' ... - addedAugments.add(builder); - } else { - // ... or 'uses' statement - if (parent instanceof UsesNodeBuilder) { - ((UsesNodeBuilder) parent).addAugment(builder); - } else { - throw new YangParseException(name, line, "Augment can be declared only under module or uses statement."); - } - } - allAugments.add(builder); - - return builder; - } - - @Override - public Set getUsesNodes() { - return addedUsesNodes; - } - - @Override - public void addUsesNode(UsesNodeBuilder usesBuilder) { - addedUsesNodes.add(usesBuilder); - allUsesNodes.add(usesBuilder); - } - - public UsesNodeBuilder addUsesNode(final int line, final String groupingPathStr) { - final UsesNodeBuilder usesBuilder = new UsesNodeBuilderImpl(name, line, groupingPathStr); - - Builder parent = getActualNode(); - usesBuilder.setParent(parent); - - if (parent.equals(this)) { - addedUsesNodes.add(usesBuilder); - } else { - if (!(parent instanceof DataNodeContainerBuilder)) { - throw new YangParseException(name, line, "Unresolved parent of uses '" + groupingPathStr + "'."); - } - ((DataNodeContainerBuilder) parent).addUsesNode(usesBuilder); - } - allUsesNodes.add(usesBuilder); - return usesBuilder; - } - - public void addRefine(final RefineHolder refine) { - final Builder parent = getActualNode(); - if (!(parent instanceof UsesNodeBuilder)) { - throw new YangParseException(name, refine.getLine(), "refine can be defined only in uses statement"); - } - ((UsesNodeBuilder) parent).addRefine(refine); - refine.setParent(parent); - } - - public RpcDefinitionBuilder addRpc(final int line, final QName qname) { - Builder parent = getActualNode(); - if (!(parent.equals(this))) { - throw new YangParseException(name, line, "rpc can be defined only in module or submodule"); - } - - final RpcDefinitionBuilder rpcBuilder = new RpcDefinitionBuilder(name, line, qname); - rpcBuilder.setParent(parent); - - String rpcName = qname.getLocalName(); - for (RpcDefinitionBuilder rpc : addedRpcs) { - if (rpc.getQName().getLocalName().equals(rpcName)) { - throw new YangParseException(name, line, "rpc with same name '" + rpcName - + "' already declared at line " + rpc.getLine()); - } - } - for (DataSchemaNodeBuilder addedChild : addedChildNodes) { - if (addedChild.getQName().getLocalName().equals(rpcName)) { - throw new YangParseException(name, line, "Can not add rpc: node with same name '" + rpcName - + "' already declared at line " + addedChild.getLine()); - } - } - for (NotificationBuilder addedNotification : addedNotifications) { - if (addedNotification.getQName().getLocalName().equals(rpcName)) { - throw new YangParseException(name, line, "Can not add rpc: notification with same name '" + rpcName - + "' already declared at line " + addedNotification.getLine()); - } - } - addedRpcs.add(rpcBuilder); - return rpcBuilder; - } - - public ContainerSchemaNodeBuilder addRpcInput(final int line, final QName qname, final SchemaPath schemaPath) { - final Builder parent = getActualNode(); - if (!(parent instanceof RpcDefinitionBuilder)) { - throw new YangParseException(name, line, "input can be defined only in rpc statement"); - } - final RpcDefinitionBuilder rpc = (RpcDefinitionBuilder) parent; - - final ContainerSchemaNodeBuilder inputBuilder = new ContainerSchemaNodeBuilder(name, line, qname, schemaPath); - inputBuilder.setParent(rpc); - - rpc.setInput(inputBuilder); - return inputBuilder; - } - - public ContainerSchemaNodeBuilder addRpcOutput(final SchemaPath schemaPath, final QName qname, final int line) { - final Builder parent = getActualNode(); - if (!(parent instanceof RpcDefinitionBuilder)) { - throw new YangParseException(name, line, "output can be defined only in rpc statement"); - } - final RpcDefinitionBuilder rpc = (RpcDefinitionBuilder) parent; - - final ContainerSchemaNodeBuilder outputBuilder = new ContainerSchemaNodeBuilder(name, line, qname, schemaPath); - outputBuilder.setParent(rpc); - - rpc.setOutput(outputBuilder); - return outputBuilder; - } - - public NotificationBuilder addNotification(final int line, final QName qname) { - final Builder parent = getActualNode(); - if (!(parent.equals(this))) { - throw new YangParseException(name, line, "notification can be defined only in module or submodule"); - } - - String notificationName = qname.getLocalName(); - for (NotificationBuilder nb : addedNotifications) { - if (nb.getQName().equals(qname)) { - throw new YangParseException(name, line, "notification with same name '" + notificationName - + "' already declared at line " + nb.getLine()); - } - } - for (RpcDefinitionBuilder rpc : addedRpcs) { - if (rpc.getQName().getLocalName().equals(notificationName)) { - throw new YangParseException(name, line, "Can not add notification: rpc with same name '" - + notificationName + "' already declared at line " + rpc.getLine()); - } - } - for (DataSchemaNodeBuilder addedChild : addedChildNodes) { - if (addedChild.getQName().getLocalName().equals(notificationName)) { - throw new YangParseException(name, line, "Can not add notification: node with same name '" - + notificationName + "' already declared at line " + addedChild.getLine()); - } - } - - final NotificationBuilder builder = new NotificationBuilder(name, line, qname); - builder.setParent(parent); - addedNotifications.add(builder); - - return builder; - } - - public FeatureBuilder addFeature(final int line, final QName qname) { - Builder parent = getActualNode(); - if (!(parent.equals(this))) { - throw new YangParseException(name, line, "feature can be defined only in module or submodule"); - } - - final FeatureBuilder builder = new FeatureBuilder(name, line, qname); - builder.setParent(parent); - - String featureName = qname.getLocalName(); - for (FeatureBuilder addedFeature : addedFeatures) { - if (addedFeature.getQName().getLocalName().equals(featureName)) { - throw new YangParseException(name, line, "feature with same name '" + featureName - + "' already declared at line " + addedFeature.getLine()); - } - } - addedFeatures.add(builder); - return builder; - } - - public ChoiceBuilder addChoice(final int line, final QName qname) { - final ChoiceBuilder builder = new ChoiceBuilder(name, line, qname); - - Builder parent = getActualNode(); - builder.setParent(parent); - addChildToParent(parent, builder, qname.getLocalName()); - - return builder; - } - - public ChoiceCaseBuilder addCase(final int line, final QName qname) { - Builder parent = getActualNode(); - if (parent == null || parent.equals(this)) { - throw new YangParseException(name, line, "'case' parent not found"); - } - - final ChoiceCaseBuilder builder = new ChoiceCaseBuilder(name, line, qname); - builder.setParent(parent); - - if (parent instanceof ChoiceBuilder) { - ((ChoiceBuilder) parent).addCase(builder); - } else if (parent instanceof AugmentationSchemaBuilder) { - ((AugmentationSchemaBuilder) parent).addChildNode(builder); - } else { - throw new YangParseException(name, line, "Unresolved parent of 'case' " + qname.getLocalName()); - } - - return builder; - } - - public AnyXmlBuilder addAnyXml(final int line, final QName qname, final SchemaPath schemaPath) { - final AnyXmlBuilder builder = new AnyXmlBuilder(name, line, qname, schemaPath); - - Builder parent = getActualNode(); - builder.setParent(parent); - addChildToParent(parent, builder, qname.getLocalName()); - - return builder; - } - - @Override - public void addTypedef(TypeDefinitionBuilder typedefBuilder) { - String nodeName = typedefBuilder.getQName().getLocalName(); - for (TypeDefinitionBuilder tdb : addedTypedefs) { - if (tdb.getQName().getLocalName().equals(nodeName)) { - throw new YangParseException(name, typedefBuilder.getLine(), "typedef with same name '" + nodeName - + "' already declared at line " + tdb.getLine()); - } - } - addedTypedefs.add(typedefBuilder); - } - - public TypeDefinitionBuilderImpl addTypedef(final int line, final QName qname) { - final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(name, line, qname); - - Builder parent = getActualNode(); - builder.setParent(parent); - - String typedefName = qname.getLocalName(); - if (parent.equals(this)) { - for (TypeDefinitionBuilder tdb : addedTypedefs) { - if (tdb.getQName().getLocalName().equals(typedefName)) { - throw new YangParseException(name, line, "typedef with same name '" + typedefName - + "' already declared at line " + tdb.getLine()); - } - } - addedTypedefs.add(builder); - } else { - if (parent instanceof DataNodeContainerBuilder) { - DataNodeContainerBuilder parentNode = (DataNodeContainerBuilder) parent; - for (TypeDefinitionBuilder child : parentNode.getTypeDefinitionBuilders()) { - if (child.getQName().getLocalName().equals(typedefName)) { - throw new YangParseException(name, line, "typedef with same name '" + typedefName - + "' already declared at line " + child.getLine()); - } - } - parentNode.addTypedef(builder); - } else if (parent instanceof RpcDefinitionBuilder) { - RpcDefinitionBuilder rpcParent = (RpcDefinitionBuilder) parent; - for (TypeDefinitionBuilder tdb : rpcParent.getTypeDefinitions()) { - if (tdb.getQName().getLocalName().equals(builder.getQName().getLocalName())) { - throw new YangParseException(name, line, "typedef with same name '" + typedefName - + "' already declared at line " + tdb.getLine()); - } - } - rpcParent.addTypedef(builder); - } else { - throw new YangParseException(name, line, "Unresolved parent of typedef " + typedefName); - } - } - - return builder; - } - - public void setType(final TypeDefinition type) { - Builder parent = getActualNode(); - if (parent == null || !(parent instanceof TypeAwareBuilder)) { - throw new YangParseException("Failed to set type '" + type.getQName().getLocalName() - + "'. Invalid parent node: " + parent); - } - ((TypeAwareBuilder) parent).setType(type); - } - - public UnionTypeBuilder addUnionType(final int line, final URI namespace, final Date revision) { - final Builder parent = getActualNode(); - if (parent == null) { - throw new YangParseException(name, line, "Unresolved parent of union type"); - } else { - final UnionTypeBuilder union = new UnionTypeBuilder(name, line); - if (parent instanceof TypeAwareBuilder) { - ((TypeAwareBuilder) parent).setTypedef(union); - return union; - } else { - throw new YangParseException(name, line, "Invalid parent of union type."); - } - } - } - - public void addIdentityrefType(final int line, final SchemaPath schemaPath, final String baseString) { - final IdentityrefTypeBuilder identityref = new IdentityrefTypeBuilder(name, line, baseString, schemaPath); - - final Builder parent = getActualNode(); - if (parent == null) { - throw new YangParseException(name, line, "Unresolved parent of identityref type."); - } else { - if (parent instanceof TypeAwareBuilder) { - final TypeAwareBuilder typeParent = (TypeAwareBuilder) parent; - typeParent.setTypedef(identityref); - dirtyNodes.add(typeParent); - } else { - throw new YangParseException(name, line, "Invalid parent of identityref type."); - } - } - } - - public DeviationBuilder addDeviation(final int line, final String targetPath) { - Builder parent = getActualNode(); - if (!(parent.equals(this))) { - throw new YangParseException(name, line, "deviation can be defined only in module or submodule"); - } - - final DeviationBuilder builder = new DeviationBuilder(name, line, targetPath); - builder.setParent(parent); - addedDeviations.add(builder); - return builder; - } - - public IdentitySchemaNodeBuilder addIdentity(final QName qname, final int line) { - Builder parent = getActualNode(); - if (!(parent.equals(this))) { - throw new YangParseException(name, line, "identity can be defined only in module or submodule"); - } - String identityName = qname.getLocalName(); - for (IdentitySchemaNodeBuilder idBuilder : addedIdentities) { - if (idBuilder.getQName().equals(qname)) { - throw new YangParseException(name, line, "identity with same name '" + identityName - + "' already declared at line " + idBuilder.getLine()); - } - } - - final IdentitySchemaNodeBuilder builder = new IdentitySchemaNodeBuilder(name, line, qname); - builder.setParent(parent); - addedIdentities.add(builder); - return builder; - } - - @Override - public void addUnknownNodeBuilder(final UnknownSchemaNodeBuilder builder) { - addedUnknownNodes.add(builder); - allUnknownNodes.add(builder); - } - - public UnknownSchemaNodeBuilder addUnknownSchemaNode(final int line, final QName qname) { - final Builder parent = getActualNode(); - final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(name, line, qname); - builder.setParent(parent); - allUnknownNodes.add(builder); - - if (parent.equals(this)) { - addedUnknownNodes.add(builder); - } else { - if (parent instanceof SchemaNodeBuilder) { - ((SchemaNodeBuilder) parent).addUnknownNodeBuilder(builder); - } else if (parent instanceof DataNodeContainerBuilder) { - ((DataNodeContainerBuilder) parent).addUnknownNodeBuilder(builder); - } else if (parent instanceof RefineHolder) { - ((RefineHolder) parent).addUnknownNodeBuilder(builder); - } else { - throw new YangParseException(name, line, "Unresolved parent of unknown node '" + qname.getLocalName() - + "'"); - } - } - - return builder; - } - - @Override - public String toString() { - return "module " + name; - } - - private final class ModuleImpl implements Module { - private URI namespace; - private final String name; - private Date revision; - private String prefix; - private String yangVersion; - private String description; - private String reference; - private String organization; - private String contact; - private Set imports = Collections.emptySet(); - private Set features = Collections.emptySet(); - private Set> typeDefinitions = Collections.emptySet(); - private Set notifications = Collections.emptySet(); - private Set augmentations = Collections.emptySet(); - private Set rpcs = Collections.emptySet(); - private Set deviations = Collections.emptySet(); - private Map childNodes = Collections.emptyMap(); - private Set groupings = Collections.emptySet(); - private Set uses = Collections.emptySet(); - private List extensionNodes = Collections.emptyList(); - private Set identities = Collections.emptySet(); - private List unknownNodes = Collections.emptyList(); - - private ModuleImpl(String name) { - this.name = name; - } - - @Override - public URI getNamespace() { - return namespace; - } - - private void setNamespace(URI namespace) { - this.namespace = namespace; - } - - @Override - public String getName() { - return name; - } - - @Override - public Date getRevision() { - return revision; - } - - private void setRevision(Date revision) { - this.revision = revision; - } - - @Override - public String getPrefix() { - return prefix; - } - - private void setPrefix(String prefix) { - this.prefix = prefix; - } - - @Override - public String getYangVersion() { - return yangVersion; - } - - private void setYangVersion(String yangVersion) { - this.yangVersion = yangVersion; - } - - @Override - public String getDescription() { - return description; - } - - private void setDescription(String description) { - this.description = description; - } - - @Override - public String getReference() { - return reference; - } - - private void setReference(String reference) { - this.reference = reference; - } - - @Override - public String getOrganization() { - return organization; - } - - private void setOrganization(String organization) { - this.organization = organization; - } - - @Override - public String getContact() { - return contact; - } - - private void setContact(String contact) { - this.contact = contact; - } - - @Override - public Set getImports() { - return imports; - } - - private void setImports(Set imports) { - if (imports != null) { - this.imports = imports; - } - } - - @Override - public Set getFeatures() { - return features; - } - - private void setFeatures(Set features) { - if (features != null) { - this.features = features; - } - } - - @Override - public Set> getTypeDefinitions() { - return typeDefinitions; - } - - private void setTypeDefinitions(Set> typeDefinitions) { - if (typeDefinitions != null) { - this.typeDefinitions = typeDefinitions; - } - } - - @Override - public Set getNotifications() { - return notifications; - } - - private void setNotifications(Set notifications) { - if (notifications != null) { - this.notifications = notifications; - } - } - - @Override - public Set getAugmentations() { - return augmentations; - } - - private void setAugmentations(Set augmentations) { - if (augmentations != null) { - this.augmentations = augmentations; - } - } - - @Override - public Set getRpcs() { - return rpcs; - } - - private void setRpcs(Set rpcs) { - if (rpcs != null) { - this.rpcs = rpcs; - } - } - - @Override - public Set getDeviations() { - return deviations; - } - - private void setDeviations(Set deviations) { - if (deviations != null) { - this.deviations = deviations; - } - } - - @Override - public Set getChildNodes() { - return new LinkedHashSet(childNodes.values()); - } - - private void setChildNodes(Map childNodes) { - if (childNodes != null) { - this.childNodes = childNodes; - } - } - - @Override - public Set getGroupings() { - return groupings; - } - - private void setGroupings(Set groupings) { - if (groupings != null) { - this.groupings = groupings; - } - } - - @Override - public Set getUses() { - return uses; - } - - private void setUses(Set uses) { - if (uses != null) { - this.uses = uses; - } - } - - @Override - public List getExtensionSchemaNodes() { - return extensionNodes; - } - - private void setExtensionSchemaNodes(final List extensionNodes) { - if (extensionNodes != null) { - this.extensionNodes = extensionNodes; - } - } - - @Override - public Set getIdentities() { - return identities; - } - - private void setIdentities(final Set identities) { - if (identities != null) { - this.identities = identities; - } - } - - @Override - public List getUnknownSchemaNodes() { - return unknownNodes; - } - - private void setUnknownSchemaNodes(final List unknownNodes) { - if (unknownNodes != null) { - this.unknownNodes = unknownNodes; - } - } - - @Override - public DataSchemaNode getDataChildByName(QName name) { - return childNodes.get(name); - } - - @Override - public DataSchemaNode getDataChildByName(String name) { - DataSchemaNode result = null; - for (Map.Entry entry : childNodes.entrySet()) { - if (entry.getKey().getLocalName().equals(name)) { - result = entry.getValue(); - break; - } - } - return result; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((namespace == null) ? 0 : namespace.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((revision == null) ? 0 : revision.hashCode()); - result = prime * result + ((prefix == null) ? 0 : prefix.hashCode()); - result = prime * result + ((yangVersion == null) ? 0 : yangVersion.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - ModuleImpl other = (ModuleImpl) obj; - if (namespace == null) { - if (other.namespace != null) { - return false; - } - } else if (!namespace.equals(other.namespace)) { - return false; - } - if (name == null) { - if (other.name != null) { - return false; - } - } else if (!name.equals(other.name)) { - return false; - } - if (revision == null) { - if (other.revision != null) { - return false; - } - } else if (!revision.equals(other.revision)) { - return false; - } - if (prefix == null) { - if (other.prefix != null) { - return false; - } - } else if (!prefix.equals(other.prefix)) { - return false; - } - if (yangVersion == null) { - if (other.yangVersion != null) { - return false; - } - } else if (!yangVersion.equals(other.yangVersion)) { - return false; - } - return true; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(ModuleImpl.class.getSimpleName()); - sb.append("["); - sb.append("name=" + name); - sb.append(", namespace=" + namespace); - sb.append(", revision=" + revision); - sb.append(", prefix=" + prefix); - sb.append(", yangVersion=" + yangVersion); - sb.append("]"); - return sb.toString(); - } - } - - /** - * Add child to parent. Method checks for duplicates and add given child - * node to parent. If node with same name is found, throws exception. If - * parent is null, child node will be added directly to module. - * - * @param parent - * @param child - * @param childName - */ - private void addChildToParent(final Builder parent, final DataSchemaNodeBuilder child, final String childName) { - final int line = child.getLine(); - if (parent.equals(this)) { - // if parent == null => node is defined under module - // All leafs, leaf-lists, lists, containers, choices, rpcs, - // notifications, and anyxmls defined within a parent node or at the - // top level of the module or its submodules share the same - // identifier namespace. - for (DataSchemaNodeBuilder childNode : addedChildNodes) { - if (childNode.getQName().getLocalName().equals(childName)) { - throw new YangParseException(name, line, "Can not add '" + child - + "': node with same name already declared at line " + childNode.getLine()); - } - } - for (RpcDefinitionBuilder rpc : addedRpcs) { - if (rpc.getQName().getLocalName().equals(childName)) { - throw new YangParseException(name, line, "Can not add '" + child - + "': rpc with same name already declared at line " + rpc.getLine()); - } - } - for (NotificationBuilder notification : addedNotifications) { - if (notification.getQName().getLocalName().equals(childName)) { - throw new YangParseException(name, line, "Can not add '" + child - + "': notification with same name already declared at line " + notification.getLine()); - } - } - addedChildNodes.add(child); - } else { - if(parent instanceof AugmentationSchemaBuilder) { - child.setAugmenting(true); - } - // no need for checking rpc and notification because they can be - // defined only under module or submodule - if (parent instanceof DataNodeContainerBuilder) { - DataNodeContainerBuilder parentNode = (DataNodeContainerBuilder) parent; - for (DataSchemaNodeBuilder childNode : parentNode.getChildNodeBuilders()) { - if (childNode.getQName().getLocalName().equals(childName)) { - throw new YangParseException(name, line, "Can not add '" + child + "': node with same name '" - + childName + "' already declared at line " + childNode.getLine()); - } - } - parentNode.addChildNode(child); - } else if (parent instanceof ChoiceBuilder) { - ChoiceBuilder parentNode = (ChoiceBuilder) parent; - for (ChoiceCaseBuilder caseBuilder : parentNode.getCases()) { - if (caseBuilder.getQName().getLocalName().equals(childName)) { - throw new YangParseException(name, line, "Can not add '" + child + "': case with same name '" - + childName + "' already declared at line " + caseBuilder.getLine()); - } - } - parentNode.addCase(child); - } else { - throw new YangParseException(name, line, "Unresolved parent of node '" + childName + "'."); - } - } - } - - private ModuleImport createModuleImport(final String moduleName, final Date revision, final String prefix) { - final ModuleImport moduleImport = new ModuleImport() { - @Override - public String getModuleName() { - return moduleName; - } - - @Override - public Date getRevision() { - return revision; - } - - @Override - public String getPrefix() { - return prefix; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((moduleName == null) ? 0 : moduleName.hashCode()); - result = prime * result + ((revision == null) ? 0 : revision.hashCode()); - result = prime * result + ((prefix == null) ? 0 : prefix.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - ModuleImport other = (ModuleImport) obj; - if (getModuleName() == null) { - if (other.getModuleName() != null) { - return false; - } - } else if (!getModuleName().equals(other.getModuleName())) { - return false; - } - if (getRevision() == null) { - if (other.getRevision() != null) { - return false; - } - } else if (!getRevision().equals(other.getRevision())) { - return false; - } - if (getPrefix() == null) { - if (other.getPrefix() != null) { - return false; - } - } else if (!getPrefix().equals(other.getPrefix())) { - return false; - } - return true; - } - - @Override - public String toString() { - return "ModuleImport[moduleName=" + moduleName + ", revision=" + revision + ", prefix=" + prefix + "]"; - } - }; - return moduleImport; - } - -} +/* + * 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.builder.impl; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +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.TreeMap; +import java.util.TreeSet; + +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Deviation; +import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition; +import org.opendaylight.yangtools.yang.model.api.FeatureDefinition; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; +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.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.parser.builder.api.AbstractDataNodeContainerBuilder; +import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder; +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; +import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder; +import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder; +import org.opendaylight.yangtools.yang.parser.builder.api.TypeAwareBuilder; +import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder; +import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder; +import org.opendaylight.yangtools.yang.parser.util.Comparators; +import org.opendaylight.yangtools.yang.parser.util.RefineHolder; +import org.opendaylight.yangtools.yang.parser.util.YangParseException; + +/** + * Builder of Module object. If this module is dependent on external + * module/modules, these dependencies must be resolved before module is built, + * otherwise result may not be valid. + */ +public class ModuleBuilder extends AbstractDataNodeContainerBuilder { + private final ModuleImpl instance; + private final String name; + private final SchemaPath schemaPath; + private URI namespace; + private String prefix; + private Date revision; + + private final LinkedList actualPath = new LinkedList(); + private final Set dirtyNodes = new HashSet(); + + private final Set imports = new HashSet(); + private final List addedAugments = new ArrayList(); + private final List allAugments = new ArrayList(); + private final Set addedUsesNodes = new HashSet(); + private final List allUsesNodes = new ArrayList(); + private final Set addedRpcs = new HashSet(); + private final Set addedNotifications = new HashSet(); + private final Set addedIdentities = new HashSet(); + private final Set addedFeatures = new HashSet(); + private final Set addedDeviations = new HashSet(); + private final Set addedTypedefs = new HashSet(); + private final List addedExtensions = new ArrayList(); + private final List allUnknownNodes = new ArrayList(); + + public ModuleBuilder(final String name) { + super(name, 0, null); + this.name = name; + schemaPath = new SchemaPath(Collections.emptyList(), true); + instance = new ModuleImpl(name); + actualPath.push(this); + } + + /** + * Build new Module object based on this builder. + */ + @Override + public Module build() { + instance.setPrefix(prefix); + instance.setRevision(revision); + instance.setImports(imports); + instance.setNamespace(namespace); + + // TYPEDEFS + final Set> typedefs = new TreeSet>(Comparators.SCHEMA_NODE_COMP); + for (TypeDefinitionBuilder tdb : addedTypedefs) { + typedefs.add(tdb.build()); + } + instance.setTypeDefinitions(typedefs); + + // CHILD NODES + final Map children = new TreeMap(Comparators.QNAME_COMP); + for (DataSchemaNodeBuilder child : addedChildNodes) { + children.put(child.getQName(), child.build()); + } + instance.setChildNodes(children); + + // GROUPINGS + final Set groupings = new TreeSet(Comparators.SCHEMA_NODE_COMP); + for (GroupingBuilder gb : addedGroupings) { + groupings.add(gb.build()); + } + instance.setGroupings(groupings); + + // USES + final Set usesDefinitions = new HashSet(); + for (UsesNodeBuilder unb : addedUsesNodes) { + usesDefinitions.add(unb.build()); + } + instance.setUses(usesDefinitions); + + // FEATURES + final Set features = new TreeSet(Comparators.SCHEMA_NODE_COMP); + for (FeatureBuilder fb : addedFeatures) { + features.add(fb.build()); + } + instance.setFeatures(features); + + // NOTIFICATIONS + final Set notifications = new TreeSet( + Comparators.SCHEMA_NODE_COMP); + for (NotificationBuilder entry : addedNotifications) { + notifications.add(entry.build()); + } + instance.setNotifications(notifications); + + // AUGMENTATIONS + final Set augmentations = new HashSet(); + for (AugmentationSchemaBuilder builder : addedAugments) { + augmentations.add(builder.build()); + } + instance.setAugmentations(augmentations); + + // RPCs + final Set rpcs = new TreeSet(Comparators.SCHEMA_NODE_COMP); + for (RpcDefinitionBuilder rpc : addedRpcs) { + rpcs.add(rpc.build()); + } + instance.setRpcs(rpcs); + + // DEVIATIONS + final Set deviations = new HashSet(); + for (DeviationBuilder entry : addedDeviations) { + deviations.add(entry.build()); + } + instance.setDeviations(deviations); + + // EXTENSIONS + final List extensions = new ArrayList(); + for (ExtensionBuilder eb : addedExtensions) { + extensions.add(eb.build()); + } + Collections.sort(extensions, Comparators.SCHEMA_NODE_COMP); + instance.setExtensionSchemaNodes(extensions); + + // IDENTITIES + final Set identities = new TreeSet(Comparators.SCHEMA_NODE_COMP); + for (IdentitySchemaNodeBuilder id : addedIdentities) { + identities.add(id.build()); + } + instance.setIdentities(identities); + + // UNKNOWN NODES + final List unknownNodes = new ArrayList(); + for (UnknownSchemaNodeBuilder unb : addedUnknownNodes) { + unknownNodes.add(unb.build()); + } + instance.setUnknownSchemaNodes(unknownNodes); + + return instance; + } + + public boolean isAllUsesDataCollected() { + for(UsesNodeBuilder usesNode : allUsesNodes) { + if(!usesNode.isDataCollected()) { + return false; + } + } + return true; + } + + @Override + public void setParent(Builder parent) { + throw new YangParseException(name, 0, "Can not set parent to module"); + } + + @Override + public SchemaPath getPath() { + return schemaPath; + } + + @Override + public Set getTypeDefinitionBuilders() { + return addedTypedefs; + } + + public void enterNode(final Builder node) { + actualPath.push(node); + } + + public void exitNode() { + actualPath.pop(); + } + + public Builder getActualNode() { + if (actualPath.isEmpty()) { + return null; + } else { + return actualPath.get(0); + } + } + + public Builder getActualParent() { + if (actualPath.size() < 2) { + return null; + } else { + return actualPath.get(1); + } + } + + public Set getDirtyNodes() { + return dirtyNodes; + } + + public List getAllAugments() { + return allAugments; + } + + public Set getIdentities() { + return addedIdentities; + } + + public List getAllUsesNodes() { + return allUsesNodes; + } + + public Set getDeviations() { + return addedDeviations; + } + + public List getExtensions() { + return addedExtensions; + } + + public List getAllUnknownNodes() { + return allUnknownNodes; + } + + public String getName() { + return name; + } + + public URI getNamespace() { + return namespace; + } + + public void setNamespace(final URI namespace) { + this.namespace = namespace; + } + + public String getPrefix() { + return prefix; + } + + public Date getRevision() { + return revision; + } + + public void markActualNodeDirty() { + final TypeAwareBuilder nodeBuilder = (TypeAwareBuilder) getActualNode(); + dirtyNodes.add(nodeBuilder); + } + + public void setRevision(final Date revision) { + this.revision = revision; + } + + public void setPrefix(final String prefix) { + this.prefix = prefix; + } + + public void setYangVersion(final String yangVersion) { + instance.setYangVersion(yangVersion); + } + + public void setDescription(final String description) { + instance.setDescription(description); + } + + public void setReference(final String reference) { + instance.setReference(reference); + } + + public void setOrganization(final String organization) { + instance.setOrganization(organization); + } + + public void setContact(final String contact) { + instance.setContact(contact); + } + + public boolean addModuleImport(final String moduleName, final Date revision, final String prefix) { + final ModuleImport moduleImport = createModuleImport(moduleName, revision, prefix); + return imports.add(moduleImport); + } + + public Set getModuleImports() { + return imports; + } + + public ExtensionBuilder addExtension(final QName qname, final int line) { + final String extName = qname.getLocalName(); + for (ExtensionBuilder addedExtension : addedExtensions) { + if (addedExtension.getQName().getLocalName().equals(extName)) { + throw new YangParseException(moduleName, line, "Can not add extension '" + extName + + "': extension with same name already declared at line " + addedExtension.getLine()); + } + } + final ExtensionBuilder builder = new ExtensionBuilder(name, line, qname); + addedExtensions.add(builder); + return builder; + } + + public ContainerSchemaNodeBuilder addContainerNode(final int line, final QName qname, final SchemaPath schemaPath) { + final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(name, line, qname, schemaPath); + + Builder parent = getActualNode(); + builder.setParent(parent); + addChildToParent(parent, builder, qname.getLocalName()); + + return builder; + } + + public ListSchemaNodeBuilder addListNode(final int line, final QName qname, final SchemaPath schemaPath) { + final ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(name, line, qname, schemaPath); + + Builder parent = getActualNode(); + builder.setParent(parent); + addChildToParent(parent, builder, qname.getLocalName()); + + return builder; + } + + public LeafSchemaNodeBuilder addLeafNode(final int line, final QName qname, final SchemaPath schemaPath) { + final LeafSchemaNodeBuilder builder = new LeafSchemaNodeBuilder(name, line, qname, schemaPath); + + Builder parent = getActualNode(); + builder.setParent(parent); + addChildToParent(parent, builder, qname.getLocalName()); + + return builder; + } + + public LeafListSchemaNodeBuilder addLeafListNode(final int line, final QName qname, final SchemaPath schemaPath) { + final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(name, line, qname, schemaPath); + + Builder parent = getActualNode(); + builder.setParent(parent); + addChildToParent(parent, builder, qname.getLocalName()); + + return builder; + } + + public GroupingBuilder addGrouping(final int line, final QName qname) { + final GroupingBuilder builder = new GroupingBuilderImpl(name, line, qname); + + Builder parent = getActualNode(); + builder.setParent(parent); + + String groupingName = qname.getLocalName(); + if (parent.equals(this)) { + for (GroupingBuilder addedGrouping : addedGroupings) { + if (addedGrouping.getQName().getLocalName().equals(groupingName)) { + throw new YangParseException(name, line, "grouping with same name '" + groupingName + + "' already declared at line " + addedGrouping.getLine()); + } + } + addedGroupings.add(builder); + } else { + if (parent instanceof DataNodeContainerBuilder) { + DataNodeContainerBuilder parentNode = (DataNodeContainerBuilder) parent; + for (GroupingBuilder addedGrouping : parentNode.getGroupingBuilders()) { + if (addedGrouping.getQName().getLocalName().equals(groupingName)) { + throw new YangParseException(name, line, "grouping with same name '" + groupingName + + "' already declared at line " + addedGrouping.getLine()); + } + } + parentNode.addGrouping(builder); + } else if (parent instanceof RpcDefinitionBuilder) { + RpcDefinitionBuilder parentNode = (RpcDefinitionBuilder) parent; + for (GroupingBuilder child : parentNode.getGroupings()) { + if (child.getQName().getLocalName().equals(groupingName)) { + throw new YangParseException(name, line, "grouping with same name '" + groupingName + + "' already declared at line " + child.getLine()); + } + } + parentNode.addGrouping(builder); + } else { + throw new YangParseException(name, line, "Unresolved parent of grouping " + groupingName); + } + } + + return builder; + } + + public AugmentationSchemaBuilder addAugment(final int line, final String augmentTargetStr) { + final AugmentationSchemaBuilder builder = new AugmentationSchemaBuilderImpl(name, line, augmentTargetStr); + + Builder parent = getActualNode(); + builder.setParent(parent); + + if (parent.equals(this)) { + // augment can be declared only under 'module' ... + addedAugments.add(builder); + } else { + // ... or 'uses' statement + if (parent instanceof UsesNodeBuilder) { + ((UsesNodeBuilder) parent).addAugment(builder); + } else { + throw new YangParseException(name, line, "Augment can be declared only under module or uses statement."); + } + } + allAugments.add(builder); + + return builder; + } + + @Override + public Set getUsesNodes() { + return addedUsesNodes; + } + + @Override + public void addUsesNode(UsesNodeBuilder usesBuilder) { + addedUsesNodes.add(usesBuilder); + allUsesNodes.add(usesBuilder); + } + + public UsesNodeBuilder addUsesNode(final int line, final String groupingPathStr) { + final UsesNodeBuilder usesBuilder = new UsesNodeBuilderImpl(name, line, groupingPathStr); + + Builder parent = getActualNode(); + usesBuilder.setParent(parent); + + if (parent.equals(this)) { + addedUsesNodes.add(usesBuilder); + } else { + if (!(parent instanceof DataNodeContainerBuilder)) { + throw new YangParseException(name, line, "Unresolved parent of uses '" + groupingPathStr + "'."); + } + ((DataNodeContainerBuilder) parent).addUsesNode(usesBuilder); + } + allUsesNodes.add(usesBuilder); + return usesBuilder; + } + + public void addRefine(final RefineHolder refine) { + final Builder parent = getActualNode(); + if (!(parent instanceof UsesNodeBuilder)) { + throw new YangParseException(name, refine.getLine(), "refine can be defined only in uses statement"); + } + ((UsesNodeBuilder) parent).addRefine(refine); + refine.setParent(parent); + } + + public RpcDefinitionBuilder addRpc(final int line, final QName qname) { + Builder parent = getActualNode(); + if (!(parent.equals(this))) { + throw new YangParseException(name, line, "rpc can be defined only in module or submodule"); + } + + final RpcDefinitionBuilder rpcBuilder = new RpcDefinitionBuilder(name, line, qname); + rpcBuilder.setParent(parent); + + String rpcName = qname.getLocalName(); + for (RpcDefinitionBuilder rpc : addedRpcs) { + if (rpc.getQName().getLocalName().equals(rpcName)) { + throw new YangParseException(name, line, "rpc with same name '" + rpcName + + "' already declared at line " + rpc.getLine()); + } + } + for (DataSchemaNodeBuilder addedChild : addedChildNodes) { + if (addedChild.getQName().getLocalName().equals(rpcName)) { + throw new YangParseException(name, line, "Can not add rpc: node with same name '" + rpcName + + "' already declared at line " + addedChild.getLine()); + } + } + for (NotificationBuilder addedNotification : addedNotifications) { + if (addedNotification.getQName().getLocalName().equals(rpcName)) { + throw new YangParseException(name, line, "Can not add rpc: notification with same name '" + rpcName + + "' already declared at line " + addedNotification.getLine()); + } + } + addedRpcs.add(rpcBuilder); + return rpcBuilder; + } + + public ContainerSchemaNodeBuilder addRpcInput(final int line, final QName qname, final SchemaPath schemaPath) { + final Builder parent = getActualNode(); + if (!(parent instanceof RpcDefinitionBuilder)) { + throw new YangParseException(name, line, "input can be defined only in rpc statement"); + } + final RpcDefinitionBuilder rpc = (RpcDefinitionBuilder) parent; + + final ContainerSchemaNodeBuilder inputBuilder = new ContainerSchemaNodeBuilder(name, line, qname, schemaPath); + inputBuilder.setParent(rpc); + + rpc.setInput(inputBuilder); + return inputBuilder; + } + + public ContainerSchemaNodeBuilder addRpcOutput(final SchemaPath schemaPath, final QName qname, final int line) { + final Builder parent = getActualNode(); + if (!(parent instanceof RpcDefinitionBuilder)) { + throw new YangParseException(name, line, "output can be defined only in rpc statement"); + } + final RpcDefinitionBuilder rpc = (RpcDefinitionBuilder) parent; + + final ContainerSchemaNodeBuilder outputBuilder = new ContainerSchemaNodeBuilder(name, line, qname, schemaPath); + outputBuilder.setParent(rpc); + + rpc.setOutput(outputBuilder); + return outputBuilder; + } + + public NotificationBuilder addNotification(final int line, final QName qname) { + final Builder parent = getActualNode(); + if (!(parent.equals(this))) { + throw new YangParseException(name, line, "notification can be defined only in module or submodule"); + } + + String notificationName = qname.getLocalName(); + for (NotificationBuilder nb : addedNotifications) { + if (nb.getQName().equals(qname)) { + throw new YangParseException(name, line, "notification with same name '" + notificationName + + "' already declared at line " + nb.getLine()); + } + } + for (RpcDefinitionBuilder rpc : addedRpcs) { + if (rpc.getQName().getLocalName().equals(notificationName)) { + throw new YangParseException(name, line, "Can not add notification: rpc with same name '" + + notificationName + "' already declared at line " + rpc.getLine()); + } + } + for (DataSchemaNodeBuilder addedChild : addedChildNodes) { + if (addedChild.getQName().getLocalName().equals(notificationName)) { + throw new YangParseException(name, line, "Can not add notification: node with same name '" + + notificationName + "' already declared at line " + addedChild.getLine()); + } + } + + final NotificationBuilder builder = new NotificationBuilder(name, line, qname); + builder.setParent(parent); + addedNotifications.add(builder); + + return builder; + } + + public FeatureBuilder addFeature(final int line, final QName qname) { + Builder parent = getActualNode(); + if (!(parent.equals(this))) { + throw new YangParseException(name, line, "feature can be defined only in module or submodule"); + } + + final FeatureBuilder builder = new FeatureBuilder(name, line, qname); + builder.setParent(parent); + + String featureName = qname.getLocalName(); + for (FeatureBuilder addedFeature : addedFeatures) { + if (addedFeature.getQName().getLocalName().equals(featureName)) { + throw new YangParseException(name, line, "feature with same name '" + featureName + + "' already declared at line " + addedFeature.getLine()); + } + } + addedFeatures.add(builder); + return builder; + } + + public ChoiceBuilder addChoice(final int line, final QName qname) { + final ChoiceBuilder builder = new ChoiceBuilder(name, line, qname); + + Builder parent = getActualNode(); + builder.setParent(parent); + addChildToParent(parent, builder, qname.getLocalName()); + + return builder; + } + + public ChoiceCaseBuilder addCase(final int line, final QName qname) { + Builder parent = getActualNode(); + if (parent == null || parent.equals(this)) { + throw new YangParseException(name, line, "'case' parent not found"); + } + + final ChoiceCaseBuilder builder = new ChoiceCaseBuilder(name, line, qname); + builder.setParent(parent); + + if (parent instanceof ChoiceBuilder) { + ((ChoiceBuilder) parent).addCase(builder); + } else if (parent instanceof AugmentationSchemaBuilder) { + ((AugmentationSchemaBuilder) parent).addChildNode(builder); + } else { + throw new YangParseException(name, line, "Unresolved parent of 'case' " + qname.getLocalName()); + } + + return builder; + } + + public AnyXmlBuilder addAnyXml(final int line, final QName qname, final SchemaPath schemaPath) { + final AnyXmlBuilder builder = new AnyXmlBuilder(name, line, qname, schemaPath); + + Builder parent = getActualNode(); + builder.setParent(parent); + addChildToParent(parent, builder, qname.getLocalName()); + + return builder; + } + + @Override + public void addTypedef(TypeDefinitionBuilder typedefBuilder) { + String nodeName = typedefBuilder.getQName().getLocalName(); + for (TypeDefinitionBuilder tdb : addedTypedefs) { + if (tdb.getQName().getLocalName().equals(nodeName)) { + throw new YangParseException(name, typedefBuilder.getLine(), "typedef with same name '" + nodeName + + "' already declared at line " + tdb.getLine()); + } + } + addedTypedefs.add(typedefBuilder); + } + + public TypeDefinitionBuilderImpl addTypedef(final int line, final QName qname) { + final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(name, line, qname); + + Builder parent = getActualNode(); + builder.setParent(parent); + + String typedefName = qname.getLocalName(); + if (parent.equals(this)) { + for (TypeDefinitionBuilder tdb : addedTypedefs) { + if (tdb.getQName().getLocalName().equals(typedefName)) { + throw new YangParseException(name, line, "typedef with same name '" + typedefName + + "' already declared at line " + tdb.getLine()); + } + } + addedTypedefs.add(builder); + } else { + if (parent instanceof DataNodeContainerBuilder) { + DataNodeContainerBuilder parentNode = (DataNodeContainerBuilder) parent; + for (TypeDefinitionBuilder child : parentNode.getTypeDefinitionBuilders()) { + if (child.getQName().getLocalName().equals(typedefName)) { + throw new YangParseException(name, line, "typedef with same name '" + typedefName + + "' already declared at line " + child.getLine()); + } + } + parentNode.addTypedef(builder); + } else if (parent instanceof RpcDefinitionBuilder) { + RpcDefinitionBuilder rpcParent = (RpcDefinitionBuilder) parent; + for (TypeDefinitionBuilder tdb : rpcParent.getTypeDefinitions()) { + if (tdb.getQName().getLocalName().equals(builder.getQName().getLocalName())) { + throw new YangParseException(name, line, "typedef with same name '" + typedefName + + "' already declared at line " + tdb.getLine()); + } + } + rpcParent.addTypedef(builder); + } else { + throw new YangParseException(name, line, "Unresolved parent of typedef " + typedefName); + } + } + + return builder; + } + + public void setType(final TypeDefinition type) { + Builder parent = getActualNode(); + if (parent == null || !(parent instanceof TypeAwareBuilder)) { + throw new YangParseException("Failed to set type '" + type.getQName().getLocalName() + + "'. Invalid parent node: " + parent); + } + ((TypeAwareBuilder) parent).setType(type); + } + + public UnionTypeBuilder addUnionType(final int line, final URI namespace, final Date revision) { + final Builder parent = getActualNode(); + if (parent == null) { + throw new YangParseException(name, line, "Unresolved parent of union type"); + } else { + final UnionTypeBuilder union = new UnionTypeBuilder(name, line); + if (parent instanceof TypeAwareBuilder) { + ((TypeAwareBuilder) parent).setTypedef(union); + return union; + } else { + throw new YangParseException(name, line, "Invalid parent of union type."); + } + } + } + + public void addIdentityrefType(final int line, final SchemaPath schemaPath, final String baseString) { + final IdentityrefTypeBuilder identityref = new IdentityrefTypeBuilder(name, line, baseString, schemaPath); + + final Builder parent = getActualNode(); + if (parent == null) { + throw new YangParseException(name, line, "Unresolved parent of identityref type."); + } else { + if (parent instanceof TypeAwareBuilder) { + final TypeAwareBuilder typeParent = (TypeAwareBuilder) parent; + typeParent.setTypedef(identityref); + dirtyNodes.add(typeParent); + } else { + throw new YangParseException(name, line, "Invalid parent of identityref type."); + } + } + } + + public DeviationBuilder addDeviation(final int line, final String targetPath) { + Builder parent = getActualNode(); + if (!(parent.equals(this))) { + throw new YangParseException(name, line, "deviation can be defined only in module or submodule"); + } + + final DeviationBuilder builder = new DeviationBuilder(name, line, targetPath); + builder.setParent(parent); + addedDeviations.add(builder); + return builder; + } + + public IdentitySchemaNodeBuilder addIdentity(final QName qname, final int line) { + Builder parent = getActualNode(); + if (!(parent.equals(this))) { + throw new YangParseException(name, line, "identity can be defined only in module or submodule"); + } + String identityName = qname.getLocalName(); + for (IdentitySchemaNodeBuilder idBuilder : addedIdentities) { + if (idBuilder.getQName().equals(qname)) { + throw new YangParseException(name, line, "identity with same name '" + identityName + + "' already declared at line " + idBuilder.getLine()); + } + } + + final IdentitySchemaNodeBuilder builder = new IdentitySchemaNodeBuilder(name, line, qname); + builder.setParent(parent); + addedIdentities.add(builder); + return builder; + } + + @Override + public void addUnknownNodeBuilder(final UnknownSchemaNodeBuilder builder) { + addedUnknownNodes.add(builder); + allUnknownNodes.add(builder); + } + + public UnknownSchemaNodeBuilder addUnknownSchemaNode(final int line, final QName qname) { + final Builder parent = getActualNode(); + final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(name, line, qname); + builder.setParent(parent); + allUnknownNodes.add(builder); + + if (parent.equals(this)) { + addedUnknownNodes.add(builder); + } else { + if (parent instanceof SchemaNodeBuilder) { + ((SchemaNodeBuilder) parent).addUnknownNodeBuilder(builder); + } else if (parent instanceof DataNodeContainerBuilder) { + ((DataNodeContainerBuilder) parent).addUnknownNodeBuilder(builder); + } else if (parent instanceof RefineHolder) { + ((RefineHolder) parent).addUnknownNodeBuilder(builder); + } else { + throw new YangParseException(name, line, "Unresolved parent of unknown node '" + qname.getLocalName() + + "'"); + } + } + + return builder; + } + + public Set getRpcs() { + return addedRpcs; + } + + public Set getNotifications() { + return addedNotifications; + } + + @Override + public String toString() { + return "module " + name; + } + + private final class ModuleImpl implements Module { + private URI namespace; + private final String name; + private Date revision; + private String prefix; + private String yangVersion; + private String description; + private String reference; + private String organization; + private String contact; + private Set imports = Collections.emptySet(); + private Set features = Collections.emptySet(); + private Set> typeDefinitions = Collections.emptySet(); + private Set notifications = Collections.emptySet(); + private Set augmentations = Collections.emptySet(); + private Set rpcs = Collections.emptySet(); + private Set deviations = Collections.emptySet(); + private Map childNodes = Collections.emptyMap(); + private Set groupings = Collections.emptySet(); + private Set uses = Collections.emptySet(); + private List extensionNodes = Collections.emptyList(); + private Set identities = Collections.emptySet(); + private List unknownNodes = Collections.emptyList(); + + private ModuleImpl(String name) { + this.name = name; + } + + @Override + public URI getNamespace() { + return namespace; + } + + private void setNamespace(URI namespace) { + this.namespace = namespace; + } + + @Override + public String getName() { + return name; + } + + @Override + public Date getRevision() { + return revision; + } + + private void setRevision(Date revision) { + this.revision = revision; + } + + @Override + public String getPrefix() { + return prefix; + } + + private void setPrefix(String prefix) { + this.prefix = prefix; + } + + @Override + public String getYangVersion() { + return yangVersion; + } + + private void setYangVersion(String yangVersion) { + this.yangVersion = yangVersion; + } + + @Override + public String getDescription() { + return description; + } + + private void setDescription(String description) { + this.description = description; + } + + @Override + public String getReference() { + return reference; + } + + private void setReference(String reference) { + this.reference = reference; + } + + @Override + public String getOrganization() { + return organization; + } + + private void setOrganization(String organization) { + this.organization = organization; + } + + @Override + public String getContact() { + return contact; + } + + private void setContact(String contact) { + this.contact = contact; + } + + @Override + public Set getImports() { + return imports; + } + + private void setImports(Set imports) { + if (imports != null) { + this.imports = imports; + } + } + + @Override + public Set getFeatures() { + return features; + } + + private void setFeatures(Set features) { + if (features != null) { + this.features = features; + } + } + + @Override + public Set> getTypeDefinitions() { + return typeDefinitions; + } + + private void setTypeDefinitions(Set> typeDefinitions) { + if (typeDefinitions != null) { + this.typeDefinitions = typeDefinitions; + } + } + + @Override + public Set getNotifications() { + return notifications; + } + + private void setNotifications(Set notifications) { + if (notifications != null) { + this.notifications = notifications; + } + } + + @Override + public Set getAugmentations() { + return augmentations; + } + + private void setAugmentations(Set augmentations) { + if (augmentations != null) { + this.augmentations = augmentations; + } + } + + @Override + public Set getRpcs() { + return rpcs; + } + + private void setRpcs(Set rpcs) { + if (rpcs != null) { + this.rpcs = rpcs; + } + } + + @Override + public Set getDeviations() { + return deviations; + } + + private void setDeviations(Set deviations) { + if (deviations != null) { + this.deviations = deviations; + } + } + + @Override + public Set getChildNodes() { + return new LinkedHashSet(childNodes.values()); + } + + private void setChildNodes(Map childNodes) { + if (childNodes != null) { + this.childNodes = childNodes; + } + } + + @Override + public Set getGroupings() { + return groupings; + } + + private void setGroupings(Set groupings) { + if (groupings != null) { + this.groupings = groupings; + } + } + + @Override + public Set getUses() { + return uses; + } + + private void setUses(Set uses) { + if (uses != null) { + this.uses = uses; + } + } + + @Override + public List getExtensionSchemaNodes() { + return extensionNodes; + } + + private void setExtensionSchemaNodes(final List extensionNodes) { + if (extensionNodes != null) { + this.extensionNodes = extensionNodes; + } + } + + @Override + public Set getIdentities() { + return identities; + } + + private void setIdentities(final Set identities) { + if (identities != null) { + this.identities = identities; + } + } + + @Override + public List getUnknownSchemaNodes() { + return unknownNodes; + } + + private void setUnknownSchemaNodes(final List unknownNodes) { + if (unknownNodes != null) { + this.unknownNodes = unknownNodes; + } + } + + @Override + public DataSchemaNode getDataChildByName(QName name) { + return childNodes.get(name); + } + + @Override + public DataSchemaNode getDataChildByName(String name) { + DataSchemaNode result = null; + for (Map.Entry entry : childNodes.entrySet()) { + if (entry.getKey().getLocalName().equals(name)) { + result = entry.getValue(); + break; + } + } + return result; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((namespace == null) ? 0 : namespace.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((revision == null) ? 0 : revision.hashCode()); + result = prime * result + ((prefix == null) ? 0 : prefix.hashCode()); + result = prime * result + ((yangVersion == null) ? 0 : yangVersion.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ModuleImpl other = (ModuleImpl) obj; + if (namespace == null) { + if (other.namespace != null) { + return false; + } + } else if (!namespace.equals(other.namespace)) { + return false; + } + if (name == null) { + if (other.name != null) { + return false; + } + } else if (!name.equals(other.name)) { + return false; + } + if (revision == null) { + if (other.revision != null) { + return false; + } + } else if (!revision.equals(other.revision)) { + return false; + } + if (prefix == null) { + if (other.prefix != null) { + return false; + } + } else if (!prefix.equals(other.prefix)) { + return false; + } + if (yangVersion == null) { + if (other.yangVersion != null) { + return false; + } + } else if (!yangVersion.equals(other.yangVersion)) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(ModuleImpl.class.getSimpleName()); + sb.append("["); + sb.append("name=" + name); + sb.append(", namespace=" + namespace); + sb.append(", revision=" + revision); + sb.append(", prefix=" + prefix); + sb.append(", yangVersion=" + yangVersion); + sb.append("]"); + return sb.toString(); + } + } + + /** + * Add child to parent. Method checks for duplicates and add given child + * node to parent. If node with same name is found, throws exception. If + * parent is null, child node will be added directly to module. + * + * @param parent + * @param child + * @param childName + */ + private void addChildToParent(final Builder parent, final DataSchemaNodeBuilder child, final String childName) { + final int line = child.getLine(); + if (parent.equals(this)) { + // if parent == null => node is defined under module + // All leafs, leaf-lists, lists, containers, choices, rpcs, + // notifications, and anyxmls defined within a parent node or at the + // top level of the module or its submodules share the same + // identifier namespace. + for (DataSchemaNodeBuilder childNode : addedChildNodes) { + if (childNode.getQName().getLocalName().equals(childName)) { + throw new YangParseException(name, line, "Can not add '" + child + + "': node with same name already declared at line " + childNode.getLine()); + } + } + for (RpcDefinitionBuilder rpc : addedRpcs) { + if (rpc.getQName().getLocalName().equals(childName)) { + throw new YangParseException(name, line, "Can not add '" + child + + "': rpc with same name already declared at line " + rpc.getLine()); + } + } + for (NotificationBuilder notification : addedNotifications) { + if (notification.getQName().getLocalName().equals(childName)) { + throw new YangParseException(name, line, "Can not add '" + child + + "': notification with same name already declared at line " + notification.getLine()); + } + } + addedChildNodes.add(child); + } else { + if(parent instanceof AugmentationSchemaBuilder) { + child.setAugmenting(true); + } + // no need for checking rpc and notification because they can be + // defined only under module or submodule + if (parent instanceof DataNodeContainerBuilder) { + DataNodeContainerBuilder parentNode = (DataNodeContainerBuilder) parent; + for (DataSchemaNodeBuilder childNode : parentNode.getChildNodeBuilders()) { + if (childNode.getQName().getLocalName().equals(childName)) { + throw new YangParseException(name, line, "Can not add '" + child + "': node with same name '" + + childName + "' already declared at line " + childNode.getLine()); + } + } + parentNode.addChildNode(child); + } else if (parent instanceof ChoiceBuilder) { + ChoiceBuilder parentNode = (ChoiceBuilder) parent; + for (ChoiceCaseBuilder caseBuilder : parentNode.getCases()) { + if (caseBuilder.getQName().getLocalName().equals(childName)) { + throw new YangParseException(name, line, "Can not add '" + child + "': case with same name '" + + childName + "' already declared at line " + caseBuilder.getLine()); + } + } + parentNode.addCase(child); + } else { + throw new YangParseException(name, line, "Unresolved parent of node '" + childName + "'."); + } + } + } + + private ModuleImport createModuleImport(final String moduleName, final Date revision, final String prefix) { + final ModuleImport moduleImport = new ModuleImport() { + @Override + public String getModuleName() { + return moduleName; + } + + @Override + public Date getRevision() { + return revision; + } + + @Override + public String getPrefix() { + return prefix; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((moduleName == null) ? 0 : moduleName.hashCode()); + result = prime * result + ((revision == null) ? 0 : revision.hashCode()); + result = prime * result + ((prefix == null) ? 0 : prefix.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ModuleImport other = (ModuleImport) obj; + if (getModuleName() == null) { + if (other.getModuleName() != null) { + return false; + } + } else if (!getModuleName().equals(other.getModuleName())) { + return false; + } + if (getRevision() == null) { + if (other.getRevision() != null) { + return false; + } + } else if (!getRevision().equals(other.getRevision())) { + return false; + } + if (getPrefix() == null) { + if (other.getPrefix() != null) { + return false; + } + } else if (!getPrefix().equals(other.getPrefix())) { + return false; + } + return true; + } + + @Override + public String toString() { + return "ModuleImport[moduleName=" + moduleName + ", revision=" + revision + ", prefix=" + prefix + "]"; + } + }; + return moduleImport; + } + +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/RpcDefinitionBuilder.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/RpcDefinitionBuilder.java index da752b0c69..04af1d3e92 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/RpcDefinitionBuilder.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/RpcDefinitionBuilder.java @@ -1,303 +1,311 @@ -/* - * 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.builder.impl; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; - -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; -import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; -import org.opendaylight.yangtools.yang.model.api.RpcDefinition; -import org.opendaylight.yangtools.yang.model.api.SchemaPath; -import org.opendaylight.yangtools.yang.model.api.Status; -import org.opendaylight.yangtools.yang.model.api.TypeDefinition; -import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; -import org.opendaylight.yangtools.yang.parser.builder.api.AbstractSchemaNodeBuilder; -import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder; -import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder; -import org.opendaylight.yangtools.yang.parser.util.Comparators; - -public final class RpcDefinitionBuilder extends AbstractSchemaNodeBuilder { - private boolean isBuilt; - private final RpcDefinitionImpl instance; - private ContainerSchemaNodeBuilder inputBuilder; - private ContainerSchemaNodeBuilder outputBuilder; - private final Set addedTypedefs = new HashSet(); - private final Set addedGroupings = new HashSet(); - - RpcDefinitionBuilder(final String moduleName, final int line, final QName qname) { - super(moduleName, line, qname); - this.instance = new RpcDefinitionImpl(qname); - } - - @Override - public RpcDefinition build() { - if (!isBuilt) { - instance.setDescription(description); - instance.setReference(reference); - instance.setStatus(status); - - final ContainerSchemaNode input = inputBuilder == null ? null : inputBuilder.build(); - final ContainerSchemaNode output = outputBuilder == null ? null : outputBuilder.build(); - instance.setInput(input); - instance.setOutput(output); - - instance.setPath(schemaPath); - - // TYPEDEFS - final Set> typedefs = new TreeSet>(Comparators.SCHEMA_NODE_COMP); - for (TypeDefinitionBuilder entry : addedTypedefs) { - typedefs.add(entry.build()); - } - instance.setTypeDefinitions(typedefs); - - // GROUPINGS - final Set groupings = new TreeSet(Comparators.SCHEMA_NODE_COMP); - for (GroupingBuilder entry : addedGroupings) { - groupings.add(entry.build()); - } - instance.setGroupings(groupings); - - // UNKNOWN NODES - if (unknownNodes == null) { - unknownNodes = new ArrayList(); - for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { - unknownNodes.add(b.build()); - } - Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP); - } - instance.setUnknownSchemaNodes(unknownNodes); - - isBuilt = true; - } - return instance; - } - - void setInput(final ContainerSchemaNodeBuilder inputBuilder) { - this.inputBuilder = inputBuilder; - } - - void setOutput(final ContainerSchemaNodeBuilder outputBuilder) { - this.outputBuilder = outputBuilder; - } - - public Set getTypeDefinitions() { - return addedTypedefs; - } - - public void addTypedef(final TypeDefinitionBuilder type) { - addedTypedefs.add(type); - } - - public Set getGroupings() { - return addedGroupings; - } - - public void addGrouping(GroupingBuilder grouping) { - addedGroupings.add(grouping); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((qname == null) ? 0 : qname.hashCode()); - result = prime * result + ((schemaPath == null) ? 0 : schemaPath.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (!(obj instanceof RpcDefinitionBuilder)) { - return false; - } - final RpcDefinitionBuilder other = (RpcDefinitionBuilder) obj; - if (other.qname == null) { - if (this.qname != null) { - return false; - } - } else if (!other.qname.equals(this.qname)) { - return false; - } - if (other.schemaPath == null) { - if (this.schemaPath != null) { - return false; - } - } else if (!other.schemaPath.equals(this.schemaPath)) { - return false; - } - return true; - } - - @Override - public String toString() { - return "rpc " + qname.getLocalName(); - } - - private final class RpcDefinitionImpl implements RpcDefinition { - private final QName qname; - private SchemaPath path; - private String description; - private String reference; - private Status status; - private ContainerSchemaNode input; - private ContainerSchemaNode output; - private Set> typeDefinitions; - private Set groupings; - private List unknownNodes = Collections.emptyList(); - - private RpcDefinitionImpl(final QName qname) { - this.qname = qname; - } - - @Override - public QName getQName() { - return qname; - } - - @Override - public SchemaPath getPath() { - return path; - } - - private void setPath(SchemaPath path) { - this.path = path; - } - - @Override - public String getDescription() { - return description; - } - - private void setDescription(String description) { - this.description = description; - } - - @Override - public String getReference() { - return reference; - } - - private void setReference(String reference) { - this.reference = reference; - } - - @Override - public Status getStatus() { - return status; - } - - private void setStatus(Status status) { - this.status = status; - } - - @Override - public ContainerSchemaNode getInput() { - return input; - } - - private void setInput(ContainerSchemaNode input) { - this.input = input; - } - - @Override - public ContainerSchemaNode getOutput() { - return output; - } - - private void setOutput(ContainerSchemaNode output) { - this.output = output; - } - - @Override - public Set> getTypeDefinitions() { - return typeDefinitions; - } - - private void setTypeDefinitions(Set> typeDefinitions) { - this.typeDefinitions = typeDefinitions; - } - - @Override - public Set getGroupings() { - return groupings; - } - - private void setGroupings(Set groupings) { - this.groupings = groupings; - } - - @Override - public List getUnknownSchemaNodes() { - return unknownNodes; - } - - private void setUnknownSchemaNodes(List unknownNodes) { - if (unknownNodes != null) { - this.unknownNodes = unknownNodes; - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((qname == null) ? 0 : qname.hashCode()); - result = prime * result + ((path == null) ? 0 : path.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final RpcDefinitionImpl other = (RpcDefinitionImpl) obj; - if (qname == null) { - if (other.qname != null) { - return false; - } - } else if (!qname.equals(other.qname)) { - return false; - } - if (path == null) { - if (other.path != null) { - return false; - } - } else if (!path.equals(other.path)) { - return false; - } - return true; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(RpcDefinitionImpl.class.getSimpleName() + "["); - sb.append("qname=" + qname); - sb.append(", path=" + path); - sb.append(", input=" + input); - sb.append(", output=" + output + "]"); - return sb.toString(); - } - } - -} +/* + * 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.builder.impl; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; + +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.RpcDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.Status; +import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; +import org.opendaylight.yangtools.yang.parser.builder.api.AbstractSchemaNodeBuilder; +import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder; +import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder; +import org.opendaylight.yangtools.yang.parser.util.Comparators; + +public final class RpcDefinitionBuilder extends AbstractSchemaNodeBuilder { + private boolean isBuilt; + private final RpcDefinitionImpl instance; + private ContainerSchemaNodeBuilder inputBuilder; + private ContainerSchemaNodeBuilder outputBuilder; + private final Set addedTypedefs = new HashSet(); + private final Set addedGroupings = new HashSet(); + + public ContainerSchemaNodeBuilder getInput() { + return inputBuilder; + } + + public ContainerSchemaNodeBuilder getOutput() { + return outputBuilder; + } + + RpcDefinitionBuilder(final String moduleName, final int line, final QName qname) { + super(moduleName, line, qname); + this.instance = new RpcDefinitionImpl(qname); + } + + @Override + public RpcDefinition build() { + if (!isBuilt) { + instance.setDescription(description); + instance.setReference(reference); + instance.setStatus(status); + + final ContainerSchemaNode input = inputBuilder == null ? null : inputBuilder.build(); + final ContainerSchemaNode output = outputBuilder == null ? null : outputBuilder.build(); + instance.setInput(input); + instance.setOutput(output); + + instance.setPath(schemaPath); + + // TYPEDEFS + final Set> typedefs = new TreeSet>(Comparators.SCHEMA_NODE_COMP); + for (TypeDefinitionBuilder entry : addedTypedefs) { + typedefs.add(entry.build()); + } + instance.setTypeDefinitions(typedefs); + + // GROUPINGS + final Set groupings = new TreeSet(Comparators.SCHEMA_NODE_COMP); + for (GroupingBuilder entry : addedGroupings) { + groupings.add(entry.build()); + } + instance.setGroupings(groupings); + + // UNKNOWN NODES + if (unknownNodes == null) { + unknownNodes = new ArrayList(); + for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { + unknownNodes.add(b.build()); + } + Collections.sort(unknownNodes, Comparators.SCHEMA_NODE_COMP); + } + instance.setUnknownSchemaNodes(unknownNodes); + + isBuilt = true; + } + return instance; + } + + void setInput(final ContainerSchemaNodeBuilder inputBuilder) { + this.inputBuilder = inputBuilder; + } + + void setOutput(final ContainerSchemaNodeBuilder outputBuilder) { + this.outputBuilder = outputBuilder; + } + + public Set getTypeDefinitions() { + return addedTypedefs; + } + + public void addTypedef(final TypeDefinitionBuilder type) { + addedTypedefs.add(type); + } + + public Set getGroupings() { + return addedGroupings; + } + + public void addGrouping(GroupingBuilder grouping) { + addedGroupings.add(grouping); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((qname == null) ? 0 : qname.hashCode()); + result = prime * result + ((schemaPath == null) ? 0 : schemaPath.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (!(obj instanceof RpcDefinitionBuilder)) { + return false; + } + final RpcDefinitionBuilder other = (RpcDefinitionBuilder) obj; + if (other.qname == null) { + if (this.qname != null) { + return false; + } + } else if (!other.qname.equals(this.qname)) { + return false; + } + if (other.schemaPath == null) { + if (this.schemaPath != null) { + return false; + } + } else if (!other.schemaPath.equals(this.schemaPath)) { + return false; + } + return true; + } + + @Override + public String toString() { + return "rpc " + qname.getLocalName(); + } + + private final class RpcDefinitionImpl implements RpcDefinition { + private final QName qname; + private SchemaPath path; + private String description; + private String reference; + private Status status; + private ContainerSchemaNode input; + private ContainerSchemaNode output; + private Set> typeDefinitions; + private Set groupings; + private List unknownNodes = Collections.emptyList(); + + private RpcDefinitionImpl(final QName qname) { + this.qname = qname; + } + + @Override + public QName getQName() { + return qname; + } + + @Override + public SchemaPath getPath() { + return path; + } + + private void setPath(SchemaPath path) { + this.path = path; + } + + @Override + public String getDescription() { + return description; + } + + private void setDescription(String description) { + this.description = description; + } + + @Override + public String getReference() { + return reference; + } + + private void setReference(String reference) { + this.reference = reference; + } + + @Override + public Status getStatus() { + return status; + } + + private void setStatus(Status status) { + this.status = status; + } + + @Override + public ContainerSchemaNode getInput() { + return input; + } + + private void setInput(ContainerSchemaNode input) { + this.input = input; + } + + @Override + public ContainerSchemaNode getOutput() { + return output; + } + + private void setOutput(ContainerSchemaNode output) { + this.output = output; + } + + @Override + public Set> getTypeDefinitions() { + return typeDefinitions; + } + + private void setTypeDefinitions(Set> typeDefinitions) { + this.typeDefinitions = typeDefinitions; + } + + @Override + public Set getGroupings() { + return groupings; + } + + private void setGroupings(Set groupings) { + this.groupings = groupings; + } + + @Override + public List getUnknownSchemaNodes() { + return unknownNodes; + } + + private void setUnknownSchemaNodes(List unknownNodes) { + if (unknownNodes != null) { + this.unknownNodes = unknownNodes; + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((qname == null) ? 0 : qname.hashCode()); + result = prime * result + ((path == null) ? 0 : path.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final RpcDefinitionImpl other = (RpcDefinitionImpl) obj; + if (qname == null) { + if (other.qname != null) { + return false; + } + } else if (!qname.equals(other.qname)) { + return false; + } + if (path == null) { + if (other.path != null) { + return false; + } + } else if (!path.equals(other.path)) { + return false; + } + return true; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(RpcDefinitionImpl.class.getSimpleName() + "["); + sb.append("qname=" + qname); + sb.append(", path=" + path); + sb.append(", input=" + input); + sb.append(", output=" + output + "]"); + return sb.toString(); + } + } + +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java index 48bca6716c..c7782adf2b 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java @@ -1,986 +1,986 @@ -/* - * 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 static org.opendaylight.yangtools.yang.parser.util.ParserUtils.*; -import static org.opendaylight.yangtools.yang.parser.util.TypeUtils.*; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.TreeMap; - -import org.antlr.v4.runtime.ANTLRInputStream; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.tree.ParseTree; -import org.antlr.v4.runtime.tree.ParseTreeWalker; -import org.opendaylight.yangtools.antlrv4.code.gen.YangLexer; -import org.opendaylight.yangtools.antlrv4.code.gen.YangParser; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; -import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition; -import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; -import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; -import org.opendaylight.yangtools.yang.model.api.Module; -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.YangModelParser; -import org.opendaylight.yangtools.yang.model.util.IdentityrefType; -import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder; -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.GroupingBuilder; -import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder; -import org.opendaylight.yangtools.yang.parser.builder.api.TypeAwareBuilder; -import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder; -import org.opendaylight.yangtools.yang.parser.builder.impl.DeviationBuilder; -import org.opendaylight.yangtools.yang.parser.builder.impl.ExtensionBuilder; -import org.opendaylight.yangtools.yang.parser.builder.impl.IdentitySchemaNodeBuilder; -import org.opendaylight.yangtools.yang.parser.builder.impl.IdentityrefTypeBuilder; -import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder; -import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder; -import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilder; -import org.opendaylight.yangtools.yang.parser.util.GroupingUtils; -import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort; -import org.opendaylight.yangtools.yang.parser.util.ParserUtils; -import org.opendaylight.yangtools.yang.parser.util.YangParseException; -import org.opendaylight.yangtools.yang.validator.YangModelBasicValidator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; - -public final class YangParserImpl implements YangModelParser { - private static final Logger LOG = LoggerFactory.getLogger(YangParserImpl.class); - - @Override - public Set parseYangModels(final List yangFiles) { - return Sets.newLinkedHashSet(parseYangModelsMapped(yangFiles).values()); - } - - @Override - public Set parseYangModels(final List yangFiles, final SchemaContext context) { - if (yangFiles != null) { - final Map inputStreams = Maps.newHashMap(); - - for (final File yangFile : yangFiles) { - try { - inputStreams.put(new FileInputStream(yangFile), yangFile); - } catch (FileNotFoundException e) { - LOG.warn("Exception while reading yang file: " + yangFile.getName(), e); - } - } - - Map builderToStreamMap = Maps.newHashMap(); - - final Map> modules = resolveModuleBuilders( - Lists.newArrayList(inputStreams.keySet()), builderToStreamMap); - - for (InputStream is : inputStreams.keySet()) { - try { - is.close(); - } catch (IOException e) { - LOG.debug("Failed to close stream."); - } - } - - return new LinkedHashSet(buildWithContext(modules, context).values()); - } - return Collections.emptySet(); - } - - @Override - public Set parseYangModelsFromStreams(final List yangModelStreams) { - return Sets.newHashSet(parseYangModelsFromStreamsMapped(yangModelStreams).values()); - } - - @Override - public Set parseYangModelsFromStreams(final List yangModelStreams, SchemaContext context) { - if (yangModelStreams != null) { - Map builderToStreamMap = Maps.newHashMap(); - final Map> modules = resolveModuleBuildersWithContext( - yangModelStreams, builderToStreamMap, context); - return new LinkedHashSet(buildWithContext(modules, context).values()); - } - return Collections.emptySet(); - } - - @Override - public Map parseYangModelsMapped(List yangFiles) { - if (yangFiles != null) { - final Map inputStreams = Maps.newHashMap(); - - for (final File yangFile : yangFiles) { - try { - inputStreams.put(new FileInputStream(yangFile), yangFile); - } catch (FileNotFoundException e) { - LOG.warn("Exception while reading yang file: " + yangFile.getName(), e); - } - } - - Map builderToStreamMap = Maps.newHashMap(); - final Map> modules = resolveModuleBuilders( - Lists.newArrayList(inputStreams.keySet()), builderToStreamMap); - - for (InputStream is : inputStreams.keySet()) { - try { - is.close(); - } catch (IOException e) { - LOG.debug("Failed to close stream."); - } - } - - Map retVal = Maps.newLinkedHashMap(); - Map builderToModuleMap = build(modules); - - for (Entry builderToModule : builderToModuleMap.entrySet()) { - retVal.put(inputStreams.get(builderToStreamMap.get(builderToModule.getKey())), - builderToModule.getValue()); - } - - return retVal; - } - return Collections.emptyMap(); - } - - @Override - public Map parseYangModelsFromStreamsMapped(final List yangModelStreams) { - Map builderToStreamMap = Maps.newHashMap(); - - final Map> modules = resolveModuleBuilders(yangModelStreams, - builderToStreamMap); - Map retVal = Maps.newLinkedHashMap(); - Map builderToModuleMap = build(modules); - - for (Entry builderToModule : builderToModuleMap.entrySet()) { - retVal.put(builderToStreamMap.get(builderToModule.getKey()), builderToModule.getValue()); - } - return retVal; - } - - @Override - public SchemaContext resolveSchemaContext(final Set modules) { - return new SchemaContextImpl(modules); - } - - private ModuleBuilder[] parseModuleBuilders(List inputStreams, - Map streamToBuilderMap) { - - final ParseTreeWalker walker = new ParseTreeWalker(); - final List trees = parseStreams(inputStreams); - final ModuleBuilder[] builders = new ModuleBuilder[trees.size()]; - - // validate yang - new YangModelBasicValidator(walker).validate(trees); - - YangParserListenerImpl yangModelParser = null; - for (int i = 0; i < trees.size(); i++) { - yangModelParser = new YangParserListenerImpl(); - walker.walk(yangModelParser, trees.get(i)); - ModuleBuilder moduleBuilder = yangModelParser.getModuleBuilder(); - - // We expect the order of trees and streams has to be the same - streamToBuilderMap.put(moduleBuilder, inputStreams.get(i)); - builders[i] = moduleBuilder; - } - return builders; - } - - private Map> resolveModuleBuilders(final List yangFileStreams, - Map streamToBuilderMap) { - return resolveModuleBuildersWithContext(yangFileStreams, streamToBuilderMap, null); - } - - private Map> resolveModuleBuildersWithContext( - final List yangFileStreams, final Map streamToBuilderMap, - final SchemaContext context) { - final ModuleBuilder[] builders = parseModuleBuilders(yangFileStreams, streamToBuilderMap); - - // LinkedHashMap must be used to preserve order - final LinkedHashMap> modules = new LinkedHashMap>(); - - // module dependency graph sorted - List sorted = null; - if (context == null) { - sorted = ModuleDependencySort.sort(builders); - } else { - sorted = ModuleDependencySort.sortWithContext(context, builders); - } - - for (final ModuleBuilder builder : sorted) { - if (builder == null) { - continue; - } - final String builderName = builder.getName(); - Date builderRevision = builder.getRevision(); - if (builderRevision == null) { - builderRevision = new Date(0L); - } - TreeMap builderByRevision = modules.get(builderName); - if (builderByRevision == null) { - builderByRevision = new TreeMap(); - } - builderByRevision.put(builderRevision, builder); - modules.put(builderName, builderByRevision); - } - return modules; - } - - private List parseStreams(final List yangStreams) { - final List trees = new ArrayList(); - for (InputStream yangStream : yangStreams) { - trees.add(parseStream(yangStream)); - } - return trees; - } - - private ParseTree parseStream(final InputStream yangStream) { - ParseTree result = null; - try { - final ANTLRInputStream input = new ANTLRInputStream(yangStream); - final YangLexer lexer = new YangLexer(input); - final CommonTokenStream tokens = new CommonTokenStream(lexer); - final YangParser parser = new YangParser(tokens); - parser.removeErrorListeners(); - parser.addErrorListener(new YangErrorListener()); - - result = parser.yang(); - } catch (IOException e) { - LOG.warn("Exception while reading yang file: " + yangStream, e); - } - return result; - } - - private Map build(final Map> modules) { - // fix unresolved nodes - findUsesTargets(modules, null); - resolveDirtyNodes(modules); - resolveAugments(modules); - resolveUses(modules); - resolveDeviations(modules); - - // build - final Map result = new LinkedHashMap(); - for (Map.Entry> entry : modules.entrySet()) { - final Map modulesByRevision = new HashMap(); - for (Map.Entry childEntry : entry.getValue().entrySet()) { - final ModuleBuilder moduleBuilder = childEntry.getValue(); - final Module module = moduleBuilder.build(); - modulesByRevision.put(childEntry.getKey(), module); - result.put(moduleBuilder, module); - } - } - return result; - } - - private Map buildWithContext(final Map> modules, - final SchemaContext context) { - // fix unresolved nodes - findUsesTargets(modules, context); - resolvedDirtyNodesWithContext(modules, context); - resolveAugmentsWithContext(modules, context); - resolveUsesWithContext(modules, context); - resolveDeviationsWithContext(modules, context); - - // build - final Map result = new LinkedHashMap(); - for (Map.Entry> entry : modules.entrySet()) { - final Map modulesByRevision = new HashMap(); - for (Map.Entry childEntry : entry.getValue().entrySet()) { - final ModuleBuilder moduleBuilder = childEntry.getValue(); - final Module module = moduleBuilder.build(); - modulesByRevision.put(childEntry.getKey(), module); - result.put(moduleBuilder, module); - } - } - return result; - } - - private void resolveDirtyNodes(final Map> modules) { - for (Map.Entry> entry : modules.entrySet()) { - for (Map.Entry childEntry : entry.getValue().entrySet()) { - final ModuleBuilder module = childEntry.getValue(); - resolveDirtyNodes(modules, module); - resolveIdentities(modules, module); - resolveUnknownNodes(modules, module); - } - } - } - - private void resolvedDirtyNodesWithContext(final Map> modules, - final SchemaContext context) { - for (Map.Entry> entry : modules.entrySet()) { - for (Map.Entry childEntry : entry.getValue().entrySet()) { - final ModuleBuilder module = childEntry.getValue(); - resolveDirtyNodesWithContext(modules, module, context); - resolveIdentitiesWithContext(modules, module, context); - resolveUnknownNodesWithContext(modules, module, context); - } - } - } - - /** - * Search for dirty nodes (node which contains UnknownType) and resolve - * unknown types. - * - * @param modules - * all available modules - * @param module - * current module - */ - private void resolveDirtyNodes(final Map> modules, final ModuleBuilder module) { - final Set dirtyNodes = module.getDirtyNodes(); - if (!dirtyNodes.isEmpty()) { - for (TypeAwareBuilder nodeToResolve : dirtyNodes) { - if (nodeToResolve instanceof UnionTypeBuilder) { - // special handling for union types - resolveTypeUnion((UnionTypeBuilder) nodeToResolve, modules, module); - } else if (nodeToResolve.getTypedef() instanceof IdentityrefTypeBuilder) { - // special handling for identityref types - IdentityrefTypeBuilder idref = (IdentityrefTypeBuilder) nodeToResolve.getTypedef(); - nodeToResolve.setType(new IdentityrefType(findFullQName(modules, module, idref), idref.getPath())); - } else { - resolveType(nodeToResolve, modules, module); - } - } - } - } - - private void resolveDirtyNodesWithContext(final Map> modules, - final ModuleBuilder module, SchemaContext context) { - final Set 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(); - nodeToResolve.setType(new IdentityrefType(findFullQName(modules, module, idref), idref.getPath())); - } else { - resolveTypeWithContext(nodeToResolve, modules, module, context); - } - } - } - } - - /** - * Go through all augment definitions and perform augmentation. It is - * expected that modules are already sorted by their dependencies. - * - * @param modules - * all loaded modules - */ - private void resolveAugments(final Map> modules) { - // collect augments from all loaded modules - final List allAugments = new ArrayList<>(); - for (Map.Entry> entry : modules.entrySet()) { - for (Map.Entry inner : entry.getValue().entrySet()) { - allAugments.addAll(inner.getValue().getAllAugments()); - } - } - - for (int i = 0; i < allAugments.size(); i++) { - // pick one augment - final AugmentationSchemaBuilder augment = allAugments.get(i); - // create collection of others - List others = new ArrayList<>(allAugments); - others.remove(augment); - - // try to resolve it - boolean resolved = resolveAugment(modules, augment); - // while not resolved - int j = 0; - while (!(resolved) && j < others.size()) { - // try to resolve next augment - resolveAugment(modules, others.get(j)); - // then try to resolve first again - resolved = resolveAugment(modules, augment); - j++; - - } - - if (!resolved) { - throw new YangParseException(augment.getModuleName(), augment.getLine(), - "Error in augment parsing: failed to find augment target"); - } - } - } - - /** - * Search for augment target and perform augmentation. - * - * @param modules - * all loaded modules - * @param augmentBuilder - * augment to resolve - * @return true if target node found, false otherwise - */ - private boolean resolveAugment(final Map> modules, - final AugmentationSchemaBuilder augmentBuilder) { - if (augmentBuilder.isResolved()) { - return true; - } - - int line = augmentBuilder.getLine(); - ModuleBuilder module = getParentModule(augmentBuilder); - List path = augmentBuilder.getTargetPath().getPath(); - Builder augmentParent = augmentBuilder.getParent(); - - Builder firstNodeParent = null; - if (augmentParent instanceof ModuleBuilder) { - // if augment is defined under module, parent of first node is - // target module - final QName firstNameInPath = path.get(0); - String prefix = firstNameInPath.getPrefix(); - if (prefix == null) { - prefix = module.getPrefix(); - } - firstNodeParent = findDependentModuleBuilder(modules, module, prefix, line); - } else if (augmentParent instanceof UsesNodeBuilder) { - firstNodeParent = augmentParent.getParent(); - } else { - // augment can be defined only under module or uses - throw new YangParseException(augmentBuilder.getModuleName(), line, - "Failed to parse augment: Unresolved parent of augment: " + augmentParent); - } - - return processAugmentation(augmentBuilder, firstNodeParent, path); - } - - /** - * Go through all augment definitions and resolve them. This method works in - * same way as {@link #resolveAugments(Map)} except that if target node is - * not found in loaded modules, it search for target node in given context. - * - * @param modules - * all loaded modules - * @param context - * SchemaContext containing already resolved modules - */ - private void resolveAugmentsWithContext(final Map> modules, - final SchemaContext context) { - // collect augments from all loaded modules - final List allAugments = new ArrayList<>(); - for (Map.Entry> entry : modules.entrySet()) { - for (Map.Entry inner : entry.getValue().entrySet()) { - allAugments.addAll(inner.getValue().getAllAugments()); - } - } - - for (int i = 0; i < allAugments.size(); i++) { - // pick augment from list - final AugmentationSchemaBuilder augment = allAugments.get(i); - // try to resolve it - boolean resolved = resolveAugmentWithContext(modules, augment, context); - // while not resolved - int j = i + 1; - while (!(resolved) && j < allAugments.size()) { - // try to resolve next augment - resolveAugmentWithContext(modules, allAugments.get(j), context); - // then try to resolve first again - resolved = resolveAugmentWithContext(modules, augment, context); - j++; - } - - if (!resolved) { - throw new YangParseException(augment.getModuleName(), augment.getLine(), - "Error in augment parsing: failed to find augment target"); - } - } - } - - /** - * Search for augment target and perform augmentation. - * - * @param modules - * all loaded modules - * @param augment - * augment to resolve - * @param context - * SchemaContext containing already resolved modules - * @return true if target node found, false otherwise - */ - private boolean resolveAugmentWithContext(final Map> modules, - final AugmentationSchemaBuilder augment, final SchemaContext context) { - if (augment.isResolved()) { - return true; - } - int line = augment.getLine(); - ModuleBuilder module = getParentModule(augment); - List path = augment.getTargetPath().getPath(); - final QName firstNameInPath = path.get(0); - String prefix = firstNameInPath.getPrefix(); - if (prefix == null) { - prefix = module.getPrefix(); - } - Builder augmentParent = augment.getParent(); - Builder currentParent = null; - - if (augmentParent instanceof ModuleBuilder) { - // if augment is defined under module, first parent is target module - currentParent = findDependentModuleBuilder(modules, module, prefix, line); - } else if (augmentParent instanceof UsesNodeBuilder) { - currentParent = augmentParent.getParent(); - } else { - // augment can be defined only under module or uses - throw new YangParseException(augment.getModuleName(), augment.getLine(), - "Error in augment parsing: Unresolved parent of augment: " + augmentParent); - } - - if (currentParent == null) { - return processAugmentationOnContext(augment, path, module, prefix, context); - } else { - return processAugmentation(augment, currentParent, path); - } - } - - /** - * Go through identity statements defined in current module and resolve - * their 'base' statement if present. - * - * @param modules - * all modules - * @param module - * module being resolved - */ - private void resolveIdentities(final Map> modules, final ModuleBuilder module) { - final Set identities = module.getIdentities(); - for (IdentitySchemaNodeBuilder identity : identities) { - final String baseIdentityName = identity.getBaseIdentityName(); - if (baseIdentityName != null) { - String baseIdentityPrefix = null; - String baseIdentityLocalName = null; - if (baseIdentityName.contains(":")) { - final String[] splitted = baseIdentityName.split(":"); - baseIdentityPrefix = splitted[0]; - baseIdentityLocalName = splitted[1]; - } else { - baseIdentityPrefix = module.getPrefix(); - baseIdentityLocalName = baseIdentityName; - } - final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, baseIdentityPrefix, - identity.getLine()); - - final Set dependentModuleIdentities = dependentModule.getIdentities(); - for (IdentitySchemaNodeBuilder idBuilder : dependentModuleIdentities) { - if (idBuilder.getQName().getLocalName().equals(baseIdentityLocalName)) { - identity.setBaseIdentity(idBuilder); - } - } - } - } - } - - /** - * 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> modules, - final ModuleBuilder module, final SchemaContext context) { - final Set identities = module.getIdentities(); - for (IdentitySchemaNodeBuilder identity : identities) { - final String baseIdentityName = identity.getBaseIdentityName(); - if (baseIdentityName != null) { - String baseIdentityPrefix = null; - String baseIdentityLocalName = null; - if (baseIdentityName.contains(":")) { - final String[] splitted = baseIdentityName.split(":"); - baseIdentityPrefix = splitted[0]; - baseIdentityLocalName = splitted[1]; - } else { - baseIdentityPrefix = module.getPrefix(); - baseIdentityLocalName = baseIdentityName; - } - final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, module, - baseIdentityPrefix, identity.getLine()); - - if (dependentModuleBuilder == null) { - final Module dependentModule = findModuleFromContext(context, module, baseIdentityPrefix, - identity.getLine()); - final Set dependentModuleIdentities = dependentModule.getIdentities(); - for (IdentitySchemaNode idNode : dependentModuleIdentities) { - if (idNode.getQName().getLocalName().equals(baseIdentityLocalName)) { - identity.setBaseIdentity(idNode); - } - } - } else { - final Set dependentModuleIdentities = dependentModuleBuilder - .getIdentities(); - for (IdentitySchemaNodeBuilder idBuilder : dependentModuleIdentities) { - if (idBuilder.getQName().getLocalName().equals(baseIdentityLocalName)) { - identity.setBaseIdentity(idBuilder); - } - } - } - } - } - } - - /** - * Find and add reference of uses target grouping. - * - * @param modules - * all loaded modules - * @param context - * SchemaContext containing already resolved modules or null if - * context is not available - */ - private void findUsesTargets(final Map> modules, final SchemaContext context) { - final List allUses = new ArrayList<>(); - for (Map.Entry> entry : modules.entrySet()) { - for (Map.Entry inner : entry.getValue().entrySet()) { - allUses.addAll(inner.getValue().getAllUsesNodes()); - } - } - for (UsesNodeBuilder usesNode : allUses) { - ModuleBuilder module = ParserUtils.getParentModule(usesNode); - 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); - } - } - } - - /** - * Copy data from uses target, update uses parent and perform refinement. - * Augmentations have to be resolved already. - * - * @param modules - * all loaded modules - */ - private void resolveUses(final Map> modules) { - for (Map.Entry> entry : modules.entrySet()) { - for (Map.Entry inner : entry.getValue().entrySet()) { - ModuleBuilder module = inner.getValue(); - List usesNodes = null; - boolean dataCollected = module.isAllUsesDataCollected(); - - while (!dataCollected) { - usesNodes = new ArrayList<>(module.getAllUsesNodes()); - for (UsesNodeBuilder usesNode : usesNodes) { - if (!usesNode.isDataCollected()) { - GroupingUtils.collectUsesData(usesNode); - } - } - dataCollected = module.isAllUsesDataCollected(); - } - } - } - - // new loop is must because in collecting data process new uses could - // be created - final List allModulesUses = new ArrayList<>(); - for (Map.Entry> entry : modules.entrySet()) { - for (Map.Entry inner : entry.getValue().entrySet()) { - allModulesUses.addAll(inner.getValue().getAllUsesNodes()); - } - } - - for (UsesNodeBuilder usesNode : allModulesUses) { - GroupingUtils.updateUsesParent(usesNode); - GroupingUtils.performRefine(usesNode); - } - for (UsesNodeBuilder usesNode : allModulesUses) { - GroupingUtils.fixUsesNodesPath(usesNode); - } - - for (UsesNodeBuilder usesNode : allModulesUses) { - if (usesNode.isCopy()) { - usesNode.getParent().getUsesNodes().remove(usesNode); - } - } - } - - /** - * Copy data from uses target, update uses parent and perform refinement. - * Augmentations have to be resolved already. - * - * @param modules - * all loaded modules - * @param context - * SchemaContext containing already resolved modules - */ - private void resolveUsesWithContext(final Map> modules, - final SchemaContext context) { - for (Map.Entry> entry : modules.entrySet()) { - for (Map.Entry inner : entry.getValue().entrySet()) { - ModuleBuilder module = inner.getValue(); - List usesNodes = null; - boolean dataCollected = module.isAllUsesDataCollected(); - - while (!dataCollected) { - usesNodes = new ArrayList<>(module.getAllUsesNodes()); - for (UsesNodeBuilder usesNode : usesNodes) { - if (!usesNode.isDataCollected()) { - if (usesNode.getGroupingBuilder() == null) { - GroupingUtils.collectUsesDataFromContext(usesNode); - } else { - GroupingUtils.collectUsesData(usesNode); - } - } - } - dataCollected = module.isAllUsesDataCollected(); - } - } - } - - // new loop is must because in collecting data process new uses could - // be created - final List allModulesUses = new ArrayList<>(); - for (Map.Entry> entry : modules.entrySet()) { - for (Map.Entry inner : entry.getValue().entrySet()) { - allModulesUses.addAll(inner.getValue().getAllUsesNodes()); - } - } - - for (UsesNodeBuilder usesNode : allModulesUses) { - GroupingUtils.updateUsesParent(usesNode); - GroupingUtils.performRefine(usesNode); - } - for (UsesNodeBuilder usesNode : allModulesUses) { - GroupingUtils.fixUsesNodesPath(usesNode); - } - } - - private void resolveUnknownNodes(final Map> modules, final ModuleBuilder module) { - for (UnknownSchemaNodeBuilder usnb : module.getAllUnknownNodes()) { - QName nodeType = usnb.getNodeType(); - try { - ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, nodeType.getPrefix(), - usnb.getLine()); - for (ExtensionBuilder extension : dependentModule.getExtensions()) { - if (extension.getQName().getLocalName().equals(nodeType.getLocalName())) { - usnb.setNodeType(extension.getQName()); - usnb.setExtensionBuilder(extension); - break; - } - } - } catch (YangParseException e) { - throw new YangParseException(module.getName(), usnb.getLine(), "Failed to resolve node " + usnb - + ": no such extension definition found."); - } - } - } - - private void resolveUnknownNodesWithContext(final Map> modules, - final ModuleBuilder module, final SchemaContext context) { - for (UnknownSchemaNodeBuilder usnb : module.getAllUnknownNodes()) { - QName nodeType = usnb.getNodeType(); - try { - ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(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.getExtensions()) { - 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."); - } - - } - } - - /** - * Traverse through modules and resolve their deviation statements. - * - * @param modules - * all loaded modules - */ - private void resolveDeviations(final Map> modules) { - for (Map.Entry> entry : modules.entrySet()) { - for (Map.Entry inner : entry.getValue().entrySet()) { - ModuleBuilder b = inner.getValue(); - resolveDeviation(modules, b); - } - } - } - - /** - * Traverse through module and resolve its deviation statements. - * - * @param modules - * all loaded modules - * @param module - * module in which resolve deviations - */ - private void resolveDeviation(final Map> modules, final ModuleBuilder module) { - for (DeviationBuilder dev : module.getDeviations()) { - int line = dev.getLine(); - SchemaPath targetPath = dev.getTargetPath(); - List path = targetPath.getPath(); - QName q0 = path.get(0); - String prefix = q0.getPrefix(); - if (prefix == null) { - prefix = module.getPrefix(); - } - - ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, module, prefix, line); - 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> modules, - final SchemaContext context) { - for (Map.Entry> entry : modules.entrySet()) { - for (Map.Entry 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> modules, - final ModuleBuilder module, final SchemaContext context) { - for (DeviationBuilder dev : module.getDeviations()) { - int line = dev.getLine(); - SchemaPath targetPath = dev.getTargetPath(); - List path = targetPath.getPath(); - QName q0 = path.get(0); - String prefix = q0.getPrefix(); - if (prefix == null) { - prefix = module.getPrefix(); - } - String name = null; - - ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, module, prefix, line); - if (dependentModuleBuilder == null) { - Module dependentModule = findModuleFromContext(context, module, prefix, line); - Object currentParent = dependentModule; - - for (int i = 0; i < path.size(); i++) { - if (currentParent == null) { - throw new YangParseException(module.getName(), line, "Failed to find deviation target."); - } - QName q = path.get(i); - name = q.getLocalName(); - if (currentParent instanceof DataNodeContainer) { - currentParent = ((DataNodeContainer) currentParent).getDataChildByName(name); - } - } - - if (currentParent == null) { - throw new YangParseException(module.getName(), line, "Failed to find deviation target."); - } - if (currentParent instanceof SchemaNode) { - dev.setTargetPath(((SchemaNode) currentParent).getPath()); - } - - } else { - processDeviation(dev, dependentModuleBuilder, path, module); - } - } - } - - /** - * Correct deviation target path in deviation builder. - * - * @param dev - * deviation - * @param dependentModuleBuilder - * module containing deviation target - * @param path - * current deviation target path - * @param module - * current module - */ - private void processDeviation(final DeviationBuilder dev, final ModuleBuilder dependentModuleBuilder, - final List path, final ModuleBuilder module) { - final int line = dev.getLine(); - Builder currentParent = dependentModuleBuilder; - - for (int i = 0; i < path.size(); i++) { - if (currentParent == null) { - throw new YangParseException(module.getName(), line, "Failed to find deviation target."); - } - QName q = path.get(i); - String name = q.getLocalName(); - if (currentParent instanceof DataNodeContainerBuilder) { - currentParent = ((DataNodeContainerBuilder) currentParent).getDataChildByName(name); - } - } - - if (currentParent == null || !(currentParent instanceof SchemaNodeBuilder)) { - throw new YangParseException(module.getName(), line, "Failed to find deviation target."); - } - dev.setTargetPath(((SchemaNodeBuilder) currentParent).getPath()); - } - -} +/* + * 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 static org.opendaylight.yangtools.yang.parser.util.ParserUtils.*; +import static org.opendaylight.yangtools.yang.parser.util.TypeUtils.*; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; + +import org.antlr.v4.runtime.ANTLRInputStream; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.tree.ParseTree; +import org.antlr.v4.runtime.tree.ParseTreeWalker; +import org.opendaylight.yangtools.antlrv4.code.gen.YangLexer; +import org.opendaylight.yangtools.antlrv4.code.gen.YangParser; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; +import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; +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.YangModelParser; +import org.opendaylight.yangtools.yang.model.util.IdentityrefType; +import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder; +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.GroupingBuilder; +import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder; +import org.opendaylight.yangtools.yang.parser.builder.api.TypeAwareBuilder; +import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder; +import org.opendaylight.yangtools.yang.parser.builder.impl.DeviationBuilder; +import org.opendaylight.yangtools.yang.parser.builder.impl.ExtensionBuilder; +import org.opendaylight.yangtools.yang.parser.builder.impl.IdentitySchemaNodeBuilder; +import org.opendaylight.yangtools.yang.parser.builder.impl.IdentityrefTypeBuilder; +import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder; +import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder; +import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilder; +import org.opendaylight.yangtools.yang.parser.util.GroupingUtils; +import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort; +import org.opendaylight.yangtools.yang.parser.util.ParserUtils; +import org.opendaylight.yangtools.yang.parser.util.YangParseException; +import org.opendaylight.yangtools.yang.validator.YangModelBasicValidator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +public final class YangParserImpl implements YangModelParser { + private static final Logger LOG = LoggerFactory.getLogger(YangParserImpl.class); + + @Override + public Set parseYangModels(final List yangFiles) { + return Sets.newLinkedHashSet(parseYangModelsMapped(yangFiles).values()); + } + + @Override + public Set parseYangModels(final List yangFiles, final SchemaContext context) { + if (yangFiles != null) { + final Map inputStreams = Maps.newHashMap(); + + for (final File yangFile : yangFiles) { + try { + inputStreams.put(new FileInputStream(yangFile), yangFile); + } catch (FileNotFoundException e) { + LOG.warn("Exception while reading yang file: " + yangFile.getName(), e); + } + } + + Map builderToStreamMap = Maps.newHashMap(); + + final Map> modules = resolveModuleBuilders( + Lists.newArrayList(inputStreams.keySet()), builderToStreamMap); + + for (InputStream is : inputStreams.keySet()) { + try { + is.close(); + } catch (IOException e) { + LOG.debug("Failed to close stream."); + } + } + + return new LinkedHashSet(buildWithContext(modules, context).values()); + } + return Collections.emptySet(); + } + + @Override + public Set parseYangModelsFromStreams(final List yangModelStreams) { + return Sets.newHashSet(parseYangModelsFromStreamsMapped(yangModelStreams).values()); + } + + @Override + public Set parseYangModelsFromStreams(final List yangModelStreams, SchemaContext context) { + if (yangModelStreams != null) { + Map builderToStreamMap = Maps.newHashMap(); + final Map> modules = resolveModuleBuildersWithContext( + yangModelStreams, builderToStreamMap, context); + return new LinkedHashSet(buildWithContext(modules, context).values()); + } + return Collections.emptySet(); + } + + @Override + public Map parseYangModelsMapped(List yangFiles) { + if (yangFiles != null) { + final Map inputStreams = Maps.newHashMap(); + + for (final File yangFile : yangFiles) { + try { + inputStreams.put(new FileInputStream(yangFile), yangFile); + } catch (FileNotFoundException e) { + LOG.warn("Exception while reading yang file: " + yangFile.getName(), e); + } + } + + Map builderToStreamMap = Maps.newHashMap(); + final Map> modules = resolveModuleBuilders( + Lists.newArrayList(inputStreams.keySet()), builderToStreamMap); + + for (InputStream is : inputStreams.keySet()) { + try { + is.close(); + } catch (IOException e) { + LOG.debug("Failed to close stream."); + } + } + + Map retVal = Maps.newLinkedHashMap(); + Map builderToModuleMap = build(modules); + + for (Entry builderToModule : builderToModuleMap.entrySet()) { + retVal.put(inputStreams.get(builderToStreamMap.get(builderToModule.getKey())), + builderToModule.getValue()); + } + + return retVal; + } + return Collections.emptyMap(); + } + + @Override + public Map parseYangModelsFromStreamsMapped(final List yangModelStreams) { + Map builderToStreamMap = Maps.newHashMap(); + + final Map> modules = resolveModuleBuilders(yangModelStreams, + builderToStreamMap); + Map retVal = Maps.newLinkedHashMap(); + Map builderToModuleMap = build(modules); + + for (Entry builderToModule : builderToModuleMap.entrySet()) { + retVal.put(builderToStreamMap.get(builderToModule.getKey()), builderToModule.getValue()); + } + return retVal; + } + + @Override + public SchemaContext resolveSchemaContext(final Set modules) { + return new SchemaContextImpl(modules); + } + + private ModuleBuilder[] parseModuleBuilders(List inputStreams, + Map streamToBuilderMap) { + + final ParseTreeWalker walker = new ParseTreeWalker(); + final List trees = parseStreams(inputStreams); + final ModuleBuilder[] builders = new ModuleBuilder[trees.size()]; + + // validate yang + new YangModelBasicValidator(walker).validate(trees); + + YangParserListenerImpl yangModelParser = null; + for (int i = 0; i < trees.size(); i++) { + yangModelParser = new YangParserListenerImpl(); + walker.walk(yangModelParser, trees.get(i)); + ModuleBuilder moduleBuilder = yangModelParser.getModuleBuilder(); + + // We expect the order of trees and streams has to be the same + streamToBuilderMap.put(moduleBuilder, inputStreams.get(i)); + builders[i] = moduleBuilder; + } + return builders; + } + + private Map> resolveModuleBuilders(final List yangFileStreams, + Map streamToBuilderMap) { + return resolveModuleBuildersWithContext(yangFileStreams, streamToBuilderMap, null); + } + + private Map> resolveModuleBuildersWithContext( + final List yangFileStreams, final Map streamToBuilderMap, + final SchemaContext context) { + final ModuleBuilder[] builders = parseModuleBuilders(yangFileStreams, streamToBuilderMap); + + // LinkedHashMap must be used to preserve order + final LinkedHashMap> modules = new LinkedHashMap>(); + + // module dependency graph sorted + List sorted = null; + if (context == null) { + sorted = ModuleDependencySort.sort(builders); + } else { + sorted = ModuleDependencySort.sortWithContext(context, builders); + } + + for (final ModuleBuilder builder : sorted) { + if (builder == null) { + continue; + } + final String builderName = builder.getName(); + Date builderRevision = builder.getRevision(); + if (builderRevision == null) { + builderRevision = new Date(0L); + } + TreeMap builderByRevision = modules.get(builderName); + if (builderByRevision == null) { + builderByRevision = new TreeMap(); + } + builderByRevision.put(builderRevision, builder); + modules.put(builderName, builderByRevision); + } + return modules; + } + + private List parseStreams(final List yangStreams) { + final List trees = new ArrayList(); + for (InputStream yangStream : yangStreams) { + trees.add(parseStream(yangStream)); + } + return trees; + } + + private ParseTree parseStream(final InputStream yangStream) { + ParseTree result = null; + try { + final ANTLRInputStream input = new ANTLRInputStream(yangStream); + final YangLexer lexer = new YangLexer(input); + final CommonTokenStream tokens = new CommonTokenStream(lexer); + final YangParser parser = new YangParser(tokens); + parser.removeErrorListeners(); + parser.addErrorListener(new YangErrorListener()); + + result = parser.yang(); + } catch (IOException e) { + LOG.warn("Exception while reading yang file: " + yangStream, e); + } + return result; + } + + private Map build(final Map> modules) { + // fix unresolved nodes + findUsesTargets(modules, null); + resolveDirtyNodes(modules); + resolveAugments(modules); + resolveUses(modules); + resolveDeviations(modules); + + // build + final Map result = new LinkedHashMap(); + for (Map.Entry> entry : modules.entrySet()) { + final Map modulesByRevision = new HashMap(); + for (Map.Entry childEntry : entry.getValue().entrySet()) { + final ModuleBuilder moduleBuilder = childEntry.getValue(); + final Module module = moduleBuilder.build(); + modulesByRevision.put(childEntry.getKey(), module); + result.put(moduleBuilder, module); + } + } + return result; + } + + private Map buildWithContext(final Map> modules, + final SchemaContext context) { + // fix unresolved nodes + findUsesTargets(modules, context); + resolvedDirtyNodesWithContext(modules, context); + resolveAugmentsWithContext(modules, context); + resolveUsesWithContext(modules, context); + resolveDeviationsWithContext(modules, context); + + // build + final Map result = new LinkedHashMap(); + for (Map.Entry> entry : modules.entrySet()) { + final Map modulesByRevision = new HashMap(); + for (Map.Entry childEntry : entry.getValue().entrySet()) { + final ModuleBuilder moduleBuilder = childEntry.getValue(); + final Module module = moduleBuilder.build(); + modulesByRevision.put(childEntry.getKey(), module); + result.put(moduleBuilder, module); + } + } + return result; + } + + private void resolveDirtyNodes(final Map> modules) { + for (Map.Entry> entry : modules.entrySet()) { + for (Map.Entry childEntry : entry.getValue().entrySet()) { + final ModuleBuilder module = childEntry.getValue(); + resolveDirtyNodes(modules, module); + resolveIdentities(modules, module); + resolveUnknownNodes(modules, module); + } + } + } + + private void resolvedDirtyNodesWithContext(final Map> modules, + final SchemaContext context) { + for (Map.Entry> entry : modules.entrySet()) { + for (Map.Entry childEntry : entry.getValue().entrySet()) { + final ModuleBuilder module = childEntry.getValue(); + resolveDirtyNodesWithContext(modules, module, context); + resolveIdentitiesWithContext(modules, module, context); + resolveUnknownNodesWithContext(modules, module, context); + } + } + } + + /** + * Search for dirty nodes (node which contains UnknownType) and resolve + * unknown types. + * + * @param modules + * all available modules + * @param module + * current module + */ + private void resolveDirtyNodes(final Map> modules, final ModuleBuilder module) { + final Set dirtyNodes = module.getDirtyNodes(); + if (!dirtyNodes.isEmpty()) { + for (TypeAwareBuilder nodeToResolve : dirtyNodes) { + if (nodeToResolve instanceof UnionTypeBuilder) { + // special handling for union types + resolveTypeUnion((UnionTypeBuilder) nodeToResolve, modules, module); + } else if (nodeToResolve.getTypedef() instanceof IdentityrefTypeBuilder) { + // special handling for identityref types + IdentityrefTypeBuilder idref = (IdentityrefTypeBuilder) nodeToResolve.getTypedef(); + nodeToResolve.setType(new IdentityrefType(findFullQName(modules, module, idref), idref.getPath())); + } else { + resolveType(nodeToResolve, modules, module); + } + } + } + } + + private void resolveDirtyNodesWithContext(final Map> modules, + final ModuleBuilder module, SchemaContext context) { + final Set 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(); + nodeToResolve.setType(new IdentityrefType(findFullQName(modules, module, idref), idref.getPath())); + } else { + resolveTypeWithContext(nodeToResolve, modules, module, context); + } + } + } + } + + /** + * Go through all augment definitions and perform augmentation. It is + * expected that modules are already sorted by their dependencies. + * + * @param modules + * all loaded modules + */ + private void resolveAugments(final Map> modules) { + // collect augments from all loaded modules + final List allAugments = new ArrayList<>(); + for (Map.Entry> entry : modules.entrySet()) { + for (Map.Entry inner : entry.getValue().entrySet()) { + allAugments.addAll(inner.getValue().getAllAugments()); + } + } + + for (int i = 0; i < allAugments.size(); i++) { + // pick one augment + final AugmentationSchemaBuilder augment = allAugments.get(i); + // create collection of others + List others = new ArrayList<>(allAugments); + others.remove(augment); + + // try to resolve it + boolean resolved = resolveAugment(modules, augment); + // while not resolved + int j = 0; + while (!(resolved) && j < others.size()) { + // try to resolve next augment + resolveAugment(modules, others.get(j)); + // then try to resolve first again + resolved = resolveAugment(modules, augment); + j++; + + } + + if (!resolved) { + throw new YangParseException(augment.getModuleName(), augment.getLine(), + "Error in augment parsing: failed to find augment target"); + } + } + } + + /** + * Search for augment target and perform augmentation. + * + * @param modules + * all loaded modules + * @param augmentBuilder + * augment to resolve + * @return true if target node found, false otherwise + */ + private boolean resolveAugment(final Map> modules, + final AugmentationSchemaBuilder augmentBuilder) { + if (augmentBuilder.isResolved()) { + return true; + } + + int line = augmentBuilder.getLine(); + ModuleBuilder module = getParentModule(augmentBuilder); + List path = augmentBuilder.getTargetPath().getPath(); + Builder augmentParent = augmentBuilder.getParent(); + + Builder firstNodeParent = null; + if (augmentParent instanceof ModuleBuilder) { + // if augment is defined under module, parent of first node is + // target module + final QName firstNameInPath = path.get(0); + String prefix = firstNameInPath.getPrefix(); + if (prefix == null) { + prefix = module.getPrefix(); + } + firstNodeParent = findDependentModuleBuilder(modules, module, prefix, line); + } else if (augmentParent instanceof UsesNodeBuilder) { + firstNodeParent = augmentParent.getParent(); + } else { + // augment can be defined only under module or uses + throw new YangParseException(augmentBuilder.getModuleName(), line, + "Failed to parse augment: Unresolved parent of augment: " + augmentParent); + } + + return processAugmentation(augmentBuilder, firstNodeParent, path); + } + + /** + * Go through all augment definitions and resolve them. This method works in + * same way as {@link #resolveAugments(Map)} except that if target node is + * not found in loaded modules, it search for target node in given context. + * + * @param modules + * all loaded modules + * @param context + * SchemaContext containing already resolved modules + */ + private void resolveAugmentsWithContext(final Map> modules, + final SchemaContext context) { + // collect augments from all loaded modules + final List allAugments = new ArrayList<>(); + for (Map.Entry> entry : modules.entrySet()) { + for (Map.Entry inner : entry.getValue().entrySet()) { + allAugments.addAll(inner.getValue().getAllAugments()); + } + } + + for (int i = 0; i < allAugments.size(); i++) { + // pick augment from list + final AugmentationSchemaBuilder augment = allAugments.get(i); + // try to resolve it + boolean resolved = resolveAugmentWithContext(modules, augment, context); + // while not resolved + int j = i + 1; + while (!(resolved) && j < allAugments.size()) { + // try to resolve next augment + resolveAugmentWithContext(modules, allAugments.get(j), context); + // then try to resolve first again + resolved = resolveAugmentWithContext(modules, augment, context); + j++; + } + + if (!resolved) { + throw new YangParseException(augment.getModuleName(), augment.getLine(), + "Error in augment parsing: failed to find augment target"); + } + } + } + + /** + * Search for augment target and perform augmentation. + * + * @param modules + * all loaded modules + * @param augment + * augment to resolve + * @param context + * SchemaContext containing already resolved modules + * @return true if target node found, false otherwise + */ + private boolean resolveAugmentWithContext(final Map> modules, + final AugmentationSchemaBuilder augment, final SchemaContext context) { + if (augment.isResolved()) { + return true; + } + int line = augment.getLine(); + ModuleBuilder module = getParentModule(augment); + List path = augment.getTargetPath().getPath(); + final QName firstNameInPath = path.get(0); + String prefix = firstNameInPath.getPrefix(); + if (prefix == null) { + prefix = module.getPrefix(); + } + Builder augmentParent = augment.getParent(); + Builder currentParent = null; + + if (augmentParent instanceof ModuleBuilder) { + // if augment is defined under module, first parent is target module + currentParent = findDependentModuleBuilder(modules, module, prefix, line); + } else if (augmentParent instanceof UsesNodeBuilder) { + currentParent = augmentParent.getParent(); + } else { + // augment can be defined only under module or uses + throw new YangParseException(augment.getModuleName(), augment.getLine(), + "Error in augment parsing: Unresolved parent of augment: " + augmentParent); + } + + if (currentParent == null) { + return processAugmentationOnContext(augment, path, module, prefix, context); + } else { + return processAugmentation(augment, currentParent, path); + } + } + + /** + * Go through identity statements defined in current module and resolve + * their 'base' statement if present. + * + * @param modules + * all modules + * @param module + * module being resolved + */ + private void resolveIdentities(final Map> modules, final ModuleBuilder module) { + final Set identities = module.getIdentities(); + for (IdentitySchemaNodeBuilder identity : identities) { + final String baseIdentityName = identity.getBaseIdentityName(); + if (baseIdentityName != null) { + String baseIdentityPrefix = null; + String baseIdentityLocalName = null; + if (baseIdentityName.contains(":")) { + final String[] splitted = baseIdentityName.split(":"); + baseIdentityPrefix = splitted[0]; + baseIdentityLocalName = splitted[1]; + } else { + baseIdentityPrefix = module.getPrefix(); + baseIdentityLocalName = baseIdentityName; + } + final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, baseIdentityPrefix, + identity.getLine()); + + final Set dependentModuleIdentities = dependentModule.getIdentities(); + for (IdentitySchemaNodeBuilder idBuilder : dependentModuleIdentities) { + if (idBuilder.getQName().getLocalName().equals(baseIdentityLocalName)) { + identity.setBaseIdentity(idBuilder); + } + } + } + } + } + + /** + * 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> modules, + final ModuleBuilder module, final SchemaContext context) { + final Set identities = module.getIdentities(); + for (IdentitySchemaNodeBuilder identity : identities) { + final String baseIdentityName = identity.getBaseIdentityName(); + if (baseIdentityName != null) { + String baseIdentityPrefix = null; + String baseIdentityLocalName = null; + if (baseIdentityName.contains(":")) { + final String[] splitted = baseIdentityName.split(":"); + baseIdentityPrefix = splitted[0]; + baseIdentityLocalName = splitted[1]; + } else { + baseIdentityPrefix = module.getPrefix(); + baseIdentityLocalName = baseIdentityName; + } + final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, module, + baseIdentityPrefix, identity.getLine()); + + if (dependentModuleBuilder == null) { + final Module dependentModule = findModuleFromContext(context, module, baseIdentityPrefix, + identity.getLine()); + final Set dependentModuleIdentities = dependentModule.getIdentities(); + for (IdentitySchemaNode idNode : dependentModuleIdentities) { + if (idNode.getQName().getLocalName().equals(baseIdentityLocalName)) { + identity.setBaseIdentity(idNode); + } + } + } else { + final Set dependentModuleIdentities = dependentModuleBuilder + .getIdentities(); + for (IdentitySchemaNodeBuilder idBuilder : dependentModuleIdentities) { + if (idBuilder.getQName().getLocalName().equals(baseIdentityLocalName)) { + identity.setBaseIdentity(idBuilder); + } + } + } + } + } + } + + /** + * Find and add reference of uses target grouping. + * + * @param modules + * all loaded modules + * @param context + * SchemaContext containing already resolved modules or null if + * context is not available + */ + private void findUsesTargets(final Map> modules, final SchemaContext context) { + final List allUses = new ArrayList<>(); + for (Map.Entry> entry : modules.entrySet()) { + for (Map.Entry inner : entry.getValue().entrySet()) { + allUses.addAll(inner.getValue().getAllUsesNodes()); + } + } + for (UsesNodeBuilder usesNode : allUses) { + ModuleBuilder module = ParserUtils.getParentModule(usesNode); + 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); + } + } + } + + /** + * Copy data from uses target, update uses parent and perform refinement. + * Augmentations have to be resolved already. + * + * @param modules + * all loaded modules + */ + private void resolveUses(final Map> modules) { + for (Map.Entry> entry : modules.entrySet()) { + for (Map.Entry inner : entry.getValue().entrySet()) { + ModuleBuilder module = inner.getValue(); + List usesNodes = null; + boolean dataCollected = module.isAllUsesDataCollected(); + + while (!dataCollected) { + usesNodes = new ArrayList<>(module.getAllUsesNodes()); + for (UsesNodeBuilder usesNode : usesNodes) { + if (!usesNode.isDataCollected()) { + GroupingUtils.collectUsesData(usesNode); + } + } + dataCollected = module.isAllUsesDataCollected(); + } + } + } + + // new loop is must because in collecting data process new uses could + // be created + final List allModulesUses = new ArrayList<>(); + for (Map.Entry> entry : modules.entrySet()) { + for (Map.Entry inner : entry.getValue().entrySet()) { + allModulesUses.addAll(inner.getValue().getAllUsesNodes()); + } + } + + for (UsesNodeBuilder usesNode : allModulesUses) { + GroupingUtils.updateUsesParent(usesNode); + GroupingUtils.performRefine(usesNode); + } + for (UsesNodeBuilder usesNode : allModulesUses) { + GroupingUtils.fixUsesNodesPath(usesNode); + } + + for (UsesNodeBuilder usesNode : allModulesUses) { + if (usesNode.isCopy()) { + usesNode.getParent().getUsesNodes().remove(usesNode); + } + } + } + + /** + * Copy data from uses target, update uses parent and perform refinement. + * Augmentations have to be resolved already. + * + * @param modules + * all loaded modules + * @param context + * SchemaContext containing already resolved modules + */ + private void resolveUsesWithContext(final Map> modules, + final SchemaContext context) { + for (Map.Entry> entry : modules.entrySet()) { + for (Map.Entry inner : entry.getValue().entrySet()) { + ModuleBuilder module = inner.getValue(); + List usesNodes = null; + boolean dataCollected = module.isAllUsesDataCollected(); + + while (!dataCollected) { + usesNodes = new ArrayList<>(module.getAllUsesNodes()); + for (UsesNodeBuilder usesNode : usesNodes) { + if (!usesNode.isDataCollected()) { + if (usesNode.getGroupingBuilder() == null) { + GroupingUtils.collectUsesDataFromContext(usesNode); + } else { + GroupingUtils.collectUsesData(usesNode); + } + } + } + dataCollected = module.isAllUsesDataCollected(); + } + } + } + + // new loop is must because in collecting data process new uses could + // be created + final List allModulesUses = new ArrayList<>(); + for (Map.Entry> entry : modules.entrySet()) { + for (Map.Entry inner : entry.getValue().entrySet()) { + allModulesUses.addAll(inner.getValue().getAllUsesNodes()); + } + } + + for (UsesNodeBuilder usesNode : allModulesUses) { + GroupingUtils.updateUsesParent(usesNode); + GroupingUtils.performRefine(usesNode); + } + for (UsesNodeBuilder usesNode : allModulesUses) { + GroupingUtils.fixUsesNodesPath(usesNode); + } + } + + private void resolveUnknownNodes(final Map> modules, final ModuleBuilder module) { + for (UnknownSchemaNodeBuilder usnb : module.getAllUnknownNodes()) { + QName nodeType = usnb.getNodeType(); + try { + ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, nodeType.getPrefix(), + usnb.getLine()); + for (ExtensionBuilder extension : dependentModule.getExtensions()) { + if (extension.getQName().getLocalName().equals(nodeType.getLocalName())) { + usnb.setNodeType(extension.getQName()); + usnb.setExtensionBuilder(extension); + break; + } + } + } catch (YangParseException e) { + throw new YangParseException(module.getName(), usnb.getLine(), "Failed to resolve node " + usnb + + ": no such extension definition found."); + } + } + } + + private void resolveUnknownNodesWithContext(final Map> modules, + final ModuleBuilder module, final SchemaContext context) { + for (UnknownSchemaNodeBuilder usnb : module.getAllUnknownNodes()) { + QName nodeType = usnb.getNodeType(); + try { + ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(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.getExtensions()) { + 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."); + } + + } + } + + /** + * Traverse through modules and resolve their deviation statements. + * + * @param modules + * all loaded modules + */ + private void resolveDeviations(final Map> modules) { + for (Map.Entry> entry : modules.entrySet()) { + for (Map.Entry inner : entry.getValue().entrySet()) { + ModuleBuilder b = inner.getValue(); + resolveDeviation(modules, b); + } + } + } + + /** + * Traverse through module and resolve its deviation statements. + * + * @param modules + * all loaded modules + * @param module + * module in which resolve deviations + */ + private void resolveDeviation(final Map> modules, final ModuleBuilder module) { + for (DeviationBuilder dev : module.getDeviations()) { + int line = dev.getLine(); + SchemaPath targetPath = dev.getTargetPath(); + List path = targetPath.getPath(); + QName q0 = path.get(0); + String prefix = q0.getPrefix(); + if (prefix == null) { + prefix = module.getPrefix(); + } + + ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, module, prefix, line); + 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> modules, + final SchemaContext context) { + for (Map.Entry> entry : modules.entrySet()) { + for (Map.Entry 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> modules, + final ModuleBuilder module, final SchemaContext context) { + for (DeviationBuilder dev : module.getDeviations()) { + int line = dev.getLine(); + SchemaPath targetPath = dev.getTargetPath(); + List path = targetPath.getPath(); + QName q0 = path.get(0); + String prefix = q0.getPrefix(); + if (prefix == null) { + prefix = module.getPrefix(); + } + String name = null; + + ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, module, prefix, line); + if (dependentModuleBuilder == null) { + Module dependentModule = findModuleFromContext(context, module, prefix, line); + Object currentParent = dependentModule; + + for (int i = 0; i < path.size(); i++) { + if (currentParent == null) { + throw new YangParseException(module.getName(), line, "Failed to find deviation target."); + } + QName q = path.get(i); + name = q.getLocalName(); + if (currentParent instanceof DataNodeContainer) { + currentParent = ((DataNodeContainer) currentParent).getDataChildByName(name); + } + } + + if (currentParent == null) { + throw new YangParseException(module.getName(), line, "Failed to find deviation target."); + } + if (currentParent instanceof SchemaNode) { + dev.setTargetPath(((SchemaNode) currentParent).getPath()); + } + + } else { + processDeviation(dev, dependentModuleBuilder, path, module); + } + } + } + + /** + * Correct deviation target path in deviation builder. + * + * @param dev + * deviation + * @param dependentModuleBuilder + * module containing deviation target + * @param path + * current deviation target path + * @param module + * current module + */ + private void processDeviation(final DeviationBuilder dev, final ModuleBuilder dependentModuleBuilder, + final List path, final ModuleBuilder module) { + final int line = dev.getLine(); + Builder currentParent = dependentModuleBuilder; + + for (int i = 0; i < path.size(); i++) { + if (currentParent == null) { + throw new YangParseException(module.getName(), line, "Failed to find deviation target."); + } + QName q = path.get(i); + String name = q.getLocalName(); + if (currentParent instanceof DataNodeContainerBuilder) { + currentParent = ((DataNodeContainerBuilder) currentParent).getDataChildByName(name); + } + } + + if (currentParent == null || !(currentParent instanceof SchemaNodeBuilder)) { + throw new YangParseException(module.getName(), line, "Failed to find deviation target."); + } + dev.setTargetPath(((SchemaNodeBuilder) currentParent).getPath()); + } + +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ParserUtils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ParserUtils.java deleted file mode 100644 index f368e837ed..0000000000 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ParserUtils.java +++ /dev/null @@ -1,528 +0,0 @@ -/* - * 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.util; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; - -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.ChoiceNode; -import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; -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.SchemaContext; -import org.opendaylight.yangtools.yang.model.api.SchemaNode; -import org.opendaylight.yangtools.yang.model.api.SchemaPath; -import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder; -import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationTargetBuilder; -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; -import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder; -import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder; -import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder; -import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder; -import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder.ChoiceNodeImpl; -import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder; -import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder.ChoiceCaseNodeImpl; -import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder; -import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder.ContainerSchemaNodeImpl; -import org.opendaylight.yangtools.yang.parser.builder.impl.IdentityrefTypeBuilder; -import org.opendaylight.yangtools.yang.parser.builder.impl.ListSchemaNodeBuilder; -import org.opendaylight.yangtools.yang.parser.builder.impl.ListSchemaNodeBuilder.ListSchemaNodeImpl; -import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder; -import org.opendaylight.yangtools.yang.parser.builder.impl.NotificationBuilder; -import org.opendaylight.yangtools.yang.parser.builder.impl.NotificationBuilder.NotificationDefinitionImpl; - -public final class ParserUtils { - - private ParserUtils() { - } - - /** - * Create new SchemaPath from given path and qname. - * - * @param schemaPath - * @param qname - * @return - */ - public static SchemaPath createSchemaPath(SchemaPath schemaPath, QName... qname) { - List path = new ArrayList<>(schemaPath.getPath()); - path.addAll(Arrays.asList(qname)); - return new SchemaPath(path, schemaPath.isAbsolute()); - } - - /** - * Get module import referenced by given prefix. - * - * @param builder - * module to search - * @param prefix - * prefix associated with import - * @return ModuleImport based on given prefix - */ - public static ModuleImport getModuleImport(final ModuleBuilder builder, final String prefix) { - ModuleImport moduleImport = null; - for (ModuleImport mi : builder.getModuleImports()) { - if (mi.getPrefix().equals(prefix)) { - moduleImport = mi; - break; - } - } - return moduleImport; - } - - /** - * Find dependent module based on given prefix - * - * @param modules - * all available modules - * @param module - * current module - * @param prefix - * target module prefix - * @param line - * current line in yang model - * @return module builder if found, null otherwise - */ - public static ModuleBuilder findDependentModuleBuilder(final Map> modules, - final ModuleBuilder module, final String prefix, final int line) { - ModuleBuilder dependentModule = null; - Date dependentModuleRevision = null; - - if (prefix.equals(module.getPrefix())) { - dependentModule = module; - } else { - final ModuleImport dependentModuleImport = getModuleImport(module, prefix); - if (dependentModuleImport == null) { - throw new YangParseException(module.getName(), line, "No import found with prefix '" + prefix + "'."); - } - final String dependentModuleName = dependentModuleImport.getModuleName(); - dependentModuleRevision = dependentModuleImport.getRevision(); - - final TreeMap moduleBuildersByRevision = modules.get(dependentModuleName); - if (moduleBuildersByRevision == null) { - return null; - } - if (dependentModuleRevision == null) { - dependentModule = moduleBuildersByRevision.lastEntry().getValue(); - } else { - dependentModule = moduleBuildersByRevision.get(dependentModuleRevision); - } - } - return dependentModule; - } - - /** - * Find module from context based on prefix. - * - * @param context - * schema context - * @param currentModule - * current module - * @param prefix - * current 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 - */ - public static Module findModuleFromContext(final SchemaContext context, final ModuleBuilder currentModule, - final String prefix, final int line) { - TreeMap modulesByRevision = new TreeMap(); - - final ModuleImport dependentModuleImport = ParserUtils.getModuleImport(currentModule, prefix); - if (dependentModuleImport == null) { - throw new YangParseException(currentModule.getName(), line, "No import found with prefix '" + prefix + "'."); - } - final String dependentModuleName = dependentModuleImport.getModuleName(); - final Date dependentModuleRevision = dependentModuleImport.getRevision(); - - for (Module contextModule : context.getModules()) { - if (contextModule.getName().equals(dependentModuleName)) { - Date revision = contextModule.getRevision(); - if (revision == null) { - revision = new Date(0L); - } - modulesByRevision.put(revision, contextModule); - break; - } - } - - Module result = null; - if (dependentModuleRevision == null) { - result = modulesByRevision.get(modulesByRevision.firstKey()); - } else { - result = modulesByRevision.get(dependentModuleRevision); - } - - return result; - } - - /** - * Parse XPath string. - * - * @param xpathString - * as String - * @return SchemaPath from given String - */ - public static SchemaPath parseXPathString(final String xpathString) { - final boolean absolute = xpathString.startsWith("/"); - final String[] splittedPath = xpathString.split("/"); - final List path = new ArrayList(); - QName name; - for (String pathElement : splittedPath) { - if (pathElement.length() > 0) { - final String[] splittedElement = pathElement.split(":"); - if (splittedElement.length == 1) { - name = new QName(null, null, null, splittedElement[0]); - } else { - name = new QName(null, null, splittedElement[0], splittedElement[1]); - } - path.add(name); - } - } - return new SchemaPath(path, absolute); - } - - /** - * Add all augment's child nodes to given target. - * - * @param augment - * builder of augment statement - * @param target - * augmentation target node - */ - public static void fillAugmentTarget(final AugmentationSchemaBuilder augment, final DataNodeContainerBuilder target) { - for (DataSchemaNodeBuilder child : augment.getChildNodeBuilders()) { - DataSchemaNodeBuilder childCopy = CopyUtils.copy(child, target, false); - childCopy.setAugmenting(true); - correctNodePath(child, target.getPath()); - correctNodePath(childCopy, target.getPath()); - try { - target.addChildNode(childCopy); - } catch (YangParseException e) { - // more descriptive message - throw new YangParseException(augment.getModuleName(), augment.getLine(), - "Failed to perform augmentation: " + e.getMessage()); - } - - } - for (UsesNodeBuilder usesNode : augment.getUsesNodes()) { - UsesNodeBuilder copy = CopyUtils.copyUses(usesNode, target); - target.addUsesNode(copy); - } - } - - /** - * Add all augment's child nodes to given target. - * - * @param augment - * builder of augment statement - * @param target - * augmentation target choice node - */ - public static void fillAugmentTarget(final AugmentationSchemaBuilder augment, final ChoiceBuilder target) { - for (DataSchemaNodeBuilder builder : augment.getChildNodeBuilders()) { - DataSchemaNodeBuilder childCopy = CopyUtils.copy(builder, target, false); - childCopy.setAugmenting(true); - correctNodePath(builder, target.getPath()); - correctNodePath(childCopy, target.getPath()); - target.addCase(childCopy); - } - for (UsesNodeBuilder usesNode : augment.getUsesNodes()) { - if (usesNode != null) { - throw new YangParseException(augment.getModuleName(), augment.getLine(), - "Error in augment parsing: cannot augment uses to choice"); - } - } - } - - /** - * Create new schema path of node based on parent node schema path. - * - * @param node - * node to correct - * @param parentSchemaPath - * schema path of node parent - */ - static void correctNodePath(final SchemaNodeBuilder node, final SchemaPath parentSchemaPath) { - // set correct path - List targetNodePath = new ArrayList(parentSchemaPath.getPath()); - targetNodePath.add(node.getQName()); - node.setPath(new SchemaPath(targetNodePath, true)); - - // set correct path for all child nodes - if (node instanceof DataNodeContainerBuilder) { - DataNodeContainerBuilder dataNodeContainer = (DataNodeContainerBuilder) node; - for (DataSchemaNodeBuilder child : dataNodeContainer.getChildNodeBuilders()) { - correctNodePath(child, node.getPath()); - } - } - - // set correct path for all cases - if (node instanceof ChoiceBuilder) { - ChoiceBuilder choiceBuilder = (ChoiceBuilder) node; - for (ChoiceCaseBuilder choiceCaseBuilder : choiceBuilder.getCases()) { - correctNodePath(choiceCaseBuilder, node.getPath()); - } - } - } - - /** - * Find augment target node and perform augmentation. - * - * @param augment - * @param firstNodeParent - * parent of first node in path - * @param path - * path to augment target - * @return true if augmentation process succeed, false otherwise - */ - public static boolean processAugmentation(final AugmentationSchemaBuilder augment, final Builder firstNodeParent, - final List path) { - // traverse augment target path and try to reach target node - String currentName = null; - Builder currentParent = firstNodeParent; - - for (int i = 0; i < path.size(); i++) { - QName qname = path.get(i); - - currentName = qname.getLocalName(); - if (currentParent instanceof DataNodeContainerBuilder) { - DataSchemaNodeBuilder nodeFound = ((DataNodeContainerBuilder) currentParent) - .getDataChildByName(currentName); - // if not found as regular child, search in uses - if (nodeFound == null) { - boolean found = false; - for (UsesNodeBuilder unb : ((DataNodeContainerBuilder) currentParent).getUsesNodes()) { - DataSchemaNodeBuilder result = findNodeInUses(currentName, unb); - if (result != null) { - currentParent = result; - found = true; - break; - } - } - // if not found even in uses nodes, return false - if (!found) { - return false; - } - } else { - currentParent = nodeFound; - } - } else if (currentParent instanceof ChoiceBuilder) { - currentParent = ((ChoiceBuilder) currentParent).getCaseNodeByName(currentName); - } else { - throw new YangParseException(augment.getModuleName(), augment.getLine(), - "Error in augment parsing: failed to find node " + currentName); - } - - // if node in path not found, return false - if (currentParent == null) { - return false; - } - } - if (!(currentParent instanceof DataSchemaNodeBuilder)) { - throw new YangParseException( - augment.getModuleName(), - augment.getLine(), - "Error in augment parsing: The target node MUST be either a container, list, choice, case, input, output, or notification node."); - } - - if (currentParent instanceof ChoiceBuilder) { - fillAugmentTarget(augment, (ChoiceBuilder) currentParent); - } else { - fillAugmentTarget(augment, (DataNodeContainerBuilder) currentParent); - } - ((AugmentationTargetBuilder) currentParent).addAugmentation(augment); - SchemaPath oldPath = ((DataSchemaNodeBuilder) currentParent).getPath(); - augment.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute())); - augment.setResolved(true); - - return true; - } - - /** - * Find node with given name in uses target. - * - * @param localName - * name of node to find - * @param uses - * uses node which target grouping should be searched - * @return node with given name if found, null otherwise - */ - private static DataSchemaNodeBuilder findNodeInUses(String localName, UsesNodeBuilder uses) { - GroupingBuilder target = uses.getGroupingBuilder(); - for (DataSchemaNodeBuilder child : target.getChildNodeBuilders()) { - if (child.getQName().getLocalName().equals(localName)) { - return child; - } - } - for (UsesNodeBuilder usesNode : target.getUsesNodes()) { - DataSchemaNodeBuilder result = findNodeInUses(localName, usesNode); - if (result != null) { - return result; - } - } - return null; - } - - /** - * Find augment target node in given context and perform augmentation. - * - * @param augment - * @param path - * path to augment target - * @param module - * current module - * @param prefix - * current prefix of target module - * @param context - * SchemaContext containing already resolved modules - * @return true if augment process succeed, false otherwise - */ - public static boolean processAugmentationOnContext(final AugmentationSchemaBuilder augment, final List path, - final ModuleBuilder module, final String prefix, final SchemaContext context) { - final int line = augment.getLine(); - final Module dependentModule = findModuleFromContext(context, module, prefix, line); - if (dependentModule == null) { - throw new YangParseException(module.getName(), line, - "Error in augment parsing: failed to find module with prefix " + prefix + "."); - } - - String currentName = path.get(0).getLocalName(); - SchemaNode currentParent = dependentModule.getDataChildByName(currentName); - if (currentParent == null) { - Set notifications = dependentModule.getNotifications(); - for (NotificationDefinition ntf : notifications) { - if (ntf.getQName().getLocalName().equals(currentName)) { - currentParent = ntf; - break; - } - } - } - if (currentParent == null) { - throw new YangParseException(module.getName(), line, "Error in augment parsing: failed to find node " - + currentName + "."); - } - - for (int i = 1; i < path.size(); i++) { - currentName = path.get(i).getLocalName(); - if (currentParent instanceof DataNodeContainer) { - currentParent = ((DataNodeContainer) currentParent).getDataChildByName(currentName); - } else if (currentParent instanceof ChoiceNode) { - currentParent = ((ChoiceNode) currentParent).getCaseNodeByName(currentName); - } else { - throw new YangParseException(augment.getModuleName(), line, - "Error in augment parsing: failed to find node " + currentName); - } - // if node in path not found, return false - if (currentParent == null) { - throw new YangParseException(module.getName(), line, "Error in augment parsing: failed to find node " - + currentName + "."); - } - } - - if (currentParent instanceof ContainerSchemaNodeImpl) { - // includes container, input and output statement - ContainerSchemaNodeImpl c = (ContainerSchemaNodeImpl) currentParent; - ContainerSchemaNodeBuilder cb = c.toBuilder(); - fillAugmentTarget(augment, cb); - ((AugmentationTargetBuilder) cb).addAugmentation(augment); - SchemaPath oldPath = cb.getPath(); - cb.rebuild(); - augment.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute())); - augment.setResolved(true); - } else if (currentParent instanceof ListSchemaNodeImpl) { - ListSchemaNodeImpl l = (ListSchemaNodeImpl) currentParent; - ListSchemaNodeBuilder lb = l.toBuilder(); - fillAugmentTarget(augment, lb); - ((AugmentationTargetBuilder) lb).addAugmentation(augment); - SchemaPath oldPath = lb.getPath(); - lb.rebuild(); - augment.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute())); - augment.setResolved(true); - } else if (currentParent instanceof ChoiceNodeImpl) { - ChoiceNodeImpl ch = (ChoiceNodeImpl) currentParent; - ChoiceBuilder chb = ch.toBuilder(); - fillAugmentTarget(augment, chb); - ((AugmentationTargetBuilder) chb).addAugmentation(augment); - SchemaPath oldPath = chb.getPath(); - chb.rebuild(); - augment.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute())); - augment.setResolved(true); - } else if (currentParent instanceof ChoiceCaseNodeImpl) { - ChoiceCaseNodeImpl chc = (ChoiceCaseNodeImpl) currentParent; - ChoiceCaseBuilder chcb = chc.toBuilder(); - fillAugmentTarget(augment, chcb); - ((AugmentationTargetBuilder) chcb).addAugmentation(augment); - SchemaPath oldPath = chcb.getPath(); - chcb.rebuild(); - augment.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute())); - augment.setResolved(true); - } else if (currentParent instanceof NotificationDefinitionImpl) { - NotificationDefinitionImpl nd = (NotificationDefinitionImpl) currentParent; - NotificationBuilder nb = nd.toBuilder(); - fillAugmentTarget(augment, nb); - ((AugmentationTargetBuilder) nb).addAugmentation(augment); - SchemaPath oldPath = nb.getPath(); - nb.rebuild(); - augment.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute())); - augment.setResolved(true); - } else { - throw new YangParseException(module.getName(), line, "Target of type " + currentParent.getClass() - + " cannot be augmented."); - } - - return true; - } - - public static QName findFullQName(final Map> modules, - final ModuleBuilder module, final IdentityrefTypeBuilder idref) { - QName result = null; - String baseString = idref.getBaseString(); - if (baseString.contains(":")) { - String[] splittedBase = baseString.split(":"); - if (splittedBase.length > 2) { - throw new YangParseException(module.getName(), idref.getLine(), "Failed to parse identityref base: " - + baseString); - } - String prefix = splittedBase[0]; - String name = splittedBase[1]; - ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, prefix, idref.getLine()); - result = new QName(dependentModule.getNamespace(), dependentModule.getRevision(), prefix, name); - } else { - result = new QName(module.getNamespace(), module.getRevision(), module.getPrefix(), baseString); - } - return result; - } - - /** - * Get module in which this node is defined. - * - * @param node - * @return builder of module where this node is defined - */ - public static ModuleBuilder getParentModule(Builder node) { - if (node instanceof ModuleBuilder) { - return (ModuleBuilder) node; - } - - Builder parent = node.getParent(); - while (!(parent instanceof ModuleBuilder)) { - parent = parent.getParent(); - } - return (ModuleBuilder) parent; - } - -} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ParserUtils.xtend b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ParserUtils.xtend new file mode 100644 index 0000000000..4bd5a24784 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ParserUtils.xtend @@ -0,0 +1,553 @@ +/* + * 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.util; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.ChoiceNode; +import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; +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.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder; +import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationTargetBuilder; +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; +import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder; +import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder; +import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder; +import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder.ChoiceNodeImpl; +import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder; +import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder.ChoiceCaseNodeImpl; +import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder.ContainerSchemaNodeImpl; +import org.opendaylight.yangtools.yang.parser.builder.impl.IdentityrefTypeBuilder; +import org.opendaylight.yangtools.yang.parser.builder.impl.ListSchemaNodeBuilder.ListSchemaNodeImpl; +import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder; +import org.opendaylight.yangtools.yang.parser.builder.impl.NotificationBuilder.NotificationDefinitionImpl; +import org.opendaylight.yangtools.yang.model.api.AugmentationTarget +import org.opendaylight.yangtools.yang.parser.builder.impl.RpcDefinitionBuilder + + +public final class ParserUtils { + + private new() { + } + + /** + * Create new SchemaPath from given path and qname. + * + * @param schemaPath + * @param qname + * @return + */ + public static def SchemaPath createSchemaPath(SchemaPath schemaPath, QName... qname) { + val path = new ArrayList(schemaPath.getPath()); + path.addAll(Arrays.asList(qname)); + return new SchemaPath(path, schemaPath.isAbsolute()); + } + + /** + * Get module import referenced by given prefix. + * + * @param builder + * module to search + * @param prefix + * prefix associated with import + * @return ModuleImport based on given prefix + */ + public static def ModuleImport getModuleImport(ModuleBuilder builder, String prefix) { + for (ModuleImport mi : builder.getModuleImports()) { + if (mi.getPrefix().equals(prefix)) { + return mi; + + } + } + return null; + } + + /** + * Find dependent module based on given prefix + * + * @param modules + * all available modules + * @param module + * current module + * @param prefix + * target module prefix + * @param line + * current line in yang model + * @return module builder if found, null otherwise + */ + public static def ModuleBuilder findDependentModuleBuilder(Map> modules, + ModuleBuilder module, String prefix, int line) { + var ModuleBuilder dependentModule = null; + var Date dependentModuleRevision = null; + + if (prefix.equals(module.getPrefix())) { + dependentModule = module; + } else { + val ModuleImport dependentModuleImport = getModuleImport(module, prefix); + if (dependentModuleImport === null) { + throw new YangParseException(module.getName(), line, "No import found with prefix '" + prefix + "'."); + } + val String dependentModuleName = dependentModuleImport.getModuleName(); + dependentModuleRevision = dependentModuleImport.getRevision(); + + val TreeMap moduleBuildersByRevision = modules.get(dependentModuleName); + if (moduleBuildersByRevision === null) { + return null; + } + if (dependentModuleRevision === null) { + dependentModule = moduleBuildersByRevision.lastEntry().getValue(); + } else { + dependentModule = moduleBuildersByRevision.get(dependentModuleRevision); + } + } + return dependentModule; + } + + /** + * Find module from context based on prefix. + * + * @param context + * schema context + * @param currentModule + * current module + * @param prefix + * current 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 + */ + public static def Module findModuleFromContext(SchemaContext context, ModuleBuilder currentModule, + String prefix, int line) { + val modulesByRevision = new TreeMap(); + + val dependentModuleImport = ParserUtils.getModuleImport(currentModule, prefix); + if (dependentModuleImport === null) { + throw new YangParseException(currentModule.getName(), line, "No import found with prefix '" + prefix + "'."); + } + val dependentModuleName = dependentModuleImport.getModuleName(); + val dependentModuleRevision = dependentModuleImport.getRevision(); + + for (Module contextModule : context.getModules()) { + if (contextModule.getName().equals(dependentModuleName)) { + var revision = contextModule.getRevision(); + if (revision === null) { + revision = new Date(0L); + } + modulesByRevision.put(revision, contextModule); + } + } + + var Module result = null; + if (dependentModuleRevision === null) { + result = modulesByRevision.get(modulesByRevision.firstKey()); + } else { + result = modulesByRevision.get(dependentModuleRevision); + } + return result; + } + + /** + * Parse XPath string. + * + * @param xpathString + * as String + * @return SchemaPath from given String + */ + public static def SchemaPath parseXPathString(String xpathString) { + val absolute = xpathString.startsWith("/"); + val String[] splittedPath = xpathString.split("/"); + val path = new ArrayList(); + var QName name; + for (String pathElement : splittedPath) { + if (pathElement.length() > 0) { + val String[] splittedElement = pathElement.split(":"); + if (splittedElement.length == 1) { + name = new QName(null, null, null, splittedElement.get(0)); + } else { + name = new QName(null, null, splittedElement.get(0), splittedElement.get(1)); + } + path.add(name); + } + } + return new SchemaPath(path, absolute); + } + + /** + * Add all augment's child nodes to given target. + * + * @param augment + * builder of augment statement + * @param target + * augmentation target node + */ + public static def void fillAugmentTarget(AugmentationSchemaBuilder augment, DataNodeContainerBuilder target) { + for (DataSchemaNodeBuilder child : augment.getChildNodeBuilders()) { + val childCopy = CopyUtils.copy(child, target, false); + childCopy.setAugmenting(true); + correctNodePath(child, target.getPath()); + correctNodePath(childCopy, target.getPath()); + try { + target.addChildNode(childCopy); + } catch (YangParseException e) { + + // more descriptive message + throw new YangParseException(augment.getModuleName(), augment.getLine(), + "Failed to perform augmentation: " + e.getMessage()); + } + + } + for (UsesNodeBuilder usesNode : augment.getUsesNodes()) { + val copy = CopyUtils.copyUses(usesNode, target); + target.addUsesNode(copy); + } + } + + /** + * Add all augment's child nodes to given target. + * + * @param augment + * builder of augment statement + * @param target + * augmentation target choice node + */ + public static def void fillAugmentTarget(AugmentationSchemaBuilder augment, ChoiceBuilder target) { + for (DataSchemaNodeBuilder builder : augment.getChildNodeBuilders()) { + val childCopy = CopyUtils.copy(builder, target, false); + childCopy.setAugmenting(true); + correctNodePath(builder, target.getPath()); + correctNodePath(childCopy, target.getPath()); + target.addCase(childCopy); + } + for (UsesNodeBuilder usesNode : augment.getUsesNodes()) { + if (usesNode !== null) { + throw new YangParseException(augment.getModuleName(), augment.getLine(), + "Error in augment parsing: cannot augment uses to choice"); + } + } + } + + /** + * Create new schema path of node based on parent node schema path. + * + * @param node + * node to correct + * @param parentSchemaPath + * schema path of node parent + */ + static def void correctNodePath(SchemaNodeBuilder node, SchemaPath parentSchemaPath) { + + // set correct path + val targetNodePath = new ArrayList(parentSchemaPath.getPath()); + targetNodePath.add(node.getQName()); + node.setPath(new SchemaPath(targetNodePath, true)); + + // set correct path for all child nodes + if (node instanceof DataNodeContainerBuilder) { + val dataNodeContainer = node as DataNodeContainerBuilder; + for (DataSchemaNodeBuilder child : dataNodeContainer.getChildNodeBuilders()) { + correctNodePath(child, node.getPath()); + } + } + + // set correct path for all cases + if (node instanceof ChoiceBuilder) { + val choiceBuilder = node as ChoiceBuilder; + for (ChoiceCaseBuilder choiceCaseBuilder : choiceBuilder.getCases()) { + correctNodePath(choiceCaseBuilder, node.getPath()); + } + } + } + + + + public static dispatch def SchemaNodeBuilder findNode(ModuleBuilder parent,List path) { + var node = _findNode(parent as DataNodeContainerBuilder,path); + if(node !== null) return node; + + val current = path.get(0); + node = parent.getRpc(current.localName); + if(node !== null) return _findNode(node as RpcDefinitionBuilder,path.nextLevel); + node = parent.getNotification(current.localName); + return node; + } + + public static dispatch def SchemaNodeBuilder findNode(DataNodeContainerBuilder parent,List path) { + if(path.empty) return parent as SchemaNodeBuilder; + + var current = path.get(0); + var node = parent.getDataChildByName(current.localName) + if(node !== null) return findNode(node,path.nextLevel); + for (UsesNodeBuilder unb : parent.usesNodes) { + node = findNodeInUses(current.localName, unb); + if (node !== null) { + return findNode(node,path.nextLevel); + } + } + } + + public static dispatch def SchemaNodeBuilder findNode(RpcDefinitionBuilder parent,List path) { + val current = path.get(0); + switch(current.localName) { + case "input": return findNode(parent.input,path.nextLevel) + case "output": return findNode(parent.output,path.nextLevel) + } + return null; + } + + public static dispatch def SchemaNodeBuilder findNode(ChoiceBuilder parent,List path) { + if(path.empty) return parent as SchemaNodeBuilder; + var current = path.get(0); + val node = parent.getCaseNodeByName(current.localName); + if(node === null) return null; + return findNode(node,path.nextLevel); + } + + public static def getRpc(ModuleBuilder module,String name) { + for(rpc : module.rpcs) { + if(name == rpc.QName.localName) { + return rpc; + } + } + return null; + } + + public static def getNotification(ModuleBuilder module,String name) { + for(notification : module.notifications) { + if(name == notification.QName.localName) { + return notification; + } + } + } + + private static def nextLevel(List path){ + return path.subList(1,path.size) + } + + /** + * Find augment target node and perform augmentation. + * + * @param augment + * @param firstNodeParent + * parent of first node in path + * @param path + * path to augment target + * @return true if augmentation process succeed, false otherwise + */ + public static def boolean processAugmentation(AugmentationSchemaBuilder augment, Builder firstNodeParent, + List path) { + + // traverse augment target path and try to reach target node + val currentParent = findNode(firstNodeParent,path); + if (currentParent === null) return false; + + if ((currentParent instanceof DataNodeContainerBuilder)) { + fillAugmentTarget(augment, currentParent as DataNodeContainerBuilder); + } else if (currentParent instanceof ChoiceBuilder) { + fillAugmentTarget(augment, currentParent as ChoiceBuilder); + } else { + throw new YangParseException(augment.getModuleName(), augment.getLine(), + "Error in augment parsing: The target node MUST be either a container, list, choice, case, input, output, or notification node."); + } + (currentParent as AugmentationTargetBuilder).addAugmentation(augment); + val oldPath = (currentParent as SchemaNodeBuilder).getPath(); + augment.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute())); + augment.setResolved(true); + return true; + } + + /** + * Find node with given name in uses target. + * + * @param localName + * name of node to find + * @param uses + * uses node which target grouping should be searched + * @return node with given name if found, null otherwise + */ + private static def DataSchemaNodeBuilder findNodeInUses(String localName, UsesNodeBuilder uses) { + val target = uses.getGroupingBuilder(); + for (DataSchemaNodeBuilder child : target.getChildNodeBuilders()) { + if (child.getQName().getLocalName().equals(localName)) { + return child; + } + } + for (UsesNodeBuilder usesNode : target.getUsesNodes()) { + val result = findNodeInUses(localName, usesNode); + if (result !== null) { + return result; + } + } + return null; + } + + /** + * Find augment target node in given context and perform augmentation. + * + * @param augment + * @param path + * path to augment target + * @param module + * current module + * @param prefix + * current prefix of target module + * @param context + * SchemaContext containing already resolved modules + * @return true if augment process succeed, false otherwise + */ + public static def boolean processAugmentationOnContext(AugmentationSchemaBuilder augment, List path, + ModuleBuilder module, String prefix, SchemaContext context) { + val int line = augment.getLine(); + val Module dependentModule = findModuleFromContext(context, module, prefix, line); + if (dependentModule === null) { + throw new YangParseException(module.getName(), line, + "Error in augment parsing: failed to find module with prefix " + prefix + "."); + } + + var currentName = path.get(0).getLocalName(); + var SchemaNode currentParent = dependentModule.getDataChildByName(currentName); + if (currentParent === null) { + val notifications = dependentModule.getNotifications(); + for (NotificationDefinition ntf : notifications) { + if (ntf.getQName().getLocalName().equals(currentName)) { + currentParent = ntf; + } + } + } + if (currentParent === null) { + throw new YangParseException(module.getName(), line, + "Error in augment parsing: failed to find node " + currentName + "."); + } + + for (qname : path.nextLevel) { + currentName = qname.getLocalName(); + if (currentParent instanceof DataNodeContainer) { + currentParent = (currentParent as DataNodeContainer).getDataChildByName(currentName); + } else if (currentParent instanceof ChoiceNode) { + currentParent = (currentParent as ChoiceNode).getCaseNodeByName(currentName); + } else { + throw new YangParseException(augment.getModuleName(), line, + "Error in augment parsing: failed to find node " + currentName); + } + + // if node in path not found, return false + if (currentParent === null) { + throw new YangParseException(module.getName(), line, + "Error in augment parsing: failed to find node " + currentName + "."); + } + } + + val oldPath = currentParent.path; + + if (!(currentParent instanceof AugmentationTarget)) { + throw new YangParseException(module.getName(), line, + "Target of type " + currentParent.class + " cannot be augmented."); + } + + switch (currentParent) { + case (currentParent instanceof ContainerSchemaNodeImpl): { + + // includes container, input and output statement + val c = currentParent as ContainerSchemaNodeImpl; + val cb = c.toBuilder(); + fillAugmentTarget(augment, cb); + (cb as AugmentationTargetBuilder ).addAugmentation(augment); + cb.rebuild(); + } + case (currentParent instanceof ListSchemaNodeImpl): { + val l = currentParent as ListSchemaNodeImpl; + val lb = l.toBuilder(); + fillAugmentTarget(augment, lb); + (lb as AugmentationTargetBuilder ).addAugmentation(augment); + lb.rebuild(); + augment.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute())); + augment.setResolved(true); + } + case (currentParent instanceof ChoiceNodeImpl): { + val ch = currentParent as ChoiceNodeImpl; + val chb = ch.toBuilder(); + fillAugmentTarget(augment, chb); + (chb as AugmentationTargetBuilder ).addAugmentation(augment); + chb.rebuild(); + augment.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute())); + augment.setResolved(true); + } + case (currentParent instanceof ChoiceCaseNodeImpl): { + val chc = currentParent as ChoiceCaseNodeImpl; + val chcb = chc.toBuilder(); + fillAugmentTarget(augment, chcb); + (chcb as AugmentationTargetBuilder ).addAugmentation(augment); + chcb.rebuild(); + augment.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute())); + augment.setResolved(true); + } + case (currentParent instanceof NotificationDefinitionImpl): { + val nd = currentParent as NotificationDefinitionImpl; + val nb = nd.toBuilder(); + fillAugmentTarget(augment, nb); + (nb as AugmentationTargetBuilder ).addAugmentation(augment); + nb.rebuild(); + augment.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute())); + augment.setResolved(true); + } + } + augment.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute())); + augment.setResolved(true); + return true; + } + + public static def QName findFullQName(Map> modules, + ModuleBuilder module, IdentityrefTypeBuilder idref) { + var QName result = null; + val String baseString = idref.getBaseString(); + if (baseString.contains(":")) { + val String[] splittedBase = baseString.split(":"); + if (splittedBase.length > 2) { + throw new YangParseException(module.getName(), idref.getLine(), + "Failed to parse identityref base: " + baseString); + } + val prefix = splittedBase.get(0); + val name = splittedBase.get(1); + val dependentModule = findDependentModuleBuilder(modules, module, prefix, idref.getLine()); + result = new QName(dependentModule.getNamespace(), dependentModule.getRevision(), prefix, name); + } else { + result = new QName(module.getNamespace(), module.getRevision(), module.getPrefix(), baseString); + } + return result; + } + + /** + * Get module in which this node is defined. + * + * @param node + * @return builder of module where this node is defined + */ + public static def ModuleBuilder getParentModule(Builder node) { + if (node instanceof ModuleBuilder) { + return node as ModuleBuilder; + } + var parent = node.getParent(); + while (!(parent instanceof ModuleBuilder)) { + parent = parent.getParent(); + } + return parent as ModuleBuilder; + } + } + \ No newline at end of file