Package com.mangofactory.swagger.models.alternates

Source Code of com.mangofactory.swagger.models.alternates.WildcardType

package com.mangofactory.swagger.models.alternates;

import com.fasterxml.classmate.ResolvedType;
import com.fasterxml.classmate.TypeBindings;
import com.fasterxml.classmate.TypeResolver;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;

import java.lang.reflect.Type;
import java.util.Iterator;
import java.util.List;

import static com.google.common.collect.Iterables.*;
import static com.google.common.collect.Lists.*;

public class WildcardType {
  public static boolean hasWildcards(ResolvedType type) {
    return any(type.getTypeBindings().getTypeParameters(), thatAreWildcards());
  }

  private static Predicate<ResolvedType> thatAreWildcards() {
    return new Predicate<ResolvedType>() {
      @Override
      public boolean apply(ResolvedType input) {
        return WildcardType.class.equals(input.getErasedType()) || hasWildcards(input);
      }
    };
  }

  public static boolean exactMatch(ResolvedType first, ResolvedType second) {
    return first.equals(second);
  }

  public static boolean wildcardMatch(ResolvedType toMatch, ResolvedType wildcardType) {
    if (!toMatch.getErasedType().equals(wildcardType.getErasedType())) {
      return false;
    }
    if (!typeBindingsAreOfSameSize(wildcardType, toMatch)) {
      return false;
    }
    TypeBindings wildcardTypeBindings = wildcardType.getTypeBindings();
    TypeBindings bindingsToMatch = toMatch.getTypeBindings();
    for (int index = 0; index < bindingsToMatch.size(); index++) {
      ResolvedType wildcardTypeBindingsBoundType = wildcardTypeBindings.getBoundType(index);
      ResolvedType bindingsToMatchBoundType = bindingsToMatch.getBoundType(index);

      if (!wildcardTypeBindingsBoundType.getErasedType().equals(WildcardType.class)
              && !wildcardMatch(bindingsToMatchBoundType, wildcardTypeBindingsBoundType)) {
        return false;
      }
    }
    return true;
  }

  private static boolean typeBindingsAreOfSameSize(ResolvedType toMatch, ResolvedType wildcardType) {
    TypeBindings wildcardTypeBindings = wildcardType.getTypeBindings();
    TypeBindings bindingsToMatch = toMatch.getTypeBindings();
    return bindingsToMatch.size() == wildcardTypeBindings.size();
  }

  static ResolvedType replaceWildcardsFrom(Iterable<ResolvedType> replaceables, ResolvedType wildcardType) {
    Iterator<ResolvedType> replaceableIterator = replaceables.iterator();
    return breadthFirstReplace(replaceableIterator, wildcardType);
  }

  private static ResolvedType breadthFirstReplace(Iterator<ResolvedType> replaceableIterator,
                                                  ResolvedType wildcardType) {
    if (WildcardType.class.equals(wildcardType.getErasedType())) {
      if (replaceableIterator.hasNext()) {
        return replaceableIterator.next();
      } else {
        throw new IllegalStateException("Expecting the same number of wildcard types as the replaceables");
      }

    }
    TypeBindings wildcardTypeBindings = wildcardType.getTypeBindings();
    List<Type> bindings = newArrayList();
    for (int index = 0; index < wildcardTypeBindings.size(); index++) {
      if (WildcardType.class.equals(wildcardTypeBindings.getBoundType(index).getErasedType())) {
        if (replaceableIterator.hasNext()) {
          bindings.add(replaceableIterator.next());
        } else {
          throw new IllegalStateException("Count of wildcards to candidates do not match");
        }
      } else {
        bindings.add(breadthFirstReplace(replaceableIterator, wildcardTypeBindings.getBoundType(index)));
      }
    }
    return new TypeResolver().resolve(wildcardType.getErasedType(), toArray(bindings, Type.class));
  }

  static List<ResolvedType> collectReplaceables(ResolvedType replacingType, ResolvedType wildcardType) {
    return breadthFirstSearch(replacingType, wildcardType);
  }

  private static List<ResolvedType> breadthFirstSearch(ResolvedType replacingType, ResolvedType wildcardType) {
    TypeBindings wildcardTypeBindings = wildcardType.getTypeBindings();
    TypeBindings bindingsToMatch = replacingType.getTypeBindings();
    Preconditions.checkArgument(typeBindingsAreOfSameSize(wildcardType, replacingType));
    List<ResolvedType> bindings = newArrayList();
    for (int index = 0; index < bindingsToMatch.size(); index++) {
      if (WildcardType.class.equals(wildcardTypeBindings.getBoundType(index).getErasedType())) {
        bindings.add(bindingsToMatch.getBoundType(index));
      } else {
        bindings.addAll(breadthFirstSearch(bindingsToMatch.getBoundType(index),
                wildcardTypeBindings.getBoundType(index)));
      }
    }
    return bindings;
  }
}
TOP

Related Classes of com.mangofactory.swagger.models.alternates.WildcardType

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.