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

org.springframework.aot.hint.ResourcePatternHints Maven / Gradle / Ivy

There is a newer version: 6.1.6
Show newest version
/*
 * Copyright 2002-2022 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
 *
 *      https://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.aot.hint;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.springframework.lang.Nullable;

/**
 * A collection of {@link ResourcePatternHint} describing whether resources should
 * be made available at runtime using a matching algorithm based on include/exclude
 * patterns.
 *
 * @author Stephane Nicoll
 * @author Brian Clozel
 * @author Sam Brannen
 * @since 6.0
 */
public final class ResourcePatternHints {

	private final List includes;

	private final List excludes;


	private ResourcePatternHints(Builder builder) {
		this.includes = new ArrayList<>(builder.includes);
		this.excludes = new ArrayList<>(builder.excludes);
	}

	/**
	 * Return the include patterns to use to identify the resources to match.
	 * @return the include patterns
	 */
	public List getIncludes() {
		return this.includes;
	}

	/**
	 * Return the exclude patterns to use to identify the resources to match.
	 * @return the exclude patterns
	 */
	public List getExcludes() {
		return this.excludes;
	}


	/**
	 * Builder for {@link ResourcePatternHints}.
	 */
	public static class Builder {

		private final Set includes = new LinkedHashSet<>();

		private final Set excludes = new LinkedHashSet<>();

		Builder() {
		}

		/**
		 * Include resources matching the specified patterns.
		 * @param reachableType the type that should be reachable for this hint to apply
		 * @param includes the include patterns (see {@link ResourcePatternHint} documentation)
		 * @return {@code this}, to facilitate method chaining
		 */
		public Builder includes(@Nullable TypeReference reachableType, String... includes) {
			Arrays.stream(includes)
					.map(this::expandToIncludeDirectories)
					.flatMap(List::stream)
					.map(include -> new ResourcePatternHint(include, reachableType))
					.forEach(this.includes::add);
			return this;
		}

		/**
		 * Expand the supplied include pattern into multiple patterns that include
		 * all parent directories for the ultimate resource or resources.
		 * 

This is necessary to support classpath scanning within a GraalVM * native image. * @see gh-29403 */ private List expandToIncludeDirectories(String includePattern) { // Resource in root or no explicit subdirectories? if (!includePattern.contains("/")) { // Include the root directory as well as the pattern return List.of("/", includePattern); } List includePatterns = new ArrayList<>(); // Ensure the root directory and original pattern are always included includePatterns.add("/"); includePatterns.add(includePattern); StringBuilder path = new StringBuilder(); for (String pathElement : includePattern.split("/")) { if (pathElement.isEmpty()) { // Skip empty path elements continue; } if (pathElement.contains("*")) { // Stop at the first encountered wildcard, since we cannot reliably reason // any further about the directory structure below this path element. break; } if (!path.isEmpty()) { path.append("/"); } path.append(pathElement); includePatterns.add(path.toString()); } return includePatterns; } /** * Include resources matching the specified patterns. * @param includes the include patterns (see {@link ResourcePatternHint} documentation) * @return {@code this}, to facilitate method chaining */ public Builder includes(String... includes) { return includes(null, includes); } /** * Exclude resources matching the specified patterns. * @param reachableType the type that should be reachable for this hint to apply * @param excludes the exclude patterns (see {@link ResourcePatternHint} documentation) * @return {@code this}, to facilitate method chaining */ public Builder excludes(TypeReference reachableType, String... excludes) { List newExcludes = Arrays.stream(excludes) .map(include -> new ResourcePatternHint(include, reachableType)).toList(); this.excludes.addAll(newExcludes); return this; } /** * Exclude resources matching the specified patterns. * @param excludes the exclude patterns (see {@link ResourcePatternHint} documentation) * @return {@code this}, to facilitate method chaining */ public Builder excludes(String... excludes) { return excludes(null, excludes); } /** * Create {@link ResourcePatternHints} based on the state of this * builder. * @return resource pattern hints */ ResourcePatternHints build() { return new ResourcePatternHints(this); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy