[ONOS-4910, ONOS-4921] Framework: utils validation and defect fix

Change-Id: I821920fa8c88e64406b702c2b8736bdeaf231474
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/BuiltInTypeObjectFactory.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/BuiltInTypeObjectFactory.java
index 7be4fc1..b77b6ae 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/BuiltInTypeObjectFactory.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/BuiltInTypeObjectFactory.java
@@ -16,7 +16,6 @@
 package org.onosproject.yangutils.datamodel;
 
 import java.io.Serializable;
-import java.math.BigDecimal;
 import org.onosproject.yangutils.datamodel.utils.builtindatatype.DataTypeException;
 import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangBuiltInDataTypeInfo;
 import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
@@ -80,7 +79,7 @@
                 return (T) new YangUint64(valueInStr);
             }
             case DECIMAL64: {
-                return (T) new YangDecimal64(new BigDecimal(valueInStr));
+                return (T) new YangDecimal64(valueInStr);
             }
             default: {
                 throw new DataTypeException("YANG file error : Unsupported data type");
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangBits.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangBits.java
index b0810e9..3f9cd59 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangBits.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangBits.java
@@ -67,17 +67,6 @@
     }
 
     /**
-     * Creates an instance of YANG bits.
-     *
-     * @param bits set of bit names
-     * @throws DataModelException due to violation in data model rules
-     */
-    public YangBits(String bits) throws DataModelException {
-        String[] bitNames = bits.trim().split(Pattern.quote(SPACE));
-        setBitDataSet(bitNames);
-    }
-
-    /**
      * Returns the bits name.
      *
      * @return the bits name
@@ -229,9 +218,11 @@
      * @param bits set of bit names
      * @return Object of YANG bits
      */
-    public static YangBits fromString(String bits) {
+    public YangBits fromString(String bits) {
         try {
-            return new YangBits(bits);
+            String[] bitNames = bits.trim().split(Pattern.quote(SPACE));
+            setBitDataSet(bitNames);
+            return this;
         } catch (Exception e) {
         }
         return null;
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangChoice.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangChoice.java
index 7aa0d5d..48b763b 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangChoice.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangChoice.java
@@ -84,32 +84,6 @@
     private boolean isConfig;
 
     /**
-     * Reference RFC 6020.
-     *
-     * The "default" statement indicates if a case should be considered as the
-     * default if no child nodes from any of the choice's cases exist. The
-     * argument is the identifier of the "case" statement. If the "default"
-     * statement is missing, there is no default case.
-     *
-     * The "default" statement MUST NOT be present on choices where "mandatory"
-     * is true.
-     *
-     * The default case is only important when considering the default values of
-     * nodes under the cases. The default values for nodes under the default
-     * case are used if none of the nodes under any of the cases are present.
-     *
-     * There MUST NOT be any mandatory nodes directly under the default case.
-     *
-     * Default values for child nodes under a case are only used if one of the
-     * nodes under that case is present, or if that case is the default case. If
-     * none of the nodes under a case are present and the case is not the
-     * default case, the default values of the cases' child nodes are ignored.
-     *
-     * the default case to be used if no case members is present.
-     */
-    private String defaultCase;
-
-    /**
      * Description of choice.
      */
     private String description;
@@ -146,8 +120,28 @@
     private YangStatusType status;
 
     /**
-     * Default value in string, needs to be converted to the target object,
-     * based on the type.
+     * Reference RFC 6020.
+     * <p>
+     * The "default" statement indicates if a case should be considered as the
+     * default if no child nodes from any of the choice's cases exist. The
+     * argument is the identifier of the "case" statement. If the "default"
+     * statement is missing, there is no default case.
+     * <p>
+     * The "default" statement MUST NOT be present on choices where "mandatory"
+     * is true.
+     * <p>
+     * The default case is only important when considering the default values of
+     * nodes under the cases. The default values for nodes under the default
+     * case are used if none of the nodes under any of the cases are present.
+     * <p>
+     * There MUST NOT be any mandatory nodes directly under the default case.
+     * <p>
+     * Default values for child nodes under a case are only used if one of the
+     * nodes under that case is present, or if that case is the default case. If
+     * none of the nodes under a case are present and the case is not the
+     * default case, the default values of the cases' child nodes are ignored.
+     * <p>
+     * the default case to be used if no case members is present.
      */
     private String defaultValueInString;
 
@@ -238,24 +232,6 @@
     }
 
     /**
-     * Returns the default case.
-     *
-     * @return the default case
-     */
-    public String getDefaultCase() {
-        return defaultCase;
-    }
-
-    /**
-     * Sets the default case.
-     *
-     * @param defaultCase the default case to set
-     */
-    public void setDefaultCase(String defaultCase) {
-        this.defaultCase = defaultCase;
-    }
-
-    /**
      * Returns the mandatory status.
      *
      * @return the mandatory status
@@ -378,7 +354,25 @@
      */
     @Override
     public void validateDataOnExit() throws DataModelException {
-        // TODO auto-generated method stub, to be implemented by parser
+        if (defaultValueInString != null && !defaultValueInString.isEmpty()) {
+            YangNode node = getChild();
+            boolean matched = false;
+            // Check whether default string matches the case
+            while (node != null) {
+                if (node instanceof YangCase) {
+                    if (defaultValueInString.equals(((YangCase) node).getName())) {
+                        matched = true;
+                        break;
+                    }
+                }
+                node = node.getNextSibling();
+            }
+
+            if (!matched) {
+                throw new DataModelException("YANG file error: default string \"" + defaultValueInString
+                                                     + "\" not matching choice \"" + getName() + "\" case.");
+            }
+        }
     }
 
     @Override
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangDecimal64.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangDecimal64.java
index 2b19f10..a4c40b1 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangDecimal64.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangDecimal64.java
@@ -20,6 +20,7 @@
 import org.onosproject.yangutils.datamodel.utils.FractionDigits;
 import org.onosproject.yangutils.datamodel.utils.Parsable;
 import org.onosproject.yangutils.datamodel.utils.YangConstructType;
+import org.onosproject.yangutils.datamodel.utils.builtindatatype.DataTypeException;
 import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangBuiltInDataTypeInfo;
 import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
 
@@ -55,6 +56,16 @@
      */
     public static final int MAX_FRACTION_DIGITS_VALUE = 18;
 
+    /**
+     * Valid minimum value of YANG's decimal64.
+     */
+    public static final BigDecimal MIN_VALUE = BigDecimal.valueOf(-922337203685477580.8);
+
+    /**
+     * Valid maximum value of YANG's decimal64.
+     */
+    public static final BigDecimal MAX_VALUE = BigDecimal.valueOf(922337203685477580.7);
+
     // Decimal64 value
     private BigDecimal value;
 
@@ -84,11 +95,29 @@
     /**
      * Creates an instance of YANG decimal64.
      *
-     * @param value of decimal64 in string
-     * @throws DataModelException a violation of data model rules
+     * @param valueInString of decimal64 in string
      */
-    public YangDecimal64(String value) throws DataModelException {
-        fromString(value);
+    public YangDecimal64(String valueInString) {
+        if (valueInString.matches(MIN_KEYWORD)) {
+            value = MIN_VALUE;
+        } else if (valueInString.matches(MAX_KEYWORD)) {
+            value = MAX_VALUE;
+        } else {
+            try {
+                value = new BigDecimal(valueInString);
+            } catch (Exception e) {
+                throw new DataTypeException("YANG file error : Input value \"" + valueInString + "\" is not a valid " +
+                                                    "decimal64.");
+            }
+        }
+
+        if (value.doubleValue() < MIN_VALUE.doubleValue()) {
+            throw new DataTypeException("YANG file error : " + valueInString + " is lesser than minimum value "
+                                                + MIN_VALUE + ".");
+        } else if (value.doubleValue() > MAX_VALUE.doubleValue()) {
+            throw new DataTypeException("YANG file error : " + valueInString + " is greater than maximum value "
+                                                + MAX_VALUE + ".");
+        }
     }
 
     /**
@@ -178,20 +207,53 @@
      * @throws DataModelException a violation of data model rules
      */
     public static YangDecimal64 fromString(String valInString) throws DataModelException {
-        YangDecimal64 decimal64;
-        decimal64 = of(new BigDecimal(valInString));
-        decimal64.validateValue();
-        return decimal64;
+        return new YangDecimal64(valInString);
     }
 
     /**
-     * Validate decimal64 value.
+     * Checks whether specific fraction-digit in its range.
+     *
+     * @return true if fraction-digit is in its range otherwise false
+     */
+    public boolean isValidFractionDigit() {
+        if ((fractionDigit >= 1) && (fractionDigit <= 18)) {
+            return true;
+        }
+        return false;
+    }
+
+
+    /**
+     * Checks whether value is in correct decimal64 value range.
      *
      * @throws DataModelException a violation of data model rules
      */
-    public void validateValue() throws DataModelException {
-        if (!(FractionDigits.isValidDecimal64(this.value, this.fractionDigit))) {
-            throw new DataModelException("YANG file error : decimal64 validation failed.");
+    public void validateDecimal64() throws DataModelException {
+        YangRangeRestriction rangeRestriction = (YangRangeRestriction) getRangeRestrictedExtendedInfo();
+        if (rangeRestriction != null) {
+            // Check whether value is within provided range value
+            ListIterator<YangRangeInterval> rangeListIterator = rangeRestriction.getAscendingRangeIntervals()
+                    .listIterator();
+            boolean isMatched = false;
+            while (rangeListIterator.hasNext()) {
+                YangRangeInterval rangeInterval = rangeListIterator.next();
+                BigDecimal startValue = ((YangDecimal64) rangeInterval.getStartValue()).getValue();
+                BigDecimal endValue = ((YangDecimal64) rangeInterval.getEndValue()).getValue();
+                if ((this.value.doubleValue() >= startValue.doubleValue()) &&
+                        (this.value.doubleValue() <= endValue.doubleValue())) {
+                    isMatched = true;
+                    break;
+                }
+            }
+            // If range is not matched then throw error
+            if (!isMatched) {
+                throw new DataModelException("YANG file error : decimal64 validation failed.");
+            }
+        } else {
+            // Check value is in fraction-digits decimal64 value range
+            if (!FractionDigits.isValueInDecimal64Range(this.value, getFractionDigit())) {
+                throw new DataModelException("YANG file error : decimal64 validation failed.");
+            }
         }
     }
 
@@ -203,6 +265,7 @@
     public void validateRange() throws DataModelException {
         YangRangeRestriction rangeRestriction = (YangRangeRestriction) getRangeRestrictedExtendedInfo();
         if (rangeRestriction == null) {
+            // No need to validate. Range is optional.
             return;
         }
 
@@ -210,14 +273,14 @@
                 .listIterator();
         while (rangeListIterator.hasNext()) {
             YangRangeInterval rangeInterval = rangeListIterator.next();
-            if (!(FractionDigits.isValidDecimal64(((YangDecimal64) rangeInterval.getStartValue()).getValue(),
-                                                  getFractionDigit()))) {
-                throw new DataModelException("YANG file error : decimal64 validation failed.");
+            if (!(FractionDigits.isValueInDecimal64Range(((YangDecimal64) rangeInterval.getStartValue()).getValue(),
+                                                         getFractionDigit()))) {
+                throw new DataModelException("YANG file error : range validation failed.");
             }
 
-            if (!(FractionDigits.isValidDecimal64(((YangDecimal64) rangeInterval.getEndValue()).getValue(),
-                                                  getFractionDigit()))) {
-                throw new DataModelException("YANG file error : decimal64 validation failed.");
+            if (!(FractionDigits.isValueInDecimal64Range(((YangDecimal64) rangeInterval.getEndValue()).getValue(),
+                                                         getFractionDigit()))) {
+                throw new DataModelException("YANG file error : range validation failed.");
             }
         }
     }
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeaf.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeaf.java
index b01ff63..3060fd4 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeaf.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangLeaf.java
@@ -380,8 +380,9 @@
     @Override
     public void validateDataOnExit()
             throws DataModelException {
-        // TODO auto-generated method stub, to be implemented by parser
-
+        if (defaultValueInString != null && !defaultValueInString.isEmpty() && dataType != null) {
+            dataType.isValidValue(defaultValueInString);
+        }
     }
 
     @Override
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangStringRestriction.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangStringRestriction.java
index b52a70e..dcd0f1d 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangStringRestriction.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangStringRestriction.java
@@ -17,6 +17,8 @@
 package org.onosproject.yangutils.datamodel;
 
 import java.io.Serializable;
+import java.math.BigInteger;
+import java.util.ListIterator;
 
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
 import org.onosproject.yangutils.datamodel.utils.Parsable;
@@ -193,6 +195,61 @@
         return YangConstructType.PATTERN_DATA;
     }
 
+    /**
+     * Validates if the given value is correct as per the length restriction.
+     *
+     * @param valueInString value
+     * @return true, if the value is confirming to length restriction, false otherwise
+     */
+    public boolean isValidStringOnLengthRestriction(String valueInString) {
+        if (lengthRestriction == null || lengthRestriction.getAscendingRangeIntervals() == null
+                || lengthRestriction.getAscendingRangeIntervals().isEmpty()) {
+            // Length restriction is optional
+            return true;
+        }
+
+        ListIterator<YangRangeInterval<YangUint64>> rangeListIterator = lengthRestriction.getAscendingRangeIntervals()
+                .listIterator();
+        boolean isMatched = false;
+        while (rangeListIterator.hasNext()) {
+            YangRangeInterval rangeInterval = rangeListIterator.next();
+            BigInteger startValue = ((YangUint64) rangeInterval.getStartValue()).getValue();
+            BigInteger endValue = ((YangUint64) rangeInterval.getEndValue()).getValue();
+            if ((valueInString.length() >= startValue.intValue()) &&
+                    (valueInString.length() <= endValue.intValue())) {
+                isMatched = true;
+                break;
+            }
+        }
+
+        return isMatched;
+    }
+
+    /**
+     * Validates if the given value is correct as per the pattern restriction.
+     *
+     * @param valueInString value
+     * @return true, if the value is confirming to pattern restriction, false otherwise
+     */
+    public boolean isValidStringOnPatternRestriction(String valueInString) {
+        if (patternRestriction == null
+                || patternRestriction.getPatternList().isEmpty()) {
+            // Pattern restriction is optional
+            return true;
+        }
+
+        ListIterator<String> patternListIterator = patternRestriction.getPatternList().listIterator();
+        boolean isMatched = false;
+        while (patternListIterator.hasNext()) {
+            if (valueInString.matches(patternListIterator.next())) {
+                isMatched = true;
+                break;
+            }
+        }
+
+        return isMatched;
+    }
+
     @Override
     public void validateDataOnEntry() throws DataModelException {
         // TODO: implement the method.
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangType.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangType.java
index d49241e..75b92b4 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangType.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangType.java
@@ -17,12 +17,18 @@
 package org.onosproject.yangutils.datamodel;
 
 import java.io.Serializable;
+import java.math.BigInteger;
+import java.util.Iterator;
+import java.util.ListIterator;
 
 import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.datamodel.utils.DataModelUtils;
 import org.onosproject.yangutils.datamodel.utils.Parsable;
 import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
 import org.onosproject.yangutils.datamodel.utils.YangConstructType;
+import org.onosproject.yangutils.datamodel.utils.builtindatatype.DataTypeException;
 import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
+import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangUint64;
 
 import static org.onosproject.yangutils.datamodel.BuiltInTypeObjectFactory.getDataObjectFromString;
 import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypeUtils.isOfRangeRestrictedType;
@@ -268,9 +274,9 @@
      * type as per the YANG file.
      *
      * @param value input data value
-     * @return status of validation
+     * @throws DataModelException a violation of data model rules
      */
-    public boolean isValidValue(String value) {
+    public void isValidValue(String value) throws DataModelException {
         switch (getDataType()) {
             case INT8:
             case INT16:
@@ -280,83 +286,210 @@
             case UINT16:
             case UINT32:
             case UINT64: {
-                isValidValueForRangeRestrictedType(value);
+                if (getDataTypeExtendedInfo() == null) {
+                    getDataObjectFromString(value, getDataType());
+                } else {
+                    ((YangRangeRestriction) getDataTypeExtendedInfo()).isValidValueString(value);
+                }
+                break;
             }
             case DECIMAL64: {
-                // TODO
+                // Fraction-Digits and range needs to get it from yang
+                YangDecimal64<YangRangeRestriction> decimal64 =
+                        (YangDecimal64<YangRangeRestriction>) getDataTypeExtendedInfo();
+                validateDecimal64(value, decimal64.getFractionDigit(),
+                                        decimal64.getRangeRestrictedExtendedInfo());
+                break;
             }
             case STRING: {
-                // TODO implement in string restriction similar to range restriction
+                if (!(((YangStringRestriction) getDataTypeExtendedInfo()).isValidStringOnLengthRestriction(value) &&
+                        ((YangStringRestriction) getDataTypeExtendedInfo()).isValidStringOnPatternRestriction(value))) {
+                    throw new DataTypeException("YANG file error : Input value \"" + value + "\" is not a valid " +
+                                                        "string");
+                }
+                break;
             }
+            case BOOLEAN:
+                if (!(value.equals(DataModelUtils.TRUE) || value.equals(DataModelUtils.FALSE))) {
+                    throw new DataTypeException("YANG file error : Input value \"" + value + "\" is not a valid " +
+                                                        "boolean");
+                }
+                break;
             case ENUMERATION: {
-                // TODO validate using list of YANG enum of enumeration class in extended info.
-            }
-            case BINARY: {
-                // TODO validate based on extended info
+                Iterator<YangEnum> iterator = ((YangEnumeration) getDataTypeExtendedInfo()).getEnumSet().iterator();
+                boolean isValidated = false;
+                while (iterator.hasNext()) {
+                    YangEnum enumTemp = (YangEnum) iterator.next();
+                    if (enumTemp.getNamedValue().equals(value)) {
+                        isValidated = true;
+                        break;
+                    }
+                }
+
+                if (!isValidated) {
+                    throw new DataTypeException("YANG file error : Input value \"" + value + "\" is not a valid " +
+                                                        "union");
+                }
+                break;
             }
             case BITS: {
-                // TODO validate based on extended info
+                YangBits bits = (YangBits) getDataTypeExtendedInfo();
+                if (bits.fromString(value) == null) {
+                    throw new DataTypeException("YANG file error : Input value \"" + value + "\" is not a valid " +
+                                                        "bits");
+                }
+                break;
             }
-            case BOOLEAN: {
-                // TODO true or false
+            case BINARY: {
+                if (!isValidBinary(value, (YangRangeRestriction) getDataTypeExtendedInfo())) {
+                    throw new DataTypeException("YANG file error : Input value \"" + value + "\" is not a valid " +
+                                                        "binary");
+                }
+                break;
             }
             case LEAFREF: {
-                // TODO validate based on extended info
+                YangLeafRef<?> leafRef = (YangLeafRef<?>) getDataTypeExtendedInfo();
+                leafRef.validateDataOnExit();
+                break;
             }
             case IDENTITYREF: {
                 // TODO TBD
+                break;
             }
             case EMPTY: {
-                // TODO true or false
+                throw new DataTypeException("YANG file error : Input value \"" + value
+                                                    + "\" is not a allowed for a data type " + "empty");
             }
             case UNION: {
-                // TODO validate based on extended info
+                ListIterator<YangType<?>> listIterator = ((YangUnion) getDataTypeExtendedInfo()).getTypeList()
+                                                                                                .listIterator();
+                boolean isValidated = false;
+                while (listIterator.hasNext()) {
+                    YangType<?> type = (YangType<?>) listIterator.next();
+                    try {
+                        type.isValidValue(value);
+                        // If it is not thrown exception then validation is success
+                        isValidated = true;
+                        break;
+                    } catch (Exception e) {
+                    }
+                }
+
+                if (!isValidated) {
+                    throw new DataTypeException("YANG file error : Input value \"" + value + "\" is not a valid " +
+                                                        "union");
+                }
+                break;
             }
             case INSTANCE_IDENTIFIER: {
                 // TODO TBD
+                break;
             }
             case DERIVED: {
-                if (isOfRangeRestrictedType(((YangDerivedInfo) getDataTypeExtendedInfo()).getEffectiveBuiltInType())) {
-                    try {
-                        if (((YangDerivedInfo) getDataTypeExtendedInfo()).getResolvedExtendedInfo() == null) {
-                            getDataObjectFromString(value,
-                                    ((YangDerivedInfo) getDataTypeExtendedInfo()).getEffectiveBuiltInType());
-                            return true;
-                        } else {
-                            return ((YangRangeRestriction) ((YangDerivedInfo) getDataTypeExtendedInfo())
-                                    .getResolvedExtendedInfo()).isValidValueString(value);
+                YangDataTypes dataType = ((YangDerivedInfo) getDataTypeExtendedInfo()).getEffectiveBuiltInType();
+                if (isOfRangeRestrictedType(dataType)) {
+                    if (((YangDerivedInfo) getDataTypeExtendedInfo()).getResolvedExtendedInfo() == null) {
+                        getDataObjectFromString(value,
+                                                ((YangDerivedInfo) getDataTypeExtendedInfo())
+                                                        .getEffectiveBuiltInType());
+                    } else {
+                        if (!((YangRangeRestriction) ((YangDerivedInfo) getDataTypeExtendedInfo())
+                                .getResolvedExtendedInfo()).isValidValueString(value)) {
+                            throw new DataTypeException("YANG file error : Input value \"" + value
+                                                                + "\" is not a valid " + dataType.toString());
                         }
-                    } catch (Exception e) {
-                        return false;
                     }
-                } else {
-                    // TODO
+                } else if (dataType == YangDataTypes.STRING) {
+                    if (((YangDerivedInfo) getDataTypeExtendedInfo()).getResolvedExtendedInfo() != null) {
+                        YangStringRestriction stringRestriction =
+                                ((YangStringRestriction) ((YangDerivedInfo) getDataTypeExtendedInfo())
+                                        .getResolvedExtendedInfo());
+                        if (!(stringRestriction.isValidStringOnLengthRestriction(value) &&
+                                stringRestriction.isValidStringOnPatternRestriction(value))) {
+                            throw new DataTypeException("YANG file error : Input value \"" + value
+                                                                + "\" is not a valid " + dataType.toString());
+                        }
+                    }
+                } else if (dataType == YangDataTypes.BITS) {
+                    YangBits bits = (YangBits) getDataTypeExtendedInfo();
+                    if (bits.fromString(value) == null) {
+                        throw new DataTypeException("YANG file error : Input value \"" + value + "\" is not a valid " +
+                                                            "bits");
+                    }
+                } else if (dataType == YangDataTypes.BINARY) {
+                    if (!isValidBinary(value, (YangRangeRestriction) ((YangDerivedInfo)
+                            getDataTypeExtendedInfo()).getResolvedExtendedInfo())) {
+                        throw new DataTypeException("YANG file error : Input value \"" + value + "\" is not a valid " +
+                                                            dataType.toString());
+                    }
+                } else if (dataType == YangDataTypes.DECIMAL64) {
+                    YangDerivedInfo derivedInfo = (YangDerivedInfo) getDataTypeExtendedInfo();
+                    YangTypeDef typedef = (YangTypeDef) derivedInfo.getReferredTypeDef();
+                    YangType<YangDecimal64> decimal64Type =
+                            (YangType<YangDecimal64>) typedef.getTypeList().iterator().next();
+                    YangDecimal64<YangRangeRestriction> decimal64 = decimal64Type.getDataTypeExtendedInfo();
+                    // Fraction-Digits and range needs to get it from yang
+                    validateDecimal64(value, decimal64.getFractionDigit(),
+                                            decimal64.getRangeRestrictedExtendedInfo());
                 }
+                break;
             }
             default: {
-                // TODO
+                throw new DataTypeException("YANG file error : Input value \"" + value + "\" is for unsupported " +
+                                                    "data type.");
             }
         }
-        return true;
+    }
+
+
+    /**
+     * Checks whether specific string is valid decimal64 value.
+     *
+     * @param value decimal64 value
+     */
+    private  void validateDecimal64(String value, int fractionDigit, YangRangeRestriction rangeRestriction)
+            throws DataModelException {
+        YangDecimal64<YangRangeRestriction> decimal64 = YangDecimal64.fromString(value);
+        decimal64.setFractionDigit(fractionDigit);
+        decimal64.setRangeRestrictedExtendedInfo(rangeRestriction);
+        decimal64.validateDecimal64();
     }
 
     /**
-     * Validates the input data value for range restricted types against the
-     * permissible value for the type as per the YANG file.
+     * Checks whether specific string is valid binary.
      *
-     * @param value input data value
-     * @return status of validation
+     * @param value binary value
+     * @return true if validation success otherwise false
      */
-    private boolean isValidValueForRangeRestrictedType(String value) {
-        try {
-            if (getDataTypeExtendedInfo() == null) {
-                getDataObjectFromString(value, getDataType());
-                return true;
-            } else {
-                return ((YangRangeRestriction) getDataTypeExtendedInfo()).isValidValueString(value);
-            }
-        } catch (Exception e) {
+    private boolean isValidBinary(String value, YangRangeRestriction lengthRestriction) {
+        YangBinary binary = new YangBinary(value);
+
+        // After decoding binary, its length should not be zero
+        if (binary.getBinaryData().length == 0) {
             return false;
         }
+
+        if (lengthRestriction == null || lengthRestriction.getAscendingRangeIntervals() == null
+                || lengthRestriction.getAscendingRangeIntervals().isEmpty()) {
+            // Length restriction is optional
+            return true;
+        }
+
+        ListIterator<YangRangeInterval<YangUint64>> rangeListIterator = lengthRestriction.getAscendingRangeIntervals()
+                .listIterator();
+        boolean isMatched = false;
+        while (rangeListIterator.hasNext()) {
+            YangRangeInterval rangeInterval = rangeListIterator.next();
+            BigInteger startValue = ((YangUint64) rangeInterval.getStartValue()).getValue();
+            BigInteger endValue = ((YangUint64) rangeInterval.getEndValue()).getValue();
+            // convert (encode) back and check length
+            if ((binary.toString().length() >= startValue.intValue()) &&
+                    (binary.toString().length() <= endValue.intValue())) {
+                isMatched = true;
+                break;
+            }
+        }
+
+        return isMatched;
     }
 }
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangTypeDef.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangTypeDef.java
index 6fd95e0..085a5c8 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangTypeDef.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/YangTypeDef.java
@@ -251,7 +251,9 @@
      */
     @Override
     public void validateDataOnExit() throws DataModelException {
-        // TODO auto-generated method stub, to be implemented by parser
+        if (defaultValueInString != null && !defaultValueInString.isEmpty() && getTypeDefBaseType() != null) {
+            getTypeDefBaseType().isValidValue(defaultValueInString);
+        }
     }
 
     /**
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
index 5b29216..d6e7217 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/DataModelUtils.java
@@ -55,6 +55,8 @@
  * Represents utilities for data model tree.
  */
 public final class DataModelUtils {
+    public static final String TRUE = "true";
+    public static final String FALSE = "false";
 
     /**
      * Creates a new data model tree utility.
diff --git a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/FractionDigits.java b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/FractionDigits.java
index eebe6ab..f5c644a 100644
--- a/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/FractionDigits.java
+++ b/utils/yangutils/datamodel/src/main/java/org/onosproject/yangutils/datamodel/utils/FractionDigits.java
@@ -105,7 +105,7 @@
      *
      * @return decimal64 value range by fraction-digits as index
      */
-    private static ArrayList<Range> getDecimal64ValueRange() {
+    public static ArrayList<Range> getDecimal64ValueRange() {
         if (decimal64ValueRange == null) {
             decimal64ValueRange = new ArrayList<>();
             decimal64ValueRange.add(new Range(-922337203685477580.8, 922337203685477580.7)); // fraction-digit: 1
@@ -131,26 +131,6 @@
     }
 
     /**
-     * Checks given decimal64 value is in the specific range based on given fraction-digit.
-     *
-     * @param value decimal64 value
-     * @param fractionDigit fraction-digits
-     * @return success when it is in specific range otherwise false
-     */
-    public static boolean isValidDecimal64(BigDecimal value, int fractionDigit) {
-        if (!((fractionDigit >= 1) && (fractionDigit <= 18))) {
-            return false;
-        }
-
-        // ArrayList index starts from 0.
-        Range range = getDecimal64ValueRange().get(fractionDigit - 1);
-        if ((value.doubleValue() >= range.min) && (value.doubleValue() <= range.max)) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
      * Retrieve range based on fraction-digits.
      *
      * @param fractionDigit fraction-digits
@@ -164,4 +144,25 @@
 
         return getDecimal64ValueRange().get(fractionDigit - 1);
     }
+
+    /**
+     * Checks whether specific decimal64 value is in correct range based fraction-digit.
+     *
+     * @param value decimal64 value
+     * @param fractionDigit fraction-digits
+     * @return true when it is in correct range otherwise false
+     */
+    public static boolean isValueInDecimal64Range(BigDecimal value, int fractionDigit) {
+        // Fraction-digits should be in correct its own range.
+        if (!((fractionDigit >= 1) && (fractionDigit <= 18))) {
+            return false;
+        }
+
+        // ArrayList index starts from 0.
+        FractionDigits.Range range = FractionDigits.getDecimal64ValueRange().get(fractionDigit - 1);
+        if ((value.doubleValue() >= range.getMin()) && (value.doubleValue() <= range.getMax())) {
+            return true;
+        }
+        return false;
+    }
 }