1 /**
2 * @file GeneAssociation.cpp
3 * @brief Implementation of GeneAssociation, the SBase derived class of the fbc package.
4 * @author Akiya Jouraku
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 * This library is free software; you can redistribute it and/or modify it
29 * under the terms of the GNU Lesser General Public License as published by
30 * the Free Software Foundation. A copy of the license agreement is provided
31 * in the file named "LICENSE.txt" included with this software distribution
32 * and also available online as http://sbml.org/software/libsbml/license.html
33 *------------------------------------------------------------------------- -->
34 */
35
36 #include <iostream>
37 #include <limits>
38
39 #include <sbml/SBMLVisitor.h>
40 #include <sbml/xml/XMLNode.h>
41 #include <sbml/xml/XMLToken.h>
42 #include <sbml/xml/XMLAttributes.h>
43 #include <sbml/xml/XMLInputStream.h>
44 #include <sbml/xml/XMLOutputStream.h>
45
46 #include <sbml/packages/fbc/sbml/GeneAssociation.h>
47 #include <sbml/packages/fbc/extension/FbcExtension.h>
48
49 using namespace std;
50
51 LIBSBML_CPP_NAMESPACE_BEGIN
52 #ifdef __cplusplus
53
54 /*
55 * Creates a new GeneAssociation with the given level, version, and package version.
56 */
GeneAssociation(unsigned int level,unsigned int version,unsigned int pkgVersion)57 GeneAssociation::GeneAssociation (unsigned int level, unsigned int version, unsigned int pkgVersion)
58 : SBase (level,version)
59 // ,mId("")
60 ,mReaction("")
61 ,mAssociation(NULL)
62 {
63 // set an SBMLNamespaces derived object (FbcPkgNamespaces) of this package.
64 setSBMLNamespacesAndOwn(new FbcPkgNamespaces(level,version,pkgVersion));
65 }
66
67
68 /*
69 * Creates a new GeneAssociation with the given FbcPkgNamespaces object.
70 */
GeneAssociation(FbcPkgNamespaces * fbcns)71 GeneAssociation::GeneAssociation(FbcPkgNamespaces* fbcns)
72 : SBase(fbcns)
73 // ,mId("")
74 ,mReaction("")
75 ,mAssociation(NULL)
76 {
77 //
78 // set the element namespace of this object
79 //
80 setElementNamespace(fbcns->getURI());
81
82 // load package extensions bound with this object (if any)
83 loadPlugins(fbcns);
84 }
85
86
87 /*
88 * Copy constructor.
89 */
GeneAssociation(const GeneAssociation & source)90 GeneAssociation::GeneAssociation(const GeneAssociation& source)
91 : SBase(source)
92 // , mId(source.mId)
93 , mReaction(source.mReaction)
94 , mAssociation(NULL)
95 {
96 if (source.mAssociation != NULL)
97 this->mAssociation = new Association(*source.mAssociation);
98 else
99 this->mAssociation = NULL;
100 }
101
102
103
104 /*
105 * Creates a new GeneAssociation from the given XMLNode
106 */
GeneAssociation(const XMLNode & node,FbcPkgNamespaces * fbcns)107 GeneAssociation::GeneAssociation(const XMLNode& node, FbcPkgNamespaces* fbcns)
108 : SBase(fbcns)
109 //,mId("")
110 ,mReaction("")
111 ,mAssociation(NULL)
112 {
113 //
114 // set the element namespace of this object
115 //
116 setElementNamespace(fbcns->getURI());
117
118 // load package extensions bound with this object (if any)
119 loadPlugins(fbcns);
120
121 const XMLAttributes& attributes=node.getAttributes();
122 const XMLNode* child;
123
124 //ExpectedAttributes ea(getElementName());
125 ExpectedAttributes ea;
126 addExpectedAttributes(ea);
127 this->readAttributes(attributes,ea);
128 unsigned int n=0,nMax = node.getNumChildren();
129 while(n<nMax)
130 {
131 child=&node.getChild(n);
132 const std::string& childName=child->getName();
133
134 if(childName=="gene" || childName=="or" || childName == "and")
135 {
136 mAssociation = new Association(*child, new FbcPkgNamespaces(*fbcns));
137 }
138 else if(childName=="annotation")
139 {
140 this->mAnnotation=new XMLNode(*child);
141 }
142 else if(childName=="notes")
143 {
144 this->mNotes=new XMLNode(*child);
145 }
146 else
147 {
148 //throw;
149 }
150 ++n;
151 }
152 setSBMLNamespacesAndOwn(fbcns);
153 connectToChild();
154 }
155
156
157 /*
158 * Creates an XMLNode object from this.
159 */
toXML() const160 XMLNode GeneAssociation::toXML() const
161 {
162 XMLNamespaces xmlns = XMLNamespaces();
163 XMLTriple triple = XMLTriple(getElementName(), "", "");
164 XMLAttributes att = XMLAttributes();
165
166 if (isSetId())
167 {
168 att.add("id", mId);
169 }
170 if (isSetReaction())
171 {
172 att.add("reaction", mReaction);
173 }
174
175 XMLToken token = XMLToken(triple, att, xmlns);
176 XMLNode node(token);
177 // add the notes and annotations
178 if(mNotes) node.addChild(*this->mNotes);
179 if(mAnnotation) node.addChild(*this->mAnnotation);
180
181 if (isSetAssociation())
182 {
183 node.addChild(mAssociation->toXML());
184 }
185 return node;
186 }
187
188
189 /*
190 * Assignment operator.
191 */
operator =(const GeneAssociation & source)192 GeneAssociation& GeneAssociation::operator=(const GeneAssociation& source)
193 {
194 if(&source!=this)
195 {
196 this->SBase::operator=(source);
197 this->mId = source.mId;
198 this->mReaction = source.mReaction;
199 if (mAssociation != NULL)
200 delete mAssociation;
201 if (source.mAssociation != NULL)
202 this->mAssociation = new Association(*source.mAssociation);
203 else
204 this->mAssociation = NULL;
205 }
206
207 return *this;
208 }
209
210
211 /*
212 * Destructor.
213 */
~GeneAssociation()214 GeneAssociation::~GeneAssociation ()
215 {
216 if (isSetAssociation())
217 {
218 delete mAssociation;
219 mAssociation = NULL;
220 }
221 }
222
223
224 /*
225 * Returns the value of the "id" attribute of this GeneAssociation.
226 */
227 const std::string&
getId() const228 GeneAssociation::getId () const
229 {
230 return mId;
231 }
232
233
234 /*
235 * Predicate returning @c true or @c false depending on whether this
236 * GeneAssociation's "id" attribute has been set.
237 */
238 bool
isSetId() const239 GeneAssociation::isSetId () const
240 {
241 return (mId.empty() == false);
242 }
243
244 /*
245 * Sets the value of the "id" attribute of this GeneAssociation.
246 */
247 int
setId(const std::string & id)248 GeneAssociation::setId (const std::string& id)
249 {
250 return SyntaxChecker::checkAndSetSId(id ,mId);
251 }
252
253
254 /*
255 * Unsets the value of the "id" attribute of this GeneAssociation.
256 */
257 int
unsetId()258 GeneAssociation::unsetId ()
259 {
260 mId.erase();
261 if (mId.empty())
262 {
263 return LIBSBML_OPERATION_SUCCESS;
264 }
265 else
266 {
267 return LIBSBML_OPERATION_FAILED;
268 }
269 }
270
271
272
273 /*
274 * Returns the value of the "reaction" attribute of this GeneAssociation.
275 */
276 const std::string&
getReaction() const277 GeneAssociation::getReaction () const
278 {
279 return mReaction;
280 }
281
282
283 /*
284 * Predicate returning @c true or @c false depending on whether this
285 * GeneAssociation's "reaction" attribute has been set.
286 */
287 bool
isSetReaction() const288 GeneAssociation::isSetReaction () const
289 {
290 return (mReaction.empty() == false);
291 }
292
293 /*
294 * Sets the value of the "reaction" attribute of this GeneAssociation.
295 */
296 int
setReaction(const std::string & reaction)297 GeneAssociation::setReaction (const std::string& reaction)
298 {
299 return SyntaxChecker::checkAndSetSId(reaction ,mReaction);
300 }
301
302
303 /*
304 * Unsets the value of the "reaction" attribute of this GeneAssociation.
305 */
306 int
unsetReaction()307 GeneAssociation::unsetReaction ()
308 {
309 mReaction.erase();
310 if (mReaction.empty())
311 {
312 return LIBSBML_OPERATION_SUCCESS;
313 }
314 else
315 {
316 return LIBSBML_OPERATION_FAILED;
317 }
318 }
319
320
321 /*
322 * Returns the value of the "association" attribute of this GeneAssociation.
323 */
324 const Association*
getAssociation() const325 GeneAssociation::getAssociation () const
326 {
327 return mAssociation;
328 }
329
330 /*
331 * Returns the value of the "association" attribute of this GeneAssociation.
332 */
333 Association*
getAssociation()334 GeneAssociation::getAssociation ()
335 {
336 return mAssociation;
337 }
338
339 /*
340 * Predicate returning @c true or @c false depending on whether this
341 * GeneAssociation's "association" attribute has been set.
342 */
343 bool
isSetAssociation() const344 GeneAssociation::isSetAssociation () const
345 {
346 return (mAssociation != NULL);
347 }
348
349
createAssociation()350 Association* GeneAssociation::createAssociation()
351 {
352 Association* result = NULL;
353 try
354 {
355 FBC_CREATE_NS_WITH_VERSION(fbcns, getSBMLNamespaces(), getPackageVersion());
356 result = new Association(fbcns);
357 unsetAssociation();
358 mAssociation = result;
359 mAssociation->connectToParent(this);
360 delete fbcns;
361 }
362 catch(...)
363 {
364 /*
365 * NULL will be returned if the mSBMLNS is invalid (basically this
366 * should not happen) or some exception is thrown (e.g. std::bad_alloc)
367 *
368 * (Maybe this should be changed so that caller can detect what kind
369 * of error happened in this function.)
370 */
371 }
372
373 return result;
374 }
375
376 /*
377 * Sets the value of the "association" attribute of this GeneAssociation.
378 */
379 int
setAssociation(const Association * association)380 GeneAssociation::setAssociation (const Association* association)
381 {
382 if (mAssociation == association)
383 {
384 return LIBSBML_OPERATION_SUCCESS;
385 }
386 else if (association == NULL)
387 {
388 return unsetAssociation();
389 }
390 else if (getLevel() != association->getLevel())
391 {
392 return LIBSBML_LEVEL_MISMATCH;
393 }
394 else if (getVersion() != association->getVersion())
395 {
396 return LIBSBML_VERSION_MISMATCH;
397 }
398 else
399 {
400 if (mAssociation != NULL)
401 delete mAssociation;
402
403 mAssociation = (association != NULL) ?
404 static_cast<Association*>( association->clone() ) : NULL;
405
406 if (mAssociation != NULL)
407 mAssociation->connectToParent(this);
408
409 return LIBSBML_OPERATION_SUCCESS;
410 }
411 }
412
413
414 /*
415 * Unsets the value of the "association" attribute of this GeneAssociation.
416 */
417 int
unsetAssociation()418 GeneAssociation::unsetAssociation ()
419 {
420 if (mAssociation != NULL)
421 delete mAssociation;
422 mAssociation=NULL;
423 return LIBSBML_OPERATION_SUCCESS;
424 }
425
426
427 /*
428 * Returns the XML element name of
429 * this SBML object.
430 */
431 const std::string&
getElementName() const432 GeneAssociation::getElementName () const
433 {
434 static const std::string name = "geneAssociation";
435 return name;
436 }
437
438
439 /** @cond doxygenLibsbmlInternal */
440 SBase*
createObject(XMLInputStream & stream)441 GeneAssociation::createObject (XMLInputStream& stream)
442 {
443 SBase* object = NULL;
444
445 const string& name = stream.peek().getName();
446 if (name == "gene" || name == "or" || name == "and")
447 {
448 if (mAssociation != NULL)
449 {
450 logError(NotSchemaConformant, getLevel(), getVersion(),
451 "Only one <association> element is permitted "
452 "in a single <geneAssociation> element.");
453 }
454
455 mAssociation = new Association(getLevel(), getVersion());
456 if (name == "gene")
457 mAssociation->setType(GENE_ASSOCIATION);
458 else if (name == "and")
459 mAssociation->setType(AND_ASSOCIATION);
460 else if (name == "or")
461 mAssociation->setType(OR_ASSOCIATION);
462 object = mAssociation;
463 }
464 return object;
465 }
466 /** @endcond */
467
468 /** @cond doxygenLibsbmlInternal */
469 void
addExpectedAttributes(ExpectedAttributes & attributes)470 GeneAssociation::addExpectedAttributes(ExpectedAttributes& attributes)
471 {
472 SBase::addExpectedAttributes(attributes);
473
474 attributes.add("id");
475 attributes.add("reaction");
476 }
477 /** @endcond */
478
479 /** @cond doxygenLibsbmlInternal */
480 void
readAttributes(const XMLAttributes & attributes,const ExpectedAttributes & expectedAttributes)481 GeneAssociation::readAttributes (const XMLAttributes& attributes,
482 const ExpectedAttributes& expectedAttributes)
483 {
484 SBase::readAttributes(attributes,expectedAttributes);
485
486 const unsigned int sbmlLevel = getLevel ();
487 const unsigned int sbmlVersion = getVersion();
488
489 bool assigned = attributes.readInto("id", mId, getErrorLog(), true, getLine(), getColumn());
490 if (assigned && mId.empty())
491 {
492 logEmptyString(mId, sbmlLevel, sbmlVersion, "<geneAssociation>");
493 }
494 if (!SyntaxChecker::isValidSBMLSId(mId))
495 logError(InvalidIdSyntax, sbmlLevel, sbmlVersion, "The id '" + mId + "' does not conform to the syntax.");
496
497 assigned = attributes.readInto("reaction", mReaction, getErrorLog(), true, getLine(), getColumn());
498 if (assigned && mReaction.empty())
499 {
500 logEmptyString(mReaction, sbmlLevel, sbmlVersion, "<geneAssociation>");
501 }
502 if (!SyntaxChecker::isValidSBMLSId(mReaction))
503 logError(InvalidIdSyntax, getLevel(), getVersion(),
504 "The syntax of the attribute reaction='" + mReaction + "' does not conform.");
505 }
506 /** @endcond */
507
508 /** @cond doxygenLibsbmlInternal */
509 void
writeAttributes(XMLOutputStream & stream) const510 GeneAssociation::writeAttributes (XMLOutputStream& stream) const
511 {
512 SBase::writeAttributes(stream);
513
514 stream.writeAttribute("id", getPrefix(), mId);
515 stream.writeAttribute("reaction", getPrefix(), mReaction);
516
517 //
518 // (EXTENSION)
519 //
520 SBase::writeExtensionAttributes(stream);
521 }
522 /** @endcond */
523
524 /** @cond doxygenLibsbmlInternal */
525 void
writeElements(XMLOutputStream & stream) const526 GeneAssociation::writeElements (XMLOutputStream& stream) const
527 {
528 SBase::writeElements(stream);
529
530 if (isSetAssociation())
531 mAssociation ->write(stream);
532
533
534 //
535 // (EXTENSION)
536 //
537 SBase::writeExtensionElements(stream);
538 }
539 /** @endcond */
540
541
542 /*
543 * @return the typecode (int) of this SBML object or SBML_UNKNOWN
544 * (default).
545 *
546 * @see getElementName()
547 */
548 int
getTypeCode() const549 GeneAssociation::getTypeCode () const
550 {
551 return SBML_FBC_GENEASSOCIATION;
552 }
553
554 GeneAssociation*
clone() const555 GeneAssociation::clone() const
556 {
557 return new GeneAssociation(*this);
558 }
559
560
561 /** @cond doxygenLibsbmlInternal */
562 bool
accept(SBMLVisitor & v) const563 GeneAssociation::accept (SBMLVisitor& v) const
564 {
565 v.visit(*this);
566 v.leave(*this);
567
568 return true;
569 }
570 /** @endcond */
571
572
573 /*
574 * Constructor.
575 */
ListOfGeneAssociations(FbcPkgNamespaces * fbcns)576 ListOfGeneAssociations::ListOfGeneAssociations(FbcPkgNamespaces* fbcns)
577 : ListOf(fbcns)
578 {
579 //
580 // set the element namespace of this object
581 //
582 setElementNamespace(fbcns->getURI());
583 }
584
585
586 /*
587 * Constructor.
588 */
ListOfGeneAssociations(unsigned int level,unsigned int version,unsigned int pkgVersion)589 ListOfGeneAssociations::ListOfGeneAssociations(unsigned int level, unsigned int version, unsigned int pkgVersion)
590 : ListOf(level,version)
591 {
592 setSBMLNamespacesAndOwn(new FbcPkgNamespaces(level,version,pkgVersion));
593 };
594
595
596 /*
597 * @return a (deep) copy of this ListOfGeneAssociations.
598 */
599 ListOfGeneAssociations*
clone() const600 ListOfGeneAssociations::clone () const
601 {
602 return new ListOfGeneAssociations(*this);
603 }
604
605
606 /* return nth item in list */
607 GeneAssociation *
get(unsigned int n)608 ListOfGeneAssociations::get(unsigned int n)
609 {
610 return static_cast<GeneAssociation*>(ListOf::get(n));
611 }
612
613
614 /* return nth item in list */
615 const GeneAssociation *
get(unsigned int n) const616 ListOfGeneAssociations::get(unsigned int n) const
617 {
618 return static_cast<const GeneAssociation*>(ListOf::get(n));
619 }
620
621
622 /* return item by symbol */
623 GeneAssociation*
get(const std::string & symbol)624 ListOfGeneAssociations::get (const std::string& symbol)
625 {
626 return const_cast<GeneAssociation*>(
627 static_cast<const ListOfGeneAssociations&>(*this).get(symbol) );
628 }
629
630
631 /* return item by symbol */
632 const GeneAssociation*
get(const std::string & symbol) const633 ListOfGeneAssociations::get (const std::string& symbol) const
634 {
635 vector<SBase*>::const_iterator result;
636
637 result = find_if( mItems.begin(), mItems.end(), IdEq<GeneAssociation>(symbol) );
638 return (result == mItems.end()) ? 0 : static_cast <GeneAssociation*> (*result);
639 }
640
641
642 /* Removes the nth item from this list */
643 GeneAssociation*
remove(unsigned int n)644 ListOfGeneAssociations::remove (unsigned int n)
645 {
646 return static_cast<GeneAssociation*>(ListOf::remove(n));
647 }
648
649
650 /* Removes item in this list by symbol */
651 GeneAssociation*
remove(const std::string & symbol)652 ListOfGeneAssociations::remove (const std::string& symbol)
653 {
654 SBase* item = 0;
655 vector<SBase*>::iterator result;
656
657 result = find_if( mItems.begin(), mItems.end(), IdEq<GeneAssociation>(symbol) );
658
659 if (result != mItems.end())
660 {
661 item = *result;
662 mItems.erase(result);
663 }
664
665 return static_cast <GeneAssociation*> (item);
666 }
667
668
669 /*
670 * @return the typecode (int) of SBML objects contained in this ListOf or
671 * SBML_UNKNOWN (default).
672 */
673 int
getItemTypeCode() const674 ListOfGeneAssociations::getItemTypeCode () const
675 {
676 return SBML_FBC_GENEASSOCIATION;
677 }
678
679
680 /*
681 * Returns the XML element name of
682 * this SBML object.
683 */
684 const std::string&
getElementName() const685 ListOfGeneAssociations::getElementName () const
686 {
687 static const std::string name = "listOfGeneAssociations";
688 return name;
689 }
690
691
692 /** @cond doxygenLibsbmlInternal */
693 SBase*
createObject(XMLInputStream & stream)694 ListOfGeneAssociations::createObject (XMLInputStream& stream)
695 {
696 const std::string& name = stream.peek().getName();
697 SBase* object = 0;
698
699
700 if (name == "geneAssociation")
701 {
702 try
703 {
704 FBC_CREATE_NS_WITH_VERSION(fbcns, getSBMLNamespaces(), getPackageVersion());
705 object = new GeneAssociation(fbcns);
706 appendAndOwn(object);
707 delete fbcns;
708 //mItems.push_back(object);
709 }
710 catch(...)
711 {
712 /*
713 * NULL will be returned if the mSBMLNS is invalid (basically this
714 * should not happen) or some exception is thrown (e.g. std::bad_alloc)
715 *
716 * (Maybe this should be changed so that caller can detect what kind
717 * of error happened in this function.)
718 */
719 }
720 }
721
722 return object;
723 }
724 /** @endcond */
725
726
727 #endif /* __cplusplus */
728 LIBSBML_CPP_NAMESPACE_END
729
730