source: ndgCommon/trunk/ndg/common/src/models/MolesEntity.py @ 4810

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

Create new class (and test suite) to do all the eXist DB setting up - and move this code from the
eXistdbclient to tidy things up.
Allow feed publishing to be done synch/asynch.
Improve loading of non-python resources - adding code to store the various schemata and indexes
required for setting up eXist
Improve parsing of atom URLs to allow browser host to change
Fix moles data in testconstants
Add tests for looking up associated atom data
Add indexing configuration files - to optimise atom processing in eXist + add code in initialiser class to set these up on eXist.
Add all the required schemata required for atom schema validation in eXist + add code in initialiser class to set these up on eXist;
this allows eXist to be ran without need of access beyond the firewall.

Line 
1'''
2 Class representing moles data that is too structured to be included in the basic Atom elements
3 
4 @author: C Byrom, Tessella Jun 2008
5'''
6from xml.etree import cElementTree as ET
7import logging, datetime, re
8from ndg.common.src.lib.utilities import escapeSpecialCharacters
9from ndg.common.src.models.ndgObject import ndgObject
10
11class MolesEntity(object):
12   
13    # URL which points to the browse service - NB ensure this is properly defined
14    BROWSE_URL = "http://ndg.badc.rl.ac.uk:8080/view"
15   
16    def __init__(self):
17        '''
18        Constructor - initialise the atom variables
19        '''
20        logging.info("Initialising MolesEntity")
21
22        # an array of Atom.Person objects
23        self.responsibleParties = []
24        self.deployments = {}
25        self.abbreviation = None
26        self.providerID = None
27        self.createdDate = None
28               
29        self.datasetLanguage = 'English'
30        self.metadataLanguage = 'English'
31       
32        # helper arrays to produce summary info for atom in templates
33        self.activities = []
34        self.obs = []
35        self.dpts = []
36        logging.info("MolesEntity initialised")     
37
38
39    def addResponsibleParty(self, partyVals):
40        '''
41        Add a responsible party - using the input string format,
42        ' name | uri | role '
43        '''
44        logging.debug("Adding responsible party data")
45        from ndg.common.src.models.Atom import Person
46        if type(partyVals) is not list:
47            partyVals = [partyVals]
48       
49        for vals in partyVals:
50            rp = Person(personType = Person.RESPONSIBLE_PARTY_TYPE)
51            rp.fromString(vals)
52            self.responsibleParties.append(rp)
53        logging.debug("Finished adding responsible party data")
54
55       
56    def toXML(self):
57        '''
58        Convert the atom into XML representation and return this
59        @return: xml version of atom
60        '''
61        logging.info("Creating formatted XML version of MolesEntity")
62        molesEntity = ET.Element("moles:entity")
63        molesEntity.attrib["xmlns:moles"] = ndgObject.MOLES_NS
64       
65        molesISO = ET.SubElement(molesEntity, "moles:molesISO")
66        datasetLanguage = ET.SubElement(molesISO, "moles:datasetLanguage")
67        datasetLanguage.text = self.datasetLanguage
68        metadataLanguage = ET.SubElement(molesISO, "moles:metadataLanguage")
69        metadataLanguage.text = self.metadataLanguage
70
71        if self.responsibleParties:
72            rpElement = ET.SubElement(molesISO, "moles:responsibleParties")
73            logging.info("Adding responsible parties info")
74            for party in self.responsibleParties:
75                rpElement.append(party.toXML())
76
77        if self.abbreviation:
78            logging.info("Adding abbreviation element")
79            abbreviationElement = ET.SubElement(molesISO, "moles:abbreviation")
80            abbreviationElement.text = self.abbreviation
81
82        if self.providerID:
83            logging.info("Adding providerID element")
84            subElement = ET.SubElement(molesISO, "moles:providerID")
85            subElement.text = self.providerID
86           
87        # if there's a created date already defined, use this, otherwise assume this is the creation point
88        # so use current time
89        if not self.createdDate:
90            self.createdDate = datetime.datetime.today().strftime("%Y-%m-%dT%H:%M:%SZ")
91
92        createdElement = ET.SubElement(molesISO, "moles:created")
93        createdElement.text = self.createdDate
94
95        logging.info("XML version of MolesEntity created")
96        return molesEntity
97
98
99    def fromET(self, tree):
100        '''
101        Initialise MolesEntity object using an elementtree
102        @param tree: ElementTree with moles entity data
103        '''
104        logging.info("Ingesting data from ElementTree object")
105        authorElements = tree.findall('{%s}molesISO/{%s}responsibleParties/{%s}responsibleParty' \
106                                      %(ndgObject.MOLES_NS, ndgObject.MOLES_NS, ndgObject.MOLES_NS))
107        from ndg.common.src.models.Atom import Person
108        for authorElement in authorElements:
109            logging.debug("Adding atom author data")
110            author = Person(personType = Person.RESPONSIBLE_PARTY_TYPE)
111            author.fromETElement(authorElement)
112            self.responsibleParties.append(author)
113               
114        self.abbreviation = tree.findtext('{%s}molesISO/{%s}abbreviation' \
115                                          %(ndgObject.MOLES_NS, ndgObject.MOLES_NS))
116
117        self.providerID = tree.findtext('{%s}molesISO/{%s}providerID' \
118                                        %(ndgObject.MOLES_NS, ndgObject.MOLES_NS))
119
120        self.datasetLanguage = tree.findtext('{%s}molesISO/{%s}datasetLanguage' \
121                                             %(ndgObject.MOLES_NS, ndgObject.MOLES_NS))
122        self.metadataLanguage = tree.findtext('{%s}molesISO/{%s}metadataLanguage' \
123                                              %(ndgObject.MOLES_NS, ndgObject.MOLES_NS))
124
125        createdDate = tree.findtext('{%s}molesISO/{%s}created' \
126                                    %(ndgObject.MOLES_NS, ndgObject.MOLES_NS))
127        if createdDate:
128            logging.debug("Adding created date")
129            self.createdDate = createdDate
130           
131        logging.info("Data ingested from tree")
132           
133           
134    def fromString(self, xmlString):
135        '''
136        Initialise MolesEntity object using an xmlString
137        @param xmlString: representation of atom as an XML string
138        '''
139        logging.info("Ingesting data from XML string")
140       
141        # now create elementtree with the XML string
142        logging.debug("Create elementtree instance with XML string")
143        # NB, there is every chance that the namespace will not be available in
144        # the input xmlString - since it is likely to be part of the Atom string
145        # passed in - and this will have the namespaces defined in the parent tag
146        # - check and add the moles NS if it is missing
147        xmlString = self.__addMolesNS(xmlString)
148       
149        tree = ET.fromstring(xmlString)
150        self.fromET(tree)
151        logging.info("Completed data ingest from XML string")
152
153
154    def __addMolesNS(self, xmlString):
155        '''
156        Check an XML string representation of the moles entity to see if it
157        contains the required moles namespace; if not, add it
158        '''
159        logging.debug("Checking if entity requires moles namespace adding")
160        if xmlString.find(ndgObject.MOLES_NS) > -1:
161            logging.debug("- namespace found - returning entity as is")
162            return
163
164        logging.debug("- namespace not found - adding this now")
165       
166        # firstly get the local namespace prefix name
167        prefix = re.search('<(\w+):', xmlString).group(1)
168        elementName = prefix + ':entity '
169       
170        # now do a replace on this to add in the namespace
171        xmlString = xmlString.replace(elementName, elementName + "xmlns:%s= '%s' " \
172                                      %(prefix, ndgObject.MOLES_NS))
173       
174        return xmlString
175
176       
177    def setAttribute(self, attributeName, attributeValue):
178        '''
179        Set the value of an atom attribute - and do some basic tidying up of the string content
180        - to escape any XML unfriendly characters
181        @param attributeName: name of the attribute whose value to set
182        @param attributeValue: value to set the attribute to 
183        '''
184        logging.debug("Setting attribute, %s, to %s" %(attributeName, attributeValue))
185        origValue = attributeValue
186       
187        # escape any special characters if a value has been specified
188        # NB, need to cope with both single values and arrays
189        if attributeValue:
190            if type(attributeValue) is list:
191                newVals = []
192                for val in attributeValue:
193                    newVals.append(escapeSpecialCharacters(val))
194                attributeValue = newVals
195            else:
196                attributeValue = escapeSpecialCharacters(attributeValue) 
197        setattr(self, attributeName, attributeValue)
Note: See TracBrowser for help on using the repository browser.