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
|
|