All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.linkedin.restli.client.config.RequestConfigTree Maven / Gradle / Ivy

There is a newer version: 4.0.1
Show newest version
package com.linkedin.restli.client.config;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;

import com.linkedin.restli.common.ResourceMethod;

class RequestConfigTree {

  /**
   * Priorities:
   * 1. outbound name
   * 2. inbound name
   * 3. outbound operation
   * 4. outbound operation name
   * 5. inbound operation
   * 6. inbound operation name
   */
  private final Map, Map, Map, Map, Map, Map, ConfigValue>>>>>> _tree =
      new HashMap<>();

  @SuppressWarnings("unchecked")
  void add(RequestConfigElement element) {
    _tree.computeIfAbsent(element.getOutboundName(), k -> new HashMap<>())
         .computeIfAbsent(element.getInboundName(), k -> new HashMap<>())
         .computeIfAbsent(element.getOutboundOp(), k -> new HashMap<>())
         .computeIfAbsent(element.getOutboundOpName(), k -> new HashMap<>())
         .computeIfAbsent(element.getInboundOp(), k -> new HashMap<>())
         .putIfAbsent(element.getInboundOpName(), new ConfigValue<>((T)element.getValue(), element.getKey()));
  }

  Optional> resolveInboundOpName(RequestConfigCacheKey cacheKeyd,
     Map, ConfigValue> map) {
    if (map != null) {
      Optional inboundOpName = cacheKeyd.getInboundOpName();
      if (inboundOpName.isPresent()) {
        ConfigValue value = map.get(inboundOpName);
        if (value != null) {
          return Optional.of(value);
        }
      }
      return Optional.ofNullable(map.get(Optional.empty()));
    } else {
      return Optional.empty();
    }
  }

  Optional> resolveInboundOp(RequestConfigCacheKey cacheKeyd,
      Map, Map, ConfigValue>> map) {
    if (map != null) {
      Optional inboundOp = cacheKeyd.getInboundOp();
      if (inboundOp.isPresent()) {
        Optional> value = resolveInboundOpName(cacheKeyd, map.get(inboundOp));
        if (value.isPresent()) {
          return value;
        }
      }
      return resolveInboundOpName(cacheKeyd, map.get(Optional.empty()));
    } else {
      return Optional.empty();
    }
  }

  Optional> resolveOutboundOpName(RequestConfigCacheKey cacheKeyd,
      Map, Map, Map, ConfigValue>>> map) {
    if (map != null) {
      Optional outboundOpName = cacheKeyd.getOutboundOpName();
      if (outboundOpName.isPresent()) {
        Optional> value = resolveInboundOp(cacheKeyd, map.get(outboundOpName));
        if (value.isPresent()) {
          return value;
        }
      }
      return resolveInboundOp(cacheKeyd, map.get(Optional.empty()));
    } else {
      return Optional.empty();
    }
  }

  Optional> resolveOutboundOp(RequestConfigCacheKey cacheKeyd,
      Map, Map, Map, Map, ConfigValue>>>> map) {
    if (map != null) {
      Optional outboundOp = Optional.of(cacheKeyd.getOutboundOp());
      if (outboundOp.isPresent()) {
        Optional> value = resolveOutboundOpName(cacheKeyd, map.get(outboundOp));
        if (value.isPresent()) {
          return value;
        }
      }
      return resolveOutboundOpName(cacheKeyd, map.get(Optional.empty()));
    } else {
      return Optional.empty();
    }
  }

  /**
   * This method recursively uses given resolver to resolve a config by given name taking into account
   * syntax of sub-resource names. For example, for given name: Optional.of("foo:bar:baz") it will make
   * the following resolver calls:
   * - resolver(Optional.of("foo:bar:baz"))
   * - resolver(Optional.of("foo:bar"))
   * - resolver(Optional.of("foo"))
   * - resolver(Optional.empty())
   */
  Optional> resolveNameRecursively(Optional name, Function, Optional>> resolver) {
    Optional> value = resolver.apply(name);
    if (value.isPresent()) {
      return value;
    } else {
      if (name.isPresent()) {
        return resolveNameRecursively(name.filter(s -> s.lastIndexOf(':') > 0).map(s -> s.substring(0, s.lastIndexOf(':'))), resolver);
      } else {
        return Optional.empty();
      }
    }
  }

  Optional> resolveInboundName(RequestConfigCacheKey cacheKeyd,
      Map, Map, Map, Map, Map, ConfigValue>>>>> map) {
    if (map != null) {
      return resolveNameRecursively(cacheKeyd.getInboundName(), x -> resolveOutboundOp(cacheKeyd, map.get(x)));
    } else {
      return Optional.empty();
    }
  }

  Optional> resolveOutboundName(RequestConfigCacheKey cacheKeyd) {
    return resolveNameRecursively(Optional.of(cacheKeyd.getOutboundName()), x -> resolveInboundName(cacheKeyd, _tree.get(x)));
  }

  ConfigValue resolve(RequestConfigCacheKey cacheKey) {
    return resolveOutboundName(cacheKey).get();
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy