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