int Submodel::replaceElement(SBase* toReplace, SBase* replacement) { if (mInstantiatedModel == NULL) return LIBSBML_INVALID_OBJECT; //Must call 'instantiate' first (and probably rename your objects, too!). string oldSId = toReplace->getId(); string oldMetaId = toReplace->getMetaId(); List* allElements = mInstantiatedModel->getAllElements(); for (ListIterator iter = allElements->begin(); iter != allElements->end(); ++iter) { SBase* element = static_cast<SBase*>(*iter); assert(element != NULL); if (element == NULL) continue; if (toReplace->isSetId()) { if (replacement->getTypeCode() == SBML_UNIT_DEFINITION) { element->renameUnitSIdRefs(toReplace->getId(), replacement->getId()); } else { element->renameSIdRefs(toReplace->getId(), replacement->getId()); } } if (toReplace->isSetMetaId()) { element->renameMetaIdRefs(toReplace->getMetaId(), replacement->getMetaId()); } } delete allElements; return LIBSBML_OPERATION_FAILED; }
/** @cond doxygenLibsbmlInternal */ void CompModelPlugin::renameIDs(List* allElements, const string& prefix) { if (prefix=="") return; //Nothing to prepend. vector<pair<string, string> > renamedSIds; vector<pair<string, string> > renamedUnitSIds; vector<pair<string, string> > renamedMetaIds; //PrefixTransformer trans(prefix); for (unsigned long el=0; el < allElements->getSize(); ++el) { SBase* element = static_cast<SBase*>(allElements->get(el)); string id = element->getId(); string metaid = element->getMetaId(); //element->transformIdentifiers(&trans); element->prependStringToAllIdentifiers(prefix); if (element->getTypeCode() == SBML_LOCAL_PARAMETER) { element->setId(id); //Change it back. This would perhaps be better served by overriding 'prependStringToAllIdentifiers' but hey. } string newid = element->getId(); string newmetaid = element->getMetaId(); if (id != newid) { int type = element->getTypeCode(); if (type==SBML_UNIT_DEFINITION) { renamedUnitSIds.push_back(make_pair(id, newid)); } else if (type==SBML_COMP_PORT) { //Do nothing--these can only be referenced from outside the Model, so they need to be handled specially. // (In the default case, we throw them away). } else { //This is a little dangerous, but hey! What's a little danger between friends! //(What we are assuming is that any attribute you can get with 'getId' is of the type 'SId') renamedSIds.push_back(make_pair(id, newid)); } } if (metaid != newmetaid) { renamedMetaIds.push_back(make_pair(metaid, newmetaid)); } } for (unsigned long el=0; el<allElements->getSize(); el++) { SBase* element = static_cast<SBase*>(allElements->get(el)); for (size_t id=0; id<renamedSIds.size(); id++) { element->renameSIdRefs(renamedSIds[id].first, renamedSIds[id].second); } for (size_t uid=0; uid<renamedUnitSIds.size(); uid++) { element->renameUnitSIdRefs(renamedUnitSIds[uid].first, renamedUnitSIds[uid].second); } for (size_t mid=0; mid<renamedMetaIds.size(); mid++) { element->renameMetaIdRefs(renamedMetaIds[mid].first, renamedMetaIds[mid].second); } } }
/** @cond doxygenLibsbmlInternal */ int Replacing::updateIDs(SBase* oldnames, SBase* newnames) { int ret = LIBSBML_OPERATION_SUCCESS; SBMLDocument* doc = getSBMLDocument(); if (oldnames->isSetId() && !newnames->isSetId()) { if (doc) { string error = "Unable to transform IDs in Replacing::updateIDs during replacement: the '" + oldnames->getId() + "' element's replacement does not have an ID set."; doc->getErrorLog()->logPackageError("comp", CompMustReplaceIDs, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn()); } return LIBSBML_INVALID_OBJECT; } if (oldnames->isSetMetaId() && !newnames->isSetMetaId()) { if (doc) { string error = "Unable to transform IDs in Replacing::updateIDs during replacement: the replacement of the element with metaid '" + oldnames->getMetaId() + "' does not have a metaid."; doc->getErrorLog()->logPackageError("comp", CompMustReplaceMetaIDs, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn()); } return LIBSBML_INVALID_OBJECT; } //LS DEBUG Somehow we need to check identifiers from other packages here (like spatial id's). How, exactly, is anyone's guess. Model* replacedmod = const_cast<Model*>(CompBase::getParentModel(oldnames)); KineticLaw* replacedkl; ASTNode newkl; if (replacedmod==NULL) { if (doc) { string error = "Unable to transform IDs in Replacing::updateIDs during replacement: the replacement of '" + oldnames->getId() + "' does not have a valid model."; doc->getErrorLog()->logPackageError("comp", CompModelFlatteningFailed, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn()); } return LIBSBML_INVALID_OBJECT; } List* allElements = replacedmod->getAllElements(); string oldid = oldnames->getId(); string newid = newnames->getId(); if (!oldid.empty()) { switch(oldnames->getTypeCode()) { case SBML_UNIT_DEFINITION: replacedmod->renameUnitSIdRefs(oldid, newid); for (unsigned int e=0; e<allElements->getSize(); e++) { SBase* element = static_cast<SBase*>(allElements->get(e)); element->renameUnitSIdRefs(oldid, newid); } break; case SBML_LOCAL_PARAMETER: replacedkl = static_cast<KineticLaw*>(oldnames->getAncestorOfType(SBML_KINETIC_LAW)); if (replacedkl->isSetMath()) { newkl = *replacedkl->getMath(); newkl.renameSIdRefs(oldid, newid); replacedkl->setMath(&newkl); } break; case SBML_COMP_PORT: break; //LS DEBUG And here is where we would need some sort of way to check if the id wasn't an SId for some objects. default: replacedmod->renameSIdRefs(oldnames->getId(), newnames->getId()); for (unsigned int e=0; e<allElements->getSize(); e++) { SBase* element = static_cast<SBase*>(allElements->get(e)); element->renameSIdRefs(oldid, newid); } } } string oldmetaid = oldnames->getMetaId(); string newmetaid = newnames->getMetaId(); if (oldnames->isSetMetaId()) { replacedmod->renameMetaIdRefs(oldmetaid, newmetaid); for (unsigned int e=0; e<allElements->getSize(); e++) { SBase* element = static_cast<SBase*>(allElements->get(e)); element->renameMetaIdRefs(oldmetaid, newmetaid); } } //LS DEBUG And here is where we would need some sort of way to check for ids that were not 'id' or 'metaid'. delete allElements; return ret; }
void Model::dealWithModelUnits() { UnitRefsFilter filter; List * elements = getAllElements(&filter); unsigned int n = 0; unsigned int num = elements->getSize(); if (isSetVolumeUnits()) { std::string volume = getVolumeUnits(); // if in an L3 model a user used volume as an id of a UnitDefinition // but they declared the volume units of teh model to be something // else then the UD with id volume is nothing to do with the // L2 interpretation of volume // so replace that UD and all references to it if (volume != "volume") { UnitDefinition * existingUD = removeUnitDefinition("volume"); if (existingUD != NULL) { std::string newSubsName = "volumeFromOriginal"; existingUD->setId(newSubsName); SBase* obj; for (n = 0; n < num; n++) { obj = (SBase*)(elements->get(n)); obj->renameUnitSIdRefs("volume", newSubsName); } addUnitDefinition(existingUD); } } UnitDefinition * ud = getUnitDefinition(volume) != NULL ? getUnitDefinition(volume)->clone() : NULL; if (ud != NULL) { ud->setId("volume"); } else { Unit *u = new Unit(getSBMLNamespaces()); u->initDefaults(); u->setKind(UnitKind_forName(volume.c_str())); ud = new UnitDefinition(getSBMLNamespaces()); ud->setId("volume"); ud->addUnit(u); } addUnitDefinition(ud); } if (isSetAreaUnits()) { std::string area = getAreaUnits(); // if in an L3 model a user used area as an id of a UnitDefinition // but they declared the area units of teh model to be something // else then the UD with id area is nothing to do with the // L2 interpretation of area // so replace that UD and all references to it if (area != "area") { UnitDefinition * existingUD = removeUnitDefinition("area"); if (existingUD != NULL) { std::string newSubsName = "areaFromOriginal"; existingUD->setId(newSubsName); SBase* obj; for (n = 0; n < num; n++) { obj = (SBase*)(elements->get(n)); obj->renameUnitSIdRefs("area", newSubsName); } addUnitDefinition(existingUD); } } UnitDefinition * ud = getUnitDefinition(area) != NULL ? getUnitDefinition(area)->clone() : NULL; if (ud != NULL) { ud->setId("area"); } else { Unit *u = new Unit(getSBMLNamespaces()); u->initDefaults(); u->setKind(UnitKind_forName(area.c_str())); ud = new UnitDefinition(getSBMLNamespaces()); ud->setId("area"); ud->addUnit(u); } addUnitDefinition(ud); } if (isSetLengthUnits()) { std::string length = getLengthUnits(); // if in an L3 model a user used length as an id of a UnitDefinition // but they declared the length units of teh model to be something // else then the UD with id length is nothing to do with the // L2 interpretation of length // so replace that UD and all references to it if (length != "length") { UnitDefinition * existingUD = removeUnitDefinition("length"); if (existingUD != NULL) { std::string newSubsName = "lengthFromOriginal"; existingUD->setId(newSubsName); SBase* obj; for (n = 0; n < num; n++) { obj = (SBase*)(elements->get(n)); obj->renameUnitSIdRefs("length", newSubsName); } addUnitDefinition(existingUD); } } UnitDefinition * ud = getUnitDefinition(length) != NULL ? getUnitDefinition(length)->clone() : NULL; if (ud != NULL) { ud->setId("length"); } else { Unit *u = new Unit(getSBMLNamespaces()); u->initDefaults(); u->setKind(UnitKind_forName(length.c_str())); ud = new UnitDefinition(getSBMLNamespaces()); ud->setId("length"); ud->addUnit(u); } addUnitDefinition(ud); } if (isSetSubstanceUnits()) { std::string substance = getSubstanceUnits(); // if in an L3 model a user used substance as an id of a UnitDefinition // but they declared the substance units of teh model to be something // else then the UD with id substance is nothing to do with the // L2 interpretation of substance // so replace that UD and all references to it if (substance != "substance") { UnitDefinition * existingUD = removeUnitDefinition("substance"); if (existingUD != NULL) { std::string newSubsName = "substanceFromOriginal"; existingUD->setId(newSubsName); SBase* obj; for (n = 0; n < num; n++) { obj = (SBase*)(elements->get(n)); obj->renameUnitSIdRefs("substance", newSubsName); } addUnitDefinition(existingUD); } } UnitDefinition * ud = getUnitDefinition(substance) != NULL ? getUnitDefinition(substance)->clone() : NULL; if (ud != NULL) { ud->setId("substance"); } else { Unit *u = new Unit(getSBMLNamespaces()); u->initDefaults(); u->setKind(UnitKind_forName(substance.c_str())); ud = new UnitDefinition(getSBMLNamespaces()); ud->setId("substance"); ud->addUnit(u); } addUnitDefinition(ud); } if (isSetTimeUnits()) { std::string time = getTimeUnits(); // if in an L3 model a user used time as an id of a UnitDefinition // but they declared the time units of teh model to be something // else then the UD with id time is nothing to do with the // L2 interpretation of time // so replace that UD and all references to it if (time != "time") { UnitDefinition * existingUD = removeUnitDefinition("time"); if (existingUD != NULL) { std::string newSubsName = "timeFromOriginal"; existingUD->setId(newSubsName); SBase* obj; for (n = 0; n < num; n++) { obj = (SBase*)(elements->get(n)); obj->renameUnitSIdRefs("time", newSubsName); } addUnitDefinition(existingUD); } } UnitDefinition * ud = getUnitDefinition(time) != NULL ? getUnitDefinition(time)->clone() : NULL; if (ud != NULL) { ud->setId("time"); } else { ud = new UnitDefinition(getSBMLNamespaces()); ud->setId("time"); Unit *u = ud->createUnit(); u->initDefaults(); u->setKind(UnitKind_forName(time.c_str())); } addUnitDefinition(ud); } }