BUG-865: deprecate pre-Beryllium parser elements
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / builder / impl / GroupingUtils.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.parser.builder.impl;
9
10 import com.google.common.base.Splitter;
11 import java.net.URI;
12 import java.util.Comparator;
13 import java.util.Date;
14 import java.util.Map;
15 import java.util.NavigableMap;
16 import java.util.Set;
17 import org.opendaylight.yangtools.yang.common.QName;
18 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
19 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
20 import org.opendaylight.yangtools.yang.parser.builder.api.DataNodeContainerBuilder;
21 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
22 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
23 import org.opendaylight.yangtools.yang.parser.builder.api.RefineBuilder;
24 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
25 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 /**
30  * @deprecated Pre-Beryllium implementation, scheduled for removal.
31  */
32 @Deprecated
33 public final class GroupingUtils {
34     private static final Logger LOG = LoggerFactory.getLogger(GroupingUtils.class);
35
36     private static final Splitter SLASH_SPLITTER = Splitter.on('/');
37
38     private GroupingUtils() {
39     }
40
41     /**
42      * Search given modules for grouping by name defined in uses node.
43      *
44      * @param usesBuilder
45      *            builder of uses statement
46      * @param modules
47      *            all loaded modules
48      * @param module
49      *            current module
50      * @return grouping with given name, never null
51      * @throws YangParseException
52      *             if no grouping found
53      */
54     public static GroupingBuilder getTargetGroupingFromModules(final UsesNodeBuilder usesBuilder,
55             final Map<URI, NavigableMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
56         final int line = usesBuilder.getLine();
57
58         SchemaPath groupingPath = usesBuilder.getTargetGroupingPath();
59         QName groupingName = groupingPath.getPathFromRoot().iterator().next();
60         ModuleBuilder dependentModule = BuilderUtils.findModule(groupingName, modules);
61
62         Set<GroupingBuilder> groupings = dependentModule.getGroupingBuilders();
63         GroupingBuilder result = findGroupingBuilder(groupings, groupingName.getLocalName());
64         if (result != null) {
65             return result;
66         }
67
68         Builder parent = usesBuilder.getParent();
69         while (parent != null) {
70             if (parent instanceof DataNodeContainerBuilder) {
71                 groupings = ((DataNodeContainerBuilder) parent).getGroupingBuilders();
72             } else if (parent instanceof RpcDefinitionBuilder) {
73                 groupings = ((RpcDefinitionBuilder) parent).getGroupings();
74             }
75             result = findGroupingBuilder(groupings, groupingName.getLocalName());
76             if (result == null) {
77                 parent = parent.getParent();
78             } else {
79                 break;
80             }
81         }
82
83         if (result == null) {
84             throw new YangParseException(module.getName(), line, "Grouping '" + groupingName + "' not found.");
85         }
86         return result;
87     }
88
89     /**
90      * Find grouping by name.
91      *
92      * @param groupings
93      *            collection of grouping builders to search
94      * @param name
95      *            name of grouping
96      * @return grouping with given name if present in collection, null otherwise
97      */
98     private static GroupingBuilder findGroupingBuilder(final Set<GroupingBuilder> groupings, final String name) {
99         for (GroupingBuilder grouping : groupings) {
100             if (grouping.getQName().getLocalName().equals(name)) {
101                 return grouping;
102             }
103         }
104         return null;
105     }
106
107     /**
108      * Perform refinement of uses target grouping nodes. Uses process has to be
109      * already performed.
110      *
111      * @param usesNode
112      *            uses node containing refine statements
113      */
114     public static void performRefine(final UsesNodeBuilder usesNode) {
115         for (RefineBuilder refine : usesNode.getRefines()) {
116             String refineTargetPath = refine.getTargetPathString();
117
118             Builder currentNode = usesNode.getParent();
119             for (String pathElement : SLASH_SPLITTER.split(refineTargetPath)) {
120                 if (currentNode instanceof DataNodeContainerBuilder) {
121                     currentNode = ((DataNodeContainerBuilder) currentNode).getDataChildByName(pathElement);
122                 } else if (currentNode instanceof ChoiceBuilder) {
123                     currentNode = ((ChoiceBuilder) currentNode).getCaseNodeByName(pathElement);
124                 }
125             }
126
127             DataSchemaNodeBuilder nodeToRefine = (DataSchemaNodeBuilder) currentNode;
128             if (nodeToRefine == null) {
129                 // FIXME: exception replaced with log to avoid breakage when
130                 // user tries to refine instance of extension (unknown node)
131
132                 // throw new YangParseException(refine.getModuleName(),
133                 // refine.getLine(), "Refine target node '" +
134                 // refine.getTargetPathString() + "' not found");
135                 LOG.warn("Error in module {} at line {}: Refine target node {} not found.", refine.getModuleName(),
136                         refine.getLine(), refine.getTargetPathString());
137                 continue;
138             }
139             RefineUtils.performRefine(nodeToRefine, refine);
140             usesNode.addRefineNode(nodeToRefine);
141         }
142     }
143
144     public static class UsesComparator implements Comparator<UsesNodeBuilder> {
145         @Override
146         public int compare(final UsesNodeBuilder o1, final UsesNodeBuilder o2) {
147             return getElementPosition(o2) - getElementPosition(o1);
148         }
149     }
150
151     private static int getElementPosition(final UsesNodeBuilder usesNode) {
152         int i = 0;
153         Builder parent = usesNode.getParent();
154         while (!(parent instanceof ModuleBuilder)) {
155             parent = parent.getParent();
156             i++;
157         }
158         return i;
159     }
160
161 }