blob: fe3769723b2da4eea36be8e52f1b3c1f205496e9 [file] [log] [blame]
Sithara Punnassery4b091dc2017-03-02 17:22:40 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Sithara Punnassery4b091dc2017-03-02 17:22:40 -08003 *
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.config;
17
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -070018import java.util.Arrays;
Sithara Punnassery4b091dc2017-03-02 17:22:40 -080019import java.util.Iterator;
Sithara Punnassery44e2a702017-03-06 15:38:10 -080020
Sithara Punnasserybc9edb12017-07-20 14:32:33 -070021import java.util.LinkedList;
Sithara Punnassery44e2a702017-03-06 15:38:10 -080022import java.util.List;
23
24import org.onosproject.yang.model.KeyLeaf;
25import org.onosproject.yang.model.LeafListKey;
26import org.onosproject.yang.model.ListKey;
Sithara Punnassery4b091dc2017-03-02 17:22:40 -080027import org.onosproject.yang.model.NodeKey;
28import org.onosproject.yang.model.ResourceId;
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -070029import org.slf4j.Logger;
30import org.slf4j.LoggerFactory;
Sithara Punnassery4b091dc2017-03-02 17:22:40 -080031
Yuta HIGUCHI3b5d64e2017-09-12 22:44:22 -070032import com.google.common.annotations.Beta;
33
Yuta HIGUCHIde667842017-07-12 17:19:24 -070034// FIXME add non-trivial examples
Sithara Punnassery4b091dc2017-03-02 17:22:40 -080035/**
Sithara Punnassery44e2a702017-03-06 15:38:10 -080036 * Utilities to work on the ResourceId.
Yuta HIGUCHIde667842017-07-12 17:19:24 -070037 * <p>
38 * Examples:
39 * <dl>
40 * <dt>root node</dt>
41 * <dd>root</dd>
42 * </dl>
43 *
Sithara Punnassery4b091dc2017-03-02 17:22:40 -080044 */
Sithara Punnasserybda82502017-03-22 19:08:19 -070045//FIXME add javadocs
Yuta HIGUCHI3b5d64e2017-09-12 22:44:22 -070046@Beta
Sithara Punnassery4b091dc2017-03-02 17:22:40 -080047public final class ResourceIdParser {
48
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -070049 private static final Logger log = LoggerFactory.getLogger(ResourceIdParser.class);
50
Yuta HIGUCHIde667842017-07-12 17:19:24 -070051 /**
52 * root node name.
53 */
Sithara Punnassery44e2a702017-03-06 15:38:10 -080054 public static final String ROOT = "root";
Yuta HIGUCHIde667842017-07-12 17:19:24 -070055
56 /**
57 * Separator between SchemaId components and value part.
58 */
Sithara Punnassery44e2a702017-03-06 15:38:10 -080059 public static final String NM_SEP = "#";
Yuta HIGUCHIde667842017-07-12 17:19:24 -070060 // TODO not used in #parseResId(ResourceId)??
Sithara Punnassery44e2a702017-03-06 15:38:10 -080061 public static final String VAL_SEP = "@";
Yuta HIGUCHIde667842017-07-12 17:19:24 -070062 /**
63 * Separator between ListKey schemaId and keyLeafs.
64 */
Sithara Punnassery44e2a702017-03-06 15:38:10 -080065 public static final String KEY_SEP = "$";
Yuta HIGUCHIde667842017-07-12 17:19:24 -070066 /**
67 * Separator between {@code NodeKey}s (~=tree nodes).
68 */
Sithara Punnasserybda82502017-03-22 19:08:19 -070069 public static final String EL_SEP = "|";
Yuta HIGUCHIde667842017-07-12 17:19:24 -070070
Sithara Punnassery4cd2ced2017-03-17 17:36:43 -070071 public static final String VAL_CHK = "\\@";
72 public static final String KEY_CHK = "\\$";
Sithara Punnasserybda82502017-03-22 19:08:19 -070073 public static final String NM_CHK = "\\#";
Sithara Punnassery0b51d432017-03-28 01:09:28 -070074 public static final String EL_CHK = "\\|";
Sithara Punnassery44e2a702017-03-06 15:38:10 -080075
76
Sithara Punnassery4b091dc2017-03-02 17:22:40 -080077 private ResourceIdParser() {
78
79 }
Sithara Punnassery44e2a702017-03-06 15:38:10 -080080
Sithara Punnassery44e2a702017-03-06 15:38:10 -080081 public static NodeKey getInstanceKey(ResourceId path) {
82 int last = path.nodeKeys().size();
Ray Milkeyef310052018-02-06 08:58:51 -080083 return path.nodeKeys().get(last - 1);
Sithara Punnassery44e2a702017-03-06 15:38:10 -080084 }
85
86 public static NodeKey getMultiInstanceKey(ResourceId path) {
87 int last = path.nodeKeys().size();
88 NodeKey ret = path.nodeKeys().get(last - 1);
89 if (ret instanceof ListKey) {
90 return ret;
91 } else {
92 return null;
93 }
94 }
95
Sithara Punnassery4cd2ced2017-03-17 17:36:43 -070096 public static String getNamespace(String nmspc) {
97 String ret = null;
98 if (nmspc.contains(ResourceIdParser.KEY_SEP)) {
99 ret = nmspc.split(KEY_CHK)[0];
100 } else if (nmspc.contains(ResourceIdParser.VAL_SEP)) {
101 ret = nmspc.split(VAL_CHK)[0];
102 } else {
103 ret = nmspc;
104 }
105 return ret;
106 }
107
108 public static String getKeyVal(String nmspc) {
109 String ret = null;
110 if (nmspc.contains(ResourceIdParser.VAL_SEP)) {
111 ret = nmspc.split(VAL_CHK)[1];
112 }
113 return ret;
114 }
115
Sithara Punnassery44e2a702017-03-06 15:38:10 -0800116 public static String appendMultiInstKey(String path, String leaf) {
117 return (path + leaf.substring(leaf.indexOf(KEY_SEP)));
118 }
119
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700120 // 1.12.0 - not used by anyone
121 @Deprecated
Sithara Punnassery44e2a702017-03-06 15:38:10 -0800122 public static String appendKeyLeaf(String path, String key) {
123 return (path + EL_SEP + key);
124 }
125
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700126 // 1.12.0 - not used by anyone
127 @Deprecated
Sithara Punnassery44e2a702017-03-06 15:38:10 -0800128 public static String appendKeyLeaf(String path, KeyLeaf key) {
Sithara Punnassery4b091dc2017-03-02 17:22:40 -0800129 StringBuilder bldr = new StringBuilder();
Sithara Punnassery44e2a702017-03-06 15:38:10 -0800130 bldr.append(key.leafSchema().name());
131 bldr.append(NM_SEP);
132 bldr.append(key.leafSchema().namespace());
133 bldr.append(NM_SEP);
134 bldr.append(key.leafValue().toString());
135 return (path + EL_SEP + bldr.toString());
136 }
137
138 public static String appendNodeKey(String path, NodeKey key) {
Yuta HIGUCHI3b5d64e2017-09-12 22:44:22 -0700139 // FIXME this is not handling root path exception
Sithara Punnassery44e2a702017-03-06 15:38:10 -0800140 return (path + EL_SEP + key.schemaId().name() + NM_SEP + key.schemaId().namespace());
141 }
142
143 public static String appendNodeKey(String path, String name, String nmSpc) {
144 return (path + EL_SEP + name + NM_SEP + nmSpc);
145 }
146
147 public static String appendLeafList(String path, LeafListKey key) {
Sithara Punnassery4cd2ced2017-03-17 17:36:43 -0700148 return (path + VAL_SEP + key.asString());
Sithara Punnassery44e2a702017-03-06 15:38:10 -0800149 }
150
151 public static String appendLeafList(String path, String val) {
Sithara Punnassery4cd2ced2017-03-17 17:36:43 -0700152 return (path + VAL_SEP + val);
Sithara Punnassery44e2a702017-03-06 15:38:10 -0800153 }
154
155 public static String appendKeyList(String path, ListKey key) {
156 StringBuilder bldr = new StringBuilder();
157 for (KeyLeaf keyLeaf : key.keyLeafs()) {
158 bldr.append(KEY_SEP);
159 bldr.append(keyLeaf.leafSchema().name());
160 bldr.append(NM_SEP);
161 bldr.append(keyLeaf.leafSchema().namespace());
162 bldr.append(NM_SEP);
163 bldr.append(keyLeaf.leafValue().toString());
164 }
165 return (path + bldr.toString());
166 }
167
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700168 // 1.12.0 - not used by anyone
169 @Deprecated
Sithara Punnassery44e2a702017-03-06 15:38:10 -0800170 public static String parseNodeKey(NodeKey key) {
171 if (key == null) {
172 return null;
173 }
174 StringBuilder bldr = new StringBuilder();
175 if (key instanceof LeafListKey) {
176 parseLeafList((LeafListKey) key, bldr);
177 } else if (key instanceof ListKey) {
178 parseKeyList((ListKey) key, bldr);
179 } else {
180 parseNodeKey(key, bldr);
181 }
Sithara Punnassery4b091dc2017-03-02 17:22:40 -0800182 return bldr.toString();
183 }
Sithara Punnassery44e2a702017-03-06 15:38:10 -0800184
Yuta HIGUCHIde667842017-07-12 17:19:24 -0700185 /**
186 * Gets String representation of ResourceId.
187 * <p>
188 * <pre>
189 * ResourceId := 'root' ('|' element)*
190 * element := LeafListKey | ListKey | NodeKey
191 * SchemaId := [string SchemaId#name] '#' [string SchemaId#namespace]
192 * LeafListKey := SchemaId '#' [string representation of LeafListKey#value]
193 * ListKey := SchemaId (KeyLeaf)*
194 * KeyLeaf := '$' SchemaId '#' [string representation of KeyLeaf#leafValue]
195 * NodeKey := SchemaId
196 * </pre>
197 *
198 * @param path to convert
199 * @return String representation
200 */
Sithara Punnassery44e2a702017-03-06 15:38:10 -0800201 public static String parseResId(ResourceId path) {
202 StringBuilder bldr = new StringBuilder();
203 bldr.append(ROOT);
204 if (path == null) {
205 return bldr.toString();
206 }
Sithara Punnasserybc9edb12017-07-20 14:32:33 -0700207 List<NodeKey> nodeKeyList = new LinkedList<>();
208 Iterator<NodeKey> itr = path.nodeKeys().iterator();
209 while (itr.hasNext()) {
210 nodeKeyList.add(itr.next());
211 }
Yuta HIGUCHI3b5d64e2017-09-12 22:44:22 -0700212 // exception for dealing with root
213 if (nodeKeyList.get(0).schemaId().name().equals("/")) {
Sithara Punnasserybc9edb12017-07-20 14:32:33 -0700214 nodeKeyList.remove(0);
215 }
Sithara Punnassery44e2a702017-03-06 15:38:10 -0800216 for (NodeKey key : nodeKeyList) {
217 bldr.append(EL_SEP);
218 if (key instanceof LeafListKey) {
219 parseLeafList((LeafListKey) key, bldr);
220 } else if (key instanceof ListKey) {
221 parseKeyList((ListKey) key, bldr);
222 } else {
223 parseNodeKey(key, bldr);
224 }
225 }
226 return bldr.toString();
227 }
228
229 private static void parseLeafList(LeafListKey key, StringBuilder bldr) {
230 bldr.append(key.schemaId().name());
231 bldr.append(NM_SEP);
232 bldr.append(key.schemaId().namespace());
233 bldr.append(NM_SEP);
234 bldr.append(key.asString());
235 }
236
237 private static void parseKeyList(ListKey key, StringBuilder bldr) {
238 bldr.append(key.schemaId().name());
239 bldr.append(NM_SEP);
240 bldr.append(key.schemaId().namespace());
Sithara Punnassery44e2a702017-03-06 15:38:10 -0800241 Iterator<KeyLeaf> iter = key.keyLeafs().iterator();
242 KeyLeaf next;
243 while (iter.hasNext()) {
244 next = iter.next();
245 bldr.append(KEY_SEP);
246 bldr.append(next.leafSchema().name());
247 bldr.append(NM_SEP);
248 bldr.append(next.leafSchema().namespace());
249 bldr.append(NM_SEP);
250 bldr.append(next.leafValue().toString());
251 }
252 }
253
254 private static void parseNodeKey(NodeKey key, StringBuilder bldr) {
255 bldr.append(key.schemaId().name());
256 bldr.append(NM_SEP);
257 bldr.append(key.schemaId().namespace());
258 }
259
260 public static ResourceId getResId(List<String> dpath) {
261 ResourceId.Builder resBldr = new ResourceId.Builder();
262 Iterator<String> itr = dpath.iterator();
263 itr.next();
264 while (itr.hasNext()) {
265 String name = itr.next();
266 if (name.contains(VAL_SEP)) {
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700267 // dead branch? VAL_SEP never used in parseResId
Sithara Punnassery44e2a702017-03-06 15:38:10 -0800268 resBldr.addLeafListBranchPoint(name.substring(0, name.indexOf(NM_SEP)),
269 name.substring(name.indexOf(NM_SEP) + 1, name.indexOf(VAL_SEP)),
270 name.substring(name.indexOf(VAL_SEP) + 1));
271 } else if (name.contains(KEY_SEP)) {
Sithara Punnasserybda82502017-03-22 19:08:19 -0700272 String[] keys = name.split(KEY_CHK);
273 String[] nm = keys[0].split(NM_CHK);
274 resBldr.addBranchPointSchema(nm[0], nm[1]);
Sithara Punnassery44e2a702017-03-06 15:38:10 -0800275 for (int i = 1; i < keys.length; i++) {
276 String key = keys[i];
Sithara Punnasserybda82502017-03-22 19:08:19 -0700277 String[] el = keys[i].split(NM_CHK);
278 if (el.length != 3) {
Yuta HIGUCHIdbc08c02018-02-12 16:40:05 -0800279 throw new FailedException("Malformed event subject, cannot parse " +
280 key + " in " + dpath);
Sithara Punnasserybda82502017-03-22 19:08:19 -0700281 }
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700282 try {
Sithara Punnasserybda82502017-03-22 19:08:19 -0700283 resBldr.addKeyLeaf(el[0], el[1], el[2]);
Yuta HIGUCHIe057dee2017-09-15 13:56:10 -0700284 } catch (Exception e) {
285 log.error("dpath={}", dpath);
286 log.error("name={}", name);
287 log.error("key={}", key);
288 log.error("el={}", Arrays.asList(el));
289 throw e;
290 }
Sithara Punnassery44e2a702017-03-06 15:38:10 -0800291 }
292 } else {
293 resBldr.addBranchPointSchema(name.substring(0, name.indexOf(NM_SEP)),
294 name.substring(name.indexOf(NM_SEP) + 1));
295 }
296 }
297 return resBldr.build();
298 }
Sithara Punnassery4b091dc2017-03-02 17:22:40 -0800299}