<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/report/CCopasiContainer.cpp,v $
   $Revision: 1.35 $
   $Name:  $
   $Author: shoops $ 
   $Date: 2005/05/12 11:36:18 $
   End CVS Header */

/**
 * Class CCopasiContainer
 *
 * This class is the is used to group CCopasiObjects logically. It inself is 
 * an object. Contained objects are still globally accessible.
 *
 * Copyright <NAME> 2002
 */

#include "copasi.h"
#include "CCopasiObjectName.h"
#include "CCopasiContainer.h"
#include "CCopasiObjectReference.h"
#include "CCopasiStaticString.h"
#include "utilities/CCopasiVector.h"

CCopasiContainer * CCopasiContainer::Root = NULL;

const std::vector< CCopasiContainer * > CCopasiContainer::EmptyList;

void CCopasiContainer::init() {CCopasiContainer::Root = new CCopasiContainer();}

CCopasiObject * CCopasiContainer::ObjectFromName(const CCopasiObjectName & objName)
{return CCopasiContainer::ObjectFromName(EmptyList, objName);}

CCopasiObject * CCopasiContainer::ObjectFromName(const std::vector< CCopasiContainer * > & listOfContainer,
    const CCopasiObjectName & objName)
{
  const CCopasiObject * pObject = NULL;
  CCopasiContainer* pContainer;
  CCopasiObjectName Name;
  unsigned C_INT32 containerIndex;

  //favor to search the list of container first
  for (containerIndex = 0;
       containerIndex < listOfContainer.size() && !pObject;
       containerIndex++)
    {
      pContainer = listOfContainer[containerIndex];

      for (Name = objName, pObject = NULL;
           (Name.getRemainder() != ""
            || Name.getObjectType() == "String") &&
           !pObject;
           Name = Name.getRemainder())
        pObject = pContainer->getObject(Name);
    }

  // if not found search the root
  if (!pObject)
    pObject = CCopasiContainer::Root->getObject(objName);

  return const_cast<CCopasiObject *>(pObject);
}

CCopasiContainer::CCopasiContainer() :
    CCopasiObject("Root", NULL, "CN", CCopasiObject::Container),
    mObjects(),
    mUpdates()
{addObjectReference("Name", *const_cast<std::string *>(&getObjectName()));}

CCopasiContainer::CCopasiContainer(const std::string & name,
                                   const CCopasiContainer * pParent,
                                   const std::string & type,
                                   const unsigned C_INT32 & flag):
    CCopasiObject(name, pParent, type, flag | CCopasiObject::Container),
    mObjects(),
    mUpdates()
{addObjectReference("Name", *const_cast<std::string *>(&getObjectName()));}

CCopasiContainer::CCopasiContainer(const CCopasiContainer & src,
                                   const CCopasiContainer * pParent):
    CCopasiObject(src, pParent),
    mObjects(),
    mUpdates()
{addObjectReference("Name", *const_cast<std::string *>(&getObjectName()));}

CCopasiContainer::~CCopasiContainer()
{
  objectMap::iterator it = mObjects.begin();
  objectMap::iterator end = mObjects.end();

  for (; it != end; it++)
    if (it->second->getObjectParent() == this)
      {
        it->second->setObjectParent(NULL);
        pdelete(it->second);
      }
}

const std::string CCopasiContainer::getObjectUniqueName() const
  {
    // return getObjectName();
    return CCopasiObject::getObjectUniqueName();
  }

const CCopasiObject * CCopasiContainer::getObject(const CCopasiObjectName & cn) const
  {
    if (cn == "")
      return this;

    std::string Name = cn.getObjectName();
    std::string Type = cn.getObjectType();

    if (getObjectName() == Name && getObjectType() == Type)
      return getObject(cn.getRemainder());

    std::pair< objectMap::const_iterator, objectMap::const_iterator > range =
      mObjects.equal_range(Name);

    objectMap::const_iterator it = range.first;

    while (it != range.second && it->second->getObjectType() != Type) ++it;

    //debug
    /*
    std::cout << "Container::getObject(); this->getObjectName(): " << getObjectName() << " CN: " << cn << std::endl;
    objectMap::const_iterator dit, ditEnd=mObjects.end();
    for (dit=mObjects.begin(); dit != ditEnd; ++dit)
      std::cout << "   " << dit->first << " (Name: " << dit->second->getObjectName() << ", Type: " << dit->second->getObjectType() << ")" << std::endl;
    ditEnd=range.second;
    for (dit=range.first; dit != ditEnd; ++dit)
      std::cout << " * " << dit->first << " (Name: " << dit->second->getObjectName() << ", Type: " << dit->second->getObjectType() << ")" << std::endl;
    */

    if (it == range.second)
      {
        if (Type == "String")
          return new CCopasiStaticString(Name, this);
        else if (Type == "Separator")
          return new CCopasiReportSeparator(Name, this);
        else
          return NULL;
      }

    const CCopasiObject * pObject = NULL;

    if (it->second->isNameVector() || it->second->isVector())
      {
        if (cn.getElementName(0, false) == "")
          return it->second;

        pObject = it->second->getObject("[" + cn.getElementName(0, false) + "]");

        if (it->second->getObjectType() == "Reference" || !pObject)
          return pObject;
        else
          return pObject->getObject(cn.getRemainder());
      }

    if (it->second->isContainer())
      return it->second->getObject(cn.getRemainder());

    if (it->second->isMatrix())
      {
        if (cn.getElementName(0, false) == "")
          return it->second;

        pObject = it->second->getObject("[" + cn.getElementName(0, false) + "]" +             //TODO really?
                                        "[" + cn.getElementName(1, false) + "]");

        if (it->second->getObjectType() == "Reference" || !pObject)
          return pObject;
        else
          return pObject->getObject(cn.getRemainder());
      }

    if (it->second->isReference() || it->second->isStaticString())
      return it->second;

    return it->second->getObject(cn.getRemainder());
  }

const CCopasiContainer::objectMap & CCopasiContainer::getObjects() const
{return mObjects;}

void CCopasiContainer::initObjects() {}

bool CCopasiContainer::add(CCopasiObject * pObject,
                           const bool & adopt)
{
  /* We check wheter we are already containing that object. */
  std::pair< objectMap::iterator, objectMap::iterator > range =
    mObjects.equal_range(pObject->getObjectName());
  objectMap::iterator it;<commit_msg>Fixed ObjectFromName which was never checking for the named object being contained in the current container.<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/report/CCopasiContainer.cpp,v $
   $Revision: 1.36 $
   $Name:  $
   $Author: shoops $ 
   $Date: 2005/07/13 20:05:12 $
   End CVS Header */

/**
 * Class CCopasiContainer
 *
 * This class is the is used to group CCopasiObjects logically. It inself is 
 * an object. Contained objects are still globally accessible.
 *
 * Copyright <NAME> 2002
 */

#include "copasi.h"
#include "CCopasiObjectName.h"
#include "CCopasiContainer.h"
#include "CCopasiObjectReference.h"
#include "CCopasiStaticString.h"
#include "utilities/CCopasiVector.h"

CCopasiContainer * CCopasiContainer::Root = NULL;

const std::vector< CCopasiContainer * > CCopasiContainer::EmptyList;

void CCopasiContainer::init() {CCopasiContainer::Root = new CCopasiContainer();}

CCopasiObject * CCopasiContainer::ObjectFromName(const CCopasiObjectName & objName)
{return CCopasiContainer::ObjectFromName(EmptyList, objName);}

CCopasiObject * CCopasiContainer::ObjectFromName(const std::vector< CCopasiContainer * > & listOfContainer,
    const CCopasiObjectName & objName)
{
  const CCopasiObject * pObject = NULL;
  CCopasiContainer* pContainer;
  CCopasiObjectName Name;
  unsigned C_INT32 containerIndex;

  //favor to search the list of container first
  for (containerIndex = 0;
       containerIndex < listOfContainer.size() && !pObject;
       containerIndex++)
    {
      pContainer = listOfContainer[containerIndex];

      Name = objName;

      pObject = pContainer->getObject(Name);

      for (; Name.getRemainder() != "" && !pObject; Name = Name.getRemainder())
        pObject = pContainer->getObject(Name);
    }

  // if not found search the root
  if (!pObject)
    pObject = CCopasiContainer::Root->getObject(objName);

  return const_cast<CCopasiObject *>(pObject);
}

CCopasiContainer::CCopasiContainer() :
    CCopasiObject("Root", NULL, "CN", CCopasiObject::Container),
    mObjects(),
    mUpdates()
{addObjectReference("Name", *const_cast<std::string *>(&getObjectName()));}

CCopasiContainer::CCopasiContainer(const std::string & name,
                                   const CCopasiContainer * pParent,
                                   const std::string & type,
                                   const unsigned C_INT32 & flag):
    CCopasiObject(name, pParent, type, flag | CCopasiObject::Container),
    mObjects(),
    mUpdates()
{addObjectReference("Name", *const_cast<std::string *>(&getObjectName()));}

CCopasiContainer::CCopasiContainer(const CCopasiContainer & src,
                                   const CCopasiContainer * pParent):
    CCopasiObject(src, pParent),
    mObjects(),
    mUpdates()
{addObjectReference("Name", *const_cast<std::string *>(&getObjectName()));}

CCopasiContainer::~CCopasiContainer()
{
  objectMap::iterator it = mObjects.begin();
  objectMap::iterator end = mObjects.end();

  for (; it != end; it++)
    if (it->second->getObjectParent() == this)
      {
        it->second->setObjectParent(NULL);
        pdelete(it->second);
      }
}

const std::string CCopasiContainer::getObjectUniqueName() const
  {
    // return getObjectName();
    return CCopasiObject::getObjectUniqueName();
  }

const CCopasiObject * CCopasiContainer::getObject(const CCopasiObjectName & cn) const
  {
    if (cn == "")
      return this;

    std::string Name = cn.getObjectName();
    std::string Type = cn.getObjectType();

    if (getObjectName() == Name && getObjectType() == Type)
      return getObject(cn.getRemainder());

    std::pair< objectMap::const_iterator, objectMap::const_iterator > range =
      mObjects.equal_range(Name);

    objectMap::const_iterator it = range.first;

    while (it != range.second && it->second->getObjectType() != Type) ++it;

    //debug
    /*
    std::cout << "Container::getObject(); this->getObjectName(): " << getObjectName() << " CN: " << cn << std::endl;
    objectMap::const_iterator dit, ditEnd=mObjects.end();
    for (dit=mObjects.begin(); dit != ditEnd; ++dit)
      std::cout << "   " << dit->first << " (Name: " << dit->second->getObjectName() << ", Type: " << dit->second->getObjectType() << ")" << std::endl;
    ditEnd=range.second;
    for (dit=range.first; dit != ditEnd; ++dit)
      std::cout << " * " << dit->first << " (Name: " << dit->second->getObjectName() << ", Type: " << dit->second->getObjectType() << ")" << std::endl;
    */

    if (it == range.second)
      {
        if (Type == "String")
          return new CCopasiStaticString(Name, this);
        else if (Type == "Separator")
          return new CCopasiReportSeparator(Name, this);
        else
          return NULL;
      }

    const CCopasiObject * pObject = NULL;

    if (it->second->isNameVector() || it->second->isVector())
      {
        if (cn.getElementName(0, false) == "")
          return it->second;

        pObject = it->second->getObject("[" + cn.getElementName(0, false) + "]");

        if (it->second->getObjectType() == "Reference" || !pObject)
          return pObject;
        else
          return pObject->getObject(cn.getRemainder());
      }

    if (it->second->isContainer())
      return it->second->getObject(cn.getRemainder());

    if (it->second->isMatrix())
      {
        if (cn.getElementName(0, false) == "")
          return it->second;

        pObject = it->second->getObject("[" + cn.getElementName(0, false) + "]" +              //TODO really?
                                        "[" + cn.getElementName(1, false) + "]");

        if (it->second->getObjectType() == "Reference" || !pObject)
          return pObject;
        else
          return pObject->getObject(cn.getRemainder());
      }

    if (it->second->isReference() || it->second->isStaticString())
      return it->second;

    return it->second->getObject(cn.getRemainder());
  }

const CCopasiContainer::objectMap & CCopasiContainer::getObjects() const
{return mObjects;}

void CCopasiContainer::initObjects() {}

bool CCopasiContainer::add(CCopasiObject * pObject,
                           const bool & adopt)
{
  /* We check wheter we are already containing that object. */
  std::pair< objectMap::iterator, objectMap::iterator > range =
    mObjects.equal_range(pObject->getObjectName());
  objectMap::iterator it;
{'fraction_non_alphanumeric': 0.1495833988366609, 'fraction_numerical': 0.004873447571136614, 'mean_word_length': 3.201783355350066, 'pattern_counts': {'":': 0, '<': 107, '<?xml version=': 0, '>': 122, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7569292', 'n_tokens_mistral': 3967, 'n_tokens_neox': 3860, 'n_words': 792}