blob: 4340d278b12aa155b5486646379d5a0ee8dfd8d2 [file] [log] [blame]
Yuta HIGUCHI24057822017-08-02 15:03:51 -07001/*
2 * Copyright 2017-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.d.config;
17
18import static com.google.common.base.Preconditions.checkArgument;
19import static org.slf4j.LoggerFactory.getLogger;
20
21import org.onosproject.yang.model.DataNode;
22import org.onosproject.yang.model.KeyLeaf;
23import org.onosproject.yang.model.LeafListKey;
24import org.onosproject.yang.model.ListKey;
25import org.onosproject.yang.model.NodeKey;
26import org.onosproject.yang.model.ResourceId;
27import org.onosproject.yang.model.ResourceId.Builder;
28import org.onosproject.yang.model.SchemaId;
29import org.slf4j.Logger;
30
31import com.google.common.annotations.Beta;
32
33/**
34 * Utility related to ResourceId.
35 */
36@Beta
37public abstract class ResourceIds {
38
39 private static final Logger log = getLogger(ResourceIds.class);
40
41 /**
42 * Builds the ResourceId of specified {@code node}.
43 *
44 * @param parent ResourceId of {@code node} parent
45 * @param node to create ResourceId.
46 * @return ResourceId of {@code node}
47 */
48 public static ResourceId resourceId(ResourceId parent, DataNode node) {
49 final ResourceId.Builder builder;
50 if (parent == null) {
51 builder = ResourceId.builder();
52 } else {
53 try {
54 builder = parent.copyBuilder();
55 } catch (CloneNotSupportedException e) {
56 throw new IllegalArgumentException(e);
57 }
58 }
59
60 SchemaId sid = node.key().schemaId();
61 switch (node.type()) {
62 case MULTI_INSTANCE_LEAF_VALUE_NODE:
63 builder.addLeafListBranchPoint(sid.name(), sid.namespace(),
64 ((LeafListKey) node.key()).asString());
65 break;
66
67 case MULTI_INSTANCE_NODE:
68 builder.addBranchPointSchema(sid.name(), sid.namespace());
69 for (KeyLeaf keyLeaf : ((ListKey) node.key()).keyLeafs()) {
70 builder.addKeyLeaf(keyLeaf.leafSchema().name(),
71 keyLeaf.leafSchema().namespace(),
72 keyLeaf.leafValAsString());
73 }
74 break;
75
76 case SINGLE_INSTANCE_LEAF_VALUE_NODE:
77 case SINGLE_INSTANCE_NODE:
78 builder.addBranchPointSchema(sid.name(), sid.namespace());
79 break;
80
81 default:
82 throw new IllegalArgumentException("Unknown type " + node);
83
84 }
85
86 return builder.build();
87 }
88
89 /**
90 * Concats {@code path} after {@code prefix}.
91 *
92 * @param prefix path
93 * @param path to append after {@code path}
94 * @return concatenated ResouceId
95 */
96 public static ResourceId concat(ResourceId prefix, ResourceId path) {
97 checkArgument(!path.nodeKeys().contains(DeviceResourceIds.ROOT_NODE),
98 "%s was already absolute path", path);
99 try {
100 return prefix.copyBuilder().append(path).build();
101 } catch (CloneNotSupportedException e) {
102 log.error("Could not copy {}", path, e);
103 throw new IllegalArgumentException("Could not copy " + path, e);
104 }
105 }
106
107
108 /**
109 * Returns {@code child} ad relative ResourceId against {@code base}.
110 *
111 * @param base ResourceId
112 * @param child ResourceId to relativize
113 * @return relative ResourceId
114 */
115 public static ResourceId relativize(ResourceId base, ResourceId child) {
116 checkArgument(child.nodeKeys().size() >= base.nodeKeys().size(),
117 "%s path must be deeper than base prefix %s", child, base);
118 checkArgument(base.nodeKeys().equals(child.nodeKeys().subList(0, base.nodeKeys().size())),
119 "%s is not a prefix of %s", child, base);
120
121 // FIXME waiting for Yang tools 2.2.0-b4 or later
122// return ResourceId.builder().append(child.nodeKeys().subList(base.nodeKeys().size(),
123// child.nodeKeys().size())).build();
124
125 Builder builder = ResourceId.builder();
126 for (NodeKey nodeKey : child.nodeKeys().subList(base.nodeKeys().size(),
127 child.nodeKeys().size())) {
128 if (nodeKey instanceof ListKey) {
129 ListKey listKey = (ListKey) nodeKey;
130 for (KeyLeaf keyLeaf : listKey.keyLeafs()) {
131 builder.addKeyLeaf(keyLeaf.leafSchema().name(),
132 keyLeaf.leafSchema().namespace(),
133 keyLeaf.leafValAsString());
134 }
135 } else if (nodeKey instanceof LeafListKey) {
136 LeafListKey llKey = (LeafListKey) nodeKey;
137 builder.addLeafListBranchPoint(llKey.schemaId().name(),
138 llKey.schemaId().namespace(),
139 llKey.value());
140
141 } else {
142 builder.addBranchPointSchema(nodeKey.schemaId().name(),
143 nodeKey.schemaId().namespace());
144 }
145 }
146 return builder.build();
147 }
148
149 /**
150 * Tests if {@code child} starts with {@code prefix}.
151 *
152 * @param prefix expected
153 * @param child to test
154 * @return true if {@code child} starts with {@code prefix}
155 */
156 public static boolean isPrefix(ResourceId prefix, ResourceId child) {
157
158 return child.nodeKeys().size() >= prefix.nodeKeys().size() &&
159 prefix.nodeKeys().equals(child.nodeKeys().subList(0, prefix.nodeKeys().size()));
160 }
161
162}