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$
|
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
|
var requestName = toolNode.selectSingleNode("mb:requestName");
|
32
|
if (requestName) {
|
33
|
this.requestName = requestName.firstChild.nodeValue;
|
34
|
}
|
35
|
|
36
|
//get the request filter to add to the request
|
37
|
var requestFilter = toolNode.selectSingleNode("mb:requestFilter");
|
38
|
if (requestFilter) {
|
39
|
this.requestFilter = requestFilter.firstChild.nodeValue;
|
40
|
}
|
41
|
|
42
|
var styleUrl = baseDir+"/tool/xsl/"+this.requestName.replace(/:/,"_")+".xsl";
|
43
|
this.requestStylesheet = new XslProcessor(styleUrl);
|
44
|
|
45
|
// Set stylesheet parameters for all the child nodes from the config file
|
46
|
for (var j=0;j<toolNode.childNodes.length;j++) {
|
47
|
if (toolNode.childNodes[j].firstChild && toolNode.childNodes[j].firstChild.nodeValue) {
|
48
|
this.requestStylesheet.setParameter(toolNode.childNodes[j].nodeName,toolNode.childNodes[j].firstChild.nodeValue);
|
49
|
}
|
50
|
}
|
51
|
|
52
|
/**
|
53
|
* Function which create the HTTP payload for a request
|
54
|
* @param requestName the name of the web service operation to execute
|
55
|
* @param featureNodeId the id of the node in the doc to be processed by the stylesheet
|
56
|
*/
|
57
|
this.createHttpPayload = function(feature) {
|
58
|
//confirm inputs
|
59
|
if (this.debug) alert("source:"+Sarissa.serialize(feature));
|
60
|
//if (this.debug) alert("stylesheet:"+Sarissa.serialize(this.requestStylesheet.xslDom));
|
61
|
|
62
|
|
63
|
//prepare the stylesheet
|
64
|
var httpPayload = new Object();
|
65
|
httpPayload.method = this.targetModel.method;
|
66
|
this.requestStylesheet.setParameter("httpMethod", httpPayload.method );
|
67
|
this.requestStylesheet.setParameter("version", this.model.getVersion(feature) );
|
68
|
if (this.requestFilter) {
|
69
|
var filter = config.objects[this.requestFilter];
|
70
|
this.requestStylesheet.setParameter("filter", escape(Sarissa.serialize(filter.doc).replace(/[\n\f\r\t]/g,'') ));
|
71
|
if (this.debug) alert(Sarissa.serialize(filter.doc));
|
72
|
}
|
73
|
|
74
|
//process the doc with the stylesheet
|
75
|
httpPayload.postData = this.requestStylesheet.transformNodeToObject(feature);
|
76
|
if (this.debug) {
|
77
|
alert("request data:"+Sarissa.serialize(httpPayload.postData));
|
78
|
if (config.serializeUrl) var response = postLoad(config.serializeUrl, httpPayload.postData);
|
79
|
}
|
80
|
|
81
|
//allow the tool to have a serverUrl property which overrides the model server URL
|
82
|
//TBD: this still used?
|
83
|
if (this.serverUrl) {
|
84
|
httpPayload.url = this.serverUrl;
|
85
|
} else {
|
86
|
httpPayload.url = this.model.getServerUrl(this.requestName, httpPayload.method, feature);
|
87
|
}
|
88
|
|
89
|
//extract the URL from the transformation result for GET method
|
90
|
if (httpPayload.method.toLowerCase() == "get") {
|
91
|
httpPayload.postData.setProperty("SelectionLanguage", "XPath");
|
92
|
Sarissa.setXpathNamespaces(httpPayload.postData, "xmlns:mb='http://mapbuilder.sourceforge.net/mapbuilder'");
|
93
|
var queryString = httpPayload.postData.selectSingleNode("//mb:QueryString");
|
94
|
if (httpPayload.url.indexOf("?") < 0) httpPayload.url += "?";
|
95
|
httpPayload.url += queryString.firstChild.nodeValue;
|
96
|
httpPayload.postData = null;
|
97
|
}
|
98
|
if (this.debug) alert("URL:"+httpPayload.url);
|
99
|
return httpPayload;
|
100
|
}
|
101
|
|
102
|
|
103
|
/**
|
104
|
* Listener function which will actually issue the request. This method
|
105
|
* will prepare the HTTP payload for a particular featureName.
|
106
|
* @param requestName the name of the web service operation to execute
|
107
|
* @param featureNodeId the id of the node in the doc to be processed by the stylesheet
|
108
|
*/
|
109
|
this.doRequest = function(objRef, featureName) {
|
110
|
objRef.targetModel.featureName = featureName;
|
111
|
|
112
|
var feature = objRef.model.getFeatureNode(featureName);
|
113
|
if (objRef.model.setRequestParameters) objRef.model.setRequestParameters(featureName, objRef.requestStylesheet);
|
114
|
var httpPayload = objRef.createHttpPayload(feature);
|
115
|
objRef.targetModel.newRequest(objRef.targetModel,httpPayload);
|
116
|
}
|
117
|
this.model.addListener(this.requestName.replace(/:/,"_"), this.doRequest, this);
|
118
|
|
119
|
this.setAoiParameters = function(objRef,bbox) {
|
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.targetModel.containerModel) {
|
123
|
var featureSRS = null;
|
124
|
var containerSRS = "EPSG:4326";
|
125
|
//var bbox = objRef.targetModel.containerModel.getBoundingBox();
|
126
|
/*
|
127
|
//convert the BBOX to the feature SRS for the request
|
128
|
var containerSRS = objRef.targetModel.containerModel.getSRS();
|
129
|
if (featureSRS) {
|
130
|
var sourceProj = new Proj(featureSRS.firstChild.nodeValue);
|
131
|
if ( !sourceProj.matchSrs( containerSRS )) {
|
132
|
var containerProj = new Proj(objRef.targetModel.containerModel.getSRS());
|
133
|
var llTemp = containerProj.Inverse(new Array(bbox[0],bbox[1]));
|
134
|
var xy = sourceProj.Forward(llTemp);
|
135
|
bbox[0] = xy[0]; bbox[1] = xy[1];
|
136
|
llTemp = containerProj.Inverse(new Array(bbox[2],bbox[3]));
|
137
|
xy = sourceProj.Forward(llTemp);
|
138
|
bbox[2] = xy[0]; bbox[3] = xy[1];
|
139
|
}
|
140
|
}
|
141
|
*/
|
142
|
objRef.requestStylesheet.setParameter("bBoxMinX", bbox[0][0] );
|
143
|
objRef.requestStylesheet.setParameter("bBoxMinY", bbox[1][1] );
|
144
|
objRef.requestStylesheet.setParameter("bBoxMaxX", bbox[1][0] );
|
145
|
objRef.requestStylesheet.setParameter("bBoxMaxY", bbox[0][1] );
|
146
|
objRef.requestStylesheet.setParameter("srs", containerSRS );
|
147
|
objRef.requestStylesheet.setParameter("width", objRef.targetModel.containerModel.getWindowWidth() );
|
148
|
objRef.requestStylesheet.setParameter("height", objRef.targetModel.containerModel.getWindowHeight() );
|
149
|
}
|
150
|
}
|
151
|
|
152
|
this.init = function(objRef) {
|
153
|
if (objRef.targetModel.containerModel) {
|
154
|
objRef.targetModel.containerModel.addListener("aoi", objRef.setAoiParameters, objRef);
|
155
|
//TBD: another one for bbox
|
156
|
}
|
157
|
}
|
158
|
this.model.addListener("init", this.init, this);
|
159
|
|
160
|
}
|