void GenericHandler<Request, Model, IdPolicy> ::load_collection(JsonAgentSPtr agent, const std::string &parent, const CollectionType& collection_type, bool recursively) { Context ctx; ctx.agent = agent.get(); ctx.mode = Context::Mode::LOADING; auto indent = ctx.indent; ctx.indent += " "; log_info(GET_LOGGER("rest"), ctx.indent << "[" << static_cast<char>(ctx.mode) << "] " << "Loading collections of type [" << collection_type.to_string() << "] for [" << component_s() << " " << parent << " " << "]"); Request request{parent}; const Model entry = ctx.agent->execute<Model>(request); std::vector<Collection> collections{}; std::for_each(entry.get_collections().get_array().begin(), entry.get_collections().get_array().end(), [&collection_type, &collections] (const Collection& element) { if (element.get_type() == collection_type) { collections.push_back(element); } } ); if (collections.empty()) { log_error(GET_LOGGER("rest"), ctx.indent << "[" << static_cast<char>(ctx.mode) << "] " << "No collection of type \'" << collection_type << "\' for [" << component_s() << " " << parent << "]"); } if (recursively) { fetch_subcomponents(ctx, parent, collections); } else { // same as in fetch_siblings, this method maps component types (aka collection types) // to the epoch from before loading in order to know what we should remove std::map<CollectionType, uint64_t> epochs{}; for (const auto& collection : collections) { log_info(GET_LOGGER("rest"), ctx.indent << "[" << static_cast<char>(ctx.mode) << "] Collection [" << collection.get_name() << "]"); auto handler = HandlerManager::get_instance()->get_handler(collection.get_type()); if (epochs.find(collection.get_type()) == epochs.end()) { epochs[collection.get_type()] = handler->get_manager_epoch(); } const auto siblings = handler->fetch_sibling_uuid_list(ctx, parent, collection.get_name()); for (const auto& sibling: siblings) { handler->update(ctx, parent, sibling.get_subcomponent()); } } // removing the components we did not touch for (const auto& collection_epoch : epochs) { HandlerManager::get_instance()->get_handler(collection_epoch.first) ->remove_untouched(ctx, parent, collection_epoch.second); } } ctx.indent = indent; SubscriptionManager::get_instance()->notify(ctx.events); }