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.Optional;
+import com.google.common.collect.Lists;
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.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;
import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
+import org.opendaylight.controller.config.yangjmxgenerator.attribute.VoidAttribute;
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.UnknownSchemaNode;
import org.opendaylight.yangtools.yang.model.api.UsesNode;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
-
/**
* Holds information about runtime bean to be generated. There are two kinds of
* RuntimeBeanEntry instances: if isRoot flag is set to true, this bean
private final Set<Rpc> rpcs;
@VisibleForTesting
- public RuntimeBeanEntry(String packageName,
- DataSchemaNode nodeForReporting, String yangName,
+ RuntimeBeanEntry(String packageName,
+ DataNodeContainer nodeForReporting, String yangName,
String javaNamePrefix, boolean isRoot,
Optional<String> keyYangName, List<AttributeIfc> attributes,
List<RuntimeBeanEntry> children, Set<Rpc> rpcs) {
* not contain special configuration for it.
*/
public static Map<String, RuntimeBeanEntry> extractClassNameToRuntimeBeanMap(
- String packageName, ChoiceCaseNode container,
+ String packageName, DataNodeContainer container,
String moduleYangName, TypeProviderWrapper typeProviderWrapper,
String javaNamePrefix, Module currentModule) {
for (RpcDefinition rpc : currentModule.getRpcs()) {
ContainerSchemaNode input = rpc.getInput();
- 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<RpcDefinition> rpcDefinitions = result
- .get(identityQName);
- if (rpcDefinitions == null) {
- throw new IllegalArgumentException(
- "Identity referenced by rpc not found. Identity:"
- + localIdentityName + " , rpc "
- + rpc);
+ 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<RpcDefinition> rpcDefinitions = result
+ .get(identityQName);
+ if (rpcDefinitions == null) {
+ throw new IllegalArgumentException(
+ "Identity referenced by rpc not found. Identity:"
+ + localIdentityName + " , rpc "
+ + rpc);
+ }
+ rpcDefinitions.add(rpc);
}
- rpcDefinitions.add(rpc);
}
}
-
}
}
}
ContainerSchemaNode container = (ContainerSchemaNode) child;
// this can be either TO or hierarchical RB
TOAttribute toAttribute = TOAttribute.create(container,
- typeProviderWrapper);
+ typeProviderWrapper, packageName);
attributes.add(toAttribute);
} else if (child instanceof ListSchemaNode) {
if (isInnerStateBean(child)) {
runtimeBeanEntries.add(hierarchicalChild);
} else /* ordinary list attribute */{
ListAttribute listAttribute = ListAttribute.create(
- (ListSchemaNode) child, typeProviderWrapper);
+ (ListSchemaNode) child, typeProviderWrapper, packageName);
attributes.add(listAttribute);
}
+ } else if (child instanceof LeafListSchemaNode) {
+ ListAttribute listAttribute = ListAttribute.create(
+ (LeafListSchemaNode) child, typeProviderWrapper);
+ attributes.add(listAttribute);
} else {
- throw new IllegalStateException("Unknown running-data node "
- + child + " , " + "" + "expected leaf or container");
+ throw new IllegalStateException("Unexpected running-data node "
+ + child);
}
}
Set<Rpc> rpcs = new HashSet<>();
}
// convert RpcDefinition to Rpc
for (RpcDefinition rpcDefinition : rpcDefinitions) {
- String name = ModuleMXBeanEntry
+ String name = TypeProviderWrapper
.findJavaParameter(rpcDefinition);
- String returnType;
+ AttributeIfc returnType;
if (rpcDefinition.getOutput() == null
|| rpcDefinition.getOutput().getChildNodes().size() == 0) {
- returnType = "void";
+ returnType = VoidAttribute.getInstance();
} else if (rpcDefinition.getOutput().getChildNodes().size() == 1) {
DataSchemaNode returnDSN = rpcDefinition.getOutput()
.getChildNodes().iterator().next();
- checkArgument(
- returnDSN instanceof LeafSchemaNode,
- "Unexpected type of rpc return type. "
- + "Currently only leafs and empty output nodes are supported, got "
- + returnDSN);
- LeafSchemaNode returnLeaf = (LeafSchemaNode) returnDSN;
- // We currently expect leaf defined in output element in yang to be named result
- // FIXME: value of result is fully qualified name - should be extended to accept TOs
- String localName = returnLeaf.getQName().getLocalName();
- checkArgument(
- localName.equals("result"),
- "Unexpected name of leaf in output element, expected leaf named result, was %s at %s",
- localName, currentModule.getName());
-
- returnType = typeProviderWrapper.getType(returnLeaf)
- .getFullyQualifiedName();
+ returnType = getReturnTypeAttribute(returnDSN, typeProviderWrapper, packageName);
+
} else {
throw new IllegalArgumentException(
"More than one child node in rpc output is not supported. "
+ "Error occured in " + rpcDefinition);
}
List<JavaAttribute> parameters = new ArrayList<>();
- for (DataSchemaNode childNode : rpcDefinition.getInput()
- .getChildNodes()) {
+ for (DataSchemaNode childNode : sortAttributes(rpcDefinition.getInput()
+ .getChildNodes())) {
if (childNode.isAddedByUses() == false) { // skip
// refined
// context-instance
attributes, rpcs);
}
+ private static AttributeIfc getReturnTypeAttribute(DataSchemaNode child, TypeProviderWrapper typeProviderWrapper,
+ String packageName) {
+ if (child instanceof LeafSchemaNode) {
+ LeafSchemaNode leaf = (LeafSchemaNode) child;
+ return new JavaAttribute(leaf, typeProviderWrapper);
+ } else if (child instanceof ContainerSchemaNode) {
+ ContainerSchemaNode container = (ContainerSchemaNode) child;
+ TOAttribute toAttribute = TOAttribute.create(container, typeProviderWrapper, packageName);
+ return toAttribute;
+ } else if (child instanceof ListSchemaNode) {
+ return ListAttribute.create((ListSchemaNode) child, typeProviderWrapper, packageName);
+ } else if (child instanceof LeafListSchemaNode) {
+ return ListAttribute.create((LeafListSchemaNode) child, typeProviderWrapper);
+ } else {
+ throw new IllegalStateException("Unknown output data node " + child + " for rpc");
+ }
+ }
+
+ private static Collection<DataSchemaNode> sortAttributes(Set<DataSchemaNode> childNodes) {
+ final TreeSet<DataSchemaNode> dataSchemaNodes = new TreeSet<>(new Comparator<DataSchemaNode>() {
+ @Override
+ public int compare(DataSchemaNode o1, DataSchemaNode o2) {
+ return o1.getQName().getLocalName().compareTo(o2.getQName().getLocalName());
+ }
+ });
+ dataSchemaNodes.addAll(childNodes);
+ return dataSchemaNodes;
+ }
+
private static boolean isInnerStateBean(DataSchemaNode child) {
for (UnknownSchemaNode unknownSchemaNode : child
.getUnknownSchemaNodes()) {
"More than one key is not supported in " + listSchemaNode);
}
- String javaNamePrefix = ModuleMXBeanEntry
+ String javaNamePrefix = TypeProviderWrapper
.findJavaNamePrefix(listSchemaNode);
RuntimeBeanEntry rbFromAttributes = new RuntimeBeanEntry(packageName,
}
private static RuntimeBeanEntry createRoot(String packageName,
- DataSchemaNode nodeForReporting, String attributeYangName,
+ DataNodeContainer nodeForReporting, String attributeYangName,
List<AttributeIfc> attributes, String javaNamePrefix,
List<RuntimeBeanEntry> children, Set<Rpc> rpcs) {
return new RuntimeBeanEntry(packageName, nodeForReporting,
public static class Rpc {
private final String name;
private final List<JavaAttribute> parameters;
- private final String returnType;
+ private final AttributeIfc returnType;
private final String yangName;
- Rpc(String returnType, String name, String yangName,
+ Rpc(AttributeIfc returnType, String name, String yangName,
List<JavaAttribute> parameters) {
this.returnType = returnType;
this.name = name;
return parameters;
}
- public String getReturnType() {
+ public AttributeIfc getReturnType() {
return returnType;
}
}