39 #include <boost/noncopyable.hpp>
40 #include <boost/algorithm/string/predicate.hpp>
41 #include <boost/algorithm/string/erase.hpp>
49 static const char PRIORITY_KEY[] =
"$priority";
50 static const char WILDCARD_SUFFIX[] =
"/*";
51 static const size_t WILDCARD_SUFFIX_LEN =
sizeof(WILDCARD_SUFFIX) - 1;
57 inline void applyWildcard(
PathNode &node,
58 std::string
const &pathWithWildcard,
60 auto startingPath = pathWithWildcard;
61 boost::algorithm::erase_tail(startingPath, WILDCARD_SUFFIX_LEN);
63 auto absoluteStartingPath =
getFullPath(startingNode);
64 auto absoluteStartingPathLen = absoluteStartingPath.length();
73 auto relPath = visitPath;
74 boost::algorithm::erase_head(relPath,
75 absoluteStartingPathLen + 1);
76 functor(node, relPath);
81 inline bool doesPathContainWildcard(std::string
const &path) {
82 return boost::algorithm::ends_with(path, WILDCARD_SUFFIX);
86 class AutomaticAliases : boost::noncopyable {
89 detail::AliasProcessorOptions
opts)
90 : m_devNode(devNode), m_opts(opts) {}
96 util::Flag operator()(Json::Value
const &val) {
99 }
else if (val.isObject()) {
100 m_processObject(val);
108 void m_processArray(Json::Value
const &arr) {
109 for (
auto const &elt : arr) {
110 if (elt.isObject()) {
111 m_processObject(elt);
120 void m_processObject(Json::Value
const &obj) {
121 AliasPriority priority{m_opts.defaultPriority};
122 if (obj.isMember(PRIORITY_KEY)) {
124 static_cast<AliasPriority
>(obj[PRIORITY_KEY].asInt());
126 for (
auto const &key : obj.getMemberNames()) {
127 if (PRIORITY_KEY == key) {
130 m_processEntry(key, obj[key], priority);
137 void m_processEntry(std::string
const &path,
138 Json::Value
const &source,
139 AliasPriority priority) {
140 if (!m_opts.permitRelativePath && !isPathAbsolute(path)) {
142 "Got a non-permitted relative path: " << path);
145 ParsedAlias parsedSource(source);
146 auto leaf = parsedSource.getLeaf();
147 if (!m_opts.permitRelativeSource && !isPathAbsolute(leaf)) {
149 "Got a non-permitted relative source leaf: " << leaf);
152 if (!doesPathContainWildcard(leaf)) {
154 m_processSingleEntry(path, parsedSource.getAlias(),
160 if (!m_opts.permitWildcard) {
162 "Got a non-permitted wildcard in the source leaf of: "
163 << parsedSource.getAlias());
166 if (parsedSource.isSimple()) {
169 [&](
PathNode &node, std::string
const &relPath) {
177 applyWildcard(m_devNode, leaf, [&](
PathNode &node,
178 std::string
const &relPath) {
181 parsedSource.getAlias(), priority);
187 void m_processSingleEntry(std::string
const &path,
188 std::string
const &source,
189 AliasPriority priority) {
195 detail::AliasProcessorOptions m_opts;
201 bool AliasProcessor::process(
PathNode &node, Json::Value
const &val) {
202 AutomaticAliases processor{node, m_opts};
203 return processor(val).get();
207 Json::Value
const &destination) {
208 Json::Value ret{Json::nullValue};
212 if (destination.isNull()) {
215 ret = Json::objectValue;
216 ret[path] = destination;
221 Json::Value ret{val};
222 if (!val.isObject()) {
226 if (val.isMember(routing_keys::destination()) &&
227 val.isMember(routing_keys::source())) {
230 val[routing_keys::source()]);
236 AliasPriority priority) {
237 Json::Value ret{alias};
238 if (ret.isObject()) {
239 ret[PRIORITY_KEY] = priority;
::osvr::util::TreeNode< PathElement > PathNode
The specific tree node type that contains a path element.
util::TreeNode< ValueType > & treePathRetrieve(util::TreeNode< ValueType > &node, std::string path, bool permitParent=false)
Internal method for parsing a path and getting or creating the nodes along it.
std::string getFullPath(PathNode const &node)
Gets the absolute path for the given node.
Json::Value convertRouteToAlias(Json::Value const &val)
Given a single JSON object, if it's an old-fashioned "routing directive", convert it to a normal "ali...
void traverseWith(T &node, F &&functor)
A method to handle visiting every node in a tree with a lambda or other by-value function object...
bool isNull(PathElement const &elt)
Returns true if the path element provided is a NullElement.
Json::Value applyPriorityToAlias(Json::Value const &alias, AliasPriority priority)
Given a JSON object describing one or more aliases, set the priority of the alias(es).
Internal, configured header file for verbosity macros.
const char * getPathSeparator()
Gets the path separator - a slash - as a null-terminated string.
Json::Value createJSONAlias(std::string const &path, Json::Value const &destination)
Given a path and a destination, combine them into a JSON alias description.
bool addAliasFromSourceAndRelativeDest(PathNode &node, std::string const &source, std::string const &dest, AliasPriority priority=ALIASPRIORITY_MANUAL)