<commit_before>// xml_file_loader.cc
// Implements file reader for an XML format
#include <algorithm>
#include <fstream>
#include <set>
#include <streambuf>

#include <boost/filesystem.hpp>

#include "blob.h"
#include "context.h"
#include "cyc_std.h"
#include "env.h"
#include "error.h"
#include "event_manager.h"
#include "greedy_preconditioner.h"
#include "greedy_solver.h"
#include "logger.h"
#include "model.h"
#include "timer.h"
#include "xml_query_engine.h"

#include "xml_file_loader.h"

namespace cyclus {

namespace fs = boost::filesystem;

// - - - - - - - - - - - - - - - -   - - - - - - - - - - - - - - - - - -
void LoadStringstreamFromFile(std::stringstream& stream,
                              std::string file) {
  std::ifstream file_stream(file.c_str());
  if (!file_stream) {
    throw IOError("The file '" + file + "' could not be loaded.");
  }

  stream << file_stream.rdbuf();
  file_stream.close();
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
std::string BuildMasterSchema() {
  Timer ti;
  EventManager em;
  Context ctx(&ti, &em);

  std::stringstream schema("");
  std::string schema_path = Env::GetInstallPath() + "/share/cyclus.rng.in";
  LoadStringstreamFromFile(schema, schema_path);
  std::string master = schema.str();

  std::vector<std::string> names = Env::ListModules();
  std::map<std::string, std::string> subschemas;
  for (int i = 0; i < names.size(); ++i) {
    DynamicModule dyn(names[i]);
    Model* m = dyn.ConstructInstance(&ctx);
    subschemas[m->ModelType()] += "<element name=\"" + names[i] + "\">\n";
    subschemas[m->ModelType()] += m->schema() + "\n";
    subschemas[m->ModelType()] += "</element>\n";
    delete m;
    dyn.CloseLibrary();
  }

  // replace refs in master rng template file
  std::map<std::string, std::string>::iterator it;
  for (it = subschemas.begin(); it != subschemas.end(); ++it) {
    std::string search_str = std::string("@") + it->first + std::string("_REFS@");
    size_t pos = master.find(search_str);
    if (pos != std::string::npos) {
      master.replace(pos, search_str.size(), it->second);
    }
  }

  return master;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
XMLFileLoader::XMLFileLoader(Context* ctx,
                             const std::string load_filename) : ctx_(ctx) {
  file_ = load_filename;
  std::stringstream input;
  LoadStringstreamFromFile(input, file_);
  parser_ = boost::shared_ptr<XMLParser>(new XMLParser());
  parser_->Init(input);

  ctx_->NewEvent("InputFiles")
  ->AddVal("Data", Blob(input.str()))
  ->Record();

  schema_paths_["Region"] = "/*/region";
  schema_paths_["Inst"] = "/*/region/institution";
  schema_paths_["Facility"] = "/*/facility";
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
XMLFileLoader::~XMLFileLoader() {
  std::map<std::string, DynamicModule*>::iterator it;
  for (it = modules_.begin(); it != modules_.end(); it++) {
    it->second->CloseLibrary();
    delete it->second;
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void XMLFileLoader::ApplySchema(const std::stringstream& schema) {
  parser_->Validate(schema);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void XMLFileLoader::LoadSim(bool use_main_schema) {
  LoadDynamicModules();

  if (use_main_schema) {
    std::stringstream ss(BuildMasterSchema());
    parser_->Validate(ss);
  }

  LoadSolver();
  LoadControlParams();
  LoadRecipes();
  LoadInitialAgents();
};

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void XMLFileLoader::LoadSolver() {
  XMLQueryEngine xqe(*parser_);
  std::string query = "/*/commodity";

  std::map<std::string, double> commodity_order;
  std::string name;
  double order;
  int num_commods = xqe.NElementsMatchingQuery(query);
  for (int i = 0; i < num_commods; i++) {
    QueryEngine* qe = xqe.QueryElement(query, i);
    name = qe->GetElementContent("name");
    order = GetOptionalQuery<double>(qe, "solution_order", -1);
    commodity_order[name] = order;
  }
  
  ProcessCommodities(&commodity_order);
  
  // solver will delete conditioner
  GreedyPreconditioner* conditioner = new GreedyPreconditioner(
      commodity_order,
      GreedyPreconditioner::REVERSE);
  
  // context will delete solver
  GreedySolver* solver = new GreedySolver(conditioner);<commit_msg>wraps XML errors which are not very the easiest to tell where they came from<commit_after>// xml_file_loader.cc
// Implements file reader for an XML format
#include <algorithm>
#include <fstream>
#include <set>
#include <streambuf>

#include <boost/filesystem.hpp>

#include "blob.h"
#include "context.h"
#include "cyc_std.h"
#include "env.h"
#include "error.h"
#include "event_manager.h"
#include "greedy_preconditioner.h"
#include "greedy_solver.h"
#include "logger.h"
#include "model.h"
#include "timer.h"
#include "xml_query_engine.h"

#include "xml_file_loader.h"

namespace cyclus {

namespace fs = boost::filesystem;

// - - - - - - - - - - - - - - - -   - - - - - - - - - - - - - - - - - -
void LoadStringstreamFromFile(std::stringstream& stream,
                              std::string file) {
  std::ifstream file_stream(file.c_str());
  if (!file_stream) {
    throw IOError("The file '" + file + "' could not be loaded.");
  }

  stream << file_stream.rdbuf();
  file_stream.close();
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
std::string BuildMasterSchema() {
  Timer ti;
  EventManager em;
  Context ctx(&ti, &em);

  std::stringstream schema("");
  std::string schema_path = Env::GetInstallPath() + "/share/cyclus.rng.in";
  LoadStringstreamFromFile(schema, schema_path);
  std::string master = schema.str();

  std::vector<std::string> names = Env::ListModules();
  std::map<std::string, std::string> subschemas;
  for (int i = 0; i < names.size(); ++i) {
    DynamicModule dyn(names[i]);
    Model* m = dyn.ConstructInstance(&ctx);
    subschemas[m->ModelType()] += "<element name=\"" + names[i] + "\">\n";
    subschemas[m->ModelType()] += m->schema() + "\n";
    subschemas[m->ModelType()] += "</element>\n";
    delete m;
    dyn.CloseLibrary();
  }

  // replace refs in master rng template file
  std::map<std::string, std::string>::iterator it;
  for (it = subschemas.begin(); it != subschemas.end(); ++it) {
    std::string search_str = std::string("@") + it->first + std::string("_REFS@");
    size_t pos = master.find(search_str);
    if (pos != std::string::npos) {
      master.replace(pos, search_str.size(), it->second);
    }
  }

  return master;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
XMLFileLoader::XMLFileLoader(Context* ctx,
                             const std::string load_filename) : ctx_(ctx) {
  file_ = load_filename;
  std::stringstream input;
  LoadStringstreamFromFile(input, file_);
  parser_ = boost::shared_ptr<XMLParser>(new XMLParser());
  parser_->Init(input);

  ctx_->NewEvent("InputFiles")
  ->AddVal("Data", Blob(input.str()))
  ->Record();

  schema_paths_["Region"] = "/*/region";
  schema_paths_["Inst"] = "/*/region/institution";
  schema_paths_["Facility"] = "/*/facility";
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
XMLFileLoader::~XMLFileLoader() {
  std::map<std::string, DynamicModule*>::iterator it;
  for (it = modules_.begin(); it != modules_.end(); it++) {
    it->second->CloseLibrary();
    delete it->second;
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void XMLFileLoader::ApplySchema(const std::stringstream& schema) {
  parser_->Validate(schema);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void XMLFileLoader::LoadSim(bool use_main_schema) {
  try {
    LoadDynamicModules();
    
    if (use_main_schema) {
      std::stringstream ss(BuildMasterSchema());
      parser_->Validate(ss);
    }
    
    LoadSolver();
    LoadControlParams();
    LoadRecipes();
    LoadInitialAgents();
  } catch(std::exception& e) {
    std::string msg = "Error reading xml file: ";
    msg += e.what();
    throw cyclus::Error(msg);
  }
};

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void XMLFileLoader::LoadSolver() {
  XMLQueryEngine xqe(*parser_);
  std::string query = "/*/commodity";

  std::map<std::string, double> commodity_order;
  std::string name;
  double order;
  int num_commods = xqe.NElementsMatchingQuery(query);
  for (int i = 0; i < num_commods; i++) {
    QueryEngine* qe = xqe.QueryElement(query, i);
    name = qe->GetElementContent("name");
    order = GetOptionalQuery<double>(qe, "solution_order", -1);
    commodity_order[name] = order;
  }
  
  ProcessCommodities(&commodity_order);
  
  // solver will delete conditioner
  GreedyPreconditioner* conditioner = new GreedyPreconditioner(
      commodity_order,
      GreedyPreconditioner::REVERSE);
  
  // context will delete solver
  GreedySolver* solver = new GreedySolver(conditioner);
{'fraction_non_alphanumeric': 0.20412920412920413, 'fraction_numerical': 0.000666000666000666, 'mean_word_length': 2.558451816745656, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 7}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 60, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '318721', 'n_tokens_mistral': 3235, 'n_tokens_neox': 3205, 'n_words': 556}