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%2FRuntimeBeanEntry.java;h=74981a95827d7aafd4cf767599d363575e6a4a99;hp=cd14458b0fe6b44b76bb1e58513628f27ad8a80c;hb=63d1393226781ef6fa1c2cf0cdba5f0b5240ab6e;hpb=2e7347fdc0eb7734ff59a4f902227a93ab6afece diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.java index cd14458b0f..74981a9582 100644 --- a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.java +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.java @@ -7,9 +7,31 @@ */ package org.opendaylight.controller.config.yangjmxgenerator; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; + import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Function; import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.Collections2; +import com.google.common.collect.HashMultimap; import com.google.common.collect.Lists; +import com.google.common.collect.Multimap; +import com.google.common.collect.Sets; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Deque; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute; @@ -18,35 +40,19 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.VoidAttribu import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.FullyQualifiedNameHelper; import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.NameConflictException; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; -import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.RpcDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; import org.opendaylight.yangtools.yang.model.api.UsesNode; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Deque; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; +import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; /** * Holds information about runtime bean to be generated. There are two kinds of @@ -58,6 +64,21 @@ import static com.google.common.base.Preconditions.checkState; * lined via children so that a tree with all beans can be created. */ public class RuntimeBeanEntry { + + private static final Function QNAME_FROM_NODE = new Function() { + @Override + public QName apply(final SchemaNode input) { + return input.getQName(); + } + }; + + private static final Function UNKNOWN_NODE_TO_STRING = new Function() { + @Override + public String apply(final UnknownSchemaNode input) { + return input.getQName().getLocalName() + input.getNodeParameter(); + } + }; + private final String packageName; private final String yangName, javaNamePrefix; private final boolean isRoot; @@ -67,11 +88,11 @@ public class RuntimeBeanEntry { private final Set rpcs; @VisibleForTesting - RuntimeBeanEntry(String packageName, - DataSchemaNode nodeForReporting, String yangName, - String javaNamePrefix, boolean isRoot, - Optional keyYangName, List attributes, - List children, Set rpcs) { + RuntimeBeanEntry(final String packageName, + final DataNodeContainer nodeForReporting, final String yangName, + final String javaNamePrefix, final boolean isRoot, + final Optional keyYangName, final List attributes, + final List children, final Set rpcs) { checkArgument(isRoot == false || keyYangName.isPresent() == false, "Root RuntimeBeanEntry must not have key " + "set"); @@ -88,7 +109,7 @@ public class RuntimeBeanEntry { for (AttributeIfc a : attributes) { checkState(map.containsKey(a.getAttributeYangName()) == false, "Attribute already defined: " + a.getAttributeYangName() - + " in " + nodeForReporting); + + " in " + nodeForReporting); map.put(a.getAttributeYangName(), a); } @@ -112,15 +133,14 @@ public class RuntimeBeanEntry { * not contain special configuration for it. */ public static Map extractClassNameToRuntimeBeanMap( - String packageName, ChoiceCaseNode container, - String moduleYangName, TypeProviderWrapper typeProviderWrapper, - String javaNamePrefix, Module currentModule) { + final String packageName, final DataNodeContainer container, + final String moduleYangName, final TypeProviderWrapper typeProviderWrapper, + final String javaNamePrefix, final Module currentModule, final SchemaContext schemaContext) { - Map> identitiesToRpcs = getIdentitiesToRpcs(currentModule); AttributesRpcsAndRuntimeBeans attributesRpcsAndRuntimeBeans = extractSubtree( packageName, container, typeProviderWrapper, currentModule, - identitiesToRpcs); + schemaContext); Map result = new HashMap<>(); List attributes; @@ -152,50 +172,41 @@ public class RuntimeBeanEntry { return result; } - private static Map> getIdentitiesToRpcs( - Module currentModule) { - // currently only looks for local identities (found in currentModule) - Map> result = new HashMap<>(); - for (IdentitySchemaNode identity : currentModule.getIdentities()) { - // add all - result.put(identity.getQName(), new HashSet()); - } + private static Multimap getIdentitiesToRpcs( + final SchemaContext schemaCtx) { + Multimap result = HashMultimap.create(); + for (Module currentModule : schemaCtx.getModules()) { + + // Find all identities in current module for later identity->rpc mapping + Set allIdentitiesInModule = Sets.newHashSet(Collections2.transform(currentModule.getIdentities(), QNAME_FROM_NODE)); - for (RpcDefinition rpc : currentModule.getRpcs()) { - ContainerSchemaNode input = rpc.getInput(); - if (input != null) { - for (UsesNode uses : input.getUses()) { - - if (uses.getGroupingPath().getPath().size() != 1) - continue; - - // check grouping path - QName qname = uses.getGroupingPath().getPath().get(0); - if (false == qname - .equals(ConfigConstants.RPC_CONTEXT_REF_GROUPING_QNAME)) - continue; - - for (SchemaNode refinedNode : uses.getRefines().values()) { - - for (UnknownSchemaNode unknownSchemaNode : refinedNode - .getUnknownSchemaNodes()) { - if (ConfigConstants.RPC_CONTEXT_INSTANCE_EXTENSION_QNAME - .equals(unknownSchemaNode.getNodeType())) { - String localIdentityName = unknownSchemaNode - .getNodeParameter(); - QName identityQName = new QName( - currentModule.getNamespace(), - currentModule.getRevision(), - localIdentityName); - Set rpcDefinitions = result - .get(identityQName); - if (rpcDefinitions == null) { - throw new IllegalArgumentException( - "Identity referenced by rpc not found. Identity:" - + localIdentityName + " , rpc " - + rpc); + for (RpcDefinition rpc : currentModule.getRpcs()) { + ContainerSchemaNode input = rpc.getInput(); + if (input != null) { + for (UsesNode uses : input.getUses()) { + + // Check if the rpc is config rpc by looking for input argument rpc-context-ref + Iterator pathFromRoot = uses.getGroupingPath().getPathFromRoot().iterator(); + if (!pathFromRoot.hasNext() || + !pathFromRoot.next().equals(ConfigConstants.RPC_CONTEXT_REF_GROUPING_QNAME)) { + continue; + } + + for (SchemaNode refinedNode : uses.getRefines().values()) { + for (UnknownSchemaNode unknownSchemaNode : refinedNode + .getUnknownSchemaNodes()) { + if (ConfigConstants.RPC_CONTEXT_INSTANCE_EXTENSION_QNAME + .equals(unknownSchemaNode.getNodeType())) { + String localIdentityName = unknownSchemaNode + .getNodeParameter(); + QName identityQName = QName.create( + currentModule.getNamespace(), + currentModule.getRevision(), + localIdentityName); + Preconditions.checkArgument(allIdentitiesInModule.contains(identityQName), + "Identity referenced by rpc not found. Identity: %s, rpc: %s", localIdentityName, rpc); + result.put(identityQName, rpc); } - rpcDefinitions.add(rpc); } } } @@ -210,13 +221,13 @@ public class RuntimeBeanEntry { * in subtree. */ private static AttributesRpcsAndRuntimeBeans extractSubtree( - String packageName, DataNodeContainer subtree, - TypeProviderWrapper typeProviderWrapper, Module currentModule, - Map> identitiesToRpcs) { + final String packageName, final DataNodeContainer subtree, + final TypeProviderWrapper typeProviderWrapper, final Module currentModule, + final SchemaContext ctx) { + + Multimap identitiesToRpcs = getIdentitiesToRpcs(ctx); List attributes = Lists.newArrayList(); - // List javaAttributes = new ArrayList<>(); - // List toAttributes = new ArrayList<>(); List runtimeBeanEntries = new ArrayList<>(); for (DataSchemaNode child : subtree.getChildNodes()) { // child leaves can be java attributes, TO attributes, or child @@ -236,7 +247,7 @@ public class RuntimeBeanEntry { ListSchemaNode listSchemaNode = (ListSchemaNode) child; RuntimeBeanEntry hierarchicalChild = createHierarchical( packageName, listSchemaNode, typeProviderWrapper, - currentModule, identitiesToRpcs); + currentModule, ctx); runtimeBeanEntries.add(hierarchicalChild); } else /* ordinary list attribute */{ ListAttribute listAttribute = ListAttribute.create( @@ -260,23 +271,16 @@ public class RuntimeBeanEntry { if (ConfigConstants.RPC_CONTEXT_INSTANCE_EXTENSION_QNAME .equals(unknownSchemaNode.getNodeType())) { String localIdentityName = unknownSchemaNode.getNodeParameter(); - QName identityQName = new QName(currentModule.getNamespace(), - currentModule.getRevision(), localIdentityName); - Set rpcDefinitions = identitiesToRpcs - .get(identityQName); - if (rpcDefinitions == null) { - throw new IllegalArgumentException("Cannot find identity " - + localIdentityName + " to be used as " - + "context reference when resolving " - + unknownSchemaNode); - } + QName identityQName = unknownSchemaNode.isAddedByUses() ? + findQNameFromGrouping(subtree, ctx, unknownSchemaNode, localIdentityName) : + QName.create(currentModule.getNamespace(), currentModule.getRevision(), localIdentityName); // convert RpcDefinition to Rpc - for (RpcDefinition rpcDefinition : rpcDefinitions) { + for (RpcDefinition rpcDefinition : identitiesToRpcs.get(identityQName)) { String name = TypeProviderWrapper .findJavaParameter(rpcDefinition); AttributeIfc returnType; if (rpcDefinition.getOutput() == null - || rpcDefinition.getOutput().getChildNodes().size() == 0) { + || rpcDefinition.getOutput().getChildNodes().isEmpty()) { returnType = VoidAttribute.getInstance(); } else if (rpcDefinition.getOutput().getChildNodes().size() == 1) { DataSchemaNode returnDSN = rpcDefinition.getOutput() @@ -292,8 +296,8 @@ public class RuntimeBeanEntry { for (DataSchemaNode childNode : sortAttributes(rpcDefinition.getInput() .getChildNodes())) { if (childNode.isAddedByUses() == false) { // skip - // refined - // context-instance + // refined + // context-instance checkArgument(childNode instanceof LeafSchemaNode, "Unexpected type of rpc input type. " + "Currently only leafs and empty output nodes are supported, got " + childNode); JavaAttribute javaAttribute = new JavaAttribute( @@ -312,8 +316,24 @@ public class RuntimeBeanEntry { attributes, rpcs); } - private static AttributeIfc getReturnTypeAttribute(DataSchemaNode child, TypeProviderWrapper typeProviderWrapper, - String packageName) { + /** + * Find "proper" qname of unknown node in case it comes from a grouping + */ + private static QName findQNameFromGrouping(final DataNodeContainer subtree, final SchemaContext ctx, final UnknownSchemaNode unknownSchemaNode, final String localIdentityName) { + QName identityQName = null; + for (UsesNode usesNode : subtree.getUses()) { + SchemaNode dataChildByName = SchemaContextUtil.findDataSchemaNode(ctx, usesNode.getGroupingPath()); + Module m = SchemaContextUtil.findParentModule(ctx, dataChildByName); + List unknownSchemaNodes = dataChildByName.getUnknownSchemaNodes(); + if(Collections2.transform(unknownSchemaNodes, UNKNOWN_NODE_TO_STRING).contains(UNKNOWN_NODE_TO_STRING.apply(unknownSchemaNode))) { + identityQName = QName.create(dataChildByName.getQName(), localIdentityName); + } + } + return identityQName; + } + + private static AttributeIfc getReturnTypeAttribute(final DataSchemaNode child, final TypeProviderWrapper typeProviderWrapper, + final String packageName) { if (child instanceof LeafSchemaNode) { LeafSchemaNode leaf = (LeafSchemaNode) child; return new JavaAttribute(leaf, typeProviderWrapper); @@ -330,10 +350,10 @@ public class RuntimeBeanEntry { } } - private static Collection sortAttributes(Set childNodes) { + private static Collection sortAttributes(final Collection childNodes) { final TreeSet dataSchemaNodes = new TreeSet<>(new Comparator() { @Override - public int compare(DataSchemaNode o1, DataSchemaNode o2) { + public int compare(final DataSchemaNode o1, final DataSchemaNode o2) { return o1.getQName().getLocalName().compareTo(o2.getQName().getLocalName()); } }); @@ -341,29 +361,30 @@ public class RuntimeBeanEntry { return dataSchemaNodes; } - private static boolean isInnerStateBean(DataSchemaNode child) { + private static boolean isInnerStateBean(final DataSchemaNode child) { for (UnknownSchemaNode unknownSchemaNode : child .getUnknownSchemaNodes()) { if (unknownSchemaNode.getNodeType().equals( - ConfigConstants.INNER_STATE_BEAN_EXTENSION_QNAME)) + ConfigConstants.INNER_STATE_BEAN_EXTENSION_QNAME)) { return true; + } } return false; } - private static RuntimeBeanEntry createHierarchical(String packageName, - ListSchemaNode listSchemaNode, - TypeProviderWrapper typeProviderWrapper, Module currentModule, - Map> identitiesToRpcs) { + private static RuntimeBeanEntry createHierarchical(final String packageName, + final ListSchemaNode listSchemaNode, + final TypeProviderWrapper typeProviderWrapper, final Module currentModule, + final SchemaContext ctx) { // supported are numeric types, strings, enums // get all attributes AttributesRpcsAndRuntimeBeans attributesRpcsAndRuntimeBeans = extractSubtree( packageName, listSchemaNode, typeProviderWrapper, - currentModule, identitiesToRpcs); + currentModule, ctx); Optional keyYangName; - if (listSchemaNode.getKeyDefinition().size() == 0) { + if (listSchemaNode.getKeyDefinition().isEmpty()) { keyYangName = Optional.absent(); } else if (listSchemaNode.getKeyDefinition().size() == 1) { // key must be either null or one of supported key types @@ -389,10 +410,10 @@ public class RuntimeBeanEntry { return rbFromAttributes; } - private static RuntimeBeanEntry createRoot(String packageName, - DataSchemaNode nodeForReporting, String attributeYangName, - List attributes, String javaNamePrefix, - List children, Set rpcs) { + private static RuntimeBeanEntry createRoot(final String packageName, + final DataNodeContainer nodeForReporting, final String attributeYangName, + final List attributes, final String javaNamePrefix, + final List children, final Set rpcs) { return new RuntimeBeanEntry(packageName, nodeForReporting, attributeYangName, javaNamePrefix, true, Optional. absent(), attributes, children, rpcs); @@ -444,8 +465,8 @@ public class RuntimeBeanEntry { private final Set rpcs; public AttributesRpcsAndRuntimeBeans( - List runtimeBeanEntries, - List attributes, Set rpcs) { + final List runtimeBeanEntries, + final List attributes, final Set rpcs) { this.runtimeBeanEntries = runtimeBeanEntries; this.attributes = attributes; this.rpcs = rpcs; @@ -474,8 +495,8 @@ public class RuntimeBeanEntry { private final AttributeIfc returnType; private final String yangName; - Rpc(AttributeIfc returnType, String name, String yangName, - List parameters) { + Rpc(final AttributeIfc returnType, final String name, final String yangName, + final List parameters) { this.returnType = returnType; this.name = name; this.parameters = parameters; @@ -505,12 +526,12 @@ public class RuntimeBeanEntry { return getJavaNameOfRuntimeMXBean(javaNamePrefix); } - public String getFullyQualifiedName(String typeName) { + public String getFullyQualifiedName(final String typeName) { return FullyQualifiedNameHelper.getFullyQualifiedName(packageName, typeName); } - private static String getJavaNameOfRuntimeMXBean(String javaNamePrefix) { + private static String getJavaNameOfRuntimeMXBean(final String javaNamePrefix) { return javaNamePrefix + MXBEAN_SUFFIX; }