source: exist/trunk/python/ndgUtils/ndgObject.py @ 4696

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/exist/trunk/python/ndgUtils/ndgObject.py@4696
Revision 4696, 7.4 KB checked in by cbyrom, 11 years ago (diff)

Adjust Atom and MolesEntity? data models to properly use namespaces when
dealing with xpath queries - rather than having these stripped out. This
avoids problems when namespaces are given arbitrary names and is a more
exact, hence robust, approach.
Create new test class to put the xmlhandler2 tests separately in.
Add delete function to granulite - to allow data granules, and their
connections to data entities, to be removed + add 'roll back' functionality
to cope with scenarios when granulite replace/delete fails to complete
properly. Add new methods to the existdbclient to allow the restore/delete/backup
functionality.
Extend test suite to exercise new functionality.

Line 
1import ndgRetrieve, xmlHandler2, logging
2
3class ndgObject:
4    ''' This class instantiates an ndgObject which describes the various ways
5        of obtaining itself, primarily
6                (1) a downloadable xml representation from a repository,
7                (2) a printable xml representation '''
8
9    # The various different document types:
10    MOLES_DOC_TYPE = 'NDG-B1'
11    DIF_DOC_TYPE = 'DIF'
12    DC_DOC_TYPE = 'DC'
13    ISO_DOC_TYPE = 'ISO19139'
14    NDGB1_DOC_TYPE = 'NDG-B1'
15    NDGB0_DOC_TYPE = 'NDG-B0'
16    MDIP_DOC_TYPE = 'MDIP'
17    NDGA0_DOC_TYPE = 'NDG-A0'
18    NUMSIM_DOC_TYPE = 'NumSim'
19    ATOM_DOC_TYPE = 'ATOM'
20    ATOM_BACKUP_DOC_TYPE = 'ATOM-BACKUP'
21
22        # various namespaces used in the docs
23    ATOM_NS = 'http://www.w3.org/2005/Atom'
24    DIF_NS = 'http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/'
25    MOLES_NS = 'http://ndg.nerc.ac.uk/schema/moles2beta'
26    GEOSS_NS = 'http://www.georss.org/georss/10'
27    GML_NS = 'http://www.opengis.net/gml'
28    CSML_NS = 'http://ndg.nerc.ac.uk/csml'
29    XHTML_NS = "http://www.w3.org/1999/xhtml"
30    CDML_DTD = 'http://www-pcmdi.llnl.gov/software/cdms/cdml.dtd'
31       
32    # Group the doc types according to the source they should be retrieved from
33    DISCOVERY_SCHEMES = [DIF_DOC_TYPE, DC_DOC_TYPE, \
34                         MDIP_DOC_TYPE, ISO_DOC_TYPE, 'ISO']
35    BROWSE_SCHEMES = [MOLES_DOC_TYPE, NDGB1_DOC_TYPE, \
36                      NUMSIM_DOC_TYPE, ATOM_DOC_TYPE, \
37                      ATOM_BACKUP_DOC_TYPE]
38   
39    def __init__(self,uri,config=None):
40        ''' Parse the uri and prepare for obtaining the actual content'''
41        logging.debug("Initialising ndgObject with uri: '%s'" %uri)
42        #Dom had problem with unicode coming in here ... dunno why @@@@
43        uri=str(uri) 
44       
45        # a priori, assume we can't get content for this object
46        self.gettable=-1 
47       
48        # handle all the known ways of doing an NDG URI ...
49        bits=uri.split(':')
50        bits2=uri.split('__')
51        ok=1
52        if len(bits)==3:
53            repository,schema,localID=bits
54            self.uri=uri.replace(':','__')
55        elif len(bits2)==3:
56            repository,schema,localID=bits2
57            self.uri=uri
58        elif len(bits2)>3:
59            repository,schema,localID=bits2[0],bits2[1],'__'.join(bits2[2:])
60            self.uri=uri
61        else:
62            bits=uri.split('/')
63            if len(bits)==2:
64                schema='NDG-B0'
65                repository,localID=bits
66                self.uri=None  #
67                ok=0  # I reckon we shouldn't ever see any of these again ...
68                # but if we do, the uri will need fixing too ...
69            else: ok=0
70       
71        if not ok:
72            # after all that, we don't think it's an NDG URI ...
73            raise ValueError,'The identifier [%s] is not a valid NDG style URI'%uri
74
75        # yes, it is an NDG URI ...
76        self.repository,self.schema,self.localID=repository,schema,localID
77        logging.debug("Extracted valid NDG values from URI: repository: '%s', schema: '%s', localID: '%s'" \
78                      %(repository, schema, localID))
79        self.setConfig(config)
80
81    def setDefaultProperties(self):
82        '''
83        Set default properties for object
84        '''
85        self.discoveryURL,self.baseURL,self.xmlURL,\
86            self.printableURL =None,None,None,None
87        self.useDiscoveryService = 1
88        self.BURL=None
89
90       
91    def setConfig(self, config):
92        '''
93        Set up the configuration for retrieving this document
94        '''
95        logging.debug("Setting up configuration for retrieving document")
96        self.config=config
97        if config is None:
98            self.setDefaultProperties()
99            return
100
101        self.server=self.config.get('DISCOVERY','default')
102        server=self.server
103        qs=None
104        # This NDG object may itself be a discovery record, which makes life easy, but
105        # it might not be, in which case we have to build up all the possible views upon it.
106        # But remember only data entity b records have discovery records ...
107        self.viewService='%s/view/'%server
108        discoveryBASE='%s%s__%s__%s'%(self.viewService,self.repository,self.schema,self.localID)
109
110        # set default return format - if not set, just return in original format
111        fmt = self.config.get('DISCOVERY','formatDefault')
112        logging.info("Default discovery format set to: %s" %fmt)
113           
114        self.BURL=None
115        # We'll build the following even if it can't be used (as would be the case for
116        # a non data entity B record or an A record) because it's a useful template.
117        if self.schema!=fmt: 
118            qs=('outputSchema',fmt)
119        self.discoveryURL=self.__buildURL(discoveryBASE,[qs])
120
121        # config file should have details on the service to use for the repository
122        # - if not, default to 'unknown'
123        servicehost = self.config.get('NDG_B_SERVICE',self.repository)
124        if not servicehost:
125            servicehost = 'unknown'
126           
127        # If this record is itself a discovery record, then we don't have much more to do
128        if self.schema in self.DISCOVERY_SCHEMES:
129            self.xmlURL=self.__buildURL(
130                discoveryBASE.replace('/view/','/retrieve/'),[qs,('format','raw')])
131            self.printableURL=self.__buildURL(discoveryBASE,[qs,('format','xml')])
132            self.URL=self.discoveryURL
133            if servicehost != 'unknown':
134                self.gettable=1
135        elif self.schema in self.BROWSE_SCHEMES:
136            # One day we'll use a service binding to get this
137            # This is a mapping from the ndg repository id to an actual repository id
138            # understood by the ndg exist interface
139            blank=self.config.get('NDG_B_SERVICE','instance')
140            url=blank.replace('SERVICEHOST',servicehost)
141            url=url.replace('URI',self.uri)
142            self.URL=url
143            self.xmlURL=url.replace('/view/','/retrieve/')+'?format=raw'
144            self.printableURL=url+'?format=xml'
145            if servicehost !='unknown': 
146                self.gettable=0
147            self.useDiscoveryService = 0
148        else:
149            #currently we don't know how to get this one
150            self.URL='unknown'
151            self.setDefaultProperties()
152
153        logging.debug("Set up URL: '%s', discoveryURL: '%s'" %(self.URL, self.discoveryURL))
154           
155        #now, we'll build a stub-B url as well, in case that comes in handy
156        if self.schema!='NumSim' and self.gettable<>-1:
157            if self.schema:
158                self.BURL=discoveryBASE.replace(self.schema,'NDG-B1')
159            if server:
160                self.BURL=self.BURL.replace(server,servicehost)
161            logging.debug("Set up stub-B url: '%s'" %self.BURL)
162
163
164    def __buildURL(self,base,queryStuff):
165        ss=''
166        for i in queryStuff: 
167            if i!=None:ss+='&%s=%s'%(i[0],i[1])
168        if ss!='':ss='?'+ss[1:]
169        return base+ss
170           
171    def get(self,securityCredentials=None):
172        ''' Actually retrieve an ORIGINAL xml record corresponding to an ndg URI
173        NB, not sure if this method is actually used anywhere - since get is
174        usually done via ndgRetrieve
175        '''
176        if self.config is None: return None
177        status,xmlh=ndgRetrieve.ndgRetrieve(self,self.config, \
178                                            discovery = self.useDiscoveryService)
179        if status:
180            x=xmlHandler2.xmlHandler(xmlh,string=1)
181            return x.xmls
182        else:
183            return status
184       
185    def __str__(self):
186        return self.uri
187
Note: See TracBrowser for help on using the repository browser.