/** @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); } } }
int ReplacedBy::performReplacementAndCollect(set<SBase*>* removed, set<SBase*>* toremove) { SBMLDocument* doc = getSBMLDocument(); //Find the various objects and plugin objects we need for this to work. SBase* parent = getParentSBMLObject(); if (parent==NULL) { if (doc) { string error = "Unable to perform replacement in ReplacedBy::performReplacement: no parent object for this <replacedBy> could be found."; 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; } //Update the IDs. (Will set its own error messages.) int ret = updateIDs(ref, parent); //ReplacedBy elements do get the name of the top-level element, assuming it has one: if (parent->isSetId()) { ref->setId(parent->getId()); } if (parent->isSetMetaId()) { ref->setMetaId(parent->getMetaId()); } if (ret != LIBSBML_OPERATION_SUCCESS) return ret; //And finally, get ready to delete the parent object. if (toremove) { toremove->insert(parent); } return LIBSBML_OPERATION_SUCCESS; }
int SBMLIdConverter::convert() { if (mDocument == NULL) return LIBSBML_INVALID_OBJECT; Model* mModel = mDocument->getModel(); if (mModel == NULL) return LIBSBML_INVALID_OBJECT; // nothing to do if (!mProps->hasOption("currentIds") || !mProps->hasOption("newIds")) return LIBSBML_OPERATION_SUCCESS; bool success = true; IdList currentIds(mProps->getOption("currentIds")->getValue()); IdList newIds(mProps->getOption("newIds")->getValue()); // if the size does not match something is wrong. if (newIds.size() != currentIds.size()) return LIBSBML_UNEXPECTED_ATTRIBUTE; List* allElements = mDocument->getAllElements(); std::map<std::string, std::string> renamed; // rename ids for (unsigned int i = 0; i < allElements->getSize(); ++i) { SBase* current = static_cast<SBase*>(allElements->get(i)); if (current == NULL || !current->isSetId() || current->getTypeCode() == SBML_LOCAL_PARAMETER) continue; for (unsigned int j = 0; j < currentIds.size(); ++j) { if (current->getId() != currentIds.at((int)j)) continue; // return error code in case new id is invalid if (!SyntaxChecker::isValidSBMLSId(newIds.at((int)j))) { delete allElements; return LIBSBML_INVALID_ATTRIBUTE_VALUE; } current->setId(newIds.at((int)j)); renamed[currentIds.at((int)j)] = newIds.at((int)j); break; } } // update all references that we changed std::map<std::string, std::string>::const_iterator it; for (unsigned int i = 0; i < allElements->getSize(); ++i) { SBase* current = static_cast<SBase*>(allElements->get(i)); for (it = renamed.begin(); it != renamed.end(); ++it) { current->renameSIdRefs(it->first, it->second); } } delete allElements; if (success) return LIBSBML_OPERATION_SUCCESS; return LIBSBML_OPERATION_FAILED; }
LIBSBML_CPP_NAMESPACE_USE BEGIN_C_DECLS int main (int argc, char* argv[]) { if (argc != 5) { cout << endl << "Usage: renameSId filename oldSId newSId output" << endl << endl; return 1; } const char* filename = argv[1]; const char* oldSId = argv[2]; const char* newSId = argv[3]; const char* output = argv[4]; if (strcmp(oldSId, newSId) == 0) { cout << "The Ids are identical, renaming stopped." << endl; return 1; } if (!SyntaxChecker::isValidInternalSId(newSId)) { cout << "The new SId '" << newSId << "' does not represent a valid SId." << endl; return 1; } SBMLDocument* document; SBMLReader reader; #ifdef __BORLANDC__ unsigned long start, stop; #else unsigned long long start, stop; #endif start = getCurrentMillis(); document = reader.readSBML(filename); stop = getCurrentMillis(); unsigned int errors = document->getNumErrors(LIBSBML_SEV_ERROR); cout << endl; cout << " filename: " << filename << endl; cout << " file size: " << getFileSize(filename) << endl; cout << " read time (ms): " << stop - start << endl; cout << " error(s): " << errors << endl; cout << endl; if (errors > 0) { document->printErrors(cerr); delete document; return errors; } // find elements for old id SBase* element = document->getElementBySId(oldSId); if (element == NULL) { cout << "Found no element with SId '" << oldSId << "'." << endl; return 1; } // found element --> renaming element->setId(newSId); // update all references to this element List *allElements = document->getAllElements(); for (unsigned int i = 0; i < allElements->getSize(); ++i) static_cast<SBase*>(allElements->get(i))->renameSIdRefs(oldSId, newSId); // write to file writeSBMLToFile(document, output); delete document; return errors; }