X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fconfig%2Fyang-jmx-generator%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fconfig%2Fyangjmxgenerator%2FModuleMXBeanEntryBuilder.java;h=6da8dfc663b9cb1e8b8ef43a384151af7c7d18f0;hb=aefe82b158bc1694fe633053d04f2364bcbe67d9;hp=676c8eca6ec6f9a903c34aeebd69d9c8abbeae07;hpb=6623a8370580d5210be559299e165c96d4097fe2;p=controller.git diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryBuilder.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryBuilder.java index 676c8eca6e..6da8dfc663 100644 --- a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryBuilder.java +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryBuilder.java @@ -7,12 +7,27 @@ */ package org.opendaylight.controller.config.yangjmxgenerator; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static java.lang.String.format; +import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants.createConfigQName; + import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.collect.Collections2; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.annotation.Nullable; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AbstractDependencyAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute; @@ -35,26 +50,13 @@ import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.ModuleImport; 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.UnknownSchemaNode; import org.opendaylight.yangtools.yang.model.api.UsesNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.Nullable; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static com.google.common.base.Preconditions.checkState; -import static java.lang.String.format; -import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants.createConfigQName; - final class ModuleMXBeanEntryBuilder { private Module currentModule; @@ -233,7 +235,7 @@ final class ModuleMXBeanEntryBuilder { return true; } - private void processChoiceCaseNode(Map result, + private void processChoiceCaseNode(Map result, Map uniqueGeneratedClassesNames, String configModulePrefix, Map moduleIdentities, Map unaugmentedModuleIdentities, AugmentationSchema augmentation, @@ -266,15 +268,17 @@ final class ModuleMXBeanEntryBuilder { // runtime-data Collection runtimeBeans = null; + HAS_CHILDREN_AND_QNAME dataNodeContainer = getDataNodeContainer(choiceCaseNode); + if (expectedConfigurationAugmentationSchemaPath.equals(augmentation.getTargetPath())) { logger.debug("Parsing configuration of {}", moduleLocalNameFromXPath); - yangToAttributes = fillConfiguration(choiceCaseNode, currentModule, typeProviderWrapper, qNamesToSIEs, + yangToAttributes = fillConfiguration(dataNodeContainer, currentModule, typeProviderWrapper, qNamesToSIEs, schemaContext, packageName); checkUniqueAttributesWithGeneratedClass(uniqueGeneratedClassesNames, when.getQName(), yangToAttributes); } else if (expectedStateAugmentationSchemaPath.equals(augmentation.getTargetPath())) { logger.debug("Parsing state of {}", moduleLocalNameFromXPath); try { - runtimeBeans = fillRuntimeBeans(choiceCaseNode, currentModule, typeProviderWrapper, packageName, + runtimeBeans = fillRuntimeBeans(dataNodeContainer, currentModule, typeProviderWrapper, packageName, moduleLocalNameFromXPath, javaNamePrefix); } catch (NameConflictException e) { throw new NameConflictException(e.getConflictingName(), when.getQName(), when.getQName()); @@ -289,14 +293,20 @@ final class ModuleMXBeanEntryBuilder { } else { throw new IllegalArgumentException("Cannot parse augmentation " + augmentation); } + boolean hasDummyContainer = choiceCaseNode.equals(dataNodeContainer) == false; + + String nullableDummyContainerName = hasDummyContainer ? dataNodeContainer.getQName().getLocalName() : null; if (result.containsKey(moduleLocalNameFromXPath)) { - // either fill runtimeBeans or yangToAttributes + // either fill runtimeBeans or yangToAttributes, merge ModuleMXBeanEntry moduleMXBeanEntry = result.get(moduleLocalNameFromXPath); if (yangToAttributes != null && moduleMXBeanEntry.getAttributes() == null) { moduleMXBeanEntry.setYangToAttributes(yangToAttributes); } else if (runtimeBeans != null && moduleMXBeanEntry.getRuntimeBeans() == null) { moduleMXBeanEntry.setRuntimeBeans(runtimeBeans); } + checkState(Objects.equals(nullableDummyContainerName, moduleMXBeanEntry.getNullableDummyContainerName()), + "Mismatch in module " + moduleMXBeanEntry.toString() + " - dummy container must be present/missing in" + + " both state and configuration"); } else { ModuleMXBeanEntry.ModuleMXBeanEntryInitial initial = new ModuleMXBeanEntry.ModuleMXBeanEntryInitialBuilder() .setIdSchemaNode(moduleIdentity).setPackageName(packageName).setJavaNamePrefix(javaNamePrefix) @@ -309,6 +319,7 @@ final class ModuleMXBeanEntryBuilder { moduleMXBeanEntry.setYangModuleName(currentModule.getName()); moduleMXBeanEntry.setYangModuleLocalname(moduleLocalNameFromXPath); + moduleMXBeanEntry.setNullableDummyContainerName(nullableDummyContainerName); result.put(moduleLocalNameFromXPath, moduleMXBeanEntry); } } @@ -352,29 +363,52 @@ final class ModuleMXBeanEntryBuilder { } private void checkUniqueTOAttr(Map uniqueGeneratedClassNames, QName parentQName, TOAttribute attr) { - final String upperCaseCammelCase = attr.getUpperCaseCammelCase(); - if (uniqueGeneratedClassNames.containsKey(upperCaseCammelCase)) { - QName firstDefinedQName = uniqueGeneratedClassNames.get(upperCaseCammelCase); - throw new NameConflictException(upperCaseCammelCase, firstDefinedQName, parentQName); + final String upperCaseCamelCase = attr.getUpperCaseCammelCase(); + if (uniqueGeneratedClassNames.containsKey(upperCaseCamelCase)) { + QName firstDefinedQName = uniqueGeneratedClassNames.get(upperCaseCamelCase); + throw new NameConflictException(upperCaseCamelCase, firstDefinedQName, parentQName); } else { - uniqueGeneratedClassNames.put(upperCaseCammelCase, parentQName); + uniqueGeneratedClassNames.put(upperCaseCamelCase, parentQName); } } - private Collection fillRuntimeBeans(ChoiceCaseNode choiceCaseNode, Module currentModule, + private Collection fillRuntimeBeans(DataNodeContainer dataNodeContainer, Module currentModule, TypeProviderWrapper typeProviderWrapper, String packageName, String moduleLocalNameFromXPath, String javaNamePrefix) { - return RuntimeBeanEntry.extractClassNameToRuntimeBeanMap(packageName, choiceCaseNode, moduleLocalNameFromXPath, + return RuntimeBeanEntry.extractClassNameToRuntimeBeanMap(packageName, dataNodeContainer, moduleLocalNameFromXPath, typeProviderWrapper, javaNamePrefix, currentModule).values(); } - private Map fillConfiguration(ChoiceCaseNode choiceCaseNode, Module currentModule, + /** + * Since each case statement within a module must provide unique child nodes, it is allowed to wrap + * the actual configuration with a container node with name equal to case name. + * + * @param choiceCaseNode state or configuration case statement + * @return either choiceCaseNode or its only child container + */ + private HAS_CHILDREN_AND_QNAME getDataNodeContainer(ChoiceCaseNode choiceCaseNode) { + Set childNodes = choiceCaseNode.getChildNodes(); + if (childNodes.size() == 1) { + DataSchemaNode onlyChild = childNodes.iterator().next(); + if (onlyChild instanceof ContainerSchemaNode) { + ContainerSchemaNode onlyContainer = (ContainerSchemaNode) onlyChild; + if (Objects.equals(onlyContainer.getQName().getLocalName(), choiceCaseNode.getQName().getLocalName())) { + // the actual configuration is inside dummy container + return (HAS_CHILDREN_AND_QNAME) onlyContainer; + } + } + } + return (HAS_CHILDREN_AND_QNAME) choiceCaseNode; + } + + private Map fillConfiguration(DataNodeContainer dataNodeContainer, Module currentModule, TypeProviderWrapper typeProviderWrapper, Map qNamesToSIEs, SchemaContext schemaContext, String packageName) { Map yangToAttributes = new HashMap<>(); - for (DataSchemaNode attrNode : choiceCaseNode.getChildNodes()) { + Set childNodes = dataNodeContainer.getChildNodes(); + for (DataSchemaNode attrNode : childNodes) { AttributeIfc attributeValue = getAttributeValue(attrNode, currentModule, qNamesToSIEs, typeProviderWrapper, schemaContext, packageName); yangToAttributes.put(attributeValue.getAttributeYangName(), attributeValue); @@ -483,7 +517,7 @@ final class ModuleMXBeanEntryBuilder { String prefix = m.group(1); ModuleImport moduleImport = findModuleImport(currentModule, prefix); foundModule = schemaContext.findModuleByName(moduleImport.getModuleName(), moduleImport.getRevision()); - checkState(foundModule != null, format("Module not found in SchemaContext by %s", moduleImport)); + checkNotNull(foundModule, format("Module not found in SchemaContext by %s", moduleImport)); localSIName = m.group(2); } else { foundModule = currentModule; // no prefix => SIE is in currentModule