YMS migration to onos-yangtool 1.10
Change-Id: I22ddf23f813840e0afec1e7713a86891f2a52f28
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ydt/YdtUtils.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ydt/YdtUtils.java
new file mode 100644
index 0000000..a9f15f2
--- /dev/null
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ydt/YdtUtils.java
@@ -0,0 +1,303 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * 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 org.onosproject.yangutils.datamodel.YangAugment;
+import org.onosproject.yangutils.datamodel.YangSchemaNode;
+import org.onosproject.yangutils.datamodel.YangSchemaNodeContextInfo;
+import org.onosproject.yangutils.datamodel.YangSchemaNodeIdentifier;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yms.app.ydt.exceptions.YdtException;
+import org.onosproject.yms.ydt.YdtContextOperationType;
+
+import static org.onosproject.yms.app.ydt.YdtAppNodeOperationType.DELETE_ONLY;
+import static org.onosproject.yms.app.ydt.YdtAppNodeOperationType.OTHER_EDIT;
+import static org.onosproject.yms.app.ydt.YdtConstants.errorMsg;
+import static org.onosproject.yms.ydt.YdtContextOperationType.CREATE;
+import static org.onosproject.yms.ydt.YdtContextOperationType.DELETE;
+import static org.onosproject.yms.ydt.YdtContextOperationType.MERGE;
+
+/**
+ * Utils to support yang data tree node creation.
+ */
+final class YdtUtils {
+
+ // YDT formatted error string
+ private static final String E_CREATE_OP =
+ "Create request is not allowed under delete operation.";
+ private static final String E_DELETE_OP =
+ "Delete request is not allowed under create operation.";
+ private static final String FMT_TOO_FEW =
+ "Too few key parameters in %s. Expected %d; actual %d.";
+ private static final String FMT_TOO_MANY =
+ "Too many key parameters in %s. Expected %d; actual %d.";
+
+ //No instantiation.
+ private YdtUtils() {
+ }
+
+ /**
+ * Returns the app tree operation type with the help of YdtOperation type.
+ *
+ * @param opType ydt operation type
+ * @return app tree operation type
+ */
+ static YdtAppNodeOperationType getAppOpTypeFromYdtOpType(
+ YdtContextOperationType opType) {
+ // Get the app tree operation type.
+ switch (opType) {
+ case CREATE:
+ case MERGE:
+ case REPLACE:
+ return OTHER_EDIT;
+
+ case DELETE:
+ case REMOVE:
+ return DELETE_ONLY;
+
+ default:
+ return null;
+ //TODO handle the default data type.
+ }
+ }
+
+ /**
+ * Validates the various combination of operation type.
+ *
+ * @param parentOpType Reference for parent node operation type
+ * @param childOpType type of YANG data tree node operation
+ * @throws YdtException when user requested node operation type is
+ * not valid as per parent node operation type
+ */
+ private static void validateOperationType(YdtContextOperationType parentOpType,
+ YdtContextOperationType childOpType)
+ throws YdtException {
+
+ switch (parentOpType) {
+ case CREATE:
+ // Inside the create operation delete operation should not come.
+ if (childOpType == DELETE) {
+ throw new YdtException(E_CREATE_OP);
+ }
+ break;
+ case DELETE:
+ // Inside the delete operation create operation should not come.
+ if (childOpType == CREATE) {
+ throw new YdtException(E_DELETE_OP);
+ }
+ break;
+ default:
+ //TODO check all possible scenario.
+ }
+ }
+
+ /**
+ * Returns the operation type for non leaf node.
+ * When "operation" attribute for current node is not specified or null,
+ * then the operation applied to the parent data node of the
+ * configuration is used. If no parent data node is available,
+ * then the default-operation'value is used.
+ * If default operation type is not set, merge will be taken as default
+ * operation type.
+ *
+ * @param type operation type of parent node
+ * @param defType YDT default operation type
+ * @return operation type for current non leaf node
+ */
+ private static YdtContextOperationType getOperationType(
+ YdtContextOperationType type, YdtContextOperationType defType) {
+ return type != null ? type : (defType != null ? defType : MERGE);
+ }
+
+ /**
+ * Returns the yang node identifier with requested name and namespace.
+ *
+ * @param name name of the node
+ * @param namespace namespace of the node
+ * @return yang node identifier
+ */
+ static YangSchemaNodeIdentifier getNodeIdentifier(String name,
+ String namespace) {
+ YangSchemaNodeIdentifier id = new YangSchemaNodeIdentifier();
+ id.setName(name);
+ id.setNameSpace(new NameSpace(namespace));
+ return id;
+ }
+
+ /**
+ * Checks the user supplied list of argument match's the expected value
+ * or not.
+ *
+ * @param name name of the parent list/leaf-list node
+ * @param expected count suppose to be
+ * @param actual user supplied values count
+ * @throws YdtException when user requested multi instance node instance's
+ * count doesn't fit into the allowed instance limit
+ */
+ static void checkElementCount(String name, int expected,
+ int actual) throws YdtException {
+ if (expected < actual) {
+ throw new YdtException(
+ errorMsg(FMT_TOO_MANY, name, expected, actual));
+ } else if (expected > actual) {
+ throw new YdtException(
+ errorMsg(FMT_TOO_FEW, name, expected, actual));
+ }
+ }
+
+ /**
+ * Returns the valid operation type for requested ydt node after performing
+ * validation.
+ *
+ * @param opType user requested operation type
+ * @param newNode new requested ydt node
+ * @param parentNode parent node under which new node to be added
+ * @return operation type
+ * @throws YdtException when user requested node operation type is
+ * not valid as per parent node operation type
+ */
+ static YdtContextOperationType getValidOpType(
+ YdtContextOperationType opType, YdtContextOperationType defOpType,
+ YdtNode newNode, YdtNode parentNode)
+ throws YdtException {
+
+ switch (newNode.getYdtType()) {
+
+ case SINGLE_INSTANCE_NODE:
+ case MULTI_INSTANCE_NODE:
+
+ // Reference for parent node operation type.
+ YdtContextOperationType parentOpType =
+ parentNode.getYdtContextOperationType();
+
+ if (opType == null) {
+ opType = getOperationType(parentOpType, defOpType);
+ } else if (parentOpType != null) {
+ validateOperationType(parentOpType, opType);
+ }
+
+ return opType;
+
+ /*
+ * Nodes other then single/multi instance node does not support
+ * operation type so no need of validation for those.
+ */
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Returns augmenting node module yang schema node.
+ *
+ * @param id schema node identifier
+ * @param contextInfo Yang Schema node context info
+ * which is having YangSchemaNode and
+ * ContextSwitchedNode
+ * @return augmenting node module yang schema node
+ * @throws YdtException when user requested node schema doesn't exist
+ */
+ public static YangSchemaNode getAugmentingSchemaNode(
+ YangSchemaNodeIdentifier id,
+ YangSchemaNodeContextInfo contextInfo) throws YdtException {
+ YangSchemaNode lastAugMod = null;
+ YangSchemaNode switchedNode =
+ contextInfo.getContextSwitchedNode();
+
+ // Finding the last augmenting schema for case/choice scenario.
+ while (switchedNode != null) {
+ if (switchedNode instanceof YangAugment) {
+ lastAugMod = switchedNode;
+ }
+ try {
+ switchedNode = switchedNode.getChildSchema(id)
+ .getContextSwitchedNode();
+ } catch (DataModelException e) {
+ throw new YdtException(e.getMessage());
+ }
+ }
+ return lastAugMod;
+ }
+
+ /**
+ * De-reference all the tree node by walking the whole YDT from logical
+ * root node.
+ * This will be called only when any exception occurs while processing
+ * the node in Ydt tree.
+ *
+ * @param rootNode ydt logical root node
+ */
+ public static void freeRestResources(YdtNode rootNode) {
+
+ YdtNode currentNode = rootNode;
+ while (currentNode != null) {
+
+ // Move down to first child
+ YdtNode nextNode = currentNode.getFirstChild();
+ if (nextNode != null) {
+ currentNode = nextNode;
+ continue;
+ }
+
+ // No child nodes, so walk tree
+ while (currentNode != null) {
+ // To keep the track of last sibling.
+ YdtNode lastSibling = currentNode;
+
+ // Move to sibling if possible.
+ nextNode = currentNode.getNextSibling();
+
+ // free currentNode resources
+ free(lastSibling);
+
+ lastSibling.getNamespace();
+ if (nextNode != null) {
+ currentNode = nextNode;
+ break;
+ }
+
+ // Move up
+ if (currentNode.equals(rootNode)) {
+ currentNode = null;
+ } else {
+ currentNode = currentNode.getParent();
+ lastSibling.setParent(null);
+ }
+ }
+ }
+ }
+
+ /**
+ * Free the give YDT node by de-referencing it to null.
+ *
+ * @param node node to be freed
+ */
+ private static void free(YdtNode node) {
+ if (node.getParent() != null) {
+ YdtNode parent = node.getParent();
+ parent.setChild(null);
+ parent.setLastChild(null);
+ if (node.getNextSibling() != null) {
+ parent.setChild(node.getNextSibling());
+ }
+ }
+ YdtNode parentRef = node.getParent();
+ node = new YdtLogicalNode(null, null);
+ node.setParent(parentRef);
+ }
+}