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

com.github.dakusui.floorplan.resolver.Resolvers Maven / Gradle / Ivy

Go to download

A library to model a heterogeneous and distributed software system for testing

There is a newer version: 5.1.1
Show newest version
package com.github.dakusui.floorplan.resolver;

import com.github.dakusui.floorplan.component.Attribute;
import com.github.dakusui.floorplan.component.Ref;
import com.github.dakusui.floorplan.exception.Exceptions;
import com.github.dakusui.floorplan.utils.Utils;

import java.util.List;

import static com.github.dakusui.floorplan.exception.Exceptions.typeMismatch;
import static com.github.dakusui.floorplan.utils.Checks.require;
import static com.github.dakusui.floorplan.utils.Checks.requireNonNull;
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;

public enum Resolvers {
  ;

  public static  Resolver immediate(T value) {
    return Resolver.of(
        a -> c -> p -> value,
        () -> String.format("immediate(%s)", value)
    );
  }

  public static  Resolver instanceId() {
    return Resolver.of(
        a -> c -> p -> c.ref().id(),
        () -> "instanceId()"
    );
  }

  public static  Resolver referenceTo(Ref ref) {
    return Resolver.of(
        a -> c -> p -> ref,
        () -> String.format("referenceTo(component:%s)", ref)
    );
  }

  public static  Resolver referenceTo(A another) {
    requireNonNull(another);
    return Resolver.of(
        a -> c -> p -> Utils.resolve(another, c, p),
        () -> String.format("referenceTo(attr:%s)", another)
    );
  }

  @SuppressWarnings("unchecked")
  public static  Resolver attributeValueOf(B attr, Resolver holder) {
    return Resolver.of(
        a -> c -> p -> Utils.resolve(attr, p.fixtureConfigurator().lookUp(holder.apply(a).apply(c).apply(p)), p),
        () -> String.format("attributeValueOf(%s, %s)", attr, holder)
    );
  }

  public static  Resolver profileValue(String key) {
    return Resolver.of(
        a -> c -> p -> p.profile().resolverFor(key).apply(a).apply(c).apply(p),
        () -> String.format("profileValueOf(%s)", key)
    );
  }

  /**
   * Returned resolver will give a value specified by a {@code key} from a slot.
   *
   * @param key A key to specify a value in a slot
   * @param  Type of attribute
   * @param  Type of returned value.
   */
  public static  Resolver slotValue(String key) {
    return Resolver.of(
        a -> c -> p -> p.profile().slotFor(c.ref()).resolverFor(key).apply(a).apply(c).apply(p),
        () -> String.format("slotValueOf(%s)", key)
    );
  }

  @SuppressWarnings("unchecked")
  public static 
  Resolver> listOf(Class type, Resolver... resolvers) {
    return listOf(type, asList(resolvers));
  }

  @SuppressWarnings("unchecked")
  public static 
  Resolver> listOf(Class type, List> resolvers) {
    return Resolver.of(
        a -> c -> p ->
            resolvers.stream().map(
                resolver -> resolver.apply(a, c, p)
            ).map(
                e -> require(e, o -> o == null || type.isAssignableFrom(o.getClass()), typeMismatch(a, e))
            ).collect(toList()),
        () -> String.format(
            "listOf(%s, %s)",
            type.getSimpleName(),
            String.join(
                ",",
                resolvers.stream().map(Object::toString).collect(toList())))
    );
  }

  public static 
  Resolver transform(Resolver resolver, Mapper mapper) {
    return Resolver.of(
        a -> c -> p ->
            mapper.apply(a, c, p, resolver.apply(a, c, p)),
        () -> String.format(
            "transform(%s, %s)",
            resolver,
            mapper
        )
    );
  }

  public static 
  Resolver> transformList(Resolver> resolver, Mapper mapper) {
    return Resolver.of(
        a -> c -> p ->
            resolver.apply(a, c, p).stream().map(t -> mapper.apply(a, c, p, t)).collect(toList()),
        () -> String.format(
            "transformList(%s, %s)",
            resolver,
            mapper
        )
    );
  }

  public static 
  Resolver sizeOf(Resolver> resolver) {
    return a -> c -> p -> resolver.apply(a, c, p).size();
  }


  /**
   * Returns a resolver that always throw a missing value exception.
   * This method is useful to define an attribute that does not have a default value,
   * i.e., a 'required' attribute.
   *
   * @param  Type of attribute
   * @param  Type of an expected value.
   * @return A resolver that throws an exception always when applied.
   */
  public static  Resolver nothing() {
    return Resolver.of(
        a -> c -> p -> {
          throw Exceptions.missingValue(c.ref(), a).get();
        },
        () -> "nothing"
    );
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy