Bug 735 - Part 1: Update ietf-restconf and ietf-yangtypes to newer versions
[yangtools.git] / code-generator / binding-generator-impl / src / main / java / org / opendaylight / yangtools / sal / binding / generator / impl / BindingSchemaContextUtils.java
1 package org.opendaylight.yangtools.sal.binding.generator.impl;
2
3 import java.util.HashSet;
4 import java.util.Iterator;
5 import java.util.Set;
6
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
26 import com.google.common.base.Optional;
27 import com.google.common.base.Preconditions;
28
29 public class BindingSchemaContextUtils {
30
31     // FIXME: THis method does not search in case augmentations.
32     public static Optional<DataNodeContainer> findDataNodeContainer(final SchemaContext ctx,
33             final InstanceIdentifier<?> path) {
34         Iterator<PathArgument> pathArguments = path.getPathArguments().iterator();
35         PathArgument currentArg = pathArguments.next();
36         Preconditions.checkArgument(currentArg != null);
37         QName currentQName = BindingReflections.findQName(currentArg.getType());
38
39         Optional<DataNodeContainer> currentContainer = Optional.absent();
40         if (BindingReflections.isNotification(currentArg.getType())) {
41             currentContainer = findNotification(ctx, currentQName);
42         } else if (BindingReflections.isRpcType(currentArg.getType())) {
43             currentContainer = findFirstDataNodeContainerInRpc(ctx, currentArg.getType());
44         } else {
45             currentContainer = findDataNodeContainer(ctx, currentQName);
46         }
47
48         while (currentContainer.isPresent() && pathArguments.hasNext()) {
49             currentArg = pathArguments.next();
50             if (Augmentation.class.isAssignableFrom(currentArg.getType())) {
51                 currentQName = BindingReflections.findQName(currentArg.getType());
52                 if(pathArguments.hasNext()) {
53                     currentArg = pathArguments.next();
54                 } else {
55                     return Optional.absent();
56                 }
57             }
58             if(ChildOf.class.isAssignableFrom(currentArg.getType()) && BindingReflections.isAugmentationChild(currentArg.getType())) {
59                 currentQName = BindingReflections.findQName(currentArg.getType());
60             } else {
61                 currentQName = QName.create(currentQName, BindingReflections.findQName(currentArg.getType()).getLocalName());
62             }
63             Optional<DataNodeContainer> potential = findDataNodeContainer(currentContainer.get(), currentQName);
64             if (potential.isPresent()) {
65                 currentContainer = potential;
66             } else {
67                 return Optional.absent();
68             }
69         }
70         return currentContainer;
71     }
72
73     private static Optional<DataNodeContainer> findNotification(final SchemaContext ctx, final QName notificationQName) {
74         for (NotificationDefinition notification : ctx.getNotifications()) {
75             if (notification.getQName().equals(notificationQName)) {
76                 return Optional.<DataNodeContainer> of(notification);
77             }
78         }
79         return Optional.absent();
80     }
81
82     private static Optional<DataNodeContainer> findDataNodeContainer(final DataNodeContainer ctx,
83             final QName targetQName) {
84
85         for (DataSchemaNode child : ctx.getChildNodes()) {
86             if (child instanceof ChoiceNode) {
87                 DataNodeContainer potential = findInCases(((ChoiceNode) child), targetQName);
88                 if (potential != null) {
89                     return Optional.of(potential);
90                 }
91             } else if (child instanceof DataNodeContainer && child.getQName().equals(targetQName)) {
92                 return Optional.of((DataNodeContainer) child);
93             } else if (child instanceof DataNodeContainer //
94                     && child.isAddedByUses() //
95                     && child.getQName().getLocalName().equals(targetQName.getLocalName())) {
96                 return Optional.of((DataNodeContainer) child);
97             }
98
99         }
100         return Optional.absent();
101     }
102
103     private static DataNodeContainer findInCases(final ChoiceNode choiceNode, final QName targetQName) {
104         for (ChoiceCaseNode caze : choiceNode.getCases()) {
105             Optional<DataNodeContainer> potential = findDataNodeContainer(caze, targetQName);
106             if (potential.isPresent()) {
107                 return potential.get();
108             }
109         }
110         return null;
111     }
112
113     private static Optional<DataNodeContainer> findFirstDataNodeContainerInRpc(final SchemaContext ctx,
114             final Class<? extends DataObject> targetType) {
115         try {
116             YangModuleInfo moduleInfo = BindingReflections.getModuleInfo(targetType);
117             for(RpcDefinition rpc : ctx.getOperations()) {
118                 String rpcNamespace = rpc.getQName().getNamespace().toString();
119                 String rpcRevision = rpc.getQName().getFormattedRevision();
120                 if(moduleInfo.getNamespace().equals(rpcNamespace) && moduleInfo.getRevision().equals(rpcRevision)) {
121                     Optional<DataNodeContainer> potential = findInputOutput(rpc,targetType.getSimpleName());
122                     if(potential.isPresent()) {
123                         return potential;
124                     }
125                 }
126             }
127         } catch (Exception e) {
128             // FIXME: Add logging
129         }
130         return Optional.absent();
131     }
132
133     private static Optional<DataNodeContainer> findInputOutput(final RpcDefinition rpc, final String targetType) {
134         String rpcName = BindingMapping.getClassName(rpc.getQName());
135         String rpcInputName = rpcName + BindingMapping.RPC_INPUT_SUFFIX;
136         String rpcOutputName = rpcName + BindingMapping.RPC_OUTPUT_SUFFIX;
137         if(targetType.equals(rpcInputName)) {
138             return Optional.<DataNodeContainer>of(rpc.getInput());
139         } else if (targetType.equals(rpcOutputName)) {
140             return Optional.<DataNodeContainer>of(rpc.getOutput());
141         }
142        return Optional.absent();
143     }
144
145     public static Set<AugmentationSchema> collectAllAugmentationDefinitions(final SchemaContext currentSchema, final AugmentationTarget ctxNode) {
146         HashSet<AugmentationSchema> augmentations = new HashSet<>();
147         augmentations.addAll(ctxNode.getAvailableAugmentations());
148         if(ctxNode instanceof DataSchemaNode && ((DataSchemaNode) ctxNode).isAddedByUses()) {
149
150             System.out.println(ctxNode);
151
152         }
153
154         // TODO Auto-generated method stub
155         return augmentations;
156     }
157
158 }