aboutsummaryrefslogtreecommitdiffstats
path: root/jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils
diff options
context:
space:
mode:
Diffstat (limited to 'jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils')
-rw-r--r--jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils/CopyUtils.java29
-rw-r--r--jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils/DumpUtils.java55
-rw-r--r--jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils/TOSCAVersionProperty.java182
-rw-r--r--jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils/UrlUtils.java123
-rw-r--r--jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils/ValidateUtils.java409
5 files changed, 798 insertions, 0 deletions
diff --git a/jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils/CopyUtils.java b/jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils/CopyUtils.java
new file mode 100644
index 0000000..db236e1
--- /dev/null
+++ b/jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils/CopyUtils.java
@@ -0,0 +1,29 @@
+package org.openecomp.sdc.toscaparser.api.utils;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class CopyUtils {
+
+ @SuppressWarnings("unchecked")
+ public static Object copyLhmOrAl(Object src) {
+ if(src instanceof LinkedHashMap) {
+ LinkedHashMap<String,Object> dst = new LinkedHashMap<String,Object>();
+ for(Map.Entry<String,Object> me: ((LinkedHashMap<String,Object>)src).entrySet()) {
+ dst.put(me.getKey(),me.getValue());
+ }
+ return dst;
+ }
+ else if(src instanceof ArrayList) {
+ ArrayList<Object> dst = new ArrayList<Object>();
+ for(Object o: (ArrayList<Object>)src) {
+ dst.add(o);
+ }
+ return dst;
+ }
+ else {
+ return null;
+ }
+ }
+}
diff --git a/jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils/DumpUtils.java b/jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils/DumpUtils.java
new file mode 100644
index 0000000..32c69cd
--- /dev/null
+++ b/jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils/DumpUtils.java
@@ -0,0 +1,55 @@
+package org.openecomp.sdc.toscaparser.api.utils;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class DumpUtils {
+
+ @SuppressWarnings("unchecked")
+ public static void dumpYaml(Object yo,int level) {
+ final String indent = " ";
+ try {
+ if(yo == null) {
+ System.out.println("<null>");
+ return;
+ }
+ String cname = yo.getClass().getSimpleName();
+ System.out.print(cname);
+ if(cname.equals("LinkedHashMap")) {
+ LinkedHashMap<String,Object> lhm = (LinkedHashMap<String,Object>)yo;
+ System.out.println();
+ for(Map.Entry<String,Object> me: lhm.entrySet()) {
+ System.out.print(indent.substring(0,level) + me.getKey() + ": ");
+ dumpYaml(me.getValue(),level+2);
+ }
+ }
+ else if(cname.equals("ArrayList")) {
+ ArrayList<Object> al = (ArrayList<Object>)yo;
+ System.out.println();
+ for (int i=0; i<al.size(); i++) {
+ System.out.format("%s[%d] ",indent.substring(0,level),i);
+ dumpYaml(al.get(i),level+2);
+ }
+ }
+ else if(cname.equals("String")) {
+ System.out.println(" ==> \"" + (String)yo + "\"");
+ }
+ else if(cname.equals("Integer")) {
+ System.out.println(" ==> " + (int)yo);
+ }
+ else if(cname.equals("Boolean")) {
+ System.out.println(" ==> " + (boolean)yo);
+ }
+ else if(cname.equals("Double")) {
+ System.out.println(" ==> " + (double)yo);
+ }
+ else {
+ System.out.println(" !! unexpected type");
+ }
+ }
+ catch(Exception e) {
+ System.out.println("Exception!! " + e.getMessage());
+ }
+ }
+} \ No newline at end of file
diff --git a/jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils/TOSCAVersionProperty.java b/jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils/TOSCAVersionProperty.java
new file mode 100644
index 0000000..7c6b62f
--- /dev/null
+++ b/jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils/TOSCAVersionProperty.java
@@ -0,0 +1,182 @@
+package org.openecomp.sdc.toscaparser.api.utils;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.openecomp.sdc.toscaparser.api.common.ExceptionCollector;
+
+public class TOSCAVersionProperty {// test with functions/test_concat.yaml
+
+ private String version;
+
+ private static final String versionRe =
+ "^(?<gMajorVersion>([0-9][0-9]*))" +
+ "(\\.(?<gMinorVersion>([0-9][0-9]*)))?" +
+ "(\\.(?<gFixVersion>([0-9][0-9]*)))?" +
+ "(\\.(?<gQualifier>([0-9A-Za-z]+)))?" +
+ "(\\-(?<gBuildVersion>[0-9])*)?$";
+
+ private String minorVersion = null;
+ private String majorVersion = null;
+ private String fixVersion = null;
+ private String qualifier = null;
+ private String buildVersion = null;
+
+
+ public TOSCAVersionProperty(Object _version) {
+ version = _version.toString();
+
+ if(version.equals("0") || version.equals("0.0") || version.equals("0.0.0")) {
+ //log.warning(_('Version assumed as not provided'))
+ version = "";
+ return;
+ }
+
+ Pattern pattern = Pattern.compile(versionRe);
+ Matcher matcher = pattern.matcher(version);
+ if(!matcher.find()) {
+ ExceptionCollector.appendException(String.format(
+ "InvalidTOSCAVersionPropertyException: " +
+ "Value of TOSCA version property \"%s\" is invalid",
+ version));
+ return;
+ }
+ minorVersion = matcher.group("gMinorVersion");
+ majorVersion = matcher.group("gMajorVersion");
+ fixVersion = matcher.group("gFixVersion");
+ qualifier = _validateQualifier(matcher.group("gQualifier"));
+ buildVersion = _validateBuild(matcher.group("gBuildVersion"));
+ _validateMajorVersion(majorVersion);
+
+ }
+
+ private String _validateMajorVersion(String value) {
+ // Validate major version
+
+ // Checks if only major version is provided and assumes
+ // minor version as 0.
+ // Eg: If version = 18, then it returns version = '18.0'
+
+ if(minorVersion == null && buildVersion == null && !value.equals("0")) {
+ //log.warning(_('Minor version assumed "0".'))
+ version = version + "0";
+ }
+ return value;
+ }
+
+ private String _validateQualifier(String value) {
+ // Validate qualifier
+
+ // TOSCA version is invalid if a qualifier is present without the
+ // fix version or with all of major, minor and fix version 0s.
+
+ // For example, the following versions are invalid
+ // 18.0.abc
+ // 0.0.0.abc
+
+ if((fixVersion == null && value != null) ||
+ (minorVersion.equals("0") && majorVersion.equals("0") &&
+ fixVersion.equals("0") && value != null)) {
+ ExceptionCollector.appendException(String.format(
+ "InvalidTOSCAVersionPropertyException: " +
+ "Value of TOSCA version property \"%s\" is invalid",
+ version));
+ }
+ return value;
+ }
+
+ private String _validateBuild(String value) {
+ // Validate build version
+
+ // TOSCA version is invalid if build version is present without the qualifier.
+ // Eg: version = 18.0.0-1 is invalid.
+
+ if(qualifier == null && value != null) {
+ ExceptionCollector.appendException(String.format(
+ "InvalidTOSCAVersionPropertyException: " +
+ "Value of TOSCA version property \"%s\" is invalid",
+ version));
+ }
+ return value;
+ }
+
+ public Object getVersion() {
+ return version;
+ }
+
+}
+
+/*python
+
+class TOSCAVersionProperty(object):
+
+ VERSION_RE = re.compile('^(?P<major_version>([0-9][0-9]*))'
+ '(\.(?P<minor_version>([0-9][0-9]*)))?'
+ '(\.(?P<fix_version>([0-9][0-9]*)))?'
+ '(\.(?P<qualifier>([0-9A-Za-z]+)))?'
+ '(\-(?P<build_version>[0-9])*)?$')
+
+ def __init__(self, version):
+ self.version = str(version)
+ match = self.VERSION_RE.match(self.version)
+ if not match:
+ ExceptionCollector.appendException(
+ InvalidTOSCAVersionPropertyException(what=(self.version)))
+ return
+ ver = match.groupdict()
+ if self.version in ['0', '0.0', '0.0.0']:
+ log.warning(_('Version assumed as not provided'))
+ self.version = None
+ self.minor_version = ver['minor_version']
+ self.major_version = ver['major_version']
+ self.fix_version = ver['fix_version']
+ self.qualifier = self._validate_qualifier(ver['qualifier'])
+ self.build_version = self._validate_build(ver['build_version'])
+ self._validate_major_version(self.major_version)
+
+ def _validate_major_version(self, value):
+ """Validate major version
+
+ Checks if only major version is provided and assumes
+ minor version as 0.
+ Eg: If version = 18, then it returns version = '18.0'
+ """
+
+ if self.minor_version is None and self.build_version is None and \
+ value != '0':
+ log.warning(_('Minor version assumed "0".'))
+ self.version = '.'.join([value, '0'])
+ return value
+
+ def _validate_qualifier(self, value):
+ """Validate qualifier
+
+ TOSCA version is invalid if a qualifier is present without the
+ fix version or with all of major, minor and fix version 0s.
+
+ For example, the following versions are invalid
+ 18.0.abc
+ 0.0.0.abc
+ """
+ if (self.fix_version is None and value) or \
+ (self.minor_version == self.major_version ==
+ self.fix_version == '0' and value):
+ ExceptionCollector.appendException(
+ InvalidTOSCAVersionPropertyException(what=(self.version)))
+ return value
+
+ def _validate_build(self, value):
+ """Validate build version
+
+ TOSCA version is invalid if build version is present without the
+ qualifier.
+ Eg: version = 18.0.0-1 is invalid.
+ """
+ if not self.qualifier and value:
+ ExceptionCollector.appendException(
+ InvalidTOSCAVersionPropertyException(what=(self.version)))
+ return value
+
+ def get_version(self):
+ return self.version
+*/ \ No newline at end of file
diff --git a/jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils/UrlUtils.java b/jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils/UrlUtils.java
new file mode 100644
index 0000000..0aadcfe
--- /dev/null
+++ b/jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils/UrlUtils.java
@@ -0,0 +1,123 @@
+package org.openecomp.sdc.toscaparser.api.utils;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.openecomp.sdc.toscaparser.api.common.ExceptionCollector;
+
+public class UrlUtils {
+
+ public static boolean validateUrl(String sUrl) {
+ // Validates whether the given path is a URL or not
+
+ // If the given path includes a scheme (http, https, ftp, ...) and a net
+ // location (a domain name such as www.github.com) it is validated as a URL
+ try {
+ URL url = new URL(sUrl);
+ if(url.getProtocol().equals("file")) {
+ return true;
+ }
+ return url.getAuthority() != null;
+ }
+ catch(MalformedURLException e) {
+ return false;
+ }
+ }
+
+ public static String joinUrl(String sUrl,String relativePath) {
+ // Builds a new URL from the given URL and the relative path
+
+ // Example:
+ // url: http://www.githib.com/openstack/heat
+ // relative_path: heat-translator
+ // - joined: http://www.githib.com/openstack/heat-translator
+ if(!validateUrl(sUrl)) {
+ ExceptionCollector.appendException(String.format(
+ "ValueError: The URL \"%s\" is malformed",sUrl));
+ }
+ try {
+ URL base = new URL(sUrl);
+ return (new URL(base,relativePath)).toString();
+ }
+ catch(MalformedURLException e) {
+ ExceptionCollector.appendException(String.format(
+ "ValueError: Joining URL \"%s\" and relative path \"%s\" caused an exception",sUrl,relativePath));
+ return sUrl;
+ }
+ }
+
+ public static boolean isUrlAccessible(String sUrl) {
+ // Validates whether the given URL is accessible
+
+ // Returns true if the get call returns a 200 response code.
+ // Otherwise, returns false.
+ try {
+ HttpURLConnection connection = (HttpURLConnection) new URL(sUrl).openConnection();
+ connection.setRequestMethod("HEAD");
+ int responseCode = connection.getResponseCode();
+ return responseCode == 200;
+ }
+ catch(IOException e) {
+ return false;
+ }
+ }
+
+}
+
+/*python
+
+from six.moves.urllib.parse import urljoin
+from six.moves.urllib.parse import urlparse
+from toscaparser.common.exception import ExceptionCollector
+from toscaparser.utils.gettextutils import _
+
+try:
+ # Python 3.x
+ import urllib.request as urllib2
+except ImportError:
+ # Python 2.x
+ import urllib2
+
+
+class UrlUtils(object):
+
+ @staticmethod
+ def validate_url(path):
+ """Validates whether the given path is a URL or not.
+
+ If the given path includes a scheme (http, https, ftp, ...) and a net
+ location (a domain name such as www.github.com) it is validated as a
+ URL.
+ """
+ parsed = urlparse(path)
+ if parsed.scheme == 'file':
+ # If the url uses the file scheme netloc will be ""
+ return True
+ else:
+ return bool(parsed.scheme) and bool(parsed.netloc)
+
+ @staticmethod
+ def join_url(url, relative_path):
+ """Builds a new URL from the given URL and the relative path.
+
+ Example:
+ url: http://www.githib.com/openstack/heat
+ relative_path: heat-translator
+ - joined: http://www.githib.com/openstack/heat-translator
+ """
+ if not UrlUtils.validate_url(url):
+ ExceptionCollector.appendException(
+ ValueError(_('"%s" is not a valid URL.') % url))
+ return urljoin(url, relative_path)
+
+ @staticmethod
+ def url_accessible(url):
+ """Validates whether the given URL is accessible.
+
+ Returns true if the get call returns a 200 response code.
+ Otherwise, returns false.
+ """
+ return urllib2.urlopen(url).getcode() == 200
+*/ \ No newline at end of file
diff --git a/jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils/ValidateUtils.java b/jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils/ValidateUtils.java
new file mode 100644
index 0000000..675ab16
--- /dev/null
+++ b/jtosca/src/main/java/org/openecomp/sdc/toscaparser/api/utils/ValidateUtils.java
@@ -0,0 +1,409 @@
+package org.openecomp.sdc.toscaparser.api.utils;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedHashMap;
+
+import org.openecomp.sdc.toscaparser.api.common.ExceptionCollector;
+
+public class ValidateUtils {
+
+ private static final String RANGE_UNBOUNDED = "UNBOUNDED";
+
+ public static Object strToNum(Object value) {
+ // Convert a string representation of a number into a numeric type
+ // tODO(TBD) we should not allow numeric values in, input should be str
+ if(value instanceof Number) {
+ return value;
+ }
+ if(!(value instanceof String)) {
+
+ }
+ try {
+ return Integer.parseInt((String)value);
+ }
+ catch(NumberFormatException e) {
+ }
+ try {
+ return Float.parseFloat((String)value);
+ }
+ catch(Exception e) {
+ }
+ return null;
+ }
+
+ public static Object validateNumeric(Object value) {
+ if(!(value instanceof Number)) {
+ ExceptionCollector.appendException(String.format(
+ "ValueError: \"%s\" is not a numeric",value.toString()));
+ }
+ return value;
+ }
+
+ public static Object validateInteger(Object value) {
+ if(!(value instanceof Integer)) {
+ // allow "true" and "false"
+ if(value instanceof Boolean) {
+ return (Boolean)value ? 1 : 0;
+ }
+ ExceptionCollector.appendException(String.format(
+ "ValueError: \"%s\" is not an integer",value.toString()));
+ }
+ return value;
+ }
+
+ public static Object validateFloat(Object value) {
+ if(!(value instanceof Float || value instanceof Double)) {
+ ExceptionCollector.appendException(String.format(
+ "ValueError: \"%s\" is not a float",value.toString()));
+ }
+ return value;
+ }
+
+ public static Object validateString(Object value) {
+ if(!(value instanceof String)) {
+ ExceptionCollector.appendException(String.format(
+ "ValueError: \'%s\' is not a string",value.toString()));
+ }
+ return value;
+ }
+
+ public static Object validateList(Object value) {
+ if(!(value instanceof ArrayList)) {
+ ExceptionCollector.appendException(String.format(
+ "ValueError: \"%s\" is not a list",value.toString()));
+ }
+ return value;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public static Object validateRange(Object range) {
+ // list class check
+ validateList(range);
+ // validate range list has a min and max
+ if(range instanceof ArrayList && ((ArrayList<Object>)range).size() != 2) {
+ ExceptionCollector.appendException(String.format(
+ "ValueError: \"%s\" is not a valid range",range.toString()));
+ // too dangerous to continue...
+ return range;
+ }
+ // validate min and max are numerics or the keyword UNBOUNDED
+ boolean minTest = false;
+ boolean maxTest = false;
+ Object r0 = ((ArrayList<Object>)range).get(0);
+ Object r1 = ((ArrayList<Object>)range).get(1);
+
+ if(!(r0 instanceof Integer) && !(r0 instanceof Float) ||
+ !(r1 instanceof Integer) && !(r1 instanceof Float)) {
+ ExceptionCollector.appendException(String.format(
+ "ValueError: \"%s\" is not a valid range",range.toString()));
+ // too dangerous to continue...
+ return range;
+ }
+
+ Float min = 0.0F;
+ Float max = 0.0F;
+ if(r0 instanceof String && ((String)r0).equals(RANGE_UNBOUNDED)) {
+ minTest = true;
+ }
+ else {
+ min = r0 instanceof Integer ? ((Integer)r0).floatValue() : (Float)r0;
+ }
+ if(r1 instanceof String && ((String)r1).equals(RANGE_UNBOUNDED)) {
+ maxTest = true;
+ }
+ else {
+ max = r1 instanceof Integer ? ((Integer)r1).floatValue() : (Float)r1;
+ }
+
+ // validate the max > min (account for UNBOUNDED)
+ if(!minTest && !maxTest) {
+ // Note: min == max is allowed
+ if(min > max) {
+ ExceptionCollector.appendException(String.format(
+ "ValueError:\"%s\" is not a valid range",range.toString()));
+ }
+ }
+ return range;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Object validateValueInRange(Object value,Object range,String propName) {
+ // verify all 3 are numeric and convert to Floats
+ if(!(value instanceof Integer || value instanceof Float)) {
+ ExceptionCollector.appendException(String.format(
+ "ValueError: validateInRange: \"%s\" is not a number",range.toString()));
+ return value;
+ }
+ Float fval = value instanceof Integer ? ((Integer)value).floatValue() : (Float)value;
+
+ //////////////////////////
+ //"validateRange(range);"
+ //////////////////////////
+ // better safe than sorry...
+ // validate that range list has a min and max
+ if(range instanceof ArrayList && ((ArrayList<Object>)range).size() != 2) {
+ ExceptionCollector.appendException(String.format(
+ "ValueError: \"%s\" is not a valid range",range.toString()));
+ // too dangerous to continue...
+ return value;
+ }
+ // validate min and max are numerics or the keyword UNBOUNDED
+ boolean minTest = false;
+ boolean maxTest = false;
+ Object r0 = ((ArrayList<Object>)range).get(0);
+ Object r1 = ((ArrayList<Object>)range).get(1);
+
+ if(!(r0 instanceof Integer) && !(r0 instanceof Float) ||
+ !(r1 instanceof Integer) && !(r1 instanceof Float)) {
+ ExceptionCollector.appendException(String.format(
+ "ValueError: \"%s\" is not a valid range",range.toString()));
+ // too dangerous to continue...
+ return value;
+ }
+
+ Float min = 0.0F;
+ Float max = 0.0F;
+ if(r0 instanceof String && ((String)r0).equals(RANGE_UNBOUNDED)) {
+ minTest = true;
+ }
+ else {
+ min = r0 instanceof Integer ? ((Integer)r0).floatValue() : (Float)r0;
+ }
+ if(r1 instanceof String && ((String)r1).equals(RANGE_UNBOUNDED)) {
+ maxTest = true;
+ }
+ else {
+ max = r1 instanceof Integer ? ((Integer)r1).floatValue() : (Float)r1;
+ }
+
+ // validate the max > min (account for UNBOUNDED)
+ if(!minTest && !maxTest) {
+ // Note: min == max is allowed
+ if(min > max) {
+ ExceptionCollector.appendException(String.format(
+ "ValueError:\"%s\" is not a valid range",range.toString()));
+ }
+ }
+ // finally...
+ boolean bError = false;
+ //Note: value is valid if equal to min
+ if(!minTest) {
+ if(fval < min) {
+ bError = true;
+ }
+ }
+ // Note: value is valid if equal to max
+ if(!maxTest) {
+ if(fval > max) {
+ bError = true;
+ }
+ }
+ if(bError) {
+ ExceptionCollector.appendException(String.format(
+ "RangeValueError: Property \"%s\", \"%s\" not in range [\"%s\" - \"%s\"",
+ propName,value.toString(),r0.toString(),r1.toString()));
+ }
+ return value;
+ }
+
+ public static Object validateMap(Object ob) {
+ if(!(ob instanceof LinkedHashMap)) {
+ ExceptionCollector.appendException(String.format(
+ "ValueError\"%s\" is not a map.",ob.toString()));
+ }
+ return ob;
+ }
+
+ public static Object validateBoolean(Object value) {
+ if(value instanceof Boolean) {
+ return value;
+ }
+ if(value instanceof String) {
+ String normalized = ((String)value).toLowerCase();
+ if(normalized.equals("true") || normalized.equals("false")) {
+ return normalized.equals("true");
+ }
+ }
+ ExceptionCollector.appendException(String.format(
+ "ValueError: \"%s\" is not a boolean",value.toString()));
+ return value;
+ }
+
+ public static Object validateTimestamp(Object value) {
+ /*
+ try:
+ # Note: we must return our own exception message
+ # as dateutil's parser returns different types / values on
+ # different systems. OSX, for example, returns a tuple
+ # containing a different error message than Linux
+ dateutil.parser.parse(value)
+ except Exception as e:
+ original_err_msg = str(e)
+ log.error(original_err_msg)
+ ExceptionCollector.appendException(
+ ValueError(_('"%(val)s" is not a valid timestamp. "%(msg)s"') %
+ {'val': value, 'msg': original_err_msg}))
+ */
+
+ // timestamps are loaded as Date objects by the YAML parser
+ if(!(value instanceof Date)) {
+ ExceptionCollector.appendException(String.format(
+ "ValueError: \"%s\" is not a valid timestamp",
+ value.toString()));
+
+ }
+ return value;
+ }
+
+}
+
+/*python
+
+from toscaparser.elements import constraints
+from toscaparser.common.exception import ExceptionCollector
+from toscaparser.common.exception import InvalidTOSCAVersionPropertyException
+from toscaparser.common.exception import RangeValueError
+from toscaparser.utils.gettextutils import _
+
+log = logging.getLogger('tosca')
+
+RANGE_UNBOUNDED = 'UNBOUNDED'
+
+
+def str_to_num(value):
+ '''Convert a string representation of a number into a numeric type.'''
+ # tODO(TBD) we should not allow numeric values in, input should be str
+ if isinstance(value, numbers.Number):
+ return value
+ try:
+ return int(value)
+ except ValueError:
+ return float(value)
+
+
+def validate_numeric(value):
+ if not isinstance(value, numbers.Number):
+ ExceptionCollector.appendException(
+ ValueError(_('"%s" is not a numeric.') % value))
+ return value
+
+
+def validate_integer(value):
+ if not isinstance(value, int):
+ try:
+ value = int(value)
+ except Exception:
+ ExceptionCollector.appendException(
+ ValueError(_('"%s" is not an integer.') % value))
+ return value
+
+
+def validate_float(value):
+ if not isinstance(value, float):
+ ExceptionCollector.appendException(
+ ValueError(_('"%s" is not a float.') % value))
+ return value
+
+
+def validate_string(value):
+ if not isinstance(value, six.string_types):
+ ExceptionCollector.appendException(
+ ValueError(_('"%s" is not a string.') % value))
+ return value
+
+
+def validate_list(value):
+ if not isinstance(value, list):
+ ExceptionCollector.appendException(
+ ValueError(_('"%s" is not a list.') % value))
+ return value
+
+
+def validate_range(range):
+ # list class check
+ validate_list(range)
+ # validate range list has a min and max
+ if len(range) != 2:
+ ExceptionCollector.appendException(
+ ValueError(_('"%s" is not a valid range.') % range))
+ # validate min and max are numerics or the keyword UNBOUNDED
+ min_test = max_test = False
+ if not range[0] == RANGE_UNBOUNDED:
+ min = validate_numeric(range[0])
+ else:
+ min_test = True
+ if not range[1] == RANGE_UNBOUNDED:
+ max = validate_numeric(range[1])
+ else:
+ max_test = True
+ # validate the max > min (account for UNBOUNDED)
+ if not min_test and not max_test:
+ # Note: min == max is allowed
+ if min > max:
+ ExceptionCollector.appendException(
+ ValueError(_('"%s" is not a valid range.') % range))
+
+ return range
+
+
+def validate_value_in_range(value, range, prop_name):
+ validate_numeric(value)
+ validate_range(range)
+
+ # Note: value is valid if equal to min
+ if range[0] != RANGE_UNBOUNDED:
+ if value < range[0]:
+ ExceptionCollector.appendException(
+ RangeValueError(pname=prop_name,
+ pvalue=value,
+ vmin=range[0],
+ vmax=range[1]))
+ # Note: value is valid if equal to max
+ if range[1] != RANGE_UNBOUNDED:
+ if value > range[1]:
+ ExceptionCollector.appendException(
+ RangeValueError(pname=prop_name,
+ pvalue=value,
+ vmin=range[0],
+ vmax=range[1]))
+ return value
+
+
+def validate_map(value):
+ if not isinstance(value, collections.Mapping):
+ ExceptionCollector.appendException(
+ ValueError(_('"%s" is not a map.') % value))
+ return value
+
+
+def validate_boolean(value):
+ if isinstance(value, bool):
+ return value
+
+ if isinstance(value, str):
+ normalised = value.lower()
+ if normalised in ['true', 'false']:
+ return normalised == 'true'
+
+ ExceptionCollector.appendException(
+ ValueError(_('"%s" is not a boolean.') % value))
+
+
+def validate_timestamp(value):
+ try:
+ # Note: we must return our own exception message
+ # as dateutil's parser returns different types / values on
+ # different systems. OSX, for example, returns a tuple
+ # containing a different error message than Linux
+ dateutil.parser.parse(value)
+ except Exception as e:
+ original_err_msg = str(e)
+ log.error(original_err_msg)
+ ExceptionCollector.appendException(
+ ValueError(_('"%(val)s" is not a valid timestamp. "%(msg)s"') %
+ {'val': value, 'msg': original_err_msg}))
+ return
+
+*/ \ No newline at end of file