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);
  }


}
Esempio n. 3
0
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;
  }
}