void frontend_registrar::register_frontend_for_extension(const std::string& ext, std::shared_ptr<frontend_interface> s) { // note: not logging by design if (!s) BOOST_THROW_EXCEPTION(registrar_error(null_frontend)); const auto i(frontends_by_extension_.insert(std::make_pair(ext, s))); if (!i.second) BOOST_THROW_EXCEPTION( registrar_error(extension_already_registered + ext)); }
void registrar::register_formatter_helper( std::shared_ptr<helper_formatter_interface> fh) { // note: not logging by design if (!fh) BOOST_THROW_EXCEPTION(registrar_error(null_formatter_helper)); if(fh->family().empty()) BOOST_THROW_EXCEPTION(registrar_error(empty_family)); auto& f(formatter_repository_.helper_formatters_[fh->family()]); for (const auto& of : fh->owning_formatters()) f[of].push_back(fh); }
void frontend_registrar::validate() const { if (frontends_by_extension_.empty()) { BOOST_LOG_SEV(lg, debug) << no_frontends; BOOST_THROW_EXCEPTION(registrar_error(no_frontends)); } BOOST_LOG_SEV(lg, debug) << "Registrar is in a valid state."; }
void registrar:: register_formatter(std::shared_ptr<artefact_formatter_interface> f) { // note: not logging by design if (!f) BOOST_THROW_EXCEPTION(registrar_error(null_formatter)); const auto& al(f->archetype_location()); if (al.archetype().empty()) BOOST_THROW_EXCEPTION(registrar_error(empty_formatter_name)); if (al.facet().empty()) BOOST_THROW_EXCEPTION(registrar_error(empty_facet_name)); if (al.kernel().empty()) BOOST_THROW_EXCEPTION(registrar_error(empty_model_name)); archetype_locations_.push_front(al); formatter_repository_.stock_artefact_formatters_.push_front(f); /* * Add the formatter to the index by element type index. */ auto& ffti(formatter_repository_.stock_artefact_formatters_by_type_index()); auto& ti(ffti[f->element_type_index()]); ti.push_front(f); /* * Add formatter to the index by archetype name. Inserting the * formatter into this repository has the helpful side-effect of * ensuring the formatter id is unique in formatter space. */ const auto arch(al.archetype()); auto& fffn(formatter_repository_.stock_artefact_formatters_by_archetype()); const auto pair(std::make_pair(arch, f)); const auto inserted(fffn.insert(pair).second); if (!inserted) { BOOST_LOG_SEV(lg, error) << duplicate_formatter_name << arch; BOOST_THROW_EXCEPTION(registrar_error(duplicate_formatter_name + arch)); } }
frontend_interface& frontend_registrar:: frontend_for_extension(const std::string& ext) { BOOST_LOG_SEV(lg, debug) << "Looking for frontend for extension: " << ext; const auto i(frontends_by_extension_.find(ext)); if (i != frontends_by_extension_.end()) { BOOST_LOG_SEV(lg, debug) << "Found frontend for extension. Extension '" << ext << "' frontend: '" << i->second->id() << "'"; return *i->second; } BOOST_LOG_SEV(lg, error) << no_frontend_for_extension << ext; BOOST_THROW_EXCEPTION(registrar_error(no_frontend_for_extension + ext)); }
void registrar::validate() const { /* * We must have at least one registered formatter. This is a quick * way of troubleshooting validation errors. */ const auto& frp(formatter_repository_); if (frp.stock_artefact_formatters_by_type_index().empty()) { BOOST_LOG_SEV(lg, error) << no_file_formatters_by_type_index; BOOST_THROW_EXCEPTION( registrar_error(no_file_formatters_by_type_index)); } /* * Validate the registered canonical formatters. */ const auto cs(inclusion_support_types::canonical_support); for (const auto& pair : frp.stock_artefact_formatters_by_type_index()) { BOOST_LOG_SEV(lg, debug) << "Processing type: " << pair.first.name(); const auto& ti(pair.first); const auto& formatters(pair.second); std::set<std::string> facets_found; std::set<std::string> all_facets; for (const auto& ptr : formatters) { const auto& formatter(*ptr); const auto& al(formatter.archetype_location()); const auto fct(al.facet()); all_facets.insert(fct); if (formatter.inclusion_support_type() != cs) continue; /* * We can only have one canonical formatter per type per facet. */ const auto i(facets_found.find(fct)); if (i != facets_found.end()) { const auto arch(al.archetype()); BOOST_LOG_SEV(lg, error) << more_than_one_canonical_archetype << fct << " archetype: " << arch << " type: " << ti.name(); BOOST_THROW_EXCEPTION(registrar_error( more_than_one_canonical_archetype + fct)); } facets_found.insert(fct); } BOOST_LOG_SEV(lg, debug) << "All Facets: " << all_facets; BOOST_LOG_SEV(lg, debug) << "Facets found: " << facets_found; /* * We must have one canonical formatter per type per facet. * FIXME: this check is broken at the moment because this is * only applicable to yarn types, not fabric types. It is also * not applicable to forward declarations. We need some * additional information from yarn to be able to figure out * which types must have a canonical archetype. */ std::set<std::string> result; std::set_difference(all_facets.begin(), all_facets.end(), facets_found.begin(), facets_found.end(), std::inserter(result, result.end())); if (!result.empty()) { BOOST_LOG_SEV(lg, warn) << facets_missing_canonical_archetype << " : " << result; // FIXME: broken at present. // BOOST_THROW_EXCEPTION( // registrar_error(facets_missing_canonical_archetype)); } } if (frp.stock_artefact_formatters().empty()) { BOOST_LOG_SEV(lg, error) << no_file_formatters; BOOST_THROW_EXCEPTION( registrar_error(no_file_formatters)); } BOOST_LOG_SEV(lg, debug) << "Registrar is in a valid state. Repository: " << frp; BOOST_LOG_SEV(lg, debug) << "Archetype locations: " << archetype_locations_; }