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 ClassReplacements::checkReferencedElement(ReplacedElement& repE) { // if the deletion attribute is set then we don't care what // it points to 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->getTypeCode() != parent->getTypeCode()) { int parentTC = parent->getTypeCode(); // exception is anything with mathematical meaning // may replace a parameter if (refElem->getTypeCode() == SBML_PARAMETER) { if (parentTC == SBML_COMPARTMENT || parentTC == SBML_SPECIES || parentTC == SBML_SPECIES_REFERENCE || parentTC == SBML_REACTION || parentTC == SBML_LOCAL_PARAMETER) { return; } } else if (refElem->getTypeCode() == SBML_LOCAL_PARAMETER) { if (parentTC == SBML_PARAMETER) { return; } } logBadClassReplacement(repE, refElem, parent); } }
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; }
void UnitReplacementCheck::checkReferencedElement(ReplacedElement& repE, const Model& m) { // if the deletion attribute is set then it is not a true replacement 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(); UnitDefinition *parentUnits = parent->getDerivedUnitDefinition(); UnitDefinition *refElemUnits = refElem->getDerivedUnitDefinition(); bool delrefelem = false; bool cfPresent = false; /* adjust the refElement units for conversion factor */ if (repE.isSetConversionFactor() == true && refElemUnits && refElemUnits->getNumUnits() > 0) { Parameter * p = const_cast<Model *>(&m) ->getParameter(repE.getConversionFactor()); UnitDefinition *ud = p->getDerivedUnitDefinition(); UnitDefinition *newRefElemUnits = UnitDefinition::combine(refElemUnits, ud); refElemUnits = newRefElemUnits; delrefelem = true; cfPresent = true; } if (parentUnits == NULL) { if (delrefelem) { delete refElemUnits; } return; } if (refElemUnits == NULL) { return; } if (parent->containsUndeclaredUnits() == true || refElem->containsUndeclaredUnits() == true) { if (delrefelem) { delete refElemUnits; } return; } if (UnitDefinition::areIdentical(parentUnits, refElemUnits) == false) { logMismatchUnits(repE, refElem, parent, cfPresent); } else { // if we have Compartments that have spatialDimensions but no units // we can check this if (parent->getTypeCode() == SBML_COMPARTMENT && parentUnits->getNumUnits() == 0 && refElem->getTypeCode() == SBML_COMPARTMENT && refElemUnits->getNumUnits() == 0) { if (static_cast<Compartment *>(parent)->isSetSpatialDimensions() == true && static_cast<Compartment *>(refElem)->isSetSpatialDimensions() == true) { if (util_isEqual( static_cast<Compartment *>(parent)->getSpatialDimensionsAsDouble(), static_cast<Compartment *>(refElem)->getSpatialDimensionsAsDouble()) == 0) { logMismatchSpatialDimensions(repE, refElem, parent); } } } } if (delrefelem) { delete refElemUnits; } }