2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.parser.util;
11 import java.util.ArrayList;
12 import java.util.Date;
13 import java.util.HashSet;
14 import java.util.List;
17 import java.util.TreeMap;
19 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
20 import org.opendaylight.yangtools.yang.model.api.Module;
21 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
22 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
23 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
24 import org.opendaylight.yangtools.yang.parser.builder.api.DataNodeContainerBuilder;
25 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
26 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
27 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingMember;
28 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
29 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
30 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
31 import org.opendaylight.yangtools.yang.parser.builder.impl.RpcDefinitionBuilder;
32 import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
34 public class GroupingUtils {
37 * Search given modules for grouping by name defined in uses node.
40 * builder of uses statement
45 * @return grouping with given name if found, null otherwise
47 public static GroupingBuilder getTargetGroupingFromModules(final UsesNodeBuilder usesBuilder,
48 final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
49 final int line = usesBuilder.getLine();
50 final String groupingString = usesBuilder.getGroupingName();
51 String groupingPrefix;
54 if (groupingString.contains(":")) {
55 String[] splitted = groupingString.split(":");
56 if (splitted.length != 2 || groupingString.contains("/")) {
57 throw new YangParseException(module.getName(), line, "Invalid name of target grouping");
59 groupingPrefix = splitted[0];
60 groupingName = splitted[1];
62 groupingPrefix = module.getPrefix();
63 groupingName = groupingString;
66 ModuleBuilder dependentModule = null;
67 if (groupingPrefix.equals(module.getPrefix())) {
68 dependentModule = module;
70 dependentModule = ParserUtils.findDependentModuleBuilder(modules, module, groupingPrefix, line);
73 if (dependentModule == null) {
77 GroupingBuilder result = null;
78 Set<GroupingBuilder> groupings = dependentModule.getGroupingBuilders();
79 result = findGroupingBuilder(groupings, groupingName);
84 Builder parent = usesBuilder.getParent();
86 while (parent != null) {
87 if (parent instanceof DataNodeContainerBuilder) {
88 groupings = ((DataNodeContainerBuilder) parent).getGroupingBuilders();
89 } else if (parent instanceof RpcDefinitionBuilder) {
90 groupings = ((RpcDefinitionBuilder) parent).getGroupings();
92 result = findGroupingBuilder(groupings, groupingName);
94 parent = parent.getParent();
100 if (result == null) {
101 throw new YangParseException(module.getName(), line, "Referenced grouping '" + groupingName
108 * Search context for grouping by name defined in uses node.
111 * builder of uses statement
115 * SchemaContext containing already resolved modules
116 * @return grouping with given name if found, null otherwise
118 public static GroupingDefinition getTargetGroupingFromContext(final UsesNodeBuilder usesBuilder,
119 final ModuleBuilder module, final SchemaContext context) {
120 final int line = usesBuilder.getLine();
121 String groupingString = usesBuilder.getGroupingName();
122 String groupingPrefix;
125 if (groupingString.contains(":")) {
126 String[] splitted = groupingString.split(":");
127 if (splitted.length != 2 || groupingString.contains("/")) {
128 throw new YangParseException(module.getName(), line, "Invalid name of target grouping");
130 groupingPrefix = splitted[0];
131 groupingName = splitted[1];
133 groupingPrefix = module.getPrefix();
134 groupingName = groupingString;
137 Module dependentModule = ParserUtils.findModuleFromContext(context, module, groupingPrefix, line);
138 return findGroupingDefinition(dependentModule.getGroupings(), groupingName);
142 * Find grouping by name.
145 * collection of grouping builders to search
148 * @return grouping with given name if present in collection, null otherwise
150 public static GroupingBuilder findGroupingBuilder(Set<GroupingBuilder> groupings, String name) {
151 for (GroupingBuilder grouping : groupings) {
152 if (grouping.getQName().getLocalName().equals(name)) {
160 * Find grouping by name.
163 * collection of grouping definitions to search
166 * @return grouping with given name if present in collection, null otherwise
168 public static GroupingDefinition findGroupingDefinition(Set<GroupingDefinition> groupings, String name) {
169 for (GroupingDefinition grouping : groupings) {
170 if (grouping.getQName().getLocalName().equals(name)) {
178 * Copy target grouping data to given uses node.
180 * Copy all data-schema-nodes, groupings, typedefs and unknown nodes from
181 * target grouping to uses node.
185 * @param targetGrouping
187 public static void loadTargetGroupingData(final UsesNodeBuilder usesNode, final GroupingBuilder targetGrouping) {
189 Set<DataSchemaNodeBuilder> targetChildren = new HashSet<>();
190 for (DataSchemaNodeBuilder targetChild : targetGrouping.getChildNodeBuilders()) {
191 targetChildren.add(CopyUtils.copy(targetChild, usesNode.getParent(), true));
193 usesNode.setTargetChildren(targetChildren);
196 Set<GroupingBuilder> targetGroupingGroupings = new HashSet<>();
197 for (GroupingBuilder targetGroupingGrouping : targetGrouping.getGroupingBuilders()) {
198 targetGroupingGroupings.add(CopyUtils.copy(targetGroupingGrouping, usesNode.getParent(), true));
200 usesNode.setTargetGroupings(targetGroupingGroupings);
203 Set<TypeDefinitionBuilder> targetGroupingTypedefs = new HashSet<>();
204 for(TypeDefinitionBuilder targetGroupingTypedef : targetGrouping.getTypeDefinitionBuilders()) {
205 targetGroupingTypedefs.add(CopyUtils.copy(targetGroupingTypedef, usesNode.getParent(), true));
207 usesNode.setTargetTypedefs(targetGroupingTypedefs);
210 List<UnknownSchemaNodeBuilder> targetGroupingUNs = new ArrayList<>();
211 for(UnknownSchemaNodeBuilder targetGroupingUN : targetGrouping.getUnknownNodeBuilders()) {
212 targetGroupingUNs.add(CopyUtils.copy(targetGroupingUN, usesNode.getParent(), true));
214 usesNode.setTargetUnknownNodes(targetGroupingUNs);
216 usesNode.setLoadDone(true);
220 * Copy all data from target grouping which were added by uses.
222 * Traverse uses statements in target grouping and copy all
223 * data-schema-nodes, groupings, typedefs and unknown nodes to current uses
228 * @param targetGrouping
230 public static void loadTargetGroupingUses(final UsesNodeBuilder usesNode, final GroupingBuilder targetGrouping) {
231 usesNode.getTargetGroupingUses().addAll(targetGrouping.getUsesNodes());
235 * Create copy of collection of given nodes with new schema path.
240 * schema path of parent node
242 * new namespace of node qname
244 * new revision of node qname
246 * new prefix of node qname
248 * current yang module name
250 * current line in yang module
251 * @return collection of new nodes with corrected path
253 public static Set<DataSchemaNodeBuilder> copyUsesTargetNodesWithNewPath(UsesNodeBuilder usesNode, Builder parent) {
254 Set<DataSchemaNodeBuilder> newNodes = new HashSet<>();
256 for (DataSchemaNodeBuilder node : usesNode.getTargetChildren()) {
258 if (node instanceof GroupingMember) {
259 ((GroupingMember) node).setAddedByUses(true);
269 * Create copy of collection of given groupings with new schema path.
274 * schema path of parent node
276 * new namespace of node qname
278 * new revision of node qname
280 * new prefix of node qname
281 * @return collection of new groupings with corrected path
283 public static Set<GroupingBuilder> copyUsesTargetGroupingsWithNewPath(UsesNodeBuilder usesNode,
284 SchemaPath parentPath, URI namespace, Date revision, String prefix) {
285 Set<GroupingBuilder> newGroupings = new HashSet<>();
286 for (GroupingBuilder node : usesNode.getTargetGroupings()) {
288 if (node instanceof GroupingMember) {
289 ((GroupingMember) node).setAddedByUses(true);
291 newGroupings.add(node);
299 * Create copy of collection of given typedefs with new schema path.
304 * schema path of parent node
306 * new namespace of node qname
308 * new revision of node qname
310 * new prefix of node qname
311 * @return collection of new typedefs with corrected path
313 public static Set<TypeDefinitionBuilder> copyUsesTargetTypedefsWithNewPath(UsesNodeBuilder usesNode,
314 SchemaPath parentPath, URI namespace, Date revision, String prefix) {
315 Set<TypeDefinitionBuilder> newTypedefs = new HashSet<>();
317 for (TypeDefinitionBuilder node : usesNode.getTargetTypedefs()) {
319 if (node instanceof GroupingMember) {
320 ((GroupingMember) node).setAddedByUses(true);
322 newTypedefs.add(node);
330 * Create copy of collection of given unknown nodes with new schema path.
334 * schema path of parent node
336 * new namespace of node qname
338 * new revision of node qname
340 * new prefix of node qname
341 * @return collection of new unknownNodes with corrected path
343 public static List<UnknownSchemaNodeBuilder> copyUsesTargetUnknownNodesWithNewPath(UsesNodeBuilder usesNode,
344 SchemaPath parentPath, URI namespace, Date revision, String prefix) {
345 List<UnknownSchemaNodeBuilder> newUnknownNodes = new ArrayList<>();
347 for (UnknownSchemaNodeBuilder node : usesNode.getTargetUnknownNodes()) {
349 node.setAddedByUses(true);
350 newUnknownNodes.add(node);
354 return newUnknownNodes;