blob: 1691d2a306c137f74695e8a0c5ad2ccdd3f8d494 [file] [log] [blame]
/*
* Copyright 2016-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.yms.app.ydt;
import com.google.common.collect.ImmutableList;
import org.onosproject.yangutils.datamodel.YangList;
import org.onosproject.yangutils.datamodel.YangSchemaNode;
import org.onosproject.yangutils.datamodel.YangSchemaNodeIdentifier;
import org.onosproject.yms.app.ydt.exceptions.YdtException;
import org.onosproject.yms.ydt.YdtContext;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import static org.onosproject.yms.app.ydt.YdtConstants.errorMsg;
import static org.onosproject.yms.ydt.YdtType.MULTI_INSTANCE_NODE;
/**
* Represents a multi instance node in YANG data tree.
*/
public class YdtMultiInstanceNode extends YdtNode {
// YDT formatted error string
private static final String FMT_MISSING_KEY =
"%s is missing some of the keys of %s.";
private static final String FMT_UNI_KEY =
"Some of the key elements are not unique in %s.";
private static final String FMT_MANY_INS =
"Too many instances of %s. Expected maximum instances %d.";
private static final String FMT_FEW_INS =
"Too few instances of %s. Expected minimum instances %d.";
/*
* Reference for list of key element's ydtContext.
*/
private List<YdtContext> keyNodeList = new ArrayList<>();
/*
* Reference for composite key string for multi Instance Node..
*/
private String compositeKey;
/**
* Creates a YANG multi instance node object.
*
* @param node schema of YDT multi instance node .
*/
YdtMultiInstanceNode(YangSchemaNode node) {
super(MULTI_INSTANCE_NODE, node);
}
/**
* Returns the composite key string for current multi instance node.
*
* @return composite key string
*/
private String getCompositeKey() {
return compositeKey;
}
/**
* Returns the list of key element's ydtContext.
*
* @return list of key element's ydtContext
*/
public List<YdtContext> getKeyNodeList() {
return ImmutableList.copyOf(keyNodeList);
}
@Override
public void createKeyNodeList() throws YdtException {
YangList yangListHolder = (YangList) getYangSchemaNode();
List<String> schemaKeyList = yangListHolder.getKeyList();
/*
* If key element not defined in schema or config is false then
* return no need to do create key list.
*/
if (schemaKeyList == null || !yangListHolder.isConfig()) {
return;
}
StringBuilder ksb = new StringBuilder();
// Iterator for schema key name list.
Iterator<String> sklItr = schemaKeyList.iterator();
List<YdtContext> nodeList = new ArrayList<>();
YangSchemaNodeIdentifier id = new YangSchemaNodeIdentifier();
id.setNameSpace(new NameSpace(getNamespace()));
// This loop should run while schema key list is not finished
while (sklItr.hasNext()) {
String name = sklItr.next();
id.setName(name);
YdtNode<YdtSingleInstanceLeafNode> collidingChild =
(YdtNode<YdtSingleInstanceLeafNode>) ydtNodeMap.get(id);
if (collidingChild == null) {
throw new YdtException(
errorMsg(FMT_MISSING_KEY, yangListHolder.getParent()
.getName(), yangListHolder.getName()));
}
/*
* Preparing composite key string by concatenating values of
* all the key leaf.
*/
ksb.append(collidingChild.getValue());
nodeList.add(collidingChild);
}
//Setting te key object in List.
keyNodeList = nodeList;
compositeKey = ksb.toString();
}
/**
* Validates the given list of instances by verifying the allowed
* instance count and key element uniqueness.
*
* @param keyStringSet set to validate the key element uniqueness
* @param list list of instance's of same list
* @throws YdtException when user requested multi instance node instance's
* count doesn't fit into the allowed instance's limit
* or doesn't have unique key's
*/
public void validateInstances(Set keyStringSet, List list)
throws YdtException {
// Clearing the set.
keyStringSet.clear();
/*
* Storing the number of multiInstance node for number
* if instance validation.
*/
int instanceCount = list.size();
YangList listSchema = (YangList) ((YdtMultiInstanceNode) list.get(0))
.getYangSchemaNode();
validateInstanceCount(instanceCount, listSchema);
if (listSchema.isConfig() && instanceCount > 1) {
/*
* Iterating over values in ydtNodeList of
* multiInstanceNode and compare the key string.
*/
for (YdtNode ydtNode : (List<YdtNode<YdtMultiInstanceNode>>) list) {
if (!keyStringSet.add(((YdtMultiInstanceNode) ydtNode)
.getCompositeKey())) {
throw new YdtException(
errorMsg(FMT_UNI_KEY, ydtNode.getName()));
}
}
}
}
/**
* Validates the instance count for given list entry.
*
* @param instanceCount actual count
* @param list list entry for which instance count need
* to be validated
* @throws YdtException when user requested multi instance node instance's
* count doesn't fit into the allowed instance's limit
*/
private void validateInstanceCount(int instanceCount, YangList list)
throws YdtException {
if (list.getMinElements() != null) {
int minElement = list.getMinElements().getMinElement();
if (instanceCount < minElement) {
throw new YdtException(errorMsg(FMT_FEW_INS, list.getName(),
minElement));
}
}
if (list.getMaxElements() != null) {
int maxElement = list.getMaxElements().getMaxElement();
if (instanceCount > maxElement) {
throw new YdtException(errorMsg(FMT_MANY_INS, list.getName(),
maxElement));
}
}
}
}