Merge branch '5.2.x'
This commit is contained in:
commit
42ff01b5aa
|
@ -432,8 +432,7 @@ public abstract class YamlProcessor {
|
||||||
/**
|
/**
|
||||||
* {@link Constructor} that supports filtering of unsupported types.
|
* {@link Constructor} that supports filtering of unsupported types.
|
||||||
* <p>If an unsupported type is encountered in a YAML document, an
|
* <p>If an unsupported type is encountered in a YAML document, an
|
||||||
* {@link IllegalStateException} will be thrown from {@link #getClassForName(String)}.
|
* {@link IllegalStateException} will be thrown from {@link #getClassForName}.
|
||||||
* @since 5.1.16
|
|
||||||
*/
|
*/
|
||||||
private class FilteringConstructor extends Constructor {
|
private class FilteringConstructor extends Constructor {
|
||||||
|
|
||||||
|
@ -441,7 +440,6 @@ public abstract class YamlProcessor {
|
||||||
super(loaderOptions);
|
super(loaderOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<?> getClassForName(String name) throws ClassNotFoundException {
|
protected Class<?> getClassForName(String name) throws ClassNotFoundException {
|
||||||
Assert.state(YamlProcessor.this.supportedTypes.contains(name),
|
Assert.state(YamlProcessor.this.supportedTypes.contains(name),
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -79,6 +79,7 @@ import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
|
@ -836,7 +837,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||||
// Publish early application events now that we finally have a multicaster...
|
// Publish early application events now that we finally have a multicaster...
|
||||||
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
|
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
|
||||||
this.earlyApplicationEvents = null;
|
this.earlyApplicationEvents = null;
|
||||||
if (earlyEventsToProcess != null) {
|
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
|
||||||
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
|
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
|
||||||
getApplicationEventMulticaster().multicastEvent(earlyEvent);
|
getApplicationEventMulticaster().multicastEvent(earlyEvent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2018 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -223,6 +223,9 @@ public abstract class AbstractPropertyResolver implements ConfigurablePropertyRe
|
||||||
* @see #setIgnoreUnresolvableNestedPlaceholders
|
* @see #setIgnoreUnresolvableNestedPlaceholders
|
||||||
*/
|
*/
|
||||||
protected String resolveNestedPlaceholders(String value) {
|
protected String resolveNestedPlaceholders(String value) {
|
||||||
|
if (value.isEmpty()) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
return (this.ignoreUnresolvableNestedPlaceholders ?
|
return (this.ignoreUnresolvableNestedPlaceholders ?
|
||||||
resolvePlaceholders(value) : resolveRequiredPlaceholders(value));
|
resolvePlaceholders(value) : resolveRequiredPlaceholders(value));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2018 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -44,10 +44,20 @@ import org.springframework.util.ObjectUtils;
|
||||||
*/
|
*/
|
||||||
public abstract class EnumerablePropertySource<T> extends PropertySource<T> {
|
public abstract class EnumerablePropertySource<T> extends PropertySource<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@code EnumerablePropertySource} with the given name and source object.
|
||||||
|
* @param name the associated name
|
||||||
|
* @param source the source object
|
||||||
|
*/
|
||||||
public EnumerablePropertySource(String name, T source) {
|
public EnumerablePropertySource(String name, T source) {
|
||||||
super(name, source);
|
super(name, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@code EnumerablePropertySource} with the given name and with a new
|
||||||
|
* {@code Object} instance as the underlying source.
|
||||||
|
* @param name the associated name
|
||||||
|
*/
|
||||||
protected EnumerablePropertySource(String name) {
|
protected EnumerablePropertySource(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -23,6 +23,8 @@ import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link PropertySource} that reads keys and values from a {@code Map} object.
|
* {@link PropertySource} that reads keys and values from a {@code Map} object.
|
||||||
|
* The underlying map should not contain any {@code null} values in order to
|
||||||
|
* comply with {@link #getProperty} and {@link #containsProperty} semantics.
|
||||||
*
|
*
|
||||||
* @author Chris Beams
|
* @author Chris Beams
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
@ -31,6 +33,12 @@ import org.springframework.util.StringUtils;
|
||||||
*/
|
*/
|
||||||
public class MapPropertySource extends EnumerablePropertySource<Map<String, Object>> {
|
public class MapPropertySource extends EnumerablePropertySource<Map<String, Object>> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new {@code MapPropertySource} with the given name and {@code Map}.
|
||||||
|
* @param name the associated name
|
||||||
|
* @param source the Map source (without {@code null} values in order to get
|
||||||
|
* consistent {@link #getProperty} and {@link #containsProperty} behavior)
|
||||||
|
*/
|
||||||
public MapPropertySource(String name, Map<String, Object> source) {
|
public MapPropertySource(String name, Map<String, Object> source) {
|
||||||
super(name, source);
|
super(name, source);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -98,7 +98,6 @@ public interface PropertyResolver {
|
||||||
* @return the resolved String (never {@code null})
|
* @return the resolved String (never {@code null})
|
||||||
* @throws IllegalArgumentException if given text is {@code null}
|
* @throws IllegalArgumentException if given text is {@code null}
|
||||||
* @see #resolveRequiredPlaceholders
|
* @see #resolveRequiredPlaceholders
|
||||||
* @see org.springframework.util.SystemPropertyUtils#resolvePlaceholders(String)
|
|
||||||
*/
|
*/
|
||||||
String resolvePlaceholders(String text);
|
String resolvePlaceholders(String text);
|
||||||
|
|
||||||
|
@ -109,7 +108,6 @@ public interface PropertyResolver {
|
||||||
* @return the resolved String (never {@code null})
|
* @return the resolved String (never {@code null})
|
||||||
* @throws IllegalArgumentException if given text is {@code null}
|
* @throws IllegalArgumentException if given text is {@code null}
|
||||||
* or if any placeholders are unresolvable
|
* or if any placeholders are unresolvable
|
||||||
* @see org.springframework.util.SystemPropertyUtils#resolvePlaceholders(String, boolean)
|
|
||||||
*/
|
*/
|
||||||
String resolveRequiredPlaceholders(String text) throws IllegalArgumentException;
|
String resolveRequiredPlaceholders(String text) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2018 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -68,6 +68,8 @@ public abstract class PropertySource<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@code PropertySource} with the given name and source object.
|
* Create a new {@code PropertySource} with the given name and source object.
|
||||||
|
* @param name the associated name
|
||||||
|
* @param source the source object
|
||||||
*/
|
*/
|
||||||
public PropertySource(String name, T source) {
|
public PropertySource(String name, T source) {
|
||||||
Assert.hasText(name, "Property source name must contain at least one character");
|
Assert.hasText(name, "Property source name must contain at least one character");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package org.springframework.util;
|
package org.springframework.util;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -24,7 +23,6 @@ import java.util.Collections;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
@ -412,25 +410,28 @@ public abstract class CollectionUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapt a {@code Map<K, List<V>>} to an {@code MultiValueMap<K, V>}.
|
* Adapt a {@code Map<K, List<V>>} to an {@code MultiValueMap<K, V>}.
|
||||||
* @param map the original map
|
* @param targetMap the original map
|
||||||
* @return the multi-value map
|
* @return the adapted multi-value map (wrapping the original map)
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public static <K, V> MultiValueMap<K, V> toMultiValueMap(Map<K, List<V>> map) {
|
public static <K, V> MultiValueMap<K, V> toMultiValueMap(Map<K, List<V>> targetMap) {
|
||||||
return new MultiValueMapAdapter<>(map);
|
Assert.notNull(targetMap, "'targetMap' must not be null");
|
||||||
|
return new MultiValueMapAdapter<>(targetMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an unmodifiable view of the specified multi-value map.
|
* Return an unmodifiable view of the specified multi-value map.
|
||||||
* @param map the map for which an unmodifiable view is to be returned.
|
* @param targetMap the map for which an unmodifiable view is to be returned.
|
||||||
* @return an unmodifiable view of the specified multi-value map.
|
* @return an unmodifiable view of the specified multi-value map
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <K, V> MultiValueMap<K, V> unmodifiableMultiValueMap(MultiValueMap<? extends K, ? extends V> map) {
|
public static <K, V> MultiValueMap<K, V> unmodifiableMultiValueMap(
|
||||||
Assert.notNull(map, "'map' must not be null");
|
MultiValueMap<? extends K, ? extends V> targetMap) {
|
||||||
Map<K, List<V>> result = new LinkedHashMap<>(map.size());
|
|
||||||
map.forEach((key, value) -> {
|
Assert.notNull(targetMap, "'targetMap' must not be null");
|
||||||
|
Map<K, List<V>> result = new LinkedHashMap<>(targetMap.size());
|
||||||
|
targetMap.forEach((key, value) -> {
|
||||||
List<? extends V> values = Collections.unmodifiableList(value);
|
List<? extends V> values = Collections.unmodifiableList(value);
|
||||||
result.put(key, (List<V>) values);
|
result.put(key, (List<V>) values);
|
||||||
});
|
});
|
||||||
|
@ -467,141 +468,4 @@ public abstract class CollectionUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapts a Map to the MultiValueMap contract.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
private static class MultiValueMapAdapter<K, V> implements MultiValueMap<K, V>, Serializable {
|
|
||||||
|
|
||||||
private final Map<K, List<V>> map;
|
|
||||||
|
|
||||||
public MultiValueMapAdapter(Map<K, List<V>> map) {
|
|
||||||
Assert.notNull(map, "'map' must not be null");
|
|
||||||
this.map = map;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public V getFirst(K key) {
|
|
||||||
List<V> values = this.map.get(key);
|
|
||||||
return (values != null ? values.get(0) : null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(K key, @Nullable V value) {
|
|
||||||
List<V> values = this.map.computeIfAbsent(key, k -> new LinkedList<>());
|
|
||||||
values.add(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addAll(K key, List<? extends V> values) {
|
|
||||||
List<V> currentValues = this.map.computeIfAbsent(key, k -> new LinkedList<>());
|
|
||||||
currentValues.addAll(values);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addAll(MultiValueMap<K, V> values) {
|
|
||||||
for (Entry<K, List<V>> entry : values.entrySet()) {
|
|
||||||
addAll(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void set(K key, @Nullable V value) {
|
|
||||||
List<V> values = new LinkedList<>();
|
|
||||||
values.add(value);
|
|
||||||
this.map.put(key, values);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAll(Map<K, V> values) {
|
|
||||||
values.forEach(this::set);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<K, V> toSingleValueMap() {
|
|
||||||
LinkedHashMap<K, V> singleValueMap = new LinkedHashMap<>(this.map.size());
|
|
||||||
this.map.forEach((key, value) -> singleValueMap.put(key, value.get(0)));
|
|
||||||
return singleValueMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
return this.map.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEmpty() {
|
|
||||||
return this.map.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean containsKey(Object key) {
|
|
||||||
return this.map.containsKey(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean containsValue(Object value) {
|
|
||||||
return this.map.containsValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<V> get(Object key) {
|
|
||||||
return this.map.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<V> put(K key, List<V> value) {
|
|
||||||
return this.map.put(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<V> remove(Object key) {
|
|
||||||
return this.map.remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void putAll(Map<? extends K, ? extends List<V>> map) {
|
|
||||||
this.map.putAll(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clear() {
|
|
||||||
this.map.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<K> keySet() {
|
|
||||||
return this.map.keySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<List<V>> values() {
|
|
||||||
return this.map.values();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Entry<K, List<V>>> entrySet() {
|
|
||||||
return this.map.entrySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(@Nullable Object other) {
|
|
||||||
if (this == other) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return this.map.equals(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return this.map.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.map.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -273,8 +273,8 @@ public class LinkedCaseInsensitiveMap<V> implements Map<String, V>, Serializable
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(@Nullable Object obj) {
|
public boolean equals(@Nullable Object other) {
|
||||||
return this.targetMap.equals(obj);
|
return (this == other || this.targetMap.equals(other));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -17,14 +17,10 @@
|
||||||
package org.springframework.util;
|
package org.springframework.util;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.springframework.lang.Nullable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple implementation of {@link MultiValueMap} that wraps a {@link LinkedHashMap},
|
* Simple implementation of {@link MultiValueMap} that wraps a {@link LinkedHashMap},
|
||||||
|
@ -39,18 +35,16 @@ import org.springframework.lang.Nullable;
|
||||||
* @param <K> the key type
|
* @param <K> the key type
|
||||||
* @param <V> the value element type
|
* @param <V> the value element type
|
||||||
*/
|
*/
|
||||||
public class LinkedMultiValueMap<K, V> implements MultiValueMap<K, V>, Serializable, Cloneable {
|
public class LinkedMultiValueMap<K, V> extends MultiValueMapAdapter<K, V> implements Serializable, Cloneable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 3801124242820219131L;
|
private static final long serialVersionUID = 3801124242820219131L;
|
||||||
|
|
||||||
private final Map<K, List<V>> targetMap;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new LinkedMultiValueMap that wraps a {@link LinkedHashMap}.
|
* Create a new LinkedMultiValueMap that wraps a {@link LinkedHashMap}.
|
||||||
*/
|
*/
|
||||||
public LinkedMultiValueMap() {
|
public LinkedMultiValueMap() {
|
||||||
this.targetMap = new LinkedHashMap<>();
|
super(new LinkedHashMap<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,7 +53,7 @@ public class LinkedMultiValueMap<K, V> implements MultiValueMap<K, V>, Serializa
|
||||||
* @param initialCapacity the initial capacity
|
* @param initialCapacity the initial capacity
|
||||||
*/
|
*/
|
||||||
public LinkedMultiValueMap(int initialCapacity) {
|
public LinkedMultiValueMap(int initialCapacity) {
|
||||||
this.targetMap = new LinkedHashMap<>(initialCapacity);
|
super(new LinkedHashMap<>(initialCapacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -71,125 +65,7 @@ public class LinkedMultiValueMap<K, V> implements MultiValueMap<K, V>, Serializa
|
||||||
* @see #deepCopy()
|
* @see #deepCopy()
|
||||||
*/
|
*/
|
||||||
public LinkedMultiValueMap(Map<K, List<V>> otherMap) {
|
public LinkedMultiValueMap(Map<K, List<V>> otherMap) {
|
||||||
this.targetMap = new LinkedHashMap<>(otherMap);
|
super(new LinkedHashMap<>(otherMap));
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// MultiValueMap implementation
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public V getFirst(K key) {
|
|
||||||
List<V> values = this.targetMap.get(key);
|
|
||||||
return (values != null && !values.isEmpty() ? values.get(0) : null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(K key, @Nullable V value) {
|
|
||||||
List<V> values = this.targetMap.computeIfAbsent(key, k -> new LinkedList<>());
|
|
||||||
values.add(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addAll(K key, List<? extends V> values) {
|
|
||||||
List<V> currentValues = this.targetMap.computeIfAbsent(key, k -> new LinkedList<>());
|
|
||||||
currentValues.addAll(values);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addAll(MultiValueMap<K, V> values) {
|
|
||||||
for (Entry<K, List<V>> entry : values.entrySet()) {
|
|
||||||
addAll(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void set(K key, @Nullable V value) {
|
|
||||||
List<V> values = new LinkedList<>();
|
|
||||||
values.add(value);
|
|
||||||
this.targetMap.put(key, values);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAll(Map<K, V> values) {
|
|
||||||
values.forEach(this::set);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<K, V> toSingleValueMap() {
|
|
||||||
LinkedHashMap<K, V> singleValueMap = new LinkedHashMap<>(this.targetMap.size());
|
|
||||||
this.targetMap.forEach((key, values) -> {
|
|
||||||
if (values != null && !values.isEmpty()) {
|
|
||||||
singleValueMap.put(key, values.get(0));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return singleValueMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Map implementation
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
return this.targetMap.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEmpty() {
|
|
||||||
return this.targetMap.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean containsKey(Object key) {
|
|
||||||
return this.targetMap.containsKey(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean containsValue(Object value) {
|
|
||||||
return this.targetMap.containsValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public List<V> get(Object key) {
|
|
||||||
return this.targetMap.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public List<V> put(K key, List<V> value) {
|
|
||||||
return this.targetMap.put(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public List<V> remove(Object key) {
|
|
||||||
return this.targetMap.remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void putAll(Map<? extends K, ? extends List<V>> map) {
|
|
||||||
this.targetMap.putAll(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clear() {
|
|
||||||
this.targetMap.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<K> keySet() {
|
|
||||||
return this.targetMap.keySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<List<V>> values() {
|
|
||||||
return this.targetMap.values();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Entry<K, List<V>>> entrySet() {
|
|
||||||
return this.targetMap.entrySet();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -203,8 +79,8 @@ public class LinkedMultiValueMap<K, V> implements MultiValueMap<K, V>, Serializa
|
||||||
* @see #clone()
|
* @see #clone()
|
||||||
*/
|
*/
|
||||||
public LinkedMultiValueMap<K, V> deepCopy() {
|
public LinkedMultiValueMap<K, V> deepCopy() {
|
||||||
LinkedMultiValueMap<K, V> copy = new LinkedMultiValueMap<>(this.targetMap.size());
|
LinkedMultiValueMap<K, V> copy = new LinkedMultiValueMap<>(size());
|
||||||
this.targetMap.forEach((key, value) -> copy.put(key, new LinkedList<>(value)));
|
forEach((key, values) -> copy.put(key, new LinkedList<>(values)));
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,19 +100,4 @@ public class LinkedMultiValueMap<K, V> implements MultiValueMap<K, V>, Serializa
|
||||||
return new LinkedMultiValueMap<>(this);
|
return new LinkedMultiValueMap<>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(@Nullable Object obj) {
|
|
||||||
return this.targetMap.equals(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return this.targetMap.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return this.targetMap.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,178 @@
|
||||||
|
/*
|
||||||
|
* 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.util;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapts a given {@link Map} to the {@link MultiValueMap} contract.
|
||||||
|
*
|
||||||
|
* @author Arjen Poutsma
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 3.1
|
||||||
|
* @param <K> the key type
|
||||||
|
* @param <V> the value element type
|
||||||
|
* @see CollectionUtils#toMultiValueMap
|
||||||
|
* @see LinkedMultiValueMap
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
class MultiValueMapAdapter<K, V> implements MultiValueMap<K, V>, Serializable {
|
||||||
|
|
||||||
|
private final Map<K, List<V>> targetMap;
|
||||||
|
|
||||||
|
|
||||||
|
MultiValueMapAdapter(Map<K, List<V>> targetMap) {
|
||||||
|
this.targetMap = targetMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public V getFirst(K key) {
|
||||||
|
List<V> values = this.targetMap.get(key);
|
||||||
|
return (values != null && !values.isEmpty() ? values.get(0) : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(K key, @Nullable V value) {
|
||||||
|
List<V> values = this.targetMap.computeIfAbsent(key, k -> new LinkedList<>());
|
||||||
|
values.add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addAll(K key, List<? extends V> values) {
|
||||||
|
List<V> currentValues = this.targetMap.computeIfAbsent(key, k -> new LinkedList<>());
|
||||||
|
currentValues.addAll(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addAll(MultiValueMap<K, V> values) {
|
||||||
|
for (Entry<K, List<V>> entry : values.entrySet()) {
|
||||||
|
addAll(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(K key, @Nullable V value) {
|
||||||
|
List<V> values = new LinkedList<>();
|
||||||
|
values.add(value);
|
||||||
|
this.targetMap.put(key, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAll(Map<K, V> values) {
|
||||||
|
values.forEach(this::set);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<K, V> toSingleValueMap() {
|
||||||
|
Map<K, V> singleValueMap = new LinkedHashMap<>(this.targetMap.size());
|
||||||
|
this.targetMap.forEach((key, values) -> {
|
||||||
|
if (values != null && !values.isEmpty()) {
|
||||||
|
singleValueMap.put(key, values.get(0));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return singleValueMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return this.targetMap.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return this.targetMap.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsKey(Object key) {
|
||||||
|
return this.targetMap.containsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsValue(Object value) {
|
||||||
|
return this.targetMap.containsValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public List<V> get(Object key) {
|
||||||
|
return this.targetMap.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public List<V> put(K key, List<V> value) {
|
||||||
|
return this.targetMap.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public List<V> remove(Object key) {
|
||||||
|
return this.targetMap.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putAll(Map<? extends K, ? extends List<V>> map) {
|
||||||
|
this.targetMap.putAll(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
this.targetMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<K> keySet() {
|
||||||
|
return this.targetMap.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<List<V>> values() {
|
||||||
|
return this.targetMap.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Entry<K, List<V>>> entrySet() {
|
||||||
|
return this.targetMap.entrySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(@Nullable Object other) {
|
||||||
|
return (this == other || this.targetMap.equals(other));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return this.targetMap.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.targetMap.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2018 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -78,6 +78,9 @@ public abstract class SystemPropertyUtils {
|
||||||
* and the "ignoreUnresolvablePlaceholders" flag is {@code false}
|
* and the "ignoreUnresolvablePlaceholders" flag is {@code false}
|
||||||
*/
|
*/
|
||||||
public static String resolvePlaceholders(String text, boolean ignoreUnresolvablePlaceholders) {
|
public static String resolvePlaceholders(String text, boolean ignoreUnresolvablePlaceholders) {
|
||||||
|
if (text.isEmpty()) {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
PropertyPlaceholderHelper helper = (ignoreUnresolvablePlaceholders ? nonStrictHelper : strictHelper);
|
PropertyPlaceholderHelper helper = (ignoreUnresolvablePlaceholders ? nonStrictHelper : strictHelper);
|
||||||
return helper.replacePlaceholders(text, new SystemPropertyPlaceholderResolver(text));
|
return helper.replacePlaceholders(text, new SystemPropertyPlaceholderResolver(text));
|
||||||
}
|
}
|
||||||
|
|
|
@ -965,6 +965,8 @@ public interface JdbcOperations {
|
||||||
* @param pss object to set parameters on the PreparedStatement
|
* @param pss object to set parameters on the PreparedStatement
|
||||||
* created by this method
|
* created by this method
|
||||||
* @return an array of the number of rows affected by each statement
|
* @return an array of the number of rows affected by each statement
|
||||||
|
* (may also contain special JDBC-defined negative values for affected rows such as
|
||||||
|
* {@link java.sql.Statement#SUCCESS_NO_INFO}/{@link java.sql.Statement#EXECUTE_FAILED})
|
||||||
* @throws DataAccessException if there is any problem issuing the update
|
* @throws DataAccessException if there is any problem issuing the update
|
||||||
*/
|
*/
|
||||||
int[] batchUpdate(String sql, BatchPreparedStatementSetter pss) throws DataAccessException;
|
int[] batchUpdate(String sql, BatchPreparedStatementSetter pss) throws DataAccessException;
|
||||||
|
@ -974,6 +976,8 @@ public interface JdbcOperations {
|
||||||
* @param sql the SQL statement to execute
|
* @param sql the SQL statement to execute
|
||||||
* @param batchArgs the List of Object arrays containing the batch of arguments for the query
|
* @param batchArgs the List of Object arrays containing the batch of arguments for the query
|
||||||
* @return an array containing the numbers of rows affected by each update in the batch
|
* @return an array containing the numbers of rows affected by each update in the batch
|
||||||
|
* (may also contain special JDBC-defined negative values for affected rows such as
|
||||||
|
* {@link java.sql.Statement#SUCCESS_NO_INFO}/{@link java.sql.Statement#EXECUTE_FAILED})
|
||||||
* @throws DataAccessException if there is any problem issuing the update
|
* @throws DataAccessException if there is any problem issuing the update
|
||||||
*/
|
*/
|
||||||
int[] batchUpdate(String sql, List<Object[]> batchArgs) throws DataAccessException;
|
int[] batchUpdate(String sql, List<Object[]> batchArgs) throws DataAccessException;
|
||||||
|
@ -985,20 +989,24 @@ public interface JdbcOperations {
|
||||||
* @param argTypes the SQL types of the arguments
|
* @param argTypes the SQL types of the arguments
|
||||||
* (constants from {@code java.sql.Types})
|
* (constants from {@code java.sql.Types})
|
||||||
* @return an array containing the numbers of rows affected by each update in the batch
|
* @return an array containing the numbers of rows affected by each update in the batch
|
||||||
|
* (may also contain special JDBC-defined negative values for affected rows such as
|
||||||
|
* {@link java.sql.Statement#SUCCESS_NO_INFO}/{@link java.sql.Statement#EXECUTE_FAILED})
|
||||||
* @throws DataAccessException if there is any problem issuing the update
|
* @throws DataAccessException if there is any problem issuing the update
|
||||||
*/
|
*/
|
||||||
int[] batchUpdate(String sql, List<Object[]> batchArgs, int[] argTypes) throws DataAccessException;
|
int[] batchUpdate(String sql, List<Object[]> batchArgs, int[] argTypes) throws DataAccessException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute multiple batches using the supplied SQL statement with the collect of supplied arguments.
|
* Execute multiple batches using the supplied SQL statement with the collect of supplied
|
||||||
* The arguments' values will be set using the ParameterizedPreparedStatementSetter.
|
* arguments. The arguments' values will be set using the ParameterizedPreparedStatementSetter.
|
||||||
* Each batch should be of size indicated in 'batchSize'.
|
* Each batch should be of size indicated in 'batchSize'.
|
||||||
* @param sql the SQL statement to execute.
|
* @param sql the SQL statement to execute.
|
||||||
* @param batchArgs the List of Object arrays containing the batch of arguments for the query
|
* @param batchArgs the List of Object arrays containing the batch of arguments for the query
|
||||||
* @param batchSize batch size
|
* @param batchSize batch size
|
||||||
* @param pss the ParameterizedPreparedStatementSetter to use
|
* @param pss the ParameterizedPreparedStatementSetter to use
|
||||||
* @return an array containing for each batch another array containing the numbers of rows affected
|
* @return an array containing for each batch another array containing the numbers of
|
||||||
* by each update in the batch
|
* rows affected by each update in the batch
|
||||||
|
* (may also contain special JDBC-defined negative values for affected rows such as
|
||||||
|
* {@link java.sql.Statement#SUCCESS_NO_INFO}/{@link java.sql.Statement#EXECUTE_FAILED})
|
||||||
* @throws DataAccessException if there is any problem issuing the update
|
* @throws DataAccessException if there is any problem issuing the update
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -530,6 +530,8 @@ public interface NamedParameterJdbcOperations {
|
||||||
* @param sql the SQL statement to execute
|
* @param sql the SQL statement to execute
|
||||||
* @param batchValues the array of Maps containing the batch of arguments for the query
|
* @param batchValues the array of Maps containing the batch of arguments for the query
|
||||||
* @return an array containing the numbers of rows affected by each update in the batch
|
* @return an array containing the numbers of rows affected by each update in the batch
|
||||||
|
* (may also contain special JDBC-defined negative values for affected rows such as
|
||||||
|
* {@link java.sql.Statement#SUCCESS_NO_INFO}/{@link java.sql.Statement#EXECUTE_FAILED})
|
||||||
* @throws DataAccessException if there is any problem issuing the update
|
* @throws DataAccessException if there is any problem issuing the update
|
||||||
*/
|
*/
|
||||||
int[] batchUpdate(String sql, Map<String, ?>[] batchValues);
|
int[] batchUpdate(String sql, Map<String, ?>[] batchValues);
|
||||||
|
@ -537,8 +539,11 @@ public interface NamedParameterJdbcOperations {
|
||||||
/**
|
/**
|
||||||
* Execute a batch using the supplied SQL statement with the batch of supplied arguments.
|
* Execute a batch using the supplied SQL statement with the batch of supplied arguments.
|
||||||
* @param sql the SQL statement to execute
|
* @param sql the SQL statement to execute
|
||||||
* @param batchArgs the array of {@link SqlParameterSource} containing the batch of arguments for the query
|
* @param batchArgs the array of {@link SqlParameterSource} containing the batch of
|
||||||
|
* arguments for the query
|
||||||
* @return an array containing the numbers of rows affected by each update in the batch
|
* @return an array containing the numbers of rows affected by each update in the batch
|
||||||
|
* (may also contain special JDBC-defined negative values for affected rows such as
|
||||||
|
* {@link java.sql.Statement#SUCCESS_NO_INFO}/{@link java.sql.Statement#EXECUTE_FAILED})
|
||||||
* @throws DataAccessException if there is any problem issuing the update
|
* @throws DataAccessException if there is any problem issuing the update
|
||||||
*/
|
*/
|
||||||
int[] batchUpdate(String sql, SqlParameterSource[] batchArgs);
|
int[] batchUpdate(String sql, SqlParameterSource[] batchArgs);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2018 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -51,11 +51,11 @@ import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
* as well as for non-transactional execution (if configured appropriately).
|
* as well as for non-transactional execution (if configured appropriately).
|
||||||
*
|
*
|
||||||
* <p><b>NOTE</b>: This filter will by default <i>not</i> flush the Hibernate Session,
|
* <p><b>NOTE</b>: This filter will by default <i>not</i> flush the Hibernate Session,
|
||||||
* with the flush mode set to {@code FlushMode.NEVER}. It assumes to be used
|
* with the flush mode set to {@code FlushMode.MANUAL}. It assumes to be used
|
||||||
* in combination with service layer transactions that care for the flushing: The
|
* in combination with service layer transactions that care for the flushing: The
|
||||||
* active transaction manager will temporarily change the flush mode to
|
* active transaction manager will temporarily change the flush mode to
|
||||||
* {@code FlushMode.AUTO} during a read-write transaction, with the flush
|
* {@code FlushMode.AUTO} during a read-write transaction, with the flush
|
||||||
* mode reset to {@code FlushMode.NEVER} at the end of each transaction.
|
* mode reset to {@code FlushMode.MANUAL} at the end of each transaction.
|
||||||
*
|
*
|
||||||
* <p><b>WARNING:</b> Applying this filter to existing logic can cause issues that
|
* <p><b>WARNING:</b> Applying this filter to existing logic can cause issues that
|
||||||
* have not appeared before, through the use of a single Hibernate Session for the
|
* have not appeared before, through the use of a single Hibernate Session for the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -383,7 +383,7 @@ public abstract class TransactionSynchronizationManager {
|
||||||
* as argument for the {@code beforeCommit} callback, to be able
|
* as argument for the {@code beforeCommit} callback, to be able
|
||||||
* to suppress change detection on commit. The present method is meant
|
* to suppress change detection on commit. The present method is meant
|
||||||
* to be used for earlier read-only checks, for example to set the
|
* to be used for earlier read-only checks, for example to set the
|
||||||
* flush mode of a Hibernate Session to "FlushMode.NEVER" upfront.
|
* flush mode of a Hibernate Session to "FlushMode.MANUAL" upfront.
|
||||||
* @see org.springframework.transaction.TransactionDefinition#isReadOnly()
|
* @see org.springframework.transaction.TransactionDefinition#isReadOnly()
|
||||||
* @see TransactionSynchronization#beforeCommit(boolean)
|
* @see TransactionSynchronization#beforeCommit(boolean)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2018 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -13,6 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.util;
|
package org.springframework.web.util;
|
||||||
|
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
|
@ -73,16 +74,18 @@ public abstract class ServletContextPropertyUtils {
|
||||||
* @see SystemPropertyUtils#PLACEHOLDER_SUFFIX
|
* @see SystemPropertyUtils#PLACEHOLDER_SUFFIX
|
||||||
* @see SystemPropertyUtils#resolvePlaceholders(String, boolean)
|
* @see SystemPropertyUtils#resolvePlaceholders(String, boolean)
|
||||||
*/
|
*/
|
||||||
public static String resolvePlaceholders(String text, ServletContext servletContext,
|
public static String resolvePlaceholders(
|
||||||
boolean ignoreUnresolvablePlaceholders) {
|
String text, ServletContext servletContext, boolean ignoreUnresolvablePlaceholders) {
|
||||||
|
|
||||||
|
if (text.isEmpty()) {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
PropertyPlaceholderHelper helper = (ignoreUnresolvablePlaceholders ? nonStrictHelper : strictHelper);
|
PropertyPlaceholderHelper helper = (ignoreUnresolvablePlaceholders ? nonStrictHelper : strictHelper);
|
||||||
return helper.replacePlaceholders(text, new ServletContextPlaceholderResolver(text, servletContext));
|
return helper.replacePlaceholders(text, new ServletContextPlaceholderResolver(text, servletContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class ServletContextPlaceholderResolver
|
private static class ServletContextPlaceholderResolver implements PropertyPlaceholderHelper.PlaceholderResolver {
|
||||||
implements PropertyPlaceholderHelper.PlaceholderResolver {
|
|
||||||
|
|
||||||
private final String text;
|
private final String text;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue