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

io.kroxylicious.proxy.config.model.Visitor Maven / Gradle / Ivy

package io.kroxylicious.proxy.config.model;

import java.util.Map.Entry;
import java.lang.Class;
import java.lang.FunctionalInterface;
import java.lang.Object;
import java.util.List;
import java.lang.String;
import java.lang.reflect.Method;
import java.lang.Boolean;
import java.util.function.Predicate;
@FunctionalInterface
public interface Visitor{
  
  
  default Class getType() {
    List args = Visitors.getTypeArguments(Visitor.class, getClass());
        if (args == null || args.isEmpty()) {
          return null;
        }
        return (Class) args.get(0);
  }
  
  void visit(T element);
  default int order() {
    return 0;
  }
  
  default void visit(List> path,T element) {
    visit(element);
  }
  
  default Boolean canVisit(List> path,F target) {
    if (target == null) {
          return false;
        }
    
        if (getType() == null) {
          return hasVisitMethodMatching(target);
        } else if (!getType().isAssignableFrom(target.getClass())) {
          return false;
        }
    
        try {
          return getRequirement().test(path);
        } catch (ClassCastException e) {
          // This will happen if predicte does not match the Object.
          // So, instead of using reflection to determine that, let's just catch the error
          return false;
        }
  }
  
  default Boolean hasVisitMethodMatching(F target) {
    for (Method method : getClass().getMethods()) {
          if (!method.getName().equals("visit") || method.getParameterTypes().length != 1) {
            continue;
          }
          Class visitorType = method.getParameterTypes()[0];
          if (visitorType.isAssignableFrom(target.getClass())) {
            return true;
          } else {
            return false;
          }
        }
        return false;
  }
  
  default Predicate>> getRequirement() {
    return p -> true;
  }
  
  default Predicate>> hasItem(Class type,Predicate predicate) {
    Predicate>> result = l -> l.stream().map(Entry::getValue).filter(i -> type.isInstance(i))
            .map(i -> type.cast(i)).anyMatch(predicate);
        return result;
  }
  
  default 

Visitor addRequirement(Class

type,Predicate

predicate) { return addRequirement(predicate); } default Visitor addRequirement(Predicate predicate) { return new DelegatingVisitor(getType(), this) { @Override public Predicate> getRequirement() { return Visitor.this.getRequirement().and(predicate); } }; } }