Exemplo n.º 1
0
int 
Submodel::instantiate()
{
  SBMLDocument* doc = getSBMLDocument();
  SBMLDocument* rootdoc = doc;
  if (doc==NULL) 
  {
    return LIBSBML_OPERATION_FAILED;
  }

  CompSBMLDocumentPlugin* docplugin = 
    static_cast<CompSBMLDocumentPlugin*>(doc->getPlugin(getPrefix()));
  if (docplugin==NULL)
  {
    return LIBSBML_OPERATION_FAILED;
  }

  SBase* parent  = getParentSBMLObject();
  string parentmodelname = "";
  string parentURI = "";
  set<string> uniqueModels;
  while (parent != NULL && parent->getTypeCode() != SBML_DOCUMENT) {
    if (parent->getTypeCode() == SBML_COMP_SUBMODEL) {
      const Submodel* parentsub = static_cast<const Submodel*>(parent);
      uniqueModels.insert(parentsub->mInstantiationOriginalURI + "::" + parentsub->getModelRef());
      if (parentURI=="") {
        parentURI=parentsub->mInstantiationOriginalURI;
      }
    }
    if (parent->getTypeCode() == SBML_MODEL ||
      parent->getTypeCode() == SBML_COMP_MODELDEFINITION)
    {
      if (parentmodelname == "") {
        parentmodelname = parent->getId();
      }
    }
    rootdoc = parent->getSBMLDocument();
    parent = parent->getParentSBMLObject();
  }

  if (mInstantiatedModel != NULL) 
  {
    delete mInstantiatedModel;
    mInstantiatedModel = NULL;
    mInstantiationOriginalURI.clear();
  }

  if (!hasRequiredAttributes()) {
    string error = "Instantiation error in Submodel::instantiate:  ";
    if (!isSetId()) {
      error += "A submodel in model '" + getParentModel(this)->getId() + "' does not have an 'id' attribute.";
    }
    else if (!isSetModelRef()) {
      error += "The submodel '" + getId() + "' does not have a 'modelRef' attribute.";
    }
    rootdoc->getErrorLog()->logPackageError("comp", CompSubmodelAllowedAttributes, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn());
    return LIBSBML_INVALID_OBJECT;
  }

  SBase* origmodel = docplugin->getModel(getModelRef());
  
  if (origmodel==NULL) {
    string error = "In Submodel::instantiate, unable to instantiate submodel '" + getId() + "' because the referenced model ('" + getModelRef() +"') does not exist.";
    rootdoc->getErrorLog()->logPackageError("comp", CompSubmodelMustReferenceModel, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn());
    return LIBSBML_INVALID_OBJECT;
  }
  ExternalModelDefinition* extmod;
  SBMLDocument* origdoc = NULL;
  string newmodel = parentURI + "::" + getModelRef();
  
  set<pair<string, string> > parents;
  switch(origmodel->getTypeCode()) 
  {
  case SBML_MODEL:
  case SBML_COMP_MODELDEFINITION:
    origdoc = origmodel->getSBMLDocument();
    mInstantiatedModel = static_cast<Model*>(origmodel)->clone();
    if (uniqueModels.insert(newmodel).second == false) {
      //Can't instantiate this model, because we are already a child of it.
      string error = "Error in Submodel::instantiate:  cannot instantiate submodel '" + getId() + "' in model '" + parentmodelname + "' because it references the model '" + getModelRef() + "', which is already an ancestor of the submodel.";
      rootdoc->getErrorLog()->logPackageError("comp", CompSubmodelCannotReferenceSelf, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn());
      return LIBSBML_OPERATION_FAILED;
    }
    mInstantiationOriginalURI = parentURI;
    break;
  case SBML_COMP_EXTERNALMODELDEFINITION:
    extmod = static_cast<ExternalModelDefinition*>(origmodel);
    if (extmod==NULL) 
    {
      //No error message:  it should be impossible, if origmodel has the type code 'external model definition', for it to not be castable to an external model definition.
      mInstantiatedModel = NULL;
      mInstantiationOriginalURI = "";
      return LIBSBML_OPERATION_FAILED;
    }
    mInstantiatedModel = extmod->getReferencedModel(rootdoc, parents);
    if (mInstantiatedModel == NULL) 
    {
      string error = "In Submodel::instantiate, unable to instantiate submodel '" + getId() + "' because the external model definition it referenced (model '" + getModelRef() +"') could not be resolved.";
      rootdoc->getErrorLog()->logPackageError("comp", CompSubmodelMustReferenceModel, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn());
      mInstantiationOriginalURI = "";
      return LIBSBML_OPERATION_FAILED;
    }
    mInstantiationOriginalURI = extmod->getSource();
    origdoc = mInstantiatedModel->getSBMLDocument();
    newmodel = extmod->getSource() + "::" + getModelRef();
    if (uniqueModels.insert(newmodel).second == false) {
      //Can't instantiate this model, because we are already a child of it.
      string error = "Error in Submodel::instantiate:  cannot instantiate submodel '" + getId() + "' in model '" + parentmodelname + "' because it references the model '" + getModelRef() + "', which is already an ancestor of the submodel.";
      rootdoc->getErrorLog()->logPackageError("comp", CompSubmodelCannotReferenceSelf, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn());
      mInstantiatedModel = NULL;
      mInstantiationOriginalURI = "";
      return LIBSBML_OPERATION_FAILED;
    }
    mInstantiatedModel = mInstantiatedModel->clone();
    mInstantiationOriginalURI = extmod->getSource();
    break;
  default:
    //Should always be one of the above, unless someone extends one of the above and doesn't tell us.
    string error = "Instantiation error in Submodel::instantiate:  unable to parse the model '" + origmodel->getId() + "', as it was not of the type 'model' 'modelDefinition', or 'externalModelDefinition'.  The most likely cause of this situation is if some other package extended one of those three types, but the submodel code was not updated.";
    rootdoc->getErrorLog()->logPackageError("comp", CompUnresolvedReference, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn());
    mInstantiatedModel = NULL;
    mInstantiationOriginalURI = "";
    return LIBSBML_OPERATION_FAILED;
  }
  
  if (mInstantiatedModel==NULL) 
  {
    string error = "Instantiation error in Submodel::instantiate:  unable to create a valid copy of model '" + getModelRef() + "'.";
    rootdoc->getErrorLog()->logPackageError("comp", CompModelFlatteningFailed, getPackageVersion(), getLevel(), getVersion(), error, getLine(), getColumn());
    mInstantiationOriginalURI = "";
    return LIBSBML_OPERATION_FAILED;
  }

  mInstantiatedModel->connectToParent(this);
  mInstantiatedModel->setSBMLDocument(origdoc);
  mInstantiatedModel->enablePackage(getPackageURI(), getPrefix(), true);
  CompModelPlugin* instmodplug = 
    static_cast<CompModelPlugin*>(mInstantiatedModel->getPlugin(getPrefix()));
  if (instmodplug == NULL)
  {
    mInstantiatedModel->enablePackageInternal(getPackageURI(), getPrefix(), true);
  }

  // call all registered callbacks
  std::vector<ModelProcessingCallbackData*>::iterator it = mProcessingCBs.begin();
  while(it != mProcessingCBs.end())
  {
    ModelProcessingCallbackData* current = *it;
    int result = current->cb(mInstantiatedModel, rootdoc->getErrorLog(), current->data);
    if (result != LIBSBML_OPERATION_SUCCESS)
      return result;
    ++it;
  }

  
  CompModelPlugin* origmodplug = 
    static_cast<CompModelPlugin*>(rootdoc->getModel()->getPlugin(getPrefix()));

  instmodplug = 
    static_cast<CompModelPlugin*>(mInstantiatedModel->getPlugin(getPrefix()));
  
  if (instmodplug == NULL)
    return LIBSBML_OPERATION_SUCCESS;

  // if we have a transformer specified, then we need to propagate it, so it can
  // be used
  if (origmodplug->isSetTransformer())
  {
    if (instmodplug != NULL)
      instmodplug->setTransformer(origmodplug->getTransformer());
  }

  
  for (unsigned int sub=0; sub<instmodplug->getNumSubmodels(); sub++) 
  {
    Submodel* instsub = instmodplug->getSubmodel(sub);
    int ret = instsub->instantiate();
    if (ret != LIBSBML_OPERATION_SUCCESS) {
      //'instantiate' already sets its own error messages.
      delete mInstantiatedModel;
      mInstantiatedModel = NULL;
      mInstantiationOriginalURI = "";
      return ret;
    }
  }

  return LIBSBML_OPERATION_SUCCESS;
}
Exemplo n.º 2
0
/*
 * 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
    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;
}