/** @cond doxygenLibsbmlInternal */ int Replacing::replaceWithAndMaybeDelete(SBase* replacement, bool deleteme, ASTNode* conversionFactor) { //All of the following function calls that could result in errors set their own error messages. SBase* replaced = getReferencedElement(); if (replaced==NULL) return LIBSBML_INVALID_OBJECT; //Rename things int ret = updateIDs(replaced, replacement); if (ret != LIBSBML_OPERATION_SUCCESS) return ret; //Perform any conversions on references in the submodel. ret = performConversions(replacement, &conversionFactor); if (ret != LIBSBML_OPERATION_SUCCESS) return ret; //Finally, recurse down if there are things the replaced element itself replaced (or used to be replaced by) CompSBasePlugin* replacedplug = static_cast<CompSBasePlugin*>(replaced->getPlugin(getPrefix())); if (replacedplug==NULL) { //assert(false); //Not sure when this situation would come up, so I would like to see an example. //(sadly, I cannot set an assert in production code.) return LIBSBML_OPERATION_SUCCESS; //I guess? LS DEBUG } for (unsigned int re=0; re<replacedplug->getNumReplacedElements(); re++) { ret = replacedplug->getReplacedElement(re)->replaceWithAndMaybeDelete(replacement, true, conversionFactor); if (ret != LIBSBML_OPERATION_SUCCESS) return ret; } if (replacedplug->isSetReplacedBy()) { ret = replacedplug->getReplacedBy()->replaceWithAndMaybeDelete(replacement, deleteme, conversionFactor); if (ret != LIBSBML_OPERATION_SUCCESS) return ret; } return LIBSBML_OPERATION_SUCCESS; }
int SBaseRef::collectDeletions(set<SBase*>* removed, set<SBase*>* toremove) { SBase* todelete = getReferencedElement(); if (todelete==NULL) { return LIBSBML_INVALID_OBJECT; } if (removed) { if (removed->find(todelete) != removed->end()) { //Already deleted or replaced. return LIBSBML_OPERATION_SUCCESS; } } if (toremove) { toremove->insert(todelete); } CompSBasePlugin* todplug = static_cast<CompSBasePlugin*>(todelete->getPlugin(getPrefix())); if (todplug != NULL) { for (unsigned long re=0; re<todplug->getNumReplacedElements(); re++) { todplug->getReplacedElement(re)->collectDeletions(removed, toremove); } if (todplug->isSetReplacedBy()) { todplug->getReplacedBy()->collectDeletions(removed, toremove); } } return LIBSBML_OPERATION_SUCCESS; }
CompSBasePlugin::CompSBasePlugin(const CompSBasePlugin& orig) : SBasePlugin(orig) , mListOfReplacedElements(NULL) , mReplacedBy(NULL) { if (orig.isSetReplacedBy()) { mReplacedBy = orig.mReplacedBy->clone(); mReplacedBy->connectToParent(getParentSBMLObject()); } if (orig.getNumReplacedElements() > 0) { createListOfReplacedElements(); for (unsigned int re=0; re<orig.getNumReplacedElements(); re++) { mListOfReplacedElements->append(orig.getReplacedElement(re)); } } connectToChild(); }
END_TEST START_TEST (test_comp_sbase) { SBMLNamespaces sbmlns(3,1,"comp",1); Parameter param(&sbmlns); CompSBasePlugin* pplugin = static_cast<CompSBasePlugin*>(param.getPlugin("comp")); fail_unless(pplugin->getNumReplacedElements()==0); ReplacedElement* re = pplugin->createReplacedElement(); re->setMetaId("re1"); fail_unless(pplugin->getNumReplacedElements()==1); fail_unless(pplugin->addReplacedElement(NULL)==LIBSBML_INVALID_OBJECT); ReplacedElement re2(3, 1); re2.setMetaId("re2"); fail_unless(pplugin->addReplacedElement(&re2)==LIBSBML_INVALID_OBJECT); re2.setDeletion("ID1"); fail_unless(pplugin->addReplacedElement(&re2)==LIBSBML_INVALID_OBJECT); re2.setSubmodelRef("mod1"); fail_unless(pplugin->addReplacedElement(&re2)==LIBSBML_OPERATION_SUCCESS); ReplacedElement* reref = pplugin->getReplacedElement(1); fail_unless(reref != NULL); fail_unless(reref->getMetaId()=="re2"); reref = pplugin->getReplacedElement(0); fail_unless(reref != NULL); fail_unless(reref->getMetaId()=="re1"); re->setDeletion("ID1"); fail_unless(reref->getDeletion()=="ID1"); fail_unless(pplugin->removeReplacedElement(3)==NULL); fail_unless(pplugin->removeReplacedElement(0)==re); fail_unless(pplugin->getReplacedElement(1)==NULL); fail_unless(pplugin->isSetReplacedBy()==false); ReplacedBy* rb = pplugin->createReplacedBy(); fail_unless(rb != NULL); fail_unless(pplugin->isSetReplacedBy()==true); fail_unless(pplugin->setReplacedBy(NULL)==LIBSBML_OPERATION_SUCCESS); fail_unless(pplugin->isSetReplacedBy()==false); ReplacedBy rb2(3,1); fail_unless(pplugin->setReplacedBy(&rb2)==LIBSBML_INVALID_OBJECT); rb2.setIdRef("ID1"); fail_unless(pplugin->setReplacedBy(&rb2)==LIBSBML_INVALID_OBJECT); rb2.setSubmodelRef("mod1"); fail_unless(pplugin->setReplacedBy(&rb2)==LIBSBML_OPERATION_SUCCESS); fail_unless(pplugin->unsetReplacedBy()==LIBSBML_OPERATION_SUCCESS); }
int ReplacedElement::performReplacementAndCollect(set<SBase*>* removed, set<SBase*>* toremove) { SBMLDocument* doc = getSBMLDocument(); if (isSetDeletion()) { //Deletions don't need to be replaced. return LIBSBML_OPERATION_SUCCESS; } //Find the various objects and plugin objects we need for this to work. SBase* lore = getParentSBMLObject(); ListOf* lorelist = static_cast<ListOf*>(lore); if (lore == NULL) { if (doc) { string error = "Cannot carry out replacement in ReplacedElement::performReplacement: no parent <listOfReplacedElements> could be found for the given replacement element."; doc->getErrorLog()->logPackageError("comp", CompModelFlatteningFailed, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn()); } return LIBSBML_INVALID_OBJECT; } if (lore->getTypeCode() != SBML_LIST_OF || lorelist->getItemTypeCode() != SBML_COMP_REPLACEDELEMENT) { if (doc) { string error = "Cannot carry out replacement in ReplacedElement::performReplacement: no parent <listOfReplacedElements> could be found for the given replacement element."; doc->getErrorLog()->logPackageError("comp", CompModelFlatteningFailed, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn()); } return LIBSBML_INVALID_OBJECT; } SBase* parent = lore->getParentSBMLObject(); if (parent==NULL) { if (doc) { string error = "Cannot carry out replacement in ReplacedElement::performReplacement: no parent could be found for the parent <listOfReplacedElements> object."; doc->getErrorLog()->logPackageError("comp", CompModelFlatteningFailed, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn()); } return LIBSBML_INVALID_OBJECT; } SBase* ref = getReferencedElement(); if (ref==NULL) { //getReferencedElement sets its own error messages. return LIBSBML_INVALID_OBJECT; } if (removed && removed->find(ref)!=removed->end()) { //Already deleted: can't get the deleted element's ID to if (doc) { string error = "Cannot carry out replacement in ReplacedElement::performReplacement: a <" + parent->getElementName() + ">"; if (parent->isSetId()) { error += " with the ID '" + parent->getId() + "'"; } error += " has a child <replacedElement> that points to something that has already been deleted, probably because its parent was deleted."; doc->getErrorLog()->logPackageError("comp", CompDeletedReplacement, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn()); } return LIBSBML_INVALID_OBJECT; } //Update the IDs. int ret = updateIDs(ref, parent); if (ret != LIBSBML_OPERATION_SUCCESS) { return ret; } //Perform any conversions on references in the submodel. ASTNode* blank = NULL; ret = performConversions(parent, &blank); if (ret != LIBSBML_OPERATION_SUCCESS) { if (blank != NULL) { delete blank; } return ret; } CompSBasePlugin* refplug = static_cast<CompSBasePlugin*>(ref->getPlugin(getPrefix())); if (refplug != NULL) { //Now recurse down the 'replace*' tree, renaming IDs and deleting things as we go. for (unsigned int re=0; re<refplug->getNumReplacedElements(); re++) { refplug->getReplacedElement(re)->replaceWithAndMaybeDelete(parent, true, blank); if (toremove) { toremove->insert(refplug->getReplacedElement(re)->getReferencedElement()); } } if (refplug->isSetReplacedBy()) { //Even if the subelement used to be replaced by something further down, it is now being replaced by the parent. It just can't catch a break, it seems. refplug->getReplacedBy()->replaceWithAndMaybeDelete(parent, true, blank); if (toremove) { toremove->insert(refplug->getReplacedBy()->getReferencedElement()); } } } if (toremove) { toremove->insert(ref); } if (blank != NULL) { delete blank; } return LIBSBML_OPERATION_SUCCESS; }