int CompModelPlugin::collectDeletionsAndDeleteSome(set<SBase*>* removed, set<SBase*>* toremove) { int ret = LIBSBML_OPERATION_SUCCESS; SBMLDocument* doc = getSBMLDocument(); Model* model = static_cast<Model*>(getParentSBMLObject()); if (model==NULL) { if (doc) { string error = "Unable to attempt to perform deletions in CompModelPlugin::collectDeletionsAndDeleteSome: no parent model could be found for the given 'comp' model plugin element."; doc->getErrorLog()->logPackageError("comp", CompModelFlatteningFailed, getPackageVersion(), getLevel(), getVersion(), error); } return LIBSBML_OPERATION_FAILED; } //Since deletions only exist in submodels, loop through the submodels. for (unsigned int sub=0; sub<getNumSubmodels(); sub++) { Submodel* submodel = getSubmodel(sub); //First perform any deletions for (unsigned int d=0; d<submodel->getNumDeletions(); d++) { Deletion* deletion = submodel->getDeletion(d); SBase* todel = deletion->getReferencedElement(); if (todel && (todel->getTypeCode() == SBML_COMP_DELETION || todel->getTypeCode() == SBML_COMP_REPLACEDBY || todel->getTypeCode() == SBML_COMP_REPLACEDELEMENT || todel->getTypeCode() == SBML_LOCAL_PARAMETER) ) { //Go ahead and delete it! set<SBase*> newToRemove; newToRemove.insert(todel); removeCollectedElements(removed, &newToRemove); } else { //Otherwise, just collect it. ret = deletion->collectDeletions(removed, toremove); if (ret!=LIBSBML_OPERATION_SUCCESS) { return ret; } } } //Next collect any deletions in that instantiated submodel (any that weren't just deleted) Model* mod = submodel->getInstantiation(); if (mod==NULL) { //getInstantiation sets its own error messages. return LIBSBML_OPERATION_FAILED; } CompModelPlugin* modplug = static_cast<CompModelPlugin*>(mod->getPlugin(getPrefix())); if (modplug==NULL) { if (doc) { //Shouldn't happen: 'getInstantiation' turns on the comp plugin. string error = "Unable to rename elements in CompModelPlugin::collectDeletionsAndDeleteSome: no valid 'comp' plugin for the model instantiated from submodel " + submodel->getId(); doc->getErrorLog()->logPackageError("comp", CompModelFlatteningFailed, getPackageVersion(), getLevel(), getVersion(), error); } return LIBSBML_OPERATION_FAILED; } modplug->collectDeletionsAndDeleteSome(removed, toremove); } return ret; }
/* * Loop through all Submodels in this Model, instantiate all of them, * perform all deletions, and synchronize all replacements. * The resulting models are stored in the Submodel objects, * and available from 'Submodel::getInstantiation()' */ int CompModelPlugin::instantiateSubmodels() { Model* model = static_cast<Model*>(getParentSBMLObject()); if (model==NULL) return LIBSBML_INVALID_OBJECT; int ret; // First we instantiate all the submodels. // This acts recursively downward through the stack. for (unsigned int sub=0; sub<mListOfSubmodels.size(); sub++) { Submodel* submodel = mListOfSubmodels.get(sub); // Instead of 'instantiate', since we might have already // been instantiated ourselves from above. Model* submodinst = submodel->getInstantiation(); if (submodinst == NULL ) { //'getInstantiation' already sets any errors that might have occurred. return LIBSBML_OPERATION_FAILED; } //// if we have a transformer specified, then we need to propagate it, so it can //// be used // this needs to happen in Submodel:instantiate //if (isSetTransformer()) //{ // CompModelPlugin* other = dynamic_cast<CompModelPlugin*>(submodinst->getPlugin("comp")); // if (other != NULL) // other->setTransformer(getTransformer()); //} } // Next, recursively find all the targets of SBaseRef elements // and save them, since we're about to rename everything and // we won't be able to find things by name any more. ret = saveAllReferencedElements(); if (ret != LIBSBML_OPERATION_SUCCESS) { //saveAllReferencedElements sets any errors. return ret; } mRemoved.clear(); set<SBase*> toremove; // Collect deletions (top-down): // need to do this before renaming in case we delete a local parameter. ret = collectDeletionsAndDeleteSome(&mRemoved, &toremove); if (ret != LIBSBML_OPERATION_SUCCESS) { return ret; } //Next, we rename *all* the elements so everything is unique. ret = renameAllIDsAndPrepend(""); if (ret != LIBSBML_OPERATION_SUCCESS) { return ret; } //Perform replacements and conversions (top-down) and collect them. ret = collectRenameAndConvertReplacements(&mRemoved, &toremove); if (ret != LIBSBML_OPERATION_SUCCESS) { return ret; } //Finally, actually remove the collected elements from the model--they are // all now redundant. Have to wait until now to do this, because of the // possibility of nested constructs: replacing the child of a replaced // element, for example, or even replacing the child of a deleted // element. removeCollectedElements(&mRemoved, &toremove); mRemoved.clear(); return LIBSBML_OPERATION_SUCCESS; }
int CompModelPlugin::collectRenameAndConvertReplacements(set<SBase*>* removed, set<SBase*>* toremove) { int ret = LIBSBML_OPERATION_SUCCESS; SBMLDocument* doc = getSBMLDocument(); Model* model = static_cast<Model*>(getParentSBMLObject()); if (model==NULL) { if (doc) { string error = "Unable to perform replacements in CompModelPlugin::collectRenameAndConvertReplacements: no parent model could be found for the given 'comp' model plugin element."; doc->getErrorLog()->logPackageError("comp", CompModelFlatteningFailed, getPackageVersion(), getLevel(), getVersion(), error); } return LIBSBML_OPERATION_FAILED; } List* allElements = model->getAllElements(); vector<ReplacedElement*> res; vector<ReplacedBy*> rbs; //Collect replaced elements and replaced by's. for (unsigned int e=0; e<allElements->getSize(); e++) { SBase* element = static_cast<SBase*>(allElements->get(e)); int type = element->getTypeCode(); if (type==SBML_COMP_REPLACEDELEMENT) { ReplacedElement* reference = static_cast<ReplacedElement*>(element); res.push_back(reference); } if (type==SBML_COMP_REPLACEDBY) { ReplacedBy* reference = static_cast<ReplacedBy*>(element); rbs.push_back(reference); } } delete allElements; //ReplacedElement replacements for (size_t re=0; re<res.size(); re++) { ret = res[re]->performReplacementAndCollect(removed, toremove); if (ret != LIBSBML_OPERATION_SUCCESS) { return ret; } } //Now do the same thing for anything left over in the submodels for (unsigned int sub=0; sub<getNumSubmodels(); sub++) { Submodel* submodel = getSubmodel(sub); Model* mod = submodel->getInstantiation(); if (mod==NULL) return LIBSBML_OPERATION_FAILED; CompModelPlugin* modplug = static_cast<CompModelPlugin*>(mod->getPlugin(getPrefix())); if (modplug==NULL) return LIBSBML_OPERATION_FAILED; //'left behind' converions (not LaHaye-style) ret = submodel->convertTimeAndExtent(); if (ret != LIBSBML_OPERATION_SUCCESS) return ret; ret = modplug->collectRenameAndConvertReplacements(removed, toremove); if (ret != LIBSBML_OPERATION_SUCCESS) return ret; } //Perform ReplacedBy replacements *after* the submodels are done, so that the topmost-level names take precedence. for (size_t rb=0; rb<rbs.size(); rb++) { ret = rbs[rb]->performReplacementAndCollect(removed, toremove); if (ret != LIBSBML_OPERATION_SUCCESS) { return ret; } } return ret; }
int Replacing::saveReferencedElement() { SBMLDocument* doc = getSBMLDocument(); if (!isSetSubmodelRef()) { if (doc) { string error = "Unable to find referenced element in Replacing::saveReferencedElement: the given <" + getElementName() + "> element"; if (isSetId()) { error += " '" + getId() + "'"; } error += " has no 'submodelRef' attribute."; doc->getErrorLog()->logPackageError("comp", CompReplacedElementAllowedAttributes, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn()); } return LIBSBML_INVALID_OBJECT; } Model* model = getParentModel(this); if (model==NULL) { if (doc) { string error = "Unable to find referenced element in Replacing::saveReferencedElement: no parent model could be found for the given <" + getElementName() + "> element"; if (isSetId()) { error += " '" + getId() + "'."; } doc->getErrorLog()->logPackageError("comp", CompModelFlatteningFailed, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn()); } return LIBSBML_OPERATION_FAILED; } CompModelPlugin* cmp = static_cast<CompModelPlugin*>(model->getPlugin(getPrefix())); if (cmp==NULL) { if (doc) { string error = "Unable to find referenced element in Replacing::saveReferencedElement: no 'comp' plugin for the parent model could be found for the given <" + getElementName() + "> element"; if (isSetId()) { error += " '" + getId() + "'."; } doc->getErrorLog()->logPackageError("comp", CompModelFlatteningFailed, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn()); } return LIBSBML_OPERATION_FAILED; } Submodel* submod = cmp->getSubmodel(getSubmodelRef()); if (submod==NULL) { if (doc) { string error = "Unable to find referenced element for the given <" + getElementName() + "> element"; if (isSetId()) { error += " '" + getId() + "'"; } error += " in Replacing::saveReferencedElement: the submodelRef '" + getSubmodelRef() + "' could not be found in the model."; int errnumber = CompReplacedElementSubModelRef; if (getTypeCode() == SBML_COMP_REPLACEDBY) { errnumber = CompReplacedBySubModelRef; } doc->getErrorLog()->logPackageError("comp", errnumber, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn()); } return LIBSBML_INVALID_ATTRIBUTE_VALUE; } Model* inst = submod->getInstantiation(); if (inst==NULL) { //getInstantiation sets it own error messages. return LIBSBML_OPERATION_FAILED; } mReferencedElement = getReferencedElementFrom(inst); if (mDirectReference==NULL) { mDirectReference = mReferencedElement; } //getReferencedElement* set their own error messages: if (mReferencedElement==NULL) { return LIBSBML_OPERATION_FAILED; } if (mReferencedElement->getTypeCode()==SBML_COMP_PORT) { mReferencedElement = static_cast<Port*>(mReferencedElement)->getReferencedElement(); } if (mReferencedElement==NULL) { return LIBSBML_OPERATION_FAILED; } 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; }