1 /**
2  * @file SedChangeXML.cpp
3  * @brief Implementation of the SedChangeXML class.
4  * @author DEVISER
5  *
6  * <!--------------------------------------------------------------------------
7  * This file is part of libSEDML. Please visit http://sed-ml.org for more
8  * information about SED-ML. The latest version of libSEDML can be found on
9  * github: https://github.com/fbergmann/libSEDML/
10  *
11 
12  * Copyright (c) 2013-2019, Frank T. Bergmann
13  * All rights reserved.
14  *
15 
16  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions are met:
18  *
19 
20  * 1. Redistributions of source code must retain the above copyright notice,
21  * this
22  * list of conditions and the following disclaimer.
23  * 2. Redistributions in binary form must reproduce the above copyright notice,
24  * this list of conditions and the following disclaimer in the documentation
25  * and/or other materials provided with the distribution.
26  *
27  * This library is free software; you can redistribute it and/or modify it
28  * under the terms of the GNU Lesser General Public License as published by the
29  * Free Software Foundation. A copy of the license agreement is provided in the
30  * file named "LICENSE.txt" included with this software distribution and also
31  * available online as http://sbml.org/software/libsbml/license.html
32  * ------------------------------------------------------------------------ -->
33  */
34 #include <sedml/SedChangeXML.h>
35 #include <sbml/xml/XMLInputStream.h>
36 
37 
38 using namespace std;
39 
40 
41 
42 LIBSEDML_CPP_NAMESPACE_BEGIN
43 
44 
45 
46 
47 #ifdef __cplusplus
48 
49 
50 /*
51  * Creates a new SedChangeXML using the given SED-ML Level and @ p version
52  * values.
53  */
SedChangeXML(unsigned int level,unsigned int version)54 SedChangeXML::SedChangeXML(unsigned int level, unsigned int version)
55   : SedChange(level, version)
56   , mNewXML (NULL)
57 {
58   setSedNamespacesAndOwn(new SedNamespaces(level, version));
59   connectToChild();
60 }
61 
62 
63 /*
64  * Creates a new SedChangeXML using the given SedNamespaces object @p sedmlns.
65  */
SedChangeXML(SedNamespaces * sedmlns)66 SedChangeXML::SedChangeXML(SedNamespaces *sedmlns)
67   : SedChange(sedmlns)
68   , mNewXML (NULL)
69 {
70   setElementNamespace(sedmlns->getURI());
71   connectToChild();
72 }
73 
74 
75 /*
76  * Copy constructor for SedChangeXML.
77  */
SedChangeXML(const SedChangeXML & orig)78 SedChangeXML::SedChangeXML(const SedChangeXML& orig)
79   : SedChange( orig )
80   , mNewXML ( NULL )
81 {
82   if (orig.mNewXML != NULL)
83   {
84     mNewXML = orig.mNewXML->clone();
85   }
86 
87   connectToChild();
88 }
89 
90 
91 /*
92  * Assignment operator for SedChangeXML.
93  */
94 SedChangeXML&
operator =(const SedChangeXML & rhs)95 SedChangeXML::operator=(const SedChangeXML& rhs)
96 {
97   if (&rhs != this)
98   {
99     SedChange::operator=(rhs);
100     delete mNewXML;
101     if (rhs.mNewXML != NULL)
102     {
103       mNewXML = rhs.mNewXML->clone();
104     }
105     else
106     {
107       mNewXML = NULL;
108     }
109 
110     connectToChild();
111   }
112 
113   return *this;
114 }
115 
116 
117 /*
118  * Creates and returns a deep copy of this SedChangeXML object.
119  */
120 SedChangeXML*
clone() const121 SedChangeXML::clone() const
122 {
123   return new SedChangeXML(*this);
124 }
125 
126 
127 /*
128  * Destructor for SedChangeXML.
129  */
~SedChangeXML()130 SedChangeXML::~SedChangeXML()
131 {
132   delete mNewXML;
133   mNewXML = NULL;
134 }
135 
136 
137 /*
138  * Returns the value of the "newXML" element of this SedChangeXML.
139  */
140 const LIBSBML_CPP_NAMESPACE_QUALIFIER XMLNode*
getNewXML() const141 SedChangeXML::getNewXML() const
142 {
143   return mNewXML;
144 }
145 
146 
147 /*
148  * Returns the value of the "newXML" element of this SedChangeXML.
149  */
150 LIBSBML_CPP_NAMESPACE_QUALIFIER XMLNode*
getNewXML()151 SedChangeXML::getNewXML()
152 {
153   return mNewXML;
154 }
155 
156 
157 /*
158  * Predicate returning @c true if this SedChangeXML's "newXML" element is set.
159  */
160 bool
isSetNewXML() const161 SedChangeXML::isSetNewXML() const
162 {
163   return (mNewXML != NULL);
164 }
165 
166 
167 /*
168  * Sets the value of the "newXML" element of this SedChangeXML.
169  */
170 int
setNewXML(const LIBSBML_CPP_NAMESPACE_QUALIFIER XMLNode * newXML)171 SedChangeXML::setNewXML(const LIBSBML_CPP_NAMESPACE_QUALIFIER XMLNode* newXML)
172 {
173   if (mNewXML == newXML)
174   {
175     return LIBSEDML_OPERATION_SUCCESS;
176   }
177   else if (newXML == NULL)
178   {
179     delete mNewXML;
180     mNewXML = NULL;
181     return LIBSEDML_OPERATION_SUCCESS;
182   }
183   else
184   {
185     delete mNewXML;
186     mNewXML = (newXML != NULL) ? newXML->clone() : NULL;
187     return LIBSEDML_OPERATION_SUCCESS;
188   }
189 }
190 
191 
192 /*
193  * Unsets the value of the "newXML" element of this SedChangeXML.
194  */
195 int
unsetNewXML()196 SedChangeXML::unsetNewXML()
197 {
198   delete mNewXML;
199   mNewXML = NULL;
200   return LIBSEDML_OPERATION_SUCCESS;
201 }
202 
203 
204 /*
205  * Returns the XML element name of this SedChangeXML object.
206  */
207 const std::string&
getElementName() const208 SedChangeXML::getElementName() const
209 {
210   static const string name = "changeXML";
211   return name;
212 }
213 
214 
215 /*
216  * Returns the libSEDML type code for this SedChangeXML object.
217  */
218 int
getTypeCode() const219 SedChangeXML::getTypeCode() const
220 {
221   return SEDML_CHANGE_CHANGEXML;
222 }
223 
224 
225 /*
226  * Predicate returning @c true if all the required attributes for this
227  * SedChangeXML object have been set.
228  */
229 bool
hasRequiredAttributes() const230 SedChangeXML::hasRequiredAttributes() const
231 {
232   bool allPresent = SedChange::hasRequiredAttributes();
233 
234   return allPresent;
235 }
236 
237 
238 /*
239  * Predicate returning @c true if all the required elements for this
240  * SedChangeXML object have been set.
241  */
242 bool
hasRequiredElements() const243 SedChangeXML::hasRequiredElements() const
244 {
245   bool allPresent = SedChange::hasRequiredElements();
246 
247   return allPresent;
248 }
249 
250 
251 
252 /** @cond doxygenLibSEDMLInternal */
253 
254 /*
255  * Write any contained elements
256  */
257 void
writeElements(LIBSBML_CPP_NAMESPACE_QUALIFIER XMLOutputStream & stream) const258 SedChangeXML::writeElements(LIBSBML_CPP_NAMESPACE_QUALIFIER XMLOutputStream&
259   stream) const
260 {
261   SedChange::writeElements(stream);
262 
263   if (isSetNewXML() == true)
264   {
265     stream.startElement("newXML");
266     stream << *mNewXML;
267     stream.endElement("newXML");
268   }
269 }
270 
271 /** @endcond */
272 
273 
274 
275 /** @cond doxygenLibSEDMLInternal */
276 
277 /*
278  * Accepts the given SedVisitor
279  */
280 bool
accept(SedVisitor & v) const281 SedChangeXML::accept(SedVisitor& v) const
282 {
283   return false;
284 }
285 
286 /** @endcond */
287 
288 
289 
290 /** @cond doxygenLibSEDMLInternal */
291 
292 /*
293  * Sets the parent SedDocument
294  */
295 void
setSedDocument(SedDocument * d)296 SedChangeXML::setSedDocument(SedDocument* d)
297 {
298   SedChange::setSedDocument(d);
299 }
300 
301 /** @endcond */
302 
303 
304 
305 /** @cond doxygenLibSEDMLInternal */
306 
307 /*
308  * Connects to child elements
309  */
310 void
connectToChild()311 SedChangeXML::connectToChild()
312 {
313   SedChange::connectToChild();
314 }
315 
316 /** @endcond */
317 
318 
319 
320 /** @cond doxygenLibSEDMLInternal */
321 
322 /*
323  * Gets the value of the "attributeName" attribute of this SedChangeXML.
324  */
325 int
getAttribute(const std::string & attributeName,bool & value) const326 SedChangeXML::getAttribute(const std::string& attributeName,
327                            bool& value) const
328 {
329   int return_value = SedChange::getAttribute(attributeName, value);
330 
331   return return_value;
332 }
333 
334 /** @endcond */
335 
336 
337 
338 /** @cond doxygenLibSEDMLInternal */
339 
340 /*
341  * Gets the value of the "attributeName" attribute of this SedChangeXML.
342  */
343 int
getAttribute(const std::string & attributeName,int & value) const344 SedChangeXML::getAttribute(const std::string& attributeName, int& value) const
345 {
346   int return_value = SedChange::getAttribute(attributeName, value);
347 
348   return return_value;
349 }
350 
351 /** @endcond */
352 
353 
354 
355 /** @cond doxygenLibSEDMLInternal */
356 
357 /*
358  * Gets the value of the "attributeName" attribute of this SedChangeXML.
359  */
360 int
getAttribute(const std::string & attributeName,double & value) const361 SedChangeXML::getAttribute(const std::string& attributeName,
362                            double& value) const
363 {
364   int return_value = SedChange::getAttribute(attributeName, value);
365 
366   return return_value;
367 }
368 
369 /** @endcond */
370 
371 
372 
373 /** @cond doxygenLibSEDMLInternal */
374 
375 /*
376  * Gets the value of the "attributeName" attribute of this SedChangeXML.
377  */
378 int
getAttribute(const std::string & attributeName,unsigned int & value) const379 SedChangeXML::getAttribute(const std::string& attributeName,
380                            unsigned int& value) const
381 {
382   int return_value = SedChange::getAttribute(attributeName, value);
383 
384   return return_value;
385 }
386 
387 /** @endcond */
388 
389 
390 
391 /** @cond doxygenLibSEDMLInternal */
392 
393 /*
394  * Gets the value of the "attributeName" attribute of this SedChangeXML.
395  */
396 int
getAttribute(const std::string & attributeName,std::string & value) const397 SedChangeXML::getAttribute(const std::string& attributeName,
398                            std::string& value) const
399 {
400   int return_value = SedChange::getAttribute(attributeName, value);
401 
402   return return_value;
403 }
404 
405 /** @endcond */
406 
407 
408 
409 /** @cond doxygenLibSEDMLInternal */
410 
411 /*
412  * Predicate returning @c true if this SedChangeXML's attribute "attributeName"
413  * is set.
414  */
415 bool
isSetAttribute(const std::string & attributeName) const416 SedChangeXML::isSetAttribute(const std::string& attributeName) const
417 {
418   bool value = SedChange::isSetAttribute(attributeName);
419 
420   return value;
421 }
422 
423 /** @endcond */
424 
425 
426 
427 /** @cond doxygenLibSEDMLInternal */
428 
429 /*
430  * Sets the value of the "attributeName" attribute of this SedChangeXML.
431  */
432 int
setAttribute(const std::string & attributeName,bool value)433 SedChangeXML::setAttribute(const std::string& attributeName, bool value)
434 {
435   int return_value = SedChange::setAttribute(attributeName, value);
436 
437   return return_value;
438 }
439 
440 /** @endcond */
441 
442 
443 
444 /** @cond doxygenLibSEDMLInternal */
445 
446 /*
447  * Sets the value of the "attributeName" attribute of this SedChangeXML.
448  */
449 int
setAttribute(const std::string & attributeName,int value)450 SedChangeXML::setAttribute(const std::string& attributeName, int value)
451 {
452   int return_value = SedChange::setAttribute(attributeName, value);
453 
454   return return_value;
455 }
456 
457 /** @endcond */
458 
459 
460 
461 /** @cond doxygenLibSEDMLInternal */
462 
463 /*
464  * Sets the value of the "attributeName" attribute of this SedChangeXML.
465  */
466 int
setAttribute(const std::string & attributeName,double value)467 SedChangeXML::setAttribute(const std::string& attributeName, double value)
468 {
469   int return_value = SedChange::setAttribute(attributeName, value);
470 
471   return return_value;
472 }
473 
474 /** @endcond */
475 
476 
477 
478 /** @cond doxygenLibSEDMLInternal */
479 
480 /*
481  * Sets the value of the "attributeName" attribute of this SedChangeXML.
482  */
483 int
setAttribute(const std::string & attributeName,unsigned int value)484 SedChangeXML::setAttribute(const std::string& attributeName,
485                            unsigned int value)
486 {
487   int return_value = SedChange::setAttribute(attributeName, value);
488 
489   return return_value;
490 }
491 
492 /** @endcond */
493 
494 
495 
496 /** @cond doxygenLibSEDMLInternal */
497 
498 /*
499  * Sets the value of the "attributeName" attribute of this SedChangeXML.
500  */
501 int
setAttribute(const std::string & attributeName,const std::string & value)502 SedChangeXML::setAttribute(const std::string& attributeName,
503                            const std::string& value)
504 {
505   int return_value = SedChange::setAttribute(attributeName, value);
506 
507   return return_value;
508 }
509 
510 /** @endcond */
511 
512 
513 
514 /** @cond doxygenLibSEDMLInternal */
515 
516 /*
517  * Unsets the value of the "attributeName" attribute of this SedChangeXML.
518  */
519 int
unsetAttribute(const std::string & attributeName)520 SedChangeXML::unsetAttribute(const std::string& attributeName)
521 {
522   int value = SedChange::unsetAttribute(attributeName);
523 
524   return value;
525 }
526 
527 /** @endcond */
528 
529 
530 
531 /** @cond doxygenLibSEDMLInternal */
532 
533 /*
534  * Creates a new object from the next XMLToken on the XMLInputStream
535  */
536 SedBase*
createObject(LIBSBML_CPP_NAMESPACE_QUALIFIER XMLInputStream & stream)537 SedChangeXML::createObject(LIBSBML_CPP_NAMESPACE_QUALIFIER XMLInputStream&
538   stream)
539 {
540   SedBase* obj = SedChange::createObject(stream);
541 
542   connectToChild();
543 
544   return obj;
545 }
546 
547 /** @endcond */
548 
549 
550 
551 /** @cond doxygenLibSEDMLInternal */
552 
553 /*
554  * Adds the expected attributes for this element
555  */
556 void
addExpectedAttributes(LIBSBML_CPP_NAMESPACE_QUALIFIER ExpectedAttributes & attributes)557 SedChangeXML::addExpectedAttributes(LIBSBML_CPP_NAMESPACE_QUALIFIER
558   ExpectedAttributes& attributes)
559 {
560   SedChange::addExpectedAttributes(attributes);
561 }
562 
563 /** @endcond */
564 
565 
566 
567 /** @cond doxygenLibSEDMLInternal */
568 
569 /*
570  * Reads the expected attributes into the member data variables
571  */
572 void
readAttributes(const LIBSBML_CPP_NAMESPACE_QUALIFIER XMLAttributes & attributes,const LIBSBML_CPP_NAMESPACE_QUALIFIER ExpectedAttributes & expectedAttributes)573 SedChangeXML::readAttributes(
574                              const LIBSBML_CPP_NAMESPACE_QUALIFIER
575                                XMLAttributes& attributes,
576                              const LIBSBML_CPP_NAMESPACE_QUALIFIER
577                                ExpectedAttributes& expectedAttributes)
578 {
579   unsigned int level = getLevel();
580   unsigned int version = getVersion();
581   unsigned int numErrs;
582   bool assigned = false;
583   SedErrorLog* log = getErrorLog();
584 
585   SedChange::readAttributes(attributes, expectedAttributes);
586 
587   if (log)
588   {
589     numErrs = log->getNumErrors();
590 
591     for (int n = numErrs-1; n >= 0; n--)
592     {
593       if (log->getError(n)->getErrorId() == SedUnknownCoreAttribute)
594       {
595         const std::string details = log->getError(n)->getMessage();
596         log->remove(SedUnknownCoreAttribute);
597         log->logError(SedmlChangeAllowedAttributes, level, version, details,
598           getLine(), getColumn());
599       }
600     }
601   }
602 }
603 
604 /** @endcond */
605 
606 
607 
608 /** @cond doxygenLibSEDMLInternal */
609 
610 /*
611  * Reads other XML such as math/notes etc.
612  */
613 bool
readOtherXML(LIBSBML_CPP_NAMESPACE_QUALIFIER XMLInputStream & stream)614 SedChangeXML::readOtherXML(LIBSBML_CPP_NAMESPACE_QUALIFIER XMLInputStream&
615   stream)
616 {
617   bool read = false;
618   const string& name = stream.peek().getName();
619   std::string newElementText;
620 
621   if (name == "newXML")
622   {
623     const LIBSBML_CPP_NAMESPACE_QUALIFIER XMLToken& token = stream.next();
624 
625     while (stream.isGood() && stream.peek().isText())
626     {
627       newElementText += stream.next().getCharacters();
628     }
629     newElementText = _trim(newElementText);
630 
631     delete mNewXML;
632     mNewXML = NULL;
633 
634     while (stream.isGood())
635     {
636       const LIBSBML_CPP_NAMESPACE_QUALIFIER XMLToken& next = stream.peek();
637       if (!stream.isGood()) break;
638 
639       if (next.isEndFor(token))
640       {
641         stream.next();
642         break;
643       }
644       else if (next.isStart())
645       {
646         if (mNewXML == NULL)
647         {
648           mNewXML = new
649             LIBSBML_CPP_NAMESPACE_QUALIFIER XMLNode();
650 
651           if (!newElementText.empty())
652             mNewXML->addChild(LIBSBML_CPP_NAMESPACE_QUALIFIER XMLNode(newElementText));
653 
654         }
655 
656         mNewXML->addChild(LIBSBML_CPP_NAMESPACE_QUALIFIER XMLNode(stream));
657       }
658       else if (next.isText())
659       {
660         std::string s = _trim(next.getCharacters());
661 
662         if (s != "" && mNewXML != NULL)
663           mNewXML->addChild(stream.next());
664         else
665           stream.skipText();
666       }
667       else
668       {
669         stream.skipPastEnd(stream.next());
670       }
671     }
672 
673     if (mNewXML != NULL && mNewXML->getNumChildren() == 1)
674     {
675       // for convenience if we have just one element hide the nesting
676       LIBSBML_CPP_NAMESPACE_QUALIFIER XMLNode* copy = new
677         LIBSBML_CPP_NAMESPACE_QUALIFIER XMLNode(mNewXML->getChild(0));
678       delete mNewXML;
679       mNewXML = copy;
680     }
681 
682     if (mNewXML == NULL && !newElementText.empty())
683       mNewXML = new
684       LIBSBML_CPP_NAMESPACE_QUALIFIER XMLNode(newElementText);
685 
686     read = true;
687   }
688 
689   if (SedChange::readOtherXML(stream))
690   {
691     read = true;
692   }
693 
694   return read;
695 }
696 
697 /** @endcond */
698 
699 
700 
701 /** @cond doxygenLibSEDMLInternal */
702 
703 /*
704  * Writes the attributes to the stream
705  */
706 void
writeAttributes(LIBSBML_CPP_NAMESPACE_QUALIFIER XMLOutputStream & stream) const707 SedChangeXML::writeAttributes(LIBSBML_CPP_NAMESPACE_QUALIFIER XMLOutputStream&
708   stream) const
709 {
710   SedChange::writeAttributes(stream);
711 }
712 
713 /** @endcond */
714 
715 
716 
717 
718 #endif /* __cplusplus */
719 
720 
721 /*
722  * Creates a new SedChangeXML_t using the given SED-ML Level and @ p version
723  * values.
724  */
725 LIBSEDML_EXTERN
726 SedChangeXML_t *
SedChangeXML_create(unsigned int level,unsigned int version)727 SedChangeXML_create(unsigned int level, unsigned int version)
728 {
729   return new SedChangeXML(level, version);
730 }
731 
732 
733 /*
734  * Creates and returns a deep copy of this SedChangeXML_t object.
735  */
736 LIBSEDML_EXTERN
737 SedChangeXML_t*
SedChangeXML_clone(const SedChangeXML_t * scxml)738 SedChangeXML_clone(const SedChangeXML_t* scxml)
739 {
740   if (scxml != NULL)
741   {
742     return static_cast<SedChangeXML_t*>(scxml->clone());
743   }
744   else
745   {
746     return NULL;
747   }
748 }
749 
750 
751 /*
752  * Frees this SedChangeXML_t object.
753  */
754 LIBSEDML_EXTERN
755 void
SedChangeXML_free(SedChangeXML_t * scxml)756 SedChangeXML_free(SedChangeXML_t* scxml)
757 {
758   if (scxml != NULL)
759   {
760     delete scxml;
761   }
762 }
763 
764 
765 /*
766  * Returns the value of the "newXML" element of this SedChangeXML_t.
767  */
768 LIBSEDML_EXTERN
769 const LIBSBML_CPP_NAMESPACE_QUALIFIER XMLNode_t*
SedChangeXML_getNewXML(const SedChangeXML_t * scxml)770 SedChangeXML_getNewXML(const SedChangeXML_t * scxml)
771 {
772   if (scxml == NULL)
773   {
774     return NULL;
775   }
776 
777   return (LIBSBML_CPP_NAMESPACE_QUALIFIER XMLNode_t*)(scxml->getNewXML());
778 }
779 
780 
781 /*
782  * Predicate returning @c 1 (true) if this SedChangeXML_t's "newXML" element is
783  * set.
784  */
785 LIBSEDML_EXTERN
786 int
SedChangeXML_isSetNewXML(const SedChangeXML_t * scxml)787 SedChangeXML_isSetNewXML(const SedChangeXML_t * scxml)
788 {
789   return (scxml != NULL) ? static_cast<int>(scxml->isSetNewXML()) : 0;
790 }
791 
792 
793 /*
794  * Sets the value of the "newXML" element of this SedChangeXML_t.
795  */
796 LIBSEDML_EXTERN
797 int
SedChangeXML_setNewXML(SedChangeXML_t * scxml,const LIBSBML_CPP_NAMESPACE_QUALIFIER XMLNode_t * newXML)798 SedChangeXML_setNewXML(SedChangeXML_t * scxml,
799                        const LIBSBML_CPP_NAMESPACE_QUALIFIER XMLNode_t* newXML)
800 {
801   return (scxml != NULL) ? scxml->setNewXML(newXML) : LIBSEDML_INVALID_OBJECT;
802 }
803 
804 
805 /*
806  * Unsets the value of the "newXML" element of this SedChangeXML_t.
807  */
808 LIBSEDML_EXTERN
809 int
SedChangeXML_unsetNewXML(SedChangeXML_t * scxml)810 SedChangeXML_unsetNewXML(SedChangeXML_t * scxml)
811 {
812   return (scxml != NULL) ? scxml->unsetNewXML() : LIBSEDML_INVALID_OBJECT;
813 }
814 
815 
816 /*
817  * Predicate returning @c 1 (true) if all the required attributes for this
818  * SedChangeXML_t object have been set.
819  */
820 LIBSEDML_EXTERN
821 int
SedChangeXML_hasRequiredAttributes(const SedChangeXML_t * scxml)822 SedChangeXML_hasRequiredAttributes(const SedChangeXML_t * scxml)
823 {
824   return (scxml != NULL) ? static_cast<int>(scxml->hasRequiredAttributes()) :
825     0;
826 }
827 
828 
829 /*
830  * Predicate returning @c 1 (true) if all the required elements for this
831  * SedChangeXML_t object have been set.
832  */
833 LIBSEDML_EXTERN
834 int
SedChangeXML_hasRequiredElements(const SedChangeXML_t * scxml)835 SedChangeXML_hasRequiredElements(const SedChangeXML_t * scxml)
836 {
837   return (scxml != NULL) ? static_cast<int>(scxml->hasRequiredElements()) : 0;
838 }
839 
840 
841 
842 
843 LIBSEDML_CPP_NAMESPACE_END
844 
845 
846