source: trunk/src/groovy/dbnp/rest/CommunicationManager.groovy @ 621

Last change on this file since 621 was 621, checked in by jahn, 11 years ago

Added java.net.URLEncoder.encode() to protect URL parameters.

File size: 6.5 KB
RevLine 
[553]1package dbnp.rest
2
3import java.util.Map 
4import java.util.List
5import java.util.HashMap
[621]6import java.net.URLEncoder
[553]7import grails.converters.JSON
8import org.codehaus.groovy.grails.web.json.*
9import dbnp.studycapturing.TemplateFieldListItem
10import dbnp.studycapturing.Template
11import dbnp.data.CleanDataLayer
12import dbnp.studycapturing.Study 
[608]13import dbnp.studycapturing.Assay
[553]14
15
16
17
18/**  CommunicationManager
19 *
20 *   This class implements a REST client to fetch data from the Simple Assay Module (SAM).
21 *   The communicatino manager provides methods for accessing each resources.
22 *   Every REST resource corresponds to exactly one method in this class that makes
23 *   the communication with the resource available.
24 *
25 *   For instance, the getSearchable() method calls the getMeasurements resource of the SAM
26 *   by passing arguments to it and returning the result of the calling that resource.
27 */
28
29
30class CommunicationManager implements CleanDataLayer {
31
32   
33    /** ServerULR contains a string that represents the URL of the
34     *  rest resources that this communication manager connects to.
35     */ 
36
[609]37    //def static ServerURL = "http://localhost:8182/ClinicalChemistry"
38    def static ServerURL = "http://nbx5.nugo.org/sam"
[608]39    def static RestServerURL = ServerURL + "/rest"
[621]40    def static Encoding = "UTF-8" 
[553]41
[608]42
[553]43    /* Methods implemented for CleanDataLayer */
44
45
[608]46
[553]47    /**
48     * Get the names of all quantitative features that are available for a certain assay
49     * @param assayID the module internal ID for the assay
50     * @return
51     */
52    public String[] getFeaturesQuantitative(long assayID) {
[608]53         return new String [20]
[553]54    }
55   
56
57
58    /**
59     * Get the data for a quantitative feature for a certain assay for a certain set of samples
60     * @param feature
61     * @param assayID
62     * @param sampleIDs
63     * @return Map
64     */
65    public Map getDataQuantitative(String feature, long assayID, String[] sampleIDs) {
[608]66         return new HashMap() 
[553]67    }
68
69
70    /**
71     * Testing REST. Remove when connection to nbx5 is established.
72     *
73     * @return list of ClinicalFloatData
74     */
75    public Object getFeatures() {
[621]76        //    return  request( "features" )
[553]77        return  getStudiesForKeyword("ldl")
78    }
79
80
81    /**
82     * For a string for the searchable plugin.
83     * This works for one keyeword, but protection should be built in using
84     * the methods that searchable uses for building query strings.
85     *
86     * @return list of ClinicalFloatData
87     */
88    private String getSearchable( keyword ) {
89        return  "?submit=Query&q=" + keyword
90    }
91
92
93    /**
94     * Get all meassurements that contain a given keyword as feature.
95     *
96     * @param  keyword, the keyword used
97     * @return list of ClinicalFloatData
98     */
99    public String getStudiesForKeyword( String keyword ) {
100        def resource = "getMeasurementsForValue"
101        request( resource + getSearchable(keyword) )
102    }
103
104
105    /**
106     * Get all meassurements that contain a given keyword as feature.
107     *
108     * @param  keyword, the keyword used
109     * @return list of ClinicalFloatData
110     */
111    public Object getMeasurementsResource( String keyword ) {
[608]112        def url = new URL( RestServerURL + "/" + getSearchable(keyword) )
[553]113        return  JSON.parse( url.newReader() )
114    }
115
116
117
118    /** Send a request for the REST resource to the server and deliver the
119     *  resulting JSON object. (This is just a convenience method.)
120     *
121     *  @param resource: the name of the resource including parameters
122     *  @return JSON object
123     */
124    private Object request( String resource ) { 
[608]125        def url = new URL( RestServerURL + "/" + resource )
126        return  JSON.parse( url.newReader() )
[553]127    }
128
129
130
131    /** Send a request for the REST resource to SAM and deliver the
132     *  results for the Query controller.
133     *
134     *  @param  compound        a SAM compound, e.g., "ldl" or "weight"
135     *  @param  value           a SAM value of a measurement, e.g. "20" (without unit, please)
136     *  @param  opperator       a SAM operator, i.e., "", "=", "<", or ">"
137     *  @return List of matching studies
138     */
139    public List<Study> getSAMStudies( String compound, String value, String opperator ) {
140         return [] 
141    }
142
143
144
145
[609]146
147    /* Methods for accessing URLs in SAM */
148
149
[615]150
151
[608]152    /**
[621]153     * Convenience method for constructing URLs for SAM that need parameters.
154     * Note that parameters are first convereted to strings by calling their toString() method
155     * and then Encoded to protect special characters.
[615]156     *
157     * @params String resource The name of the resource, e.g. importer/pages
158     * @params Map params      A Map of parmater names and values., e.g. ['externalAssayID':12]
159     * @return String url   
160     */
161    private URL getSAMURL( resource, params ) {
162        def url = ServerURL + '/' + resource
163                def first = true
164                params.each { name, value ->
165                        if(first) {
[621]166                                first = false
167                                url += '/nil?' + name + "=" + URLEncoder.encode( value.toString(), Encoding )
[615]168                        }
169                        else { 
[621]170                                url += '&' + name + "=" + URLEncoder.encode( value.toString(), Encoding  )
[615]171                        }
172                }
173                return new URL( url )
174    }
175
176
177    /**
[609]178     * Get the URL for importing an assay from SAM.
[608]179     * This is not a REST method! It only creates a rest resource and returns it's url.
180     *
[615]181     * @params Study
182     * @params Assay
[609]183     * @return URL
[608]184     */
[615]185    public URL getAssayImportURL( study, assay ) {
186                def params = ['externalAssayID':assay.externalAssayID, 'externalStudyID':study.code ] 
187        return getSAMURL( 'importer/pages', params )
[608]188    }
[553]189
190
[608]191    /**
[609]192     * Get the URL for showing an assay in SAM.
[608]193     * This is not a REST method! It only creates a rest resource and returns it's url.
194     *
[615]195     * @params Assay
[608]196     * @return URL
197     */
[615]198    public URL getAssayShowURL( assay ) {
199                def params = ['externalAssayID':assay.externalAssayID ] 
200        return getSAMURL( 'simpleAssay/show', params )
[553]201    }
202
203
[608]204    /**
[609]205     * Get the URL for editing an assay in SAM.
[608]206     * This is not a REST method! It only creates a rest resource and returns it's url.
207     *
[615]208     * @params Assay
[608]209     * @return URL
210     */
[615]211    public URL getAssayEditURL( assay ) {
212                def params = ['externalAssayID':assay.externalAssayID ] 
213        return getSAMURL( 'simpleAssay/edit', params )
[553]214    }
215
216
[608]217    /**
[609]218     * Get the URL for showing a measurement in SAM.
[608]219     * This is not a REST method! It only creates a rest resource and returns it's url.
220     *
[615]221     * @params study
[608]222     * @return list of ClinicalFloatData
223     */
[615]224    public URL getMeasurementTypesURL( study ) {
225                def params = ['externalStudyID':study.code] 
226        return getSAMURL( 'simpleAssayMeasurementType/list', params )
[608]227    }
[553]228
229}
Note: See TracBrowser for help on using the repository browser.