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

org.springframework.web.method.HandlerTypePredicate Maven / Gradle / Ivy

There is a newer version: 6.1.6
Show newest version
/*
 * Copyright 2002-2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.web.method;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;

import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

/**
 * A {@code Predicate} to match request handling component types if
 * any of the following selectors match:
 * 
    *
  • Base packages -- for selecting handlers by their package. *
  • Assignable types -- for selecting handlers by super type. *
  • Annotations -- for selecting handlers annotated in a specific way. *
*

Composability methods on {@link Predicate} can be used : *

 * Predicate<Class<?>> predicate =
 * 		HandlerTypePredicate.forAnnotation(RestController.class)
 * 				.and(HandlerTypePredicate.forBasePackage("org.example"));
 * 
* * @author Rossen Stoyanchev * @since 5.1 */ public final class HandlerTypePredicate implements Predicate> { private final Set basePackages; private final List> assignableTypes; private final List> annotations; /** * Private constructor. See static factory methods. */ private HandlerTypePredicate(Set basePackages, List> assignableTypes, List> annotations) { this.basePackages = Collections.unmodifiableSet(basePackages); this.assignableTypes = Collections.unmodifiableList(assignableTypes); this.annotations = Collections.unmodifiableList(annotations); } @Override public boolean test(Class controllerType) { if (!hasSelectors()) { return true; } else if (controllerType != null) { for (String basePackage : this.basePackages) { if (controllerType.getName().startsWith(basePackage)) { return true; } } for (Class clazz : this.assignableTypes) { if (ClassUtils.isAssignable(clazz, controllerType)) { return true; } } for (Class annotationClass : this.annotations) { if (AnnotationUtils.findAnnotation(controllerType, annotationClass) != null) { return true; } } } return false; } private boolean hasSelectors() { return (!this.basePackages.isEmpty() || !this.assignableTypes.isEmpty() || !this.annotations.isEmpty()); } // Static factory methods /** * {@code Predicate} that applies to any handlers. */ public static HandlerTypePredicate forAnyHandlerType() { return new HandlerTypePredicate( Collections.emptySet(), Collections.emptyList(), Collections.emptyList()); } /** * Match handlers declared under a base package, e.g. "org.example". * @param packages one or more base package names */ public static HandlerTypePredicate forBasePackage(String... packages) { return new Builder().basePackage(packages).build(); } /** * Type-safe alternative to {@link #forBasePackage(String...)} to specify a * base package through a class. * @param packageClasses one or more base package classes */ public static HandlerTypePredicate forBasePackageClass(Class... packageClasses) { return new Builder().basePackageClass(packageClasses).build(); } /** * Match handlers that are assignable to a given type. * @param types one or more handler super types */ public static HandlerTypePredicate forAssignableType(Class... types) { return new Builder().assignableType(types).build(); } /** * Match handlers annotated with a specific annotation. * @param annotations one or more annotations to check for */ @SafeVarargs public static HandlerTypePredicate forAnnotation(Class... annotations) { return new Builder().annotation(annotations).build(); } /** * Return a builder for a {@code HandlerTypePredicate}. */ public static Builder builder() { return new Builder(); } /** * A {@link HandlerTypePredicate} builder. */ public static class Builder { private final Set basePackages = new LinkedHashSet<>(); private final List> assignableTypes = new ArrayList<>(); private final List> annotations = new ArrayList<>(); /** * Match handlers declared under a base package, e.g. "org.example". * @param packages one or more base package classes */ public Builder basePackage(String... packages) { Arrays.stream(packages).filter(StringUtils::hasText).forEach(this::addBasePackage); return this; } /** * Type-safe alternative to {@link #forBasePackage(String...)} to specify a * base package through a class. * @param packageClasses one or more base package names */ public Builder basePackageClass(Class... packageClasses) { Arrays.stream(packageClasses).forEach(clazz -> addBasePackage(ClassUtils.getPackageName(clazz))); return this; } private void addBasePackage(String basePackage) { this.basePackages.add(basePackage.endsWith(".") ? basePackage : basePackage + "."); } /** * Match handlers that are assignable to a given type. * @param types one or more handler super types */ public Builder assignableType(Class... types) { this.assignableTypes.addAll(Arrays.asList(types)); return this; } /** * Match types that are annotated with one of the given annotations. * @param annotations one or more annotations to check for */ @SuppressWarnings("unchecked") public final Builder annotation(Class... annotations) { this.annotations.addAll(Arrays.asList(annotations)); return this; } public HandlerTypePredicate build() { return new HandlerTypePredicate(this.basePackages, this.assignableTypes, this.annotations); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy