Exemple #1
0
//Deprecated function
int Replacing::performReplacement()
{
  set<SBase*> toremove;
  set<SBase*>* removed = NULL;
  CompModelPlugin* cmp = NULL;
  SBase* parent = getParentSBMLObject();
  while (parent != NULL && parent->getTypeCode() != SBML_DOCUMENT) {
    if (parent->getTypeCode() == SBML_COMP_MODELDEFINITION ||
        parent->getTypeCode() == SBML_MODEL) {
          cmp = static_cast<CompModelPlugin*>(parent->getPlugin("comp"));
          if (cmp != NULL) {
            removed = cmp->getRemovedSet();
          }
    }
    parent = parent->getParentSBMLObject();
  }
  int ret = performReplacementAndCollect(removed, &toremove);
  if (ret != LIBSBML_OPERATION_SUCCESS) {
    return ret;
  }
  if (cmp == NULL) {
    return LIBSBML_INVALID_OBJECT;
  }
  return cmp->removeCollectedElements(removed, &toremove);
}
Exemple #2
0
/** @cond doxygenLibsbmlInternal */
int 
Replacing::replaceWithAndMaybeDelete(SBase* replacement, bool deleteme, ASTNode* conversionFactor)
{
  //All of the following function calls that could result in errors set their own error messages.
  SBase* replaced = getReferencedElement();
  if (replaced==NULL) return LIBSBML_INVALID_OBJECT;

  //Rename things
  int ret = updateIDs(replaced, replacement);
  if (ret != LIBSBML_OPERATION_SUCCESS) return ret;

  //Perform any conversions on references in the submodel.
  ret = performConversions(replacement, &conversionFactor);
  if (ret != LIBSBML_OPERATION_SUCCESS) return ret;

  //Finally, recurse down if there are things the replaced element itself replaced (or used to be replaced by)
  CompSBasePlugin* replacedplug = static_cast<CompSBasePlugin*>(replaced->getPlugin(getPrefix()));
  if (replacedplug==NULL) {
    //assert(false); //Not sure when this situation would come up, so I would like to see an example.
    //(sadly, I cannot set an assert in production code.)
    return LIBSBML_OPERATION_SUCCESS; //I guess?  LS DEBUG
  }
  for (unsigned int re=0; re<replacedplug->getNumReplacedElements(); re++) {
    ret = replacedplug->getReplacedElement(re)->replaceWithAndMaybeDelete(replacement, true, conversionFactor);
    if (ret != LIBSBML_OPERATION_SUCCESS) return ret;
  }
  if (replacedplug->isSetReplacedBy()) {
    ret = replacedplug->getReplacedBy()->replaceWithAndMaybeDelete(replacement, deleteme, conversionFactor);
    if (ret != LIBSBML_OPERATION_SUCCESS) return ret;
  }
  return LIBSBML_OPERATION_SUCCESS;
}
int SBaseRef::collectDeletions(set<SBase*>* removed, set<SBase*>* toremove)
{
  SBase* todelete = getReferencedElement();
  if (todelete==NULL) {
    return LIBSBML_INVALID_OBJECT;
  }
  if (removed) {
    if (removed->find(todelete) != removed->end()) {
      //Already deleted or replaced.
      return LIBSBML_OPERATION_SUCCESS;
    }
  }

  if (toremove) {
    toremove->insert(todelete);
  }

  CompSBasePlugin* todplug = static_cast<CompSBasePlugin*>(todelete->getPlugin(getPrefix()));
  if (todplug != NULL) {
    for (unsigned long re=0; re<todplug->getNumReplacedElements(); re++) {
      todplug->getReplacedElement(re)->collectDeletions(removed, toremove);
    }
    if (todplug->isSetReplacedBy()) {
      todplug->getReplacedBy()->collectDeletions(removed, toremove);
    }
  }
  return LIBSBML_OPERATION_SUCCESS;
}
/*
 * Checks that all ids on the following Model objects are unique:
 * FunctionDefinitions, Species, Compartments, global Parameters,
 * Reactions, and Events.
 */
void
PackageIdReplacementCheck::check_ (const Model& m, const Model& object)
{
  unsigned int n, size;
  const CompSBasePlugin * plug;
  ReplacedFilter filter;
  ReplacedByFilter repByFilter;

  /* get all elements that have replaced elements */
  List* allElements = const_cast<Model *>(&m)->getAllElements(&filter);

  size = allElements->getSize();


  for (n = 0; n < size; ++n) 
  {
    SBase *sb = static_cast<SBase*>(allElements->get(n));
    plug = static_cast<const CompSBasePlugin*>(sb->getPlugin("comp"));

    for (unsigned int i = 0; i < plug->getNumReplacedElements(); i++)
    {
      checkReferencedElement(*(const_cast<ReplacedElement*>
                                        (plug->getReplacedElement(i))));
    }
  }

  delete allElements;

  /* get all elements that have replaced elements */
  allElements = const_cast<Model *>(&m)->getAllElements(&repByFilter);

  size = allElements->getSize();


  for (n = 0; n < size; ++n) 
  {
    SBase *sb = static_cast<SBase*>(allElements->get(n));
    plug = static_cast<const CompSBasePlugin*>(sb->getPlugin("comp"));

    checkReferencedElement(*(const_cast<ReplacedBy*>
                                        (plug->getReplacedBy())));
  }

  delete allElements;

}
/** @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();
  }
}
int 
ReplacedBy::removeFromParentAndDelete()
{
  SBase* parent = getParentSBMLObject();
  if (parent==NULL) return LIBSBML_OPERATION_FAILED;
  CompSBasePlugin* comp_parent = static_cast<CompSBasePlugin*>(parent->getPlugin(getPrefix()));
  if (comp_parent==NULL) return LIBSBML_OPERATION_FAILED;
  return comp_parent->unsetReplacedBy();
}
Model* CompModelPlugin::flattenModel() const
{
  //First make a copy of our parent (the model to be flattened):
  const Model* parent = static_cast<const Model*>(getParentSBMLObject());
  
  if (parent==NULL) {
    return NULL;
  }
  //doc needs to be non-const so that the error messages can be updated.  Otherwise, nothing changes.
  SBMLDocument* doc = const_cast<SBMLDocument*>(getSBMLDocument());
  if (doc==NULL) {
    return NULL;
  }

  //Set the original document so that it can find the model definitions 
  //and external model definitions while we flatten.
  Model* flat = parent->clone();
  flat->setSBMLDocument(doc);
  CompModelPlugin* flatplug = 
    static_cast<CompModelPlugin*>(flat->getPlugin(getPrefix()));

  // Now instantiate its submodels and 
  // follow all renaming/deletion/replacement rules.
  vector<const Model*> submods;
  int success = flatplug->instantiateSubmodels();

  if (success != LIBSBML_OPERATION_SUCCESS) {
    //instantiateSubmodels sets its own error messages.
    delete flat;
    return NULL;
  }

  //Now start the aggregation process.  
  //This goes from the bottom up, calling 'appendFrom' iteratively 
  //(from the plugin).
  for (unsigned int sm=0; sm<flatplug->getNumSubmodels(); sm++) 
  {
    Model* submodel = flatplug->getSubmodel(sm)->getInstantiation();
    if (submodel==NULL) {
      //getInstantiation should be calling a cached value by now, but if not, it will set its own error messages.
      delete flat;
      return NULL;
    }
    CompModelPlugin* submodplug = 
      static_cast<CompModelPlugin*>(submodel->getPlugin(getPrefix()));

    if (submodplug != NULL) {
      //Strip the ports from the submodel, as we no longer need them.
      while (submodplug->getNumPorts() > 0) 
      {
        delete submodplug->removePort(0);
      }
    }
    success = flat->appendFrom(submodel);
    if (success != LIBSBML_OPERATION_SUCCESS) {
      string error = "Unable to flatten model in CompModelPlugin::flattenModel: appending elements from the submodel '" + submodel->getId() + "' to the elements of the parent model failed.";
      doc->getErrorLog()->logPackageError("comp", CompModelFlatteningFailed, getPackageVersion(), getLevel(), getVersion(), error);
      delete flat;
      return NULL;
    }
  }

  // Now we clear the saved referenced elements in the local Port objects, 
  // but point them to the new object if necessary.
  flatplug->resetPorts();

  // Next, strip the package info from 'flat'.  
  // We're going to remove everything but the Ports:
  flatplug->mListOfSubmodels.clear();
  flatplug->clearReplacedElements();
  flatplug->unsetReplacedBy();
  
  List* allelements = flat->getAllElements();
  
  vector<SBase*> nonReplacedElements;
  
  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_REPLACEDBY ||
          type==SBML_COMP_REPLACEDELEMENT ||
          type==SBML_COMP_SBASEREF)) 
    {
            nonReplacedElements.push_back(element);
    }
  }

  // delete the list
  delete allelements;

  for (unsigned int el=0; el<nonReplacedElements.size(); el++) 
  {
    SBase* element = nonReplacedElements[el];
    CompSBasePlugin* elplug = 
      static_cast<CompSBasePlugin*>(element->getPlugin(getPrefix()));
    if (elplug != NULL) 
    {
      elplug->clearReplacedElements();
      elplug->unsetReplacedBy();
    }
  }



  //Finally, unset the document again.
  flat->setSBMLDocument(NULL);

  return flat;
}
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;
}