1 package org.opendaylight.yangtools.sal.binding.generator.impl;
3 import java.util.HashSet;
4 import java.util.Iterator;
7 import org.opendaylight.yangtools.yang.binding.Augmentation;
8 import org.opendaylight.yangtools.yang.binding.BindingMapping;
9 import org.opendaylight.yangtools.yang.binding.ChildOf;
10 import org.opendaylight.yangtools.yang.binding.DataObject;
11 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
12 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
13 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
14 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
15 import org.opendaylight.yangtools.yang.common.QName;
16 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
17 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
18 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
19 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
20 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
21 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
22 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
23 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
24 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
25 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
26 import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils;
28 import com.google.common.base.Optional;
29 import com.google.common.base.Preconditions;
31 public class BindingSchemaContextUtils {
33 // FIXME: THis method does not search in case augmentations.
34 public static Optional<DataNodeContainer> findDataNodeContainer(final SchemaContext ctx,
35 final InstanceIdentifier<?> path) {
36 Iterator<PathArgument> pathArguments = path.getPathArguments().iterator();
37 PathArgument currentArg = pathArguments.next();
38 Preconditions.checkArgument(currentArg != null);
39 QName currentQName = BindingReflections.findQName(currentArg.getType());
41 Optional<DataNodeContainer> currentContainer = Optional.absent();
42 if (BindingReflections.isNotification(currentArg.getType())) {
43 currentContainer = findNotification(ctx, currentQName);
44 } else if (BindingReflections.isRpcType(currentArg.getType())) {
45 currentContainer = findFirstDataNodeContainerInRpc(ctx, currentArg.getType());
46 if(currentQName == null && currentContainer.isPresent()) {
47 currentQName = ((DataSchemaNode) currentContainer.get()).getQName();
50 currentContainer = findDataNodeContainer(ctx, currentQName);
53 while (currentContainer.isPresent() && pathArguments.hasNext()) {
54 currentArg = pathArguments.next();
55 if (Augmentation.class.isAssignableFrom(currentArg.getType())) {
56 currentQName = BindingReflections.findQName(currentArg.getType());
57 if(pathArguments.hasNext()) {
58 currentArg = pathArguments.next();
60 return currentContainer;
63 if(ChildOf.class.isAssignableFrom(currentArg.getType()) && BindingReflections.isAugmentationChild(currentArg.getType())) {
64 currentQName = BindingReflections.findQName(currentArg.getType());
66 currentQName = QName.create(currentQName, BindingReflections.findQName(currentArg.getType()).getLocalName());
68 Optional<DataNodeContainer> potential = findDataNodeContainer(currentContainer.get(), currentQName);
69 if (potential.isPresent()) {
70 currentContainer = potential;
72 return Optional.absent();
75 return currentContainer;
78 private static Optional<DataNodeContainer> findNotification(final SchemaContext ctx, final QName notificationQName) {
79 for (NotificationDefinition notification : ctx.getNotifications()) {
80 if (notification.getQName().equals(notificationQName)) {
81 return Optional.<DataNodeContainer> of(notification);
84 return Optional.absent();
87 private static Optional<DataNodeContainer> findDataNodeContainer(final DataNodeContainer ctx,
88 final QName targetQName) {
90 for (DataSchemaNode child : ctx.getChildNodes()) {
91 if (child instanceof ChoiceNode) {
92 DataNodeContainer potential = findInCases(((ChoiceNode) child), targetQName);
93 if (potential != null) {
94 return Optional.of(potential);
96 } else if (child instanceof DataNodeContainer && child.getQName().equals(targetQName)) {
97 return Optional.of((DataNodeContainer) child);
98 } else if (child instanceof DataNodeContainer //
99 && child.isAddedByUses() //
100 && child.getQName().getLocalName().equals(targetQName.getLocalName())) {
101 return Optional.of((DataNodeContainer) child);
105 return Optional.absent();
108 private static DataNodeContainer findInCases(final ChoiceNode choiceNode, final QName targetQName) {
109 for (ChoiceCaseNode caze : choiceNode.getCases()) {
110 Optional<DataNodeContainer> potential = findDataNodeContainer(caze, targetQName);
111 if (potential.isPresent()) {
112 return potential.get();
118 private static Optional<DataNodeContainer> findFirstDataNodeContainerInRpc(final SchemaContext ctx,
119 final Class<? extends DataObject> targetType) {
120 final YangModuleInfo moduleInfo;
122 moduleInfo = BindingReflections.getModuleInfo(targetType);
123 } catch (Exception e) {
124 throw new IllegalArgumentException(
125 String.format("Failed to load module information for class %s", targetType), e);
128 for(RpcDefinition rpc : ctx.getOperations()) {
129 String rpcNamespace = rpc.getQName().getNamespace().toString();
130 String rpcRevision = rpc.getQName().getFormattedRevision();
131 if(moduleInfo.getNamespace().equals(rpcNamespace) && moduleInfo.getRevision().equals(rpcRevision)) {
132 Optional<DataNodeContainer> potential = findInputOutput(rpc,targetType.getSimpleName());
133 if(potential.isPresent()) {
138 return Optional.absent();
141 private static Optional<DataNodeContainer> findInputOutput(final RpcDefinition rpc, final String targetType) {
142 String rpcName = BindingMapping.getClassName(rpc.getQName());
143 String rpcInputName = rpcName + BindingMapping.RPC_INPUT_SUFFIX;
144 String rpcOutputName = rpcName + BindingMapping.RPC_OUTPUT_SUFFIX;
145 if(targetType.equals(rpcInputName)) {
146 return Optional.<DataNodeContainer>of(rpc.getInput());
147 } else if (targetType.equals(rpcOutputName)) {
148 return Optional.<DataNodeContainer>of(rpc.getOutput());
150 return Optional.absent();
153 public static Set<AugmentationSchema> collectAllAugmentationDefinitions(final SchemaContext currentSchema, final AugmentationTarget ctxNode) {
154 HashSet<AugmentationSchema> augmentations = new HashSet<>();
155 augmentations.addAll(ctxNode.getAvailableAugmentations());
156 if(ctxNode instanceof DataSchemaNode && ((DataSchemaNode) ctxNode).isAddedByUses()) {
158 System.out.println(ctxNode);
162 // TODO Auto-generated method stub
163 return augmentations;
166 public static Optional<ChoiceNode> findInstantiatedChoice(final DataNodeContainer parent, final Class<?> choiceClass) {
167 return findInstantiatedChoice(parent, BindingReflections.findQName(choiceClass));
170 public static Optional<ChoiceNode> findInstantiatedChoice(final DataNodeContainer ctxNode, final QName choiceName) {
171 DataSchemaNode potential = ctxNode.getDataChildByName(choiceName);
172 if (potential == null) {
173 potential = ctxNode.getDataChildByName(choiceName.getLocalName());
176 if (potential instanceof ChoiceNode) {
177 return Optional.of((ChoiceNode) potential);
180 return Optional.absent();
183 public static Optional<ChoiceCaseNode> findInstantiatedCase(final ChoiceNode instantiatedChoice, final ChoiceCaseNode originalDefinition) {
184 ChoiceCaseNode potential = instantiatedChoice.getCaseNodeByName(originalDefinition.getQName());
185 if(originalDefinition.equals(potential)) {
186 return Optional.of(potential);
188 if (potential != null) {
189 SchemaNode potentialRoot = SchemaNodeUtils.getRootOriginalIfPossible(potential);
190 if (originalDefinition.equals(potentialRoot)) {
191 return Optional.of(potential);
194 // We try to find case by name, then lookup its root definition
195 // and compare it with original definition
196 // This solves case, if choice was inside grouping
197 // which was used in different module and thus namespaces are
198 // different, but local names are still same.
200 // Still we need to check equality of definition, because local name is not
201 // sufficient to uniquelly determine equality of cases
203 potential = instantiatedChoice.getCaseNodeByName(originalDefinition.getQName().getLocalName());
204 if(potential != null && (originalDefinition.equals(SchemaNodeUtils.getRootOriginalIfPossible(potential)))) {
205 return Optional.of(potential);
207 return Optional.absent();