2 Parses an Evergreen fieldmapper IDL file and builds a global registry of
3 objects representing that IDL.
8 >>> import oils.utils.idl
9 >>> osrf.system.connect('/openils/conf/opensrf_core.xml', 'config.opensrf')
10 >>> oils.utils.idl.oilsParseIDL()
11 >>> # 'bre' is a network registry hint, or class ID in the IDL file
12 ... print oils.utils.idl.oilsGetIDLParser().IDLObject['bre']['tablename']
19 import sys, string, xml.dom.minidom
20 from oils.const import OILS_NS_OBJ, OILS_NS_PERSIST, OILS_NS_REPORTER
22 __global_parser = None
25 global __global_parser
26 if __global_parser: return # no need to re-parse the IDL
27 idlParser = oilsIDLParser();
28 idlParser.setIDL(osrf.set.get('IDL'))
30 __global_parser = idlParser
32 def oilsGetIDLParser():
33 global __global_parser
34 return __global_parser
36 class oilsIDLParser(object):
41 def setIDL(self, file):
42 osrf.log.log_info("setting IDL file to " + str(file))
45 def __getAttr(self, node, name, ns=None):
46 """ Find the attribute value on a given node
47 Namespace is ignored for now..
48 not sure if minidom has namespace support.
50 attr = node.attributes.get(name)
56 """Parses the IDL file and builds class objects"""
58 doc = xml.dom.minidom.parse(self.idlFile)
59 root = doc.childNodes[0]
61 for child in root.childNodes:
63 if child.nodeType == child.ELEMENT_NODE:
65 # -----------------------------------------------------------------------
66 # 'child' is the main class node for a fieldmapper class.
67 # It has 'fields' and 'links' nodes as children.
68 # -----------------------------------------------------------------------
70 id = self.__getAttr(child, 'id')
71 self.IDLObject[id] = {}
72 obj = self.IDLObject[id]
75 obj['controller'] = self.__getAttr(child, 'controller')
76 obj['fieldmapper'] = self.__getAttr(child, 'oils_obj:fieldmapper', OILS_NS_OBJ)
77 obj['virtual'] = self.__getAttr(child, 'oils_persist:virtual', OILS_NS_PERSIST)
78 obj['rpt_label'] = self.__getAttr(child, 'reporter:label', OILS_NS_REPORTER)
79 obj['tablename'] = self.__getAttr(child, 'oils_persist:tablename', OILS_NS_REPORTER)
82 for classNode in child.childNodes:
83 if classNode.nodeType == classNode.ELEMENT_NODE:
84 if classNode.nodeName == 'fields':
85 keys = self.parseFields(id, classNode)
87 osrf.net_obj.register_hint(id, keys, 'array')
92 def parseFields(self, cls, fields):
93 """Takes the fields node and parses the included field elements"""
96 idlobj = self.IDLObject[cls]
98 for field in fields.childNodes:
99 if field.nodeType == field.ELEMENT_NODE:
102 for field in fields.childNodes:
104 if field.nodeType == fields.ELEMENT_NODE:
105 name = self.__getAttr(field, 'name')
106 position = int(self.__getAttr(field, 'oils_obj:array_position', OILS_NS_OBJ))
110 keys[position] = name
112 osrf.log.log_error("parseFields(): position out of range. pos=%d : key-size=%d" % (position, len(keys)))
115 virtual = self.__getAttr(field, 'oils_persist:virtual', OILS_NS_PERSIST)
116 obj['rpt_label'] = self.__getAttr(field, 'reporter:label', OILS_NS_REPORTER)
117 obj['rpt_dtype'] = self.__getAttr(field, 'reporter:datatype', OILS_NS_REPORTER)
118 obj['rpt_select'] = self.__getAttr(field, 'reporter:selector', OILS_NS_REPORTER)
120 if virtual == string.lower('true'):
121 obj['virtual'] = True
123 obj['virtual'] = False
125 idlobj['fields'].append(obj)