X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fconfig%2Fyang-jmx-generator%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fconfig%2Fyangjmxgenerator%2FModuleMXBeanEntryBuilder.java;h=04d37416e3f3cd5b96dbc998ba1b93604e28c4ab;hp=676c8eca6ec6f9a903c34aeebd69d9c8abbeae07;hb=61ae01d240493950e25beffca5c5464c47d66ef7;hpb=4b5f54e25c08fc21c955ff75901abe96b12d3340 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..04d37416e3 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,25 @@ */ 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.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; @@ -21,6 +34,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribu import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute; import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.NameConflictException; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.ServiceRef; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; @@ -35,26 +49,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; @@ -63,51 +64,49 @@ final class ModuleMXBeanEntryBuilder { private TypeProviderWrapper typeProviderWrapper; private String packageName; - public ModuleMXBeanEntryBuilder setModule(Module module) { + public ModuleMXBeanEntryBuilder setModule(final Module module) { this.currentModule = module; return this; } - public ModuleMXBeanEntryBuilder setqNamesToSIEs(Map qNamesToSIEs) { + public ModuleMXBeanEntryBuilder setqNamesToSIEs(final Map qNamesToSIEs) { this.qNamesToSIEs = qNamesToSIEs; return this; } - public ModuleMXBeanEntryBuilder setSchemaContext(SchemaContext schemaContext) { + public ModuleMXBeanEntryBuilder setSchemaContext(final SchemaContext schemaContext) { this.schemaContext = schemaContext; return this; } - public ModuleMXBeanEntryBuilder setTypeProviderWrapper(TypeProviderWrapper typeProviderWrapper) { + public ModuleMXBeanEntryBuilder setTypeProviderWrapper(final TypeProviderWrapper typeProviderWrapper) { this.typeProviderWrapper = typeProviderWrapper; return this; } - public ModuleMXBeanEntryBuilder setPackageName(String packageName) { + public ModuleMXBeanEntryBuilder setPackageName(final String packageName) { this.packageName = packageName; return this; } - private static final Logger logger = LoggerFactory + private static final Logger LOG = LoggerFactory .getLogger(ModuleMXBeanEntryBuilder.class); // TODO: the XPath should be parsed by code generator IMO private static final String MAGIC_STRING = "MAGIC_STRING"; private static final String MODULE_CONDITION_XPATH_TEMPLATE = "^/MAGIC_STRING:modules/MAGIC_STRING:module/MAGIC_STRING:type\\s*=\\s*['\"](.+)['\"]$"; - private static final SchemaPath expectedConfigurationAugmentationSchemaPath = new SchemaPath( - Arrays.asList(createConfigQName("modules"), - createConfigQName("module"), - createConfigQName("configuration")), true); - private static final SchemaPath expectedStateAugmentationSchemaPath = new SchemaPath( - Arrays.asList(createConfigQName("modules"), - createConfigQName("module"), createConfigQName("state")), - true); - private static final Pattern PREFIX_COLON_LOCAL_NAME = Pattern - .compile("^(.+):(.+)$"); + private static final SchemaPath AUGMENT_SCHEMAPATH = SchemaPath.create(true, + createConfigQName("modules"), createConfigQName("module")); + + private static final SchemaPath EXPECTED_CONFIGURATION_AUGMENTATION_SCHEMA_PATH = + AUGMENT_SCHEMAPATH.createChild(createConfigQName("configuration")); + private static final SchemaPath EXPECTED_STATE_AUGMENTATION_SCHEMA_PATH = + AUGMENT_SCHEMAPATH.createChild(createConfigQName("state")); + private static final Pattern PREFIX_COLON_LOCAL_NAME = Pattern.compile("^(.+):(.+)$"); public Map build() { - logger.debug("Generating ModuleMXBeans of {} to package {}", + LOG.debug("Generating ModuleMXBeans of {} to package {}", currentModule.getNamespace(), packageName); String configModulePrefix; @@ -130,7 +129,7 @@ final class ModuleMXBeanEntryBuilder { Map result = new HashMap<>(); for (AugmentationSchema augmentation : currentModule.getAugmentations()) { - Set childNodes = augmentation.getChildNodes(); + Collection childNodes = augmentation.getChildNodes(); if (areAllChildrenChoiceCaseNodes(childNodes)) { for (ChoiceCaseNode childCase : castChildNodesToChoiceCases(childNodes)) { // TODO refactor, extract to standalone builder class @@ -145,12 +144,12 @@ final class ModuleMXBeanEntryBuilder { checkAttributeNamesUniqueness(uniqueGeneratedClassesNames, result); checkUnaugumentedIdentities(unaugmentedModuleIdentities); - logger.debug("Number of ModuleMXBeans to be generated: {}", result.size()); + LOG.debug("Number of ModuleMXBeans to be generated: {}", result.size()); return result; } - private static void cleanUpNulls(Map result) { + private static void cleanUpNulls(final Map result) { for (Map.Entry entry : result.entrySet()) { ModuleMXBeanEntry module = entry.getValue(); if (module.getAttributes() == null) { @@ -163,14 +162,14 @@ final class ModuleMXBeanEntryBuilder { } } - private static void checkUnaugumentedIdentities(Map unaugmentedModuleIdentities) { + private static void checkUnaugumentedIdentities(final Map unaugmentedModuleIdentities) { if (unaugmentedModuleIdentities.size() > 0) { - logger.warn("Augmentation not found for all currentModule identities: {}", + LOG.warn("Augmentation not found for all currentModule identities: {}", unaugmentedModuleIdentities.keySet()); } } - private static void checkAttributeNamesUniqueness(Map uniqueGeneratedClassesNames, Map result) { + private static void checkAttributeNamesUniqueness(final Map uniqueGeneratedClassesNames, final Map result) { for (Map.Entry entry : result.entrySet()) { checkUniqueRuntimeBeanAttributesName(entry.getValue(), uniqueGeneratedClassesNames); @@ -189,7 +188,7 @@ final class ModuleMXBeanEntryBuilder { + identityLocalName); } else { moduleIdentities.put(identityLocalName, id); - logger.debug("Found identity {}", identityLocalName); + LOG.debug("Found identity {}", identityLocalName); } // validation check on unknown schema nodes boolean providedServiceWasSet = false; @@ -215,29 +214,30 @@ final class ModuleMXBeanEntryBuilder { return moduleIdentities; } - private Collection castChildNodesToChoiceCases(Set childNodes) { + private static Collection castChildNodesToChoiceCases(final Collection childNodes) { return Collections2.transform(childNodes, new Function() { @Nullable @Override - public ChoiceCaseNode apply(@Nullable DataSchemaNode input) { + public ChoiceCaseNode apply(@Nullable final DataSchemaNode input) { return (ChoiceCaseNode) input; } }); } - private boolean areAllChildrenChoiceCaseNodes(Set childNodes) { + private static boolean areAllChildrenChoiceCaseNodes(final Iterable childNodes) { for (DataSchemaNode childNode : childNodes) { - if (childNode instanceof ChoiceCaseNode == false) + if (childNode instanceof ChoiceCaseNode == false) { return false; + } } return true; } - private void processChoiceCaseNode(Map result, - Map uniqueGeneratedClassesNames, String configModulePrefix, - Map moduleIdentities, - Map unaugmentedModuleIdentities, AugmentationSchema augmentation, - DataSchemaNode when) { + private void processChoiceCaseNode(final Map result, + final Map uniqueGeneratedClassesNames, final String configModulePrefix, + final Map moduleIdentities, + final Map unaugmentedModuleIdentities, final AugmentationSchema augmentation, + final DataSchemaNode when) { ChoiceCaseNode choiceCaseNode = (ChoiceCaseNode) when; if (choiceCaseNode.getConstraints() == null || choiceCaseNode.getConstraints().getWhenCondition() == null) { @@ -251,30 +251,27 @@ final class ModuleMXBeanEntryBuilder { String moduleLocalNameFromXPath = matcher.group(1); IdentitySchemaNode moduleIdentity = moduleIdentities.get(moduleLocalNameFromXPath); unaugmentedModuleIdentities.remove(moduleLocalNameFromXPath); - checkState(moduleIdentity != null, "Cannot find identity " + moduleLocalNameFromXPath - + " matching augmentation " + augmentation); + checkState(moduleIdentity != null, "Cannot find identity %s matching augmentation %s", moduleLocalNameFromXPath, augmentation); Map providedServices = findProvidedServices(moduleIdentity, currentModule, qNamesToSIEs, schemaContext); - if (moduleIdentity == null) { - throw new IllegalStateException("Cannot find identity specified by augmentation xpath constraint: " - + moduleLocalNameFromXPath + " of " + augmentation); - } String javaNamePrefix = TypeProviderWrapper.findJavaNamePrefix(moduleIdentity); Map yangToAttributes = null; // runtime-data Collection runtimeBeans = null; - if (expectedConfigurationAugmentationSchemaPath.equals(augmentation.getTargetPath())) { - logger.debug("Parsing configuration of {}", moduleLocalNameFromXPath); - yangToAttributes = fillConfiguration(choiceCaseNode, currentModule, typeProviderWrapper, qNamesToSIEs, + HAS_CHILDREN_AND_QNAME dataNodeContainer = getDataNodeContainer(choiceCaseNode); + + if (EXPECTED_CONFIGURATION_AUGMENTATION_SCHEMA_PATH.equals(augmentation.getTargetPath())) { + LOG.debug("Parsing configuration of {}", moduleLocalNameFromXPath); + 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); + } else if (EXPECTED_STATE_AUGMENTATION_SCHEMA_PATH.equals(augmentation.getTargetPath())) { + LOG.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,19 +286,25 @@ 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) - .setNamespace(currentModule.getNamespace().toString()).setqName(ModuleUtil.getQName(currentModule)) - .build(); + .setIdSchemaNode(moduleIdentity).setPackageName(packageName).setJavaNamePrefix(javaNamePrefix) + .setNamespace(currentModule.getNamespace().toString()).setqName(ModuleUtil.getQName(currentModule)) + .build(); // construct ModuleMXBeanEntry ModuleMXBeanEntry moduleMXBeanEntry = new ModuleMXBeanEntry(initial, yangToAttributes, providedServices, @@ -309,12 +312,13 @@ final class ModuleMXBeanEntryBuilder { moduleMXBeanEntry.setYangModuleName(currentModule.getName()); moduleMXBeanEntry.setYangModuleLocalname(moduleLocalNameFromXPath); + moduleMXBeanEntry.setNullableDummyContainerName(nullableDummyContainerName); result.put(moduleLocalNameFromXPath, moduleMXBeanEntry); } } - private void checkUniqueRuntimeBeansGeneratedClasses(Map uniqueGeneratedClassesNames, - DataSchemaNode when, Collection runtimeBeans) { + private static void checkUniqueRuntimeBeansGeneratedClasses(final Map uniqueGeneratedClassesNames, + final DataSchemaNode when, final Collection runtimeBeans) { for (RuntimeBeanEntry runtimeBean : runtimeBeans) { final String javaNameOfRuntimeMXBean = runtimeBean.getJavaNameOfRuntimeMXBean(); if (uniqueGeneratedClassesNames.containsKey(javaNameOfRuntimeMXBean)) { @@ -325,8 +329,8 @@ final class ModuleMXBeanEntryBuilder { } } - private static void checkUniqueRuntimeBeanAttributesName(ModuleMXBeanEntry mxBeanEntry, - Map uniqueGeneratedClassesNames) { + private static void checkUniqueRuntimeBeanAttributesName(final ModuleMXBeanEntry mxBeanEntry, + final Map uniqueGeneratedClassesNames) { for (RuntimeBeanEntry runtimeBeanEntry : mxBeanEntry.getRuntimeBeans()) { for (String runtimeAttName : runtimeBeanEntry.getYangPropertiesToTypesMap().keySet()) { if (mxBeanEntry.getAttributes().keySet().contains(runtimeAttName)) { @@ -338,8 +342,8 @@ final class ModuleMXBeanEntryBuilder { } } - private void checkUniqueAttributesWithGeneratedClass(Map uniqueGeneratedClassNames, - QName parentQName, Map yangToAttributes) { + private static void checkUniqueAttributesWithGeneratedClass(final Map uniqueGeneratedClassNames, + final QName parentQName, final Map yangToAttributes) { for (Map.Entry attr : yangToAttributes.entrySet()) { if (attr.getValue() instanceof TOAttribute) { checkUniqueTOAttr(uniqueGeneratedClassNames, parentQName, (TOAttribute) attr.getValue()); @@ -351,30 +355,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); + private static void checkUniqueTOAttr(final Map uniqueGeneratedClassNames, final QName parentQName, final TOAttribute attr) { + 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, - TypeProviderWrapper typeProviderWrapper, String packageName, String moduleLocalNameFromXPath, - String javaNamePrefix) { + private Collection fillRuntimeBeans(final DataNodeContainer dataNodeContainer, final Module currentModule, + final TypeProviderWrapper typeProviderWrapper, final String packageName, final String moduleLocalNameFromXPath, + final String javaNamePrefix) { - return RuntimeBeanEntry.extractClassNameToRuntimeBeanMap(packageName, choiceCaseNode, moduleLocalNameFromXPath, - typeProviderWrapper, javaNamePrefix, currentModule).values(); + return RuntimeBeanEntry.extractClassNameToRuntimeBeanMap(packageName, dataNodeContainer, moduleLocalNameFromXPath, + typeProviderWrapper, javaNamePrefix, currentModule, schemaContext).values(); } - private Map fillConfiguration(ChoiceCaseNode choiceCaseNode, Module currentModule, - TypeProviderWrapper typeProviderWrapper, Map qNamesToSIEs, - SchemaContext schemaContext, String packageName) { + /** + * 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 static HAS_CHILDREN_AND_QNAME getDataNodeContainer(final ChoiceCaseNode choiceCaseNode) { + Collection 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 static Map fillConfiguration(final DataNodeContainer dataNodeContainer, final Module currentModule, + final TypeProviderWrapper typeProviderWrapper, final Map qNamesToSIEs, + final SchemaContext schemaContext, final String packageName) { Map yangToAttributes = new HashMap<>(); - for (DataSchemaNode attrNode : choiceCaseNode.getChildNodes()) { + for (DataSchemaNode attrNode : dataNodeContainer.getChildNodes()) { AttributeIfc attributeValue = getAttributeValue(attrNode, currentModule, qNamesToSIEs, typeProviderWrapper, schemaContext, packageName); yangToAttributes.put(attributeValue.getAttributeYangName(), attributeValue); @@ -382,8 +408,8 @@ final class ModuleMXBeanEntryBuilder { return yangToAttributes; } - private Map findProvidedServices(IdentitySchemaNode moduleIdentity, Module currentModule, - Map qNamesToSIEs, SchemaContext schemaContext) { + private static Map findProvidedServices(final IdentitySchemaNode moduleIdentity, final Module currentModule, + final Map qNamesToSIEs, final SchemaContext schemaContext) { Map result = new HashMap<>(); for (UnknownSchemaNode unknownNode : moduleIdentity.getUnknownSchemaNodes()) { if (ConfigConstants.PROVIDED_SERVICE_EXTENSION_QNAME.equals(unknownNode.getNodeType())) { @@ -396,9 +422,9 @@ final class ModuleMXBeanEntryBuilder { return result; } - private AttributeIfc getAttributeValue(DataSchemaNode attrNode, Module currentModule, - Map qNamesToSIEs, TypeProviderWrapper typeProviderWrapper, - SchemaContext schemaContext, String packageName) { + private static AttributeIfc getAttributeValue(final DataSchemaNode attrNode, final Module currentModule, + final Map qNamesToSIEs, final TypeProviderWrapper typeProviderWrapper, + final SchemaContext schemaContext, final String packageName) { if (attrNode instanceof LeafSchemaNode) { // simple type @@ -431,10 +457,10 @@ final class ModuleMXBeanEntryBuilder { } } - private Optional extractDependency(DataNodeContainer dataNodeContainer, - DataSchemaNode attrNode, Module currentModule, Map qNamesToSIEs, - SchemaContext schemaContext) { - if (dataNodeContainer.getUses().size() == 1 && getChildNodeSizeWithoutUses(dataNodeContainer) == 0) { + private static Optional extractDependency(final DataNodeContainer dataNodeContainer, + final DataSchemaNode attrNode, final Module currentModule, final Map qNamesToSIEs, + final SchemaContext schemaContext) { + if (isDependencyContainer(dataNodeContainer)) { // reference UsesNode usesNode = dataNodeContainer.getUses().iterator().next(); checkState(usesNode.getRefines().size() == 1, "Unexpected 'refine' child node size of " + dataNodeContainer); @@ -461,7 +487,19 @@ final class ModuleMXBeanEntryBuilder { return Optional.absent(); } - private int getChildNodeSizeWithoutUses(DataNodeContainer csn) { + private static boolean isDependencyContainer(final DataNodeContainer dataNodeContainer) { + if(dataNodeContainer.getUses().size() != 1) { + return false; + } + UsesNode onlyUses = dataNodeContainer.getUses().iterator().next(); + if(onlyUses.getGroupingPath().getLastComponent().equals(ServiceRef.QNAME) == false) { + return false; + } + + return getChildNodeSizeWithoutUses(dataNodeContainer) == 0; + } + + private static int getChildNodeSizeWithoutUses(final DataNodeContainer csn) { int result = 0; for (DataSchemaNode dsn : csn.getChildNodes()) { if (dsn.isAddedByUses() == false) { @@ -471,8 +509,8 @@ final class ModuleMXBeanEntryBuilder { return result; } - private ServiceInterfaceEntry findSIE(String prefixAndIdentityLocalName, Module currentModule, - Map qNamesToSIEs, SchemaContext schemaContext) { + private static ServiceInterfaceEntry findSIE(final String prefixAndIdentityLocalName, final Module currentModule, + final Map qNamesToSIEs, final SchemaContext schemaContext) { Matcher m = PREFIX_COLON_LOCAL_NAME.matcher(prefixAndIdentityLocalName); Module foundModule; @@ -483,19 +521,19 @@ 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 localSIName = prefixAndIdentityLocalName; } - QName siQName = new QName(foundModule.getNamespace(), foundModule.getRevision(), localSIName); + QName siQName = QName.create(foundModule.getNamespace(), foundModule.getRevision(), localSIName); ServiceInterfaceEntry sie = qNamesToSIEs.get(siQName); checkState(sie != null, "Cannot find referenced Service Interface by " + prefixAndIdentityLocalName); return sie; } - private ModuleImport findModuleImport(Module module, String prefix) { + private static ModuleImport findModuleImport(final Module module, final String prefix) { for (ModuleImport moduleImport : module.getImports()) { if (moduleImport.getPrefix().equals(prefix)) { return moduleImport; @@ -505,13 +543,13 @@ final class ModuleMXBeanEntryBuilder { } @VisibleForTesting - static Matcher getWhenConditionMatcher(String prefix, RevisionAwareXPath whenConstraint) { + static Matcher getWhenConditionMatcher(final String prefix, final RevisionAwareXPath whenConstraint) { String xpathRegex = MODULE_CONDITION_XPATH_TEMPLATE.replace(MAGIC_STRING, prefix); Pattern pattern = Pattern.compile(xpathRegex); return pattern.matcher(whenConstraint.toString()); } - String getConfigModulePrefixFromImport(Module currentModule) { + private static String getConfigModulePrefixFromImport(final Module currentModule) { for (ModuleImport currentImport : currentModule.getImports()) { if (currentImport.getModuleName().equals(ConfigConstants.CONFIG_MODULE)) { return currentImport.getPrefix();