Package com.mangofactory.swagger.scanners

Source Code of com.mangofactory.swagger.scanners.ApiListingReferenceScanner

package com.mangofactory.swagger.scanners;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimaps;
import com.mangofactory.swagger.core.ResourceGroupingStrategy;
import com.mangofactory.swagger.paths.SwaggerPathProvider;
import com.wordnik.swagger.model.ApiListingReference;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.Assert;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import static com.google.common.collect.Lists.*;
import static com.mangofactory.swagger.ScalaUtils.*;
import static java.lang.String.*;

public class ApiListingReferenceScanner {
  private static final String REQUEST_MAPPINGS_EMPTY =
          "No RequestMappingHandlerMapping's found have you added <mvc:annotation-driven/>";

  private static final Logger log = LoggerFactory.getLogger(ApiListingReferenceScanner.class);
  private List<RequestMappingHandlerMapping> requestMappingHandlerMapping;
  private List<ApiListingReference> apiListingReferences = newArrayList();
  private ArrayListMultimap<ResourceGroup, RequestMappingContext> resourceGroupRequestMappings = ArrayListMultimap
          .create();
  private String swaggerGroup;
  private List<Class<? extends Annotation>> excludeAnnotations;
  private ResourceGroupingStrategy resourceGroupingStrategy;
  private SwaggerPathProvider swaggerPathProvider;
  private List<String> includePatterns = newArrayList(".*?");
  private RequestMappingPatternMatcher requestMappingPatternMatcher = new RegexRequestMappingPatternMatcher();

  public ApiListingReferenceScanner() {
  }

  public List<ApiListingReference> scan() {
    Assert.notNull(requestMappingHandlerMapping, REQUEST_MAPPINGS_EMPTY);
    Assert.notEmpty(requestMappingHandlerMapping, REQUEST_MAPPINGS_EMPTY);
    Assert.notNull(resourceGroupingStrategy, "resourceGroupingStrategy is required");
    Assert.notNull(swaggerGroup, "swaggerGroup is required");
    if (StringUtils.isBlank(swaggerGroup)) {
      throw new IllegalArgumentException("swaggerGroup must not be empty");
    }
    Assert.notNull(swaggerPathProvider, "swaggerPathProvider is required");

    log.info("Scanning for api listing references");
    scanSpringRequestMappings();
    return this.apiListingReferences;
  }

  public void scanSpringRequestMappings() {
    Map<ResourceGroup, String> resourceGroupDescriptions = new HashMap<ResourceGroup, String>();
    for (RequestMappingHandlerMapping requestMappingHandlerMapping : this.requestMappingHandlerMapping) {
      for (Entry<RequestMappingInfo, HandlerMethod> handlerMethodEntry :
              requestMappingHandlerMapping.getHandlerMethods().entrySet()) {
        RequestMappingInfo requestMappingInfo = handlerMethodEntry.getKey();
        HandlerMethod handlerMethod = handlerMethodEntry.getValue();
        if (shouldIncludeRequestMapping(requestMappingInfo, handlerMethod)) {
          Set<ResourceGroup> resourceGroups = resourceGroupingStrategy.getResourceGroups(requestMappingInfo,
                  handlerMethod);
          String handlerMethodName = handlerMethod.getMethod().getName();

          String resourceDescription = resourceGroupingStrategy.getResourceDescription(requestMappingInfo,
                  handlerMethod);
          RequestMappingContext requestMappingContext = new RequestMappingContext(requestMappingInfo,
                  handlerMethod);

          log.info("Request mapping: {} belongs to groups: [{}] ", handlerMethodName, resourceGroups);
          for (ResourceGroup group : resourceGroups) {
            resourceGroupDescriptions.put(group, resourceDescription);

            log.info("Adding resource to group:{} with description:{} for handler method:{}",
                    group, resourceDescription, handlerMethodName);

            resourceGroupRequestMappings.put(group, requestMappingContext);
          }
        }
      }
    }

    for (ResourceGroup resourceGroup : resourceGroupDescriptions.keySet()) {
      String resourceGroupName = resourceGroup.getGroupName();
      String listingDescription = resourceGroupDescriptions.get(resourceGroup);
      Integer position = resourceGroup.getPosition();
      String path = swaggerPathProvider.getResourceListingPath(swaggerGroup, resourceGroupName);
      log.info("Created resource listing Path: {} Description: {} Position: {}",
              path, resourceGroupName, position);
      this.apiListingReferences.add(new ApiListingReference(path, toOption(listingDescription), position));
    }
  }

  private boolean requestMappingMatchesAnIncludePattern(RequestMappingInfo requestMappingInfo,
                                                        HandlerMethod handlerMethod) {
    PatternsRequestCondition patternsCondition = requestMappingInfo.getPatternsCondition();
    boolean isMatch = requestMappingPatternMatcher.patternConditionsMatchOneOfIncluded(patternsCondition,
            includePatterns);
    if (isMatch) {
      return true;
    }
    log.info(format("RequestMappingInfo did not match any include patterns: | %s", requestMappingInfo));
    return false;
  }

  private boolean shouldIncludeRequestMapping(RequestMappingInfo requestMappingInfo, HandlerMethod handlerMethod) {
    return requestMappingMatchesAnIncludePattern(requestMappingInfo, handlerMethod)
            && !classHasIgnoredAnnotatedRequestMapping(handlerMethod.getMethod().getDeclaringClass())
            && !hasIgnoredAnnotatedRequestMapping(handlerMethod);
  }

  public boolean classHasIgnoredAnnotatedRequestMapping(Class<?> handlerClass) {
    if (null != excludeAnnotations) {
      for (Class<? extends Annotation> annotation : excludeAnnotations) {
        if (handlerClass.isAnnotationPresent(annotation)) {
          log.info(format("Excluding method as its class is annotated with: %s", annotation));
          return true;
        }
      }
    }
    return false;
  }

  public boolean hasIgnoredAnnotatedRequestMapping(HandlerMethod handlerMethod) {
    if (null != excludeAnnotations) {
      for (Class<? extends Annotation> annotation : excludeAnnotations) {
        if (null != AnnotationUtils.findAnnotation(handlerMethod.getMethod(), annotation)) {
          log.info(format("Excluding method as it contains the excluded annotation: %s", annotation));
          return true;
        }
      }
    }
    return false;
  }

  public Map<ResourceGroup, List<RequestMappingContext>> getResourceGroupRequestMappings() {
    return Multimaps.asMap(resourceGroupRequestMappings);
  }

  public List<RequestMappingHandlerMapping> getRequestMappingHandlerMapping() {
    return requestMappingHandlerMapping;
  }

  public void setRequestMappingHandlerMapping(List<RequestMappingHandlerMapping> requestMappingHandlerMapping) {
    this.requestMappingHandlerMapping = requestMappingHandlerMapping;
  }

  public List<ApiListingReference> getApiListingReferences() {
    return apiListingReferences;
  }

  public void setApiListingReferences(List<ApiListingReference> apiListingReferences) {
    this.apiListingReferences = apiListingReferences;
  }

  public void setResourceGroupRequestMappings(ArrayListMultimap<ResourceGroup,
          RequestMappingContext> resourceGroupRequestMappings) {
    this.resourceGroupRequestMappings = resourceGroupRequestMappings;
  }

  public String getSwaggerGroup() {
    return swaggerGroup;
  }

  public void setSwaggerGroup(String swaggerGroup) {
    this.swaggerGroup = swaggerGroup;
  }

  public List<Class<? extends Annotation>> getExcludeAnnotations() {
    return excludeAnnotations;
  }

  public void setExcludeAnnotations(List<Class<? extends Annotation>> excludeAnnotations) {
    this.excludeAnnotations = excludeAnnotations;
  }

  public ResourceGroupingStrategy getResourceGroupingStrategy() {
    return resourceGroupingStrategy;
  }

  public void setResourceGroupingStrategy(ResourceGroupingStrategy resourceGroupingStrategy) {
    this.resourceGroupingStrategy = resourceGroupingStrategy;
  }

  public SwaggerPathProvider getSwaggerPathProvider() {
    return swaggerPathProvider;
  }

  public void setSwaggerPathProvider(SwaggerPathProvider swaggerPathProvider) {
    this.swaggerPathProvider = swaggerPathProvider;
  }

  public List<String> getIncludePatterns() {
    return includePatterns;
  }

  public void setIncludePatterns(List<String> includePatterns) {
    this.includePatterns = includePatterns;
  }

  public RequestMappingPatternMatcher getRequestMappingPatternMatcher() {
    return requestMappingPatternMatcher;
  }

  public void setRequestMappingPatternMatcher(RequestMappingPatternMatcher requestMappingPatternMatcher) {
    this.requestMappingPatternMatcher = requestMappingPatternMatcher;
  }
}
TOP

Related Classes of com.mangofactory.swagger.scanners.ApiListingReferenceScanner

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.