| 111 | |
| 112 | |
| 113 | void Plugin::modulesFromJson(json_t* rootJ) { |
| 114 | // Reordered models vector |
| 115 | std::list<Model*> newModels; |
| 116 | |
| 117 | if (rootJ && json_array_size(rootJ) > 0) { |
| 118 | size_t moduleId; |
| 119 | json_t* moduleJ; |
| 120 | json_array_foreach(rootJ, moduleId, moduleJ) { |
| 121 | // Get model slug |
| 122 | json_t* modelSlugJ = json_object_get(moduleJ, "slug"); |
| 123 | if (!modelSlugJ) { |
| 124 | throw Exception("No slug found for module entry #%d", (int) moduleId); |
| 125 | } |
| 126 | std::string modelSlug = json_string_value(modelSlugJ); |
| 127 | |
| 128 | // Check model slug |
| 129 | if (!isSlugValid(modelSlug)) { |
| 130 | throw Exception("Module slug \"%s\" is invalid", modelSlug.c_str()); |
| 131 | } |
| 132 | |
| 133 | // Get model |
| 134 | auto it = std::find_if(models.begin(), models.end(), [&](Model* m) { |
| 135 | return m->slug == modelSlug; |
| 136 | }); |
| 137 | if (it == models.end()) { |
| 138 | throw Exception("Manifest contains module %s but it is not defined in plugin", modelSlug.c_str()); |
| 139 | } |
| 140 | |
| 141 | Model* model = *it; |
| 142 | models.erase(it); |
| 143 | newModels.push_back(model); |
| 144 | |
| 145 | model->fromJson(moduleJ); |
| 146 | } |
| 147 | } |
| 148 | else { |
| 149 | WARN("No modules in plugin manifest %s", slug.c_str()); |
| 150 | } |
| 151 | |
| 152 | if (!models.empty()) { |
| 153 | std::vector<std::string> slugs; |
| 154 | for (Model* model : models) { |
| 155 | slugs.push_back(model->slug); |
| 156 | delete model; |
| 157 | } |
| 158 | throw Exception("Plugin defines module %s but it is not defined in manifest", string::join(slugs, ", ").c_str()); |
| 159 | } |
| 160 | |
| 161 | models = newModels; |
| 162 | |
| 163 | // Remove models without names |
| 164 | // This is a hacky way of matching JSON models with C++ models. |
| 165 | for (auto it = models.begin(); it != models.end();) { |
| 166 | Model* model = *it; |
| 167 | if (model->name == "") { |
| 168 | it = models.erase(it); |
| 169 | delete model; |
| 170 | continue; |
no test coverage detected