source: ndgCommon/trunk/ndg/common/src/models/ndgObject.py @ 5019

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

Move deployments + DE lookup URLs for atoms to within Atom data model

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