1 package org.opendaylight.yangtools.sal.binding.generator.impl;
3 import com.google.common.base.Optional;
4 import com.google.common.base.Preconditions;
5 import java.util.HashSet;
6 import java.util.Iterator;
8 import org.opendaylight.yangtools.yang.binding.Augmentation;
9 import org.opendaylight.yangtools.yang.binding.BindingMapping;
10 import org.opendaylight.yangtools.yang.binding.ChildOf;
11 import org.opendaylight.yangtools.yang.binding.DataObject;
12 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
13 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
14 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
15 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
16 import org.opendaylight.yangtools.yang.common.QName;
17 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
18 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
19 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
20 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
21 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
22 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
23 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
24 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
25 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
26 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
27 import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils;
29 public final class BindingSchemaContextUtils {
31 private BindingSchemaContextUtils() {
32 throw new UnsupportedOperationException("Utility class should not be instantiated");
35 // FIXME: THis method does not search in case augmentations.
36 public static Optional<DataNodeContainer> findDataNodeContainer(final SchemaContext ctx,
37 final InstanceIdentifier<?> path) {
38 Iterator<PathArgument> pathArguments = path.getPathArguments().iterator();
39 PathArgument currentArg = pathArguments.next();
40 Preconditions.checkArgument(currentArg != null);
41 QName currentQName = BindingReflections.findQName(currentArg.getType());
43 Optional<DataNodeContainer> currentContainer = Optional.absent();
44 if (BindingReflections.isNotification(currentArg.getType())) {
45 currentContainer = findNotification(ctx, currentQName);
46 } else if (BindingReflections.isRpcType(currentArg.getType())) {
47 currentContainer = findFirstDataNodeContainerInRpc(ctx, currentArg.getType());
48 if(currentQName == null && currentContainer.isPresent()) {
49 currentQName = ((DataSchemaNode) currentContainer.get()).getQName();
52 currentContainer = findDataNodeContainer(ctx, currentQName);
55 while (currentContainer.isPresent() && pathArguments.hasNext()) {
56 currentArg = pathArguments.next();
57 if (Augmentation.class.isAssignableFrom(currentArg.getType())) {
58 currentQName = BindingReflections.findQName(currentArg.getType());
59 if(pathArguments.hasNext()) {
60 currentArg = pathArguments.next();
62 return currentContainer;
65 if(ChildOf.class.isAssignableFrom(currentArg.getType()) && BindingReflections.isAugmentationChild(currentArg.getType())) {
66 currentQName = BindingReflections.findQName(currentArg.getType());
68 currentQName = QName.create(currentQName, BindingReflections.findQName(currentArg.getType()).getLocalName());
70 Optional<DataNodeContainer> potential = findDataNodeContainer(currentContainer.get(), currentQName);
71 if (potential.isPresent()) {
72 currentContainer = potential;
74 return Optional.absent();
77 return currentContainer;
80 private static Optional<DataNodeContainer> findNotification(final SchemaContext ctx, final QName notificationQName) {
81 for (NotificationDefinition notification : ctx.getNotifications()) {
82 if (notification.getQName().equals(notificationQName)) {
83 return Optional.<DataNodeContainer> of(notification);
86 return Optional.absent();
89 private static Optional<DataNodeContainer> findDataNodeContainer(final DataNodeContainer ctx,
90 final QName targetQName) {
92 for (DataSchemaNode child : ctx.getChildNodes()) {
93 if (child instanceof ChoiceSchemaNode) {
94 DataNodeContainer potential = findInCases(((ChoiceSchemaNode) child), targetQName);
95 if (potential != null) {
96 return Optional.of(potential);
98 } else if (child instanceof DataNodeContainer && child.getQName().equals(targetQName)) {
99 return Optional.of((DataNodeContainer) child);
100 } else if (child instanceof DataNodeContainer //
101 && child.isAddedByUses() //
102 && child.getQName().getLocalName().equals(targetQName.getLocalName())) {
103 return Optional.of((DataNodeContainer) child);
107 return Optional.absent();
110 private static DataNodeContainer findInCases(final ChoiceSchemaNode choiceNode, final QName targetQName) {
111 for (ChoiceCaseNode caze : choiceNode.getCases()) {
112 Optional<DataNodeContainer> potential = findDataNodeContainer(caze, targetQName);
113 if (potential.isPresent()) {
114 return potential.get();
120 private static Optional<DataNodeContainer> findFirstDataNodeContainerInRpc(final SchemaContext ctx,
121 final Class<? extends DataObject> targetType) {
122 final YangModuleInfo moduleInfo;
124 moduleInfo = BindingReflections.getModuleInfo(targetType);
125 } catch (Exception e) {
126 throw new IllegalArgumentException(
127 String.format("Failed to load module information for class %s", targetType), e);
130 for(RpcDefinition rpc : ctx.getOperations()) {
131 String rpcNamespace = rpc.getQName().getNamespace().toString();
132 String rpcRevision = rpc.getQName().getFormattedRevision();
133 if(moduleInfo.getNamespace().equals(rpcNamespace) && moduleInfo.getRevision().equals(rpcRevision)) {
134 Optional<DataNodeContainer> potential = findInputOutput(rpc,targetType.getSimpleName());
135 if(potential.isPresent()) {
140 return Optional.absent();
143 private static Optional<DataNodeContainer> findInputOutput(final RpcDefinition rpc, final String targetType) {
144 String rpcName = BindingMapping.getClassName(rpc.getQName());
145 String rpcInputName = rpcName + BindingMapping.RPC_INPUT_SUFFIX;
146 String rpcOutputName = rpcName + BindingMapping.RPC_OUTPUT_SUFFIX;
147 if(targetType.equals(rpcInputName)) {
148 return Optional.<DataNodeContainer>of(rpc.getInput());
149 } else if (targetType.equals(rpcOutputName)) {
150 return Optional.<DataNodeContainer>of(rpc.getOutput());
152 return Optional.absent();
155 public static Set<AugmentationSchema> collectAllAugmentationDefinitions(final SchemaContext currentSchema, final AugmentationTarget ctxNode) {
156 HashSet<AugmentationSchema> augmentations = new HashSet<>();
157 augmentations.addAll(ctxNode.getAvailableAugmentations());
158 if(ctxNode instanceof DataSchemaNode && ((DataSchemaNode) ctxNode).isAddedByUses()) {
160 System.out.println(ctxNode);
164 // TODO Auto-generated method stub
165 return augmentations;
168 public static Optional<ChoiceSchemaNode> findInstantiatedChoice(final DataNodeContainer parent, final Class<?> choiceClass) {
169 return findInstantiatedChoice(parent, BindingReflections.findQName(choiceClass));
172 public static Optional<ChoiceSchemaNode> findInstantiatedChoice(final DataNodeContainer ctxNode, final QName choiceName) {
173 DataSchemaNode potential = ctxNode.getDataChildByName(choiceName);
174 if (potential == null) {
175 potential = ctxNode.getDataChildByName(choiceName.getLocalName());
178 if (potential instanceof ChoiceSchemaNode) {
179 return Optional.of((ChoiceSchemaNode) potential);
182 return Optional.absent();
185 public static Optional<ChoiceCaseNode> findInstantiatedCase(final ChoiceSchemaNode instantiatedChoice, final ChoiceCaseNode originalDefinition) {
186 ChoiceCaseNode potential = instantiatedChoice.getCaseNodeByName(originalDefinition.getQName());
187 if(originalDefinition.equals(potential)) {
188 return Optional.of(potential);
190 if (potential != null) {
191 SchemaNode potentialRoot = SchemaNodeUtils.getRootOriginalIfPossible(potential);
192 if (originalDefinition.equals(potentialRoot)) {
193 return Optional.of(potential);
196 // We try to find case by name, then lookup its root definition
197 // and compare it with original definition
198 // This solves case, if choice was inside grouping
199 // which was used in different module and thus namespaces are
200 // different, but local names are still same.
202 // Still we need to check equality of definition, because local name is not
203 // sufficient to uniquelly determine equality of cases
205 potential = instantiatedChoice.getCaseNodeByName(originalDefinition.getQName().getLocalName());
206 if(potential != null && (originalDefinition.equals(SchemaNodeUtils.getRootOriginalIfPossible(potential)))) {
207 return Optional.of(potential);
209 return Optional.absent();