[ONOS-4670] Removal of Data Model dependencies on Linker
Change-Id: I3f9c5af30198ea31d743e06cea1764dcb306ec32
diff --git a/src/main/java/org/onosproject/yangutils/datamodel/utils/RestrictionResolver.java b/src/main/java/org/onosproject/yangutils/datamodel/utils/RestrictionResolver.java
new file mode 100644
index 0000000..4148278
--- /dev/null
+++ b/src/main/java/org/onosproject/yangutils/datamodel/utils/RestrictionResolver.java
@@ -0,0 +1,268 @@
+/*
+ * 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.yangutils.datamodel.utils;
+
+import java.util.regex.Pattern;
+import org.onosproject.yangutils.datamodel.YangDataTypes;
+import org.onosproject.yangutils.datamodel.YangRangeInterval;
+import org.onosproject.yangutils.datamodel.YangRangeRestriction;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.utils.YangConstructType;
+import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangBuiltInDataTypeInfo;
+
+import static org.onosproject.yangutils.datamodel.YangDataTypes.DECIMAL64;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.INT16;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.INT32;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.INT64;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.INT8;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.UINT16;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.UINT32;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.UINT64;
+import static org.onosproject.yangutils.datamodel.YangDataTypes.UINT8;
+import static org.onosproject.yangutils.utils.UtilConstants.ADD;
+import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
+import static org.onosproject.yangutils.utils.YangConstructType.LENGTH_DATA;
+import static org.onosproject.yangutils.utils.YangConstructType.RANGE_DATA;
+import static org.onosproject.yangutils.datamodel.utils.builtindatatype.BuiltInTypeObjectFactory.getDataObjectFromString;
+
+/**
+ * Represents restriction resolver which provide common utility used by parser
+ * and during linking for restriction resolution.
+ */
+public final class RestrictionResolver {
+
+ private static final String PIPE = "|";
+ private static final String INTERVAL = "..";
+ private static final int MAX_RANGE_BOUNDARY = 2;
+ private static final int MIN_RANGE_BOUNDARY = 1;
+ private static final String MIN_KEYWORD = "min";
+ private static final String MAX_KEYWORD = "max";
+
+ /**
+ * Creates a restriction resolver.
+ */
+ private RestrictionResolver() {
+ }
+
+ /**
+ * Processes the range restriction for parser and linker.
+ *
+ * @param refRangeRestriction range restriction of referred typedef
+ * @param lineNumber error line number
+ * @param charPositionInLine error character position in line
+ * @param hasReferredRestriction whether has referred restriction
+ * @param curRangeString caller type's range string
+ * @param effectiveType effective type, when called from linker
+ * @return YANG range restriction
+ * @throws DataModelException a violation in data model rule
+ */
+ public static YangRangeRestriction processRangeRestriction(YangRangeRestriction refRangeRestriction,
+ int lineNumber, int charPositionInLine,
+ boolean hasReferredRestriction,
+ String curRangeString, YangDataTypes effectiveType)
+ throws DataModelException {
+ YangBuiltInDataTypeInfo<?> startValue;
+ YangBuiltInDataTypeInfo<?> endValue;
+ YangRangeRestriction rangeRestriction = new YangRangeRestriction();
+
+ String rangeArgument = removeQuotesAndHandleConcat(curRangeString);
+ String[] rangeArguments = rangeArgument.trim().split(Pattern.quote(PIPE));
+
+ for (String rangePart : rangeArguments) {
+ String startInterval;
+ String endInterval;
+ YangRangeInterval rangeInterval = new YangRangeInterval();
+ String[] rangeBoundary = rangePart.trim().split(Pattern.quote(INTERVAL));
+
+ if (rangeBoundary.length > MAX_RANGE_BOUNDARY) {
+ DataModelException dataModelException = new DataModelException("YANG file error : " +
+ YangConstructType.getYangConstructType(RANGE_DATA) + " " + rangeArgument +
+ " is not valid.");
+ dataModelException.setLine(lineNumber);
+ dataModelException.setCharPosition(charPositionInLine);
+ throw dataModelException;
+ }
+
+ if (rangeBoundary.length == MIN_RANGE_BOUNDARY) {
+ startInterval = rangeBoundary[0].trim();
+ endInterval = rangeBoundary[0].trim();
+ } else {
+ startInterval = rangeBoundary[0].trim();
+ endInterval = rangeBoundary[1].trim();
+ }
+
+ try {
+ if (hasReferredRestriction && startInterval.equals(MIN_KEYWORD)
+ && refRangeRestriction.getMinRestrictedvalue() != null) {
+ startValue = refRangeRestriction.getMinRestrictedvalue();
+ } else if (hasReferredRestriction && startInterval.equals(MAX_KEYWORD)
+ && refRangeRestriction.getMaxRestrictedvalue() != null) {
+ startValue = refRangeRestriction.getMaxRestrictedvalue();
+ } else {
+ startValue = getDataObjectFromString(startInterval, effectiveType);
+ }
+ if (hasReferredRestriction && endInterval.equals(MIN_KEYWORD)
+ && refRangeRestriction.getMinRestrictedvalue() != null) {
+ endValue = refRangeRestriction.getMinRestrictedvalue();
+ } else if (hasReferredRestriction && endInterval.equals(MAX_KEYWORD)
+ && refRangeRestriction.getMaxRestrictedvalue() != null) {
+ endValue = refRangeRestriction.getMaxRestrictedvalue();
+ } else {
+ endValue = getDataObjectFromString(endInterval, effectiveType);
+ }
+ } catch (Exception e) {
+ DataModelException dataModelException = new DataModelException(e.getMessage());
+ dataModelException.setLine(lineNumber);
+ dataModelException.setCharPosition(charPositionInLine);
+ throw dataModelException;
+ }
+
+ rangeInterval.setStartValue(startValue);
+ rangeInterval.setEndValue(endValue);
+
+ try {
+ rangeRestriction.addRangeRestrictionInterval(rangeInterval);
+ } catch (DataModelException dataModelException) {
+ dataModelException.setLine(lineNumber);
+ dataModelException.setCharPosition(charPositionInLine);
+ throw dataModelException;
+ }
+ }
+ return rangeRestriction;
+ }
+
+ /**
+ * Processes the length restriction for parser and linker.
+ *
+ * @param refLengthRestriction length restriction of referred typedef
+ * @param lineNumber error line number
+ * @param charPositionInLine error character position in line
+ * @param hasReferredRestriction whether has referred restriction
+ * @param curLengthString caller type's length string
+ * @return YANG range restriction
+ * @throws DataModelException a violation in data model rule
+ */
+ public static YangRangeRestriction processLengthRestriction(YangRangeRestriction refLengthRestriction,
+ int lineNumber, int charPositionInLine,
+ boolean hasReferredRestriction,
+ String curLengthString) throws DataModelException {
+
+ YangBuiltInDataTypeInfo<?> startValue;
+ YangBuiltInDataTypeInfo<?> endValue;
+ YangRangeRestriction lengthRestriction = new YangRangeRestriction<>();
+
+ String rangeArgument = removeQuotesAndHandleConcat(curLengthString);
+ String[] rangeArguments = rangeArgument.trim().split(Pattern.quote(PIPE));
+
+ for (String rangePart : rangeArguments) {
+ String startInterval;
+ String endInterval;
+ YangRangeInterval rangeInterval = new YangRangeInterval<>();
+ String[] rangeBoundary = rangePart.trim().split(Pattern.quote(INTERVAL));
+
+ if (rangeBoundary.length > MAX_RANGE_BOUNDARY) {
+ DataModelException dataModelException = new DataModelException("YANG file error : " +
+ YangConstructType.getYangConstructType(LENGTH_DATA) + " " + rangeArgument +
+ " is not valid.");
+ dataModelException.setLine(lineNumber);
+ dataModelException.setCharPosition(charPositionInLine);
+ throw dataModelException;
+ }
+
+ if (rangeBoundary.length == MIN_RANGE_BOUNDARY) {
+ startInterval = rangeBoundary[0].trim();
+ endInterval = rangeBoundary[0].trim();
+ } else {
+ startInterval = rangeBoundary[0].trim();
+ endInterval = rangeBoundary[1].trim();
+ }
+
+ try {
+ if (hasReferredRestriction && startInterval.equals(MIN_KEYWORD)
+ && refLengthRestriction.getMinRestrictedvalue() != null) {
+ startValue = refLengthRestriction.getMinRestrictedvalue();
+ } else if (hasReferredRestriction && startInterval.equals(MAX_KEYWORD)
+ && refLengthRestriction.getMaxRestrictedvalue() != null) {
+ startValue = refLengthRestriction.getMaxRestrictedvalue();
+ } else {
+ startValue = getDataObjectFromString(startInterval, YangDataTypes.UINT64);
+ }
+ if (hasReferredRestriction && endInterval.equals(MIN_KEYWORD)
+ && refLengthRestriction.getMinRestrictedvalue() != null) {
+ endValue = refLengthRestriction.getMinRestrictedvalue();
+ } else if (hasReferredRestriction && endInterval.equals(MAX_KEYWORD)
+ && refLengthRestriction.getMaxRestrictedvalue() != null) {
+ endValue = refLengthRestriction.getMaxRestrictedvalue();
+ } else {
+ endValue = getDataObjectFromString(endInterval, YangDataTypes.UINT64);
+ }
+ } catch (Exception e) {
+ DataModelException dataModelException = new DataModelException(e.getMessage());
+ dataModelException.setLine(lineNumber);
+ dataModelException.setCharPosition(charPositionInLine);
+ throw dataModelException;
+ }
+
+ rangeInterval.setStartValue(startValue);
+ rangeInterval.setEndValue(endValue);
+
+ try {
+ lengthRestriction.addRangeRestrictionInterval(rangeInterval);
+ } catch (DataModelException dataModelException) {
+ dataModelException.setLine(lineNumber);
+ dataModelException.setCharPosition(charPositionInLine);
+ throw dataModelException;
+ }
+ }
+ return lengthRestriction;
+ }
+
+ /**
+ * Returns whether the data type is of range restricted type.
+ *
+ * @param dataType data type to be checked
+ * @return true, if data type can have range restrictions, false otherwise
+ */
+ public static boolean isOfRangeRestrictedType(YangDataTypes dataType) {
+ return (dataType == INT8
+ || dataType == INT16
+ || dataType == INT32
+ || dataType == INT64
+ || dataType == UINT8
+ || dataType == UINT16
+ || dataType == UINT32
+ || dataType == UINT64
+ || dataType == DECIMAL64);
+ }
+
+ /**
+ * Removes doubles quotes and concatenates if string has plus symbol.
+ *
+ * @param yangStringData string from yang file
+ * @return concatenated string after removing double quotes
+ */
+ private static String removeQuotesAndHandleConcat(String yangStringData) {
+
+ yangStringData = yangStringData.replace("\"", EMPTY_STRING);
+ String[] tmpData = yangStringData.split(Pattern.quote(ADD));
+ StringBuilder builder = new StringBuilder();
+ for (String yangString : tmpData) {
+ builder.append(yangString);
+ }
+ return builder.toString();
+ }
+}