types.py
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:42k
源码类别:

网格计算

开发平台:

Java

  1. #Licensed to the Apache Software Foundation (ASF) under one
  2. #or more contributor license agreements.  See the NOTICE file
  3. #distributed with this work for additional information
  4. #regarding copyright ownership.  The ASF licenses this file
  5. #to you under the Apache License, Version 2.0 (the
  6. #"License"); you may not use this file except in compliance
  7. #with the License.  You may obtain a copy of the License at
  8. #     http://www.apache.org/licenses/LICENSE-2.0
  9. #Unless required by applicable law or agreed to in writing, software
  10. #distributed under the License is distributed on an "AS IS" BASIS,
  11. #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. #See the License for the specific language governing permissions and
  13. #limitations under the License.
  14. # $Id:types.py 6172 2007-05-22 20:26:54Z zim $
  15. #
  16. #------------------------------------------------------------------------------
  17. """ Higher level data types and type related classes.
  18.     Supported Types (Verification and Display):
  19.       address        - validates ip:port and host:port tcp addresses
  20.       ip_address     - validates and IP address
  21.       net_address    - validates an IP like address, ie netmask
  22.       hostname       - validates a hostname with DNS
  23.       eaddress       - validates a single email address or a comma
  24.                        seperated list of email addresses
  25.       http_version   - validates a value is a http version (1.0/1.1)
  26.       tcp_port       - validates a value to be a valid tcp port (2-65535)
  27.       bool           - validates value is (0, 1, true, false) / converts
  28.                        true -> 1 and false -> 0
  29.       directory      - validates a values is a directory / resolves path to
  30.                        absolute path
  31.       file           - validates a value is a file / resolves path to absolute
  32.                        path
  33.       float          - validates a value is a float, converts string to float
  34.       pos_float      - validates a value is a float and >= 0, converts string
  35.                        to float
  36.       pos_num        - same as pos_float
  37.       neg_float      - validates a value is a float and < 0, converts string to
  38.                        float
  39.       int            - validates a value is an integer, converts string to
  40.                        integer
  41.       pos_int        - validates a value is an integer and >= 0, converts
  42.                        string to integer
  43.       neg_int        - validates a values is an integer and < 0, converts
  44.                        striing to integer
  45.       freq           - frequency, positive integer
  46.       size           - validates a size in bytes, kb, mb, kb, and tb
  47.                        (int > 0 post fixed with K, M, G, or T) also converts
  48.                        value to integer bytes
  49.       range          - numeric range, x-y normalized to a tuple, if a single
  50.                        number is supplie a single element tuple is returned
  51.       timestamp      - utc timestamp of the form YYYYMMDDHHMMSS
  52.       user_account   - UNIX user account name
  53.       user_group     - UNIX group name
  54.       string         - arbitrarily long string
  55.       list           - comma seperated list of strings of arbitrary length,
  56.       keyval         - comma seperated list of key=value pairs, key does not 
  57.                        need to be unique.
  58.       uri            - a uri """
  59. import sys, os, socket, pwd, grp, stat, re, re, string, pprint, urlparse
  60. from tcp import tcpSocket, check_net_address, check_ip_address
  61. from util import check_timestamp
  62. types = { 'directory'      : { 'db'    : 'string',
  63.                                'units' : None     },
  64.           'address'        : { 'db'    : 'string',
  65.                                'units' : None     },
  66.           'ip_address'     : { 'db'    : 'string',
  67.                                'units' : None     },
  68.           'net_address'    : { 'db'    : 'string',
  69.                                'units' : None     },
  70.           'bool'           : { 'db'    : 'bool',
  71.                                'units' : None     },
  72.           'int'            : { 'db'    : 'integer',
  73.                                'units' : None     },
  74.           'float'          : { 'db'    : 'float',
  75.                                'units' : None     },
  76.           'pos_int'        : { 'db'    : 'integer',
  77.                                'units' : None     },
  78.           'neg_int'        : { 'db'    : 'integer',
  79.                                'units' : None     },
  80.           'pos_num'        : { 'db'    : 'float',
  81.                                'units' : None     },
  82.           'pos_float'      : { 'db'    : 'float',
  83.                                'units' : None     },
  84.           'neg_float'      : { 'db'    : 'float',
  85.                                'units' : None     },
  86.           'string'         : { 'db'    : 'string',
  87.                                'units' : None     },
  88.           'list'           : { 'db'    : 'string',
  89.                                'units' : None     },
  90.           'file'           : { 'db'    : 'string',
  91.                                'units' : None     },
  92.           'size'           : { 'db'    : 'integer',
  93.                                'units' : 'bytes'  },
  94.           'freq'           : { 'db'    : 'integer',
  95.                                'units' : 'hz'     },
  96.           'eaddress'       : { 'db'    : 'string',
  97.                                'units' : None     },
  98.           'tcp_port'       : { 'db'    : 'integer',
  99.                                'units' : None     },
  100.           'http_version'   : { 'db'    : 'float',
  101.                                'units' : None     },
  102.           'range'          : { 'db'    : 'string',
  103.                                'units' : None     },
  104.           'hostname'       : { 'db'    : 'string',
  105.                                'units' : None     },
  106.           'user_account'   : { 'db'    : 'string',
  107.                                'units' : None     },
  108.           'user_group'     : { 'db'    : 'string',
  109.                                'units' : None     },
  110.           'timestamp'      : { 'db'    : 'timestamp',
  111.                                'units' : None     },
  112.           'keyval'         : { 'db'    : 'string',
  113.                                'units' : None     },
  114.           
  115.           'uri'            : { 'db'    : 'string',
  116.                                'units' : None     },
  117.           ''               : { 'db'    : 'string',
  118.                                'units' : None     }}
  119. dbTypes = { 'string'  :   { 'type'  : 'varchar',
  120.                             'store' : 'type_strings_0',
  121.                             'table' : True              },
  122.             'integer' :   { 'type'  : 'bigint',
  123.                             'store' : 'integers',
  124.                             'table' : False             },
  125.             'float' :     { 'type'  : 'real',
  126.                             'store' : 'floats',
  127.                             'table' : False             },
  128.             'bool' :      { 'type'  : 'boolean',
  129.                             'store' : 'bools',
  130.                             'table' : False             },
  131.             'timestamp' : { 'type'  : 'timestamp(0)',
  132.                             'store' : 'timestamps',
  133.                             'table' : False             }}
  134. reSizeFormat = re.compile("^(d+)(k|m|g|t|p|kb|mb|gb|tb|pb)$", flags=2)
  135. reDash = re.compile("s*-s*")
  136. sizeFactors = { 'b'     : 1,
  137.                 'bytes' : 1,
  138.                 'k'     : 1024,
  139.                 'kb'    : 1024,
  140.                 'm'     : 1048576,
  141.                 'mb'    : 1048576,
  142.                 'g'     : 1073741824,
  143.                 'gb'    : 1073741824,
  144.                 't'     : 1099511627776,
  145.                 'tb'    : 1099511627776,
  146.                 'p'     : 1125899906842624,
  147.                 'pb'    : 1125899906842624 }
  148. freqFactors = { 'hz'  : 1,
  149.                 'khz' : 1000,
  150.                 'mhz' : 1000000,
  151.                 'ghz' : 1000000000,
  152.                 'thz' : 1000000000000,
  153.                 'phz' : 1000000000000000 }
  154. sizeMap = [ { 'factor' : sizeFactors['b'],
  155.               'long'   : 'byte',
  156.               'short'  : 'byte'           },
  157.             { 'factor' : sizeFactors['k'],
  158.               'long'   : 'Kilobyte',
  159.               'short'  : 'KB'             },
  160.             { 'factor' : sizeFactors['m'],
  161.               'long'   : 'Megabyte',
  162.               'short'  : 'MB'             },
  163.             { 'factor' : sizeFactors['g'],
  164.               'long'   : 'Gigabyte',
  165.               'short'  : 'GB'             },
  166.             { 'factor' : sizeFactors['t'],
  167.               'long'   : 'Terabyte',
  168.               'short'  : 'TB'             },
  169.             { 'factor' : sizeFactors['p'],
  170.               'long'   : 'Petabyte',
  171.               'short'  : 'PB'             } ]
  172. freqMap = [ { 'factor' : freqFactors['hz'],
  173.               'long'   : 'Hertz',
  174.               'short'  : 'Hz'               },
  175.             { 'factor' : freqFactors['khz'],
  176.               'long'   : 'Kilohertz',
  177.               'short'  : 'KHz'              },
  178.             { 'factor' : freqFactors['mhz'],
  179.               'long'   : 'Megahertz',
  180.               'short'  : 'MHz'              },
  181.             { 'factor' : freqFactors['ghz'],
  182.               'long'   : 'Gigahertz',
  183.               'short'  : 'GHz'              },
  184.             { 'factor' : freqFactors['thz'],
  185.               'long'   : 'Terahertz',
  186.               'short'  : 'THz'              },
  187.             { 'factor' : freqFactors['phz'],
  188.               'long'   : 'Petahertz',
  189.               'short'  : 'PHz'              } ]
  190. reListString = r"(?<!\),"
  191. reList = re.compile(reListString)
  192. reKeyVal = r"(?<!\)="
  193. reKeyVal = re.compile(reKeyVal)
  194. class typeToString:
  195.     """Provides method for converting normalized types to strings."""
  196.     def __init__(self):
  197.         self.toStringFunctions = {}
  198.         self.__build_to_string_functions()
  199.  
  200.     def __call__(self, type, value):
  201.         return self.toStringFunctions[type](value) 
  202.  
  203.     def __build_to_string_functions(self):
  204.         functions = {}
  205.         for function in dir(self):
  206.             functions[function] = 1
  207.         for type in types.keys():
  208.             # kinda bad, need to find out how to know the name of the class
  209.             #  I'm in.  But it works.
  210.             functionName = "_typeToString__tostring_%s" % type
  211.             if functions.has_key(functionName):
  212.                 self.toStringFunctions[type] = getattr(self, functionName)
  213.             else:
  214.                 if type == '':
  215.                     self.toStringFunctions[type] = self.__tostring_nothing
  216.                 else:
  217.                     error = "To string function %s for type %s does not exist." 
  218.                         % (functionName, type)
  219.                     raise Exception(error)
  220.                     sys.exit(1)        
  221.     def __tostring(self, value):
  222.         return str(value)
  223.     def __tostring_directory(self, value):
  224.         return self.__tostring(value)
  225.     def __tostring_address(self, value):
  226.         return "%s:%s" % (value[0], value[1])
  227.     def __tostring_ip_address(self, value):
  228.         return self.__tostring(value)
  229.     def __tostring_net_address(self, value):
  230.         return self.__tostring(value)
  231.     def __tostring_bool(self, value):
  232.         if value == False:
  233.             return 'false'
  234.         elif value == True:
  235.             return 'true'
  236.         else:
  237.             return str(value)
  238.     def __tostring_int(self, value):
  239.         return self.__tostring(value)
  240.     def __tostring_float(self, value):
  241.         return self.__tostring(value)
  242.     def __tostring_pos_int(self, value):
  243.         return self.__tostring(value)
  244.     def __tostring_neg_int(self, value):
  245.         return self.__tostring(value)     
  246.     def __tostring_freq(self, value):
  247.         return self.__tostring(value)
  248.     def __tostring_pos_float(self, value):
  249.         return self.__tostring(value)
  250.     def __tostring_pos_num(self, value):
  251.         return self.__tostring(value)
  252.     def __tostring_neg_float(self, value):
  253.         return self.__tostring(value)
  254.     def __tostring_string(self, value):
  255.         return value
  256.     def __tostring_keyval(self, value):
  257.         string = '"' # to protect from shell escapes
  258.         for key in value:
  259.           # for item in value[key]:
  260.           #      string = "%s%s=%s," % (string, key, item)
  261.           # Quotes still cannot protect Double-slashes.
  262.           # Dealing with them separately
  263.           val = re.sub(r"\\",r"\\\\",value[key])
  264.           string = "%s%s=%s," % (string, key, val)
  265.         return string[:-1] + '"'
  266.     def __tostring_list(self, value):
  267.         string = ''
  268.         for item in value:
  269.             string = "%s%s," % (string, item)
  270.             
  271.         return string[:-1]
  272.     def __tostring_file(self, value):
  273.         return self.__tostring(value)
  274.       
  275.     def __tostring_size(self, value):
  276.         return self.__tostring(value)
  277.         
  278.     def __tostring_eaddress(self, value):
  279.         return self.__tostring(value)
  280.     def __tostring_tcp_port(self, value):
  281.         return self.__tostring(value)
  282.     def __tostring_http_version(self, value):
  283.         return self.__tostring(value)
  284.     def __tostring_range(self, value):
  285.         if len(value) < 2:
  286.           return value[0]
  287.         else:
  288.           return "%s-%s" % (value[0], value[1])
  289.     def __tostring_timestamp(self, value):
  290.         return self.__tostring(value)
  291.     def __tostring_hostname(self, value):
  292.         return self.__tostring(value)
  293.     def __tostring_user_account(self, value):
  294.         return self.__tostring(value)
  295.     def __tostring_user_group(self, value):
  296.         return self.__tostring(value)
  297.     def __tostring_uri(self, value):
  298.         return self.__tostring(value)
  299.     def __tostring_nothing(self, value):
  300.         return value
  301. class typeValidator:
  302.     """Type validation class used to normalize values or validated 
  303.        single/large sets of values by type."""
  304.     def __init__(self, originalDir=None):
  305.         self.verifyFunctions = {}
  306.         self.__build_verify_functions()
  307.         self.validateList = []
  308.         self.validatedInfo = []
  309.         self.__originalDir = originalDir
  310.     def __getattr__(self, attrname):
  311.         """validateList  = [ { 'func' : <bound method configValidator>,
  312.                                'name' : 'SA_COMMON.old_xml_dir',
  313.                                'value': 'var/data/old'                 },
  314.                              { 'func' : <bound method configValidator>,
  315.                                'name' : 'SA_COMMON.log_level',
  316.                                'value': '4'                            } ]
  317.            validatedInfo = [ { # name supplied to add()
  318.                                'name'       : 'SA_COMMON.tmp_xml_dir',
  319.                                # is valid or not
  320.                                'isValid'    : 1
  321.                                # normalized value
  322.                                'normalized' : /var/data/tmp,
  323.                                # error string ?
  324.                                'errorData'  : 0                        },
  325.                              { 'name'       : 'SA_COMMON.new_xml_dir',
  326.                                'isValid'    : 1
  327.                                'normalized' : /var/data/new,
  328.                                'errorData'  : 0                        } ]"""
  329.         if attrname   == "validateList":
  330.             return self.validateList   # list of items to be validated
  331.         elif attrname == "validatedInfo":
  332.             return self.validatedInfo  # list of validation results
  333.         else: raise AttributeError, attrname
  334.     def __build_verify_functions(self):
  335.         functions = {}
  336.         for function in dir(self):
  337.             functions[function] = 1
  338.         for type in types.keys():
  339.             # kinda bad, need to find out how to know the name of the class
  340.             #  I'm in.  But it works.
  341.             functionName = "_typeValidator__verify_%s" % type
  342.             if functions.has_key(functionName):
  343.                 self.verifyFunctions[type] = getattr(self, functionName)
  344.             else:
  345.                 if type == '':
  346.                     self.verifyFunctions[type] = self.__verify_nothing
  347.                 else:
  348.                     error = "Verify function %s for type %s does not exist." 
  349.                         % (functionName, type)
  350.                     raise Exception(error)
  351.                     sys.exit(1)
  352.     def __get_value_info(self):
  353.         valueInfo = { 'isValid' : 0, 'normalized' : 0, 'errorData' : 0 }
  354.         return valueInfo
  355.     def __set_value_info(self, valueInfo, **valueData):
  356.         try:
  357.             valueInfo['normalized'] = valueData['normalized']
  358.             valueInfo['isValid'] = 1
  359.         except KeyError:
  360.             valueInfo['isValid'] = 0
  361.             try:
  362.                 valueInfo['errorData'] = valueData['errorData']
  363.             except:
  364.                 pass
  365.     # start of 'private' verification methods, each one should correspond to a
  366.     #   type string (see self.verify_config())
  367.     def __verify_directory(self, type, value):
  368.         valueInfo = self.__get_value_info()
  369.         if os.path.isdir(value):
  370.             self.__set_value_info(valueInfo, normalized=self.normalize(type, 
  371.                                                                        value))
  372.         else:
  373.             self.__set_value_info(valueInfo)
  374.         return valueInfo
  375.       
  376.     def __norm_directory(self, value):
  377.         return self.__normalizedPath(value)
  378.     def __verify_address(self, type, value):
  379.         valueInfo = self.__get_value_info()
  380.         try:
  381.             socket = tcpSocket(value)
  382.             if socket.verify():
  383.                 self.__set_value_info(valueInfo, normalized=self.normalize(type, 
  384.                                                                        value))
  385.             else:
  386.                 self.__set_value_info(valueInfo)
  387.         except:
  388.             self.__set_value_info(valueInfo)
  389.         return valueInfo
  390.       
  391.     def __norm_address(self, value):
  392.         return value.split(':')
  393.     def __verify_ip_address(self, type, value):
  394.         valueInfo = self.__get_value_info()
  395.         if check_ip_address(value):
  396.             self.__set_value_info(valueInfo, normalized=self.normalize(type, 
  397.                                                                        value))
  398.         else:
  399.             self.__set_value_info(valueInfo)
  400.         return valueInfo
  401.     def __verify_net_address(self, type, value):
  402.         valueInfo = self.__get_value_info()
  403.         if check_net_address(value):
  404.             self.__set_value_info(valueInfo, normalized=self.normalize(type, 
  405.                                                                        value))
  406.         else:
  407.             self.__set_value_info(valueInfo)
  408.         return valueInfo
  409.     def __verify_bool(self, type, value):
  410.         valueInfo = self.__get_value_info()
  411.         value = str(value)
  412.         if re.match("^false|0|f|no$", value, 2):
  413.             self.__set_value_info(valueInfo, normalized=False)
  414.         elif re.match("^true|1|t|yes$", value, 2):
  415.             self.__set_value_info(valueInfo, normalized=True)
  416.         else:
  417.             self.__set_value_info(valueInfo)
  418.         return valueInfo
  419.       
  420.     def __norm_bool(self, value):
  421.         value = str(value)
  422.         norm = ""
  423.         if re.match("^false|0|f|no$", value, 2):
  424.             norm = False
  425.         elif re.match("^true|1|t|yes$", value, 2):
  426.             norm = True
  427.         else:
  428.             raise Exception("invalid bool specified: %s" % value)
  429.             
  430.         return norm
  431.     def __verify_int(self, type, value):
  432.         valueInfo = self.__get_value_info()
  433.         try:
  434.             self.__set_value_info(valueInfo, normalized=self.normalize(type, 
  435.                                                                        value))
  436.         except:
  437.             self.__set_value_info(valueInfo)
  438.         return valueInfo
  439.       
  440.     def __norm_int(self, value):
  441.         return int(value)
  442.     def __verify_float(self, type, value):
  443.         valueInfo = self.__get_value_info()
  444.         try:
  445.             self.__set_value_info(valueInfo, normalized=self.normalize(type, 
  446.                                                                        value))
  447.         except:
  448.             self.__set_value_info(valueInfo)
  449.         return valueInfo
  450.       
  451.     def __norm_float(self, value):
  452.         return float(value)
  453.     def __verify_pos_int(self, type, value):
  454.         valueInfo = self.__get_value_info()
  455.         try:
  456.             value = self.normalize(type, value)
  457.         except:
  458.             self.__set_value_info(valueInfo)
  459.         else:
  460.             self.__set_value_info(valueInfo, normalized=value)
  461.         return valueInfo
  462.       
  463.     def __norm_pos_int(self, value):
  464.         value = int(value)
  465.         if value < 0:
  466.             raise Exception("value is not positive: %s" % value)
  467.         
  468.         return value
  469.     def __verify_neg_int(self, type, value):
  470.         valueInfo = self.__get_value_info()
  471.         try:
  472.             value = self.normalize(type, value)
  473.         except:
  474.             self.__set_value_info(valueInfo)
  475.         else:
  476.             self.__set_value_info(valueInfo, normalized=value)
  477.         return valueInfo
  478.       
  479.     def __norm_neg_int(self, type, value):
  480.         value = int(value)
  481.         if value > 0:
  482.             raise Exception("value is not negative: %s" % value)
  483.         
  484.         return value        
  485.     def __verify_freq(self, type, value):
  486.         return self.__verify_pos_int(type, value)
  487.     def __norm_freq(self, value):
  488.         return self.__norm_pos_int(value)
  489.     def __verify_pos_float(self, type, value):
  490.         valueInfo = self.__get_value_info()
  491.         try:
  492.             value = self.normalize(type, value)
  493.         except:
  494.             self.__set_value_info(valueInfo)
  495.         else:
  496.             self.__set_value_info(valueInfo, normalized=value)
  497.         return valueInfo
  498.     def __norm_pos_float(self, value):
  499.         value = float(value)
  500.         if value < 0:
  501.             raise Exception("value is not positive: %s" % value)
  502.         
  503.         return value
  504.     def __verify_pos_num(self, type, value):
  505.         return self.__verify_pos_float(value)
  506.       
  507.     def __norm_pos_num(self, value):
  508.         return self.__norm_pos_float(value)
  509.     def __verify_neg_float(self, type, value):
  510.         valueInfo = self.__get_value_info()
  511.         try:
  512.             value = self.normalize(type, value)
  513.         except:
  514.             self.__set_value_info(valueInfo)
  515.         else:
  516.             self.__set_value_info(valueInfo, normalized=value)
  517.         return valueInfo
  518.     def __norm_neg_float(self, value):
  519.         value = float(value)
  520.         if value >= 0:
  521.             raise Exception("value is not negative: %s" % value)
  522.         
  523.         return value
  524.     def __verify_string(self, type, value):
  525.         valueInfo = self.__get_value_info()
  526.         self.__set_value_info(valueInfo, normalized=self.normalize(type, 
  527.                                                                    value))
  528.         
  529.         return valueInfo
  530.       
  531.     def __norm_string(self, value):
  532.         return str(value)
  533.     def __verify_keyval(self, type, value):
  534.         valueInfo = self.__get_value_info()
  535.         if reKeyVal.search(value):
  536.           try:
  537.             self.__set_value_info(valueInfo, normalized=self.normalize(type, 
  538.                                 value))
  539.           except:
  540.             self.__set_value_info(valueInfo, errorData = 
  541.               "invalid list of key-value pairs : [ %s ]" % value)
  542.         else:
  543.             msg = "No key value pairs found?"
  544.             self.__set_value_info(valueInfo, errorData=msg)
  545.         return valueInfo
  546.       
  547.     def __norm_keyval(self, value):
  548.         list = self.__norm_list(value)
  549.         keyValue = {}
  550.         for item in list:
  551.             (key, value) = reKeyVal.split(item)
  552.             #if not keyValue.has_key(key):
  553.             #    keyValue[key] = []
  554.             #keyValue[key].append(value)
  555.             keyValue[key] = value
  556.         return keyValue     
  557.     def __verify_list(self, type, value):
  558.         valueInfo = self.__get_value_info()
  559.         self.__set_value_info(valueInfo, normalized=self.normalize(type,value))
  560.         return valueInfo
  561.       
  562.     def __norm_list(self, value):
  563.         norm = []
  564.         if reList.search(value):
  565.             norm = reList.split(value)
  566.         else:
  567.             norm = [value,]
  568.             
  569.         return norm
  570.     def __verify_file(self, type, value):
  571.         valueInfo = self.__get_value_info()
  572.         if os.path.isfile(value):
  573.             self.__set_value_info(valueInfo, normalized=self.normalize(type,
  574.                                                                        value))
  575.         else:
  576.             self.__set_value_info(valueInfo)
  577.         return valueInfo
  578.       
  579.     def __norm_file(self, value):
  580.         return self.__normalizedPath(value)
  581.     def __verify_size(self, type, value):
  582.         valueInfo = self.__get_value_info()
  583.         value = str(value)
  584.         if reSizeFormat.match(value):
  585.             numberPart = int(reSizeFormat.sub("g<1>", value))
  586.             factorPart = reSizeFormat.sub("g<2>", value)
  587.             try:
  588.                 normalized = normalize_size(numberPart, factorPart)
  589.                 self.__set_value_info(valueInfo,
  590.                     normalized=normalized)
  591.             except:
  592.                 self.__set_value_info(valueInfo)
  593.         else:
  594.             try:
  595.                 value = int(value)
  596.             except:
  597.                 self.__set_value_info(valueInfo)
  598.             else:
  599.                 if value >= 0:
  600.                     self.__set_value_info(valueInfo, normalized=value)
  601.                 else:
  602.                     self.__set_value_info(valueInfo)
  603.         return valueInfo
  604.     def __norm_size(self, file):
  605.         norm = None
  606.         if reSizeFormat.match(value):
  607.             numberPart = int(reSizeFormat.sub("g<1>", value))
  608.             factorPart = reSizeFormat.sub("g<2>", value)
  609.             norm = normalize_size(numberPart, factorPart)            
  610.         else:
  611.             norm = int(value)
  612.             
  613.         return norm
  614.         
  615.         
  616.     def __verify_eaddress(self, type, value):
  617.         valueInfo = self.__get_value_info()
  618.         emailList = reComma.split(value)
  619.         for emailAddress in emailList:
  620.             if reEmailAddress.match(emailAddress):
  621.                 emailParts = reEmailDelimit.split(emailAddress)
  622.                 try:
  623.                     socket.gethostbyname(emailParts[1])
  624.                     self.__set_value_info(valueInfo, normalized=self.normalize(
  625.                                           type, value))
  626.                 except:
  627.                     errorString = "%s is invalid (domain lookup failed)" % 
  628.                         emailAddress
  629.                     self.__set_value_info(valueInfo, errorData=errorString)
  630.             else:
  631.                 errorString = "%s is invalid" % emailAddress
  632.                 self.__set_value_info(valueInfo, errorData=errorString)
  633.         return valueInfo
  634.     def __verify_tcp_port(self, type, value):
  635.         valueInfo = self.__get_value_info()
  636.         try:
  637.             value = self.__norm_tcp_port(value)
  638.         except:
  639.             self.__set_value_info(valueInfo)
  640.         else:
  641.             if value in range(2, 65536):
  642.                 self.__set_value_info(valueInfo, normalized=value)
  643.             else:
  644.                 self.__set_value_info(valueInfo)
  645.         return valueInfo
  646.       
  647.     def __norm_tcp_port(self, value):
  648.         return int(value)
  649.     def __verify_http_version(self, type, value):
  650.         valueInfo = self.__get_value_info()
  651.         if value in ('1.0', '1.1'):
  652.             self.__set_value_info(valueInfo, normalized=float(value))
  653.         else:
  654.             self.__set_value_info(valueInfo)
  655.         return valueInfo
  656.     def __verify_range(self, type, value):
  657.         valueInfo = self.__get_value_info()
  658.         range = reDash.split(value)
  659.         try:
  660.             if len(range) > 1:
  661.                 start = int(range[0])
  662.                 end = int(range[1])
  663.             else:
  664.                 start = int(range[0])
  665.                 end = None
  666.         except:
  667.             self.__set_value_info(valueInfo)
  668.         else:
  669.             if end:
  670.                 if end - start != 0:
  671.                     self.__set_value_info(valueInfo, normalized=(start, end))
  672.                 else:
  673.                     self.__set_value_info(valueInfo)
  674.             else:
  675.                 self.__set_value_info(valueInfo, normalized=(start,))
  676.         return valueInfo
  677.       
  678.     def __norm_range(self, value):
  679.         range = reDash.split(value)
  680.         if len(range) > 1:
  681.             start = int(range[0])
  682.             end = int(range[1])
  683.         else:
  684.             start = int(range[0])
  685.             end = None   
  686.             
  687.         return (start, end)     
  688.     def __verify_uri(self, type, value):
  689.         valueInfo = self.__get_value_info()
  690.         _norm = None
  691.         try:
  692.             uriComponents = urlparse.urlparse(value)
  693.             if uriComponents[0] == '' or uriComponents[0] == 'file':
  694.               # if scheme is '' or 'file'
  695.               if not os.path.isfile(uriComponents[2]) and 
  696.                                          not os.path.isdir(uriComponents[2]):
  697.                   raise Exception("Invalid local URI")
  698.               else:
  699.                   self.__set_value_info(valueInfo, normalized=self.normalize(
  700.                                                                   type,value))
  701.             else:
  702.               # other schemes
  703.               # currently not checking anything. TODO
  704.               self.__set_value_info(valueInfo, normalized=self.normalize(
  705.                                                                    type,value))
  706.         except:
  707.             errorString = "%s is an invalid uri" % value
  708.             self.__set_value_info(valueInfo, errorData=errorString)
  709.         return valueInfo
  710.     def __norm_uri(self, value):
  711.        uriComponents = list(urlparse.urlparse(value))
  712.        if uriComponents[0] == '':
  713.           # if scheme is '''
  714.           return self.__normalizedPath(uriComponents[2])
  715.        elif uriComponents[0] == 'file':
  716.           # if scheme is 'file'
  717.           normalizedPath = self.__normalizedPath(uriComponents[2])
  718.           return urlparse.urlunsplit(uriComponents[0:1] + [normalizedPath] + uriComponents[3:])
  719.        # Not dealing with any other case right now
  720.        return value
  721.     def __verify_timestamp(self, type, value):
  722.         valueInfo = self.__get_value_info()
  723.         if check_timestamp(value):
  724.             self.__set_value_info(valueInfo, normalized=self.normalize(type, 
  725.                                                                        value))
  726.         else:
  727.             self.__set_value_info(valueInfo)
  728.         return valueInfo
  729.     def __verify_hostname(self, type, value):
  730.         valueInfo = self.__get_value_info()
  731.         try:
  732.             socket.gethostbyname(value)
  733.             self.__set_value_info(valueInfo, normalized=self.normalize(type, 
  734.                                                                        value))
  735.         except:
  736.             errorString = "%s is invalid (domain lookup failed)" % value
  737.             self.__set_value_info(valueInfo, errorData=errorString)
  738.         return valueInfo
  739.     def __verify_user_account(self, type, value):
  740.         valueInfo = self.__get_value_info()
  741.         try:
  742.             pwd.getpwnam(value)
  743.         except:
  744.             errorString = "'%s' user account does not exist" % value
  745.             self.__set_value_info(valueInfo, errorData=errorString)
  746.         else:
  747.             self.__set_value_info(valueInfo, normalized=self.normalize(type, 
  748.                                                                        value))
  749.         return valueInfo
  750.     def __verify_user_group(self, type, value):
  751.         valueInfo = self.__get_value_info()
  752.         try:
  753.             grp.getgrnam(value)
  754.         except:
  755.             errorString = "'%s' group does not exist" % value
  756.             self.__set_value_info(valueInfo, errorData=errorString)
  757.         else:
  758.             self.__set_value_info(valueInfo, normalized=self.normalize(type, 
  759.                                                                        value))
  760.         return valueInfo
  761.     def __verify_nothing(self, type, value):
  762.         valueInfo = self.__get_value_info()
  763.         self.__set_value_info(valueInfo, normalized=self.normalize(type, 
  764.                                                                    value))
  765.         return valueInfo
  766.     #--------------------------------------------------------------------------
  767.     def normalize(self, type, value):
  768.         try:
  769.           normFunc = getattr(self, "_typeValidator__norm_%s" % type)
  770.           return normFunc(value)
  771.         except AttributeError, A:
  772.           # this exception should occur only when we don't have corresponding normalize function
  773.           return value
  774.     def verify(self, type, value, allowNone=False):
  775.         """Verifies a value based on its type.
  776.            type      - supported configValidator type
  777.            value     - data to be validated
  778.            allowNone - don't freak out if None or '' is supplied
  779.            returns a valueInfo dictionary:
  780.             valueInfo = { 'isValid' : 1, 'normalized' : 5, 'errorData' : 0 }
  781.            where:
  782.             isValid    - true or false (0/1)
  783.             normalized - the normalized value
  784.             errorData  - if invalid an error string
  785.            supported types:
  786.             see top level"""
  787.         result = None
  788.         if allowNone:
  789.             if value == '' or value == None:
  790.                 result = self.__verify_nothing(None, None)
  791.                 result['normalized'] = None
  792.             else:
  793.                 result = self.verifyFunctions[type](type, value)
  794.         else:
  795.             result = self.verifyFunctions[type](type, value)
  796.         return result
  797.     def is_valid_type(self, type):
  798.         """Returns true if type is valid."""
  799.         return types.has_key(type)
  800.     def type_info(self, type):
  801.         """Returns type info dictionary."""
  802.         dbInfo = dbTypes[types[type]['db']]
  803.         typeInfo = types[type].copy()
  804.         typeInfo['db'] = dbInfo
  805.         return typeInfo
  806.     def add(self, name, type, value):
  807.         """Adds a value and type by name to the configValidate object to be
  808.            verified using validate().
  809.            name  - name used to key values and access the results of the
  810.                    validation
  811.            type  - configValidator type
  812.            value - data to be verified"""
  813.         self.validateList.append({ 'name' : name,
  814.                                    'type' : type,
  815.                                    'value': value })
  816.     def validate(self, allowNone=False):
  817.         """Validates configValidate object populating validatedInfo with
  818.            valueInfo dictionaries for each value added to the object."""
  819.         for valItem in self.validateList:
  820.             valueInfo = self.verify(valItem['type'], valItem['value'],
  821.                 allowNone)
  822.             if valueInfo:
  823.                 valueInfo['name'] = valItem['name']
  824.                 self.validatedInfo.append(valueInfo)
  825.             else:
  826.                 raise Exception("nMissing a return value: valueInfon%s" % 
  827.                     self.verifyFunctions[valItem['type']](valItem['value']))
  828.     def __normalizedPath(self, value):    
  829.         oldWd = os.getcwd()
  830.         if self.__originalDir:
  831.           os.chdir(self.__originalDir)
  832.         normPath = os.path.realpath(value)
  833.         os.chdir(oldWd)
  834.         return normPath
  835. class display:
  836.     def __init__(self):
  837.         self.displayFunctions = {}
  838.         self.__build_dispaly_functions()
  839.     def __build_dispaly_functions(self):
  840.         functions = {}
  841.         for function in dir(self):
  842.             functions[function] = 1
  843.         for type in types.keys():
  844.             # kinda bad, need to find out how to know the name of the class
  845.             #  I'm in.  But it works.
  846.             functionName = "_cisplay__display_%s" % type
  847.             if functions.has_key(functionName):
  848.                 self.displayFunctions[type] = getattr(self, functionName)
  849.             else:
  850.                 if type == '':
  851.                     self.displayFunctions[type] = self.__display_default
  852.                 else:
  853.                     error = "Display function %s for type %s does not exist." 
  854.                         % (functionName, type)
  855.                     raise Exception(error)
  856.                     sys.exit(1)
  857.     def __display_default(self, value, style):
  858.         return value
  859.     def __display_generic_number(self, value):
  860.         displayNumber = ''
  861.         splitNum = string.split(str(value), sep='.')
  862.         numList = list(str(splitNum[0]))
  863.         numList.reverse()
  864.         length = len(numList)
  865.         counter = 0
  866.         for char in numList:
  867.             counter = counter + 1
  868.             if counter % 3 or counter == length:
  869.                 displayNumber = "%s%s" % (char, displayNumber)
  870.             else:
  871.                 displayNumber = ",%s%s" % (char, displayNumber)
  872.         if len(splitNum) > 1:
  873.             displayNumber = "%s.%s" % (displayNumber, splitNum[1])
  874.         return displayNumber
  875.     def __display_generic_mappable(self, map, value, style, plural=True):
  876.         displayValue = ''
  877.         length = len(str(value))
  878.         if length > 3:
  879.             for factorSet in map:
  880.                 displayValue = float(value) / factorSet['factor']
  881.                 if len(str(int(displayValue))) <= 3 or 
  882.                     factorSet['factor'] == map[-1]['factor']:
  883.                     displayValue = "%10.2f" % displayValue    
  884.                     if displayValue[-1] == '0':
  885.                         if displayValue > 1 and style != 'short' and plural:
  886.                             displayValue = "%s %ss" % (displayValue[:-1], 
  887.                                                       factorSet[style])
  888.                         else:
  889.                             displayValue = "%s %s" % (displayValue[:-1], 
  890.                                                       factorSet[style])
  891.                     else:
  892.                         if displayValue > 1 and style != 'short' and plural:
  893.                             displayValue = "%s %ss" % (displayValue, 
  894.                                                       factorSet[style])
  895.                         else:
  896.                             displayValue = "%s %s" % (displayValue, 
  897.                                                       factorSet[style])
  898.                     break
  899.         return displayValue
  900.     def __display_directory(self, value, style):
  901.         return self.__display_default(value, style)
  902.     def __display_address(self, value, style):
  903.         return self.__display_default(value, style)
  904.     def __display_ip_address(self, value, style):
  905.         return self.__display_default(value, style)
  906.     def __display_net_address(self, value, style):
  907.         return self.__display_default(value, style)
  908.     def __display_bool(self, value, style):
  909.         displayValue = value
  910.         
  911.         if not isinstance(displayValue, bool):
  912.             if re.match("^false|0|f|no$", value, 2):
  913.                 displayValue=False
  914.             elif re.match("^true|1|t|yes$", value, 2):
  915.                 displayValue=True
  916.         return displayValue
  917.     def __display_int(self, value, style):
  918.         return self.__display_generic_number(value)
  919.     def __display_float(self, value, style):
  920.         return self.__display_generic_number(value)
  921.     def __display_pos_int(self, value, style):
  922.         return self.__display_generic_number(value)
  923.     def __display_neg_int(self, value, style):
  924.         return self.__display_generic_number(value)
  925.     def __display_pos_num(self, value, style):
  926.         return self.__display_generic_number(value)
  927.     def __display_pos_float(self, value, style):
  928.         return self.__display_generic_number(value)
  929.     def __display_neg_float(self, value, style):
  930.         return self.__display_generic_number(value)
  931.     def __display_string(self, value, style):
  932.         return self.__display_default(value, style)
  933.     def __display_list(self, value, style):
  934.         value = value.rstrip()
  935.         return value.rstrip(',')
  936.     def __display_keyval(self, value, style):
  937.         value = value.rstrip()
  938.         return value.rstrip(',')
  939.     def __display_file(self, value, style):
  940.         return self.__display_default(value, style)
  941.     def __display_size(self, value, style):
  942.         return self.__display_generic_mappable(sizeMap, value, style)
  943.     def __display_freq(self, value, style):
  944.         return self.__display_generic_mappable(freqMap, value, style, False)
  945.     def __display_eaddress(self, value, style):
  946.         return self.__display_default(value, style)
  947.     def __display_tcp_port(self, value, style):
  948.         return self.__display_default(value, style)
  949.     def __display_http_version(self, value, style):
  950.         return self.__display_default(value, style)
  951.     def __display_range(self, value, style):
  952.         return self.__display_default(value, style)
  953.     def __display_hostname(self, value, style):
  954.         return self.__display_default(value, style)
  955.     def __display_user_account(self, value, style):
  956.         return self.__display_default(value, style)
  957.     def __display_user_group(self, value, style):
  958.         return self.__display_default(value, style)
  959.     def __display_timestamp(self, value, style):
  960.         return self.__display_default(value, style)
  961.     def display(self, type, value, style='short'):
  962.         displayValue = value
  963.         if value != None:
  964.             displayValue = self.displayFunctions[type](value, style)
  965.         return displayValue
  966. typeValidatorInstance = typeValidator()
  967. def is_valid_type(type):
  968.     """Returns true if type is valid."""
  969.     return typeValidatorInstance.is_valid_type(type)
  970. def type_info(type):
  971.     """Returns type info dictionary."""
  972.     return typeValidatorInstance.type_info(type)
  973. def verify(type, value, allowNone=False):
  974.     """Returns a normalized valueInfo dictionary."""
  975.     return typeValidatorInstance.verify(type, value, allowNone)
  976. def __normalize(map, val, factor):
  977.     normFactor = string.lower(factor)
  978.     normVal = float(val)
  979.     return int(normVal * map[normFactor])
  980. def normalize_size(size, factor):
  981.     """ Normalize a size to bytes.
  982.         size   - number of B, KB, MB, GB, TB, or PB
  983.         factor - size factor (case insensitive):
  984.                  b | bytes - bytes
  985.                  k | kb    - kilobytes
  986.                  m | mb    - megabytes
  987.                  g | gb    - gigabytes
  988.                  t | tb    - terabytes
  989.                  p | pb    - petabytes
  990.     """
  991.     return __normalize(sizeFactors, size, factor)
  992. def normalize_freq(freq, factor):
  993.     """ Normalize a frequency to hertz.
  994.         freq   - number of Hz, Khz, Mhz, Ghz, Thz, or Phz
  995.         factor - size factor (case insensitive):
  996.                  Hz  - Hertz
  997.                  Mhz - Megahertz
  998.                  Ghz - Gigahertz
  999.                  Thz - Terahertz
  1000.                  Phz - Petahertz
  1001.     """
  1002.     return __normalize(freqFactors, freq, factor)