Project

General

Profile

1
/*
2
Author:       Mike Adair  mike.adairATccrs.nrcan.gc.ca
3
License:      LGPL as per: http://www.gnu.org/copyleft/lesser.html
4

    
5
$Id: WebServiceRequest.js 3881 2008-02-27 15:41:07Z gjvoosten $
6
*/
7

    
8
// Ensure this object's dependancies are loaded.
9
mapbuilder.loadScript(baseDir+"/tool/ToolBase.js");
10

    
11
/**
12
 * A controller issuing OGC web service requests.  The request is generated
13
 * by applying a stylesheet to a Layer/FeatureType/Coverage node from a 
14
 * capabilities document as a listener function.  The listener event name is 
15
 * a combination of the service type and the request name (e.g. wfs_GetFeature)
16
 * and the parameter passed to the listener is the featureName (Layer/FeatureType/Coverage).
17
 * The response from the request is stored in the targetModel.  If the 
18
 * targetModel is a template model (attribute template="true") the a new model 
19
 * is created and appended to the parentModel's <models> list.
20
 * @constructor
21
 * @base ToolBase
22
 * @param toolNode The tools's XML object node from the configuration document.
23
 * @param model    The model that this tool belongs to
24
 */
25
function WebServiceRequest(toolNode, model) {
26
  ToolBase.apply(this, new Array(toolNode, model));
27

    
28
  //this.debug=true;
29
  
30
  //get the request name to add listener to
31
  this.requestName = this.getProperty("mb:requestName");
32

    
33
  //get the request filter to add to the request
34
  this.requestFilter = this.getProperty("mb:requestFilter");
35

    
36
  var styleUrl = toolNode.selectSingleNode("mb:stylesheet");
37
  styleUrl = styleUrl ? getNodeValue(styleUrl) :
38
          baseDir+"/tool/xsl/"+this.requestName.replace(/:/,"_")+".xsl";
39
  this.requestStylesheet = new XslProcessor(styleUrl);
40

    
41
  // Set stylesheet parameters for all the child nodes from the config file
42
  for (var j=0;j<toolNode.childNodes.length;j++) {
43
    if (getNodeValue(toolNode.childNodes[j])) {
44
      this.requestStylesheet.setParameter(toolNode.childNodes[j].nodeName,getNodeValue(toolNode.childNodes[j]));
45
    }
46
  }
47

    
48
  this.model.addListener("init", this.init, this);
49
  this.model.addListener(this.requestName.replace(/:/,"_"), this.doRequest, this);
50
}
51

    
52
/**
53
 * Function which create the HTTP payload for a request
54
 * @param feature the feature object
55
 */
56
WebServiceRequest.prototype.createHttpPayload = function(feature) {
57
  //confirm inputs
58
  if (this.debug) mbDebugMessage(this, "source:"+(new XMLSerializer()).serializeToString(feature));
59
  //if (this.debug) mbDebugMessage(this, "stylesheet:"+(new XMLSerializer()).serializeToString(this.requestStylesheet.xslDom));
60

    
61

    
62
  //prepare the stylesheet
63
  var httpPayload = new Object();
64
  httpPayload.method = this.targetModel.method;
65
  this.requestStylesheet.setParameter("httpMethod", httpPayload.method );
66
  this.requestStylesheet.setParameter("version", this.model.getVersion(feature) );
67
  if (this.requestFilter) {
68
    var filter = config.objects[this.requestFilter];
69
    this.requestStylesheet.setParameter("filter", escape((new XMLSerializer()).serializeToString(filter.doc).replace(/[\n\f\r\t]/g,'') ));
70
    if (this.debug) mbDebugMessage(this, (new XMLSerializer()).serializeToString(filter.doc));
71
  }
72

    
73
  //process the doc with the stylesheet
74
  httpPayload.postData = this.requestStylesheet.transformNodeToObject(feature);
75
  if (this.debug) {
76
    mbDebugMessage(this, "request data:"+(new XMLSerializer()).serializeToString(httpPayload.postData));
77
    if (config.serializeUrl) var response = postLoad(config.serializeUrl, httpPayload.postData);
78
  }
79

    
80
  httpPayload.url = this.model.getServerUrl(this.requestName, httpPayload.method, feature);
81

    
82
  //extract the URL from the transformation result for GET method
83
  if (httpPayload.method.toLowerCase() == "get") {
84
    httpPayload.postData.setProperty("SelectionLanguage", "XPath");
85
    Sarissa.setXpathNamespaces(httpPayload.postData, "xmlns:mb='http://mapbuilder.sourceforge.net/mapbuilder'");
86
    var queryString = httpPayload.postData.selectSingleNode("//mb:QueryString");
87
    if (httpPayload.url.indexOf("?") < 0) {
88
      httpPayload.url += "?";
89
    } else {
90
      httpPayload.url += "&";
91
    }
92
    httpPayload.url += getNodeValue(queryString);
93
    httpPayload.postData = null;
94
  }
95
  mbDebugMessage(this, "URL:"+httpPayload.url);
96
  return httpPayload;
97
}
98

    
99

    
100
/**
101
 * Listener function which will actually issue the request.  This method
102
 * will prepare the HTTP payload for a particular featureName.
103
 * @param requestName the name of the web service operation to execute
104
 * @param featureNodeId the id of the node in the doc to be processed by the stylesheet
105
 */
106
WebServiceRequest.prototype.doRequest = function(objRef, featureName) {
107
  objRef.targetModel.featureName = featureName;
108

    
109
  var feature = objRef.model.getFeatureNode(featureName);
110
  if (!feature) {
111
    alert(mbGetMessage("featureNotFoundWebServiceRequest", featureName));
112
    return;
113
  }
114
  if (objRef.model.setRequestParameters) objRef.model.setRequestParameters(featureName, objRef.requestStylesheet);
115
  var httpPayload = objRef.createHttpPayload(feature);
116
  objRef.targetModel.newRequest(objRef.targetModel,httpPayload);
117
}
118

    
119
WebServiceRequest.prototype.setAoiParameters = function(objRef) {
120
  //TBD: this depends on the targetModel having a containerModel to extract the AOI from.
121
  //we probably need a config property to point to the AOI model to handle this properly.
122
  if (objRef.containerModel) {
123
    var featureSRS = null;
124
    var containerSRS = "EPSG:4326";
125
    var bbox = objRef.containerModel.getBoundingBox();
126
/*
127
TBD: figure out when to use AOI or BBOX
128
    var aoi = objRef.containerModel.getParam("aoi");
129
    if (aoi) {
130
      bbox[0] = aoi[0][0];
131
      bbox[1] = aoi[1][1];
132
      bbox[2] = aoi[1][0];
133
      bbox[3] = aoi[0][1];
134
    }
135
*/
136
    var containerSRS = objRef.containerModel.getSRS();
137
/*
138
    //convert the BBOX to the feature SRS for the request
139
    if (featureSRS) {
140
      var sourceProj = new Proj4js.Proj(getNodeValue(featureSRS));
141
      if ( !sourceProj.matchSrs( containerSRS )) {  
142
        var containerProj = new Proj4js.Proj(objRef.containerModel.getSRS());
143
        var llTemp = containerProj.Inverse(new Array(bbox[0],bbox[1]));
144
        var xy = sourceProj.Forward(llTemp);
145
        bbox[0] = xy[0]; bbox[1] = xy[1];
146
        llTemp = containerProj.Inverse(new Array(bbox[2],bbox[3]));
147
        xy = sourceProj.Forward(llTemp);
148
        bbox[2] = xy[0]; bbox[3] = xy[1];
149
      }
150
    }
151
*/
152
    objRef.requestStylesheet.setParameter("bBoxMinX", bbox[0]);
153
    objRef.requestStylesheet.setParameter("bBoxMinY", bbox[1]);
154
    objRef.requestStylesheet.setParameter("bBoxMaxX", bbox[2]);
155
    objRef.requestStylesheet.setParameter("bBoxMaxY", bbox[3]);
156
    objRef.requestStylesheet.setParameter("srs", containerSRS );
157
    objRef.requestStylesheet.setParameter("width", objRef.containerModel.getWindowWidth() );
158
    objRef.requestStylesheet.setParameter("height", objRef.containerModel.getWindowHeight() );
159
  }
160
}
161

    
162
WebServiceRequest.prototype.init = function(objRef) {
163
  if (objRef.targetModel.containerModel) {
164
    objRef.containerModel = objRef.targetModel.containerModel;
165
  } else if (objRef.model.containerModel) {
166
    objRef.containerModel = objRef.model.containerModel;
167
  }
168
  if (objRef.containerModel) {
169
    objRef.containerModel.addListener("aoi", objRef.setAoiParameters, objRef);
170
    objRef.containerModel.addListener("bbox", objRef.setAoiParameters, objRef);
171
    objRef.containerModel.addListener("selectedLayer", objRef.selectFeature, objRef);
172
    objRef.containerModel.addListener("loadModel", objRef.mapInit, objRef);
173
    objRef.containerModel.addListener("newModel", objRef.clear, objRef);
174
  }
175
}
176

    
177
/**
178
 * set map events needed for this tool
179
 * @param objRef reference to this tool
180
 */
181
WebServiceRequest.prototype.mapInit = function(objRef) {
182
  // register OpenLayers event to do updates onmouseup
183
  objRef.containerModel.map.events.registerPriority('mouseup', objRef, objRef.setClickPosition);  
184
}
185

    
186
/**
187
 * remove map events for this tool
188
 * @param objRef reference to this tool
189
 */
190
WebServiceRequest.prototype.clear = function(objRef) {
191
  if (objRef.containerModel.map && objRef.containerModel.map.events) {
192
    objRef.containerModel.map.events.unregister('mouseup', objRef, objRef.setClickPosition);  
193
  }
194
}
195

    
196
/**
197
 * Listener function that will clear the templates and set the mouse
198
 * positions when the user clicks on the map.
199
 * @param e OpenLayers event
200
 */
201
WebServiceRequest.prototype.setClickPosition = function(e) {
202
  this.targetModel.deleteTemplates();
203
  this.requestStylesheet.setParameter("xCoord", e.xy.x);
204
  this.requestStylesheet.setParameter("yCoord", e.xy.y);
205
}
206

    
207
/**
208
 * Listener function which will actually issue the request.  This method
209
 * will prepare the HTTP payload for a particular featureName.
210
 * @param requestName the name of the web service operation to execute
211
 * @param featureNodeId the id of the node in the doc to be processed by the stylesheet
212
 */
213
WebServiceRequest.prototype.selectFeature = function(objRef, featureName) {
214
  objRef.requestStylesheet.setParameter("queryLayer", featureName);
215
}
216

    
(14-14/15)