source: TI05-delivery/ows_framework/trunk/ows_server/ows_server/models/ndgVocab.py @ 2938

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI05-delivery/ows_framework/trunk/ows_server/ows_server/models/ndgVocab.py@2938
Revision 2938, 8.0 KB checked in by lawrence, 13 years ago (diff)

Provides a test harness for the getrelatedrecords option in
the BODC VocabServer?.

Line 
1# Provides an interface to the vocab server via the soap wsdl ...
2from xml.dom import expatbuilder
3# These two are generated from the wsdl via the wsdl2py command
4# with flags as in the wsdlUse script ...
5
6from vocabDefs_services_types import *
7from vocabDefs_services import *
8
9class ExpatReaderClass:
10      fromString = staticmethod(expatbuilder.parseString)
11      fromStream = staticmethod(expatbuilder.parse)
12 
13
14class ndgVocab:
15
16    def __init__(self,logger=None,tracefile=None):
17        '''Get an instance of the vocab service'''
18       
19        loc=vocabLocator()
20       
21        self.server=loc.getvocabPortType(readerclass=ExpatReaderClass,tracefile=tracefile)
22        self.logger=logger
23       
24    def getRelated (self, term, matchType='hasNarrowMatch'): 
25        ''' Here is the relevant bits of wsdl ...
26        <xsd:complexType name="getRelatedRecordType">
27            <xsd:sequence>
28                    <xsd:element name="recordSelection" type="types:recordSelection" />
29                    <xsd:element name="predicate" type="xsd:int" />
30                    <xsd:element name="objectList" type="xsd:string"
31                            minOccurs="0" maxOccurs="unbounded"/>
32                    <xsd:element name="inferences" type="xsd:string"/>
33            </xsd:sequence>
34        </xsd:complexType>
35        Which is kind of ugly, because it's a nested complex type, so we need to go
36        get the meaning of recordSelection ...which leads me to:
37        <xsd:complexType name="recordSelection">
38            <xsd:choice>
39                    <xsd:element name="recordIdentifer" type="types:recordIdentifier" />
40                    <xsd:element name="recordCriteria" type="types:recordCriteria" />
41            </xsd:choice>
42        </xsd:complexType>
43
44        <xsd:complexType name="recordIdentifier">
45            <xsd:sequence>
46                    <xsd:element name="subjectTerm" type="xsd:string"
47                            minOccurs="1" maxOccurs="unbounded" />
48            </xsd:sequence>
49        </xsd:complexType>
50            <xsd:complexType name="recordCriteria">
51                    <xsd:sequence>
52                            <xsd:element name="subjectList" type="xsd:string"
53                                    minOccurs="1" maxOccurs="unbounded" />
54                            <xsd:element name="subjectField" type="xsd:string"
55                                    minOccurs="0" default="long"/>
56                            <xsd:element name="subjectText" type="xsd:string" />
57                            <xsd:element name="caseSensitivity" type="xsd:boolean"
58                                    minOccurs="0" default="true" />
59                            <xsd:element name="partialMatch" type="xsd:boolean"
60                                                minOccurs="0" default="false"/>
61                            </xsd:sequence>
62                      </xsd:complexType>
63        </xsd:complexType>
64       
65       
66       
67        Relationships are documented as:
68
69            Uses a bit mask supplied as a hexadecimal number mapped as follows:
70           
71            1:  hasExactMatch
72            2:  hasNarrowMatch
73            4:  hasBroadMatch
74            8:  hasMinorMatch
75            16: hasMajorMatch
76           
77            Mask Conversion table
78           
79            Hex Relationships Included  Binary
80            '01'        hasExactMatch   00000001
81            '02'        hasNarrowMatch  00000010
82            '03'        hasExactMatch + hasNarrowMatch  00000011
83            '04'        hasBroadMatch   00000100
84            '05'        hasExactMatch + hasBroadMatch   00000101
85            '06'        hasNarrowMatch + hasBroadMatch  00000110
86            '07'        hasExactMatch + hasNarrowMatch + hasBroadMatch  00000111
87            '08'        hasMinorMatch   00001000
88            '09'        hasMinorMatch + hasExactMatch   00001001
89            '0A'        hasMinorMatch + hasNarrowMatch  00001010
90            '0B'        hasMinorMatch + hasExactMatch + hasNarrowMatch  00001011
91            '0C'        hasMinorMatch + hasBroadMatch   00001100
92            '0D'        hasMinorMatch + hasExactMatch + hasBroadMatch   00001101
93            '0E'        hasMinorMatch + hasNarrowMatch + hasBroadMatch  00001110
94            '0F'        hasMinorMatch + hasExactMatch + hasNarrowMatch + hasBroadMatch  00001111
95            '10'        hasMajorMatch   00010000
96            '11'        hasMajorMatch  + hasExactMatch  00010001
97            '12'        hasMajorMatch  + hasNarrowMatch 00010010
98            '13'        hasMajorMatch  + hasExactMatch + hasNarrowMatch 00010011
99            '14'        hasMajorMatch  + hasBroadMatch  00010100
100            '15'        hasMajorMatch  + hasExactMatch + hasBroadMatch  00010101
101            '16'        hasMajorMatch  + hasNarrowMatch + hasBroadMatch 00010110
102            '17'        hasMajorMatch  + hasExactMatch + hasNarrowMatch + hasBroadMatch 00010111
103            '18'        hasMajorMatch  + hasMinorMatch  00011000
104            '19'        hasMajorMatch  + hasMinorMatch + hasExactMatch  00011001
105            '1A'        hasMajorMatch  + hasMinorMatch + hasNarrowMatch 00011010
106            '1B'        hasMajorMatch  + hasMinorMatch + hasExactMatch + hasNarrowMatch 00011011
107            '1C'        hasMajorMatch  + hasMinorMatch + hasBroadMatch  00011100
108            '1D'        hasMajorMatch  + hasMinorMatch + hasExactMatch + hasBroadMatch  00011101
109            '1E'        hasMajorMatch  + hasMinorMatch + hasNarrowMatch + hasBroadMatch 00011110
110            '1F'        hasMajorMatch  + hasMinorMatch + hasExactMatch + hasNarrowMatch + hasBroadMatch 00011111
111            'FF'        All relationships currently defined plus any added in the future        11111111
112           
113        Roy's email specifies:
114        subjectText is your target string
115        subjectField - always set to 'long'
116        subjectList and objectList always
117            http://vocab.ndg.nerc.ac.uk/list/P211/27 or
118            http://vocab.ndg.nerc.ac.uk/list/P211/current
119        caseSensitivity and partialMatch - true or false (up to you)
120        inference set to true and don't worry about it (hook for the future -
121            the backend is currently limited to one end of the vocab tree)
122        The predicate is a number between 1 and 255 that controls the
123        predicates to be included (see the table at the end of the attached
124        document). 255 includes everything.
125           
126        '''
127
128        request=getRelatedRecordRequest()
129        request.Inferences=True
130        request.ObjectList=['http://vocab.ndg.nerc.ac.uk/list/P211/current']
131       
132       
133        selection=request.new_recordSelection()
134       
135        criteria=selection.new_recordCriteria()
136       
137        criteria.SubjectText=term
138        criteria.SubjectList=['http://vocab.ndg.nerc.ac.uk/list/P211/current']
139        criteria.CaseSensitivity=False
140        criteria.PartialMatch=True
141       
142        selection.RecordCriteria=criteria
143        request.RecordSelection=selection
144       
145        try:
146            #Obviously we just add things from the list above to the dictionary as required
147            request.Predicate={'hasNarrowMatch':2,
148                                  'hasBroadMatch':4
149                                    }[matchType]
150        except KeyError,e:
151            raise KeyError,e
152       
153        if self.logger: itime=time.time()
154       
155        #Do the vocab request
156        response=self.server.getRelatedRecord(request)
157       
158        # The response type is supposed to follow this schema fragment
159        # <xsd:complexType name="getRelatedRecordResponseType">
160        #    <xsd:sequence>
161        #    <xsd:element name="codeTableRecord" type="types:codeTableRecordType"
162        #                 minOccurs="0" maxOccurs="unbounded" />
163        #    </xsd:sequence>
164        # </xsd:complexType>
165        #
166        # But at the moment I can't find a definition of this
167           
168        if self.logger:
169            etime=time.time()-itime
170            self.logger.info('Vocab Request [%s] took [%ss]'%(term,etime))
171       
172        print dir(response)
173       
174        return response
175       
176       
177if __name__=="__main__":
178   
179    import unittest
180
181    class TestCase(unittest.TestCase):
182   
183        def testgetRelated(self):
184             term='Temperature'
185             x=ndgVocab()
186             r=x.getRelated(term)
187             self.assertEqual(r,'blah')
188   
189    unittest.main()
190             
191             
192             
193
Note: See TracBrowser for help on using the repository browser.