-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathLocationManager.cpp
139 lines (127 loc) · 5.04 KB
/
LocationManager.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include "LocationManager.h"
#include "../Utils.h"
#include "Enum.h"
#include "Struct.h"
#include <fstream>
#include <stdexcept>
#include <sstream>
LocationManager::LocationManager(std::string mainHeaderPath)
: mainHeaderPath(std::move(mainHeaderPath)) {}
void LocationManager::loadConfig(const std::string &path) {
std::string realPath = getRealPath(path.c_str());
std::stringstream s;
std::ifstream input(realPath);
for (std::string line; getline(input, line);) {
s << line;
}
config = json::parse(s.str());
validateConfig(config);
}
void LocationManager::validateConfig(const json &config) const {
if (!config.is_object()) {
throw std::invalid_argument(
"Invalid configuration. Configuration should be an object.");
}
for (auto it = config.begin(); it != config.end(); ++it) {
std::string headerName = it.key();
if (headerName.empty()) {
throw std::invalid_argument("Invalid configuration. Header name "
"should not be an empty string.");
}
json headerEntry = it.value();
validateHeaderEntry(headerEntry);
}
}
void LocationManager::validateHeaderEntry(const json &headerEntry) const {
if (headerEntry.is_string()) {
std::string object = headerEntry.get<std::string>();
if (object.empty()) {
throw std::invalid_argument("Invalid configuration. Each header "
"entry should contain non-empty "
"value.");
}
} else if (headerEntry.is_object()) {
std::unordered_set<std::string> headerKeys = {"object", "names"};
validateKeys(headerEntry, headerKeys);
if (headerEntry.find("object") == headerEntry.end()) {
throw std::invalid_argument("Invalid configuration. Header entry "
"that is represented as an object "
"should contain 'object' property.");
}
json object = headerEntry["object"];
if (!object.is_string() || object.get<std::string>().empty()) {
throw std::invalid_argument("Invalid configuration. 'object' "
"property should be a not empty "
"string.");
}
if (headerEntry.find("name") != headerEntry.end()) {
validateNames(headerEntry["names"]);
}
} else {
throw std::invalid_argument("Invalid configuration. Header entry "
"should be a string or an object.");
}
}
void LocationManager::validateKeys(
const json &object, const std::unordered_set<std::string> &keys) const {
for (auto it = object.begin(); it != object.end(); ++it) {
if (keys.find(it.key()) == keys.end()) {
throw std::invalid_argument(
"Invalid configuration. Unknown key: '" + it.key() + "'.");
}
}
}
void LocationManager::validateNames(const json &names) const {
if (!names.is_object()) {
throw std::invalid_argument("Invalid configuration. Library property "
"'names' should be an object.");
}
for (auto it = names.begin(); it != names.end(); ++it) {
if (!it.value().is_string()) {
throw std::invalid_argument(
"Invalid configuration. property 'names'"
" should contain only string values.");
}
}
}
bool LocationManager::inMainFile(const Location &location) const {
return location.getPath() == mainHeaderPath;
}
bool LocationManager::isImported(const Location &location) const {
if (location.getPath().empty()) {
return false;
}
json headerEntry = getHeaderEntry(location);
return !headerEntry.empty();
}
json LocationManager::getHeaderEntry(const Location &location) const {
for (auto it = config.begin(); it != config.end(); ++it) {
std::string pathToHeader = it.key();
if (startsWith(pathToHeader, "/")) {
/* full path */
if (location.getPath() == pathToHeader) {
return it.value();
}
} else if (endsWith(location.getPath(), "/" + pathToHeader)) {
return it.value();
}
}
return json::object();
}
std::string LocationManager::getImportedType(const Location &location,
const std::string &name) const {
json headerEntry = getHeaderEntry(location);
if (headerEntry.is_string()) {
return headerEntry.get<std::string>() + "." +
handleReservedWords(replaceChar(name, " ", "_"));
}
std::string scalaObject = headerEntry["object"];
if (headerEntry.find("names") != headerEntry.end()) {
/* name mapping */
json names = headerEntry["names"];
if (names.find(name) != names.end()) {
return scalaObject + "." + names[name].get<std::string>();
}
}
return scalaObject + "." + handleReservedWords(replaceChar(name, " ", "_"));
}