void PackageIdReplacementCheck::checkReferencedElement(ReplacedElement& repE) { // if the deletion attribute is set then it does not point // to another package element if (repE.isSetDeletion() == true) { return; } unsigned int numErrsB4 = repE.getSBMLDocument()->getNumErrors(); SBase* refElem = repE.getReferencedElement(); // if there is an issue with references the getReferencedElement // will log errors and possibly fail // we dont want to try any further unsigned int numErrsAfter = repE.getSBMLDocument()->getNumErrors(); if (numErrsB4 != numErrsAfter || refElem == NULL) { return; } SBase * parent = repE.getParentSBMLObject()->getParentSBMLObject(); if (refElem->isSetId() == true && parent->isSetId() == false) { logMissingIdAttribute(repE, refElem, parent); } }
void PackageIdReplacementCheck::checkReferencedElement(ReplacedBy& repBy) { unsigned int numErrsB4 = repBy.getSBMLDocument()->getNumErrors(); SBase* refElem = repBy.getReferencedElement(); // if there is an issue with references the getReferencedElement // will log errors and possibly fail // we dont want to try any further unsigned int numErrsAfter = repBy.getSBMLDocument()->getNumErrors(); if (numErrsB4 != numErrsAfter || refElem == NULL) { return; } SBase * parent = repBy.getParentSBMLObject(); if (parent->isSetId() == true && refElem->isSetId() == false) { logMissingIdAttribute(repBy, refElem, parent); } }
/* * @return the error message to use when logging constraint violations. * This method is called by logFailure. * * Returns a message that the given @p id and its corresponding object are * in conflict with an object previously defined. */ const string NumericArgsMathCheck::getMessage (const ASTNode& node, const SBase& object) { ostringstream msg; //msg << getPreamble(); char * formula = SBML_formulaToString(&node); msg << "The formula '" << formula; msg << "' in the " << getFieldname() << " element of the <" << object.getElementName(); msg << "> "; switch(object.getTypeCode()) { case SBML_INITIAL_ASSIGNMENT: case SBML_EVENT_ASSIGNMENT: case SBML_ASSIGNMENT_RULE: case SBML_RATE_RULE: //LS DEBUG: could use other attribute values, or 'isSetActualId'. break; default: if (object.isSetId()) { msg << "with id '" << object.getId() << "' "; } break; } msg << "uses an argument to a operator that expects a numeric value."; safe_free(formula); return msg.str(); }
/* * Logs a message about the conditional part of a piecewise function * that should have dimensionless units */ void ArgumentsUnitsCheck::logInconsistentPiecewiseCondition (const ASTNode & node, const SBase & sb) { char * formula = SBML_formulaToString(&node); msg = "The formula '"; msg += formula; msg += "' in the math element of the <"; msg += sb.getElementName(); msg += "> "; switch(sb.getTypeCode()) { case SBML_INITIAL_ASSIGNMENT: case SBML_EVENT_ASSIGNMENT: case SBML_ASSIGNMENT_RULE: case SBML_RATE_RULE: //LS DEBUG: could use other attribute values, or 'isSetActualId'. break; default: if (sb.isSetId()) { msg += "with id '"; msg += sb.getId() + "' "; } break; } msg += "uses a piecewise function"; msg += " where the conditional statement is not dimensionless."; safe_free(formula); logFailure(sb, msg); }
/* * @return the error message to use when logging constraint violations. * This method is called by logFailure. * * Returns a message that the given @p id and its corresponding object are * in conflict with an object previously defined. */ const string PieceBooleanMathCheck::getMessage (const ASTNode& node, const SBase& object) { ostringstream oss_msg; //oss_msg << getPreamble(); char * formula = SBML_formulaToString(&node); oss_msg << "The formula '" << formula; oss_msg << "' in the " << getFieldname() << " element of the <" << object.getElementName(); oss_msg << "> "; switch(object.getTypeCode()) { case SBML_INITIAL_ASSIGNMENT: case SBML_EVENT_ASSIGNMENT: case SBML_ASSIGNMENT_RULE: case SBML_RATE_RULE: //LS DEBUG: could use other attribute values, or 'isSetActualId'. break; default: if (object.isSetId()) { oss_msg << "with id '" << object.getId() << "' "; } break; } oss_msg << "uses a piecewise function that does not return a Boolean."; safe_free(formula); return oss_msg.str(); }
/* * @return the error message to use when logging constraint violations. * This method is called by logFailure. * * Returns a message that the given @p id and its corresponding object are * in conflict with an object previously defined. */ const string FunctionApplyMathCheck::getMessage (const ASTNode& node, const SBase& object) { ostringstream msg; //msg << getPreamble(); char * formula = SBML_formulaToString(&node); msg << "The formula '" << formula; msg << "' in the " << getFieldname() << " element of the <" << object.getElementName(); msg << "> "; switch(object.getTypeCode()) { case SBML_INITIAL_ASSIGNMENT: case SBML_EVENT_ASSIGNMENT: case SBML_ASSIGNMENT_RULE: case SBML_RATE_RULE: //LS DEBUG: could use other attribute values, or 'isSetActualId'. break; default: if (object.isSetId()) { msg << "with id '" << object.getId() << "' "; } break; } msg << "uses '" << node.getName() << "' which is not a function definition id."; safe_free(formula); return msg.str(); }
/* * Subclasses should override this method to read values from the given * XMLAttributes set into their specific fields. Be sure to call your * parents implementation of this method as well. */ void SpeciesReference::readL3Attributes (const XMLAttributes& attributes) { const unsigned int level = 3; const unsigned int version = getVersion(); // // stoichiometry: double { use="optional" default="1" } (L2v1->) // mIsSetStoichiometry = attributes.readInto("stoichiometry", mStoichiometry, getErrorLog(), false, getLine(), getColumn()); string elplusid = "<" + getElementName() + ">"; if (!mId.empty()) { elplusid += " with the id '" + mId + "'"; } SBase* rxn = getAncestorOfType(SBML_REACTION); if (rxn && rxn->isSetId()) { elplusid += " from the <reaction> with the id '" + rxn->getId() + "'"; } // // constant: bool { use="required" } (L3v1 -> ) // mIsSetConstant = attributes.readInto("constant", mConstant, getErrorLog(), false, getLine(), getColumn()); if (!mIsSetConstant && !isModifier()) { logError(AllowedAttributesOnSpeciesReference, level, version, "The required attribute 'constant' is missing from the " + elplusid + "."); } }
/* * @return the error message to use when logging constraint violations. * This method is called by logFailure. * * Returns a message that the given @p id and its corresponding object are * in conflict with an object previously defined. */ const string CiElementMathCheck::getMessage (const ASTNode& node, const SBase& object) { ostringstream msg; //msg << getPreamble(); char * formula = SBML_formulaToString(&node); msg << "The formula '" << formula; msg << "' in the " << getFieldname() << " element of the <" << object.getElementName(); msg << "> "; switch(object.getTypeCode()) { case SBML_INITIAL_ASSIGNMENT: case SBML_EVENT_ASSIGNMENT: case SBML_ASSIGNMENT_RULE: case SBML_RATE_RULE: //LS DEBUG: could use other attribute values, or 'isSetActualId'. break; default: if (object.isSetId()) { msg << "with id '" << object.getId() << "' "; } break; } if (object.getLevel() == 2 && object.getVersion() == 1) msg << "uses '" << node.getName() << "' that is not the id of a species/compartment/parameter."; else if (object.getLevel() < 3) msg << "uses '" << node.getName() << "' that is not the id of a species/compartment/parameter/reaction."; else msg << "uses '" << node.getName() << "' that is not the id of a species/compartment/parameter/reaction/speciesReference."; safe_free(formula); return msg.str(); }
/* * Logs a message about a function that should return same units * as the arguments */ void ArgumentsUnitsCheck::logInconsistentSameUnits (const ASTNode & node, const SBase & sb) { char * formula = SBML_formulaToString(&node); msg = "The formula '" ; msg += formula; msg += "' in the math element of the <"; msg += sb.getElementName(); msg += "> "; switch(sb.getTypeCode()) { case SBML_INITIAL_ASSIGNMENT: case SBML_EVENT_ASSIGNMENT: case SBML_ASSIGNMENT_RULE: case SBML_RATE_RULE: //LS DEBUG: could use other attribute values, or 'isSetActualId'. break; default: if (sb.isSetId()) { msg += "with id '"; msg += sb.getId() + "' "; } break; } msg += "can only act on variables with the same units."; safe_free(formula); logFailure(sb, msg); }
/* * @return the error message to use when logging constraint violations. * This method is called by logFailure. * * Returns a message that the given @p id and its corresponding object are * in conflict with an object previously defined. */ const string ArgumentsUnitsCheck::getMessage (const ASTNode& node, const SBase& object) { ostringstream msg; //msg << getPreamble(); char * formula = SBML_formulaToString(&node); msg << "The formula '" << formula; msg << "' in the " << getFieldname() << " element of the <" << object.getElementName(); msg << "> "; switch(object.getTypeCode()) { case SBML_INITIAL_ASSIGNMENT: case SBML_EVENT_ASSIGNMENT: case SBML_ASSIGNMENT_RULE: case SBML_RATE_RULE: //LS DEBUG: could use other attribute values, or 'isSetActualId'. break; default: if (object.isSetId()) { msg << "with id '" << object.getId() << "' "; } break; } msg << "produces an exponent that is not an integer and thus may produce "; msg << "invalid units."; safe_free(formula); return msg.str(); }
/** @cond doxygenLibsbmlInternal */ void CompModelPlugin::findUniqueSubmodPrefixes(vector<string>& submodids, List* allElements) { vector<int> suffixes(submodids.size(), 0); bool done=false; while (!done) { done = true; for (size_t str=0; str<submodids.size(); str++) { stringstream fullprefix; fullprefix << submodids[str]; if (suffixes[str] > 0) { fullprefix << suffixes[str]; } fullprefix << getDivider(); for (unsigned long el=0; el<allElements->getSize(); ++el) { SBase* element = static_cast<SBase*>(allElements->get((unsigned int)el)); if (element==NULL) { assert(false); continue; } if (element->isSetId() && element->getId().find(fullprefix.str())==0) { done = false; continue; } else if (element->isSetMetaId() && element->getMetaId().find(fullprefix.str())==0) { done = false; continue; } else if (element->hasNonstandardIdentifierBeginningWith(fullprefix.str())) { done = false; continue; } else { for (unsigned int p=0; p<element->getNumPlugins(); p++) { if (element->getPlugin(p)->hasIdentifierBeginningWith(fullprefix.str())) { done = false; continue; } } } } if (!done) { suffixes[str]++; continue; //Start over from the first ID; otherwise we end up checking a lot of things twice. } } } //Now change the submodid's: for (size_t str=0; str<submodids.size(); str++) { stringstream fullprefix; fullprefix << submodids[str]; if (suffixes[str] > 0) { fullprefix << suffixes[str]; } fullprefix << getDivider(); submodids[str] = fullprefix.str(); } }
void GroupsUniqueModelWideIds::logId (const SBase& object) { if (object.isSetId()) { const string& id = object.getId(); mIdMap.insert( make_pair(id, &object) ); } }
/* * Checks that the id associated with the given object is unique. If it * is not, logIdConflict is called. */ void GroupsUniqueModelWideIds::doCheckId (const SBase& object) { if (object.isSetId()) { const string& id = object.getId(); if (mIdMap.insert( make_pair(id, &object) ).second == false) { logIdConflict(id, object); } } }
SBase* ListOf::getElementBySId(const std::string& id) { if (id.empty()) return NULL; for (unsigned int i = 0; i < size(); i++) { SBase* obj = get(i); if (obj->isSetId() && obj->getId() == id) { return obj; } obj = obj->getElementBySId(id); if (obj != NULL) return obj; } return getElementFromPluginsBySId(id); }
/** @cond doxygenLibsbmlInternal */ void CompModelPlugin::resetPorts() { for (unsigned int p=0; p<getNumPorts(); p++) { Port* port = getPort(p); SBase* referenced = port->getReferencedElement(); if (port->isSetSBaseRef()) { port->unsetSBaseRef(); port->unsetIdRef(); port->unsetMetaIdRef(); port->unsetUnitRef(); int type = referenced->getTypeCode(); if (referenced->isSetId() && type != SBML_INITIAL_ASSIGNMENT && type != SBML_ASSIGNMENT_RULE && type != SBML_RATE_RULE && type != SBML_EVENT_ASSIGNMENT) { if (type==SBML_UNIT_DEFINITION) { port->setUnitRef(referenced->getId()); } else { port->setIdRef(referenced->getId()); } } else if (referenced->isSetMetaId()) { port->setMetaIdRef(referenced->getMetaId()); } else { stringstream newname; newname << "auto_port_" << p; referenced->setMetaId(newname.str()); port->setMetaIdRef(newname.str()); } } port->clearReferencedElement(); } }
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; }
SBase* SBaseRef::getReferencedElementFrom(Model* model) { SBMLDocument* doc = getSBMLDocument(); if (!hasRequiredAttributes()) { if (doc) { string error = "In SBaseRef::getReferencedElementFrom, unable to find referenced element from <" + getElementName() + "> "; if (isSetId()) { error += "with ID '" + getId() + "' "; } error += "as it does not have the required attributes."; int en = CompSBaseRefMustReferenceObject; switch(getTypeCode()) { case SBML_COMP_REPLACEDBY: en = CompReplacedByAllowedAttributes; break; case SBML_COMP_REPLACEDELEMENT: en = CompReplacedElementAllowedAttributes; break; case SBML_COMP_PORT: en = CompPortAllowedAttributes; break; case SBML_COMP_DELETION: en = CompDeletionAllowedAttributes; } doc->getErrorLog()->logPackageError("comp", en, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn()); } return NULL; } SBase* referent = NULL; if (isSetPortRef()) { CompModelPlugin* mplugin = static_cast<CompModelPlugin*>(model->getPlugin(getPrefix())); Port* port = mplugin->getPort(getPortRef()); if (port==NULL) { if (doc) { string error = "In SBaseRef::getReferencedElementFrom, unable to find referenced element from SBase reference "; if (isSetId()) { error += "'" + getId() + "' "; } error += "as the port it references ('" + getPortRef() +"') could not be found."; doc->getErrorLog()->logPackageError("comp", CompPortRefMustReferencePort, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn()); } return NULL; } mDirectReference = port; referent = port->getReferencedElementFrom(model); } else if (isSetIdRef()) { referent = model->getElementBySId(getIdRef()); if (referent == NULL && doc) { string error = "In SBaseRef::getReferencedElementFrom, unable to find referenced element: no such SId in the model: '" + getIdRef() + "'."; if (doc->getErrorLog()->contains(UnrequiredPackagePresent) || doc->getErrorLog()->contains(RequiredPackagePresent)) { doc->getErrorLog()->logPackageError("comp", CompIdRefMayReferenceUnknownPackage, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn()); } else { doc->getErrorLog()->logPackageError("comp", CompIdRefMustReferenceObject, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn()); } } } else if (isSetUnitRef()) { referent = model->getUnitDefinition(getUnitRef()); if (referent == NULL && doc) { string error = "In SBaseRef::getReferencedElementFrom, unable to find referenced element: no such Unit in the model: '" + getUnitRef() + "'."; doc->getErrorLog()->logPackageError("comp", CompUnitRefMustReferenceUnitDef, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn()); } } else if (isSetMetaIdRef()) { referent = model->getElementByMetaId(getMetaIdRef()); if (referent == NULL && doc) { string error = "In SBaseRef::getReferencedElementFrom, unable to find referenced element: no such metaid in the model: '" + getMetaIdRef() + "'."; if (doc->getErrorLog()->contains(UnrequiredPackagePresent) || doc->getErrorLog()->contains(RequiredPackagePresent)) { doc->getErrorLog()->logPackageError("comp", CompIdRefMayReferenceUnknownPackage, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn()); } else { doc->getErrorLog()->logPackageError("comp", CompMetaIdRefMustReferenceObject, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn()); } } } else { //This is actually possible if the subclass overrides getNumReferents() (which some do). In that case, we just return NULL and let the overriding function find the referent instead. return NULL; } if (referent == NULL) { //No need to set an error message--one was already set above. return NULL; } if (isSetSBaseRef()) { //We're drilling into the submodels here, so our referent must be a submodel. if (referent->getTypeCode() != SBML_COMP_SUBMODEL) { if (doc) { string error = "In SBaseRef::getReferencedElementFrom, unable to find referenced element: the element "; if (referent->isSetId()) { error += "'" + referent->getId() + "'"; } else if (referent->isSetMetaId()) { error += "with the metaid '" + referent->getMetaId() + "'"; } error += " is not a submodel, and therefore has no subobjects for the child <sBaseRef> to refer to."; doc->getErrorLog()->logPackageError("comp", CompParentOfSBRefChildMustBeSubmodel, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn()); } return NULL; } Submodel* subm = static_cast<Submodel*>(referent); if (subm==NULL) { //Note: should be impossible. if (doc) { string error = "In SBaseRef::getReferencedElementFrom, unable to find referenced element: the element "; if (referent->isSetId()) { error += "'" + referent->getId() + "' "; } else if (referent->isSetMetaId()) { error += "with the metaid '" + referent->getMetaId() + "' "; } error += "claims to be a Submodel, but could not be programmatically turned into one."; doc->getErrorLog()->logPackageError("comp", CompParentOfSBRefChildMustBeSubmodel, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn()); } return NULL; } Model* inst = subm->getInstantiation(); if (inst==NULL) { //No need to set an additional error, as 'getInstantiation' will set one itself. return NULL; } //Recursive, so will set its own error messages: referent = getSBaseRef()->getReferencedElementFrom(inst); mDirectReference = getSBaseRef()->getDirectReference(); } return referent; }
//static void SBMLUtils::collectIds(Model* pModel, std::map<std::string, const SBase*>& ids, std::map<std::string, const SBase*>& metaIds) { if (pModel != NULL) { // the model itself SBase* pSBase = NULL; std::string id; if (pModel->isSetId()) { id = pModel->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pModel->isSetMetaId()) { id = pModel->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } // ListOfFunctionDefinitions pSBase = pModel->getListOfFunctionDefinitions(); if (pSBase != NULL) { if (pSBase->isSetId()) { id = pSBase->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } // all FunctionDefinitions unsigned int i, iMax = pModel->getListOfFunctionDefinitions()->size(); for (i = 0; i < iMax; ++i) { pSBase = pModel->getListOfFunctionDefinitions()->get(i); if (pSBase->isSetId()) { id = pSBase->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } } } // ListOfUnitDefinition pSBase = pModel->getListOfUnitDefinitions(); if (pSBase != NULL) { if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } // all UnitDefinitions // for each UnitDefinition: ListOfUnits, each Unit in ListOfUnits unsigned int i, iMax = pModel->getListOfUnitDefinitions()->size(); for (i = 0; i < iMax; ++i) { /* UnitDefinitions have their ids in a different namespace so we only consider meta ids. */ UnitDefinition* pUDef = pModel->getUnitDefinition(i); assert(pUDef != NULL); if (pUDef->isSetMetaId()) { id = pUDef->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pUDef)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } ListOf* pList = pUDef->getListOfUnits(); if (pList != NULL) { if (pList->isSetMetaId()) { id = pList->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pList)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } unsigned j, jMax = pList->size(); for (j = 0; j < jMax; ++j) { pSBase = pList->get(j); assert(pSBase != NULL); if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } } } } } // ListOfCompartmentTypes pSBase = pModel->getListOfCompartmentTypes(); if (pSBase != NULL) { if (pSBase->isSetId()) { id = pSBase->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } // each compartment type unsigned int i, iMax = pModel->getListOfCompartmentTypes()->size(); for (i = 0; i < iMax; ++i) { pSBase = pModel->getCompartmentType(i); assert(pSBase != NULL); if (pSBase->isSetId()) { id = pSBase->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } } } // ListOfSpeciesTypes pSBase = pModel->getListOfSpeciesTypes(); if (pSBase != NULL) { if (pSBase->isSetId()) { id = pSBase->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } // each species type unsigned int i, iMax = pModel->getListOfSpeciesTypes()->size(); for (i = 0; i < iMax; ++i) { pSBase = pModel->getSpeciesType(i); assert(pSBase != NULL); if (pSBase->isSetId()) { id = pSBase->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } } } // ListOfCompartments pSBase = pModel->getListOfCompartments(); if (pSBase != NULL) { if (pSBase->isSetId()) { id = pSBase->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } // all compartments unsigned int i, iMax = pModel->getListOfCompartments()->size(); for (i = 0; i < iMax; ++i) { pSBase = pModel->getCompartment(i); assert(pSBase != NULL); if (pSBase->isSetId()) { id = pSBase->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } } } // ListOfSpecies pSBase = pModel->getListOfSpecies(); if (pSBase != NULL) { if (pSBase->isSetId()) { id = pSBase->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } // all species unsigned int i, iMax = pModel->getListOfSpecies()->size(); for (i = 0; i < iMax; ++i) { pSBase = pModel->getSpecies(i); assert(pSBase != NULL); if (pSBase->isSetId()) { id = pSBase->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } } } // ListOfParameters pSBase = pModel->getListOfParameters(); if (pSBase != NULL) { if (pSBase->isSetId()) { id = pSBase->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } // each parameter unsigned int i, iMax = pModel->getListOfParameters()->size(); for (i = 0; i < iMax; ++i) { pSBase = pModel->getParameter(i); assert(pSBase != NULL); if (pSBase->isSetId()) { id = pSBase->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } } } // ListOfInitialAssignments pSBase = pModel->getListOfInitialAssignments(); if (pSBase != NULL) { if (pSBase->isSetId()) { id = pSBase->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } // each initial assignment unsigned int i, iMax = pModel->getListOfInitialAssignments()->size(); for (i = 0; i < iMax; ++i) { pSBase = pModel->getInitialAssignment(i); assert(pSBase != NULL); // initial assignments have no ids if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } } } // ListOfRules pSBase = pModel->getListOfRules(); if (pSBase != NULL) { if (pSBase->isSetId()) { id = pSBase->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } // each rule unsigned int i, iMax = pModel->getListOfRules()->size(); for (i = 0; i < iMax; ++i) { pSBase = pModel->getRule(i); assert(pSBase != NULL); // rules don't have ids if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } } } // ListOfConstraints pSBase = pModel->getListOfConstraints(); if (pSBase != NULL) { if (pSBase->isSetId()) { id = pSBase->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } // each constraint unsigned int i, iMax = pModel->getListOfConstraints()->size(); for (i = 0; i < iMax; ++i) { pSBase = pModel->getConstraint(i); assert(pSBase != NULL); // constraints don't have ids if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } } } // ListOfReactions pSBase = pModel->getListOfReactions(); if (pSBase != NULL) { if (pSBase->isSetId()) { id = pSBase->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } // all reactions unsigned int i, iMax = pModel->getListOfReactions()->size(); for (i = 0; i < iMax; ++i) { Reaction* pReaction = pModel->getReaction(i); assert(pReaction != NULL); if (pReaction->isSetId()) { id = pReaction->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pReaction)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pReaction->isSetMetaId()) { id = pReaction->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pReaction)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } // for each reaction: ListOfSubstrates, each substrate, ListOfProducts, each // Product, ListOfModifieres, each modifier, KineticLaw, ListOfparameters, // each parameter if (pReaction->getListOfReactants() != NULL) { pSBase = pReaction->getListOfReactants(); if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } unsigned int j, jMax = pReaction->getListOfReactants()->size(); for (j = 0; j < jMax; ++j) { pSBase = pReaction->getReactant(j); assert(pSBase != NULL); // since L2V2 species references can have ids if (pSBase->isSetId()) { id = pSBase->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } } } if (pReaction->getListOfProducts() != NULL) { pSBase = pReaction->getListOfProducts(); if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } unsigned int j, jMax = pReaction->getListOfProducts()->size(); for (j = 0; j < jMax; ++j) { pSBase = pReaction->getProduct(j); assert(pSBase != NULL); // since L2V2 species references can have ids if (pSBase->isSetId()) { id = pSBase->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } } } if (pReaction->getListOfModifiers() != NULL) { pSBase = pReaction->getListOfModifiers(); if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } unsigned int j, jMax = pReaction->getListOfModifiers()->size(); for (j = 0; j < jMax; ++j) { pSBase = pReaction->getModifier(j); assert(pSBase != NULL); // since L2V2 species references can have ids if (pSBase->isSetId()) { id = pSBase->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } } } KineticLaw* pKLaw = pReaction->getKineticLaw(); if (pKLaw != NULL) { if (pKLaw->isSetMetaId()) { id = pKLaw->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pKLaw)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } pSBase = pKLaw->getListOfParameters(); if (pSBase != NULL) { if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } unsigned int j, jMax = pKLaw->getListOfParameters()->size(); for (j = 0; j < jMax; ++j) { pSBase = pKLaw->getParameter(j); assert(pSBase != NULL); // local parameters have their ids in a // different namespace if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } } } } } } // ListOfEvents pSBase = pModel->getListOfEvents(); if (pSBase != NULL) { if (pSBase->isSetId()) { id = pSBase->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } // each event unsigned int i, iMax = pModel->getListOfEvents()->size(); for (i = 0; i < iMax; ++i) { Event* pEvent = pModel->getEvent(i); assert(pEvent != NULL); if (pEvent->isSetId()) { id = pEvent->getId(); if (ids.find(id) == ids.end()) { ids.insert(std::pair<const std::string, const SBase*>(id, pEvent)); } else { CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str()); } } if (pEvent->isSetMetaId()) { id = pEvent->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pEvent)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } // in each event Trigger,Delay,ListOfEventAssignments, each event assignment if (pEvent->isSetTrigger()) { pSBase = pEvent->getTrigger(); assert(pSBase != NULL); if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } } if (pEvent->isSetDelay()) { pSBase = pEvent->getDelay(); assert(pSBase != NULL); if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } } if (pEvent->getListOfEventAssignments() != NULL) { pSBase = pEvent->getListOfEventAssignments(); if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } unsigned int j, jMax = pEvent->getListOfEventAssignments()->size(); for (j = 0; j < jMax; ++j) { pSBase = pEvent->getEventAssignment(j); assert(pSBase != NULL); if (pSBase->isSetMetaId()) { id = pSBase->getMetaId(); if (metaIds.find(id) == metaIds.end()) { metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase)); } else { CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str()); } } } } } } } }
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() + "'"; } set<SBase*> todelete; 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); } 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); } } //Whether or not we could figure out the error, we can always still continue flattening. todelete.insert(element); continue; } 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; } } } } for(set<SBase*>::iterator el=todelete.begin(); el != todelete.end(); el++) { (*el)->removeFromParentAndDelete(); } delete allElements; //Now call saveAllReferencedElements for all instantiated submodels. for (unsigned long sm=0; sm<getNumSubmodels(); ++sm) { Model* sub = getSubmodel((unsigned int)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; }
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; }
int Submodel::convertTimeAndExtentWith(const ASTNode* tcf, const ASTNode* xcf, const ASTNode* klmod) { if (tcf==NULL && xcf==NULL) return LIBSBML_OPERATION_SUCCESS; Model* model = getInstantiation(); if (model==NULL) { //getInstantiation sets its own error messages. return LIBSBML_OPERATION_FAILED; } ASTNode tcftimes(AST_TIMES); ASTNode tcfdiv(AST_DIVIDE); if (tcf != NULL) { tcftimes.addChild(tcf->deepCopy()); tcfdiv.addChild(tcf->deepCopy()); } ASTNode rxndivide(AST_DIVIDE); if (klmod != NULL) { ASTNode rxnref(AST_NAME); rxndivide.addChild(rxnref.deepCopy()); rxndivide.addChild(klmod->deepCopy()); } List* allElements = model->getAllElements(); for (ListIterator iter = allElements->begin(); iter != allElements->end(); ++iter) { SBase* element = static_cast<SBase*>(*iter); assert(element != NULL); ASTNode* ast1 = NULL; ASTNode* ast2 = NULL; Constraint* constraint = NULL; Delay* delay = NULL; EventAssignment* ea = NULL; InitialAssignment* ia = NULL; KineticLaw* kl = NULL; Priority* priority = NULL; RateRule* rrule = NULL; Rule* rule = NULL; Submodel* submodel = NULL; Trigger* trigger = NULL; string cf = ""; //Reaction math will be converted below, in the bits with the kinetic law. But because of that, we need to handle references *to* the reaction: even if it has no kinetic law, the units have changed, and this needs to be reflected by the flattening routine. if (rxndivide.getNumChildren() != 0 && element->getTypeCode()==SBML_REACTION && element->isSetId()) { rxndivide.getChild(0)->setName(element->getId().c_str()); for (ListIterator iter = allElements->begin(); iter != allElements->end(); ++iter) { SBase* subelement = static_cast<SBase*>(*iter); subelement->replaceSIDWithFunction(element->getId(), &rxndivide); } } //Submodels need their timeConversionFactor and extentConversionFactor attributes converted. We're moving top-down, so all we need to do here is fix the conversion factor attributes themselves, pointing them to new parameters if need be. if ((tcf !=NULL || xcf != NULL) && element->getTypeCode()==SBML_COMP_SUBMODEL) { submodel = static_cast<Submodel*>(element); if (tcf != NULL) { if (submodel->isSetTimeConversionFactor()) { createNewConversionFactor(cf, tcf, submodel->getTimeConversionFactor(), model); submodel->setTimeConversionFactor(cf); } else { submodel->setTimeConversionFactor(tcf->getName()); } } if (xcf != NULL) { if (submodel->isSetExtentConversionFactor()) { createNewConversionFactor(cf, xcf, submodel->getExtentConversionFactor(), model); submodel->setExtentConversionFactor(cf); } else { submodel->setExtentConversionFactor(xcf->getName()); } } } if (tcf==NULL) { if (klmod !=NULL && element->getTypeCode()==SBML_KINETIC_LAW) { kl = static_cast<KineticLaw*>(element); if (kl->isSetMath()) { ast1 = new ASTNode(AST_TIMES); ast1->addChild(klmod->deepCopy()); ast1->addChild(kl->getMath()->deepCopy()); kl->setMath(ast1); delete ast1; } } } else { // All math 'time' and 'delay' csymbols must still be converted. // Also, several constructs are modified directly. switch(element->getTypeCode()) { //This would be a WHOLE LOT SIMPLER if there was a 'hasMath' class in libsbml. But even so, it would have to // handle the kinetic laws, rate rules, and delays separately. case SBML_KINETIC_LAW: //Kinetic laws are multiplied by 'klmod'. kl = static_cast<KineticLaw*>(element); ast1 = kl->getMath()->deepCopy(); convertCSymbols(ast1, &tcfdiv, &tcftimes); if (klmod !=NULL) { kl = static_cast<KineticLaw*>(element); if (kl->isSetMath()) { ast2 = new ASTNode(AST_TIMES); ast2->addChild(klmod->deepCopy()); ast2->addChild(ast1); kl->setMath(ast2); delete ast2; } } else { kl->setMath(ast1); delete ast1; } break; case SBML_DELAY: //Delays are multiplied by the time conversion factor. delay = static_cast<Delay*>(element); if (delay->isSetMath()) { ast1 = delay->getMath()->deepCopy(); convertCSymbols(ast1, &tcfdiv, &tcftimes); tcftimes.addChild(ast1); delay->setMath(&tcftimes); tcftimes.removeChild(1); delete ast1; } break; case SBML_RATE_RULE: //Rate rules are divided by the time conversion factor. rrule = static_cast<RateRule*>(element); if (rrule->isSetMath()) { ast1 = rrule->getMath()->deepCopy(); tcfdiv.insertChild(0, ast1); rrule->setMath(&tcfdiv); tcfdiv.removeChild(0); delete ast1; } //Fall through to: case SBML_ASSIGNMENT_RULE: case SBML_ALGEBRAIC_RULE: //Rules in general need csymbols converted. rule = static_cast<Rule*>(element); if (rule->isSetMath()) { ast1 = rule->getMath()->deepCopy(); convertCSymbols(ast1, &tcfdiv, &tcftimes); rule->setMath(ast1); delete ast1; } break; case SBML_EVENT_ASSIGNMENT: //Event assignments need csymbols converted. ea = static_cast<EventAssignment*>(element); if (ea->isSetMath()) { ast1 = ea->getMath()->deepCopy(); convertCSymbols(ast1, &tcfdiv, &tcftimes); ea->setMath(ast1); delete ast1; } break; case SBML_INITIAL_ASSIGNMENT: //Initial assignments need csymbols converted. ia = static_cast<InitialAssignment*>(element); if (ia->isSetMath()) { ast1 = ia->getMath()->deepCopy(); convertCSymbols(ast1, &tcfdiv, &tcftimes); ia->setMath(ast1); delete ast1; } break; case SBML_CONSTRAINT: //Constraints need csymbols converted. constraint = static_cast<Constraint*>(element); if (constraint->isSetMath()) { ast1 = constraint->getMath()->deepCopy(); convertCSymbols(ast1, &tcfdiv, &tcftimes); constraint->setMath(ast1); delete ast1; } break; case SBML_PRIORITY: //Priorities need csymbols converted. priority = static_cast<Priority*>(element); if (priority->isSetMath()) { ast1 = priority->getMath()->deepCopy(); convertCSymbols(ast1, &tcfdiv, &tcftimes); priority->setMath(ast1); delete ast1; } break; case SBML_TRIGGER: //Triggers need csymbols converted. trigger = static_cast<Trigger*>(element); if (trigger->isSetMath()) { ast1 = trigger->getMath()->deepCopy(); convertCSymbols(ast1, &tcfdiv, &tcftimes); trigger->setMath(ast1); delete ast1; } break; default: //Do nothing! If we wanted to call a plugin routine, this would be the place. The only other alternative is to #ifdef some code in here that deals with the math-containing package objects explicitly. Which might be the best option, all told. break; } } } delete allElements; return 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; }