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$
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
}
(11-11/12)