serialization/xml/AbstractOp.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 /*!
21  \file terralib/fe/serialization/xml/AbstractOp.cpp
22 
23  \brief Auxiliary classes and functions to serialize filter operations from a XML document.
24 */
25 
26 // TerraLib
27 #include "../../../core/translator/Translator.h"
28 #include "../../../fe/BBOXOp.h"
29 #include "../../../fe/BinaryComparisonOp.h"
30 #include "../../../fe/BinaryLogicOp.h"
31 #include "../../../fe/BinarySpatialOp.h"
32 #include "../../../fe/DistanceBuffer.h"
33 #include "../../../fe/Globals.h"
34 #include "../../../fe/Literal.h"
35 #include "../../../fe/PropertyIsBetween.h"
36 #include "../../../fe/PropertyIsLike.h"
37 #include "../../../fe/PropertyIsNull.h"
38 #include "../../../fe/PropertyName.h"
39 #include "../../../fe/UnaryLogicOp.h"
40 #include "../../../xml/AbstractWriter.h"
41 #include "../../../xml/Reader.h"
42 #include "../../Exception.h"
43 #include "AbstractOp.h"
44 #include "Expression.h"
45 
46 // STL
47 #include <cassert>
48 
49 // Boost
50 #include <boost/format.hpp>
51 
52 
53 /* @name AbstractOp Reader Methods */
54 //@{
55 
56 te::fe::AbstractOp* BinaryComparsionOpReader(const char* opName, te::xml::Reader& reader);
57 
58 te::fe::AbstractOp* BetweenReader(const char* opName, te::xml::Reader& reader);
59 te::fe::AbstractOp* LikeReader(const char* opName, te::xml::Reader& reader);
60 te::fe::AbstractOp* NullReader(const char* opName, te::xml::Reader& reader);
61 
62 te::fe::AbstractOp* BinaryLogicOpReader(const char* opName, te::xml::Reader& reader);
63 te::fe::AbstractOp* UnaryLogicOpReader(const char* opName, te::xml::Reader& reader);
64 
65 te::fe::AbstractOp* BinarySpatialOpReader(const char* opName, te::xml::Reader& reader);
66 te::fe::AbstractOp* DistanceBufferReader(const char* opName, te::xml::Reader& reader);
67 te::fe::AbstractOp* BBOXReader(const char* opName, te::xml::Reader& reader);
68 
69 //@}
70 
71 /* @name AbstractOp Writer Methods */
72 //@{
73 
75 
79 
82 
86 
87 //@}
88 
89 std::string GetQualifiedName(const te::fe::AbstractOp* op)
90 {
91  std::string name = "ogc:";
92  name += op->getName();
93  return name;
94 }
95 
96 void te::fe::serialize::AbstractOp::reg(const std::string& opName, const AbstractOpFnctSerializeType& fncts)
97 {
98  m_fncts[opName] = fncts;
99 }
100 
102 {
103  std::string opName = reader.getElementLocalName();
104 
105  AbstractOpFnctIdxType::const_iterator it = m_fncts.find(opName);
106 
107  if(it == m_fncts.end())
108  throw Exception((boost::format(TE_TR("Could not find a reader for the following operator type: %1%.")) % opName).str());
109 
110  assert(it->second.second);
111 
112  return it->second.first(m_names.find(opName)->second, reader);
113 }
114 
116 {
117  assert(op);
118 
119  AbstractOpFnctIdxType::const_iterator it = m_fncts.find(op->getName());
120 
121  if(it == m_fncts.end())
122  throw Exception((boost::format(TE_TR("Could not find a writer for the following operator type: %1%.")) % op->getName()).str());
123 
124  assert(it->second.second);
125 
126  return it->second.second(op, writer);
127 }
128 
130 
132 {
133  // BinaryComparisonOp
140 
141  // IsBetween
143 
144  // IsLike
146 
147  // Null
149 
150  // BinaryLogicOp
153 
154  // UnaryLogicOp
156 
157  // BBOX
159 
160  // Binary SpatialOp
169 
170  // DistanceBuffer
173 
174  // string to char*
198 }
199 
201 {
202  assert(reader.getNodeType() == te::xml::START_ELEMENT);
203  assert(reader.getElementLocalName() == opName);
204 
205  std::unique_ptr<te::fe::BinaryComparisonOp> op(new te::fe::BinaryComparisonOp(opName));
206 
207  reader.next();
208 
209  op->setFirst( te::fe::serialize::Expression::getInstance().read(reader));
210 
211  op->setSecond( te::fe::serialize::Expression::getInstance().read(reader));
212 
213  assert(reader.getNodeType() == te::xml::END_ELEMENT);
214  reader.next();
215 
216  return op.release();
217 }
218 
219 te::fe::AbstractOp* BetweenReader(const char* /*opName*/,
220  te::xml::Reader& reader)
221 {
222  assert(reader.getNodeType() == te::xml::START_ELEMENT);
224 
225  std::unique_ptr<te::fe::PropertyIsBetween> op(new te::fe::PropertyIsBetween);
226 
227  reader.next();
228 
229  op->setExpression(te::fe::serialize::Expression::getInstance().read(reader));
230 
231  op->setLowerBoundary(te::fe::serialize::Expression::getInstance().read(reader));
232 
233  op->setUpperBoundary(te::fe::serialize::Expression::getInstance().read(reader));
234 
235  assert(reader.getNodeType() == te::xml::END_ELEMENT);
236  reader.next();
237 
238  return op.release();
239 }
240 
241 te::fe::AbstractOp* LikeReader(const char* /*opName*/, te::xml::Reader& reader)
242 {
243  assert(reader.getNodeType() == te::xml::START_ELEMENT);
245  assert(reader.hasAttrs());
246 
247  std::unique_ptr<te::fe::PropertyIsLike> op(new te::fe::PropertyIsLike);
248 
249  std::string wildCard = reader.getAttr("wildCard");
250  assert(!wildCard.empty());
251  op->setWildCard(wildCard);
252 
253  std::string singleChar = reader.getAttr("singleChar");
254  assert(!singleChar.empty());
255  op->setSingleChar(singleChar);
256 
257  std::string escapeChar = reader.getAttr("escapeChar");
258  assert(!escapeChar.empty());
259  op->setEscapeChar(escapeChar);
260 
261  reader.next();
262 
263  assert(reader.getNodeType() == te::xml::START_ELEMENT);
264  assert(reader.getElementLocalName() == "PropertyName");
265 
266  op->setPropertyName(static_cast<te::fe::PropertyName*>(te::fe::serialize::Expression::getInstance().read(reader)));
267 
268  assert(reader.getNodeType() == te::xml::START_ELEMENT);
269  assert(reader.getElementLocalName() == "Literal");
270 
271  op->setLiteral(static_cast<te::fe::Literal*>(te::fe::serialize::Expression::getInstance().read(reader)));
272 
273  assert(reader.getNodeType() == te::xml::END_ELEMENT);
274  reader.next();
275 
276  return op.release();
277 }
278 
279 te::fe::AbstractOp* NullReader(const char* /*opName*/, te::xml::Reader& reader)
280 {
281  assert(reader.getNodeType() == te::xml::START_ELEMENT);
283 
284  std::unique_ptr<te::fe::PropertyIsNull> op(new te::fe::PropertyIsNull);
285 
286  reader.next();
287 
288  assert(reader.getNodeType() == te::xml::START_ELEMENT);
289  assert(reader.getElementLocalName() == "PropertyName");
290 
291  op->setPropertyName(static_cast<te::fe::PropertyName*>(te::fe::serialize::Expression::getInstance().read(reader)));
292 
293  assert(reader.getNodeType() == te::xml::END_ELEMENT);
294  reader.next();
295 
296  return op.release();
297 }
298 
300 {
301  assert(reader.getNodeType() == te::xml::START_ELEMENT);
302  assert(reader.getElementLocalName() == opName);
303 
304  std::unique_ptr<te::fe::BinaryLogicOp> op(new te::fe::BinaryLogicOp(opName));
305 
306  reader.next();
307 
308  // TODO: The BinaryLogicOp has a set of AbstractOp's. I don't know how to do this. The Reader never tells about END_ELEMENT's?
309  /*while(reader.getNodeType() != te::xml::END_ELEMENT)
310  op->add(te::serialize::AbstractOp::getInstance().read(reader));*/
311 
312  // So, for while, read only two AbstractOp's...
315 
316  assert(reader.getNodeType() == te::xml::END_ELEMENT);
317  reader.next();
318 
319  return op.release();
320 }
321 
323 {
324  assert(reader.getNodeType() == te::xml::START_ELEMENT);
325  assert(reader.getElementLocalName() == te::fe::Globals::sm_not);
326 
327  std::unique_ptr<te::fe::UnaryLogicOp> op(new te::fe::UnaryLogicOp(opName));
328 
329  reader.next();
330 
332 
333  assert(reader.getNodeType() == te::xml::END_ELEMENT);
334  reader.next();
335 
336  return op.release();
337 }
338 
340 {
341  assert(reader.getNodeType() == te::xml::START_ELEMENT);
342  assert(reader.getElementLocalName() == opName);
343 
344  std::unique_ptr<te::fe::BinarySpatialOp> op(new te::fe::BinarySpatialOp(opName));
345 
346  reader.next();
347 
348  assert(reader.getNodeType() == te::xml::START_ELEMENT);
349  assert(reader.getElementLocalName() == "PropertyName");
350 
351  op->setProperty(static_cast<te::fe::PropertyName*>(te::fe::serialize::Expression::getInstance().read(reader)));
352 
353  // TODO: read Envelope or Geometry!
354  // op->setGeometry(...);
355  // op->setEnvelope(...);
356 
357  assert(reader.getNodeType() == te::xml::END_ELEMENT);
358  reader.next();
359 
360  return op.release();
361 }
362 
364 {
365  assert(reader.getNodeType() == te::xml::START_ELEMENT);
366  assert(reader.getElementLocalName() == opName);
367 
368  std::unique_ptr<te::fe::DistanceBuffer> op(new te::fe::DistanceBuffer(opName));
369 
370  reader.next();
371 
372  assert(reader.getNodeType() == te::xml::START_ELEMENT);
373  assert(reader.getElementLocalName() == "PropertyName");
374 
375  op->setProperty(static_cast<te::fe::PropertyName*>(te::fe::serialize::Expression::getInstance().read(reader)));
376 
377  // TODO: read geom and distance!
378  // op->setGeometry(...);
379  // op->setDistance(...);
380 
381  assert(reader.getNodeType() == te::xml::END_ELEMENT);
382  reader.next();
383 
384  return op.release();
385 }
386 
387 te::fe::AbstractOp* BBOXReader(const char* /*opName*/, te::xml::Reader& reader)
388 {
389  assert(reader.getNodeType() == te::xml::START_ELEMENT);
390  assert(reader.getElementLocalName() == te::fe::Globals::sm_bbox);
391 
392  std::unique_ptr<te::fe::BBOXOp> op(new te::fe::BBOXOp);
393 
394  reader.next();
395 
396  assert(reader.getNodeType() == te::xml::START_ELEMENT);
397  assert(reader.getElementLocalName() == "PropertyName");
398 
399  op->setProperty(static_cast<te::fe::PropertyName*>(te::fe::serialize::Expression::getInstance().read(reader)));
400 
401  // TODO: read envelope !
402  // op->setEnvelope(...);
403 
404  assert(reader.getNodeType() == te::xml::END_ELEMENT);
405  reader.next();
406 
407  return op.release();
408 }
409 
411 {
412  const te::fe::BinaryComparisonOp* binaryOp = dynamic_cast<const te::fe::BinaryComparisonOp*>(op);
413 
414  if(binaryOp == nullptr)
415  return;
416 
418 
419  te::fe::serialize::Expression::getInstance().write(binaryOp->getFirst(), writer);
420 
421  te::fe::serialize::Expression::getInstance().write(binaryOp->getSecond(), writer);
422 
423  writer.writeEndElement(GetQualifiedName(op));
424 }
425 
427 {
428  const te::fe::PropertyIsBetween* between = dynamic_cast<const te::fe::PropertyIsBetween*>(op);
429 
430  if(between == nullptr)
431  return;
432 
434 
435  te::fe::serialize::Expression::getInstance().write(between->getExpression(), writer);
436 
438 
440 
441  writer.writeEndElement(GetQualifiedName(op));
442 }
443 
445 {
446  const te::fe::PropertyIsLike* like = dynamic_cast<const te::fe::PropertyIsLike*>(op);
447 
448  if(like == nullptr)
449  return;
450 
452 
453  // Attributes
454  std::string wildCard = like->getWildCard();
455  assert(!wildCard.empty());
456 
457  std::string singleChar = like->getSingleChar();
458  assert(!singleChar.empty());
459 
460  std::string escapeChar = like->getEscapeChar();
461  assert(!escapeChar.empty());
462 
463  writer.writeAttribute("wildCard", wildCard);
464  writer.writeAttribute("singleChar", singleChar);
465  writer.writeAttribute("escapeChar", escapeChar);
466 
468 
470 
471  writer.writeEndElement(GetQualifiedName(op));
472 }
473 
475 {
476  const te::fe::PropertyIsNull* isNull = dynamic_cast<const te::fe::PropertyIsNull*>(op);
477 
478  if(isNull == nullptr)
479  return;
480 
482 
484 
485  writer.writeEndElement(GetQualifiedName(op));
486 }
487 
489 {
490  const te::fe::BinaryLogicOp* binaryLogicOp = dynamic_cast<const te::fe::BinaryLogicOp*>(op);
491 
492  if(binaryLogicOp == nullptr)
493  return;
494 
496 
497  assert(binaryLogicOp->size() >= 2);
498 
499  for(std::size_t i = 0; i < binaryLogicOp->size(); ++i)
500  te::fe::serialize::AbstractOp::getInstance().write(binaryLogicOp->getOp(i), writer);
501 
502  writer.writeEndElement(GetQualifiedName(op));
503 }
504 
506 {
507  const te::fe::UnaryLogicOp* unaryLogicOp = dynamic_cast<const te::fe::UnaryLogicOp*>(op);
508 
509  if(unaryLogicOp == nullptr)
510  return;
511 
513 
514  te::fe::serialize::AbstractOp::getInstance().write(unaryLogicOp->getOp(), writer);
515 
516  writer.writeEndElement(GetQualifiedName(op));
517 }
518 
520 {
521  const te::fe::BinarySpatialOp* binarySpatialOp = dynamic_cast<const te::fe::BinarySpatialOp*>(op);
522 
523  if(binarySpatialOp == nullptr)
524  return;
525 
527 
528  te::fe::serialize::Expression::getInstance().write(binarySpatialOp->getProperty(), writer);
529 
530  // Envelope || Geometry
531  //te::gml::Envelope* env = binarySpatialOp->getEnvelope();
532  //te::gm::Geometry* geom = binarySpatialOp->getGeometry();
533 
534  // TODO: write Envelope or Geometry!
535 
536  writer.writeEndElement(GetQualifiedName(op));
537 }
538 
540 {
541  const te::fe::DistanceBuffer* db = dynamic_cast<const te::fe::DistanceBuffer*>(op);
542 
543  if(db == nullptr)
544  return;
545 
547 
549 
550  // TODO: write geom and distance!
551 
552  writer.writeEndElement(GetQualifiedName(op));
553 }
554 
556 {
557  const te::fe::BBOXOp* bbox = dynamic_cast<const te::fe::BBOXOp*>(op);
558 
559  if(bbox == nullptr)
560  return;
561 
563 
565 
566  // TODO: write envelope !
567 
568  writer.writeEndElement(GetQualifiedName(op));
569 }
void BinaryLogicOpWriter(const te::fe::AbstractOp *op, te::xml::AbstractWriter &writer)
static const char * sm_propertyIsLessThan
static const char * sm_touches
void UnaryLogicOpWriter(const te::fe::AbstractOp *op, te::xml::AbstractWriter &writer)
const char * getName() const
It returns the operator name.
Definition: AbstractOp.h:82
te::fe::AbstractOp * DistanceBufferReader(const char *opName, te::xml::Reader &reader)
static const char * sm_dWithin
PropertyName * getPropertyName() const
It returns the property name.
Distance buffer operator.
static const char * sm_contains
This class models a XML reader object.
Definition: xml/Reader.h:55
void write(const te::fe::AbstractOp *op, te::xml::AbstractWriter &writer) const
boost::function< te::fe::AbstractOp *(const char *opName, te::xml::Reader &)> AbstractOpReadFnctType
te::fe::AbstractOp * BinaryLogicOpReader(const char *opName, te::xml::Reader &reader)
virtual void writeStartElement(const std::string &qName)=0
virtual bool hasAttrs() const =0
It tells if the element has attributes in the case of an element node.
static const char * sm_propertyIsGreaterThanOrEqualTo
static const char * sm_propertyIsGreaterThan
static const char * sm_crosses
Base exception class for plugin module.
static const char * sm_or
boost::function< void(const te::fe::AbstractOp *, te::xml::AbstractWriter &)> AbstractOpWriteFnctType
A convenient and more compact way of encoding the very common bounding box constraint based on an env...
Definition: BBOXOp.h:71
PropertyName * getPropertyName() const
It returns the property name.
const std::string & getWildCard() const
It returns the wild character.
static const char * sm_intersects
A class for binary spatial operators.
te::fe::AbstractOp * BetweenReader(const char *opName, te::xml::Reader &reader)
virtual std::string getElementLocalName() const =0
It returns the local part of the element name in the case of an element node.
static const char * sm_disjoint
The PropertyIsBetween element is defined as a compact way of encoding a range check.
static const char * sm_within
This class models a XML writer object.
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
PropertyName * getProperty() const
It returns the property name.
std::size_t size() const
It returns the number of operands.
static const char * sm_propertyIsEqualTo
A logical operator that can be used to combine one conditional expressions.
Definition: UnaryLogicOp.h:46
The PropertyIsNull class encodes an operator that checks to see if the value of its content is NULL...
Literal * getLiteral() const
It returns the literal value.
static const char * sm_propertyIsLike
const std::string & getSingleChar() const
It returns the single wild character.
te::fe::AbstractOp * UnaryLogicOpReader(const char *opName, te::xml::Reader &reader)
void BinarySpatialOpWriter(const te::fe::AbstractOp *op, te::xml::AbstractWriter &writer)
Expression * getUpperBoundary() const
It returns the upper boundary expression.
static const char * sm_propertyIsNotEqualTo
virtual std::string getAttr(const std::string &name) const =0
It returns the attribute value in the case of an element node with valid attributes.
It is intended to encode a character string comparison operator with pattern matching.
std::map< std::string, const char * > m_names
Auxiliary map of string to te::fe::Global names pointers.
static T & getInstance()
It returns a reference to the singleton instance.
Definition: Singleton.h:126
PropertyName * getProperty() const
It returns the property name.
static const char * sm_beyond
AbstractOp * getOp(std::size_t i) const
It returns a specified operand.
void BetweenWriter(const te::fe::AbstractOp *op, te::xml::AbstractWriter &writer)
Expression * getSecond() const
It returns the second operand.
const std::string & getEscapeChar() const
It returns the escape character.
te::fe::AbstractOp * NullReader(const char *opName, te::xml::Reader &reader)
std::string GetQualifiedName(const te::fe::AbstractOp *op)
AbstractOp * getOp() const
It returns the operand.
void BBOXWriter(const te::fe::AbstractOp *op, te::xml::AbstractWriter &writer)
std::pair< AbstractOpReadFnctType, AbstractOpWriteFnctType > AbstractOpFnctSerializeType
static const char * sm_propertyIsNull
An abstract interface for operators.
Definition: AbstractOp.h:47
Auxiliary classes and functions to serialize filter operations from a XML document.
PropertyName * getProperty() const
It returns the property name.
Definition: BBOXOp.cpp:51
A class for binary comparison operators.
static const char * sm_and
te::fe::AbstractOp * BinaryComparsionOpReader(const char *opName, te::xml::Reader &reader)
virtual void writeAttribute(const std::string &attName, const std::string &value)=0
te::fe::AbstractOp * LikeReader(const char *opName, te::xml::Reader &reader)
static const char * sm_equals
virtual void writeEndElement(const std::string &qName)=0
A logical operator can be used to combine two or more conditional expressions.
Definition: BinaryLogicOp.h:58
void LikeWriter(const te::fe::AbstractOp *op, te::xml::AbstractWriter &writer)
virtual NodeType getNodeType() const =0
It return the type of node read.
void BinaryComparsionOpWriter(const te::fe::AbstractOp *op, te::xml::AbstractWriter &writer)
void reg(const std::string &opName, const AbstractOpFnctSerializeType &fncts)
static const char * sm_overlaps
Auxiliary classes and functions to serialize filter expressions from a XML document.
static const char * sm_not
Expression * getFirst() const
It returns the first operand.
te::fe::AbstractOp * BinarySpatialOpReader(const char *opName, te::xml::Reader &reader)
void NullWriter(const te::fe::AbstractOp *op, te::xml::AbstractWriter &writer)
static const char * sm_propertyIsBetween
static const char * sm_bbox
virtual bool next()=0
It gets the next event to be read.
Expression * getLowerBoundary() const
It returns the lower boundary expression.
void DistanceBufferOpWriter(const te::fe::AbstractOp *op, te::xml::AbstractWriter &writer)
static const char * sm_propertyIsLessThanOrEqualTo
te::fe::AbstractOp * read(te::xml::Reader &reader) const
Expression * getExpression() const
It returns the between expression.
te::fe::AbstractOp * BBOXReader(const char *opName, te::xml::Reader &reader)