int CompModelPlugin::saveAllReferencedElements(set<SBase*> uniqueRefs, set<SBase*> replacedBys) { SBMLDocument* doc = getSBMLDocument(); Model* model = static_cast<Model*>(getParentSBMLObject()); if (model==NULL) { if (doc) { string error = "Unable to discover any referenced elements in CompModelPlugin::saveAllReferencedElements: no Model parent of the 'comp' model plugin."; doc->getErrorLog()->logPackageError("comp", CompModelFlatteningFailed, getPackageVersion(), getLevel(), getVersion(), error); } return LIBSBML_OPERATION_FAILED; } int ret = LIBSBML_OPERATION_SUCCESS; //Get a list of everything, pull out anything that's a deletion, replacement, or port, and save what they're pointing to. //At the same time, make sure that no two things point to the same thing. set<SBase*> RE_deletions = set<SBase*>(); //Deletions only point to things in the same model. List* allElements = model->getAllElements(); string modname = "the main model in the document"; if (model->isSetId()) { modname = "the model '" + model->getId() + "'"; } for (unsigned int el=0; el<allElements->getSize(); el++) { SBase* element = static_cast<SBase*>(allElements->get(el)); int type = element->getTypeCode(); if (type==SBML_COMP_DELETION || type==SBML_COMP_REPLACEDBY || type==SBML_COMP_REPLACEDELEMENT || type==SBML_COMP_PORT) { //Don't worry about SBML_COMP_SBASEREF because they're all children of one of the above types. SBaseRef* reference = static_cast<SBaseRef*>(element); ReplacedElement* re = static_cast<ReplacedElement*>(element); ret = reference->saveReferencedElement(); if (ret != LIBSBML_OPERATION_SUCCESS) { if (type != SBML_COMP_REPLACEDBY && doc) { SBMLErrorLog* errlog = doc->getErrorLog(); SBMLError* lasterr = const_cast<SBMLError*> (doc->getErrorLog()->getError(doc->getNumErrors()-1)); if ( (errlog->contains(UnrequiredPackagePresent) || errlog->contains(RequiredPackagePresent))) { if ( lasterr->getErrorId() == CompIdRefMustReferenceObject) { //Change the error into a warning string fullmsg = lasterr->getMessage() + " However, this may be because of the unrecognized " + "package present in this document: ignoring this " + "element and flattening anyway."; errlog->remove(lasterr->getErrorId()); errlog->logPackageError("comp", CompIdRefMayReferenceUnknownPackage, getPackageVersion(), getLevel(), getVersion(), fullmsg, element->getLine(), element->getColumn(), LIBSBML_SEV_WARNING); element->removeFromParentAndDelete(); continue; } else if ( lasterr->getErrorId() == CompMetaIdRefMustReferenceObject) { //Change the error into a warning string fullmsg = lasterr->getMessage() + " However, this may be because of the unrecognized " + "package present in this document: ignoring this " + "element and flattening anyway."; errlog->remove(lasterr->getErrorId()); errlog->logPackageError("comp", CompMetaIdRefMayReferenceUnknownPkg, getPackageVersion(), getLevel(), getVersion(), fullmsg, element->getLine(), element->getColumn(), LIBSBML_SEV_WARNING); element->removeFromParentAndDelete(); continue; } else if (lasterr->getErrorId() == CompIdRefMayReferenceUnknownPackage) { element->removeFromParentAndDelete(); continue; } else if (lasterr->getErrorId() == CompMetaIdRefMayReferenceUnknownPkg) { element->removeFromParentAndDelete(); continue; } } else { delete allElements; return ret; } } else { delete allElements; return ret; } } SBase* direct = reference->getDirectReference(); bool adddirect = true; if (type == SBML_COMP_REPLACEDBY) { SBase* rbParent = reference->getParentSBMLObject(); if (uniqueRefs.insert(rbParent).second == false) { if (doc) { string error = "Error discovered in CompModelPlugin::saveAllReferencedElements when checking " + modname + ": a <" + rbParent->getElementName() + "> "; if (direct->isSetId()) { error += "with the id '" + rbParent->getId() + "'"; if (rbParent->isSetMetaId()) { error += ", and the metaid '" + rbParent->getMetaId() + "'"; } } else if (rbParent->isSetMetaId()) { error += "with the metaId '" + rbParent->getMetaId() + "'"; } error += " has a <replacedBy> child and is also pointed to by a <port>, <deletion>, <replacedElement>, or one or more <replacedBy> objects."; doc->getErrorLog()->logPackageError("comp", CompNoMultipleReferences, getPackageVersion(), getLevel(), getVersion(), error); } delete allElements; return LIBSBML_OPERATION_FAILED; } adddirect = replacedBys.insert(direct).second; } if (type==SBML_COMP_REPLACEDELEMENT && re->isSetDeletion()) { adddirect = RE_deletions.insert(direct).second; } if (adddirect) { if (uniqueRefs.insert(direct).second == false) { if (doc) { string error = "Error discovered in CompModelPlugin::saveAllReferencedElements when checking " + modname + ": "; if (replacedBys.find(direct) != replacedBys.end()) { error += "one or more <replacedBy> elements, plus a <deletion>, <replacedElement>, or <port> element"; } else if (RE_deletions.find(direct) != RE_deletions.end()) { error += "one or more <replacedElement> elements using a 'deletion' attribute, plus a <deletion>, <replacedElement>, or <port> element"; } else { error += "multiple <deletion>, <replacedElement>, and/or <port> elements"; } error += " point directly to the <" + direct->getElementName() + "> "; if (direct->isSetId()) { error += "with the id '" + direct->getId() + "'"; if (direct->isSetMetaId()) { error += ", and the metaid '" + direct->getMetaId() + "'"; } error += "."; } else if (direct->isSetMetaId()) { error += "with the metaId '" + direct->getMetaId() + "'."; } doc->getErrorLog()->logPackageError("comp", CompNoMultipleReferences, getPackageVersion(), getLevel(), getVersion(), error); } delete allElements; return LIBSBML_OPERATION_FAILED; } } } } delete allElements; //Now call saveAllReferencedElements for all instantiated submodels. for (unsigned long sm=0; sm<getNumSubmodels(); sm++) { Model* sub = getSubmodel(sm)->getInstantiation(); if (sub==NULL) { return LIBSBML_OPERATION_FAILED; } CompModelPlugin* subplug = static_cast<CompModelPlugin*>(sub->getPlugin(getPrefix())); if (subplug==NULL) { return LIBSBML_OPERATION_FAILED; } ret = subplug->saveAllReferencedElements(uniqueRefs, replacedBys); if (ret != LIBSBML_OPERATION_SUCCESS) { return ret; } } return LIBSBML_OPERATION_SUCCESS; }
END_TEST START_TEST (test_RemoveFromParent_alreadyRemoved) { SBMLReader reader; SBMLDocument* d; std::string filename(TestDataDirectory); filename += "multiple-ids.xml"; d = reader.readSBML(filename); if (d == NULL) { fail("readSBML(\"multiple-ids.xml\") returned a NULL pointer."); } SBase* obj; //List of function definitions obj = d->getElementByMetaId("meta20"); fail_unless(obj != NULL); fail_unless(obj->removeFromParentAndDelete() == LIBSBML_OPERATION_SUCCESS); obj = d->getElementByMetaId("meta20"); fail_unless(obj == NULL); //Function definition obj = d->getElementByMetaId("meta21"); fail_unless(obj == NULL); //Unit Definition obj = d->getElementByMetaId("meta30"); fail_unless(obj != NULL); fail_unless(obj->removeFromParentAndDelete() == LIBSBML_OPERATION_SUCCESS); obj = d->getElementByMetaId("meta30"); fail_unless(obj == NULL); //Unit obj = d->getElementByMetaId("meta32"); fail_unless(obj == NULL); //List of units obj = d->getElementByMetaId("meta31"); fail_unless(obj == NULL); //List of compartments obj = d->getElementByMetaId("meta3"); fail_unless(obj != NULL); fail_unless(obj->removeFromParentAndDelete() == LIBSBML_OPERATION_SUCCESS); obj = d->getElementByMetaId("meta3"); fail_unless(obj == NULL); //Compartment obj = d->getElementByMetaId("meta4"); fail_unless(obj == NULL); //List of species obj = d->getElementByMetaId("meta5"); fail_unless(obj != NULL); fail_unless(obj->removeFromParentAndDelete() == LIBSBML_OPERATION_SUCCESS); obj = d->getElementByMetaId("meta5"); fail_unless(obj == NULL); //Species obj = d->getElementByMetaId("meta6"); fail_unless(obj == NULL); //Kinetic law obj = d->getElementByMetaId("meta11"); fail_unless(obj != NULL); fail_unless(obj->removeFromParentAndDelete() == LIBSBML_OPERATION_SUCCESS); obj = d->getElementByMetaId("meta11"); fail_unless(obj == NULL); //Local parameter obj = d->getElementByMetaId("meta28"); fail_unless(obj == NULL); //List of local parameters obj = d->getElementByMetaId("meta27"); fail_unless(obj == NULL); //List of modifiers obj = d->getElementByMetaId("meta34"); fail_unless(obj != NULL); fail_unless(obj->removeFromParentAndDelete() == LIBSBML_OPERATION_SUCCESS); obj = d->getElementByMetaId("meta34"); fail_unless(obj == NULL); //Modifier species reference obj = d->getElementByMetaId("meta35"); fail_unless(obj == NULL); //Reaction obj = d->getElementByMetaId("meta8"); fail_unless(obj != NULL); fail_unless(obj->removeFromParentAndDelete() == LIBSBML_OPERATION_SUCCESS); obj = d->getElementByMetaId("meta8"); fail_unless(obj == NULL); //Species reference obj = d->getElementByMetaId("meta10"); fail_unless(obj == NULL); //List of reactants obj = d->getElementByMetaId("meta9"); fail_unless(obj == NULL); //List of parameters obj = d->getElementByMetaId("meta33"); fail_unless(obj != NULL); fail_unless(obj->removeFromParentAndDelete() == LIBSBML_OPERATION_SUCCESS); obj = d->getElementByMetaId("meta33"); fail_unless(obj == NULL); //Parameter obj = d->getElementByMetaId("meta18"); fail_unless(obj == NULL); //List of event assignments obj = d->getElementByMetaId("meta15"); fail_unless(obj != NULL); fail_unless(obj->removeFromParentAndDelete() == LIBSBML_OPERATION_SUCCESS); obj = d->getElementByMetaId("meta15"); fail_unless(obj == NULL); //Event assignment obj = d->getElementByMetaId("meta16"); fail_unless(obj == NULL); //Event obj = d->getElementByMetaId("meta13"); fail_unless(obj != NULL); fail_unless(obj->removeFromParentAndDelete() == LIBSBML_OPERATION_SUCCESS); obj = d->getElementByMetaId("meta13"); fail_unless(obj == NULL); //Trigger obj = d->getElementByMetaId("meta14"); fail_unless(obj == NULL); //Delay obj = d->getElementByMetaId("meta17"); fail_unless(obj == NULL); //Priority obj = d->getElementByMetaId("meta19"); fail_unless(obj == NULL); //List of initial assignments obj = d->getElementByMetaId("meta22"); fail_unless(obj != NULL); fail_unless(obj->removeFromParentAndDelete() == LIBSBML_OPERATION_SUCCESS); obj = d->getElementByMetaId("meta22"); fail_unless(obj == NULL); //Initial assignment obj = d->getElementByMetaId("meta23"); fail_unless(obj == NULL); //List of rules obj = d->getElementByMetaId("meta24"); fail_unless(obj != NULL); fail_unless(obj->removeFromParentAndDelete() == LIBSBML_OPERATION_SUCCESS); obj = d->getElementByMetaId("meta24"); fail_unless(obj == NULL); //Rate rule obj = d->getElementByMetaId("meta25"); fail_unless(obj == NULL); //Assignment rule obj = d->getElementByMetaId("meta26"); fail_unless(obj == NULL); delete d; }