Esempio n. 1
0
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);
}