1 /**
2 * @file FunctionDefinition.cpp
3 * @brief Implementation of FunctionDefinition and ListOfFunctionDefinitions.
4 * @author Ben Bornstein
5 *
6 * <!--------------------------------------------------------------------------
7 * This file is part of libSBML. Please visit http://sbml.org for more
8 * information about SBML, and the latest version of libSBML.
9 *
10 * Copyright (C) 2020 jointly by the following organizations:
11 * 1. California Institute of Technology, Pasadena, CA, USA
12 * 2. University of Heidelberg, Heidelberg, Germany
13 * 3. University College London, London, UK
14 *
15 * Copyright (C) 2019 jointly by the following organizations:
16 * 1. California Institute of Technology, Pasadena, CA, USA
17 * 2. University of Heidelberg, Heidelberg, Germany
18 *
19 * Copyright (C) 2013-2018 jointly by the following organizations:
20 * 1. California Institute of Technology, Pasadena, CA, USA
21 * 2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
22 * 3. University of Heidelberg, Heidelberg, Germany
23 *
24 * Copyright (C) 2009-2013 jointly by the following organizations:
25 * 1. California Institute of Technology, Pasadena, CA, USA
26 * 2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
27 *
28 * Copyright (C) 2006-2008 by the California Institute of Technology,
29 * Pasadena, CA, USA
30 *
31 * Copyright (C) 2002-2005 jointly by the following organizations:
32 * 1. California Institute of Technology, Pasadena, CA, USA
33 * 2. Japan Science and Technology Agency, Japan
34 *
35 * This library is free software; you can redistribute it and/or modify it
36 * under the terms of the GNU Lesser General Public License as published by
37 * the Free Software Foundation. A copy of the license agreement is provided
38 * in the file named "LICENSE.txt" included with this software distribution
39 * and also available online as http://sbml.org/software/libsbml/license.html
40 * ---------------------------------------------------------------------- -->*/
41
42 #include <cstring>
43
44 #include <sbml/xml/XMLNode.h>
45 #include <sbml/xml/XMLAttributes.h>
46 #include <sbml/xml/XMLInputStream.h>
47 #include <sbml/xml/XMLOutputStream.h>
48
49 #include <sbml/math/FormulaParser.h>
50 #include <sbml/math/ASTNode.h>
51 #include <sbml/math/MathML.h>
52
53 #include <sbml/SBO.h>
54 #include <sbml/SBMLVisitor.h>
55 #include <sbml/SBMLError.h>
56 #include <sbml/FunctionDefinition.h>
57 #include <sbml/SBMLDocument.h>
58 #include <sbml/Model.h>
59
60 /** @cond doxygenIgnored */
61 using namespace std;
62 /** @endcond */
63
64 LIBSBML_CPP_NAMESPACE_BEGIN
65 #ifdef __cplusplus
66
FunctionDefinition(unsigned int level,unsigned int version)67 FunctionDefinition::FunctionDefinition (unsigned int level, unsigned int version) :
68 SBase ( level, version )
69 , mMath ( NULL )
70 {
71 if (!hasValidLevelVersionNamespaceCombination())
72 throw SBMLConstructorException();
73 }
74
75
FunctionDefinition(SBMLNamespaces * sbmlns)76 FunctionDefinition::FunctionDefinition (SBMLNamespaces * sbmlns) :
77 SBase ( sbmlns )
78 , mMath ( NULL )
79 {
80 if (!hasValidLevelVersionNamespaceCombination())
81 {
82 throw SBMLConstructorException(getElementName(), sbmlns);
83 }
84
85 loadPlugins(sbmlns);
86 }
87
88
89 /*
90 * Destroys this FunctionDefinition.
91 */
~FunctionDefinition()92 FunctionDefinition::~FunctionDefinition ()
93 {
94 delete mMath;
95 }
96
97
98 /*
99 * Copy constructor. Creates a copy of this FunctionDefinition.
100 */
FunctionDefinition(const FunctionDefinition & orig)101 FunctionDefinition::FunctionDefinition (const FunctionDefinition& orig) :
102 SBase ( orig )
103 , mMath ( NULL )
104 {
105
106 if (orig.mMath != NULL)
107 {
108 mMath = orig.mMath->deepCopy();
109 mMath->setParentSBMLObject(this);
110 }
111 }
112
113
114 /*
115 * Assignment operator
116 */
operator =(const FunctionDefinition & rhs)117 FunctionDefinition& FunctionDefinition::operator=(const FunctionDefinition& rhs)
118 {
119 if(&rhs!=this)
120 {
121 this->SBase::operator =(rhs);
122
123 delete mMath;
124 if (rhs.mMath != NULL)
125 {
126 mMath = rhs.mMath->deepCopy();
127 mMath->setParentSBMLObject(this);
128 }
129 else
130 {
131 mMath = NULL;
132 }
133 }
134
135 return *this;
136 }
137
138
139 /** @cond doxygenLibsbmlInternal */
140 bool
accept(SBMLVisitor & v) const141 FunctionDefinition::accept (SBMLVisitor& v) const
142 {
143 return v.visit(*this);
144 }
145 /** @endcond */
146
147
148 /*
149 * @return a (deep) copy of this FunctionDefinition.
150 */
151 FunctionDefinition*
clone() const152 FunctionDefinition::clone () const
153 {
154 return new FunctionDefinition(*this);
155 }
156
157
158 /*
159 * @return the id of this SBML object.
160 */
161 const string&
getId() const162 FunctionDefinition::getId () const
163 {
164 return mId;
165 }
166
167
168 /*
169 * @return the name of this SBML object.
170 */
171 const string&
getName() const172 FunctionDefinition::getName () const
173 {
174 return (getLevel() == 1) ? mId : mName;
175 }
176
177
178 /*
179 * @return the math of this FunctionDefinition.
180 */
181 const ASTNode*
getMath() const182 FunctionDefinition::getMath () const
183 {
184 return mMath;
185 }
186
187
188 /*
189 * @return @c true if the id of this SBML object is set, false
190 * otherwise.
191 */
192 bool
isSetId() const193 FunctionDefinition::isSetId () const
194 {
195 return (mId.empty() == false);
196 }
197
198
199 /*
200 * @return @c true if the name of this SBML object is set, false
201 * otherwise.
202 */
203 bool
isSetName() const204 FunctionDefinition::isSetName () const
205 {
206 return (getLevel() == 1) ? (mId.empty() == false) :
207 (mName.empty() == false);
208 }
209
210
211 /*
212 * @return @c true if the math of this FunctionDefinition is set, false
213 * otherwise.
214 */
215 bool
isSetMath() const216 FunctionDefinition::isSetMath () const
217 {
218 return (mMath != NULL);
219 }
220
221 /*
222 * Sets the id of this SBML object to a copy of @p sid.
223 */
224 int
setId(const std::string & sid)225 FunctionDefinition::setId (const std::string& sid)
226 {
227 /* since the setId function has been used as an
228 * alias for setName we cant require it to only
229 * be used on a L2 model
230 */
231 /* if (getLevel() == 1)
232 {
233 return LIBSBML_UNEXPECTED_ATTRIBUTE;
234 }
235 */
236 if (!(SyntaxChecker::isValidInternalSId(sid)))
237 {
238 return LIBSBML_INVALID_ATTRIBUTE_VALUE;
239 }
240 else
241 {
242 mId = sid;
243 return LIBSBML_OPERATION_SUCCESS;
244 }
245 }
246
247
248 /*
249 * Sets the name of this SBML object to a copy of name.
250 */
251 int
setName(const std::string & name)252 FunctionDefinition::setName (const std::string& name)
253 {
254 /* if this is setting an L2 name the type is string
255 * whereas if it is setting an L1 name its type is SId
256 */
257 if (getLevel() == 1)
258 {
259 if (!(SyntaxChecker::isValidInternalSId(name)))
260 {
261 return LIBSBML_INVALID_ATTRIBUTE_VALUE;
262 }
263 else
264 {
265 mId = name;
266 return LIBSBML_OPERATION_SUCCESS;
267 }
268 }
269 else
270 {
271 mName = name;
272 return LIBSBML_OPERATION_SUCCESS;
273 }
274 }
275
276
277 /*
278 * Sets the math of this FunctionDefinition to the given ASTNode.
279 */
280 int
setMath(const ASTNode * math)281 FunctionDefinition::setMath (const ASTNode* math)
282 {
283 if (mMath == math)
284 {
285 return LIBSBML_OPERATION_SUCCESS;
286 }
287 else if (math == NULL)
288 {
289 delete mMath;
290 mMath = NULL;
291 return LIBSBML_OPERATION_SUCCESS;
292 }
293 else if (!(math->isWellFormedASTNode()))
294 {
295 return LIBSBML_INVALID_OBJECT;
296 }
297 else
298 {
299 delete mMath;
300 mMath = (math != NULL) ? math->deepCopy() : NULL;
301 if (mMath != NULL) mMath->setParentSBMLObject(this);
302 return LIBSBML_OPERATION_SUCCESS;
303 }
304 }
305
306
307 /*
308 * Unsets the name of this SBML object.
309 */
310 int
unsetName()311 FunctionDefinition::unsetName ()
312 {
313 if (getLevel() == 1)
314 {
315 mId.erase();
316 }
317 else
318 {
319 mName.erase();
320 }
321
322 if (getLevel() == 1 && mId.empty())
323 {
324 return LIBSBML_OPERATION_SUCCESS;
325 }
326 else if (mName.empty())
327 {
328 return LIBSBML_OPERATION_SUCCESS;
329 }
330 else
331 {
332 return LIBSBML_OPERATION_FAILED;
333 }
334 }
335
336
337 /*
338 * @return the nth argument (bound variable) passed to this
339 * FunctionDefinition.
340 */
341 const ASTNode*
getArgument(unsigned int n) const342 FunctionDefinition::getArgument (unsigned int n) const
343 {
344 if (mMath == NULL) return NULL;
345
346 /* if the math is not a lambda this function can cause issues
347 * elsewhere, technically if the math is not a lambda
348 * function the body is NULL
349 */
350 ASTNode * lambda = NULL;
351
352 if (mMath->isLambda() == true)
353 {
354 lambda = mMath;
355 }
356 else
357 {
358 if ((getLevel() == 2 && getVersion() > 2) || getLevel() > 2)
359 {
360 if (mMath->isSemantics() == true && mMath->getNumChildren() == 1
361 && mMath->getChild(0)->isLambda() == true)
362 {
363 lambda = mMath->getChild(0);
364 }
365 }
366 }
367
368 if (lambda == NULL)
369 {
370 return NULL;
371 }
372 else if (n < getNumArguments())
373 {
374 return lambda->getChild(n);
375 }
376 else
377 {
378 return NULL;
379 }
380 }
381
382
383 /*
384 * @return the argument (bound variable) in this FunctionDefinition with
385 * the given name or @c NULL if no such argument exists.
386 */
387 const ASTNode*
getArgument(const std::string & name) const388 FunctionDefinition::getArgument (const std::string& name) const
389 {
390 const char* cname = name.c_str();
391 const ASTNode* found = NULL;
392
393
394 for (unsigned int n = 0; n < getNumArguments(); ++n)
395 {
396 const ASTNode* node = getArgument(n);
397
398 if (node != NULL && node->isName() && !strcmp(node->getName(), cname))
399 {
400 found = node;
401 break;
402 }
403 }
404
405 return found;
406 }
407
408
409 /*
410 * @return the body of this FunctionDefinition, or @c NULL if no body is
411 * defined.
412 */
413 const ASTNode*
getBody() const414 FunctionDefinition::getBody () const
415 {
416 if (mMath == NULL) return NULL;
417
418 /* if the math is not a lambda this function can cause issues
419 * elsewhere, technically if the math is not a lambda
420 * function the body is NULL
421 */
422 ASTNode * lambda = NULL;
423
424 if (mMath->isLambda() == true)
425 {
426 lambda = mMath;
427 }
428 else
429 {
430 if ((getLevel() == 2 && getVersion() > 2) || getLevel() > 2)
431 {
432 if (mMath->isSemantics() == true && mMath->getNumChildren() == 1
433 && mMath->getChild(0)->isLambda() == true)
434 {
435 lambda = mMath->getChild(0);
436 }
437 }
438 }
439
440 if (lambda == NULL)
441 {
442 return NULL;
443 }
444
445
446 unsigned int nc = lambda->getNumChildren();
447 /* here we do actually need to look at whether something is a bvar
448 * and not just assume that the last child is a function body
449 * it should be BUT it might not be
450 */
451
452 if (nc > 0 && lambda->getNumBvars() < nc)
453 {
454 return lambda->getChild(nc-1);
455 }
456 else
457 {
458 return NULL;
459 }
460 }
461
462
463 /*
464 * @return the body of this FunctionDefinition, or @c NULL if no body is
465 * defined.
466 */
467 ASTNode*
getBody()468 FunctionDefinition::getBody ()
469 {
470 if (mMath == NULL) return NULL;
471
472 /* if the math is not a lambda this function can cause issues
473 * elsewhere, technically if the math is not a lambda
474 * function the body is NULL
475 */
476 ASTNode * lambda = NULL;
477
478 if (mMath->isLambda() == true)
479 {
480 lambda = mMath;
481 }
482 else
483 {
484 if ((getLevel() == 2 && getVersion() > 2) || getLevel() > 2)
485 {
486 if (mMath->isSemantics() == true && mMath->getNumChildren() == 1
487 && mMath->getChild(0)->isLambda() == true)
488 {
489 lambda = mMath->getChild(0);
490 }
491 }
492 }
493
494 if (lambda == NULL)
495 {
496 return NULL;
497 }
498
499
500 unsigned int nc = lambda->getNumChildren();
501 /* here we do actually need to look at whether something is a bvar
502 * and not just assume that the last child is a function body
503 * it should be BUT it might not be
504 */
505
506 if (nc > 0 && lambda->getNumBvars() < nc)
507 {
508 return lambda->getChild(nc-1);
509 }
510 else
511 {
512 return NULL;
513 }
514 }
515
516
517 /*
518 * @return the true if the body of this FunctionDefinition is set
519 */
520 bool
isSetBody() const521 FunctionDefinition::isSetBody () const
522 {
523 return (getBody() == NULL) ? false : true;
524 }
525
526
527 /*
528 * @return the number of arguments (bound variables) that must be passed
529 * to this FunctionDefinition.
530 */
531 unsigned int
getNumArguments() const532 FunctionDefinition::getNumArguments () const
533 {
534 if (isSetMath() == false)
535 {
536 return 0;
537 }
538
539 /* if the math is not a lambda this function can cause issues
540 * elsewhere, technically if the math is not a lambda
541 * function there are no arguments
542 */
543 ASTNode * lambda = NULL;
544
545 if (mMath->isLambda() == true)
546 {
547 lambda = mMath;
548 }
549 else
550 {
551 if ((getLevel() == 2 && getVersion() > 2) || getLevel() > 2)
552 {
553 if (mMath->isSemantics() == true && mMath->getNumChildren() == 1
554 && mMath->getChild(0)->isLambda() == true)
555 {
556 lambda = mMath->getChild(0);
557 }
558 }
559 }
560
561 if ( lambda == NULL)
562 {
563 return 0;
564 }
565 else
566 {
567 return lambda->getNumBvars();
568 }
569 }
570
571
572 /*
573 * @return the typecode (int) of this SBML object or SBML_UNKNOWN
574 * (default).
575 *
576 * @see getElementName()
577 */
578 int
getTypeCode() const579 FunctionDefinition::getTypeCode () const
580 {
581 return SBML_FUNCTION_DEFINITION;
582 }
583
584
585 /*
586 * @return the name of this element ie "functionDefinition".
587 */
588 const string&
getElementName() const589 FunctionDefinition::getElementName () const
590 {
591 static const string name = "functionDefinition";
592 return name;
593 }
594
595
596 bool
hasRequiredAttributes() const597 FunctionDefinition::hasRequiredAttributes() const
598 {
599 bool allPresent = true;
600
601 /* required attributes for functionDefinition: id */
602
603 if (!isSetId())
604 allPresent = false;
605
606 return allPresent;
607 }
608
609
610 bool
hasRequiredElements() const611 FunctionDefinition::hasRequiredElements() const
612 {
613 bool allPresent = true;
614
615 /* required attributes for functionDefinition: math */
616 /* l3v2 removed that requirement */
617
618 if ((getLevel() < 3 ) || (getLevel() == 3 && getVersion() == 1))
619 {
620 if (!isSetMath())
621 allPresent = false;
622 }
623
624 return allPresent;
625 }
626
627 void
renameUnitSIdRefs(const std::string & oldid,const std::string & newid)628 FunctionDefinition::renameUnitSIdRefs(const std::string& oldid, const std::string& newid)
629 {
630 SBase::renameUnitSIdRefs(oldid, newid);
631 if (isSetMath()) {
632 mMath->renameUnitSIdRefs(oldid, newid);
633 }
634 }
635
636 /** @cond doxygenLibsbmlInternal */
637
638 /*
639 * Returns the value of the "attributeName" attribute of this FunctionDefinition.
640 */
641 int
getAttribute(const std::string & attributeName,bool & value) const642 FunctionDefinition::getAttribute(const std::string& attributeName,
643 bool& value) const
644 {
645 int return_value = SBase::getAttribute(attributeName, value);
646
647 return return_value;
648 }
649
650 /** @endcond */
651
652
653
654 /** @cond doxygenLibsbmlInternal */
655
656 /*
657 * Returns the value of the "attributeName" attribute of this FunctionDefinition.
658 */
659 int
getAttribute(const std::string & attributeName,int & value) const660 FunctionDefinition::getAttribute(const std::string& attributeName,
661 int& value) const
662 {
663 int return_value = SBase::getAttribute(attributeName, value);
664
665 return return_value;
666 }
667
668 /** @endcond */
669
670
671
672 /** @cond doxygenLibsbmlInternal */
673
674 /*
675 * Returns the value of the "attributeName" attribute of this FunctionDefinition.
676 */
677 int
getAttribute(const std::string & attributeName,double & value) const678 FunctionDefinition::getAttribute(const std::string& attributeName,
679 double& value) const
680 {
681 int return_value = SBase::getAttribute(attributeName, value);
682
683 return return_value;
684 }
685
686 /** @endcond */
687
688
689
690 /** @cond doxygenLibsbmlInternal */
691
692 /*
693 * Returns the value of the "attributeName" attribute of this FunctionDefinition.
694 */
695 int
getAttribute(const std::string & attributeName,unsigned int & value) const696 FunctionDefinition::getAttribute(const std::string& attributeName,
697 unsigned int& value) const
698 {
699 int return_value = SBase::getAttribute(attributeName, value);
700
701 return return_value;
702 }
703
704 /** @endcond */
705
706
707
708 /** @cond doxygenLibsbmlInternal */
709
710 /*
711 * Returns the value of the "attributeName" attribute of this FunctionDefinition.
712 */
713 int
getAttribute(const std::string & attributeName,std::string & value) const714 FunctionDefinition::getAttribute(const std::string& attributeName,
715 std::string& value) const
716 {
717 int return_value = SBase::getAttribute(attributeName, value);
718
719 return return_value;
720 }
721
722 /** @endcond */
723
724
725
726 /** @cond doxygenLibsbmlInternal */
727
728 /*
729 * Returns the value of the "attributeName" attribute of this FunctionDefinition.
730 */
731 //int
732 //FunctionDefinition::getAttribute(const std::string& attributeName,
733 // const char* value) const
734 //{
735 // int return_value = SBase::getAttribute(attributeName, value);
736 //
737 // return return_value;
738 //}
739
740 /** @endcond */
741
742
743
744 /** @cond doxygenLibsbmlInternal */
745
746 /*
747 * Predicate returning @c true if this FunctionDefinition's attribute
748 * "attributeName" is set.
749 */
750 bool
isSetAttribute(const std::string & attributeName) const751 FunctionDefinition::isSetAttribute(const std::string& attributeName) const
752 {
753 bool value = SBase::isSetAttribute(attributeName);
754
755 return value;
756 }
757
758 /** @endcond */
759
760
761
762 /** @cond doxygenLibsbmlInternal */
763
764 /*
765 * Sets the value of the "attributeName" attribute of this FunctionDefinition.
766 */
767 int
setAttribute(const std::string & attributeName,bool value)768 FunctionDefinition::setAttribute(const std::string& attributeName, bool value)
769 {
770 int return_value = SBase::setAttribute(attributeName, value);
771
772 return return_value;
773 }
774
775 /** @endcond */
776
777
778
779 /** @cond doxygenLibsbmlInternal */
780
781 /*
782 * Sets the value of the "attributeName" attribute of this FunctionDefinition.
783 */
784 int
setAttribute(const std::string & attributeName,int value)785 FunctionDefinition::setAttribute(const std::string& attributeName, int value)
786 {
787 int return_value = SBase::setAttribute(attributeName, value);
788
789 return return_value;
790 }
791
792 /** @endcond */
793
794
795
796 /** @cond doxygenLibsbmlInternal */
797
798 /*
799 * Sets the value of the "attributeName" attribute of this FunctionDefinition.
800 */
801 int
setAttribute(const std::string & attributeName,double value)802 FunctionDefinition::setAttribute(const std::string& attributeName,
803 double value)
804 {
805 int return_value = SBase::setAttribute(attributeName, value);
806
807 return return_value;
808 }
809
810 /** @endcond */
811
812
813
814 /** @cond doxygenLibsbmlInternal */
815
816 /*
817 * Sets the value of the "attributeName" attribute of this FunctionDefinition.
818 */
819 int
setAttribute(const std::string & attributeName,unsigned int value)820 FunctionDefinition::setAttribute(const std::string& attributeName,
821 unsigned int value)
822 {
823 int return_value = SBase::setAttribute(attributeName, value);
824
825 return return_value;
826 }
827
828 /** @endcond */
829
830
831
832 /** @cond doxygenLibsbmlInternal */
833
834 /*
835 * Sets the value of the "attributeName" attribute of this FunctionDefinition.
836 */
837 int
setAttribute(const std::string & attributeName,const std::string & value)838 FunctionDefinition::setAttribute(const std::string& attributeName,
839 const std::string& value)
840 {
841 int return_value = SBase::setAttribute(attributeName, value);
842
843 return return_value;
844 }
845
846 /** @endcond */
847
848
849
850 /** @cond doxygenLibsbmlInternal */
851
852 /*
853 * Sets the value of the "attributeName" attribute of this FunctionDefinition.
854 */
855 //int
856 //FunctionDefinition::setAttribute(const std::string& attributeName,
857 // const char* value)
858 //{
859 // int return_value = SBase::setAttribute(attributeName, value);
860 //
861 // return return_value;
862 //}
863
864 /** @endcond */
865
866
867
868 /** @cond doxygenLibsbmlInternal */
869
870 /*
871 * Unsets the value of the "attributeName" attribute of this
872 * FunctionDefinition.
873 */
874 int
unsetAttribute(const std::string & attributeName)875 FunctionDefinition::unsetAttribute(const std::string& attributeName)
876 {
877 int value = SBase::unsetAttribute(attributeName);
878
879 return value;
880 }
881
882 /** @endcond */
883
884
885
886 /** @cond doxygenLibsbmlInternal */
887 /*
888 * Subclasses should override this method to read (and store) XHTML,
889 * MathML, etc. directly from the XMLInputStream.
890 *
891 * @return @c true if the subclass read from the stream, false otherwise.
892 */
893 bool
readOtherXML(XMLInputStream & stream)894 FunctionDefinition::readOtherXML (XMLInputStream& stream)
895 {
896 bool read = false;
897 const string& name = stream.peek().getName();
898
899 if (name == "math")
900 {
901 // if this is level 1 there shouldnt be any math!!!
902 if (getLevel() == 1)
903 {
904 logError(NotSchemaConformant, getLevel(), getVersion(),
905 "SBML Level 1 does not support MathML.");
906 delete mMath;
907 return false;
908 }
909
910
911 if (mMath != NULL)
912 {
913 if (getLevel() < 3)
914 {
915 logError(NotSchemaConformant, getLevel(), getVersion(),
916 "Only one <math> element is permitted inside a "
917 "particular containing element.");
918 }
919 else
920 {
921 logError(OneMathElementPerFunc, getLevel(), getVersion(),
922 "The <functionDefinition> with id '" + getId() + "' contains "
923 "more than one <math> element.");
924 }
925 }
926 /* check for MathML namespace
927 * this may be explicitly declared here
928 * or implicitly declared on the whole document
929 */
930 const XMLToken elem = stream.peek();
931 const std::string prefix = checkMathMLNamespace(elem);
932
933 delete mMath;
934 mMath = readMathML(stream, prefix);
935 if (mMath != NULL) mMath->setParentSBMLObject(this);
936 read = true;
937 }
938
939 /* ------------------------------
940 *
941 * (EXTENSION)
942 *
943 * ------------------------------ */
944 if ( SBase::readOtherXML(stream) )
945 read = true;
946
947 return read;
948 }
949 /** @endcond */
950
951
952 /** @cond doxygenLibsbmlInternal */
953 /**
954 * Subclasses should override this method to get the list of
955 * expected attributes.
956 * This function is invoked from corresponding readAttributes()
957 * function.
958 */
959 void
addExpectedAttributes(ExpectedAttributes & attributes)960 FunctionDefinition::addExpectedAttributes(ExpectedAttributes& attributes)
961 {
962 SBase::addExpectedAttributes(attributes);
963
964 attributes.add("name");
965 attributes.add("id");
966
967 const unsigned int level = getLevel();
968 const unsigned int version = getVersion();
969
970 if (level == 2 && version == 2)
971 {
972 attributes.add("sboTerm");
973 }
974
975 }
976
977 /*
978 * Subclasses should override this method to read values from the given
979 * XMLAttributes set into their specific fields. Be sure to call your
980 * parent's implementation of this method as well.
981 */
982 void
readAttributes(const XMLAttributes & attributes,const ExpectedAttributes & expectedAttributes)983 FunctionDefinition::readAttributes (const XMLAttributes& attributes,
984 const ExpectedAttributes& expectedAttributes)
985 {
986 const unsigned int level = getLevel ();
987 const unsigned int version = getVersion();
988
989 SBase::readAttributes(attributes, expectedAttributes);
990
991 switch (level)
992 {
993 case 1:
994 logError(NotSchemaConformant, level, version,
995 "FunctionDefinition is not a valid component for this level/version.");
996 break;
997 case 2:
998 readL2Attributes(attributes);
999 break;
1000 case 3:
1001 default:
1002 readL3Attributes(attributes);
1003 break;
1004 }
1005 }
1006 /** @endcond */
1007
1008
1009 /** @cond doxygenLibsbmlInternal */
1010 /*
1011 * Subclasses should override this method to read values from the given
1012 * XMLAttributes set into their specific fields. Be sure to call your
1013 * parent's implementation of this method as well.
1014 */
1015 void
readL2Attributes(const XMLAttributes & attributes)1016 FunctionDefinition::readL2Attributes (const XMLAttributes& attributes)
1017 {
1018 const unsigned int level = getLevel();
1019 const unsigned int version = getVersion();
1020
1021 //
1022 // id: SId { use="required" } (L2v1 ->)
1023 //
1024 bool assigned;
1025 assigned = attributes.readInto("id", mId, getErrorLog(), true, getLine(), getColumn());
1026 if (assigned && mId.size() == 0)
1027 {
1028 logEmptyString("id", level, version, "<functionDefinition>");
1029 }
1030 if (!SyntaxChecker::isValidInternalSId(mId))
1031 logError(InvalidIdSyntax, level, version, "The id '" + mId + "' does not conform to the syntax.");
1032
1033 //
1034 // name: string { use="optional" } (L2v1 ->)
1035 //
1036 attributes.readInto("name", mName, getErrorLog(), false, getLine(), getColumn());
1037
1038 //
1039 // sboTerm: SBOTerm { use="optional" } (L2v2 ->)
1040 //
1041 if (version == 2)
1042 mSBOTerm = SBO::readTerm(attributes, this->getErrorLog(), level, version,
1043 getLine(), getColumn());
1044
1045 }
1046 /** @endcond */
1047
1048
1049 /** @cond doxygenLibsbmlInternal */
1050 /*
1051 * Subclasses should override this method to read values from the given
1052 * XMLAttributes set into their specific fields. Be sure to call your
1053 * parent's implementation of this method as well.
1054 */
1055 void
readL3Attributes(const XMLAttributes & attributes)1056 FunctionDefinition::readL3Attributes (const XMLAttributes& attributes)
1057 {
1058 const unsigned int level = getLevel();
1059 const unsigned int version = getVersion();
1060
1061 //
1062 // id: SId { use="required" } (L2v1 ->)
1063 //
1064 bool assigned;
1065 // for l3v2 sbase will read this as generically optional
1066 // we want to log errors relating to the specific object
1067 if (version == 1)
1068 {
1069 assigned = attributes.readInto("id", mId, getErrorLog(), false, getLine(), getColumn());
1070 if (!assigned)
1071 {
1072 logError(AllowedAttributesOnFunc, level, version,
1073 "The required attribute 'id' is missing.");
1074 }
1075 if (assigned && mId.size() == 0)
1076 {
1077 logEmptyString("id", level, version, "<functionDefinition>");
1078 }
1079 if (!SyntaxChecker::isValidInternalSId(mId))
1080 logError(InvalidIdSyntax, level, version, "The id '" + mId + "' does not conform to the syntax.");
1081 }
1082 else
1083 {
1084 // need to check that id was present
1085 // it has already been read and checked for syntax/emptyness
1086 if (attributes.hasAttribute("id") == false)
1087 {
1088 logError(AllowedAttributesOnFunc, level, version,
1089 "The required attribute 'id' is missing.");
1090 }
1091 }
1092
1093 //
1094 // name: string { use="optional" } (L2v1 ->)
1095 //
1096 // for l3v2 sbase will read this
1097 if (version == 1)
1098 {
1099 attributes.readInto("name", mName, getErrorLog(), false,
1100 getLine(), getColumn());
1101 }
1102 }
1103 /** @endcond */
1104
1105
1106 /** @cond doxygenLibsbmlInternal */
1107 /*
1108 * Subclasses should override this method to write their XML attributes
1109 * to the XMLOutputStream. Be sure to call your parent's implementation
1110 * of this method as well.
1111 */
1112 void
writeAttributes(XMLOutputStream & stream) const1113 FunctionDefinition::writeAttributes (XMLOutputStream& stream) const
1114 {
1115 const unsigned int level = getLevel();
1116 const unsigned int version = getVersion();
1117
1118 /* invalid level/version */
1119 if (level < 2)
1120 {
1121 return;
1122 }
1123
1124 SBase::writeAttributes(stream);
1125
1126 //
1127 // sboTerm: SBOTerm { use="optional" } (L2v2 ->)
1128 //
1129 // sboTerm for L2V3 or later is written in SBase::writeAttributes()
1130 //
1131 if ( (level == 2) && (version == 2) )
1132 {
1133 SBO::writeTerm(stream, mSBOTerm);
1134 }
1135
1136 // for L3V2 and above SBase will write this out
1137 if (level < 3 || (level == 3 && version == 1))
1138 {
1139 //
1140 // id: SId { use="required" } (L2v1 ->)
1141 //
1142 stream.writeAttribute("id", mId);
1143
1144 //
1145 // name: string { use="optional" } (L2v1 ->)
1146 //
1147 stream.writeAttribute("name", mName);
1148 }
1149
1150 //
1151 // (EXTENSION)
1152 //
1153 SBase::writeExtensionAttributes(stream);
1154
1155 }
1156 /** @endcond */
1157
1158
1159 /** @cond doxygenLibsbmlInternal */
1160 /*
1161 * Subclasses should override this method to write out their contained
1162 * SBML objects as XML elements. Be sure to call your parent's
1163 * implementation of this method as well.
1164 */
1165 void
writeElements(XMLOutputStream & stream) const1166 FunctionDefinition::writeElements (XMLOutputStream& stream) const
1167 {
1168 SBase::writeElements(stream);
1169
1170 if (mMath) writeMathML(mMath, stream, getSBMLNamespaces());
1171
1172 //
1173 // (EXTENSION)
1174 //
1175 SBase::writeExtensionElements(stream);
1176 }
1177 /** @endcond */
1178
1179
1180 /*
1181 * Creates a new ListOfFunctionDefinitions items.
1182 */
ListOfFunctionDefinitions(unsigned int level,unsigned int version)1183 ListOfFunctionDefinitions::ListOfFunctionDefinitions (unsigned int level, unsigned int version)
1184 : ListOf(level,version)
1185 {
1186 }
1187
1188
1189 /*
1190 * Creates a new ListOfFunctionDefinitions items.
1191 */
ListOfFunctionDefinitions(SBMLNamespaces * sbmlns)1192 ListOfFunctionDefinitions::ListOfFunctionDefinitions (SBMLNamespaces* sbmlns)
1193 : ListOf(sbmlns)
1194 {
1195 loadPlugins(sbmlns);
1196 }
1197
1198
1199 /*
1200 * @return a (deep) copy of this ListOfFunctionDefinitions.
1201 */
1202 ListOfFunctionDefinitions*
clone() const1203 ListOfFunctionDefinitions::clone () const
1204 {
1205 return new ListOfFunctionDefinitions(*this);
1206 }
1207
1208
1209 /*
1210 * @return the typecode (int) of SBML objects contained in this ListOf or
1211 * SBML_UNKNOWN (default).
1212 */
1213 int
getItemTypeCode() const1214 ListOfFunctionDefinitions::getItemTypeCode () const
1215 {
1216 return SBML_FUNCTION_DEFINITION;
1217 }
1218
1219
1220 /*
1221 * @return the name of this element ie "listOfFunctionDefinitions".
1222 */
1223 const string&
getElementName() const1224 ListOfFunctionDefinitions::getElementName () const
1225 {
1226 static const string name = "listOfFunctionDefinitions";
1227 return name;
1228 }
1229
1230
1231 /* return nth item in list */
1232 FunctionDefinition *
get(unsigned int n)1233 ListOfFunctionDefinitions::get(unsigned int n)
1234 {
1235 return static_cast<FunctionDefinition*>(ListOf::get(n));
1236 }
1237
1238
1239 /* return nth item in list */
1240 const FunctionDefinition *
get(unsigned int n) const1241 ListOfFunctionDefinitions::get(unsigned int n) const
1242 {
1243 return static_cast<const FunctionDefinition*>(ListOf::get(n));
1244 }
1245
1246
1247 /**
1248 * Used by ListOf::get() to lookup an SBase based by its id.
1249 */
1250 struct IdEqFD : public unary_function<SBase*, bool>
1251 {
1252 const string& mId;
1253
IdEqFDIdEqFD1254 IdEqFD (const string& id) : mId(id) { }
operator ()IdEqFD1255 bool operator() (SBase* sb)
1256 { return static_cast <FunctionDefinition *> (sb)->getId() == mId; }
1257 };
1258
1259
1260 /* return item by id */
1261 FunctionDefinition*
get(const std::string & sid)1262 ListOfFunctionDefinitions::get (const std::string& sid)
1263 {
1264 return const_cast<FunctionDefinition*>(
1265 static_cast<const ListOfFunctionDefinitions&>(*this).get(sid) );
1266 }
1267
1268
1269 /* return item by id */
1270 const FunctionDefinition*
get(const std::string & sid) const1271 ListOfFunctionDefinitions::get (const std::string& sid) const
1272 {
1273 vector<SBase*>::const_iterator result;
1274
1275 result = find_if( mItems.begin(), mItems.end(), IdEqFD(sid) );
1276 return (result == mItems.end()) ? NULL :
1277 static_cast <FunctionDefinition*> (*result);
1278
1279 }
1280
1281
1282 /* Removes the nth item from this list */
1283 FunctionDefinition*
remove(unsigned int n)1284 ListOfFunctionDefinitions::remove (unsigned int n)
1285 {
1286 return static_cast<FunctionDefinition*>(ListOf::remove(n));
1287 }
1288
1289
1290 /* Removes item in this list by id */
1291 FunctionDefinition*
remove(const std::string & sid)1292 ListOfFunctionDefinitions::remove (const std::string& sid)
1293 {
1294 SBase* item = NULL;
1295 vector<SBase*>::iterator result;
1296
1297 result = find_if( mItems.begin(), mItems.end(), IdEqFD(sid) );
1298
1299 if (result != mItems.end())
1300 {
1301 item = *result;
1302 mItems.erase(result);
1303 }
1304
1305 return static_cast <FunctionDefinition*> (item);
1306 }
1307
1308
1309 /** @cond doxygenLibsbmlInternal */
1310 /*
1311 * @return the ordinal position of the element with respect to its siblings
1312 * or -1 (default) to indicate the position is not significant.
1313 */
1314 int
getElementPosition() const1315 ListOfFunctionDefinitions::getElementPosition () const
1316 {
1317 return 1;
1318 }
1319 /** @endcond */
1320
1321
1322 /** @cond doxygenLibsbmlInternal */
1323 /*
1324 * @return the SBML object corresponding to next XMLToken in the
1325 * XMLInputStream or @c NULL if the token was not recognized.
1326 */
1327 SBase*
createObject(XMLInputStream & stream)1328 ListOfFunctionDefinitions::createObject (XMLInputStream& stream)
1329 {
1330 const string& name = stream.peek().getName();
1331 SBase* object = NULL;
1332
1333
1334 if (name == "functionDefinition")
1335 {
1336 try
1337 {
1338 object = new FunctionDefinition(getSBMLNamespaces());
1339 }
1340 catch (SBMLConstructorException*)
1341 {
1342 object = new FunctionDefinition(SBMLDocument::getDefaultLevel(),
1343 SBMLDocument::getDefaultVersion());
1344 }
1345 catch ( ... )
1346 {
1347 object = new FunctionDefinition(SBMLDocument::getDefaultLevel(),
1348 SBMLDocument::getDefaultVersion());
1349 }
1350
1351 if (object != NULL) mItems.push_back(object);
1352 }
1353
1354 return object;
1355 }
1356 /** @endcond */
1357
1358
1359 #endif /* __cplusplus */
1360 /** @cond doxygenIgnored */
1361 LIBSBML_EXTERN
1362 FunctionDefinition_t *
FunctionDefinition_create(unsigned int level,unsigned int version)1363 FunctionDefinition_create (unsigned int level, unsigned int version)
1364 {
1365 try
1366 {
1367 FunctionDefinition* obj = new FunctionDefinition(level,version);
1368 return obj;
1369 }
1370 catch (SBMLConstructorException)
1371 {
1372 return NULL;
1373 }
1374 }
1375
1376
1377 LIBSBML_EXTERN
1378 FunctionDefinition_t *
FunctionDefinition_createWithNS(SBMLNamespaces_t * sbmlns)1379 FunctionDefinition_createWithNS (SBMLNamespaces_t* sbmlns)
1380 {
1381 try
1382 {
1383 FunctionDefinition* obj = new FunctionDefinition(sbmlns);
1384 return obj;
1385 }
1386 catch (SBMLConstructorException)
1387 {
1388 return NULL;
1389 }
1390 }
1391
1392
1393 LIBSBML_EXTERN
1394 void
FunctionDefinition_free(FunctionDefinition_t * fd)1395 FunctionDefinition_free (FunctionDefinition_t *fd)
1396 {
1397 if (fd != NULL)
1398 delete fd;
1399 }
1400
1401
1402 LIBSBML_EXTERN
1403 FunctionDefinition_t *
FunctionDefinition_clone(const FunctionDefinition_t * fd)1404 FunctionDefinition_clone (const FunctionDefinition_t* fd)
1405 {
1406 return (fd != NULL) ? static_cast<FunctionDefinition*>( fd->clone() ) : NULL;
1407 }
1408
1409
1410 LIBSBML_EXTERN
1411 const XMLNamespaces_t *
FunctionDefinition_getNamespaces(FunctionDefinition_t * fd)1412 FunctionDefinition_getNamespaces(FunctionDefinition_t *fd)
1413 {
1414 return (fd != NULL) ? fd->getNamespaces() : NULL;
1415 }
1416
1417
1418 LIBSBML_EXTERN
1419 const char *
FunctionDefinition_getId(const FunctionDefinition_t * fd)1420 FunctionDefinition_getId (const FunctionDefinition_t *fd)
1421 {
1422 return (fd != NULL && fd->isSetId()) ? fd->getId().c_str() : NULL;
1423 }
1424
1425
1426 LIBSBML_EXTERN
1427 const char *
FunctionDefinition_getName(const FunctionDefinition_t * fd)1428 FunctionDefinition_getName (const FunctionDefinition_t *fd)
1429 {
1430 return (fd != NULL && fd->isSetName()) ? fd->getName().c_str() : NULL;
1431 }
1432
1433
1434 LIBSBML_EXTERN
1435 const ASTNode_t *
FunctionDefinition_getMath(const FunctionDefinition_t * fd)1436 FunctionDefinition_getMath (const FunctionDefinition_t *fd)
1437 {
1438 return (fd != NULL) ? fd->getMath() : NULL;
1439 }
1440
1441
1442 LIBSBML_EXTERN
1443 int
FunctionDefinition_isSetId(const FunctionDefinition_t * fd)1444 FunctionDefinition_isSetId (const FunctionDefinition_t *fd)
1445 {
1446 return (fd != NULL) ? static_cast<int>( fd->isSetId() ) : 0;
1447 }
1448
1449
1450 LIBSBML_EXTERN
1451 int
FunctionDefinition_isSetName(const FunctionDefinition_t * fd)1452 FunctionDefinition_isSetName (const FunctionDefinition_t *fd)
1453 {
1454 return (fd != NULL) ? static_cast<int>( fd->isSetName() ) : 0;
1455 }
1456
1457
1458 LIBSBML_EXTERN
1459 int
FunctionDefinition_isSetMath(const FunctionDefinition_t * fd)1460 FunctionDefinition_isSetMath (const FunctionDefinition_t *fd)
1461 {
1462 return (fd != NULL) ? static_cast<int>( fd->isSetMath() ) : 0;
1463 }
1464
1465
1466 LIBSBML_EXTERN
1467 int
FunctionDefinition_setId(FunctionDefinition_t * fd,const char * sid)1468 FunctionDefinition_setId (FunctionDefinition_t *fd, const char *sid)
1469 {
1470 if (fd != NULL)
1471 return (sid == NULL) ? fd->setId("") : fd->setId(sid);
1472 else
1473 return LIBSBML_INVALID_OBJECT;
1474 }
1475
1476
1477 LIBSBML_EXTERN
1478 int
FunctionDefinition_setName(FunctionDefinition_t * fd,const char * name)1479 FunctionDefinition_setName (FunctionDefinition_t *fd, const char *name)
1480 {
1481 if (fd != NULL)
1482 return (name == NULL) ? fd->unsetName() : fd->setName(name);
1483 else
1484 return LIBSBML_INVALID_OBJECT;
1485 }
1486
1487
1488 LIBSBML_EXTERN
1489 int
FunctionDefinition_setMath(FunctionDefinition_t * fd,const ASTNode_t * math)1490 FunctionDefinition_setMath (FunctionDefinition_t *fd, const ASTNode_t *math)
1491 {
1492 if (fd != NULL)
1493 return fd->setMath(math);
1494 else
1495 return LIBSBML_INVALID_OBJECT;
1496 }
1497
1498
1499 LIBSBML_EXTERN
1500 int
FunctionDefinition_unsetName(FunctionDefinition_t * fd)1501 FunctionDefinition_unsetName (FunctionDefinition_t *fd)
1502 {
1503 if (fd != NULL)
1504 return fd->unsetName();
1505 else
1506 return LIBSBML_INVALID_OBJECT;
1507 }
1508
1509
1510 LIBSBML_EXTERN
1511 const ASTNode_t *
FunctionDefinition_getArgument(const FunctionDefinition_t * fd,unsigned int n)1512 FunctionDefinition_getArgument (const FunctionDefinition_t *fd, unsigned int n)
1513 {
1514 return (fd != NULL) ? fd->getArgument(n) : NULL;
1515 }
1516
1517
1518 LIBSBML_EXTERN
1519 const ASTNode_t *
FunctionDefinition_getArgumentByName(FunctionDefinition_t * fd,const char * name)1520 FunctionDefinition_getArgumentByName ( FunctionDefinition_t *fd,
1521 const char *name )
1522 {
1523 return (fd != NULL) ? fd->getArgument(name != NULL ? name : "") : NULL;
1524 }
1525
1526
1527 LIBSBML_EXTERN
1528 const ASTNode_t *
FunctionDefinition_getBody(const FunctionDefinition_t * fd)1529 FunctionDefinition_getBody (const FunctionDefinition_t *fd)
1530 {
1531 return (fd != NULL) ? fd->getBody() : NULL;
1532 }
1533
1534
1535 LIBSBML_EXTERN
1536 int
FunctionDefinition_isSetBody(const FunctionDefinition_t * fd)1537 FunctionDefinition_isSetBody (const FunctionDefinition_t *fd)
1538 {
1539 return (fd != NULL) ? static_cast<int>( fd->isSetBody() ) : 0;
1540 }
1541
1542
1543 LIBSBML_EXTERN
1544 unsigned int
FunctionDefinition_getNumArguments(const FunctionDefinition_t * fd)1545 FunctionDefinition_getNumArguments (const FunctionDefinition_t *fd)
1546 {
1547 return (fd != NULL) ? fd->getNumArguments() : SBML_INT_MAX;
1548 }
1549
1550
1551
1552 LIBSBML_EXTERN
1553 FunctionDefinition_t *
ListOfFunctionDefinitions_getById(ListOf_t * lo,const char * sid)1554 ListOfFunctionDefinitions_getById (ListOf_t *lo, const char *sid)
1555 {
1556 if (lo != NULL)
1557 return (sid != NULL) ?
1558 static_cast <ListOfFunctionDefinitions *> (lo)->get(sid) : NULL;
1559 else
1560 return NULL;
1561 }
1562
1563
1564 LIBSBML_EXTERN
1565 FunctionDefinition_t *
ListOfFunctionDefinitions_removeById(ListOf_t * lo,const char * sid)1566 ListOfFunctionDefinitions_removeById (ListOf_t *lo, const char *sid)
1567 {
1568 if (lo != NULL)
1569 return (sid != NULL) ?
1570 static_cast <ListOfFunctionDefinitions *> (lo)->remove(sid) : NULL;
1571 else
1572 return NULL;
1573 }
1574 /** @endcond */
1575
1576 LIBSBML_CPP_NAMESPACE_END
1577
1578