wcs/client/XMLParser.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 #include "XMLParser.h"
21 
22 #include <iostream>
23 
24 //BOOST
25 #include <boost/algorithm/string.hpp>
26 
27 //TerraLib
28 #include "../../../../core/uri/URI.h"
29 #include "../../../../common/StringUtils.h"
30 #include "../../../core/Exception.h"
31 
33 
35 
37 {
38 
39  // Read XML file
40  std::unique_ptr<te::xml::Reader> reader(te::xml::ReaderFactory::make("XERCES"));
41  reader->setValidationScheme(false);
42  reader->setDoSchema(false);
43  reader->setIgnoreWhiteSpaces(true);
44 
45  try
46  {
47  reader->read(xmlPath);
48  }
49  catch (...)
50  {
51  throw te::ws::core::Exception() << te::ErrorDescription(TE_TR("Can not read the Capabilities XML file!"));
52  }
53 
54 
55  // Validate the XML file
56  if(!reader->next())
57  {
58  throw te::ws::core::Exception() << te::ErrorDescription(TE_TR("Can not read the Capabilities XML file!"));
59  }
60 
61  if(!boost::iequals(reader->getElementLocalName(), "Capabilities"))
62  {
63  throw te::ws::core::Exception() << te::ErrorDescription(TE_TR("Can not find Capabilities on the received XML!"));
64  }
65 
67  while(reader->next())
68  {
69  if(reader->getNodeType() == te::xml::START_ELEMENT)
70  {
71  if(boost::iequals(reader->getElementLocalName(), "OperationsMetadata"))
72  {
73  while(reader->next() && !(te::xml::END_ELEMENT && boost::iequals(reader->getElementLocalName(), "OperationsMetadata")))
74  {
75  if(reader->getNodeType() == te::xml::START_ELEMENT && boost::iequals(reader->getElementLocalName(), "Operation") && reader->hasAttrs())
76  {
77  capabilities.operations.push_back(reader->getAttr(0));
78  }
79  }
80  }
81  else if(boost::iequals(reader->getElementLocalName(), "Contents"))
82  {
83  while(reader->next() && !(te::xml::END_ELEMENT && boost::iequals(reader->getElementLocalName(), "Contents")))
84  {
85  if(boost::iequals(reader->getElementLocalName(), "CoverageSummary"))
86  {
87  while(reader->next() && !(te::xml::END_ELEMENT && boost::iequals(reader->getElementLocalName(), "CoverageSummary")))
88  {
89  if(reader->getNodeType() == te::xml::VALUE && boost::iequals(reader->getElementLocalName(), "CoverageId"))
90  {
91  capabilities.coverages.push_back(reader->getElementValue());
92  }
93  }
94  }
95  }
96  }
97  }
98  }
99  return capabilities;
100 }
101 
103 {
104  // Read XML file
105  std::unique_ptr<te::xml::Reader> reader(te::xml::ReaderFactory::make("XERCES"));
106  reader->setValidationScheme(false);
107  reader->setDoSchema(false);
108  reader->setIgnoreWhiteSpaces(true);
109 
110  reader->read(xmlPath);
111 
112  // Validate the XML file
113  if(!reader->next())
114  {
115  throw te::ws::core::Exception() << te::ErrorDescription(TE_TR("Can not read the Coverage Descriptions XML file!"));
116  }
117 
118  if(!boost::algorithm::iequals(reader->getElementLocalName(), "CoverageDescriptions"))
119  {
120  throw te::ws::core::Exception() << te::ErrorDescription(TE_TR("Can not find Coverage Descriptions on the received XML!"));
121  }
122 
123  te::ws::ogc::wcs::CoverageDescription coverageDescription;
125  te::ws::ogc::wcs::DomainSet domainSet;
126  te::ws::ogc::wcs::ServiceParameters serviceParameters;
127  std::vector< std::string > fieldNames;
128  te::ws::ogc::wcs::TimeDomain timeDomain;
129 
130  while(reader->next())
131  {
132  if(reader->getNodeType() == te::xml::START_ELEMENT)
133  {
134  if(boost::iequals(reader->getElementLocalName(), "CoverageId"))
135  {
136  while(reader->next() && !(reader->getNodeType() == te::xml::END_ELEMENT && boost::iequals(reader->getElementLocalName(), "CoverageId")))
137  {
138  if(reader->getNodeType() == te::xml::VALUE)
139  {
140  if(boost::iequals(reader->getElementLocalName(), "CoverageId"))
141  coverageDescription.coverageId = reader->getElementValue();
142  }
143  }
144  }
145  else if(boost::algorithm::iequals(reader->getElementLocalName(), "boundedBy"))
146  {
147  while(reader->next() && !(reader->getNodeType() == te::xml::END_ELEMENT && boost::iequals(reader->getElementLocalName(), "boundedBy")))
148  {
149  if((boost::iequals(reader->getElementLocalName(), "Envelope") || boost::iequals(reader->getElementLocalName(), "EnvelopeWithTimePeriod")) && reader->hasAttrs())
150  {
151  std::stringstream axis, uom;
152  for(unsigned int i = 0; i < reader->getNumberOfAttrs(); i++)
153  {
154  if(boost::iequals(reader->getAttrLocalName(i), "srsName"))
155  {
156  envelope.srsName = reader->getAttr(i);
157 
158  te::core::URI url (envelope.srsName);
159 
160  if (url.isValid())
161  {
162  std::string path = url.path();
163  std::vector<std::string> elements = te::common::SplitString(path, '/');
164 
165  std::string code = elements.back(); // getting SRS code.
166  elements.pop_back(); // removing code.
167  elements.pop_back(); // removing version.
168  std::string auth = elements.back(); // getting authority eg.: EPSG
169 
170  envelope.srsName = auth + ":" + code;
171  }
172 
173  }
174 
175  else if(boost::iequals(reader->getAttrLocalName(i), "axisLabels"))
176  axis.str(reader->getAttr(i));
177  else if(boost::iequals(reader->getAttrLocalName(i), "uomLabels"))
178  uom.str(reader->getAttr(i));
179  else if(boost::iequals(reader->getAttrLocalName(i), "srsDimension"))
180  envelope.srsDimension = reader->getAttr(i);
181  }
182 
183  if(axis.good())
184  {
185  std::string part;
186  axis >> part;
187  envelope.firstLabel = part;
188 
189  if(axis.good())
190  {
191  axis >> part;
192  envelope.secondLabel = part;
193  }
194 
195  if(axis.good())
196  {
197  axis >> part;
198  envelope.timeLabel = part;
199  }
200  }
201 
202  while(uom.good())
203  {
204  std::string part;
205  uom >> part;
206  envelope.uomLabels.push_back(part);
207  }
208 
209  std::stringstream lower, upper;
210 
211  while(reader->next() && !(reader->getNodeType() == te::xml::END_ELEMENT
212  && (boost::iequals(reader->getElementLocalName(), "Envelope")
213  || boost::iequals(reader->getElementLocalName(), "EnvelopeWithTimePeriod"))))
214  {
215 
216  if(reader->getNodeType() == te::xml::VALUE)
217  {
218  if(boost::iequals(reader->getElementLocalName(), "lowerCorner"))
219  lower.str(reader->getElementValue());
220  else if(boost::iequals(reader->getElementLocalName(), "upperCorner"))
221  upper.str(reader->getElementValue());
222  else if(boost::iequals(reader->getElementLocalName(), "beginPosition"))
223  envelope.beginPosition = reader->getElementValue();
224  else if(boost::iequals(reader->getElementLocalName(), "endPosition"))
225  envelope.endPosition = reader->getElementValue();
226  }
227  }
228 
229  if(lower.good())
230  {
231  std::string part;
232  lower >> part;
233  envelope.lowerCorner_X = part;
234 
235  if(lower.good())
236  {
237  lower >> part;
238  envelope.lowerCorner_Y = part;
239  }
240  }
241 
242  if(upper.good())
243  {
244  std::string part;
245  upper >> part;
246  envelope.upperCorner_X = part;
247 
248  if(upper.good())
249  {
250  upper >> part;
251  envelope.upperCorner_Y = part;
252  }
253  }
254  }
255  }
256  }
257  else if(boost::iequals(reader->getElementLocalName(), "metadata"))
258  {
259  reader->next();
260 
261  if(boost::iequals(reader->getElementLocalName(), "Extension"))
262  {
263  reader->next();
264 
265  if(boost::iequals(reader->getElementLocalName(), "TimeDomain"))
266  {
267  timeDomain = this->parseTimeDomain(reader);
268  }
269  }
270  }
271  else if(boost::iequals(reader->getElementLocalName(), "domainSet"))
272  {
273  std::stringstream axis;
274  std::stringstream low;
275  std::stringstream high;
276 
277  while(reader->next() && !(reader->getNodeType() == te::xml::END_ELEMENT && boost::iequals(reader->getElementLocalName(), "domainSet")))
278  {
279  if(reader->getNodeType() == te::xml::VALUE)
280  {
281  if(boost::iequals(reader->getElementLocalName(), "axisLabels"))
282  axis.str(reader->getElementValue());
283  else if(boost::iequals(reader->getElementLocalName(), "low"))
284  low.str(reader->getElementValue());
285  else if(boost::iequals(reader->getElementLocalName(), "high"))
286  high.str(reader->getElementValue());
287  }
288  }
289 
290  SubSet subSet;
291 
292  while(axis.good())
293  {
294  std::string element;
295  axis >> element;
296  subSet.axis = element;
297 
298  if(low.good())
299  {
300  std::string element;
301  low >> element;
302  subSet.min = element;
303  }
304 
305  if(high.good())
306  {
307  std::string element;
308  high >> element;
309  subSet.max = element;
310  }
311 
312  domainSet.subSet.push_back(subSet);
313  }
314  }
315  else if(boost::iequals(reader->getElementLocalName(), "rangeType"))
316  {
317  while(reader->next() && !(reader->getNodeType() == te::xml::END_ELEMENT && boost::iequals(reader->getElementLocalName(), "rangeType")))
318  {
319  if(boost::iequals(reader->getElementLocalName(), "field") && reader->hasAttrs())
320  {
321  for(unsigned int i = 0; i < reader->getNumberOfAttrs(); i++)
322  {
323  if(boost::iequals(reader->getAttrLocalName(i), "name"))
324  fieldNames.push_back(reader->getAttr(i));
325  }
326  }
327  }
328  }
329  else if(boost::iequals(reader->getElementLocalName(), "ServiceParameters"))
330  {
331  while(reader->next() && !(reader->getNodeType() == te::xml::END_ELEMENT && boost::iequals(reader->getElementLocalName(), "ServiceParameters")))
332  {
333  if(reader->getNodeType() == te::xml::VALUE)
334  {
335  if(boost::iequals(reader->getElementLocalName(), "CoverageSubtype"))
336  serviceParameters.coverageSubtype = reader->getElementValue();
337  else if(boost::iequals(reader->getElementLocalName(), "coverageSubtypeParent"))
338  serviceParameters.coverageSubtypeParent = reader->getElementValue();
339  else if(boost::iequals(reader->getElementLocalName(), "nativeFormat"))
340  serviceParameters.nativeFormat = reader->getElementValue();
341  else if(boost::iequals(reader->getElementLocalName(), "extension"))
342  serviceParameters.extension = reader->getElementValue();
343  }
344  }
345  }
346  }
347  }
348 
349  coverageDescription.envelope = envelope;
350  coverageDescription.domainSet = domainSet;
351  coverageDescription.serviceParameters = serviceParameters;
352  coverageDescription.fieldNames = fieldNames;
353  coverageDescription.timeDomain = timeDomain;
354 
355  return coverageDescription;
356 }
357 
358 te::ws::ogc::wcs::TimeDomain te::ws::ogc::wcs::XMLParser::parseTimeDomain(const std::unique_ptr<te::xml::Reader> &reader)
359 {
360  TimeDomain timeDomain;
361 
362  if(reader->hasAttrs())
363  {
364  timeDomain.defaultTime = reader->getAttr("default");
365  }
366 
367  std::vector<TimeInstant> timeInstant;
368 
369  while(reader->next() && !(reader->getNodeType() == te::xml::END_ELEMENT && boost::iequals(reader->getElementLocalName(), "TimeDomain")))
370  {
371  if(boost::iequals(reader->getElementLocalName(), "TimeInstant"))
372  {
373  TimeInstant time;
374 
375  if(reader->hasAttrs())
376  {
377  time.id = reader->getAttr("gml:id");
378  }
379 
380  while(reader->next() && !(reader->getNodeType() == te::xml::END_ELEMENT && boost::iequals(reader->getElementLocalName(), "TimeInstant")))
381  {
382  if(reader->getNodeType() == te::xml::VALUE)
383  {
384  if(boost::iequals(reader->getElementLocalName(), "timePosition"))
385  time.timePosition = reader->getElementValue();
386  }
387  }
388 
389  timeInstant.push_back(time);
390  }
391  }
392 
393  timeDomain.timeInstant = timeInstant;
394 
395  return timeDomain;
396 }
TimeDomain parseTimeDomain(const std::unique_ptr< te::xml::Reader > &reader)
std::string path() const
Retrieving the path.
Definition: URI.cpp:118
TECOMMONEXPORT std::vector< std::string > SplitString(const std::string &str, const char &delimiter)
Definition: StringUtils.cpp:32
CoverageDescription parseDescribeCoverage(const std::string &xmlPath)
bool isValid() const
Return if the given URI is valid or not.
Definition: URI.cpp:133
static te::xml::Reader * make()
It creates a new XML reader using the dafault implementation.
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
The TimeDomain GeoServer WCS 2.0.1 struct.
boost::error_info< struct tag_error_description, std::string > ErrorDescription
The base type for error report messages.
std::vector< TimeInstant > timeInstant
te::da::DataSourceCapabilities capabilities
Base exception class for WS Core Runtime Library.
A class for representing an Uniform Resource Identifier (URI).
Definition: URI.h:49
Capabilities parseCapabilities(const std::string &xmlPath)
Parse the WCS XML to a WCS struct.
The TimeInstant GML 3.2.1 struct.