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

org.springframework.core.annotation.MergedAnnotationCollectors Maven / Gradle / Ivy

/*
 * Copyright 2002-2020 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.core.annotation;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.stream.Collector;
import java.util.stream.Collector.Characteristics;

import org.springframework.core.annotation.MergedAnnotation.Adapt;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

/**
 * {@link Collector} implementations that provide various reduction operations for
 * {@link MergedAnnotation} instances.
 *
 * @author Phillip Webb
 * @author Sam Brannen
 * @since 5.2
 */
public abstract class MergedAnnotationCollectors {

	private static final Characteristics[] NO_CHARACTERISTICS = {};

	private static final Characteristics[] IDENTITY_FINISH_CHARACTERISTICS = {Characteristics.IDENTITY_FINISH};


	private MergedAnnotationCollectors() {
	}


	/**
	 * Create a new {@link Collector} that accumulates merged annotations to a
	 * {@link LinkedHashSet} containing {@linkplain MergedAnnotation#synthesize()
	 * synthesized} versions.
	 * 

The collector returned by this method is effectively equivalent to * {@code Collectors.mapping(MergedAnnotation::synthesize, Collectors.toCollection(LinkedHashSet::new))} * but avoids the creation of a composite collector. * @param the annotation type * @return a {@link Collector} which collects and synthesizes the * annotations into a {@link Set} */ public static Collector, ?, Set> toAnnotationSet() { return Collector.of(LinkedHashSet::new, (set, annotation) -> set.add(annotation.synthesize()), MergedAnnotationCollectors::combiner); } /** * Create a new {@link Collector} that accumulates merged annotations to an * {@link Annotation} array containing {@linkplain MergedAnnotation#synthesize() * synthesized} versions. * @param the annotation type * @return a {@link Collector} which collects and synthesizes the * annotations into an {@code Annotation[]} * @see #toAnnotationArray(IntFunction) */ public static Collector, ?, Annotation[]> toAnnotationArray() { return toAnnotationArray(Annotation[]::new); } /** * Create a new {@link Collector} that accumulates merged annotations to an * {@link Annotation} array containing {@linkplain MergedAnnotation#synthesize() * synthesized} versions. * @param the annotation type * @param the resulting array type * @param generator a function which produces a new array of the desired * type and the provided length * @return a {@link Collector} which collects and synthesizes the * annotations into an annotation array * @see #toAnnotationArray */ public static Collector, ?, R[]> toAnnotationArray( IntFunction generator) { return Collector.of(ArrayList::new, (list, annotation) -> list.add(annotation.synthesize()), MergedAnnotationCollectors::combiner, list -> list.toArray(generator.apply(list.size()))); } /** * Create a new {@link Collector} that accumulates merged annotations to a * {@link MultiValueMap} with items {@linkplain MultiValueMap#add(Object, Object) * added} from each merged annotation * {@linkplain MergedAnnotation#asMap(Adapt...) as a map}. * @param the annotation type * @param adaptations the adaptations that should be applied to the annotation values * @return a {@link Collector} which collects and synthesizes the * annotations into a {@link LinkedMultiValueMap} * @see #toMultiValueMap(Function, MergedAnnotation.Adapt...) */ public static Collector, ?, MultiValueMap> toMultiValueMap( Adapt... adaptations) { return toMultiValueMap(Function.identity(), adaptations); } /** * Create a new {@link Collector} that accumulates merged annotations to a * {@link MultiValueMap} with items {@linkplain MultiValueMap#add(Object, Object) * added} from each merged annotation * {@linkplain MergedAnnotation#asMap(Adapt...) as a map}. * @param the annotation type * @param finisher the finisher function for the new {@link MultiValueMap} * @param adaptations the adaptations that should be applied to the annotation values * @return a {@link Collector} which collects and synthesizes the * annotations into a {@link LinkedMultiValueMap} * @see #toMultiValueMap(MergedAnnotation.Adapt...) */ public static Collector, ?, MultiValueMap> toMultiValueMap( Function, MultiValueMap> finisher, Adapt... adaptations) { Characteristics[] characteristics = (isSameInstance(finisher, Function.identity()) ? IDENTITY_FINISH_CHARACTERISTICS : NO_CHARACTERISTICS); return Collector.of(LinkedMultiValueMap::new, (map, annotation) -> annotation.asMap(adaptations).forEach(map::add), MergedAnnotationCollectors::combiner, finisher, characteristics); } private static boolean isSameInstance(Object instance, Object candidate) { return instance == candidate; } /** * {@link Collector#combiner() Combiner} for collections. *

This method is only invoked if the {@link java.util.stream.Stream} is * processed in {@linkplain java.util.stream.Stream#parallel() parallel}. */ private static > C combiner(C collection, C additions) { collection.addAll(additions); return collection; } /** * {@link Collector#combiner() Combiner} for multi-value maps. *

This method is only invoked if the {@link java.util.stream.Stream} is * processed in {@linkplain java.util.stream.Stream#parallel() parallel}. */ private static MultiValueMap combiner(MultiValueMap map, MultiValueMap additions) { map.addAll(additions); return map; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy