source: ndgCommon/trunk/ndg/common/src/models/abstractrecord.py @ 5147

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/ndgCommon/trunk/ndg/common/src/models/abstractrecord.py@5147
Revision 5147, 5.0 KB checked in by cbyrom, 13 years ago (diff)

Add new tests and test constants.

Line 
1'''
2 Abstract implementation of InterfaceRecord adding generic methods
3   
4 @author: C Byrom, Tessella Feb 2009
5'''
6from xml.etree import cElementTree as ET
7import logging, datetime, re
8from ndg.common.src.lib.ETxmlView import et2text
9from interfacerecord import InterfaceRecord
10from ndg.common.src.lib.utilities import DATE_FORMAT
11
12class AbstractRecord(InterfaceRecord):
13
14    STRING_MESSAGE = "%s type data record - attributes: "
15   
16    CREATED_DATE = 'createdDate'
17    ATTS_TO_SKIP = [CREATED_DATE, 'entryTermLastMod', 'listLastMod', 
18                    'createdDate', 'fields']
19   
20    def __init__(self, et = None, **inputs):
21        '''
22        Constructor - initialise the CF Standard name object
23        @keyword et: elementtree entry representing a Standard Name entry - to
24        read in
25        '''
26        logging.debug("Initialising AbstractRecord object")
27
28        logging.debug("Initialising fields")
29        for att in self.__slots__:
30            setattr(self, att, '')
31
32        self.id = ''
33        self.createdDate = datetime.datetime.now().strftime(DATE_FORMAT)
34        logging.debug("Fields initialised")
35
36        if et:
37            self.fromET(et)
38
39        for key, val in inputs.items():
40            logging.debug("Adding inputs dict data: %s = %s" %(key, val))
41            setattr(self, key, val)
42
43        logging.debug("AbstractRecord initialised")
44
45
46    def isEmpty(self):
47        '''
48        Determine whether the record has any values set on it
49        @return True if the object is effectively empty, False otherwise
50        '''
51        for att in self.__slots__:
52            if att in self.ATTS_TO_SKIP:
53                continue
54           
55            if getattr(self, att):
56                return False
57       
58        return True
59           
60       
61    def __cmp__(self, other):
62        '''
63        Override standard compare to allow sorting on createdDate
64        @param other: other object with which to compare this object to
65        '''
66        if not other or not isinstance(other, InterfaceRecord):
67            return -1
68       
69        d0 = datetime.datetime.strptime(self.createdDate, DATE_FORMAT)
70        d1 = datetime.datetime.strptime(other.createdDate, DATE_FORMAT)
71        if self is other:
72            return 0
73        elif d0 == d1:
74            return 0
75        elif d0 < d1:
76            return -1
77        return 1
78
79    def __str__(self):
80        outString = self.STRING_MESSAGE %type(self)
81        attString = ""
82        for att in self.__slots__:
83            if attString:
84                attString += ', '
85            attString += "%s = '%s'" %(att, getattr(self, att))
86       
87        return outString + attString
88
89
90    def toET(self):
91        '''
92        Convert the Record data into ElementTree representation and return this
93        @return: ElementTree version of data
94        '''
95        raise NotImplementedError("This is an interface class and this method has not " + \
96                                  "been implemented yet")
97
98       
99    def fromET(self, et):
100        '''
101        Extract and add data from an elementtree object
102        @param et: Elementtree object representing a Record data entry
103        '''
104        raise NotImplementedError("This is an interface class and this method has not " + \
105                                  "been implemented yet")
106
107
108    def toXMLString(self):
109        '''
110        Returns data as nicely formatted XML string
111        @return xmlString: record object in XML string representation
112        '''
113        xml = self.toET()
114
115        # create the string
116        logging.debug("Converting the elementtree object into a string")
117        # NB, the commented out approach is the simplest - but this doesn't
118        # preserve tab spacing and new lines
119        prettyXML = et2text(xml)#ET.tostring(xml)
120
121        logging.debug("Created formatted version of XML object")
122        return prettyXML
123
124           
125    def fromXMLString(self, xmlString):
126        '''
127        Initialise Record object using an xmlString
128        @param xmlString: representation of Record as an XML string
129        @return ElementTree representation of string
130        '''
131        logging.debug("Ingesting data from XML string")
132        logging.debug("Create elementtree instance with XML string")
133        tree = ET.fromstring(xmlString)
134        self.fromET(tree)
135        logging.debug("Completed data ingest")
136        return tree
137
138
139    def getRecordTypeName(self):
140        '''
141        Return the type of record, i.e. the class name, in a nice formatted
142        way
143        @return typeName: class name of record in formatted readable way
144        '''
145        logging.debug("Getting record type name for '%s' record" %type(self))
146        # get the class name, without the package info - there may be an easier way to do this??
147        typeName = str(type(self)).split('\'')[1].split('.')[-1]
148        # and fix any camelcase - putting into words
149        typeName = re.sub('([A-Z])', r" \1", typeName).strip()
150        logging.debug(" - returning type name, '%s'" %typeName)
151        return typeName
Note: See TracBrowser for help on using the repository browser.