diff --git a/spring-beans/src/main/java/org/springframework/beans/annotation/AnnotationBeanUtils.java b/spring-beans/src/main/java/org/springframework/beans/annotation/AnnotationBeanUtils.java deleted file mode 100644 index c0b22ad47d..0000000000 --- a/spring-beans/src/main/java/org/springframework/beans/annotation/AnnotationBeanUtils.java +++ /dev/null @@ -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. - *

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 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); - } - } - } - -} diff --git a/spring-beans/src/main/java/org/springframework/beans/annotation/package-info.java b/spring-beans/src/main/java/org/springframework/beans/annotation/package-info.java deleted file mode 100644 index d2667da96f..0000000000 --- a/spring-beans/src/main/java/org/springframework/beans/annotation/package-info.java +++ /dev/null @@ -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; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java index 026790c361..f11dcce9a3 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java @@ -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 diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/Required.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/Required.java deleted file mode 100644 index 4993cf25d4..0000000000 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/Required.java +++ /dev/null @@ -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. - * - *

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 { - -} diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.java deleted file mode 100644 index a4cf5f314c..0000000000 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.java +++ /dev/null @@ -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. - * - *

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 (in part) for a developer to code a method that - * simply checks that all required properties have actually been set. - * - *

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 - * not check anything else... In particular, it does not check that a - * configured value is not {@code null}. - * - *

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 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 validatedBeanNames = Collections.newSetFromMap(new ConcurrentHashMap<>(64)); - - - /** - * Set the 'required' annotation type, to be used on bean property - * setter methods. - *

The default required annotation type is the Spring-provided - * {@link Required} annotation. - *

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 requiredAnnotationType) { - Assert.notNull(requiredAnnotationType, "'requiredAnnotationType' must not be null"); - this.requiredAnnotationType = requiredAnnotationType; - } - - /** - * Return the 'required' annotation type. - */ - protected Class 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 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. - *

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)? - *

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 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(); - } - -} diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java index c16db6ca73..c808a81541 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java @@ -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}. - *

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 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. diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/InstantiationAwareBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/InstantiationAwareBeanPostProcessor.java index c4e21122ed..e842353cb5 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/InstantiationAwareBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/InstantiationAwareBeanPostProcessor.java @@ -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; * *

NOTE: 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. - *

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. - *

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. *

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; } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/InstantiationAwareBeanPostProcessorAdapter.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/InstantiationAwareBeanPostProcessorAdapter.java deleted file mode 100644 index b3c112c8be..0000000000 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/InstantiationAwareBeanPostProcessorAdapter.java +++ /dev/null @@ -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. - * - *

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 { - -} diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index 5ab6fb085a..d7f32a8ac5 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -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). - *

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); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java index b33651f186..6c2e05068c 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java @@ -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. - *

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). *

This allows the bean factory to optimize its caching for repeated diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/XmlBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/XmlBeanFactory.java deleted file mode 100644 index b762a41810..0000000000 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/XmlBeanFactory.java +++ /dev/null @@ -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. - * - *

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. - * - *

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. - * - *

For advanced needs, consider using a {@link DefaultListableBeanFactory} with - * an {@link XmlBeanDefinitionReader}. 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); - } - -} diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java index c746f21949..2d95718172 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessorTests.java @@ -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); diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/InjectAnnotationBeanPostProcessorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/InjectAnnotationBeanPostProcessorTests.java index d4b97bdb19..079f395560 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/InjectAnnotationBeanPostProcessorTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/InjectAnnotationBeanPostProcessorTests.java @@ -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); diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessorTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessorTests.java deleted file mode 100644 index a88a756029..0000000000 --- a/spring-beans/src/test/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessorTests.java +++ /dev/null @@ -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(); - } - } - -} diff --git a/spring-context/src/jmh/java/org/springframework/context/annotation/AnnotationProcessorBenchmark.java b/spring-context/src/jmh/java/org/springframework/context/annotation/AnnotationProcessorBenchmark.java index 3e19ca7e97..f78c671817 100644 --- a/spring-context/src/jmh/java/org/springframework/context/annotation/AnnotationProcessorBenchmark.java +++ b/spring-context/src/jmh/java/org/springframework/context/annotation/AnnotationProcessorBenchmark.java @@ -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); } diff --git a/spring-context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java b/spring-context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java index 50516d0727..c7f7ef5da0 100644 --- a/spring-context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java +++ b/spring-context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java @@ -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. *

This will always be called within a full {@link #cacheMap} lock diff --git a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigUtils.java b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigUtils.java index 20ed51eff6..9a1a146290 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigUtils.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/AnnotationConfigUtils.java @@ -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. */ diff --git a/spring-context/src/main/java/org/springframework/context/annotation/Bean.java b/spring-context/src/main/java/org/springframework/context/annotation/Bean.java index 2f254d5a71..14732b1783 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/Bean.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/Bean.java @@ -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? - *

Note that this autowire mode is just about externally driven autowiring based - * on bean property setter methods by convention, analogous to XML bean definitions. - *

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? *

Default is {@code true}; set this to {@code false} for internal delegates diff --git a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java index db8c8e2c28..18a6245b64 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java @@ -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. diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java index 85b45e1574..86bcbb5e5b 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java @@ -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); diff --git a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java index dae989caa6..27b050838c 100644 --- a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java @@ -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). - *

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. *

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)); diff --git a/spring-context/src/main/java/org/springframework/context/support/LiveBeansView.java b/spring-context/src/main/java/org/springframework/context/support/LiveBeansView.java deleted file mode 100644 index 96a9b212e3..0000000000 --- a/spring-context/src/main/java/org/springframework/context/support/LiveBeansView.java +++ /dev/null @@ -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 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 contexts; - if (this.applicationContext != null) { - contexts = Collections.singleton(this.applicationContext); - } - else { - contexts = findApplicationContexts(); - } - return generateJson(contexts); - } - - /** - * Find all applicable ApplicationContexts for the current application. - *

Called if no specific ApplicationContext has been set for this LiveBeansView. - * @return the set of ApplicationContexts - */ - protected Set findApplicationContexts() { - synchronized (applicationContexts) { - return new LinkedHashSet<>(applicationContexts); - } - } - - /** - * Actually generate a JSON snapshot of the beans in the given ApplicationContexts. - *

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 contexts) { - StringBuilder result = new StringBuilder("[\n"); - for (Iterator 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(']'); - } - -} diff --git a/spring-context/src/main/java/org/springframework/context/support/LiveBeansViewMBean.java b/spring-context/src/main/java/org/springframework/context/support/LiveBeansViewMBean.java deleted file mode 100644 index b8e0ba01bd..0000000000 --- a/spring-context/src/main/java/org/springframework/context/support/LiveBeansViewMBean.java +++ /dev/null @@ -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(); - -} diff --git a/spring-context/src/test/java/org/springframework/context/annotation/configuration/BeanAnnotationAttributePropagationTests.java b/spring-context/src/test/java/org/springframework/context/annotation/configuration/BeanAnnotationAttributePropagationTests.java index 0ba5a87265..e334bddff5 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/configuration/BeanAnnotationAttributePropagationTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/configuration/BeanAnnotationAttributePropagationTests.java @@ -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 { diff --git a/spring-context/src/test/java/org/springframework/context/support/LiveBeansViewTests.java b/spring-context/src/test/java/org/springframework/context/support/LiveBeansViewTests.java deleted file mode 100644 index 983fa9bc88..0000000000 --- a/spring-context/src/test/java/org/springframework/context/support/LiveBeansViewTests.java +++ /dev/null @@ -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 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 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); - } - -} diff --git a/spring-core/src/main/java/org/springframework/core/codec/StringDecoder.java b/spring-core/src/main/java/org/springframework/core/codec/StringDecoder.java index e805414c13..5749d859eb 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/StringDecoder.java +++ b/spring-core/src/main/java/org/springframework/core/codec/StringDecoder.java @@ -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 { } } - /** - * 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 { 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. */ diff --git a/spring-core/src/main/java/org/springframework/core/io/ClassPathResource.java b/spring-core/src/main/java/org/springframework/core/io/ClassPathResource.java index cbaad7001b..2ba871bbc1 100644 --- a/spring-core/src/main/java/org/springframework/core/io/ClassPathResource.java +++ b/spring-core/src/main/java/org/springframework/core/io/ClassPathResource.java @@ -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). diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/AbstractRecursiveAnnotationVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/AbstractRecursiveAnnotationVisitor.java deleted file mode 100644 index 356ab5b461..0000000000 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/AbstractRecursiveAnnotationVisitor.java +++ /dev/null @@ -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; - } - -} diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java deleted file mode 100644 index ba1bfe06cf..0000000000 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java +++ /dev/null @@ -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. - * - *

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 attributesMap; - - private final Map> metaAnnotationMap; - - - public AnnotationAttributesReadingVisitor(String annotationType, - MultiValueMap attributesMap, Map> metaAnnotationMap, - @Nullable ClassLoader classLoader) { - - super(annotationType, new AnnotationAttributes(annotationType, classLoader), classLoader); - this.attributesMap = attributesMap; - this.metaAnnotationMap = metaAnnotationMap; - } - - - @Override - public void visitEnd() { - super.visitEnd(); - - Class annotationClass = this.attributes.annotationType(); - if (annotationClass != null) { - List 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 visited = new LinkedHashSet<>(); - for (Annotation metaAnnotation : metaAnnotations) { - recursivelyCollectMetaAnnotations(visited, metaAnnotation); - } - if (!visited.isEmpty()) { - Set 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 visited, Annotation annotation) { - Class 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); - } - } - } - } - -} diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java deleted file mode 100644 index 9435af78ed..0000000000 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java +++ /dev/null @@ -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 annotationSet = new LinkedHashSet<>(4); - - protected final Map> 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 attributesMap = new LinkedMultiValueMap<>(3); - - protected final Set 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 getAnnotationTypes() { - return this.annotationSet; - } - - @Override - public Set getMetaAnnotationTypes(String annotationName) { - Set metaAnnotationTypes = this.metaAnnotationMap.get(annotationName); - return (metaAnnotationTypes != null ? metaAnnotationTypes : Collections.emptySet()); - } - - @Override - public boolean hasMetaAnnotation(String metaAnnotationType) { - if (AnnotationUtils.isInJavaLangAnnotationPackage(metaAnnotationType)) { - return false; - } - Collection> allMetaTypes = this.metaAnnotationMap.values(); - for (Set 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 getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) { - MultiValueMap allAttributes = new LinkedMultiValueMap<>(); - List attributes = this.attributesMap.get(annotationName); - if (attributes == null) { - return null; - } - String annotatedElement = "class '" + getClassName() + "'"; - for (AnnotationAttributes raw : attributes) { - for (Map.Entry 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 getAnnotatedMethods(String annotationName) { - Set annotatedMethods = new LinkedHashSet<>(4); - for (MethodMetadata methodMetadata : this.methodMetadataSet) { - if (methodMetadata.isAnnotated(annotationName)) { - annotatedMethods.add(methodMetadata); - } - } - return annotatedMethods; - } - -} diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationReadingVisitorUtils.java b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationReadingVisitorUtils.java deleted file mode 100644 index 98bb301ba4..0000000000 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationReadingVisitorUtils.java +++ /dev/null @@ -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 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}. - *

Annotation attribute values appearing lower in the annotation - * hierarchy (i.e., closer to the declaring class) will override those - * defined higher 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 attributesMap, - Map> metaAnnotationMap, String annotationName) { - - // Get the unmerged list of attributes for the target annotation. - List 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 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 annotationTypes = new ArrayList<>(attributesMap.keySet()); - Collections.reverse(annotationTypes); - - // No need to revisit the target annotation type: - annotationTypes.remove(annotationName); - - for (String currentAnnotationType : annotationTypes) { - List currentAttributesList = attributesMap.get(currentAnnotationType); - if (!ObjectUtils.isEmpty(currentAttributesList)) { - Set 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; - } - -} diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/ClassMetadataReadingVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/ClassMetadataReadingVisitor.java deleted file mode 100644 index c80520cb5e..0000000000 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/ClassMetadataReadingVisitor.java +++ /dev/null @@ -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 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); - } - } - -} diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java deleted file mode 100644 index f352428b33..0000000000 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java +++ /dev/null @@ -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 methodMetadataSet; - - protected final Map> metaAnnotationMap = new LinkedHashMap<>(4); - - protected final LinkedMultiValueMap attributesMap = new LinkedMultiValueMap<>(3); - - - public MethodMetadataReadingVisitor(String methodName, int access, String declaringClassName, - String returnTypeName, @Nullable ClassLoader classLoader, Set 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 getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) { - if (!this.attributesMap.containsKey(annotationName)) { - return null; - } - MultiValueMap allAttributes = new LinkedMultiValueMap<>(); - List 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; - } - -} diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/RecursiveAnnotationArrayVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/RecursiveAnnotationArrayVisitor.java deleted file mode 100644 index 68bc0258aa..0000000000 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/RecursiveAnnotationArrayVisitor.java +++ /dev/null @@ -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 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 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. - } - } - } - } - -} diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/RecursiveAnnotationAttributesVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/RecursiveAnnotationAttributesVisitor.java deleted file mode 100644 index b5953c8dad..0000000000 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/RecursiveAnnotationAttributesVisitor.java +++ /dev/null @@ -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); - } - -} diff --git a/spring-core/src/main/java/org/springframework/lang/UsesJava7.java b/spring-core/src/main/java/org/springframework/lang/UsesJava7.java deleted file mode 100644 index c59159c472..0000000000 --- a/spring-core/src/main/java/org/springframework/lang/UsesJava7.java +++ /dev/null @@ -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 { -} diff --git a/spring-core/src/main/java/org/springframework/lang/UsesJava8.java b/spring-core/src/main/java/org/springframework/lang/UsesJava8.java deleted file mode 100644 index 1c2416b576..0000000000 --- a/spring-core/src/main/java/org/springframework/lang/UsesJava8.java +++ /dev/null @@ -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 { -} diff --git a/spring-core/src/main/java/org/springframework/lang/UsesSunHttpServer.java b/spring-core/src/main/java/org/springframework/lang/UsesSunHttpServer.java deleted file mode 100644 index 2147079f0a..0000000000 --- a/spring-core/src/main/java/org/springframework/lang/UsesSunHttpServer.java +++ /dev/null @@ -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 { -} diff --git a/spring-core/src/main/java/org/springframework/lang/UsesSunMisc.java b/spring-core/src/main/java/org/springframework/lang/UsesSunMisc.java deleted file mode 100644 index f86ccd9636..0000000000 --- a/spring-core/src/main/java/org/springframework/lang/UsesSunMisc.java +++ /dev/null @@ -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 { -} diff --git a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java index f5a703c301..297789e381 100644 --- a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java @@ -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 diff --git a/spring-core/src/main/java/org/springframework/util/StringUtils.java b/spring-core/src/main/java/org/springframework/util/StringUtils.java index 5b5c762408..313979e87e 100644 --- a/spring-core/src/main/java/org/springframework/util/StringUtils.java +++ b/spring-core/src/main/java/org/springframework/util/StringUtils.java @@ -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. - *

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 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) diff --git a/spring-core/src/main/java/org/springframework/util/comparator/CompoundComparator.java b/spring-core/src/main/java/org/springframework/util/comparator/CompoundComparator.java deleted file mode 100644 index a7e3565c44..0000000000 --- a/spring-core/src/main/java/org/springframework/util/comparator/CompoundComparator.java +++ /dev/null @@ -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. - * - *

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. - * - *

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 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 implements Comparator, Serializable { - - private final List 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. - *

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. - *

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 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 comparator, boolean ascending) { - this.comparators.add(new InvertibleComparator(comparator, ascending)); - } - - /** - * Replace the Comparator at the given index. - *

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 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 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) other).comparators))); - } - - @Override - public int hashCode() { - return this.comparators.hashCode(); - } - - @Override - public String toString() { - return "CompoundComparator: " + this.comparators; - } - -} diff --git a/spring-core/src/main/java/org/springframework/util/comparator/InvertibleComparator.java b/spring-core/src/main/java/org/springframework/util/comparator/InvertibleComparator.java deleted file mode 100644 index 7da876615b..0000000000 --- a/spring-core/src/main/java/org/springframework/util/comparator/InvertibleComparator.java +++ /dev/null @@ -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 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 implements Comparator, Serializable { - - private final Comparator 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 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 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 otherComp = (InvertibleComparator) 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; - } - -} diff --git a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationTypeMappingsTests.java b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationTypeMappingsTests.java index a6baf3a8e7..ce383eec49 100644 --- a/spring-core/src/test/java/org/springframework/core/annotation/AnnotationTypeMappingsTests.java +++ b/spring-core/src/test/java/org/springframework/core/annotation/AnnotationTypeMappingsTests.java @@ -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 { } diff --git a/spring-core/src/test/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitorTests.java b/spring-core/src/test/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitorTests.java deleted file mode 100644 index 844f56b86d..0000000000 --- a/spring-core/src/test/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitorTests.java +++ /dev/null @@ -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); - } - -} diff --git a/spring-core/src/test/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitorTests.java b/spring-core/src/test/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitorTests.java deleted file mode 100644 index d303b031bf..0000000000 --- a/spring-core/src/test/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitorTests.java +++ /dev/null @@ -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); - } - -} diff --git a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java index c89286af88..5390d01782 100644 --- a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java @@ -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(); diff --git a/spring-core/src/test/java/org/springframework/util/StringUtilsTests.java b/spring-core/src/test/java/org/springframework/util/StringUtilsTests.java index 2b46f73a56..24525c9f2d 100644 --- a/spring-core/src/test/java/org/springframework/util/StringUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/StringUtilsTests.java @@ -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"}; diff --git a/spring-core/src/test/java/org/springframework/util/comparator/CompoundComparatorTests.java b/spring-core/src/test/java/org/springframework/util/comparator/CompoundComparatorTests.java deleted file mode 100644 index bf60e2d81f..0000000000 --- a/spring-core/src/test/java/org/springframework/util/comparator/CompoundComparatorTests.java +++ /dev/null @@ -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 c = new CompoundComparator<>(); - assertThatIllegalStateException().isThrownBy(() -> - c.compare("foo", "bar")); - } - -} diff --git a/spring-core/src/test/java/org/springframework/util/comparator/InvertibleComparatorTests.java b/spring-core/src/test/java/org/springframework/util/comparator/InvertibleComparatorTests.java deleted file mode 100644 index df3f1a25e6..0000000000 --- a/spring-core/src/test/java/org/springframework/util/comparator/InvertibleComparatorTests.java +++ /dev/null @@ -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 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 invertibleComparator = new InvertibleComparator<>(comparator); - assertThat(invertibleComparator.isAscending()).isTrue(); - assertThat(invertibleComparator.compare(1, 2)).isEqualTo(-1); - } - - @Test - void shouldInvert() throws Exception { - InvertibleComparator 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 invertibleComparator = new InvertibleComparator<>(comparator, true); - assertThat(invertibleComparator.compare(1, 2)).isEqualTo(-1); - } - - @Test - void shouldCompareDescending() throws Exception { - InvertibleComparator invertibleComparator = new InvertibleComparator<>(comparator, false); - assertThat(invertibleComparator.compare(1, 2)).isEqualTo(1); - } - -} diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java index fae62e1d37..f9fbd7b638 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java @@ -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) { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/BatchUpdateUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/BatchUpdateUtils.java deleted file mode 100644 index dcab3b2ca9..0000000000 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/BatchUpdateUtils.java +++ /dev/null @@ -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 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); - } - } - } - -} diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallParameterMetaData.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallParameterMetaData.java index 76d9cec68f..edce0df036 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallParameterMetaData.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallParameterMetaData.java @@ -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 diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java index be0ef871bc..6676d9d8df 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java @@ -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: diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterBatchUpdateUtils.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterBatchUpdateUtils.java deleted file mode 100644 index 8678bfb811..0000000000 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterBatchUpdateUtils.java +++ /dev/null @@ -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; - } - }); - } - -} diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/DB2MainframeSequenceMaxValueIncrementer.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/DB2MainframeSequenceMaxValueIncrementer.java deleted file mode 100644 index de88a53593..0000000000 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/DB2MainframeSequenceMaxValueIncrementer.java +++ /dev/null @@ -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). - * - *

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"; - } - -} diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/DB2SequenceMaxValueIncrementer.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/DB2SequenceMaxValueIncrementer.java deleted file mode 100644 index bf6e1c9bfb..0000000000 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/DB2SequenceMaxValueIncrementer.java +++ /dev/null @@ -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). - * - *

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); - } - -} diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/PostgreSQLSequenceMaxValueIncrementer.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/PostgreSQLSequenceMaxValueIncrementer.java deleted file mode 100644 index 0d02917105..0000000000 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/PostgreSQLSequenceMaxValueIncrementer.java +++ /dev/null @@ -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. - * - *

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); - } - -} diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/PayloadArgumentResolver.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/PayloadArgumentResolver.java deleted file mode 100644 index e2829b10bc..0000000000 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/PayloadArgumentResolver.java +++ /dev/null @@ -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); - } - -} diff --git a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketFrameTypeMessageCondition.java b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketFrameTypeMessageCondition.java index b8e1f303e8..12ab2ead21 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketFrameTypeMessageCondition.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketFrameTypeMessageCondition.java @@ -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 frameTypeConditionCache; diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractMessageBrokerConfiguration.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractMessageBrokerConfiguration.java index c44ff26010..7c5cfed550 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractMessageBrokerConfiguration.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractMessageBrokerConfiguration.java @@ -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}. diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/config/ChannelRegistration.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/config/ChannelRegistration.java index 58a1a2f4e2..baaa9f8bbd 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/config/ChannelRegistration.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/config/ChannelRegistration.java @@ -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); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/DefaultUserDestinationResolver.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/DefaultUserDestinationResolver.java index 62729df07e..86e59e73c2 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/DefaultUserDestinationResolver.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/DefaultUserDestinationResolver.java @@ -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}. - *

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 diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInterceptor.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInterceptor.java index 26a3a70af9..a2016e8314 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInterceptor.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInterceptor.java @@ -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; } } diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java b/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java index 0f68a6ebcb..66971589a3 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java @@ -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); diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaSessionFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaSessionFactoryBean.java deleted file mode 100644 index b02e90d04f..0000000000 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaSessionFactoryBean.java +++ /dev/null @@ -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}. - * - *

Primarily available for resolving a SessionFactory by JPA persistence unit name - * via the {@link #setPersistenceUnitName "persistenceUnitName"} bean property. - * - *

Note that, for straightforward cases, you could also simply declare a factory method: - * - *

- * <bean id="sessionFactory" factory-bean="entityManagerFactory" factory-method="getSessionFactory"/>
- * 
- * - *

And as of JPA 2.1, {@link EntityManagerFactory#unwrap} provides a nice approach as well, - * in particular within configuration class arrangements: - * - *

- * @Bean
- * public SessionFactory sessionFactory(@Qualifier("entityManagerFactory") EntityManagerFactory emf) {
- *     return emf.unwrap(SessionFactory.class);
- * }
- * 
- * - * 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 { - - @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; - } - -} diff --git a/spring-test/src/main/java/org/springframework/mock/jndi/ExpectedLookupTemplate.java b/spring-test/src/main/java/org/springframework/mock/jndi/ExpectedLookupTemplate.java deleted file mode 100644 index c8887da9fd..0000000000 --- a/spring-test/src/main/java/org/springframework/mock/jndi/ExpectedLookupTemplate.java +++ /dev/null @@ -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. - * - *

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 Simple-JNDI - */ -@Deprecated -public class ExpectedLookupTemplate extends JndiTemplate { - - private final Map 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; - } - -} diff --git a/spring-test/src/main/java/org/springframework/mock/jndi/SimpleNamingContext.java b/spring-test/src/main/java/org/springframework/mock/jndi/SimpleNamingContext.java deleted file mode 100644 index 14c4881c80..0000000000 --- a/spring-test/src/main/java/org/springframework/mock/jndi/SimpleNamingContext.java +++ /dev/null @@ -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. - * - *

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 Simple-JNDI - */ -@Deprecated -public class SimpleNamingContext implements Context { - - private final Log logger = LogFactory.getLog(getClass()); - - private final String root; - - private final Hashtable boundObjects; - - private final Hashtable 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 boundObjects, @Nullable Hashtable env) { - - this.root = root; - this.boundObjects = boundObjects; - if (env != null) { - this.environment.putAll(env); - } - } - - - // Actual implementations of Context methods follow - - @Override - public NamingEnumeration list(String root) throws NamingException { - if (logger.isDebugEnabled()) { - logger.debug("Listing name/class pairs under [" + root + "]"); - } - return new NameClassPairEnumeration(this, root); - } - - @Override - public NamingEnumeration 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. - *

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 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 list(Name name) throws NamingException { - throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]"); - } - - @Override - public NamingEnumeration 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 implements NamingEnumeration { - - private final Iterator iterator; - - private AbstractNamingEnumeration(SimpleNamingContext context, String proot) throws NamingException { - if (!proot.isEmpty() && !proot.endsWith("/")) { - proot = proot + "/"; - } - String root = context.root + proot; - Map 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 { - - 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 { - - private BindingEnumeration(SimpleNamingContext context, String root) throws NamingException { - super(context, root); - } - - @Override - protected Binding createObject(String strippedName, Object obj) { - return new Binding(strippedName, obj); - } - } - -} diff --git a/spring-test/src/main/java/org/springframework/mock/jndi/SimpleNamingContextBuilder.java b/spring-test/src/main/java/org/springframework/mock/jndi/SimpleNamingContextBuilder.java deleted file mode 100644 index 802dcaf32c..0000000000 --- a/spring-test/src/main/java/org/springframework/mock/jndi/SimpleNamingContextBuilder.java +++ /dev/null @@ -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. - * - *

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. - * - *

There are various choices for DataSource implementations: - *

- * - *

Typical usage in bootstrap code: - * - *

- * SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
- * DataSource ds = new DriverManagerDataSource(...);
- * builder.bind("java:comp/env/jdbc/myds", ds);
- * builder.activate();
- * - * 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: - * - *
- * SimpleNamingContextBuilder builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder();
- * DataSource ds = new DriverManagerDataSource(...);
- * builder.bind("java:comp/env/jdbc/myds", ds);
- * - * Note that you should not call {@code activate()} on a builder from - * this factory method, as there will already be an activated one in any case. - * - *

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 Simple-JNDI - */ -@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. - *

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 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. - *

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) env); - } - -} diff --git a/spring-test/src/main/java/org/springframework/mock/jndi/package-info.java b/spring-test/src/main/java/org/springframework/mock/jndi/package-info.java deleted file mode 100644 index b2ec4eaaca..0000000000 --- a/spring-test/src/main/java/org/springframework/mock/jndi/package-info.java +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Deprecated as of Spring Framework 5.2 in favor of complete - * solutions from third parties such as - * Simple-JNDI. - * - *

The simplest implementation of the JNDI SPI that could possibly work. - * - *

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; diff --git a/spring-test/src/main/java/org/springframework/mock/web/reactive/function/server/MockServerRequest.java b/spring-test/src/main/java/org/springframework/mock/web/reactive/function/server/MockServerRequest.java index 26f874aa33..21440f4a07 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/reactive/function/server/MockServerRequest.java +++ b/spring-test/src/main/java/org/springframework/mock/web/reactive/function/server/MockServerRequest.java @@ -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"); diff --git a/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java b/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java deleted file mode 100644 index 6da1e6da85..0000000000 --- a/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java +++ /dev/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}. - * - *

Whereas {@code AnnotationUtils} provides utilities for getting or - * finding an annotation, {@code MetaAnnotationUtils} goes a step further - * by providing support for determining the root class on which an - * annotation is declared, either directly or indirectly via a composed - * annotation. This additional information is encapsulated in an - * {@link AnnotationDescriptor}. - * - *

The additional information provided by an {@code AnnotationDescriptor} is - * required by the Spring TestContext Framework 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 inherited - * 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. - *

This method explicitly handles class-level annotations which are not - * declared as {@linkplain java.lang.annotation.Inherited inherited} as - * well as meta-annotations. - *

The algorithm operates as follows: - *

    - *
  1. Search for the annotation on the given class and return a corresponding - * {@code AnnotationDescriptor} if found. - *
  2. Recursively search through all annotations that the given class declares. - *
  3. Recursively search through all interfaces implemented by the given class. - *
  4. Recursively search through the superclass hierarchy of the given class. - *
- *

In this context, the term recursively 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 AnnotationDescriptor findAnnotationDescriptor( - Class clazz, Class 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 - * visited. - * @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 AnnotationDescriptor findAnnotationDescriptor( - @Nullable Class clazz, Set visited, Class 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 composedType = composedAnn.annotationType(); - if (!AnnotationUtils.isInJavaLangAnnotationPackage(composedType.getName()) && visited.add(composedAnn)) { - AnnotationDescriptor 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 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}. - *

This method traverses the annotations, interfaces, and superclasses - * of the specified {@code clazz} if no annotation can be found on the given - * class itself. - *

This method explicitly handles class-level annotations which are not - * declared as {@linkplain java.lang.annotation.Inherited inherited} as - * well as meta-annotations. - *

The algorithm operates as follows: - *

    - *
  1. Search for a local declaration of one of the annotation types on - * the given class and return a corresponding {@code UntypedAnnotationDescriptor} - * if found. - *
  2. Recursively search through all annotations that the given class declares. - *
  3. Recursively search through all interfaces implemented by the given class. - *
  4. Recursively search through the superclass hierarchy of the given class. - *
- *

In this context, the term recursively 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... 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 - * visited. - * @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 visited, Class... annotationTypes) { - - assertNonEmptyAnnotationTypeArray(annotationTypes, "The list of annotation types must not be empty"); - if (clazz == null || Object.class == clazz) { - return null; - } - - // Declared locally? - for (Class 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 declared - * as well as the actual {@linkplain #getAnnotation() annotation} instance. - *

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 root declaring class is - * not directly annotated with the annotation but rather indirectly via the - * composed annotation. - *

Given the following example, if we are searching for the {@code @Transactional} - * annotation on the {@code TransactionalTests} class, then the - * properties of the {@code AnnotationDescriptor} would be as follows. - *

- *

-	 * @Transactional
-	 * @ContextConfiguration({"/test-datasource.xml", "/repository-config.xml"})
-	 * public class TransactionalTests { }
-	 * 
- *

Given the following example, if we are searching for the {@code @Transactional} - * annotation on the {@code UserRepositoryTests} class, then the - * properties of the {@code AnnotationDescriptor} would be as follows. - *

- *

-	 * @Transactional
-	 * @ContextConfiguration({"/test-datasource.xml", "/repository-config.xml"})
-	 * @Retention(RetentionPolicy.RUNTIME)
-	 * public @interface RepositoryTests { }
-	 *
-	 * @RepositoryTests
-	 * public class UserRepositoryTests { }
-	 * 
- * - * @param the annotation type - */ - public static class AnnotationDescriptor { - - 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) getAnnotationType(), getRootDeclaringClass()); - } - - public Class getAnnotationType() { - return this.annotation.annotationType(); - } - - public AnnotationAttributes getAnnotationAttributes() { - return this.annotationAttributes; - } - - @Nullable - public Annotation getComposedAnnotation() { - return this.composedAnnotation; - } - - @Nullable - public Class 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(); - } - } - - - /** - * Untyped 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 { - - 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"); - } - } - -} diff --git a/spring-test/src/main/java/org/springframework/test/web/client/AbstractRequestExpectationManager.java b/spring-test/src/main/java/org/springframework/test/web/client/AbstractRequestExpectationManager.java index bd57ec72fc..3796dc87ae 100644 --- a/spring-test/src/main/java/org/springframework/test/web/client/AbstractRequestExpectationManager.java +++ b/spring-test/src/main/java/org/springframework/test/web/client/AbstractRequestExpectationManager.java @@ -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 expectations) { - expectations.forEach(this::updateInternal); - } - /** * Reset all expectations for this group. */ diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockMvcRequestBuilders.java b/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockMvcRequestBuilders.java index c9e7dbc74c..07830ac327 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockMvcRequestBuilders.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockMvcRequestBuilders.java @@ -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 diff --git a/spring-test/src/test/java/org/springframework/mock/jndi/SimpleNamingContextTests.java b/spring-test/src/test/java/org/springframework/mock/jndi/SimpleNamingContextTests.java deleted file mode 100644 index 95b2a377be..0000000000 --- a/spring-test/src/test/java/org/springframework/mock/jndi/SimpleNamingContextTests.java +++ /dev/null @@ -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 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 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 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 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 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 unwrap(Class arg0) throws SQLException { - return null; - } - - @Override - public Logger getParentLogger() { - return null; - } - } - -} diff --git a/spring-test/src/test/java/org/springframework/test/util/MetaAnnotationUtilsTests.java b/spring-test/src/test/java/org/springframework/test/util/MetaAnnotationUtilsTests.java deleted file mode 100644 index 4fd375f8c3..0000000000 --- a/spring-test/src/test/java/org/springframework/test/util/MetaAnnotationUtilsTests.java +++ /dev/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 composedAnnotationType) { - - assertAtComponentOnComposedAnnotation(rootDeclaringClass, rootDeclaringClass, name, composedAnnotationType); - } - - private void assertAtComponentOnComposedAnnotation( - Class startClass, Class rootDeclaringClass, String name, Class composedAnnotationType) { - - assertAtComponentOnComposedAnnotation(startClass, rootDeclaringClass, composedAnnotationType, name, composedAnnotationType); - } - - private void assertAtComponentOnComposedAnnotation(Class startClass, Class rootDeclaringClass, - Class declaringClass, String name, Class composedAnnotationType) { - - AnnotationDescriptor 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 composedAnnotationType) { - - assertAtComponentOnComposedAnnotationForMultipleCandidateTypes( - startClass, startClass, name, composedAnnotationType); - } - - private void assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(Class startClass, - Class rootDeclaringClass, String name, Class composedAnnotationType) { - - assertAtComponentOnComposedAnnotationForMultipleCandidateTypes( - startClass, rootDeclaringClass, composedAnnotationType, name, composedAnnotationType); - } - - @SuppressWarnings("unchecked") - private void assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(Class startClass, - Class rootDeclaringClass, Class declaringClass, String name, - Class composedAnnotationType) { - - Class 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 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 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 annotationType = Component.class; - AnnotationDescriptor 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 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 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 startClass = MetaMetaAnnotatedClass.class; - assertAtComponentOnComposedAnnotation(startClass, startClass, Meta2.class, "meta2", MetaMeta.class); - } - - /** - * @since 4.0.3 - */ - @Test - void findAnnotationDescriptorOnMetaMetaMetaAnnotatedClass() { - Class 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 descriptor = findAnnotationDescriptor( - InheritedAnnotationClass.class, Component.class); - assertThat(descriptor).as("Should not find @Component on InheritedAnnotationClass").isNull(); - } - - /** - * @since 4.0.3 - */ - @Test - void findAnnotationDescriptorOnMetaCycleAnnotatedClassWithMissingTargetMetaAnnotation() { - AnnotationDescriptor 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 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 startClass = HasMetaComponentAnnotation.class; - assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(startClass, "meta1", Meta1.class); - } - - @Test - @SuppressWarnings("unchecked") - void findAnnotationDescriptorForTypesWithMetaAnnotationWithDefaultAttributes() { - Class startClass = MetaConfigWithDefaultAttributesTestCase.class; - Class 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 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 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 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 startClass = MetaMetaAnnotatedClass.class; - assertAtComponentOnComposedAnnotationForMultipleCandidateTypes( - startClass, startClass, Meta2.class, "meta2", MetaMeta.class); - } - - /** - * @since 4.0.3 - */ - @Test - void findAnnotationDescriptorForTypesOnMetaMetaMetaAnnotatedClass() { - Class 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 { - } - -} diff --git a/spring-test/src/test/java/org/springframework/test/util/OverriddenMetaAnnotationAttributesTests.java b/spring-test/src/test/java/org/springframework/test/util/OverriddenMetaAnnotationAttributesTests.java deleted file mode 100644 index e95d8a83d3..0000000000 --- a/spring-test/src/test/java/org/springframework/test/util/OverriddenMetaAnnotationAttributesTests.java +++ /dev/null @@ -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. - * - *

See SPR-10181. - * - * @author Sam Brannen - * @since 4.0 - * @see MetaAnnotationUtilsTests - */ -@SuppressWarnings("deprecation") -class OverriddenMetaAnnotationAttributesTests { - - @Test - void contextConfigurationValue() throws Exception { - Class declaringClass = MetaValueConfigTestCase.class; - AnnotationDescriptor 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 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 declaringClass = MetaLocationsConfigTestCase.class; - AnnotationDescriptor 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 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 { - } - -} diff --git a/spring-tx/src/main/java/org/springframework/transaction/reactive/TransactionContext.java b/spring-tx/src/main/java/org/springframework/transaction/reactive/TransactionContext.java index 280669b83f..3fe4ad088d 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/reactive/TransactionContext.java +++ b/spring-tx/src/main/java/org/springframework/transaction/reactive/TransactionContext.java @@ -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 contextId = SingletonSupplier.of(UUID::randomUUID); - private final Map 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 getResources() { return this.resources; } diff --git a/spring-web/src/main/java/org/springframework/http/client/support/BasicAuthorizationInterceptor.java b/spring-web/src/main/java/org/springframework/http/client/support/BasicAuthorizationInterceptor.java deleted file mode 100644 index 87936fb000..0000000000 --- a/spring-web/src/main/java/org/springframework/http/client/support/BasicAuthorizationInterceptor.java +++ /dev/null @@ -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); - } - -} diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java index 3a547e62c5..9be9d73ef7 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java @@ -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 diff --git a/spring-web/src/main/java/org/springframework/http/converter/protobuf/ExtensionRegistryInitializer.java b/spring-web/src/main/java/org/springframework/http/converter/protobuf/ExtensionRegistryInitializer.java deleted file mode 100644 index 9f11533c79..0000000000 --- a/spring-web/src/main/java/org/springframework/http/converter/protobuf/ExtensionRegistryInitializer.java +++ /dev/null @@ -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}. - * - *

This interface provides a facility to populate the {@code ExtensionRegistry}. - * - * @author Alex Antonov - * @author Sebastien Deleuze - * @since 4.1 - * @see - * com.google.protobuf.ExtensionRegistry - * @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); - -} diff --git a/spring-web/src/main/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverter.java index ba06466948..ec4ad27ee0 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverter.java @@ -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 implements ProcessorThe 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 diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpResponse.java index 5a0ee5aba5..3e6120e67a 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpResponse.java @@ -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) { diff --git a/spring-web/src/main/java/org/springframework/web/bind/annotation/CrossOrigin.java b/spring-web/src/main/java/org/springframework/web/bind/annotation/CrossOrigin.java index 0a568d25db..122c55d2e2 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/annotation/CrossOrigin.java +++ b/spring-web/src/main/java/org/springframework/web/bind/annotation/CrossOrigin.java @@ -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}. */ diff --git a/spring-web/src/main/java/org/springframework/web/bind/support/DefaultDataBinderFactory.java b/spring-web/src/main/java/org/springframework/web/bind/support/DefaultDataBinderFactory.java index c6482d8b46..abca503604 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/support/DefaultDataBinderFactory.java +++ b/spring-web/src/main/java/org/springframework/web/bind/support/DefaultDataBinderFactory.java @@ -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; diff --git a/spring-web/src/main/java/org/springframework/web/bind/support/WebBindingInitializer.java b/spring-web/src/main/java/org/springframework/web/bind/support/WebBindingInitializer.java index 58d5df5f73..a0048af1b3 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/support/WebBindingInitializer.java +++ b/spring-web/src/main/java/org/springframework/web/bind/support/WebBindingInitializer.java @@ -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); - } - } diff --git a/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java b/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java index 505c51fff6..70664a2e4c 100644 --- a/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java +++ b/spring-web/src/main/java/org/springframework/web/client/DefaultResponseErrorHandler.java @@ -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 diff --git a/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java b/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java index 3d1bcb5b0a..b38076727a 100644 --- a/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java +++ b/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java @@ -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 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}. - *

Note: 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) { diff --git a/spring-web/src/main/java/org/springframework/web/context/support/LiveBeansViewServlet.java b/spring-web/src/main/java/org/springframework/web/context/support/LiveBeansViewServlet.java deleted file mode 100644 index 0a500097f1..0000000000 --- a/spring-web/src/main/java/org/springframework/web/context/support/LiveBeansViewServlet.java +++ /dev/null @@ -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. - * - *

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); - } - -} diff --git a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextLiveBeansView.java b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextLiveBeansView.java deleted file mode 100644 index f8da1abc2d..0000000000 --- a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextLiveBeansView.java +++ /dev/null @@ -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 findApplicationContexts() { - Set contexts = new LinkedHashSet<>(); - Enumeration 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; - } - -} diff --git a/spring-web/src/main/java/org/springframework/web/filter/HttpPutFormContentFilter.java b/spring-web/src/main/java/org/springframework/web/filter/HttpPutFormContentFilter.java deleted file mode 100644 index 66745fc0cb..0000000000 --- a/spring-web/src/main/java/org/springframework/web/filter/HttpPutFormContentFilter.java +++ /dev/null @@ -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. - * - *

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. - *

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:
- * {@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 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 formParameters; - - public HttpPutFormContentRequestWrapper(HttpServletRequest request, MultiValueMap 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 getParameterMap() { - Map result = new LinkedHashMap<>(); - Enumeration names = getParameterNames(); - while (names.hasMoreElements()) { - String name = names.nextElement(); - result.put(name, getParameterValues(name)); - } - return result; - } - - @Override - public Enumeration getParameterNames() { - Set 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 formParam = this.formParameters.get(name); - if (formParam == null) { - return parameterValues; - } - if (parameterValues == null || getQueryString() == null) { - return StringUtils.toStringArray(formParam); - } - else { - List result = new ArrayList<>(parameterValues.length + formParam.size()); - result.addAll(Arrays.asList(parameterValues)); - result.addAll(formParam); - return StringUtils.toStringArray(result); - } - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/web/filter/reactive/ForwardedHeaderFilter.java b/spring-web/src/main/java/org/springframework/web/filter/reactive/ForwardedHeaderFilter.java deleted file mode 100644 index 85e7215b4e..0000000000 --- a/spring-web/src/main/java/org/springframework/web/filter/reactive/ForwardedHeaderFilter.java +++ /dev/null @@ -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. - * - *

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 https://tools.ietf.org/html/rfc7239 - * @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 filter(ServerWebExchange exchange, WebFilterChain chain) { - ServerHttpRequest request = exchange.getRequest(); - if (hasForwardedHeaders(request)) { - exchange = exchange.mutate().request(apply(request)).build(); - } - return chain.filter(exchange); - } - -} diff --git a/spring-web/src/main/java/org/springframework/web/server/MediaTypeNotSupportedStatusException.java b/spring-web/src/main/java/org/springframework/web/server/MediaTypeNotSupportedStatusException.java deleted file mode 100644 index 690e7a136b..0000000000 --- a/spring-web/src/main/java/org/springframework/web/server/MediaTypeNotSupportedStatusException.java +++ /dev/null @@ -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 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 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 getSupportedMediaTypes() { - return this.supportedMediaTypes; - } - -} diff --git a/spring-web/src/main/java/org/springframework/web/server/MethodNotAllowedException.java b/spring-web/src/main/java/org/springframework/web/server/MethodNotAllowedException.java index e6e78dd883..40f78ed70e 100644 --- a/spring-web/src/main/java/org/springframework/web/server/MethodNotAllowedException.java +++ b/spring-web/src/main/java/org/springframework/web/server/MethodNotAllowedException.java @@ -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 getHeaders() { - return getResponseHeaders().toSingleValueMap(); - } - /** * Return HttpHeaders with an "Allow" header. * @since 5.1.13 diff --git a/spring-web/src/main/java/org/springframework/web/server/NotAcceptableStatusException.java b/spring-web/src/main/java/org/springframework/web/server/NotAcceptableStatusException.java index 6045dbd516..7874fe1a2d 100644 --- a/spring-web/src/main/java/org/springframework/web/server/NotAcceptableStatusException.java +++ b/spring-web/src/main/java/org/springframework/web/server/NotAcceptableStatusException.java @@ -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 getHeaders() { - return getResponseHeaders().toSingleValueMap(); - } - /** * Return HttpHeaders with an "Accept" header, or an empty instance. * @since 5.1.13 diff --git a/spring-web/src/main/java/org/springframework/web/server/ResponseStatusException.java b/spring-web/src/main/java/org/springframework/web/server/ResponseStatusException.java index 73f41c48c7..9aefb13334 100644 --- a/spring-web/src/main/java/org/springframework/web/server/ResponseStatusException.java +++ b/spring-web/src/main/java/org/springframework/web/server/ResponseStatusException.java @@ -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. - *

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 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 headers = getHeaders(); - if (headers.isEmpty()) { - return HttpHeaders.EMPTY; - } - HttpHeaders result = new HttpHeaders(); - getHeaders().forEach(result::add); - return result; + return HttpHeaders.EMPTY; } /** diff --git a/spring-web/src/main/java/org/springframework/web/server/ServerErrorException.java b/spring-web/src/main/java/org/springframework/web/server/ServerErrorException.java index 8f994f81db..5e4a8d6353 100644 --- a/spring-web/src/main/java/org/springframework/web/server/ServerErrorException.java +++ b/spring-web/src/main/java/org/springframework/web/server/ServerErrorException.java @@ -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. diff --git a/spring-web/src/main/java/org/springframework/web/server/handler/DefaultWebFilterChain.java b/spring-web/src/main/java/org/springframework/web/server/handler/DefaultWebFilterChain.java index deca3c2e23..c255dd0688 100644 --- a/spring-web/src/main/java/org/springframework/web/server/handler/DefaultWebFilterChain.java +++ b/spring-web/src/main/java/org/springframework/web/server/handler/DefaultWebFilterChain.java @@ -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 getFilters() { return this.allFilters; diff --git a/spring-web/src/main/java/org/springframework/web/util/AbstractUriTemplateHandler.java b/spring-web/src/main/java/org/springframework/web/util/AbstractUriTemplateHandler.java deleted file mode 100644 index 19066ea4ad..0000000000 --- a/spring-web/src/main/java/org/springframework/web/util/AbstractUriTemplateHandler.java +++ /dev/null @@ -1,143 +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.web.util; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * Abstract base class for {@link UriTemplateHandler} implementations. - * - *

Support {@link #setBaseUrl} and {@link #setDefaultUriVariables} properties - * that should be relevant regardless of the URI template expand and encode - * mechanism used in sub-classes. - * - * @author Rossen Stoyanchev - * @since 4.3 - * @deprecated as of 5.0 in favor of {@link DefaultUriBuilderFactory} - */ -@Deprecated -public abstract class AbstractUriTemplateHandler implements UriTemplateHandler { - - @Nullable - private String baseUrl; - - private final Map defaultUriVariables = new HashMap<>(); - - - /** - * Configure a base URL to prepend URI templates with. The base URL must - * have a scheme and host but may optionally contain a port and a path. - * The base URL must be fully expanded and encoded which can be done via - * {@link UriComponentsBuilder}. - * @param baseUrl the base URL. - */ - public void setBaseUrl(@Nullable String baseUrl) { - if (baseUrl != null) { - UriComponents uriComponents = UriComponentsBuilder.fromUriString(baseUrl).build(); - Assert.hasText(uriComponents.getScheme(), "'baseUrl' must have a scheme"); - Assert.hasText(uriComponents.getHost(), "'baseUrl' must have a host"); - Assert.isNull(uriComponents.getQuery(), "'baseUrl' cannot have a query"); - Assert.isNull(uriComponents.getFragment(), "'baseUrl' cannot have a fragment"); - } - this.baseUrl = baseUrl; - } - - /** - * Return the configured base URL. - */ - @Nullable - public String getBaseUrl() { - return this.baseUrl; - } - - /** - * Configure default URI variable values to use with every expanded URI - * template. These default values apply only when expanding with a Map, and - * not with an array, where the Map supplied to {@link #expand(String, Map)} - * can override the default values. - * @param defaultUriVariables the default URI variable values - * @since 4.3 - */ - public void setDefaultUriVariables(@Nullable Map defaultUriVariables) { - this.defaultUriVariables.clear(); - if (defaultUriVariables != null) { - this.defaultUriVariables.putAll(defaultUriVariables); - } - } - - /** - * Return a read-only copy of the configured default URI variables. - */ - public Map getDefaultUriVariables() { - return Collections.unmodifiableMap(this.defaultUriVariables); - } - - - @Override - public URI expand(String uriTemplate, Map uriVariables) { - if (!getDefaultUriVariables().isEmpty()) { - Map map = new HashMap<>(); - map.putAll(getDefaultUriVariables()); - map.putAll(uriVariables); - uriVariables = map; - } - URI url = expandInternal(uriTemplate, uriVariables); - return insertBaseUrl(url); - } - - @Override - public URI expand(String uriTemplate, Object... uriVariables) { - URI url = expandInternal(uriTemplate, uriVariables); - return insertBaseUrl(url); - } - - - /** - * Actually expand and encode the URI template. - */ - protected abstract URI expandInternal(String uriTemplate, Map uriVariables); - - /** - * Actually expand and encode the URI template. - */ - protected abstract URI expandInternal(String uriTemplate, Object... uriVariables); - - - /** - * Insert a base URL (if configured) unless the given URL has a host already. - */ - private URI insertBaseUrl(URI url) { - try { - String baseUrl = getBaseUrl(); - if (baseUrl != null && url.getHost() == null) { - url = new URI(baseUrl + url.toString()); - } - return url; - } - catch (URISyntaxException ex) { - throw new IllegalArgumentException("Invalid URL after inserting base URL: " + url, ex); - } - } - -} diff --git a/spring-web/src/main/java/org/springframework/web/util/ContentCachingResponseWrapper.java b/spring-web/src/main/java/org/springframework/web/util/ContentCachingResponseWrapper.java index d7fdb0e0e2..ab13b1c88f 100644 --- a/spring-web/src/main/java/org/springframework/web/util/ContentCachingResponseWrapper.java +++ b/spring-web/src/main/java/org/springframework/web/util/ContentCachingResponseWrapper.java @@ -158,15 +158,6 @@ public class ContentCachingResponseWrapper extends HttpServletResponseWrapper { this.content.reset(); } - /** - * Return the status code as specified on the response. - * @deprecated as of 5.2 in favor of {@link HttpServletResponse#getStatus()} - */ - @Deprecated - public int getStatusCode() { - return getStatus(); - } - /** * Return the cached response content as a byte array. */ diff --git a/spring-web/src/main/java/org/springframework/web/util/DefaultUriTemplateHandler.java b/spring-web/src/main/java/org/springframework/web/util/DefaultUriTemplateHandler.java deleted file mode 100644 index 385608dc84..0000000000 --- a/spring-web/src/main/java/org/springframework/web/util/DefaultUriTemplateHandler.java +++ /dev/null @@ -1,158 +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.web.util; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.List; -import java.util.Map; - -/** - * Default implementation of {@link UriTemplateHandler} based on the use of - * {@link UriComponentsBuilder} for expanding and encoding variables. - * - *

There are also several properties to customize how URI template handling - * is performed, including a {@link #setBaseUrl baseUrl} to be used as a prefix - * for all URI templates and a couple of encoding related options — - * {@link #setParsePath parsePath} and {@link #setStrictEncoding strictEncoding} - * respectively. - * - * @author Rossen Stoyanchev - * @since 4.2 - * @deprecated as of 5.0 in favor of {@link DefaultUriBuilderFactory}. - *

Note: {@link DefaultUriBuilderFactory} has a different - * default for the {@link #setParsePath(boolean) parsePath} property (from - * false to true). - */ -@Deprecated -public class DefaultUriTemplateHandler extends AbstractUriTemplateHandler { - - private boolean parsePath; - - private boolean strictEncoding; - - - /** - * Whether to parse the path of a URI template string into path segments. - *

If set to {@code true} the URI template path is immediately decomposed - * into path segments any URI variables expanded into it are then subject to - * path segment encoding rules. In effect URI variables in the path have any - * "/" characters percent encoded. - *

By default this is set to {@code false} in which case the path is kept - * as a full path and expanded URI variables will preserve "/" characters. - * @param parsePath whether to parse the path into path segments - */ - public void setParsePath(boolean parsePath) { - this.parsePath = parsePath; - } - - /** - * Whether the handler is configured to parse the path into path segments. - */ - public boolean shouldParsePath() { - return this.parsePath; - } - - /** - * Whether to encode characters outside the unreserved set as defined in - * RFC 3986 Section 2. - * This ensures a URI variable value will not contain any characters with a - * reserved purpose. - *

By default this is set to {@code false} in which case only characters - * illegal for the given URI component are encoded. For example when expanding - * a URI variable into a path segment the "/" character is illegal and - * encoded. The ";" character however is legal and not encoded even though - * it has a reserved purpose. - *

Note: this property supersedes the need to also set - * the {@link #setParsePath parsePath} property. - * @param strictEncoding whether to perform strict encoding - * @since 4.3 - */ - public void setStrictEncoding(boolean strictEncoding) { - this.strictEncoding = strictEncoding; - } - - /** - * Whether to strictly encode any character outside the unreserved set. - */ - public boolean isStrictEncoding() { - return this.strictEncoding; - } - - - @Override - protected URI expandInternal(String uriTemplate, Map uriVariables) { - UriComponentsBuilder uriComponentsBuilder = initUriComponentsBuilder(uriTemplate); - UriComponents uriComponents = expandAndEncode(uriComponentsBuilder, uriVariables); - return createUri(uriComponents); - } - - @Override - protected URI expandInternal(String uriTemplate, Object... uriVariables) { - UriComponentsBuilder uriComponentsBuilder = initUriComponentsBuilder(uriTemplate); - UriComponents uriComponents = expandAndEncode(uriComponentsBuilder, uriVariables); - return createUri(uriComponents); - } - - /** - * Create a {@code UriComponentsBuilder} from the URI template string. - * This implementation also breaks up the path into path segments depending - * on whether {@link #setParsePath parsePath} is enabled. - */ - protected UriComponentsBuilder initUriComponentsBuilder(String uriTemplate) { - UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(uriTemplate); - if (shouldParsePath() && !isStrictEncoding()) { - List pathSegments = builder.build().getPathSegments(); - builder.replacePath(null); - for (String pathSegment : pathSegments) { - builder.pathSegment(pathSegment); - } - } - return builder; - } - - protected UriComponents expandAndEncode(UriComponentsBuilder builder, Map uriVariables) { - if (!isStrictEncoding()) { - return builder.buildAndExpand(uriVariables).encode(); - } - else { - Map encodedUriVars = UriUtils.encodeUriVariables(uriVariables); - return builder.buildAndExpand(encodedUriVars); - } - } - - protected UriComponents expandAndEncode(UriComponentsBuilder builder, Object[] uriVariables) { - if (!isStrictEncoding()) { - return builder.buildAndExpand(uriVariables).encode(); - } - else { - Object[] encodedUriVars = UriUtils.encodeUriVariables(uriVariables); - return builder.buildAndExpand(encodedUriVars); - } - } - - private URI createUri(UriComponents uriComponents) { - try { - // Avoid further encoding (in the case of strictEncoding=true) - return new URI(uriComponents.toUriString()); - } - catch (URISyntaxException ex) { - throw new IllegalStateException("Could not create URI object: " + ex.getMessage(), ex); - } - } - -} diff --git a/spring-web/src/test/java/org/springframework/http/client/support/BasicAuthorizationInterceptorTests.java b/spring-web/src/test/java/org/springframework/http/client/support/BasicAuthorizationInterceptorTests.java deleted file mode 100644 index 133051e077..0000000000 --- a/spring-web/src/test/java/org/springframework/http/client/support/BasicAuthorizationInterceptorTests.java +++ /dev/null @@ -1,76 +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.http.client.support; - -import java.net.URI; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.DirectFieldAccessor; -import org.springframework.http.HttpMethod; -import org.springframework.http.client.ClientHttpRequest; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.SimpleClientHttpRequestFactory; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -/** - * Tests for {@link BasicAuthorizationInterceptor}. - * - * @author Phillip Webb - * @author Stephane Nicoll - */ -@SuppressWarnings("deprecation") -public class BasicAuthorizationInterceptorTests { - - @Test - public void createWhenUsernameContainsColonShouldThrowException() { - assertThatIllegalArgumentException().isThrownBy(() -> - new BasicAuthorizationInterceptor("username:", "password")) - .withMessageContaining("Username must not contain a colon"); - } - - @Test - public void createWhenUsernameIsNullShouldUseEmptyUsername() throws Exception { - BasicAuthorizationInterceptor interceptor = new BasicAuthorizationInterceptor( - null, "password"); - assertThat(new DirectFieldAccessor(interceptor).getPropertyValue("username")).isEqualTo(""); - } - - @Test - public void createWhenPasswordIsNullShouldUseEmptyPassword() throws Exception { - BasicAuthorizationInterceptor interceptor = new BasicAuthorizationInterceptor( - "username", null); - assertThat(new DirectFieldAccessor(interceptor).getPropertyValue("password")).isEqualTo(""); - } - - @Test - public void interceptShouldAddHeader() throws Exception { - SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); - ClientHttpRequest request = requestFactory.createRequest(new URI("https://example.com"), HttpMethod.GET); - ClientHttpRequestExecution execution = mock(ClientHttpRequestExecution.class); - byte[] body = new byte[] {}; - new BasicAuthorizationInterceptor("spring", "boot").intercept(request, body, - execution); - verify(execution).execute(request, body); - assertThat(request.getHeaders().getFirst("Authorization")).isEqualTo("Basic c3ByaW5nOmJvb3Q="); - } - -} diff --git a/spring-web/src/test/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverterTests.java b/spring-web/src/test/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverterTests.java index 26106e13d3..6d89057ea8 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverterTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverterTests.java @@ -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,6 +18,7 @@ package org.springframework.http.converter.protobuf; import java.io.IOException; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import com.google.protobuf.ExtensionRegistry; import com.google.protobuf.Message; @@ -32,10 +33,7 @@ import org.springframework.protobuf.Msg; import org.springframework.protobuf.SecondMsg; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; /** * Test suite for {@link ProtobufHttpMessageConverter}. @@ -45,44 +43,23 @@ import static org.mockito.Mockito.verify; * @author Andreas Ahlenstorf * @author Sebastien Deleuze */ -@SuppressWarnings("deprecation") public class ProtobufHttpMessageConverterTests { private ProtobufHttpMessageConverter converter; private ExtensionRegistry extensionRegistry; - private ExtensionRegistryInitializer registryInitializer; - private Msg testMsg; @BeforeEach public void setup() { - this.registryInitializer = mock(ExtensionRegistryInitializer.class); this.extensionRegistry = mock(ExtensionRegistry.class); - this.converter = new ProtobufHttpMessageConverter(this.registryInitializer); + this.converter = new ProtobufHttpMessageConverter(); this.testMsg = Msg.newBuilder().setFoo("Foo").setBlah(SecondMsg.newBuilder().setBlah(123).build()).build(); } - @Test - public void extensionRegistryInitialized() { - verify(this.registryInitializer, times(1)).initializeExtensionRegistry(any()); - } - - @Test - public void extensionRegistryInitializerNull() { - ProtobufHttpMessageConverter converter = new ProtobufHttpMessageConverter((ExtensionRegistryInitializer)null); - assertThat(converter.extensionRegistry).isNotNull(); - } - - @Test - public void extensionRegistryNull() { - ProtobufHttpMessageConverter converter = new ProtobufHttpMessageConverter((ExtensionRegistry)null); - assertThat(converter.extensionRegistry).isNotNull(); - } - @Test public void canRead() { assertThat(this.converter.canRead(Msg.class, null)).isTrue(); @@ -175,7 +152,7 @@ public class ProtobufHttpMessageConverterTests { assertThat(outputMessage.getHeaders().getContentType()).isEqualTo(contentType); - final String body = outputMessage.getBodyAsString(Charset.forName("UTF-8")); + String body = outputMessage.getBodyAsString(StandardCharsets.UTF_8); assertThat(body.isEmpty()).as("body is empty").isFalse(); Msg.Builder builder = Msg.newBuilder(); @@ -189,12 +166,12 @@ public class ProtobufHttpMessageConverterTests { } @Test - public void defaultContentType() throws Exception { + public void defaultContentType() { assertThat(this.converter.getDefaultContentType(this.testMsg)).isEqualTo(ProtobufHttpMessageConverter.PROTOBUF); } @Test - public void getContentLength() throws Exception { + public void getContentLength() throws IOException { MockHttpOutputMessage outputMessage = new MockHttpOutputMessage(); MediaType contentType = ProtobufHttpMessageConverter.PROTOBUF; this.converter.write(this.testMsg, contentType, outputMessage); diff --git a/spring-web/src/test/java/org/springframework/http/converter/protobuf/ProtobufJsonFormatHttpMessageConverterTests.java b/spring-web/src/test/java/org/springframework/http/converter/protobuf/ProtobufJsonFormatHttpMessageConverterTests.java index 296efbd8b3..a2d549daab 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/protobuf/ProtobufJsonFormatHttpMessageConverterTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/protobuf/ProtobufJsonFormatHttpMessageConverterTests.java @@ -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.http.converter.protobuf; import java.io.IOException; -import com.google.protobuf.ExtensionRegistry; import com.google.protobuf.Message; import com.google.protobuf.util.JsonFormat; import org.junit.jupiter.api.Test; @@ -30,10 +29,6 @@ import org.springframework.protobuf.Msg; import org.springframework.protobuf.SecondMsg; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; /** * Test suite for {@link ProtobufJsonFormatHttpMessageConverter}. @@ -41,34 +36,14 @@ import static org.mockito.Mockito.verify; * @author Juergen Hoeller * @author Sebastien Deleuze */ -@SuppressWarnings("deprecation") public class ProtobufJsonFormatHttpMessageConverterTests { - private final ExtensionRegistryInitializer registryInitializer = mock(ExtensionRegistryInitializer.class); - private final ProtobufHttpMessageConverter converter = new ProtobufJsonFormatHttpMessageConverter( - JsonFormat.parser(), JsonFormat.printer(), this.registryInitializer); + JsonFormat.parser(), JsonFormat.printer()); private final Msg testMsg = Msg.newBuilder().setFoo("Foo").setBlah(SecondMsg.newBuilder().setBlah(123).build()).build(); - @Test - public void extensionRegistryInitialized() { - verify(this.registryInitializer, times(1)).initializeExtensionRegistry(any()); - } - - @Test - public void extensionRegistryInitializerNull() { - ProtobufHttpMessageConverter converter = new ProtobufHttpMessageConverter((ExtensionRegistryInitializer)null); - assertThat(converter).isNotNull(); - } - - @Test - public void extensionRegistryInitializer() { - ProtobufHttpMessageConverter converter = new ProtobufHttpMessageConverter((ExtensionRegistry)null); - assertThat(converter).isNotNull(); - } - @Test public void canRead() { assertThat(this.converter.canRead(Msg.class, null)).isTrue(); diff --git a/spring-web/src/test/java/org/springframework/web/cors/reactive/CorsUtilsTests.java b/spring-web/src/test/java/org/springframework/web/cors/reactive/CorsUtilsTests.java index 617655643d..7780a1f7f9 100644 --- a/spring-web/src/test/java/org/springframework/web/cors/reactive/CorsUtilsTests.java +++ b/spring-web/src/test/java/org/springframework/web/cors/reactive/CorsUtilsTests.java @@ -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,13 +16,11 @@ package org.springframework.web.cors.reactive; -import java.util.concurrent.atomic.AtomicReference; - import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; import org.springframework.http.HttpHeaders; import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.web.server.adapter.ForwardedHeaderTransformer; import org.springframework.web.testfixture.http.server.reactive.MockServerHttpRequest; import org.springframework.web.testfixture.server.MockServerWebExchange; @@ -32,6 +30,7 @@ import static org.springframework.web.testfixture.http.server.reactive.MockServe /** * Test case for reactive {@link CorsUtils}. + * * @author Sebastien Deleuze * @author Rossen Stoyanchev */ @@ -141,15 +140,9 @@ public class CorsUtilsTests { } // SPR-16668 - @SuppressWarnings("deprecation") private ServerHttpRequest adaptFromForwardedHeaders(MockServerHttpRequest.BaseBuilder builder) { - AtomicReference requestRef = new AtomicReference<>(); MockServerWebExchange exchange = MockServerWebExchange.from(builder); - new org.springframework.web.filter.reactive.ForwardedHeaderFilter().filter(exchange, exchange2 -> { - requestRef.set(exchange2.getRequest()); - return Mono.empty(); - }).block(); - return requestRef.get(); + return new ForwardedHeaderTransformer().apply(exchange.getRequest()); } } diff --git a/spring-web/src/test/java/org/springframework/web/server/adapter/WebHttpHandlerBuilderTests.java b/spring-web/src/test/java/org/springframework/web/server/adapter/WebHttpHandlerBuilderTests.java index 18c4dc8cc5..a5c36cf842 100644 --- a/spring-web/src/test/java/org/springframework/web/server/adapter/WebHttpHandlerBuilderTests.java +++ b/spring-web/src/test/java/org/springframework/web/server/adapter/WebHttpHandlerBuilderTests.java @@ -48,6 +48,7 @@ import static org.assertj.core.api.Assertions.assertThat; /** * Unit tests for {@link WebHttpHandlerBuilder}. + * * @author Rossen Stoyanchev */ public class WebHttpHandlerBuilderTests { @@ -73,7 +74,7 @@ public class WebHttpHandlerBuilderTests { @Test void forwardedHeaderTransformer() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - context.register(ForwardedHeaderFilterConfig.class); + context.register(ForwardedHeaderTransformerConfig.class); context.refresh(); WebHttpHandlerBuilder builder = WebHttpHandlerBuilder.applicationContext(context); @@ -199,7 +200,6 @@ public class WebHttpHandlerBuilderTests { @Configuration - @SuppressWarnings("unused") static class OrderedWebFilterBeanConfig { private static final String ATTRIBUTE = "attr"; @@ -234,7 +234,6 @@ public class WebHttpHandlerBuilderTests { @Configuration - @SuppressWarnings("unused") static class OrderedExceptionHandlerBeanConfig { @Bean @@ -256,13 +255,11 @@ public class WebHttpHandlerBuilderTests { } @Configuration - @SuppressWarnings("unused") - static class ForwardedHeaderFilterConfig { + static class ForwardedHeaderTransformerConfig { @Bean - @SuppressWarnings("deprecation") - public WebFilter forwardedHeaderFilter() { - return new org.springframework.web.filter.reactive.ForwardedHeaderFilter(); + public ForwardedHeaderTransformer forwardedHeaderTransformer() { + return new ForwardedHeaderTransformer(); } @Bean @@ -272,7 +269,6 @@ public class WebHttpHandlerBuilderTests { } @Configuration - @SuppressWarnings("unused") static class NoFilterConfig { @Bean diff --git a/spring-web/src/test/java/org/springframework/web/util/DefaultUriTemplateHandlerTests.java b/spring-web/src/test/java/org/springframework/web/util/DefaultUriTemplateHandlerTests.java deleted file mode 100644 index edb284c9c1..0000000000 --- a/spring-web/src/test/java/org/springframework/web/util/DefaultUriTemplateHandlerTests.java +++ /dev/null @@ -1,151 +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.web.util; - -import java.net.URI; -import java.util.HashMap; -import java.util.Map; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Unit tests for {@link DefaultUriTemplateHandler}. - * - * @author Rossen Stoyanchev - */ -@SuppressWarnings("deprecation") -public class DefaultUriTemplateHandlerTests { - - private final DefaultUriTemplateHandler handler = new DefaultUriTemplateHandler(); - - - @Test - public void baseUrlWithoutPath() throws Exception { - this.handler.setBaseUrl("http://localhost:8080"); - URI actual = this.handler.expand("/myapiresource"); - - assertThat(actual.toString()).isEqualTo("http://localhost:8080/myapiresource"); - } - - @Test - public void baseUrlWithPath() throws Exception { - this.handler.setBaseUrl("http://localhost:8080/context"); - URI actual = this.handler.expand("/myapiresource"); - - assertThat(actual.toString()).isEqualTo("http://localhost:8080/context/myapiresource"); - } - - @Test // SPR-14147 - public void defaultUriVariables() throws Exception { - Map defaultVars = new HashMap<>(2); - defaultVars.put("host", "api.example.com"); - defaultVars.put("port", "443"); - this.handler.setDefaultUriVariables(defaultVars); - - Map vars = new HashMap<>(1); - vars.put("id", 123L); - - String template = "https://{host}:{port}/v42/customers/{id}"; - URI actual = this.handler.expand(template, vars); - - assertThat(actual.toString()).isEqualTo("https://api.example.com:443/v42/customers/123"); - } - - @Test - public void parsePathIsOff() throws Exception { - this.handler.setParsePath(false); - Map vars = new HashMap<>(2); - vars.put("hotel", "1"); - vars.put("publicpath", "pics/logo.png"); - String template = "https://example.com/hotels/{hotel}/pic/{publicpath}"; - URI actual = this.handler.expand(template, vars); - - assertThat(actual.toString()).isEqualTo("https://example.com/hotels/1/pic/pics/logo.png"); - } - - @Test - public void parsePathIsOn() throws Exception { - this.handler.setParsePath(true); - Map vars = new HashMap<>(2); - vars.put("hotel", "1"); - vars.put("publicpath", "pics/logo.png"); - vars.put("scale", "150x150"); - String template = "https://example.com/hotels/{hotel}/pic/{publicpath}/size/{scale}"; - URI actual = this.handler.expand(template, vars); - - assertThat(actual.toString()).isEqualTo("https://example.com/hotels/1/pic/pics%2Flogo.png/size/150x150"); - } - - @Test - public void strictEncodingIsOffWithMap() throws Exception { - this.handler.setStrictEncoding(false); - Map vars = new HashMap<>(2); - vars.put("userId", "john;doe"); - String template = "https://www.example.com/user/{userId}/dashboard"; - URI actual = this.handler.expand(template, vars); - - assertThat(actual.toString()).isEqualTo("https://www.example.com/user/john;doe/dashboard"); - } - - @Test - public void strictEncodingOffWithArray() throws Exception { - this.handler.setStrictEncoding(false); - String template = "https://www.example.com/user/{userId}/dashboard"; - URI actual = this.handler.expand(template, "john;doe"); - - assertThat(actual.toString()).isEqualTo("https://www.example.com/user/john;doe/dashboard"); - } - - @Test - public void strictEncodingOnWithMap() throws Exception { - this.handler.setStrictEncoding(true); - Map vars = new HashMap<>(2); - vars.put("userId", "john;doe"); - String template = "https://www.example.com/user/{userId}/dashboard"; - URI actual = this.handler.expand(template, vars); - - assertThat(actual.toString()).isEqualTo("https://www.example.com/user/john%3Bdoe/dashboard"); - } - - @Test - public void strictEncodingOnWithArray() throws Exception { - this.handler.setStrictEncoding(true); - String template = "https://www.example.com/user/{userId}/dashboard"; - URI actual = this.handler.expand(template, "john;doe"); - - assertThat(actual.toString()).isEqualTo("https://www.example.com/user/john%3Bdoe/dashboard"); - } - - @Test // SPR-14147 - public void strictEncodingAndDefaultUriVariables() throws Exception { - Map defaultVars = new HashMap<>(1); - defaultVars.put("host", "www.example.com"); - this.handler.setDefaultUriVariables(defaultVars); - this.handler.setStrictEncoding(true); - - Map vars = new HashMap<>(1); - vars.put("userId", "john;doe"); - - String template = "https://{host}/user/{userId}/dashboard"; - URI actual = this.handler.expand(template, vars); - - assertThat(actual.toString()).isEqualTo("https://www.example.com/user/john%3Bdoe/dashboard"); - } - -} diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFilterFunctions.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFilterFunctions.java index 42ad43e22c..f79635e5fd 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFilterFunctions.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/ExchangeFilterFunctions.java @@ -43,11 +43,8 @@ public abstract class ExchangeFilterFunctions { /** * Name of the request attribute with {@link Credentials} for {@link #basicAuthentication()}. - * @deprecated as of Spring 5.1 in favor of using - * {@link HttpHeaders#setBasicAuth(String, String)} while building the request. */ - @Deprecated - public static final String BASIC_AUTHENTICATION_CREDENTIALS_ATTRIBUTE = + private static final String BASIC_AUTHENTICATION_CREDENTIALS_ATTRIBUTE = ExchangeFilterFunctions.class.getName() + ".basicAuthenticationCredentials"; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/AppCacheManifestTransformer.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/AppCacheManifestTransformer.java deleted file mode 100644 index 95fbce8734..0000000000 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/AppCacheManifestTransformer.java +++ /dev/null @@ -1,252 +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.reactive.resource; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.nio.CharBuffer; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Collection; -import java.util.Scanner; -import java.util.function.Consumer; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.Exceptions; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.core.publisher.SynchronousSink; - -import org.springframework.core.io.Resource; -import org.springframework.core.io.buffer.DataBuffer; -import org.springframework.core.io.buffer.DataBufferFactory; -import org.springframework.core.io.buffer.DataBufferUtils; -import org.springframework.lang.Nullable; -import org.springframework.util.DigestUtils; -import org.springframework.util.StreamUtils; -import org.springframework.util.StringUtils; -import org.springframework.web.server.ServerWebExchange; - -/** - * A {@link ResourceTransformer} HTML5 AppCache manifests. - * - *

This transformer: - *

    - *
  • modifies links to match the public URL paths that should be exposed to - * clients, using configured {@code ResourceResolver} strategies - *
  • appends a comment in the manifest, containing a Hash - * (e.g. "# Hash: 9de0f09ed7caf84e885f1f0f11c7e326"), thus changing the content - * of the manifest in order to trigger an appcache reload in the browser. - *
- * - *

All files with an ".appcache" file extension (or the extension given - * to the constructor) will be transformed by this class. The hash is computed - * using the content of the appcache manifest so that changes in the manifest - * should invalidate the browser cache. This should also work with changes in - * referenced resources whose links are also versioned. - * - * @author Rossen Stoyanchev - * @author Brian Clozel - * @since 5.0 - * @see HTML5 offline applications spec - * @deprecated as of 5.3 since browser support is going away - */ -@Deprecated -public class AppCacheManifestTransformer extends ResourceTransformerSupport { - - private static final String MANIFEST_HEADER = "CACHE MANIFEST"; - - private static final String CACHE_HEADER = "CACHE:"; - - private static final Collection MANIFEST_SECTION_HEADERS = - Arrays.asList(MANIFEST_HEADER, "NETWORK:", "FALLBACK:", CACHE_HEADER); - - private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; - - private static final Log logger = LogFactory.getLog(AppCacheManifestTransformer.class); - - - private final String fileExtension; - - - /** - * Create an AppCacheResourceTransformer that transforms files with extension ".appcache". - */ - public AppCacheManifestTransformer() { - this("appcache"); - } - - /** - * Create an AppCacheResourceTransformer that transforms files with the extension - * given as a parameter. - */ - public AppCacheManifestTransformer(String fileExtension) { - this.fileExtension = fileExtension; - } - - - @Override - public Mono transform(ServerWebExchange exchange, Resource inputResource, - ResourceTransformerChain chain) { - - return chain.transform(exchange, inputResource) - .flatMap(outputResource -> { - String name = outputResource.getFilename(); - if (!this.fileExtension.equals(StringUtils.getFilenameExtension(name))) { - return Mono.just(outputResource); - } - DataBufferFactory bufferFactory = exchange.getResponse().bufferFactory(); - Flux flux = DataBufferUtils - .read(outputResource, bufferFactory, StreamUtils.BUFFER_SIZE); - return DataBufferUtils.join(flux) - .flatMap(dataBuffer -> { - CharBuffer charBuffer = DEFAULT_CHARSET.decode(dataBuffer.asByteBuffer()); - DataBufferUtils.release(dataBuffer); - String content = charBuffer.toString(); - return transform(content, outputResource, chain, exchange); - }); - }); - } - - private Mono transform(String content, Resource resource, - ResourceTransformerChain chain, ServerWebExchange exchange) { - - if (!content.startsWith(MANIFEST_HEADER)) { - if (logger.isTraceEnabled()) { - logger.trace(exchange.getLogPrefix() + - "Skipping " + resource + ": Manifest does not start with 'CACHE MANIFEST'"); - } - return Mono.just(resource); - } - return Flux.generate(new LineInfoGenerator(content)) - .concatMap(info -> processLine(info, exchange, resource, chain)) - .reduce(new ByteArrayOutputStream(), (out, line) -> { - writeToByteArrayOutputStream(out, line + "\n"); - return out; - }) - .map(out -> { - String hash = DigestUtils.md5DigestAsHex(out.toByteArray()); - writeToByteArrayOutputStream(out, "\n" + "# Hash: " + hash); - return new TransformedResource(resource, out.toByteArray()); - }); - } - - private static void writeToByteArrayOutputStream(ByteArrayOutputStream out, String toWrite) { - try { - byte[] bytes = toWrite.getBytes(DEFAULT_CHARSET); - out.write(bytes); - } - catch (IOException ex) { - throw Exceptions.propagate(ex); - } - } - - private Mono processLine(LineInfo info, ServerWebExchange exchange, - Resource resource, ResourceTransformerChain chain) { - - if (!info.isLink()) { - return Mono.just(info.getLine()); - } - - String link = toAbsolutePath(info.getLine(), exchange); - return resolveUrlPath(link, exchange, resource, chain); - } - - - private static class LineInfoGenerator implements Consumer> { - - private final Scanner scanner; - - @Nullable - private LineInfo previous; - - - LineInfoGenerator(String content) { - this.scanner = new Scanner(content); - } - - - @Override - public void accept(SynchronousSink sink) { - if (this.scanner.hasNext()) { - String line = this.scanner.nextLine(); - LineInfo current = new LineInfo(line, this.previous); - sink.next(current); - this.previous = current; - } - else { - sink.complete(); - } - } - } - - - private static class LineInfo { - - private final String line; - - private final boolean cacheSection; - - private final boolean link; - - - LineInfo(String line, @Nullable LineInfo previousLine) { - this.line = line; - this.cacheSection = initCacheSectionFlag(line, previousLine); - this.link = iniLinkFlag(line, this.cacheSection); - } - - - private static boolean initCacheSectionFlag(String line, @Nullable LineInfo previousLine) { - String trimmedLine = line.trim(); - if (MANIFEST_SECTION_HEADERS.contains(trimmedLine)) { - return trimmedLine.equals(CACHE_HEADER); - } - else if (previousLine != null) { - return previousLine.isCacheSection(); - } - throw new IllegalStateException( - "Manifest does not start with " + MANIFEST_HEADER + ": " + line); - } - - private static boolean iniLinkFlag(String line, boolean isCacheSection) { - return (isCacheSection && StringUtils.hasText(line) && !line.startsWith("#") - && !line.startsWith("//") && !hasScheme(line)); - } - - private static boolean hasScheme(String line) { - int index = line.indexOf(':'); - return (line.startsWith("//") || (index > 0 && !line.substring(0, index).contains("/"))); - } - - - public String getLine() { - return this.line; - } - - public boolean isCacheSection() { - return this.cacheSection; - } - - public boolean isLink() { - return this.link; - } - } - -} diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/CssLinkResourceTransformer.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/CssLinkResourceTransformer.java index ab0dfd4c6c..0e0e36c433 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/CssLinkResourceTransformer.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/CssLinkResourceTransformer.java @@ -79,8 +79,7 @@ public class CssLinkResourceTransformer extends ResourceTransformerSupport { .flatMap(outputResource -> { String filename = outputResource.getFilename(); if (!"css".equals(StringUtils.getFilenameExtension(filename)) || - inputResource instanceof EncodedResourceResolver.EncodedResource || - inputResource instanceof GzipResourceResolver.GzippedResource) { + inputResource instanceof EncodedResourceResolver.EncodedResource) { return Mono.just(outputResource); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/GzipResourceResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/GzipResourceResolver.java deleted file mode 100644 index 74a7a628bb..0000000000 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/GzipResourceResolver.java +++ /dev/null @@ -1,173 +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.web.reactive.resource; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.net.URL; -import java.util.List; - -import reactor.core.publisher.Mono; - -import org.springframework.core.io.AbstractResource; -import org.springframework.core.io.Resource; -import org.springframework.http.HttpHeaders; -import org.springframework.lang.Nullable; -import org.springframework.web.server.ServerWebExchange; - -/** - * A {@code ResourceResolver} that delegates to the chain to locate a resource - * and then attempts to find a variation with the ".gz" extension. - * - *

The resolver gets involved only if the "Accept-Encoding" request header - * contains the value "gzip" indicating the client accepts gzipped responses. - * - * @author Rossen Stoyanchev - * @since 5.0 - * @deprecated as of 5.1, in favor of using {@link EncodedResourceResolver} - */ -@Deprecated -public class GzipResourceResolver extends AbstractResourceResolver { - - @Override - protected Mono resolveResourceInternal(@Nullable ServerWebExchange exchange, - String requestPath, List locations, ResourceResolverChain chain) { - - return chain.resolveResource(exchange, requestPath, locations) - .map(resource -> { - if (exchange == null || isGzipAccepted(exchange)) { - try { - Resource gzipped = new GzippedResource(resource); - if (gzipped.exists()) { - resource = gzipped; - } - } - catch (IOException ex) { - String logPrefix = exchange != null ? exchange.getLogPrefix() : ""; - logger.trace(logPrefix + "No gzip resource for [" + resource.getFilename() + "]", ex); - } - } - return resource; - }); - } - - private boolean isGzipAccepted(ServerWebExchange exchange) { - String value = exchange.getRequest().getHeaders().getFirst("Accept-Encoding"); - return (value != null && value.toLowerCase().contains("gzip")); - } - - @Override - protected Mono resolveUrlPathInternal(String resourceUrlPath, - List locations, ResourceResolverChain chain) { - - return chain.resolveUrlPath(resourceUrlPath, locations); - } - - - /** - * A gzipped {@link HttpResource}. - */ - static final class GzippedResource extends AbstractResource implements HttpResource { - - private final Resource original; - - private final Resource gzipped; - - public GzippedResource(Resource original) throws IOException { - this.original = original; - this.gzipped = original.createRelative(original.getFilename() + ".gz"); - } - - @Override - public InputStream getInputStream() throws IOException { - return this.gzipped.getInputStream(); - } - - @Override - public boolean exists() { - return this.gzipped.exists(); - } - - @Override - public boolean isReadable() { - return this.gzipped.isReadable(); - } - - @Override - public boolean isOpen() { - return this.gzipped.isOpen(); - } - - @Override - public boolean isFile() { - return this.gzipped.isFile(); - } - - @Override - public URL getURL() throws IOException { - return this.gzipped.getURL(); - } - - @Override - public URI getURI() throws IOException { - return this.gzipped.getURI(); - } - - @Override - public File getFile() throws IOException { - return this.gzipped.getFile(); - } - - @Override - public long contentLength() throws IOException { - return this.gzipped.contentLength(); - } - - @Override - public long lastModified() throws IOException { - return this.gzipped.lastModified(); - } - - @Override - public Resource createRelative(String relativePath) throws IOException { - return this.gzipped.createRelative(relativePath); - } - - @Override - @Nullable - public String getFilename() { - return this.original.getFilename(); - } - - @Override - public String getDescription() { - return this.gzipped.getDescription(); - } - - @Override - public HttpHeaders getResponseHeaders() { - HttpHeaders headers = (this.original instanceof HttpResource ? - ((HttpResource) this.original).getResponseHeaders() : new HttpHeaders()); - headers.add(HttpHeaders.CONTENT_ENCODING, "gzip"); - headers.add(HttpHeaders.VARY, HttpHeaders.ACCEPT_ENCODING); - return headers; - } - } - -} diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/AbstractView.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/AbstractView.java index 4090982ae6..5e88cd487e 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/AbstractView.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/AbstractView.java @@ -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. @@ -230,9 +230,7 @@ public abstract class AbstractView implements View, BeanNameAware, ApplicationCo attributes = new ConcurrentHashMap<>(0); } - //noinspection deprecation - return resolveAsyncAttributes(attributes) - .then(resolveAsyncAttributes(attributes, exchange)) + return resolveAsyncAttributes(attributes, exchange) .doOnTerminate(() -> exchange.getAttributes().remove(BINDING_CONTEXT_ATTRIBUTE)) .thenReturn(attributes); } @@ -293,22 +291,6 @@ public abstract class AbstractView implements View, BeanNameAware, ApplicationCo model.put(BindingResult.MODEL_KEY_PREFIX + name, result); } - /** - * Use the configured {@link ReactiveAdapterRegistry} to adapt asynchronous - * attributes to {@code Mono} or {@code Mono>} and then wait to - * resolve them into actual values. When the returned {@code Mono} - * completes, the asynchronous attributes in the model would have been - * replaced with their corresponding resolved values. - * @return result {@code Mono} that completes when the model is ready - * @deprecated as of 5.1.8 this method is still invoked but it is a no-op. - * Please use {@link #resolveAsyncAttributes(Map, ServerWebExchange)} - * instead. It is invoked after this one and does the actual work. - */ - @Deprecated - protected Mono resolveAsyncAttributes(Map model) { - return Mono.empty(); - } - /** * Create a {@link RequestContext} to expose under the * {@linkplain #setRequestContextAttribute specified attribute name}. diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/RequestUpgradeStrategy.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/RequestUpgradeStrategy.java index a50fe279ec..059e52376d 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/RequestUpgradeStrategy.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/server/RequestUpgradeStrategy.java @@ -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. @@ -41,23 +41,6 @@ import org.springframework.web.server.ServerWebExchange; */ public interface RequestUpgradeStrategy { - /** - * Upgrade to a WebSocket session and handle it with the given handler. - * @param exchange the current exchange - * @param webSocketHandler handler for the WebSocket session - * @param subProtocol the selected sub-protocol got the handler - * @return completion {@code Mono} to indicate the outcome of the - * WebSocket session handling. - * @deprecated as of 5.1 in favor of - * {@link #upgrade(ServerWebExchange, WebSocketHandler, String, Supplier)} - */ - @Deprecated - default Mono upgrade(ServerWebExchange exchange, WebSocketHandler webSocketHandler, - @Nullable String subProtocol) { - - return Mono.error(new UnsupportedOperationException()); - } - /** * Upgrade to a WebSocket session and handle it with the given handler. * @param exchange the current exchange @@ -68,10 +51,7 @@ public interface RequestUpgradeStrategy { * WebSocket session handling. * @since 5.1 */ - default Mono upgrade(ServerWebExchange exchange, WebSocketHandler webSocketHandler, - @Nullable String subProtocol, Supplier handshakeInfoFactory) { - - return upgrade(exchange, webSocketHandler, subProtocol); - } + Mono upgrade(ServerWebExchange exchange, WebSocketHandler webSocketHandler, + @Nullable String subProtocol, Supplier handshakeInfoFactory); } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/config/ResourceHandlerRegistryTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/config/ResourceHandlerRegistryTests.java index 21b493829d..64934cf08c 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/config/ResourceHandlerRegistryTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/config/ResourceHandlerRegistryTests.java @@ -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. @@ -165,14 +165,12 @@ class ResourceHandlerRegistryTests { } @Test - @SuppressWarnings("deprecation") void resourceChainWithVersionResolver() { VersionResourceResolver versionResolver = new VersionResourceResolver() .addFixedVersionStrategy("fixed", "/**/*.js") .addContentVersionStrategy("/**"); - this.registration.resourceChain(true).addResolver(versionResolver) - .addTransformer(new org.springframework.web.reactive.resource.AppCacheManifestTransformer()); + this.registration.resourceChain(true).addResolver(versionResolver); ResourceWebHandler handler = getHandler("/resources/**"); List resolvers = handler.getResourceResolvers(); @@ -183,10 +181,9 @@ class ResourceHandlerRegistryTests { assertThat(resolvers.get(3)).isInstanceOf(PathResourceResolver.class); List transformers = handler.getResourceTransformers(); - assertThat(transformers).hasSize(3); + assertThat(transformers).hasSize(2); assertThat(transformers.get(0)).isInstanceOf(CachingResourceTransformer.class); assertThat(transformers.get(1)).isInstanceOf(CssLinkResourceTransformer.class); - assertThat(transformers.get(2)).isInstanceOf(org.springframework.web.reactive.resource.AppCacheManifestTransformer.class); } @Test @@ -197,8 +194,6 @@ class ResourceHandlerRegistryTests { WebJarsResourceResolver webjarsResolver = Mockito.mock(WebJarsResourceResolver.class); PathResourceResolver pathResourceResolver = new PathResourceResolver(); CachingResourceTransformer cachingTransformer = Mockito.mock(CachingResourceTransformer.class); - org.springframework.web.reactive.resource.AppCacheManifestTransformer appCacheTransformer = - Mockito.mock(org.springframework.web.reactive.resource.AppCacheManifestTransformer.class); CssLinkResourceTransformer cssLinkTransformer = new CssLinkResourceTransformer(); this.registration.setCacheControl(CacheControl.maxAge(3600, TimeUnit.MILLISECONDS)) @@ -208,7 +203,6 @@ class ResourceHandlerRegistryTests { .addResolver(webjarsResolver) .addResolver(pathResourceResolver) .addTransformer(cachingTransformer) - .addTransformer(appCacheTransformer) .addTransformer(cssLinkTransformer); ResourceWebHandler handler = getHandler("/resources/**"); @@ -220,10 +214,9 @@ class ResourceHandlerRegistryTests { assertThat(resolvers.get(3)).isSameAs(pathResourceResolver); List transformers = handler.getResourceTransformers(); - assertThat(transformers).hasSize(3); + assertThat(transformers).hasSize(2); assertThat(transformers.get(0)).isSameAs(cachingTransformer); - assertThat(transformers.get(1)).isSameAs(appCacheTransformer); - assertThat(transformers.get(2)).isSameAs(cssLinkTransformer); + assertThat(transformers.get(1)).isSameAs(cssLinkTransformer); } @Test diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/resource/AppCacheManifestTransformerTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/resource/AppCacheManifestTransformerTests.java deleted file mode 100644 index 24ce532e49..0000000000 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/resource/AppCacheManifestTransformerTests.java +++ /dev/null @@ -1,123 +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.reactive.resource; - -import java.time.Duration; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; -import org.springframework.util.FileCopyUtils; -import org.springframework.web.testfixture.server.MockServerWebExchange; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.web.testfixture.http.server.reactive.MockServerHttpRequest.get; - -/** - * Unit tests for {@link AppCacheManifestTransformer}. - * @author Rossen Stoyanchev - * @author Brian Clozel - */ -@SuppressWarnings("deprecation") -public class AppCacheManifestTransformerTests { - - private static final Duration TIMEOUT = Duration.ofSeconds(5); - - - private final AppCacheManifestTransformer transformer = new AppCacheManifestTransformer(); - - private ResourceTransformerChain chain; - - - @BeforeEach - public void setup() { - VersionResourceResolver versionResolver = new VersionResourceResolver(); - versionResolver.setStrategyMap(Collections.singletonMap("/**", new ContentVersionStrategy())); - List resolvers = new ArrayList<>(); - resolvers.add(versionResolver); - resolvers.add(new PathResourceResolver()); - ResourceResolverChain resolverChain = new DefaultResourceResolverChain(resolvers); - - this.chain = new DefaultResourceTransformerChain(resolverChain, Collections.emptyList()); - this.transformer.setResourceUrlProvider(createUrlProvider(resolvers)); - } - - private ResourceUrlProvider createUrlProvider(List resolvers) { - ResourceWebHandler handler = new ResourceWebHandler(); - handler.setLocations(Collections.singletonList(new ClassPathResource("test/", getClass()))); - handler.setResourceResolvers(resolvers); - - ResourceUrlProvider urlProvider = new ResourceUrlProvider(); - urlProvider.registerHandlers(Collections.singletonMap("/static/**", handler)); - return urlProvider; - } - - - @Test - public void noTransformIfExtensionDoesNotMatch() { - MockServerWebExchange exchange = MockServerWebExchange.from(get("/static/foo.css")); - Resource expected = getResource("foo.css"); - Resource actual = this.transformer.transform(exchange, expected, this.chain).block(TIMEOUT); - - assertThat(actual).isSameAs(expected); - } - - @Test - public void syntaxErrorInManifest() { - MockServerWebExchange exchange = MockServerWebExchange.from(get("/static/error.appcache")); - Resource expected = getResource("error.appcache"); - Resource actual = this.transformer.transform(exchange, expected, this.chain).block(TIMEOUT); - - assertThat(actual).isEqualTo(expected); - } - - @Test - public void transformManifest() throws Exception { - MockServerWebExchange exchange = MockServerWebExchange.from(get("/static/test.appcache")); - Resource resource = getResource("test.appcache"); - Resource actual = this.transformer.transform(exchange, resource, this.chain).block(TIMEOUT); - - assertThat(actual).isNotNull(); - byte[] bytes = FileCopyUtils.copyToByteArray(actual.getInputStream()); - String content = new String(bytes, "UTF-8"); - - assertThat(content).as("rewrite resource links") - .contains("/static/foo-e36d2e05253c6c7085a91522ce43a0b4.css") - .contains("/static/bar-11e16cf79faee7ac698c805cf28248d2.css") - .contains("/static/js/bar-bd508c62235b832d960298ca6c0b7645.js"); - - assertThat(content).as("not rewrite external resources") - .contains("//example.org/style.css") - .contains("https://example.org/image.png"); - - // Not the same hash as Spring MVC - // Hash is computed from links, and not from the linked content - - assertThat(content).as("generate fingerprint") - .contains("# Hash: d4437f1d7ae9530ab3ae71d5375b46ff"); - } - - private Resource getResource(String filePath) { - return new ClassPathResource("test/" + filePath, getClass()); - } - -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerMappingIntrospector.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerMappingIntrospector.java index 76d90f320b..a10055bfa8 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerMappingIntrospector.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerMappingIntrospector.java @@ -85,32 +85,6 @@ public class HandlerMappingIntrospector private Map pathPatternHandlerMappings = Collections.emptyMap(); - /** - * Constructor for use with {@link ApplicationContextAware}. - */ - public HandlerMappingIntrospector() { - } - - /** - * Constructor that detects the configured {@code HandlerMapping}s in the - * given {@code ApplicationContext} or falls back on - * "DispatcherServlet.properties" like the {@code DispatcherServlet}. - * @deprecated as of 4.3.12, in favor of {@link #setApplicationContext} - */ - @Deprecated - public HandlerMappingIntrospector(ApplicationContext context) { - this.handlerMappings = initHandlerMappings(context); - } - - - /** - * Return the configured or detected {@code HandlerMapping}s. - */ - public List getHandlerMappings() { - return (this.handlerMappings != null ? this.handlerMappings : Collections.emptyList()); - } - - @Override public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; @@ -125,6 +99,13 @@ public class HandlerMappingIntrospector } } + /** + * Return the configured or detected {@code HandlerMapping}s. + */ + public List getHandlerMappings() { + return (this.handlerMappings != null ? this.handlerMappings : Collections.emptyList()); + } + /** * Find the {@link HandlerMapping} that would handle the given request and diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/LocaleChangeInterceptor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/LocaleChangeInterceptor.java index 6f118374a2..93996c9b94 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/LocaleChangeInterceptor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/LocaleChangeInterceptor.java @@ -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. @@ -108,34 +108,6 @@ public class LocaleChangeInterceptor implements HandlerInterceptor { return this.ignoreInvalidLocale; } - /** - * Specify whether to parse request parameter values as BCP 47 language tags - * instead of Java's legacy locale specification format. - *

NOTE: As of 5.1, this resolver leniently accepts the legacy - * {@link Locale#toString} format as well as BCP 47 language tags. - * @since 4.3 - * @see Locale#forLanguageTag(String) - * @see Locale#toLanguageTag() - * @deprecated as of 5.1 since it only accepts {@code true} now - */ - @Deprecated - public void setLanguageTagCompliant(boolean languageTagCompliant) { - if (!languageTagCompliant) { - throw new IllegalArgumentException("LocaleChangeInterceptor always accepts BCP 47 language tags"); - } - } - - /** - * Return whether to use BCP 47 language tags instead of Java's legacy - * locale specification format. - * @since 4.3 - * @deprecated as of 5.1 since it always returns {@code true} now - */ - @Deprecated - public boolean isLanguageTagCompliant() { - return true; - } - @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/AppCacheManifestTransformer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/AppCacheManifestTransformer.java deleted file mode 100644 index 4c0d9b4d3b..0000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/AppCacheManifestTransformer.java +++ /dev/null @@ -1,259 +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.servlet.resource; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.StringWriter; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Scanner; - -import jakarta.servlet.http.HttpServletRequest; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.core.io.Resource; -import org.springframework.lang.Nullable; -import org.springframework.util.DigestUtils; -import org.springframework.util.FileCopyUtils; -import org.springframework.util.StringUtils; - -/** - * A {@link ResourceTransformer} implementation that helps handling resources - * within HTML5 AppCache manifests for HTML5 offline applications. - * - *

This transformer: - *

    - *
  • modifies links to match the public URL paths that should be exposed to clients, - * using configured {@code ResourceResolver} strategies - *
  • appends a comment in the manifest, containing a Hash (e.g. "# Hash: 9de0f09ed7caf84e885f1f0f11c7e326"), - * thus changing the content of the manifest in order to trigger an appcache reload in the browser. - *
- * - *

All files that have the ".appcache" file extension, or the extension given in the constructor, - * will be transformed by this class. This hash is computed using the content of the appcache manifest - * and the content of the linked resources; so changing a resource linked in the manifest - * or the manifest itself should invalidate the browser cache. - * - *

In order to serve manifest files with the proper {@code "text/manifest"} content type, - * it is required to configure it with - * {@code contentNegotiationConfigurer.mediaType("appcache", MediaType.valueOf("text/manifest")} - * in a {@code WebMvcConfigurer}. - * - * @author Brian Clozel - * @since 4.1 - * @see HTML5 offline applications spec - * @deprecated as of 5.3 since browser support is going away - */ -@Deprecated -public class AppCacheManifestTransformer extends ResourceTransformerSupport { - - private static final String MANIFEST_HEADER = "CACHE MANIFEST"; - - private static final String CACHE_HEADER = "CACHE:"; - - private static final Collection MANIFEST_SECTION_HEADERS = - Arrays.asList(MANIFEST_HEADER, "NETWORK:", "FALLBACK:", CACHE_HEADER); - - private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; - - private static final Log logger = LogFactory.getLog(AppCacheManifestTransformer.class); - - - private final String fileExtension; - - - /** - * Create an AppCacheResourceTransformer that transforms files with extension ".appcache". - */ - public AppCacheManifestTransformer() { - this("appcache"); - } - - /** - * Create an AppCacheResourceTransformer that transforms files with the extension - * given as a parameter. - */ - public AppCacheManifestTransformer(String fileExtension) { - this.fileExtension = fileExtension; - } - - - @Override - public Resource transform(HttpServletRequest request, Resource resource, - ResourceTransformerChain chain) throws IOException { - - resource = chain.transform(request, resource); - if (!this.fileExtension.equals(StringUtils.getFilenameExtension(resource.getFilename()))) { - return resource; - } - - byte[] bytes = FileCopyUtils.copyToByteArray(resource.getInputStream()); - String content = new String(bytes, DEFAULT_CHARSET); - - if (!content.startsWith(MANIFEST_HEADER)) { - if (logger.isTraceEnabled()) { - logger.trace("Skipping " + resource + ": Manifest does not start with 'CACHE MANIFEST'"); - } - return resource; - } - - @SuppressWarnings("resource") - Scanner scanner = new Scanner(content); - LineInfo previous = null; - LineAggregator aggregator = new LineAggregator(resource, content); - - while (scanner.hasNext()) { - String line = scanner.nextLine(); - LineInfo current = new LineInfo(line, previous); - LineOutput lineOutput = processLine(current, request, resource, chain); - aggregator.add(lineOutput); - previous = current; - } - - return aggregator.createResource(); - } - - private static byte[] getResourceBytes(Resource resource) throws IOException { - return FileCopyUtils.copyToByteArray(resource.getInputStream()); - } - - private LineOutput processLine(LineInfo info, HttpServletRequest request, - Resource resource, ResourceTransformerChain transformerChain) { - - if (!info.isLink()) { - return new LineOutput(info.getLine(), null); - } - - Resource appCacheResource = transformerChain.getResolverChain() - .resolveResource(null, info.getLine(), Collections.singletonList(resource)); - - String path = info.getLine(); - String absolutePath = toAbsolutePath(path, request); - String newPath = resolveUrlPath(absolutePath, request, resource, transformerChain); - - return new LineOutput((newPath != null ? newPath : path), appCacheResource); - } - - - private static class LineInfo { - - private final String line; - - private final boolean cacheSection; - - private final boolean link; - - public LineInfo(String line, @Nullable LineInfo previous) { - this.line = line; - this.cacheSection = initCacheSectionFlag(line, previous); - this.link = iniLinkFlag(line, this.cacheSection); - } - - private static boolean initCacheSectionFlag(String line, @Nullable LineInfo previousLine) { - String trimmedLine = line.trim(); - if (MANIFEST_SECTION_HEADERS.contains(trimmedLine)) { - return trimmedLine.equals(CACHE_HEADER); - } - else if (previousLine != null) { - return previousLine.isCacheSection(); - } - throw new IllegalStateException( - "Manifest does not start with " + MANIFEST_HEADER + ": " + line); - } - - private static boolean iniLinkFlag(String line, boolean isCacheSection) { - return (isCacheSection && StringUtils.hasText(line) && !line.startsWith("#") - && !line.startsWith("//") && !hasScheme(line)); - } - - private static boolean hasScheme(String line) { - int index = line.indexOf(':'); - return (line.startsWith("//") || (index > 0 && !line.substring(0, index).contains("/"))); - } - - public String getLine() { - return this.line; - } - - public boolean isCacheSection() { - return this.cacheSection; - } - - public boolean isLink() { - return this.link; - } - } - - - private static class LineOutput { - - private final String line; - - @Nullable - private final Resource resource; - - public LineOutput(String line, @Nullable Resource resource) { - this.line = line; - this.resource = resource; - } - - public String getLine() { - return this.line; - } - - @Nullable - public Resource getResource() { - return this.resource; - } - } - - - private static class LineAggregator { - - private final StringWriter writer = new StringWriter(); - - private final ByteArrayOutputStream baos; - - private final Resource resource; - - public LineAggregator(Resource resource, String content) { - this.resource = resource; - this.baos = new ByteArrayOutputStream(content.length()); - } - - public void add(LineOutput lineOutput) throws IOException { - this.writer.write(lineOutput.getLine() + "\n"); - byte[] bytes = (lineOutput.getResource() != null ? - DigestUtils.md5Digest(getResourceBytes(lineOutput.getResource())) : - lineOutput.getLine().getBytes(DEFAULT_CHARSET)); - this.baos.write(bytes); - } - - public TransformedResource createResource() { - String hash = DigestUtils.md5DigestAsHex(this.baos.toByteArray()); - this.writer.write("\n" + "# Hash: " + hash); - byte[] bytes = this.writer.toString().getBytes(DEFAULT_CHARSET); - return new TransformedResource(this.resource, bytes); - } - } - -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CssLinkResourceTransformer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CssLinkResourceTransformer.java index 3193814625..26548d8c5f 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CssLinkResourceTransformer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/CssLinkResourceTransformer.java @@ -72,8 +72,7 @@ public class CssLinkResourceTransformer extends ResourceTransformerSupport { String filename = resource.getFilename(); if (!"css".equals(StringUtils.getFilenameExtension(filename)) || - resource instanceof EncodedResourceResolver.EncodedResource || - resource instanceof GzipResourceResolver.GzippedResource) { + resource instanceof EncodedResourceResolver.EncodedResource) { return resource; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/GzipResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/GzipResourceResolver.java deleted file mode 100644 index e38cea0bf2..0000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/GzipResourceResolver.java +++ /dev/null @@ -1,174 +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.web.servlet.resource; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.net.URL; -import java.util.List; - -import jakarta.servlet.http.HttpServletRequest; - -import org.springframework.core.io.AbstractResource; -import org.springframework.core.io.Resource; -import org.springframework.http.HttpHeaders; -import org.springframework.lang.Nullable; - -/** - * A {@code ResourceResolver} that delegates to the chain to locate a resource - * and then attempts to find a variation with the ".gz" extension. - * - *

The resolver gets involved only if the "Accept-Encoding" request header - * contains the value "gzip" indicating the client accepts gzipped responses. - * - * @author Jeremy Grelle - * @author Rossen Stoyanchev - * @author Sam Brannen - * @since 4.1 - * @deprecated as of 5.1, in favor of using {@link EncodedResourceResolver} - */ -@Deprecated -public class GzipResourceResolver extends AbstractResourceResolver { - - @Override - protected Resource resolveResourceInternal(@Nullable HttpServletRequest request, String requestPath, - List locations, ResourceResolverChain chain) { - - Resource resource = chain.resolveResource(request, requestPath, locations); - if (resource == null || (request != null && !isGzipAccepted(request))) { - return resource; - } - - try { - Resource gzipped = new GzippedResource(resource); - if (gzipped.exists()) { - return gzipped; - } - } - catch (IOException ex) { - logger.trace("No gzip resource for [" + resource.getFilename() + "]", ex); - } - - return resource; - } - - private boolean isGzipAccepted(HttpServletRequest request) { - String value = request.getHeader("Accept-Encoding"); - return (value != null && value.toLowerCase().contains("gzip")); - } - - @Override - protected String resolveUrlPathInternal(String resourceUrlPath, - List locations, ResourceResolverChain chain) { - - return chain.resolveUrlPath(resourceUrlPath, locations); - } - - - /** - * A gzipped {@link HttpResource}. - */ - static final class GzippedResource extends AbstractResource implements HttpResource { - - private final Resource original; - - private final Resource gzipped; - - public GzippedResource(Resource original) throws IOException { - this.original = original; - this.gzipped = original.createRelative(original.getFilename() + ".gz"); - } - - @Override - public InputStream getInputStream() throws IOException { - return this.gzipped.getInputStream(); - } - - @Override - public boolean exists() { - return this.gzipped.exists(); - } - - @Override - public boolean isReadable() { - return this.gzipped.isReadable(); - } - - @Override - public boolean isOpen() { - return this.gzipped.isOpen(); - } - - @Override - public boolean isFile() { - return this.gzipped.isFile(); - } - - @Override - public URL getURL() throws IOException { - return this.gzipped.getURL(); - } - - @Override - public URI getURI() throws IOException { - return this.gzipped.getURI(); - } - - @Override - public File getFile() throws IOException { - return this.gzipped.getFile(); - } - - @Override - public long contentLength() throws IOException { - return this.gzipped.contentLength(); - } - - @Override - public long lastModified() throws IOException { - return this.gzipped.lastModified(); - } - - @Override - public Resource createRelative(String relativePath) throws IOException { - return this.gzipped.createRelative(relativePath); - } - - @Override - @Nullable - public String getFilename() { - return this.original.getFilename(); - } - - @Override - public String getDescription() { - return this.gzipped.getDescription(); - } - - @Override - public HttpHeaders getResponseHeaders() { - HttpHeaders headers = (this.original instanceof HttpResource ? - ((HttpResource) this.original).getResponseHeaders() : new HttpHeaders()); - headers.add(HttpHeaders.CONTENT_ENCODING, "gzip"); - headers.add(HttpHeaders.VARY, HttpHeaders.ACCEPT_ENCODING); - return headers; - } - } - -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/WebContentGenerator.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/WebContentGenerator.java index 25913228d9..52acc16047 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/WebContentGenerator.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/WebContentGenerator.java @@ -475,22 +475,6 @@ public abstract class WebContentGenerator extends WebApplicationObjectSupport { } - /** - * Check and prepare the given request and response according to the settings - * of this generator. - * @see #checkRequest(HttpServletRequest) - * @see #prepareResponse(HttpServletResponse) - * @deprecated as of 4.2, since the {@code lastModified} flag is effectively ignored, - * with a must-revalidate header only generated if explicitly configured - */ - @Deprecated - protected final void checkAndPrepare( - HttpServletRequest request, HttpServletResponse response, boolean lastModified) throws ServletException { - - checkRequest(request); - prepareResponse(response); - } - /** * Check and prepare the given request and response according to the settings * of this generator. diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/DefaultRequestToViewNameTranslator.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/DefaultRequestToViewNameTranslator.java index 7178edc491..df59805bd7 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/DefaultRequestToViewNameTranslator.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/DefaultRequestToViewNameTranslator.java @@ -23,7 +23,6 @@ import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; import org.springframework.web.servlet.RequestToViewNameTranslator; import org.springframework.web.util.ServletRequestPathUtils; -import org.springframework.web.util.UrlPathHelper; /** * {@link RequestToViewNameTranslator} that simply transforms the URI of @@ -122,48 +121,6 @@ public class DefaultRequestToViewNameTranslator implements RequestToViewNameTran this.stripExtension = stripExtension; } - /** - * Shortcut to same property on underlying {@link #setUrlPathHelper UrlPathHelper}. - * @see org.springframework.web.util.UrlPathHelper#setAlwaysUseFullPath - * @deprecated as of 5.3, the path is resolved externally and obtained with - * {@link ServletRequestPathUtils#getCachedPathValue(ServletRequest)} - */ - @Deprecated - public void setAlwaysUseFullPath(boolean alwaysUseFullPath) { - } - - /** - * Shortcut to same property on underlying {@link #setUrlPathHelper UrlPathHelper}. - * @see org.springframework.web.util.UrlPathHelper#setUrlDecode - * @deprecated as of 5.3, the path is resolved externally and obtained with - * {@link ServletRequestPathUtils#getCachedPathValue(ServletRequest)} - */ - @Deprecated - public void setUrlDecode(boolean urlDecode) { - } - - /** - * Set if ";" (semicolon) content should be stripped from the request URI. - * @see org.springframework.web.util.UrlPathHelper#setRemoveSemicolonContent(boolean) - * @deprecated as of 5.3, the path is resolved externally and obtained with - * {@link ServletRequestPathUtils#getCachedPathValue(ServletRequest)} - */ - @Deprecated - public void setRemoveSemicolonContent(boolean removeSemicolonContent) { - } - - /** - * Set the {@link org.springframework.web.util.UrlPathHelper} to use for - * the resolution of lookup paths. - *

Use this to override the default UrlPathHelper with a custom subclass, - * or to share common UrlPathHelper settings across multiple web components. - * @deprecated as of 5.3, the path is resolved externally and obtained with - * {@link ServletRequestPathUtils#getCachedPathValue(ServletRequest)} - */ - @Deprecated - public void setUrlPathHelper(UrlPathHelper urlPathHelper) { - } - /** * Translates the request URI of the incoming {@link HttpServletRequest} diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java index 60406a0026..01b23847fa 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java @@ -467,10 +467,9 @@ public class MvcNamespaceTests { assertThat(locationCharsets.values().iterator().next()).isEqualTo(StandardCharsets.ISO_8859_1); List transformers = handler.getResourceTransformers(); - assertThat(transformers).hasSize(3); + assertThat(transformers).hasSize(2); assertThat(transformers.get(0)).isInstanceOf(CachingResourceTransformer.class); assertThat(transformers.get(1)).isInstanceOf(CssLinkResourceTransformer.class); - assertThat(transformers.get(2)).isInstanceOf(org.springframework.web.servlet.resource.AppCacheManifestTransformer.class); CachingResourceTransformer cachingTransformer = (CachingResourceTransformer) transformers.get(0); assertThat(cachingTransformer.getCache()).isInstanceOf(ConcurrentMapCache.class); @@ -506,9 +505,8 @@ public class MvcNamespaceTests { .isInstanceOf(ContentVersionStrategy.class); List transformers = handler.getResourceTransformers(); - assertThat(transformers).hasSize(2); + assertThat(transformers).hasSize(1); assertThat(transformers.get(0)).isInstanceOf(CachingResourceTransformer.class); - assertThat(transformers.get(1)).isInstanceOf(org.springframework.web.servlet.resource.AppCacheManifestTransformer.class); } @Test diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistryTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistryTests.java index fccde83979..7cbedbfd00 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistryTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistryTests.java @@ -167,14 +167,12 @@ public class ResourceHandlerRegistryTests { } @Test - @SuppressWarnings("deprecation") public void resourceChainWithVersionResolver() { VersionResourceResolver versionResolver = new VersionResourceResolver() .addFixedVersionStrategy("fixed", "/**/*.js") .addContentVersionStrategy("/**"); - this.registration.resourceChain(true).addResolver(versionResolver) - .addTransformer(new org.springframework.web.servlet.resource.AppCacheManifestTransformer()); + this.registration.resourceChain(true).addResolver(versionResolver); ResourceHttpRequestHandler handler = getHandler("/resources/**"); List resolvers = handler.getResourceResolvers(); @@ -185,22 +183,18 @@ public class ResourceHandlerRegistryTests { assertThat(resolvers.get(3)).isInstanceOf(PathResourceResolver.class); List transformers = handler.getResourceTransformers(); - assertThat(transformers).hasSize(3); + assertThat(transformers).hasSize(2); assertThat(transformers.get(0)).isInstanceOf(CachingResourceTransformer.class); assertThat(transformers.get(1)).isInstanceOf(CssLinkResourceTransformer.class); - assertThat(transformers.get(2)).isInstanceOf(org.springframework.web.servlet.resource.AppCacheManifestTransformer.class); } @Test - @SuppressWarnings("deprecation") public void resourceChainWithOverrides() { CachingResourceResolver cachingResolver = Mockito.mock(CachingResourceResolver.class); VersionResourceResolver versionResolver = Mockito.mock(VersionResourceResolver.class); WebJarsResourceResolver webjarsResolver = Mockito.mock(WebJarsResourceResolver.class); PathResourceResolver pathResourceResolver = new PathResourceResolver(); CachingResourceTransformer cachingTransformer = Mockito.mock(CachingResourceTransformer.class); - org.springframework.web.servlet.resource.AppCacheManifestTransformer appCacheTransformer = - Mockito.mock(org.springframework.web.servlet.resource.AppCacheManifestTransformer.class); CssLinkResourceTransformer cssLinkTransformer = new CssLinkResourceTransformer(); this.registration.setCachePeriod(3600) @@ -210,7 +204,6 @@ public class ResourceHandlerRegistryTests { .addResolver(webjarsResolver) .addResolver(pathResourceResolver) .addTransformer(cachingTransformer) - .addTransformer(appCacheTransformer) .addTransformer(cssLinkTransformer); ResourceHttpRequestHandler handler = getHandler("/resources/**"); @@ -222,10 +215,9 @@ public class ResourceHandlerRegistryTests { assertThat(resolvers.get(3)).isSameAs(pathResourceResolver); List transformers = handler.getResourceTransformers(); - assertThat(transformers).hasSize(3); + assertThat(transformers).hasSize(2); assertThat(transformers.get(0)).isSameAs(cachingTransformer); - assertThat(transformers.get(1)).isSameAs(appCacheTransformer); - assertThat(transformers.get(2)).isSameAs(cssLinkTransformer); + assertThat(transformers.get(1)).isSameAs(cssLinkTransformer); } @Test diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/AppCacheManifestTransformerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/AppCacheManifestTransformerTests.java deleted file mode 100644 index 9132e8c237..0000000000 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/AppCacheManifestTransformerTests.java +++ /dev/null @@ -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.web.servlet.resource; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import jakarta.servlet.http.HttpServletRequest; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; -import org.springframework.util.FileCopyUtils; -import org.springframework.web.testfixture.servlet.MockHttpServletRequest; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Unit tests for {@link AppCacheManifestTransformer}. - * - * @author Brian Clozel - * @author Rossen Stoyanchev - */ -@SuppressWarnings("deprecation") -public class AppCacheManifestTransformerTests { - - private final AppCacheManifestTransformer transformer = new AppCacheManifestTransformer(); - - private ResourceTransformerChain chain; - - private HttpServletRequest request; - - - @BeforeEach - public void setup() { - VersionResourceResolver versionResolver = new VersionResourceResolver(); - versionResolver.setStrategyMap(Collections.singletonMap("/**", new ContentVersionStrategy())); - PathResourceResolver pathResolver = new PathResourceResolver(); - pathResolver.setAllowedLocations(new ClassPathResource("test/", getClass())); - List resolvers = new ArrayList<>(); - resolvers.add(versionResolver); - resolvers.add(pathResolver); - ResourceResolverChain resolverChain = new DefaultResourceResolverChain(resolvers); - - this.chain = new DefaultResourceTransformerChain(resolverChain, Collections.emptyList()); - this.transformer.setResourceUrlProvider(createUrlProvider(resolvers)); - } - - private ResourceUrlProvider createUrlProvider(List resolvers) { - ClassPathResource allowedLocation = new ClassPathResource("test/", getClass()); - ResourceHttpRequestHandler resourceHandler = new ResourceHttpRequestHandler(); - - resourceHandler.setResourceResolvers(resolvers); - resourceHandler.setLocations(Collections.singletonList(allowedLocation)); - - ResourceUrlProvider resourceUrlProvider = new ResourceUrlProvider(); - resourceUrlProvider.setHandlerMap(Collections.singletonMap("/static/**", resourceHandler)); - return resourceUrlProvider; - } - - - @Test - public void noTransformIfExtensionDoesNotMatch() throws Exception { - this.request = new MockHttpServletRequest("GET", "/static/foo.css"); - Resource resource = getResource("foo.css"); - Resource result = this.transformer.transform(this.request, resource, this.chain); - - assertThat(result).isEqualTo(resource); - } - - @Test - public void syntaxErrorInManifest() throws Exception { - this.request = new MockHttpServletRequest("GET", "/static/error.appcache"); - Resource resource = getResource("error.appcache"); - Resource result = this.transformer.transform(this.request, resource, this.chain); - - assertThat(result).isEqualTo(resource); - } - - @Test - public void transformManifest() throws Exception { - this.request = new MockHttpServletRequest("GET", "/static/test.appcache"); - Resource resource = getResource("test.appcache"); - Resource actual = this.transformer.transform(this.request, resource, this.chain); - - byte[] bytes = FileCopyUtils.copyToByteArray(actual.getInputStream()); - String content = new String(bytes, "UTF-8"); - - assertThat(content).as("rewrite resource links") - .contains("/static/foo-e36d2e05253c6c7085a91522ce43a0b4.css") - .contains("/static/bar-11e16cf79faee7ac698c805cf28248d2.css") - .contains("/static/js/bar-bd508c62235b832d960298ca6c0b7645.js"); - - assertThat(content).as("not rewrite external resources") - .contains("//example.org/style.css") - .contains("https://example.org/image.png"); - - assertThat(content).as("generate fingerprint") - .contains("# Hash: 65ebc023e50b2b731fcace2871f0dae3"); - } - - private Resource getResource(String filePath) { - return new ClassPathResource("test/" + filePath, getClass()); - } - -} diff --git a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-resources-chain-no-auto.xml b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-resources-chain-no-auto.xml index d58def13ab..d6a7870f5d 100644 --- a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-resources-chain-no-auto.xml +++ b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-resources-chain-no-auto.xml @@ -22,7 +22,6 @@ - diff --git a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-resources-chain.xml b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-resources-chain.xml index 122d520db3..5ab96045b8 100644 --- a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-resources-chain.xml +++ b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-resources-chain.xml @@ -35,9 +35,6 @@ - - - diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/WebSocketHttpHeaders.java b/spring-websocket/src/main/java/org/springframework/web/socket/WebSocketHttpHeaders.java index cb30c423bb..9198a8d5d6 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/WebSocketHttpHeaders.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/WebSocketHttpHeaders.java @@ -68,16 +68,6 @@ public class WebSocketHttpHeaders extends HttpHeaders { this.headers = headers; } - /** - * Returns {@code WebSocketHttpHeaders} object that can only be read, not written to. - * @deprecated as of 5.1.16, in favor of calling {@link #WebSocketHttpHeaders(HttpHeaders)} - * with a read-only wrapper from {@link HttpHeaders#readOnlyHttpHeaders(HttpHeaders)} - */ - @Deprecated - public static WebSocketHttpHeaders readOnlyWebSocketHttpHeaders(WebSocketHttpHeaders headers) { - return new WebSocketHttpHeaders(HttpHeaders.readOnlyHttpHeaders(headers)); - } - /** * Sets the (new) value of the {@code Sec-WebSocket-Accept} header. diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java index 1c9fd553ee..b06c9a8003 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java @@ -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. @@ -626,10 +626,6 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { if (brokerElem.hasAttribute("user-destination-prefix")) { beanDef.getPropertyValues().add("userDestinationPrefix", brokerElem.getAttribute("user-destination-prefix")); } - if (brokerElem.hasAttribute("path-matcher")) { - String pathMatcherRef = brokerElem.getAttribute("path-matcher"); - beanDef.getPropertyValues().add("pathMatcher", new RuntimeBeanReference(pathMatcherRef)); - } return new RuntimeBeanReference(registerBeanDef(beanDef, context, source)); } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/AbstractWebSocketMessageBrokerConfigurer.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/AbstractWebSocketMessageBrokerConfigurer.java deleted file mode 100644 index 07ec4f1903..0000000000 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/AbstractWebSocketMessageBrokerConfigurer.java +++ /dev/null @@ -1,68 +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.web.socket.config.annotation; - -import java.util.List; - -import org.springframework.messaging.converter.MessageConverter; -import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver; -import org.springframework.messaging.handler.invocation.HandlerMethodReturnValueHandler; -import org.springframework.messaging.simp.config.ChannelRegistration; -import org.springframework.messaging.simp.config.MessageBrokerRegistry; - -/** - * A convenient abstract base class for {@link WebSocketMessageBrokerConfigurer} - * implementations providing empty method implementations for optional methods. - * - * @author Rossen Stoyanchev - * @since 4.0.1 - * @deprecated as of 5.0 in favor of simply using {@link WebSocketMessageBrokerConfigurer} - * which has default methods, made possible by a Java 8 baseline. - */ -@Deprecated -public abstract class AbstractWebSocketMessageBrokerConfigurer implements WebSocketMessageBrokerConfigurer { - - @Override - public void configureWebSocketTransport(WebSocketTransportRegistration registration) { - } - - @Override - public void configureClientInboundChannel(ChannelRegistration registration) { - } - - @Override - public void configureClientOutboundChannel(ChannelRegistration registration) { - } - - @Override - public boolean configureMessageConverters(List messageConverters) { - return true; - } - - @Override - public void addArgumentResolvers(List argumentResolvers) { - } - - @Override - public void addReturnValueHandlers(List returnValueHandlers) { - } - - @Override - public void configureMessageBroker(MessageBrokerRegistry registry) { - } - -}