Exemplo n.º 1
0
/** @cond doxygenLibsbmlInternal */
void CompModelPlugin::renameIDs(List* allElements, const string& prefix)
{
  if (prefix=="") return; //Nothing to prepend.
  vector<pair<string, string> > renamedSIds;
  vector<pair<string, string> > renamedUnitSIds;
  vector<pair<string, string> > renamedMetaIds;
  //PrefixTransformer trans(prefix);
  for (unsigned long el=0; el < allElements->getSize(); ++el) 
  {
    SBase* element = static_cast<SBase*>(allElements->get(el));
    string id = element->getId();
    string metaid = element->getMetaId();
    //element->transformIdentifiers(&trans);
    element->prependStringToAllIdentifiers(prefix);
    if (element->getTypeCode() == SBML_LOCAL_PARAMETER) {
      element->setId(id); //Change it back.  This would perhaps be better served by overriding 'prependStringToAllIdentifiers' but hey.
    }
    string newid = element->getId();
    string newmetaid = element->getMetaId();
    if (id != newid) {
      int type = element->getTypeCode();
      if (type==SBML_UNIT_DEFINITION) {
        renamedUnitSIds.push_back(make_pair(id, newid));
      }
      else if (type==SBML_COMP_PORT) {
        //Do nothing--these can only be referenced from outside the Model, so they need to be handled specially.
        // (In the default case, we throw them away).
      }
      else {
        //This is a little dangerous, but hey!  What's a little danger between friends!
        //(What we are assuming is that any attribute you can get with 'getId' is of the type 'SId')
        renamedSIds.push_back(make_pair(id, newid));
      }
    }
    if (metaid != newmetaid) {
      renamedMetaIds.push_back(make_pair(metaid, newmetaid));
    }
  }

  for (unsigned long el=0; el<allElements->getSize(); el++) {
    SBase* element = static_cast<SBase*>(allElements->get(el));
    for (size_t id=0; id<renamedSIds.size(); id++) 
    {
      element->renameSIdRefs(renamedSIds[id].first, renamedSIds[id].second);
    }
    for (size_t uid=0; uid<renamedUnitSIds.size(); uid++) 
    {
      element->renameUnitSIdRefs(renamedUnitSIds[uid].first, renamedUnitSIds[uid].second);
    }
    for (size_t mid=0; mid<renamedMetaIds.size(); mid++) 
    {
      element->renameMetaIdRefs(renamedMetaIds[mid].first, renamedMetaIds[mid].second);
    }
  }
}
/*
* Logs a message about a function that should return same units
* as the arguments
*/
void 
ArgumentsUnitsCheck::logInconsistentSameUnits (const ASTNode & node, 
                                             const SBase & sb)
{
  char * formula = SBML_formulaToString(&node);
  msg = "The formula '" ;
  msg += formula;
  msg += "' in the math element of the <";
  msg += sb.getElementName();
  msg += "> ";
  switch(sb.getTypeCode()) {
  case SBML_INITIAL_ASSIGNMENT:
  case SBML_EVENT_ASSIGNMENT:
  case SBML_ASSIGNMENT_RULE:
  case SBML_RATE_RULE:
    //LS DEBUG:  could use other attribute values, or 'isSetActualId'.
    break;
  default:
    if (sb.isSetId()) {
      msg += "with id '";
      msg += sb.getId() + "' ";
    }
    break;
  }
  msg += "can only act on variables with the same units.";
  safe_free(formula);

  logFailure(sb, msg);

}
/*
 * @return the error message to use when logging constraint violations.
 * This method is called by logFailure.
 *
 * Returns a message that the given @p id and its corresponding object are
 * in  conflict with an object previously defined.
 */
const string
PieceBooleanMathCheck::getMessage (const ASTNode& node, const SBase& object)
{

  ostringstream oss_msg;

  //oss_msg << getPreamble();

  char * formula = SBML_formulaToString(&node);
  oss_msg << "The formula '" << formula;
  oss_msg << "' in the " << getFieldname() << " element of the <" << object.getElementName();
  oss_msg << "> ";
  switch(object.getTypeCode()) {
  case SBML_INITIAL_ASSIGNMENT:
  case SBML_EVENT_ASSIGNMENT:
  case SBML_ASSIGNMENT_RULE:
  case SBML_RATE_RULE:
    //LS DEBUG:  could use other attribute values, or 'isSetActualId'.
    break;
  default:
    if (object.isSetId()) {
      oss_msg << "with id '" << object.getId() << "' ";
    }
    break;
  }
  oss_msg << "uses a piecewise function that does not return a Boolean.";
  safe_free(formula);

  return oss_msg.str();
}
/*
* Logs a message about the conditional part of a piecewise function 
* that should have dimensionless units
*/
void 
ArgumentsUnitsCheck::logInconsistentPiecewiseCondition (const ASTNode & node, 
                                          const SBase & sb)
{
  char * formula = SBML_formulaToString(&node);
  msg = "The formula '";
  msg += formula;
  msg += "' in the math element of the <";
  msg += sb.getElementName();
  msg += "> ";
  switch(sb.getTypeCode()) {
  case SBML_INITIAL_ASSIGNMENT:
  case SBML_EVENT_ASSIGNMENT:
  case SBML_ASSIGNMENT_RULE:
  case SBML_RATE_RULE:
    //LS DEBUG:  could use other attribute values, or 'isSetActualId'.
    break;
  default:
    if (sb.isSetId()) {
      msg += "with id '";
      msg += sb.getId() + "' ";
    }
    break;
  }
  msg += "uses a piecewise function";
  msg += " where the conditional statement is not dimensionless.";
  safe_free(formula);

  logFailure(sb, msg);

}
/*
 * @return the error message to use when logging constraint violations.
 * This method is called by logFailure.
 *
 * Returns a message that the given @p id and its corresponding object are
 * in  conflict with an object previously defined.
 */
const string
FunctionApplyMathCheck::getMessage (const ASTNode& node, const SBase& object)
{

  ostringstream msg;

  //msg << getPreamble();
  char * formula = SBML_formulaToString(&node);
  msg << "The formula '" << formula;
  msg << "' in the " << getFieldname() << " element of the <" << object.getElementName();
  msg << "> ";
  switch(object.getTypeCode()) {
  case SBML_INITIAL_ASSIGNMENT:
  case SBML_EVENT_ASSIGNMENT:
  case SBML_ASSIGNMENT_RULE:
  case SBML_RATE_RULE:
    //LS DEBUG:  could use other attribute values, or 'isSetActualId'.
    break;
  default:
    if (object.isSetId()) {
      msg << "with id '" << object.getId() << "' ";
    }
    break;
  }
  msg << "uses '" << node.getName() << "' which is not a function definition id.";
  safe_free(formula);

  return msg.str();
}
Exemplo n.º 6
0
/*
 * Subclasses should override this method to read values from the given
 * XMLAttributes set into their specific fields.  Be sure to call your
 * parents implementation of this method as well.
 */
void
SpeciesReference::readL3Attributes (const XMLAttributes& attributes)
{
  const unsigned int level = 3;
  const unsigned int version = getVersion();
  //
  // stoichiometry: double   { use="optional" default="1" }  (L2v1->)
  //
  mIsSetStoichiometry = attributes.readInto("stoichiometry", mStoichiometry, getErrorLog(), false, getLine(), getColumn());

  string elplusid = "<" + getElementName() + ">";
  if (!mId.empty()) {
    elplusid += " with the id '" + mId + "'";
  }
  SBase* rxn = getAncestorOfType(SBML_REACTION);
  if (rxn && rxn->isSetId()) 
  {
    elplusid += " from the <reaction> with the id '" + rxn->getId() + "'";
  }
  //
  // constant: bool { use="required" } (L3v1 -> )
  //
  mIsSetConstant = attributes.readInto("constant", mConstant, getErrorLog(), false, getLine(), getColumn());
  if (!mIsSetConstant && !isModifier())
  {
    logError(AllowedAttributesOnSpeciesReference, level, version, 
             "The required attribute 'constant' is missing from the "
             + elplusid + ".");
  }

}
/*
 * @return the error message to use when logging constraint violations.
 * This method is called by logFailure.
 *
 * Returns a message that the given @p id and its corresponding object are
 * in  conflict with an object previously defined.
 */
const string
CiElementMathCheck::getMessage (const ASTNode& node, const SBase& object)
{

  ostringstream msg;

  //msg << getPreamble();
  char * formula = SBML_formulaToString(&node);
  msg << "The formula '" << formula;
  msg << "' in the " << getFieldname() << " element of the <" << object.getElementName();
  msg << "> ";
  switch(object.getTypeCode()) {
  case SBML_INITIAL_ASSIGNMENT:
  case SBML_EVENT_ASSIGNMENT:
  case SBML_ASSIGNMENT_RULE:
  case SBML_RATE_RULE:
    //LS DEBUG:  could use other attribute values, or 'isSetActualId'.
    break;
  default:
    if (object.isSetId()) {
      msg << "with id '" << object.getId() << "' ";
    }
    break;
  }
  if (object.getLevel() == 2 && object.getVersion() == 1)
    msg << "uses '" << node.getName() << "' that is not the id of a species/compartment/parameter.";
  else if (object.getLevel() < 3)
    msg << "uses '" << node.getName() << "' that is not the id of a species/compartment/parameter/reaction.";
  else
    msg << "uses '" << node.getName() << "' that is not the id of a species/compartment/parameter/reaction/speciesReference.";
  safe_free(formula);

  return msg.str();
}
/*
 * @return the error message to use when logging constraint violations.
 * This method is called by logFailure.
 *
 * Returns a message that the given @p id and its corresponding object are
 * in  conflict with an object previously defined.
 */
const string
NumericArgsMathCheck::getMessage (const ASTNode& node, const SBase& object)
{

  ostringstream msg;

  //msg << getPreamble();

  char * formula = SBML_formulaToString(&node);
  msg << "The formula '" << formula;
  msg << "' in the " << getFieldname() << " element of the <" << object.getElementName();
  msg << "> ";
  switch(object.getTypeCode()) {
  case SBML_INITIAL_ASSIGNMENT:
  case SBML_EVENT_ASSIGNMENT:
  case SBML_ASSIGNMENT_RULE:
  case SBML_RATE_RULE:
    //LS DEBUG:  could use other attribute values, or 'isSetActualId'.
    break;
  default:
    if (object.isSetId()) {
      msg << "with id '" << object.getId() << "' ";
    }
    break;
  }
  msg << "uses an argument to a operator that expects a numeric value.";
  safe_free(formula);

  return msg.str();
}
/*
 * @return the error message to use when logging constraint violations.
 * This method is called by logFailure.
 *
 * Returns a message that the given @p id and its corresponding object are
 * in  conflict with an object previously defined.
 */
const string
ArgumentsUnitsCheck::getMessage (const ASTNode& node, const SBase& object)
{

  ostringstream msg;

  //msg << getPreamble();
  char * formula = SBML_formulaToString(&node);
  msg << "The formula '" << formula;
  msg << "' in the " << getFieldname() << " element of the <" << object.getElementName();
  msg << "> ";
  switch(object.getTypeCode()) {
  case SBML_INITIAL_ASSIGNMENT:
  case SBML_EVENT_ASSIGNMENT:
  case SBML_ASSIGNMENT_RULE:
  case SBML_RATE_RULE:
    //LS DEBUG:  could use other attribute values, or 'isSetActualId'.
    break;
  default:
    if (object.isSetId()) {
      msg << "with id '" << object.getId() << "' ";
    }
    break;
  }
  msg << "produces an exponent that is not an integer and thus may produce ";
  msg << "invalid units.";
  safe_free(formula);

  return msg.str();
}
Exemplo n.º 10
0
/** @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();
  }
}
void
GroupsUniqueModelWideIds::logId (const SBase& object)
{ 
  if (object.isSetId())
  {
    const string& id = object.getId();

    mIdMap.insert( make_pair(id, &object) );
  }
}
/*
 * Checks that the id associated with the given object is unique.  If it
 * is not, logIdConflict is called.
 */
void
GroupsUniqueModelWideIds::doCheckId (const SBase& object)
{ 
  if (object.isSetId())
  {
    const string& id = object.getId();

    if (mIdMap.insert( make_pair(id, &object) ).second == false)
    {
      logIdConflict(id, object);
    }
  }
}
void
ResultExceedsMaximum::logExceedsMaximum (const Transition& tr,
                          const SBase& object)
{
  msg =
    "The <transition> with id '";
  msg += tr.getId();
  msg += "' includes a resultLevel";
  msg += " that may cause the <qualitativeSpecies> '";
  msg += object.getId();
  msg += "' to exceed its maximumLevel.";
  
  logFailure(object);

}
Exemplo n.º 14
0
void
ResultBecomesNegative::logNegativeResult (const Transition& tr,
                          const SBase& object)
{
  msg =
    "The Transition with id '";
  msg += tr.getId();
  msg += "' includes a resultLevel";
  msg += " that may cause the QualitativeSpecies '";
  msg += object.getId();
  msg += "' to become negative.";
  
  logFailure(object);

}
const std::string
KineticLawUnitsCheck::getMessage (const ASTNode& node, const SBase& object)
{
  ostringstream oss_msg;

  //oss_msg << getPreamble();
  char * formula = SBML_formulaToString(&node);
  oss_msg << "The formula '" << formula;
  oss_msg << "' in the <kineticLaw> element of the <reaction> with id '" << object.getId();
  oss_msg << "' produces units that are inconsistent with units of earlier KineticLaw ";
  oss_msg << "elements.";
  safe_free(formula);

  return oss_msg.str();
}
Exemplo n.º 16
0
/** @cond doxygenLibsbmlInternal */
void CompModelPlugin::resetPorts()
{
  for (unsigned int p=0; p<getNumPorts(); p++) {
    Port* port = getPort(p);
    SBase* referenced = port->getReferencedElement();
    if (port->isSetSBaseRef()) {
      port->unsetSBaseRef();
      port->unsetIdRef();
      port->unsetMetaIdRef();
      port->unsetUnitRef();
      int type = referenced->getTypeCode();
      if (referenced->isSetId() && 
          type != SBML_INITIAL_ASSIGNMENT &&
          type != SBML_ASSIGNMENT_RULE &&
          type != SBML_RATE_RULE &&
          type != SBML_EVENT_ASSIGNMENT) {
        if (type==SBML_UNIT_DEFINITION) {
          port->setUnitRef(referenced->getId());
        }
        else {
          port->setIdRef(referenced->getId());
        }
      }
      else if (referenced->isSetMetaId()) {
        port->setMetaIdRef(referenced->getMetaId());
      }
      else {
        stringstream newname;
        newname << "auto_port_" << p;
        referenced->setMetaId(newname.str());
        port->setMetaIdRef(newname.str());
      }
    }
    port->clearReferencedElement();
  }
}
/*
  * Logs a message about dupliacte top level annotations.
  */
void
DuplicateTopLevelAnnotation::logDuplicate (std::string name, const SBase& object )
{

  msg = "The namespaces '";
  msg += name;
  msg += "' is duplicated within the annotation of the ";
  msg += SBMLTypeCode_toString( object.getTypeCode(), object.getPackageName().c_str() );
  msg += " with id '";
  msg += object.getId();
  msg += "'.";

  
  logFailure(object);
}
void 
ReportEmptyListOf::logEmptyList(const ListOf* list, const SBase& parent)
{
  msg = "The ListOf";
  msg += SBMLTypeCode_toString( list->getItemTypeCode(), list->getPackageName().c_str());
  msg += "s in the ";
  msg += SBMLTypeCode_toString(parent.getTypeCode(), parent.getPackageName().c_str());
  msg += " with id '";
  msg += parent.getId();
  msg += "' has no child ";
  msg += SBMLTypeCode_toString( list->getItemTypeCode(), list->getPackageName().c_str());
  msg += " elements.";
  
  logFailure(*list);
}
Exemplo n.º 19
0
void
AssignmentRuleOrdering::logRuleRefersToSelf (const ASTNode & node,
                                             const SBase& object)
{
  char * formula = SBML_formulaToString(&node);
  msg =
    "The AssignmentRule with variable '";
  msg += object.getId();
  msg += "' refers to that variable within the math formula '";
  msg += formula;
  msg += "'.";
  safe_free(formula);
  
  logFailure(object);

}
Exemplo n.º 20
0
SBase*
ListOf::getElementBySId(const std::string& id)
{
  if (id.empty()) return NULL;
  for (unsigned int i = 0; i < size(); i++)
  {
    SBase* obj = get(i);
    if (obj->isSetId() && obj->getId() == id)
    {
      return obj;
    }
    obj = obj->getElementBySId(id);
    if (obj != NULL) return obj;
  }

  return getElementFromPluginsBySId(id);
}
Exemplo n.º 21
0
SBase*
SBasePlugin::getElementBySId(const std::string& id)
{
  if (id.empty()) return NULL;
  IdFilter filter;
  List* allElementsWithIds = this->getAllElements(&filter);
  if (allElementsWithIds == NULL) return NULL;
  for (unsigned int i = 0; i < allElementsWithIds->getSize(); i++)
  {
    SBase* obj = (SBase*)(allElementsWithIds->get(i));
    if (obj->getId() == id)
    {
      return obj;
     }
  }
  return NULL;
}
Exemplo n.º 22
0
void
AssignmentRuleOrdering::logForwardReference (const ASTNode & node,
                                             const SBase& object,
                                             std::string name)
{
  char * formula = SBML_formulaToString(&node);
  msg =
    "The AssignmentRule with variable '";
  msg += object.getId();
  msg += "' refers to the variable '";
  msg += name;
  msg += "' within the math formula '";
  msg += formula;
  msg += "'. '";
  msg += name;
  msg += "' is the subject of a later assignment rule.";
  safe_free(formula);
  
  logFailure(object);

}
Exemplo n.º 23
0
std::string SEDMLUtils::findIdByNameAndType(
  const std::map<CCopasiObject*, SBase*>& map,
  int typeCode,
  const std::string& name)
{
  std::map<CCopasiObject*, SBase*>::const_iterator it = map.begin();

  std::string::size_type compartmentStart = name.find("{");
  std::string nameOnly = name.substr(0, compartmentStart);

  while (it != map.end())
    {
      SBase* current = it->second;

      if (((current->getTypeCode() & typeCode) == typeCode) &&
          current->getName() == name)
        return current->getId();

      if (typeCode == SBML_SPECIES  && compartmentStart != std::string::npos)
        {
          if (((current->getTypeCode() & typeCode) == typeCode) &&
              current->getName() == nameOnly)
            {
              std::string compName = name.substr(compartmentStart + 1, name.size() - compartmentStart  - 2);
              std::string compId = findIdByNameAndType(map, SBML_COMPARTMENT, compName);
              Species* species = (Species*) current;

              if (species->getCompartment() == compId)
                return species->getId();
            }
        }

      ++it;
    }

  return "";
}
Exemplo n.º 24
0
int ReplacedBy::performReplacementAndCollect(set<SBase*>* removed, set<SBase*>* toremove)
{
  SBMLDocument* doc = getSBMLDocument();
  //Find the various objects and plugin objects we need for this to work.
  SBase* parent = getParentSBMLObject();
  if (parent==NULL) {
    if (doc) {
      string error = "Unable to perform replacement in ReplacedBy::performReplacement: no parent object for this <replacedBy> could be found.";
      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;
  }

  //Update the IDs. (Will set its own error messages.)
  int ret = updateIDs(ref, parent);
  
  //ReplacedBy elements do get the name of the top-level element, assuming it has one:
  if (parent->isSetId()) {
    ref->setId(parent->getId());
  }
  if (parent->isSetMetaId()) {
    ref->setMetaId(parent->getMetaId());
  }
  if (ret != LIBSBML_OPERATION_SUCCESS) return ret;

  //And finally, get ready to delete the parent object.
  if (toremove) {
    toremove->insert(parent);
  }
  return LIBSBML_OPERATION_SUCCESS;
}
Exemplo n.º 25
0
int Submodel::convertTimeAndExtentWith(const ASTNode* tcf, const ASTNode* xcf, const ASTNode* klmod)
{
  if (tcf==NULL && xcf==NULL) return LIBSBML_OPERATION_SUCCESS;
  Model* model = getInstantiation();
  if (model==NULL) {
    //getInstantiation sets its own error messages.
    return LIBSBML_OPERATION_FAILED;
  }
  ASTNode tcftimes(AST_TIMES);
  ASTNode tcfdiv(AST_DIVIDE);
  if (tcf != NULL) {
    tcftimes.addChild(tcf->deepCopy());
    tcfdiv.addChild(tcf->deepCopy());
  }
  ASTNode rxndivide(AST_DIVIDE);
  if (klmod != NULL) {
    ASTNode rxnref(AST_NAME);
    rxndivide.addChild(rxnref.deepCopy());
    rxndivide.addChild(klmod->deepCopy());
  }
  List* allElements = model->getAllElements();
  for (ListIterator iter = allElements->begin(); iter != allElements->end(); ++iter)
  {
    SBase* element = static_cast<SBase*>(*iter);
    assert(element != NULL);
    ASTNode* ast1 = NULL;
    ASTNode* ast2 = NULL;
    Constraint* constraint = NULL;
    Delay* delay = NULL;
    EventAssignment* ea = NULL;
    InitialAssignment* ia = NULL;
    KineticLaw* kl = NULL;
    Priority* priority = NULL;
    RateRule* rrule = NULL;
    Rule* rule = NULL;
    Submodel* submodel = NULL;
    Trigger* trigger = NULL;
    string cf = "";
    //Reaction math will be converted below, in the bits with the kinetic law.  But because of that, we need to handle references *to* the reaction:  even if it has no kinetic law, the units have changed, and this needs to be reflected by the flattening routine.
    if (rxndivide.getNumChildren() != 0 && element->getTypeCode()==SBML_REACTION && element->isSetId()) {
      rxndivide.getChild(0)->setName(element->getId().c_str());
      for (ListIterator iter = allElements->begin(); iter != allElements->end(); ++iter)
      {
        SBase* subelement = static_cast<SBase*>(*iter);
        subelement->replaceSIDWithFunction(element->getId(), &rxndivide);
      }
    }

    //Submodels need their timeConversionFactor and extentConversionFactor attributes converted.  We're moving top-down, so all we need to do here is fix the conversion factor attributes themselves, pointing them to new parameters if need be.
    if ((tcf !=NULL || xcf != NULL) && element->getTypeCode()==SBML_COMP_SUBMODEL) {
      submodel = static_cast<Submodel*>(element);
      if (tcf != NULL) {
        if (submodel->isSetTimeConversionFactor()) {
          createNewConversionFactor(cf, tcf, submodel->getTimeConversionFactor(), model);
          submodel->setTimeConversionFactor(cf);
        }
        else {
          submodel->setTimeConversionFactor(tcf->getName());
        }
      }
      if (xcf != NULL) {
        if (submodel->isSetExtentConversionFactor()) {
          createNewConversionFactor(cf, xcf, submodel->getExtentConversionFactor(), model);
          submodel->setExtentConversionFactor(cf);
        }
        else {
          submodel->setExtentConversionFactor(xcf->getName());
        }
      }
    }
    if (tcf==NULL) {
      if (klmod !=NULL && element->getTypeCode()==SBML_KINETIC_LAW) {
        kl = static_cast<KineticLaw*>(element);
        if (kl->isSetMath()) {
          ast1 = new ASTNode(AST_TIMES);
          ast1->addChild(klmod->deepCopy());
          ast1->addChild(kl->getMath()->deepCopy());
          kl->setMath(ast1);
          delete ast1;
        }
      }
    }
    else {
      // All math 'time' and 'delay' csymbols must still be converted.
      // Also, several constructs are modified directly.
      switch(element->getTypeCode()) {
        //This would be a WHOLE LOT SIMPLER if there was a 'hasMath' class in libsbml.  But even so, it would have to
        // handle the kinetic laws, rate rules, and delays separately.
      case SBML_KINETIC_LAW:
        //Kinetic laws are multiplied by 'klmod'.
        kl = static_cast<KineticLaw*>(element);
        ast1 = kl->getMath()->deepCopy();
        convertCSymbols(ast1, &tcfdiv, &tcftimes);
        if (klmod !=NULL) {
          kl = static_cast<KineticLaw*>(element);
          if (kl->isSetMath()) {
            ast2 = new ASTNode(AST_TIMES);
            ast2->addChild(klmod->deepCopy());
            ast2->addChild(ast1);
            kl->setMath(ast2);
            delete ast2;
          }
        }
        else {
          kl->setMath(ast1);
          delete ast1;
        }
        break;
      case SBML_DELAY:
        //Delays are multiplied by the time conversion factor.
        delay = static_cast<Delay*>(element);
        if (delay->isSetMath()) {
          ast1 = delay->getMath()->deepCopy();
          convertCSymbols(ast1, &tcfdiv, &tcftimes);
          tcftimes.addChild(ast1);
          delay->setMath(&tcftimes);
          tcftimes.removeChild(1);
          delete ast1;
        }
        break;
      case SBML_RATE_RULE:
        //Rate rules are divided by the time conversion factor.
        rrule = static_cast<RateRule*>(element);
        if (rrule->isSetMath()) {
          ast1 = rrule->getMath()->deepCopy();
          tcfdiv.insertChild(0, ast1);
          rrule->setMath(&tcfdiv);
          tcfdiv.removeChild(0);
          delete ast1;
        }
        //Fall through to:
      case SBML_ASSIGNMENT_RULE:
      case SBML_ALGEBRAIC_RULE:
        //Rules in general need csymbols converted.
        rule = static_cast<Rule*>(element);
        if (rule->isSetMath()) {
          ast1 = rule->getMath()->deepCopy();
          convertCSymbols(ast1, &tcfdiv, &tcftimes);
          rule->setMath(ast1);
          delete ast1;
        }
        break;
      case SBML_EVENT_ASSIGNMENT:
        //Event assignments need csymbols converted.
        ea = static_cast<EventAssignment*>(element);
        if (ea->isSetMath()) {
          ast1 = ea->getMath()->deepCopy();
          convertCSymbols(ast1, &tcfdiv, &tcftimes);
          ea->setMath(ast1);
          delete ast1;
        }
        break;
      case SBML_INITIAL_ASSIGNMENT:
        //Initial assignments need csymbols converted.
        ia = static_cast<InitialAssignment*>(element);
        if (ia->isSetMath()) {
          ast1 = ia->getMath()->deepCopy();
          convertCSymbols(ast1, &tcfdiv, &tcftimes);
          ia->setMath(ast1);
          delete ast1;
        }
        break;
      case SBML_CONSTRAINT:
        //Constraints need csymbols converted.
        constraint = static_cast<Constraint*>(element);
        if (constraint->isSetMath()) {
          ast1 = constraint->getMath()->deepCopy();
          convertCSymbols(ast1, &tcfdiv, &tcftimes);
          constraint->setMath(ast1);
          delete ast1;
        }
        break;
      case SBML_PRIORITY:
        //Priorities need csymbols converted.
        priority = static_cast<Priority*>(element);
        if (priority->isSetMath()) {
          ast1 = priority->getMath()->deepCopy();
          convertCSymbols(ast1, &tcfdiv, &tcftimes);
          priority->setMath(ast1);
          delete ast1;
        }
        break;
      case SBML_TRIGGER:
        //Triggers need csymbols converted.
        trigger = static_cast<Trigger*>(element);
        if (trigger->isSetMath()) {
          ast1 = trigger->getMath()->deepCopy();
          convertCSymbols(ast1, &tcfdiv, &tcftimes);
          trigger->setMath(ast1);
          delete ast1;
        }
        break;
      default:
        //Do nothing!  If we wanted to call a plugin routine, this would be the place.  The only other alternative is to #ifdef some code in here that deals with the math-containing package objects explicitly.  Which might be the best option, all told.
        break;
      }
    }
  }

  delete allElements;

  return LIBSBML_OPERATION_SUCCESS;
}
Exemplo n.º 26
0
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;
}
Exemplo n.º 27
0
int 
SBMLIdConverter::convert()
{
  if (mDocument == NULL) return LIBSBML_INVALID_OBJECT;
  Model* mModel = mDocument->getModel();
  if (mModel == NULL) return LIBSBML_INVALID_OBJECT;

  // nothing to do
  if (!mProps->hasOption("currentIds") || !mProps->hasOption("newIds"))
	return LIBSBML_OPERATION_SUCCESS;
  
  bool success = true;
  
  IdList currentIds(mProps->getOption("currentIds")->getValue());
  IdList newIds(mProps->getOption("newIds")->getValue());
  
  // if the size does not match something is wrong. 
  if (newIds.size() != currentIds.size())
	return LIBSBML_UNEXPECTED_ATTRIBUTE;
  
  List* allElements = mDocument->getAllElements();
  std::map<std::string, std::string> renamed;
  
  // rename ids 
  for (unsigned int i = 0; i < allElements->getSize(); ++i)
  {
    SBase* current = static_cast<SBase*>(allElements->get(i));
    if (current == NULL || !current->isSetId() 
      || current->getTypeCode() == SBML_LOCAL_PARAMETER)
      continue;	 

    for (unsigned int j = 0; j < currentIds.size(); ++j)
    {
      if (current->getId() != currentIds.at((int)j))
        continue;

      // return error code in case new id is invalid		
      if (!SyntaxChecker::isValidSBMLSId(newIds.at((int)j)))
      {
        delete allElements;
        return LIBSBML_INVALID_ATTRIBUTE_VALUE;
      }

      current->setId(newIds.at((int)j));
      renamed[currentIds.at((int)j)] = newIds.at((int)j);
      break;
    }	
  }

  // update all references that we changed
  std::map<std::string, std::string>::const_iterator it;
  for (unsigned int i = 0; i < allElements->getSize(); ++i)
  {
	  SBase* current = static_cast<SBase*>(allElements->get(i));
	  for (it = renamed.begin(); it != renamed.end(); ++it)
	  {
	    current->renameSIdRefs(it->first, it->second);
	  }
  }
  
  delete allElements;

  if (success) return LIBSBML_OPERATION_SUCCESS;
  return LIBSBML_OPERATION_FAILED;
  
}
Exemplo n.º 28
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;
}
Exemplo n.º 29
0
//static
void SBMLUtils::collectIds(Model* pModel, std::map<std::string, const SBase*>& ids, std::map<std::string, const SBase*>& metaIds)
{
  if (pModel != NULL)
    {
      // the model itself
      SBase* pSBase = NULL;
      std::string id;

      if (pModel->isSetId())
        {
          id = pModel->getId();

          if (ids.find(id) == ids.end())
            {
              ids.insert(std::pair<const std::string, const SBase*>(id, pModel));
            }
          else
            {
              CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
            }
        }

      if (pModel->isSetMetaId())
        {
          id = pModel->getMetaId();

          if (metaIds.find(id) == metaIds.end())
            {
              metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel));
            }
          else
            {
              CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
            }
        }

      // ListOfFunctionDefinitions
      pSBase = pModel->getListOfFunctionDefinitions();

      if (pSBase != NULL)
        {
          if (pSBase->isSetId())
            {
              id = pSBase->getId();

              if (ids.find(id) == ids.end())
                {
                  ids.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                }
            }

          if (pSBase->isSetMetaId())
            {
              id = pSBase->getMetaId();

              if (metaIds.find(id) == metaIds.end())
                {
                  metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                }
            }

          // all FunctionDefinitions
          unsigned int i, iMax = pModel->getListOfFunctionDefinitions()->size();

          for (i = 0; i < iMax; ++i)
            {
              pSBase = pModel->getListOfFunctionDefinitions()->get(i);

              if (pSBase->isSetId())
                {
                  id = pSBase->getId();

                  if (ids.find(id) == ids.end())
                    {
                      ids.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                    }
                  else
                    {
                      CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                    }
                }

              if (pSBase->isSetMetaId())
                {
                  id = pSBase->getMetaId();

                  if (metaIds.find(id) == metaIds.end())
                    {
                      metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                    }
                  else
                    {
                      CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                    }
                }
            }
        }

      // ListOfUnitDefinition
      pSBase = pModel->getListOfUnitDefinitions();

      if (pSBase != NULL)
        {
          if (pSBase->isSetMetaId())
            {
              id = pSBase->getMetaId();

              if (metaIds.find(id) == metaIds.end())
                {
                  metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                }
            }

          // all UnitDefinitions
          // for each UnitDefinition: ListOfUnits, each Unit in ListOfUnits
          unsigned int i, iMax = pModel->getListOfUnitDefinitions()->size();

          for (i = 0; i < iMax; ++i)
            {
              /* UnitDefinitions have their ids in a different namespace
                 so we only consider meta ids.
                 */
              UnitDefinition* pUDef = pModel->getUnitDefinition(i);
              assert(pUDef != NULL);

              if (pUDef->isSetMetaId())
                {
                  id = pUDef->getMetaId();

                  if (metaIds.find(id) == metaIds.end())
                    {
                      metaIds.insert(std::pair<const std::string, const SBase*>(id, pUDef));
                    }
                  else
                    {
                      CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                    }
                }

              ListOf* pList = pUDef->getListOfUnits();

              if (pList != NULL)
                {
                  if (pList->isSetMetaId())
                    {
                      id = pList->getMetaId();

                      if (metaIds.find(id) == metaIds.end())
                        {
                          metaIds.insert(std::pair<const std::string, const SBase*>(id, pList));
                        }
                      else
                        {
                          CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                        }
                    }

                  unsigned j, jMax = pList->size();

                  for (j = 0; j < jMax; ++j)
                    {
                      pSBase = pList->get(j);
                      assert(pSBase != NULL);

                      if (pSBase->isSetMetaId())
                        {
                          id = pSBase->getMetaId();

                          if (metaIds.find(id) == metaIds.end())
                            {
                              metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                            }
                          else
                            {
                              CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                            }
                        }
                    }
                }
            }
        }

      // ListOfCompartmentTypes
      pSBase = pModel->getListOfCompartmentTypes();

      if (pSBase != NULL)
        {
          if (pSBase->isSetId())
            {
              id = pSBase->getId();

              if (ids.find(id) == ids.end())
                {
                  ids.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                }
            }

          if (pSBase->isSetMetaId())
            {
              id = pSBase->getMetaId();

              if (metaIds.find(id) == metaIds.end())
                {
                  metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                }
            }

          // each compartment type
          unsigned int i, iMax = pModel->getListOfCompartmentTypes()->size();

          for (i = 0; i < iMax; ++i)
            {
              pSBase = pModel->getCompartmentType(i);
              assert(pSBase != NULL);

              if (pSBase->isSetId())
                {
                  id = pSBase->getId();

                  if (ids.find(id) == ids.end())
                    {
                      ids.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                    }
                  else
                    {
                      CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                    }
                }

              if (pSBase->isSetMetaId())
                {
                  id = pSBase->getMetaId();

                  if (metaIds.find(id) == metaIds.end())
                    {
                      metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                    }
                  else
                    {
                      CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                    }
                }
            }
        }

      // ListOfSpeciesTypes
      pSBase = pModel->getListOfSpeciesTypes();

      if (pSBase != NULL)
        {
          if (pSBase->isSetId())
            {
              id = pSBase->getId();

              if (ids.find(id) == ids.end())
                {
                  ids.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                }
            }

          if (pSBase->isSetMetaId())
            {
              id = pSBase->getMetaId();

              if (metaIds.find(id) == metaIds.end())
                {
                  metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                }
            }

          // each species type
          unsigned int i, iMax = pModel->getListOfSpeciesTypes()->size();

          for (i = 0; i < iMax; ++i)
            {
              pSBase = pModel->getSpeciesType(i);
              assert(pSBase != NULL);

              if (pSBase->isSetId())
                {
                  id = pSBase->getId();

                  if (ids.find(id) == ids.end())
                    {
                      ids.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                    }
                  else
                    {
                      CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                    }
                }

              if (pSBase->isSetMetaId())
                {
                  id = pSBase->getMetaId();

                  if (metaIds.find(id) == metaIds.end())
                    {
                      metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                    }
                  else
                    {
                      CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                    }
                }
            }
        }

      // ListOfCompartments
      pSBase = pModel->getListOfCompartments();

      if (pSBase != NULL)
        {
          if (pSBase->isSetId())
            {
              id = pSBase->getId();

              if (ids.find(id) == ids.end())
                {
                  ids.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                }
            }

          if (pSBase->isSetMetaId())
            {
              id = pSBase->getMetaId();

              if (metaIds.find(id) == metaIds.end())
                {
                  metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                }
            }

          // all compartments
          unsigned int i, iMax = pModel->getListOfCompartments()->size();

          for (i = 0; i < iMax; ++i)
            {
              pSBase = pModel->getCompartment(i);
              assert(pSBase != NULL);

              if (pSBase->isSetId())
                {
                  id = pSBase->getId();

                  if (ids.find(id) == ids.end())
                    {
                      ids.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                    }
                  else
                    {
                      CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                    }
                }

              if (pSBase->isSetMetaId())
                {
                  id = pSBase->getMetaId();

                  if (metaIds.find(id) == metaIds.end())
                    {
                      metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                    }
                  else
                    {
                      CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                    }
                }
            }
        }

      // ListOfSpecies
      pSBase = pModel->getListOfSpecies();

      if (pSBase != NULL)
        {
          if (pSBase->isSetId())
            {
              id = pSBase->getId();

              if (ids.find(id) == ids.end())
                {
                  ids.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                }
            }

          if (pSBase->isSetMetaId())
            {
              id = pSBase->getMetaId();

              if (metaIds.find(id) == metaIds.end())
                {
                  metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                }
            }

          // all species
          unsigned int i, iMax = pModel->getListOfSpecies()->size();

          for (i = 0; i < iMax; ++i)
            {
              pSBase = pModel->getSpecies(i);
              assert(pSBase != NULL);

              if (pSBase->isSetId())
                {
                  id = pSBase->getId();

                  if (ids.find(id) == ids.end())
                    {
                      ids.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                    }
                  else
                    {
                      CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                    }
                }

              if (pSBase->isSetMetaId())
                {
                  id = pSBase->getMetaId();

                  if (metaIds.find(id) == metaIds.end())
                    {
                      metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                    }
                  else
                    {
                      CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                    }
                }
            }
        }

      // ListOfParameters
      pSBase = pModel->getListOfParameters();

      if (pSBase != NULL)
        {
          if (pSBase->isSetId())
            {
              id = pSBase->getId();

              if (ids.find(id) == ids.end())
                {
                  ids.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                }
            }

          if (pSBase->isSetMetaId())
            {
              id = pSBase->getMetaId();

              if (metaIds.find(id) == metaIds.end())
                {
                  metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                }
            }

          // each parameter
          unsigned int i, iMax = pModel->getListOfParameters()->size();

          for (i = 0; i < iMax; ++i)
            {
              pSBase = pModel->getParameter(i);
              assert(pSBase != NULL);

              if (pSBase->isSetId())
                {
                  id = pSBase->getId();

                  if (ids.find(id) == ids.end())
                    {
                      ids.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                    }
                  else
                    {
                      CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                    }
                }

              if (pSBase->isSetMetaId())
                {
                  id = pSBase->getMetaId();

                  if (metaIds.find(id) == metaIds.end())
                    {
                      metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                    }
                  else
                    {
                      CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                    }
                }
            }
        }

      // ListOfInitialAssignments
      pSBase = pModel->getListOfInitialAssignments();

      if (pSBase != NULL)
        {
          if (pSBase->isSetId())
            {
              id = pSBase->getId();

              if (ids.find(id) == ids.end())
                {
                  ids.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                }
            }

          if (pSBase->isSetMetaId())
            {
              id = pSBase->getMetaId();

              if (metaIds.find(id) == metaIds.end())
                {
                  metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                }
            }

          // each initial assignment
          unsigned int i, iMax = pModel->getListOfInitialAssignments()->size();

          for (i = 0; i < iMax; ++i)
            {
              pSBase = pModel->getInitialAssignment(i);
              assert(pSBase != NULL);

              // initial assignments have no ids
              if (pSBase->isSetMetaId())
                {
                  id = pSBase->getMetaId();

                  if (metaIds.find(id) == metaIds.end())
                    {
                      metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                    }
                  else
                    {
                      CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                    }
                }
            }
        }

      // ListOfRules
      pSBase = pModel->getListOfRules();

      if (pSBase != NULL)
        {
          if (pSBase->isSetId())
            {
              id = pSBase->getId();

              if (ids.find(id) == ids.end())
                {
                  ids.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                }
            }

          if (pSBase->isSetMetaId())
            {
              id = pSBase->getMetaId();

              if (metaIds.find(id) == metaIds.end())
                {
                  metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                }
            }

          // each rule
          unsigned int i, iMax = pModel->getListOfRules()->size();

          for (i = 0; i < iMax; ++i)
            {
              pSBase = pModel->getRule(i);
              assert(pSBase != NULL);

              // rules don't have ids
              if (pSBase->isSetMetaId())
                {
                  id = pSBase->getMetaId();

                  if (metaIds.find(id) == metaIds.end())
                    {
                      metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                    }
                  else
                    {
                      CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                    }
                }
            }
        }

      // ListOfConstraints
      pSBase = pModel->getListOfConstraints();

      if (pSBase != NULL)
        {
          if (pSBase->isSetId())
            {
              id = pSBase->getId();

              if (ids.find(id) == ids.end())
                {
                  ids.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                }
            }

          if (pSBase->isSetMetaId())
            {
              id = pSBase->getMetaId();

              if (metaIds.find(id) == metaIds.end())
                {
                  metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                }
            }

          // each constraint
          unsigned int i, iMax = pModel->getListOfConstraints()->size();

          for (i = 0; i < iMax; ++i)
            {
              pSBase = pModel->getConstraint(i);
              assert(pSBase != NULL);

              // constraints don't have ids
              if (pSBase->isSetMetaId())
                {
                  id = pSBase->getMetaId();

                  if (metaIds.find(id) == metaIds.end())
                    {
                      metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                    }
                  else
                    {
                      CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                    }
                }
            }
        }

      // ListOfReactions
      pSBase = pModel->getListOfReactions();

      if (pSBase != NULL)
        {
          if (pSBase->isSetId())
            {
              id = pSBase->getId();

              if (ids.find(id) == ids.end())
                {
                  ids.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                }
            }

          if (pSBase->isSetMetaId())
            {
              id = pSBase->getMetaId();

              if (metaIds.find(id) == metaIds.end())
                {
                  metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                }
            }

          // all reactions
          unsigned int i, iMax = pModel->getListOfReactions()->size();

          for (i = 0; i < iMax; ++i)
            {
              Reaction* pReaction = pModel->getReaction(i);
              assert(pReaction != NULL);

              if (pReaction->isSetId())
                {
                  id = pReaction->getId();

                  if (ids.find(id) == ids.end())
                    {
                      ids.insert(std::pair<const std::string, const SBase*>(id, pReaction));
                    }
                  else
                    {
                      CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                    }
                }

              if (pReaction->isSetMetaId())
                {
                  id = pReaction->getMetaId();

                  if (metaIds.find(id) == metaIds.end())
                    {
                      metaIds.insert(std::pair<const std::string, const SBase*>(id, pReaction));
                    }
                  else
                    {
                      CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                    }
                }

              // for each reaction: ListOfSubstrates, each substrate, ListOfProducts, each
              // Product, ListOfModifieres, each modifier, KineticLaw, ListOfparameters,
              // each parameter
              if (pReaction->getListOfReactants() != NULL)
                {
                  pSBase = pReaction->getListOfReactants();

                  if (pSBase->isSetMetaId())
                    {
                      id = pSBase->getMetaId();

                      if (metaIds.find(id) == metaIds.end())
                        {
                          metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                        }
                      else
                        {
                          CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                        }
                    }

                  unsigned int j, jMax = pReaction->getListOfReactants()->size();

                  for (j = 0; j < jMax; ++j)
                    {
                      pSBase = pReaction->getReactant(j);
                      assert(pSBase != NULL);

                      // since L2V2 species references can have ids
                      if (pSBase->isSetId())
                        {
                          id = pSBase->getId();

                          if (ids.find(id) == ids.end())
                            {
                              ids.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                            }
                          else
                            {
                              CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                            }
                        }

                      if (pSBase->isSetMetaId())
                        {
                          id = pSBase->getMetaId();

                          if (metaIds.find(id) == metaIds.end())
                            {
                              metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                            }
                          else
                            {
                              CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                            }
                        }
                    }
                }

              if (pReaction->getListOfProducts() != NULL)
                {
                  pSBase = pReaction->getListOfProducts();

                  if (pSBase->isSetMetaId())
                    {
                      id = pSBase->getMetaId();

                      if (metaIds.find(id) == metaIds.end())
                        {
                          metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                        }
                      else
                        {
                          CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                        }
                    }

                  unsigned int j, jMax = pReaction->getListOfProducts()->size();

                  for (j = 0; j < jMax; ++j)
                    {
                      pSBase = pReaction->getProduct(j);
                      assert(pSBase != NULL);

                      // since L2V2 species references can have ids
                      if (pSBase->isSetId())
                        {
                          id = pSBase->getId();

                          if (ids.find(id) == ids.end())
                            {
                              ids.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                            }
                          else
                            {
                              CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                            }
                        }

                      if (pSBase->isSetMetaId())
                        {
                          id = pSBase->getMetaId();

                          if (metaIds.find(id) == metaIds.end())
                            {
                              metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                            }
                          else
                            {
                              CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                            }
                        }
                    }
                }

              if (pReaction->getListOfModifiers() != NULL)
                {
                  pSBase = pReaction->getListOfModifiers();

                  if (pSBase->isSetMetaId())
                    {
                      id = pSBase->getMetaId();

                      if (metaIds.find(id) == metaIds.end())
                        {
                          metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                        }
                      else
                        {
                          CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                        }
                    }

                  unsigned int j, jMax = pReaction->getListOfModifiers()->size();

                  for (j = 0; j < jMax; ++j)
                    {
                      pSBase = pReaction->getModifier(j);
                      assert(pSBase != NULL);

                      // since L2V2 species references can have ids
                      if (pSBase->isSetId())
                        {
                          id = pSBase->getId();

                          if (ids.find(id) == ids.end())
                            {
                              ids.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                            }
                          else
                            {
                              CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                            }
                        }

                      if (pSBase->isSetMetaId())
                        {
                          id = pSBase->getMetaId();

                          if (metaIds.find(id) == metaIds.end())
                            {
                              metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                            }
                          else
                            {
                              CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                            }
                        }
                    }
                }

              KineticLaw* pKLaw = pReaction->getKineticLaw();

              if (pKLaw != NULL)
                {
                  if (pKLaw->isSetMetaId())
                    {
                      id = pKLaw->getMetaId();

                      if (metaIds.find(id) == metaIds.end())
                        {
                          metaIds.insert(std::pair<const std::string, const SBase*>(id, pKLaw));
                        }
                      else
                        {
                          CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                        }
                    }

                  pSBase = pKLaw->getListOfParameters();

                  if (pSBase != NULL)
                    {
                      if (pSBase->isSetMetaId())
                        {
                          id = pSBase->getMetaId();

                          if (metaIds.find(id) == metaIds.end())
                            {
                              metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                            }
                          else
                            {
                              CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                            }
                        }

                      unsigned int j, jMax = pKLaw->getListOfParameters()->size();

                      for (j = 0; j < jMax; ++j)
                        {
                          pSBase = pKLaw->getParameter(j);
                          assert(pSBase != NULL);

                          // local parameters have their ids in a
                          // different namespace
                          if (pSBase->isSetMetaId())
                            {
                              id = pSBase->getMetaId();

                              if (metaIds.find(id) == metaIds.end())
                                {
                                  metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                                }
                              else
                                {
                                  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                                }
                            }
                        }
                    }
                }
            }
        }

      // ListOfEvents
      pSBase = pModel->getListOfEvents();

      if (pSBase != NULL)
        {
          if (pSBase->isSetId())
            {
              id = pSBase->getId();

              if (ids.find(id) == ids.end())
                {
                  ids.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                }
            }

          if (pSBase->isSetMetaId())
            {
              id = pSBase->getMetaId();

              if (metaIds.find(id) == metaIds.end())
                {
                  metaIds.insert(std::pair<const std::string, const SBase*>(id, pModel));
                }
              else
                {
                  CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                }
            }

          // each event
          unsigned int i, iMax = pModel->getListOfEvents()->size();

          for (i = 0; i < iMax; ++i)
            {
              Event* pEvent = pModel->getEvent(i);
              assert(pEvent != NULL);

              if (pEvent->isSetId())
                {
                  id = pEvent->getId();

                  if (ids.find(id) == ids.end())
                    {
                      ids.insert(std::pair<const std::string, const SBase*>(id, pEvent));
                    }
                  else
                    {
                      CCopasiMessage(CCopasiMessage::EXCEPTION, MCSBML + 68, id.c_str());
                    }
                }

              if (pEvent->isSetMetaId())
                {
                  id = pEvent->getMetaId();

                  if (metaIds.find(id) == metaIds.end())
                    {
                      metaIds.insert(std::pair<const std::string, const SBase*>(id, pEvent));
                    }
                  else
                    {
                      CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                    }
                }

              // in each event Trigger,Delay,ListOfEventAssignments, each event assignment
              if (pEvent->isSetTrigger())
                {
                  pSBase = pEvent->getTrigger();
                  assert(pSBase != NULL);

                  if (pSBase->isSetMetaId())
                    {
                      id = pSBase->getMetaId();

                      if (metaIds.find(id) == metaIds.end())
                        {
                          metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                        }
                      else
                        {
                          CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                        }
                    }
                }

              if (pEvent->isSetDelay())
                {
                  pSBase = pEvent->getDelay();
                  assert(pSBase != NULL);

                  if (pSBase->isSetMetaId())
                    {
                      id = pSBase->getMetaId();

                      if (metaIds.find(id) == metaIds.end())
                        {
                          metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                        }
                      else
                        {
                          CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                        }
                    }
                }

              if (pEvent->getListOfEventAssignments() != NULL)
                {
                  pSBase = pEvent->getListOfEventAssignments();

                  if (pSBase->isSetMetaId())
                    {
                      id = pSBase->getMetaId();

                      if (metaIds.find(id) == metaIds.end())
                        {
                          metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                        }
                      else
                        {
                          CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                        }
                    }

                  unsigned int j, jMax = pEvent->getListOfEventAssignments()->size();

                  for (j = 0; j < jMax; ++j)
                    {
                      pSBase = pEvent->getEventAssignment(j);
                      assert(pSBase != NULL);

                      if (pSBase->isSetMetaId())
                        {
                          id = pSBase->getMetaId();

                          if (metaIds.find(id) == metaIds.end())
                            {
                              metaIds.insert(std::pair<const std::string, const SBase*>(id, pSBase));
                            }
                          else
                            {
                              CCopasiMessage(CCopasiMessage::WARNING, MCSBML + 67, id.c_str());
                            }
                        }
                    }
                }
            }
        }
    }
}
Exemplo n.º 30
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;
}