Esempio n. 1
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;
}
Esempio n. 2
0
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;
}
CompSBasePlugin::CompSBasePlugin(const CompSBasePlugin& orig)
  : SBasePlugin(orig)
  , mListOfReplacedElements(NULL)
  , mReplacedBy(NULL)
{
  if (orig.isSetReplacedBy()) {
    mReplacedBy = orig.mReplacedBy->clone();
    mReplacedBy->connectToParent(getParentSBMLObject());
  }
  if (orig.getNumReplacedElements() > 0) {
    createListOfReplacedElements();
    for (unsigned int re=0; re<orig.getNumReplacedElements(); re++) {
      mListOfReplacedElements->append(orig.getReplacedElement(re));
    }
  }
  connectToChild();
}
END_TEST

START_TEST (test_comp_sbase)
{
  SBMLNamespaces sbmlns(3,1,"comp",1);
  Parameter param(&sbmlns);
  CompSBasePlugin* pplugin = static_cast<CompSBasePlugin*>(param.getPlugin("comp"));

  fail_unless(pplugin->getNumReplacedElements()==0);
  ReplacedElement* re = pplugin->createReplacedElement();
  re->setMetaId("re1");
  fail_unless(pplugin->getNumReplacedElements()==1);
  fail_unless(pplugin->addReplacedElement(NULL)==LIBSBML_INVALID_OBJECT);
  ReplacedElement re2(3, 1);
  re2.setMetaId("re2");
  fail_unless(pplugin->addReplacedElement(&re2)==LIBSBML_INVALID_OBJECT);
  re2.setDeletion("ID1");
  fail_unless(pplugin->addReplacedElement(&re2)==LIBSBML_INVALID_OBJECT);
  re2.setSubmodelRef("mod1");
  fail_unless(pplugin->addReplacedElement(&re2)==LIBSBML_OPERATION_SUCCESS);
  ReplacedElement* reref = pplugin->getReplacedElement(1);
  fail_unless(reref != NULL);
  fail_unless(reref->getMetaId()=="re2");
  reref = pplugin->getReplacedElement(0);
  fail_unless(reref != NULL);
  fail_unless(reref->getMetaId()=="re1");
  re->setDeletion("ID1");
  fail_unless(reref->getDeletion()=="ID1");
  fail_unless(pplugin->removeReplacedElement(3)==NULL);
  fail_unless(pplugin->removeReplacedElement(0)==re);
  fail_unless(pplugin->getReplacedElement(1)==NULL);

  fail_unless(pplugin->isSetReplacedBy()==false);
  ReplacedBy* rb = pplugin->createReplacedBy();
  fail_unless(rb != NULL);
  fail_unless(pplugin->isSetReplacedBy()==true);
  fail_unless(pplugin->setReplacedBy(NULL)==LIBSBML_OPERATION_SUCCESS);
  fail_unless(pplugin->isSetReplacedBy()==false);
  ReplacedBy rb2(3,1);
  fail_unless(pplugin->setReplacedBy(&rb2)==LIBSBML_INVALID_OBJECT);
  rb2.setIdRef("ID1");
  fail_unless(pplugin->setReplacedBy(&rb2)==LIBSBML_INVALID_OBJECT);
  rb2.setSubmodelRef("mod1");
  fail_unless(pplugin->setReplacedBy(&rb2)==LIBSBML_OPERATION_SUCCESS);
  fail_unless(pplugin->unsetReplacedBy()==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;
}