parent
17cdd97c37
commit
4750a9430c
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2019 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.beans.annotation;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.BeanWrapper;
|
||||
import org.springframework.beans.PropertyAccessorFactory;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringValueResolver;
|
||||
|
||||
/**
|
||||
* General utility methods for working with annotations in JavaBeans style.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
* @deprecated as of 5.2, in favor of custom annotation attribute processing
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class AnnotationBeanUtils {
|
||||
|
||||
/**
|
||||
* Copy the properties of the supplied {@link Annotation} to the supplied target bean.
|
||||
* Any properties defined in {@code excludedProperties} will not be copied.
|
||||
* @param ann the annotation to copy from
|
||||
* @param bean the bean instance to copy to
|
||||
* @param excludedProperties the names of excluded properties, if any
|
||||
* @see org.springframework.beans.BeanWrapper
|
||||
*/
|
||||
public static void copyPropertiesToBean(Annotation ann, Object bean, String... excludedProperties) {
|
||||
copyPropertiesToBean(ann, bean, null, excludedProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the properties of the supplied {@link Annotation} to the supplied target bean.
|
||||
* Any properties defined in {@code excludedProperties} will not be copied.
|
||||
* <p>A specified value resolver may resolve placeholders in property values, for example.
|
||||
* @param ann the annotation to copy from
|
||||
* @param bean the bean instance to copy to
|
||||
* @param valueResolver a resolve to post-process String property values (may be {@code null})
|
||||
* @param excludedProperties the names of excluded properties, if any
|
||||
* @see org.springframework.beans.BeanWrapper
|
||||
*/
|
||||
public static void copyPropertiesToBean(Annotation ann, Object bean, @Nullable StringValueResolver valueResolver,
|
||||
String... excludedProperties) {
|
||||
|
||||
Set<String> excluded = (excludedProperties.length == 0 ? Collections.emptySet() :
|
||||
new HashSet<>(Arrays.asList(excludedProperties)));
|
||||
Method[] annotationProperties = ann.annotationType().getDeclaredMethods();
|
||||
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(bean);
|
||||
for (Method annotationProperty : annotationProperties) {
|
||||
String propertyName = annotationProperty.getName();
|
||||
if (!excluded.contains(propertyName) && bw.isWritableProperty(propertyName)) {
|
||||
Object value = ReflectionUtils.invokeMethod(annotationProperty, ann);
|
||||
if (valueResolver != null && value instanceof String) {
|
||||
value = valueResolver.resolveStringValue((String) value);
|
||||
}
|
||||
bw.setPropertyValue(propertyName, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
/**
|
||||
* Support package for beans-style handling of Java 5 annotations.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.beans.annotation;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
|
@ -419,14 +419,6 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
|
|||
return pvs;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public PropertyValues postProcessPropertyValues(
|
||||
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {
|
||||
|
||||
return postProcessProperties(pvs, bean, beanName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 'Native' processing method for direct calls with an arbitrary target instance,
|
||||
* resolving all of its fields and methods which are annotated with one of the
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.beans.factory.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Marks a method (typically a JavaBean setter method) as being 'required': that is,
|
||||
* the setter method must be configured to be dependency-injected with a value.
|
||||
*
|
||||
* <p>Please do consult the javadoc for the {@link RequiredAnnotationBeanPostProcessor}
|
||||
* class (which, by default, checks for the presence of this annotation).
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @since 2.0
|
||||
* @see RequiredAnnotationBeanPostProcessor
|
||||
* @deprecated as of 5.1, in favor of using constructor injection for required settings
|
||||
* (or a custom {@link org.springframework.beans.factory.InitializingBean} implementation)
|
||||
*/
|
||||
@Deprecated
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface Required {
|
||||
|
||||
}
|
|
@ -1,230 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2021 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.beans.factory.annotation;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.beans.PropertyValues;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
|
||||
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.core.Conventions;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.PriorityOrdered;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation
|
||||
* that enforces required JavaBean properties to have been configured.
|
||||
* Required bean properties are detected through a Java 5 annotation:
|
||||
* by default, Spring's {@link Required} annotation.
|
||||
*
|
||||
* <p>The motivation for the existence of this BeanPostProcessor is to allow
|
||||
* developers to annotate the setter properties of their own classes with an
|
||||
* arbitrary JDK 1.5 annotation to indicate that the container must check
|
||||
* for the configuration of a dependency injected value. This neatly pushes
|
||||
* responsibility for such checking onto the container (where it arguably belongs),
|
||||
* and obviates the need (<b>in part</b>) for a developer to code a method that
|
||||
* simply checks that all required properties have actually been set.
|
||||
*
|
||||
* <p>Please note that an 'init' method may still need to be implemented (and may
|
||||
* still be desirable), because all that this class does is enforcing that a
|
||||
* 'required' property has actually been configured with a value. It does
|
||||
* <b>not</b> check anything else... In particular, it does not check that a
|
||||
* configured value is not {@code null}.
|
||||
*
|
||||
* <p>Note: A default RequiredAnnotationBeanPostProcessor will be registered
|
||||
* by the "context:annotation-config" and "context:component-scan" XML tags.
|
||||
* Remove or turn off the default annotation configuration there if you intend
|
||||
* to specify a custom RequiredAnnotationBeanPostProcessor bean definition.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
* @see #setRequiredAnnotationType
|
||||
* @see Required
|
||||
* @deprecated as of 5.1, in favor of using constructor injection for required settings
|
||||
* (or a custom {@link org.springframework.beans.factory.InitializingBean} implementation)
|
||||
*/
|
||||
@Deprecated
|
||||
public class RequiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor,
|
||||
MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
|
||||
|
||||
/**
|
||||
* Bean definition attribute that may indicate whether a given bean is supposed
|
||||
* to be skipped when performing this post-processor's required property check.
|
||||
* @see #shouldSkip
|
||||
*/
|
||||
public static final String SKIP_REQUIRED_CHECK_ATTRIBUTE =
|
||||
Conventions.getQualifiedAttributeName(RequiredAnnotationBeanPostProcessor.class, "skipRequiredCheck");
|
||||
|
||||
|
||||
private Class<? extends Annotation> requiredAnnotationType = Required.class;
|
||||
|
||||
private int order = Ordered.LOWEST_PRECEDENCE - 1;
|
||||
|
||||
@Nullable
|
||||
private ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
/**
|
||||
* Cache for validated bean names, skipping re-validation for the same bean.
|
||||
*/
|
||||
private final Set<String> validatedBeanNames = Collections.newSetFromMap(new ConcurrentHashMap<>(64));
|
||||
|
||||
|
||||
/**
|
||||
* Set the 'required' annotation type, to be used on bean property
|
||||
* setter methods.
|
||||
* <p>The default required annotation type is the Spring-provided
|
||||
* {@link Required} annotation.
|
||||
* <p>This setter property exists so that developers can provide their own
|
||||
* (non-Spring-specific) annotation type to indicate that a property value
|
||||
* is required.
|
||||
*/
|
||||
public void setRequiredAnnotationType(Class<? extends Annotation> requiredAnnotationType) {
|
||||
Assert.notNull(requiredAnnotationType, "'requiredAnnotationType' must not be null");
|
||||
this.requiredAnnotationType = requiredAnnotationType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the 'required' annotation type.
|
||||
*/
|
||||
protected Class<? extends Annotation> getRequiredAnnotationType() {
|
||||
return this.requiredAnnotationType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
if (beanFactory instanceof ConfigurableListableBeanFactory) {
|
||||
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
|
||||
}
|
||||
}
|
||||
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyValues postProcessPropertyValues(
|
||||
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {
|
||||
|
||||
if (!this.validatedBeanNames.contains(beanName)) {
|
||||
if (!shouldSkip(this.beanFactory, beanName)) {
|
||||
List<String> invalidProperties = new ArrayList<>();
|
||||
for (PropertyDescriptor pd : pds) {
|
||||
if (isRequiredProperty(pd) && !pvs.contains(pd.getName())) {
|
||||
invalidProperties.add(pd.getName());
|
||||
}
|
||||
}
|
||||
if (!invalidProperties.isEmpty()) {
|
||||
throw new BeanInitializationException(buildExceptionMessage(invalidProperties, beanName));
|
||||
}
|
||||
}
|
||||
this.validatedBeanNames.add(beanName);
|
||||
}
|
||||
return pvs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given bean definition is not subject to the annotation-based
|
||||
* required property check as performed by this post-processor.
|
||||
* <p>The default implementations check for the presence of the
|
||||
* {@link #SKIP_REQUIRED_CHECK_ATTRIBUTE} attribute in the bean definition, if any.
|
||||
* It also suggests skipping in case of a bean definition with a "factory-bean"
|
||||
* reference set, assuming that instance-based factories pre-populate the bean.
|
||||
* @param beanFactory the BeanFactory to check against
|
||||
* @param beanName the name of the bean to check against
|
||||
* @return {@code true} to skip the bean; {@code false} to process it
|
||||
*/
|
||||
protected boolean shouldSkip(@Nullable ConfigurableListableBeanFactory beanFactory, String beanName) {
|
||||
if (beanFactory == null || !beanFactory.containsBeanDefinition(beanName)) {
|
||||
return false;
|
||||
}
|
||||
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
|
||||
if (beanDefinition.getFactoryBeanName() != null) {
|
||||
return true;
|
||||
}
|
||||
Object value = beanDefinition.getAttribute(SKIP_REQUIRED_CHECK_ATTRIBUTE);
|
||||
return (value != null && (Boolean.TRUE.equals(value) || Boolean.parseBoolean(value.toString())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the supplied property required to have a value (that is, to be dependency-injected)?
|
||||
* <p>This implementation looks for the existence of a
|
||||
* {@link #setRequiredAnnotationType "required" annotation}
|
||||
* on the supplied {@link PropertyDescriptor property}.
|
||||
* @param propertyDescriptor the target PropertyDescriptor (never {@code null})
|
||||
* @return {@code true} if the supplied property has been marked as being required;
|
||||
* {@code false} if not, or if the supplied property does not have a setter method
|
||||
*/
|
||||
protected boolean isRequiredProperty(PropertyDescriptor propertyDescriptor) {
|
||||
Method setter = propertyDescriptor.getWriteMethod();
|
||||
return (setter != null && AnnotationUtils.getAnnotation(setter, getRequiredAnnotationType()) != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an exception message for the given list of invalid properties.
|
||||
* @param invalidProperties the list of names of invalid properties
|
||||
* @param beanName the name of the bean
|
||||
* @return the exception message
|
||||
*/
|
||||
private String buildExceptionMessage(List<String> invalidProperties, String beanName) {
|
||||
int size = invalidProperties.size();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(size == 1 ? "Property" : "Properties");
|
||||
for (int i = 0; i < size; i++) {
|
||||
String propertyName = invalidProperties.get(i);
|
||||
if (i > 0) {
|
||||
if (i == (size - 1)) {
|
||||
sb.append(" and");
|
||||
}
|
||||
else {
|
||||
sb.append(',');
|
||||
}
|
||||
}
|
||||
sb.append(" '").append(propertyName).append('\'');
|
||||
}
|
||||
sb.append(size == 1 ? " is" : " are");
|
||||
sb.append(" required for bean '").append(beanName).append('\'');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -220,26 +220,6 @@ public class DependencyDescriptor extends InjectionPoint implements Serializable
|
|||
throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the specified not-unique scenario: by default,
|
||||
* throwing a {@link NoUniqueBeanDefinitionException}.
|
||||
* <p>Subclasses may override this to select one of the instances or
|
||||
* to opt out with no result at all through returning {@code null}.
|
||||
* @param type the requested bean type
|
||||
* @param matchingBeans a map of bean names and corresponding bean
|
||||
* instances which have been pre-selected for the given type
|
||||
* (qualifiers etc already applied)
|
||||
* @return a bean instance to proceed with, or {@code null} for none
|
||||
* @throws BeansException in case of the not-unique scenario being fatal
|
||||
* @since 4.3
|
||||
* @deprecated as of 5.1, in favor of {@link #resolveNotUnique(ResolvableType, Map)}
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
public Object resolveNotUnique(Class<?> type, Map<String, Object> matchingBeans) throws BeansException {
|
||||
throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a shortcut for this dependency against the given factory, for example
|
||||
* taking some pre-resolved information into account.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -16,8 +16,6 @@
|
|||
|
||||
package org.springframework.beans.factory.config;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.PropertyValues;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
@ -34,9 +32,7 @@ import org.springframework.lang.Nullable;
|
|||
*
|
||||
* <p><b>NOTE:</b> This interface is a special purpose interface, mainly for
|
||||
* internal use within the framework. It is recommended to implement the plain
|
||||
* {@link BeanPostProcessor} interface as far as possible, or to derive from
|
||||
* {@link InstantiationAwareBeanPostProcessorAdapter} in order to be shielded
|
||||
* from extensions to this interface.
|
||||
* {@link BeanPostProcessor} interface as far as possible.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rod Johnson
|
||||
|
@ -96,53 +92,19 @@ public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
|
|||
|
||||
/**
|
||||
* Post-process the given property values before the factory applies them
|
||||
* to the given bean, without any need for property descriptors.
|
||||
* <p>Implementations should return {@code null} (the default) if they provide a custom
|
||||
* {@link #postProcessPropertyValues} implementation, and {@code pvs} otherwise.
|
||||
* In a future version of this interface (with {@link #postProcessPropertyValues} removed),
|
||||
* the default implementation will return the given {@code pvs} as-is directly.
|
||||
* @param pvs the property values that the factory is about to apply (never {@code null})
|
||||
* @param bean the bean instance created, but whose properties have not yet been set
|
||||
* @param beanName the name of the bean
|
||||
* @return the actual property values to apply to the given bean (can be the passed-in
|
||||
* PropertyValues instance), or {@code null} which proceeds with the existing properties
|
||||
* but specifically continues with a call to {@link #postProcessPropertyValues}
|
||||
* (requiring initialized {@code PropertyDescriptor}s for the current bean class)
|
||||
* @throws org.springframework.beans.BeansException in case of errors
|
||||
* @since 5.1
|
||||
* @see #postProcessPropertyValues
|
||||
*/
|
||||
@Nullable
|
||||
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
|
||||
throws BeansException {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post-process the given property values before the factory applies them
|
||||
* to the given bean. Allows for checking whether all dependencies have been
|
||||
* satisfied, for example based on a "Required" annotation on bean property setters.
|
||||
* <p>Also allows for replacing the property values to apply, typically through
|
||||
* creating a new MutablePropertyValues instance based on the original PropertyValues,
|
||||
* adding or removing specific values.
|
||||
* to the given bean.
|
||||
* <p>The default implementation returns the given {@code pvs} as-is.
|
||||
* @param pvs the property values that the factory is about to apply (never {@code null})
|
||||
* @param pds the relevant property descriptors for the target bean (with ignored
|
||||
* dependency types - which the factory handles specifically - already filtered out)
|
||||
* @param bean the bean instance created, but whose properties have not yet been set
|
||||
* @param beanName the name of the bean
|
||||
* @return the actual property values to apply to the given bean (can be the passed-in
|
||||
* PropertyValues instance), or {@code null} to skip property population
|
||||
* @throws org.springframework.beans.BeansException in case of errors
|
||||
* @see #postProcessProperties
|
||||
* @see org.springframework.beans.MutablePropertyValues
|
||||
* @deprecated as of 5.1, in favor of {@link #postProcessProperties(PropertyValues, Object, String)}
|
||||
* @since 5.1
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
default PropertyValues postProcessPropertyValues(
|
||||
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
|
||||
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
|
||||
throws BeansException {
|
||||
|
||||
return pvs;
|
||||
}
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* 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.beans.factory.config;
|
||||
|
||||
/**
|
||||
* Adapter that implements all methods on {@link SmartInstantiationAwareBeanPostProcessor}
|
||||
* as no-ops, which will not change normal processing of each bean instantiated
|
||||
* by the container. Subclasses may override merely those methods that they are
|
||||
* actually interested in.
|
||||
*
|
||||
* <p>Note that this base class is only recommendable if you actually require
|
||||
* {@link InstantiationAwareBeanPostProcessor} functionality. If all you need
|
||||
* is plain {@link BeanPostProcessor} functionality, prefer a straight
|
||||
* implementation of that (simpler) interface.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
* @deprecated as of 5.3 in favor of implementing {@link InstantiationAwareBeanPostProcessor}
|
||||
* or {@link SmartInstantiationAwareBeanPostProcessor} directly.
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class InstantiationAwareBeanPostProcessorAdapter implements SmartInstantiationAwareBeanPostProcessor {
|
||||
|
||||
}
|
|
@ -936,24 +936,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
return finder.getResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation attempts to query the FactoryBean's generic parameter metadata
|
||||
* if present to determine the object type. If not present, i.e. the FactoryBean is
|
||||
* declared as a raw type, checks the FactoryBean's {@code getObjectType} method
|
||||
* on a plain instance of the FactoryBean, without bean properties applied yet.
|
||||
* If this doesn't return a type yet, a full creation of the FactoryBean is
|
||||
* used as fallback (through delegation to the superclass's implementation).
|
||||
* <p>The shortcut check for a FactoryBean is only applied in case of a singleton
|
||||
* FactoryBean. If the FactoryBean instance itself is not kept as singleton,
|
||||
* it will be fully created to check the type of its exposed object.
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
@Nullable
|
||||
protected Class<?> getTypeForFactoryBean(String beanName, RootBeanDefinition mbd) {
|
||||
return getTypeForFactoryBean(beanName, mbd, true).resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a reference for early access to the specified bean,
|
||||
* typically for the purpose of resolving a circular reference.
|
||||
|
@ -1398,7 +1380,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
|
||||
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
|
||||
|
||||
PropertyDescriptor[] filteredPds = null;
|
||||
if (hasInstAwareBpps) {
|
||||
if (pvs == null) {
|
||||
pvs = mbd.getPropertyValues();
|
||||
|
@ -1406,21 +1387,13 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
|
||||
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
|
||||
if (pvsToUse == null) {
|
||||
if (filteredPds == null) {
|
||||
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
|
||||
}
|
||||
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
|
||||
if (pvsToUse == null) {
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
pvs = pvsToUse;
|
||||
}
|
||||
}
|
||||
if (needsDepCheck) {
|
||||
if (filteredPds == null) {
|
||||
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
|
||||
}
|
||||
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
|
||||
checkDependencies(beanName, mbd, filteredPds, pvs);
|
||||
}
|
||||
|
||||
|
|
|
@ -1694,28 +1694,6 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||
return ResolvableType.NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the bean type for the given FactoryBean definition, as far as possible.
|
||||
* Only called if there is no singleton instance registered for the target bean already.
|
||||
* <p>The default implementation creates the FactoryBean via {@code getBean}
|
||||
* to call its {@code getObjectType} method. Subclasses are encouraged to optimize
|
||||
* this, typically by just instantiating the FactoryBean but not populating it yet,
|
||||
* trying whether its {@code getObjectType} method already returns a type.
|
||||
* If no type found, a full FactoryBean creation as performed by this implementation
|
||||
* should be used as fallback.
|
||||
* @param beanName the name of the bean
|
||||
* @param mbd the merged bean definition for the bean
|
||||
* @return the type for the bean if determinable, or {@code null} otherwise
|
||||
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
|
||||
* @see #getBean(String)
|
||||
* @deprecated since 5.2 in favor of {@link #getTypeForFactoryBean(String, RootBeanDefinition, boolean)}
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated
|
||||
protected Class<?> getTypeForFactoryBean(String beanName, RootBeanDefinition mbd) {
|
||||
return getTypeForFactoryBean(beanName, mbd, true).resolve();
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the specified bean as already created (or about to be created).
|
||||
* <p>This allows the bean factory to optimize its caching for repeated
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.beans.factory.xml;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
/**
|
||||
* Convenience extension of {@link DefaultListableBeanFactory} that reads bean definitions
|
||||
* from an XML document. Delegates to {@link XmlBeanDefinitionReader} underneath; effectively
|
||||
* equivalent to using an XmlBeanDefinitionReader with a DefaultListableBeanFactory.
|
||||
*
|
||||
* <p>The structure, element and attribute names of the required XML document
|
||||
* are hard-coded in this class. (Of course a transform could be run if necessary
|
||||
* to produce this format). "beans" doesn't need to be the root element of the XML
|
||||
* document: This class will parse all bean definition elements in the XML file.
|
||||
*
|
||||
* <p>This class registers each bean definition with the {@link DefaultListableBeanFactory}
|
||||
* superclass, and relies on the latter's implementation of the {@link BeanFactory} interface.
|
||||
* It supports singletons, prototypes, and references to either of these kinds of bean.
|
||||
* See {@code "spring-beans-3.x.xsd"} (or historically, {@code "spring-beans-2.0.dtd"}) for
|
||||
* details on options and configuration style.
|
||||
*
|
||||
* <p><b>For advanced needs, consider using a {@link DefaultListableBeanFactory} with
|
||||
* an {@link XmlBeanDefinitionReader}.</b> The latter allows for reading from multiple XML
|
||||
* resources and is highly configurable in its actual XML parsing behavior.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @since 15 April 2001
|
||||
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory
|
||||
* @see XmlBeanDefinitionReader
|
||||
* @deprecated as of Spring 3.1 in favor of {@link DefaultListableBeanFactory} and
|
||||
* {@link XmlBeanDefinitionReader}
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings({"serial", "all"})
|
||||
public class XmlBeanFactory extends DefaultListableBeanFactory {
|
||||
|
||||
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
|
||||
|
||||
|
||||
/**
|
||||
* Create a new XmlBeanFactory with the given resource,
|
||||
* which must be parsable using DOM.
|
||||
* @param resource the XML resource to load bean definitions from
|
||||
* @throws BeansException in case of loading or parsing errors
|
||||
*/
|
||||
public XmlBeanFactory(Resource resource) throws BeansException {
|
||||
this(resource, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new XmlBeanFactory with the given input stream,
|
||||
* which must be parsable using DOM.
|
||||
* @param resource the XML resource to load bean definitions from
|
||||
* @param parentBeanFactory parent bean factory
|
||||
* @throws BeansException in case of loading or parsing errors
|
||||
*/
|
||||
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
|
||||
super(parentBeanFactory);
|
||||
this.reader.loadBeanDefinitions(resource);
|
||||
}
|
||||
|
||||
}
|
|
@ -250,27 +250,6 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
|||
assertThat(bean.subInjected).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testExtendedResourceInjectionWithAtRequired() {
|
||||
bf.addBeanPostProcessor(new RequiredAnnotationBeanPostProcessor());
|
||||
RootBeanDefinition bd = new RootBeanDefinition(TypedExtendedResourceInjectionBean.class);
|
||||
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
bf.registerBeanDefinition("annotatedBean", bd);
|
||||
TestBean tb = new TestBean();
|
||||
bf.registerSingleton("testBean", tb);
|
||||
NestedTestBean ntb = new NestedTestBean();
|
||||
bf.registerSingleton("nestedTestBean", ntb);
|
||||
|
||||
TypedExtendedResourceInjectionBean bean = (TypedExtendedResourceInjectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBean()).isSameAs(tb);
|
||||
assertThat(bean.getTestBean2()).isSameAs(tb);
|
||||
assertThat(bean.getTestBean3()).isSameAs(tb);
|
||||
assertThat(bean.getTestBean4()).isSameAs(tb);
|
||||
assertThat(bean.getNestedTestBean()).isSameAs(ntb);
|
||||
assertThat(bean.getBeanFactory()).isSameAs(bf);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOptionalResourceInjection() {
|
||||
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(OptionalResourceInjectionBean.class));
|
||||
|
@ -2401,7 +2380,6 @@ public class AutowiredAnnotationBeanPostProcessorTests {
|
|||
|
||||
@Override
|
||||
@Autowired
|
||||
@Required
|
||||
@SuppressWarnings("deprecation")
|
||||
public void setTestBean2(TestBean testBean2) {
|
||||
super.setTestBean2(testBean2);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -154,27 +154,6 @@ public class InjectAnnotationBeanPostProcessorTests {
|
|||
assertThat(bean.getBeanFactory()).isSameAs(bf);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testExtendedResourceInjectionWithAtRequired() {
|
||||
bf.addBeanPostProcessor(new RequiredAnnotationBeanPostProcessor());
|
||||
RootBeanDefinition bd = new RootBeanDefinition(TypedExtendedResourceInjectionBean.class);
|
||||
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
bf.registerBeanDefinition("annotatedBean", bd);
|
||||
TestBean tb = new TestBean();
|
||||
bf.registerSingleton("testBean", tb);
|
||||
NestedTestBean ntb = new NestedTestBean();
|
||||
bf.registerSingleton("nestedTestBean", ntb);
|
||||
|
||||
TypedExtendedResourceInjectionBean bean = (TypedExtendedResourceInjectionBean) bf.getBean("annotatedBean");
|
||||
assertThat(bean.getTestBean()).isSameAs(tb);
|
||||
assertThat(bean.getTestBean2()).isSameAs(tb);
|
||||
assertThat(bean.getTestBean3()).isSameAs(tb);
|
||||
assertThat(bean.getTestBean4()).isSameAs(tb);
|
||||
assertThat(bean.getNestedTestBean()).isSameAs(ntb);
|
||||
assertThat(bean.getBeanFactory()).isSameAs(bf);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructorResourceInjection() {
|
||||
RootBeanDefinition bd = new RootBeanDefinition(ConstructorResourceInjectionBean.class);
|
||||
|
@ -666,7 +645,6 @@ public class InjectAnnotationBeanPostProcessorTests {
|
|||
|
||||
@Override
|
||||
@Inject
|
||||
@Required
|
||||
@SuppressWarnings("deprecation")
|
||||
public void setTestBean2(TestBean testBean2) {
|
||||
super.setTestBean2(testBean2);
|
||||
|
|
|
@ -1,244 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2019 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.beans.factory.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @author Chris Beams
|
||||
* @since 2.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class RequiredAnnotationBeanPostProcessorTests {
|
||||
|
||||
@Test
|
||||
public void testWithRequiredPropertyOmitted() {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
BeanDefinition beanDef = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(RequiredTestBean.class)
|
||||
.addPropertyValue("name", "Rob Harrop")
|
||||
.addPropertyValue("favouriteColour", "Blue")
|
||||
.addPropertyValue("jobTitle", "Grand Poobah")
|
||||
.getBeanDefinition();
|
||||
factory.registerBeanDefinition("testBean", beanDef);
|
||||
factory.addBeanPostProcessor(new RequiredAnnotationBeanPostProcessor());
|
||||
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(
|
||||
factory::preInstantiateSingletons)
|
||||
.withMessageContaining("Property")
|
||||
.withMessageContaining("age")
|
||||
.withMessageContaining("testBean");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithThreeRequiredPropertiesOmitted() {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
BeanDefinition beanDef = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(RequiredTestBean.class)
|
||||
.addPropertyValue("name", "Rob Harrop")
|
||||
.getBeanDefinition();
|
||||
factory.registerBeanDefinition("testBean", beanDef);
|
||||
factory.addBeanPostProcessor(new RequiredAnnotationBeanPostProcessor());
|
||||
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(
|
||||
factory::preInstantiateSingletons)
|
||||
.withMessageContaining("Properties")
|
||||
.withMessageContaining("age")
|
||||
.withMessageContaining("favouriteColour")
|
||||
.withMessageContaining("jobTitle")
|
||||
.withMessageContaining("testBean");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithAllRequiredPropertiesSpecified() {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
BeanDefinition beanDef = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(RequiredTestBean.class)
|
||||
.addPropertyValue("age", "24")
|
||||
.addPropertyValue("favouriteColour", "Blue")
|
||||
.addPropertyValue("jobTitle", "Grand Poobah")
|
||||
.getBeanDefinition();
|
||||
factory.registerBeanDefinition("testBean", beanDef);
|
||||
factory.addBeanPostProcessor(new RequiredAnnotationBeanPostProcessor());
|
||||
factory.preInstantiateSingletons();
|
||||
RequiredTestBean bean = (RequiredTestBean) factory.getBean("testBean");
|
||||
assertThat(bean.getAge()).isEqualTo(24);
|
||||
assertThat(bean.getFavouriteColour()).isEqualTo("Blue");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithCustomAnnotation() {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
BeanDefinition beanDef = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(RequiredTestBean.class)
|
||||
.getBeanDefinition();
|
||||
factory.registerBeanDefinition("testBean", beanDef);
|
||||
RequiredAnnotationBeanPostProcessor rabpp = new RequiredAnnotationBeanPostProcessor();
|
||||
rabpp.setRequiredAnnotationType(MyRequired.class);
|
||||
factory.addBeanPostProcessor(rabpp);
|
||||
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(
|
||||
factory::preInstantiateSingletons)
|
||||
.withMessageContaining("Property")
|
||||
.withMessageContaining("name")
|
||||
.withMessageContaining("testBean");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithStaticFactoryMethod() {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
BeanDefinition beanDef = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(RequiredTestBean.class)
|
||||
.setFactoryMethod("create")
|
||||
.addPropertyValue("name", "Rob Harrop")
|
||||
.addPropertyValue("favouriteColour", "Blue")
|
||||
.addPropertyValue("jobTitle", "Grand Poobah")
|
||||
.getBeanDefinition();
|
||||
factory.registerBeanDefinition("testBean", beanDef);
|
||||
factory.addBeanPostProcessor(new RequiredAnnotationBeanPostProcessor());
|
||||
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(
|
||||
factory::preInstantiateSingletons)
|
||||
.withMessageContaining("Property")
|
||||
.withMessageContaining("age")
|
||||
.withMessageContaining("testBean");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithStaticFactoryMethodAndRequiredPropertiesSpecified() {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
BeanDefinition beanDef = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(RequiredTestBean.class)
|
||||
.setFactoryMethod("create")
|
||||
.addPropertyValue("age", "24")
|
||||
.addPropertyValue("favouriteColour", "Blue")
|
||||
.addPropertyValue("jobTitle", "Grand Poobah")
|
||||
.getBeanDefinition();
|
||||
factory.registerBeanDefinition("testBean", beanDef);
|
||||
factory.addBeanPostProcessor(new RequiredAnnotationBeanPostProcessor());
|
||||
factory.preInstantiateSingletons();
|
||||
RequiredTestBean bean = (RequiredTestBean) factory.getBean("testBean");
|
||||
assertThat(bean.getAge()).isEqualTo(24);
|
||||
assertThat(bean.getFavouriteColour()).isEqualTo("Blue");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithFactoryBean() {
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
RootBeanDefinition beanDef = new RootBeanDefinition(RequiredTestBean.class);
|
||||
beanDef.setFactoryBeanName("testBeanFactory");
|
||||
beanDef.setFactoryMethodName("create");
|
||||
factory.registerBeanDefinition("testBean", beanDef);
|
||||
factory.registerBeanDefinition("testBeanFactory", new RootBeanDefinition(RequiredTestBeanFactory.class));
|
||||
RequiredAnnotationBeanPostProcessor bpp = new RequiredAnnotationBeanPostProcessor();
|
||||
bpp.setBeanFactory(factory);
|
||||
factory.addBeanPostProcessor(bpp);
|
||||
factory.preInstantiateSingletons();
|
||||
}
|
||||
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface MyRequired {
|
||||
}
|
||||
|
||||
|
||||
public static class RequiredTestBean implements BeanNameAware, BeanFactoryAware {
|
||||
|
||||
private String name;
|
||||
|
||||
private int age;
|
||||
|
||||
private String favouriteColour;
|
||||
|
||||
private String jobTitle;
|
||||
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@MyRequired
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getFavouriteColour() {
|
||||
return favouriteColour;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setFavouriteColour(String favouriteColour) {
|
||||
this.favouriteColour = favouriteColour;
|
||||
}
|
||||
|
||||
public String getJobTitle() {
|
||||
return jobTitle;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setJobTitle(String jobTitle) {
|
||||
this.jobTitle = jobTitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Required
|
||||
public void setBeanName(String name) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Required
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
}
|
||||
|
||||
public static RequiredTestBean create() {
|
||||
return new RequiredTestBean();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class RequiredTestBeanFactory {
|
||||
|
||||
public RequiredTestBean create() {
|
||||
return new RequiredTestBean();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -84,7 +84,6 @@ public class AnnotationProcessorBenchmark {
|
|||
@Override
|
||||
@Resource
|
||||
@SuppressWarnings("deprecation")
|
||||
@org.springframework.beans.factory.annotation.Required
|
||||
public void setSpouse(ITestBean spouse) {
|
||||
super.setSpouse(spouse);
|
||||
}
|
||||
|
@ -95,7 +94,6 @@ public class AnnotationProcessorBenchmark {
|
|||
@Override
|
||||
@Autowired
|
||||
@SuppressWarnings("deprecation")
|
||||
@org.springframework.beans.factory.annotation.Required
|
||||
public void setSpouse(ITestBean spouse) {
|
||||
super.setSpouse(spouse);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -132,21 +132,6 @@ public abstract class AbstractCacheManager implements CacheManager, Initializing
|
|||
return this.cacheMap.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically register an additional Cache with this manager.
|
||||
* @param cache the Cache to register
|
||||
* @deprecated as of Spring 4.3, in favor of {@link #getMissingCache(String)}
|
||||
*/
|
||||
@Deprecated
|
||||
protected final void addCache(Cache cache) {
|
||||
String name = cache.getName();
|
||||
synchronized (this.cacheMap) {
|
||||
if (this.cacheMap.put(name, decorateCache(cache)) == null) {
|
||||
updateCacheNames(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the exposed {@link #cacheNames} set with the given name.
|
||||
* <p>This will always be called within a full {@link #cacheMap} lock
|
||||
|
|
|
@ -83,14 +83,6 @@ public abstract class AnnotationConfigUtils {
|
|||
public static final String AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME =
|
||||
"org.springframework.context.annotation.internalAutowiredAnnotationProcessor";
|
||||
|
||||
/**
|
||||
* The bean name of the internally managed Required annotation processor.
|
||||
* @deprecated as of 5.1, since no Required processor is registered by default anymore
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME =
|
||||
"org.springframework.context.annotation.internalRequiredAnnotationProcessor";
|
||||
|
||||
/**
|
||||
* The bean name of the internally managed common annotation processor.
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -22,7 +22,6 @@ import java.lang.annotation.Retention;
|
|||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowire;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
|
||||
|
@ -239,21 +238,6 @@ public @interface Bean {
|
|||
@AliasFor("value")
|
||||
String[] name() default {};
|
||||
|
||||
/**
|
||||
* Are dependencies to be injected via convention-based autowiring by name or type?
|
||||
* <p>Note that this autowire mode is just about externally driven autowiring based
|
||||
* on bean property setter methods by convention, analogous to XML bean definitions.
|
||||
* <p>The default mode does allow for annotation-driven autowiring. "no" refers to
|
||||
* externally driven autowiring only, not affecting any autowiring demands that the
|
||||
* bean class itself expresses through annotations.
|
||||
* @see Autowire#BY_NAME
|
||||
* @see Autowire#BY_TYPE
|
||||
* @deprecated as of 5.1, since {@code @Bean} factory method argument resolution and
|
||||
* {@code @Autowired} processing supersede name/type-based bean property injection
|
||||
*/
|
||||
@Deprecated
|
||||
Autowire autowire() default Autowire.NO;
|
||||
|
||||
/**
|
||||
* Is this bean a candidate for getting autowired into some other bean?
|
||||
* <p>Default is {@code true}; set this to {@code false} for internal delegates
|
||||
|
|
|
@ -306,14 +306,6 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
|||
return pvs;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public PropertyValues postProcessPropertyValues(
|
||||
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {
|
||||
|
||||
return postProcessProperties(pvs, bean, beanName);
|
||||
}
|
||||
|
||||
|
||||
private InjectionMetadata findResourceMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
|
||||
// Fall back to class name as cache key, for backwards compatibility with custom callers.
|
||||
|
|
|
@ -30,7 +30,6 @@ import org.apache.commons.logging.LogFactory;
|
|||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
|
||||
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
|
||||
import org.springframework.beans.factory.annotation.Autowire;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader;
|
||||
|
@ -244,16 +243,8 @@ class ConfigurationClassBeanDefinitionReader {
|
|||
}
|
||||
|
||||
beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
|
||||
beanDef.setAttribute(org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.
|
||||
SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);
|
||||
|
||||
AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);
|
||||
|
||||
Autowire autowire = bean.getEnum("autowire");
|
||||
if (autowire.isAutowire()) {
|
||||
beanDef.setAutowireMode(autowire.value());
|
||||
}
|
||||
|
||||
boolean autowireCandidate = bean.getBoolean("autowireCandidate");
|
||||
if (!autowireCandidate) {
|
||||
beanDef.setAutowireCandidate(false);
|
||||
|
|
|
@ -935,11 +935,6 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
|||
|
||||
// Publish the final event.
|
||||
publishEvent(new ContextRefreshedEvent(this));
|
||||
|
||||
// Participate in LiveBeansView MBean, if active.
|
||||
if (!NativeDetector.inNativeImage()) {
|
||||
LiveBeansView.registerApplicationContext(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -995,18 +990,6 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for destruction of this instance, originally attached
|
||||
* to a {@code DisposableBean} implementation (not anymore in 5.0).
|
||||
* <p>The {@link #close()} method is the native way to shut down
|
||||
* an ApplicationContext, which this method simply delegates to.
|
||||
* @deprecated as of Spring Framework 5.0, in favor of {@link #close()}
|
||||
*/
|
||||
@Deprecated
|
||||
public void destroy() {
|
||||
close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Close this application context, destroying all beans in its bean factory.
|
||||
* <p>Delegates to {@code doClose()} for the actual closing procedure.
|
||||
|
@ -1048,10 +1031,6 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
|||
logger.debug("Closing " + this);
|
||||
}
|
||||
|
||||
if (!NativeDetector.inNativeImage()) {
|
||||
LiveBeansView.unregisterApplicationContext(this);
|
||||
}
|
||||
|
||||
try {
|
||||
// Publish shutdown event.
|
||||
publishEvent(new ContextClosedEvent(this));
|
||||
|
|
|
@ -1,270 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2021 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.context.support;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ApplicationContextException;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Adapter for live beans view exposure, building a snapshot of current beans
|
||||
* and their dependencies from either a local {@code ApplicationContext} (with a
|
||||
* local {@code LiveBeansView} bean definition) or all registered ApplicationContexts
|
||||
* (driven by the {@value #MBEAN_DOMAIN_PROPERTY_NAME} environment property).
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
* @since 3.2
|
||||
* @see #getSnapshotAsJson()
|
||||
* @see org.springframework.web.context.support.LiveBeansViewServlet
|
||||
* @deprecated as of 5.3, in favor of using Spring Boot actuators for such needs
|
||||
*/
|
||||
@Deprecated
|
||||
public class LiveBeansView implements LiveBeansViewMBean, ApplicationContextAware {
|
||||
|
||||
/**
|
||||
* The "MBean Domain" property name.
|
||||
*/
|
||||
public static final String MBEAN_DOMAIN_PROPERTY_NAME = "spring.liveBeansView.mbeanDomain";
|
||||
|
||||
/**
|
||||
* The MBean application key.
|
||||
*/
|
||||
public static final String MBEAN_APPLICATION_KEY = "application";
|
||||
|
||||
private static final Set<ConfigurableApplicationContext> applicationContexts = new LinkedHashSet<>();
|
||||
|
||||
@Nullable
|
||||
private static String applicationName;
|
||||
|
||||
|
||||
static void registerApplicationContext(ConfigurableApplicationContext applicationContext) {
|
||||
String mbeanDomain = applicationContext.getEnvironment().getProperty(MBEAN_DOMAIN_PROPERTY_NAME);
|
||||
if (mbeanDomain != null) {
|
||||
synchronized (applicationContexts) {
|
||||
if (applicationContexts.isEmpty()) {
|
||||
try {
|
||||
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
|
||||
applicationName = applicationContext.getApplicationName();
|
||||
server.registerMBean(new LiveBeansView(),
|
||||
new ObjectName(mbeanDomain, MBEAN_APPLICATION_KEY, applicationName));
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new ApplicationContextException("Failed to register LiveBeansView MBean", ex);
|
||||
}
|
||||
}
|
||||
applicationContexts.add(applicationContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void unregisterApplicationContext(ConfigurableApplicationContext applicationContext) {
|
||||
synchronized (applicationContexts) {
|
||||
if (applicationContexts.remove(applicationContext) && applicationContexts.isEmpty()) {
|
||||
try {
|
||||
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
|
||||
String mbeanDomain = applicationContext.getEnvironment().getProperty(MBEAN_DOMAIN_PROPERTY_NAME);
|
||||
if (mbeanDomain != null) {
|
||||
server.unregisterMBean(new ObjectName(mbeanDomain, MBEAN_APPLICATION_KEY, applicationName));
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new ApplicationContextException("Failed to unregister LiveBeansView MBean", ex);
|
||||
}
|
||||
finally {
|
||||
applicationName = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private ConfigurableApplicationContext applicationContext;
|
||||
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) {
|
||||
Assert.isTrue(applicationContext instanceof ConfigurableApplicationContext,
|
||||
"ApplicationContext does not implement ConfigurableApplicationContext");
|
||||
this.applicationContext = (ConfigurableApplicationContext) applicationContext;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate a JSON snapshot of current beans and their dependencies,
|
||||
* finding all active ApplicationContexts through {@link #findApplicationContexts()},
|
||||
* then delegating to {@link #generateJson(java.util.Set)}.
|
||||
*/
|
||||
@Override
|
||||
public String getSnapshotAsJson() {
|
||||
Set<ConfigurableApplicationContext> contexts;
|
||||
if (this.applicationContext != null) {
|
||||
contexts = Collections.singleton(this.applicationContext);
|
||||
}
|
||||
else {
|
||||
contexts = findApplicationContexts();
|
||||
}
|
||||
return generateJson(contexts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all applicable ApplicationContexts for the current application.
|
||||
* <p>Called if no specific ApplicationContext has been set for this LiveBeansView.
|
||||
* @return the set of ApplicationContexts
|
||||
*/
|
||||
protected Set<ConfigurableApplicationContext> findApplicationContexts() {
|
||||
synchronized (applicationContexts) {
|
||||
return new LinkedHashSet<>(applicationContexts);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually generate a JSON snapshot of the beans in the given ApplicationContexts.
|
||||
* <p>This implementation doesn't use any JSON parsing libraries in order to avoid
|
||||
* third-party library dependencies. It produces an array of context description
|
||||
* objects, each containing a context and parent attribute as well as a beans
|
||||
* attribute with nested bean description objects. Each bean object contains a
|
||||
* bean, scope, type and resource attribute, as well as a dependencies attribute
|
||||
* with a nested array of bean names that the present bean depends on.
|
||||
* @param contexts the set of ApplicationContexts
|
||||
* @return the JSON document
|
||||
*/
|
||||
protected String generateJson(Set<ConfigurableApplicationContext> contexts) {
|
||||
StringBuilder result = new StringBuilder("[\n");
|
||||
for (Iterator<ConfigurableApplicationContext> it = contexts.iterator(); it.hasNext();) {
|
||||
ConfigurableApplicationContext context = it.next();
|
||||
result.append("{\n\"context\": \"").append(context.getId()).append("\",\n");
|
||||
if (context.getParent() != null) {
|
||||
result.append("\"parent\": \"").append(context.getParent().getId()).append("\",\n");
|
||||
}
|
||||
else {
|
||||
result.append("\"parent\": null,\n");
|
||||
}
|
||||
result.append("\"beans\": [\n");
|
||||
ConfigurableListableBeanFactory bf = context.getBeanFactory();
|
||||
String[] beanNames = bf.getBeanDefinitionNames();
|
||||
boolean elementAppended = false;
|
||||
for (String beanName : beanNames) {
|
||||
BeanDefinition bd = bf.getBeanDefinition(beanName);
|
||||
if (isBeanEligible(beanName, bd, bf)) {
|
||||
if (elementAppended) {
|
||||
result.append(",\n");
|
||||
}
|
||||
result.append("{\n\"bean\": \"").append(beanName).append("\",\n");
|
||||
result.append("\"aliases\": ");
|
||||
appendArray(result, bf.getAliases(beanName));
|
||||
result.append(",\n");
|
||||
String scope = bd.getScope();
|
||||
if (!StringUtils.hasText(scope)) {
|
||||
scope = BeanDefinition.SCOPE_SINGLETON;
|
||||
}
|
||||
result.append("\"scope\": \"").append(scope).append("\",\n");
|
||||
Class<?> beanType = bf.getType(beanName);
|
||||
if (beanType != null) {
|
||||
result.append("\"type\": \"").append(beanType.getName()).append("\",\n");
|
||||
}
|
||||
else {
|
||||
result.append("\"type\": null,\n");
|
||||
}
|
||||
result.append("\"resource\": \"").append(getEscapedResourceDescription(bd)).append("\",\n");
|
||||
result.append("\"dependencies\": ");
|
||||
appendArray(result, bf.getDependenciesForBean(beanName));
|
||||
result.append("\n}");
|
||||
elementAppended = true;
|
||||
}
|
||||
}
|
||||
result.append("]\n");
|
||||
result.append('}');
|
||||
if (it.hasNext()) {
|
||||
result.append(",\n");
|
||||
}
|
||||
}
|
||||
result.append(']');
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the specified bean is eligible for inclusion in the
|
||||
* LiveBeansView JSON snapshot.
|
||||
* @param beanName the name of the bean
|
||||
* @param bd the corresponding bean definition
|
||||
* @param bf the containing bean factory
|
||||
* @return {@code true} if the bean is to be included; {@code false} otherwise
|
||||
*/
|
||||
protected boolean isBeanEligible(String beanName, BeanDefinition bd, ConfigurableBeanFactory bf) {
|
||||
return (bd.getRole() != BeanDefinition.ROLE_INFRASTRUCTURE &&
|
||||
(!bd.isLazyInit() || bf.containsSingleton(beanName)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine a resource description for the given bean definition and
|
||||
* apply basic JSON escaping (backslashes, double quotes) to it.
|
||||
* @param bd the bean definition to build the resource description for
|
||||
* @return the JSON-escaped resource description
|
||||
*/
|
||||
@Nullable
|
||||
protected String getEscapedResourceDescription(BeanDefinition bd) {
|
||||
String resourceDescription = bd.getResourceDescription();
|
||||
if (resourceDescription == null) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder result = new StringBuilder(resourceDescription.length() + 16);
|
||||
for (int i = 0; i < resourceDescription.length(); i++) {
|
||||
char character = resourceDescription.charAt(i);
|
||||
if (character == '\\') {
|
||||
result.append('/');
|
||||
}
|
||||
else if (character == '"') {
|
||||
result.append("\\").append('"');
|
||||
}
|
||||
else {
|
||||
result.append(character);
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private void appendArray(StringBuilder result, String[] arr) {
|
||||
result.append('[');
|
||||
if (arr.length > 0) {
|
||||
result.append('\"');
|
||||
}
|
||||
result.append(StringUtils.arrayToDelimitedString(arr, "\", \""));
|
||||
if (arr.length > 0) {
|
||||
result.append('\"');
|
||||
}
|
||||
result.append(']');
|
||||
}
|
||||
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* 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.context.support;
|
||||
|
||||
/**
|
||||
* MBean operation interface for the {@link LiveBeansView} feature.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.2
|
||||
* @deprecated as of 5.3, in favor of using Spring Boot actuators for such needs
|
||||
*/
|
||||
@Deprecated
|
||||
public interface LiveBeansViewMBean {
|
||||
|
||||
/**
|
||||
* Generate a JSON snapshot of current beans and their dependencies.
|
||||
*/
|
||||
String getSnapshotAsJson();
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -18,7 +18,6 @@ package org.springframework.context.annotation.configuration;
|
|||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowire;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
|
@ -46,15 +45,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
*/
|
||||
public class BeanAnnotationAttributePropagationTests {
|
||||
|
||||
@Test
|
||||
public void autowireMetadataIsPropagated() {
|
||||
@Configuration class Config {
|
||||
@Bean(autowire=Autowire.BY_TYPE) Object foo() { return null; }
|
||||
}
|
||||
|
||||
assertThat(beanDef(Config.class).getAutowireMode()).as("autowire mode was not propagated").isEqualTo(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void autowireCandidateMetadataIsPropagated() {
|
||||
@Configuration class Config {
|
||||
|
|
|
@ -1,122 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2021 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.context.support;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.management.MalformedObjectNameException;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInfo;
|
||||
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link LiveBeansView}
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
class LiveBeansViewTests {
|
||||
|
||||
private final MockEnvironment environment = new MockEnvironment();
|
||||
|
||||
|
||||
@Test
|
||||
void registerIgnoredIfPropertyIsNotSet(TestInfo testInfo) throws MalformedObjectNameException {
|
||||
ConfigurableApplicationContext context = createApplicationContext("app");
|
||||
assertThat(searchLiveBeansViewMeans(testInfo).size()).isEqualTo(0);
|
||||
LiveBeansView.registerApplicationContext(context);
|
||||
assertThat(searchLiveBeansViewMeans(testInfo).size()).isEqualTo(0);
|
||||
LiveBeansView.unregisterApplicationContext(context);
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerUnregisterSingleContext(TestInfo testInfo) throws MalformedObjectNameException {
|
||||
this.environment.setProperty(LiveBeansView.MBEAN_DOMAIN_PROPERTY_NAME,
|
||||
testInfo.getTestMethod().get().getName());
|
||||
ConfigurableApplicationContext context = createApplicationContext("app");
|
||||
assertThat(searchLiveBeansViewMeans(testInfo).size()).isEqualTo(0);
|
||||
LiveBeansView.registerApplicationContext(context);
|
||||
assertSingleLiveBeansViewMbean(testInfo, "app");
|
||||
LiveBeansView.unregisterApplicationContext(context);
|
||||
assertThat(searchLiveBeansViewMeans(testInfo).size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerUnregisterSeveralContexts(TestInfo testInfo) throws MalformedObjectNameException {
|
||||
this.environment.setProperty(LiveBeansView.MBEAN_DOMAIN_PROPERTY_NAME,
|
||||
testInfo.getTestMethod().get().getName());
|
||||
ConfigurableApplicationContext context = createApplicationContext("app");
|
||||
ConfigurableApplicationContext childContext = createApplicationContext("child");
|
||||
assertThat(searchLiveBeansViewMeans(testInfo).size()).isEqualTo(0);
|
||||
LiveBeansView.registerApplicationContext(context);
|
||||
assertSingleLiveBeansViewMbean(testInfo, "app");
|
||||
LiveBeansView.registerApplicationContext(childContext);
|
||||
// Only one MBean
|
||||
assertThat(searchLiveBeansViewMeans(testInfo).size()).isEqualTo(1);
|
||||
LiveBeansView.unregisterApplicationContext(childContext);
|
||||
assertSingleLiveBeansViewMbean(testInfo, "app"); // Root context removes it
|
||||
LiveBeansView.unregisterApplicationContext(context);
|
||||
assertThat(searchLiveBeansViewMeans(testInfo).size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerUnregisterSeveralContextsDifferentOrder(TestInfo testInfo) throws MalformedObjectNameException {
|
||||
this.environment.setProperty(LiveBeansView.MBEAN_DOMAIN_PROPERTY_NAME,
|
||||
testInfo.getTestMethod().get().getName());
|
||||
ConfigurableApplicationContext context = createApplicationContext("app");
|
||||
ConfigurableApplicationContext childContext = createApplicationContext("child");
|
||||
assertThat(searchLiveBeansViewMeans(testInfo).size()).isEqualTo(0);
|
||||
LiveBeansView.registerApplicationContext(context);
|
||||
assertSingleLiveBeansViewMbean(testInfo, "app");
|
||||
LiveBeansView.registerApplicationContext(childContext);
|
||||
assertSingleLiveBeansViewMbean(testInfo, "app"); // Only one MBean
|
||||
LiveBeansView.unregisterApplicationContext(context);
|
||||
LiveBeansView.unregisterApplicationContext(childContext);
|
||||
assertThat(searchLiveBeansViewMeans(testInfo).size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
private ConfigurableApplicationContext createApplicationContext(String applicationName) {
|
||||
ConfigurableApplicationContext context = mock(ConfigurableApplicationContext.class);
|
||||
given(context.getEnvironment()).willReturn(this.environment);
|
||||
given(context.getApplicationName()).willReturn(applicationName);
|
||||
return context;
|
||||
}
|
||||
|
||||
private void assertSingleLiveBeansViewMbean(TestInfo testInfo, String applicationName) throws MalformedObjectNameException {
|
||||
Set<ObjectName> objectNames = searchLiveBeansViewMeans(testInfo);
|
||||
assertThat(objectNames.size()).isEqualTo(1);
|
||||
assertThat(objectNames.iterator().next().getCanonicalName()).as("Wrong MBean name").isEqualTo(
|
||||
String.format("%s:application=%s", testInfo.getTestMethod().get().getName(), applicationName));
|
||||
}
|
||||
|
||||
private Set<ObjectName> searchLiveBeansViewMeans(TestInfo testInfo) throws MalformedObjectNameException {
|
||||
String objectName = String.format("%s:*,%s=*", testInfo.getTestMethod().get().getName(),
|
||||
LiveBeansView.MBEAN_APPLICATION_KEY);
|
||||
return ManagementFactory.getPlatformMBeanServer().queryNames(new ObjectName(objectName), null);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -207,17 +207,6 @@ public final class StringDecoder extends AbstractDataBufferDecoder<String> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code StringDecoder} for {@code "text/plain"}.
|
||||
* @param stripDelimiter this flag is ignored
|
||||
* @deprecated as of Spring 5.0.4, in favor of {@link #textPlainOnly()} or
|
||||
* {@link #textPlainOnly(List, boolean)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static StringDecoder textPlainOnly(boolean stripDelimiter) {
|
||||
return textPlainOnly();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code StringDecoder} for {@code "text/plain"}.
|
||||
*/
|
||||
|
@ -235,17 +224,6 @@ public final class StringDecoder extends AbstractDataBufferDecoder<String> {
|
|||
return new StringDecoder(delimiters, stripDelimiter, new MimeType("text", "plain", DEFAULT_CHARSET));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code StringDecoder} that supports all MIME types.
|
||||
* @param stripDelimiter this flag is ignored
|
||||
* @deprecated as of Spring 5.0.4, in favor of {@link #allMimeTypes()} or
|
||||
* {@link #allMimeTypes(List, boolean)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static StringDecoder allMimeTypes(boolean stripDelimiter) {
|
||||
return allMimeTypes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code StringDecoder} that supports all MIME types.
|
||||
*/
|
||||
|
|
|
@ -99,22 +99,6 @@ public class ClassPathResource extends AbstractFileResolvingResource {
|
|||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code ClassPathResource} with optional {@code ClassLoader}
|
||||
* and {@code Class}. Only for internal usage.
|
||||
* @param path relative or absolute path within the classpath
|
||||
* @param classLoader the class loader to load the resource with, if any
|
||||
* @param clazz the class to load resources with, if any
|
||||
* @deprecated as of 4.3.13, in favor of selective use of
|
||||
* {@link #ClassPathResource(String, ClassLoader)} vs {@link #ClassPathResource(String, Class)}
|
||||
*/
|
||||
@Deprecated
|
||||
protected ClassPathResource(String path, @Nullable ClassLoader classLoader, @Nullable Class<?> clazz) {
|
||||
this.path = StringUtils.cleanPath(path);
|
||||
this.classLoader = classLoader;
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the path for this resource (as resource path within the class path).
|
||||
|
|
|
@ -1,105 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2021 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.type.classreading;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.asm.AnnotationVisitor;
|
||||
import org.springframework.asm.SpringAsmInfo;
|
||||
import org.springframework.asm.Type;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* {@link AnnotationVisitor} to recursively visit annotations.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @author Juergen Hoeller
|
||||
* @author Phillip Webb
|
||||
* @author Sam Brannen
|
||||
* @since 3.1.1
|
||||
* @deprecated As of Spring Framework 5.2, this class and related classes in this
|
||||
* package have been replaced by {@link SimpleAnnotationMetadataReadingVisitor}
|
||||
* and related classes for internal use within the framework.
|
||||
*/
|
||||
@Deprecated
|
||||
abstract class AbstractRecursiveAnnotationVisitor extends AnnotationVisitor {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
protected final AnnotationAttributes attributes;
|
||||
|
||||
@Nullable
|
||||
protected final ClassLoader classLoader;
|
||||
|
||||
|
||||
public AbstractRecursiveAnnotationVisitor(@Nullable ClassLoader classLoader, AnnotationAttributes attributes) {
|
||||
super(SpringAsmInfo.ASM_VERSION);
|
||||
this.classLoader = classLoader;
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(String attributeName, Object attributeValue) {
|
||||
this.attributes.put(attributeName, attributeValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String attributeName, String asmTypeDescriptor) {
|
||||
String annotationType = Type.getType(asmTypeDescriptor).getClassName();
|
||||
AnnotationAttributes nestedAttributes = new AnnotationAttributes(annotationType, this.classLoader);
|
||||
this.attributes.put(attributeName, nestedAttributes);
|
||||
return new RecursiveAnnotationAttributesVisitor(annotationType, nestedAttributes, this.classLoader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitArray(String attributeName) {
|
||||
return new RecursiveAnnotationArrayVisitor(attributeName, this.attributes, this.classLoader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnum(String attributeName, String asmTypeDescriptor, String attributeValue) {
|
||||
Object newValue = getEnumValue(asmTypeDescriptor, attributeValue);
|
||||
visit(attributeName, newValue);
|
||||
}
|
||||
|
||||
protected Object getEnumValue(String asmTypeDescriptor, String attributeValue) {
|
||||
Object valueToUse = attributeValue;
|
||||
try {
|
||||
Class<?> enumType = ClassUtils.forName(Type.getType(asmTypeDescriptor).getClassName(), this.classLoader);
|
||||
Field enumConstant = ReflectionUtils.findField(enumType, attributeValue);
|
||||
if (enumConstant != null) {
|
||||
ReflectionUtils.makeAccessible(enumConstant);
|
||||
valueToUse = enumConstant.get(null);
|
||||
}
|
||||
}
|
||||
catch (ClassNotFoundException | NoClassDefFoundError ex) {
|
||||
logger.debug("Failed to classload enum type while reading annotation metadata", ex);
|
||||
}
|
||||
catch (IllegalAccessException ex) {
|
||||
logger.debug("Could not access enum value while reading annotation metadata", ex);
|
||||
}
|
||||
return valueToUse;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,127 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2019 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.type.classreading;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* ASM visitor which looks for annotations defined on a class or method,
|
||||
* including meta-annotations.
|
||||
*
|
||||
* <p>This visitor is fully recursive, taking into account any nested
|
||||
* annotations or nested annotation arrays.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @author Phillip Webb
|
||||
* @author Sam Brannen
|
||||
* @since 3.0
|
||||
* @deprecated As of Spring Framework 5.2, this class and related classes in this
|
||||
* package have been replaced by {@link SimpleAnnotationMetadataReadingVisitor}
|
||||
* and related classes for internal use within the framework.
|
||||
*/
|
||||
@Deprecated
|
||||
final class AnnotationAttributesReadingVisitor extends RecursiveAnnotationAttributesVisitor {
|
||||
|
||||
private final MultiValueMap<String, AnnotationAttributes> attributesMap;
|
||||
|
||||
private final Map<String, Set<String>> metaAnnotationMap;
|
||||
|
||||
|
||||
public AnnotationAttributesReadingVisitor(String annotationType,
|
||||
MultiValueMap<String, AnnotationAttributes> attributesMap, Map<String, Set<String>> metaAnnotationMap,
|
||||
@Nullable ClassLoader classLoader) {
|
||||
|
||||
super(annotationType, new AnnotationAttributes(annotationType, classLoader), classLoader);
|
||||
this.attributesMap = attributesMap;
|
||||
this.metaAnnotationMap = metaAnnotationMap;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
super.visitEnd();
|
||||
|
||||
Class<? extends Annotation> annotationClass = this.attributes.annotationType();
|
||||
if (annotationClass != null) {
|
||||
List<AnnotationAttributes> attributeList = this.attributesMap.get(this.annotationType);
|
||||
if (attributeList == null) {
|
||||
this.attributesMap.add(this.annotationType, this.attributes);
|
||||
}
|
||||
else {
|
||||
attributeList.add(0, this.attributes);
|
||||
}
|
||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotationClass.getName())) {
|
||||
try {
|
||||
Annotation[] metaAnnotations = annotationClass.getAnnotations();
|
||||
if (!ObjectUtils.isEmpty(metaAnnotations)) {
|
||||
Set<Annotation> visited = new LinkedHashSet<>();
|
||||
for (Annotation metaAnnotation : metaAnnotations) {
|
||||
recursivelyCollectMetaAnnotations(visited, metaAnnotation);
|
||||
}
|
||||
if (!visited.isEmpty()) {
|
||||
Set<String> metaAnnotationTypeNames = new LinkedHashSet<>(visited.size());
|
||||
for (Annotation ann : visited) {
|
||||
metaAnnotationTypeNames.add(ann.annotationType().getName());
|
||||
}
|
||||
this.metaAnnotationMap.put(annotationClass.getName(), metaAnnotationTypeNames);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Failed to introspect meta-annotations on " + annotationClass + ": " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void recursivelyCollectMetaAnnotations(Set<Annotation> visited, Annotation annotation) {
|
||||
Class<? extends Annotation> annotationType = annotation.annotationType();
|
||||
String annotationName = annotationType.getName();
|
||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotationName) && visited.add(annotation)) {
|
||||
try {
|
||||
// Only do attribute scanning for public annotations.
|
||||
if (Modifier.isPublic(annotationType.getModifiers())) {
|
||||
this.attributesMap.add(annotationName,
|
||||
AnnotationUtils.getAnnotationAttributes(annotation, false, true));
|
||||
}
|
||||
for (Annotation metaMetaAnnotation : annotationType.getAnnotations()) {
|
||||
recursivelyCollectMetaAnnotations(visited, metaMetaAnnotation);
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Failed to introspect meta-annotations on " + annotation + ": " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,200 +0,0 @@
|
|||
/*
|
||||
* 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.type.classreading;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.asm.AnnotationVisitor;
|
||||
import org.springframework.asm.MethodVisitor;
|
||||
import org.springframework.asm.Opcodes;
|
||||
import org.springframework.asm.Type;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.annotation.MergedAnnotations;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.core.type.MethodMetadata;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
/**
|
||||
* ASM class visitor which looks for the class name and implemented types as
|
||||
* well as for the annotations defined on the class, exposing them through
|
||||
* the {@link org.springframework.core.type.AnnotationMetadata} interface.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Mark Fisher
|
||||
* @author Costin Leau
|
||||
* @author Phillip Webb
|
||||
* @author Sam Brannen
|
||||
* @since 2.5
|
||||
* @deprecated As of Spring Framework 5.2, this class has been replaced by
|
||||
* {@link SimpleAnnotationMetadataReadingVisitor} for internal use within the
|
||||
* framework, but there is no public replacement for
|
||||
* {@code AnnotationMetadataReadingVisitor}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor implements AnnotationMetadata {
|
||||
|
||||
@Nullable
|
||||
protected final ClassLoader classLoader;
|
||||
|
||||
protected final Set<String> annotationSet = new LinkedHashSet<>(4);
|
||||
|
||||
protected final Map<String, Set<String>> metaAnnotationMap = new LinkedHashMap<>(4);
|
||||
|
||||
/**
|
||||
* Declared as a {@link LinkedMultiValueMap} instead of a {@link MultiValueMap}
|
||||
* to ensure that the hierarchical ordering of the entries is preserved.
|
||||
* @see AnnotationReadingVisitorUtils#getMergedAnnotationAttributes
|
||||
*/
|
||||
protected final LinkedMultiValueMap<String, AnnotationAttributes> attributesMap = new LinkedMultiValueMap<>(3);
|
||||
|
||||
protected final Set<MethodMetadata> methodMetadataSet = new LinkedHashSet<>(4);
|
||||
|
||||
|
||||
public AnnotationMetadataReadingVisitor(@Nullable ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public MergedAnnotations getAnnotations() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||
// Skip bridge methods - we're only interested in original annotation-defining user methods.
|
||||
// On JDK 8, we'd otherwise run into double detection of the same annotated method...
|
||||
if ((access & Opcodes.ACC_BRIDGE) != 0) {
|
||||
return super.visitMethod(access, name, desc, signature, exceptions);
|
||||
}
|
||||
return new MethodMetadataReadingVisitor(name, access, getClassName(),
|
||||
Type.getReturnType(desc).getClassName(), this.classLoader, this.methodMetadataSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
|
||||
if (!visible) {
|
||||
return null;
|
||||
}
|
||||
String className = Type.getType(desc).getClassName();
|
||||
if (AnnotationUtils.isInJavaLangAnnotationPackage(className)) {
|
||||
return null;
|
||||
}
|
||||
this.annotationSet.add(className);
|
||||
return new AnnotationAttributesReadingVisitor(
|
||||
className, this.attributesMap, this.metaAnnotationMap, this.classLoader);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<String> getAnnotationTypes() {
|
||||
return this.annotationSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getMetaAnnotationTypes(String annotationName) {
|
||||
Set<String> metaAnnotationTypes = this.metaAnnotationMap.get(annotationName);
|
||||
return (metaAnnotationTypes != null ? metaAnnotationTypes : Collections.emptySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMetaAnnotation(String metaAnnotationType) {
|
||||
if (AnnotationUtils.isInJavaLangAnnotationPackage(metaAnnotationType)) {
|
||||
return false;
|
||||
}
|
||||
Collection<Set<String>> allMetaTypes = this.metaAnnotationMap.values();
|
||||
for (Set<String> metaTypes : allMetaTypes) {
|
||||
if (metaTypes.contains(metaAnnotationType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnnotated(String annotationName) {
|
||||
return (!AnnotationUtils.isInJavaLangAnnotationPackage(annotationName) &&
|
||||
this.attributesMap.containsKey(annotationName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAnnotation(String annotationName) {
|
||||
return getAnnotationTypes().contains(annotationName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public AnnotationAttributes getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
|
||||
AnnotationAttributes raw = AnnotationReadingVisitorUtils.getMergedAnnotationAttributes(
|
||||
this.attributesMap, this.metaAnnotationMap, annotationName);
|
||||
if (raw == null) {
|
||||
return null;
|
||||
}
|
||||
return AnnotationReadingVisitorUtils.convertClassValues(
|
||||
"class '" + getClassName() + "'", this.classLoader, raw, classValuesAsString);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) {
|
||||
MultiValueMap<String, Object> allAttributes = new LinkedMultiValueMap<>();
|
||||
List<AnnotationAttributes> attributes = this.attributesMap.get(annotationName);
|
||||
if (attributes == null) {
|
||||
return null;
|
||||
}
|
||||
String annotatedElement = "class '" + getClassName() + "'";
|
||||
for (AnnotationAttributes raw : attributes) {
|
||||
for (Map.Entry<String, Object> entry : AnnotationReadingVisitorUtils.convertClassValues(
|
||||
annotatedElement, this.classLoader, raw, classValuesAsString).entrySet()) {
|
||||
allAttributes.add(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
return allAttributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAnnotatedMethods(String annotationName) {
|
||||
for (MethodMetadata methodMetadata : this.methodMetadataSet) {
|
||||
if (methodMetadata.isAnnotated(annotationName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<MethodMetadata> getAnnotatedMethods(String annotationName) {
|
||||
Set<MethodMetadata> annotatedMethods = new LinkedHashSet<>(4);
|
||||
for (MethodMetadata methodMetadata : this.methodMetadataSet) {
|
||||
if (methodMetadata.isAnnotated(annotationName)) {
|
||||
annotatedMethods.add(methodMetadata);
|
||||
}
|
||||
}
|
||||
return annotatedMethods;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,172 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2021 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.type.classreading;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.asm.Type;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Internal utility class used when reading annotations via ASM.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Mark Fisher
|
||||
* @author Costin Leau
|
||||
* @author Phillip Webb
|
||||
* @author Sam Brannen
|
||||
* @since 4.0
|
||||
* @deprecated As of Spring Framework 5.2, this class and related classes in this
|
||||
* package have been replaced by {@link SimpleAnnotationMetadataReadingVisitor}
|
||||
* and related classes for internal use within the framework.
|
||||
*/
|
||||
@Deprecated
|
||||
abstract class AnnotationReadingVisitorUtils {
|
||||
|
||||
public static AnnotationAttributes convertClassValues(Object annotatedElement,
|
||||
@Nullable ClassLoader classLoader, AnnotationAttributes original, boolean classValuesAsString) {
|
||||
|
||||
AnnotationAttributes result = new AnnotationAttributes(original);
|
||||
AnnotationUtils.postProcessAnnotationAttributes(annotatedElement, result, classValuesAsString);
|
||||
|
||||
for (Map.Entry<String, Object> entry : result.entrySet()) {
|
||||
try {
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof AnnotationAttributes) {
|
||||
value = convertClassValues(
|
||||
annotatedElement, classLoader, (AnnotationAttributes) value, classValuesAsString);
|
||||
}
|
||||
else if (value instanceof AnnotationAttributes[] values) {
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
values[i] = convertClassValues(annotatedElement, classLoader, values[i], classValuesAsString);
|
||||
}
|
||||
value = values;
|
||||
}
|
||||
else if (value instanceof Type) {
|
||||
value = (classValuesAsString ? ((Type) value).getClassName() :
|
||||
ClassUtils.forName(((Type) value).getClassName(), classLoader));
|
||||
}
|
||||
else if (value instanceof Type[] array) {
|
||||
Object[] convArray =
|
||||
(classValuesAsString ? new String[array.length] : new Class<?>[array.length]);
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
convArray[i] = (classValuesAsString ? array[i].getClassName() :
|
||||
ClassUtils.forName(array[i].getClassName(), classLoader));
|
||||
}
|
||||
value = convArray;
|
||||
}
|
||||
else if (classValuesAsString) {
|
||||
if (value instanceof Class) {
|
||||
value = ((Class<?>) value).getName();
|
||||
}
|
||||
else if (value instanceof Class[]) {
|
||||
Class<?>[] clazzArray = (Class<?>[]) value;
|
||||
String[] newValue = new String[clazzArray.length];
|
||||
for (int i = 0; i < clazzArray.length; i++) {
|
||||
newValue[i] = clazzArray[i].getName();
|
||||
}
|
||||
value = newValue;
|
||||
}
|
||||
}
|
||||
entry.setValue(value);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
// Class not found - can't resolve class reference in annotation attribute.
|
||||
result.put(entry.getKey(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the merged attributes of the annotation of the given type,
|
||||
* if any, from the supplied {@code attributesMap}.
|
||||
* <p>Annotation attribute values appearing <em>lower</em> in the annotation
|
||||
* hierarchy (i.e., closer to the declaring class) will override those
|
||||
* defined <em>higher</em> in the annotation hierarchy.
|
||||
* @param attributesMap the map of annotation attribute lists, keyed by
|
||||
* annotation type name
|
||||
* @param metaAnnotationMap the map of meta annotation relationships,
|
||||
* keyed by annotation type name
|
||||
* @param annotationName the fully qualified class name of the annotation
|
||||
* type to look for
|
||||
* @return the merged annotation attributes, or {@code null} if no
|
||||
* matching annotation is present in the {@code attributesMap}
|
||||
* @since 4.0.3
|
||||
*/
|
||||
@Nullable
|
||||
public static AnnotationAttributes getMergedAnnotationAttributes(
|
||||
LinkedMultiValueMap<String, AnnotationAttributes> attributesMap,
|
||||
Map<String, Set<String>> metaAnnotationMap, String annotationName) {
|
||||
|
||||
// Get the unmerged list of attributes for the target annotation.
|
||||
List<AnnotationAttributes> attributesList = attributesMap.get(annotationName);
|
||||
if (CollectionUtils.isEmpty(attributesList)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// To start with, we populate the result with a copy of all attribute values
|
||||
// from the target annotation. A copy is necessary so that we do not
|
||||
// inadvertently mutate the state of the metadata passed to this method.
|
||||
AnnotationAttributes result = new AnnotationAttributes(attributesList.get(0));
|
||||
|
||||
Set<String> overridableAttributeNames = new HashSet<>(result.keySet());
|
||||
overridableAttributeNames.remove(AnnotationUtils.VALUE);
|
||||
|
||||
// Since the map is a LinkedMultiValueMap, we depend on the ordering of
|
||||
// elements in the map and reverse the order of the keys in order to traverse
|
||||
// "down" the annotation hierarchy.
|
||||
List<String> annotationTypes = new ArrayList<>(attributesMap.keySet());
|
||||
Collections.reverse(annotationTypes);
|
||||
|
||||
// No need to revisit the target annotation type:
|
||||
annotationTypes.remove(annotationName);
|
||||
|
||||
for (String currentAnnotationType : annotationTypes) {
|
||||
List<AnnotationAttributes> currentAttributesList = attributesMap.get(currentAnnotationType);
|
||||
if (!ObjectUtils.isEmpty(currentAttributesList)) {
|
||||
Set<String> metaAnns = metaAnnotationMap.get(currentAnnotationType);
|
||||
if (metaAnns != null && metaAnns.contains(annotationName)) {
|
||||
AnnotationAttributes currentAttributes = currentAttributesList.get(0);
|
||||
for (String overridableAttributeName : overridableAttributeNames) {
|
||||
Object value = currentAttributes.get(overridableAttributeName);
|
||||
if (value != null) {
|
||||
// Store the value, potentially overriding a value from an attribute
|
||||
// of the same name found higher in the annotation hierarchy.
|
||||
result.put(overridableAttributeName, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,244 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2021 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.type.classreading;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.asm.AnnotationVisitor;
|
||||
import org.springframework.asm.Attribute;
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
import org.springframework.asm.FieldVisitor;
|
||||
import org.springframework.asm.MethodVisitor;
|
||||
import org.springframework.asm.Opcodes;
|
||||
import org.springframework.asm.SpringAsmInfo;
|
||||
import org.springframework.core.type.ClassMetadata;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* ASM class visitor which looks only for the class name and implemented types,
|
||||
* exposing them through the {@link org.springframework.core.type.ClassMetadata}
|
||||
* interface.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Costin Leau
|
||||
* @author Mark Fisher
|
||||
* @author Ramnivas Laddad
|
||||
* @author Chris Beams
|
||||
* @since 2.5
|
||||
* @deprecated As of Spring Framework 5.2, this class and related classes in this
|
||||
* package have been replaced by {@link SimpleAnnotationMetadataReadingVisitor}
|
||||
* and related classes for internal use within the framework.
|
||||
*/
|
||||
@Deprecated
|
||||
class ClassMetadataReadingVisitor extends ClassVisitor implements ClassMetadata {
|
||||
|
||||
private String className = "";
|
||||
|
||||
private boolean isInterface;
|
||||
|
||||
private boolean isAnnotation;
|
||||
|
||||
private boolean isAbstract;
|
||||
|
||||
private boolean isFinal;
|
||||
|
||||
@Nullable
|
||||
private String enclosingClassName;
|
||||
|
||||
private boolean independentInnerClass;
|
||||
|
||||
@Nullable
|
||||
private String superClassName;
|
||||
|
||||
private String[] interfaces = new String[0];
|
||||
|
||||
private final Set<String> memberClassNames = new LinkedHashSet<>(4);
|
||||
|
||||
|
||||
public ClassMetadataReadingVisitor() {
|
||||
super(SpringAsmInfo.ASM_VERSION);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(
|
||||
int version, int access, String name, String signature, @Nullable String supername, String[] interfaces) {
|
||||
|
||||
this.className = ClassUtils.convertResourcePathToClassName(name);
|
||||
this.isInterface = ((access & Opcodes.ACC_INTERFACE) != 0);
|
||||
this.isAnnotation = ((access & Opcodes.ACC_ANNOTATION) != 0);
|
||||
this.isAbstract = ((access & Opcodes.ACC_ABSTRACT) != 0);
|
||||
this.isFinal = ((access & Opcodes.ACC_FINAL) != 0);
|
||||
if (supername != null && !this.isInterface) {
|
||||
this.superClassName = ClassUtils.convertResourcePathToClassName(supername);
|
||||
}
|
||||
this.interfaces = new String[interfaces.length];
|
||||
for (int i = 0; i < interfaces.length; i++) {
|
||||
this.interfaces[i] = ClassUtils.convertResourcePathToClassName(interfaces[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitOuterClass(String owner, String name, String desc) {
|
||||
this.enclosingClassName = ClassUtils.convertResourcePathToClassName(owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInnerClass(String name, @Nullable String outerName, String innerName, int access) {
|
||||
if (outerName != null) {
|
||||
String fqName = ClassUtils.convertResourcePathToClassName(name);
|
||||
String fqOuterName = ClassUtils.convertResourcePathToClassName(outerName);
|
||||
if (this.className.equals(fqName)) {
|
||||
this.enclosingClassName = fqOuterName;
|
||||
this.independentInnerClass = ((access & Opcodes.ACC_STATIC) != 0);
|
||||
}
|
||||
else if (this.className.equals(fqOuterName)) {
|
||||
this.memberClassNames.add(fqName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSource(String source, String debug) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
|
||||
// no-op
|
||||
return new EmptyAnnotationVisitor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAttribute(Attribute attr) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
|
||||
// no-op
|
||||
return new EmptyFieldVisitor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||
// no-op
|
||||
return new EmptyMethodVisitor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return this.className;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInterface() {
|
||||
return this.isInterface;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnnotation() {
|
||||
return this.isAnnotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbstract() {
|
||||
return this.isAbstract;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinal() {
|
||||
return this.isFinal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIndependent() {
|
||||
return (this.enclosingClassName == null || this.independentInnerClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasEnclosingClass() {
|
||||
return (this.enclosingClassName != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getEnclosingClassName() {
|
||||
return this.enclosingClassName;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getSuperClassName() {
|
||||
return this.superClassName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getInterfaceNames() {
|
||||
return this.interfaces;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getMemberClassNames() {
|
||||
return StringUtils.toStringArray(this.memberClassNames);
|
||||
}
|
||||
|
||||
|
||||
private static class EmptyAnnotationVisitor extends AnnotationVisitor {
|
||||
|
||||
public EmptyAnnotationVisitor() {
|
||||
super(SpringAsmInfo.ASM_VERSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String name, String desc) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitArray(String name) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class EmptyMethodVisitor extends MethodVisitor {
|
||||
|
||||
public EmptyMethodVisitor() {
|
||||
super(SpringAsmInfo.ASM_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class EmptyFieldVisitor extends FieldVisitor {
|
||||
|
||||
public EmptyFieldVisitor() {
|
||||
super(SpringAsmInfo.ASM_VERSION);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,174 +0,0 @@
|
|||
/*
|
||||
* 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.type.classreading;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.asm.AnnotationVisitor;
|
||||
import org.springframework.asm.MethodVisitor;
|
||||
import org.springframework.asm.Opcodes;
|
||||
import org.springframework.asm.SpringAsmInfo;
|
||||
import org.springframework.asm.Type;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.annotation.MergedAnnotations;
|
||||
import org.springframework.core.type.MethodMetadata;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
/**
|
||||
* ASM method visitor which looks for the annotations defined on a method,
|
||||
* exposing them through the {@link org.springframework.core.type.MethodMetadata}
|
||||
* interface.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Mark Pollack
|
||||
* @author Costin Leau
|
||||
* @author Chris Beams
|
||||
* @author Phillip Webb
|
||||
* @since 3.0
|
||||
* @deprecated As of Spring Framework 5.2, this class and related classes in this
|
||||
* package have been replaced by {@link SimpleAnnotationMetadataReadingVisitor}
|
||||
* and related classes for internal use within the framework.
|
||||
*/
|
||||
@Deprecated
|
||||
public class MethodMetadataReadingVisitor extends MethodVisitor implements MethodMetadata {
|
||||
|
||||
protected final String methodName;
|
||||
|
||||
protected final int access;
|
||||
|
||||
protected final String declaringClassName;
|
||||
|
||||
protected final String returnTypeName;
|
||||
|
||||
@Nullable
|
||||
protected final ClassLoader classLoader;
|
||||
|
||||
protected final Set<MethodMetadata> methodMetadataSet;
|
||||
|
||||
protected final Map<String, Set<String>> metaAnnotationMap = new LinkedHashMap<>(4);
|
||||
|
||||
protected final LinkedMultiValueMap<String, AnnotationAttributes> attributesMap = new LinkedMultiValueMap<>(3);
|
||||
|
||||
|
||||
public MethodMetadataReadingVisitor(String methodName, int access, String declaringClassName,
|
||||
String returnTypeName, @Nullable ClassLoader classLoader, Set<MethodMetadata> methodMetadataSet) {
|
||||
|
||||
super(SpringAsmInfo.ASM_VERSION);
|
||||
this.methodName = methodName;
|
||||
this.access = access;
|
||||
this.declaringClassName = declaringClassName;
|
||||
this.returnTypeName = returnTypeName;
|
||||
this.classLoader = classLoader;
|
||||
this.methodMetadataSet = methodMetadataSet;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public MergedAnnotations getAnnotations() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) {
|
||||
if (!visible) {
|
||||
return null;
|
||||
}
|
||||
this.methodMetadataSet.add(this);
|
||||
String className = Type.getType(desc).getClassName();
|
||||
return new AnnotationAttributesReadingVisitor(
|
||||
className, this.attributesMap, this.metaAnnotationMap, this.classLoader);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getMethodName() {
|
||||
return this.methodName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbstract() {
|
||||
return ((this.access & Opcodes.ACC_ABSTRACT) != 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
return ((this.access & Opcodes.ACC_STATIC) != 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinal() {
|
||||
return ((this.access & Opcodes.ACC_FINAL) != 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverridable() {
|
||||
return (!isStatic() && !isFinal() && ((this.access & Opcodes.ACC_PRIVATE) == 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnnotated(String annotationName) {
|
||||
return this.attributesMap.containsKey(annotationName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public AnnotationAttributes getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
|
||||
AnnotationAttributes raw = AnnotationReadingVisitorUtils.getMergedAnnotationAttributes(
|
||||
this.attributesMap, this.metaAnnotationMap, annotationName);
|
||||
if (raw == null) {
|
||||
return null;
|
||||
}
|
||||
return AnnotationReadingVisitorUtils.convertClassValues(
|
||||
"method '" + getMethodName() + "'", this.classLoader, raw, classValuesAsString);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) {
|
||||
if (!this.attributesMap.containsKey(annotationName)) {
|
||||
return null;
|
||||
}
|
||||
MultiValueMap<String, Object> allAttributes = new LinkedMultiValueMap<>();
|
||||
List<AnnotationAttributes> attributesList = this.attributesMap.get(annotationName);
|
||||
if (attributesList != null) {
|
||||
String annotatedElement = "method '" + getMethodName() + '\'';
|
||||
for (AnnotationAttributes annotationAttributes : attributesList) {
|
||||
AnnotationAttributes convertedAttributes = AnnotationReadingVisitorUtils.convertClassValues(
|
||||
annotatedElement, this.classLoader, annotationAttributes, classValuesAsString);
|
||||
convertedAttributes.forEach(allAttributes::add);
|
||||
}
|
||||
}
|
||||
return allAttributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeclaringClassName() {
|
||||
return this.declaringClassName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReturnTypeName() {
|
||||
return this.returnTypeName;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2019 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.type.classreading;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.asm.AnnotationVisitor;
|
||||
import org.springframework.asm.Type;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* {@link AnnotationVisitor} to recursively visit annotation arrays.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.1.1
|
||||
* @deprecated As of Spring Framework 5.2, this class and related classes in this
|
||||
* package have been replaced by {@link SimpleAnnotationMetadataReadingVisitor}
|
||||
* and related classes for internal use within the framework.
|
||||
*/
|
||||
@Deprecated
|
||||
class RecursiveAnnotationArrayVisitor extends AbstractRecursiveAnnotationVisitor {
|
||||
|
||||
private final String attributeName;
|
||||
|
||||
private final List<AnnotationAttributes> allNestedAttributes = new ArrayList<>();
|
||||
|
||||
|
||||
public RecursiveAnnotationArrayVisitor(
|
||||
String attributeName, AnnotationAttributes attributes, @Nullable ClassLoader classLoader) {
|
||||
|
||||
super(classLoader, attributes);
|
||||
this.attributeName = attributeName;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(String attributeName, Object attributeValue) {
|
||||
Object newValue = attributeValue;
|
||||
Object existingValue = this.attributes.get(this.attributeName);
|
||||
if (existingValue != null) {
|
||||
newValue = ObjectUtils.addObjectToArray((Object[]) existingValue, newValue);
|
||||
}
|
||||
else {
|
||||
Class<?> arrayClass = newValue.getClass();
|
||||
if (Enum.class.isAssignableFrom(arrayClass)) {
|
||||
while (arrayClass.getSuperclass() != null && !arrayClass.isEnum()) {
|
||||
arrayClass = arrayClass.getSuperclass();
|
||||
}
|
||||
}
|
||||
Object[] newArray = (Object[]) Array.newInstance(arrayClass, 1);
|
||||
newArray[0] = newValue;
|
||||
newValue = newArray;
|
||||
}
|
||||
this.attributes.put(this.attributeName, newValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String attributeName, String asmTypeDescriptor) {
|
||||
String annotationType = Type.getType(asmTypeDescriptor).getClassName();
|
||||
AnnotationAttributes nestedAttributes = new AnnotationAttributes(annotationType, this.classLoader);
|
||||
this.allNestedAttributes.add(nestedAttributes);
|
||||
return new RecursiveAnnotationAttributesVisitor(annotationType, nestedAttributes, this.classLoader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
if (!this.allNestedAttributes.isEmpty()) {
|
||||
this.attributes.put(this.attributeName, this.allNestedAttributes.toArray(new AnnotationAttributes[0]));
|
||||
}
|
||||
else if (!this.attributes.containsKey(this.attributeName)) {
|
||||
Class<? extends Annotation> annotationType = this.attributes.annotationType();
|
||||
if (annotationType != null) {
|
||||
try {
|
||||
Class<?> attributeType = annotationType.getMethod(this.attributeName).getReturnType();
|
||||
if (attributeType.isArray()) {
|
||||
Class<?> elementType = attributeType.getComponentType();
|
||||
if (elementType.isAnnotation()) {
|
||||
elementType = AnnotationAttributes.class;
|
||||
}
|
||||
this.attributes.put(this.attributeName, Array.newInstance(elementType, 0));
|
||||
}
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
// Corresponding attribute method not found: cannot expose empty array.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2019 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.type.classreading;
|
||||
|
||||
import org.springframework.asm.AnnotationVisitor;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* {@link AnnotationVisitor} to recursively visit annotation attributes.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.1.1
|
||||
* @deprecated As of Spring Framework 5.2, this class and related classes in this
|
||||
* package have been replaced by {@link SimpleAnnotationMetadataReadingVisitor}
|
||||
* and related classes for internal use within the framework.
|
||||
*/
|
||||
@Deprecated
|
||||
class RecursiveAnnotationAttributesVisitor extends AbstractRecursiveAnnotationVisitor {
|
||||
|
||||
protected final String annotationType;
|
||||
|
||||
|
||||
public RecursiveAnnotationAttributesVisitor(
|
||||
String annotationType, AnnotationAttributes attributes, @Nullable ClassLoader classLoader) {
|
||||
|
||||
super(classLoader, attributes);
|
||||
this.annotationType = annotationType;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visitEnd() {
|
||||
AnnotationUtils.registerDefaultValues(this.attributes);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.lang;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Indicates that the annotated element uses Java 7 specific API constructs,
|
||||
* without implying that it strictly requires Java 7.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.1
|
||||
* @deprecated as of 5.0 since the framework is based on Java 8+ now
|
||||
*/
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE})
|
||||
@Documented
|
||||
@Deprecated
|
||||
public @interface UsesJava7 {
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.lang;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Indicates that the annotated element uses Java 8 specific API constructs,
|
||||
* without implying that it strictly requires Java 8.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.1
|
||||
* @deprecated as of 5.0 since the framework is based on Java 8+ now
|
||||
*/
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE})
|
||||
@Documented
|
||||
@Deprecated
|
||||
public @interface UsesJava8 {
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.lang;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Indicates that the annotated element uses the Http Server available in
|
||||
* {@code com.sun.*} classes, which is only available on a Sun/Oracle JVM.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.1
|
||||
* @deprecated as of 5.1, along with Spring's Sun HTTP Server support classes
|
||||
*/
|
||||
@Deprecated
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE})
|
||||
@Documented
|
||||
public @interface UsesSunHttpServer {
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2016 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.lang;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Indicates that the annotated element uses an API from the {@code sun.misc}
|
||||
* package.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.3
|
||||
*/
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE})
|
||||
@Documented
|
||||
public @interface UsesSunMisc {
|
||||
}
|
|
@ -558,42 +558,6 @@ public abstract class ObjectUtils {
|
|||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the same value as {@link Boolean#hashCode(boolean)}}.
|
||||
* @deprecated as of Spring Framework 5.0, in favor of the native JDK 8 variant
|
||||
*/
|
||||
@Deprecated
|
||||
public static int hashCode(boolean bool) {
|
||||
return Boolean.hashCode(bool);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the same value as {@link Double#hashCode(double)}}.
|
||||
* @deprecated as of Spring Framework 5.0, in favor of the native JDK 8 variant
|
||||
*/
|
||||
@Deprecated
|
||||
public static int hashCode(double dbl) {
|
||||
return Double.hashCode(dbl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the same value as {@link Float#hashCode(float)}}.
|
||||
* @deprecated as of Spring Framework 5.0, in favor of the native JDK 8 variant
|
||||
*/
|
||||
@Deprecated
|
||||
public static int hashCode(float flt) {
|
||||
return Float.hashCode(flt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the same value as {@link Long#hashCode(long)}}.
|
||||
* @deprecated as of Spring Framework 5.0, in favor of the native JDK 8 variant
|
||||
*/
|
||||
@Deprecated
|
||||
public static int hashCode(long lng) {
|
||||
return Long.hashCode(lng);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Convenience methods for toString output
|
||||
|
|
|
@ -886,18 +886,6 @@ public abstract class StringUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the RFC 3066 compliant language tag,
|
||||
* as used for the HTTP "Accept-Language" header.
|
||||
* @param locale the Locale to transform to a language tag
|
||||
* @return the RFC 3066 compliant language tag as {@code String}
|
||||
* @deprecated as of 5.0.4, in favor of {@link Locale#toLanguageTag()}
|
||||
*/
|
||||
@Deprecated
|
||||
public static String toLanguageTag(Locale locale) {
|
||||
return locale.getLanguage() + (hasText(locale.getCountry()) ? "-" + locale.getCountry() : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the given {@code timeZoneString} value into a {@link TimeZone}.
|
||||
* @param timeZoneString the time zone {@code String}, following {@link TimeZone#getTimeZone(String)}
|
||||
|
@ -983,37 +971,6 @@ public abstract class StringUtils {
|
|||
return newArr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the given {@code String} arrays into one, with overlapping
|
||||
* array elements only included once.
|
||||
* <p>The order of elements in the original arrays is preserved
|
||||
* (with the exception of overlapping elements, which are only
|
||||
* included on their first occurrence).
|
||||
* @param array1 the first array (can be {@code null})
|
||||
* @param array2 the second array (can be {@code null})
|
||||
* @return the new array ({@code null} if both given arrays were {@code null})
|
||||
* @deprecated as of 4.3.15, in favor of manual merging via {@link LinkedHashSet}
|
||||
* (with every entry included at most once, even entries within the first array)
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
public static String[] mergeStringArrays(@Nullable String[] array1, @Nullable String[] array2) {
|
||||
if (ObjectUtils.isEmpty(array1)) {
|
||||
return array2;
|
||||
}
|
||||
if (ObjectUtils.isEmpty(array2)) {
|
||||
return array1;
|
||||
}
|
||||
|
||||
List<String> result = new ArrayList<>(Arrays.asList(array1));
|
||||
for (String str : array2) {
|
||||
if (!result.contains(str)) {
|
||||
result.add(str);
|
||||
}
|
||||
}
|
||||
return toStringArray(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the given {@code String} array if necessary.
|
||||
* @param array the original array (potentially empty)
|
||||
|
|
|
@ -1,206 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.util.comparator;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A comparator that chains a sequence of one or more Comparators.
|
||||
*
|
||||
* <p>A compound comparator calls each Comparator in sequence until a single
|
||||
* Comparator returns a non-zero result, or the comparators are exhausted and
|
||||
* zero is returned.
|
||||
*
|
||||
* <p>This facilitates in-memory sorting similar to multi-column sorting in SQL.
|
||||
* The order of any single Comparator in the list can also be reversed.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.2.2
|
||||
* @param <T> the type of objects that may be compared by this comparator
|
||||
* @deprecated as of Spring Framework 5.0, in favor of the standard JDK 8
|
||||
* {@link Comparator#thenComparing(Comparator)}
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings({"serial", "rawtypes"})
|
||||
public class CompoundComparator<T> implements Comparator<T>, Serializable {
|
||||
|
||||
private final List<InvertibleComparator> comparators;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a CompoundComparator with initially no Comparators. Clients
|
||||
* must add at least one Comparator before calling the compare method or an
|
||||
* IllegalStateException is thrown.
|
||||
*/
|
||||
public CompoundComparator() {
|
||||
this.comparators = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a CompoundComparator from the Comparators in the provided array.
|
||||
* <p>All Comparators will default to ascending sort order,
|
||||
* unless they are InvertibleComparators.
|
||||
* @param comparators the comparators to build into a compound comparator
|
||||
* @see InvertibleComparator
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public CompoundComparator(Comparator... comparators) {
|
||||
Assert.notNull(comparators, "Comparators must not be null");
|
||||
this.comparators = new ArrayList<>(comparators.length);
|
||||
for (Comparator comparator : comparators) {
|
||||
addComparator(comparator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a Comparator to the end of the chain.
|
||||
* <p>The Comparator will default to ascending sort order,
|
||||
* unless it is a InvertibleComparator.
|
||||
* @param comparator the Comparator to add to the end of the chain
|
||||
* @see InvertibleComparator
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void addComparator(Comparator<? extends T> comparator) {
|
||||
if (comparator instanceof InvertibleComparator) {
|
||||
this.comparators.add((InvertibleComparator) comparator);
|
||||
}
|
||||
else {
|
||||
this.comparators.add(new InvertibleComparator(comparator));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Comparator to the end of the chain using the provided sort order.
|
||||
* @param comparator the Comparator to add to the end of the chain
|
||||
* @param ascending the sort order: ascending (true) or descending (false)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void addComparator(Comparator<? extends T> comparator, boolean ascending) {
|
||||
this.comparators.add(new InvertibleComparator(comparator, ascending));
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the Comparator at the given index.
|
||||
* <p>The Comparator will default to ascending sort order,
|
||||
* unless it is a InvertibleComparator.
|
||||
* @param index the index of the Comparator to replace
|
||||
* @param comparator the Comparator to place at the given index
|
||||
* @see InvertibleComparator
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setComparator(int index, Comparator<? extends T> comparator) {
|
||||
if (comparator instanceof InvertibleComparator) {
|
||||
this.comparators.set(index, (InvertibleComparator) comparator);
|
||||
}
|
||||
else {
|
||||
this.comparators.set(index, new InvertibleComparator(comparator));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the Comparator at the given index using the given sort order.
|
||||
* @param index the index of the Comparator to replace
|
||||
* @param comparator the Comparator to place at the given index
|
||||
* @param ascending the sort order: ascending (true) or descending (false)
|
||||
*/
|
||||
public void setComparator(int index, Comparator<T> comparator, boolean ascending) {
|
||||
this.comparators.set(index, new InvertibleComparator<>(comparator, ascending));
|
||||
}
|
||||
|
||||
/**
|
||||
* Invert the sort order of each sort definition contained by this compound
|
||||
* comparator.
|
||||
*/
|
||||
public void invertOrder() {
|
||||
for (InvertibleComparator comparator : this.comparators) {
|
||||
comparator.invertOrder();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invert the sort order of the sort definition at the specified index.
|
||||
* @param index the index of the comparator to invert
|
||||
*/
|
||||
public void invertOrder(int index) {
|
||||
this.comparators.get(index).invertOrder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the sort order at the given index to ascending.
|
||||
* @param index the index of the comparator to change
|
||||
*/
|
||||
public void setAscendingOrder(int index) {
|
||||
this.comparators.get(index).setAscending(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the sort order at the given index to descending sort.
|
||||
* @param index the index of the comparator to change
|
||||
*/
|
||||
public void setDescendingOrder(int index) {
|
||||
this.comparators.get(index).setAscending(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of aggregated comparators.
|
||||
*/
|
||||
public int getComparatorCount() {
|
||||
return this.comparators.size();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public int compare(T o1, T o2) {
|
||||
Assert.state(!this.comparators.isEmpty(),
|
||||
"No sort definitions have been added to this CompoundComparator to compare");
|
||||
for (InvertibleComparator comparator : this.comparators) {
|
||||
int result = comparator.compare(o1, o2);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean equals(@Nullable Object other) {
|
||||
return (this == other || (other instanceof CompoundComparator &&
|
||||
this.comparators.equals(((CompoundComparator<T>) other).comparators)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.comparators.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CompoundComparator: " + this.comparators;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.util.comparator;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A decorator for a comparator, with an "ascending" flag denoting
|
||||
* whether comparison results should be treated in forward (standard
|
||||
* ascending) order or flipped for reverse (descending) order.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.2.2
|
||||
* @param <T> the type of objects that may be compared by this comparator
|
||||
* @deprecated as of Spring Framework 5.0, in favor of the standard JDK 8
|
||||
* {@link Comparator#reversed()}
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("serial")
|
||||
public class InvertibleComparator<T> implements Comparator<T>, Serializable {
|
||||
|
||||
private final Comparator<T> comparator;
|
||||
|
||||
private boolean ascending = true;
|
||||
|
||||
|
||||
/**
|
||||
* Create an InvertibleComparator that sorts ascending by default.
|
||||
* For the actual comparison, the specified Comparator will be used.
|
||||
* @param comparator the comparator to decorate
|
||||
*/
|
||||
public InvertibleComparator(Comparator<T> comparator) {
|
||||
Assert.notNull(comparator, "Comparator must not be null");
|
||||
this.comparator = comparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an InvertibleComparator that sorts based on the provided order.
|
||||
* For the actual comparison, the specified Comparator will be used.
|
||||
* @param comparator the comparator to decorate
|
||||
* @param ascending the sort order: ascending (true) or descending (false)
|
||||
*/
|
||||
public InvertibleComparator(Comparator<T> comparator, boolean ascending) {
|
||||
Assert.notNull(comparator, "Comparator must not be null");
|
||||
this.comparator = comparator;
|
||||
setAscending(ascending);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specify the sort order: ascending (true) or descending (false).
|
||||
*/
|
||||
public void setAscending(boolean ascending) {
|
||||
this.ascending = ascending;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the sort order: ascending (true) or descending (false).
|
||||
*/
|
||||
public boolean isAscending() {
|
||||
return this.ascending;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invert the sort order: ascending → descending or
|
||||
* descending → ascending.
|
||||
*/
|
||||
public void invertOrder() {
|
||||
this.ascending = !this.ascending;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int compare(T o1, T o2) {
|
||||
int result = this.comparator.compare(o1, o2);
|
||||
if (result != 0) {
|
||||
// Invert the order if it is a reverse sort.
|
||||
if (!this.ascending) {
|
||||
if (Integer.MIN_VALUE == result) {
|
||||
result = Integer.MAX_VALUE;
|
||||
}
|
||||
else {
|
||||
result *= -1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof InvertibleComparator)) {
|
||||
return false;
|
||||
}
|
||||
InvertibleComparator<T> otherComp = (InvertibleComparator<T>) other;
|
||||
return (this.comparator.equals(otherComp.comparator) && this.ascending == otherComp.ascending);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.comparator.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "InvertibleComparator: [" + this.comparator + "]; ascending=" + this.ascending;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -19,7 +19,6 @@ package org.springframework.core.annotation;
|
|||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Repeatable;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
@ -36,7 +35,6 @@ import org.junit.jupiter.api.Test;
|
|||
|
||||
import org.springframework.core.annotation.AnnotationTypeMapping.MirrorSets;
|
||||
import org.springframework.core.annotation.AnnotationTypeMapping.MirrorSets.MirrorSet;
|
||||
import org.springframework.lang.UsesSunMisc;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
@ -60,12 +58,6 @@ class AnnotationTypeMappingsTests {
|
|||
AnnotationTypeMapping::getAnnotationType).containsExactly(SimpleAnnotation.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void forAnnotationWhenHasSpringAnnotationReturnsFilteredMappings() {
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(WithSpringLangAnnotation.class);
|
||||
assertThat(mappings.size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void forAnnotationTypeWhenMetaAnnotationsReturnsMappings() {
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(MetaAnnotated.class);
|
||||
|
@ -526,12 +518,6 @@ class AnnotationTypeMappingsTests {
|
|||
@interface SimpleAnnotation {
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
@UsesSunMisc
|
||||
@interface WithSpringLangAnnotation {
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface AA {
|
||||
}
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2021 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.type.classreading;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.asm.ClassReader;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.core.type.AbstractAnnotationMetadataTests;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Tests for {@link AnnotationMetadataReadingVisitor}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
class AnnotationMetadataReadingVisitorTests extends AbstractAnnotationMetadataTests {
|
||||
|
||||
@Override
|
||||
protected AnnotationMetadata get(Class<?> source) {
|
||||
try {
|
||||
ClassLoader classLoader = source.getClassLoader();
|
||||
String className = source.getName();
|
||||
String resourcePath = ResourceLoader.CLASSPATH_URL_PREFIX
|
||||
+ ClassUtils.convertClassNameToResourcePath(className)
|
||||
+ ClassUtils.CLASS_FILE_SUFFIX;
|
||||
Resource resource = new DefaultResourceLoader().getResource(resourcePath);
|
||||
try (InputStream inputStream = new BufferedInputStream(
|
||||
resource.getInputStream())) {
|
||||
ClassReader classReader = new ClassReader(inputStream);
|
||||
AnnotationMetadataReadingVisitor metadata = new AnnotationMetadataReadingVisitor(
|
||||
classLoader);
|
||||
classReader.accept(metadata, ClassReader.SKIP_DEBUG);
|
||||
return metadata;
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("equals() not implemented in deprecated AnnotationMetadataReadingVisitor")
|
||||
@Override
|
||||
public void verifyEquals() throws Exception {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("hashCode() not implemented in deprecated AnnotationMetadataReadingVisitor")
|
||||
@Override
|
||||
public void verifyHashCode() throws Exception {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("toString() not implemented in deprecated AnnotationMetadataReadingVisitor")
|
||||
@Override
|
||||
public void verifyToString() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
public void getAnnotationsReturnsDirectAnnotations() {
|
||||
assertThatExceptionOfType(UnsupportedOperationException.class)
|
||||
.isThrownBy(super::getAnnotationsReturnsDirectAnnotations);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2021 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.type.classreading;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.asm.ClassReader;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.core.type.AbstractMethodMetadataTests;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Tests for {@link MethodMetadataReadingVisitor}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
class MethodMetadataReadingVisitorTests extends AbstractMethodMetadataTests {
|
||||
|
||||
@Override
|
||||
protected AnnotationMetadata get(Class<?> source) {
|
||||
try {
|
||||
ClassLoader classLoader = source.getClassLoader();
|
||||
String className = source.getName();
|
||||
String resourcePath = ResourceLoader.CLASSPATH_URL_PREFIX
|
||||
+ ClassUtils.convertClassNameToResourcePath(className)
|
||||
+ ClassUtils.CLASS_FILE_SUFFIX;
|
||||
Resource resource = new DefaultResourceLoader().getResource(resourcePath);
|
||||
try (InputStream inputStream = new BufferedInputStream(
|
||||
resource.getInputStream())) {
|
||||
ClassReader classReader = new ClassReader(inputStream);
|
||||
AnnotationMetadataReadingVisitor metadata = new AnnotationMetadataReadingVisitor(
|
||||
classLoader);
|
||||
classReader.accept(metadata, ClassReader.SKIP_DEBUG);
|
||||
return metadata;
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("equals() not implemented in deprecated MethodMetadataReadingVisitor")
|
||||
@Override
|
||||
public void verifyEquals() throws Exception {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("hashCode() not implemented in deprecated MethodMetadataReadingVisitor")
|
||||
@Override
|
||||
public void verifyHashCode() throws Exception {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("toString() not implemented in deprecated MethodMetadataReadingVisitor")
|
||||
@Override
|
||||
public void verifyToString() {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void getAnnotationsReturnsDirectAnnotations() {
|
||||
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(
|
||||
super::getAnnotationsReturnsDirectAnnotations);
|
||||
}
|
||||
|
||||
}
|
|
@ -233,44 +233,6 @@ class ObjectUtilsTests {
|
|||
assertThat(ObjectUtils.nullSafeEquals(new int[] {1, 2, 3}, new int[] {1, 2, 3})).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Deprecated
|
||||
void hashCodeWithBooleanFalse() {
|
||||
int expected = Boolean.FALSE.hashCode();
|
||||
assertThat(ObjectUtils.hashCode(false)).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Deprecated
|
||||
void hashCodeWithBooleanTrue() {
|
||||
int expected = Boolean.TRUE.hashCode();
|
||||
assertThat(ObjectUtils.hashCode(true)).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Deprecated
|
||||
void hashCodeWithDouble() {
|
||||
double dbl = 9830.43;
|
||||
int expected = Double.valueOf(dbl).hashCode();
|
||||
assertThat(ObjectUtils.hashCode(dbl)).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Deprecated
|
||||
void hashCodeWithFloat() {
|
||||
float flt = 34.8f;
|
||||
int expected = (Float.valueOf(flt)).hashCode();
|
||||
assertThat(ObjectUtils.hashCode(flt)).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Deprecated
|
||||
void hashCodeWithLong() {
|
||||
long lng = 883L;
|
||||
int expected = (Long.valueOf(lng)).hashCode();
|
||||
assertThat(ObjectUtils.hashCode(lng)).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
void identityToString() {
|
||||
Object obj = new Object();
|
||||
|
|
|
@ -440,21 +440,6 @@ class StringUtilsTests {
|
|||
assertThat(StringUtils.concatenateStringArrays(null, null)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Deprecated
|
||||
void mergeStringArrays() {
|
||||
String[] input1 = new String[] {"myString2"};
|
||||
String[] input2 = new String[] {"myString1", "myString2"};
|
||||
String[] result = StringUtils.mergeStringArrays(input1, input2);
|
||||
assertThat(result.length).isEqualTo(2);
|
||||
assertThat(result[0]).isEqualTo("myString2");
|
||||
assertThat(result[1]).isEqualTo("myString1");
|
||||
|
||||
assertThat(StringUtils.mergeStringArrays(input1, null)).isEqualTo(input1);
|
||||
assertThat(StringUtils.mergeStringArrays(null, input2)).isEqualTo(input2);
|
||||
assertThat(StringUtils.mergeStringArrays(null, null)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void sortStringArray() {
|
||||
String[] input = new String[] {"myString2"};
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2019 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.util.comparator;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
|
||||
/**
|
||||
* Test for {@link CompoundComparator}.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Chris Beams
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Deprecated
|
||||
class CompoundComparatorTests {
|
||||
|
||||
@Test
|
||||
void shouldNeedAtLeastOneComparator() {
|
||||
Comparator<String> c = new CompoundComparator<>();
|
||||
assertThatIllegalStateException().isThrownBy(() ->
|
||||
c.compare("foo", "bar"));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2019 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.util.comparator;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
|
||||
/**
|
||||
* Tests for {@link InvertibleComparator}.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Chris Beams
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Deprecated
|
||||
class InvertibleComparatorTests {
|
||||
|
||||
private final Comparator<Integer> comparator = new ComparableComparator<>();
|
||||
|
||||
|
||||
@Test
|
||||
void shouldNeedComparator() throws Exception {
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
new InvertibleComparator<>(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNeedComparatorWithAscending() throws Exception {
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
new InvertibleComparator<>(null, true));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldDefaultToAscending() throws Exception {
|
||||
InvertibleComparator<Integer> invertibleComparator = new InvertibleComparator<>(comparator);
|
||||
assertThat(invertibleComparator.isAscending()).isTrue();
|
||||
assertThat(invertibleComparator.compare(1, 2)).isEqualTo(-1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldInvert() throws Exception {
|
||||
InvertibleComparator<Integer> invertibleComparator = new InvertibleComparator<>(comparator);
|
||||
assertThat(invertibleComparator.isAscending()).isTrue();
|
||||
assertThat(invertibleComparator.compare(1, 2)).isEqualTo(-1);
|
||||
invertibleComparator.invertOrder();
|
||||
assertThat(invertibleComparator.isAscending()).isFalse();
|
||||
assertThat(invertibleComparator.compare(1, 2)).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldCompareAscending() throws Exception {
|
||||
InvertibleComparator<Integer> invertibleComparator = new InvertibleComparator<>(comparator, true);
|
||||
assertThat(invertibleComparator.compare(1, 2)).isEqualTo(-1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldCompareDescending() throws Exception {
|
||||
InvertibleComparator<Integer> invertibleComparator = new InvertibleComparator<>(comparator, false);
|
||||
assertThat(invertibleComparator.compare(1, 2)).isEqualTo(1);
|
||||
}
|
||||
|
||||
}
|
|
@ -332,17 +332,6 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
|||
throw new AccessException("Neither setter method nor field found for property '" + name + "'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last read invoker pair.
|
||||
* @deprecated as of 4.3.15 since it is not used within the framework anymore
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
public Member getLastReadInvokerPair() {
|
||||
InvokerPair lastReadInvoker = this.lastReadInvokerPair;
|
||||
return (lastReadInvoker != null ? lastReadInvoker.member : null);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private TypeDescriptor getTypeDescriptor(EvaluationContext context, Object target, String name) {
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2021 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.jdbc.core;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Generic utility methods for working with JDBC batch statements.
|
||||
* Mainly for internal use within the framework.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @deprecated as of 5.1.3, not used by {@link JdbcTemplate} anymore
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class BatchUpdateUtils {
|
||||
|
||||
public static int[] executeBatchUpdate(
|
||||
String sql, final List<Object[]> batchArgs, final int[] columnTypes, JdbcOperations jdbcOperations) {
|
||||
|
||||
if (batchArgs.isEmpty()) {
|
||||
return new int[0];
|
||||
}
|
||||
|
||||
return jdbcOperations.batchUpdate(
|
||||
sql,
|
||||
new BatchPreparedStatementSetter() {
|
||||
@Override
|
||||
public void setValues(PreparedStatement ps, int i) throws SQLException {
|
||||
Object[] values = batchArgs.get(i);
|
||||
setStatementParameters(values, ps, columnTypes);
|
||||
}
|
||||
@Override
|
||||
public int getBatchSize() {
|
||||
return batchArgs.size();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected static void setStatementParameters(Object[] values, PreparedStatement ps, @Nullable int[] columnTypes)
|
||||
throws SQLException {
|
||||
|
||||
int colIndex = 0;
|
||||
for (Object value : values) {
|
||||
colIndex++;
|
||||
if (value instanceof SqlParameterValue paramValue) {
|
||||
StatementCreatorUtils.setParameterValue(ps, colIndex, paramValue, paramValue.getValue());
|
||||
}
|
||||
else {
|
||||
int colType;
|
||||
if (columnTypes == null || columnTypes.length < colIndex) {
|
||||
colType = SqlTypeValue.TYPE_UNKNOWN;
|
||||
}
|
||||
else {
|
||||
colType = columnTypes[colIndex - 1];
|
||||
}
|
||||
StatementCreatorUtils.setParameterValue(ps, colIndex, colType, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -45,16 +45,6 @@ public class CallParameterMetaData {
|
|||
private final boolean nullable;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor taking all the properties except the function marker.
|
||||
*/
|
||||
@Deprecated
|
||||
public CallParameterMetaData(
|
||||
@Nullable String columnName, int columnType, int sqlType, @Nullable String typeName, boolean nullable) {
|
||||
|
||||
this(false, columnName, columnType, sqlType, typeName, nullable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor taking all the properties including the function marker.
|
||||
* @since 5.2.9
|
||||
|
|
|
@ -365,18 +365,6 @@ public class TableMetaDataContext {
|
|||
return obtainMetaDataProvider().isGetGeneratedKeysSimulated();
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this database support a simple query to retrieve generated keys
|
||||
* when the JDBC 3.0 feature is not supported:
|
||||
* {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}?
|
||||
* @deprecated as of 4.3.15, in favor of {@link #getSimpleQueryForGetGeneratedKey}
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
public String getSimulationQueryForGetGeneratedKey(String tableName, String keyColumnName) {
|
||||
return getSimpleQueryForGetGeneratedKey(tableName, keyColumnName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this database support a simple query to retrieve generated keys
|
||||
* when the JDBC 3.0 feature is not supported:
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.jdbc.core.namedparam;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
|
||||
import org.springframework.jdbc.core.JdbcOperations;
|
||||
|
||||
/**
|
||||
* Generic utility methods for working with JDBC batch statements using named parameters.
|
||||
* Mainly for internal use within the framework.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @deprecated as of 5.1.3, not used by {@link NamedParameterJdbcTemplate} anymore
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class NamedParameterBatchUpdateUtils extends org.springframework.jdbc.core.BatchUpdateUtils {
|
||||
|
||||
public static int[] executeBatchUpdateWithNamedParameters(
|
||||
final ParsedSql parsedSql, final SqlParameterSource[] batchArgs, JdbcOperations jdbcOperations) {
|
||||
|
||||
if (batchArgs.length == 0) {
|
||||
return new int[0];
|
||||
}
|
||||
|
||||
String sqlToUse = NamedParameterUtils.substituteNamedParameters(parsedSql, batchArgs[0]);
|
||||
return jdbcOperations.batchUpdate(
|
||||
sqlToUse,
|
||||
new BatchPreparedStatementSetter() {
|
||||
@Override
|
||||
public void setValues(PreparedStatement ps, int i) throws SQLException {
|
||||
Object[] values = NamedParameterUtils.buildValueArray(parsedSql, batchArgs[i], null);
|
||||
int[] columnTypes = NamedParameterUtils.buildSqlTypeArray(parsedSql, batchArgs[i]);
|
||||
setStatementParameters(values, ps, columnTypes);
|
||||
}
|
||||
@Override
|
||||
public int getBatchSize() {
|
||||
return batchArgs.length;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2008 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.jdbc.support.incrementer;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
/**
|
||||
* {@link DataFieldMaxValueIncrementer} that retrieves the next value
|
||||
* of a given sequence on DB2 for the mainframe (z/OS, DB2/390, DB2/400).
|
||||
*
|
||||
* <p>Thanks to Jens Eickmeyer for the suggestion!
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5.3
|
||||
* @deprecated in favor of the differently named {@link Db2MainframeMaxValueIncrementer}
|
||||
*/
|
||||
@Deprecated
|
||||
public class DB2MainframeSequenceMaxValueIncrementer extends AbstractSequenceMaxValueIncrementer {
|
||||
|
||||
/**
|
||||
* Default constructor for bean property style usage.
|
||||
* @see #setDataSource
|
||||
* @see #setIncrementerName
|
||||
*/
|
||||
public DB2MainframeSequenceMaxValueIncrementer() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience constructor.
|
||||
* @param dataSource the DataSource to use
|
||||
* @param incrementerName the name of the sequence/table to use
|
||||
*/
|
||||
public DB2MainframeSequenceMaxValueIncrementer(DataSource dataSource, String incrementerName) {
|
||||
super(dataSource, incrementerName);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String getSequenceQuery() {
|
||||
return "select next value for " + getIncrementerName() + " from sysibm.sysdummy1";
|
||||
}
|
||||
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2008 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.jdbc.support.incrementer;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
/**
|
||||
* {@link DataFieldMaxValueIncrementer} that retrieves the next value
|
||||
* of a given sequence on DB2 LUW (for Linux, Unix and Windows).
|
||||
*
|
||||
* <p>Thanks to Mark MacMahon for the suggestion!
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.1.3
|
||||
* @deprecated in favor of the specifically named {@link Db2LuwMaxValueIncrementer}
|
||||
*/
|
||||
@Deprecated
|
||||
public class DB2SequenceMaxValueIncrementer extends Db2LuwMaxValueIncrementer {
|
||||
|
||||
/**
|
||||
* Default constructor for bean property style usage.
|
||||
* @see #setDataSource
|
||||
* @see #setIncrementerName
|
||||
*/
|
||||
public DB2SequenceMaxValueIncrementer() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience constructor.
|
||||
* @param dataSource the DataSource to use
|
||||
* @param incrementerName the name of the sequence/table to use
|
||||
*/
|
||||
public DB2SequenceMaxValueIncrementer(DataSource dataSource, String incrementerName) {
|
||||
super(dataSource, incrementerName);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.jdbc.support.incrementer;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
/**
|
||||
* {@link DataFieldMaxValueIncrementer} that retrieves the next value
|
||||
* of a given PostgreSQL sequence.
|
||||
*
|
||||
* <p>Thanks to Tomislav Urban for the suggestion!
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @deprecated in favor of the differently named {@link PostgresSequenceMaxValueIncrementer}
|
||||
*/
|
||||
@Deprecated
|
||||
public class PostgreSQLSequenceMaxValueIncrementer extends PostgresSequenceMaxValueIncrementer {
|
||||
|
||||
/**
|
||||
* Default constructor for bean property style usage.
|
||||
* @see #setDataSource
|
||||
* @see #setIncrementerName
|
||||
*/
|
||||
public PostgreSQLSequenceMaxValueIncrementer() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience constructor.
|
||||
* @param dataSource the DataSource to use
|
||||
* @param incrementerName the name of the sequence/table to use
|
||||
*/
|
||||
public PostgreSQLSequenceMaxValueIncrementer(DataSource dataSource, String incrementerName) {
|
||||
super(dataSource, incrementerName);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2019 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.messaging.handler.annotation.support;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.converter.MessageConverter;
|
||||
import org.springframework.validation.Validator;
|
||||
|
||||
/**
|
||||
* A resolver to extract and convert the payload of a message using a
|
||||
* {@link MessageConverter}. It also validates the payload using a
|
||||
* {@link Validator} if the argument is annotated with a Validation annotation.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Juergen Hoeller
|
||||
* @author Brian Clozel
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.0
|
||||
* @deprecated as of 5.2, in favor of {@link PayloadMethodArgumentResolver}
|
||||
*/
|
||||
@Deprecated
|
||||
public class PayloadArgumentResolver extends PayloadMethodArgumentResolver {
|
||||
|
||||
/**
|
||||
* Create a new {@code PayloadArgumentResolver} with the given
|
||||
* {@link MessageConverter}.
|
||||
* @param messageConverter the MessageConverter to use (required)
|
||||
* @since 4.0.9
|
||||
*/
|
||||
public PayloadArgumentResolver(MessageConverter messageConverter) {
|
||||
this(messageConverter, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code PayloadArgumentResolver} with the given
|
||||
* {@link MessageConverter} and {@link Validator}.
|
||||
* @param messageConverter the MessageConverter to use (required)
|
||||
* @param validator the Validator to use (optional)
|
||||
*/
|
||||
public PayloadArgumentResolver(MessageConverter messageConverter, @Nullable Validator validator) {
|
||||
this(messageConverter, validator, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code PayloadArgumentResolver} with the given
|
||||
* {@link MessageConverter} and {@link Validator}.
|
||||
* @param messageConverter the MessageConverter to use (required)
|
||||
* @param validator the Validator to use (optional)
|
||||
* @param useDefaultResolution if "true" (the default) this resolver supports
|
||||
* all parameters; if "false" then only arguments with the {@code @Payload}
|
||||
* annotation are supported.
|
||||
*/
|
||||
public PayloadArgumentResolver(MessageConverter messageConverter, @Nullable Validator validator,
|
||||
boolean useDefaultResolution) {
|
||||
|
||||
|
||||
super(messageConverter, validator, useDefaultResolution);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -70,21 +70,6 @@ public class RSocketFrameTypeMessageCondition extends AbstractMessageCondition<R
|
|||
public static final RSocketFrameTypeMessageCondition EMPTY_CONDITION = new RSocketFrameTypeMessageCondition();
|
||||
|
||||
|
||||
/**
|
||||
* Condition to match "REQUEST_FNF", "REQUEST_RESPONSE", "REQUEST_STREAM",
|
||||
* and "REQUEST_CHANNEL".
|
||||
* @deprecated as of 5.2.2 because matching to all interaction types is too
|
||||
* flexible. Please use one of the other constants in this class that match
|
||||
* to specific frames.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final RSocketFrameTypeMessageCondition REQUEST_CONDITION =
|
||||
new RSocketFrameTypeMessageCondition(
|
||||
FrameType.REQUEST_FNF,
|
||||
FrameType.REQUEST_RESPONSE,
|
||||
FrameType.REQUEST_STREAM,
|
||||
FrameType.REQUEST_CHANNEL);
|
||||
|
||||
/** Per FrameType cache to return ready instances from getMatchingCondition. */
|
||||
private static final Map<String, RSocketFrameTypeMessageCondition> frameTypeConditionCache;
|
||||
|
||||
|
|
|
@ -504,29 +504,15 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC
|
|||
}
|
||||
|
||||
@Bean
|
||||
@SuppressWarnings("deprecation")
|
||||
public SimpUserRegistry userRegistry(
|
||||
AbstractSubscribableChannel clientInboundChannel, AbstractSubscribableChannel clientOutboundChannel) {
|
||||
|
||||
SimpUserRegistry userRegistry = createLocalUserRegistry();
|
||||
MessageBrokerRegistry brokerRegistry = getBrokerRegistry(clientInboundChannel, clientOutboundChannel);
|
||||
if (userRegistry == null) {
|
||||
userRegistry = createLocalUserRegistry(brokerRegistry.getUserRegistryOrder());
|
||||
}
|
||||
SimpUserRegistry userRegistry = createLocalUserRegistry(brokerRegistry.getUserRegistryOrder());
|
||||
boolean broadcast = brokerRegistry.getUserRegistryBroadcast() != null;
|
||||
return (broadcast ? new MultiServerUserRegistry(userRegistry) : userRegistry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the user registry that provides access to local users.
|
||||
* @deprecated as of 5.1 in favor of {@link #createLocalUserRegistry(Integer)}
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
protected SimpUserRegistry createLocalUserRegistry() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the user registry that provides access to local users.
|
||||
* @param order the order to use as a {@link SmartApplicationListener}.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -69,18 +69,6 @@ public class ChannelRegistration {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure interceptors for the message channel.
|
||||
* @deprecated as of 4.3.12, in favor of {@link #interceptors(ChannelInterceptor...)}
|
||||
*/
|
||||
@Deprecated
|
||||
public ChannelRegistration setInterceptors(@Nullable ChannelInterceptor... interceptors) {
|
||||
if (interceptors != null) {
|
||||
this.interceptors.addAll(Arrays.asList(interceptors));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
protected boolean hasTaskExecutor() {
|
||||
return (this.registration != null);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -30,7 +30,6 @@ import org.springframework.messaging.simp.SimpLogging;
|
|||
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
|
||||
import org.springframework.messaging.simp.SimpMessageType;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.PathMatcher;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
|
@ -122,29 +121,6 @@ public class DefaultUserDestinationResolver implements UserDestinationResolver {
|
|||
return this.removeLeadingSlash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide the {@code PathMatcher} in use for working with destinations
|
||||
* which in turn helps to determine whether the leading slash should be
|
||||
* kept in actual destinations after removing the
|
||||
* {@link #setUserDestinationPrefix userDestinationPrefix}.
|
||||
* <p>By default actual destinations have a leading slash, e.g.
|
||||
* {@code /queue/position-updates} which makes sense with brokers that
|
||||
* support destinations with slash as separator. When a {@code PathMatcher}
|
||||
* is provided that supports an alternative separator, then resulting
|
||||
* destinations won't have a leading slash, e.g. {@code
|
||||
* jms.queue.position-updates}.
|
||||
* @param pathMatcher the PathMatcher used to work with destinations
|
||||
* @since 4.3
|
||||
* @deprecated as of 4.3.14 this property is no longer used and is replaced
|
||||
* by {@link #setRemoveLeadingSlash(boolean)} that indicates more explicitly
|
||||
* whether to keep the leading slash which may or may not be the case
|
||||
* regardless of how the {@code PathMatcher} is configured.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setPathMatcher(@Nullable PathMatcher pathMatcher) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -112,27 +112,14 @@ public class OpenSessionInterceptor implements MethodInterceptor, InitializingBe
|
|||
* @see FlushMode#MANUAL
|
||||
*/
|
||||
protected Session openSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
|
||||
Session session = openSession();
|
||||
if (session == null) {
|
||||
try {
|
||||
session = sessionFactory.openSession();
|
||||
session.setHibernateFlushMode(FlushMode.MANUAL);
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex);
|
||||
}
|
||||
try {
|
||||
Session session = sessionFactory.openSession();
|
||||
session.setHibernateFlushMode(FlushMode.MANUAL);
|
||||
return session;
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex);
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a Session for the given SessionFactory.
|
||||
* @deprecated as of 5.0, in favor of {@link #openSession(SessionFactory)}
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
protected Session openSession() throws DataAccessResourceFailureException {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -353,14 +353,6 @@ public class PersistenceAnnotationBeanPostProcessor
|
|||
return pvs;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public PropertyValues postProcessPropertyValues(
|
||||
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {
|
||||
|
||||
return postProcessProperties(pvs, bean, beanName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessBeforeDestruction(Object bean, String beanName) {
|
||||
EntityManager emToClose = this.extendedEntityManagersToClose.remove(bean);
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2017 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.orm.jpa.vendor;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import jakarta.persistence.EntityManagerFactory;
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.orm.jpa.EntityManagerFactoryAccessor;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Simple {@code FactoryBean} that exposes the underlying {@link SessionFactory}
|
||||
* behind a Hibernate-backed JPA {@link EntityManagerFactory}.
|
||||
*
|
||||
* <p>Primarily available for resolving a SessionFactory by JPA persistence unit name
|
||||
* via the {@link #setPersistenceUnitName "persistenceUnitName"} bean property.
|
||||
*
|
||||
* <p>Note that, for straightforward cases, you could also simply declare a factory method:
|
||||
*
|
||||
* <pre class="code">
|
||||
* <bean id="sessionFactory" factory-bean="entityManagerFactory" factory-method="getSessionFactory"/>
|
||||
* </pre>
|
||||
*
|
||||
* <p>And as of JPA 2.1, {@link EntityManagerFactory#unwrap} provides a nice approach as well,
|
||||
* in particular within configuration class arrangements:
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Bean
|
||||
* public SessionFactory sessionFactory(@Qualifier("entityManagerFactory") EntityManagerFactory emf) {
|
||||
* return emf.unwrap(SessionFactory.class);
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* Please note: Since Hibernate 5.2 changed its {@code SessionFactory} interface to extend JPA's
|
||||
* {@code EntityManagerFactory}, you may get conflicts when injecting by type, with both the
|
||||
* original factory and your custom {@code SessionFactory} matching {@code EntityManagerFactory}.
|
||||
* An explicit qualifier for the original factory (as indicated above) is recommended here.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.1
|
||||
* @see #setPersistenceUnitName
|
||||
* @see #setEntityManagerFactory
|
||||
* @deprecated as of Spring Framework 4.3.12 against Hibernate 5.2, in favor of a custom solution
|
||||
* based on {@link EntityManagerFactory#unwrap} with explicit qualifiers and/or primary markers
|
||||
*/
|
||||
@Deprecated
|
||||
public class HibernateJpaSessionFactoryBean extends EntityManagerFactoryAccessor implements FactoryBean<SessionFactory> {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public SessionFactory getObject() {
|
||||
EntityManagerFactory emf = getEntityManagerFactory();
|
||||
Assert.state(emf != null, "EntityManagerFactory must not be null");
|
||||
try {
|
||||
Method getSessionFactory = emf.getClass().getMethod("getSessionFactory");
|
||||
return (SessionFactory) ReflectionUtils.invokeMethod(getSessionFactory, emf);
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
throw new IllegalStateException("No compatible Hibernate EntityManagerFactory found: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return SessionFactory.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2019 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.mock.jndi;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
|
||||
import org.springframework.jndi.JndiTemplate;
|
||||
|
||||
/**
|
||||
* Simple extension of the JndiTemplate class that always returns a given object.
|
||||
*
|
||||
* <p>Very useful for testing. Effectively a mock object.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @deprecated Deprecated as of Spring Framework 5.2 in favor of complete solutions from
|
||||
* third parties such as <a href="https://github.com/h-thurow/Simple-JNDI">Simple-JNDI</a>
|
||||
*/
|
||||
@Deprecated
|
||||
public class ExpectedLookupTemplate extends JndiTemplate {
|
||||
|
||||
private final Map<String, Object> jndiObjects = new ConcurrentHashMap<>(16);
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new JndiTemplate that will always return given objects for
|
||||
* given names. To be populated through {@code addObject} calls.
|
||||
* @see #addObject(String, Object)
|
||||
*/
|
||||
public ExpectedLookupTemplate() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new JndiTemplate that will always return the given object,
|
||||
* but honour only requests for the given name.
|
||||
* @param name the name the client is expected to look up
|
||||
* @param object the object that will be returned
|
||||
*/
|
||||
public ExpectedLookupTemplate(String name, Object object) {
|
||||
addObject(name, object);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add the given object to the list of JNDI objects that this template will expose.
|
||||
* @param name the name the client is expected to look up
|
||||
* @param object the object that will be returned
|
||||
*/
|
||||
public void addObject(String name, Object object) {
|
||||
this.jndiObjects.put(name, object);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the name is the expected name specified in the constructor, return the
|
||||
* object provided in the constructor. If the name is unexpected, a
|
||||
* respective NamingException gets thrown.
|
||||
*/
|
||||
@Override
|
||||
public Object lookup(String name) throws NamingException {
|
||||
Object object = this.jndiObjects.get(name);
|
||||
if (object == null) {
|
||||
throw new NamingException("Unexpected JNDI name '" + name + "': expecting " + this.jndiObjects.keySet());
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,389 +0,0 @@
|
|||
/*
|
||||
* 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.mock.jndi;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.naming.Binding;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.Name;
|
||||
import javax.naming.NameClassPair;
|
||||
import javax.naming.NameNotFoundException;
|
||||
import javax.naming.NameParser;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.OperationNotSupportedException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Simple implementation of a JNDI naming context.
|
||||
* Only supports binding plain Objects to String names.
|
||||
* Mainly for test environments, but also usable for standalone applications.
|
||||
*
|
||||
* <p>This class is not intended for direct usage by applications, although it
|
||||
* can be used for example to override JndiTemplate's {@code createInitialContext}
|
||||
* method in unit tests. Typically, SimpleNamingContextBuilder will be used to
|
||||
* set up a JVM-level JNDI environment.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @see SimpleNamingContextBuilder
|
||||
* @see org.springframework.jndi.JndiTemplate#createInitialContext
|
||||
* @deprecated Deprecated as of Spring Framework 5.2 in favor of complete solutions from
|
||||
* third parties such as <a href="https://github.com/h-thurow/Simple-JNDI">Simple-JNDI</a>
|
||||
*/
|
||||
@Deprecated
|
||||
public class SimpleNamingContext implements Context {
|
||||
|
||||
private final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private final String root;
|
||||
|
||||
private final Hashtable<String, Object> boundObjects;
|
||||
|
||||
private final Hashtable<String, Object> environment = new Hashtable<>();
|
||||
|
||||
|
||||
/**
|
||||
* Create a new naming context.
|
||||
*/
|
||||
public SimpleNamingContext() {
|
||||
this("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new naming context with the given naming root.
|
||||
*/
|
||||
public SimpleNamingContext(String root) {
|
||||
this.root = root;
|
||||
this.boundObjects = new Hashtable<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new naming context with the given naming root,
|
||||
* the given name/object map, and the JNDI environment entries.
|
||||
*/
|
||||
public SimpleNamingContext(
|
||||
String root, Hashtable<String, Object> boundObjects, @Nullable Hashtable<String, Object> env) {
|
||||
|
||||
this.root = root;
|
||||
this.boundObjects = boundObjects;
|
||||
if (env != null) {
|
||||
this.environment.putAll(env);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Actual implementations of Context methods follow
|
||||
|
||||
@Override
|
||||
public NamingEnumeration<NameClassPair> list(String root) throws NamingException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Listing name/class pairs under [" + root + "]");
|
||||
}
|
||||
return new NameClassPairEnumeration(this, root);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamingEnumeration<Binding> listBindings(String root) throws NamingException {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Listing bindings under [" + root + "]");
|
||||
}
|
||||
return new BindingEnumeration(this, root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up the object with the given name.
|
||||
* <p>Note: Not intended for direct use by applications.
|
||||
* Will be used by any standard InitialContext JNDI lookups.
|
||||
* @throws javax.naming.NameNotFoundException if the object could not be found
|
||||
*/
|
||||
@Override
|
||||
public Object lookup(String lookupName) throws NameNotFoundException {
|
||||
String name = this.root + lookupName;
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Static JNDI lookup: [" + name + "]");
|
||||
}
|
||||
if (name.isEmpty()) {
|
||||
return new SimpleNamingContext(this.root, this.boundObjects, this.environment);
|
||||
}
|
||||
Object found = this.boundObjects.get(name);
|
||||
if (found == null) {
|
||||
if (!name.endsWith("/")) {
|
||||
name = name + "/";
|
||||
}
|
||||
for (String boundName : this.boundObjects.keySet()) {
|
||||
if (boundName.startsWith(name)) {
|
||||
return new SimpleNamingContext(name, this.boundObjects, this.environment);
|
||||
}
|
||||
}
|
||||
throw new NameNotFoundException(
|
||||
"Name [" + this.root + lookupName + "] not bound; " + this.boundObjects.size() + " bindings: [" +
|
||||
StringUtils.collectionToDelimitedString(this.boundObjects.keySet(), ",") + "]");
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object lookupLink(String name) throws NameNotFoundException {
|
||||
return lookup(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind the given object to the given name.
|
||||
* Note: Not intended for direct use by applications
|
||||
* if setting up a JVM-level JNDI environment.
|
||||
* Use SimpleNamingContextBuilder to set up JNDI bindings then.
|
||||
* @see org.springframework.mock.jndi.SimpleNamingContextBuilder#bind
|
||||
*/
|
||||
@Override
|
||||
public void bind(String name, Object obj) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Static JNDI binding: [" + this.root + name + "] = [" + obj + "]");
|
||||
}
|
||||
this.boundObjects.put(this.root + name, obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unbind(String name) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Static JNDI remove: [" + this.root + name + "]");
|
||||
}
|
||||
this.boundObjects.remove(this.root + name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rebind(String name, Object obj) {
|
||||
bind(name, obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rename(String oldName, String newName) throws NameNotFoundException {
|
||||
Object obj = lookup(oldName);
|
||||
unbind(oldName);
|
||||
bind(newName, obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context createSubcontext(String name) {
|
||||
String subcontextName = this.root + name;
|
||||
if (!subcontextName.endsWith("/")) {
|
||||
subcontextName += "/";
|
||||
}
|
||||
Context subcontext = new SimpleNamingContext(subcontextName, this.boundObjects, this.environment);
|
||||
bind(name, subcontext);
|
||||
return subcontext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroySubcontext(String name) {
|
||||
unbind(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String composeName(String name, String prefix) {
|
||||
return prefix + name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hashtable<String, Object> getEnvironment() {
|
||||
return this.environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object addToEnvironment(String propName, Object propVal) {
|
||||
return this.environment.put(propName, propVal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object removeFromEnvironment(String propName) {
|
||||
return this.environment.remove(propName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
|
||||
// Unsupported methods follow: no support for javax.naming.Name
|
||||
|
||||
@Override
|
||||
public NamingEnumeration<NameClassPair> list(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamingEnumeration<Binding> listBindings(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object lookup(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object lookupLink(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(Name name, Object obj) throws NamingException {
|
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unbind(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rebind(Name name, Object obj) throws NamingException {
|
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rename(Name oldName, Name newName) throws NamingException {
|
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context createSubcontext(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroySubcontext(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameInNamespace() throws NamingException {
|
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public NameParser getNameParser(Name name) throws NamingException {
|
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public NameParser getNameParser(String name) throws NamingException {
|
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Name composeName(Name name, Name prefix) throws NamingException {
|
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
|
||||
}
|
||||
|
||||
|
||||
private abstract static class AbstractNamingEnumeration<T> implements NamingEnumeration<T> {
|
||||
|
||||
private final Iterator<T> iterator;
|
||||
|
||||
private AbstractNamingEnumeration(SimpleNamingContext context, String proot) throws NamingException {
|
||||
if (!proot.isEmpty() && !proot.endsWith("/")) {
|
||||
proot = proot + "/";
|
||||
}
|
||||
String root = context.root + proot;
|
||||
Map<String, T> contents = new HashMap<>();
|
||||
for (String boundName : context.boundObjects.keySet()) {
|
||||
if (boundName.startsWith(root)) {
|
||||
int startIndex = root.length();
|
||||
int endIndex = boundName.indexOf('/', startIndex);
|
||||
String strippedName =
|
||||
(endIndex != -1 ? boundName.substring(startIndex, endIndex) : boundName.substring(startIndex));
|
||||
if (!contents.containsKey(strippedName)) {
|
||||
try {
|
||||
contents.put(strippedName, createObject(strippedName, context.lookup(proot + strippedName)));
|
||||
}
|
||||
catch (NameNotFoundException ex) {
|
||||
// cannot happen
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (contents.size() == 0) {
|
||||
throw new NamingException("Invalid root: [" + context.root + proot + "]");
|
||||
}
|
||||
this.iterator = contents.values().iterator();
|
||||
}
|
||||
|
||||
protected abstract T createObject(String strippedName, Object obj);
|
||||
|
||||
@Override
|
||||
public boolean hasMore() {
|
||||
return this.iterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
return this.iterator.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMoreElements() {
|
||||
return this.iterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T nextElement() {
|
||||
return this.iterator.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final class NameClassPairEnumeration extends AbstractNamingEnumeration<NameClassPair> {
|
||||
|
||||
private NameClassPairEnumeration(SimpleNamingContext context, String root) throws NamingException {
|
||||
super(context, root);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NameClassPair createObject(String strippedName, Object obj) {
|
||||
return new NameClassPair(strippedName, obj.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final class BindingEnumeration extends AbstractNamingEnumeration<Binding> {
|
||||
|
||||
private BindingEnumeration(SimpleNamingContext context, String root) throws NamingException {
|
||||
super(context, root);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Binding createObject(String strippedName, Object obj) {
|
||||
return new Binding(strippedName, obj);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,236 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2019 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.mock.jndi;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.spi.InitialContextFactory;
|
||||
import javax.naming.spi.InitialContextFactoryBuilder;
|
||||
import javax.naming.spi.NamingManager;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Simple implementation of a JNDI naming context builder.
|
||||
*
|
||||
* <p>Mainly targeted at test environments, where each test case can
|
||||
* configure JNDI appropriately, so that {@code new InitialContext()}
|
||||
* will expose the required objects. Also usable for standalone applications,
|
||||
* e.g. for binding a JDBC DataSource to a well-known JNDI location, to be
|
||||
* able to use traditional Jakarta EE data access code outside of a Jakarta EE
|
||||
* container.
|
||||
*
|
||||
* <p>There are various choices for DataSource implementations:
|
||||
* <ul>
|
||||
* <li>{@code SingleConnectionDataSource} (using the same Connection for all getConnection calls)
|
||||
* <li>{@code DriverManagerDataSource} (creating a new Connection on each getConnection call)
|
||||
* <li>Apache's Commons DBCP offers {@code org.apache.commons.dbcp.BasicDataSource} (a real pool)
|
||||
* </ul>
|
||||
*
|
||||
* <p>Typical usage in bootstrap code:
|
||||
*
|
||||
* <pre class="code">
|
||||
* SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
|
||||
* DataSource ds = new DriverManagerDataSource(...);
|
||||
* builder.bind("java:comp/env/jdbc/myds", ds);
|
||||
* builder.activate();</pre>
|
||||
*
|
||||
* Note that it's impossible to activate multiple builders within the same JVM,
|
||||
* due to JNDI restrictions. Thus to configure a fresh builder repeatedly, use
|
||||
* the following code to get a reference to either an already activated builder
|
||||
* or a newly activated one:
|
||||
*
|
||||
* <pre class="code">
|
||||
* SimpleNamingContextBuilder builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder();
|
||||
* DataSource ds = new DriverManagerDataSource(...);
|
||||
* builder.bind("java:comp/env/jdbc/myds", ds);</pre>
|
||||
*
|
||||
* Note that you <i>should not</i> call {@code activate()} on a builder from
|
||||
* this factory method, as there will already be an activated one in any case.
|
||||
*
|
||||
* <p>An instance of this class is only necessary at setup time.
|
||||
* An application does not need to keep a reference to it after activation.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rod Johnson
|
||||
* @see #emptyActivatedContextBuilder()
|
||||
* @see #bind(String, Object)
|
||||
* @see #activate()
|
||||
* @see SimpleNamingContext
|
||||
* @see org.springframework.jdbc.datasource.SingleConnectionDataSource
|
||||
* @see org.springframework.jdbc.datasource.DriverManagerDataSource
|
||||
* @deprecated Deprecated as of Spring Framework 5.2 in favor of complete solutions from
|
||||
* third parties such as <a href="https://github.com/h-thurow/Simple-JNDI">Simple-JNDI</a>
|
||||
*/
|
||||
@Deprecated
|
||||
public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder {
|
||||
|
||||
/** An instance of this class bound to JNDI. */
|
||||
@Nullable
|
||||
private static volatile SimpleNamingContextBuilder activated;
|
||||
|
||||
private static boolean initialized = false;
|
||||
|
||||
private static final Object initializationLock = new Object();
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a SimpleNamingContextBuilder is active.
|
||||
* @return the current SimpleNamingContextBuilder instance,
|
||||
* or {@code null} if none
|
||||
*/
|
||||
@Nullable
|
||||
public static SimpleNamingContextBuilder getCurrentContextBuilder() {
|
||||
return activated;
|
||||
}
|
||||
|
||||
/**
|
||||
* If no SimpleNamingContextBuilder is already configuring JNDI,
|
||||
* create and activate one. Otherwise take the existing activated
|
||||
* SimpleNamingContextBuilder, clear it and return it.
|
||||
* <p>This is mainly intended for test suites that want to
|
||||
* reinitialize JNDI bindings from scratch repeatedly.
|
||||
* @return an empty SimpleNamingContextBuilder that can be used
|
||||
* to control JNDI bindings
|
||||
*/
|
||||
public static SimpleNamingContextBuilder emptyActivatedContextBuilder() throws NamingException {
|
||||
SimpleNamingContextBuilder builder = activated;
|
||||
if (builder != null) {
|
||||
// Clear already activated context builder.
|
||||
builder.clear();
|
||||
}
|
||||
else {
|
||||
// Create and activate new context builder.
|
||||
builder = new SimpleNamingContextBuilder();
|
||||
// The activate() call will cause an assignment to the activated variable.
|
||||
builder.activate();
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
private final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private final Hashtable<String,Object> boundObjects = new Hashtable<>();
|
||||
|
||||
|
||||
/**
|
||||
* Register the context builder by registering it with the JNDI NamingManager.
|
||||
* Note that once this has been done, {@code new InitialContext()} will always
|
||||
* return a context from this factory. Use the {@code emptyActivatedContextBuilder()}
|
||||
* static method to get an empty context (for example, in test methods).
|
||||
* @throws IllegalStateException if there's already a naming context builder
|
||||
* registered with the JNDI NamingManager
|
||||
*/
|
||||
public void activate() throws IllegalStateException, NamingException {
|
||||
logger.info("Activating simple JNDI environment");
|
||||
synchronized (initializationLock) {
|
||||
if (!initialized) {
|
||||
Assert.state(!NamingManager.hasInitialContextFactoryBuilder(),
|
||||
"Cannot activate SimpleNamingContextBuilder: there is already a JNDI provider registered. " +
|
||||
"Note that JNDI is a JVM-wide service, shared at the JVM system class loader level, " +
|
||||
"with no reset option. As a consequence, a JNDI provider must only be registered once per JVM.");
|
||||
NamingManager.setInitialContextFactoryBuilder(this);
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
activated = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporarily deactivate this context builder. It will remain registered with
|
||||
* the JNDI NamingManager but will delegate to the standard JNDI InitialContextFactory
|
||||
* (if configured) instead of exposing its own bound objects.
|
||||
* <p>Call {@code activate()} again in order to expose this context builder's own
|
||||
* bound objects again. Such activate/deactivate sequences can be applied any number
|
||||
* of times (e.g. within a larger integration test suite running in the same VM).
|
||||
* @see #activate()
|
||||
*/
|
||||
public void deactivate() {
|
||||
logger.info("Deactivating simple JNDI environment");
|
||||
activated = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all bindings in this context builder, while keeping it active.
|
||||
*/
|
||||
public void clear() {
|
||||
this.boundObjects.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind the given object under the given name, for all naming contexts
|
||||
* that this context builder will generate.
|
||||
* @param name the JNDI name of the object (e.g. "java:comp/env/jdbc/myds")
|
||||
* @param obj the object to bind (e.g. a DataSource implementation)
|
||||
*/
|
||||
public void bind(String name, Object obj) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Static JNDI binding: [" + name + "] = [" + obj + "]");
|
||||
}
|
||||
this.boundObjects.put(name, obj);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Simple InitialContextFactoryBuilder implementation,
|
||||
* creating a new SimpleNamingContext instance.
|
||||
* @see SimpleNamingContext
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public InitialContextFactory createInitialContextFactory(@Nullable Hashtable<?,?> environment) {
|
||||
if (activated == null && environment != null) {
|
||||
Object icf = environment.get(Context.INITIAL_CONTEXT_FACTORY);
|
||||
if (icf != null) {
|
||||
Class<?> icfClass;
|
||||
if (icf instanceof Class) {
|
||||
icfClass = (Class<?>) icf;
|
||||
}
|
||||
else if (icf instanceof String) {
|
||||
icfClass = ClassUtils.resolveClassName((String) icf, getClass().getClassLoader());
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Invalid value type for environment key [" +
|
||||
Context.INITIAL_CONTEXT_FACTORY + "]: " + icf.getClass().getName());
|
||||
}
|
||||
if (!InitialContextFactory.class.isAssignableFrom(icfClass)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Specified class does not implement [" + InitialContextFactory.class.getName() + "]: " + icf);
|
||||
}
|
||||
try {
|
||||
return (InitialContextFactory) ReflectionUtils.accessibleConstructor(icfClass).newInstance();
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new IllegalStateException("Unable to instantiate specified InitialContextFactory: " + icf, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Default case...
|
||||
return env -> new SimpleNamingContext("", this.boundObjects, (Hashtable<String, Object>) env);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
/**
|
||||
* <strong>Deprecated</strong> as of Spring Framework 5.2 in favor of complete
|
||||
* solutions from third parties such as
|
||||
* <a href="https://github.com/h-thurow/Simple-JNDI">Simple-JNDI</a>.
|
||||
*
|
||||
* <p>The simplest implementation of the JNDI SPI that could possibly work.
|
||||
*
|
||||
* <p>Useful for setting up a simple JNDI environment for test suites
|
||||
* or stand-alone applications. If, for example, JDBC DataSources get bound to the
|
||||
* same JNDI names as within a Jakarta EE container, both application code and
|
||||
* configuration can be reused without changes.
|
||||
*/
|
||||
@NonNullApi
|
||||
@NonNullFields
|
||||
package org.springframework.mock.jndi;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.lang.NonNullFields;
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -300,13 +300,6 @@ public final class MockServerRequest implements ServerRequest {
|
|||
|
||||
Builder session(WebSession session);
|
||||
|
||||
/**
|
||||
* Sets the request {@link Principal}.
|
||||
* @deprecated in favor of {@link #principal(Principal)}
|
||||
*/
|
||||
@Deprecated
|
||||
Builder session(Principal principal);
|
||||
|
||||
Builder principal(Principal principal);
|
||||
|
||||
Builder remoteAddress(InetSocketAddress remoteAddress);
|
||||
|
@ -463,12 +456,6 @@ public final class MockServerRequest implements ServerRequest {
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public Builder session(Principal principal) {
|
||||
return principal(principal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder principal(Principal principal) {
|
||||
Assert.notNull(principal, "'principal' must not be null");
|
||||
|
|
|
@ -1,409 +0,0 @@
|
|||
/*
|
||||
* 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.test.util;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* {@code MetaAnnotationUtils} is a collection of utility methods that complements
|
||||
* the standard support already available in {@link AnnotationUtils}.
|
||||
*
|
||||
* <p>Whereas {@code AnnotationUtils} provides utilities for <em>getting</em> or
|
||||
* <em>finding</em> an annotation, {@code MetaAnnotationUtils} goes a step further
|
||||
* by providing support for determining the <em>root class</em> on which an
|
||||
* annotation is declared, either directly or indirectly via a <em>composed
|
||||
* annotation</em>. This additional information is encapsulated in an
|
||||
* {@link AnnotationDescriptor}.
|
||||
*
|
||||
* <p>The additional information provided by an {@code AnnotationDescriptor} is
|
||||
* required by the <em>Spring TestContext Framework</em> in order to be able to
|
||||
* support class hierarchy traversals for annotations such as
|
||||
* {@link org.springframework.test.context.ContextConfiguration @ContextConfiguration},
|
||||
* {@link org.springframework.test.context.TestExecutionListeners @TestExecutionListeners},
|
||||
* and {@link org.springframework.test.context.ActiveProfiles @ActiveProfiles}
|
||||
* which offer support for merging and overriding various <em>inherited</em>
|
||||
* annotation attributes (e.g.
|
||||
* {@link org.springframework.test.context.ContextConfiguration#inheritLocations}).
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.0
|
||||
* @see AnnotationUtils
|
||||
* @see AnnotationDescriptor
|
||||
* @deprecated as of Spring Framework 5.3 in favor of
|
||||
* {@link org.springframework.test.context.TestContextAnnotationUtils}
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class MetaAnnotationUtils {
|
||||
|
||||
/**
|
||||
* Find the {@link AnnotationDescriptor} for the supplied {@code annotationType}
|
||||
* on the supplied {@link Class}, traversing its annotations, interfaces, and
|
||||
* superclasses if no annotation can be found on the given class itself.
|
||||
* <p>This method explicitly handles class-level annotations which are not
|
||||
* declared as {@linkplain java.lang.annotation.Inherited inherited} <em>as
|
||||
* well as meta-annotations</em>.
|
||||
* <p>The algorithm operates as follows:
|
||||
* <ol>
|
||||
* <li>Search for the annotation on the given class and return a corresponding
|
||||
* {@code AnnotationDescriptor} if found.
|
||||
* <li>Recursively search through all annotations that the given class declares.
|
||||
* <li>Recursively search through all interfaces implemented by the given class.
|
||||
* <li>Recursively search through the superclass hierarchy of the given class.
|
||||
* </ol>
|
||||
* <p>In this context, the term <em>recursively</em> means that the search
|
||||
* process continues by returning to step #1 with the current annotation,
|
||||
* interface, or superclass as the class to look for annotations on.
|
||||
* @param clazz the class to look for annotations on
|
||||
* @param annotationType the type of annotation to look for
|
||||
* @return the corresponding annotation descriptor if the annotation was found;
|
||||
* otherwise {@code null}
|
||||
* @see #findAnnotationDescriptorForTypes(Class, Class...)
|
||||
*/
|
||||
@Nullable
|
||||
public static <T extends Annotation> AnnotationDescriptor<T> findAnnotationDescriptor(
|
||||
Class<?> clazz, Class<T> annotationType) {
|
||||
|
||||
return findAnnotationDescriptor(clazz, new HashSet<>(), annotationType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the search algorithm for {@link #findAnnotationDescriptor(Class, Class)},
|
||||
* avoiding endless recursion by tracking which annotations have already been
|
||||
* <em>visited</em>.
|
||||
* @param clazz the class to look for annotations on
|
||||
* @param visited the set of annotations that have already been visited
|
||||
* @param annotationType the type of annotation to look for
|
||||
* @return the corresponding annotation descriptor if the annotation was found;
|
||||
* otherwise {@code null}
|
||||
*/
|
||||
@Nullable
|
||||
private static <T extends Annotation> AnnotationDescriptor<T> findAnnotationDescriptor(
|
||||
@Nullable Class<?> clazz, Set<Annotation> visited, Class<T> annotationType) {
|
||||
|
||||
Assert.notNull(annotationType, "Annotation type must not be null");
|
||||
if (clazz == null || Object.class == clazz) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Declared locally?
|
||||
if (AnnotationUtils.isAnnotationDeclaredLocally(annotationType, clazz)) {
|
||||
return new AnnotationDescriptor<>(clazz, clazz.getAnnotation(annotationType));
|
||||
}
|
||||
|
||||
// Declared on a composed annotation (i.e., as a meta-annotation)?
|
||||
for (Annotation composedAnn : clazz.getDeclaredAnnotations()) {
|
||||
Class<? extends Annotation> composedType = composedAnn.annotationType();
|
||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(composedType.getName()) && visited.add(composedAnn)) {
|
||||
AnnotationDescriptor<T> descriptor = findAnnotationDescriptor(composedType, visited, annotationType);
|
||||
if (descriptor != null) {
|
||||
return new AnnotationDescriptor<>(
|
||||
clazz, descriptor.getDeclaringClass(), composedAnn, descriptor.getAnnotation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Declared on an interface?
|
||||
for (Class<?> ifc : clazz.getInterfaces()) {
|
||||
AnnotationDescriptor<T> descriptor = findAnnotationDescriptor(ifc, visited, annotationType);
|
||||
if (descriptor != null) {
|
||||
return new AnnotationDescriptor<>(clazz, descriptor.getDeclaringClass(),
|
||||
descriptor.getComposedAnnotation(), descriptor.getAnnotation());
|
||||
}
|
||||
}
|
||||
|
||||
// Declared on a superclass?
|
||||
return findAnnotationDescriptor(clazz.getSuperclass(), visited, annotationType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the {@link UntypedAnnotationDescriptor} for the first {@link Class}
|
||||
* in the inheritance hierarchy of the specified {@code clazz} (including
|
||||
* the specified {@code clazz} itself) which declares at least one of the
|
||||
* specified {@code annotationTypes}.
|
||||
* <p>This method traverses the annotations, interfaces, and superclasses
|
||||
* of the specified {@code clazz} if no annotation can be found on the given
|
||||
* class itself.
|
||||
* <p>This method explicitly handles class-level annotations which are not
|
||||
* declared as {@linkplain java.lang.annotation.Inherited inherited} <em>as
|
||||
* well as meta-annotations</em>.
|
||||
* <p>The algorithm operates as follows:
|
||||
* <ol>
|
||||
* <li>Search for a local declaration of one of the annotation types on
|
||||
* the given class and return a corresponding {@code UntypedAnnotationDescriptor}
|
||||
* if found.
|
||||
* <li>Recursively search through all annotations that the given class declares.
|
||||
* <li>Recursively search through all interfaces implemented by the given class.
|
||||
* <li>Recursively search through the superclass hierarchy of the given class.
|
||||
* </ol>
|
||||
* <p>In this context, the term <em>recursively</em> means that the search
|
||||
* process continues by returning to step #1 with the current annotation,
|
||||
* interface, or superclass as the class to look for annotations on.
|
||||
* @param clazz the class to look for annotations on
|
||||
* @param annotationTypes the types of annotations to look for
|
||||
* @return the corresponding annotation descriptor if one of the annotations
|
||||
* was found; otherwise {@code null}
|
||||
* @see #findAnnotationDescriptor(Class, Class)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
public static UntypedAnnotationDescriptor findAnnotationDescriptorForTypes(
|
||||
Class<?> clazz, Class<? extends Annotation>... annotationTypes) {
|
||||
|
||||
return findAnnotationDescriptorForTypes(clazz, new HashSet<>(), annotationTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the search algorithm for {@link #findAnnotationDescriptorForTypes(Class, Class...)},
|
||||
* avoiding endless recursion by tracking which annotations have already been
|
||||
* <em>visited</em>.
|
||||
* @param clazz the class to look for annotations on
|
||||
* @param visited the set of annotations that have already been visited
|
||||
* @param annotationTypes the types of annotations to look for
|
||||
* @return the corresponding annotation descriptor if one of the annotations
|
||||
* was found; otherwise {@code null}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
private static UntypedAnnotationDescriptor findAnnotationDescriptorForTypes(@Nullable Class<?> clazz,
|
||||
Set<Annotation> visited, Class<? extends Annotation>... annotationTypes) {
|
||||
|
||||
assertNonEmptyAnnotationTypeArray(annotationTypes, "The list of annotation types must not be empty");
|
||||
if (clazz == null || Object.class == clazz) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Declared locally?
|
||||
for (Class<? extends Annotation> annotationType : annotationTypes) {
|
||||
if (AnnotationUtils.isAnnotationDeclaredLocally(annotationType, clazz)) {
|
||||
return new UntypedAnnotationDescriptor(clazz, clazz.getAnnotation(annotationType));
|
||||
}
|
||||
}
|
||||
|
||||
// Declared on a composed annotation (i.e., as a meta-annotation)?
|
||||
for (Annotation composedAnnotation : clazz.getDeclaredAnnotations()) {
|
||||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(composedAnnotation) && visited.add(composedAnnotation)) {
|
||||
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(
|
||||
composedAnnotation.annotationType(), visited, annotationTypes);
|
||||
if (descriptor != null) {
|
||||
return new UntypedAnnotationDescriptor(clazz, descriptor.getDeclaringClass(),
|
||||
composedAnnotation, descriptor.getAnnotation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Declared on an interface?
|
||||
for (Class<?> ifc : clazz.getInterfaces()) {
|
||||
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(ifc, visited, annotationTypes);
|
||||
if (descriptor != null) {
|
||||
return new UntypedAnnotationDescriptor(clazz, descriptor.getDeclaringClass(),
|
||||
descriptor.getComposedAnnotation(), descriptor.getAnnotation());
|
||||
}
|
||||
}
|
||||
|
||||
// Declared on a superclass?
|
||||
return findAnnotationDescriptorForTypes(clazz.getSuperclass(), visited, annotationTypes);
|
||||
}
|
||||
|
||||
private static void assertNonEmptyAnnotationTypeArray(Class<?>[] annotationTypes, String message) {
|
||||
if (ObjectUtils.isEmpty(annotationTypes)) {
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
for (Class<?> clazz : annotationTypes) {
|
||||
if (!Annotation.class.isAssignableFrom(clazz)) {
|
||||
throw new IllegalArgumentException("Array elements must be of type Annotation");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Descriptor for an {@link Annotation}, including the {@linkplain
|
||||
* #getDeclaringClass() class} on which the annotation is <em>declared</em>
|
||||
* as well as the actual {@linkplain #getAnnotation() annotation} instance.
|
||||
* <p>If the annotation is used as a meta-annotation, the descriptor also includes
|
||||
* the {@linkplain #getComposedAnnotation() composed annotation} on which the
|
||||
* annotation is present. In such cases, the <em>root declaring class</em> is
|
||||
* not directly annotated with the annotation but rather indirectly via the
|
||||
* composed annotation.
|
||||
* <p>Given the following example, if we are searching for the {@code @Transactional}
|
||||
* annotation <em>on</em> the {@code TransactionalTests} class, then the
|
||||
* properties of the {@code AnnotationDescriptor} would be as follows.
|
||||
* <ul>
|
||||
* <li>rootDeclaringClass: {@code TransactionalTests} class object</li>
|
||||
* <li>declaringClass: {@code TransactionalTests} class object</li>
|
||||
* <li>composedAnnotation: {@code null}</li>
|
||||
* <li>annotation: instance of the {@code Transactional} annotation</li>
|
||||
* </ul>
|
||||
* <p><pre style="code">
|
||||
* @Transactional
|
||||
* @ContextConfiguration({"/test-datasource.xml", "/repository-config.xml"})
|
||||
* public class TransactionalTests { }
|
||||
* </pre>
|
||||
* <p>Given the following example, if we are searching for the {@code @Transactional}
|
||||
* annotation <em>on</em> the {@code UserRepositoryTests} class, then the
|
||||
* properties of the {@code AnnotationDescriptor} would be as follows.
|
||||
* <ul>
|
||||
* <li>rootDeclaringClass: {@code UserRepositoryTests} class object</li>
|
||||
* <li>declaringClass: {@code RepositoryTests} class object</li>
|
||||
* <li>composedAnnotation: instance of the {@code RepositoryTests} annotation</li>
|
||||
* <li>annotation: instance of the {@code Transactional} annotation</li>
|
||||
* </ul>
|
||||
* <p><pre style="code">
|
||||
* @Transactional
|
||||
* @ContextConfiguration({"/test-datasource.xml", "/repository-config.xml"})
|
||||
* @Retention(RetentionPolicy.RUNTIME)
|
||||
* public @interface RepositoryTests { }
|
||||
*
|
||||
* @RepositoryTests
|
||||
* public class UserRepositoryTests { }
|
||||
* </pre>
|
||||
*
|
||||
* @param <T> the annotation type
|
||||
*/
|
||||
public static class AnnotationDescriptor<T extends Annotation> {
|
||||
|
||||
private final Class<?> rootDeclaringClass;
|
||||
|
||||
private final Class<?> declaringClass;
|
||||
|
||||
@Nullable
|
||||
private final Annotation composedAnnotation;
|
||||
|
||||
private final T annotation;
|
||||
|
||||
private final AnnotationAttributes annotationAttributes;
|
||||
|
||||
public AnnotationDescriptor(Class<?> rootDeclaringClass, T annotation) {
|
||||
this(rootDeclaringClass, rootDeclaringClass, null, annotation);
|
||||
}
|
||||
|
||||
public AnnotationDescriptor(Class<?> rootDeclaringClass, Class<?> declaringClass,
|
||||
@Nullable Annotation composedAnnotation, T annotation) {
|
||||
|
||||
Assert.notNull(rootDeclaringClass, "'rootDeclaringClass' must not be null");
|
||||
Assert.notNull(annotation, "Annotation must not be null");
|
||||
this.rootDeclaringClass = rootDeclaringClass;
|
||||
this.declaringClass = declaringClass;
|
||||
this.composedAnnotation = composedAnnotation;
|
||||
this.annotation = annotation;
|
||||
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
|
||||
rootDeclaringClass, annotation.annotationType().getName(), false, false);
|
||||
Assert.state(attributes != null, "No annotation attributes");
|
||||
this.annotationAttributes = attributes;
|
||||
}
|
||||
|
||||
public Class<?> getRootDeclaringClass() {
|
||||
return this.rootDeclaringClass;
|
||||
}
|
||||
|
||||
public Class<?> getDeclaringClass() {
|
||||
return this.declaringClass;
|
||||
}
|
||||
|
||||
public T getAnnotation() {
|
||||
return this.annotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Synthesize the merged {@link #getAnnotationAttributes AnnotationAttributes}
|
||||
* in this descriptor back into an annotation of the target
|
||||
* {@linkplain #getAnnotationType annotation type}.
|
||||
* @since 4.2
|
||||
* @see #getAnnotationAttributes()
|
||||
* @see #getAnnotationType()
|
||||
* @see AnnotationUtils#synthesizeAnnotation(java.util.Map, Class, java.lang.reflect.AnnotatedElement)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public T synthesizeAnnotation() {
|
||||
return AnnotationUtils.synthesizeAnnotation(
|
||||
getAnnotationAttributes(), (Class<T>) getAnnotationType(), getRootDeclaringClass());
|
||||
}
|
||||
|
||||
public Class<? extends Annotation> getAnnotationType() {
|
||||
return this.annotation.annotationType();
|
||||
}
|
||||
|
||||
public AnnotationAttributes getAnnotationAttributes() {
|
||||
return this.annotationAttributes;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Annotation getComposedAnnotation() {
|
||||
return this.composedAnnotation;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Class<? extends Annotation> getComposedAnnotationType() {
|
||||
return (this.composedAnnotation != null ? this.composedAnnotation.annotationType() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a textual representation of this {@code AnnotationDescriptor}.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringCreator(this)
|
||||
.append("rootDeclaringClass", this.rootDeclaringClass)
|
||||
.append("declaringClass", this.declaringClass)
|
||||
.append("composedAnnotation", this.composedAnnotation)
|
||||
.append("annotation", this.annotation)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <em>Untyped</em> extension of {@link AnnotationDescriptor} that is used
|
||||
* to describe the declaration of one of several candidate annotation types
|
||||
* where the actual annotation type cannot be predetermined.
|
||||
*/
|
||||
public static class UntypedAnnotationDescriptor extends AnnotationDescriptor<Annotation> {
|
||||
|
||||
public UntypedAnnotationDescriptor(Class<?> rootDeclaringClass, Annotation annotation) {
|
||||
this(rootDeclaringClass, rootDeclaringClass, null, annotation);
|
||||
}
|
||||
|
||||
public UntypedAnnotationDescriptor(Class<?> rootDeclaringClass, Class<?> declaringClass,
|
||||
@Nullable Annotation composedAnnotation, Annotation annotation) {
|
||||
|
||||
super(rootDeclaringClass, declaringClass, composedAnnotation, annotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an {@link UnsupportedOperationException} since the type of annotation
|
||||
* represented by the {@link #getAnnotationAttributes AnnotationAttributes} in
|
||||
* an {@code UntypedAnnotationDescriptor} is unknown.
|
||||
* @since 4.2
|
||||
*/
|
||||
@Override
|
||||
public Annotation synthesizeAnnotation() {
|
||||
throw new UnsupportedOperationException(
|
||||
"synthesizeAnnotation() is unsupported in UntypedAnnotationDescriptor");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -88,14 +88,7 @@ public abstract class AbstractRequestExpectationManager implements RequestExpect
|
|||
afterExpectationsDeclared();
|
||||
}
|
||||
try {
|
||||
// Try this first for backwards compatibility
|
||||
ClientHttpResponse response = validateRequestInternal(request);
|
||||
if (response != null) {
|
||||
return response;
|
||||
}
|
||||
else {
|
||||
expectation = matchRequest(request);
|
||||
}
|
||||
expectation = matchRequest(request);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
this.requestFailures.put(request, ex);
|
||||
|
@ -115,19 +108,6 @@ public abstract class AbstractRequestExpectationManager implements RequestExpect
|
|||
protected void afterExpectationsDeclared() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must implement the actual validation of the request
|
||||
* matching to declared expectations.
|
||||
* @deprecated as of 5.0.3, subclasses should implement {@link #matchRequest(ClientHttpRequest)}
|
||||
* instead and return only the matched expectation, leaving the call to create the response
|
||||
* as a separate step (to be invoked by this class).
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
protected ClientHttpResponse validateRequestInternal(ClientHttpRequest request) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* As of 5.0.3 subclasses should implement this method instead of
|
||||
* {@link #validateRequestInternal(ClientHttpRequest)} in order to match the
|
||||
|
@ -272,15 +252,6 @@ public abstract class AbstractRequestExpectationManager implements RequestExpect
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add expectations to this group.
|
||||
* @deprecated as of 5.0.3, if favor of {@link #addAllExpectations}
|
||||
*/
|
||||
@Deprecated
|
||||
public void updateAll(Collection<RequestExpectation> expectations) {
|
||||
expectations.forEach(this::updateInternal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset all expectations for this group.
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -223,28 +223,6 @@ public abstract class MockMvcRequestBuilders {
|
|||
return new MockMultipartHttpServletRequestBuilder(uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link MockMultipartHttpServletRequestBuilder} for a multipart request.
|
||||
* @param urlTemplate a URL template; the resulting URL will be encoded
|
||||
* @param uriVars zero or more URI variables
|
||||
* @deprecated in favor of {@link #multipart(String, Object...)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static MockMultipartHttpServletRequestBuilder fileUpload(String urlTemplate, Object... uriVars) {
|
||||
return new MockMultipartHttpServletRequestBuilder(urlTemplate, uriVars);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link MockMultipartHttpServletRequestBuilder} for a multipart request.
|
||||
* @param uri the URL
|
||||
* @since 4.0.3
|
||||
* @deprecated in favor of {@link #multipart(URI)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static MockMultipartHttpServletRequestBuilder fileUpload(URI uri) {
|
||||
return new MockMultipartHttpServletRequestBuilder(uri);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a {@link RequestBuilder} for an async dispatch from the
|
||||
|
|
|
@ -1,244 +0,0 @@
|
|||
/*
|
||||
* 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.mock.jndi;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.naming.Binding;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.NameClassPair;
|
||||
import javax.naming.NameNotFoundException;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.spi.InitialContextFactory;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
/**
|
||||
* Tests for {@link SimpleNamingContextBuilder} and {@link SimpleNamingContext}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
class SimpleNamingContextTests {
|
||||
|
||||
@Test
|
||||
void namingContextBuilder() throws NamingException {
|
||||
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
|
||||
InitialContextFactory factory = builder.createInitialContextFactory(null);
|
||||
|
||||
DataSource ds = new StubDataSource();
|
||||
builder.bind("java:comp/env/jdbc/myds", ds);
|
||||
Object obj = new Object();
|
||||
builder.bind("myobject", obj);
|
||||
|
||||
Context context1 = factory.getInitialContext(null);
|
||||
assertThat(context1.lookup("java:comp/env/jdbc/myds") == ds).as("Correct DataSource registered").isTrue();
|
||||
assertThat(context1.lookup("myobject") == obj).as("Correct Object registered").isTrue();
|
||||
|
||||
Hashtable<String, String> env2 = new Hashtable<>();
|
||||
env2.put("key1", "value1");
|
||||
Context context2 = factory.getInitialContext(env2);
|
||||
assertThat(context2.lookup("java:comp/env/jdbc/myds") == ds).as("Correct DataSource registered").isTrue();
|
||||
assertThat(context2.lookup("myobject") == obj).as("Correct Object registered").isTrue();
|
||||
assertThat(context2.getEnvironment() != env2).as("Correct environment").isTrue();
|
||||
assertThat("value1".equals(context2.getEnvironment().get("key1"))).as("Correct key1").isTrue();
|
||||
|
||||
Integer i = 0;
|
||||
context1.rebind("myinteger", i);
|
||||
String s = "";
|
||||
context2.bind("mystring", s);
|
||||
|
||||
Context context3 = (Context) context2.lookup("");
|
||||
context3.rename("java:comp/env/jdbc/myds", "jdbc/myds");
|
||||
context3.unbind("myobject");
|
||||
|
||||
assertThat(context3.getEnvironment() != context2.getEnvironment()).as("Correct environment").isTrue();
|
||||
context3.addToEnvironment("key2", "value2");
|
||||
assertThat("value2".equals(context3.getEnvironment().get("key2"))).as("key2 added").isTrue();
|
||||
context3.removeFromEnvironment("key1");
|
||||
assertThat(context3.getEnvironment().get("key1") == null).as("key1 removed").isTrue();
|
||||
|
||||
assertThat(context1.lookup("jdbc/myds") == ds).as("Correct DataSource registered").isTrue();
|
||||
assertThatExceptionOfType(NameNotFoundException.class).isThrownBy(() ->
|
||||
context1.lookup("myobject"));
|
||||
assertThat(context1.lookup("myinteger") == i).as("Correct Integer registered").isTrue();
|
||||
assertThat(context1.lookup("mystring") == s).as("Correct String registered").isTrue();
|
||||
|
||||
assertThat(context2.lookup("jdbc/myds") == ds).as("Correct DataSource registered").isTrue();
|
||||
assertThatExceptionOfType(NameNotFoundException.class).isThrownBy(() ->
|
||||
context2.lookup("myobject"));
|
||||
assertThat(context2.lookup("myinteger") == i).as("Correct Integer registered").isTrue();
|
||||
assertThat(context2.lookup("mystring") == s).as("Correct String registered").isTrue();
|
||||
|
||||
assertThat(context3.lookup("jdbc/myds") == ds).as("Correct DataSource registered").isTrue();
|
||||
assertThatExceptionOfType(NameNotFoundException.class).isThrownBy(() ->
|
||||
context3.lookup("myobject"));
|
||||
assertThat(context3.lookup("myinteger") == i).as("Correct Integer registered").isTrue();
|
||||
assertThat(context3.lookup("mystring") == s).as("Correct String registered").isTrue();
|
||||
|
||||
Map<String, Binding> bindingMap = new HashMap<>();
|
||||
NamingEnumeration<?> bindingEnum = context3.listBindings("");
|
||||
while (bindingEnum.hasMoreElements()) {
|
||||
Binding binding = (Binding) bindingEnum.nextElement();
|
||||
bindingMap.put(binding.getName(), binding);
|
||||
}
|
||||
boolean condition = bindingMap.get("jdbc").getObject() instanceof Context;
|
||||
assertThat(condition).as("Correct jdbc subcontext").isTrue();
|
||||
assertThat(SimpleNamingContext.class.getName().equals(bindingMap.get("jdbc").getClassName())).as("Correct jdbc subcontext").isTrue();
|
||||
|
||||
Context jdbcContext = (Context) context3.lookup("jdbc");
|
||||
jdbcContext.bind("mydsX", ds);
|
||||
Map<String, Binding> subBindingMap = new HashMap<>();
|
||||
NamingEnumeration<?> subBindingEnum = jdbcContext.listBindings("");
|
||||
while (subBindingEnum.hasMoreElements()) {
|
||||
Binding binding = (Binding) subBindingEnum.nextElement();
|
||||
subBindingMap.put(binding.getName(), binding);
|
||||
}
|
||||
|
||||
assertThat(ds.equals(subBindingMap.get("myds").getObject())).as("Correct DataSource registered").isTrue();
|
||||
assertThat(StubDataSource.class.getName().equals(subBindingMap.get("myds").getClassName())).as("Correct DataSource registered").isTrue();
|
||||
assertThat(ds.equals(subBindingMap.get("mydsX").getObject())).as("Correct DataSource registered").isTrue();
|
||||
assertThat(StubDataSource.class.getName().equals(subBindingMap.get("mydsX").getClassName())).as("Correct DataSource registered").isTrue();
|
||||
assertThat(i.equals(bindingMap.get("myinteger").getObject())).as("Correct Integer registered").isTrue();
|
||||
assertThat(Integer.class.getName().equals(bindingMap.get("myinteger").getClassName())).as("Correct Integer registered").isTrue();
|
||||
assertThat(s.equals(bindingMap.get("mystring").getObject())).as("Correct String registered").isTrue();
|
||||
assertThat(String.class.getName().equals(bindingMap.get("mystring").getClassName())).as("Correct String registered").isTrue();
|
||||
|
||||
context1.createSubcontext("jdbc").bind("sub/subds", ds);
|
||||
|
||||
Map<String, String> pairMap = new HashMap<>();
|
||||
NamingEnumeration<?> pairEnum = context2.list("jdbc");
|
||||
while (pairEnum.hasMore()) {
|
||||
NameClassPair pair = (NameClassPair) pairEnum.next();
|
||||
pairMap.put(pair.getName(), pair.getClassName());
|
||||
}
|
||||
assertThat(SimpleNamingContext.class.getName().equals(pairMap.get("sub"))).as("Correct sub subcontext").isTrue();
|
||||
|
||||
Context subContext = (Context) context2.lookup("jdbc/sub");
|
||||
Map<String, String> subPairMap = new HashMap<>();
|
||||
NamingEnumeration<?> subPairEnum = subContext.list("");
|
||||
while (subPairEnum.hasMoreElements()) {
|
||||
NameClassPair pair = (NameClassPair) subPairEnum.next();
|
||||
subPairMap.put(pair.getName(), pair.getClassName());
|
||||
}
|
||||
|
||||
assertThat(StubDataSource.class.getName().equals(subPairMap.get("subds"))).as("Correct DataSource registered").isTrue();
|
||||
assertThat(StubDataSource.class.getName().equals(pairMap.get("myds"))).as("Correct DataSource registered").isTrue();
|
||||
assertThat(StubDataSource.class.getName().equals(pairMap.get("mydsX"))).as("Correct DataSource registered").isTrue();
|
||||
|
||||
pairMap.clear();
|
||||
pairEnum = context1.list("jdbc/");
|
||||
while (pairEnum.hasMore()) {
|
||||
NameClassPair pair = (NameClassPair) pairEnum.next();
|
||||
pairMap.put(pair.getName(), pair.getClassName());
|
||||
}
|
||||
assertThat(StubDataSource.class.getName().equals(pairMap.get("myds"))).as("Correct DataSource registered").isTrue();
|
||||
assertThat(StubDataSource.class.getName().equals(pairMap.get("mydsX"))).as("Correct DataSource registered").isTrue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Demonstrates how emptyActivatedContextBuilder() method can be
|
||||
* used repeatedly, and how it affects creating a new InitialContext()
|
||||
*/
|
||||
@Test
|
||||
void createInitialContext() throws Exception {
|
||||
SimpleNamingContextBuilder builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder();
|
||||
String name = "foo";
|
||||
Object o = new Object();
|
||||
builder.bind(name, o);
|
||||
// Check it affects JNDI
|
||||
Context ctx = new InitialContext();
|
||||
assertThat(ctx.lookup(name) == o).isTrue();
|
||||
// Check it returns mutable contexts
|
||||
ctx.unbind(name);
|
||||
InitialContext badCtx1 = new InitialContext();
|
||||
assertThatExceptionOfType(NamingException.class).isThrownBy(() ->
|
||||
badCtx1.lookup(name));
|
||||
|
||||
// Check the same call will work again, but the context is empty
|
||||
builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder();
|
||||
InitialContext badCtx2 = new InitialContext();
|
||||
assertThatExceptionOfType(NamingException.class).isThrownBy(() ->
|
||||
badCtx2.lookup(name));
|
||||
Object o2 = new Object();
|
||||
builder.bind(name, o2);
|
||||
assertThat(o2).isEqualTo(badCtx2.lookup(name));
|
||||
}
|
||||
|
||||
|
||||
static class StubDataSource implements DataSource {
|
||||
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection(String username, String password) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrintWriter getLogWriter() throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLoginTimeout() throws SQLException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLogWriter(PrintWriter arg0) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLoginTimeout(int arg0) throws SQLException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWrapperFor(Class<?> arg0) throws SQLException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T unwrap(Class<T> arg0) throws SQLException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger getParentLogger() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,639 +0,0 @@
|
|||
/*
|
||||
* 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.test.util;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.util.MetaAnnotationUtils.AnnotationDescriptor;
|
||||
import org.springframework.test.util.MetaAnnotationUtils.UntypedAnnotationDescriptor;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.test.util.MetaAnnotationUtils.findAnnotationDescriptor;
|
||||
import static org.springframework.test.util.MetaAnnotationUtils.findAnnotationDescriptorForTypes;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MetaAnnotationUtils}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.0
|
||||
* @see OverriddenMetaAnnotationAttributesTests
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
class MetaAnnotationUtilsTests {
|
||||
|
||||
private void assertAtComponentOnComposedAnnotation(
|
||||
Class<?> rootDeclaringClass, String name, Class<? extends Annotation> composedAnnotationType) {
|
||||
|
||||
assertAtComponentOnComposedAnnotation(rootDeclaringClass, rootDeclaringClass, name, composedAnnotationType);
|
||||
}
|
||||
|
||||
private void assertAtComponentOnComposedAnnotation(
|
||||
Class<?> startClass, Class<?> rootDeclaringClass, String name, Class<? extends Annotation> composedAnnotationType) {
|
||||
|
||||
assertAtComponentOnComposedAnnotation(startClass, rootDeclaringClass, composedAnnotationType, name, composedAnnotationType);
|
||||
}
|
||||
|
||||
private void assertAtComponentOnComposedAnnotation(Class<?> startClass, Class<?> rootDeclaringClass,
|
||||
Class<?> declaringClass, String name, Class<? extends Annotation> composedAnnotationType) {
|
||||
|
||||
AnnotationDescriptor<Component> descriptor = findAnnotationDescriptor(startClass, Component.class);
|
||||
assertThat(descriptor).as("AnnotationDescriptor should not be null").isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).as("rootDeclaringClass").isEqualTo(rootDeclaringClass);
|
||||
assertThat(descriptor.getDeclaringClass()).as("declaringClass").isEqualTo(declaringClass);
|
||||
assertThat(descriptor.getAnnotationType()).as("annotationType").isEqualTo(Component.class);
|
||||
assertThat(descriptor.getAnnotation().value()).as("component name").isEqualTo(name);
|
||||
assertThat(descriptor.getComposedAnnotation()).as("composedAnnotation should not be null").isNotNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).as("composedAnnotationType").isEqualTo(composedAnnotationType);
|
||||
}
|
||||
|
||||
private void assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(
|
||||
Class<?> startClass, String name, Class<? extends Annotation> composedAnnotationType) {
|
||||
|
||||
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(
|
||||
startClass, startClass, name, composedAnnotationType);
|
||||
}
|
||||
|
||||
private void assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(Class<?> startClass,
|
||||
Class<?> rootDeclaringClass, String name, Class<? extends Annotation> composedAnnotationType) {
|
||||
|
||||
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(
|
||||
startClass, rootDeclaringClass, composedAnnotationType, name, composedAnnotationType);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(Class<?> startClass,
|
||||
Class<?> rootDeclaringClass, Class<?> declaringClass, String name,
|
||||
Class<? extends Annotation> composedAnnotationType) {
|
||||
|
||||
Class<Component> annotationType = Component.class;
|
||||
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(
|
||||
startClass, Service.class, annotationType, Order.class, Transactional.class);
|
||||
|
||||
assertThat(descriptor).as("UntypedAnnotationDescriptor should not be null").isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).as("rootDeclaringClass").isEqualTo(rootDeclaringClass);
|
||||
assertThat(descriptor.getDeclaringClass()).as("declaringClass").isEqualTo(declaringClass);
|
||||
assertThat(descriptor.getAnnotationType()).as("annotationType").isEqualTo(annotationType);
|
||||
assertThat(((Component) descriptor.getAnnotation()).value()).as("component name").isEqualTo(name);
|
||||
assertThat(descriptor.getComposedAnnotation()).as("composedAnnotation should not be null").isNotNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).as("composedAnnotationType").isEqualTo(composedAnnotationType);
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAnnotationDescriptorWithNoAnnotationPresent() {
|
||||
assertThat(findAnnotationDescriptor(NonAnnotatedInterface.class, Transactional.class)).isNull();
|
||||
assertThat(findAnnotationDescriptor(NonAnnotatedClass.class, Transactional.class)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAnnotationDescriptorWithInheritedAnnotationOnClass() {
|
||||
// Note: @Transactional is inherited
|
||||
assertThat(findAnnotationDescriptor(InheritedAnnotationClass.class, Transactional.class).getRootDeclaringClass()).isEqualTo(InheritedAnnotationClass.class);
|
||||
assertThat(findAnnotationDescriptor(SubInheritedAnnotationClass.class, Transactional.class).getRootDeclaringClass()).isEqualTo(InheritedAnnotationClass.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAnnotationDescriptorWithInheritedAnnotationOnInterface() {
|
||||
// Note: @Transactional is inherited
|
||||
Transactional rawAnnotation = InheritedAnnotationInterface.class.getAnnotation(Transactional.class);
|
||||
|
||||
AnnotationDescriptor<Transactional> descriptor =
|
||||
findAnnotationDescriptor(InheritedAnnotationInterface.class, Transactional.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(InheritedAnnotationInterface.class);
|
||||
assertThat(descriptor.getDeclaringClass()).isEqualTo(InheritedAnnotationInterface.class);
|
||||
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
|
||||
|
||||
descriptor = findAnnotationDescriptor(SubInheritedAnnotationInterface.class, Transactional.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(SubInheritedAnnotationInterface.class);
|
||||
assertThat(descriptor.getDeclaringClass()).isEqualTo(InheritedAnnotationInterface.class);
|
||||
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
|
||||
|
||||
descriptor = findAnnotationDescriptor(SubSubInheritedAnnotationInterface.class, Transactional.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(SubSubInheritedAnnotationInterface.class);
|
||||
assertThat(descriptor.getDeclaringClass()).isEqualTo(InheritedAnnotationInterface.class);
|
||||
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAnnotationDescriptorForNonInheritedAnnotationOnClass() {
|
||||
// Note: @Order is not inherited.
|
||||
assertThat(findAnnotationDescriptor(NonInheritedAnnotationClass.class, Order.class).getRootDeclaringClass()).isEqualTo(NonInheritedAnnotationClass.class);
|
||||
assertThat(findAnnotationDescriptor(SubNonInheritedAnnotationClass.class, Order.class).getRootDeclaringClass()).isEqualTo(NonInheritedAnnotationClass.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAnnotationDescriptorForNonInheritedAnnotationOnInterface() {
|
||||
// Note: @Order is not inherited.
|
||||
Order rawAnnotation = NonInheritedAnnotationInterface.class.getAnnotation(Order.class);
|
||||
|
||||
AnnotationDescriptor<Order> descriptor =
|
||||
findAnnotationDescriptor(NonInheritedAnnotationInterface.class, Order.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(NonInheritedAnnotationInterface.class);
|
||||
assertThat(descriptor.getDeclaringClass()).isEqualTo(NonInheritedAnnotationInterface.class);
|
||||
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
|
||||
|
||||
descriptor = findAnnotationDescriptor(SubNonInheritedAnnotationInterface.class, Order.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(SubNonInheritedAnnotationInterface.class);
|
||||
assertThat(descriptor.getDeclaringClass()).isEqualTo(NonInheritedAnnotationInterface.class);
|
||||
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAnnotationDescriptorWithMetaComponentAnnotation() {
|
||||
assertAtComponentOnComposedAnnotation(HasMetaComponentAnnotation.class, "meta1", Meta1.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAnnotationDescriptorWithLocalAndMetaComponentAnnotation() {
|
||||
Class<Component> annotationType = Component.class;
|
||||
AnnotationDescriptor<Component> descriptor = findAnnotationDescriptor(
|
||||
HasLocalAndMetaComponentAnnotation.class, annotationType);
|
||||
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(HasLocalAndMetaComponentAnnotation.class);
|
||||
assertThat(descriptor.getAnnotationType()).isEqualTo(annotationType);
|
||||
assertThat(descriptor.getComposedAnnotation()).isNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAnnotationDescriptorForInterfaceWithMetaAnnotation() {
|
||||
assertAtComponentOnComposedAnnotation(InterfaceWithMetaAnnotation.class, "meta1", Meta1.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAnnotationDescriptorForClassWithMetaAnnotatedInterface() {
|
||||
Component rawAnnotation = AnnotationUtils.findAnnotation(ClassWithMetaAnnotatedInterface.class, Component.class);
|
||||
AnnotationDescriptor<Component> descriptor =
|
||||
findAnnotationDescriptor(ClassWithMetaAnnotatedInterface.class, Component.class);
|
||||
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(ClassWithMetaAnnotatedInterface.class);
|
||||
assertThat(descriptor.getDeclaringClass()).isEqualTo(Meta1.class);
|
||||
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
|
||||
assertThat(descriptor.getComposedAnnotation().annotationType()).isEqualTo(Meta1.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAnnotationDescriptorForClassWithLocalMetaAnnotationAndAnnotatedSuperclass() {
|
||||
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(
|
||||
MetaAnnotatedAndSuperAnnotatedContextConfigClass.class, ContextConfiguration.class);
|
||||
|
||||
assertThat(descriptor).as("AnnotationDescriptor should not be null").isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).as("rootDeclaringClass").isEqualTo(MetaAnnotatedAndSuperAnnotatedContextConfigClass.class);
|
||||
assertThat(descriptor.getDeclaringClass()).as("declaringClass").isEqualTo(MetaConfig.class);
|
||||
assertThat(descriptor.getAnnotationType()).as("annotationType").isEqualTo(ContextConfiguration.class);
|
||||
assertThat(descriptor.getComposedAnnotation()).as("composedAnnotation should not be null").isNotNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).as("composedAnnotationType").isEqualTo(MetaConfig.class);
|
||||
|
||||
assertThat(descriptor.getAnnotationAttributes().getClassArray("classes")).as("configured classes").isEqualTo(new Class<?>[] {String.class});
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAnnotationDescriptorForClassWithLocalMetaAnnotationAndMetaAnnotatedInterface() {
|
||||
assertAtComponentOnComposedAnnotation(ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface.class, "meta2", Meta2.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAnnotationDescriptorForSubClassWithLocalMetaAnnotationAndMetaAnnotatedInterface() {
|
||||
assertAtComponentOnComposedAnnotation(SubClassWithLocalMetaAnnotationAndMetaAnnotatedInterface.class,
|
||||
ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface.class, "meta2", Meta2.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.3
|
||||
*/
|
||||
@Test
|
||||
void findAnnotationDescriptorOnMetaMetaAnnotatedClass() {
|
||||
Class<MetaMetaAnnotatedClass> startClass = MetaMetaAnnotatedClass.class;
|
||||
assertAtComponentOnComposedAnnotation(startClass, startClass, Meta2.class, "meta2", MetaMeta.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.3
|
||||
*/
|
||||
@Test
|
||||
void findAnnotationDescriptorOnMetaMetaMetaAnnotatedClass() {
|
||||
Class<MetaMetaMetaAnnotatedClass> startClass = MetaMetaMetaAnnotatedClass.class;
|
||||
assertAtComponentOnComposedAnnotation(startClass, startClass, Meta2.class, "meta2", MetaMetaMeta.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.3
|
||||
*/
|
||||
@Test
|
||||
void findAnnotationDescriptorOnAnnotatedClassWithMissingTargetMetaAnnotation() {
|
||||
// InheritedAnnotationClass is NOT annotated or meta-annotated with @Component
|
||||
AnnotationDescriptor<Component> descriptor = findAnnotationDescriptor(
|
||||
InheritedAnnotationClass.class, Component.class);
|
||||
assertThat(descriptor).as("Should not find @Component on InheritedAnnotationClass").isNull();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.3
|
||||
*/
|
||||
@Test
|
||||
void findAnnotationDescriptorOnMetaCycleAnnotatedClassWithMissingTargetMetaAnnotation() {
|
||||
AnnotationDescriptor<Component> descriptor = findAnnotationDescriptor(
|
||||
MetaCycleAnnotatedClass.class, Component.class);
|
||||
assertThat(descriptor).as("Should not find @Component on MetaCycleAnnotatedClass").isNull();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void findAnnotationDescriptorForTypesWithNoAnnotationPresent() {
|
||||
assertThat(findAnnotationDescriptorForTypes(NonAnnotatedInterface.class, Transactional.class, Component.class)).isNull();
|
||||
assertThat(findAnnotationDescriptorForTypes(NonAnnotatedClass.class, Transactional.class, Order.class)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void findAnnotationDescriptorForTypesWithInheritedAnnotationOnClass() {
|
||||
// Note: @Transactional is inherited
|
||||
assertThat(findAnnotationDescriptorForTypes(InheritedAnnotationClass.class, Transactional.class).getRootDeclaringClass()).isEqualTo(InheritedAnnotationClass.class);
|
||||
assertThat(findAnnotationDescriptorForTypes(SubInheritedAnnotationClass.class, Transactional.class).getRootDeclaringClass()).isEqualTo(InheritedAnnotationClass.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void findAnnotationDescriptorForTypesWithInheritedAnnotationOnInterface() {
|
||||
// Note: @Transactional is inherited
|
||||
Transactional rawAnnotation = InheritedAnnotationInterface.class.getAnnotation(Transactional.class);
|
||||
|
||||
UntypedAnnotationDescriptor descriptor =
|
||||
findAnnotationDescriptorForTypes(InheritedAnnotationInterface.class, Transactional.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(InheritedAnnotationInterface.class);
|
||||
assertThat(descriptor.getDeclaringClass()).isEqualTo(InheritedAnnotationInterface.class);
|
||||
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
|
||||
|
||||
descriptor = findAnnotationDescriptorForTypes(SubInheritedAnnotationInterface.class, Transactional.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(SubInheritedAnnotationInterface.class);
|
||||
assertThat(descriptor.getDeclaringClass()).isEqualTo(InheritedAnnotationInterface.class);
|
||||
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
|
||||
|
||||
descriptor = findAnnotationDescriptorForTypes(SubSubInheritedAnnotationInterface.class, Transactional.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(SubSubInheritedAnnotationInterface.class);
|
||||
assertThat(descriptor.getDeclaringClass()).isEqualTo(InheritedAnnotationInterface.class);
|
||||
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void findAnnotationDescriptorForTypesForNonInheritedAnnotationOnClass() {
|
||||
// Note: @Order is not inherited.
|
||||
assertThat(findAnnotationDescriptorForTypes(NonInheritedAnnotationClass.class, Order.class).getRootDeclaringClass()).isEqualTo(NonInheritedAnnotationClass.class);
|
||||
assertThat(findAnnotationDescriptorForTypes(SubNonInheritedAnnotationClass.class, Order.class).getRootDeclaringClass()).isEqualTo(NonInheritedAnnotationClass.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void findAnnotationDescriptorForTypesForNonInheritedAnnotationOnInterface() {
|
||||
// Note: @Order is not inherited.
|
||||
Order rawAnnotation = NonInheritedAnnotationInterface.class.getAnnotation(Order.class);
|
||||
|
||||
UntypedAnnotationDescriptor descriptor =
|
||||
findAnnotationDescriptorForTypes(NonInheritedAnnotationInterface.class, Order.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(NonInheritedAnnotationInterface.class);
|
||||
assertThat(descriptor.getDeclaringClass()).isEqualTo(NonInheritedAnnotationInterface.class);
|
||||
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
|
||||
|
||||
descriptor = findAnnotationDescriptorForTypes(SubNonInheritedAnnotationInterface.class, Order.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(SubNonInheritedAnnotationInterface.class);
|
||||
assertThat(descriptor.getDeclaringClass()).isEqualTo(NonInheritedAnnotationInterface.class);
|
||||
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void findAnnotationDescriptorForTypesWithLocalAndMetaComponentAnnotation() {
|
||||
Class<Component> annotationType = Component.class;
|
||||
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(
|
||||
HasLocalAndMetaComponentAnnotation.class, Transactional.class, annotationType, Order.class);
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(HasLocalAndMetaComponentAnnotation.class);
|
||||
assertThat(descriptor.getAnnotationType()).isEqualTo(annotationType);
|
||||
assertThat(descriptor.getComposedAnnotation()).isNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAnnotationDescriptorForTypesWithMetaComponentAnnotation() {
|
||||
Class<HasMetaComponentAnnotation> startClass = HasMetaComponentAnnotation.class;
|
||||
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(startClass, "meta1", Meta1.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void findAnnotationDescriptorForTypesWithMetaAnnotationWithDefaultAttributes() {
|
||||
Class<?> startClass = MetaConfigWithDefaultAttributesTestCase.class;
|
||||
Class<ContextConfiguration> annotationType = ContextConfiguration.class;
|
||||
|
||||
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(startClass,
|
||||
Service.class, ContextConfiguration.class, Order.class, Transactional.class);
|
||||
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(startClass);
|
||||
assertThat(descriptor.getAnnotationType()).isEqualTo(annotationType);
|
||||
assertThat(((ContextConfiguration) descriptor.getAnnotation()).value()).isEqualTo(new Class<?>[] {});
|
||||
assertThat(descriptor.getAnnotationAttributes().getClassArray("classes")).isEqualTo(new Class<?>[] {MetaConfig.DevConfig.class, MetaConfig.ProductionConfig.class});
|
||||
assertThat(descriptor.getComposedAnnotation()).isNotNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaConfig.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void findAnnotationDescriptorForTypesWithMetaAnnotationWithOverriddenAttributes() {
|
||||
Class<?> startClass = MetaConfigWithOverriddenAttributesTestCase.class;
|
||||
Class<ContextConfiguration> annotationType = ContextConfiguration.class;
|
||||
|
||||
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(
|
||||
startClass, Service.class, ContextConfiguration.class, Order.class, Transactional.class);
|
||||
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(startClass);
|
||||
assertThat(descriptor.getAnnotationType()).isEqualTo(annotationType);
|
||||
assertThat(((ContextConfiguration) descriptor.getAnnotation()).value()).isEqualTo(new Class<?>[] {});
|
||||
assertThat(descriptor.getAnnotationAttributes().getClassArray("classes")).isEqualTo(new Class<?>[] {MetaAnnotationUtilsTests.class});
|
||||
assertThat(descriptor.getComposedAnnotation()).isNotNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaConfig.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAnnotationDescriptorForTypesForInterfaceWithMetaAnnotation() {
|
||||
Class<InterfaceWithMetaAnnotation> startClass = InterfaceWithMetaAnnotation.class;
|
||||
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(startClass, "meta1", Meta1.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void findAnnotationDescriptorForTypesForClassWithMetaAnnotatedInterface() {
|
||||
Component rawAnnotation = AnnotationUtils.findAnnotation(ClassWithMetaAnnotatedInterface.class, Component.class);
|
||||
|
||||
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(
|
||||
ClassWithMetaAnnotatedInterface.class, Service.class, Component.class, Order.class, Transactional.class);
|
||||
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(ClassWithMetaAnnotatedInterface.class);
|
||||
assertThat(descriptor.getDeclaringClass()).isEqualTo(Meta1.class);
|
||||
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
|
||||
assertThat(descriptor.getComposedAnnotation().annotationType()).isEqualTo(Meta1.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAnnotationDescriptorForTypesForClassWithLocalMetaAnnotationAndMetaAnnotatedInterface() {
|
||||
Class<ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface> startClass = ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface.class;
|
||||
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(startClass, "meta2", Meta2.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAnnotationDescriptorForTypesForSubClassWithLocalMetaAnnotationAndMetaAnnotatedInterface() {
|
||||
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(
|
||||
SubClassWithLocalMetaAnnotationAndMetaAnnotatedInterface.class,
|
||||
ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface.class, "meta2", Meta2.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.3
|
||||
*/
|
||||
@Test
|
||||
void findAnnotationDescriptorForTypesOnMetaMetaAnnotatedClass() {
|
||||
Class<MetaMetaAnnotatedClass> startClass = MetaMetaAnnotatedClass.class;
|
||||
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(
|
||||
startClass, startClass, Meta2.class, "meta2", MetaMeta.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.3
|
||||
*/
|
||||
@Test
|
||||
void findAnnotationDescriptorForTypesOnMetaMetaMetaAnnotatedClass() {
|
||||
Class<MetaMetaMetaAnnotatedClass> startClass = MetaMetaMetaAnnotatedClass.class;
|
||||
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(
|
||||
startClass, startClass, Meta2.class, "meta2", MetaMetaMeta.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.3
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void findAnnotationDescriptorForTypesOnAnnotatedClassWithMissingTargetMetaAnnotation() {
|
||||
// InheritedAnnotationClass is NOT annotated or meta-annotated with @Component,
|
||||
// @Service, or @Order, but it is annotated with @Transactional.
|
||||
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(
|
||||
InheritedAnnotationClass.class, Service.class, Component.class, Order.class);
|
||||
assertThat(descriptor).as("Should not find @Component on InheritedAnnotationClass").isNull();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0.3
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void findAnnotationDescriptorForTypesOnMetaCycleAnnotatedClassWithMissingTargetMetaAnnotation() {
|
||||
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(
|
||||
MetaCycleAnnotatedClass.class, Service.class, Component.class, Order.class);
|
||||
assertThat(descriptor).as("Should not find @Component on MetaCycleAnnotatedClass").isNull();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Component(value = "meta1")
|
||||
@Order
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Documented
|
||||
static @interface Meta1 {
|
||||
}
|
||||
|
||||
@Component(value = "meta2")
|
||||
@Transactional
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Documented
|
||||
static @interface Meta2 {
|
||||
}
|
||||
|
||||
@Meta2
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Documented
|
||||
@interface MetaMeta {
|
||||
}
|
||||
|
||||
@MetaMeta
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Documented
|
||||
@interface MetaMetaMeta {
|
||||
}
|
||||
|
||||
@MetaCycle3
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.ANNOTATION_TYPE)
|
||||
@Documented
|
||||
@interface MetaCycle1 {
|
||||
}
|
||||
|
||||
@MetaCycle1
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.ANNOTATION_TYPE)
|
||||
@Documented
|
||||
@interface MetaCycle2 {
|
||||
}
|
||||
|
||||
@MetaCycle2
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Documented
|
||||
@interface MetaCycle3 {
|
||||
}
|
||||
|
||||
@ContextConfiguration
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Documented
|
||||
static @interface MetaConfig {
|
||||
|
||||
static class DevConfig {
|
||||
}
|
||||
|
||||
static class ProductionConfig {
|
||||
}
|
||||
|
||||
|
||||
Class<?>[] classes() default { DevConfig.class, ProductionConfig.class };
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Meta1
|
||||
static class HasMetaComponentAnnotation {
|
||||
}
|
||||
|
||||
@Meta1
|
||||
@Component(value = "local")
|
||||
@Meta2
|
||||
static class HasLocalAndMetaComponentAnnotation {
|
||||
}
|
||||
|
||||
@Meta1
|
||||
static interface InterfaceWithMetaAnnotation {
|
||||
}
|
||||
|
||||
static class ClassWithMetaAnnotatedInterface implements InterfaceWithMetaAnnotation {
|
||||
}
|
||||
|
||||
@Meta2
|
||||
static class ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface implements InterfaceWithMetaAnnotation {
|
||||
}
|
||||
|
||||
static class SubClassWithLocalMetaAnnotationAndMetaAnnotatedInterface extends
|
||||
ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface {
|
||||
}
|
||||
|
||||
@MetaMeta
|
||||
static class MetaMetaAnnotatedClass {
|
||||
}
|
||||
|
||||
@MetaMetaMeta
|
||||
static class MetaMetaMetaAnnotatedClass {
|
||||
}
|
||||
|
||||
@MetaCycle3
|
||||
static class MetaCycleAnnotatedClass {
|
||||
}
|
||||
|
||||
@MetaConfig
|
||||
class MetaConfigWithDefaultAttributesTestCase {
|
||||
}
|
||||
|
||||
@MetaConfig(classes = MetaAnnotationUtilsTests.class)
|
||||
class MetaConfigWithOverriddenAttributesTestCase {
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Transactional
|
||||
static interface InheritedAnnotationInterface {
|
||||
}
|
||||
|
||||
static interface SubInheritedAnnotationInterface extends InheritedAnnotationInterface {
|
||||
}
|
||||
|
||||
static interface SubSubInheritedAnnotationInterface extends SubInheritedAnnotationInterface {
|
||||
}
|
||||
|
||||
@Order
|
||||
static interface NonInheritedAnnotationInterface {
|
||||
}
|
||||
|
||||
static interface SubNonInheritedAnnotationInterface extends NonInheritedAnnotationInterface {
|
||||
}
|
||||
|
||||
static class NonAnnotatedClass {
|
||||
}
|
||||
|
||||
static interface NonAnnotatedInterface {
|
||||
}
|
||||
|
||||
@Transactional
|
||||
static class InheritedAnnotationClass {
|
||||
}
|
||||
|
||||
static class SubInheritedAnnotationClass extends InheritedAnnotationClass {
|
||||
}
|
||||
|
||||
@Order
|
||||
static class NonInheritedAnnotationClass {
|
||||
}
|
||||
|
||||
static class SubNonInheritedAnnotationClass extends NonInheritedAnnotationClass {
|
||||
}
|
||||
|
||||
@ContextConfiguration(classes = Number.class)
|
||||
static class AnnotatedContextConfigClass {
|
||||
}
|
||||
|
||||
@MetaConfig(classes = String.class)
|
||||
static class MetaAnnotatedAndSuperAnnotatedContextConfigClass extends AnnotatedContextConfigClass {
|
||||
}
|
||||
|
||||
}
|
|
@ -1,158 +0,0 @@
|
|||
/*
|
||||
* 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.test.util;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.util.MetaAnnotationUtils.AnnotationDescriptor;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.test.util.MetaAnnotationUtils.findAnnotationDescriptor;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MetaAnnotationUtils} that verify support for overridden
|
||||
* meta-annotation attributes.
|
||||
*
|
||||
* <p>See <a href="https://jira.spring.io/browse/SPR-10181">SPR-10181</a>.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.0
|
||||
* @see MetaAnnotationUtilsTests
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
class OverriddenMetaAnnotationAttributesTests {
|
||||
|
||||
@Test
|
||||
void contextConfigurationValue() throws Exception {
|
||||
Class<MetaValueConfigTestCase> declaringClass = MetaValueConfigTestCase.class;
|
||||
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(declaringClass,
|
||||
ContextConfiguration.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(declaringClass);
|
||||
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaValueConfig.class);
|
||||
assertThat(descriptor.getAnnotationType()).isEqualTo(ContextConfiguration.class);
|
||||
assertThat(descriptor.getComposedAnnotation()).isNotNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaValueConfig.class);
|
||||
|
||||
// direct access to annotation value:
|
||||
assertThat(descriptor.getAnnotation().value()).isEqualTo(new String[] { "foo.xml" });
|
||||
}
|
||||
|
||||
@Test
|
||||
void overriddenContextConfigurationValue() throws Exception {
|
||||
Class<?> declaringClass = OverriddenMetaValueConfigTestCase.class;
|
||||
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(declaringClass,
|
||||
ContextConfiguration.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(declaringClass);
|
||||
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaValueConfig.class);
|
||||
assertThat(descriptor.getAnnotationType()).isEqualTo(ContextConfiguration.class);
|
||||
assertThat(descriptor.getComposedAnnotation()).isNotNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaValueConfig.class);
|
||||
|
||||
// direct access to annotation value:
|
||||
assertThat(descriptor.getAnnotation().value()).isEqualTo(new String[] { "foo.xml" });
|
||||
|
||||
// overridden attribute:
|
||||
AnnotationAttributes attributes = descriptor.getAnnotationAttributes();
|
||||
|
||||
// NOTE: we would like to be able to override the 'value' attribute; however,
|
||||
// Spring currently does not allow overrides for the 'value' attribute.
|
||||
// See SPR-11393 for related discussions.
|
||||
assertThat(attributes.getStringArray("value")).isEqualTo(new String[] { "foo.xml" });
|
||||
}
|
||||
|
||||
@Test
|
||||
void contextConfigurationLocationsAndInheritLocations() throws Exception {
|
||||
Class<MetaLocationsConfigTestCase> declaringClass = MetaLocationsConfigTestCase.class;
|
||||
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(declaringClass,
|
||||
ContextConfiguration.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(declaringClass);
|
||||
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaLocationsConfig.class);
|
||||
assertThat(descriptor.getAnnotationType()).isEqualTo(ContextConfiguration.class);
|
||||
assertThat(descriptor.getComposedAnnotation()).isNotNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaLocationsConfig.class);
|
||||
|
||||
// direct access to annotation attributes:
|
||||
assertThat(descriptor.getAnnotation().locations()).isEqualTo(new String[] { "foo.xml" });
|
||||
assertThat(descriptor.getAnnotation().inheritLocations()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void overriddenContextConfigurationLocationsAndInheritLocations() throws Exception {
|
||||
Class<?> declaringClass = OverriddenMetaLocationsConfigTestCase.class;
|
||||
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(declaringClass,
|
||||
ContextConfiguration.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(declaringClass);
|
||||
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaLocationsConfig.class);
|
||||
assertThat(descriptor.getAnnotationType()).isEqualTo(ContextConfiguration.class);
|
||||
assertThat(descriptor.getComposedAnnotation()).isNotNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaLocationsConfig.class);
|
||||
|
||||
// direct access to annotation attributes:
|
||||
assertThat(descriptor.getAnnotation().locations()).isEqualTo(new String[] { "foo.xml" });
|
||||
assertThat(descriptor.getAnnotation().inheritLocations()).isFalse();
|
||||
|
||||
// overridden attributes:
|
||||
AnnotationAttributes attributes = descriptor.getAnnotationAttributes();
|
||||
assertThat(attributes.getStringArray("locations")).isEqualTo(new String[] { "bar.xml" });
|
||||
assertThat(attributes.getBoolean("inheritLocations")).isTrue();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ContextConfiguration("foo.xml")
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
static @interface MetaValueConfig {
|
||||
|
||||
String[] value() default {};
|
||||
}
|
||||
|
||||
@MetaValueConfig
|
||||
static class MetaValueConfigTestCase {
|
||||
}
|
||||
|
||||
@MetaValueConfig("bar.xml")
|
||||
static class OverriddenMetaValueConfigTestCase {
|
||||
}
|
||||
|
||||
@ContextConfiguration(locations = "foo.xml", inheritLocations = false)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
static @interface MetaLocationsConfig {
|
||||
|
||||
String[] locations() default {};
|
||||
|
||||
boolean inheritLocations();
|
||||
}
|
||||
|
||||
@MetaLocationsConfig(inheritLocations = true)
|
||||
static class MetaLocationsConfigTestCase {
|
||||
}
|
||||
|
||||
@MetaLocationsConfig(locations = "bar.xml", inheritLocations = true)
|
||||
static class OverriddenMetaLocationsConfigTestCase {
|
||||
}
|
||||
|
||||
}
|
|
@ -19,11 +19,8 @@ package org.springframework.transaction.reactive;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.function.SingletonSupplier;
|
||||
|
||||
/**
|
||||
* Mutable transaction context that encapsulates transactional synchronizations and
|
||||
|
@ -41,8 +38,6 @@ public class TransactionContext {
|
|||
|
||||
private final @Nullable TransactionContext parent;
|
||||
|
||||
private final SingletonSupplier<UUID> contextId = SingletonSupplier.of(UUID::randomUUID);
|
||||
|
||||
private final Map<Object, Object> resources = new LinkedHashMap<>();
|
||||
|
||||
@Nullable
|
||||
|
@ -71,20 +66,6 @@ public class TransactionContext {
|
|||
return this.parent;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getName() {
|
||||
String name = getCurrentTransactionName();
|
||||
if (StringUtils.hasText(name)) {
|
||||
return getContextId() + ": " + name;
|
||||
}
|
||||
return getContextId().toString();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public UUID getContextId() {
|
||||
return this.contextId.obtain();
|
||||
}
|
||||
|
||||
public Map<Object, Object> getResources() {
|
||||
return this.resources;
|
||||
}
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.http.client.support;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.client.ClientHttpRequestExecution;
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.Base64Utils;
|
||||
|
||||
/**
|
||||
* {@link ClientHttpRequestInterceptor} to apply a BASIC authorization header.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 4.3.1
|
||||
* @deprecated as of 5.1.1, in favor of {@link BasicAuthenticationInterceptor}
|
||||
* which reuses {@link org.springframework.http.HttpHeaders#setBasicAuth},
|
||||
* sharing its default charset ISO-8859-1 instead of UTF-8 as used here
|
||||
*/
|
||||
@Deprecated
|
||||
public class BasicAuthorizationInterceptor implements ClientHttpRequestInterceptor {
|
||||
|
||||
private final String username;
|
||||
|
||||
private final String password;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new interceptor which adds a BASIC authorization header
|
||||
* for the given username and password.
|
||||
* @param username the username to use
|
||||
* @param password the password to use
|
||||
*/
|
||||
public BasicAuthorizationInterceptor(@Nullable String username, @Nullable String password) {
|
||||
Assert.doesNotContain(username, ":", "Username must not contain a colon");
|
||||
this.username = (username != null ? username : "");
|
||||
this.password = (password != null ? password : "");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ClientHttpResponse intercept(
|
||||
HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
|
||||
|
||||
String token = Base64Utils.encodeToString(
|
||||
(this.username + ":" + this.password).getBytes(StandardCharsets.UTF_8));
|
||||
request.getHeaders().add("Authorization", "Basic " + token);
|
||||
return execution.execute(request, body);
|
||||
}
|
||||
|
||||
}
|
|
@ -91,14 +91,6 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* The default charset used by the converter.
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated
|
||||
public static final Charset DEFAULT_CHARSET = null;
|
||||
|
||||
|
||||
protected ObjectMapper defaultObjectMapper;
|
||||
|
||||
@Nullable
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.http.converter.protobuf;
|
||||
|
||||
import com.google.protobuf.ExtensionRegistry;
|
||||
|
||||
/**
|
||||
* Google Protocol Messages can contain message extensions that can be parsed if
|
||||
* the appropriate configuration has been registered in the {@code ExtensionRegistry}.
|
||||
*
|
||||
* <p>This interface provides a facility to populate the {@code ExtensionRegistry}.
|
||||
*
|
||||
* @author Alex Antonov
|
||||
* @author Sebastien Deleuze
|
||||
* @since 4.1
|
||||
* @see <a href="https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/ExtensionRegistry">
|
||||
* com.google.protobuf.ExtensionRegistry</a>
|
||||
* @deprecated as of Spring Framework 5.1, use {@link ExtensionRegistry} based constructors instead
|
||||
*/
|
||||
@Deprecated
|
||||
public interface ExtensionRegistryInitializer {
|
||||
|
||||
/**
|
||||
* Initializes the {@code ExtensionRegistry} with Protocol Message extensions.
|
||||
* @param registry the registry to populate
|
||||
*/
|
||||
void initializeExtensionRegistry(ExtensionRegistry registry);
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -121,20 +121,6 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
|
|||
this(null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@code ProtobufHttpMessageConverter} with an
|
||||
* initializer that allows the registration of message extensions.
|
||||
* @param registryInitializer an initializer for message extensions
|
||||
* @deprecated as of Spring Framework 5.1, use {@link #ProtobufHttpMessageConverter(ExtensionRegistry)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public ProtobufHttpMessageConverter(@Nullable ExtensionRegistryInitializer registryInitializer) {
|
||||
this(null, null);
|
||||
if (registryInitializer != null) {
|
||||
registryInitializer.initializeExtensionRegistry(this.extensionRegistry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@code ProtobufHttpMessageConverter} with a registry that specifies
|
||||
* protocol message extensions.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -75,24 +75,4 @@ public class ProtobufJsonFormatHttpMessageConverter extends ProtobufHttpMessageC
|
|||
super(new ProtobufJavaUtilSupport(parser, printer), extensionRegistry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@code ProtobufJsonFormatHttpMessageConverter} with the given
|
||||
* {@code JsonFormat.Parser} and {@code JsonFormat.Printer} configuration, also
|
||||
* accepting an initializer that allows the registration of message extensions.
|
||||
* @param parser the JSON parser configuration
|
||||
* @param printer the JSON printer configuration
|
||||
* @param registryInitializer an initializer for message extensions
|
||||
* @deprecated as of 5.1, in favor of
|
||||
* {@link #ProtobufJsonFormatHttpMessageConverter(com.google.protobuf.util.JsonFormat.Parser, com.google.protobuf.util.JsonFormat.Printer, ExtensionRegistry)}
|
||||
*/
|
||||
@Deprecated
|
||||
public ProtobufJsonFormatHttpMessageConverter(@Nullable JsonFormat.Parser parser,
|
||||
@Nullable JsonFormat.Printer printer, @Nullable ExtensionRegistryInitializer registryInitializer) {
|
||||
|
||||
super(new ProtobufJavaUtilSupport(parser, printer), null);
|
||||
if (registryInitializer != null) {
|
||||
registryInitializer.initializeExtensionRegistry(this.extensionRegistry);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -254,7 +254,7 @@ public abstract class AbstractListenerWriteProcessor<T> implements Processor<T,
|
|||
* the next item from the upstream, write Publisher.
|
||||
* <p>The default implementation is a no-op.
|
||||
* @deprecated originally introduced for Undertow to stop write notifications
|
||||
* when no data is available, but deprecated as of as of 5.0.6 since constant
|
||||
* when no data is available, but deprecated as of 5.0.6 since constant
|
||||
* switching on every requested item causes a significant slowdown.
|
||||
*/
|
||||
@Deprecated
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -128,31 +128,6 @@ public abstract class AbstractServerHttpResponse implements ServerHttpResponse {
|
|||
return this.statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the HTTP status code of the response.
|
||||
* @param statusCode the HTTP status as an integer value
|
||||
* @since 5.0.1
|
||||
* @deprecated as of 5.2.4 in favor of {@link ServerHttpResponse#setRawStatusCode(Integer)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setStatusCodeValue(@Nullable Integer statusCode) {
|
||||
if (this.state.get() != State.COMMITTED) {
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the HTTP status code of the response.
|
||||
* @return the HTTP status as an integer value
|
||||
* @since 5.0.1
|
||||
* @deprecated as of 5.2.4 in favor of {@link ServerHttpResponse#getRawStatusCode()}.
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated
|
||||
public Integer getStatusCodeValue() {
|
||||
return this.statusCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
if (this.readOnlyHeaders != null) {
|
||||
|
|
|
@ -54,23 +54,6 @@ import org.springframework.web.cors.CorsConfiguration;
|
|||
@Documented
|
||||
public @interface CrossOrigin {
|
||||
|
||||
/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
|
||||
@Deprecated
|
||||
String[] DEFAULT_ORIGINS = {"*"};
|
||||
|
||||
/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
|
||||
@Deprecated
|
||||
String[] DEFAULT_ALLOWED_HEADERS = {"*"};
|
||||
|
||||
/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
|
||||
@Deprecated
|
||||
boolean DEFAULT_ALLOW_CREDENTIALS = false;
|
||||
|
||||
/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
|
||||
@Deprecated
|
||||
long DEFAULT_MAX_AGE = 1800;
|
||||
|
||||
|
||||
/**
|
||||
* Alias for {@link #origins}.
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -49,13 +49,12 @@ public class DefaultDataBinderFactory implements WebDataBinderFactory {
|
|||
* @throws Exception in case of invalid state or arguments
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public final WebDataBinder createBinder(
|
||||
NativeWebRequest webRequest, @Nullable Object target, String objectName) throws Exception {
|
||||
|
||||
WebDataBinder dataBinder = createBinderInstance(target, objectName, webRequest);
|
||||
if (this.initializer != null) {
|
||||
this.initializer.initBinder(dataBinder, webRequest);
|
||||
this.initializer.initBinder(dataBinder);
|
||||
}
|
||||
initBinder(dataBinder, webRequest);
|
||||
return dataBinder;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -17,7 +17,6 @@
|
|||
package org.springframework.web.bind.support;
|
||||
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
|
||||
/**
|
||||
* Callback interface for initializing a {@link WebDataBinder} for performing
|
||||
|
@ -36,15 +35,4 @@ public interface WebBindingInitializer {
|
|||
*/
|
||||
void initBinder(WebDataBinder binder);
|
||||
|
||||
/**
|
||||
* Initialize the given DataBinder for the given (Servlet) request.
|
||||
* @param binder the DataBinder to initialize
|
||||
* @param request the web request that the data binding happens within
|
||||
* @deprecated as of 5.0 in favor of {@link #initBinder(WebDataBinder)}
|
||||
*/
|
||||
@Deprecated
|
||||
default void initBinder(WebDataBinder binder, WebRequest request) {
|
||||
initBinder(binder);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -173,26 +173,6 @@ public class DefaultResponseErrorHandler implements ResponseErrorHandler {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the HTTP status of the given response.
|
||||
* @param response the response to inspect
|
||||
* @return the associated HTTP status
|
||||
* @throws IOException in case of I/O errors
|
||||
* @throws UnknownHttpStatusCodeException in case of an unknown status code
|
||||
* that cannot be represented with the {@link HttpStatus} enum
|
||||
* @since 4.3.8
|
||||
* @deprecated as of 5.0, in favor of {@link #handleError(ClientHttpResponse, HttpStatus)}
|
||||
*/
|
||||
@Deprecated
|
||||
protected HttpStatus getHttpStatusCode(ClientHttpResponse response) throws IOException {
|
||||
HttpStatus statusCode = HttpStatus.resolve(response.getRawStatusCode());
|
||||
if (statusCode == null) {
|
||||
throw new UnknownHttpStatusCodeException(response.getRawStatusCode(), response.getStatusText(),
|
||||
response.getHeaders(), getResponseBody(response), getCharset(response));
|
||||
}
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the body of the given response (for inclusion in a status exception).
|
||||
* @param response the response to inspect
|
||||
|
|
|
@ -282,15 +282,10 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
|
|||
* @param uriVars the default URI variable values
|
||||
* @since 4.3
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public void setDefaultUriVariables(Map<String, ?> uriVars) {
|
||||
if (this.uriTemplateHandler instanceof DefaultUriBuilderFactory) {
|
||||
((DefaultUriBuilderFactory) this.uriTemplateHandler).setDefaultUriVariables(uriVars);
|
||||
}
|
||||
else if (this.uriTemplateHandler instanceof org.springframework.web.util.AbstractUriTemplateHandler) {
|
||||
((org.springframework.web.util.AbstractUriTemplateHandler) this.uriTemplateHandler)
|
||||
.setDefaultUriVariables(uriVars);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(
|
||||
"This property is not supported with the configured UriTemplateHandler.");
|
||||
|
@ -303,11 +298,6 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
|
|||
* backwards compatibility, the encoding mode is set to
|
||||
* {@link EncodingMode#URI_COMPONENT URI_COMPONENT}. As of 5.0.8, prefer
|
||||
* using {@link EncodingMode#TEMPLATE_AND_VALUES TEMPLATE_AND_VALUES}.
|
||||
* <p><strong>Note:</strong> in 5.0 the switch from
|
||||
* {@link org.springframework.web.util.DefaultUriTemplateHandler
|
||||
* DefaultUriTemplateHandler} (deprecated in 4.3), as the default to use, to
|
||||
* {@link DefaultUriBuilderFactory} brings in a different default for the
|
||||
* {@code parsePath} property (switching from false to true).
|
||||
* @param handler the URI template handler to use
|
||||
*/
|
||||
public void setUriTemplateHandler(UriTemplateHandler handler) {
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
* 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.web.context.support;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Servlet variant of {@link org.springframework.context.support.LiveBeansView}'s
|
||||
* MBean exposure.
|
||||
*
|
||||
* <p>Generates a JSON snapshot for current beans and their dependencies in
|
||||
* all ApplicationContexts that live within the current web application.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.2
|
||||
* @see org.springframework.context.support.LiveBeansView#getSnapshotAsJson()
|
||||
* @deprecated as of 5.3, in favor of using Spring Boot actuators for such needs
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("serial")
|
||||
public class LiveBeansViewServlet extends HttpServlet {
|
||||
|
||||
@Nullable
|
||||
private org.springframework.context.support.LiveBeansView liveBeansView;
|
||||
|
||||
|
||||
@Override
|
||||
public void init() throws ServletException {
|
||||
this.liveBeansView = buildLiveBeansView();
|
||||
}
|
||||
|
||||
protected org.springframework.context.support.LiveBeansView buildLiveBeansView() {
|
||||
return new ServletContextLiveBeansView(getServletContext());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
|
||||
Assert.state(this.liveBeansView != null, "No LiveBeansView available");
|
||||
String content = this.liveBeansView.getSnapshotAsJson();
|
||||
response.setContentType("application/json");
|
||||
response.setContentLength(content.length());
|
||||
response.getWriter().write(content);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* 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.web.context.support;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import jakarta.servlet.ServletContext;
|
||||
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.context.support.LiveBeansView} subclass
|
||||
* which looks for all ApplicationContexts in the web application,
|
||||
* as exposed in ServletContext attributes.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.2
|
||||
* @deprecated as of 5.3, in favor of using Spring Boot actuators for such needs
|
||||
*/
|
||||
@Deprecated
|
||||
public class ServletContextLiveBeansView extends org.springframework.context.support.LiveBeansView {
|
||||
|
||||
private final ServletContext servletContext;
|
||||
|
||||
/**
|
||||
* Create a new LiveBeansView for the given ServletContext.
|
||||
* @param servletContext current ServletContext
|
||||
*/
|
||||
public ServletContextLiveBeansView(ServletContext servletContext) {
|
||||
Assert.notNull(servletContext, "ServletContext must not be null");
|
||||
this.servletContext = servletContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<ConfigurableApplicationContext> findApplicationContexts() {
|
||||
Set<ConfigurableApplicationContext> contexts = new LinkedHashSet<>();
|
||||
Enumeration<String> attrNames = this.servletContext.getAttributeNames();
|
||||
while (attrNames.hasMoreElements()) {
|
||||
String attrName = attrNames.nextElement();
|
||||
Object attrValue = this.servletContext.getAttribute(attrName);
|
||||
if (attrValue instanceof ConfigurableApplicationContext) {
|
||||
contexts.add((ConfigurableApplicationContext) attrValue);
|
||||
}
|
||||
}
|
||||
return contexts;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,189 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2021 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.web.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletRequestWrapper;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.FormHttpMessageConverter;
|
||||
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
|
||||
import org.springframework.http.server.ServletServerHttpRequest;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link jakarta.servlet.Filter} that makes form encoded data available through
|
||||
* the {@code ServletRequest.getParameter*()} family of methods during HTTP PUT
|
||||
* or PATCH requests.
|
||||
*
|
||||
* <p>The Servlet spec requires form data to be available for HTTP POST but
|
||||
* not for HTTP PUT or PATCH requests. This filter intercepts HTTP PUT and PATCH
|
||||
* requests where content type is {@code 'application/x-www-form-urlencoded'},
|
||||
* reads form encoded content from the body of the request, and wraps the ServletRequest
|
||||
* in order to make the form data available as request parameters just like
|
||||
* it is for HTTP POST requests.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
* @deprecated as of 5.1 in favor of {@link FormContentFilter} which is the same
|
||||
* but also handles DELETE.
|
||||
*/
|
||||
@Deprecated
|
||||
public class HttpPutFormContentFilter extends OncePerRequestFilter {
|
||||
|
||||
private FormHttpMessageConverter formConverter = new AllEncompassingFormHttpMessageConverter();
|
||||
|
||||
|
||||
/**
|
||||
* Set the converter to use for parsing form content.
|
||||
* <p>By default this is an instance of {@link AllEncompassingFormHttpMessageConverter}.
|
||||
*/
|
||||
public void setFormConverter(FormHttpMessageConverter converter) {
|
||||
Assert.notNull(converter, "FormHttpMessageConverter is required.");
|
||||
this.formConverter = converter;
|
||||
}
|
||||
|
||||
public FormHttpMessageConverter getFormConverter() {
|
||||
return this.formConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default character set to use for reading form data.
|
||||
* This is a shortcut for:<br>
|
||||
* {@code getFormConverter.setCharset(charset)}.
|
||||
*/
|
||||
public void setCharset(Charset charset) {
|
||||
this.formConverter.setCharset(charset);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(final HttpServletRequest request, HttpServletResponse response,
|
||||
FilterChain filterChain) throws ServletException, IOException {
|
||||
|
||||
if (("PUT".equals(request.getMethod()) || "PATCH".equals(request.getMethod())) && isFormContentType(request)) {
|
||||
HttpInputMessage inputMessage = new ServletServerHttpRequest(request) {
|
||||
@Override
|
||||
public InputStream getBody() throws IOException {
|
||||
return request.getInputStream();
|
||||
}
|
||||
};
|
||||
MultiValueMap<String, String> formParameters = this.formConverter.read(null, inputMessage);
|
||||
if (!formParameters.isEmpty()) {
|
||||
HttpServletRequest wrapper = new HttpPutFormContentRequestWrapper(request, formParameters);
|
||||
filterChain.doFilter(wrapper, response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
|
||||
private boolean isFormContentType(HttpServletRequest request) {
|
||||
String contentType = request.getContentType();
|
||||
if (contentType != null) {
|
||||
try {
|
||||
MediaType mediaType = MediaType.parseMediaType(contentType);
|
||||
return (MediaType.APPLICATION_FORM_URLENCODED.includes(mediaType));
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class HttpPutFormContentRequestWrapper extends HttpServletRequestWrapper {
|
||||
|
||||
private final MultiValueMap<String, String> formParameters;
|
||||
|
||||
public HttpPutFormContentRequestWrapper(HttpServletRequest request, MultiValueMap<String, String> parameters) {
|
||||
super(request);
|
||||
this.formParameters = parameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getParameter(String name) {
|
||||
String queryStringValue = super.getParameter(name);
|
||||
String formValue = this.formParameters.getFirst(name);
|
||||
return (queryStringValue != null ? queryStringValue : formValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String[]> getParameterMap() {
|
||||
Map<String, String[]> result = new LinkedHashMap<>();
|
||||
Enumeration<String> names = getParameterNames();
|
||||
while (names.hasMoreElements()) {
|
||||
String name = names.nextElement();
|
||||
result.put(name, getParameterValues(name));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<String> getParameterNames() {
|
||||
Set<String> names = new LinkedHashSet<>();
|
||||
names.addAll(Collections.list(super.getParameterNames()));
|
||||
names.addAll(this.formParameters.keySet());
|
||||
return Collections.enumeration(names);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String[] getParameterValues(String name) {
|
||||
String[] parameterValues = super.getParameterValues(name);
|
||||
List<String> formParam = this.formParameters.get(name);
|
||||
if (formParam == null) {
|
||||
return parameterValues;
|
||||
}
|
||||
if (parameterValues == null || getQueryString() == null) {
|
||||
return StringUtils.toStringArray(formParam);
|
||||
}
|
||||
else {
|
||||
List<String> result = new ArrayList<>(parameterValues.length + formParam.size());
|
||||
result.addAll(Arrays.asList(parameterValues));
|
||||
result.addAll(formParam);
|
||||
return StringUtils.toStringArray(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2021 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.web.filter.reactive;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebFilter;
|
||||
import org.springframework.web.server.WebFilterChain;
|
||||
import org.springframework.web.server.adapter.ForwardedHeaderTransformer;
|
||||
|
||||
/**
|
||||
* Extract values from "Forwarded" and "X-Forwarded-*" headers to override the
|
||||
* request URI (i.e. {@link ServerHttpRequest#getURI()}) so it reflects the
|
||||
* client-originated protocol and address.
|
||||
*
|
||||
* <p>Alternatively if {@link #setRemoveOnly removeOnly} is set to "true", then
|
||||
* "Forwarded" and "X-Forwarded-*" headers are only removed and not used.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
* @see <a href="https://tools.ietf.org/html/rfc7239">https://tools.ietf.org/html/rfc7239</a>
|
||||
* @deprecated as of 5.1 this filter is deprecated in favor of using
|
||||
* {@link ForwardedHeaderTransformer} which can be declared as a bean with the
|
||||
* name "forwardedHeaderTransformer" or registered explicitly in
|
||||
* {@link org.springframework.web.server.adapter.WebHttpHandlerBuilder
|
||||
* WebHttpHandlerBuilder}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class ForwardedHeaderFilter extends ForwardedHeaderTransformer implements WebFilter {
|
||||
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
if (hasForwardedHeaders(request)) {
|
||||
exchange = exchange.mutate().request(apply(request)).build();
|
||||
}
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* 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.web.server;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
|
||||
/**
|
||||
* Exception for errors that fit response status 415 (unsupported media type).
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
* @deprecated in favor of {@link UnsupportedMediaTypeStatusException},
|
||||
* with this class never thrown by Spring code and to be removed in 5.3
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("serial")
|
||||
public class MediaTypeNotSupportedStatusException extends ResponseStatusException {
|
||||
|
||||
private final List<MediaType> supportedMediaTypes;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for when the Content-Type is invalid.
|
||||
*/
|
||||
public MediaTypeNotSupportedStatusException(String reason) {
|
||||
super(HttpStatus.UNSUPPORTED_MEDIA_TYPE, reason);
|
||||
this.supportedMediaTypes = Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for when the Content-Type is not supported.
|
||||
*/
|
||||
public MediaTypeNotSupportedStatusException(List<MediaType> supportedMediaTypes) {
|
||||
super(HttpStatus.UNSUPPORTED_MEDIA_TYPE, "Unsupported media type", null);
|
||||
this.supportedMediaTypes = Collections.unmodifiableList(supportedMediaTypes);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the list of supported content types in cases when the Accept
|
||||
* header is parsed but not supported, or an empty list otherwise.
|
||||
*/
|
||||
public List<MediaType> getSupportedMediaTypes() {
|
||||
return this.supportedMediaTypes;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -19,7 +19,6 @@ package org.springframework.web.server;
|
|||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
@ -58,16 +57,6 @@ public class MethodNotAllowedException extends ResponseStatusException {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a Map with an "Allow" header.
|
||||
* @since 5.1.11
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public Map<String, String> getHeaders() {
|
||||
return getResponseHeaders().toSingleValueMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return HttpHeaders with an "Allow" header.
|
||||
* @since 5.1.13
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -18,7 +18,6 @@ package org.springframework.web.server;
|
|||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
@ -54,16 +53,6 @@ public class NotAcceptableStatusException extends ResponseStatusException {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a Map with an "Accept" header.
|
||||
* @since 5.1.11
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public Map<String, String> getHeaders() {
|
||||
return getResponseHeaders().toSingleValueMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return HttpHeaders with an "Accept" header, or an empty instance.
|
||||
* @since 5.1.13
|
||||
|
|
|
@ -16,9 +16,6 @@
|
|||
|
||||
package org.springframework.web.server;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.NestedExceptionUtils;
|
||||
import org.springframework.core.NestedRuntimeException;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
@ -114,18 +111,6 @@ public class ResponseStatusException extends NestedRuntimeException {
|
|||
return this.status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return headers associated with the exception that should be added to the
|
||||
* error response, e.g. "Allow", "Accept", etc.
|
||||
* <p>The default implementation in this class returns an empty map.
|
||||
* @since 5.1.11
|
||||
* @deprecated as of 5.1.13 in favor of {@link #getResponseHeaders()}
|
||||
*/
|
||||
@Deprecated
|
||||
public Map<String, String> getHeaders() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return headers associated with the exception that should be added to the
|
||||
* error response, e.g. "Allow", "Accept", etc.
|
||||
|
@ -133,13 +118,7 @@ public class ResponseStatusException extends NestedRuntimeException {
|
|||
* @since 5.1.13
|
||||
*/
|
||||
public HttpHeaders getResponseHeaders() {
|
||||
Map<String, String> headers = getHeaders();
|
||||
if (headers.isEmpty()) {
|
||||
return HttpHeaders.EMPTY;
|
||||
}
|
||||
HttpHeaders result = new HttpHeaders();
|
||||
getHeaders().forEach(result::add);
|
||||
return result;
|
||||
return HttpHeaders.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -69,26 +69,6 @@ public class ServerErrorException extends ResponseStatusException {
|
|||
this.parameter = parameter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for a 500 error linked to a specific {@code MethodParameter}.
|
||||
* @deprecated in favor of {@link #ServerErrorException(String, MethodParameter, Throwable)}
|
||||
*/
|
||||
@Deprecated
|
||||
public ServerErrorException(String reason, MethodParameter parameter) {
|
||||
this(reason, parameter, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for a 500 error with a reason only.
|
||||
* @deprecated in favor of {@link #ServerErrorException(String, Throwable)}
|
||||
*/
|
||||
@Deprecated
|
||||
public ServerErrorException(String reason) {
|
||||
super(HttpStatus.INTERNAL_SERVER_ERROR, reason, null);
|
||||
this.handlerMethod = null;
|
||||
this.parameter = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the handler method associated with the error, if any.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
|
@ -16,7 +16,6 @@
|
|||
|
||||
package org.springframework.web.server.handler;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
@ -92,18 +91,6 @@ public class DefaultWebFilterChain implements WebFilterChain {
|
|||
this.chain = chain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public constructor with the list of filters and the target handler to use.
|
||||
* @param handler the target handler
|
||||
* @param filters the filters ahead of the handler
|
||||
* @deprecated as of 5.1 this constructor is deprecated in favor of
|
||||
* {@link #DefaultWebFilterChain(WebHandler, List)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public DefaultWebFilterChain(WebHandler handler, WebFilter... filters) {
|
||||
this(handler, Arrays.asList(filters));
|
||||
}
|
||||
|
||||
|
||||
public List<WebFilter> getFilters() {
|
||||
return this.allFilters;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue